Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/

/**
* GraphBinary 1.0 support implementation.
* GraphBinary 4.0 support implementation.
*
* The officially expected entrypoint is GraphBinaryReader/GraphBinaryWriter pair of classes,
* examine lib/driver/** for use cases.
Expand All @@ -27,33 +27,13 @@
* also consider AnySerializer.serialize() unit tests for real examples.
* See NumberSerializationStrategy to understand how it deals with JavaScript numbers' serialization.
*
* Consider AnySerializer.serialize()/deserialize() unit tests to see what is not implemented,
* what is ignored, what is not expected to be (de)serialized, etc.
*
* TODO: it has the following open topics:
* - [] Should we do anything for application/vnd.graphbinary-v1.0-stringd mime type support?
* Core Data Types support:
* - [] 0x22: BigDecimal
* - [] 0x2b: Tree
* - [] 0x2c: Metrics
* - [] 0x2d: TraversalMetrics
* - [] 0x00: Custom
* Extended Types support:
* - [] 0x80: Char
* - [] 0x81: Duration
* - [] 0x82: InetAddress
* - [] 0x83: Instant
* - [] 0x84: LocalDate
* - [] 0x85: LocalDateTime
* - [] 0x86: LocalTime
* - [] 0x87: MonthDay
* - [] 0x88: OffsetDateTime
* - [] 0x89: OffsetTime
* - [] 0x8a: Period
* - [] 0x8b: Year
* - [] 0x8c: YearMonth
* - [] 0x8d: ZonedDateTime
* - [] 0x8e: ZoneOffset
*
* @author Igor Ostapenko
*/
Expand All @@ -63,10 +43,8 @@ import DataType from './internals/DataType.js';
import * as utils from './internals/utils.js';
import IntSerializer from './internals/IntSerializer.js';
import LongSerializer from './internals/LongSerializer.js';
import LongSerializerNg from './internals/LongSerializerNg.js';
import StringSerializer from './internals/StringSerializer.js';
import DateSerializer from './internals/DateSerializer.js';
import OffsetDateTimeSerializer from './internals/OffsetDateTimeSerializer.js';
import DateTimeSerializer from './internals/DateTimeSerializer.js';
import DoubleSerializer from './internals/DoubleSerializer.js';
import FloatSerializer from './internals/FloatSerializer.js';
import ArraySerializer from './internals/ArraySerializer.js';
Expand All @@ -78,19 +56,15 @@ import PathSerializer from './internals/PathSerializer.js';
import PropertySerializer from './internals/PropertySerializer.js';
import VertexSerializer from './internals/VertexSerializer.js';
import VertexPropertySerializer from './internals/VertexPropertySerializer.js';
import PSerializer from './internals/PSerializer.js';
import TraverserSerializer from './internals/TraverserSerializer.js';
import EnumSerializer from './internals/EnumSerializer.js';
import LambdaSerializer from './internals/LambdaSerializer.js';
import BigIntegerSerializer from './internals/BigIntegerSerializer.js';
import ByteSerializer from './internals/ByteSerializer.js';
import ByteBufferSerializer from './internals/ByteBufferSerializer.js';
import BinarySerializer from './internals/BinarySerializer.js';
import ShortSerializer from './internals/ShortSerializer.js';
import BooleanSerializer from './internals/BooleanSerializer.js';
import TextPSerializer from './internals/TextPSerializer.js';
import TraversalStrategySerializer from './internals/TraversalStrategySerializer.js';
import BulkSetSerializer from './internals/BulkSetSerializer.js';
import MarkerSerializer from './internals/MarkerSerializer.js';
import UnspecifiedNullSerializer from './internals/UnspecifiedNullSerializer.js';
import EnumSerializer from './internals/EnumSerializer.js';
import StubSerializer from './internals/StubSerializer.js';
import NumberSerializationStrategy from './internals/NumberSerializationStrategy.js';
import AnySerializer from './internals/AnySerializer.js';
import GraphBinaryReader from './internals/GraphBinaryReader.js';
Expand All @@ -105,12 +79,8 @@ ioc.serializers = {};

