package gremlin import ( "encoding/binary" "errors" "fmt" gremlingo "github.com/apache/tinkerpop/gremlin-go/v3/driver" ) const ( valueFlagNone byte = 0 ) func readTemp(data *[]byte, i *int, len int) *[]byte { tmp := make([]byte, len) for j := 0; j < len; j++ { tmp[j] = (*data)[j+*i] } *i += len return &tmp } func readUint32Safe(data *[]byte, i *int) uint32 { return binary.BigEndian.Uint32(*readTemp(data, i, 4)) } func readByteSafe(data *[]byte, i *int) byte { *i++ return (*data)[*i-1] } func readLongSafe(data *[]byte, i *int) int64 { return int64(binary.BigEndian.Uint64(*readTemp(data, i, 8))) } func readString(data *[]byte, i *int) (interface{}, error) { sz := int(readUint32Safe(data, i)) if sz == 0 { return "", nil } *i += sz return string((*data)[*i-sz : *i]), nil } // https://github.com/JanusGraph/janusgraph-python/blob/cd812fc0614047d25a2cabd143902806a74a8465/janusgraph_python/structure/io/graphbinaryV1.py#L133 func janusgraphRelationIdentifierReader(data *[]byte, i *int) (interface{}, error) { const relationIdentifierType = 0x1001 const ( longMarker = 0 stringMarker = 1 ) // expect type code customDataTyp := readUint32Safe(data, i) if customDataTyp != relationIdentifierType { return nil, fmt.Errorf("unknown type code. got 0x%x, expected 0x%x", customDataTyp, relationIdentifierType) } // value flag, expect this to be non-nullable if readByteSafe(data, i) != valueFlagNone { return nil, errors.New("expected non-null value") } // outVertexId var ( outVertexID any err error ) if readByteSafe(data, i) == stringMarker { outVertexID, err = readString(data, i) if err != nil { return nil, fmt.Errorf("unable to read outVertexId: %w", err) } } else { outVertexID = readLongSafe(data, i) } typeID := readLongSafe(data, i) // relationID relationID := readLongSafe(data, i) // inVertexId var inVertexID any if readByteSafe(data, i) == stringMarker { inVertexID, err = readString(data, i) if err != nil { return nil, fmt.Errorf("unable to read inVertexId: %w", err) } } else { inVertexID = readLongSafe(data, i) } return map[string]any{ "outVertexId": outVertexID, "typeId": typeID, "relationId": relationID, "inVertexId": inVertexID, }, nil } func init() { // https://issues.apache.org/jira/browse/TINKERPOP-2802 gremlingo.RegisterCustomTypeReader("janusgraph.RelationIdentifier", janusgraphRelationIdentifierReader) }