UNPKG

@wireapp/cryptobox

Version:

High-level API with persistent storage for Proteus.

1,608 lines (1,398 loc) 35.3 kB
/*! @wireapp/cbor v3.0.6 */ var CBOR = /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) { /******/ return installedModules[moduleId].exports; /******/ } /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ i: moduleId, /******/ l: false, /******/ exports: {} /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.l = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // define getter function for harmony exports /******/ __webpack_require__.d = function(exports, name, getter) { /******/ if(!__webpack_require__.o(exports, name)) { /******/ Object.defineProperty(exports, name, { /******/ configurable: false, /******/ enumerable: true, /******/ get: getter /******/ }); /******/ } /******/ }; /******/ /******/ // getDefaultExport function for compatibility with non-harmony modules /******/ __webpack_require__.n = function(module) { /******/ var getter = module && module.__esModule ? /******/ function getDefault() { return module['default']; } : /******/ function getModuleExports() { return module; }; /******/ __webpack_require__.d(getter, 'a', getter); /******/ return getter; /******/ }; /******/ /******/ // Object.prototype.hasOwnProperty.call /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(__webpack_require__.s = 3); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ (function(module, exports) { /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ /* eslint no-magic-numbers: "off" */ /** * @class Types * @throws Error */ class Types { constructor() { throw new Error("Can't create instance of singleton"); } /** @type {number} */ static get ARRAY() { return 1; } /** @type {number} */ static get BOOL() { return 2; } /** @type {number} */ static get BREAK() { return 3; } /** @type {number} */ static get BYTES() { return 4; } /** @type {number} */ static get FLOAT16() { return 5; } /** @type {number} */ static get FLOAT32() { return 6; } /** @type {number} */ static get FLOAT64() { return 7; } /** @type {number} */ static get UINT8() { return 8; } /** @type {number} */ static get UINT16() { return 9; } /** @type {number} */ static get UINT32() { return 10; } /** @type {number} */ static get UINT64() { return 11; } /** @type {number} */ static get INT8() { return 12; } /** @type {number} */ static get INT16() { return 13; } /** @type {number} */ static get INT32() { return 14; } /** @type {number} */ static get INT64() { return 15; } /** @type {number} */ static get NULL() { return 16; } /** @type {number} */ static get OBJECT() { return 17; } /** @type {number} */ static get TAGGED() { return 18; } /** @type {number} */ static get TEXT() { return 19; } /** @type {number} */ static get UNDEFINED() { return 20; } /** * @param {!Types} type * @returns {number} * @throws TypeError */ static major(type) { switch (type) { case this.ARRAY: return 4; case this.BOOL: return 7; case this.BREAK: return 7; case this.BYTES: return 2; case this.FLOAT16: return 7; case this.FLOAT32: return 7; case this.FLOAT64: return 7; case this.UINT8: return 0; case this.UINT16: return 0; case this.UINT32: return 0; case this.UINT64: return 0; case this.INT8: return 1; case this.INT16: return 1; case this.INT32: return 1; case this.INT64: return 1; case this.NULL: return 7; case this.OBJECT: return 5; case this.TAGGED: return 6; case this.TEXT: return 3; case this.UNDEFINED: return 7; default: throw new TypeError('Invalid CBOR type'); } } } module.exports = Types; /***/ }), /* 1 */ /***/ (function(module, exports) { /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ /** * @class BaseError * @extends Error * @param {string} message * @returns {string} */ module.exports = (function() { const BaseError = function(message) { this.name = this.constructor.name; this.message = message; this.stack = new Error().stack; }; BaseError.prototype = new Error(); BaseError.prototype.constructor = BaseError; return BaseError; })(); /***/ }), /* 2 */ /***/ (function(module, exports, __webpack_require__) { /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ const BaseError = __webpack_require__(1); /** * @class DecodeError * @param {string} message * @param {*} [extra] */ class DecodeError extends BaseError { constructor(message, extra) { super(message); this.extra = extra; } /** @type {string} */ static get INVALID_TYPE() { return 'Invalid type'; } /** @type {string} */ static get UNEXPECTED_EOF() { return 'Unexpected end-of-buffer'; } /** @type {string} */ static get UNEXPECTED_TYPE() { return 'Unexpected type'; } /** @type {string} */ static get INT_OVERFLOW() { return 'Integer overflow'; } /** @type {string} */ static get TOO_LONG() { return 'Field too long'; } /** @type {string} */ static get TOO_NESTED() { return 'Object nested too deep'; } } module.exports = DecodeError; /***/ }), /* 3 */ /***/ (function(module, exports, __webpack_require__) { /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ module.exports = { BaseError: __webpack_require__(1), DecodeError: __webpack_require__(2), Decoder: __webpack_require__(4), Encoder: __webpack_require__(5), Types: __webpack_require__(0), }; /***/ }), /* 4 */ /***/ (function(module, exports, __webpack_require__) { /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ /* eslint no-magic-numbers: "off" */ const DecodeError = __webpack_require__(2); const Types = __webpack_require__(0); const DEFAULT_CONFIG = { max_array_length: 1000, max_bytes_length: 5242880, max_nesting: 16, max_object_size: 1000, max_text_length: 5242880, }; /** * @class Decoder * @param {!ArrayBuffer} buffer * @param {Object} [config=DEFAULT_CONFIG] config * @returns {Decoder} `this` */ class Decoder { /** * @callback closureCallback */ constructor(buffer, config = DEFAULT_CONFIG) { // buffer *must* be an ArrayBuffer this.buffer = buffer; this.config = config; this.view = new DataView(this.buffer); return this; } /** * @param {!number} int * @param {!number} overflow * @returns {number} * @private * @throws DecodeError */ static _check_overflow(int, overflow) { if (int > overflow) { throw new DecodeError(DecodeError.INT_OVERFLOW); } return int; } /** * @param {!number} bytes * @returns {void} * @private */ _advance(bytes) { this.view = new DataView(this.buffer, this.view.byteOffset + bytes); } /** * @returns {!number} * @private */ _available() { return this.view.byteLength; } /** * @param {!number} bytes * @param {!closureCallback} closure * @returns {number} * @private * @throws DecodeError */ _read(bytes, closure) { if (this._available < bytes) { throw new DecodeError(DecodeError.UNEXPECTED_EOF); } const value = closure(); this._advance(bytes); return value; } /* * reader-like interface for @buffer */ /** * @returns {number} * @private */ _u8() { return this._read(1, () => this.view.getUint8(0)); } /** * @returns {number} * @private */ _u16() { return this._read(2, () => this.view.getUint16(0)); } /** * @returns {number} * @private */ _u32() { return this._read(4, () => this.view.getUint32(0)); } /** * @returns {number} * @private */ _u64() { const r64 = () => this.view.getUint32(0) * Math.pow(2, 32) + this.view.getUint32(4); return this._read(8, r64); } /** * @returns {number} * @private */ _f32() { return this._read(4, () => this.view.getFloat32(0)); } /** * @returns {number} * @private */ _f64() { return this._read(8, () => this.view.getFloat64(0)); } /** * @param {!number} minor * @returns {number} * @private * @throws DecodeError */ _read_length(minor) { if (0 <= minor && minor <= 23) { return minor; } switch (minor) { case 24: return this._u8(); case 25: return this._u16(); case 26: return this._u32(); case 27: return Decoder._check_overflow(this._u64(), Number.MAX_SAFE_INTEGER); } throw new DecodeError(DecodeError.UNEXPECTED_TYPE); } /** * @param {!number} minor * @param {!number} max_len * @returns {number} * @private * @throws DecodeError */ _bytes(minor, max_len) { const len = this._read_length(minor); if (len > max_len) { throw new DecodeError(DecodeError.TOO_LONG); } return this._read(len, () => this.buffer.slice(this.view.byteOffset, this.view.byteOffset + len)); } /** * @returns {Array<Types|number>} * @private * @throws DecodeError */ _read_type_info() { let type = this._u8(); const major = (type & 0xe0) >> 5; const minor = type & 0x1f; switch (major) { case 0: type = 0 <= minor && minor <= 24 ? Types.UINT8 : (() => { switch (minor) { case 25: return Types.UINT16; case 26: return Types.UINT32; case 27: return Types.UINT64; default: throw new DecodeError(DecodeError.INVALID_TYPE); } })(); return [type, minor]; case 1: type = 0 <= minor && minor <= 24 ? Types.INT8 : (() => { switch (minor) { case 25: return Types.INT16; case 26: return Types.INT32; case 27: return Types.INT64; default: throw new DecodeError(DecodeError.INVALID_TYPE); } })(); return [type, minor]; case 2: return [Types.BYTES, minor]; case 3: return [Types.TEXT, minor]; case 4: return [Types.ARRAY, minor]; case 5: return [Types.OBJECT, minor]; case 7: switch (minor) { case 20: case 21: return [Types.BOOL, minor]; case 22: return [Types.NULL, minor]; case 25: return [Types.FLOAT16, minor]; case 26: return [Types.FLOAT32, minor]; case 27: return [Types.FLOAT64, minor]; case 31: return [Types.BREAK, minor]; } break; } throw new DecodeError(DecodeError.INVALID_TYPE); } /** * @param {!(number|Array<number>)} expected * @returns {Array<Types|number>} * @private * @throws DecodeError */ _type_info_with_assert(expected) { const [type, minor] = this._read_type_info(); if (!Array.isArray(expected)) { expected = [expected]; } if (!expected.some(error => type === error)) { throw new DecodeError(DecodeError.UNEXPECTED_TYPE, [type, minor]); } return [type, minor]; } /** * @param {Types} type * @param {!number} minor * @returns {number} * @private * @throws DecodeError */ _read_unsigned(type, minor) { switch (type) { case Types.UINT8: return minor <= 23 ? minor : this._u8(); case Types.UINT16: return this._u16(); case Types.UINT32: return this._u32(); case Types.UINT64: return this._u64(); } throw new DecodeError(DecodeError.UNEXPECTED_TYPE, [type, minor]); } /** * @param {!number} overflow * @param {*} type * @param {!number} minor * @returns {number} * @private * @throws DecodeError */ _read_signed(overflow, type, minor) { switch (type) { case Types.INT8: if (minor <= 23) { return -1 - minor; } return -1 - Decoder._check_overflow(this._u8(), overflow); case Types.INT16: return -1 - Decoder._check_overflow(this._u16(), overflow); case Types.INT32: return -1 - Decoder._check_overflow(this._u32(), overflow); case Types.INT64: return -1 - Decoder._check_overflow(this._u64(), overflow); case Types.UINT8: case Types.UINT16: case Types.UINT32: case Types.UINT64: return Decoder._check_overflow(this._read_unsigned(type, minor), overflow); } throw new DecodeError(DecodeError.UNEXPECTED_TYPE, [type, minor]); } /* * public API */ /** @returns {number} */ u8() { return this._read_unsigned(...this._type_info_with_assert([Types.UINT8])); } /** @returns {number} */ u16() { return this._read_unsigned(...this._type_info_with_assert([Types.UINT8, Types.UINT16])); } /** @returns {number} */ u32() { return this._read_unsigned(...this._type_info_with_assert([Types.UINT8, Types.UINT16, Types.UINT32])); } /** @returns {number} */ u64() { return this._read_unsigned(...this._type_info_with_assert([Types.UINT8, Types.UINT16, Types.UINT32, Types.UINT64])); } /** @returns {number} */ i8() { return this._read_signed(127, ...this._type_info_with_assert([Types.INT8, Types.UINT8])); } /** @returns {number} */ i16() { return this._read_signed( 32767, ...this._type_info_with_assert([Types.INT8, Types.INT16, Types.UINT8, Types.UINT16]) ); } /** @returns {number} */ i32() { return this._read_signed( 2147483647, ...this._type_info_with_assert([Types.INT8, Types.INT16, Types.INT32, Types.UINT8, Types.UINT16, Types.UINT32]) ); } /** @returns {number} */ i64() { return this._read_signed( Number.MAX_SAFE_INTEGER, ...this._type_info_with_assert([ Types.INT8, Types.INT16, Types.INT32, Types.INT64, Types.UINT8, Types.UINT16, Types.UINT32, Types.UINT64, ]) ); } /** @returns {number} */ unsigned() { return this.u64(); } /** @returns {number} */ int() { return this.i64(); } /** @returns {number} */ f16() { this._type_info_with_assert(Types.FLOAT16); const half = this._u16(); const exp = (half >> 10) & 0x1f; const mant = half & 0x3ff; const ldexp = (significand, exponent) => significand * Math.pow(2, exponent); let val; switch (exp) { case 0: val = ldexp(mant, -24); break; case 31: val = mant === 0 ? Number.POSITIVE_INFINITY : Number.NaN; break; default: val = ldexp(mant + 1024, exp - 25); break; } return half & 0x8000 ? -val : val; } /** @returns {number} */ f32() { this._type_info_with_assert(Types.FLOAT32); return this._f32(); } /** @returns {number} */ f64() { this._type_info_with_assert(Types.FLOAT64); return this._f64(); } /** * @returns {boolean} * @throws DecodeError */ bool() { const minor = this._type_info_with_assert(Types.BOOL)[1]; switch (minor) { case 20: return false; case 21: return true; default: throw new DecodeError(DecodeError.UNEXPECTED_TYPE); } } /** * @returns {number} * @throws DecodeError */ bytes() { const minor = this._type_info_with_assert(Types.BYTES)[1]; if (minor === 31) { // XXX: handle indefinite encoding throw new DecodeError(DecodeError.UNEXPECTED_TYPE); } return this._bytes(minor, this.config.max_bytes_length); } /** * @returns {string} * @throws DecodeError */ text() { const minor = this._type_info_with_assert(Types.TEXT)[1]; if (minor === 31) { // XXX: handle indefinite encoding throw new DecodeError(DecodeError.UNEXPECTED_TYPE); } const buf = this._bytes(minor, this.config.max_text_length); const utf8 = String.fromCharCode(...new Uint8Array(buf)); // http://ecmanaut.blogspot.de/2006/07/encoding-decoding-utf8-in-javascript.html return decodeURIComponent(escape(utf8)); } /** * @param {!closureCallback} closure * @returns {(closureCallback|null)} * @throws DecodeError */ optional(closure) { try { return closure(); } catch (error) { if (error instanceof DecodeError && error.extra[0] === Types.NULL) { return null; } throw error; } } /** * @returns {number} * @throws DecodeError */ array() { const minor = this._type_info_with_assert(Types.ARRAY)[1]; if (minor === 31) { // XXX: handle indefinite encoding throw new DecodeError(DecodeError.UNEXPECTED_TYPE); } const len = this._read_length(minor); if (len > this.config.max_array_length) { throw new DecodeError(DecodeError.TOO_LONG); } return len; } /** * @returns {number} * @throws DecodeError */ object() { const minor = this._type_info_with_assert(Types.OBJECT)[1]; if (minor === 31) { // XXX: handle indefinite encoding throw new DecodeError(DecodeError.UNEXPECTED_TYPE); } const len = this._read_length(minor); if (len > this.config.max_object_size) { throw new DecodeError(DecodeError.TOO_LONG); } return len; } /** * @param {*} type * @returns {void} * @private * @throws DecodeError */ _skip_until_break(type) { for (;;) { const [t, minor] = this._read_type_info(); if (t === Types.BREAK) { return; } if (t !== type || minor === 31) { throw new DecodeError(DecodeError.UNEXPECTED_TYPE); } const len = this._read_length(minor); this._advance(len); } } /** * @param {!number} level * @returns {boolean} * @private * @throws DecodeError */ _skip_value(level) { if (level === 0) { throw new DecodeError(DecodeError.TOO_NESTED); } const [type, minor] = this._read_type_info(); let len; switch (type) { case Types.UINT8: case Types.UINT16: case Types.UINT32: case Types.UINT64: case Types.INT8: case Types.INT16: case Types.INT32: case Types.INT64: this._read_length(minor); return true; case Types.BOOL: case Types.NULL: return true; case Types.BREAK: return false; case Types.FLOAT16: this._advance(2); return true; case Types.FLOAT32: this._advance(4); return true; case Types.FLOAT64: this._advance(8); return true; case Types.BYTES: case Types.TEXT: if (minor === 31) { this._skip_until_break(type); return true; } len = this._read_length(minor); this._advance(len); return true; case Types.ARRAY: case Types.OBJECT: if (minor === 31) { while (this._skip_value(level - 1)) { // do nothing } return true; } len = this._read_length(minor); while (len--) { this._skip_value(level - 1); } return true; } } /** @returns {boolean} */ skip() { return this._skip_value(this.config.max_nesting); } } module.exports = Decoder; /***/ }), /* 5 */ /***/ (function(module, exports, __webpack_require__) { /* * Wire * Copyright (C) 2016 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ /* eslint no-magic-numbers: "off" */ const Types = __webpack_require__(0); /** * @class Encoder * @returns {Encoder} `this` */ class Encoder { constructor() { this.buffer = new ArrayBuffer(4); this.view = new DataView(this.buffer); return this; } /** @returns {ArrayBuffer} */ get_buffer() { return this.buffer.slice(0, this.view.byteOffset); } /** * @param {!number} need_nbytes * @returns {number} * @private */ _new_buffer_length(need_nbytes) { return ~~Math.max(this.buffer.byteLength * 1.5, this.buffer.byteLength + need_nbytes); } /** * @param {!number} need_nbytes * @returns {void} * @private */ _grow_buffer(need_nbytes) { const new_len = this._new_buffer_length(need_nbytes); const new_buf = new ArrayBuffer(new_len); new Uint8Array(new_buf).set(new Uint8Array(this.buffer)); this.buffer = new_buf; this.view = new DataView(this.buffer, this.view.byteOffset); } /** * @param {!number} bytes * @returns {void} * @private */ _ensure(bytes) { if (!(this.view.byteLength < bytes)) { return; } return this._grow_buffer(bytes); } /** * @param {!number} bytes * @returns {void} * @private */ _advance(bytes) { this.view = new DataView(this.buffer, this.view.byteOffset + bytes); } /** * @callback closureCallback */ /** * @param {!number} bytes * @param {!closureCallback} closure * @returns {void} * @private */ _write(bytes, closure) { this._ensure(bytes); closure(); return this._advance(bytes); } /** * @param {Types} type * @param {!number} len * @returns {void} * @private * @throws RangeError */ _write_type_and_len(type, len) { const major = Types.major(type) << 5; if (0 <= len && len <= 23) { return this._u8(major | len); } else if (24 <= len && len <= 255) { this._u8(major | 24); return this._u8(len); } else if (0x100 <= len && len <= 0xffff) { this._u8(major | 25); return this._u16(len); } else if (0x10000 <= len && len <= 0xffffffff) { this._u8(major | 26); return this._u32(len); } else if (len <= Number.MAX_SAFE_INTEGER) { this._u8(major | 27); return this._u64(len); } throw new RangeError('Invalid size for CBOR object'); } /* * writer-like interface over our ArrayBuffer */ /** * @param {!number} value * @returns {void} * @private */ _u8(value) { return this._write(1, () => this.view.setUint8(0, value)); } /** * @param {!number} value * @returns {void} * @private */ _u16(value) { return this._write(2, () => this.view.setUint16(0, value)); } /** * @param {!number} value * @returns {void} * @private */ _u32(value) { return this._write(4, () => this.view.setUint32(0, value)); } /** * @param {!number} value * @returns {void} * @private */ _u64(value) { const low = value % Math.pow(2, 32); const high = (value - low) / Math.pow(2, 32); const w64 = () => { this.view.setUint32(0, high); return this.view.setUint32(4, low); }; return this._write(8, w64); } /** * @param {!number} value * @returns {void} * @private */ _f32(value) { return this._write(4, () => this.view.setFloat32(0, value)); } /** * @param {!number} value * @returns {void} * @private */ _f64(value) { return this._write(8, () => this.view.setFloat64(0, value)); } /** * @param {!Uint8Array} value * @returns {void} * @private */ _bytes(value) { const nbytes = value.byteLength; this._ensure(nbytes); new Uint8Array(this.buffer, this.view.byteOffset).set(value); return this._advance(nbytes); } /* * public API */ /** * @param {!number} value * @returns {Encoder} `this` * @throws RangeError */ u8(value) { if (0 <= value && value <= 23) { this._u8(value); } else if (24 <= value && value <= 255) { this._u8(24); this._u8(value); } else { throw new RangeError('Invalid u8'); } return this; } /** * @param {!number} value * @returns {Encoder} `this` * @throws RangeError */ u16(value) { if (0 <= value && value <= 23) { this._u8(value); } else if (24 <= value && value <= 255) { this._u8(24); this._u8(value); } else if (0x100 <= value && value <= 0xffff) { this._u8(25); this._u16(value); } else { throw new RangeError('Invalid u16'); } return this; } /** * @param {!number} value * @returns {Encoder} `this` * @throws RangeError */ u32(value) { if (0 <= value && value <= 23) { this._u8(value); } else if (24 <= value && value <= 255) { this._u8(24); this._u8(value); } else if (0x100 <= value && value <= 0xffff) { this._u8(25); this._u16(value); } else if (0x10000 <= value && value <= 0xffffffff) { this._u8(26); this._u32(value); } else { throw new RangeError('Invalid u32'); } return this; } /** * @param {!number} value * @returns {Encoder} `this` * @throws RangeError */ u64(value) { if (0 <= value && value <= 23) { this._u8(value); } else if (24 <= value && value <= 255) { this._u8(24); this._u8(value); } else if (0x100 <= value && value <= 0xffff) { this._u8(25); this._u16(value); } else if (0x10000 <= value && value <= 0xffffffff) { this._u8(26); this._u32(value); } else if (value <= Number.MAX_SAFE_INTEGER) { this._u8(27); this._u64(value); } else { throw new RangeError('Invalid unsigned integer'); } return this; } /** * @param {!number} value * @returns {Encoder} `this` * @throws RangeError */ i8(value) { if (value >= 0) { this._u8(value); return this; } value = -1 - value; if (0 <= value && value <= 23) { this._u8(0x20 | value); } else if (24 <= value && value <= 255) { this._u8(0x20 | 24); this._u8(value); } else { throw new RangeError('Invalid i8'); } return this; } /** * @param {!number} value * @returns {Encoder} `this` * @throws RangeError */ i16(value) { if (value >= 0) { this._u16(value); return this; } value = -1 - value; if (0 <= value && value <= 23) { this._u8(0x20 | value); } else if (24 <= value && value <= 255) { this._u8(0x20 | 24); this._u8(value); } else if (0x100 <= value && value <= 0xffff) { this._u8(0x20 | 25); this._u16(value); } else { throw new RangeError('Invalid i16'); } return this; } /** * @param {!number} value * @returns {Encoder} `this` * @throws RangeError */ i32(value) { if (value >= 0) { this._u32(value); return this; } value = -1 - value; if (0 <= value && value <= 23) { this._u8(0x20 | value); } else if (24 <= value && value <= 255) { this._u8(0x20 | 24); this._u8(value); } else if (0x100 <= value && value <= 0xffff) { this._u8(0x20 | 25); this._u16(value); } else if (0x10000 <= value && value <= 0xffffffff) { this._u8(0x20 | 26); this._u32(value); } else { throw new RangeError('Invalid i32'); } return this; } /** * @param {!number} value * @returns {Encoder} `this` * @throws RangeError */ i64(value) { if (value >= 0) { this._u64(value); return this; } value = -1 - value; if (0 <= value && value <= 23) { this._u8(0x20 | value); } else if (24 <= value && value <= 255) { this._u8(0x20 | 24); this._u8(value); } else if (0x100 <= value && value <= 0xffff) { this._u8(0x20 | 25); this._u16(value); } else if (0x10000 <= value && value <= 0xffffffff) { this._u8(0x20 | 26); this._u32(value); } else if (value <= Number.MAX_SAFE_INTEGER) { this._u8(0x20 | 27); this._u64(value); } else { throw new RangeError('Invalid i64'); } return this; } /** * @param {!number} value * @returns {Encoder} `this` */ f32(value) { this._u8(0xe0 | 26); this._f32(value); return this; } /** * @param {!number} value * @returns {Encoder} `this` */ f64(value) { this._u8(0xe0 | 27); this._f64(value); return this; } /** * @param {!number} value * @returns {Encoder} `this` */ bool(value) { this._u8(0xe0 | (value ? 21 : 20)); return this; } /** * @param {!(ArrayBuffer|Uint8Array)} value * @returns {Encoder} `this` */ bytes(value) { this._write_type_and_len(Types.BYTES, value.byteLength); this._bytes(value); return this; } /** * @param {!number} value * @returns {Encoder} `this` */ text(value) { // http://ecmanaut.blogspot.de/2006/07/encoding-decoding-utf8-in-javascript.html const utf8 = unescape(encodeURIComponent(value)); this._write_type_and_len(Types.TEXT, utf8.length); this._bytes(new Uint8Array(utf8.split('').map(char => char.charCodeAt(0)))); return this; } /** @returns {Encoder} `this` */ null() { this._u8(0xe0 | 22); return this; } /** @returns {Encoder} `this` */ undefined() { this._u8(0xe0 | 23); return this; } /** * @param {!number} len * @returns {Encoder} `this` */ array(len) { this._write_type_and_len(Types.ARRAY, len); return this; } /** @returns {Encoder} `this` */ array_begin() { this._u8(0x9f); return this; } /** @returns {Encoder} `this` */ array_end() { this._u8(0xff); return this; } /** * @param {!number} len * @returns {Encoder} `this` */ object(len) { this._write_type_and_len(Types.OBJECT, len); return this; } /** @returns {Encoder} `this` */ object_begin() { this._u8(0xbf); return this; } /** @returns {Encoder} `this` */ object_end() { this._u8(0xff); return this; } } module.exports = Encoder; /***/ }) /******/ ]); //# sourceMappingURL=cbor.bundle.js.map