@devgrid/messagepack
Version:
Extandable MessagePack serializer
217 lines • 7.09 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const buffer_1 = require("buffer");
const type_detect_1 = __importDefault(require("type-detect"));
const es_toolkit_1 = require("es-toolkit");
const common_1 = require("@devgrid/common");
const smartbuffer_1 = require("@devgrid/smartbuffer");
const encodeString = (x, buf) => {
const len = buffer_1.Buffer.byteLength(x);
if (len < 32) {
buf.writeInt8(0xa0 | len);
if (len === 0) {
return;
}
}
else if (len <= 0xff) {
buf.writeUInt16BE(0xd900 | len);
}
else if (len <= 0xffff) {
buf.writeInt8(0xda);
buf.writeUInt16BE(len);
}
else {
buf.writeInt8(0xdb);
buf.writeUInt32BE(len);
}
buf.write(x, undefined, len);
};
const encodeCustom = (x, type, encFunc, buf) => {
const encoded = encFunc(x, buf);
const length = encoded.length;
if (length === 1) {
buf.writeUInt8(0xd4);
}
else if (length === 2) {
buf.writeUInt8(0xd5);
}
else if (length === 4) {
buf.writeUInt8(0xd6);
}
else if (length === 8) {
buf.writeUInt8(0xd7);
}
else if (length === 16) {
buf.writeUInt8(0xd8);
}
else if (length < 256) {
buf.writeUInt16BE(0xc700 | length);
}
else if (length < 0x10000) {
buf.writeUInt32BE(0xc8000000 | (length << 8));
buf.woffset -= 1;
}
else {
buf.writeUInt8(0xc9);
buf.writeUInt32BE(length);
}
buf.writeInt8(type);
buf.write(encoded);
};
class Encoder {
constructor(encodingTypes) {
this.encodingTypes = encodingTypes;
}
encode(x, buf) {
buf = buf || new smartbuffer_1.SmartBuffer(1024, true);
this._encode(x, buf);
return buf;
}
_encode(x, buf) {
const type = typeof x;
switch (type) {
case 'undefined': {
buf.writeUInt32BE(0xd4000000);
buf.woffset--;
break;
}
case 'boolean': {
if (x === true) {
buf.writeInt8(0xc3);
}
else {
buf.writeInt8(0xc2);
}
break;
}
case 'string': {
encodeString(x, buf);
break;
}
case 'bigint': {
encodeCustom(x, 120, this.encodingTypes.get(120).encode, buf);
break;
}
case 'number': {
if (x !== (x | 0)) {
buf.writeInt8(0xcb);
buf.writeDoubleBE(x);
}
else if (x >= 0) {
if (x < 128) {
buf.writeInt8(x);
}
else if (x < 256) {
buf.writeInt16BE(0xcc00 | x);
}
else if (x < 65536) {
buf.writeInt8(0xcd);
buf.writeUInt16BE(x);
}
else if (x <= 0xffffffff) {
buf.writeInt8(0xce);
buf.writeUInt32BE(x);
}
else if (x <= 9007199254740991) {
buf.writeInt8(0xcf);
buf.writeUInt64BE(x);
}
else {
buf.writeInt8(0xcb);
buf.writeDoubleBE(x);
}
}
else {
if (x >= -32) {
buf.writeInt8(0x100 + x);
}
else if (x >= -128) {
buf.writeInt8(0xd0);
buf.writeInt8(x);
}
else if (x >= -32768) {
buf.writeInt8(0xd1);
buf.writeInt16BE(x);
}
else if (x > -214748365) {
buf.writeInt8(0xd2);
buf.writeInt32BE(x);
}
else if (x >= -9007199254740991) {
buf.writeInt8(0xd3);
buf.writeInt64BE(x);
}
else {
buf.writeInt8(0xcb);
buf.writeDoubleBE(x);
}
}
break;
}
default: {
if (x === null) {
buf.writeInt8(0xc0);
}
else if ((0, common_1.isBuffer)(x)) {
if (x.length <= 0xff) {
buf.writeInt16BE(0xc400 | x.length);
}
else if (x.length <= 0xffff) {
buf.writeInt8(0xc5);
buf.writeUInt16BE(x.length);
}
else {
buf.writeUInt8(0xc6);
buf.writeUInt32BE(x.length);
}
buf.write(x);
}
else if (Array.isArray(x)) {
if (x.length < 16) {
buf.writeInt8(0x90 | x.length);
}
else if (x.length < 65536) {
buf.writeInt8(0xdc);
buf.writeUInt16BE(x.length);
}
else {
buf.writeInt8(0xdd);
buf.writeUInt32BE(x.length);
}
for (const obj of x) {
this._encode(obj, buf);
}
}
else if ((0, es_toolkit_1.isPlainObject)(x)) {
const keys = Object.keys(x);
if (keys.length < 16) {
buf.writeInt8(0x80 | keys.length);
}
else {
buf.writeInt8(0xde);
buf.writeUInt16BE(keys.length);
}
for (const key of keys) {
encodeString(key, buf);
this._encode(x[key], buf);
}
}
else {
const encTypes = this.encodingTypes;
for (const [type_, info] of encTypes.entries()) {
if (info.check(x)) {
encodeCustom(x, type_, info.encode, buf);
return;
}
}
throw new Error(`Not supported: ${(0, type_detect_1.default)(x)}`);
}
}
}
}
}
exports.default = Encoder;
//# sourceMappingURL=encoder.js.map