UNPKG

diffusion

Version:

Diffusion JavaScript client

382 lines (381 loc) 12.4 kB
"use strict"; /** * @module CBOR */ var __values = (this && this.__values) || function(o) { var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0; if (m) return m.call(o); if (o && typeof o.length === "number") return { next: function () { if (o && i >= o.length) o = void 0; return { value: o && o[i++], done: !o }; } }; throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined."); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Encoder = void 0; /* eslint-disable no-bitwise */ var int64_impl_1 = require("./../data/primitive/int64-impl"); var buffer_output_stream_1 = require("./../io/buffer-output-stream"); var uint8array_1 = require("./../util/uint8array"); var consts_1 = require("./consts"); var TWO_POW_32 = 4294967296; /** * Encoder to encode values into CBOR */ var Encoder = /** @class */ (function () { /** * Create an encoder */ function Encoder() { this.bos = new buffer_output_stream_1.BufferOutputStream(); } /** * Write a byte to the output stream * * @param byte the byte to wryte */ Encoder.prototype.writeByte = function (byte) { this.bos.write(byte); }; /** * Write a `Uint8Array` to the output stream * * @param buf the buffer to write * @param offset the starting position in the buffer * @param length the number of bytes to write */ Encoder.prototype.writeBuffer = function (buf, offset, length) { if (offset === void 0) { offset = 0; } if (length === void 0) { length = buf.length; } this.bos.writeMany(buf, offset, length); }; /** * Write an unsigned 16 bit integer to the output stream * * @param val the integer to write */ Encoder.prototype.writeUint16 = function (val) { this.writeByte((val >> 8) & 0xff); this.writeByte(val & 0xff); }; /** * Write an unsigned 32 bit integer to the output stream * * @param val the integer to write */ Encoder.prototype.writeUint32 = function (val) { this.writeUint16((val >> 16) & 0xffff); this.writeUint16(val & 0xffff); }; /** * Write an unsigned 64 bit integer to the output stream * * @param val the integer to write */ Encoder.prototype.writeUint64 = function (val) { this.writeUint32(Math.floor(val / TWO_POW_32)); this.writeUint32(val % TWO_POW_32); }; /** * Write a break header to the output stream * * @param type the header type */ Encoder.prototype.writeBreakHeader = function (type) { this.writeByte(type << 5 | consts_1.additional.BREAK); }; /** * Write a token to the output stream * * @param type the token type * @param val the numeric value associated with the token */ Encoder.prototype.writeToken = function (type, val) { var first = type << 5; if (val < 24) { this.writeByte(first | val); } else if (val < 256) { this.writeByte(first | 24); this.writeByte(val); } else if (val < 65536) { this.writeByte(first | 25); this.writeUint16(val); } else if (val < TWO_POW_32) { this.writeByte(first | 26); this.writeUint32(val); } else { this.writeByte(first | 27); this.writeUint64(val); } }; /** * Write a number of any type to the output stream * * @param val the number to write */ Encoder.prototype.writeNumber = function (val) { // determine if the number is int or not if (val.toString().indexOf('.') > -1) { /* Because Numbers are 53 bits, always write non-integers as doubles * Can't bit-twiddle to figure out how to encode, as bitwise operations * will coerce to a 32-bit integer under the hood. */ var buf = uint8array_1.uint8FromDoubleBE(val); this.writeByte((consts_1.types.SIMPLE << 5) | consts_1.additional.DOUBLE_PRECISION); this.writeBuffer(buf); } else { if (val < 0) { this.writeToken(consts_1.types.INT, -1 - val); } else { this.writeToken(consts_1.types.UINT, val); } } }; /** * Write a string to the output stream * * @param val the string to write */ Encoder.prototype.writeString = function (val) { var buf = uint8array_1.uint8FromUtf8(val); this.writeToken(consts_1.types.STRING, buf.length); this.writeBuffer(buf); }; /** * Write a Binary value to the output stream * * @param buf the buffer that contains the binary value * @param offset the starting position in the buffer * @param length the number of bytes to write */ Encoder.prototype.writeBinary = function (val, offset, length) { if (length === void 0) { length = val.length; } this.writeToken(consts_1.types.BYTES, length); this.writeBuffer(val, offset, length); }; /** * Write a boolean to the output stream * * @param val the boolean to write */ Encoder.prototype.writeBoolean = function (val) { this.writeToken(consts_1.types.SIMPLE, val ? consts_1.additional.TRUE : consts_1.additional.FALSE); }; /** * Write `undefined` to the output stream */ Encoder.prototype.writeUndefined = function () { this.writeToken(consts_1.types.SIMPLE, consts_1.additional.UNDEFINED); }; /** * Write `null` to the output stream */ Encoder.prototype.writeNull = function () { this.writeToken(consts_1.types.SIMPLE, consts_1.additional.NULL); }; /** * Write an object to the output stream * * @param val the object to encode */ Encoder.prototype.writeObject = function (val) { var e_1, _a; var keys = Object.getOwnPropertyNames(val); this.startObject(); try { for (var keys_1 = __values(keys), keys_1_1 = keys_1.next(); !keys_1_1.done; keys_1_1 = keys_1.next()) { var key = keys_1_1.value; this.encode(key); this.encode(val[key]); } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (keys_1_1 && !keys_1_1.done && (_a = keys_1.return)) _a.call(keys_1); } finally { if (e_1) throw e_1.error; } } this.break(); }; /** * Write an array to the output stream * * @param val the array to encode */ Encoder.prototype.writeArray = function (val) { var e_2, _a; this.startArray(); try { for (var val_1 = __values(val), val_1_1 = val_1.next(); !val_1_1.done; val_1_1 = val_1.next()) { var entry = val_1_1.value; this.encode(entry); } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (val_1_1 && !val_1_1.done && (_a = val_1.return)) _a.call(val_1); } finally { if (e_2) throw e_2.error; } } this.break(); }; /** * Write a BREAK stop code. This is not constrained by any pre-written strucutural context. * * @returns this encoder */ Encoder.prototype.break = function () { this.writeBreakHeader(consts_1.types.SIMPLE); return this; }; /** * Write the header for an array. * * Data may be subsequently written. No constraints are applied to subsequent data, i.e the header for a * fixed-length array may be immediately followed by a break flag * * @param length the length of the array. If not provided, this array will be considered * indefinite-length * * @returns this encoder */ Encoder.prototype.startArray = function (length) { if (length === undefined) { this.writeBreakHeader(consts_1.types.ARRAY); } else { this.writeToken(consts_1.types.ARRAY, length); } return this; }; /** * Write the header for an object. * * Data may be subsequently written. No constraints are applied to subsequent data, i.e the header for a * fixed-length object may be immediately followed by a break flag * * @param length the number of keys in the object. If not provided, this object will be considered * indefinite-length * * @returns this encoder */ Encoder.prototype.startObject = function (length) { if (length === undefined) { this.writeBreakHeader(consts_1.types.MAP); } else { this.writeToken(consts_1.types.MAP, length); } return this; }; /** * Write an {@link Int64Impl} value. * * @param val the int64 value to encode * @returns this encoder */ Encoder.prototype.writeInt64 = function (val) { var high = val.getHighBits() | 0; if (high === 0 || high === -1) { this.writeNumber(val.toNumber()); } else { if (val.isNegative()) { this.writeByte((consts_1.types.INT << 5) | 27); var buf = Uint8Array.from(val.toBuffer()); for (var i = 0; i < 8; ++i) { buf[i] = ~buf[i]; } this.writeBuffer(buf); } else { this.writeByte((consts_1.types.UINT << 5) | 27); this.writeBuffer(val.toBuffer()); } } return this; }; /** Write a double value. * * @param val the double value to encode * @returns this encoder */ Encoder.prototype.writeDouble = function (val) { var buf = uint8array_1.uint8FromDoubleBE(val); this.writeByte((consts_1.types.SIMPLE << 5) | consts_1.additional.DOUBLE_PRECISION); this.writeBuffer(buf); return this; }; /** * Encode a value to a CBOR representation. * * If a buffer is provided, optional offset & length parameters may be provided to * dictate which bytes are to be encoded. * * @param value the value to encode * @param offset the offset to use if encoding a buffer. Defaults to 0 * @param length the length to use if encoding a buffer. Defaults to the length of the buffer * * @returns this encoder */ Encoder.prototype.encode = function (value, offset, length) { if (value instanceof Date) { this.writeString(value.toJSON()); } else if (value === null) { this.writeNull(); } else if (value === undefined) { this.writeUndefined(); } else if (value instanceof int64_impl_1.Int64Impl) { this.writeInt64(value); } else { switch (typeof value) { case 'boolean': this.writeBoolean(value); break; case 'string': this.writeString(value); break; case 'number': this.writeNumber(value); break; case 'object': if (uint8array_1.isUint8Array(value)) { this.writeBinary(value, offset, length); } else if (Array.isArray(value)) { this.writeArray(value); } else { this.writeObject(value); } } } return this; }; /** * Flush the encoded data and empty the internal buffer * * @return the contents of the buffer */ Encoder.prototype.flush = function () { var res = this.bos.getBuffer(); this.bos = new buffer_output_stream_1.BufferOutputStream(); return res; }; return Encoder; }()); exports.Encoder = Encoder;