Spaces:
Running
Running
| const flexbuffers = {}; | |
| flexbuffers.BinaryReader = class { | |
| static open(buffer) { | |
| const length = buffer.length; | |
| if (length >= 3) { | |
| const byteWidth = buffer[length - 1]; | |
| if (byteWidth <= 8) { | |
| const packedType = buffer[length - 2]; | |
| return new flexbuffers.BinaryReader(buffer, length - 2 - byteWidth, byteWidth, 1 << (packedType & 3), packedType >> 2); | |
| } | |
| } | |
| return null; | |
| } | |
| constructor(buffer, offset, parentWidth, byteWidth, type) { | |
| this._buffer = buffer; | |
| this._length = buffer.length; | |
| this._view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength); | |
| this._utf8Decoder = new TextDecoder('utf-8'); | |
| this._root = new flexbuffers.Reference(this, offset, parentWidth, byteWidth, type); | |
| } | |
| read() { | |
| return this._root.read(); | |
| } | |
| get length() { | |
| return this._length; | |
| } | |
| int(offset, size) { | |
| switch (size) { | |
| case 1: return this._view.getInt8(offset); | |
| case 2: return this._view.getInt16(offset, true); | |
| case 4: return this._view.getInt32(offset, true); | |
| case 8: return this._view.getBigInt64(offset, true); | |
| default: throw new flexbuffers.Error(`Invalid int size '${size}'.`); | |
| } | |
| } | |
| uint(offset, size) { | |
| switch (size) { | |
| case 1: return this._view.getUint8(offset); | |
| case 2: return this._view.getUint16(offset, true); | |
| case 4: return this._view.getUint32(offset, true); | |
| case 8: return this._view.getBigUint64(offset, true); | |
| default: throw new flexbuffers.Error(`Invalid uint size '${size}'.`); | |
| } | |
| } | |
| float(offset, size) { | |
| switch (size) { | |
| case 4: return this._view.getFloat32(offset, true); | |
| case 8: return this._view.getFloat64(offset, true); | |
| default: throw new flexbuffers.Error(`Invalid float size '${size}'.`); | |
| } | |
| } | |
| string(offset, size) { | |
| let end = size === undefined ? this._buffer.indexOf(0, offset) : offset + size; | |
| end = end === -1 ? this._buffer.length : end; | |
| const bytes = this._buffer.subarray(offset, end); | |
| return this._utf8Decoder.decode(bytes); | |
| } | |
| bytes(offset, size) { | |
| return this._buffer.slice(offset, offset + size); | |
| } | |
| }; | |
| flexbuffers.Reference = class { | |
| constructor(reader, offset, parentWidth, byteWidth, type) { | |
| this._reader = reader; | |
| this._offset = offset; | |
| this._parentWidth = parentWidth; | |
| this._byteWidth = byteWidth; | |
| this._type = type; | |
| } | |
| read() { | |
| switch (this._type) { | |
| case 0x00: // null | |
| return null; | |
| case 0x01: // int | |
| return this._reader.int(this._offset, this._parentWidth); | |
| case 0x02: // uint | |
| return this._reader.uint(this._offset, this._parentWidth); | |
| case 0x03: // float | |
| return this._reader.float(this._offset, this._parentWidth); | |
| case 0x04: { // key | |
| return this._reader.string(this._indirect()); | |
| } | |
| case 0x05: { // string | |
| const offset = this._indirect(); | |
| const size = this._reader.uint(offset - this._byteWidth, this._byteWidth); | |
| return this._reader.string(offset, size); | |
| } | |
| case 0x06: // indirect int | |
| return this._reader.int(this._indirect(), this._byteWidth); | |
| case 0x07: // indirect uint | |
| return this._reader.uint(this._indirect(), this._byteWidth); | |
| case 0x08: // indirect float | |
| return this._reader.float(this._indirect(), this._byteWidth); | |
| case 0x09: { // map | |
| const offset = this._indirect(); | |
| const keysOffset = offset - (this._byteWidth * 3); | |
| const keysVectorOffset = keysOffset - this._reader.uint(keysOffset, this._byteWidth); | |
| const keysByteWidth = this._reader.uint(keysOffset + this._byteWidth, this._byteWidth); | |
| const keys = this._typedVector(keysVectorOffset, keysByteWidth, 0x04); | |
| const values = this._vector(offset, this._byteWidth); | |
| const map = {}; | |
| for (let i = 0; i < keys.length; i++) { | |
| map[keys[i]] = values[i]; | |
| } | |
| return map; | |
| } | |
| case 0x0a: { // vector | |
| return this._vector(this._indirect(), this._byteWidth); | |
| } | |
| case 0x0b: // vector int | |
| case 0x0c: // vector uint | |
| case 0x0d: // vector float | |
| case 0x0e: // vector key | |
| case 0x0f: // vector string deprecated | |
| case 0x24: { // vector bool | |
| return this._typedVector(this._indirect(), this._byteWidth, this._type - 0x0b + 0x01); | |
| } | |
| case 0x10: // vector int2 | |
| case 0x11: // vector uint2 | |
| case 0x12: // vector float2 | |
| case 0x13: // vector int3 | |
| case 0x14: // vector uint3 | |
| case 0x15: // vector float3 | |
| case 0x16: // vector int4 | |
| case 0x17: // vector uint4 | |
| case 0x18: { // vector float4 | |
| const offset = this._indirect(); | |
| const size = (((this._type - 0x10) / 3) >> 0) + 2; | |
| const type = ((this._type - 0x10) % 3) + 0x01; | |
| return this._typedVector(offset, this._byteWidth, type, size); | |
| } | |
| case 0x19: { // blob | |
| const offset = this._indirect(); | |
| const size = this._reader.uint(offset - this._byteWidth, this._byteWidth); | |
| return this._reader.bytes(offset, size); | |
| } | |
| case 0x1a: { // bool | |
| return this._reader.uint(this._offset, this._parentWidth) !== 0; | |
| } | |
| default: { | |
| throw new flexbuffers.Error(`Unsupported reference type '${this._type}`); | |
| } | |
| } | |
| } | |
| _indirect() { | |
| return this._offset - this._reader.uint(this._offset, this._parentWidth); | |
| } | |
| _vector(offset, byteWidth) { | |
| const size = this._reader.uint(offset - byteWidth, byteWidth); | |
| const packedTypeOffset = offset + (size * byteWidth); | |
| const vector = new Array(size); | |
| for (let i = 0; i < size; i++) { | |
| const packedType = this._reader.uint(packedTypeOffset + i, 1); | |
| const reference = new flexbuffers.Reference(this._reader, offset + (i * byteWidth), byteWidth, 1 << (packedType & 3), packedType >> 2); | |
| vector[i] = reference.read(); | |
| } | |
| return vector; | |
| } | |
| _typedVector(offset, byteWidth, type, size) { | |
| size = size === undefined ? this._reader.uint(offset - byteWidth, byteWidth) : size; | |
| const vector = new Array(size); | |
| for (let i = 0; i < size; i++) { | |
| const reference = new flexbuffers.Reference(this._reader, offset + (i * byteWidth), byteWidth, 1, type); | |
| vector[i] = reference.read(); | |
| } | |
| return vector; | |
| } | |
| }; | |
| flexbuffers.Error = class extends Error { | |
| constructor(message) { | |
| super(message); | |
| this.name = 'FlexBuffers Error'; | |
| this.message = message; | |
| } | |
| }; | |
| export const BinaryReader = flexbuffers.BinaryReader; | |