UNPKG

diffusion

Version:

Diffusion JavaScript client

186 lines (185 loc) 6.75 kB
"use strict"; /** * @module CBOR */ Object.defineProperty(exports, "__esModule", { value: true }); exports.isAny = exports.isString = exports.isInt64 = exports.isDouble = exports.Decoder = void 0; var uint8array_1 = require("./../util/uint8array"); var errors_1 = require("../../errors/errors"); var consts_1 = require("./consts"); var tokeniser_1 = require("./tokeniser"); /** * Recursive token-parsing function; will evaluate tokens and build up complete object representations in order. * * @throws an {@link InvalidDataError} if there was an error parsing the next value */ /* eslint-disable-next-line complexity */ function decode(token, tokeniser) { switch (token.type) { case consts_1.tokens.VALUE: return token.value; case consts_1.tokens.MAP_START: var obj = {}; for (;;) { var field = tokeniser.nextToken(); if (field === null) { throw new errors_1.InvalidDataError('Unexpected EOF (reading: map key)'); } if (field.type === consts_1.tokens.MAP_END) { break; } var value = tokeniser.nextToken(); if (value === null || value.type === consts_1.tokens.MAP_END) { throw new errors_1.InvalidDataError('Unexpected EOF (reading: map value)'); } var key = decode(field, tokeniser); if (key === undefined || key === null) { throw new errors_1.InvalidDataError('Cannot have undefined key (reading: map key)'); } obj[key.toString()] = decode(value, tokeniser); } return obj; case consts_1.tokens.ARRAY_START: var arr = []; for (;;) { var element = tokeniser.nextToken(); /* istanbul ignore next */ if (element === null) { throw new errors_1.InvalidDataError('Unexpected EOF (reading: array value)'); } if (element.type === consts_1.tokens.ARRAY_END) { break; } arr.push(decode(element, tokeniser)); } return arr; case consts_1.tokens.STRING_START: var chunks = []; for (;;) { var chunk = tokeniser.nextToken(); /* istanbul ignore next */ if (chunk === null) { throw new errors_1.InvalidDataError('Unexpected EOF (reading: indefinite-length string'); } if (chunk.type === consts_1.tokens.STRING_END) { break; } if (chunk.header.type !== token.header.type) { throw new errors_1.InvalidDataError('Unexpected chunk type (' + chunk.header.type + ') within string'); } chunks.push(chunk.value); } switch (token.header.type) { case consts_1.types.BYTES: return uint8array_1.concatUint8Arrays(chunks); case consts_1.types.STRING: return chunks.join(''); /* istanbul ignore next */ default: throw new errors_1.InvalidDataError('Unexpected chunk type (' + token.header.type + ') (reading: string)'); } /* istanbul ignore next */ default: throw new errors_1.InvalidDataError('Unexpected token: ' + JSON.stringify(token)); } } /** * Provide a higher-level interface around Tokeniser, to enable the reading of * complex values as represented in arrays/objects etc. */ var Decoder = /** @class */ (function () { /** * Create a decoder * * @param initial the `Uint8Array` or `Tokeniser` to read from * @param offset if a `Uint8Array` is supplied as first argument, the optional * offset from which to start reading. Ignored otherwise. * @param length if a `Uint8Array` is supplied as first argument, the optional * number of bytes to read. Ignored otherwise. */ function Decoder(initial, offset, length) { this.tokeniser = (uint8array_1.isUint8Array(initial)) ? new tokeniser_1.Tokeniser(initial, offset, length) : initial; } /** * Check if more tokens can be read from the tokeniser * * @return `true` if there are more tokens */ Decoder.prototype.hasRemaining = function () { return this.tokeniser.hasRemaining(); }; /** * Return the next value, parsed recursively. * * If no tokens can be read, a read error will be thrown. * * @return the next value * @throws an {@link InvalidDataError} if no value can be read */ Decoder.prototype.nextValue = function () { return this.nextValueExpecting(isAny); }; /** * Return the next value, if its CBOR type is acceptable to `cborTypePredicate` * * @parame cborTypePredicate a predicate that should return true if the * CBOR type is acceptable, false otherwise. * @return the next value * @throws an {@link InvalidDataError} if no value can be read */ Decoder.prototype.nextValueExpecting = function (cborTypePredicate) { if (!this.tokeniser.hasRemaining()) { throw new errors_1.InvalidDataError('Token stream exhausted'); } var token = this.tokeniser.nextToken(); if (cborTypePredicate(token.header.type)) { return decode(token, this.tokeniser); } else { throw new errors_1.InvalidDataError('Unexpected CBOR type'); } }; return Decoder; }()); exports.Decoder = Decoder; /** * Allow only floating point CBOR types * * @param cborType the CBOR type * @return `true` if the type is a floating point number */ function isDouble(cborType) { return cborType === consts_1.types.FLOAT; } exports.isDouble = isDouble; /** * Allow only int CBOR types * * @param cborType the CBOR type * @return `true` if the type is an integer */ function isInt64(cborType) { return cborType === consts_1.types.UINT || cborType === consts_1.types.INT; } exports.isInt64 = isInt64; /** * Allow only string CBOR types * * @param cborType the CBOR type * @return `true` if the type is a string */ function isString(cborType) { return cborType === consts_1.types.STRING; } exports.isString = isString; /** * Allow any CBOR types * * @return will always return `true` */ function isAny() { return true; } exports.isAny = isAny;