Spaces:
Running
Running
| import * as text from './text.js'; | |
| const protobuf = {}; | |
| protobuf.BinaryReader = class { | |
| static open(data, offset) { | |
| offset = offset || 0; | |
| if (data instanceof Uint8Array) { | |
| return new protobuf.BufferReader(data, offset); | |
| } | |
| if (data.length < 0x20000000) { | |
| data = data.peek(); | |
| return new protobuf.BufferReader(data, offset); | |
| } | |
| return new protobuf.StreamReader(data, offset); | |
| } | |
| constructor() { | |
| this._utf8Decoder = new TextDecoder('utf-8'); | |
| } | |
| signature() { | |
| const tags = new Map(); | |
| this._position = 0; | |
| try { | |
| if (this._length > 0) { | |
| const type = this.byte() & 7; | |
| this.skip(-1); | |
| if (type !== 4 && type !== 6 && type !== 7) { | |
| const length = this.length; | |
| while (this._position < length) { | |
| const tag = this.uint32(); | |
| const field = tag >>> 3; | |
| const type = tag & 7; | |
| if (type > 5 || field === 0) { | |
| tags.clear(); | |
| break; | |
| } | |
| tags.set(field, type); | |
| if (!this._skipType(type)) { | |
| tags.clear(); | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| } catch { | |
| tags.clear(); | |
| } | |
| this._position = 0; | |
| return tags; | |
| } | |
| decode() { | |
| let tags = {}; | |
| this._position = 0; | |
| try { | |
| const decodeMessage = (max) => { | |
| const length = this._uint32(); | |
| if (length === undefined) { | |
| return undefined; | |
| } | |
| if (length === 0) { | |
| // return 2; | |
| } | |
| const end = this.position + length; | |
| if (end > max) { | |
| return undefined; | |
| } | |
| try { | |
| const tags = {}; | |
| while (this.position < end) { | |
| const tag = this._uint32(); | |
| if (tag === undefined) { | |
| this.seek(end); | |
| return 2; | |
| } | |
| const field = tag >>> 3; | |
| const type = tag & 7; | |
| if (type > 5 || field === 0) { | |
| this.seek(end); | |
| return 2; | |
| } | |
| if (type === 2) { | |
| const type = tags[field]; | |
| if (type !== 2) { | |
| const inner = decodeMessage(end); | |
| if (this.position > end) { | |
| this.seek(end); | |
| return 2; | |
| } | |
| if (inner === undefined) { | |
| this.seek(end); | |
| return 2; | |
| } | |
| if (inner === 2) { | |
| tags[field] = inner; | |
| } else if (type) { | |
| for (const [key, value] of Object.entries(inner)) { | |
| if (type[key] === 2 && value !== 2) { | |
| continue; | |
| } | |
| type[key] = value; | |
| } | |
| } else { | |
| tags[field] = inner; | |
| } | |
| continue; | |
| } | |
| } | |
| tags[field] = type; | |
| if (!this._skipType(type)) { | |
| this.seek(end); | |
| return 2; | |
| } | |
| } | |
| if (this.position === end) { | |
| return tags; | |
| } | |
| } catch { | |
| // continue regardless of error | |
| } | |
| this.seek(end); | |
| return 2; | |
| }; | |
| if (this._length > 0) { | |
| const type = this.byte() & 7; | |
| this.skip(-1); | |
| if (type !== 4 && type !== 6 && type !== 7) { | |
| const length = this.length; | |
| while (this.position < length) { | |
| const tag = this.uint32(); | |
| const field = tag >>> 3; | |
| const type = tag & 7; | |
| if (type > 5 || field === 0) { | |
| tags = {}; | |
| break; | |
| } | |
| if (type === 2) { | |
| const type = tags[field]; | |
| if (type !== 2) { | |
| const inner = decodeMessage(length); | |
| if (inner === undefined) { | |
| tags = {}; | |
| break; | |
| } | |
| if (inner === 2) { | |
| tags[field] = inner; | |
| } else if (type) { | |
| for (const [name, value] of Object.entries(inner)) { | |
| if (type[name] === 2 && value !== 2) { | |
| continue; | |
| } | |
| type[name] = value; | |
| } | |
| } else { | |
| tags[field] = inner; | |
| } | |
| continue; | |
| } | |
| } | |
| tags[field] = type; | |
| if (!this._skipType(type)) { | |
| tags = {}; | |
| break; | |
| } | |
| } | |
| } | |
| } | |
| } catch { | |
| tags = {}; | |
| } | |
| this._position = 0; | |
| return tags; | |
| } | |
| get length() { | |
| return this._length; | |
| } | |
| get position() { | |
| return this._position; | |
| } | |
| seek(position) { | |
| this._position = position >= 0 ? position : this._length + position; | |
| } | |
| bytes() { | |
| const length = this.uint32(); | |
| return this.read(length); | |
| } | |
| string() { | |
| const buffer = this.bytes(); | |
| return this._utf8Decoder.decode(buffer); | |
| } | |
| bool() { | |
| return this.uint32() !== 0; | |
| } | |
| uint32() { | |
| let c = this.byte(); | |
| let value = (c & 127) >>> 0; | |
| if (c < 128) { | |
| return value; | |
| } | |
| c = this.byte(); | |
| value = (value | (c & 127) << 7) >>> 0; | |
| if (c < 128) { | |
| return value; | |
| } | |
| c = this.byte(); | |
| value = (value | (c & 127) << 14) >>> 0; | |
| if (c < 128) { | |
| return value; | |
| } | |
| c = this.byte(); | |
| value = (value | (c & 127) << 21) >>> 0; | |
| if (c < 128) { | |
| return value; | |
| } | |
| c = this.byte(); | |
| value += (c & 127) * 0x10000000; | |
| if (c < 128) { | |
| return value; | |
| } | |
| if (this.byte() !== 255 || this.byte() !== 255 || this.byte() !== 255 || this.byte() !== 255 || this.byte() !== 1) { | |
| throw new protobuf.Error('Varint is not 32-bit.'); | |
| } | |
| return value; | |
| } | |
| _uint32() { | |
| if (this._position < this._length) { | |
| let c = this.byte(); | |
| let value = (c & 127) >>> 0; | |
| if (c < 128) { | |
| return value; | |
| } | |
| if (this._position < this._length) { | |
| c = this.byte(); | |
| value = (value | (c & 127) << 7) >>> 0; | |
| if (c < 128) { | |
| return value; | |
| } | |
| if (this._position < this._length) { | |
| c = this.byte(); | |
| value = (value | (c & 127) << 14) >>> 0; | |
| if (c < 128) { | |
| return value; | |
| } | |
| if (this._position < this._length) { | |
| c = this.byte(); | |
| value = (value | (c & 127) << 21) >>> 0; | |
| if (c < 128) { | |
| return value; | |
| } | |
| if (this._position < this._length) { | |
| c = this.byte(); | |
| value += (c & 127) * 0x10000000; | |
| if (c < 128) { | |
| return value; | |
| } | |
| if (this.byte() !== 255 || this.byte() !== 255 || this.byte() !== 255 || this.byte() !== 255 || this.byte() !== 1) { | |
| return undefined; | |
| } | |
| return value; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| return undefined; | |
| } | |
| int32() { | |
| return this.uint32() | 0; | |
| } | |
| sint32() { | |
| const value = this.uint32(); | |
| return value >>> 1 ^ -(value & 1) | 0; | |
| } | |
| int64() { | |
| return BigInt.asIntN(64, this.varint()); | |
| } | |
| uint64() { | |
| return this.varint(); | |
| } | |
| sint64() { | |
| const value = this.varint(); | |
| return (value >> 1n) ^ (-(value & 1n)); // ZigZag decode | |
| } | |
| array(obj, item, tag) { | |
| if ((tag & 7) === 2) { | |
| const end = this.uint32() + this._position; | |
| while (this._position < end) { | |
| obj.push(item()); | |
| } | |
| } else { | |
| obj.push(item()); | |
| } | |
| return obj; | |
| } | |
| floats(obj, tag) { | |
| if ((tag & 7) === 2) { | |
| if (obj && obj.length > 0) { | |
| throw new protobuf.Error('Invalid packed float array.'); | |
| } | |
| const size = this.uint32(); | |
| const end = this._position + size; | |
| if (end > this._length) { | |
| this._unexpected(); | |
| } | |
| const length = size >>> 2; | |
| obj = size > 0x100000 ? new Float32Array(length) : new Array(length); | |
| for (let i = 0; i < length; i++) { | |
| obj[i] = this.float(); | |
| } | |
| this._position = end; | |
| } else if (obj !== undefined && obj.length <= 0x4000000) { | |
| obj.push(this.float()); | |
| } else { | |
| obj = undefined; | |
| this.float(); | |
| } | |
| return obj; | |
| } | |
| doubles(obj, tag) { | |
| if ((tag & 7) === 2) { | |
| if (obj && obj.length > 0) { | |
| throw new protobuf.Error('Invalid packed float array.'); | |
| } | |
| const size = this.uint32(); | |
| const end = this._position + size; | |
| if (end > this._length) { | |
| this._unexpected(); | |
| } | |
| const length = size >>> 3; | |
| obj = size > 1048576 ? new Float64Array(length) : new Array(length); | |
| for (let i = 0; i < length; i++) { | |
| obj[i] = this.double(); | |
| } | |
| this._position = end; | |
| } else if (obj !== undefined && obj.length < 1000000) { | |
| obj.push(this.double()); | |
| } else { | |
| obj = undefined; | |
| this.double(); | |
| } | |
| return obj; | |
| } | |
| skip(offset) { | |
| this._position += offset; | |
| if (this._position > this._length) { | |
| this._unexpected(); | |
| } | |
| } | |
| skipType(type) { | |
| switch (type) { | |
| case 0: | |
| this.skipVarint(); | |
| break; | |
| case 1: | |
| this.skip(8); | |
| break; | |
| case 2: | |
| this.skip(this.uint32()); | |
| break; | |
| case 3: | |
| while ((type = this.uint32() & 7) !== 4) { | |
| this.skipType(type); | |
| } | |
| break; | |
| case 5: | |
| this.skip(4); | |
| break; | |
| default: | |
| throw new protobuf.Error(`Invalid type '${type}' at offset ${this._position}.`); | |
| } | |
| } | |
| _skipType(type) { | |
| switch (type) { | |
| case 0: { | |
| // const max = this._position + 9; | |
| do { | |
| if (this._position >= this._length /* || this._position > max */) { | |
| return false; | |
| } | |
| } | |
| while (this.byte() & 128); | |
| break; | |
| } | |
| case 1: { | |
| const position = this._position + 8; | |
| if (position > this._length) { | |
| return false; | |
| } | |
| this._position = position; | |
| break; | |
| } | |
| case 2: { | |
| const length = this.uint32(); | |
| if (length === undefined) { | |
| return false; | |
| } | |
| const position = this._position + length; | |
| if (position > this._end) { | |
| return false; | |
| } | |
| this._position = position; | |
| break; | |
| } | |
| case 3: { | |
| for (;;) { | |
| const tag = this.uint32(); | |
| if (tag === undefined) { | |
| return false; | |
| } | |
| const wireType = tag & 7; | |
| if (wireType === 4) { | |
| break; | |
| } | |
| if (!this._skipType(wireType)) { | |
| return false; | |
| } | |
| } | |
| break; | |
| } | |
| case 5: { | |
| const position = this._position + 4; | |
| if (position > this._length) { | |
| return false; | |
| } | |
| this._position = position; | |
| break; | |
| } | |
| default: { | |
| return false; | |
| } | |
| } | |
| return true; | |
| } | |
| entry(obj, key, value) { | |
| this.skipVarint(); | |
| this.skip(1); | |
| let k = key(); | |
| if (!Number.isInteger(k) && typeof k !== 'string') { | |
| k = Number(k); | |
| } | |
| this.skip(1); | |
| const v = value(); | |
| obj[k] = v; | |
| } | |
| _unexpected() { | |
| throw new RangeError('Unexpected end of file.'); | |
| } | |
| }; | |
| protobuf.BufferReader = class extends protobuf.BinaryReader { | |
| constructor(buffer, offset = 0) { | |
| super(); | |
| this._buffer = buffer; | |
| this._length = buffer.length; | |
| this._position = offset; | |
| this._view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); | |
| } | |
| skipVarint() { | |
| do { | |
| if (this._position >= this._length) { | |
| this._unexpected(); | |
| } | |
| } | |
| while (this._buffer[this._position++] & 128); | |
| } | |
| read(length) { | |
| const position = this._position; | |
| this.skip(length); | |
| return this._buffer.slice(position, this._position); | |
| } | |
| byte() { | |
| if (this._position < this._length) { | |
| return this._buffer[this._position++]; | |
| } | |
| throw new RangeError('Unexpected end of file.'); | |
| } | |
| fixed64() { | |
| const position = this._position; | |
| this.skip(8); | |
| return this._view.getBigUint64(position, true); | |
| } | |
| sfixed64() { | |
| const position = this._position; | |
| this.skip(8); | |
| return this._view.getBigInt64(position, true); | |
| } | |
| fixed32() { | |
| const position = this._position; | |
| this.skip(4); | |
| return this._view.getUint32(position, true); | |
| } | |
| sfixed32() { | |
| const position = this._position; | |
| this.skip(4); | |
| return this._view.getInt32(position, true); | |
| } | |
| float() { | |
| const position = this._position; | |
| this.skip(4); | |
| return this._view.getFloat32(position, true); | |
| } | |
| double() { | |
| const position = this._position; | |
| this.skip(8); | |
| return this._view.getFloat64(position, true); | |
| } | |
| varint() { | |
| let value = 0n; | |
| let shift = 0n; | |
| for (let i = 0; i < 10 && this._position < this._length; i++) { | |
| const byte = this._buffer[this._position++]; | |
| value |= BigInt(byte & 0x7F) << shift; | |
| if ((byte & 0x80) === 0) { | |
| return value; | |
| } | |
| shift += 7n; | |
| } | |
| throw new protobuf.Error('Invalid varint value.'); | |
| } | |
| }; | |
| protobuf.StreamReader = class extends protobuf.BinaryReader { | |
| constructor(stream, offset) { | |
| super(new Uint8Array(0)); | |
| this._stream = stream; | |
| this._length = stream.length; | |
| this.seek(offset || 0); | |
| } | |
| skipVarint() { | |
| do { | |
| if (this._position >= this._length) { | |
| this._unexpected(); | |
| } | |
| } | |
| while (this.byte() & 128); | |
| } | |
| read(length) { | |
| this._stream.seek(this._position); | |
| this.skip(length); | |
| return this._stream.read(length); | |
| } | |
| byte() { | |
| const position = this._fill(1); | |
| return this._view.getUint8(position); | |
| } | |
| fixed64() { | |
| const position = this._fill(8); | |
| return this._view.getBigUint64(position, true); | |
| } | |
| sfixed64() { | |
| const position = this._fill(8); | |
| return this._view.getBigInt64(position, true); | |
| } | |
| fixed32() { | |
| const position = this._fill(4); | |
| return this._view.getUint32(position, true); | |
| } | |
| sfixed32() { | |
| const position = this._fill(4); | |
| return this._view.getInt32(position, true); | |
| } | |
| float() { | |
| const position = this._fill(4); | |
| return this._view.getFloat32(position, true); | |
| } | |
| double() { | |
| const position = this._fill(8); | |
| return this._view.getFloat64(position, true); | |
| } | |
| varint() { | |
| let value = 0n; | |
| let shift = 0n; | |
| for (let i = 0; i < 10 && this._position < this._length; i++) { | |
| const byte = this.byte(); | |
| value |= BigInt(byte & 0x7F) << shift; | |
| if ((byte & 0x80) === 0) { | |
| return value; | |
| } | |
| shift += 7n; | |
| } | |
| throw new protobuf.Error('Invalid varint value.'); | |
| } | |
| _fill(length) { | |
| if (this._position + length > this._length) { | |
| throw new Error(`Expected ${this._position + length - this._length} more bytes. The file might be corrupted. Unexpected end of file.`); | |
| } | |
| if (!this._buffer || this._position < this._offset || this._position + length > this._offset + this._buffer.length) { | |
| this._offset = this._position; | |
| this._stream.seek(this._offset); | |
| const size = Math.min(0x10000000, this._length - this._offset); | |
| this._buffer = this._stream.read(size); | |
| this._view = new DataView(this._buffer.buffer, this._buffer.byteOffset, this._buffer.byteLength); | |
| } | |
| const position = this._position; | |
| this._position += length; | |
| return position - this._offset; | |
| } | |
| }; | |
| protobuf.TextReader = class { | |
| static open(data) { | |
| if (data) { | |
| const buffer = data instanceof Uint8Array ? data : data.peek(); | |
| const decoder = text.Decoder.open(buffer); | |
| let first = true; | |
| for (let i = 0; i < 0x100; i++) { | |
| const c = decoder.decode(); | |
| if (c === undefined) { | |
| if (i === 0) { | |
| return null; | |
| } | |
| break; | |
| } | |
| if (c === '\0') { | |
| return null; | |
| } | |
| const whitespace = c === ' ' || c === '\n' || c === '\r' || c === '\t'; | |
| if (c < ' ' && !whitespace) { | |
| return null; | |
| } | |
| if (first && !whitespace) { | |
| first = false; | |
| if (c === '#') { | |
| let c = ''; | |
| do { | |
| c = decoder.decode(); | |
| } | |
| while (c !== undefined && c !== '\n'); | |
| if (c === undefined) { | |
| break; | |
| } | |
| continue; | |
| } | |
| if (c === '[') { | |
| continue; | |
| } | |
| if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z') { | |
| continue; | |
| } | |
| return null; | |
| } | |
| } | |
| return new protobuf.TextReader(buffer); | |
| } | |
| return null; | |
| } | |
| constructor(buffer) { | |
| this._decoder = text.Decoder.open(buffer); | |
| this.reset(); | |
| } | |
| signature() { | |
| const tags = new Map(); | |
| this.reset(); | |
| try { | |
| this.start(); | |
| while (!this.end()) { | |
| const tag = this.tag(); | |
| if (this.token() === '{' || this.token() === '<') { | |
| this.start(); | |
| tags.set(tag, true); | |
| while (!this.end()) { | |
| const subtag = this.tag(); | |
| tags.set(`${tag}.${subtag}`, true); | |
| this.skip(); | |
| this.match(','); | |
| } | |
| } else { | |
| this.skip(); | |
| tags.set(tag, true); | |
| } | |
| } | |
| } catch { | |
| if (tags.has('[')) { | |
| tags.clear(); | |
| } | |
| } | |
| this.reset(); | |
| return tags; | |
| } | |
| reset() { | |
| this._decoder.position = 0; | |
| this._position = 0; | |
| this._depth = 0; | |
| this._arrayDepth = 0; | |
| this._brackets = []; | |
| this._token = ''; | |
| this.next(); | |
| } | |
| start() { | |
| if (this._depth > 0) { | |
| if (this._token === '<') { | |
| this.expect('<'); | |
| this._brackets.push('>'); | |
| } else { | |
| this.expect('{'); | |
| this._brackets.push('}'); | |
| } | |
| } | |
| this._depth++; | |
| } | |
| end() { | |
| if (this._depth <= 0) { | |
| throw new protobuf.Error(`Invalid depth ${this.location()}`); | |
| } | |
| const close = this._brackets.length > 0 ? this._brackets[this._brackets.length - 1] : '}'; | |
| if (this._token === '}' || this._token === '>') { | |
| this.expect(close); | |
| this._brackets.pop(); | |
| if (!this.match(';')) { | |
| this.match(','); | |
| } | |
| this._depth--; | |
| return true; | |
| } | |
| if (this._token === undefined) { | |
| if (this._depth !== 1) { | |
| throw new protobuf.Error(`Unexpected end of input ${this.location()}`); | |
| } | |
| this._depth--; | |
| return true; | |
| } | |
| return false; | |
| } | |
| tag() { | |
| const name = this._token; | |
| this.next(); | |
| if (this._token !== '[' && this._token !== '{' && this._token !== '<') { | |
| this.expect(':'); | |
| } | |
| return name; | |
| } | |
| integer() { | |
| const token = this._token; | |
| const value = Number.parseInt(token, 10); | |
| if (Number.isNaN(token - value)) { | |
| throw new protobuf.Error(`Couldn't parse integer '${token}' ${this.location()}`); | |
| } | |
| this.next(); | |
| this.semicolon(); | |
| return value; | |
| } | |
| double() { | |
| let value = 0; | |
| let token = this._token; | |
| switch (token) { | |
| case 'nan': value = NaN; break; | |
| case 'inf': value = Infinity; break; | |
| case '-inf': value = -Infinity; break; | |
| default: | |
| if (token.endsWith('f')) { | |
| token = token.substring(0, token.length - 1); | |
| } | |
| value = Number.parseFloat(token); | |
| if (Number.isNaN(token - value)) { | |
| throw new protobuf.Error(`Couldn't parse float '${token}' ${this.location()}`); | |
| } | |
| break; | |
| } | |
| this.next(); | |
| this.semicolon(); | |
| return value; | |
| } | |
| float() { | |
| return this.double(); | |
| } | |
| uint32() { | |
| return this.integer(); | |
| } | |
| int32() { | |
| return this.integer(); | |
| } | |
| sint32() { | |
| return this.integer(); | |
| } | |
| int64() { | |
| return BigInt(this.integer()); | |
| } | |
| uint64() { | |
| return BigInt.asUintN(64, BigInt(this.integer())); | |
| } | |
| sint64() { | |
| return BigInt(this.integer()); | |
| } | |
| fixed64() { | |
| return BigInt.asUintN(64, BigInt(this.integer())); | |
| } | |
| sfixed64() { | |
| return BigInt(this.integer()); | |
| } | |
| fixed32() { | |
| return this.integer(); | |
| } | |
| sfixed32() { | |
| return this.integer(); | |
| } | |
| string() { | |
| const token = this._token; | |
| if (token.length < 2) { | |
| throw new protobuf.Error(`String is too short ${this.location()}`); | |
| } | |
| const quote = token.substring(0, 1); | |
| if (quote !== "'" && quote !== '"') { | |
| throw new protobuf.Error(`String is not in quotes ${this.location()}`); | |
| } | |
| if (quote !== token.substring(token.length - 1)) { | |
| throw new protobuf.Error(`String quotes do not match ${this.location()}`); | |
| } | |
| const value = token.substring(1, token.length - 1); | |
| this.next(); | |
| this.semicolon(); | |
| return value; | |
| } | |
| bool() { | |
| const token = this._token; | |
| switch (token) { | |
| case 'true': | |
| case 'True': | |
| case '1': | |
| this.next(); | |
| this.semicolon(); | |
| return true; | |
| case 'false': | |
| case 'False': | |
| case '0': | |
| this.next(); | |
| this.semicolon(); | |
| return false; | |
| default: | |
| throw new protobuf.Error(`Couldn't parse boolean '${token}' ${this.location()}`); | |
| } | |
| } | |
| bytes() { | |
| const token = this.string(); | |
| const length = token.length; | |
| const array = new Uint8Array(length); | |
| for (let i = 0; i < length; i++) { | |
| array[i] = token.charCodeAt(i); | |
| } | |
| return array; | |
| } | |
| enum(type) { | |
| const token = this._token; | |
| let value = 0; | |
| if (Object.prototype.hasOwnProperty.call(type, token)) { | |
| value = type[token]; | |
| } else { | |
| value = Number.parseInt(token, 10); | |
| if (Number.isNaN(token - value)) { | |
| throw new protobuf.Error(`Couldn't parse enum '${token === undefined ? '' : token}' ${this.location()}`); | |
| } | |
| } | |
| this.next(); | |
| this.semicolon(); | |
| return value; | |
| } | |
| any(type) { | |
| this.start(); | |
| const message = type(); | |
| if (this._token.startsWith('[') && this._token.endsWith(']')) { | |
| message.type_url = this._token.substring(1, this._token.length - 1).trim(); | |
| this.next(); | |
| this.match(':'); | |
| message.value = this.read(); | |
| this.match(';'); | |
| if (!this.end()) { | |
| this.expect('}'); | |
| } | |
| } else { | |
| while (!this.end()) { | |
| const tag = this.tag(); | |
| switch (tag) { | |
| case "type_url": | |
| message.type_url = this.string(); | |
| break; | |
| case "value": | |
| message.value = this.bytes(); | |
| break; | |
| default: | |
| this.field(tag, message); | |
| break; | |
| } | |
| } | |
| } | |
| return message; | |
| } | |
| anyarray(obj, type) { | |
| this.start(); | |
| if (this._token.startsWith('[') && this._token.endsWith(']')) { | |
| while (!this.end()) { | |
| if (this._token.startsWith('[') && this._token.endsWith(']')) { | |
| const message = type(); | |
| message.type_url = this._token.substring(1, this._token.length - 1).trim(); | |
| this.next(); | |
| this.match(':'); | |
| message.value = this.read(); | |
| this.match(';'); | |
| obj.push(message); | |
| continue; | |
| } | |
| this.expect('['); | |
| } | |
| } else { | |
| const message = type(); | |
| while (!this.end()) { | |
| const tag = this.tag(); | |
| switch (tag) { | |
| case "type_url": | |
| message.type_url = this.string(); | |
| break; | |
| case "value": | |
| message.value = this.bytes(); | |
| break; | |
| default: | |
| this.field(tag, message); | |
| break; | |
| } | |
| } | |
| obj.push(message); | |
| } | |
| } | |
| entry(obj, key, value) { | |
| this.start(); | |
| let k = ''; | |
| let v = null; | |
| while (!this.end()) { | |
| const tag = this.tag(); | |
| switch (tag) { | |
| case 'key': | |
| k = key(); | |
| break; | |
| case 'value': | |
| v = value(); | |
| break; | |
| default: | |
| throw new protobuf.Error(`Unsupported entry tag '${tag}'.`); | |
| } | |
| } | |
| obj[k] = v; | |
| } | |
| array(obj, item) { | |
| if (this.first()) { | |
| while (!this.last()) { | |
| obj.push(item()); | |
| switch (this._token) { | |
| case ',': | |
| this.next(); | |
| break; | |
| case ']': | |
| break; | |
| default: | |
| this.handle(this._token); | |
| break; | |
| } | |
| } | |
| } else { | |
| obj.push(item()); | |
| } | |
| } | |
| first() { | |
| if (this.match('[')) { | |
| this._arrayDepth++; | |
| return true; | |
| } | |
| return false; | |
| } | |
| last() { | |
| if (this.match(']')) { | |
| this._arrayDepth--; | |
| return true; | |
| } | |
| return false; | |
| } | |
| read() { | |
| const start = this._position; | |
| this.skip(); | |
| const end = this._position; | |
| const position = this._decoder.position; | |
| this._decoder.position = start; | |
| let content = ''; | |
| while (this._decoder.position < end) { | |
| content += this._decoder.decode(); | |
| } | |
| this._decoder.position = position; | |
| return content; | |
| } | |
| skip() { | |
| switch (this._token) { | |
| case '<': | |
| case '{': { | |
| const depth = this._depth; | |
| this.start(); | |
| while (!this.end() || depth < this._depth) { | |
| if (this._token === '{' || this._token === '<') { | |
| this.start(); | |
| } else if (this._token !== '}' && this._token !== '>') { | |
| this.next(); | |
| if (!this.match(';')) { | |
| this.match(','); | |
| } | |
| } | |
| } | |
| break; | |
| } | |
| case '[': { | |
| const depth = this._arrayDepth; | |
| this.first(); | |
| while (!this.last() || depth < this._arrayDepth) { | |
| this.next(); | |
| if (this._token === '[') { | |
| this.first(); | |
| } else if (this._token === undefined) { | |
| this.handle(this._token); | |
| } | |
| } | |
| break; | |
| } | |
| default: { | |
| this.next(); | |
| this.semicolon(); | |
| break; | |
| } | |
| } | |
| } | |
| handle(token) { | |
| throw new protobuf.Error(`Unexpected token '${token}' ${this.location()}`); | |
| } | |
| field(token /*, module */) { | |
| throw new protobuf.Error(`Unsupported field '${token}' ${this.location()}`); | |
| } | |
| token() { | |
| return this._token; | |
| } | |
| next() { | |
| if (this._token === undefined) { | |
| throw new protobuf.Error(`Unexpected end of input ${this.location()}`); | |
| } | |
| this._position = this._decoder.position; | |
| let c = this._decoder.decode(); | |
| for (;;) { | |
| switch (c) { | |
| case ' ': | |
| case '\n': | |
| case '\r': | |
| case '\t': | |
| this._position = this._decoder.position; | |
| c = this._decoder.decode(); | |
| continue; | |
| case '#': | |
| do { | |
| c = this._decoder.decode(); | |
| if (c === undefined) { | |
| this._token = undefined; | |
| return; | |
| } | |
| } | |
| while (c !== '\n'); | |
| this._position = this._decoder.position; | |
| c = this._decoder.decode(); | |
| continue; | |
| default: | |
| break; | |
| } | |
| break; | |
| } | |
| if (c === undefined) { | |
| this._token = undefined; | |
| return; | |
| } | |
| if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c === '_' || c === '$') { | |
| let token = c; | |
| let position = this._decoder.position; | |
| for (;;) { | |
| c = this._decoder.decode(); | |
| if (c === undefined || c === '\n') { | |
| break; | |
| } | |
| if (c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= '0' && c <= '9' || c === '_' || c === '+' || c === '-') { | |
| token += c; | |
| position = this._decoder.position; | |
| continue; | |
| } | |
| break; | |
| } | |
| this._decoder.position = position; | |
| this._token = token; | |
| return; | |
| } | |
| switch (c) { | |
| case '{': | |
| case '}': | |
| case '<': | |
| case '>': | |
| case ':': | |
| case ',': | |
| case ']': | |
| case ';': | |
| this._token = c; | |
| return; | |
| case '[': { | |
| let token = c; | |
| let position = this._decoder.position; | |
| let x = this._decoder.decode(); | |
| if ((x !== undefined) && x >= 'a' && x <= 'z' || x >= 'A' && x <= 'Z') { | |
| token += x; | |
| for (;;) { | |
| x = this._decoder.decode(); | |
| if (x === undefined || x === '\n') { | |
| break; | |
| } | |
| if (x >= 'a' && x <= 'z' || x >= 'A' && x <= 'Z' || x >= '0' && x <= '9' || x === '.' || x === '/') { | |
| token += x; | |
| position = this._decoder.position; | |
| continue; | |
| } | |
| if (x === ']') { | |
| this._token = token + x; | |
| return; | |
| } | |
| } | |
| } | |
| this._decoder.position = position; | |
| this._token = '['; | |
| return; | |
| } | |
| case '"': | |
| case "'": { | |
| const quote = c; | |
| let content = c; | |
| for (;;) { | |
| c = this._decoder.decode(); | |
| if (c === undefined || c === '\n') { | |
| throw new protobuf.Error(`Unexpected end of string ${this.location()}`); | |
| } | |
| if (c === '\\') { | |
| c = this._decoder.decode(); | |
| if (c === undefined || c === '\n') { | |
| throw new protobuf.Error(`Unexpected end of string ${this.location()}`); | |
| } | |
| switch (c) { | |
| case '\\': c = '\\'; break; | |
| case "'": c = "'"; break; | |
| case '"': c = '"'; break; | |
| case 'r': c = '\r'; break; | |
| case 'n': c = '\n'; break; | |
| case 't': c = '\t'; break; | |
| case 'b': c = '\b'; break; | |
| case 'x': | |
| case 'X': { | |
| let value = 0; | |
| for (let xi = 0; xi < 2; xi++) { | |
| let c = this._decoder.decode(); | |
| if (c === undefined) { | |
| throw new protobuf.Error(`Unexpected end of string ${this.location()}`); | |
| } | |
| c = c.charCodeAt(0); | |
| if (c >= 65 && c <= 70) { | |
| c -= 55; | |
| } else if (c >= 97 && c <= 102) { | |
| c -= 87; | |
| } else if (c >= 48 && c <= 57) { | |
| c -= 48; | |
| } else { | |
| c = -1; | |
| } | |
| if (c === -1) { | |
| throw new protobuf.Error(`Unexpected hex digit '${c}' in bytes string ${this.location()}`); | |
| } | |
| value = value << 4 | c; | |
| } | |
| c = String.fromCharCode(value); | |
| break; | |
| } | |
| default: { | |
| if (c < '0' || c > '9') { | |
| throw new protobuf.Error(`Unexpected character '${c}' in string ${this.location()}`); | |
| } | |
| let value = 0; | |
| let od = c; | |
| if (od < '0' || od > '9') { | |
| throw new protobuf.Error(`Unexpected octal digit '${od}' in bytes string ${this.location()}`); | |
| } | |
| od = od.charCodeAt(0); | |
| value = value << 3 | od - 48; | |
| od = this._decoder.decode(); | |
| if (od === undefined) { | |
| throw new protobuf.Error(`Unexpected end of string ${this.location()}`); | |
| } | |
| if (od < '0' || od > '9') { | |
| throw new protobuf.Error(`Unexpected octal digit '${od}' in bytes string ${this.location()}`); | |
| } | |
| od = od.charCodeAt(0); | |
| value = value << 3 | od - 48; | |
| od = this._decoder.decode(); | |
| if (od === undefined) { | |
| throw new protobuf.Error(`Unexpected end of string ${this.location()}`); | |
| } | |
| if (od < '0' || od > '9') { | |
| throw new protobuf.Error(`Unexpected octal digit '${od}' in bytes string ${this.location()}`); | |
| } | |
| od = od.charCodeAt(0); | |
| value = value << 3 | od - 48; | |
| c = String.fromCharCode(value); | |
| break; | |
| } | |
| } | |
| content += c; | |
| continue; | |
| } else { | |
| content += c; | |
| if (c === quote) { | |
| break; | |
| } | |
| } | |
| } | |
| this._token = content; | |
| return; | |
| } | |
| case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': | |
| case '-': case '+': case '.': { | |
| let token = c; | |
| let position = this._decoder.position; | |
| for (;;) { | |
| c = this._decoder.decode(); | |
| if (c === undefined || c === '\n') { | |
| break; | |
| } | |
| if ((c >= '0' && c <= '9') || c === '_' || c === '+' || c === '-' || c === '.' || c === 'e' || c === 'E') { | |
| token += c; | |
| position = this._decoder.position; | |
| continue; | |
| } | |
| break; | |
| } | |
| if (token === '-' && c === 'i' && this._decoder.decode() === 'n' && this._decoder.decode() === 'f') { | |
| token = '-inf'; | |
| position = this._decoder.position; | |
| } | |
| if (token === '-' || token === '+' || token === '.') { | |
| throw new protobuf.Error(`Unexpected token '${token}' ${this.location()}`); | |
| } | |
| this._decoder.position = position; | |
| this._token = token; | |
| return; | |
| } | |
| default: { | |
| throw new protobuf.Error(`Unexpected token '${c}' ${this.location()}`); | |
| } | |
| } | |
| } | |
| expect(value) { | |
| if (this._token !== value) { | |
| throw new protobuf.Error(`Unexpected '${this._token}' instead of '${value}' ${this.location()}`); | |
| } | |
| this.next(); | |
| } | |
| match(value) { | |
| if (value === this._token) { | |
| this.next(); | |
| return true; | |
| } | |
| return false; | |
| } | |
| location() { | |
| let line = 1; | |
| let column = 1; | |
| this._decoder.position = 0; | |
| let c = ''; | |
| do { | |
| if (this._decoder.position === this._position) { | |
| return `at ${line}:${column}.`; | |
| } | |
| c = this._decoder.decode(); | |
| if (c === '\n') { | |
| line++; | |
| column = 1; | |
| } else { | |
| column++; | |
| } | |
| } | |
| while (c !== undefined); | |
| return `at ${line}:${column}.`; | |
| } | |
| semicolon() { | |
| if (this._arrayDepth === 0) { | |
| if (!this.match(';')) { | |
| this.match(','); | |
| } | |
| } | |
| } | |
| }; | |
| protobuf.Error = class extends Error { | |
| constructor(message) { | |
| super(message); | |
| this.name = 'Protocol Buffers Error'; | |
| this.message = message; | |
| } | |
| }; | |
| export const BinaryReader = protobuf.BinaryReader; | |
| export const TextReader = protobuf.TextReader; | |