ioc.intSerializer = new IntSerializer(ioc);
ioc.longSerializer = new LongSerializer(ioc);
ioc.longSerializerNg = new LongSerializerNg(ioc);
ioc.stringSerializer = new StringSerializer(ioc, ioc.DataType.STRING);
ioc.dateSerializer = new DateSerializer(ioc, ioc.DataType.DATE);
ioc.offsetDateTimeSerializer = new OffsetDateTimeSerializer(ioc, ioc.DataType.OFFSETDATETIME);
ioc.timestampSerializer = new DateSerializer(ioc, ioc.DataType.TIMESTAMP);
ioc.classSerializer = new StringSerializer(ioc, ioc.DataType.CLASS);
ioc.dateTimeSerializer = new DateTimeSerializer(ioc);
ioc.doubleSerializer = new DoubleSerializer(ioc);
ioc.floatSerializer = new FloatSerializer(ioc);
ioc.listSerializer = new ArraySerializer(ioc, ioc.DataType.LIST);
Expand All @@ -122,19 +92,20 @@ ioc.pathSerializer = new PathSerializer(ioc);
ioc.propertySerializer = new PropertySerializer(ioc);
ioc.vertexSerializer = new VertexSerializer(ioc);
ioc.vertexPropertySerializer = new VertexPropertySerializer(ioc);
ioc.pSerializer = new PSerializer(ioc);
ioc.traverserSerializer = new TraverserSerializer(ioc);
ioc.enumSerializer = new EnumSerializer(ioc);
ioc.lambdaSerializer = new LambdaSerializer(ioc);
ioc.bigIntegerSerializer = new BigIntegerSerializer(ioc);
ioc.byteSerializer = new ByteSerializer(ioc);
ioc.byteBufferSerializer = new ByteBufferSerializer(ioc);
ioc.binarySerializer = new BinarySerializer(ioc);
ioc.shortSerializer = new ShortSerializer(ioc);
ioc.booleanSerializer = new BooleanSerializer(ioc);
ioc.textPSerializer = new TextPSerializer(ioc);
ioc.traversalStrategySerializer = new TraversalStrategySerializer(ioc);
ioc.bulkSetSerializer = new BulkSetSerializer(ioc);
ioc.markerSerializer = new MarkerSerializer(ioc);
ioc.unspecifiedNullSerializer = new UnspecifiedNullSerializer(ioc);
ioc.enumSerializer = new EnumSerializer(ioc);

// Register stub serializers for unimplemented v4 types
new StubSerializer(ioc, ioc.DataType.TREE, 'Tree');
new StubSerializer(ioc, ioc.DataType.GRAPH, 'Graph');
new StubSerializer(ioc, ioc.DataType.COMPOSITEPDT, 'CompositePDT');
new StubSerializer(ioc, ioc.DataType.PRIMITIVEPDT, 'PrimitivePDT');

