jsonbinpack
Version:
A space-efficient schema-driven binary JSON serialization format based on JSON Schema
194 lines (193 loc) • 9.46 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ANY_PACKED_TYPE_TAG_BYTE_PREFIX = void 0;
var assert_1 = require("assert");
var limits_1 = require("../../utils/limits");
var types_1 = require("./types");
var encoding_type_1 = require("../encoding-type");
var encode_1 = require("../integer/encode");
var encode_2 = require("../string/encode");
var encode_3 = require("../number/encode");
var encode_4 = require("../object/encode");
var encode_5 = require("../array/encode");
var STRING_ENCODING = 'utf8';
var encodeTypeTag = function (buffer, offset, tag, context) {
return encode_1.BOUNDED_MULTIPLE_8BITS_ENUM_FIXED(buffer, offset, tag, {
minimum: limits_1.UINT8_MIN,
maximum: limits_1.UINT8_MAX,
multiplier: 1
}, context);
};
var findHighest2Exponent = function (value, start, limit) {
var exponent = start - 1;
if (((2 << exponent) >>> 0) > value) {
return null;
}
while (((2 << exponent) >>> 0) <= value) {
exponent += 1;
if (exponent > limit) {
return null;
}
}
return exponent;
};
var ANY_PACKED_TYPE_TAG_BYTE_PREFIX = function (buffer, offset, value, _options, context) {
if (Array.isArray(value)) {
var size = value.length;
if (size >= limits_1.UINT5_MAX) {
var typeTag_1 = types_1.getTypeTag(types_1.Type.Array, 0);
var tagBytes_1 = encodeTypeTag(buffer, offset, typeTag_1, context);
var valueBytes_1 = encode_5.FLOOR_TYPED_LENGTH_PREFIX(buffer, offset + tagBytes_1, value, {
minimum: 0,
prefixEncodings: [],
encoding: {
type: encoding_type_1.EncodingType.Any,
encoding: 'ANY_PACKED_TYPE_TAG_BYTE_PREFIX',
options: {}
}
}, context);
return tagBytes_1 + valueBytes_1;
}
var typeTag_2 = types_1.getTypeTag(types_1.Type.Array, value.length + 1);
var tagBytes_2 = encodeTypeTag(buffer, offset, typeTag_2, context);
var valueBytes_2 = encode_5.FIXED_TYPED_ARRAY(buffer, offset + tagBytes_2, value, {
size: size,
prefixEncodings: [],
encoding: {
type: encoding_type_1.EncodingType.Any,
encoding: 'ANY_PACKED_TYPE_TAG_BYTE_PREFIX',
options: {}
}
}, context);
return tagBytes_2 + valueBytes_2;
}
else if (typeof value === 'object' && value !== null) {
var size = Object.keys(value).length;
if (size > limits_1.UINT5_MAX - 1) {
var typeTag_3 = types_1.getTypeTag(types_1.Type.Object, 0);
var tagBytes_3 = encodeTypeTag(buffer, offset, typeTag_3, context);
var valueBytes_3 = encode_4.ARBITRARY_TYPED_KEYS_OBJECT(buffer, offset + tagBytes_3, value, {
keyEncoding: {
type: encoding_type_1.EncodingType.String,
encoding: 'STRING_UNBOUNDED_SCOPED_PREFIX_LENGTH',
options: {}
},
encoding: {
type: encoding_type_1.EncodingType.Any,
encoding: 'ANY_PACKED_TYPE_TAG_BYTE_PREFIX',
options: {}
}
}, context);
return tagBytes_3 + valueBytes_3;
}
var typeTag_4 = types_1.getTypeTag(types_1.Type.Object, size + 1);
var tagBytes_4 = encodeTypeTag(buffer, offset, typeTag_4, context);
var valueBytes_4 = encode_4.ARBITRARY_TYPED_KEYS_OBJECT_WITHOUT_LENGTH(buffer, offset + tagBytes_4, value, {
size: size,
keyEncoding: {
type: encoding_type_1.EncodingType.String,
encoding: 'STRING_UNBOUNDED_SCOPED_PREFIX_LENGTH',
options: {}
},
encoding: {
type: encoding_type_1.EncodingType.Any,
encoding: 'ANY_PACKED_TYPE_TAG_BYTE_PREFIX',
options: {}
}
}, context);
return tagBytes_4 + valueBytes_4;
}
else if (value === null) {
var typeTag_5 = types_1.getTypeTag(types_1.Type.Other, types_1.Subtype.Null);
return encodeTypeTag(buffer, offset, typeTag_5, context);
}
else if (typeof value === 'boolean') {
var typeTag_6 = value
? types_1.getTypeTag(types_1.Type.Other, types_1.Subtype.True)
: types_1.getTypeTag(types_1.Type.Other, types_1.Subtype.False);
return encodeTypeTag(buffer, offset, typeTag_6, context);
}
else if (typeof value === 'string') {
var length_1 = Buffer.byteLength(value, STRING_ENCODING);
if (length_1 < limits_1.UINT5_MAX && context.strings.has(value)) {
var typeTag_7 = types_1.getTypeTag(types_1.Type.SharedString, length_1 + 1);
var tagBytes_5 = encodeTypeTag(buffer, offset, typeTag_7, context);
return tagBytes_5 + encode_2.SHARED_STRING_POINTER_RELATIVE_OFFSET(buffer, offset + tagBytes_5, value, {
size: length_1
}, context);
}
else if (length_1 < limits_1.UINT5_MAX && !context.strings.has(value)) {
var typeTag_8 = types_1.getTypeTag(types_1.Type.String, length_1 + 1);
var tagBytes_6 = encodeTypeTag(buffer, offset, typeTag_8, context);
return tagBytes_6 + encode_2.UTF8_STRING_NO_LENGTH(buffer, offset + tagBytes_6, value, {
size: length_1
}, context);
}
else if (length_1 >= limits_1.UINT5_MAX && length_1 < limits_1.UINT5_MAX * 2 && !context.strings.has(value)) {
var typeTag_9 = types_1.getTypeTag(types_1.Type.LongString, length_1 - limits_1.UINT5_MAX);
var tagBytes_7 = encodeTypeTag(buffer, offset, typeTag_9, context);
return tagBytes_7 + encode_2.UTF8_STRING_NO_LENGTH(buffer, offset + tagBytes_7, value, {
size: length_1
}, context);
}
else if (length_1 >= Math.pow(2, types_1.LONG_STRING_BASE_EXPONENT_MINIMUM) &&
length_1 <= Math.pow(2, types_1.LONG_STRING_BASE_EXPONENT_MAXIMUM) &&
!context.strings.has(value)) {
var exponent = findHighest2Exponent(length_1, types_1.LONG_STRING_BASE_EXPONENT_MINIMUM, types_1.LONG_STRING_BASE_EXPONENT_MAXIMUM);
assert_1.strict(typeof exponent === 'number' && Math.pow(2, exponent) <= length_1);
var typeTag_10 = types_1.getTypeTag(types_1.Type.Other, exponent);
var tagBytes_8 = encodeTypeTag(buffer, offset, typeTag_10, context);
var lengthBytes = encode_1.FLOOR_MULTIPLE_ENUM_VARINT(buffer, offset + tagBytes_8, length_1, {
minimum: Math.pow(2, exponent),
multiplier: 1
}, context);
return tagBytes_8 + lengthBytes + encode_2.UTF8_STRING_NO_LENGTH(buffer, offset + tagBytes_8 + lengthBytes, value, {
size: length_1
}, context);
}
var typeTag_11 = types_1.getTypeTag(types_1.Type.String, 0);
var tagBytes_9 = context.strings.has(value)
? 0
: encodeTypeTag(buffer, offset, typeTag_11, context);
var valueBytes_5 = encode_2.FLOOR_PREFIX_LENGTH_ENUM_VARINT(buffer, offset + tagBytes_9, value, {
minimum: 0
}, context);
return tagBytes_9 + valueBytes_5;
}
else if (Number.isInteger(value)) {
var isPositive = value >= 0;
var absoluteValue = isPositive ? value : Math.abs(value) - 1;
if (absoluteValue <= limits_1.UINT8_MAX) {
var type_1 = isPositive
? types_1.Type.PositiveIntegerByte : types_1.Type.NegativeIntegerByte;
if (absoluteValue <= limits_1.UINT5_MAX - 1) {
var typeTag_12 = types_1.getTypeTag(type_1, absoluteValue + 1);
return encodeTypeTag(buffer, offset, typeTag_12, context);
}
var typeTag_13 = types_1.getTypeTag(type_1, 0);
var tagBytes_10 = encodeTypeTag(buffer, offset, typeTag_13, context);
var valueBytes_6 = encode_1.BOUNDED_MULTIPLE_8BITS_ENUM_FIXED(buffer, offset + tagBytes_10, absoluteValue, {
minimum: limits_1.UINT8_MIN,
maximum: limits_1.UINT8_MAX,
multiplier: 1
}, context);
return tagBytes_10 + valueBytes_6;
}
var type = types_1.Type.Other;
var subtype = isPositive
? types_1.Subtype.PositiveInteger : types_1.Subtype.NegativeInteger;
assert_1.strict(subtype === types_1.Subtype.PositiveInteger || -(absoluteValue + 1) === value);
var typeTag_14 = types_1.getTypeTag(type, subtype);
var tagBytes_11 = encodeTypeTag(buffer, offset, typeTag_14, context);
var valueBytes_7 = encode_1.FLOOR_MULTIPLE_ENUM_VARINT(buffer, offset + tagBytes_11, absoluteValue, {
minimum: 0,
multiplier: 1
}, context);
return tagBytes_11 + valueBytes_7;
}
var typeTag = types_1.getTypeTag(types_1.Type.Other, types_1.Subtype.Number);
var tagBytes = encodeTypeTag(buffer, offset, typeTag, context);
var valueBytes = encode_3.DOUBLE_VARINT_TUPLE(buffer, offset + tagBytes, value, {}, context);
return tagBytes + valueBytes;
};
exports.ANY_PACKED_TYPE_TAG_BYTE_PREFIX = ANY_PACKED_TYPE_TAG_BYTE_PREFIX;