@atproto/lex-cbor 0.0.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.
- package/dist/encoding.d.ts +6 -0
- package/dist/encoding.d.ts.map +1 -0
- package/dist/index.cjs.js +1707 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.es.js +1703 -0
- package/package.json +52 -0
- package/src/encoding.ts +101 -0
- package/src/index.ts +73 -0
|
@@ -0,0 +1,1707 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
3
|
+
const digest = require("multiformats/hashes/digest");
|
|
4
|
+
const sha2 = require("multiformats/hashes/sha2");
|
|
5
|
+
const lexData = require("@atproto/lex-data");
|
|
6
|
+
const typeofs = [
|
|
7
|
+
"string",
|
|
8
|
+
"number",
|
|
9
|
+
"bigint",
|
|
10
|
+
"symbol"
|
|
11
|
+
];
|
|
12
|
+
const objectTypeNames = [
|
|
13
|
+
"Function",
|
|
14
|
+
"Generator",
|
|
15
|
+
"AsyncGenerator",
|
|
16
|
+
"GeneratorFunction",
|
|
17
|
+
"AsyncGeneratorFunction",
|
|
18
|
+
"AsyncFunction",
|
|
19
|
+
"Observable",
|
|
20
|
+
"Array",
|
|
21
|
+
"Buffer",
|
|
22
|
+
"Object",
|
|
23
|
+
"RegExp",
|
|
24
|
+
"Date",
|
|
25
|
+
"Error",
|
|
26
|
+
"Map",
|
|
27
|
+
"Set",
|
|
28
|
+
"WeakMap",
|
|
29
|
+
"WeakSet",
|
|
30
|
+
"ArrayBuffer",
|
|
31
|
+
"SharedArrayBuffer",
|
|
32
|
+
"DataView",
|
|
33
|
+
"Promise",
|
|
34
|
+
"URL",
|
|
35
|
+
"HTMLElement",
|
|
36
|
+
"Int8Array",
|
|
37
|
+
"Uint8Array",
|
|
38
|
+
"Uint8ClampedArray",
|
|
39
|
+
"Int16Array",
|
|
40
|
+
"Uint16Array",
|
|
41
|
+
"Int32Array",
|
|
42
|
+
"Uint32Array",
|
|
43
|
+
"Float32Array",
|
|
44
|
+
"Float64Array",
|
|
45
|
+
"BigInt64Array",
|
|
46
|
+
"BigUint64Array"
|
|
47
|
+
];
|
|
48
|
+
function is(value) {
|
|
49
|
+
if (value === null) {
|
|
50
|
+
return "null";
|
|
51
|
+
}
|
|
52
|
+
if (value === void 0) {
|
|
53
|
+
return "undefined";
|
|
54
|
+
}
|
|
55
|
+
if (value === true || value === false) {
|
|
56
|
+
return "boolean";
|
|
57
|
+
}
|
|
58
|
+
const typeOf = typeof value;
|
|
59
|
+
if (typeofs.includes(typeOf)) {
|
|
60
|
+
return typeOf;
|
|
61
|
+
}
|
|
62
|
+
if (typeOf === "function") {
|
|
63
|
+
return "Function";
|
|
64
|
+
}
|
|
65
|
+
if (Array.isArray(value)) {
|
|
66
|
+
return "Array";
|
|
67
|
+
}
|
|
68
|
+
if (isBuffer$1(value)) {
|
|
69
|
+
return "Buffer";
|
|
70
|
+
}
|
|
71
|
+
const objectType = getObjectType(value);
|
|
72
|
+
if (objectType) {
|
|
73
|
+
return objectType;
|
|
74
|
+
}
|
|
75
|
+
return "Object";
|
|
76
|
+
}
|
|
77
|
+
function isBuffer$1(value) {
|
|
78
|
+
return value && value.constructor && value.constructor.isBuffer && value.constructor.isBuffer.call(null, value);
|
|
79
|
+
}
|
|
80
|
+
function getObjectType(value) {
|
|
81
|
+
const objectTypeName = Object.prototype.toString.call(value).slice(8, -1);
|
|
82
|
+
if (objectTypeNames.includes(objectTypeName)) {
|
|
83
|
+
return objectTypeName;
|
|
84
|
+
}
|
|
85
|
+
return void 0;
|
|
86
|
+
}
|
|
87
|
+
class Type {
|
|
88
|
+
/**
|
|
89
|
+
* @param {number} major
|
|
90
|
+
* @param {string} name
|
|
91
|
+
* @param {boolean} terminal
|
|
92
|
+
*/
|
|
93
|
+
constructor(major, name, terminal) {
|
|
94
|
+
this.major = major;
|
|
95
|
+
this.majorEncoded = major << 5;
|
|
96
|
+
this.name = name;
|
|
97
|
+
this.terminal = terminal;
|
|
98
|
+
}
|
|
99
|
+
/* c8 ignore next 3 */
|
|
100
|
+
toString() {
|
|
101
|
+
return `Type[${this.major}].${this.name}`;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* @param {Type} typ
|
|
105
|
+
* @returns {number}
|
|
106
|
+
*/
|
|
107
|
+
compare(typ) {
|
|
108
|
+
return this.major < typ.major ? -1 : this.major > typ.major ? 1 : 0;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
Type.uint = new Type(0, "uint", true);
|
|
112
|
+
Type.negint = new Type(1, "negint", true);
|
|
113
|
+
Type.bytes = new Type(2, "bytes", true);
|
|
114
|
+
Type.string = new Type(3, "string", true);
|
|
115
|
+
Type.array = new Type(4, "array", false);
|
|
116
|
+
Type.map = new Type(5, "map", false);
|
|
117
|
+
Type.tag = new Type(6, "tag", false);
|
|
118
|
+
Type.float = new Type(7, "float", true);
|
|
119
|
+
Type.false = new Type(7, "false", true);
|
|
120
|
+
Type.true = new Type(7, "true", true);
|
|
121
|
+
Type.null = new Type(7, "null", true);
|
|
122
|
+
Type.undefined = new Type(7, "undefined", true);
|
|
123
|
+
Type.break = new Type(7, "break", true);
|
|
124
|
+
class Token {
|
|
125
|
+
/**
|
|
126
|
+
* @param {Type} type
|
|
127
|
+
* @param {any} [value]
|
|
128
|
+
* @param {number} [encodedLength]
|
|
129
|
+
*/
|
|
130
|
+
constructor(type, value, encodedLength) {
|
|
131
|
+
this.type = type;
|
|
132
|
+
this.value = value;
|
|
133
|
+
this.encodedLength = encodedLength;
|
|
134
|
+
this.encodedBytes = void 0;
|
|
135
|
+
this.byteValue = void 0;
|
|
136
|
+
}
|
|
137
|
+
/* c8 ignore next 3 */
|
|
138
|
+
toString() {
|
|
139
|
+
return `Token[${this.type}].${this.value}`;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const useBuffer = globalThis.process && // @ts-ignore
|
|
143
|
+
!globalThis.process.browser && // @ts-ignore
|
|
144
|
+
globalThis.Buffer && // @ts-ignore
|
|
145
|
+
typeof globalThis.Buffer.isBuffer === "function";
|
|
146
|
+
const textDecoder = new TextDecoder();
|
|
147
|
+
const textEncoder = new TextEncoder();
|
|
148
|
+
function isBuffer(buf2) {
|
|
149
|
+
return useBuffer && globalThis.Buffer.isBuffer(buf2);
|
|
150
|
+
}
|
|
151
|
+
function asU8A(buf2) {
|
|
152
|
+
if (!(buf2 instanceof Uint8Array)) {
|
|
153
|
+
return Uint8Array.from(buf2);
|
|
154
|
+
}
|
|
155
|
+
return isBuffer(buf2) ? new Uint8Array(buf2.buffer, buf2.byteOffset, buf2.byteLength) : buf2;
|
|
156
|
+
}
|
|
157
|
+
const toString = useBuffer ? (
|
|
158
|
+
// eslint-disable-line operator-linebreak
|
|
159
|
+
/**
|
|
160
|
+
* @param {Uint8Array} bytes
|
|
161
|
+
* @param {number} start
|
|
162
|
+
* @param {number} end
|
|
163
|
+
*/
|
|
164
|
+
(bytes, start, end) => {
|
|
165
|
+
return end - start > 64 ? (
|
|
166
|
+
// eslint-disable-line operator-linebreak
|
|
167
|
+
// @ts-ignore
|
|
168
|
+
globalThis.Buffer.from(bytes.subarray(start, end)).toString("utf8")
|
|
169
|
+
) : utf8Slice(bytes, start, end);
|
|
170
|
+
}
|
|
171
|
+
) : (
|
|
172
|
+
// eslint-disable-line operator-linebreak
|
|
173
|
+
/**
|
|
174
|
+
* @param {Uint8Array} bytes
|
|
175
|
+
* @param {number} start
|
|
176
|
+
* @param {number} end
|
|
177
|
+
*/
|
|
178
|
+
(bytes, start, end) => {
|
|
179
|
+
return end - start > 64 ? textDecoder.decode(bytes.subarray(start, end)) : utf8Slice(bytes, start, end);
|
|
180
|
+
}
|
|
181
|
+
);
|
|
182
|
+
const fromString = useBuffer ? (
|
|
183
|
+
// eslint-disable-line operator-linebreak
|
|
184
|
+
/**
|
|
185
|
+
* @param {string} string
|
|
186
|
+
*/
|
|
187
|
+
(string) => {
|
|
188
|
+
return string.length > 64 ? (
|
|
189
|
+
// eslint-disable-line operator-linebreak
|
|
190
|
+
// @ts-ignore
|
|
191
|
+
globalThis.Buffer.from(string)
|
|
192
|
+
) : utf8ToBytes(string);
|
|
193
|
+
}
|
|
194
|
+
) : (
|
|
195
|
+
// eslint-disable-line operator-linebreak
|
|
196
|
+
/**
|
|
197
|
+
* @param {string} string
|
|
198
|
+
*/
|
|
199
|
+
(string) => {
|
|
200
|
+
return string.length > 64 ? textEncoder.encode(string) : utf8ToBytes(string);
|
|
201
|
+
}
|
|
202
|
+
);
|
|
203
|
+
const fromArray = (arr) => {
|
|
204
|
+
return Uint8Array.from(arr);
|
|
205
|
+
};
|
|
206
|
+
const slice = useBuffer ? (
|
|
207
|
+
// eslint-disable-line operator-linebreak
|
|
208
|
+
/**
|
|
209
|
+
* @param {Uint8Array} bytes
|
|
210
|
+
* @param {number} start
|
|
211
|
+
* @param {number} end
|
|
212
|
+
*/
|
|
213
|
+
(bytes, start, end) => {
|
|
214
|
+
if (isBuffer(bytes)) {
|
|
215
|
+
return new Uint8Array(bytes.subarray(start, end));
|
|
216
|
+
}
|
|
217
|
+
return bytes.slice(start, end);
|
|
218
|
+
}
|
|
219
|
+
) : (
|
|
220
|
+
// eslint-disable-line operator-linebreak
|
|
221
|
+
/**
|
|
222
|
+
* @param {Uint8Array} bytes
|
|
223
|
+
* @param {number} start
|
|
224
|
+
* @param {number} end
|
|
225
|
+
*/
|
|
226
|
+
(bytes, start, end) => {
|
|
227
|
+
return bytes.slice(start, end);
|
|
228
|
+
}
|
|
229
|
+
);
|
|
230
|
+
const concat = useBuffer ? (
|
|
231
|
+
// eslint-disable-line operator-linebreak
|
|
232
|
+
/**
|
|
233
|
+
* @param {Uint8Array[]} chunks
|
|
234
|
+
* @param {number} length
|
|
235
|
+
* @returns {Uint8Array}
|
|
236
|
+
*/
|
|
237
|
+
(chunks, length) => {
|
|
238
|
+
chunks = chunks.map((c) => c instanceof Uint8Array ? c : (
|
|
239
|
+
// eslint-disable-line operator-linebreak
|
|
240
|
+
// @ts-ignore
|
|
241
|
+
globalThis.Buffer.from(c)
|
|
242
|
+
));
|
|
243
|
+
return asU8A(globalThis.Buffer.concat(chunks, length));
|
|
244
|
+
}
|
|
245
|
+
) : (
|
|
246
|
+
// eslint-disable-line operator-linebreak
|
|
247
|
+
/**
|
|
248
|
+
* @param {Uint8Array[]} chunks
|
|
249
|
+
* @param {number} length
|
|
250
|
+
* @returns {Uint8Array}
|
|
251
|
+
*/
|
|
252
|
+
(chunks, length) => {
|
|
253
|
+
const out = new Uint8Array(length);
|
|
254
|
+
let off = 0;
|
|
255
|
+
for (let b of chunks) {
|
|
256
|
+
if (off + b.length > out.length) {
|
|
257
|
+
b = b.subarray(0, out.length - off);
|
|
258
|
+
}
|
|
259
|
+
out.set(b, off);
|
|
260
|
+
off += b.length;
|
|
261
|
+
}
|
|
262
|
+
return out;
|
|
263
|
+
}
|
|
264
|
+
);
|
|
265
|
+
const alloc = useBuffer ? (
|
|
266
|
+
// eslint-disable-line operator-linebreak
|
|
267
|
+
/**
|
|
268
|
+
* @param {number} size
|
|
269
|
+
* @returns {Uint8Array}
|
|
270
|
+
*/
|
|
271
|
+
(size) => {
|
|
272
|
+
return globalThis.Buffer.allocUnsafe(size);
|
|
273
|
+
}
|
|
274
|
+
) : (
|
|
275
|
+
// eslint-disable-line operator-linebreak
|
|
276
|
+
/**
|
|
277
|
+
* @param {number} size
|
|
278
|
+
* @returns {Uint8Array}
|
|
279
|
+
*/
|
|
280
|
+
(size) => {
|
|
281
|
+
return new Uint8Array(size);
|
|
282
|
+
}
|
|
283
|
+
);
|
|
284
|
+
function compare(b1, b2) {
|
|
285
|
+
if (isBuffer(b1) && isBuffer(b2)) {
|
|
286
|
+
return b1.compare(b2);
|
|
287
|
+
}
|
|
288
|
+
for (let i = 0; i < b1.length; i++) {
|
|
289
|
+
if (b1[i] === b2[i]) {
|
|
290
|
+
continue;
|
|
291
|
+
}
|
|
292
|
+
return b1[i] < b2[i] ? -1 : 1;
|
|
293
|
+
}
|
|
294
|
+
return 0;
|
|
295
|
+
}
|
|
296
|
+
function utf8ToBytes(str) {
|
|
297
|
+
const out = [];
|
|
298
|
+
let p = 0;
|
|
299
|
+
for (let i = 0; i < str.length; i++) {
|
|
300
|
+
let c = str.charCodeAt(i);
|
|
301
|
+
if (c < 128) {
|
|
302
|
+
out[p++] = c;
|
|
303
|
+
} else if (c < 2048) {
|
|
304
|
+
out[p++] = c >> 6 | 192;
|
|
305
|
+
out[p++] = c & 63 | 128;
|
|
306
|
+
} else if ((c & 64512) === 55296 && i + 1 < str.length && (str.charCodeAt(i + 1) & 64512) === 56320) {
|
|
307
|
+
c = 65536 + ((c & 1023) << 10) + (str.charCodeAt(++i) & 1023);
|
|
308
|
+
out[p++] = c >> 18 | 240;
|
|
309
|
+
out[p++] = c >> 12 & 63 | 128;
|
|
310
|
+
out[p++] = c >> 6 & 63 | 128;
|
|
311
|
+
out[p++] = c & 63 | 128;
|
|
312
|
+
} else {
|
|
313
|
+
out[p++] = c >> 12 | 224;
|
|
314
|
+
out[p++] = c >> 6 & 63 | 128;
|
|
315
|
+
out[p++] = c & 63 | 128;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return out;
|
|
319
|
+
}
|
|
320
|
+
function utf8Slice(buf2, offset, end) {
|
|
321
|
+
const res = [];
|
|
322
|
+
while (offset < end) {
|
|
323
|
+
const firstByte = buf2[offset];
|
|
324
|
+
let codePoint = null;
|
|
325
|
+
let bytesPerSequence = firstByte > 239 ? 4 : firstByte > 223 ? 3 : firstByte > 191 ? 2 : 1;
|
|
326
|
+
if (offset + bytesPerSequence <= end) {
|
|
327
|
+
let secondByte, thirdByte, fourthByte, tempCodePoint;
|
|
328
|
+
switch (bytesPerSequence) {
|
|
329
|
+
case 1:
|
|
330
|
+
if (firstByte < 128) {
|
|
331
|
+
codePoint = firstByte;
|
|
332
|
+
}
|
|
333
|
+
break;
|
|
334
|
+
case 2:
|
|
335
|
+
secondByte = buf2[offset + 1];
|
|
336
|
+
if ((secondByte & 192) === 128) {
|
|
337
|
+
tempCodePoint = (firstByte & 31) << 6 | secondByte & 63;
|
|
338
|
+
if (tempCodePoint > 127) {
|
|
339
|
+
codePoint = tempCodePoint;
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
break;
|
|
343
|
+
case 3:
|
|
344
|
+
secondByte = buf2[offset + 1];
|
|
345
|
+
thirdByte = buf2[offset + 2];
|
|
346
|
+
if ((secondByte & 192) === 128 && (thirdByte & 192) === 128) {
|
|
347
|
+
tempCodePoint = (firstByte & 15) << 12 | (secondByte & 63) << 6 | thirdByte & 63;
|
|
348
|
+
if (tempCodePoint > 2047 && (tempCodePoint < 55296 || tempCodePoint > 57343)) {
|
|
349
|
+
codePoint = tempCodePoint;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
break;
|
|
353
|
+
case 4:
|
|
354
|
+
secondByte = buf2[offset + 1];
|
|
355
|
+
thirdByte = buf2[offset + 2];
|
|
356
|
+
fourthByte = buf2[offset + 3];
|
|
357
|
+
if ((secondByte & 192) === 128 && (thirdByte & 192) === 128 && (fourthByte & 192) === 128) {
|
|
358
|
+
tempCodePoint = (firstByte & 15) << 18 | (secondByte & 63) << 12 | (thirdByte & 63) << 6 | fourthByte & 63;
|
|
359
|
+
if (tempCodePoint > 65535 && tempCodePoint < 1114112) {
|
|
360
|
+
codePoint = tempCodePoint;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
if (codePoint === null) {
|
|
366
|
+
codePoint = 65533;
|
|
367
|
+
bytesPerSequence = 1;
|
|
368
|
+
} else if (codePoint > 65535) {
|
|
369
|
+
codePoint -= 65536;
|
|
370
|
+
res.push(codePoint >>> 10 & 1023 | 55296);
|
|
371
|
+
codePoint = 56320 | codePoint & 1023;
|
|
372
|
+
}
|
|
373
|
+
res.push(codePoint);
|
|
374
|
+
offset += bytesPerSequence;
|
|
375
|
+
}
|
|
376
|
+
return decodeCodePointsArray(res);
|
|
377
|
+
}
|
|
378
|
+
const MAX_ARGUMENTS_LENGTH = 4096;
|
|
379
|
+
function decodeCodePointsArray(codePoints) {
|
|
380
|
+
const len = codePoints.length;
|
|
381
|
+
if (len <= MAX_ARGUMENTS_LENGTH) {
|
|
382
|
+
return String.fromCharCode.apply(String, codePoints);
|
|
383
|
+
}
|
|
384
|
+
let res = "";
|
|
385
|
+
let i = 0;
|
|
386
|
+
while (i < len) {
|
|
387
|
+
res += String.fromCharCode.apply(
|
|
388
|
+
String,
|
|
389
|
+
codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
return res;
|
|
393
|
+
}
|
|
394
|
+
const defaultChunkSize = 256;
|
|
395
|
+
class Bl {
|
|
396
|
+
/**
|
|
397
|
+
* @param {number} [chunkSize]
|
|
398
|
+
*/
|
|
399
|
+
constructor(chunkSize = defaultChunkSize) {
|
|
400
|
+
this.chunkSize = chunkSize;
|
|
401
|
+
this.cursor = 0;
|
|
402
|
+
this.maxCursor = -1;
|
|
403
|
+
this.chunks = [];
|
|
404
|
+
this._initReuseChunk = null;
|
|
405
|
+
}
|
|
406
|
+
reset() {
|
|
407
|
+
this.cursor = 0;
|
|
408
|
+
this.maxCursor = -1;
|
|
409
|
+
if (this.chunks.length) {
|
|
410
|
+
this.chunks = [];
|
|
411
|
+
}
|
|
412
|
+
if (this._initReuseChunk !== null) {
|
|
413
|
+
this.chunks.push(this._initReuseChunk);
|
|
414
|
+
this.maxCursor = this._initReuseChunk.length - 1;
|
|
415
|
+
}
|
|
416
|
+
}
|
|
417
|
+
/**
|
|
418
|
+
* @param {Uint8Array|number[]} bytes
|
|
419
|
+
*/
|
|
420
|
+
push(bytes) {
|
|
421
|
+
let topChunk = this.chunks[this.chunks.length - 1];
|
|
422
|
+
const newMax = this.cursor + bytes.length;
|
|
423
|
+
if (newMax <= this.maxCursor + 1) {
|
|
424
|
+
const chunkPos = topChunk.length - (this.maxCursor - this.cursor) - 1;
|
|
425
|
+
topChunk.set(bytes, chunkPos);
|
|
426
|
+
} else {
|
|
427
|
+
if (topChunk) {
|
|
428
|
+
const chunkPos = topChunk.length - (this.maxCursor - this.cursor) - 1;
|
|
429
|
+
if (chunkPos < topChunk.length) {
|
|
430
|
+
this.chunks[this.chunks.length - 1] = topChunk.subarray(0, chunkPos);
|
|
431
|
+
this.maxCursor = this.cursor - 1;
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
if (bytes.length < 64 && bytes.length < this.chunkSize) {
|
|
435
|
+
topChunk = alloc(this.chunkSize);
|
|
436
|
+
this.chunks.push(topChunk);
|
|
437
|
+
this.maxCursor += topChunk.length;
|
|
438
|
+
if (this._initReuseChunk === null) {
|
|
439
|
+
this._initReuseChunk = topChunk;
|
|
440
|
+
}
|
|
441
|
+
topChunk.set(bytes, 0);
|
|
442
|
+
} else {
|
|
443
|
+
this.chunks.push(bytes);
|
|
444
|
+
this.maxCursor += bytes.length;
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
this.cursor += bytes.length;
|
|
448
|
+
}
|
|
449
|
+
/**
|
|
450
|
+
* @param {boolean} [reset]
|
|
451
|
+
* @returns {Uint8Array}
|
|
452
|
+
*/
|
|
453
|
+
toBytes(reset = false) {
|
|
454
|
+
let byts;
|
|
455
|
+
if (this.chunks.length === 1) {
|
|
456
|
+
const chunk = this.chunks[0];
|
|
457
|
+
if (reset && this.cursor > chunk.length / 2) {
|
|
458
|
+
byts = this.cursor === chunk.length ? chunk : chunk.subarray(0, this.cursor);
|
|
459
|
+
this._initReuseChunk = null;
|
|
460
|
+
this.chunks = [];
|
|
461
|
+
} else {
|
|
462
|
+
byts = slice(chunk, 0, this.cursor);
|
|
463
|
+
}
|
|
464
|
+
} else {
|
|
465
|
+
byts = concat(this.chunks, this.cursor);
|
|
466
|
+
}
|
|
467
|
+
if (reset) {
|
|
468
|
+
this.reset();
|
|
469
|
+
}
|
|
470
|
+
return byts;
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
const decodeErrPrefix = "CBOR decode error:";
|
|
474
|
+
const encodeErrPrefix = "CBOR encode error:";
|
|
475
|
+
function assertEnoughData(data, pos, need) {
|
|
476
|
+
if (data.length - pos < need) {
|
|
477
|
+
throw new Error(`${decodeErrPrefix} not enough data for type`);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
const uintBoundaries = [24, 256, 65536, 4294967296, BigInt("18446744073709551616")];
|
|
481
|
+
function readUint8(data, offset, options) {
|
|
482
|
+
assertEnoughData(data, offset, 1);
|
|
483
|
+
const value = data[offset];
|
|
484
|
+
if (options.strict === true && value < uintBoundaries[0]) {
|
|
485
|
+
throw new Error(`${decodeErrPrefix} integer encoded in more bytes than necessary (strict decode)`);
|
|
486
|
+
}
|
|
487
|
+
return value;
|
|
488
|
+
}
|
|
489
|
+
function readUint16(data, offset, options) {
|
|
490
|
+
assertEnoughData(data, offset, 2);
|
|
491
|
+
const value = data[offset] << 8 | data[offset + 1];
|
|
492
|
+
if (options.strict === true && value < uintBoundaries[1]) {
|
|
493
|
+
throw new Error(`${decodeErrPrefix} integer encoded in more bytes than necessary (strict decode)`);
|
|
494
|
+
}
|
|
495
|
+
return value;
|
|
496
|
+
}
|
|
497
|
+
function readUint32(data, offset, options) {
|
|
498
|
+
assertEnoughData(data, offset, 4);
|
|
499
|
+
const value = data[offset] * 16777216 + (data[offset + 1] << 16) + (data[offset + 2] << 8) + data[offset + 3];
|
|
500
|
+
if (options.strict === true && value < uintBoundaries[2]) {
|
|
501
|
+
throw new Error(`${decodeErrPrefix} integer encoded in more bytes than necessary (strict decode)`);
|
|
502
|
+
}
|
|
503
|
+
return value;
|
|
504
|
+
}
|
|
505
|
+
function readUint64(data, offset, options) {
|
|
506
|
+
assertEnoughData(data, offset, 8);
|
|
507
|
+
const hi = data[offset] * 16777216 + (data[offset + 1] << 16) + (data[offset + 2] << 8) + data[offset + 3];
|
|
508
|
+
const lo = data[offset + 4] * 16777216 + (data[offset + 5] << 16) + (data[offset + 6] << 8) + data[offset + 7];
|
|
509
|
+
const value = (BigInt(hi) << BigInt(32)) + BigInt(lo);
|
|
510
|
+
if (options.strict === true && value < uintBoundaries[3]) {
|
|
511
|
+
throw new Error(`${decodeErrPrefix} integer encoded in more bytes than necessary (strict decode)`);
|
|
512
|
+
}
|
|
513
|
+
if (value <= Number.MAX_SAFE_INTEGER) {
|
|
514
|
+
return Number(value);
|
|
515
|
+
}
|
|
516
|
+
if (options.allowBigInt === true) {
|
|
517
|
+
return value;
|
|
518
|
+
}
|
|
519
|
+
throw new Error(`${decodeErrPrefix} integers outside of the safe integer range are not supported`);
|
|
520
|
+
}
|
|
521
|
+
function decodeUint8(data, pos, _minor, options) {
|
|
522
|
+
return new Token(Type.uint, readUint8(data, pos + 1, options), 2);
|
|
523
|
+
}
|
|
524
|
+
function decodeUint16(data, pos, _minor, options) {
|
|
525
|
+
return new Token(Type.uint, readUint16(data, pos + 1, options), 3);
|
|
526
|
+
}
|
|
527
|
+
function decodeUint32(data, pos, _minor, options) {
|
|
528
|
+
return new Token(Type.uint, readUint32(data, pos + 1, options), 5);
|
|
529
|
+
}
|
|
530
|
+
function decodeUint64(data, pos, _minor, options) {
|
|
531
|
+
return new Token(Type.uint, readUint64(data, pos + 1, options), 9);
|
|
532
|
+
}
|
|
533
|
+
function encodeUint(buf2, token) {
|
|
534
|
+
return encodeUintValue(buf2, 0, token.value);
|
|
535
|
+
}
|
|
536
|
+
function encodeUintValue(buf2, major, uint) {
|
|
537
|
+
if (uint < uintBoundaries[0]) {
|
|
538
|
+
const nuint = Number(uint);
|
|
539
|
+
buf2.push([major | nuint]);
|
|
540
|
+
} else if (uint < uintBoundaries[1]) {
|
|
541
|
+
const nuint = Number(uint);
|
|
542
|
+
buf2.push([major | 24, nuint]);
|
|
543
|
+
} else if (uint < uintBoundaries[2]) {
|
|
544
|
+
const nuint = Number(uint);
|
|
545
|
+
buf2.push([major | 25, nuint >>> 8, nuint & 255]);
|
|
546
|
+
} else if (uint < uintBoundaries[3]) {
|
|
547
|
+
const nuint = Number(uint);
|
|
548
|
+
buf2.push([major | 26, nuint >>> 24 & 255, nuint >>> 16 & 255, nuint >>> 8 & 255, nuint & 255]);
|
|
549
|
+
} else {
|
|
550
|
+
const buint = BigInt(uint);
|
|
551
|
+
if (buint < uintBoundaries[4]) {
|
|
552
|
+
const set = [major | 27, 0, 0, 0, 0, 0, 0, 0];
|
|
553
|
+
let lo = Number(buint & BigInt(4294967295));
|
|
554
|
+
let hi = Number(buint >> BigInt(32) & BigInt(4294967295));
|
|
555
|
+
set[8] = lo & 255;
|
|
556
|
+
lo = lo >> 8;
|
|
557
|
+
set[7] = lo & 255;
|
|
558
|
+
lo = lo >> 8;
|
|
559
|
+
set[6] = lo & 255;
|
|
560
|
+
lo = lo >> 8;
|
|
561
|
+
set[5] = lo & 255;
|
|
562
|
+
set[4] = hi & 255;
|
|
563
|
+
hi = hi >> 8;
|
|
564
|
+
set[3] = hi & 255;
|
|
565
|
+
hi = hi >> 8;
|
|
566
|
+
set[2] = hi & 255;
|
|
567
|
+
hi = hi >> 8;
|
|
568
|
+
set[1] = hi & 255;
|
|
569
|
+
buf2.push(set);
|
|
570
|
+
} else {
|
|
571
|
+
throw new Error(`${decodeErrPrefix} encountered BigInt larger than allowable range`);
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
encodeUint.encodedSize = function encodedSize(token) {
|
|
576
|
+
return encodeUintValue.encodedSize(token.value);
|
|
577
|
+
};
|
|
578
|
+
encodeUintValue.encodedSize = function encodedSize2(uint) {
|
|
579
|
+
if (uint < uintBoundaries[0]) {
|
|
580
|
+
return 1;
|
|
581
|
+
}
|
|
582
|
+
if (uint < uintBoundaries[1]) {
|
|
583
|
+
return 2;
|
|
584
|
+
}
|
|
585
|
+
if (uint < uintBoundaries[2]) {
|
|
586
|
+
return 3;
|
|
587
|
+
}
|
|
588
|
+
if (uint < uintBoundaries[3]) {
|
|
589
|
+
return 5;
|
|
590
|
+
}
|
|
591
|
+
return 9;
|
|
592
|
+
};
|
|
593
|
+
encodeUint.compareTokens = function compareTokens(tok1, tok2) {
|
|
594
|
+
return tok1.value < tok2.value ? -1 : tok1.value > tok2.value ? 1 : (
|
|
595
|
+
/* c8 ignore next */
|
|
596
|
+
0
|
|
597
|
+
);
|
|
598
|
+
};
|
|
599
|
+
function decodeNegint8(data, pos, _minor, options) {
|
|
600
|
+
return new Token(Type.negint, -1 - readUint8(data, pos + 1, options), 2);
|
|
601
|
+
}
|
|
602
|
+
function decodeNegint16(data, pos, _minor, options) {
|
|
603
|
+
return new Token(Type.negint, -1 - readUint16(data, pos + 1, options), 3);
|
|
604
|
+
}
|
|
605
|
+
function decodeNegint32(data, pos, _minor, options) {
|
|
606
|
+
return new Token(Type.negint, -1 - readUint32(data, pos + 1, options), 5);
|
|
607
|
+
}
|
|
608
|
+
const neg1b = BigInt(-1);
|
|
609
|
+
const pos1b = BigInt(1);
|
|
610
|
+
function decodeNegint64(data, pos, _minor, options) {
|
|
611
|
+
const int = readUint64(data, pos + 1, options);
|
|
612
|
+
if (typeof int !== "bigint") {
|
|
613
|
+
const value = -1 - int;
|
|
614
|
+
if (value >= Number.MIN_SAFE_INTEGER) {
|
|
615
|
+
return new Token(Type.negint, value, 9);
|
|
616
|
+
}
|
|
617
|
+
}
|
|
618
|
+
if (options.allowBigInt !== true) {
|
|
619
|
+
throw new Error(`${decodeErrPrefix} integers outside of the safe integer range are not supported`);
|
|
620
|
+
}
|
|
621
|
+
return new Token(Type.negint, neg1b - BigInt(int), 9);
|
|
622
|
+
}
|
|
623
|
+
function encodeNegint(buf2, token) {
|
|
624
|
+
const negint = token.value;
|
|
625
|
+
const unsigned = typeof negint === "bigint" ? negint * neg1b - pos1b : negint * -1 - 1;
|
|
626
|
+
encodeUintValue(buf2, token.type.majorEncoded, unsigned);
|
|
627
|
+
}
|
|
628
|
+
encodeNegint.encodedSize = function encodedSize3(token) {
|
|
629
|
+
const negint = token.value;
|
|
630
|
+
const unsigned = typeof negint === "bigint" ? negint * neg1b - pos1b : negint * -1 - 1;
|
|
631
|
+
if (unsigned < uintBoundaries[0]) {
|
|
632
|
+
return 1;
|
|
633
|
+
}
|
|
634
|
+
if (unsigned < uintBoundaries[1]) {
|
|
635
|
+
return 2;
|
|
636
|
+
}
|
|
637
|
+
if (unsigned < uintBoundaries[2]) {
|
|
638
|
+
return 3;
|
|
639
|
+
}
|
|
640
|
+
if (unsigned < uintBoundaries[3]) {
|
|
641
|
+
return 5;
|
|
642
|
+
}
|
|
643
|
+
return 9;
|
|
644
|
+
};
|
|
645
|
+
encodeNegint.compareTokens = function compareTokens2(tok1, tok2) {
|
|
646
|
+
return tok1.value < tok2.value ? 1 : tok1.value > tok2.value ? -1 : (
|
|
647
|
+
/* c8 ignore next */
|
|
648
|
+
0
|
|
649
|
+
);
|
|
650
|
+
};
|
|
651
|
+
function toToken$3(data, pos, prefix, length) {
|
|
652
|
+
assertEnoughData(data, pos, prefix + length);
|
|
653
|
+
const buf2 = slice(data, pos + prefix, pos + prefix + length);
|
|
654
|
+
return new Token(Type.bytes, buf2, prefix + length);
|
|
655
|
+
}
|
|
656
|
+
function decodeBytesCompact(data, pos, minor, _options) {
|
|
657
|
+
return toToken$3(data, pos, 1, minor);
|
|
658
|
+
}
|
|
659
|
+
function decodeBytes8(data, pos, _minor, options) {
|
|
660
|
+
return toToken$3(data, pos, 2, readUint8(data, pos + 1, options));
|
|
661
|
+
}
|
|
662
|
+
function decodeBytes16(data, pos, _minor, options) {
|
|
663
|
+
return toToken$3(data, pos, 3, readUint16(data, pos + 1, options));
|
|
664
|
+
}
|
|
665
|
+
function decodeBytes32(data, pos, _minor, options) {
|
|
666
|
+
return toToken$3(data, pos, 5, readUint32(data, pos + 1, options));
|
|
667
|
+
}
|
|
668
|
+
function decodeBytes64(data, pos, _minor, options) {
|
|
669
|
+
const l = readUint64(data, pos + 1, options);
|
|
670
|
+
if (typeof l === "bigint") {
|
|
671
|
+
throw new Error(`${decodeErrPrefix} 64-bit integer bytes lengths not supported`);
|
|
672
|
+
}
|
|
673
|
+
return toToken$3(data, pos, 9, l);
|
|
674
|
+
}
|
|
675
|
+
function tokenBytes(token) {
|
|
676
|
+
if (token.encodedBytes === void 0) {
|
|
677
|
+
token.encodedBytes = token.type === Type.string ? fromString(token.value) : token.value;
|
|
678
|
+
}
|
|
679
|
+
return token.encodedBytes;
|
|
680
|
+
}
|
|
681
|
+
function encodeBytes(buf2, token) {
|
|
682
|
+
const bytes = tokenBytes(token);
|
|
683
|
+
encodeUintValue(buf2, token.type.majorEncoded, bytes.length);
|
|
684
|
+
buf2.push(bytes);
|
|
685
|
+
}
|
|
686
|
+
encodeBytes.encodedSize = function encodedSize4(token) {
|
|
687
|
+
const bytes = tokenBytes(token);
|
|
688
|
+
return encodeUintValue.encodedSize(bytes.length) + bytes.length;
|
|
689
|
+
};
|
|
690
|
+
encodeBytes.compareTokens = function compareTokens3(tok1, tok2) {
|
|
691
|
+
return compareBytes(tokenBytes(tok1), tokenBytes(tok2));
|
|
692
|
+
};
|
|
693
|
+
function compareBytes(b1, b2) {
|
|
694
|
+
return b1.length < b2.length ? -1 : b1.length > b2.length ? 1 : compare(b1, b2);
|
|
695
|
+
}
|
|
696
|
+
function toToken$2(data, pos, prefix, length, options) {
|
|
697
|
+
const totLength = prefix + length;
|
|
698
|
+
assertEnoughData(data, pos, totLength);
|
|
699
|
+
const tok = new Token(Type.string, toString(data, pos + prefix, pos + totLength), totLength);
|
|
700
|
+
if (options.retainStringBytes === true) {
|
|
701
|
+
tok.byteValue = slice(data, pos + prefix, pos + totLength);
|
|
702
|
+
}
|
|
703
|
+
return tok;
|
|
704
|
+
}
|
|
705
|
+
function decodeStringCompact(data, pos, minor, options) {
|
|
706
|
+
return toToken$2(data, pos, 1, minor, options);
|
|
707
|
+
}
|
|
708
|
+
function decodeString8(data, pos, _minor, options) {
|
|
709
|
+
return toToken$2(data, pos, 2, readUint8(data, pos + 1, options), options);
|
|
710
|
+
}
|
|
711
|
+
function decodeString16(data, pos, _minor, options) {
|
|
712
|
+
return toToken$2(data, pos, 3, readUint16(data, pos + 1, options), options);
|
|
713
|
+
}
|
|
714
|
+
function decodeString32(data, pos, _minor, options) {
|
|
715
|
+
return toToken$2(data, pos, 5, readUint32(data, pos + 1, options), options);
|
|
716
|
+
}
|
|
717
|
+
function decodeString64(data, pos, _minor, options) {
|
|
718
|
+
const l = readUint64(data, pos + 1, options);
|
|
719
|
+
if (typeof l === "bigint") {
|
|
720
|
+
throw new Error(`${decodeErrPrefix} 64-bit integer string lengths not supported`);
|
|
721
|
+
}
|
|
722
|
+
return toToken$2(data, pos, 9, l, options);
|
|
723
|
+
}
|
|
724
|
+
const encodeString = encodeBytes;
|
|
725
|
+
function toToken$1(_data, _pos, prefix, length) {
|
|
726
|
+
return new Token(Type.array, length, prefix);
|
|
727
|
+
}
|
|
728
|
+
function decodeArrayCompact(data, pos, minor, _options) {
|
|
729
|
+
return toToken$1(data, pos, 1, minor);
|
|
730
|
+
}
|
|
731
|
+
function decodeArray8(data, pos, _minor, options) {
|
|
732
|
+
return toToken$1(data, pos, 2, readUint8(data, pos + 1, options));
|
|
733
|
+
}
|
|
734
|
+
function decodeArray16(data, pos, _minor, options) {
|
|
735
|
+
return toToken$1(data, pos, 3, readUint16(data, pos + 1, options));
|
|
736
|
+
}
|
|
737
|
+
function decodeArray32(data, pos, _minor, options) {
|
|
738
|
+
return toToken$1(data, pos, 5, readUint32(data, pos + 1, options));
|
|
739
|
+
}
|
|
740
|
+
function decodeArray64(data, pos, _minor, options) {
|
|
741
|
+
const l = readUint64(data, pos + 1, options);
|
|
742
|
+
if (typeof l === "bigint") {
|
|
743
|
+
throw new Error(`${decodeErrPrefix} 64-bit integer array lengths not supported`);
|
|
744
|
+
}
|
|
745
|
+
return toToken$1(data, pos, 9, l);
|
|
746
|
+
}
|
|
747
|
+
function decodeArrayIndefinite(data, pos, _minor, options) {
|
|
748
|
+
if (options.allowIndefinite === false) {
|
|
749
|
+
throw new Error(`${decodeErrPrefix} indefinite length items not allowed`);
|
|
750
|
+
}
|
|
751
|
+
return toToken$1(data, pos, 1, Infinity);
|
|
752
|
+
}
|
|
753
|
+
function encodeArray(buf2, token) {
|
|
754
|
+
encodeUintValue(buf2, Type.array.majorEncoded, token.value);
|
|
755
|
+
}
|
|
756
|
+
encodeArray.compareTokens = encodeUint.compareTokens;
|
|
757
|
+
encodeArray.encodedSize = function encodedSize5(token) {
|
|
758
|
+
return encodeUintValue.encodedSize(token.value);
|
|
759
|
+
};
|
|
760
|
+
function toToken(_data, _pos, prefix, length) {
|
|
761
|
+
return new Token(Type.map, length, prefix);
|
|
762
|
+
}
|
|
763
|
+
function decodeMapCompact(data, pos, minor, _options) {
|
|
764
|
+
return toToken(data, pos, 1, minor);
|
|
765
|
+
}
|
|
766
|
+
function decodeMap8(data, pos, _minor, options) {
|
|
767
|
+
return toToken(data, pos, 2, readUint8(data, pos + 1, options));
|
|
768
|
+
}
|
|
769
|
+
function decodeMap16(data, pos, _minor, options) {
|
|
770
|
+
return toToken(data, pos, 3, readUint16(data, pos + 1, options));
|
|
771
|
+
}
|
|
772
|
+
function decodeMap32(data, pos, _minor, options) {
|
|
773
|
+
return toToken(data, pos, 5, readUint32(data, pos + 1, options));
|
|
774
|
+
}
|
|
775
|
+
function decodeMap64(data, pos, _minor, options) {
|
|
776
|
+
const l = readUint64(data, pos + 1, options);
|
|
777
|
+
if (typeof l === "bigint") {
|
|
778
|
+
throw new Error(`${decodeErrPrefix} 64-bit integer map lengths not supported`);
|
|
779
|
+
}
|
|
780
|
+
return toToken(data, pos, 9, l);
|
|
781
|
+
}
|
|
782
|
+
function decodeMapIndefinite(data, pos, _minor, options) {
|
|
783
|
+
if (options.allowIndefinite === false) {
|
|
784
|
+
throw new Error(`${decodeErrPrefix} indefinite length items not allowed`);
|
|
785
|
+
}
|
|
786
|
+
return toToken(data, pos, 1, Infinity);
|
|
787
|
+
}
|
|
788
|
+
function encodeMap(buf2, token) {
|
|
789
|
+
encodeUintValue(buf2, Type.map.majorEncoded, token.value);
|
|
790
|
+
}
|
|
791
|
+
encodeMap.compareTokens = encodeUint.compareTokens;
|
|
792
|
+
encodeMap.encodedSize = function encodedSize6(token) {
|
|
793
|
+
return encodeUintValue.encodedSize(token.value);
|
|
794
|
+
};
|
|
795
|
+
function decodeTagCompact(_data, _pos, minor, _options) {
|
|
796
|
+
return new Token(Type.tag, minor, 1);
|
|
797
|
+
}
|
|
798
|
+
function decodeTag8(data, pos, _minor, options) {
|
|
799
|
+
return new Token(Type.tag, readUint8(data, pos + 1, options), 2);
|
|
800
|
+
}
|
|
801
|
+
function decodeTag16(data, pos, _minor, options) {
|
|
802
|
+
return new Token(Type.tag, readUint16(data, pos + 1, options), 3);
|
|
803
|
+
}
|
|
804
|
+
function decodeTag32(data, pos, _minor, options) {
|
|
805
|
+
return new Token(Type.tag, readUint32(data, pos + 1, options), 5);
|
|
806
|
+
}
|
|
807
|
+
function decodeTag64(data, pos, _minor, options) {
|
|
808
|
+
return new Token(Type.tag, readUint64(data, pos + 1, options), 9);
|
|
809
|
+
}
|
|
810
|
+
function encodeTag(buf2, token) {
|
|
811
|
+
encodeUintValue(buf2, Type.tag.majorEncoded, token.value);
|
|
812
|
+
}
|
|
813
|
+
encodeTag.compareTokens = encodeUint.compareTokens;
|
|
814
|
+
encodeTag.encodedSize = function encodedSize7(token) {
|
|
815
|
+
return encodeUintValue.encodedSize(token.value);
|
|
816
|
+
};
|
|
817
|
+
const MINOR_FALSE = 20;
|
|
818
|
+
const MINOR_TRUE = 21;
|
|
819
|
+
const MINOR_NULL = 22;
|
|
820
|
+
const MINOR_UNDEFINED = 23;
|
|
821
|
+
function decodeUndefined(_data, _pos, _minor, options) {
|
|
822
|
+
if (options.allowUndefined === false) {
|
|
823
|
+
throw new Error(`${decodeErrPrefix} undefined values are not supported`);
|
|
824
|
+
} else if (options.coerceUndefinedToNull === true) {
|
|
825
|
+
return new Token(Type.null, null, 1);
|
|
826
|
+
}
|
|
827
|
+
return new Token(Type.undefined, void 0, 1);
|
|
828
|
+
}
|
|
829
|
+
function decodeBreak(_data, _pos, _minor, options) {
|
|
830
|
+
if (options.allowIndefinite === false) {
|
|
831
|
+
throw new Error(`${decodeErrPrefix} indefinite length items not allowed`);
|
|
832
|
+
}
|
|
833
|
+
return new Token(Type.break, void 0, 1);
|
|
834
|
+
}
|
|
835
|
+
function createToken(value, bytes, options) {
|
|
836
|
+
if (options) {
|
|
837
|
+
if (options.allowNaN === false && Number.isNaN(value)) {
|
|
838
|
+
throw new Error(`${decodeErrPrefix} NaN values are not supported`);
|
|
839
|
+
}
|
|
840
|
+
if (options.allowInfinity === false && (value === Infinity || value === -Infinity)) {
|
|
841
|
+
throw new Error(`${decodeErrPrefix} Infinity values are not supported`);
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
return new Token(Type.float, value, bytes);
|
|
845
|
+
}
|
|
846
|
+
function decodeFloat16(data, pos, _minor, options) {
|
|
847
|
+
return createToken(readFloat16(data, pos + 1), 3, options);
|
|
848
|
+
}
|
|
849
|
+
function decodeFloat32(data, pos, _minor, options) {
|
|
850
|
+
return createToken(readFloat32(data, pos + 1), 5, options);
|
|
851
|
+
}
|
|
852
|
+
function decodeFloat64(data, pos, _minor, options) {
|
|
853
|
+
return createToken(readFloat64(data, pos + 1), 9, options);
|
|
854
|
+
}
|
|
855
|
+
function encodeFloat(buf2, token, options) {
|
|
856
|
+
const float = token.value;
|
|
857
|
+
if (float === false) {
|
|
858
|
+
buf2.push([Type.float.majorEncoded | MINOR_FALSE]);
|
|
859
|
+
} else if (float === true) {
|
|
860
|
+
buf2.push([Type.float.majorEncoded | MINOR_TRUE]);
|
|
861
|
+
} else if (float === null) {
|
|
862
|
+
buf2.push([Type.float.majorEncoded | MINOR_NULL]);
|
|
863
|
+
} else if (float === void 0) {
|
|
864
|
+
buf2.push([Type.float.majorEncoded | MINOR_UNDEFINED]);
|
|
865
|
+
} else {
|
|
866
|
+
let decoded;
|
|
867
|
+
let success = false;
|
|
868
|
+
if (!options || options.float64 !== true) {
|
|
869
|
+
encodeFloat16(float);
|
|
870
|
+
decoded = readFloat16(ui8a, 1);
|
|
871
|
+
if (float === decoded || Number.isNaN(float)) {
|
|
872
|
+
ui8a[0] = 249;
|
|
873
|
+
buf2.push(ui8a.slice(0, 3));
|
|
874
|
+
success = true;
|
|
875
|
+
} else {
|
|
876
|
+
encodeFloat32(float);
|
|
877
|
+
decoded = readFloat32(ui8a, 1);
|
|
878
|
+
if (float === decoded) {
|
|
879
|
+
ui8a[0] = 250;
|
|
880
|
+
buf2.push(ui8a.slice(0, 5));
|
|
881
|
+
success = true;
|
|
882
|
+
}
|
|
883
|
+
}
|
|
884
|
+
}
|
|
885
|
+
if (!success) {
|
|
886
|
+
encodeFloat64(float);
|
|
887
|
+
decoded = readFloat64(ui8a, 1);
|
|
888
|
+
ui8a[0] = 251;
|
|
889
|
+
buf2.push(ui8a.slice(0, 9));
|
|
890
|
+
}
|
|
891
|
+
}
|
|
892
|
+
}
|
|
893
|
+
encodeFloat.encodedSize = function encodedSize8(token, options) {
|
|
894
|
+
const float = token.value;
|
|
895
|
+
if (float === false || float === true || float === null || float === void 0) {
|
|
896
|
+
return 1;
|
|
897
|
+
}
|
|
898
|
+
if (!options || options.float64 !== true) {
|
|
899
|
+
encodeFloat16(float);
|
|
900
|
+
let decoded = readFloat16(ui8a, 1);
|
|
901
|
+
if (float === decoded || Number.isNaN(float)) {
|
|
902
|
+
return 3;
|
|
903
|
+
}
|
|
904
|
+
encodeFloat32(float);
|
|
905
|
+
decoded = readFloat32(ui8a, 1);
|
|
906
|
+
if (float === decoded) {
|
|
907
|
+
return 5;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
910
|
+
return 9;
|
|
911
|
+
};
|
|
912
|
+
const buffer = new ArrayBuffer(9);
|
|
913
|
+
const dataView = new DataView(buffer, 1);
|
|
914
|
+
const ui8a = new Uint8Array(buffer, 0);
|
|
915
|
+
function encodeFloat16(inp) {
|
|
916
|
+
if (inp === Infinity) {
|
|
917
|
+
dataView.setUint16(0, 31744, false);
|
|
918
|
+
} else if (inp === -Infinity) {
|
|
919
|
+
dataView.setUint16(0, 64512, false);
|
|
920
|
+
} else if (Number.isNaN(inp)) {
|
|
921
|
+
dataView.setUint16(0, 32256, false);
|
|
922
|
+
} else {
|
|
923
|
+
dataView.setFloat32(0, inp);
|
|
924
|
+
const valu32 = dataView.getUint32(0);
|
|
925
|
+
const exponent = (valu32 & 2139095040) >> 23;
|
|
926
|
+
const mantissa = valu32 & 8388607;
|
|
927
|
+
if (exponent === 255) {
|
|
928
|
+
dataView.setUint16(0, 31744, false);
|
|
929
|
+
} else if (exponent === 0) {
|
|
930
|
+
dataView.setUint16(0, (inp & 2147483648) >> 16 | mantissa >> 13, false);
|
|
931
|
+
} else {
|
|
932
|
+
const logicalExponent = exponent - 127;
|
|
933
|
+
if (logicalExponent < -24) {
|
|
934
|
+
dataView.setUint16(0, 0);
|
|
935
|
+
} else if (logicalExponent < -14) {
|
|
936
|
+
dataView.setUint16(0, (valu32 & 2147483648) >> 16 | /* sign bit */
|
|
937
|
+
1 << 24 + logicalExponent, false);
|
|
938
|
+
} else {
|
|
939
|
+
dataView.setUint16(0, (valu32 & 2147483648) >> 16 | logicalExponent + 15 << 10 | mantissa >> 13, false);
|
|
940
|
+
}
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
function readFloat16(ui8a2, pos) {
|
|
945
|
+
if (ui8a2.length - pos < 2) {
|
|
946
|
+
throw new Error(`${decodeErrPrefix} not enough data for float16`);
|
|
947
|
+
}
|
|
948
|
+
const half = (ui8a2[pos] << 8) + ui8a2[pos + 1];
|
|
949
|
+
if (half === 31744) {
|
|
950
|
+
return Infinity;
|
|
951
|
+
}
|
|
952
|
+
if (half === 64512) {
|
|
953
|
+
return -Infinity;
|
|
954
|
+
}
|
|
955
|
+
if (half === 32256) {
|
|
956
|
+
return NaN;
|
|
957
|
+
}
|
|
958
|
+
const exp = half >> 10 & 31;
|
|
959
|
+
const mant = half & 1023;
|
|
960
|
+
let val;
|
|
961
|
+
if (exp === 0) {
|
|
962
|
+
val = mant * 2 ** -24;
|
|
963
|
+
} else if (exp !== 31) {
|
|
964
|
+
val = (mant + 1024) * 2 ** (exp - 25);
|
|
965
|
+
} else {
|
|
966
|
+
val = mant === 0 ? Infinity : NaN;
|
|
967
|
+
}
|
|
968
|
+
return half & 32768 ? -val : val;
|
|
969
|
+
}
|
|
970
|
+
function encodeFloat32(inp) {
|
|
971
|
+
dataView.setFloat32(0, inp, false);
|
|
972
|
+
}
|
|
973
|
+
function readFloat32(ui8a2, pos) {
|
|
974
|
+
if (ui8a2.length - pos < 4) {
|
|
975
|
+
throw new Error(`${decodeErrPrefix} not enough data for float32`);
|
|
976
|
+
}
|
|
977
|
+
const offset = (ui8a2.byteOffset || 0) + pos;
|
|
978
|
+
return new DataView(ui8a2.buffer, offset, 4).getFloat32(0, false);
|
|
979
|
+
}
|
|
980
|
+
function encodeFloat64(inp) {
|
|
981
|
+
dataView.setFloat64(0, inp, false);
|
|
982
|
+
}
|
|
983
|
+
function readFloat64(ui8a2, pos) {
|
|
984
|
+
if (ui8a2.length - pos < 8) {
|
|
985
|
+
throw new Error(`${decodeErrPrefix} not enough data for float64`);
|
|
986
|
+
}
|
|
987
|
+
const offset = (ui8a2.byteOffset || 0) + pos;
|
|
988
|
+
return new DataView(ui8a2.buffer, offset, 8).getFloat64(0, false);
|
|
989
|
+
}
|
|
990
|
+
encodeFloat.compareTokens = encodeUint.compareTokens;
|
|
991
|
+
function invalidMinor(data, pos, minor) {
|
|
992
|
+
throw new Error(`${decodeErrPrefix} encountered invalid minor (${minor}) for major ${data[pos] >>> 5}`);
|
|
993
|
+
}
|
|
994
|
+
function errorer(msg) {
|
|
995
|
+
return () => {
|
|
996
|
+
throw new Error(`${decodeErrPrefix} ${msg}`);
|
|
997
|
+
};
|
|
998
|
+
}
|
|
999
|
+
const jump = [];
|
|
1000
|
+
for (let i = 0; i <= 23; i++) {
|
|
1001
|
+
jump[i] = invalidMinor;
|
|
1002
|
+
}
|
|
1003
|
+
jump[24] = decodeUint8;
|
|
1004
|
+
jump[25] = decodeUint16;
|
|
1005
|
+
jump[26] = decodeUint32;
|
|
1006
|
+
jump[27] = decodeUint64;
|
|
1007
|
+
jump[28] = invalidMinor;
|
|
1008
|
+
jump[29] = invalidMinor;
|
|
1009
|
+
jump[30] = invalidMinor;
|
|
1010
|
+
jump[31] = invalidMinor;
|
|
1011
|
+
for (let i = 32; i <= 55; i++) {
|
|
1012
|
+
jump[i] = invalidMinor;
|
|
1013
|
+
}
|
|
1014
|
+
jump[56] = decodeNegint8;
|
|
1015
|
+
jump[57] = decodeNegint16;
|
|
1016
|
+
jump[58] = decodeNegint32;
|
|
1017
|
+
jump[59] = decodeNegint64;
|
|
1018
|
+
jump[60] = invalidMinor;
|
|
1019
|
+
jump[61] = invalidMinor;
|
|
1020
|
+
jump[62] = invalidMinor;
|
|
1021
|
+
jump[63] = invalidMinor;
|
|
1022
|
+
for (let i = 64; i <= 87; i++) {
|
|
1023
|
+
jump[i] = decodeBytesCompact;
|
|
1024
|
+
}
|
|
1025
|
+
jump[88] = decodeBytes8;
|
|
1026
|
+
jump[89] = decodeBytes16;
|
|
1027
|
+
jump[90] = decodeBytes32;
|
|
1028
|
+
jump[91] = decodeBytes64;
|
|
1029
|
+
jump[92] = invalidMinor;
|
|
1030
|
+
jump[93] = invalidMinor;
|
|
1031
|
+
jump[94] = invalidMinor;
|
|
1032
|
+
jump[95] = errorer("indefinite length bytes/strings are not supported");
|
|
1033
|
+
for (let i = 96; i <= 119; i++) {
|
|
1034
|
+
jump[i] = decodeStringCompact;
|
|
1035
|
+
}
|
|
1036
|
+
jump[120] = decodeString8;
|
|
1037
|
+
jump[121] = decodeString16;
|
|
1038
|
+
jump[122] = decodeString32;
|
|
1039
|
+
jump[123] = decodeString64;
|
|
1040
|
+
jump[124] = invalidMinor;
|
|
1041
|
+
jump[125] = invalidMinor;
|
|
1042
|
+
jump[126] = invalidMinor;
|
|
1043
|
+
jump[127] = errorer("indefinite length bytes/strings are not supported");
|
|
1044
|
+
for (let i = 128; i <= 151; i++) {
|
|
1045
|
+
jump[i] = decodeArrayCompact;
|
|
1046
|
+
}
|
|
1047
|
+
jump[152] = decodeArray8;
|
|
1048
|
+
jump[153] = decodeArray16;
|
|
1049
|
+
jump[154] = decodeArray32;
|
|
1050
|
+
jump[155] = decodeArray64;
|
|
1051
|
+
jump[156] = invalidMinor;
|
|
1052
|
+
jump[157] = invalidMinor;
|
|
1053
|
+
jump[158] = invalidMinor;
|
|
1054
|
+
jump[159] = decodeArrayIndefinite;
|
|
1055
|
+
for (let i = 160; i <= 183; i++) {
|
|
1056
|
+
jump[i] = decodeMapCompact;
|
|
1057
|
+
}
|
|
1058
|
+
jump[184] = decodeMap8;
|
|
1059
|
+
jump[185] = decodeMap16;
|
|
1060
|
+
jump[186] = decodeMap32;
|
|
1061
|
+
jump[187] = decodeMap64;
|
|
1062
|
+
jump[188] = invalidMinor;
|
|
1063
|
+
jump[189] = invalidMinor;
|
|
1064
|
+
jump[190] = invalidMinor;
|
|
1065
|
+
jump[191] = decodeMapIndefinite;
|
|
1066
|
+
for (let i = 192; i <= 215; i++) {
|
|
1067
|
+
jump[i] = decodeTagCompact;
|
|
1068
|
+
}
|
|
1069
|
+
jump[216] = decodeTag8;
|
|
1070
|
+
jump[217] = decodeTag16;
|
|
1071
|
+
jump[218] = decodeTag32;
|
|
1072
|
+
jump[219] = decodeTag64;
|
|
1073
|
+
jump[220] = invalidMinor;
|
|
1074
|
+
jump[221] = invalidMinor;
|
|
1075
|
+
jump[222] = invalidMinor;
|
|
1076
|
+
jump[223] = invalidMinor;
|
|
1077
|
+
for (let i = 224; i <= 243; i++) {
|
|
1078
|
+
jump[i] = errorer("simple values are not supported");
|
|
1079
|
+
}
|
|
1080
|
+
jump[244] = invalidMinor;
|
|
1081
|
+
jump[245] = invalidMinor;
|
|
1082
|
+
jump[246] = invalidMinor;
|
|
1083
|
+
jump[247] = decodeUndefined;
|
|
1084
|
+
jump[248] = errorer("simple values are not supported");
|
|
1085
|
+
jump[249] = decodeFloat16;
|
|
1086
|
+
jump[250] = decodeFloat32;
|
|
1087
|
+
jump[251] = decodeFloat64;
|
|
1088
|
+
jump[252] = invalidMinor;
|
|
1089
|
+
jump[253] = invalidMinor;
|
|
1090
|
+
jump[254] = invalidMinor;
|
|
1091
|
+
jump[255] = decodeBreak;
|
|
1092
|
+
const quick = [];
|
|
1093
|
+
for (let i = 0; i < 24; i++) {
|
|
1094
|
+
quick[i] = new Token(Type.uint, i, 1);
|
|
1095
|
+
}
|
|
1096
|
+
for (let i = -1; i >= -24; i--) {
|
|
1097
|
+
quick[31 - i] = new Token(Type.negint, i, 1);
|
|
1098
|
+
}
|
|
1099
|
+
quick[64] = new Token(Type.bytes, new Uint8Array(0), 1);
|
|
1100
|
+
quick[96] = new Token(Type.string, "", 1);
|
|
1101
|
+
quick[128] = new Token(Type.array, 0, 1);
|
|
1102
|
+
quick[160] = new Token(Type.map, 0, 1);
|
|
1103
|
+
quick[244] = new Token(Type.false, false, 1);
|
|
1104
|
+
quick[245] = new Token(Type.true, true, 1);
|
|
1105
|
+
quick[246] = new Token(Type.null, null, 1);
|
|
1106
|
+
function quickEncodeToken(token) {
|
|
1107
|
+
switch (token.type) {
|
|
1108
|
+
case Type.false:
|
|
1109
|
+
return fromArray([244]);
|
|
1110
|
+
case Type.true:
|
|
1111
|
+
return fromArray([245]);
|
|
1112
|
+
case Type.null:
|
|
1113
|
+
return fromArray([246]);
|
|
1114
|
+
case Type.bytes:
|
|
1115
|
+
if (!token.value.length) {
|
|
1116
|
+
return fromArray([64]);
|
|
1117
|
+
}
|
|
1118
|
+
return;
|
|
1119
|
+
case Type.string:
|
|
1120
|
+
if (token.value === "") {
|
|
1121
|
+
return fromArray([96]);
|
|
1122
|
+
}
|
|
1123
|
+
return;
|
|
1124
|
+
case Type.array:
|
|
1125
|
+
if (token.value === 0) {
|
|
1126
|
+
return fromArray([128]);
|
|
1127
|
+
}
|
|
1128
|
+
return;
|
|
1129
|
+
case Type.map:
|
|
1130
|
+
if (token.value === 0) {
|
|
1131
|
+
return fromArray([160]);
|
|
1132
|
+
}
|
|
1133
|
+
return;
|
|
1134
|
+
case Type.uint:
|
|
1135
|
+
if (token.value < 24) {
|
|
1136
|
+
return fromArray([Number(token.value)]);
|
|
1137
|
+
}
|
|
1138
|
+
return;
|
|
1139
|
+
case Type.negint:
|
|
1140
|
+
if (token.value >= -24) {
|
|
1141
|
+
return fromArray([31 - Number(token.value)]);
|
|
1142
|
+
}
|
|
1143
|
+
}
|
|
1144
|
+
}
|
|
1145
|
+
const defaultEncodeOptions = {
|
|
1146
|
+
float64: false,
|
|
1147
|
+
mapSorter,
|
|
1148
|
+
quickEncodeToken
|
|
1149
|
+
};
|
|
1150
|
+
function makeCborEncoders() {
|
|
1151
|
+
const encoders = [];
|
|
1152
|
+
encoders[Type.uint.major] = encodeUint;
|
|
1153
|
+
encoders[Type.negint.major] = encodeNegint;
|
|
1154
|
+
encoders[Type.bytes.major] = encodeBytes;
|
|
1155
|
+
encoders[Type.string.major] = encodeString;
|
|
1156
|
+
encoders[Type.array.major] = encodeArray;
|
|
1157
|
+
encoders[Type.map.major] = encodeMap;
|
|
1158
|
+
encoders[Type.tag.major] = encodeTag;
|
|
1159
|
+
encoders[Type.float.major] = encodeFloat;
|
|
1160
|
+
return encoders;
|
|
1161
|
+
}
|
|
1162
|
+
const cborEncoders = makeCborEncoders();
|
|
1163
|
+
const buf = new Bl();
|
|
1164
|
+
class Ref {
|
|
1165
|
+
/**
|
|
1166
|
+
* @param {object|any[]} obj
|
|
1167
|
+
* @param {Reference|undefined} parent
|
|
1168
|
+
*/
|
|
1169
|
+
constructor(obj, parent) {
|
|
1170
|
+
this.obj = obj;
|
|
1171
|
+
this.parent = parent;
|
|
1172
|
+
}
|
|
1173
|
+
/**
|
|
1174
|
+
* @param {object|any[]} obj
|
|
1175
|
+
* @returns {boolean}
|
|
1176
|
+
*/
|
|
1177
|
+
includes(obj) {
|
|
1178
|
+
let p = this;
|
|
1179
|
+
do {
|
|
1180
|
+
if (p.obj === obj) {
|
|
1181
|
+
return true;
|
|
1182
|
+
}
|
|
1183
|
+
} while (p = p.parent);
|
|
1184
|
+
return false;
|
|
1185
|
+
}
|
|
1186
|
+
/**
|
|
1187
|
+
* @param {Reference|undefined} stack
|
|
1188
|
+
* @param {object|any[]} obj
|
|
1189
|
+
* @returns {Reference}
|
|
1190
|
+
*/
|
|
1191
|
+
static createCheck(stack, obj) {
|
|
1192
|
+
if (stack && stack.includes(obj)) {
|
|
1193
|
+
throw new Error(`${encodeErrPrefix} object contains circular references`);
|
|
1194
|
+
}
|
|
1195
|
+
return new Ref(obj, stack);
|
|
1196
|
+
}
|
|
1197
|
+
}
|
|
1198
|
+
const simpleTokens = {
|
|
1199
|
+
null: new Token(Type.null, null),
|
|
1200
|
+
undefined: new Token(Type.undefined, void 0),
|
|
1201
|
+
true: new Token(Type.true, true),
|
|
1202
|
+
false: new Token(Type.false, false),
|
|
1203
|
+
emptyArray: new Token(Type.array, 0),
|
|
1204
|
+
emptyMap: new Token(Type.map, 0)
|
|
1205
|
+
};
|
|
1206
|
+
const typeEncoders = {
|
|
1207
|
+
/**
|
|
1208
|
+
* @param {any} obj
|
|
1209
|
+
* @param {string} _typ
|
|
1210
|
+
* @param {EncodeOptions} _options
|
|
1211
|
+
* @param {Reference} [_refStack]
|
|
1212
|
+
* @returns {TokenOrNestedTokens}
|
|
1213
|
+
*/
|
|
1214
|
+
number(obj, _typ, _options, _refStack) {
|
|
1215
|
+
if (!Number.isInteger(obj) || !Number.isSafeInteger(obj)) {
|
|
1216
|
+
return new Token(Type.float, obj);
|
|
1217
|
+
} else if (obj >= 0) {
|
|
1218
|
+
return new Token(Type.uint, obj);
|
|
1219
|
+
} else {
|
|
1220
|
+
return new Token(Type.negint, obj);
|
|
1221
|
+
}
|
|
1222
|
+
},
|
|
1223
|
+
/**
|
|
1224
|
+
* @param {any} obj
|
|
1225
|
+
* @param {string} _typ
|
|
1226
|
+
* @param {EncodeOptions} _options
|
|
1227
|
+
* @param {Reference} [_refStack]
|
|
1228
|
+
* @returns {TokenOrNestedTokens}
|
|
1229
|
+
*/
|
|
1230
|
+
bigint(obj, _typ, _options, _refStack) {
|
|
1231
|
+
if (obj >= BigInt(0)) {
|
|
1232
|
+
return new Token(Type.uint, obj);
|
|
1233
|
+
} else {
|
|
1234
|
+
return new Token(Type.negint, obj);
|
|
1235
|
+
}
|
|
1236
|
+
},
|
|
1237
|
+
/**
|
|
1238
|
+
* @param {any} obj
|
|
1239
|
+
* @param {string} _typ
|
|
1240
|
+
* @param {EncodeOptions} _options
|
|
1241
|
+
* @param {Reference} [_refStack]
|
|
1242
|
+
* @returns {TokenOrNestedTokens}
|
|
1243
|
+
*/
|
|
1244
|
+
Uint8Array(obj, _typ, _options, _refStack) {
|
|
1245
|
+
return new Token(Type.bytes, obj);
|
|
1246
|
+
},
|
|
1247
|
+
/**
|
|
1248
|
+
* @param {any} obj
|
|
1249
|
+
* @param {string} _typ
|
|
1250
|
+
* @param {EncodeOptions} _options
|
|
1251
|
+
* @param {Reference} [_refStack]
|
|
1252
|
+
* @returns {TokenOrNestedTokens}
|
|
1253
|
+
*/
|
|
1254
|
+
string(obj, _typ, _options, _refStack) {
|
|
1255
|
+
return new Token(Type.string, obj);
|
|
1256
|
+
},
|
|
1257
|
+
/**
|
|
1258
|
+
* @param {any} obj
|
|
1259
|
+
* @param {string} _typ
|
|
1260
|
+
* @param {EncodeOptions} _options
|
|
1261
|
+
* @param {Reference} [_refStack]
|
|
1262
|
+
* @returns {TokenOrNestedTokens}
|
|
1263
|
+
*/
|
|
1264
|
+
boolean(obj, _typ, _options, _refStack) {
|
|
1265
|
+
return obj ? simpleTokens.true : simpleTokens.false;
|
|
1266
|
+
},
|
|
1267
|
+
/**
|
|
1268
|
+
* @param {any} _obj
|
|
1269
|
+
* @param {string} _typ
|
|
1270
|
+
* @param {EncodeOptions} _options
|
|
1271
|
+
* @param {Reference} [_refStack]
|
|
1272
|
+
* @returns {TokenOrNestedTokens}
|
|
1273
|
+
*/
|
|
1274
|
+
null(_obj, _typ, _options, _refStack) {
|
|
1275
|
+
return simpleTokens.null;
|
|
1276
|
+
},
|
|
1277
|
+
/**
|
|
1278
|
+
* @param {any} _obj
|
|
1279
|
+
* @param {string} _typ
|
|
1280
|
+
* @param {EncodeOptions} _options
|
|
1281
|
+
* @param {Reference} [_refStack]
|
|
1282
|
+
* @returns {TokenOrNestedTokens}
|
|
1283
|
+
*/
|
|
1284
|
+
undefined(_obj, _typ, _options, _refStack) {
|
|
1285
|
+
return simpleTokens.undefined;
|
|
1286
|
+
},
|
|
1287
|
+
/**
|
|
1288
|
+
* @param {any} obj
|
|
1289
|
+
* @param {string} _typ
|
|
1290
|
+
* @param {EncodeOptions} _options
|
|
1291
|
+
* @param {Reference} [_refStack]
|
|
1292
|
+
* @returns {TokenOrNestedTokens}
|
|
1293
|
+
*/
|
|
1294
|
+
ArrayBuffer(obj, _typ, _options, _refStack) {
|
|
1295
|
+
return new Token(Type.bytes, new Uint8Array(obj));
|
|
1296
|
+
},
|
|
1297
|
+
/**
|
|
1298
|
+
* @param {any} obj
|
|
1299
|
+
* @param {string} _typ
|
|
1300
|
+
* @param {EncodeOptions} _options
|
|
1301
|
+
* @param {Reference} [_refStack]
|
|
1302
|
+
* @returns {TokenOrNestedTokens}
|
|
1303
|
+
*/
|
|
1304
|
+
DataView(obj, _typ, _options, _refStack) {
|
|
1305
|
+
return new Token(Type.bytes, new Uint8Array(obj.buffer, obj.byteOffset, obj.byteLength));
|
|
1306
|
+
},
|
|
1307
|
+
/**
|
|
1308
|
+
* @param {any} obj
|
|
1309
|
+
* @param {string} _typ
|
|
1310
|
+
* @param {EncodeOptions} options
|
|
1311
|
+
* @param {Reference} [refStack]
|
|
1312
|
+
* @returns {TokenOrNestedTokens}
|
|
1313
|
+
*/
|
|
1314
|
+
Array(obj, _typ, options, refStack) {
|
|
1315
|
+
if (!obj.length) {
|
|
1316
|
+
if (options.addBreakTokens === true) {
|
|
1317
|
+
return [simpleTokens.emptyArray, new Token(Type.break)];
|
|
1318
|
+
}
|
|
1319
|
+
return simpleTokens.emptyArray;
|
|
1320
|
+
}
|
|
1321
|
+
refStack = Ref.createCheck(refStack, obj);
|
|
1322
|
+
const entries = [];
|
|
1323
|
+
let i = 0;
|
|
1324
|
+
for (const e of obj) {
|
|
1325
|
+
entries[i++] = objectToTokens(e, options, refStack);
|
|
1326
|
+
}
|
|
1327
|
+
if (options.addBreakTokens) {
|
|
1328
|
+
return [new Token(Type.array, obj.length), entries, new Token(Type.break)];
|
|
1329
|
+
}
|
|
1330
|
+
return [new Token(Type.array, obj.length), entries];
|
|
1331
|
+
},
|
|
1332
|
+
/**
|
|
1333
|
+
* @param {any} obj
|
|
1334
|
+
* @param {string} typ
|
|
1335
|
+
* @param {EncodeOptions} options
|
|
1336
|
+
* @param {Reference} [refStack]
|
|
1337
|
+
* @returns {TokenOrNestedTokens}
|
|
1338
|
+
*/
|
|
1339
|
+
Object(obj, typ, options, refStack) {
|
|
1340
|
+
const isMap = typ !== "Object";
|
|
1341
|
+
const keys = isMap ? obj.keys() : Object.keys(obj);
|
|
1342
|
+
const length = isMap ? obj.size : keys.length;
|
|
1343
|
+
if (!length) {
|
|
1344
|
+
if (options.addBreakTokens === true) {
|
|
1345
|
+
return [simpleTokens.emptyMap, new Token(Type.break)];
|
|
1346
|
+
}
|
|
1347
|
+
return simpleTokens.emptyMap;
|
|
1348
|
+
}
|
|
1349
|
+
refStack = Ref.createCheck(refStack, obj);
|
|
1350
|
+
const entries = [];
|
|
1351
|
+
let i = 0;
|
|
1352
|
+
for (const key of keys) {
|
|
1353
|
+
entries[i++] = [
|
|
1354
|
+
objectToTokens(key, options, refStack),
|
|
1355
|
+
objectToTokens(isMap ? obj.get(key) : obj[key], options, refStack)
|
|
1356
|
+
];
|
|
1357
|
+
}
|
|
1358
|
+
sortMapEntries(entries, options);
|
|
1359
|
+
if (options.addBreakTokens) {
|
|
1360
|
+
return [new Token(Type.map, length), entries, new Token(Type.break)];
|
|
1361
|
+
}
|
|
1362
|
+
return [new Token(Type.map, length), entries];
|
|
1363
|
+
}
|
|
1364
|
+
};
|
|
1365
|
+
typeEncoders.Map = typeEncoders.Object;
|
|
1366
|
+
typeEncoders.Buffer = typeEncoders.Uint8Array;
|
|
1367
|
+
for (const typ of "Uint8Clamped Uint16 Uint32 Int8 Int16 Int32 BigUint64 BigInt64 Float32 Float64".split(" ")) {
|
|
1368
|
+
typeEncoders[`${typ}Array`] = typeEncoders.DataView;
|
|
1369
|
+
}
|
|
1370
|
+
function objectToTokens(obj, options = {}, refStack) {
|
|
1371
|
+
const typ = is(obj);
|
|
1372
|
+
const customTypeEncoder = options && options.typeEncoders && /** @type {OptionalTypeEncoder} */
|
|
1373
|
+
options.typeEncoders[typ] || typeEncoders[typ];
|
|
1374
|
+
if (typeof customTypeEncoder === "function") {
|
|
1375
|
+
const tokens = customTypeEncoder(obj, typ, options, refStack);
|
|
1376
|
+
if (tokens != null) {
|
|
1377
|
+
return tokens;
|
|
1378
|
+
}
|
|
1379
|
+
}
|
|
1380
|
+
const typeEncoder = typeEncoders[typ];
|
|
1381
|
+
if (!typeEncoder) {
|
|
1382
|
+
throw new Error(`${encodeErrPrefix} unsupported type: ${typ}`);
|
|
1383
|
+
}
|
|
1384
|
+
return typeEncoder(obj, typ, options, refStack);
|
|
1385
|
+
}
|
|
1386
|
+
function sortMapEntries(entries, options) {
|
|
1387
|
+
if (options.mapSorter) {
|
|
1388
|
+
entries.sort(options.mapSorter);
|
|
1389
|
+
}
|
|
1390
|
+
}
|
|
1391
|
+
function mapSorter(e1, e2) {
|
|
1392
|
+
const keyToken1 = Array.isArray(e1[0]) ? e1[0][0] : e1[0];
|
|
1393
|
+
const keyToken2 = Array.isArray(e2[0]) ? e2[0][0] : e2[0];
|
|
1394
|
+
if (keyToken1.type !== keyToken2.type) {
|
|
1395
|
+
return keyToken1.type.compare(keyToken2.type);
|
|
1396
|
+
}
|
|
1397
|
+
const major = keyToken1.type.major;
|
|
1398
|
+
const tcmp = cborEncoders[major].compareTokens(keyToken1, keyToken2);
|
|
1399
|
+
if (tcmp === 0) {
|
|
1400
|
+
console.warn("WARNING: complex key types used, CBOR key sorting guarantees are gone");
|
|
1401
|
+
}
|
|
1402
|
+
return tcmp;
|
|
1403
|
+
}
|
|
1404
|
+
function tokensToEncoded(buf2, tokens, encoders, options) {
|
|
1405
|
+
if (Array.isArray(tokens)) {
|
|
1406
|
+
for (const token of tokens) {
|
|
1407
|
+
tokensToEncoded(buf2, token, encoders, options);
|
|
1408
|
+
}
|
|
1409
|
+
} else {
|
|
1410
|
+
encoders[tokens.type.major](buf2, tokens, options);
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
function encodeCustom(data, encoders, options) {
|
|
1414
|
+
const tokens = objectToTokens(data, options);
|
|
1415
|
+
if (!Array.isArray(tokens) && options.quickEncodeToken) {
|
|
1416
|
+
const quickBytes = options.quickEncodeToken(tokens);
|
|
1417
|
+
if (quickBytes) {
|
|
1418
|
+
return quickBytes;
|
|
1419
|
+
}
|
|
1420
|
+
const encoder = encoders[tokens.type.major];
|
|
1421
|
+
if (encoder.encodedSize) {
|
|
1422
|
+
const size = encoder.encodedSize(tokens, options);
|
|
1423
|
+
const buf2 = new Bl(size);
|
|
1424
|
+
encoder(buf2, tokens, options);
|
|
1425
|
+
if (buf2.chunks.length !== 1) {
|
|
1426
|
+
throw new Error(`Unexpected error: pre-calculated length for ${tokens} was wrong`);
|
|
1427
|
+
}
|
|
1428
|
+
return asU8A(buf2.chunks[0]);
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
buf.reset();
|
|
1432
|
+
tokensToEncoded(buf, tokens, encoders, options);
|
|
1433
|
+
return buf.toBytes(true);
|
|
1434
|
+
}
|
|
1435
|
+
function encode$1(data, options) {
|
|
1436
|
+
options = Object.assign({}, defaultEncodeOptions, options);
|
|
1437
|
+
return encodeCustom(data, cborEncoders, options);
|
|
1438
|
+
}
|
|
1439
|
+
const defaultDecodeOptions = {
|
|
1440
|
+
strict: false,
|
|
1441
|
+
allowIndefinite: true,
|
|
1442
|
+
allowUndefined: true,
|
|
1443
|
+
allowBigInt: true
|
|
1444
|
+
};
|
|
1445
|
+
class Tokeniser {
|
|
1446
|
+
/**
|
|
1447
|
+
* @param {Uint8Array} data
|
|
1448
|
+
* @param {DecodeOptions} options
|
|
1449
|
+
*/
|
|
1450
|
+
constructor(data, options = {}) {
|
|
1451
|
+
this._pos = 0;
|
|
1452
|
+
this.data = data;
|
|
1453
|
+
this.options = options;
|
|
1454
|
+
}
|
|
1455
|
+
pos() {
|
|
1456
|
+
return this._pos;
|
|
1457
|
+
}
|
|
1458
|
+
done() {
|
|
1459
|
+
return this._pos >= this.data.length;
|
|
1460
|
+
}
|
|
1461
|
+
next() {
|
|
1462
|
+
const byt = this.data[this._pos];
|
|
1463
|
+
let token = quick[byt];
|
|
1464
|
+
if (token === void 0) {
|
|
1465
|
+
const decoder = jump[byt];
|
|
1466
|
+
if (!decoder) {
|
|
1467
|
+
throw new Error(`${decodeErrPrefix} no decoder for major type ${byt >>> 5} (byte 0x${byt.toString(16).padStart(2, "0")})`);
|
|
1468
|
+
}
|
|
1469
|
+
const minor = byt & 31;
|
|
1470
|
+
token = decoder(this.data, this._pos, minor, this.options);
|
|
1471
|
+
}
|
|
1472
|
+
this._pos += token.encodedLength;
|
|
1473
|
+
return token;
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
const DONE = Symbol.for("DONE");
|
|
1477
|
+
const BREAK = Symbol.for("BREAK");
|
|
1478
|
+
function tokenToArray(token, tokeniser, options) {
|
|
1479
|
+
const arr = [];
|
|
1480
|
+
for (let i = 0; i < token.value; i++) {
|
|
1481
|
+
const value = tokensToObject(tokeniser, options);
|
|
1482
|
+
if (value === BREAK) {
|
|
1483
|
+
if (token.value === Infinity) {
|
|
1484
|
+
break;
|
|
1485
|
+
}
|
|
1486
|
+
throw new Error(`${decodeErrPrefix} got unexpected break to lengthed array`);
|
|
1487
|
+
}
|
|
1488
|
+
if (value === DONE) {
|
|
1489
|
+
throw new Error(`${decodeErrPrefix} found array but not enough entries (got ${i}, expected ${token.value})`);
|
|
1490
|
+
}
|
|
1491
|
+
arr[i] = value;
|
|
1492
|
+
}
|
|
1493
|
+
return arr;
|
|
1494
|
+
}
|
|
1495
|
+
function tokenToMap(token, tokeniser, options) {
|
|
1496
|
+
const useMaps = options.useMaps === true;
|
|
1497
|
+
const obj = useMaps ? void 0 : {};
|
|
1498
|
+
const m = useMaps ? /* @__PURE__ */ new Map() : void 0;
|
|
1499
|
+
for (let i = 0; i < token.value; i++) {
|
|
1500
|
+
const key = tokensToObject(tokeniser, options);
|
|
1501
|
+
if (key === BREAK) {
|
|
1502
|
+
if (token.value === Infinity) {
|
|
1503
|
+
break;
|
|
1504
|
+
}
|
|
1505
|
+
throw new Error(`${decodeErrPrefix} got unexpected break to lengthed map`);
|
|
1506
|
+
}
|
|
1507
|
+
if (key === DONE) {
|
|
1508
|
+
throw new Error(`${decodeErrPrefix} found map but not enough entries (got ${i} [no key], expected ${token.value})`);
|
|
1509
|
+
}
|
|
1510
|
+
if (useMaps !== true && typeof key !== "string") {
|
|
1511
|
+
throw new Error(`${decodeErrPrefix} non-string keys not supported (got ${typeof key})`);
|
|
1512
|
+
}
|
|
1513
|
+
if (options.rejectDuplicateMapKeys === true) {
|
|
1514
|
+
if (useMaps && m.has(key) || !useMaps && key in obj) {
|
|
1515
|
+
throw new Error(`${decodeErrPrefix} found repeat map key "${key}"`);
|
|
1516
|
+
}
|
|
1517
|
+
}
|
|
1518
|
+
const value = tokensToObject(tokeniser, options);
|
|
1519
|
+
if (value === DONE) {
|
|
1520
|
+
throw new Error(`${decodeErrPrefix} found map but not enough entries (got ${i} [no value], expected ${token.value})`);
|
|
1521
|
+
}
|
|
1522
|
+
if (useMaps) {
|
|
1523
|
+
m.set(key, value);
|
|
1524
|
+
} else {
|
|
1525
|
+
obj[key] = value;
|
|
1526
|
+
}
|
|
1527
|
+
}
|
|
1528
|
+
return useMaps ? m : obj;
|
|
1529
|
+
}
|
|
1530
|
+
function tokensToObject(tokeniser, options) {
|
|
1531
|
+
if (tokeniser.done()) {
|
|
1532
|
+
return DONE;
|
|
1533
|
+
}
|
|
1534
|
+
const token = tokeniser.next();
|
|
1535
|
+
if (token.type === Type.break) {
|
|
1536
|
+
return BREAK;
|
|
1537
|
+
}
|
|
1538
|
+
if (token.type.terminal) {
|
|
1539
|
+
return token.value;
|
|
1540
|
+
}
|
|
1541
|
+
if (token.type === Type.array) {
|
|
1542
|
+
return tokenToArray(token, tokeniser, options);
|
|
1543
|
+
}
|
|
1544
|
+
if (token.type === Type.map) {
|
|
1545
|
+
return tokenToMap(token, tokeniser, options);
|
|
1546
|
+
}
|
|
1547
|
+
if (token.type === Type.tag) {
|
|
1548
|
+
if (options.tags && typeof options.tags[token.value] === "function") {
|
|
1549
|
+
const tagged = tokensToObject(tokeniser, options);
|
|
1550
|
+
return options.tags[token.value](tagged);
|
|
1551
|
+
}
|
|
1552
|
+
throw new Error(`${decodeErrPrefix} tag not supported (${token.value})`);
|
|
1553
|
+
}
|
|
1554
|
+
throw new Error("unsupported");
|
|
1555
|
+
}
|
|
1556
|
+
function decodeFirst(data, options) {
|
|
1557
|
+
if (!(data instanceof Uint8Array)) {
|
|
1558
|
+
throw new Error(`${decodeErrPrefix} data to decode must be a Uint8Array`);
|
|
1559
|
+
}
|
|
1560
|
+
options = Object.assign({}, defaultDecodeOptions, options);
|
|
1561
|
+
const tokeniser = options.tokenizer || new Tokeniser(data, options);
|
|
1562
|
+
const decoded = tokensToObject(tokeniser, options);
|
|
1563
|
+
if (decoded === DONE) {
|
|
1564
|
+
throw new Error(`${decodeErrPrefix} did not find any content to decode`);
|
|
1565
|
+
}
|
|
1566
|
+
if (decoded === BREAK) {
|
|
1567
|
+
throw new Error(`${decodeErrPrefix} got unexpected break`);
|
|
1568
|
+
}
|
|
1569
|
+
return [decoded, data.subarray(tokeniser.pos())];
|
|
1570
|
+
}
|
|
1571
|
+
function decode$1(data, options) {
|
|
1572
|
+
const [decoded, remainder] = decodeFirst(data, options);
|
|
1573
|
+
if (remainder.length > 0) {
|
|
1574
|
+
throw new Error(`${decodeErrPrefix} too many terminals, data makes no sense`);
|
|
1575
|
+
}
|
|
1576
|
+
return decoded;
|
|
1577
|
+
}
|
|
1578
|
+
const CID_CBOR_TAG = 42;
|
|
1579
|
+
function cidEncoder(obj) {
|
|
1580
|
+
const cid = lexData.CID.asCID(obj);
|
|
1581
|
+
if (!cid) return null;
|
|
1582
|
+
const bytes = new Uint8Array(cid.bytes.byteLength + 1);
|
|
1583
|
+
bytes.set(cid.bytes, 1);
|
|
1584
|
+
return [new Token(Type.tag, CID_CBOR_TAG), new Token(Type.bytes, bytes)];
|
|
1585
|
+
}
|
|
1586
|
+
function undefinedEncoder() {
|
|
1587
|
+
throw new Error("`undefined` is not allowed by the AT Data Model");
|
|
1588
|
+
}
|
|
1589
|
+
function numberEncoder(num) {
|
|
1590
|
+
if (Number.isInteger(num)) return null;
|
|
1591
|
+
throw new Error("Non-integer numbers are not allowed by the AT Data Model");
|
|
1592
|
+
}
|
|
1593
|
+
function mapEncoder(map) {
|
|
1594
|
+
for (const key of map.keys()) {
|
|
1595
|
+
if (typeof key !== "string") {
|
|
1596
|
+
throw new Error(
|
|
1597
|
+
'Only string keys are allowed in CBOR "map" by the AT Data Model'
|
|
1598
|
+
);
|
|
1599
|
+
}
|
|
1600
|
+
}
|
|
1601
|
+
return null;
|
|
1602
|
+
}
|
|
1603
|
+
const encodeOptions = {
|
|
1604
|
+
typeEncoders: {
|
|
1605
|
+
Map: mapEncoder,
|
|
1606
|
+
Object: cidEncoder,
|
|
1607
|
+
undefined: undefinedEncoder,
|
|
1608
|
+
number: numberEncoder
|
|
1609
|
+
}
|
|
1610
|
+
};
|
|
1611
|
+
function cidDecoder(bytes) {
|
|
1612
|
+
if (bytes[0] !== 0) {
|
|
1613
|
+
throw new Error("Invalid CID for CBOR tag 42; expected leading 0x00");
|
|
1614
|
+
}
|
|
1615
|
+
return lexData.CID.decode(bytes.subarray(1));
|
|
1616
|
+
}
|
|
1617
|
+
const tagDecoders = [];
|
|
1618
|
+
tagDecoders[CID_CBOR_TAG] = cidDecoder;
|
|
1619
|
+
const decodeOptions = {
|
|
1620
|
+
allowIndefinite: false,
|
|
1621
|
+
coerceUndefinedToNull: true,
|
|
1622
|
+
allowNaN: false,
|
|
1623
|
+
allowInfinity: false,
|
|
1624
|
+
allowBigInt: true,
|
|
1625
|
+
strict: true,
|
|
1626
|
+
useMaps: false,
|
|
1627
|
+
rejectDuplicateMapKeys: true,
|
|
1628
|
+
tags: tagDecoders
|
|
1629
|
+
};
|
|
1630
|
+
function encode(data) {
|
|
1631
|
+
return encode$1(data, encodeOptions);
|
|
1632
|
+
}
|
|
1633
|
+
function decode(bytes) {
|
|
1634
|
+
return decode$1(bytes, decodeOptions);
|
|
1635
|
+
}
|
|
1636
|
+
function* decodeAll(data) {
|
|
1637
|
+
do {
|
|
1638
|
+
const [result, remainingBytes] = decodeFirst(data, decodeOptions);
|
|
1639
|
+
yield result;
|
|
1640
|
+
data = remainingBytes;
|
|
1641
|
+
} while (data.byteLength > 0);
|
|
1642
|
+
}
|
|
1643
|
+
async function cidForLex(value) {
|
|
1644
|
+
return cidForCbor(encode(value));
|
|
1645
|
+
}
|
|
1646
|
+
async function cidForCbor(bytes) {
|
|
1647
|
+
const digest2 = await sha2.sha256.digest(bytes);
|
|
1648
|
+
return lexData.CID.createV1(lexData.DAG_CBOR_MULTICODEC, digest2);
|
|
1649
|
+
}
|
|
1650
|
+
async function verifyCidForBytes(cid, bytes) {
|
|
1651
|
+
const digest2 = await sha2.sha256.digest(bytes);
|
|
1652
|
+
const expected = lexData.CID.createV1(cid.code, digest2);
|
|
1653
|
+
if (!cid.equals(expected)) {
|
|
1654
|
+
throw new Error(
|
|
1655
|
+
`Not a valid CID for bytes. Expected: ${expected.toString()} Got: ${cid.toString()}`
|
|
1656
|
+
);
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
async function cidForRawBytes(bytes) {
|
|
1660
|
+
const digest2 = await sha2.sha256.digest(bytes);
|
|
1661
|
+
return lexData.CID.createV1(lexData.RAW_BIN_MULTICODEC, digest2);
|
|
1662
|
+
}
|
|
1663
|
+
function cidForRawHash(hash) {
|
|
1664
|
+
const digest$1 = digest.create(sha2.sha256.code, hash);
|
|
1665
|
+
return lexData.CID.createV1(lexData.RAW_BIN_MULTICODEC, digest$1);
|
|
1666
|
+
}
|
|
1667
|
+
function parseCidFromBytes(cidBytes) {
|
|
1668
|
+
const version = cidBytes[0];
|
|
1669
|
+
if (version !== 1) {
|
|
1670
|
+
throw new Error(`Unsupported CID version: ${version}`);
|
|
1671
|
+
}
|
|
1672
|
+
const code = cidBytes[1];
|
|
1673
|
+
if (code !== lexData.RAW_BIN_MULTICODEC && code !== lexData.DAG_CBOR_MULTICODEC) {
|
|
1674
|
+
throw new Error(`Unsupported CID codec: ${code}`);
|
|
1675
|
+
}
|
|
1676
|
+
const hashType = cidBytes[2];
|
|
1677
|
+
if (hashType !== lexData.SHA2_256_MULTIHASH_CODE) {
|
|
1678
|
+
throw new Error(`Unsupported CID hash function: ${hashType}`);
|
|
1679
|
+
}
|
|
1680
|
+
const hashLength = cidBytes[3];
|
|
1681
|
+
if (hashLength !== 32) {
|
|
1682
|
+
throw new Error(`Unexpected CID hash length: ${hashLength}`);
|
|
1683
|
+
}
|
|
1684
|
+
if (hashLength !== cidBytes.length - 4) {
|
|
1685
|
+
throw new Error(`Unexpected CID bytes length: ${hashLength}`);
|
|
1686
|
+
}
|
|
1687
|
+
const hashBytes = cidBytes.slice(4);
|
|
1688
|
+
const digest$1 = digest.create(hashType, hashBytes);
|
|
1689
|
+
return lexData.CID.create(version, code, digest$1);
|
|
1690
|
+
}
|
|
1691
|
+
Object.defineProperty(exports, "hasher", {
|
|
1692
|
+
enumerable: true,
|
|
1693
|
+
get: () => sha2.sha256
|
|
1694
|
+
});
|
|
1695
|
+
Object.defineProperty(exports, "CID", {
|
|
1696
|
+
enumerable: true,
|
|
1697
|
+
get: () => lexData.CID
|
|
1698
|
+
});
|
|
1699
|
+
exports.cidForCbor = cidForCbor;
|
|
1700
|
+
exports.cidForLex = cidForLex;
|
|
1701
|
+
exports.cidForRawBytes = cidForRawBytes;
|
|
1702
|
+
exports.cidForRawHash = cidForRawHash;
|
|
1703
|
+
exports.decode = decode;
|
|
1704
|
+
exports.decodeAll = decodeAll;
|
|
1705
|
+
exports.encode = encode;
|
|
1706
|
+
exports.parseCidFromBytes = parseCidFromBytes;
|
|
1707
|
+
exports.verifyCidForBytes = verifyCidForBytes;
|