diff --git a/decode.js b/decode.js index f49a912..073a28a 100644 --- a/decode.js +++ b/decode.js @@ -6,6 +6,7 @@ let src let srcEnd let position = 0 let alreadySet +const Buffer = globalThis.Buffer const EMPTY_ARRAY = [] const LEGACY_RECORD_INLINE_ID = 105 const RECORD_DEFINITIONS_ID = 0xdffe @@ -34,6 +35,18 @@ let defaultOptions = { } let sequentialMode = false +const concat = Buffer && Buffer.concat || (buffers => { + let length = 0 + for (let buffer of buffers) length += buffer.byteLength + let result = new Uint8Array(length) + let offset = 0 + for (let buffer of buffers) { + result.set(buffer, offset) + offset += buffer.byteLength + } + return result +}) + export class Decoder { constructor(options) { if (options) { @@ -64,7 +77,7 @@ export class Decoder { decodeKey(key) { return this.keyMap ? this.mapKey.get(key) || key : key } - + encodeKey(key) { return this.keyMap && this.keyMap.hasOwnProperty(key) ? this.keyMap[key] : key } @@ -87,12 +100,12 @@ export class Decoder { map.forEach((v,k) => res[safeKey(this._mapKey.has(k) ? this._mapKey.get(k) : k)] = v) return res } - + mapDecode(source, end) { - + let res = this.decode(source) - if (this._keyMap) { - //Experiemntal support for Optimised KeyMap decoding + if (this._keyMap) { + //Experiemntal support for Optimised KeyMap decoding switch (res.constructor.name) { case 'Array': return res.map(r => this.decodeKeys(r)) //case 'Map': return this.decodeKeys(res) @@ -273,7 +286,7 @@ export function read() { token = dataView.getBigUint64(position) position += 8 break - case 0x1f: + case 0x1f: // indefinite length switch(majorType) { case 2: // byte string @@ -285,7 +298,7 @@ export function read() { while ((value = read()) != STOP_CODE) { array[i++] = value } - return majorType == 4 ? array : majorType == 3 ? array.join('') : Buffer.concat(array) + return majorType == 4 ? array : majorType == 3 ? array.join('') : concat(array) case 5: // map let key if (currentDecoder.mapsAsObjects) { @@ -332,8 +345,8 @@ export function read() { return readFixedString(token) case 4: // array let array = new Array(token) - //if (currentDecoder.keyMap) for (let i = 0; i < token; i++) array[i] = currentDecoder.decodeKey(read()) - //else + //if (currentDecoder.keyMap) for (let i = 0; i < token; i++) array[i] = currentDecoder.decodeKey(read()) + //else for (let i = 0; i < token; i++) array[i] = read() return array case 5: // map @@ -470,7 +483,7 @@ function createStructureReader(structure) { } if (this.slowReads++ >= 3) { // create a fast compiled reader let array = this.length == length ? this : this.slice(0, length) - compiledReader = currentDecoder.keyMap + compiledReader = currentDecoder.keyMap ? new Function('r', 'return {' + array.map(k => currentDecoder.decodeKey(k)).map(k => validName.test(k) ? safeKey(k) + ':r()' : ('[' + JSON.stringify(k) + ']:r()')).join(',') + '}') : new Function('r', 'return {' + array.map(key => validName.test(key) ? safeKey(key) + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '}') if (this.compiledReader) @@ -966,7 +979,7 @@ currentExtensions[PACKED_REFERENCE_TAG_ID] = (data) => { // packed reference // } // currentExtensions[256].handlesRead = true -currentExtensions[28] = (read) => { +currentExtensions[28] = (read) => { // shareable http://cbor.schmorp.de/value-sharing (for structured clones) if (!referenceMap) { referenceMap = new Map()