{"version":3,"file":"decoding.mjs","names":[],"sources":["../../../../src/common/bin/lib0/decoding.ts"],"sourcesContent":["/**\n * Original at https://github.com/dmonad/lib0\n *\n * Efficient schema-less binary decoding with support for variable length encoding.\n *\n * Use [lib0/decoding] with [lib0/encoding]. Every encoding function has a corresponding decoding function.\n *\n * Encodes numbers in little-endian order (least to most significant byte order)\n * and is compatible with Golang's binary encoding (https://golang.org/pkg/encoding/binary/)\n * which is also used in Protocol Buffers.\n *\n * ```js\n * // encoding step\n * const encoder = new encoding.createEncoder()\n * encoding.writeVarUint(encoder, 256)\n * encoding.writeVarString(encoder, 'Hello world!')\n * const buf = encoding.toUint8Array(encoder)\n * ```\n *\n * ```js\n * // decoding step\n * const decoder = new decoding.createDecoder(buf)\n * decoding.readVarUint(decoder) // => 256\n * decoding.readVarString(decoder) // => 'Hello world!'\n * decoding.hasContent(decoder) // => false - all data is read\n * ```\n */\n\nimport { BIT7, BIT8, BITS6, BITS7 } from './binary'\nimport { createUint8ArrayViewFromArrayBuffer } from './create'\nimport { getUtf8TextDecoder } from './string'\n\nconst errorUnexpectedEndOfArray = 'Unexpected end of array'\nconst errorIntegerOutOfRange = 'Integer out of Range'\n\n/**\n * A BinDecoder handles the decoding of an Uint8Array.\n */\nexport class BinDecoder {\n  /** Decoding target. */\n  arr: Uint8Array\n  /** Current decoding position. */\n  pos: number\n\n  constructor(uint8Array: Uint8Array) {\n    this.arr = uint8Array\n    this.pos = 0\n  }\n}\n\nexport function createDecoder(uint8Array: Uint8Array): BinDecoder {\n  return new BinDecoder(uint8Array)\n}\n\nexport function hasContent(decoder: BinDecoder): boolean {\n  return decoder.pos !== decoder.arr.length\n}\n\n/**\n * Clone a decoder instance.\n * Optionally set a new position parameter.\n */\nexport function clone(decoder: BinDecoder, newPos: number = decoder.pos): BinDecoder {\n  const _decoder = createDecoder(decoder.arr)\n  _decoder.pos = newPos\n  return _decoder\n}\n\n/**\n * Create an Uint8Array view of the next `len` bytes and advance the position by `len`.\n *\n * Important: The Uint8Array still points to the underlying ArrayBuffer. Make sure to discard the result as soon as possible to prevent any memory leaks.\n *            Use `buffer.copyUint8Array` to copy the result into a new Uint8Array.\n */\nexport function readUint8Array(decoder: BinDecoder, len: number): Uint8Array {\n  const view = createUint8ArrayViewFromArrayBuffer(decoder.arr.buffer, decoder.pos + decoder.arr.byteOffset, len)\n  decoder.pos += len\n  return view\n}\n\n/**\n * Read unsigned integer (32bit) with variable length.\n * 1/8th of the storage is used as encoding overhead.\n * numbers < 2^7 is stored in one bytlength\n * numbers < 2^14 is stored in two bylength\n */\nexport function readVarUint(decoder: BinDecoder): number {\n  let num = 0\n  let mult = 1\n  const len = decoder.arr.length\n  while (decoder.pos < len) {\n    const r = decoder.arr[decoder.pos++]\n    // num = num | ((r & binary.BITS7) << len)\n    num = num + (r & BITS7) * mult // shift $r << (7*#iterations) and add it to num\n    mult *= 128 // next iteration, shift 7 \"more\" to the left\n    if (r < BIT8)\n      return num\n    if (num > Number.MAX_SAFE_INTEGER)\n      throw new Error(errorIntegerOutOfRange)\n  }\n  throw new Error(errorUnexpectedEndOfArray)\n}\n\n/**\n * Read variable length Uint8Array.\n *\n * Important: The Uint8Array still points to the underlying ArrayBuffer. Make sure to discard the result as soon as possible to prevent any memory leaks.\n *            Use `buffer.copyUint8Array` to copy the result into a new Uint8Array.\n */\nexport function readVarUint8Array(decoder: BinDecoder): Uint8Array {\n  return readUint8Array(decoder, readVarUint(decoder))\n}\n\n/**\n * Read the rest of the content as an ArrayBuffer\n */\nexport function readTailAsUint8Array(decoder: BinDecoder): Uint8Array {\n  return readUint8Array(decoder, decoder.arr.length - decoder.pos)\n}\n\n/**\n * Skip one byte, jump to the next position.\n */\nexport function skip8(decoder: BinDecoder): number {\n  return decoder.pos++\n}\n\n/**\n * Read one byte as unsigned integer.\n */\nexport function readUint8(decoder: BinDecoder): number {\n  return decoder.arr[decoder.pos++]\n}\n\n/**\n * Read 2 bytes as unsigned integer.\n */\nexport function readUint16(decoder: BinDecoder): number {\n  const uint = decoder.arr[decoder.pos]\n    + (decoder.arr[decoder.pos + 1] << 8)\n  decoder.pos += 2\n  return uint\n}\n\n/**\n * Read 4 bytes as unsigned integer.\n */\nexport function readUint32(decoder: BinDecoder): number {\n  const uint = (decoder.arr[decoder.pos]\n    + (decoder.arr[decoder.pos + 1] << 8)\n    + (decoder.arr[decoder.pos + 2] << 16)\n    + (decoder.arr[decoder.pos + 3] << 24)) >>> 0\n  decoder.pos += 4\n  return uint\n}\n\n/**\n * Read 4 bytes as unsigned integer in big endian order.\n * (most significant byte first)\n */\nexport function readUint32BigEndian(decoder: BinDecoder): number {\n  const uint = (decoder.arr[decoder.pos + 3]\n    + (decoder.arr[decoder.pos + 2] << 8)\n    + (decoder.arr[decoder.pos + 1] << 16)\n    + (decoder.arr[decoder.pos] << 24)) >>> 0\n  decoder.pos += 4\n  return uint\n}\n\n/**\n * Look ahead without incrementing the position\n * to the next byte and read it as unsigned integer.\n */\nexport function peekUint8(decoder: BinDecoder): number {\n  return decoder.arr[decoder.pos]\n}\n\n/**\n * Look ahead without incrementing the position\n * to the next byte and read it as unsigned integer.\n */\nexport function peekUint16(decoder: BinDecoder): number {\n  return decoder.arr[decoder.pos]\n    + (decoder.arr[decoder.pos + 1] << 8)\n}\n\n/**\n * Look ahead without incrementing the position\n * to the next byte and read it as unsigned integer.\n */\nexport function peekUint32(decoder: BinDecoder): number {\n  return (\n    decoder.arr[decoder.pos]\n    + (decoder.arr[decoder.pos + 1] << 8)\n    + (decoder.arr[decoder.pos + 2] << 16)\n    + (decoder.arr[decoder.pos + 3] << 24)\n  ) >>> 0\n}\n\n/**\n * Read signed integer (32bit) with variable length.\n * 1/8th of the storage is used as encoding overhead.\n * numbers < 2^7 is stored in one bytlength\n * numbers < 2^14 is stored in two bylength\n * @todo This should probably create the inverse ~num if number is negative - but this would be a breaking change.\n */\nexport function readVarInt(decoder: BinDecoder): number {\n  let r = decoder.arr[decoder.pos++]\n  let num = r & BITS6\n  let mult = 64\n  const sign = (r & BIT7) > 0 ? -1 : 1 // use Math.sign(?) for performance?\n  if ((r & BIT8) === 0) {\n    // don't continue reading\n    return sign * num\n  }\n  const len = decoder.arr.length\n  while (decoder.pos < len) {\n    r = decoder.arr[decoder.pos++]\n    // num = num | ((r & binary.BITS7) << len)\n    num = num + (r & BITS7) * mult\n    mult *= 128\n    if (r < BIT8)\n      return sign * num\n\n    if (num > Number.MAX_SAFE_INTEGER)\n      throw new Error(errorIntegerOutOfRange)\n  }\n  throw new Error(errorUnexpectedEndOfArray)\n}\n\n/**\n * Look ahead and read varUint without incrementing position\n */\nexport function peekVarUint(decoder: BinDecoder): number {\n  const pos = decoder.pos\n  const s = readVarUint(decoder)\n  decoder.pos = pos\n  return s\n}\n\n/**\n * Look ahead and read varUint without incrementing position\n */\nexport function peekVarInt(decoder: BinDecoder): number {\n  const pos = decoder.pos\n  const s = readVarInt(decoder)\n  decoder.pos = pos\n  return s\n}\n\n/**\n * We don't test this function anymore as we use native decoding/encoding by default now.\n * Better not modify this anymore..\n *\n * Transforming utf8 to a string is pretty expensive. The code performs 10x better\n * when String.fromCodePoint is fed with all characters as arguments.\n * But most environments have a maximum number of arguments per functions.\n * For effiency reasons we apply a maximum of 10000 characters at once.\n */\nfunction _readVarStringPolyfill(decoder: BinDecoder): string {\n  let remainingLen = readVarUint(decoder)\n  if (remainingLen === 0) {\n    return ''\n  }\n  else {\n    let encodedString = String.fromCodePoint(readUint8(decoder)) // remember to decrease remainingLen\n    if (--remainingLen < 100) { // do not create a Uint8Array for small strings\n      while (remainingLen--)\n        encodedString += String.fromCodePoint(readUint8(decoder))\n    }\n    else {\n      while (remainingLen > 0) {\n        const nextLen = remainingLen < 10000 ? remainingLen : 10000\n        // this is dangerous, we create a fresh array view from the existing buffer\n        const bytes = decoder.arr.subarray(decoder.pos, decoder.pos + nextLen)\n        decoder.pos += nextLen\n        // Starting with ES5.1 we can supply a generic array-like object as arguments\n        encodedString += String.fromCodePoint(...bytes as any)\n        remainingLen -= nextLen\n      }\n    }\n    return decodeURIComponent(escape(encodedString))\n  }\n}\n\n/**\n * Read string of variable length\n * varUint is used to store the length of the string\n */\nexport function readVarString(decoder: BinDecoder): string {\n  const utf8TextDecoder = getUtf8TextDecoder()\n  return utf8TextDecoder\n    ? utf8TextDecoder.decode(readVarUint8Array(decoder))\n    : _readVarStringPolyfill(decoder)\n}\n\n/**\n * Look ahead and read varString without incrementing position\n */\nexport function peekVarString(decoder: BinDecoder): string {\n  const pos = decoder.pos\n  const s = readVarString(decoder)\n  decoder.pos = pos\n  return s\n}\n\nexport function readFromDataView(decoder: BinDecoder, len: number): DataView {\n  const dv = new DataView(decoder.arr.buffer, decoder.arr.byteOffset + decoder.pos, len)\n  decoder.pos += len\n  return dv\n}\n\nexport function readFloat32(decoder: BinDecoder) {\n  return readFromDataView(decoder, 4).getFloat32(0, false)\n}\n\nexport function readFloat64(decoder: BinDecoder) {\n  return readFromDataView(decoder, 8).getFloat64(0, false)\n}\n\nexport function readBigInt64(decoder: BinDecoder) {\n  return (readFromDataView(decoder, 8)).getBigInt64(0, false)\n}\n\nexport function readBigUint64(decoder: BinDecoder) {\n  return (readFromDataView(decoder, 8)).getBigUint64(0, false)\n}\n\nconst readAnyLookupTable: Array<((arg0: BinDecoder) => any)> = [\n  _ => undefined, // CASE 127: undefined\n  _ => null, // CASE 126: null\n  readVarInt, // CASE 125: integer\n  readFloat32, // CASE 124: float32\n  readFloat64, // CASE 123: float64\n  readBigInt64, // CASE 122: bigint\n  _ => false, // CASE 121: boolean (false)\n  _ => true, // CASE 120: boolean (true)\n  readVarString, // CASE 119: string\n  (decoder) => { // CASE 118: object<string,any>\n    const len = readVarUint(decoder)\n    const obj: { [s: string]: any } = {}\n    for (let i = 0; i < len; i++) {\n      const key = readVarString(decoder)\n      obj[key] = readAny(decoder)\n    }\n    return obj\n  },\n  (decoder) => { // CASE 117: array<any>\n    const len = readVarUint(decoder)\n    const arr = []\n    for (let i = 0; i < len; i++)\n\n      arr.push(readAny(decoder))\n\n    return arr\n  },\n  readVarUint8Array, // CASE 116: Uint8Array\n]\n\nexport function readAny(decoder: BinDecoder) {\n  return readAnyLookupTable[127 - readUint8(decoder)](decoder)\n}\n"],"mappings":"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"}