compact-encoding 2.13.0 → 2.15.0

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.
Files changed (5) hide show
  1. package/README.md +11 -1
  2. package/index.js +116 -15
  3. package/package.json +1 -1
  4. package/raw.js +25 -0
  5. package/test.js +142 -0
package/README.md CHANGED
@@ -94,11 +94,16 @@ to build others on top. Feel free to PR more that are missing.
94
94
  * `cenc.int48` - Encodes a fixed size int48 using `cenc.uint48` with ZigZag encoding.
95
95
  * `cenc.int56` - Encodes a fixed size int56 using `cenc.uint56` with ZigZag encoding.
96
96
  * `cenc.int64` - Encodes a fixed size int64 using `cenc.uint64` with ZigZag encoding.
97
- * `cenc.lexint` - Encodes an int using [lexicographic-integer](https://github.com/substack/lexicographic-integer) encoding so that encoded values are lexicographically sorted in ascending numerical order.
97
+ * `cenc.biguint64` - Encodes a fixed size biguint64.
98
+ * `cenc.bigint64` - Encodes a fixed size bigint64 using `cenc.biguint64` with ZigZag encoding.
99
+ * `cenc.biguint` - Encodes a biguint with its word count uint prefixed.
100
+ * `cenc.bigint` - Encodes a bigint using `cenc.biguint` with ZigZag encoding.
98
101
  * `cenc.float32` - Encodes a fixed size float32.
99
102
  * `cenc.float64` - Encodes a fixed size float64.
100
103
  * `cenc.buffer` - Encodes a buffer with its length uint prefixed. When decoding an empty buffer, `null` is returned.
101
104
  * `cenc.raw.buffer` - Encodes a buffer without a length prefixed.
105
+ * `cenc.arraybuffer` - Encodes an arraybuffer with its length uint prefixed.
106
+ * `cenc.raw.arraybuffer` - Encodes an arraybuffer without a length prefixed.
102
107
  * `cenc.uint8array` - Encodes a uint8array with its element length uint prefixed.
103
108
  * `cenc.raw.uint8array` - Encodes a uint8array without a length prefixed.
104
109
  * `cenc.uint16array` - Encodes a uint16array with its element length uint prefixed.
@@ -111,6 +116,10 @@ to build others on top. Feel free to PR more that are missing.
111
116
  * `cenc.raw.int16array` - Encodes a int16array without a length prefixed.
112
117
  * `cenc.int32array` - Encodes a int32array with its element length uint prefixed.
113
118
  * `cenc.raw.int32array` - Encodes a int32array without a length prefixed.
119
+ * `cenc.biguint64array` - Encodes a biguint64array with its element length uint prefixed.
120
+ * `cenc.raw.biguint64array` - Encodes a biguint64array without a length prefixed.
121
+ * `cenc.bigint64array` - Encodes a bigint64array with its element length uint prefixed.
122
+ * `cenc.raw.bigint64array` - Encodes a bigint64array without a length prefixed.
114
123
  * `cenc.float32array` - Encodes a float32array with its element length uint prefixed.
115
124
  * `cenc.raw.float32array` - Encodes a float32array without a length prefixed.
116
125
  * `cenc.float64array` - Encodes a float64array with its element length uint prefixed.
@@ -142,6 +151,7 @@ to build others on top. Feel free to PR more that are missing.
142
151
  * `cenc.raw.ndjson` - Encodes a JSON value as newline delimited utf-8 without a length prefixed.
143
152
  * `cenc.any` - Encodes any JSON representable value into a self described buffer. Like JSON + buffer, but using compact types. Useful for schemaless codecs.
144
153
  * `cenc.from(enc)` - Makes a compact encoder from a [codec](https://github.com/mafintosh/codecs) or [abstract-encoding](https://github.com/mafintosh/abstract-encoding).
154
+ * `cenc.none` - Helper for when you want to just express nothing
145
155
 
146
156
  ## License
147
157
 
package/index.js CHANGED
@@ -164,15 +164,65 @@ const uint64 = exports.uint64 = {
164
164
  }
165
165
  }
166
166
 
167
- exports.int = zigZag(uint)
168
- exports.int8 = zigZag(uint8)
169
- exports.int16 = zigZag(uint16)
170
- exports.int24 = zigZag(uint24)
171
- exports.int32 = zigZag(uint32)
172
- exports.int40 = zigZag(uint40)
173
- exports.int48 = zigZag(uint48)
174
- exports.int56 = zigZag(uint56)
175
- exports.int64 = zigZag(uint64)
167
+ exports.int = zigZagInt(uint)
168
+ exports.int8 = zigZagInt(uint8)
169
+ exports.int16 = zigZagInt(uint16)
170
+ exports.int24 = zigZagInt(uint24)
171
+ exports.int32 = zigZagInt(uint32)
172
+ exports.int40 = zigZagInt(uint40)
173
+ exports.int48 = zigZagInt(uint48)
174
+ exports.int56 = zigZagInt(uint56)
175
+ exports.int64 = zigZagInt(uint64)
176
+
177
+ const biguint64 = exports.biguint64 = {
178
+ preencode (state, n) {
179
+ state.end += 8
180
+ },
181
+ encode (state, n) {
182
+ const view = new DataView(state.buffer.buffer, state.start + state.buffer.byteOffset, 8)
183
+ view.setBigUint64(0, n, true) // little endian
184
+ state.start += 8
185
+ },
186
+ decode (state) {
187
+ if (state.end - state.start < 8) throw new Error('Out of bounds')
188
+ const view = new DataView(state.buffer.buffer, state.start + state.buffer.byteOffset, 8)
189
+ const n = view.getBigUint64(0, true) // little endian
190
+ state.start += 8
191
+ return n
192
+ }
193
+ }
194
+
195
+ exports.bigint64 = zigZagBigInt(biguint64)
196
+
197
+ const biguint = exports.biguint = {
198
+ preencode (state, n) {
199
+ let len = 0
200
+ for (let m = n; m; m = m >> 64n) len++
201
+ uint.preencode(state, len)
202
+ state.end += 8 * len
203
+ },
204
+ encode (state, n) {
205
+ let len = 0
206
+ for (let m = n; m; m = m >> 64n) len++
207
+ uint.encode(state, len)
208
+ const view = new DataView(state.buffer.buffer, state.start + state.buffer.byteOffset, 8 * len)
209
+ for (let m = n, i = 0; m; m = m >> 64n, i += 8) {
210
+ view.setBigUint64(i, BigInt.asUintN(64, m), true) // little endian
211
+ }
212
+ state.start += 8 * len
213
+ },
214
+ decode (state) {
215
+ const len = uint.decode(state)
216
+ if (state.end - state.start < 8 * len) throw new Error('Out of bounds')
217
+ const view = new DataView(state.buffer.buffer, state.start + state.buffer.byteOffset, 8 * len)
218
+ let n = 0n
219
+ for (let i = len - 1; i >= 0; i--) n = (n << 64n) + view.getBigUint64(i * 8, true) // little endian
220
+ state.start += 8 * len
221
+ return n
222
+ }
223
+ }
224
+
225
+ exports.bigint = zigZagBigInt(biguint)
176
226
 
177
227
  exports.lexint = require('./lexint')
178
228
 
@@ -241,6 +291,31 @@ exports.binary = {
241
291
  }
242
292
  }
