123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242 |
- "use strict";
- Object.defineProperty(exports, "__esModule", { value: true });
- exports.IonDecoderBase = void 0;
- const tslib_1 = require("tslib");
- const Reader_1 = require("@jsonjoy.com/buffers/lib/Reader");
- const sharedCachedUtf8Decoder_1 = tslib_1.__importDefault(require("@jsonjoy.com/buffers/lib/utf8/sharedCachedUtf8Decoder"));
- const Import_1 = require("./Import");
- class IonDecoderBase {
- constructor(reader) {
- this.reader = (reader ?? new Reader_1.Reader());
- this.utf8Decoder = sharedCachedUtf8Decoder_1.default;
- }
- val() {
- const typedesc = this.reader.u8();
- const type = (typedesc >> 4) & 0xf;
- const length = typedesc & 0xf;
- switch (type) {
- case 0:
- return this.readNull(length);
- case 1:
- return this.readBool(length);
- case 2:
- return this.readUint(length);
- case 3:
- return this.readNint(length);
- case 4:
- return this.readFloat(length);
- case 8:
- return this.readString(length);
- case 10:
- return this.readBinary(length);
- case 11:
- return this.readList(length);
- case 13:
- return this.readStruct(length);
- case 14:
- return this.readAnnotation(length);
- default:
- throw new Error(`Unknown Ion type: 0x${type.toString(16)}`);
- }
- }
- readNull(length) {
- if (length === 15)
- return null;
- if (length === 0) {
- this.val();
- return null;
- }
- if (length === 14) {
- const padLength = this.readVUint();
- this.reader.x += padLength;
- this.val();
- return null;
- }
- this.reader.x += length;
- this.val();
- return null;
- }
- readBool(length) {
- if (length === 15)
- return null;
- if (length === 0)
- return false;
- if (length === 1)
- return true;
- throw new Error(`Invalid bool length: ${length}`);
- }
- readUint(length) {
- if (length === 15)
- return null;
- if (length === 0)
- return 0;
- let value = 0;
- for (let i = 0; i < length; i++) {
- value = value * 256 + this.reader.u8();
- }
- return value;
- }
- readNint(length) {
- if (length === 15)
- return null;
- if (length === 0)
- throw new Error('Negative zero is illegal');
- let value = 0;
- for (let i = 0; i < length; i++) {
- value = value * 256 + this.reader.u8();
- }
- return -value;
- }
- readFloat(length) {
- if (length === 15)
- return null;
- if (length === 0)
- return 0.0;
- if (length === 4)
- return this.reader.f32();
- if (length === 8)
- return this.reader.f64();
- throw new Error(`Unsupported float length: ${length}`);
- }
- readString(length) {
- if (length === 15)
- return null;
- let actualLength = length;
- if (length === 14) {
- actualLength = this.readVUint();
- }
- if (actualLength === 0)
- return '';
- return this.reader.utf8(actualLength);
- }
- readBinary(length) {
- if (length === 15)
- return null;
- let actualLength = length;
- if (length === 14) {
- actualLength = this.readVUint();
- }
- if (actualLength === 0)
- return new Uint8Array(0);
- return this.reader.buf(actualLength);
- }
- readList(length) {
- if (length === 15)
- return null;
- let actualLength = length;
- if (length === 14) {
- actualLength = this.readVUint();
- }
- if (actualLength === 0)
- return [];
- const endPos = this.reader.x + actualLength;
- const list = [];
- while (this.reader.x < endPos) {
- list.push(this.val());
- }
- if (this.reader.x !== endPos) {
- throw new Error('List parsing error: incorrect length');
- }
- return list;
- }
- readStruct(length) {
- if (length === 15)
- return null;
- let actualLength = length;
- if (length === 14) {
- actualLength = this.readVUint();
- }
- if (actualLength === 0)
- return {};
- const endPos = this.reader.x + actualLength;
- const struct = {};
- while (this.reader.x < endPos) {
- const fieldNameId = this.readVUint();
- const fieldName = this.getSymbolText(fieldNameId);
- const fieldValue = this.val();
- struct[fieldName] = fieldValue;
- }
- if (this.reader.x !== endPos) {
- throw new Error('Struct parsing error: incorrect length');
- }
- return struct;
- }
- readAnnotation(length) {
- if (length < 3) {
- throw new Error('Annotation wrapper must have at least 3 bytes');
- }
- let actualLength = length;
- if (length === 14) {
- actualLength = this.readVUint();
- }
- const annotLength = this.readVUint();
- const endAnnotPos = this.reader.x + annotLength;
- while (this.reader.x < endAnnotPos) {
- this.readVUint();
- }
- if (this.reader.x !== endAnnotPos) {
- throw new Error('Annotation parsing error: incorrect annotation length');
- }
- return this.val();
- }
- readVUint() {
- let value = 0;
- let byte;
- do {
- byte = this.reader.u8();
- value = (value << 7) | (byte & 0x7f);
- } while ((byte & 0x80) === 0);
- return value;
- }
- readVInt() {
- const firstByte = this.reader.u8();
- if (firstByte & 0x80) {
- const sign = firstByte & 0x40 ? -1 : 1;
- const magnitude = firstByte & 0x3f;
- return sign * magnitude;
- }
- const sign = firstByte & 0x40 ? -1 : 1;
- let magnitude = firstByte & 0x3f;
- let byte;
- do {
- byte = this.reader.u8();
- magnitude = (magnitude << 7) | (byte & 0x7f);
- } while ((byte & 0x80) === 0);
- return sign * magnitude;
- }
- getSymbolText(symbolId) {
- if (!this.symbols) {
- throw new Error('No symbol table available');
- }
- const symbol = this.symbols.getText(symbolId);
- if (symbol === undefined) {
- throw new Error(`Unknown symbol ID: ${symbolId}`);
- }
- return symbol;
- }
- validateBVM() {
- const bvm = this.reader.u32();
- if (bvm !== 0xe00100ea) {
- throw new Error(`Invalid Ion Binary Version Marker: 0x${bvm.toString(16)}`);
- }
- }
- readSymbolTable() {
- if (this.reader.x < this.reader.uint8.length) {
- const nextByte = this.reader.peak();
- const type = (nextByte >> 4) & 0xf;
- if (type === 14) {
- const annotValue = this.val();
- if (annotValue && typeof annotValue === 'object' && !Array.isArray(annotValue)) {
- const symbolsKey = 'symbols';
- const obj = annotValue;
- if (symbolsKey in obj && Array.isArray(obj[symbolsKey])) {
- const newSymbols = obj[symbolsKey];
- this.symbols = new Import_1.Import(this.symbols || null, newSymbols);
- }
- }
- }
- }
- }
- }
- exports.IonDecoderBase = IonDecoderBase;
- //# sourceMappingURL=IonDecoderBase.js.map
|