compact-encoding 2.5.1 → 2.6.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 (4) hide show
  1. package/README.md +8 -1
  2. package/index.js +47 -66
  3. package/package.json +2 -2
  4. package/test.js +85 -0
package/README.md CHANGED
@@ -90,7 +90,14 @@ to build others on top. Feel free to PR more that are missing.
90
90
  * `cenc.float64` - Encodes a fixed size float64.
91
91
  * `cenc.buffer` - Encodes a buffer with its length uint prefixed. When decoding an empty buffer, `null` is returned.
92
92
  * `cenc.raw` - Pass through encodes a buffer, i.e. a basic copy.
93
- * `cenc.uint32array` - Encodes a uint32array with its element length uint32 prefixed.
93
+ * `cenc.uint8array` - Encodes a uint8array with its element length uint prefixed.
94
+ * `cenc.uint16array` - Encodes a uint16array with its element length uint prefixed.
95
+ * `cenc.uint32array` - Encodes a uint32array with its element length uint prefixed.
96
+ * `cenc.int8array` - Encodes a int8array with its element length uint prefixed.
97
+ * `cenc.int16array` - Encodes a int16array with its element length uint prefixed.
98
+ * `cenc.int32array` - Encodes a int32array with its element length uint prefixed.
99
+ * `cenc.float32array` - Encodes a float32array with its element length uint prefixed.
100
+ * `cenc.float64array` - Encodes a float64array with its element length uint prefixed.
94
101
  * `cenc.bool` - Encodes a boolean as 1 or 0.
95
102
  * `cenc.string` - Encodes a utf-8 string, similar to buffer.
96
103
  * `cenc.fixed32` - Encodes a fixed 32 byte buffer.
package/index.js CHANGED
@@ -1,4 +1,4 @@
1
- const b = require('b4a')
1
+ const b4a = require('b4a')
2
2
 
3
3
  const LE = (new Uint8Array(new Uint16Array([255]).buffer))[0] === 0xff
4
4
  const BE = !LE
