1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210 |
- (function (global, factory) {
- typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
- typeof define === 'function' && define.amd ? define(['exports'], factory) :
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.msgpackr = {}));
- })(this, (function (exports) { 'use strict';
- var decoder;
- try {
- decoder = new TextDecoder();
- } catch(error) {}
- var src;
- var srcEnd;
- var position = 0;
- const EMPTY_ARRAY = [];
- var strings = EMPTY_ARRAY;
- var stringPosition = 0;
- var currentUnpackr = {};
- var currentStructures;
- var srcString;
- var srcStringStart = 0;
- var srcStringEnd = 0;
- var bundledStrings;
- var referenceMap;
- var currentExtensions = [];
- var dataView;
- var defaultOptions = {
- useRecords: false,
- mapsAsObjects: true
- };
- class C1Type {}
- const C1 = new C1Type();
- C1.name = 'MessagePack 0xC1';
- var sequentialMode = false;
- var inlineObjectReadThreshold = 2;
- var readStruct, onLoadedStructures, onSaveState;
- var BlockedFunction; // we use search and replace to change the next call to BlockedFunction to avoid CSP issues for
- // no-eval build
- try {
- new BlockedFunction ('');
- } catch(error) {
- // if eval variants are not supported, do not create inline object readers ever
- inlineObjectReadThreshold = Infinity;
- }
- class Unpackr {
- constructor(options) {
- if (options) {
- if (options.useRecords === false && options.mapsAsObjects === undefined)
- options.mapsAsObjects = true;
- if (options.sequential && options.trusted !== false) {
- options.trusted = true;
- if (!options.structures && options.useRecords != false) {
- options.structures = [];
- if (!options.maxSharedStructures)
- options.maxSharedStructures = 0;
- }
- }
- if (options.structures)
- options.structures.sharedLength = options.structures.length;
- else if (options.getStructures) {
- (options.structures = []).uninitialized = true; // this is what we use to denote an uninitialized structures
- options.structures.sharedLength = 0;
- }
- if (options.int64AsNumber) {
- options.int64AsType = 'number';
- }
- }
- Object.assign(this, options);
- }
- unpack(source, options) {
- if (src) {
- // re-entrant execution, save the state and restore it after we do this unpack
- return saveState(() => {
- clearSource();
- return this ? this.unpack(source, options) : Unpackr.prototype.unpack.call(defaultOptions, source, options)
- })
- }
- if (!source.buffer && source.constructor === ArrayBuffer)
- source = typeof Buffer !== 'undefined' ? Buffer.from(source) : new Uint8Array(source);
- if (typeof options === 'object') {
- srcEnd = options.end || source.length;
- position = options.start || 0;
- } else {
- position = 0;
- srcEnd = options > -1 ? options : source.length;
- }
- stringPosition = 0;
- srcStringEnd = 0;
- srcString = null;
- strings = EMPTY_ARRAY;
- bundledStrings = null;
- src = source;
- // this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
- // technique for getting data from a database where it can be copied into an existing buffer instead of creating
- // new ones
- try {
- dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength));
- } catch(error) {
- // if it doesn't have a buffer, maybe it is the wrong type of object
- src = null;
- if (source instanceof Uint8Array)
- throw error
- throw new Error('Source must be a Uint8Array or Buffer but was a ' + ((source && typeof source == 'object') ? source.constructor.name : typeof source))
- }
- if (this instanceof Unpackr) {
- currentUnpackr = this;
- if (this.structures) {
- currentStructures = this.structures;
- return checkedRead(options)
- } else if (!currentStructures || currentStructures.length > 0) {
- currentStructures = [];
- }
- } else {
- currentUnpackr = defaultOptions;
- if (!currentStructures || currentStructures.length > 0)
- currentStructures = [];
- }
- return checkedRead(options)
- }
- unpackMultiple(source, forEach) {
- let values, lastPosition = 0;
- try {
- sequentialMode = true;
- let size = source.length;
- let value = this ? this.unpack(source, size) : defaultUnpackr.unpack(source, size);
- if (forEach) {
- if (forEach(value, lastPosition, position) === false) return;
- while(position < size) {
- lastPosition = position;
- if (forEach(checkedRead(), lastPosition, position) === false) {
- return
- }
- }
- }
- else {
- values = [ value ];
- while(position < size) {
- lastPosition = position;
- values.push(checkedRead());
- }
- return values
- }
- } catch(error) {
- error.lastPosition = lastPosition;
- error.values = values;
- throw error
- } finally {
- sequentialMode = false;
- clearSource();
- }
- }
- _mergeStructures(loadedStructures, existingStructures) {
- if (onLoadedStructures)
- loadedStructures = onLoadedStructures.call(this, loadedStructures);
- loadedStructures = loadedStructures || [];
- if (Object.isFrozen(loadedStructures))
- loadedStructures = loadedStructures.map(structure => structure.slice(0));
- for (let i = 0, l = loadedStructures.length; i < l; i++) {
- let structure = loadedStructures[i];
- if (structure) {
- structure.isShared = true;
- if (i >= 32)
- structure.highByte = (i - 32) >> 5;
- }
- }
- loadedStructures.sharedLength = loadedStructures.length;
- for (let id in existingStructures || []) {
- if (id >= 0) {
- let structure = loadedStructures[id];
- let existing = existingStructures[id];
- if (existing) {
- if (structure)
- (loadedStructures.restoreStructures || (loadedStructures.restoreStructures = []))[id] = structure;
- loadedStructures[id] = existing;
- }
- }
- }
- return this.structures = loadedStructures
- }
- decode(source, options) {
- return this.unpack(source, options)
- }
- }
- function getPosition() {
- return position
- }
- function checkedRead(options) {
- try {
- if (!currentUnpackr.trusted && !sequentialMode) {
- let sharedLength = currentStructures.sharedLength || 0;
- if (sharedLength < currentStructures.length)
- currentStructures.length = sharedLength;
- }
- let result;
- if (currentUnpackr.randomAccessStructure && src[position] < 0x40 && src[position] >= 0x20 && readStruct) {
- result = readStruct(src, position, srcEnd, currentUnpackr);
- src = null; // dispose of this so that recursive unpack calls don't save state
- if (!(options && options.lazy) && result)
- result = result.toJSON();
- position = srcEnd;
- } else
- result = read();
- if (bundledStrings) { // bundled strings to skip past
- position = bundledStrings.postBundlePosition;
- bundledStrings = null;
- }
- if (sequentialMode)
- // we only need to restore the structures if there was an error, but if we completed a read,
- // we can clear this out and keep the structures we read
- currentStructures.restoreStructures = null;
- if (position == srcEnd) {
- // finished reading this source, cleanup references
- if (currentStructures && currentStructures.restoreStructures)
- restoreStructures();
- currentStructures = null;
- src = null;
- if (referenceMap)
- referenceMap = null;
- } else if (position > srcEnd) {
- // over read
- throw new Error('Unexpected end of MessagePack data')
- } else if (!sequentialMode) {
- let jsonView;
- try {
- jsonView = JSON.stringify(result, (_, value) => typeof value === "bigint" ? `${value}n` : value).slice(0, 100);
- } catch(error) {
- jsonView = '(JSON view not available ' + error + ')';
- }
- throw new Error('Data read, but end of buffer not reached ' + jsonView)
- }
- // else more to read, but we are reading sequentially, so don't clear source yet
- return result
- } catch(error) {
- if (currentStructures && currentStructures.restoreStructures)
- restoreStructures();
- clearSource();
- if (error instanceof RangeError || error.message.startsWith('Unexpected end of buffer') || position > srcEnd) {
- error.incomplete = true;
- }
- throw error
- }
- }
- function restoreStructures() {
- for (let id in currentStructures.restoreStructures) {
- currentStructures[id] = currentStructures.restoreStructures[id];
- }
- currentStructures.restoreStructures = null;
- }
- function read() {
- let token = src[position++];
- if (token < 0xa0) {
- if (token < 0x80) {
- if (token < 0x40)
- return token
- else {
- let structure = currentStructures[token & 0x3f] ||
- currentUnpackr.getStructures && loadStructures()[token & 0x3f];
- if (structure) {
- if (!structure.read) {
- structure.read = createStructureReader(structure, token & 0x3f);
- }
- return structure.read()
- } else
- return token
- }
- } else if (token < 0x90) {
- // map
- token -= 0x80;
- if (currentUnpackr.mapsAsObjects) {
- let object = {};
- for (let i = 0; i < token; i++) {
- let key = readKey();
- if (key === '__proto__')
- key = '__proto_';
- object[key] = read();
- }
- return object
- } else {
- let map = new Map();
- for (let i = 0; i < token; i++) {
- map.set(read(), read());
- }
- return map
- }
- } else {
- token -= 0x90;
- let array = new Array(token);
- for (let i = 0; i < token; i++) {
- array[i] = read();
- }
- if (currentUnpackr.freezeData)
- return Object.freeze(array)
- return array
- }
- } else if (token < 0xc0) {
- // fixstr
- let length = token - 0xa0;
- if (srcStringEnd >= position) {
- return srcString.slice(position - srcStringStart, (position += length) - srcStringStart)
- }
- if (srcStringEnd == 0 && srcEnd < 140) {
- // for small blocks, avoiding the overhead of the extract call is helpful
- let string = length < 16 ? shortStringInJS(length) : longStringInJS(length);
- if (string != null)
- return string
- }
- return readFixedString(length)
- } else {
- let value;
- switch (token) {
- case 0xc0: return null
- case 0xc1:
- if (bundledStrings) {
- value = read(); // followed by the length of the string in characters (not bytes!)
- if (value > 0)
- return bundledStrings[1].slice(bundledStrings.position1, bundledStrings.position1 += value)
- else
- return bundledStrings[0].slice(bundledStrings.position0, bundledStrings.position0 -= value)
- }
- return C1; // "never-used", return special object to denote that
- case 0xc2: return false
- case 0xc3: return true
- case 0xc4:
- // bin 8
- value = src[position++];
- if (value === undefined)
- throw new Error('Unexpected end of buffer')
- return readBin(value)
- case 0xc5:
- // bin 16
- value = dataView.getUint16(position);
- position += 2;
- return readBin(value)
- case 0xc6:
- // bin 32
- value = dataView.getUint32(position);
- position += 4;
- return readBin(value)
- case 0xc7:
- // ext 8
- return readExt(src[position++])
- case 0xc8:
- // ext 16
- value = dataView.getUint16(position);
- position += 2;
- return readExt(value)
- case 0xc9:
- // ext 32
- value = dataView.getUint32(position);
- position += 4;
- return readExt(value)
- case 0xca:
- value = dataView.getFloat32(position);
- if (currentUnpackr.useFloat32 > 2) {
- // this does rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
- let multiplier = mult10[((src[position] & 0x7f) << 1) | (src[position + 1] >> 7)];
- position += 4;
- return ((multiplier * value + (value > 0 ? 0.5 : -0.5)) >> 0) / multiplier
- }
- position += 4;
- return value
- case 0xcb:
- value = dataView.getFloat64(position);
- position += 8;
- return value
- // uint handlers
- case 0xcc:
- return src[position++]
- case 0xcd:
- value = dataView.getUint16(position);
- position += 2;
- return value
- case 0xce:
- value = dataView.getUint32(position);
- position += 4;
- return value
- case 0xcf:
- if (currentUnpackr.int64AsType === 'number') {
- value = dataView.getUint32(position) * 0x100000000;
- value += dataView.getUint32(position + 4);
- } else if (currentUnpackr.int64AsType === 'string') {
- value = dataView.getBigUint64(position).toString();
- } else if (currentUnpackr.int64AsType === 'auto') {
- value = dataView.getBigUint64(position);
- if (value<=BigInt(2)<<BigInt(52)) value=Number(value);
- } else
- value = dataView.getBigUint64(position);
- position += 8;
- return value
- // int handlers
- case 0xd0:
- return dataView.getInt8(position++)
- case 0xd1:
- value = dataView.getInt16(position);
- position += 2;
- return value
- case 0xd2:
- value = dataView.getInt32(position);
- position += 4;
- return value
- case 0xd3:
- if (currentUnpackr.int64AsType === 'number') {
- value = dataView.getInt32(position) * 0x100000000;
- value += dataView.getUint32(position + 4);
- } else if (currentUnpackr.int64AsType === 'string') {
- value = dataView.getBigInt64(position).toString();
- } else if (currentUnpackr.int64AsType === 'auto') {
- value = dataView.getBigInt64(position);
- if (value>=BigInt(-2)<<BigInt(52)&&value<=BigInt(2)<<BigInt(52)) value=Number(value);
- } else
- value = dataView.getBigInt64(position);
- position += 8;
- return value
- case 0xd4:
- // fixext 1
- value = src[position++];
- if (value == 0x72) {
- return recordDefinition(src[position++] & 0x3f)
- } else {
- let extension = currentExtensions[value];
- if (extension) {
- if (extension.read) {
- position++; // skip filler byte
- return extension.read(read())
- } else if (extension.noBuffer) {
- position++; // skip filler byte
- return extension()
- } else
- return extension(src.subarray(position, ++position))
- } else
- throw new Error('Unknown extension ' + value)
- }
- case 0xd5:
- // fixext 2
- value = src[position];
- if (value == 0x72) {
- position++;
- return recordDefinition(src[position++] & 0x3f, src[position++])
- } else
- return readExt(2)
- case 0xd6:
- // fixext 4
- return readExt(4)
- case 0xd7:
- // fixext 8
- return readExt(8)
- case 0xd8:
- // fixext 16
- return readExt(16)
- case 0xd9:
- // str 8
- value = src[position++];
- if (srcStringEnd >= position) {
- return srcString.slice(position - srcStringStart, (position += value) - srcStringStart)
- }
- return readString8(value)
- case 0xda:
- // str 16
- value = dataView.getUint16(position);
- position += 2;
- if (srcStringEnd >= position) {
- return srcString.slice(position - srcStringStart, (position += value) - srcStringStart)
- }
- return readString16(value)
- case 0xdb:
- // str 32
- value = dataView.getUint32(position);
- position += 4;
- if (srcStringEnd >= position) {
- return srcString.slice(position - srcStringStart, (position += value) - srcStringStart)
- }
- return readString32(value)
- case 0xdc:
- // array 16
- value = dataView.getUint16(position);
- position += 2;
- return readArray(value)
- case 0xdd:
- // array 32
- value = dataView.getUint32(position);
- position += 4;
- return readArray(value)
- case 0xde:
- // map 16
- value = dataView.getUint16(position);
- position += 2;
- return readMap(value)
- case 0xdf:
- // map 32
- value = dataView.getUint32(position);
- position += 4;
- return readMap(value)
- default: // negative int
- if (token >= 0xe0)
- return token - 0x100
- if (token === undefined) {
- let error = new Error('Unexpected end of MessagePack data');
- error.incomplete = true;
- throw error
- }
- throw new Error('Unknown MessagePack token ' + token)
- }
- }
- }
- const validName = /^[a-zA-Z_$][a-zA-Z\d_$]*$/;
- function createStructureReader(structure, firstId) {
- function readObject() {
- // This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
- if (readObject.count++ > inlineObjectReadThreshold) {
- let readObject = structure.read = (new BlockedFunction ('r', 'return function(){return ' + (currentUnpackr.freezeData ? 'Object.freeze' : '') +
- '({' + structure.map(key => key === '__proto__' ? '__proto_:r()' : validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '})}'))(read);
- if (structure.highByte === 0)
- structure.read = createSecondByteReader(firstId, structure.read);
- return readObject() // second byte is already read, if there is one so immediately read object
- }
- let object = {};
- for (let i = 0, l = structure.length; i < l; i++) {
- let key = structure[i];
- if (key === '__proto__')
- key = '__proto_';
- object[key] = read();
- }
- if (currentUnpackr.freezeData)
- return Object.freeze(object);
- return object
- }
- readObject.count = 0;
- if (structure.highByte === 0) {
- return createSecondByteReader(firstId, readObject)
- }
- return readObject
- }
- const createSecondByteReader = (firstId, read0) => {
- return function() {
- let highByte = src[position++];
- if (highByte === 0)
- return read0()
- let id = firstId < 32 ? -(firstId + (highByte << 5)) : firstId + (highByte << 5);
- let structure = currentStructures[id] || loadStructures()[id];
- if (!structure) {
- throw new Error('Record id is not defined for ' + id)
- }
- if (!structure.read)
- structure.read = createStructureReader(structure, firstId);
- return structure.read()
- }
- };
- function loadStructures() {
- let loadedStructures = saveState(() => {
- // save the state in case getStructures modifies our buffer
- src = null;
- return currentUnpackr.getStructures()
- });
- return currentStructures = currentUnpackr._mergeStructures(loadedStructures, currentStructures)
- }
- var readFixedString = readStringJS;
- var readString8 = readStringJS;
- var readString16 = readStringJS;
- var readString32 = readStringJS;
- exports.isNativeAccelerationEnabled = false;
- function setExtractor(extractStrings) {
- exports.isNativeAccelerationEnabled = true;
- readFixedString = readString(1);
- readString8 = readString(2);
- readString16 = readString(3);
- readString32 = readString(5);
- function readString(headerLength) {
- return function readString(length) {
- let string = strings[stringPosition++];
- if (string == null) {
- if (bundledStrings)
- return readStringJS(length)
- let byteOffset = src.byteOffset;
- let extraction = extractStrings(position - headerLength + byteOffset, srcEnd + byteOffset, src.buffer);
- if (typeof extraction == 'string') {
- string = extraction;
- strings = EMPTY_ARRAY;
- } else {
- strings = extraction;
- stringPosition = 1;
- srcStringEnd = 1; // even if a utf-8 string was decoded, must indicate we are in the midst of extracted strings and can't skip strings
- string = strings[0];
- if (string === undefined)
- throw new Error('Unexpected end of buffer')
- }
- }
- let srcStringLength = string.length;
- if (srcStringLength <= length) {
- position += length;
- return string
- }
- srcString = string;
- srcStringStart = position;
- srcStringEnd = position + srcStringLength;
- position += length;
- return string.slice(0, length) // we know we just want the beginning
- }
- }
- }
- function readStringJS(length) {
- let result;
- if (length < 16) {
- if (result = shortStringInJS(length))
- return result
- }
- if (length > 64 && decoder)
- return decoder.decode(src.subarray(position, position += length))
- const end = position + length;
- const units = [];
- result = '';
- while (position < end) {
- const byte1 = src[position++];
- if ((byte1 & 0x80) === 0) {
- // 1 byte
- units.push(byte1);
- } else if ((byte1 & 0xe0) === 0xc0) {
- // 2 bytes
- const byte2 = src[position++] & 0x3f;
- units.push(((byte1 & 0x1f) << 6) | byte2);
- } else if ((byte1 & 0xf0) === 0xe0) {
- // 3 bytes
- const byte2 = src[position++] & 0x3f;
- const byte3 = src[position++] & 0x3f;
- units.push(((byte1 & 0x1f) << 12) | (byte2 << 6) | byte3);
- } else if ((byte1 & 0xf8) === 0xf0) {
- // 4 bytes
- const byte2 = src[position++] & 0x3f;
- const byte3 = src[position++] & 0x3f;
- const byte4 = src[position++] & 0x3f;
- let unit = ((byte1 & 0x07) << 0x12) | (byte2 << 0x0c) | (byte3 << 0x06) | byte4;
- if (unit > 0xffff) {
- unit -= 0x10000;
- units.push(((unit >>> 10) & 0x3ff) | 0xd800);
- unit = 0xdc00 | (unit & 0x3ff);
- }
- units.push(unit);
- } else {
- units.push(byte1);
- }
- if (units.length >= 0x1000) {
- result += fromCharCode.apply(String, units);
- units.length = 0;
- }
- }
- if (units.length > 0) {
- result += fromCharCode.apply(String, units);
- }
- return result
- }
- function readString(source, start, length) {
- let existingSrc = src;
- src = source;
- position = start;
- try {
- return readStringJS(length);
- } finally {
- src = existingSrc;
- }
- }
- function readArray(length) {
- let array = new Array(length);
- for (let i = 0; i < length; i++) {
- array[i] = read();
- }
- if (currentUnpackr.freezeData)
- return Object.freeze(array)
- return array
- }
- function readMap(length) {
- if (currentUnpackr.mapsAsObjects) {
- let object = {};
- for (let i = 0; i < length; i++) {
- let key = readKey();
- if (key === '__proto__')
- key = '__proto_';
- object[key] = read();
- }
- return object
- } else {
- let map = new Map();
- for (let i = 0; i < length; i++) {
- map.set(read(), read());
- }
- return map
- }
- }
- var fromCharCode = String.fromCharCode;
- function longStringInJS(length) {
- let start = position;
- let bytes = new Array(length);
- for (let i = 0; i < length; i++) {
- const byte = src[position++];
- if ((byte & 0x80) > 0) {
- position = start;
- return
- }
- bytes[i] = byte;
- }
- return fromCharCode.apply(String, bytes)
- }
- function shortStringInJS(length) {
- if (length < 4) {
- if (length < 2) {
- if (length === 0)
- return ''
- else {
- let a = src[position++];
- if ((a & 0x80) > 1) {
- position -= 1;
- return
- }
- return fromCharCode(a)
- }
- } else {
- let a = src[position++];
- let b = src[position++];
- if ((a & 0x80) > 0 || (b & 0x80) > 0) {
- position -= 2;
- return
- }
- if (length < 3)
- return fromCharCode(a, b)
- let c = src[position++];
- if ((c & 0x80) > 0) {
- position -= 3;
- return
- }
- return fromCharCode(a, b, c)
- }
- } else {
- let a = src[position++];
- let b = src[position++];
- let c = src[position++];
- let d = src[position++];
- if ((a & 0x80) > 0 || (b & 0x80) > 0 || (c & 0x80) > 0 || (d & 0x80) > 0) {
- position -= 4;
- return
- }
- if (length < 6) {
- if (length === 4)
- return fromCharCode(a, b, c, d)
- else {
- let e = src[position++];
- if ((e & 0x80) > 0) {
- position -= 5;
- return
- }
- return fromCharCode(a, b, c, d, e)
- }
- } else if (length < 8) {
- let e = src[position++];
- let f = src[position++];
- if ((e & 0x80) > 0 || (f & 0x80) > 0) {
- position -= 6;
- return
- }
- if (length < 7)
- return fromCharCode(a, b, c, d, e, f)
- let g = src[position++];
- if ((g & 0x80) > 0) {
- position -= 7;
- return
- }
- return fromCharCode(a, b, c, d, e, f, g)
- } else {
- let e = src[position++];
- let f = src[position++];
- let g = src[position++];
- let h = src[position++];
- if ((e & 0x80) > 0 || (f & 0x80) > 0 || (g & 0x80) > 0 || (h & 0x80) > 0) {
- position -= 8;
- return
- }
- if (length < 10) {
- if (length === 8)
- return fromCharCode(a, b, c, d, e, f, g, h)
- else {
- let i = src[position++];
- if ((i & 0x80) > 0) {
- position -= 9;
- return
- }
- return fromCharCode(a, b, c, d, e, f, g, h, i)
- }
- } else if (length < 12) {
- let i = src[position++];
- let j = src[position++];
- if ((i & 0x80) > 0 || (j & 0x80) > 0) {
- position -= 10;
- return
- }
- if (length < 11)
- return fromCharCode(a, b, c, d, e, f, g, h, i, j)
- let k = src[position++];
- if ((k & 0x80) > 0) {
- position -= 11;
- return
- }
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k)
- } else {
- let i = src[position++];
- let j = src[position++];
- let k = src[position++];
- let l = src[position++];
- if ((i & 0x80) > 0 || (j & 0x80) > 0 || (k & 0x80) > 0 || (l & 0x80) > 0) {
- position -= 12;
- return
- }
- if (length < 14) {
- if (length === 12)
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l)
- else {
- let m = src[position++];
- if ((m & 0x80) > 0) {
- position -= 13;
- return
- }
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m)
- }
- } else {
- let m = src[position++];
- let n = src[position++];
- if ((m & 0x80) > 0 || (n & 0x80) > 0) {
- position -= 14;
- return
- }
- if (length < 15)
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n)
- let o = src[position++];
- if ((o & 0x80) > 0) {
- position -= 15;
- return
- }
- return fromCharCode(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o)
- }
- }
- }
- }
- }
- function readOnlyJSString() {
- let token = src[position++];
- let length;
- if (token < 0xc0) {
- // fixstr
- length = token - 0xa0;
- } else {
- switch(token) {
- case 0xd9:
- // str 8
- length = src[position++];
- break
- case 0xda:
- // str 16
- length = dataView.getUint16(position);
- position += 2;
- break
- case 0xdb:
- // str 32
- length = dataView.getUint32(position);
- position += 4;
- break
- default:
- throw new Error('Expected string')
- }
- }
- return readStringJS(length)
- }
- function readBin(length) {
- return currentUnpackr.copyBuffers ?
- // specifically use the copying slice (not the node one)
- Uint8Array.prototype.slice.call(src, position, position += length) :
- src.subarray(position, position += length)
- }
- function readExt(length) {
- let type = src[position++];
- if (currentExtensions[type]) {
- let end;
- return currentExtensions[type](src.subarray(position, end = (position += length)), (readPosition) => {
- position = readPosition;
- try {
- return read();
- } finally {
- position = end;
- }
- })
- }
- else
- throw new Error('Unknown extension type ' + type)
- }
- var keyCache = new Array(4096);
- function readKey() {
- let length = src[position++];
- if (length >= 0xa0 && length < 0xc0) {
- // fixstr, potentially use key cache
- length = length - 0xa0;
- if (srcStringEnd >= position) // if it has been extracted, must use it (and faster anyway)
- return srcString.slice(position - srcStringStart, (position += length) - srcStringStart)
- else if (!(srcStringEnd == 0 && srcEnd < 180))
- return readFixedString(length)
- } else { // not cacheable, go back and do a standard read
- position--;
- return asSafeString(read())
- }
- let key = ((length << 5) ^ (length > 1 ? dataView.getUint16(position) : length > 0 ? src[position] : 0)) & 0xfff;
- let entry = keyCache[key];
- let checkPosition = position;
- let end = position + length - 3;
- let chunk;
- let i = 0;
- if (entry && entry.bytes == length) {
- while (checkPosition < end) {
- chunk = dataView.getUint32(checkPosition);
- if (chunk != entry[i++]) {
- checkPosition = 0x70000000;
- break
- }
- checkPosition += 4;
- }
- end += 3;
- while (checkPosition < end) {
- chunk = src[checkPosition++];
- if (chunk != entry[i++]) {
- checkPosition = 0x70000000;
- break
- }
- }
- if (checkPosition === end) {
- position = checkPosition;
- return entry.string
- }
- end -= 3;
- checkPosition = position;
- }
- entry = [];
- keyCache[key] = entry;
- entry.bytes = length;
- while (checkPosition < end) {
- chunk = dataView.getUint32(checkPosition);
- entry.push(chunk);
- checkPosition += 4;
- }
- end += 3;
- while (checkPosition < end) {
- chunk = src[checkPosition++];
- entry.push(chunk);
- }
- // for small blocks, avoiding the overhead of the extract call is helpful
- let string = length < 16 ? shortStringInJS(length) : longStringInJS(length);
- if (string != null)
- return entry.string = string
- return entry.string = readFixedString(length)
- }
- function asSafeString(property) {
- // protect against expensive (DoS) string conversions
- if (typeof property === 'string') return property;
- if (typeof property === 'number' || typeof property === 'boolean' || typeof property === 'bigint') return property.toString();
- if (property == null) return property + '';
- throw new Error('Invalid property type for record', typeof property);
- }
- // the registration of the record definition extension (as "r")
- const recordDefinition = (id, highByte) => {
- let structure = read().map(asSafeString); // ensure that all keys are strings and
- // that the array is mutable
- let firstByte = id;
- if (highByte !== undefined) {
- id = id < 32 ? -((highByte << 5) + id) : ((highByte << 5) + id);
- structure.highByte = highByte;
- }
- let existingStructure = currentStructures[id];
- // If it is a shared structure, we need to restore any changes after reading.
- // Also in sequential mode, we may get incomplete reads and thus errors, and we need to restore
- // to the state prior to an incomplete read in order to properly resume.
- if (existingStructure && (existingStructure.isShared || sequentialMode)) {
- (currentStructures.restoreStructures || (currentStructures.restoreStructures = []))[id] = existingStructure;
- }
- currentStructures[id] = structure;
- structure.read = createStructureReader(structure, firstByte);
- return structure.read()
- };
- currentExtensions[0] = () => {}; // notepack defines extension 0 to mean undefined, so use that as the default here
- currentExtensions[0].noBuffer = true;
- currentExtensions[0x42] = (data) => {
- // decode bigint
- let length = data.length;
- let value = BigInt(data[0] & 0x80 ? data[0] - 0x100 : data[0]);
- for (let i = 1; i < length; i++) {
- value <<= BigInt(8);
- value += BigInt(data[i]);
- }
- return value;
- };
- let errors = { Error, TypeError, ReferenceError };
- currentExtensions[0x65] = () => {
- let data = read();
- return (errors[data[0]] || Error)(data[1], { cause: data[2] })
- };
- currentExtensions[0x69] = (data) => {
- // id extension (for structured clones)
- if (currentUnpackr.structuredClone === false) throw new Error('Structured clone extension is disabled')
- let id = dataView.getUint32(position - 4);
- if (!referenceMap)
- referenceMap = new Map();
- let token = src[position];
- let target;
- // TODO: handle Maps, Sets, and other types that can cycle; this is complicated, because you potentially need to read
- // ahead past references to record structure definitions
- if (token >= 0x90 && token < 0xa0 || token == 0xdc || token == 0xdd)
- target = [];
- else
- target = {};
- let refEntry = { target }; // a placeholder object
- referenceMap.set(id, refEntry);
- let targetProperties = read(); // read the next value as the target object to id
- if (refEntry.used) // there is a cycle, so we have to assign properties to original target
- return Object.assign(target, targetProperties)
- refEntry.target = targetProperties; // the placeholder wasn't used, replace with the deserialized one
- return targetProperties // no cycle, can just use the returned read object
- };
- currentExtensions[0x70] = (data) => {
- // pointer extension (for structured clones)
- if (currentUnpackr.structuredClone === false) throw new Error('Structured clone extension is disabled')
- let id = dataView.getUint32(position - 4);
- let refEntry = referenceMap.get(id);
- refEntry.used = true;
- return refEntry.target
- };
- currentExtensions[0x73] = () => new Set(read());
- const typedArrays = ['Int8','Uint8','Uint8Clamped','Int16','Uint16','Int32','Uint32','Float32','Float64','BigInt64','BigUint64'].map(type => type + 'Array');
- let glbl = typeof globalThis === 'object' ? globalThis : window;
- currentExtensions[0x74] = (data) => {
- let typeCode = data[0];
- let typedArrayName = typedArrays[typeCode];
- if (!typedArrayName) {
- if (typeCode === 16) {
- let ab = new ArrayBuffer(data.length - 1);
- let u8 = new Uint8Array(ab);
- u8.set(data.subarray(1));
- return ab;
- }
- throw new Error('Could not find typed array for code ' + typeCode)
- }
- // we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
- return new glbl[typedArrayName](Uint8Array.prototype.slice.call(data, 1).buffer)
- };
- currentExtensions[0x78] = () => {
- let data = read();
- return new RegExp(data[0], data[1])
- };
- const TEMP_BUNDLE = [];
- currentExtensions[0x62] = (data) => {
- let dataSize = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
- let dataPosition = position;
- position += dataSize - data.length;
- bundledStrings = TEMP_BUNDLE;
- bundledStrings = [readOnlyJSString(), readOnlyJSString()];
- bundledStrings.position0 = 0;
- bundledStrings.position1 = 0;
- bundledStrings.postBundlePosition = position;
- position = dataPosition;
- return read()
- };
- currentExtensions[0xff] = (data) => {
- // 32-bit date extension
- if (data.length == 4)
- return new Date((data[0] * 0x1000000 + (data[1] << 16) + (data[2] << 8) + data[3]) * 1000)
- else if (data.length == 8)
- return new Date(
- ((data[0] << 22) + (data[1] << 14) + (data[2] << 6) + (data[3] >> 2)) / 1000000 +
- ((data[3] & 0x3) * 0x100000000 + data[4] * 0x1000000 + (data[5] << 16) + (data[6] << 8) + data[7]) * 1000)
- else if (data.length == 12)// TODO: Implement support for negative
- return new Date(
- ((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +
- (((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)
- else
- return new Date('invalid')
- }; // notepack defines extension 0 to mean undefined, so use that as the default here
- // registration of bulk record definition?
- // currentExtensions[0x52] = () =>
- function saveState(callback) {
- if (onSaveState)
- onSaveState();
- let savedSrcEnd = srcEnd;
- let savedPosition = position;
- let savedStringPosition = stringPosition;
- let savedSrcStringStart = srcStringStart;
- let savedSrcStringEnd = srcStringEnd;
- let savedSrcString = srcString;
- let savedStrings = strings;
- let savedReferenceMap = referenceMap;
- let savedBundledStrings = bundledStrings;
- // TODO: We may need to revisit this if we do more external calls to user code (since it could be slow)
- let savedSrc = new Uint8Array(src.slice(0, srcEnd)); // we copy the data in case it changes while external data is processed
- let savedStructures = currentStructures;
- let savedStructuresContents = currentStructures.slice(0, currentStructures.length);
- let savedPackr = currentUnpackr;
- let savedSequentialMode = sequentialMode;
- let value = callback();
- srcEnd = savedSrcEnd;
- position = savedPosition;
- stringPosition = savedStringPosition;
- srcStringStart = savedSrcStringStart;
- srcStringEnd = savedSrcStringEnd;
- srcString = savedSrcString;
- strings = savedStrings;
- referenceMap = savedReferenceMap;
- bundledStrings = savedBundledStrings;
- src = savedSrc;
- sequentialMode = savedSequentialMode;
- currentStructures = savedStructures;
- currentStructures.splice(0, currentStructures.length, ...savedStructuresContents);
- currentUnpackr = savedPackr;
- dataView = new DataView(src.buffer, src.byteOffset, src.byteLength);
- return value
- }
- function clearSource() {
- src = null;
- referenceMap = null;
- currentStructures = null;
- }
- function addExtension(extension) {
- if (extension.unpack)
- currentExtensions[extension.type] = extension.unpack;
- else
- currentExtensions[extension.type] = extension;
- }
- const mult10 = new Array(147); // this is a table matching binary exponents to the multiplier to determine significant digit rounding
- for (let i = 0; i < 256; i++) {
- mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103));
- }
- const Decoder = Unpackr;
- var defaultUnpackr = new Unpackr({ useRecords: false });
- const unpack = defaultUnpackr.unpack;
- const unpackMultiple = defaultUnpackr.unpackMultiple;
- const decode = defaultUnpackr.unpack;
- const FLOAT32_OPTIONS = {
- NEVER: 0,
- ALWAYS: 1,
- DECIMAL_ROUND: 3,
- DECIMAL_FIT: 4
- };
- let f32Array = new Float32Array(1);
- let u8Array = new Uint8Array(f32Array.buffer, 0, 4);
- function roundFloat32(float32Number) {
- f32Array[0] = float32Number;
- let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)];
- return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
- }
- function setReadStruct(updatedReadStruct, loadedStructs, saveState) {
- readStruct = updatedReadStruct;
- onLoadedStructures = loadedStructs;
- onSaveState = saveState;
- }
- exports.C1 = C1;
- exports.C1Type = C1Type;
- exports.Decoder = Decoder;
- exports.FLOAT32_OPTIONS = FLOAT32_OPTIONS;
- exports.Unpackr = Unpackr;
- exports.addExtension = addExtension;
- exports.checkedRead = checkedRead;
- exports.clearSource = clearSource;
- exports.decode = decode;
- exports.getPosition = getPosition;
- exports.loadStructures = loadStructures;
- exports.mult10 = mult10;
- exports.read = read;
- exports.readString = readString;
- exports.roundFloat32 = roundFloat32;
- exports.setExtractor = setExtractor;
- exports.setReadStruct = setReadStruct;
- exports.typedArrays = typedArrays;
- exports.unpack = unpack;
- exports.unpackMultiple = unpackMultiple;
- }));
- //# sourceMappingURL=unpack-no-eval.cjs.map
|