ioc.numberSerializationStrategy = new NumberSerializationStrategy(ioc);
ioc.anySerializer = new AnySerializer(ioc);
Expand All @@ -148,12 +119,8 @@ export const {
serializers,
intSerializer,
longSerializer,
longSerializerNg,
stringSerializer,
dateSerializer,
offsetDateTimeSerializer,
timestampSerializer,
classSerializer,
dateTimeSerializer,
doubleSerializer,
floatSerializer,
listSerializer,
Expand All @@ -165,19 +132,14 @@ export const {
propertySerializer,
vertexSerializer,
vertexPropertySerializer,
pSerializer,
traverserSerializer,
enumSerializer,
lambdaSerializer,
bigIntegerSerializer,
byteSerializer,
byteBufferSerializer,
binarySerializer,
shortSerializer,
booleanSerializer,
textPSerializer,
traversalStrategySerializer,
bulkSetSerializer,
markerSerializer,
unspecifiedNullSerializer,
enumSerializer,
numberSerializationStrategy,
anySerializer,
graphBinaryReader,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,9 @@ export default class AnySerializer {
// specifically ordered, the first canBeUsedFor=true wins
this.serializers = [
ioc.unspecifiedNullSerializer,

ioc.numberSerializationStrategy,

ioc.booleanSerializer,
ioc.offsetDateTimeSerializer,
ioc.dateSerializer,
ioc.pSerializer,
ioc.traverserSerializer,
ioc.enumSerializer,
ioc.dateTimeSerializer,
ioc.setSerializer,
ioc.listSerializer,
ioc.uuidSerializer,
Expand All @@ -47,14 +41,10 @@ export default class AnySerializer {
ioc.propertySerializer,
ioc.vertexSerializer,
ioc.vertexPropertySerializer,
ioc.enumSerializer,
ioc.stringSerializer,
ioc.classSerializer,
ioc.textPSerializer,
ioc.traversalStrategySerializer,

ioc.byteBufferSerializer, // Buffer instance
ioc.lambdaSerializer, // any function
ioc.mapSerializer, // Map or any Object
ioc.binarySerializer,
ioc.mapSerializer,
];
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ export default class ArraySerializer {
deserialize(buffer, fullyQualifiedFormat = true) {
let len = 0;
let cursor = buffer;
let isBulked = false;

try {
if (buffer === undefined || buffer === null || !(buffer instanceof Buffer)) {
Expand All @@ -95,9 +96,10 @@ export default class ArraySerializer {
if (value_flag === 1) {
return { v: null, len };
}
if (value_flag !== 0) {
if (value_flag !== 0 && value_flag !== 2) {
throw new Error('unexpected {value_flag}');
}
isBulked = value_flag === 2;
cursor = cursor.slice(1);
}

Expand Down Expand Up @@ -125,7 +127,21 @@ export default class ArraySerializer {
throw err;
}
cursor = cursor.slice(value_len);
v.push(value);

if (isBulked) {
if (cursor.length < 8) {
throw new Error(`{item_${i}}: bulk count is missing`);
}
const bulkCount = cursor.readBigInt64BE();
len += 8;
cursor = cursor.slice(8);

for (let j = 0n; j < bulkCount; j++) {
v.push(value);
}
} else {
v.push(value);
}
}

return { v, len };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@

import { Buffer } from 'buffer';

export default class ByteBufferSerializer {
export default class BinarySerializer {
constructor(ioc) {
this.ioc = ioc;
this.ioc.serializers[ioc.DataType.BYTEBUFFER] = this;
this.ioc.serializers[ioc.DataType.BINARY] = this;
}

canBeUsedFor(value) {
Expand All @@ -36,14 +36,14 @@ export default class ByteBufferSerializer {
serialize(item, fullyQualifiedFormat = true) {
if (item === undefined || item === null) {
if (fullyQualifiedFormat) {
return Buffer.from([this.ioc.DataType.BYTEBUFFER, 0x01]);
return Buffer.from([this.ioc.DataType.BINARY, 0x01]);
}
return Buffer.from([0x00, 0x00, 0x00, 0x00]); // {length} = 0
}

const bufs = [];
if (fullyQualifiedFormat) {
bufs.push(Buffer.from([this.ioc.DataType.BYTEBUFFER, 0x00]));
bufs.push(Buffer.from([this.ioc.DataType.BINARY, 0x00]));
}

// {length}
Expand Down Expand Up @@ -79,7 +79,7 @@ export default class ByteBufferSerializer {
if (fullyQualifiedFormat) {
const type_code = cursor.readUInt8();
len++;
if (type_code !== this.ioc.DataType.BYTEBUFFER) {
if (type_code !== this.ioc.DataType.BINARY) {
throw new Error('unexpected {type_code}');
}
cursor = cursor.slice(1);
Expand Down Expand Up @@ -111,7 +111,7 @@ export default class ByteBufferSerializer {
}
cursor = cursor.slice(length_len);

if (length !== cursor.length) {
if (cursor.length < length) {
throw new Error(`{value}: unexpected actual {value} length=${cursor.length} when {length}=${length}`);
}
const v = cursor.slice(0, length);
Expand Down
Loading
Loading