compact-encoding 2.4.1 → 2.6.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/.github/workflows/test-node.yml +2 -3
- package/README.md +29 -9
- package/index.js +185 -205
- package/package.json +7 -5
- package/test.js +196 -136
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
name: Build Status
|
|
2
|
-
|
|
3
2
|
on:
|
|
4
3
|
push:
|
|
5
4
|
branches:
|
|
@@ -11,13 +10,13 @@ jobs:
|
|
|
11
10
|
build:
|
|
12
11
|
strategy:
|
|
13
12
|
matrix:
|
|
14
|
-
node-version: [
|
|
13
|
+
node-version: [lts/*]
|
|
15
14
|
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
16
15
|
runs-on: ${{ matrix.os }}
|
|
17
16
|
steps:
|
|
18
17
|
- uses: actions/checkout@v2
|
|
19
18
|
- name: Use Node.js ${{ matrix.node-version }}
|
|
20
|
-
uses: actions/setup-node@
|
|
19
|
+
uses: actions/setup-node@v2
|
|
21
20
|
with:
|
|
22
21
|
node-version: ${{ matrix.node-version }}
|
|
23
22
|
- run: npm install
|
package/README.md
CHANGED
|
@@ -40,6 +40,10 @@ Should be an object that looks like this `{ start, end, buffer }`.
|
|
|
40
40
|
|
|
41
41
|
You can also get a blank state object using `cenc.state()`.
|
|
42
42
|
|
|
43
|
+
* `start` is the byte offset to start encoding/decoding at.
|
|
44
|
+
* `end` is the byte offset indicating the end of the buffer.
|
|
45
|
+
* `buffer` should be either a Node.js Buffer or Uint8Array.
|
|
46
|
+
|
|
43
47
|
#### `enc.preencode(state, val)`
|
|
44
48
|
|
|
45
49
|
Does a fast preencode dry-run that only sets state.end.
|
|
@@ -70,21 +74,37 @@ const bool = cenc.decode(cenc.bool, buf)
|
|
|
70
74
|
The following encodings are bundled as they are primitives that can be used
|
|
71
75
|
to build others on top. Feel free to PR more that are missing.
|
|
72
76
|
|
|
73
|
-
* `cenc.uint` - Encodes a uint using [compact-uint](https://github.com/mafintosh/compact-uint)
|
|
74
|
-
* `cenc.
|
|
75
|
-
* `cenc.uint16` - Encodes a fixed size uint16
|
|
76
|
-
* `cenc.uint24` - Encodes a fixed size uint24
|
|
77
|
-
* `cenc.uint32` - Encodes a
|
|
78
|
-
* `cenc.
|
|
79
|
-
* `cenc.
|
|
80
|
-
* `cenc.
|
|
77
|
+
* `cenc.uint` - Encodes a uint using [compact-uint](https://github.com/mafintosh/compact-uint).
|
|
78
|
+
* `cenc.uint8` - Encodes a fixed size uint8.
|
|
79
|
+
* `cenc.uint16` - Encodes a fixed size uint16. Useful for things like ports.
|
|
80
|
+
* `cenc.uint24` - Encodes a fixed size uint24. Useful for message framing.
|
|
81
|
+
* `cenc.uint32` - Encodes a fixed size uint32. Useful for very large message framing.
|
|
82
|
+
* `cenc.uint64` - Encodes a fixed size uint64.
|
|
83
|
+
* `cenc.int` - Encodes an int using `cenc.uint` with ZigZag encoding.
|
|
84
|
+
* `cenc.int8` - Encodes a fixed size int8 using `cenc.uint8` with ZigZag encoding.
|
|
85
|
+
* `cenc.int16` - Encodes a fixed size int16 using `cenc.uint16` with ZigZag encoding.
|
|
86
|
+
* `cenc.int24` - Encodes a fixed size int24 using `cenc.uint24` with ZigZag encoding.
|
|
87
|
+
* `cenc.int32` - Encodes a fixed size int32 using `cenc.uint32` with ZigZag encoding.
|
|
88
|
+
* `cenc.int64` - Encodes a fixed size int64 using `cenc.uint64` with ZigZag encoding.
|
|
89
|
+
* `cenc.float32` - Encodes a fixed size float32.
|
|
90
|
+
* `cenc.float64` - Encodes a fixed size float64.
|
|
91
|
+
* `cenc.buffer` - Encodes a buffer with its length uint prefixed. When decoding an empty buffer, `null` is returned.
|
|
92
|
+
* `cenc.raw` - Pass through encodes a buffer, i.e. a basic copy.
|
|
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.
|
|
81
101
|
* `cenc.bool` - Encodes a boolean as 1 or 0.
|
|
82
102
|
* `cenc.string` - Encodes a utf-8 string, similar to buffer.
|
|
83
103
|
* `cenc.fixed32` - Encodes a fixed 32 byte buffer.
|
|
84
104
|
* `cenc.fixed64` - Encodes a fixed 64 byte buffer.
|
|
85
105
|
* `cenc.fixed(n)` - Makes a fixed sized encoder.
|
|
86
106
|
* `cenc.array(enc)` - Makes an array encoder from another encoder. Arrays are uint prefixed with their length.
|
|
87
|
-
* `cenc.from(enc)` - Makes a compact encoder from a [codec](https://github.com/mafintosh/codecs) or [abstract-encoding](https://github.com/mafintosh/abstract-encoding)
|
|
107
|
+
* `cenc.from(enc)` - Makes a compact encoder from a [codec](https://github.com/mafintosh/codecs) or [abstract-encoding](https://github.com/mafintosh/abstract-encoding).
|
|
88
108
|
|
|
89
109
|
## License
|
|
90
110
|
|
package/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
const b4a = require('b4a')
|
|
2
|
+
|
|
1
3
|
const LE = (new Uint8Array(new Uint16Array([255]).buffer))[0] === 0xff
|
|
2
4
|
const BE = !LE
|
|
3
5
|
|
|
@@ -10,34 +12,41 @@ const uint = exports.uint = {
|
|
|
10
12
|
state.end += n <= 0xfc ? 1 : n <= 0xffff ? 3 : n <= 0xffffffff ? 5 : 9
|
|
11
13
|
},
|
|
12
14
|
encode (state, n) {
|
|
13
|
-
if (n <= 0xfc)
|
|
14
|
-
else if (n <= 0xffff)
|
|
15
|
-
|
|
16
|
-
|
|
15
|
+
if (n <= 0xfc) uint8.encode(state, n)
|
|
16
|
+
else if (n <= 0xffff) {
|
|
17
|
+
state.buffer[state.start++] = 0xfd
|
|
18
|
+
uint16.encode(state, n)
|
|
19
|
+
} else if (n <= 0xffffffff) {
|
|
20
|
+
state.buffer[state.start++] = 0xfe
|
|
21
|
+
uint32.encode(state, n)
|
|
22
|
+
} else {
|
|
23
|
+
state.buffer[state.start++] = 0xff
|
|
24
|
+
uint64.encode(state, n)
|
|
25
|
+
}
|
|
17
26
|
},
|
|
18
27
|
decode (state) {
|
|
19
|
-
|
|
20
|
-
const a = state.buffer[state.start++]
|
|
28
|
+
const a = uint8.decode(state)
|
|
21
29
|
if (a <= 0xfc) return a
|
|
22
|
-
if (a === 0xfd) return
|
|
23
|
-
if (a === 0xfe) return
|
|
24
|
-
return
|
|
30
|
+
if (a === 0xfd) return uint16.decode(state)
|
|
31
|
+
if (a === 0xfe) return uint32.decode(state)
|
|
32
|
+
return uint64.decode(state)
|
|
25
33
|
}
|
|
26
34
|
}
|
|
27
35
|
|
|
28
|
-
exports.
|
|
36
|
+
const uint8 = exports.uint8 = {
|
|
29
37
|
preencode (state, n) {
|
|
30
|
-
|
|
38
|
+
state.end += 1
|
|
31
39
|
},
|
|
32
40
|
encode (state, n) {
|
|
33
|
-
|
|
41
|
+
state.buffer[state.start++] = n
|
|
34
42
|
},
|
|
35
43
|
decode (state) {
|
|
36
|
-
|
|
44
|
+
if (state.start >= state.end) throw new Error('Out of bounds')
|
|
45
|
+
return state.buffer[state.start++]
|
|
37
46
|
}
|
|
38
47
|
}
|
|
39
48
|
|
|
40
|
-
exports.uint16 = {
|
|
49
|
+
const uint16 = exports.uint16 = {
|
|
41
50
|
preencode (state, n) {
|
|
42
51
|
state.end += 2
|
|
43
52
|
},
|
|
@@ -47,11 +56,14 @@ exports.uint16 = {
|
|
|
47
56
|
},
|
|
48
57
|
decode (state) {
|
|
49
58
|
if (state.end - state.start < 2) throw new Error('Out of bounds')
|
|
50
|
-
return
|
|
59
|
+
return (
|
|
60
|
+
state.buffer[state.start++] +
|
|
61
|
+
state.buffer[state.start++] * 256
|
|
62
|
+
)
|
|
51
63
|
}
|
|
52
64
|
}
|
|
53
65
|
|
|
54
|
-
exports.uint24 = {
|
|
66
|
+
const uint24 = exports.uint24 = {
|
|
55
67
|
preencode (state, n) {
|
|
56
68
|
state.end += 3
|
|
57
69
|
},
|
|
@@ -62,11 +74,15 @@ exports.uint24 = {
|
|
|
62
74
|
},
|
|
63
75
|
decode (state) {
|
|
64
76
|
if (state.end - state.start < 3) throw new Error('Out of bounds')
|
|
65
|
-
return
|
|
77
|
+
return (
|
|
78
|
+
state.buffer[state.start++] +
|
|
79
|
+
state.buffer[state.start++] * 256 +
|
|
80
|
+
state.buffer[state.start++] * 65536
|
|
81
|
+
)
|
|
66
82
|
}
|
|
67
83
|
}
|
|
68
84
|
|
|
69
|
-
exports.uint32 = {
|
|
85
|
+
const uint32 = exports.uint32 = {
|
|
70
86
|
preencode (state, n) {
|
|
71
87
|
state.end += 4
|
|
72
88
|
},
|
|
@@ -78,7 +94,52 @@ exports.uint32 = {
|
|
|
78
94
|
},
|
|
79
95
|
decode (state) {
|
|
80
96
|
if (state.end - state.start < 4) throw new Error('Out of bounds')
|
|
81
|
-
return
|
|
97
|
+
return (
|
|
98
|
+
state.buffer[state.start++] +
|
|
99
|
+
state.buffer[state.start++] * 256 +
|
|
100
|
+
state.buffer[state.start++] * 65536 +
|
|
101
|
+
state.buffer[state.start++] * 16777216
|
|
102
|
+
)
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
const uint64 = exports.uint64 = {
|
|
107
|
+
preencode (state, n) {
|
|
108
|
+
state.end += 8
|
|
109
|
+
},
|
|
110
|
+
encode (state, n) {
|
|
111
|
+
const r = Math.floor(n / 4294967296)
|
|
112
|
+
uint32.encode(state, n)
|
|
113
|
+
uint32.encode(state, r)
|
|
114
|
+
},
|
|
115
|
+
decode (state) {
|
|
116
|
+
if (state.end - state.start < 8) throw new Error('Out of bounds')
|
|
117
|
+
return uint32.decode(state) + 4294967296 * uint32.decode(state)
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
exports.int = zigZag(uint)
|
|
122
|
+
exports.int8 = zigZag(uint8)
|
|
123
|
+
exports.int16 = zigZag(uint16)
|
|
124
|
+
exports.int24 = zigZag(uint24)
|
|
125
|
+
exports.int32 = zigZag(uint32)
|
|
126
|
+
exports.int64 = zigZag(uint64)
|
|
127
|
+
|
|
128
|
+
exports.float32 = {
|
|
129
|
+
preencode (state, n) {
|
|
130
|
+
state.end += 4
|
|
131
|
+
},
|
|
132
|
+
encode (state, n) {
|
|
133
|
+
const view = new DataView(state.buffer.buffer, state.start + state.buffer.byteOffset, 4)
|
|
134
|
+
view.setFloat32(0, n, true) // little endian
|
|
135
|
+
state.start += 4
|
|
136
|
+
},
|
|
137
|
+
decode (state) {
|
|
138
|
+
if (state.end - state.start < 4) throw new Error('Out of bounds')
|
|
139
|
+
const view = new DataView(state.buffer.buffer, state.start + state.buffer.byteOffset, 4)
|
|
140
|
+
const float = view.getFloat32(0, true) // little endian
|
|
141
|
+
state.start += 4
|
|
142
|
+
return float
|
|
82
143
|
}
|
|
83
144
|
}
|
|
84
145
|
|
|
@@ -92,6 +153,7 @@ exports.float64 = {
|
|
|
92
153
|
state.start += 8
|
|
93
154
|
},
|
|
94
155
|
decode (state) {
|
|
156
|
+
if (state.end - state.start < 8) throw new Error('Out of bounds')
|
|
95
157
|
const view = new DataView(state.buffer.buffer, state.start + state.buffer.byteOffset, 8)
|
|
96
158
|
const float = view.getFloat64(0, true) // little endian
|
|
97
159
|
state.start += 8
|
|
@@ -101,38 +163,28 @@ exports.float64 = {
|
|
|
101
163
|
|
|
102
164
|
exports.buffer = {
|
|
103
165
|
preencode (state, b) {
|
|
104
|
-
if (b)
|
|
105
|
-
|
|
106
|
-
state.end += b.length
|
|
107
|
-
} else {
|
|
108
|
-
state.end++
|
|
109
|
-
}
|
|
166
|
+
if (b) uint8array.preencode(state, b)
|
|
167
|
+
else state.end++
|
|
110
168
|
},
|
|
111
169
|
encode (state, b) {
|
|
112
|
-
if (b)
|
|
113
|
-
|
|
114
|
-
state.buffer.set(b, state.start)
|
|
115
|
-
state.start += b.length
|
|
116
|
-
} else {
|
|
117
|
-
state.buffer[state.start++] = 0
|
|
118
|
-
}
|
|
170
|
+
if (b) uint8array.encode(state, b)
|
|
171
|
+
else state.buffer[state.start++] = 0
|
|
119
172
|
},
|
|
120
173
|
decode (state) {
|
|
121
174
|
const len = uint.decode(state)
|
|
122
175
|
if (len === 0) return null
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
return b
|
|
176
|
+
if (state.end - state.start < len) throw new Error('Out of bounds')
|
|
177
|
+
return state.buffer.subarray(state.start, (state.start += len))
|
|
126
178
|
}
|
|
127
179
|
}
|
|
128
180
|
|
|
129
181
|
const raw = exports.raw = {
|
|
130
182
|
preencode (state, b) {
|
|
131
|
-
state.end += b.
|
|
183
|
+
state.end += b.byteLength
|
|
132
184
|
},
|
|
133
185
|
encode (state, b) {
|
|
134
186
|
state.buffer.set(b, state.start)
|
|
135
|
-
state.start += b.
|
|
187
|
+
state.start += b.byteLength
|
|
136
188
|
},
|
|
137
189
|
decode (state) {
|
|
138
190
|
const b = state.buffer.subarray(state.start, state.end)
|
|
@@ -141,58 +193,65 @@ const raw = exports.raw = {
|
|
|
141
193
|
}
|
|
142
194
|
}
|
|
143
195
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
uint.preencode(state, b.length)
|
|
147
|
-
state.end += b.byteLength
|
|
148
|
-
},
|
|
149
|
-
encode (state, b) {
|
|
150
|
-
uint.encode(state, b.length)
|
|
151
|
-
const view = new Uint8Array(b.buffer, b.byteOffset, b.byteLength)
|
|
152
|
-
if (BE) hostToLE32(view, b.length)
|
|
153
|
-
state.buffer.set(view, state.start)
|
|
154
|
-
state.start += b.byteLength
|
|
155
|
-
},
|
|
156
|
-
decode (state) {
|
|
157
|
-
const len = uint.decode(state)
|
|
196
|
+
function typedarray (TypedArray, swap) {
|
|
197
|
+
const n = TypedArray.BYTES_PER_ELEMENT
|
|
158
198
|
|
|
159
|
-
|
|
160
|
-
|
|
199
|
+
return {
|
|
200
|
+
preencode (state, b) {
|
|
201
|
+
uint.preencode(state, b.length)
|
|
202
|
+
state.end += b.byteLength
|
|
203
|
+
},
|
|
204
|
+
encode (state, b) {
|
|
205
|
+
uint.encode(state, b.length)
|
|
161
206
|
|
|
162
|
-
|
|
207
|
+
const view = new Uint8Array(b.buffer, b.byteOffset, b.byteLength)
|
|
163
208
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
}
|
|
209
|
+
if (BE && swap) swap(view)
|
|
210
|
+
|
|
211
|
+
state.buffer.set(view, state.start)
|
|
212
|
+
state.start += b.byteLength
|
|
213
|
+
},
|
|
214
|
+
decode (state) {
|
|
215
|
+
const len = uint.decode(state)
|
|
169
216
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
217
|
+
let b = state.buffer.subarray(state.start, state.start += len * n)
|
|
218
|
+
if (b.byteLength !== len * n) throw new Error('Out of bounds')
|
|
219
|
+
if ((b.byteOffset % n) !== 0) b = new Uint8Array(b)
|
|
220
|
+
|
|
221
|
+
if (BE && swap) swap(b)
|
|
222
|
+
|
|
223
|
+
return new TypedArray(b.buffer, b.byteOffset, b.byteLength / n)
|
|
224
|
+
}
|
|
176
225
|
}
|
|
177
226
|
}
|
|
178
227
|
|
|
179
|
-
exports.
|
|
228
|
+
const uint8array = exports.uint8array = typedarray(Uint8Array)
|
|
229
|
+
exports.uint16array = typedarray(Uint16Array, b4a.swap16)
|
|
230
|
+
exports.uint32array = typedarray(Uint32Array, b4a.swap32)
|
|
231
|
+
|
|
232
|
+
exports.int8array = typedarray(Int8Array)
|
|
233
|
+
exports.int16array = typedarray(Int16Array, b4a.swap16)
|
|
234
|
+
exports.int32array = typedarray(Int32Array, b4a.swap32)
|
|
235
|
+
|
|
236
|
+
exports.float32array = typedarray(Float32Array, b4a.swap32)
|
|
237
|
+
exports.float64array = typedarray(Float64Array, b4a.swap64)
|
|
238
|
+
|
|
239
|
+
exports.string = {
|
|
180
240
|
preencode (state, s) {
|
|
181
|
-
const len =
|
|
241
|
+
const len = b4a.byteLength(s)
|
|
182
242
|
uint.preencode(state, len)
|
|
183
243
|
state.end += len
|
|
184
244
|
},
|
|
185
245
|
encode (state, s) {
|
|
186
|
-
const len =
|
|
246
|
+
const len = b4a.byteLength(s)
|
|
187
247
|
uint.encode(state, len)
|
|
188
|
-
state.buffer
|
|
248
|
+
b4a.write(state.buffer, s, state.start)
|
|
189
249
|
state.start += len
|
|
190
250
|
},
|
|
191
251
|
decode (state) {
|
|
192
252
|
const len = uint.decode(state)
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
return s
|
|
253
|
+
if (state.end - state.start < len) throw new Error('Out of bounds')
|
|
254
|
+
return b4a.toString(state.buffer, 'utf-8', state.start, (state.start += len))
|
|
196
255
|
}
|
|
197
256
|
}
|
|
198
257
|
|
|
@@ -204,40 +263,29 @@ exports.bool = {
|
|
|
204
263
|
state.buffer[state.start++] = b ? 1 : 0
|
|
205
264
|
},
|
|
206
265
|
decode (state) {
|
|
207
|
-
if (state.start >= state.
|
|
266
|
+
if (state.start >= state.end) throw Error('Out of bounds')
|
|
208
267
|
return state.buffer[state.start++] === 1
|
|
209
268
|
}
|
|
210
269
|
}
|
|
211
270
|
|
|
212
|
-
exports.
|
|
213
|
-
|
|
214
|
-
state
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
state
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
271
|
+
const fixed = exports.fixed = function fixed (n) {
|
|
272
|
+
return {
|
|
273
|
+
preencode (state, s) {
|
|
274
|
+
state.end += n
|
|
275
|
+
},
|
|
276
|
+
encode (state, s) {
|
|
277
|
+
state.buffer.set(s, state.start)
|
|
278
|
+
state.start += n
|
|
279
|
+
},
|
|
280
|
+
decode (state) {
|
|
281
|
+
if (state.end - state.start < n) throw new Error('Out of bounds')
|
|
282
|
+
return state.buffer.subarray(state.start, (state.start += n))
|
|
283
|
+
}
|
|
224
284
|
}
|
|
225
285
|
}
|
|
226
286
|
|
|
227
|
-
exports.
|
|
228
|
-
|
|
229
|
-
state.end += 64
|
|
230
|
-
},
|
|
231
|
-
encode (state, s) {
|
|
232
|
-
state.buffer.set(s, state.start)
|
|
233
|
-
state.start += 64
|
|
234
|
-
},
|
|
235
|
-
decode (state) {
|
|
236
|
-
const b = state.buffer.subarray(state.start, state.start += 64)
|
|
237
|
-
if (b.length !== 64) throw new Error('Out of bounds')
|
|
238
|
-
return b
|
|
239
|
-
}
|
|
240
|
-
}
|
|
287
|
+
exports.fixed32 = fixed(32)
|
|
288
|
+
exports.fixed64 = fixed(64)
|
|
241
289
|
|
|
242
290
|
exports.none = {
|
|
243
291
|
preencode (state, m) {
|
|
@@ -251,23 +299,27 @@ exports.none = {
|
|
|
251
299
|
}
|
|
252
300
|
}
|
|
253
301
|
|
|
254
|
-
exports.
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
302
|
+
exports.array = function array (enc) {
|
|
303
|
+
return {
|
|
304
|
+
preencode (state, list) {
|
|
305
|
+
uint.preencode(state, list.length)
|
|
306
|
+
for (let i = 0; i < list.length; i++) enc.preencode(state, list[i])
|
|
307
|
+
},
|
|
308
|
+
encode (state, list) {
|
|
309
|
+
uint.encode(state, list.length)
|
|
310
|
+
for (let i = 0; i < list.length; i++) enc.encode(state, list[i])
|
|
311
|
+
},
|
|
312
|
+
decode (state) {
|
|
313
|
+
const len = uint.decode(state)
|
|
314
|
+
if (len > 1048576) throw new Error('Array is too big')
|
|
315
|
+
const arr = new Array(len)
|
|
316
|
+
for (let i = 0; i < len; i++) arr[i] = enc.decode(state)
|
|
317
|
+
return arr
|
|
318
|
+
}
|
|
319
|
+
}
|
|
268
320
|
}
|
|
269
321
|
|
|
270
|
-
function from (enc) {
|
|
322
|
+
exports.from = function from (enc) {
|
|
271
323
|
if (enc.preencode) return enc
|
|
272
324
|
if (enc.encodingLength) return fromAbstractEncoder(enc)
|
|
273
325
|
return fromCodec(enc)
|
|
@@ -281,7 +333,7 @@ function fromCodec (enc) {
|
|
|
281
333
|
preencode (state, m) {
|
|
282
334
|
tmpM = m
|
|
283
335
|
tmpBuf = enc.encode(m)
|
|
284
|
-
state.end += tmpBuf.
|
|
336
|
+
state.end += tmpBuf.byteLength
|
|
285
337
|
},
|
|
286
338
|
encode (state, m) {
|
|
287
339
|
raw.encode(state, m === tmpM ? tmpBuf : enc.encode(m))
|
|
@@ -310,109 +362,37 @@ function fromAbstractEncoder (enc) {
|
|
|
310
362
|
}
|
|
311
363
|
}
|
|
312
364
|
|
|
313
|
-
function
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
encode (state, list) {
|
|
320
|
-
uint.encode(state, list.length)
|
|
321
|
-
for (let i = 0; i < list.length; i++) enc.encode(state, list[i])
|
|
322
|
-
},
|
|
323
|
-
decode (state) {
|
|
324
|
-
const len = uint.decode(state)
|
|
325
|
-
if (len > 1048576) throw new Error('Array is too big')
|
|
326
|
-
const arr = new Array(len)
|
|
327
|
-
for (let i = 0; i < len; i++) arr[i] = enc.decode(state)
|
|
328
|
-
return arr
|
|
329
|
-
}
|
|
330
|
-
}
|
|
365
|
+
exports.encode = function encode (enc, m) {
|
|
366
|
+
const state = { start: 0, end: 0, buffer: null }
|
|
367
|
+
enc.preencode(state, m)
|
|
368
|
+
state.buffer = b4a.allocUnsafe(state.end)
|
|
369
|
+
enc.encode(state, m)
|
|
370
|
+
return state.buffer
|
|
331
371
|
}
|
|
332
372
|
|
|
333
|
-
function
|
|
373
|
+
exports.decode = function decode (enc, buffer) {
|
|
374
|
+
return enc.decode({ start: 0, end: buffer.byteLength, buffer })
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
function zigZag (enc) {
|
|
334
378
|
return {
|
|
335
|
-
preencode (state,
|
|
336
|
-
state
|
|
379
|
+
preencode (state, n) {
|
|
380
|
+
enc.preencode(state, zigZagEncode(n))
|
|
337
381
|
},
|
|
338
|
-
encode (state,
|
|
339
|
-
|
|
340
|
-
state.start += n
|
|
382
|
+
encode (state, n) {
|
|
383
|
+
enc.encode(state, zigZagEncode(n))
|
|
341
384
|
},
|
|
342
385
|
decode (state) {
|
|
343
|
-
|
|
344
|
-
if (b.length !== n) throw new Error('Out of bounds')
|
|
345
|
-
return b
|
|
386
|
+
return zigZagDecode(enc.decode(state))
|
|
346
387
|
}
|
|
347
388
|
}
|
|
348
389
|
}
|
|
349
390
|
|
|
350
|
-
function
|
|
351
|
-
const view = new DataView(arr.buffer, arr.byteOffset)
|
|
352
|
-
const host = new Uint32Array(arr.buffer, arr.byteOffset, len)
|
|
353
|
-
|
|
354
|
-
for (let i = 0; i < host.length; i++) {
|
|
355
|
-
host[i] = view.getUint32(4 * i, BE)
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
function hostToLE32 (arr, len) {
|
|
360
|
-
const view = new DataView(arr.buffer, arr.byteOffset)
|
|
361
|
-
const host = new Uint32Array(arr.buffer, arr.byteOffset, len)
|
|
362
|
-
|
|
363
|
-
for (let i = 0; i < host.length; i++) {
|
|
364
|
-
view.setUint32(4 * i, host[i], BE)
|
|
365
|
-
}
|
|
366
|
-
}
|
|
367
|
-
|
|
368
|
-
function decode16 (state) {
|
|
369
|
-
if (state.start + 2 > state.end) throw new Error('Out of bounds')
|
|
370
|
-
return state.buffer[state.start++] + 256 * state.buffer[state.start++]
|
|
371
|
-
}
|
|
372
|
-
|
|
373
|
-
function encode16 (state, n) {
|
|
374
|
-
state.buffer[state.start++] = 0xfd
|
|
375
|
-
state.buffer[state.start++] = n
|
|
376
|
-
state.buffer[state.start++] = (n >>> 8)
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
function decode32 (state) {
|
|
380
|
-
if (state.start + 4 > state.end) throw new Error('Out of bounds')
|
|
381
|
-
return state.buffer[state.start++] + 256 * state.buffer[state.start++] +
|
|
382
|
-
65536 * state.buffer[state.start++] + 16777216 * state.buffer[state.start++]
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
function encode32 (state, n) {
|
|
386
|
-
state.buffer[state.start++] = 0xfe
|
|
387
|
-
state.buffer[state.start++] = n
|
|
388
|
-
state.buffer[state.start++] = (n = (n >>> 8))
|
|
389
|
-
state.buffer[state.start++] = (n = (n >>> 8))
|
|
390
|
-
state.buffer[state.start++] = (n >>> 8)
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
function decode64 (state) {
|
|
394
|
-
if (state.start + 8 > state.end) throw new Error('Out of bounds')
|
|
395
|
-
return decode32(state) + 4294967296 * decode32(state)
|
|
396
|
-
}
|
|
397
|
-
|
|
398
|
-
function encode64 (state, n) {
|
|
399
|
-
state.buffer[state.start++] = 0xff
|
|
400
|
-
let r = Math.floor(n / 4294967296)
|
|
401
|
-
state.buffer[state.start++] = n
|
|
402
|
-
state.buffer[state.start++] = (n = (n >>> 8))
|
|
403
|
-
state.buffer[state.start++] = (n = (n >>> 8))
|
|
404
|
-
state.buffer[state.start++] = (n >>> 8)
|
|
405
|
-
state.buffer[state.start++] = r
|
|
406
|
-
state.buffer[state.start++] = (r = (r >>> 8))
|
|
407
|
-
state.buffer[state.start++] = (r = (r >>> 8))
|
|
408
|
-
state.buffer[state.start++] = (r >>> 8)
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
function zigzagDecode (n) {
|
|
391
|
+
function zigZagDecode (n) {
|
|
412
392
|
return n === 0 ? n : (n & 1) === 0 ? n / 2 : -(n + 1) / 2
|
|
413
393
|
}
|
|
414
394
|
|
|
415
|
-
function
|
|
395
|
+
function zigZagEncode (n) {
|
|
416
396
|
// 0, -1, 1, -2, 2, ...
|
|
417
397
|
return n < 0 ? (2 * -n) - 1 : n === 0 ? 0 : 2 * n
|
|
418
398
|
}
|
package/package.json
CHANGED
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "compact-encoding",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.6.1",
|
|
4
4
|
"description": "A series of compact encoding schemes for building small and fast parsers and serializers",
|
|
5
5
|
"main": "index.js",
|
|
6
|
-
"dependencies": {
|
|
6
|
+
"dependencies": {
|
|
7
|
+
"b4a": "^1.3.0"
|
|
8
|
+
},
|
|
7
9
|
"devDependencies": {
|
|
8
|
-
"
|
|
9
|
-
"
|
|
10
|
+
"brittle": "^1.5.1",
|
|
11
|
+
"standard": "^16.0.3"
|
|
10
12
|
},
|
|
11
13
|
"scripts": {
|
|
12
|
-
"test": "standard &&
|
|
14
|
+
"test": "standard && brittle test.js"
|
|
13
15
|
},
|
|
14
16
|
"repository": {
|
|
15
17
|
"type": "git",
|
package/test.js
CHANGED
|
@@ -1,75 +1,71 @@
|
|
|
1
1
|
const enc = require('./')
|
|
2
|
-
const tape = require('
|
|
2
|
+
const tape = require('brittle')
|
|
3
3
|
|
|
4
4
|
tape('uint', function (t) {
|
|
5
5
|
const state = enc.state()
|
|
6
6
|
|
|
7
7
|
enc.uint.preencode(state, 42)
|
|
8
|
-
t.
|
|
8
|
+
t.alike(state, { start: 0, end: 1, buffer: null })
|
|
9
9
|
enc.uint.preencode(state, 4200)
|
|
10
|
-
t.
|
|
10
|
+
t.alike(state, { start: 0, end: 4, buffer: null })
|
|
11
11
|
enc.uint.preencode(state, Number.MAX_SAFE_INTEGER)
|
|
12
|
-
t.
|
|
12
|
+
t.alike(state, { start: 0, end: 13, buffer: null })
|
|
13
13
|
|
|
14
14
|
state.buffer = Buffer.alloc(state.end)
|
|
15
15
|
enc.uint.encode(state, 42)
|
|
16
|
-
t.
|
|
16
|
+
t.alike(state, { start: 1, end: 13, buffer: Buffer.from([42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) })
|
|
17
17
|
enc.uint.encode(state, 4200)
|
|
18
|
-
t.
|
|
18
|
+
t.alike(state, { start: 4, end: 13, buffer: Buffer.from([42, 0xfd, 104, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0]) })
|
|
19
19
|
enc.uint.encode(state, Number.MAX_SAFE_INTEGER)
|
|
20
|
-
t.
|
|
20
|
+
t.alike(state, { start: 13, end: 13, buffer: Buffer.from([42, 0xfd, 104, 16, 0xff, 255, 255, 255, 255, 255, 255, 31, 0]) })
|
|
21
21
|
|
|
22
22
|
state.start = 0
|
|
23
|
-
t.
|
|
24
|
-
t.
|
|
25
|
-
t.
|
|
26
|
-
t.
|
|
23
|
+
t.is(enc.uint.decode(state), 42)
|
|
24
|
+
t.is(enc.uint.decode(state), 4200)
|
|
25
|
+
t.is(enc.uint.decode(state), Number.MAX_SAFE_INTEGER)
|
|
26
|
+
t.is(state.start, state.end)
|
|
27
27
|
|
|
28
|
-
t.
|
|
29
|
-
|
|
30
|
-
t.end()
|
|
28
|
+
t.exception(() => enc.uint.decode(state))
|
|
31
29
|
})
|
|
32
30
|
|
|
33
31
|
tape('int', function (t) {
|
|
34
32
|
const state = enc.state()
|
|
35
33
|
|
|
36
34
|
enc.int.preencode(state, 42)
|
|
37
|
-
t.
|
|
35
|
+
t.alike(state, { start: 0, end: 1, buffer: null })
|
|
38
36
|
enc.int.preencode(state, -4200)
|
|
39
|
-
t.
|
|
37
|
+
t.alike(state, { start: 0, end: 4, buffer: null })
|
|
40
38
|
|
|
41
39
|
state.buffer = Buffer.alloc(state.end)
|
|
42
40
|
enc.int.encode(state, 42)
|
|
43
|
-
t.
|
|
41
|
+
t.alike(state, { start: 1, end: 4, buffer: Buffer.from([84, 0, 0, 0]) })
|
|
44
42
|
enc.int.encode(state, -4200)
|
|
45
|
-
t.
|
|
43
|
+
t.alike(state, { start: 4, end: 4, buffer: Buffer.from([84, 0xfd, 207, 32]) })
|
|
46
44
|
|
|
47
45
|
state.start = 0
|
|
48
|
-
t.
|
|
49
|
-
t.
|
|
50
|
-
t.
|
|
51
|
-
|
|
52
|
-
t.throws(() => enc.int.decode(state))
|
|
46
|
+
t.is(enc.int.decode(state), 42)
|
|
47
|
+
t.is(enc.int.decode(state), -4200)
|
|
48
|
+
t.is(state.start, state.end)
|
|
53
49
|
|
|
54
|
-
t.
|
|
50
|
+
t.exception(() => enc.int.decode(state))
|
|
55
51
|
})
|
|
56
52
|
|
|
57
53
|
tape('float64', function (t) {
|
|
58
54
|
const state = enc.state()
|
|
59
55
|
|
|
60
56
|
enc.float64.preencode(state, 162.2377294)
|
|
61
|
-
t.
|
|
57
|
+
t.alike(state, { start: 0, end: 8, buffer: null })
|
|
62
58
|
|
|
63
59
|
state.buffer = Buffer.alloc(state.end)
|
|
64
|
-
t.
|
|
60
|
+
t.alike(state, { start: 0, end: 8, buffer: Buffer.from([0, 0, 0, 0, 0, 0, 0, 0]) })
|
|
65
61
|
enc.float64.encode(state, 162.2377294)
|
|
66
|
-
t.
|
|
62
|
+
t.alike(state, { start: 8, end: 8, buffer: Buffer.from([0x87, 0xc9, 0xaf, 0x7a, 0x9b, 0x47, 0x64, 0x40]) })
|
|
67
63
|
|
|
68
64
|
state.start = 0
|
|
69
|
-
t.
|
|
70
|
-
t.
|
|
65
|
+
t.is(enc.float64.decode(state), 162.2377294)
|
|
66
|
+
t.is(state.start, state.end)
|
|
71
67
|
|
|
72
|
-
t.
|
|
68
|
+
t.exception(() => enc.float64.decode(state))
|
|
73
69
|
|
|
74
70
|
// alignement
|
|
75
71
|
state.start = 0
|
|
@@ -78,33 +74,33 @@ tape('float64', function (t) {
|
|
|
78
74
|
|
|
79
75
|
enc.int.preencode(state, 0)
|
|
80
76
|
enc.float64.preencode(state, 162.2377294)
|
|
81
|
-
t.
|
|
77
|
+
t.alike(state, { start: 0, end: 9, buffer: null })
|
|
82
78
|
|
|
83
79
|
state.buffer = Buffer.alloc(state.end)
|
|
84
|
-
t.
|
|
80
|
+
t.alike(state, { start: 0, end: 9, buffer: Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0]) })
|
|
85
81
|
enc.int.encode(state, 0)
|
|
86
82
|
enc.float64.encode(state, 162.2377294)
|
|
87
|
-
t.
|
|
83
|
+
t.alike(state, { start: 9, end: 9, buffer: Buffer.from([0, 0x87, 0xc9, 0xaf, 0x7a, 0x9b, 0x47, 0x64, 0x40]) })
|
|
88
84
|
|
|
89
85
|
state.start = 0
|
|
90
|
-
t.
|
|
91
|
-
t.
|
|
92
|
-
t.
|
|
86
|
+
t.is(enc.int.decode(state), 0)
|
|
87
|
+
t.is(enc.float64.decode(state), 162.2377294)
|
|
88
|
+
t.is(state.start, state.end)
|
|
93
89
|
|
|
94
90
|
// subarray
|
|
95
91
|
const buf = Buffer.alloc(10)
|
|
96
92
|
state.start = 0
|
|
97
93
|
state.buffer = buf.subarray(1)
|
|
98
|
-
t.
|
|
94
|
+
t.alike(state, { start: 0, end: 9, buffer: Buffer.from([0, 0, 0, 0, 0, 0, 0, 0, 0]) })
|
|
99
95
|
enc.int.encode(state, 0)
|
|
100
96
|
enc.float64.encode(state, 162.2377294)
|
|
101
|
-
t.
|
|
102
|
-
t.
|
|
97
|
+
t.alike(state, { start: 9, end: 9, buffer: Buffer.from([0, 0x87, 0xc9, 0xaf, 0x7a, 0x9b, 0x47, 0x64, 0x40]) })
|
|
98
|
+
t.alike(buf, Buffer.from([0, 0, 0x87, 0xc9, 0xaf, 0x7a, 0x9b, 0x47, 0x64, 0x40]))
|
|
103
99
|
|
|
104
100
|
state.start = 0
|
|
105
|
-
t.
|
|
106
|
-
t.
|
|
107
|
-
t.
|
|
101
|
+
t.is(enc.int.decode(state), 0)
|
|
102
|
+
t.is(enc.float64.decode(state), 162.2377294)
|
|
103
|
+
t.is(state.start, state.end)
|
|
108
104
|
|
|
109
105
|
// 0
|
|
110
106
|
state.start = 0
|
|
@@ -114,11 +110,11 @@ tape('float64', function (t) {
|
|
|
114
110
|
enc.float64.preencode(state, 162.2377294)
|
|
115
111
|
state.buffer = Buffer.alloc(state.end)
|
|
116
112
|
enc.float64.encode(state, 0)
|
|
117
|
-
t.
|
|
113
|
+
t.alike(state, { start: 8, end: 8, buffer: Buffer.from([0, 0, 0, 0, 0, 0, 0, 0]) })
|
|
118
114
|
|
|
119
115
|
state.start = 0
|
|
120
|
-
t.
|
|
121
|
-
t.
|
|
116
|
+
t.is(enc.float64.decode(state), 0)
|
|
117
|
+
t.is(state.start, state.end)
|
|
122
118
|
|
|
123
119
|
// Infinity
|
|
124
120
|
state.start = 0
|
|
@@ -128,11 +124,11 @@ tape('float64', function (t) {
|
|
|
128
124
|
enc.float64.preencode(state, Infinity)
|
|
129
125
|
state.buffer = Buffer.alloc(state.end)
|
|
130
126
|
enc.float64.encode(state, Infinity)
|
|
131
|
-
t.
|
|
127
|
+
t.alike(state, { start: 8, end: 8, buffer: Buffer.from([0, 0, 0, 0, 0, 0, 0xf0, 0x7f]) })
|
|
132
128
|
|
|
133
129
|
state.start = 0
|
|
134
|
-
t.
|
|
135
|
-
t.
|
|
130
|
+
t.is(enc.float64.decode(state), Infinity)
|
|
131
|
+
t.is(state.start, state.end)
|
|
136
132
|
|
|
137
133
|
// Edge cases
|
|
138
134
|
state.start = 0
|
|
@@ -142,158 +138,226 @@ tape('float64', function (t) {
|
|
|
142
138
|
enc.float64.preencode(state, 0.1 + 0.2)
|
|
143
139
|
state.buffer = Buffer.alloc(state.end)
|
|
144
140
|
enc.float64.encode(state, 0.1 + 0.2)
|
|
145
|
-
t.
|
|
141
|
+
t.alike(state, { start: 8, end: 8, buffer: Buffer.from([0x34, 0x33, 0x33, 0x33, 0x33, 0x33, 0xd3, 0x3f]) })
|
|
146
142
|
|
|
147
143
|
state.start = 0
|
|
148
|
-
t.
|
|
149
|
-
t.
|
|
150
|
-
|
|
151
|
-
t.end()
|
|
144
|
+
t.is(enc.float64.decode(state), 0.1 + 0.2)
|
|
145
|
+
t.is(state.start, state.end)
|
|
152
146
|
})
|
|
153
147
|
|
|
154
148
|
tape('buffer', function (t) {
|
|
155
149
|
const state = enc.state()
|
|
156
150
|
|
|
157
151
|
enc.buffer.preencode(state, Buffer.from('hi'))
|
|
158
|
-
t.
|
|
152
|
+
t.alike(state, { start: 0, end: 3, buffer: null })
|
|
159
153
|
enc.buffer.preencode(state, Buffer.from('hello'))
|
|
160
|
-
t.
|
|
154
|
+
t.alike(state, { start: 0, end: 9, buffer: null })
|
|
161
155
|
enc.buffer.preencode(state, null)
|
|
162
|
-
t.
|
|
156
|
+
t.alike(state, { start: 0, end: 10, buffer: null })
|
|
163
157
|
|
|
164
158
|
state.buffer = Buffer.alloc(state.end)
|
|
165
159
|
enc.buffer.encode(state, Buffer.from('hi'))
|
|
166
|
-
t.
|
|
160
|
+
t.alike(state, { start: 3, end: 10, buffer: Buffer.from('\x02hi\x00\x00\x00\x00\x00\x00\x00') })
|
|
167
161
|
enc.buffer.encode(state, Buffer.from('hello'))
|
|
168
|
-
t.
|
|
162
|
+
t.alike(state, { start: 9, end: 10, buffer: Buffer.from('\x02hi\x05hello\x00') })
|
|
169
163
|
enc.buffer.encode(state, null)
|
|
170
|
-
t.
|
|
164
|
+
t.alike(state, { start: 10, end: 10, buffer: Buffer.from('\x02hi\x05hello\x00') })
|
|
171
165
|
|
|
172
166
|
state.start = 0
|
|
173
|
-
t.
|
|
174
|
-
t.
|
|
175
|
-
t.
|
|
176
|
-
t.
|
|
177
|
-
|
|
178
|
-
t.throws(() => enc.buffer.decode(state))
|
|
179
|
-
state.buffer = state.buffer.subarray(0, 8)
|
|
180
|
-
state.start = 3
|
|
181
|
-
t.throws(() => enc.buffer.decode(state), 'partial throws')
|
|
167
|
+
t.alike(enc.buffer.decode(state), Buffer.from('hi'))
|
|
168
|
+
t.alike(enc.buffer.decode(state), Buffer.from('hello'))
|
|
169
|
+
t.is(enc.buffer.decode(state), null)
|
|
170
|
+
t.is(state.start, state.end)
|
|
182
171
|
|
|
183
|
-
t.
|
|
172
|
+
t.exception(() => enc.buffer.decode(state))
|
|
184
173
|
})
|
|
185
174
|
|
|
186
175
|
tape('raw', function (t) {
|
|
187
176
|
const state = enc.state()
|
|
188
177
|
|
|
189
178
|
enc.raw.preencode(state, Buffer.from('hi'))
|
|
190
|
-
t.
|
|
179
|
+
t.alike(state, { start: 0, end: 2, buffer: null })
|
|
191
180
|
|
|
192
181
|
state.buffer = Buffer.alloc(state.end)
|
|
193
182
|
enc.raw.encode(state, Buffer.from('hi'))
|
|
194
|
-
t.
|
|
183
|
+
t.alike(state, { start: 2, end: 2, buffer: Buffer.from('hi') })
|
|
195
184
|
|
|
196
185
|
state.start = 0
|
|
197
|
-
t.
|
|
198
|
-
t.
|
|
186
|
+
t.alike(enc.raw.decode(state), Buffer.from('hi'))
|
|
187
|
+
t.is(state.start, state.end)
|
|
188
|
+
})
|
|
189
|
+
|
|
190
|
+
tape('uint16array', function (t) {
|
|
191
|
+
const state = enc.state()
|
|
199
192
|
|
|
200
|
-
|
|
193
|
+
enc.uint16array.preencode(state, new Uint16Array([1, 2, 3]))
|
|
194
|
+
t.alike(state, { start: 0, end: 7, buffer: null })
|
|
195
|
+
|
|
196
|
+
state.buffer = Buffer.alloc(state.end)
|
|
197
|
+
enc.uint16array.encode(state, new Uint16Array([1, 2, 3]))
|
|
198
|
+
t.alike(state, { start: 7, end: 7, buffer: Buffer.from([3, 1, 0, 2, 0, 3, 0]) })
|
|
199
|
+
|
|
200
|
+
state.start = 0
|
|
201
|
+
t.alike(enc.uint16array.decode(state), new Uint16Array([1, 2, 3]))
|
|
202
|
+
t.is(state.start, state.end)
|
|
203
|
+
|
|
204
|
+
t.exception(() => enc.uint16array.decode(state))
|
|
201
205
|
})
|
|
202
206
|
|
|
203
207
|
tape('uint32array', function (t) {
|
|
204
208
|
const state = enc.state()
|
|
205
209
|
|
|
206
210
|
enc.uint32array.preencode(state, new Uint32Array([1]))
|
|
207
|
-
t.
|
|
211
|
+
t.alike(state, { start: 0, end: 5, buffer: null })
|
|
208
212
|
enc.uint32array.preencode(state, new Uint32Array([42, 43]))
|
|
209
|
-
t.
|
|
213
|
+
t.alike(state, { start: 0, end: 14, buffer: null })
|
|
210
214
|
|
|
211
215
|
state.buffer = Buffer.alloc(state.end)
|
|
212
216
|
enc.uint32array.encode(state, new Uint32Array([1]))
|
|
213
|
-
t.
|
|
217
|
+
t.alike(state, { start: 5, end: 14, buffer: Buffer.from([1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) })
|
|
214
218
|
enc.uint32array.encode(state, new Uint32Array([42, 43]))
|
|
215
|
-
t.
|
|
219
|
+
t.alike(state, { start: 14, end: 14, buffer: Buffer.from([1, 1, 0, 0, 0, 2, 42, 0, 0, 0, 43, 0, 0, 0]) })
|
|
220
|
+
|
|
221
|
+
state.start = 0
|
|
222
|
+
t.alike(enc.uint32array.decode(state), new Uint32Array([1]))
|
|
223
|
+
t.alike(enc.uint32array.decode(state), new Uint32Array([42, 43]))
|
|
224
|
+
t.is(state.start, state.end)
|
|
225
|
+
|
|
226
|
+
t.exception(() => enc.uint32array.decode(state))
|
|
227
|
+
})
|
|
228
|
+
|
|
229
|
+
tape('int16array', function (t) {
|
|
230
|
+
const state = enc.state()
|
|
231
|
+
|
|
232
|
+
enc.int16array.preencode(state, new Int16Array([1, -2, 3]))
|
|
233
|
+
t.alike(state, { start: 0, end: 7, buffer: null })
|
|
234
|
+
|
|
235
|
+
state.buffer = Buffer.alloc(state.end)
|
|
236
|
+
enc.int16array.encode(state, new Int16Array([1, -2, 3]))
|
|
237
|
+
t.alike(state, { start: 7, end: 7, buffer: Buffer.from([3, 1, 0, 0xfe, 0xff, 3, 0]) })
|
|
238
|
+
|
|
239
|
+
state.start = 0
|
|
240
|
+
t.alike(enc.int16array.decode(state), new Int16Array([1, -2, 3]))
|
|
241
|
+
t.is(state.start, state.end)
|
|
242
|
+
|
|
243
|
+
t.exception(() => enc.int16array.decode(state))
|
|
244
|
+
})
|
|
245
|
+
|
|
246
|
+
tape('int32array', function (t) {
|
|
247
|
+
const state = enc.state()
|
|
248
|
+
|
|
249
|
+
enc.int32array.preencode(state, new Int32Array([1, -2, 3]))
|
|
250
|
+
t.alike(state, { start: 0, end: 13, buffer: null })
|
|
251
|
+
|
|
252
|
+
state.buffer = Buffer.alloc(state.end)
|
|
253
|
+
enc.int32array.encode(state, new Int32Array([1, -2, 3]))
|
|
254
|
+
t.alike(state, { start: 13, end: 13, buffer: Buffer.from([3, 1, 0, 0, 0, 0xfe, 0xff, 0xff, 0xff, 3, 0, 0, 0]) })
|
|
255
|
+
|
|
256
|
+
state.start = 0
|
|
257
|
+
t.alike(enc.int32array.decode(state), new Int32Array([1, -2, 3]))
|
|
258
|
+
t.is(state.start, state.end)
|
|
259
|
+
|
|
260
|
+
t.exception(() => enc.int32array.decode(state))
|
|
261
|
+
})
|
|
262
|
+
|
|
263
|
+
tape('float32array', function (t) {
|
|
264
|
+
const state = enc.state()
|
|
265
|
+
|
|
266
|
+
enc.float32array.preencode(state, new Float32Array([1.1, -2.2, 3.3]))
|
|
267
|
+
t.alike(state, { start: 0, end: 13, buffer: null })
|
|
268
|
+
|
|
269
|
+
state.buffer = Buffer.alloc(state.end)
|
|
270
|
+
enc.float32array.encode(state, new Float32Array([1.1, -2.2, 3.3]))
|
|
271
|
+
t.alike(state, { start: 13, end: 13, buffer: Buffer.from([3, 0xcd, 0xcc, 0x8c, 0x3f, 0xcd, 0xcc, 0x0c, 0xc0, 0x33, 0x33, 0x53, 0x40]) })
|
|
216
272
|
|
|
217
273
|
state.start = 0
|
|
218
|
-
t.
|
|
219
|
-
t.
|
|
220
|
-
t.same(state.start, state.end)
|
|
274
|
+
t.alike(enc.float32array.decode(state), new Float32Array([1.1, -2.2, 3.3]))
|
|
275
|
+
t.is(state.start, state.end)
|
|
221
276
|
|
|
222
|
-
t.
|
|
277
|
+
t.exception(() => enc.float32array.decode(state))
|
|
278
|
+
})
|
|
279
|
+
|
|
280
|
+
tape('float64array', function (t) {
|
|
281
|
+
const state = enc.state()
|
|
282
|
+
|
|
283
|
+
enc.float64array.preencode(state, new Float64Array([1.1, -2.2, 3.3]))
|
|
284
|
+
t.alike(state, { start: 0, end: 25, buffer: null })
|
|
223
285
|
|
|
224
|
-
|
|
286
|
+
state.buffer = Buffer.alloc(state.end)
|
|
287
|
+
enc.float64array.encode(state, new Float64Array([1.1, -2.2, 3.3]))
|
|
288
|
+
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]) })
|
|
289
|
+
|
|
290
|
+
state.start = 0
|
|
291
|
+
t.alike(enc.float64array.decode(state), new Float64Array([1.1, -2.2, 3.3]))
|
|
292
|
+
t.is(state.start, state.end)
|
|
293
|
+
|
|
294
|
+
t.exception(() => enc.float64array.decode(state))
|
|
225
295
|
})
|
|
226
296
|
|
|
227
297
|
tape('string', function (t) {
|
|
228
298
|
const state = enc.state()
|
|
229
299
|
|
|
230
|
-
enc.string.preencode(state, '
|
|
231
|
-
t.
|
|
300
|
+
enc.string.preencode(state, '🌾')
|
|
301
|
+
t.alike(state, { start: 0, end: 5, buffer: null })
|
|
232
302
|
enc.string.preencode(state, 'høsten er fin')
|
|
233
|
-
t.
|
|
303
|
+
t.alike(state, { start: 0, end: 20, buffer: null })
|
|
234
304
|
|
|
235
305
|
state.buffer = Buffer.alloc(state.end)
|
|
236
|
-
enc.string.encode(state, '
|
|
237
|
-
t.
|
|
306
|
+
enc.string.encode(state, '🌾')
|
|
307
|
+
t.alike(state, { start: 5, end: 20, buffer: Buffer.from('\x04🌾\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') })
|
|
238
308
|
enc.string.encode(state, 'høsten er fin')
|
|
239
|
-
t.
|
|
309
|
+
t.alike(state, { start: 20, end: 20, buffer: Buffer.from('\x04🌾\x0ehøsten er fin') })
|
|
240
310
|
|
|
241
311
|
state.start = 0
|
|
242
|
-
t.
|
|
243
|
-
t.
|
|
244
|
-
t.
|
|
245
|
-
|
|
246
|
-
t.throws(() => enc.string.decode(state))
|
|
312
|
+
t.is(enc.string.decode(state), '🌾')
|
|
313
|
+
t.is(enc.string.decode(state), 'høsten er fin')
|
|
314
|
+
t.is(state.start, state.end)
|
|
247
315
|
|
|
248
|
-
t.
|
|
316
|
+
t.exception(() => enc.string.decode(state))
|
|
249
317
|
})
|
|
250
318
|
|
|
251
319
|
tape('fixed32', function (t) {
|
|
252
320
|
const state = enc.state()
|
|
253
321
|
|
|
254
322
|
enc.fixed32.preencode(state, Buffer.alloc(32).fill('a'))
|
|
255
|
-
t.
|
|
323
|
+
t.alike(state, { start: 0, end: 32, buffer: null })
|
|
256
324
|
enc.fixed32.preencode(state, Buffer.alloc(32).fill('b'))
|
|
257
|
-
t.
|
|
325
|
+
t.alike(state, { start: 0, end: 64, buffer: null })
|
|
258
326
|
|
|
259
327
|
state.buffer = Buffer.alloc(state.end)
|
|
260
328
|
enc.fixed32.encode(state, Buffer.alloc(32).fill('a'))
|
|
261
|
-
t.
|
|
329
|
+
t.alike(state, { start: 32, end: 64, buffer: Buffer.alloc(64).fill('a', 0, 32) })
|
|
262
330
|
enc.fixed32.encode(state, Buffer.alloc(32).fill('b'))
|
|
263
|
-
t.
|
|
331
|
+
t.alike(state, { start: 64, end: 64, buffer: Buffer.alloc(64).fill('a', 0, 32).fill('b', 32, 64) })
|
|
264
332
|
|
|
265
333
|
state.start = 0
|
|
266
|
-
t.
|
|
267
|
-
t.
|
|
268
|
-
t.
|
|
269
|
-
|
|
270
|
-
t.throws(() => enc.fixed32.decode(state))
|
|
334
|
+
t.alike(enc.fixed32.decode(state), Buffer.alloc(32).fill('a'))
|
|
335
|
+
t.alike(enc.fixed32.decode(state), Buffer.alloc(32).fill('b'))
|
|
336
|
+
t.is(state.start, state.end)
|
|
271
337
|
|
|
272
|
-
t.
|
|
338
|
+
t.exception(() => enc.fixed32.decode(state))
|
|
273
339
|
})
|
|
274
340
|
|
|
275
341
|
tape('fixed64', function (t) {
|
|
276
342
|
const state = enc.state()
|
|
277
343
|
|
|
278
344
|
enc.fixed64.preencode(state, Buffer.alloc(64).fill('a'))
|
|
279
|
-
t.
|
|
345
|
+
t.alike(state, { start: 0, end: 64, buffer: null })
|
|
280
346
|
enc.fixed64.preencode(state, Buffer.alloc(64).fill('b'))
|
|
281
|
-
t.
|
|
347
|
+
t.alike(state, { start: 0, end: 128, buffer: null })
|
|
282
348
|
|
|
283
349
|
state.buffer = Buffer.alloc(state.end)
|
|
284
350
|
enc.fixed64.encode(state, Buffer.alloc(64).fill('a'))
|
|
285
|
-
t.
|
|
351
|
+
t.alike(state, { start: 64, end: 128, buffer: Buffer.alloc(128).fill('a', 0, 64) })
|
|
286
352
|
enc.fixed64.encode(state, Buffer.alloc(64).fill('b'))
|
|
287
|
-
t.
|
|
353
|
+
t.alike(state, { start: 128, end: 128, buffer: Buffer.alloc(128).fill('a', 0, 64).fill('b', 64, 128) })
|
|
288
354
|
|
|
289
355
|
state.start = 0
|
|
290
|
-
t.
|
|
291
|
-
t.
|
|
292
|
-
t.
|
|
356
|
+
t.alike(enc.fixed64.decode(state), Buffer.alloc(64).fill('a'))
|
|
357
|
+
t.alike(enc.fixed64.decode(state), Buffer.alloc(64).fill('b'))
|
|
358
|
+
t.is(state.start, state.end)
|
|
293
359
|
|
|
294
|
-
t.
|
|
295
|
-
|
|
296
|
-
t.end()
|
|
360
|
+
t.exception(() => enc.fixed64.decode(state))
|
|
297
361
|
})
|
|
298
362
|
|
|
299
363
|
tape('fixed n', function (t) {
|
|
@@ -301,26 +365,24 @@ tape('fixed n', function (t) {
|
|
|
301
365
|
const fixed = enc.fixed(3)
|
|
302
366
|
|
|
303
367
|
fixed.preencode(state, Buffer.alloc(3).fill('a'))
|
|
304
|
-
t.
|
|
368
|
+
t.alike(state, { start: 0, end: 3, buffer: null })
|
|
305
369
|
fixed.preencode(state, Buffer.alloc(3).fill('b'))
|
|
306
|
-
t.
|
|
370
|
+
t.alike(state, { start: 0, end: 6, buffer: null })
|
|
307
371
|
|
|
308
372
|
state.buffer = Buffer.alloc(state.end)
|
|
309
373
|
fixed.encode(state, Buffer.alloc(3).fill('a'))
|
|
310
|
-
t.
|
|
374
|
+
t.alike(state, { start: 3, end: 6, buffer: Buffer.alloc(6).fill('a', 0, 3) })
|
|
311
375
|
fixed.encode(state, Buffer.alloc(3).fill('b'))
|
|
312
|
-
t.
|
|
376
|
+
t.alike(state, { start: 6, end: 6, buffer: Buffer.alloc(6).fill('a', 0, 3).fill('b', 3, 6) })
|
|
313
377
|
|
|
314
378
|
state.start = 0
|
|
315
|
-
t.
|
|
316
|
-
t.
|
|
317
|
-
t.
|
|
379
|
+
t.alike(fixed.decode(state), Buffer.alloc(3).fill('a'))
|
|
380
|
+
t.alike(fixed.decode(state), Buffer.alloc(3).fill('b'))
|
|
381
|
+
t.is(state.start, state.end)
|
|
318
382
|
|
|
319
|
-
t.
|
|
383
|
+
t.exception(() => fixed.decode(state))
|
|
320
384
|
state.start = 4
|
|
321
|
-
t.
|
|
322
|
-
|
|
323
|
-
t.end()
|
|
385
|
+
t.exception(() => fixed.decode(state))
|
|
324
386
|
})
|
|
325
387
|
|
|
326
388
|
tape('array', function (t) {
|
|
@@ -328,22 +390,20 @@ tape('array', function (t) {
|
|
|
328
390
|
const arr = enc.array(enc.bool)
|
|
329
391
|
|
|
330
392
|
arr.preencode(state, [true, false, true])
|
|
331
|
-
t.
|
|
393
|
+
t.alike(state, { start: 0, end: 4, buffer: null })
|
|
332
394
|
arr.preencode(state, [false, false, true, true])
|
|
333
|
-
t.
|
|
395
|
+
t.alike(state, { start: 0, end: 9, buffer: null })
|
|
334
396
|
|
|
335
397
|
state.buffer = Buffer.alloc(state.end)
|
|
336
398
|
arr.encode(state, [true, false, true])
|
|
337
|
-
t.
|
|
399
|
+
t.alike(state, { start: 4, end: 9, buffer: Buffer.from([3, 1, 0, 1, 0, 0, 0, 0, 0]) })
|
|
338
400
|
arr.encode(state, [false, false, true, true])
|
|
339
|
-
t.
|
|
401
|
+
t.alike(state, { start: 9, end: 9, buffer: Buffer.from([3, 1, 0, 1, 4, 0, 0, 1, 1]) })
|
|
340
402
|
|
|
341
403
|
state.start = 0
|
|
342
|
-
t.
|
|
343
|
-
t.
|
|
344
|
-
t.
|
|
345
|
-
|
|
346
|
-
t.throws(() => arr.decode(state))
|
|
404
|
+
t.alike(arr.decode(state), [true, false, true])
|
|
405
|
+
t.alike(arr.decode(state), [false, false, true, true])
|
|
406
|
+
t.is(state.start, state.end)
|
|
347
407
|
|
|
348
|
-
t.
|
|
408
|
+
t.exception(() => arr.decode(state))
|
|
349
409
|
})
|