(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(-2)<= 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 <<= 8n; 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