@@ -163,21 +163,12 @@ exports.float64 = {
163
163
 
164
164
  exports.buffer = {
165
165
  preencode (state, b) {
166
- if (b) {
167
- uint.preencode(state, b.length)
168
- state.end += b.length
169
- } else {
170
- state.end++
171
- }
166
+ if (b) uint8array.preencode(state, b)
167
+ else state.end++
172
168
  },
173
169
  encode (state, b) {
174
- if (b) {
175
- uint.encode(state, b.length)
176
- state.buffer.set(b, state.start)
177
- state.start += b.length
178
- } else {
179
- state.buffer[state.start++] = 0
180
- }
170
+ if (b) uint8array.encode(state, b)
171
+ else state.buffer[state.start++] = 0
181
172
  },
182
173
  decode (state) {
183
174
  const len = uint.decode(state)
@@ -203,57 +194,65 @@ const raw = exports.raw = {
203
194
  }
204
195
  }
205
196
 
206
- exports.uint32array = {
207
- preencode (state, b) {
208
- uint.preencode(state, b.length)
209
- state.end += b.byteLength
210
- },
211
- encode (state, b) {
212
- uint.encode(state, b.length)
213
- const view = new Uint8Array(b.buffer, b.byteOffset, b.byteLength)
214
- if (BE) hostToLE32(view, b.length)
215
- state.buffer.set(view, state.start)
216
- state.start += b.byteLength
217
- },
218
- decode (state) {
219
- const len = uint.decode(state)
197
+ function typedarray (TypedArray, swap) {
198
+ const n = TypedArray.BYTES_PER_ELEMENT
220
199
 
221
- const byteOffset = state.buffer.byteOffset + state.start
222
- const s = state.start
200
+ return {
201
+ preencode (state, b) {
202
+ uint.preencode(state, b.length)
203
+ state.end += b.byteLength
204
+ },
205
+ encode (state, b) {
206
+ uint.encode(state, b.length)
223
207
 
224
- state.start += len * 4
208
+ const view = new Uint8Array(b.buffer, b.byteOffset, b.byteLength)
225
209
 
226
- if ((byteOffset & 3) === 0) {
227
- const arr = new Uint32Array(state.buffer.buffer, byteOffset, len)
228
- if (BE) LEToHost32(arr, len)
229
- return arr
230
- }
210
+ if (BE && swap) swap(view)
231
211
 
232
- // align mismatch
233
- const copy = new Uint8Array(len * 4)
234
- const arr = new Uint32Array(copy.buffer, copy.byteOffset, len)
235
- copy.set(state.buffer.subarray(s, state.start), 0)
236
- if (BE) LEToHost32(arr, len)
237
- return arr
212
+ state.buffer.set(view, state.start)
213
+ state.start += b.byteLength
214
+ },
215
+ decode (state) {
216
+ const len = uint.decode(state)
217
+
218
+ let b = state.buffer.subarray(state.start, state.start += len * n)
219
+ if (b.byteLength !== len * n) throw new Error('Out of bounds')
220
+ if ((b.byteOffset % n) !== 0) b = new Uint8Array(b)
221
+
222
+ if (BE && swap) swap(b)
223
+
224
+ return new TypedArray(b.buffer, b.byteOffset, b.byteLength / n)
225
+ }
238
226
  }
239
227
  }
240
228
 
229
+ const uint8array = exports.uint8array = typedarray(Uint8Array)
230
+ exports.uint16array = typedarray(Uint16Array, b4a.swap16)
231
+ exports.uint32array = typedarray(Uint32Array, b4a.swap32)
232
+
233
+ exports.int8array = typedarray(Int8Array)
234
+ exports.int16array = typedarray(Int16Array, b4a.swap16)
235
+ exports.int32array = typedarray(Int32Array, b4a.swap32)
236
+
237
+ exports.float32array = typedarray(Float32Array, b4a.swap32)
238
+ exports.float64array = typedarray(Float64Array, b4a.swap64)
239
+
241
240
  exports.string = {
242
241
  preencode (state, s) {
243
- const len = b.byteLength(s)
242
+ const len = b4a.byteLength(s)
244
243
  uint.preencode(state, len)
245
244
  state.end += len
246
245
  },
247
246
  encode (state, s) {
248
- const len = b.byteLength(s)
247
+ const len = b4a.byteLength(s)
249
248
  uint.encode(state, len)
250
- b.write(state.buffer, s, state.start)
249
+ b4a.write(state.buffer, s, state.start)
251
250
  state.start += len
252
251
  },
253
252
  decode (state) {
254
253
  const len = uint.decode(state)
255
- const s = b.toString(state.buffer, 'utf8', state.start, state.start += len)
256
- if (b.byteLength(s) !== len || state.start > state.end) throw new Error('Out of bounds')
254
+ const s = b4a.toString(state.buffer, 'utf-8', state.start, state.start += len)
255
+ if (b4a.byteLength(s) !== len || state.start > state.end) throw new Error('Out of bounds')
257
256
  return s
258
257
  }
259
258
  }
@@ -369,7 +368,7 @@ function fromAbstractEncoder (enc) {
369
368
  exports.encode = function encode (enc, m) {
370
369
  const state = { start: 0, end: 0, buffer: null }
371
370
  enc.preencode(state, m)
372
- state.buffer = b.allocUnsafe(state.end)
371
+ state.buffer = b4a.allocUnsafe(state.end)
373
372
  enc.encode(state, m)
374
373
  return state.buffer
375
374
  }
@@ -378,24 +377,6 @@ exports.decode = function decode (enc, buffer) {
378
377
  return enc.decode({ start: 0, end: buffer.byteLength, buffer })
379
378
  }
380
379
 
381
- function LEToHost32 (arr, len) {
382
- const view = new DataView(arr.buffer, arr.byteOffset)
383
- const host = new Uint32Array(arr.buffer, arr.byteOffset, len)
384
-
385
- for (let i = 0; i < host.length; i++) {
386
- host[i] = view.getUint32(4 * i, BE)
387
- }
388
- }
389
-
390
- function hostToLE32 (arr, len) {
391
- const view = new DataView(arr.buffer, arr.byteOffset)
392
- const host = new Uint32Array(arr.buffer, arr.byteOffset, len)
393
-
394
- for (let i = 0; i < host.length; i++) {
395
- view.setUint32(4 * i, host[i], BE)
396
- }
397
- }
398
-
399
380
  function zigZag (enc) {
400
381
  return {
401
382
  preencode (state, n) {
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "compact-encoding",
3
- "version": "2.5.1",
3
+ "version": "2.6.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": {
7
- "b4a": "^1.0.0"
7
+ "b4a": "^1.3.0"
8
8
  },
9
9
  "devDependencies": {
10
10
  "brittle": "^1.5.1",
package/test.js CHANGED
@@ -190,6 +190,23 @@ tape('raw', function (t) {
190
190
  t.is(state.start, state.end)
191
191
  })
192
192
 
193
+ tape('uint16array', function (t) {
194
+ const state = enc.state()
195
+
196
+ enc.uint16array.preencode(state, new Uint16Array([1, 2, 3]))
197
+ t.alike(state, { start: 0, end: 7, buffer: null })
198
+
199
+ state.buffer = Buffer.alloc(state.end)
200
+ enc.uint16array.encode(state, new Uint16Array([1, 2, 3]))
201
+ t.alike(state, { start: 7, end: 7, buffer: Buffer.from([3, 1, 0, 2, 0, 3, 0]) })
202
+
203
+ state.start = 0
204
+ t.alike(enc.uint16array.decode(state), new Uint16Array([1, 2, 3]))
205
+ t.is(state.start, state.end)
206
+
207
+ t.exception(() => enc.uint16array.decode(state))
208
+ })
209
+
193
210
  tape('uint32array', function (t) {
194
211
  const state = enc.state()
195
212
 
@@ -212,6 +229,74 @@ tape('uint32array', function (t) {
212
229
  t.exception(() => enc.uint32array.decode(state))
213
230
  })
214
231
 
232
+ tape('int16array', function (t) {
233
+ const state = enc.state()
234
+
235
+ enc.int16array.preencode(state, new Int16Array([1, -2, 3]))
236
+ t.alike(state, { start: 0, end: 7, buffer: null })
237
+
238
+ state.buffer = Buffer.alloc(state.end)
239
+ enc.int16array.encode(state, new Int16Array([1, -2, 3]))
240
+ t.alike(state, { start: 7, end: 7, buffer: Buffer.from([3, 1, 0, 0xfe, 0xff, 3, 0]) })
241
+
242
+ state.start = 0
243
+ t.alike(enc.int16array.decode(state), new Int16Array([1, -2, 3]))
244
+ t.is(state.start, state.end)
245
+
246
+ t.exception(() => enc.int16array.decode(state))
247
+ })
248
+
249
+ tape('int32array', function (t) {
250
+ const state = enc.state()
251
+
252
+ enc.int32array.preencode(state, new Int32Array([1, -2, 3]))
253
+ t.alike(state, { start: 0, end: 13, buffer: null })
254
+
255
+ state.buffer = Buffer.alloc(state.end)
256
+ enc.int32array.encode(state, new Int32Array([1, -2, 3]))
257
+ t.alike(state, { start: 13, end: 13, buffer: Buffer.from([3, 1, 0, 0, 0, 0xfe, 0xff, 0xff, 0xff, 3, 0, 0, 0]) })
258
+
259
+ state.start = 0
260
+ t.alike(enc.int32array.decode(state), new Int32Array([1, -2, 3]))
261
+ t.is(state.start, state.end)
262
+
263
+ t.exception(() => enc.int32array.decode(state))
264
+ })
265
+
266
+ tape('float32array', function (t) {
267
+ const state = enc.state()
268
+
269
+ enc.float32array.preencode(state, new Float32Array([1.1, -2.2, 3.3]))
270
+ t.alike(state, { start: 0, end: 13, buffer: null })
271
+
272
+ state.buffer = Buffer.alloc(state.end)
273
+ enc.float32array.encode(state, new Float32Array([1.1, -2.2, 3.3]))
274
+ t.alike(state, { start: 13, end: 13, buffer: Buffer.from([3, 0xcd, 0xcc, 0x8c, 0x3f, 0xcd, 0xcc, 0x0c, 0xc0, 0x33, 0x33, 0x53, 0x40]) })
275
+
276
+ state.start = 0
277
+ t.alike(enc.float32array.decode(state), new Float32Array([1.1, -2.2, 3.3]))
278
+ t.is(state.start, state.end)
279
+
280
+ t.exception(() => enc.float32array.decode(state))
281
+ })
282
+
283
+ tape('float64array', function (t) {
284
+ const state = enc.state()
285
+
286
+ enc.float64array.preencode(state, new Float64Array([1.1, -2.2, 3.3]))
287
+ t.alike(state, { start: 0, end: 25, buffer: null })
288
+
289
+ state.buffer = Buffer.alloc(state.end)
290
+ enc.float64array.encode(state, new Float64Array([1.1, -2.2, 3.3]))
291
+ t.alike(state, { start: 25, end: 25, buffer: Buffer.from([3, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0xf1, 0x3f, 0x9a, 0x99, 0x99, 0x99, 0x99, 0x99, 0x01, 0xc0, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x0a, 0x40]) })
292
+
293
+ state.start = 0
294
+ t.alike(enc.float64array.decode(state), new Float64Array([1.1, -2.2, 3.3]))
295
+ t.is(state.start, state.end)
296
+
297
+ t.exception(() => enc.float64array.decode(state))
298
+ })
299
+
215
300
  tape('string', function (t) {
216
301
  const state = enc.state()
217
302