msgpackr 1.6.2 → 1.7.0-alpha3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/unpack.js CHANGED
@@ -28,6 +28,7 @@ export const C1 = new C1Type()
28
28
  C1.name = 'MessagePack 0xC1'
29
29
  var sequentialMode = false
30
30
  var inlineObjectReadThreshold = 2
31
+ var readStruct, onLoadedStructures
31
32
  try {
32
33
  new Function('')
33
34
  } catch(error) {
@@ -57,16 +58,21 @@ export class Unpackr {
57
58
  }
58
59
  Object.assign(this, options)
59
60
  }
60
- unpack(source, end) {
61
+ unpack(source, options) {
61
62
  if (src) {
62
63
  // re-entrant execution, save the state and restore it after we do this unpack
63
64
  return saveState(() => {
64
65
  clearSource()
65
- return this ? this.unpack(source, end) : Unpackr.prototype.unpack.call(defaultOptions, source, end)
66
+ return this ? this.unpack(source, options) : Unpackr.prototype.unpack.call(defaultOptions, source, options)
66
67
  })
67
68
  }
68
- srcEnd = end > -1 ? end : source.length
69
- position = 0
69
+ if (typeof options === 'object') {
70
+ srcEnd = options.end || source.length
71
+ position = options.start || 0
72
+ } else {
73
+ position = 0
74
+ srcEnd = options > -1 ? options : source.length
75
+ }
70
76
  stringPosition = 0
71
77
  srcStringEnd = 0
72
78
  srcString = null
@@ -133,6 +139,8 @@ export class Unpackr {
133
139
  }
134
140
  }
135
141
  _mergeStructures(loadedStructures, existingStructures) {
142
+ if (onLoadedStructures)
143
+ loadedStructures = onLoadedStructures.call(this, loadedStructures);
136
144
  loadedStructures = loadedStructures || []
137
145
  for (let i = 0, l = loadedStructures.length; i < l; i++) {
138
146
  let structure = loadedStructures[i]
@@ -170,7 +178,12 @@ export function checkedRead() {
170
178
  if (sharedLength < currentStructures.length)
171
179
  currentStructures.length = sharedLength
172
180
  }
173
- let result = read()
181
+ let result
182
+ if (currentUnpackr.randomAccessStructure && src[position] < 0x40 && src[position] >= 0x20 && readStruct) {
183
+ result = readStruct(src, position, srcEnd, currentUnpackr)
184
+ position = srcEnd
185
+ } else
186
+ result = read()
174
187
  if (bundledStrings) // bundled strings to skip past
175
188
  position = bundledStrings.postBundlePosition
176
189
 
@@ -247,6 +260,8 @@ export function read() {
247
260
  for (let i = 0; i < token; i++) {
248
261
  array[i] = read()
249
262
  }
263
+ if (currentUnpackr.freezeData)
264
+ return Object.freeze(array)
250
265
  return array
251
266
  }
252
267
  } else if (token < 0xc0) {
@@ -457,7 +472,8 @@ function createStructureReader(structure, firstId) {
457
472
  function readObject() {
458
473
  // This initial function is quick to instantiate, but runs slower. After several iterations pay the cost to build the faster function
459
474
  if (readObject.count++ > inlineObjectReadThreshold) {
460
- let readObject = structure.read = (new Function('r', 'return function(){return {' + structure.map(key => validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '}}'))(read)
475
+ let readObject = structure.read = (new Function('r', 'return function(){return ' + (currentUnpackr.freezeData ? 'Object.freeze' : '') +
476
+ '({' + structure.map(key => validName.test(key) ? key + ':r()' : ('[' + JSON.stringify(key) + ']:r()')).join(',') + '})}'))(read)
461
477
  if (structure.highByte === 0)
462
478
  structure.read = createSecondByteReader(firstId, structure.read)
463
479
  return readObject() // second byte is already read, if there is one so immediately read object
@@ -467,6 +483,8 @@ function createStructureReader(structure, firstId) {
467
483
  let key = structure[i]
468
484
  object[key] = read()
469
485
  }
486
+ if (currentUnpackr.freezeData)
487
+ return Object.freeze(object);
470
488
  return object
471
489
  }
472
490
  readObject.count = 0
@@ -492,7 +510,7 @@ const createSecondByteReader = (firstId, read0) => {
492
510
  }
493
511
  }
494
512
 
495
- function loadStructures() {
513
+ export function loadStructures() {
496
514
  let loadedStructures = saveState(() => {
497
515
  // save the state in case getStructures modifies our buffer
498
516
  src = null
@@ -598,12 +616,24 @@ function readStringJS(length) {
598
616
 
599
617
  return result
600
618
  }
619
+ export function readString(source, start, length) {
620
+ let existingSrc = src;
621
+ src = source;
622
+ position = start;
623
+ try {
624
+ return readStringJS(length);
625
+ } finally {
626
+ src = existingSrc;
627
+ }
628
+ }
601
629
 
602
630
  function readArray(length) {
603
631
  let array = new Array(length)
604
632
  for (let i = 0; i < length; i++) {
605
633
  array[i] = read()
606
634
  }
635
+ if (currentUnpackr.freezeData)
636
+ return Object.freeze(array)
607
637
  return array
608
638
  }
609
639
 
@@ -816,7 +846,15 @@ function readBin(length) {
816
846
  function readExt(length) {
817
847
  let type = src[position++]
818
848
  if (currentExtensions[type]) {
819
- return currentExtensions[type](src.subarray(position, position += length))
849
+ let end
850
+ return currentExtensions[type](src.subarray(position, end = (position += length)), (readPosition) => {
851
+ position = readPosition;
852
+ try {
853
+ return read();
854
+ } finally {
855
+ position = end;
856
+ }
857
+ })
820
858
  }
821
859
  else
822
860
  throw new Error('Unknown extension type ' + type)
@@ -1059,3 +1097,7 @@ export function roundFloat32(float32Number) {
1059
1097
  let multiplier = mult10[((u8Array[3] & 0x7f) << 1) | (u8Array[2] >> 7)]
1060
1098
  return ((multiplier * float32Number + (float32Number > 0 ? 0.5 : -0.5)) >> 0) / multiplier
1061
1099
  }
1100
+ export function setReadStruct(updatedReadStruct, loadedStructs) {
1101
+ readStruct = updatedReadStruct;
1102
+ onLoadedStructures = loadedStructs;
1103
+ }