export const binary = ` // Copyright (c) 2016, Daniel Wirtz All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: // * Redistributions of source code must retain the above copyright // notice, this list of conditions and the following disclaimer. // * Redistributions in binary form must reproduce the above copyright // notice, this list of conditions and the following disclaimer in the // documentation and/or other materials provided with the distribution. // * Neither the name of its author, nor the names of its contributors // may be used to endorse or promote products derived from this software // without specific prior written permission. // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // --- // Code generated by the command line utilities is owned by the owner // of the input file used when generating it. This code is not // standalone and requires a support library to be linked with it. This // support library is itself covered by the above license. import { utf8Length, utf8Read, utf8Write } from "./utf8"; import { int64ToString, readInt32, readUInt32, uInt64ToString, varint32read, varint64read, writeVarint32, writeVarint64, int64FromString, int64Length, writeFixed32, writeByte, zzDecode, zzEncode, } from "./varint"; export enum WireType { Varint = 0, Fixed64 = 1, Bytes = 2, Fixed32 = 5, } // Reader export class BinaryReader { buf: Uint8Array; pos: number; type: number; len: number; protected assertBounds(): void { if (this.pos > this.len) throw new RangeError("premature EOF"); } constructor(buf?: ArrayLike) { this.buf = buf ? new Uint8Array(buf) : new Uint8Array(0); this.pos = 0; this.type = 0; this.len = this.buf.length; } tag(): [number, WireType, number] { const tag = this.uint32(), fieldNo = tag >>> 3, wireType = tag & 7; if (fieldNo <= 0 || wireType < 0 || wireType > 5) throw new Error( "illegal tag: field no " + fieldNo + " wire type " + wireType ); return [fieldNo, wireType, tag]; } skip(length?: number) { if (typeof length === "number") { if (this.pos + length > this.len) throw indexOutOfRange(this, length); this.pos += length; } else { do { if (this.pos >= this.len) throw indexOutOfRange(this); } while (this.buf[this.pos++] & 128); } return this; } skipType(wireType: number) { switch (wireType) { case WireType.Varint: this.skip(); break; case WireType.Fixed64: this.skip(8); break; case WireType.Bytes: this.skip(this.uint32()); break; case 3: while ((wireType = this.uint32() & 7) !== 4) { this.skipType(wireType); } break; case WireType.Fixed32: this.skip(4); break; /* istanbul ignore next */ default: throw Error("invalid wire type " + wireType + " at offset " + this.pos); } return this; } uint32(): number { return varint32read.bind(this)(); } int32(): number { return this.uint32() | 0; } sint32(): number { const num = this.uint32(); return num % 2 === 1 ? (num + 1) / -2 : num / 2; // zigzag encoding } fixed32(): number { const val = readUInt32(this.buf, this.pos); this.pos += 4; return val; } sfixed32(): number { const val = readInt32(this.buf, this.pos); this.pos += 4; return val; } int64(): bigint { const [lo, hi] = varint64read.bind(this)(); return BigInt(int64ToString(lo, hi)); } uint64(): bigint { const [lo, hi] = varint64read.bind(this)(); return BigInt(uInt64ToString(lo, hi)); } sint64(): bigint { let [lo, hi] = varint64read.bind(this)(); // zig zag [lo, hi] = zzDecode(lo, hi); return BigInt(int64ToString(lo, hi)); } fixed64(): bigint { const lo = this.sfixed32(); const hi = this.sfixed32(); return BigInt(uInt64ToString(lo, hi)); } sfixed64(): bigint { const lo = this.sfixed32(); const hi = this.sfixed32(); return BigInt(int64ToString(lo, hi)); } float(): number { throw new Error("float not supported"); } double(): number { throw new Error("double not supported"); } bool(): boolean { const [lo, hi] = varint64read.bind(this)(); return lo !== 0 || hi !== 0; } bytes(): Uint8Array { const len = this.uint32(), start = this.pos; this.pos += len; this.assertBounds(); return this.buf.subarray(start, start + len); } string(): string { const bytes = this.bytes(); return utf8Read(bytes, 0, bytes.length); } } // Writer type OpVal = string | number | object | Uint8Array; class Op { fn?: (val: OpVal, buf: Uint8Array | number[], pos: number) => void; len: number; val: OpVal; next?: Op; constructor( fn: ( val: OpVal, buf: Uint8Array | number[], pos: number ) => void | undefined, len: number, val: OpVal ) { this.fn = fn; this.len = len; this.val = val; } } class State { head: Op; tail: Op; len: number; next: State; constructor(writer: BinaryWriter) { this.head = writer.head; this.tail = writer.tail; this.len = writer.len; this.next = writer.states; } } export class BinaryWriter { len = 0; head: Op; tail: Op; states: State; constructor() { this.head = new Op(null, 0, 0); this.tail = this.head; this.states = null; } static create() { return new BinaryWriter(); } static alloc(size: number): Uint8Array | number[] { if (typeof Uint8Array !== "undefined") { return pool( (size) => new Uint8Array(size), Uint8Array.prototype.subarray )(size); } else { return new Array(size); } } private _push( fn: (val: OpVal, buf: Uint8Array | number[], pos: number) => void, len: number, val: OpVal ) { this.tail = this.tail.next = new Op(fn, len, val); this.len += len; return this; } finish(): Uint8Array { let head = this.head.next, pos = 0; const buf = BinaryWriter.alloc(this.len); while (head) { head.fn(head.val, buf, pos); pos += head.len; head = head.next; } return buf as Uint8Array; } fork(): BinaryWriter { this.states = new State(this); this.head = this.tail = new Op(null, 0, 0); this.len = 0; return this; } reset(): BinaryWriter { if (this.states) { this.head = this.states.head; this.tail = this.states.tail; this.len = this.states.len; this.states = this.states.next; } else { this.head = this.tail = new Op(null, 0, 0); this.len = 0; } return this; } ldelim(): BinaryWriter { const head = this.head, tail = this.tail, len = this.len; this.reset().uint32(len); if (len) { this.tail.next = head.next; // skip noop this.tail = tail; this.len += len; } return this; } tag(fieldNo: number, type: WireType): BinaryWriter { return this.uint32(((fieldNo << 3) | type) >>> 0); } uint32(value: number): BinaryWriter { this.len += (this.tail = this.tail.next = new Op( writeVarint32, (value = value >>> 0) < 128 ? 1 : value < 16384 ? 2 : value < 2097152 ? 3 : value < 268435456 ? 4 : 5, value )).len; return this; } int32(value: number): BinaryWriter { return value < 0 ? this._push(writeVarint64, 10, int64FromString(value.toString())) // 10 bytes per spec : this.uint32(value); } sint32(value: number): BinaryWriter { return this.uint32(((value << 1) ^ (value >> 31)) >>> 0); } int64(value: string | number | bigint): BinaryWriter { const { lo, hi } = int64FromString(value.toString()); return this._push(writeVarint64, int64Length(lo, hi), { lo, hi }); } // uint64 is the same with int64 uint64 = BinaryWriter.prototype.int64; sint64(value: string | number | bigint): BinaryWriter { let { lo, hi } = int64FromString(value.toString()); // zig zag [lo, hi] = zzEncode(lo, hi); return this._push(writeVarint64, int64Length(lo, hi), { lo, hi }); } fixed64(value: string | number | bigint): BinaryWriter { const { lo, hi } = int64FromString(value.toString()); return this._push(writeFixed32, 4, lo)._push(writeFixed32, 4, hi); } // sfixed64 is the same with fixed64 sfixed64 = BinaryWriter.prototype.fixed64; bool(value: boolean): BinaryWriter { return this._push(writeByte, 1, value ? 1 : 0); } fixed32(value: number): BinaryWriter { return this._push(writeFixed32, 4, value >>> 0); } // sfixed32 is the same with fixed32 sfixed32 = BinaryWriter.prototype.fixed32; float(value: number): BinaryWriter { throw new Error("float not supported" + value); } double(value: number): BinaryWriter { throw new Error("double not supported" + value); } bytes(value: Uint8Array): BinaryWriter { const len = value.length >>> 0; if (!len) return this._push(writeByte, 1, 0); return this.uint32(len)._push(writeBytes, len, value); } string(value: string): BinaryWriter { const len = utf8Length(value); return len ? this.uint32(len)._push(utf8Write, len, value) : this._push(writeByte, 1, 0); } } function writeBytes( val: Uint8Array | number[], buf: Uint8Array | number[], pos: number ) { if (typeof Uint8Array !== "undefined") { (buf as Uint8Array).set(val, pos); } else { for (let i = 0; i < val.length; ++i) buf[pos + i] = val[i]; } } function pool( alloc: (size: number) => Uint8Array, slice: (begin?: number, end?: number) => Uint8Array, size?: number ): (size: number) => Uint8Array { const SIZE = size || 8192; const MAX = SIZE >>> 1; let slab = null; let offset = SIZE; return function pool_alloc(size): Uint8Array { if (size < 1 || size > MAX) return alloc(size); if (offset + size > SIZE) { slab = alloc(SIZE); offset = 0; } const buf: Uint8Array = slice.call(slab, offset, (offset += size)); if (offset & 7) // align to 32 bit offset = (offset | 7) + 1; return buf; }; } function indexOutOfRange(reader: BinaryReader, writeLength?: number) { return RangeError( "index out of range: " + reader.pos + " + " + (writeLength || 1) + " > " + reader.len ); } `;