msgpackr 1.4.5 → 1.5.1
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/README.md +15 -3
- package/dist/index.js +35 -12
- package/dist/index.min.js +15 -13
- package/dist/node.cjs +36 -15
- package/dist/str.cjs +100 -0
- package/dist/test.js +20 -1
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/node-index.js +2 -4
- package/pack.js +12 -4
- package/package.json +3 -2
- package/tests/test.js +20 -1
- package/unpack.d.ts +5 -2
- package/unpack.js +23 -10
package/README.md
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
# msgpackr
|
|
2
|
-
[](LICENSE)
|
|
3
2
|
[](https://www.npmjs.org/package/msgpackr)
|
|
3
|
+
[](https://www.npmjs.org/package/msgpackr)
|
|
4
4
|
[](benchmark.md)
|
|
5
5
|
[](benchmark.md)
|
|
6
6
|
[](README.md)
|
|
7
7
|
[](README.md)
|
|
8
|
+
[](LICENSE)
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
The msgpackr package is an extremely fast MessagePack NodeJS/JavaScript implementation. Currently, it is significantly faster than any other known implementations, faster than Avro (for JS), and generally faster than native V8 JSON.stringify/parse, on NodeJS. It also includes an optional record extension (the `r` in msgpackr), for defining record structures that makes MessagePack even faster and more compact, often over twice as fast as even native JSON functions, several times faster than other JS implementations, and 15-50% more compact. See the performance section for more details. Structured cloning (with support for cyclical references) is also supported through optional extensions.
|
|
@@ -166,6 +167,8 @@ The following options properties can be provided to the Packr or Unpackr constru
|
|
|
166
167
|
* `sequential` - Encode structures in serialized data, and reference previously encoded structures with expectation that decoder will read the encoded structures in the same order as encoded, with `unpackMultiple`.
|
|
167
168
|
* `largeBigIntToFloat` - If a bigint needs to be encoded that is larger than will fit in 64-bit integers, it will be encoded as a float-64 (otherwise will throw a RangeError).
|
|
168
169
|
* `encodeUndefinedAsNil` - Encodes a value of `undefined` as a MessagePack `nil`, the same as a `null`.
|
|
170
|
+
* `int64AsNumber` - This will decode uint64 and int64 numbers as standard JS numbers rather than as bigint numbers.
|
|
171
|
+
* `onInvalidDate` - This can be provided as function that will be called when an invalid date is provided. The function can throw an error, or return a value that will be encoded in place of the invalid date. If not provided, an invalid date will be encoded as an invalid timestamp (which decodes with msgpackr back to an invalid date).
|
|
169
172
|
|
|
170
173
|
### 32-bit Float Options
|
|
171
174
|
By default all non-integer numbers are serialized as 64-bit float (double). This is fast, and ensures maximum precision. However, often real-world data doesn't not need 64-bits of precision, and using 32-bit encoding can be much more space efficient. There are several options that provide more efficient encodings. Using the decimal rounding options for encoding and decoding provides lossless storage of common decimal representations like 7.99, in more efficient 32-bit format (rather than 64-bit). The `useFloat32` property has several possible options, available from the module as constants:
|
|
@@ -176,13 +179,22 @@ const { ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } = FLOAT32_OPTIONS;
|
|
|
176
179
|
|
|
177
180
|
* `ALWAYS` (1) - Always will encode non-integers (absolute less than 2147483648) as 32-bit float.
|
|
178
181
|
* `DECIMAL_ROUND` (3) - Always will encode non-integers as 32-bit float, and when decoding 32-bit float, round to the significant decimal digits (usually 7, but 6 or 8 digits for some ranges).
|
|
179
|
-
* `DECIMAL_FIT` (4) - Only encode non-integers as 32-bit float if all significant digits (usually up to 7) can be
|
|
182
|
+
* `DECIMAL_FIT` (4) - Only encode non-integers as 32-bit float if all significant digits (usually up to 7) can be unambiguously encoded as a 32-bit float, and decode/unpack with decimal rounding (same as above). This will ensure round-trip encoding/decoding without loss in precision and uses 32-bit when possible.
|
|
180
183
|
|
|
181
184
|
Note, that the performance is decreased with decimal rounding by about 20-25%, although if only 5% of your values are floating point, that will only have about a 1% impact overall.
|
|
182
185
|
|
|
183
|
-
In addition, msgpackr exports a `roundFloat32(number)` function that can be used to round floating point numbers to the maximum significant decimal digits that can be stored in 32-bit float, just as DECIMAL_ROUND does when
|
|
186
|
+
In addition, msgpackr exports a `roundFloat32(number)` function that can be used to round floating point numbers to the maximum significant decimal digits that can be stored in 32-bit float, just as DECIMAL_ROUND does when decoding. This can be useful for determining how a number will be decoded prior to encoding it.
|
|
184
187
|
|
|
185
188
|
## Performance
|
|
189
|
+
### Native Acceleration
|
|
190
|
+
Msgpackr employs an optional native node-addon to accelerate the parsing of strings. This should be automatically installed and utilized on NodeJS. However, you can verify this by checking the `isNativeAccelerationEnabled` property that is exported from msgpackr. If this is `false`, the `msgpackr-extract` package may not have been properly installed, and you may want to verify that it is installed correctly:
|
|
191
|
+
```js
|
|
192
|
+
import { isNativeAccelerationEnabled } from 'msgpackr'
|
|
193
|
+
if (!isNativeAccelerationEnabled)
|
|
194
|
+
console.warn('Native acceleration not enabled, verify that install finished properly')
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
### Benchmarks
|
|
186
198
|
Msgpackr is fast. Really fast. Here is comparison with the next fastest JS projects using the benchmark tool from `msgpack-lite` (and the sample data is from some clinical research data we use that has a good mix of different value types and structures). It also includes comparison to V8 native JSON functionality, and JavaScript Avro (`avsc`, a very optimized Avro implementation):
|
|
187
199
|
|
|
188
200
|
operation | op | ms | op/s
|
package/dist/index.js
CHANGED
|
@@ -58,8 +58,16 @@
|
|
|
58
58
|
// this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
|
|
59
59
|
// technique for getting data from a database where it can be copied into an existing buffer instead of creating
|
|
60
60
|
// new ones
|
|
61
|
-
|
|
62
|
-
|
|
61
|
+
try {
|
|
62
|
+
dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength));
|
|
63
|
+
} catch(error) {
|
|
64
|
+
// if it doesn't have a buffer, maybe it is the wrong type of object
|
|
65
|
+
src = null;
|
|
66
|
+
if (source instanceof Uint8Array)
|
|
67
|
+
throw error
|
|
68
|
+
throw new Error('Source must be a Uint8Array or Buffer but was a ' + ((source && typeof source == 'object') ? source.constructor.name : typeof source))
|
|
69
|
+
}
|
|
70
|
+
if (this instanceof Unpackr) {
|
|
63
71
|
currentUnpackr = this;
|
|
64
72
|
if (this.structures) {
|
|
65
73
|
currentStructures = this.structures;
|
|
@@ -291,10 +299,11 @@
|
|
|
291
299
|
position += 4;
|
|
292
300
|
return value
|
|
293
301
|
case 0xcf:
|
|
294
|
-
if (currentUnpackr.
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
302
|
+
if (currentUnpackr.int64AsNumber) {
|
|
303
|
+
value = dataView.getUint32(position) * 0x100000000;
|
|
304
|
+
value += dataView.getUint32(position + 4);
|
|
305
|
+
} else
|
|
306
|
+
value = dataView.getBigUint64(position);
|
|
298
307
|
position += 8;
|
|
299
308
|
return value
|
|
300
309
|
|
|
@@ -310,7 +319,11 @@
|
|
|
310
319
|
position += 4;
|
|
311
320
|
return value
|
|
312
321
|
case 0xd3:
|
|
313
|
-
|
|
322
|
+
if (currentUnpackr.int64AsNumber) {
|
|
323
|
+
value = dataView.getInt32(position) * 0x100000000;
|
|
324
|
+
value += dataView.getUint32(position + 4);
|
|
325
|
+
} else
|
|
326
|
+
value = dataView.getBigInt64(position);
|
|
314
327
|
position += 8;
|
|
315
328
|
return value
|
|
316
329
|
|
|
@@ -459,6 +472,7 @@
|
|
|
459
472
|
var readString8 = readStringJS;
|
|
460
473
|
var readString16 = readStringJS;
|
|
461
474
|
var readString32 = readStringJS;
|
|
475
|
+
let isNativeAccelerationEnabled = false;
|
|
462
476
|
function readStringJS(length) {
|
|
463
477
|
let result;
|
|
464
478
|
if (length < 16) {
|
|
@@ -856,7 +870,7 @@
|
|
|
856
870
|
((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +
|
|
857
871
|
(((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)
|
|
858
872
|
else
|
|
859
|
-
|
|
873
|
+
return new Date('invalid')
|
|
860
874
|
}; // notepack defines extension 0 to mean undefined, so use that as the default here
|
|
861
875
|
// registration of bulk record definition?
|
|
862
876
|
// currentExtensions[0x52] = () =>
|
|
@@ -1101,9 +1115,9 @@
|
|
|
1101
1115
|
// first we estimate the header size, so we can write to the correct location
|
|
1102
1116
|
if (strLength < 0x20) {
|
|
1103
1117
|
headerSize = 1;
|
|
1104
|
-
} else if (strLength <
|
|
1118
|
+
} else if (strLength < 0x100) {
|
|
1105
1119
|
headerSize = 2;
|
|
1106
|
-
} else if (strLength <
|
|
1120
|
+
} else if (strLength < 0x10000) {
|
|
1107
1121
|
headerSize = 3;
|
|
1108
1122
|
} else {
|
|
1109
1123
|
headerSize = 5;
|
|
@@ -1516,7 +1530,7 @@
|
|
|
1516
1530
|
if ((end - start) > MAX_BUFFER_SIZE)
|
|
1517
1531
|
throw new Error('Packed buffer would be larger than maximum buffer size')
|
|
1518
1532
|
newSize = Math.min(MAX_BUFFER_SIZE,
|
|
1519
|
-
Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2),
|
|
1533
|
+
Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000);
|
|
1520
1534
|
} else // faster handling for smaller buffers
|
|
1521
1535
|
newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
|
|
1522
1536
|
let newBuffer = new ByteArrayAllocate(newSize);
|
|
@@ -1541,7 +1555,7 @@
|
|
|
1541
1555
|
|
|
1542
1556
|
extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ];
|
|
1543
1557
|
extensions = [{
|
|
1544
|
-
pack(date, allocateForWrite) {
|
|
1558
|
+
pack(date, allocateForWrite, pack) {
|
|
1545
1559
|
let seconds = date.getTime() / 1000;
|
|
1546
1560
|
if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
|
|
1547
1561
|
// Timestamp 32
|
|
@@ -1556,6 +1570,14 @@
|
|
|
1556
1570
|
target[position++] = 0xff;
|
|
1557
1571
|
targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0));
|
|
1558
1572
|
targetView.setUint32(position + 4, seconds);
|
|
1573
|
+
} else if (isNaN(seconds)) {
|
|
1574
|
+
if (this.onInvalidDate)
|
|
1575
|
+
return pack(this.onInvalidDate())
|
|
1576
|
+
// Intentionally invalid timestamp
|
|
1577
|
+
let { target, targetView, position} = allocateForWrite(3);
|
|
1578
|
+
target[position++] = 0xd4;
|
|
1579
|
+
target[position++] = 0xff;
|
|
1580
|
+
target[position++] = 0xff;
|
|
1559
1581
|
} else {
|
|
1560
1582
|
// Timestamp 96
|
|
1561
1583
|
let { target, targetView, position} = allocateForWrite(15);
|
|
@@ -1848,6 +1870,7 @@
|
|
|
1848
1870
|
exports.decodeIter = decodeIter;
|
|
1849
1871
|
exports.encode = encode;
|
|
1850
1872
|
exports.encodeIter = encodeIter;
|
|
1873
|
+
exports.isNativeAccelerationEnabled = isNativeAccelerationEnabled;
|
|
1851
1874
|
exports.mapsAsObjects = mapsAsObjects;
|
|
1852
1875
|
exports.pack = pack;
|
|
1853
1876
|
exports.roundFloat32 = roundFloat32;
|
package/dist/index.min.js
CHANGED
|
@@ -7,8 +7,8 @@ case 194:return!1;case 195:return!0;case 196:// bin 8
|
|
|
7
7
|
return m(A[G++]);case 197:return b=F.getUint16(G),G+=2,m(b);case 198:return b=F.getUint32(G),G+=4,m(b);case 199:// ext 8
|
|
8
8
|
return n(A[G++]);case 200:return b=F.getUint16(G),G+=2,n(b);case 201:return b=F.getUint32(G),G+=4,n(b);case 202:if(b=F.getFloat32(G),2<H.useFloat32){// this does rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
|
|
9
9
|
let a=_[(127&A[G])<<1|A[G+1]>>7];return G+=4,(a*b+(0<b?.5:-.5)>>0)/a}return G+=4,b;case 203:return b=F.getFloat64(G),G+=8,b;// uint handlers
|
|
10
|
-
case 204:return A[G++];case 205:return b=F.getUint16(G),G+=2,b;case 206:return b=F.getUint32(G),G+=4,b;case 207:return H.
|
|
11
|
-
case 208:return F.getInt8(G++);case 209:return b=F.getInt16(G),G+=2,b;case 210:return b=F.getInt32(G),G+=4,b;case 211:return b=F.getBigInt64(G),G+=8,b;case 212:if(b=A[G++],114==b)return Y(63&A[G++]);else{let a=K[b];if(a)return a.read?(G++,a.read(e())):a.noBuffer?(G++,a()):a(A.subarray(G,++G));throw new Error("Unknown extension "+b)}case 213:return b=A[G],114==b?(G++,Y(63&A[G++],A[G++])):n(2);case 214:// fixext 4
|
|
10
|
+
case 204:return A[G++];case 205:return b=F.getUint16(G),G+=2,b;case 206:return b=F.getUint32(G),G+=4,b;case 207:return H.int64AsNumber?(b=4294967296*F.getUint32(G),b+=F.getUint32(G+4)):b=F.getBigUint64(G),G+=8,b;// int handlers
|
|
11
|
+
case 208:return F.getInt8(G++);case 209:return b=F.getInt16(G),G+=2,b;case 210:return b=F.getInt32(G),G+=4,b;case 211:return H.int64AsNumber?(b=4294967296*F.getInt32(G),b+=F.getUint32(G+4)):b=F.getBigInt64(G),G+=8,b;case 212:if(b=A[G++],114==b)return Y(63&A[G++]);else{let a=K[b];if(a)return a.read?(G++,a.read(e())):a.noBuffer?(G++,a()):a(A.subarray(G,++G));throw new Error("Unknown extension "+b)}case 213:return b=A[G],114==b?(G++,Y(63&A[G++],A[G++])):n(2);case 214:// fixext 4
|
|
12
12
|
return n(4);case 215:// fixext 8
|
|
13
13
|
return n(8);case 216:// fixext 16
|
|
14
14
|
return n(16);case 217:return b=A[G++],J>=G?D.slice(G-I,(G+=b)-I):T(b);case 218:return b=F.getUint16(G),G+=2,J>=G?D.slice(G-I,(G+=b)-I):U(b);case 219:return b=F.getUint32(G),G+=4,J>=G?D.slice(G-I,(G+=b)-I):V(b);case 220:return b=F.getUint16(G),G+=2,i(b);case 221:return b=F.getUint32(G),G+=4,i(b);case 222:return b=F.getUint16(G),G+=2,j(b);case 223:return b=F.getUint32(G),G+=4,j(b);default:// negative int
|
|
@@ -35,21 +35,22 @@ a[g++]=214,a[g++]=105,a[g++]=f>>24,a[g++]=255&f>>16,a[g++]=255&f>>8,a[g++]=255&f
|
|
|
35
35
|
* @param {object} [options] - unpackr options
|
|
36
36
|
* @returns {IterableIterator|Promise.<AsyncIterableIterator}
|
|
37
37
|
*/var z;try{z=new TextDecoder}catch(a){}var A,B,C,D,E,F,G=0,H={},I=0,J=0,K=[],L={useRecords:!1,mapsAsObjects:!0};class M{}const N=new M;N.name="MessagePack 0xC1";var O=!1;class P{constructor(a){a&&(!1===a.useRecords&&a.mapsAsObjects===void 0&&(a.mapsAsObjects=!0),a.structures?a.structures.sharedLength=a.structures.length:a.getStructures&&((a.structures=[]).uninitialized=!0,a.structures.sharedLength=0)),Object.assign(this,a)}unpack(a,b){if(A)// re-entrant execution, save the state and restore it after we do this unpack
|
|
38
|
-
return p(()=>(q(),this?this.unpack(a,b):P.prototype.unpack.call(L,a,b)));
|
|
38
|
+
return p(()=>(q(),this?this.unpack(a,b):P.prototype.unpack.call(L,a,b)));B=-1<b?b:a.length,G=0,J=0,D=null,A=a;// this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
|
|
39
|
+
// technique for getting data from a database where it can be copied into an existing buffer instead of creating
|
|
40
|
+
// new ones
|
|
41
|
+
try{F=a.dataView||(a.dataView=new DataView(a.buffer,a.byteOffset,a.byteLength))}catch(b){if(A=null,a instanceof Uint8Array)throw b;throw new Error("Source must be a Uint8Array or Buffer but was a "+(a&&"object"==typeof a?a.constructor.name:typeof a))}if(this instanceof P){if(H=this,this.structures)return C=this.structures,c();(!C||0<C.length)&&(C=[])}else H=L,(!C||0<C.length)&&(C=[]);return c()}unpackMultiple(a,b){let d,e=0;try{O=!0;let f=a.length,g=this?this.unpack(a,f):aa.unpack(a,f);if(b){for(b(g);G<f;)if(e=G,!1===b(c()))return;}else{for(d=[g];G<f;)e=G,d.push(c());return d}}catch(a){throw a.lastPosition=e,a.values=d,a}finally{O=!1,q()}}_mergeStructures(a,b){a=a||[];for(let c,d=0,e=a.length;d<e;d++)c=a[d],c&&(c.isShared=!0,32<=d&&(c.highByte=d-32>>5));for(let c in a.sharedLength=a.length,b||[])if(0<=c){let d=a[c],e=b[c];e&&(d&&((a.restoreStructures||(a.restoreStructures=[]))[c]=d),a[c]=e)}return this.structures=a}decode(a,b){return this.unpack(a,b)}}const Q=/^[a-zA-Z_$][a-zA-Z\d_$]*$/,R=(a,b)=>function(){let c=A[G++];if(0===c)return b();let d=32>a?-(a+(c<<5)):a+(c<<5),e=C[d]||g()[d];if(!e)throw new Error("Record id is not defined for "+d);return e.read||(e.read=f(e,a)),e.read()};var S=h,T=h,U=h,V=h;var W=String.fromCharCode,X=Array(4096);const Y=(a,b)=>{var c=e();let d=a;void 0!==b&&(a=32>a?-((b<<5)+a):(b<<5)+a,c.highByte=b);let g=C[a];return g&&g.isShared&&((C.restoreStructures||(C.restoreStructures=[]))[a]=g),C[a]=c,c.read=f(c,d),c.read()};var Z="object"==typeof self?self:global;K[0]=()=>{},K[0].noBuffer=!0,K[101]=()=>{let a=e();return(Z[a[0]]||Error)(a[1])},K[105]=()=>{// id extension (for structured clones)
|
|
39
42
|
let a=F.getUint32(G-4);E||(E=new Map);let b,c=A[G];b=144<=c&&160>c||220==c||221==c?[]:{};let d={target:b};// a placeholder object
|
|
40
43
|
E.set(a,d);let f=e();// read the next value as the target object to id
|
|
41
44
|
return d.used?Object.assign(b,f):(d.target=f,f);// no cycle, can just use the returned read object
|
|
42
45
|
},K[112]=()=>{// pointer extension (for structured clones)
|
|
43
46
|
let a=F.getUint32(G-4),b=E.get(a);return b.used=!0,b.target},K[115]=()=>new Set(e());const $=["Int8","Uint8","Uint8Clamped","Int16","Uint16","Int32","Uint32","Float32","Float64","BigInt64","BigUint64"].map(a=>a+"Array");K[116]=a=>{let b=a[0],c=$[b];if(!c)throw new Error("Could not find typed array for code "+b);// we have to always slice/copy here to get a new ArrayBuffer that is word/byte aligned
|
|
44
|
-
return new Z[c](Uint8Array.prototype.slice.call(a,1).buffer)},K[120]=()=>{let a=e();return new RegExp(a[0],a[1])},K[255]=a=>
|
|
45
|
-
if(4==a.length)return new Date(1e3*(16777216*a[0]+(a[1]<<16)+(a[2]<<8)+a[3]));if(8==a.length)return new Date(((a[0]<<22)+(a[1]<<14)+(a[2]<<6)+(a[3]>>2))/1e6+1e3*(4294967296*(3&a[3])+16777216*a[4]+(a[5]<<16)+(a[6]<<8)+a[7]));if(12==a.length)// TODO: Implement support for negative
|
|
46
|
-
return new Date(((a[0]<<24)+(a[1]<<16)+(a[2]<<8)+a[3])/1e6+1e3*((128&a[4]?-281474976710656:0)+1099511627776*a[6]+4294967296*a[7]+16777216*a[8]+(a[9]<<16)+(a[10]<<8)+a[11]));throw new Error("Invalid timestamp length")};const _=Array(147);// this is a table matching binary exponents to the multiplier to determine significant digit rounding
|
|
47
|
+
return new Z[c](Uint8Array.prototype.slice.call(a,1).buffer)},K[120]=()=>{let a=e();return new RegExp(a[0],a[1])},K[255]=a=>4==a.length?new Date(1e3*(16777216*a[0]+(a[1]<<16)+(a[2]<<8)+a[3])):8==a.length?new Date(((a[0]<<22)+(a[1]<<14)+(a[2]<<6)+(a[3]>>2))/1e6+1e3*(4294967296*(3&a[3])+16777216*a[4]+(a[5]<<16)+(a[6]<<8)+a[7])):12==a.length?new Date(((a[0]<<24)+(a[1]<<16)+(a[2]<<8)+a[3])/1e6+1e3*((128&a[4]?-281474976710656:0)+1099511627776*a[6]+4294967296*a[7]+16777216*a[8]+(a[9]<<16)+(a[10]<<8)+a[11])):new Date("invalid");const _=Array(147);// this is a table matching binary exponents to the multiplier to determine significant digit rounding
|
|
47
48
|
for(let c=0;256>c;c++)_[c]=+("1e"+b(45.15-.30103*c));var aa=new P({useRecords:!1});const ba=aa.unpack,ca=aa.unpackMultiple,da=aa.unpack,ea={NEVER:0,ALWAYS:1,DECIMAL_ROUND:3,DECIMAL_FIT:4};let fa,ga=new Float32Array(1),ha=new Uint8Array(ga.buffer,0,4);try{fa=new TextEncoder}catch(a){}let ia,ja;const ka="undefined"!=typeof Buffer,la=ka?Buffer.allocUnsafeSlow:Uint8Array,ma=ka?Buffer:Uint8Array,na=ka?4294967296:2144337920;let oa,pa,qa,ra=0;const sa=Symbol("record-id");class ta extends P{constructor(a){super(a),this.offset=0;let b,c,d,e,f,g=0,h=ma.prototype.utf8Write?function(a,b,c){return oa.utf8Write(a,b,c)}:!!(fa&&fa.encodeInto)&&function(a,b){return fa.encodeInto(a,oa.subarray(b)).written},i=this;a||(a={});let j=a&&a.sequential,k=a.structures||a.saveStructures,l=a.maxSharedStructures;if(null==l&&(l=k?32:0),8160<l)throw new Error("Maximum maxSharedStructure is 8160");let m=a.maxOwnStructures;null==m&&(m=k?32:64),j&&!a.saveStructures&&(this.structures=[]);// two byte record ids for shared structures
|
|
48
49
|
let n=32<l||64<m+l,o=l+64,p=l+m+64;if(8256<p)throw new Error("Maximum maxSharedStructure + maxOwnStructure is 8192");let q=[],r=0,s=0;this.pack=this.encode=function(a,h){if(oa||(oa=new la(8192),pa=new DataView(oa.buffer,0,8192),ra=0),qa=oa.length-10,2048>qa-ra?(oa=new la(oa.length),pa=new DataView(oa.buffer,0,oa.length),qa=oa.length-10,ra=0):ra=2147483640&ra+7,b=ra,f=i.structuredClone?new Map:null,c=i.structures,c){c.uninitialized&&(c=i._mergeStructures(i.getStructures()));let a=c.sharedLength||0;if(a>l)//if (maxSharedStructures <= 32 && sharedStructures.sharedLength > 32) // TODO: could support this, but would need to update the limit ids
|
|
49
50
|
throw new Error("Shared structures is larger than maximum shared structures, try increasing maxSharedStructures to "+c.sharedLength);if(!c.transitions){c.transitions=Object.create(null);for(let b,d=0;d<a;d++){if(b=c[d],!b)continue;let a,e=c.transitions;for(let c,d=0,f=b.length;d<f;d++)c=b[d],a=e[c],a||(a=e[c]=Object.create(null)),e=a;e[sa]=d+64}g=a}j||(c.nextId=a+64)}d&&(d=!1),e=c||[];try{// update the offset so next serialization doesn't write over our buffer, but can continue writing to same buffer sequentially
|
|
50
51
|
if(t(a),i.offset=ra,f&&f.idsToInsert){ra+=6*f.idsToInsert.length,ra>qa&&x(ra),i.offset=ra;let a=v(oa.subarray(b,ra),f.idsToInsert);return f=null,a}return h===Ba?(oa.start=b,oa.end=ra,oa):oa.subarray(b,ra);// position can change if we call pack again in saveStructures, so we get the buffer now
|
|
51
52
|
}finally{if(c){if(10>s&&s++,1e4<r)c.transitions=null,s=0,r=0,0<q.length&&(q=[]);else if(0<q.length&&!j){for(let a=0,b=q.length;a<b;a++)q[a][sa]=0;q=[]}if(d&&i.saveStructures){let d=c.sharedLength||l;c.length>d&&(c=c.slice(0,d));// we can't rely on start/end with REUSE_BUFFER_MODE since they will (probably) change when we save
|
|
52
|
-
let e=oa.subarray(b,ra);return!1===i.saveStructures(c,g)?(i._mergeStructures(i.getStructures()),i.pack(a)):(g=d,e)}}}};const t=a=>{ra>qa&&(oa=x(ra));var c,d=typeof a;if("string"==d){let b,d=a.length;b=32>d?1:
|
|
53
|
+
let e=oa.subarray(b,ra);return!1===i.saveStructures(c,g)?(i._mergeStructures(i.getStructures()),i.pack(a)):(g=d,e)}}}};const t=a=>{ra>qa&&(oa=x(ra));var c,d=typeof a;if("string"==d){let b,d=a.length;b=32>d?1:256>d?2:65536>d?3:5;let e=3*d;if(ra+e>qa&&(oa=x(ra+e)),64>d||!h){let e,f,g,h=ra+b;for(e=0;e<d;e++)f=a.charCodeAt(e),128>f?oa[h++]=f:2048>f?(oa[h++]=192|f>>6,oa[h++]=128|63&f):55296==(64512&f)&&56320==(64512&(g=a.charCodeAt(e+1)))?(f=65536+((1023&f)<<10)+(1023&g),e++,oa[h++]=240|f>>18,oa[h++]=128|63&f>>12,oa[h++]=128|63&f>>6,oa[h++]=128|63&f):(oa[h++]=224|f>>12,oa[h++]=128|63&f>>6,oa[h++]=128|63&f);c=h-ra-b}else c=h(a,ra+b,e);32>c?oa[ra++]=160|c:256>c?(2>b&&oa.copyWithin(ra+2,ra+1,ra+1+c),oa[ra++]=217,oa[ra++]=c):65536>c?(3>b&&oa.copyWithin(ra+3,ra+2,ra+2+c),oa[ra++]=218,oa[ra++]=c>>8,oa[ra++]=255&c):(5>b&&oa.copyWithin(ra+5,ra+3,ra+3+c),oa[ra++]=219,pa.setUint32(ra,c),ra+=4),ra+=c}else if("number"===d){if(a>>>0===a)64>a?oa[ra++]=a:256>a?(oa[ra++]=204,oa[ra++]=a):65536>a?(oa[ra++]=205,oa[ra++]=a>>8,oa[ra++]=255&a):(oa[ra++]=206,pa.setUint32(ra,a),ra+=4);else if(a>>0===a)-32<=a?oa[ra++]=256+a:-128<=a?(oa[ra++]=208,oa[ra++]=a+256):-32768<=a?(oa[ra++]=209,pa.setInt16(ra,a),ra+=2):(oa[ra++]=210,pa.setInt32(ra,a),ra+=4);else{let b;if(0<(b=this.useFloat32)&&4294967296>a&&-2147483648<=a){oa[ra++]=202,pa.setFloat32(ra,a);let c;if(4>b||// this checks for rounding of numbers that were encoded in 32-bit float to nearest significant decimal digit that could be preserved
|
|
53
54
|
(c=a*_[(127&oa[ra])<<1|oa[ra+1]>>7])>>0===c)return void(ra+=4);// move back into position for writing a double
|
|
54
55
|
ra--}oa[ra++]=203,pa.setFloat64(ra,a),ra+=8}}else if("object"===d){if(!a)oa[ra++]=192;else{if(f){let c=f.get(a);if(c){if(!c.id){let a=f.idsToInsert||(f.idsToInsert=[]);c.id=a.push(c)}return oa[ra++]=214,oa[ra++]=112,pa.setUint32(ra,c.id),void(ra+=4)}f.set(a,{offset:ra-b})}let d=a.constructor;if(d===Object)w(a,!0);else if(d===Array){c=a.length,16>c?oa[ra++]=144|c:65536>c?(oa[ra++]=220,oa[ra++]=c>>8,oa[ra++]=255&c):(oa[ra++]=221,pa.setUint32(ra,c),ra+=4);for(let b=0;b<c;b++)t(a[b])}else if(d===Map){c=a.size,16>c?oa[ra++]=128|c:65536>c?(oa[ra++]=222,oa[ra++]=c>>8,oa[ra++]=255&c):(oa[ra++]=223,pa.setUint32(ra,c),ra+=4);for(let[b,c]of a)t(b),t(c)}else{for(let b,c=0,d=ia.length;c<d;c++)if(b=ja[c],a instanceof b){let b=ia[c];if(b.write)return b.type&&(oa[ra++]=212,oa[ra++]=b.type,oa[ra++]=0),void t(b.write.call(this,a));let d=oa,e=pa,f=ra;oa=null;let g;try{g=b.pack.call(this,a,a=>(oa=d,d=null,ra+=a,ra>qa&&x(ra),{target:oa,targetView:pa,position:ra-a}),t)}finally{d&&(oa=d,pa=e,ra=f,qa=oa.length-10)}return void(g&&(g.length+ra>qa&&x(g.length+ra),ra=u(g,oa,ra,b.type)))}// no extension found, write as object
|
|
55
56
|
w(a,!a.hasOwnProperty)}}}else if("boolean"===d)oa[ra++]=a?195:194;else if("bigint"===d){if(a<BigInt(1)<<BigInt(63)&&a>=-(BigInt(1)<<BigInt(63)))oa[ra++]=211,pa.setBigInt64(ra,a);else if(a<BigInt(1)<<BigInt(64)&&0<a)oa[ra++]=207,pa.setBigUint64(ra,a);else// overflow
|
|
@@ -97,12 +98,13 @@ let d=ra-b;ra+=2;let e=0;for(let b in a)(c||a.hasOwnProperty(b))&&(t(b),t(a[b]),
|
|
|
97
98
|
}*/a=>{let b,c=Object.keys(a),f=e.transitions||(e.transitions=Object.create(null)),g=0;for(let d,e=0,h=c.length;e<h;e++)d=c[e],b=f[d],b||(b=f[d]=Object.create(null),g++),f=b;let h=f[sa];if(h)96<=h&&n?(oa[ra++]=(31&(h-=96))+96,oa[ra++]=h>>5):oa[ra++]=h;else{h=e.nextId,h||(h=64),h<o&&this.shouldShareStructure&&!this.shouldShareStructure(c)?(h=e.nextOwnId,!(h<p)&&(h=o),e.nextOwnId=h+1):(h>=p&&(// cycle back around
|
|
98
99
|
h=o),e.nextId=h+1);let a=c.highByte=96<=h&&n?h-96>>5:-1;f[sa]=h,e[h-64]=c,h<o?(c.isShared=!0,e.sharedLength=h-63,d=!0,0<=a?(oa[ra++]=(31&h)+96,oa[ra++]=a):oa[ra++]=h):(0<=a?(oa[ra++]=213,oa[ra++]=114,oa[ra++]=(31&h)+96,oa[ra++]=a):(oa[ra++]=212,oa[ra++]=114,oa[ra++]=h),g&&(r+=s*g),q.length>=m&&(q.shift()[sa]=0),q.push(f),t(c))}// now write the values
|
|
99
100
|
for(let b=0,d=c.length;b<d;b++)t(a[c[b]])},x=a=>{var c=Math.min,d=Math.round,e=Math.max;let f;if(16777216<a){// special handling for really large buffers
|
|
100
|
-
if(a-b>na)throw new Error("Packed buffer would be larger than maximum buffer size");f=c(na,4096*d(e((a-b)*(67108864<a?1.25:2),
|
|
101
|
+
if(a-b>na)throw new Error("Packed buffer would be larger than maximum buffer size");f=c(na,4096*d(e((a-b)*(67108864<a?1.25:2),4194304)/4096))}else// faster handling for smaller buffers
|
|
101
102
|
f=(e(a-b<<2,oa.length-1)>>12)+1<<12;let g=new la(f);return pa=new DataView(g.buffer,0,f),oa.copy?oa.copy(g,0,b,a):g.set(oa.slice(b,a)),ra-=b,b=0,qa=g.length-10,oa=g}}useBuffer(a){// this means we are finished using our own buffer and we can write over it safely
|
|
102
|
-
oa=a,pa=new DataView(oa.buffer,oa.byteOffset,oa.byteLength),ra=0}}ja=[Date,Set,Error,RegExp,ArrayBuffer,Object.getPrototypeOf(Uint8Array.prototype).constructor/*TypedArray*/,M],ia=[{pack(a,c){let
|
|
103
|
-
let{target:a,targetView:b,position:
|
|
104
|
-
let{target:b,targetView:
|
|
105
|
-
let{target:
|
|
103
|
+
oa=a,pa=new DataView(oa.buffer,oa.byteOffset,oa.byteLength),ra=0}}ja=[Date,Set,Error,RegExp,ArrayBuffer,Object.getPrototypeOf(Uint8Array.prototype).constructor/*TypedArray*/,M],ia=[{pack(a,c,d){let e=a.getTime()/1e3;if((this.useTimestamp32||0===a.getMilliseconds())&&0<=e&&4294967296>e){// Timestamp 32
|
|
104
|
+
let{target:a,targetView:b,position:d}=c(6);a[d++]=214,a[d++]=255,b.setUint32(d,e)}else if(0<e&&17179869184>e){// Timestamp 64
|
|
105
|
+
let{target:b,targetView:d,position:f}=c(10);b[f++]=215,b[f++]=255,d.setUint32(f,4e6*a.getMilliseconds()+(e/1e3/4294967296>>0)),d.setUint32(f+4,e)}else if(isNaN(e)){if(this.onInvalidDate)return d(this.onInvalidDate());// Intentionally invalid timestamp
|
|
106
|
+
let{target:a,targetView:b,position:e}=c(3);a[e++]=212,a[e++]=255,a[e++]=255}else{// Timestamp 96
|
|
107
|
+
let{target:d,targetView:f,position:g}=c(15);d[g++]=199,d[g++]=12,d[g++]=255,f.setUint32(g,1e6*a.getMilliseconds()),f.setBigInt64(g+4,BigInt(b(e)))}}},{pack(a,b,c){let d=Array.from(a),{target:e,position:f}=b(this.structuredClone?3:0);this.structuredClone&&(e[f++]=212,e[f++]=115,e[f++]=0),c(d)}},{pack(a,b,c){let{target:d,position:e}=b(this.structuredClone?3:0);this.structuredClone&&(d[e++]=212,d[e++]=101,d[e++]=0),c([a.name,a.message])}},{pack(a,b,c){let{target:d,position:e}=b(this.structuredClone?3:0);this.structuredClone&&(d[e++]=212,d[e++]=120,d[e++]=0),c([a.source,a.flags])}},{pack(a,b){this.structuredClone?s(a,16,b):t(ka?Buffer.from(a):new Uint8Array(a),b)}},{pack(a,b){let c=a.constructor;c!==ma&&this.structuredClone?s(a,$.indexOf(c.name),b):t(a,b)}},{pack(a,b){// specific 0xC1 object
|
|
106
108
|
let{target:c,position:d}=b(1);c[d]=193}}];let ua=new ta({useRecords:!1});const va=ua.pack,wa=ua.pack,{NEVER:xa,ALWAYS:ya,DECIMAL_ROUND:za,DECIMAL_FIT:Aa}=ea,Ba=1e3;a.ALWAYS=ya,a.C1=N,a.DECIMAL_FIT=Aa,a.DECIMAL_ROUND=za,a.Decoder=P,a.Encoder=ta,a.FLOAT32_OPTIONS=ea,a.NEVER=xa,a.Packr=ta,a.REUSE_BUFFER_MODE=Ba,a.Unpackr=P,a.addExtension=w,a.clearSource=q,a.decode=da,a.decodeIter=function(a,b={}){if(!a||"object"!=typeof a)throw new Error("first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a promise");const c=new P(b);let d;const e=a=>{let b;// if there's incomplete data from previous chunk, concatinate and try again
|
|
107
109
|
d&&(a=Buffer.concat([d,a]),d=void 0);try{b=c.unpackMultiple(a)}catch(c){if(c.incomplete)d=a.slice(c.lastPosition),b=c.values;else throw c}return b};if("function"==typeof a[Symbol.iterator])return function*(){for(const b of a)yield*e(b)}();return"function"==typeof a[Symbol.asyncIterator]?async function*(){for await(const b of a)yield*e(b)}():void 0},a.encode=wa,a.encodeIter=/**
|
|
108
110
|
* Given an Iterable first argument, returns an Iterable where each value is packed as a Buffer
|
|
@@ -110,4 +112,4 @@ d&&(a=Buffer.concat([d,a]),d=void 0);try{b=c.unpackMultiple(a)}catch(c){if(c.inc
|
|
|
110
112
|
* @param {Iterable|Iterator|AsyncIterable|AsyncIterator} objectIterator - iterable source, like a Readable object stream, an array, Set, or custom object
|
|
111
113
|
* @param {options} [options] - msgpackr pack options
|
|
112
114
|
* @returns {IterableIterator|Promise.<AsyncIterableIterator>}
|
|
113
|
-
*/function(a,b={}){if(!a||"object"!=typeof a)throw new Error("first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable");else{if("function"==typeof a[Symbol.iterator])return x(a,b);if("function"==typeof a.then||"function"==typeof a[Symbol.asyncIterator])return y(a,b);throw new Error("first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise")}},a.mapsAsObjects=!0,a.pack=va,a.roundFloat32=function(a){ga[0]=a;let b=_[(127&ha[3])<<1|ha[2]>>7];return(b*a+(0<a?.5:-.5)>>0)/b},a.unpack=ba,a.unpackMultiple=ca,a.useRecords=!1,Object.defineProperty(a,"__esModule",{value:!0})});
|
|
115
|
+
*/function(a,b={}){if(!a||"object"!=typeof a)throw new Error("first argument must be an Iterable, Async Iterable, or a Promise for an Async Iterable");else{if("function"==typeof a[Symbol.iterator])return x(a,b);if("function"==typeof a.then||"function"==typeof a[Symbol.asyncIterator])return y(a,b);throw new Error("first argument must be an Iterable, Async Iterable, Iterator, Async Iterator, or a Promise")}},a.isNativeAccelerationEnabled=!1,a.mapsAsObjects=!0,a.pack=va,a.roundFloat32=function(a){ga[0]=a;let b=_[(127&ha[3])<<1|ha[2]>>7];return(b*a+(0<a?.5:-.5)>>0)/b},a.unpack=ba,a.unpackMultiple=ca,a.useRecords=!1,Object.defineProperty(a,"__esModule",{value:!0})});
|
package/dist/node.cjs
CHANGED
|
@@ -64,8 +64,16 @@ class Unpackr {
|
|
|
64
64
|
// this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
|
|
65
65
|
// technique for getting data from a database where it can be copied into an existing buffer instead of creating
|
|
66
66
|
// new ones
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
try {
|
|
68
|
+
dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength));
|
|
69
|
+
} catch(error) {
|
|
70
|
+
// if it doesn't have a buffer, maybe it is the wrong type of object
|
|
71
|
+
src = null;
|
|
72
|
+
if (source instanceof Uint8Array)
|
|
73
|
+
throw error
|
|
74
|
+
throw new Error('Source must be a Uint8Array or Buffer but was a ' + ((source && typeof source == 'object') ? source.constructor.name : typeof source))
|
|
75
|
+
}
|
|
76
|
+
if (this instanceof Unpackr) {
|
|
69
77
|
currentUnpackr = this;
|
|
70
78
|
if (this.structures) {
|
|
71
79
|
currentStructures = this.structures;
|
|
@@ -297,10 +305,11 @@ function read() {
|
|
|
297
305
|
position += 4;
|
|
298
306
|
return value
|
|
299
307
|
case 0xcf:
|
|
300
|
-
if (currentUnpackr.
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
308
|
+
if (currentUnpackr.int64AsNumber) {
|
|
309
|
+
value = dataView.getUint32(position) * 0x100000000;
|
|
310
|
+
value += dataView.getUint32(position + 4);
|
|
311
|
+
} else
|
|
312
|
+
value = dataView.getBigUint64(position);
|
|
304
313
|
position += 8;
|
|
305
314
|
return value
|
|
306
315
|
|
|
@@ -316,7 +325,11 @@ function read() {
|
|
|
316
325
|
position += 4;
|
|
317
326
|
return value
|
|
318
327
|
case 0xd3:
|
|
319
|
-
|
|
328
|
+
if (currentUnpackr.int64AsNumber) {
|
|
329
|
+
value = dataView.getInt32(position) * 0x100000000;
|
|
330
|
+
value += dataView.getUint32(position + 4);
|
|
331
|
+
} else
|
|
332
|
+
value = dataView.getBigInt64(position);
|
|
320
333
|
position += 8;
|
|
321
334
|
return value
|
|
322
335
|
|
|
@@ -465,8 +478,10 @@ var readFixedString = readStringJS;
|
|
|
465
478
|
var readString8 = readStringJS;
|
|
466
479
|
var readString16 = readStringJS;
|
|
467
480
|
var readString32 = readStringJS;
|
|
481
|
+
exports.isNativeAccelerationEnabled = false;
|
|
468
482
|
|
|
469
483
|
function setExtractor(extractStrings) {
|
|
484
|
+
exports.isNativeAccelerationEnabled = true;
|
|
470
485
|
readFixedString = readString(1);
|
|
471
486
|
readString8 = readString(2);
|
|
472
487
|
readString16 = readString(3);
|
|
@@ -898,7 +913,7 @@ currentExtensions[0xff] = (data) => {
|
|
|
898
913
|
((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +
|
|
899
914
|
(((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)
|
|
900
915
|
else
|
|
901
|
-
|
|
916
|
+
return new Date('invalid')
|
|
902
917
|
}; // notepack defines extension 0 to mean undefined, so use that as the default here
|
|
903
918
|
// registration of bulk record definition?
|
|
904
919
|
// currentExtensions[0x52] = () =>
|
|
@@ -1147,9 +1162,9 @@ class Packr extends Unpackr {
|
|
|
1147
1162
|
// first we estimate the header size, so we can write to the correct location
|
|
1148
1163
|
if (strLength < 0x20) {
|
|
1149
1164
|
headerSize = 1;
|
|
1150
|
-
} else if (strLength <
|
|
1165
|
+
} else if (strLength < 0x100) {
|
|
1151
1166
|
headerSize = 2;
|
|
1152
|
-
} else if (strLength <
|
|
1167
|
+
} else if (strLength < 0x10000) {
|
|
1153
1168
|
headerSize = 3;
|
|
1154
1169
|
} else {
|
|
1155
1170
|
headerSize = 5;
|
|
@@ -1562,7 +1577,7 @@ class Packr extends Unpackr {
|
|
|
1562
1577
|
if ((end - start) > MAX_BUFFER_SIZE)
|
|
1563
1578
|
throw new Error('Packed buffer would be larger than maximum buffer size')
|
|
1564
1579
|
newSize = Math.min(MAX_BUFFER_SIZE,
|
|
1565
|
-
Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2),
|
|
1580
|
+
Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000);
|
|
1566
1581
|
} else // faster handling for smaller buffers
|
|
1567
1582
|
newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12;
|
|
1568
1583
|
let newBuffer = new ByteArrayAllocate(newSize);
|
|
@@ -1587,7 +1602,7 @@ class Packr extends Unpackr {
|
|
|
1587
1602
|
|
|
1588
1603
|
extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ];
|
|
1589
1604
|
extensions = [{
|
|
1590
|
-
pack(date, allocateForWrite) {
|
|
1605
|
+
pack(date, allocateForWrite, pack) {
|
|
1591
1606
|
let seconds = date.getTime() / 1000;
|
|
1592
1607
|
if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
|
|
1593
1608
|
// Timestamp 32
|
|
@@ -1602,6 +1617,14 @@ extensions = [{
|
|
|
1602
1617
|
target[position++] = 0xff;
|
|
1603
1618
|
targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0));
|
|
1604
1619
|
targetView.setUint32(position + 4, seconds);
|
|
1620
|
+
} else if (isNaN(seconds)) {
|
|
1621
|
+
if (this.onInvalidDate)
|
|
1622
|
+
return pack(this.onInvalidDate())
|
|
1623
|
+
// Intentionally invalid timestamp
|
|
1624
|
+
let { target, targetView, position} = allocateForWrite(3);
|
|
1625
|
+
target[position++] = 0xd4;
|
|
1626
|
+
target[position++] = 0xff;
|
|
1627
|
+
target[position++] = 0xff;
|
|
1605
1628
|
} else {
|
|
1606
1629
|
// Timestamp 96
|
|
1607
1630
|
let { target, targetView, position} = allocateForWrite(15);
|
|
@@ -1939,9 +1962,7 @@ function tryRequire(moduleId) {
|
|
|
1939
1962
|
let require$1 = module$1.createRequire((typeof document === 'undefined' ? new (require('u' + 'rl').URL)('file:' + __filename).href : (document.currentScript && document.currentScript.src || new URL('node.cjs', document.baseURI).href)));
|
|
1940
1963
|
return require$1(moduleId)
|
|
1941
1964
|
} catch (error) {
|
|
1942
|
-
if (typeof window
|
|
1943
|
-
console.warn('Native extraction module not loaded, msgpackr will still run, but with decreased performance. ' + error.message.split('\n')[0]);
|
|
1944
|
-
else
|
|
1965
|
+
if (typeof window != 'undefined')
|
|
1945
1966
|
console.warn('For browser usage, directly use msgpackr/unpack or msgpackr/pack modules. ' + error.message.split('\n')[0]);
|
|
1946
1967
|
}
|
|
1947
1968
|
}
|
package/dist/str.cjs
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
let utfz = require('../../msgpack-benchmark/node_modules/utfz-lib')
|
|
2
|
+
|
|
3
|
+
var safeEnd = 1000000;
|
|
4
|
+
var b = new Uint8Array(32768)
|
|
5
|
+
function writeString(value, target, position) {
|
|
6
|
+
var length, strLength = value.length;
|
|
7
|
+
let headerSize;
|
|
8
|
+
// first we estimate the header size, so we can write to the correct location
|
|
9
|
+
if (strLength < 0x20) {
|
|
10
|
+
headerSize = 1;
|
|
11
|
+
} else if (strLength < 0x100) {
|
|
12
|
+
headerSize = 2;
|
|
13
|
+
} else if (strLength < 0x10000) {
|
|
14
|
+
headerSize = 3;
|
|
15
|
+
} else {
|
|
16
|
+
headerSize = 5;
|
|
17
|
+
}
|
|
18
|
+
let maxBytes = strLength * 3;
|
|
19
|
+
//if (position + maxBytes > safeEnd)
|
|
20
|
+
// target = makeRoom(position + maxBytes);
|
|
21
|
+
for (let i = 0; i < 100; i++) {
|
|
22
|
+
length = pack(value, strLength, target, position + headerSize);
|
|
23
|
+
}
|
|
24
|
+
if (strLength < 0x40 || !encodeUtf8) {
|
|
25
|
+
var strPosition = position + headerSize;
|
|
26
|
+
var c2 = 0;
|
|
27
|
+
for (let i = 0; i < strLength; i++) {
|
|
28
|
+
const c1 = value.charCodeAt(i);
|
|
29
|
+
if (c1 < 0x80) {
|
|
30
|
+
target[strPosition++] = c1;
|
|
31
|
+
} else if (c1 < 0x800) {
|
|
32
|
+
target[strPosition++] = c1 >> 6 | 0xc0;
|
|
33
|
+
target[strPosition++] = c1 & 0x3f | 0x80;
|
|
34
|
+
} else if (
|
|
35
|
+
(c1 & 0xfc00) === 0xd800 &&
|
|
36
|
+
((c2 = value.charCodeAt(i + 1)) & 0xfc00) === 0xdc00
|
|
37
|
+
) {
|
|
38
|
+
c1 = 0x10000 + ((c1 & 0x03ff) << 10) + (c2 & 0x03ff);
|
|
39
|
+
i++;
|
|
40
|
+
target[strPosition++] = c1 >> 18 | 0xf0;
|
|
41
|
+
target[strPosition++] = c1 >> 12 & 0x3f | 0x80;
|
|
42
|
+
target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
|
|
43
|
+
target[strPosition++] = c1 & 0x3f | 0x80;
|
|
44
|
+
} else {
|
|
45
|
+
target[strPosition++] = c1 >> 12 | 0xe0;
|
|
46
|
+
target[strPosition++] = c1 >> 6 & 0x3f | 0x80;
|
|
47
|
+
target[strPosition++] = c1 & 0x3f | 0x80;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
length = strPosition - position - headerSize;
|
|
51
|
+
} else {
|
|
52
|
+
length = encodeUtf8(value, position + headerSize, maxBytes);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
if (length < 0x20) {
|
|
57
|
+
target[position++] = 0xa0 | length;
|
|
58
|
+
} else if (length < 0x100) {
|
|
59
|
+
if (headerSize < 2) {
|
|
60
|
+
target.copyWithin(position + 2, position + 1, position + 1 + length);
|
|
61
|
+
}
|
|
62
|
+
target[position++] = 0xd9;
|
|
63
|
+
target[position++] = length;
|
|
64
|
+
} else if (length < 0x10000) {
|
|
65
|
+
if (headerSize < 3) {
|
|
66
|
+
target.copyWithin(position + 3, position + 2, position + 2 + length);
|
|
67
|
+
}
|
|
68
|
+
target[position++] = 0xda;
|
|
69
|
+
target[position++] = length >> 8;
|
|
70
|
+
target[position++] = length & 0xff;
|
|
71
|
+
} else {
|
|
72
|
+
if (headerSize < 5) {
|
|
73
|
+
target.copyWithin(position + 5, position + 3, position + 3 + length);
|
|
74
|
+
}
|
|
75
|
+
target[position++] = 0xdb;
|
|
76
|
+
targetView.setUint32(position, length);
|
|
77
|
+
position += 4;
|
|
78
|
+
}
|
|
79
|
+
return position + length
|
|
80
|
+
};
|
|
81
|
+
const pack = (str, length, buf, offset) => {
|
|
82
|
+
const start = offset;
|
|
83
|
+
let currHigh = 0;
|
|
84
|
+
for (let i = 0; i < length; i++) {
|
|
85
|
+
const code = str.charCodeAt(i);
|
|
86
|
+
const high = code >> 8;
|
|
87
|
+
if (high !== currHigh) {
|
|
88
|
+
buf[i + offset++] = 0;
|
|
89
|
+
buf[i + offset++] = high;
|
|
90
|
+
currHigh = high;
|
|
91
|
+
}
|
|
92
|
+
const low = code & 0xff;
|
|
93
|
+
buf[i + offset] = low;
|
|
94
|
+
if (!low) {
|
|
95
|
+
buf[i + ++offset] = currHigh;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return length + offset - start;
|
|
99
|
+
};
|
|
100
|
+
module.exports = writeString;
|
package/dist/test.js
CHANGED
|
@@ -660,6 +660,13 @@
|
|
|
660
660
|
assert.deepEqual(deserialized, data);
|
|
661
661
|
});
|
|
662
662
|
|
|
663
|
+
test('255 chars', function() {
|
|
664
|
+
const data = 'RRZG9A6I7xupPeOZhxcOcioFsuhszGOdyDUcbRf4Zef2kdPIfC9RaLO4jTM5JhuZvTsF09fbRHMGtqk7YAgu3vespeTe9l61ziZ6VrMnYu2CamK96wCkmz0VUXyqaiUoTPgzk414LS9yYrd5uh7w18ksJF5SlC2e91rukWvNqAZJjYN3jpkqHNOFchCwFrhbxq2Lrv1kSJPYCx9blRg2hGmYqTbElLTZHv20iNqwZeQbRMgSBPT6vnbCBPnOh1W';
|
|
665
|
+
var serialized = pack(data);
|
|
666
|
+
var deserialized = unpack(serialized);
|
|
667
|
+
assert.equal(deserialized, data);
|
|
668
|
+
});
|
|
669
|
+
|
|
663
670
|
test('pack/unpack sample data', function(){
|
|
664
671
|
var data = sampleData;
|
|
665
672
|
var serialized = pack(data);
|
|
@@ -982,6 +989,7 @@
|
|
|
982
989
|
date: new Date(1532219539733),
|
|
983
990
|
farFutureDate: new Date(3532219539133),
|
|
984
991
|
ancient: new Date(-3532219539133),
|
|
992
|
+
invalidDate: new Date('invalid')
|
|
985
993
|
};
|
|
986
994
|
let packr = new Packr();
|
|
987
995
|
var serialized = packr.pack(data);
|
|
@@ -991,6 +999,7 @@
|
|
|
991
999
|
assert.equal(deserialized.date.getTime(), 1532219539733);
|
|
992
1000
|
assert.equal(deserialized.farFutureDate.getTime(), 3532219539133);
|
|
993
1001
|
assert.equal(deserialized.ancient.getTime(), -3532219539133);
|
|
1002
|
+
assert.equal(deserialized.invalidDate.toString(), 'Invalid Date');
|
|
994
1003
|
});
|
|
995
1004
|
test('map/date with options', function(){
|
|
996
1005
|
var map = new Map();
|
|
@@ -1064,7 +1073,17 @@
|
|
|
1064
1073
|
var deserialized = packr.unpack(serialized);
|
|
1065
1074
|
assert.deepEqual(deserialized, data);
|
|
1066
1075
|
});
|
|
1067
|
-
|
|
1076
|
+
test('bigint to float', function() {
|
|
1077
|
+
var data = {
|
|
1078
|
+
a: 325283295382932843n
|
|
1079
|
+
};
|
|
1080
|
+
let packr = new Packr({
|
|
1081
|
+
int64AsNumber: true
|
|
1082
|
+
});
|
|
1083
|
+
var serialized = packr.pack(data);
|
|
1084
|
+
var deserialized = packr.unpack(serialized);
|
|
1085
|
+
assert.deepEqual(deserialized.a, 325283295382932843);
|
|
1086
|
+
});
|
|
1068
1087
|
test('numbers', function(){
|
|
1069
1088
|
var data = {
|
|
1070
1089
|
bigEncodable: 48978578104322,
|
package/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { Unpackr, Decoder, unpack, decode, addExtension, FLOAT32_OPTIONS, clearSource, roundFloat32 } from './unpack'
|
|
1
|
+
export { Unpackr, Decoder, unpack, decode, addExtension, FLOAT32_OPTIONS, clearSource, roundFloat32, isNativeAccelerationEnabled } from './unpack'
|
|
2
2
|
import { Options } from './unpack'
|
|
3
3
|
export { Packr, Encoder, pack, encode } from './pack'
|
|
4
4
|
import { Transform, Readable } from 'stream'
|
package/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { Packr, Encoder, addExtension, pack, encode, NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT, REUSE_BUFFER_MODE } from './pack.js'
|
|
2
|
-
export { Unpackr, Decoder, C1, unpack, unpackMultiple, decode, FLOAT32_OPTIONS, clearSource, roundFloat32 } from './unpack.js'
|
|
2
|
+
export { Unpackr, Decoder, C1, unpack, unpackMultiple, decode, FLOAT32_OPTIONS, clearSource, roundFloat32, isNativeAccelerationEnabled } from './unpack.js'
|
|
3
3
|
export { decodeIter, encodeIter } from './iterators.js'
|
|
4
4
|
export const useRecords = false
|
|
5
5
|
export const mapsAsObjects = true
|
package/node-index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { Packr, Encoder, addExtension, pack, encode, NEVER, ALWAYS, DECIMAL_ROUND, DECIMAL_FIT } from './pack.js'
|
|
2
|
-
export { Unpackr, Decoder, C1, unpack, unpackMultiple, decode, FLOAT32_OPTIONS, clearSource, roundFloat32 } from './unpack.js'
|
|
2
|
+
export { Unpackr, Decoder, C1, unpack, unpackMultiple, decode, FLOAT32_OPTIONS, clearSource, roundFloat32, isNativeAccelerationEnabled } from './unpack.js'
|
|
3
3
|
export { PackrStream, UnpackrStream, PackrStream as EncoderStream, UnpackrStream as DecoderStream } from './stream.js'
|
|
4
4
|
export { decodeIter, encodeIter } from './iterators.js'
|
|
5
5
|
export const useRecords = false
|
|
@@ -16,9 +16,7 @@ function tryRequire(moduleId) {
|
|
|
16
16
|
let require = createRequire(import.meta.url)
|
|
17
17
|
return require(moduleId)
|
|
18
18
|
} catch (error) {
|
|
19
|
-
if (typeof window
|
|
20
|
-
console.warn('Native extraction module not loaded, msgpackr will still run, but with decreased performance. ' + error.message.split('\n')[0])
|
|
21
|
-
else
|
|
19
|
+
if (typeof window != 'undefined')
|
|
22
20
|
console.warn('For browser usage, directly use msgpackr/unpack or msgpackr/pack modules. ' + error.message.split('\n')[0])
|
|
23
21
|
}
|
|
24
22
|
}
|
package/pack.js
CHANGED
|
@@ -176,9 +176,9 @@ export class Packr extends Unpackr {
|
|
|
176
176
|
// first we estimate the header size, so we can write to the correct location
|
|
177
177
|
if (strLength < 0x20) {
|
|
178
178
|
headerSize = 1
|
|
179
|
-
} else if (strLength <
|
|
179
|
+
} else if (strLength < 0x100) {
|
|
180
180
|
headerSize = 2
|
|
181
|
-
} else if (strLength <
|
|
181
|
+
} else if (strLength < 0x10000) {
|
|
182
182
|
headerSize = 3
|
|
183
183
|
} else {
|
|
184
184
|
headerSize = 5
|
|
@@ -591,7 +591,7 @@ export class Packr extends Unpackr {
|
|
|
591
591
|
if ((end - start) > MAX_BUFFER_SIZE)
|
|
592
592
|
throw new Error('Packed buffer would be larger than maximum buffer size')
|
|
593
593
|
newSize = Math.min(MAX_BUFFER_SIZE,
|
|
594
|
-
Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2),
|
|
594
|
+
Math.round(Math.max((end - start) * (end > 0x4000000 ? 1.25 : 2), 0x400000) / 0x1000) * 0x1000)
|
|
595
595
|
} else // faster handling for smaller buffers
|
|
596
596
|
newSize = ((Math.max((end - start) << 2, target.length - 1) >> 12) + 1) << 12
|
|
597
597
|
let newBuffer = new ByteArrayAllocate(newSize)
|
|
@@ -622,7 +622,7 @@ function copyBinary(source, target, targetOffset, offset, endOffset) {
|
|
|
622
622
|
|
|
623
623
|
extensionClasses = [ Date, Set, Error, RegExp, ArrayBuffer, Object.getPrototypeOf(Uint8Array.prototype).constructor /*TypedArray*/, C1Type ]
|
|
624
624
|
extensions = [{
|
|
625
|
-
pack(date, allocateForWrite) {
|
|
625
|
+
pack(date, allocateForWrite, pack) {
|
|
626
626
|
let seconds = date.getTime() / 1000
|
|
627
627
|
if ((this.useTimestamp32 || date.getMilliseconds() === 0) && seconds >= 0 && seconds < 0x100000000) {
|
|
628
628
|
// Timestamp 32
|
|
@@ -637,6 +637,14 @@ extensions = [{
|
|
|
637
637
|
target[position++] = 0xff
|
|
638
638
|
targetView.setUint32(position, date.getMilliseconds() * 4000000 + ((seconds / 1000 / 0x100000000) >> 0))
|
|
639
639
|
targetView.setUint32(position + 4, seconds)
|
|
640
|
+
} else if (isNaN(seconds)) {
|
|
641
|
+
if (this.onInvalidDate)
|
|
642
|
+
return pack(this.onInvalidDate())
|
|
643
|
+
// Intentionally invalid timestamp
|
|
644
|
+
let { target, targetView, position} = allocateForWrite(3)
|
|
645
|
+
target[position++] = 0xd4
|
|
646
|
+
target[position++] = 0xff
|
|
647
|
+
target[position++] = 0xff
|
|
640
648
|
} else {
|
|
641
649
|
// Timestamp 96
|
|
642
650
|
let { target, targetView, position} = allocateForWrite(15)
|
package/package.json
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "msgpackr",
|
|
3
3
|
"author": "Kris Zyp",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.1",
|
|
5
5
|
"description": "Ultra-fast MessagePack implementation with extensions for records and structured cloning",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"types": "./index.d.ts",
|
|
8
|
-
"main": "./dist/
|
|
8
|
+
"main": "./dist/node.cjs",
|
|
9
|
+
"module": "./index.js",
|
|
9
10
|
"keywords": [
|
|
10
11
|
"MessagePack",
|
|
11
12
|
"msgpack",
|
package/tests/test.js
CHANGED
|
@@ -84,6 +84,13 @@ suite('msgpackr basic tests', function(){
|
|
|
84
84
|
assert.deepEqual(deserialized, data)
|
|
85
85
|
})
|
|
86
86
|
|
|
87
|
+
test('255 chars', function() {
|
|
88
|
+
const data = 'RRZG9A6I7xupPeOZhxcOcioFsuhszGOdyDUcbRf4Zef2kdPIfC9RaLO4jTM5JhuZvTsF09fbRHMGtqk7YAgu3vespeTe9l61ziZ6VrMnYu2CamK96wCkmz0VUXyqaiUoTPgzk414LS9yYrd5uh7w18ksJF5SlC2e91rukWvNqAZJjYN3jpkqHNOFchCwFrhbxq2Lrv1kSJPYCx9blRg2hGmYqTbElLTZHv20iNqwZeQbRMgSBPT6vnbCBPnOh1W'
|
|
89
|
+
var serialized = pack(data)
|
|
90
|
+
var deserialized = unpack(serialized)
|
|
91
|
+
assert.equal(deserialized, data)
|
|
92
|
+
})
|
|
93
|
+
|
|
87
94
|
test('pack/unpack sample data', function(){
|
|
88
95
|
var data = sampleData
|
|
89
96
|
let structures = []
|
|
@@ -409,6 +416,7 @@ suite('msgpackr basic tests', function(){
|
|
|
409
416
|
date: new Date(1532219539733),
|
|
410
417
|
farFutureDate: new Date(3532219539133),
|
|
411
418
|
ancient: new Date(-3532219539133),
|
|
419
|
+
invalidDate: new Date('invalid')
|
|
412
420
|
}
|
|
413
421
|
let packr = new Packr()
|
|
414
422
|
var serialized = packr.pack(data)
|
|
@@ -418,6 +426,7 @@ suite('msgpackr basic tests', function(){
|
|
|
418
426
|
assert.equal(deserialized.date.getTime(), 1532219539733)
|
|
419
427
|
assert.equal(deserialized.farFutureDate.getTime(), 3532219539133)
|
|
420
428
|
assert.equal(deserialized.ancient.getTime(), -3532219539133)
|
|
429
|
+
assert.equal(deserialized.invalidDate.toString(), 'Invalid Date')
|
|
421
430
|
})
|
|
422
431
|
test('map/date with options', function(){
|
|
423
432
|
var map = new Map()
|
|
@@ -491,7 +500,17 @@ suite('msgpackr basic tests', function(){
|
|
|
491
500
|
var deserialized = packr.unpack(serialized)
|
|
492
501
|
assert.deepEqual(deserialized, data)
|
|
493
502
|
})
|
|
494
|
-
|
|
503
|
+
test('bigint to float', function() {
|
|
504
|
+
var data = {
|
|
505
|
+
a: 325283295382932843n
|
|
506
|
+
}
|
|
507
|
+
let packr = new Packr({
|
|
508
|
+
int64AsNumber: true
|
|
509
|
+
})
|
|
510
|
+
var serialized = packr.pack(data)
|
|
511
|
+
var deserialized = packr.unpack(serialized)
|
|
512
|
+
assert.deepEqual(deserialized.a, 325283295382932843)
|
|
513
|
+
})
|
|
495
514
|
test('numbers', function(){
|
|
496
515
|
var data = {
|
|
497
516
|
bigEncodable: 48978578104322,
|
package/unpack.d.ts
CHANGED
|
@@ -25,8 +25,10 @@ export interface Options {
|
|
|
25
25
|
interface Extension {
|
|
26
26
|
Class: Function
|
|
27
27
|
type: number
|
|
28
|
-
pack(value: any): Buffer | Uint8Array
|
|
29
|
-
unpack(messagePack: Buffer | Uint8Array): any
|
|
28
|
+
pack?(value: any): Buffer | Uint8Array
|
|
29
|
+
unpack?(messagePack: Buffer | Uint8Array): any
|
|
30
|
+
read?(datum: any): any
|
|
31
|
+
write?(instance: any): any
|
|
30
32
|
}
|
|
31
33
|
export class Unpackr {
|
|
32
34
|
constructor(options?: Options)
|
|
@@ -42,3 +44,4 @@ export function addExtension(extension: Extension): void
|
|
|
42
44
|
export function clearSource(): void
|
|
43
45
|
export function roundFloat32(float32Number: number): number
|
|
44
46
|
export const C1: {}
|
|
47
|
+
export let isNativeAccelerationEnabled: boolean
|
package/unpack.js
CHANGED
|
@@ -59,8 +59,16 @@ export class Unpackr {
|
|
|
59
59
|
// this provides cached access to the data view for a buffer if it is getting reused, which is a recommend
|
|
60
60
|
// technique for getting data from a database where it can be copied into an existing buffer instead of creating
|
|
61
61
|
// new ones
|
|
62
|
-
|
|
63
|
-
|
|
62
|
+
try {
|
|
63
|
+
dataView = source.dataView || (source.dataView = new DataView(source.buffer, source.byteOffset, source.byteLength))
|
|
64
|
+
} catch(error) {
|
|
65
|
+
// if it doesn't have a buffer, maybe it is the wrong type of object
|
|
66
|
+
src = null
|
|
67
|
+
if (source instanceof Uint8Array)
|
|
68
|
+
throw error
|
|
69
|
+
throw new Error('Source must be a Uint8Array or Buffer but was a ' + ((source && typeof source == 'object') ? source.constructor.name : typeof source))
|
|
70
|
+
}
|
|
71
|
+
if (this instanceof Unpackr) {
|
|
64
72
|
currentUnpackr = this
|
|
65
73
|
if (this.structures) {
|
|
66
74
|
currentStructures = this.structures
|
|
@@ -295,10 +303,11 @@ export function read() {
|
|
|
295
303
|
position += 4
|
|
296
304
|
return value
|
|
297
305
|
case 0xcf:
|
|
298
|
-
if (currentUnpackr.
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
306
|
+
if (currentUnpackr.int64AsNumber) {
|
|
307
|
+
value = dataView.getUint32(position) * 0x100000000
|
|
308
|
+
value += dataView.getUint32(position + 4)
|
|
309
|
+
} else
|
|
310
|
+
value = dataView.getBigUint64(position)
|
|
302
311
|
position += 8
|
|
303
312
|
return value
|
|
304
313
|
|
|
@@ -314,7 +323,11 @@ export function read() {
|
|
|
314
323
|
position += 4
|
|
315
324
|
return value
|
|
316
325
|
case 0xd3:
|
|
317
|
-
|
|
326
|
+
if (currentUnpackr.int64AsNumber) {
|
|
327
|
+
value = dataView.getInt32(position) * 0x100000000
|
|
328
|
+
value += dataView.getUint32(position + 4)
|
|
329
|
+
} else
|
|
330
|
+
value = dataView.getBigInt64(position)
|
|
318
331
|
position += 8
|
|
319
332
|
return value
|
|
320
333
|
|
|
@@ -463,8 +476,10 @@ var readFixedString = readStringJS
|
|
|
463
476
|
var readString8 = readStringJS
|
|
464
477
|
var readString16 = readStringJS
|
|
465
478
|
var readString32 = readStringJS
|
|
479
|
+
export let isNativeAccelerationEnabled = false
|
|
466
480
|
|
|
467
481
|
export function setExtractor(extractStrings) {
|
|
482
|
+
isNativeAccelerationEnabled = true
|
|
468
483
|
readFixedString = readString(1)
|
|
469
484
|
readString8 = readString(2)
|
|
470
485
|
readString16 = readString(3)
|
|
@@ -896,7 +911,7 @@ currentExtensions[0xff] = (data) => {
|
|
|
896
911
|
((data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3]) / 1000000 +
|
|
897
912
|
(((data[4] & 0x80) ? -0x1000000000000 : 0) + data[6] * 0x10000000000 + data[7] * 0x100000000 + data[8] * 0x1000000 + (data[9] << 16) + (data[10] << 8) + data[11]) * 1000)
|
|
898
913
|
else
|
|
899
|
-
|
|
914
|
+
return new Date('invalid')
|
|
900
915
|
} // notepack defines extension 0 to mean undefined, so use that as the default here
|
|
901
916
|
// registration of bulk record definition?
|
|
902
917
|
// currentExtensions[0x52] = () =>
|
|
@@ -951,8 +966,6 @@ export const mult10 = new Array(147) // this is a table matching binary exponent
|
|
|
951
966
|
for (let i = 0; i < 256; i++) {
|
|
952
967
|
mult10[i] = +('1e' + Math.floor(45.15 - i * 0.30103))
|
|
953
968
|
}
|
|
954
|
-
export const useRecords = false
|
|
955
|
-
export const mapsAsObjects = true
|
|
956
969
|
export const Decoder = Unpackr
|
|
957
970
|
var defaultUnpackr = new Unpackr({ useRecords: false })
|
|
958
971
|
export const unpack = defaultUnpackr.unpack
|