243
293
 
294
+ exports.arraybuffer = {
295
+ preencode (state, b) {
296
+ uint.preencode(state, b.byteLength)
297
+ state.end += b.byteLength
298
+ },
299
+ encode (state, b) {
300
+ uint.encode(state, b.byteLength)
301
+
302
+ const view = new Uint8Array(b)
303
+
304
+ state.buffer.set(view, state.start)
305
+ state.start += b.byteLength
306
+ },
307
+ decode (state) {
308
+ const len = uint.decode(state)
309
+
310
+ const b = new ArrayBuffer(len)
311
+ const view = new Uint8Array(b)
312
+
313
+ view.set(state.buffer.subarray(state.start, state.start += len))
314
+
315
+ return b
316
+ }
317
+ }
318
+
244
319
  function typedarray (TypedArray, swap) {
245
320
  const n = TypedArray.BYTES_PER_ELEMENT
246
321
 
@@ -281,6 +356,9 @@ exports.int8array = typedarray(Int8Array)
281
356
  exports.int16array = typedarray(Int16Array, b4a.swap16)
282
357
  exports.int32array = typedarray(Int32Array, b4a.swap32)
283
358
 
359
+ exports.biguint64array = typedarray(BigUint64Array, b4a.swap64)
360
+ exports.bigint64array = typedarray(BigInt64Array, b4a.swap64)
361
+
284
362
  exports.float32array = typedarray(Float32Array, b4a.swap32)
285
363
  exports.float64array = typedarray(Float64Array, b4a.swap64)
286
364
 
@@ -614,25 +692,48 @@ exports.decode = function decode (enc, buffer) {
614
692
  return enc.decode(exports.state(0, buffer.byteLength, buffer))
615
693
  }
616
694
 
617
- function zigZag (enc) {
695
+ function zigZagInt (enc) {
618
696
  return {
619
697
  preencode (state, n) {
620
- enc.preencode(state, zigZagEncode(n))
698
+ enc.preencode(state, zigZagEncodeInt(n))
621
699
  },
622
700
  encode (state, n) {
623
- enc.encode(state, zigZagEncode(n))
701
+ enc.encode(state, zigZagEncodeInt(n))
624
702
  },
625
703
  decode (state) {
626
- return zigZagDecode(enc.decode(state))
704
+ return zigZagDecodeInt(enc.decode(state))
627
705
  }
628
706
  }
629
707
  }
630
708
 
631
- function zigZagDecode (n) {
709
+ function zigZagDecodeInt (n) {
632
710
  return n === 0 ? n : (n & 1) === 0 ? n / 2 : -(n + 1) / 2
633
711
  }
634
712
 
635
- function zigZagEncode (n) {
713
+ function zigZagEncodeInt (n) {
636
714
  // 0, -1, 1, -2, 2, ...
637
715
  return n < 0 ? (2 * -n) - 1 : n === 0 ? 0 : 2 * n
638
716
  }
717
+
718
+ function zigZagBigInt (enc) {
719
+ return {
720
+ preencode (state, n) {
721
+ enc.preencode(state, zigZagEncodeBigInt(n))
722
+ },
723
+ encode (state, n) {
724
+ enc.encode(state, zigZagEncodeBigInt(n))
725
+ },
726
+ decode (state) {
727
+ return zigZagDecodeBigInt(enc.decode(state))
728
+ }
729
+ }
730
+ }
731
+
732
+ function zigZagDecodeBigInt (n) {
733
+ return n === 0n ? n : (n & 1n) === 0n ? n / 2n : -(n + 1n) / 2n
734
+ }
735
+
736
+ function zigZagEncodeBigInt (n) {
737
+ // 0, -1, 1, -2, 2, ...
738
+ return n < 0n ? (2n * -n) - 1n : n === 0n ? 0n : 2n * n
739
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "compact-encoding",
3
- "version": "2.13.0",
3
+ "version": "2.15.0",
4
4
  "description": "A series of compact encoding schemes for building small and fast parsers and serializers",
5
5
  "main": "index.js",
6
6
  "dependencies": {
package/raw.js CHANGED
@@ -46,6 +46,28 @@ exports.binary = {
46
46
  }
47
47
  }
48
48
 
49
+ exports.arraybuffer = {
50
+ preencode (state, b) {
51
+ state.end += b.byteLength
52
+ },
53
+ encode (state, b) {
54
+ const view = new Uint8Array(b)
55
+
56
+ state.buffer.set(view, state.start)
57
+ state.start += b.byteLength
58
+ },
59
+ decode (state) {
60
+ const b = new ArrayBuffer(state.end - state.start)
61
+ const view = new Uint8Array(b)
62
+
63
+ view.set(state.buffer.subarray(state.start))
64
+
65
+ state.start = state.end
66
+
67
+ return b
68
+ }
69
+ }
70
+
49
71
  function typedarray (TypedArray, swap) {
50
72
  const n = TypedArray.BYTES_PER_ELEMENT
51
73
 
@@ -82,6 +104,9 @@ exports.int8array = typedarray(Int8Array)
82
104
  exports.int16array = typedarray(Int16Array, b4a.swap16)
83
105
  exports.int32array = typedarray(Int32Array, b4a.swap32)
84
106
 
107
+ exports.biguint64array = typedarray(BigUint64Array, b4a.swap64)
108
+ exports.bigint64array = typedarray(BigInt64Array, b4a.swap64)
109
+
85
110
  exports.float32array = typedarray(Float32Array, b4a.swap32)
86
111
  exports.float64array = typedarray(Float64Array, b4a.swap64)
87
112
 
package/test.js CHANGED
@@ -146,6 +146,82 @@ test('float64', function (t) {
146
146
  t.is(state.start, state.end)
147
147
  })
148
148
 
149
+ test('biguint64', function (t) {
150
+ const state = enc.state()
151
+
152
+ const n = 0x0102030405060708n
153
+
154
+ enc.biguint64.preencode(state, n)
155
+ t.alike(state, enc.state(0, 8))
156
+
157
+ state.buffer = b4a.alloc(state.end)
158
+ enc.biguint64.encode(state, n)
159
+ t.alike(state, enc.state(8, 8, b4a.from([0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1])))
160
+
161
+ state.start = 0
162
+ t.is(enc.biguint64.decode(state), n)
163
+ t.is(state.start, state.end)
164
+
165
+ t.exception(() => enc.biguint64.decode(state))
166
+ })
167
+
168
+ test('bigint64', function (t) {
169
+ const state = enc.state()
170
+
171
+ const n = -0x0102030405060708n
172
+
173
+ enc.bigint64.preencode(state, n)
174
+ t.alike(state, enc.state(0, 8))
175
+
176
+ state.buffer = b4a.alloc(state.end)
177
+ enc.bigint64.encode(state, n)
178
+ t.alike(state, enc.state(8, 8, b4a.from([0xf, 0xe, 0xc, 0xa, 0x8, 0x6, 0x4, 0x2])))
179
+
180
+ state.start = 0
181
+ t.is(enc.bigint64.decode(state), n)
182
+ t.is(state.start, state.end)
183
+
184
+ t.exception(() => enc.bigint64.decode(state))
185
+ })
186
+
187
+ test('biguint', function (t) {
188
+ const state = enc.state()
189
+
190
+ const n = 0x0102030405060708090a0b0cn
191
+
192
+ enc.biguint.preencode(state, n)
193
+ t.alike(state, enc.state(0, 17))
194
+
195
+ state.buffer = b4a.alloc(state.end)
196
+ enc.biguint.encode(state, n)
197
+ t.alike(state, enc.state(17, 17, b4a.from([2, 0xc, 0xb, 0xa, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0])))
198
+
199
+ state.start = 0
200
+ t.is(enc.biguint.decode(state), n)
201
+ t.is(state.start, state.end)
202
+
203
+ t.exception(() => enc.biguint.decode(state))
204
+ })
205
+
206
+ test('bigint', function (t) {
207
+ const state = enc.state()
208
+
209
+ const n = -0x0102030405060708090a0b0cn
210
+
211
+ enc.bigint.preencode(state, n)
212
+ t.alike(state, enc.state(0, 17))
213
+
214
+ state.buffer = b4a.alloc(state.end)
215
+ enc.bigint.encode(state, n)
216
+ t.alike(state, enc.state(17, 17, b4a.from([2, 0x17, 0x16, 0x14, 0x12, 0x10, 0xe, 0xc, 0xa, 0x8, 0x6, 0x4, 0x2, 0x0, 0x0, 0x0, 0x0])))
217
+
218
+ state.start = 0
219
+ t.is(enc.bigint.decode(state), n)
220
+ t.is(state.start, state.end)
221
+
222
+ t.exception(() => enc.bigint.decode(state))
223
+ })
224
+
149
225
  test('buffer', function (t) {
150
226
  const state = enc.state()
151
227
 
@@ -173,6 +249,34 @@ test('buffer', function (t) {
173
249
  t.exception(() => enc.buffer.decode(state))
174
250
  })
175
251
 
252
+ test('arraybuffer', function (t) {
253
+ const state = enc.state()
254
+
255
+ const b1 = new ArrayBuffer(4)
256
+ b4a.from(b1).fill('a')
257
+
258
+ const b2 = new ArrayBuffer(8)
259
+ b4a.from(b2).fill('b')
260
+
261
+ enc.arraybuffer.preencode(state, b1)
262
+ t.alike(state, enc.state(0, 5))
263
+ enc.arraybuffer.preencode(state, b2)
264
+ t.alike(state, enc.state(0, 14))
265
+
266
+ state.buffer = b4a.alloc(state.end)
267
+ enc.arraybuffer.encode(state, b1)
268
+ t.alike(state, enc.state(5, 14, b4a.from('\x04aaaa\x00\x00\x00\x00\x00\x00\x00\x00\x00')))
269
+ enc.arraybuffer.encode(state, b2)
270
+ t.alike(state, enc.state(14, 14, b4a.from('\x04aaaa\x08bbbbbbbb')))
271
+
272
+ state.start = 0
273
+ t.alike(enc.arraybuffer.decode(state), b1)
274
+ t.alike(enc.arraybuffer.decode(state), b2)
275
+ t.is(state.start, state.end)
276
+
277
+ t.exception(() => enc.arraybuffer.decode(state))
278
+ })
279
+
176
280
  test('raw', function (t) {
177
281
  const state = enc.state()
178
282
 
@@ -280,6 +384,44 @@ test('int32array', function (t) {
280
384
  t.exception(() => enc.int32array.decode(state))
281
385
  })
282
386
 
387
+ test('biguint64array', function (t) {
388
+ const state = enc.state()
389
+
390
+ const arr = new BigUint64Array([0x01020304n, 0x05060708n, 0x090a0b0cn])
391
+
392
+ enc.biguint64array.preencode(state, arr)
393
+ t.alike(state, enc.state(0, 25))
394
+
395
+ state.buffer = b4a.alloc(state.end)
396
+ enc.biguint64array.encode(state, arr)
397
+ t.alike(state, enc.state(25, 25, b4a.from([3, 0x4, 0x3, 0x2, 0x1, 0x0, 0x0, 0x0, 0x0, 0x8, 0x7, 0x6, 0x5, 0x0, 0x0, 0x0, 0x0, 0xc, 0xb, 0xa, 0x9, 0x0, 0x0, 0x0, 0x0])))
398
+
399
+ state.start = 0
400
+ t.alike(enc.biguint64array.decode(state), arr)
401
+ t.is(state.start, state.end)
402
+
403
+ t.exception(() => enc.biguint64array.decode(state))
404
+ })
405
+
406
+ test('bigint64array', function (t) {
407
+ const state = enc.state()
408
+
409
+ const arr = new BigInt64Array([-0x01020304n, 0x05060708n, -0x090a0b0cn])
410
+
411
+ enc.bigint64array.preencode(state, arr)
412
+ t.alike(state, enc.state(0, 25))
413
+
414
+ state.buffer = b4a.alloc(state.end)
415
+ enc.bigint64array.encode(state, arr)
416
+ t.alike(state, enc.state(25, 25, b4a.from([3, 0xfc, 0xfc, 0xfd, 0xfe, 0xff, 0xff, 0xff, 0xff, 0x8, 0x7, 0x6, 0x5, 0x0, 0x0, 0x0, 0x0, 0xf4, 0xf4, 0xf5, 0xf6, 0xff, 0xff, 0xff, 0xff])))
417
+
418
+ state.start = 0
419
+ t.alike(enc.bigint64array.decode(state), arr)
420
+ t.is(state.start, state.end)
421
+
422
+ t.exception(() => enc.bigint64array.decode(state))
423
+ })
424
+
283
425
  test('float32array', function (t) {
284
426
  const state = enc.state()
285
427