@marcuspuchalla/nachos 0.1.3 → 0.2.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/CHANGELOG.md +75 -0
- package/dist/{chunk-PTWN7K3Y.cjs → chunk-3Z45RBZP.cjs} +469 -244
- package/dist/chunk-3Z45RBZP.cjs.map +1 -0
- package/dist/{chunk-2MTLSQ7E.js → chunk-EDXZTSIA.js} +224 -166
- package/dist/chunk-EDXZTSIA.js.map +1 -0
- package/dist/{chunk-R62CQQNI.cjs → chunk-HMUA5KLG.cjs} +239 -181
- package/dist/chunk-HMUA5KLG.cjs.map +1 -0
- package/dist/{chunk-ZDZ2B5PE.js → chunk-JESIF5IF.js} +7 -3
- package/dist/chunk-JESIF5IF.js.map +1 -0
- package/dist/{chunk-5A5T56JB.js → chunk-LWNWC2O7.js} +442 -217
- package/dist/chunk-LWNWC2O7.js.map +1 -0
- package/dist/{chunk-PD72MVTX.cjs → chunk-P6A2OOIY.cjs} +7 -3
- package/dist/chunk-P6A2OOIY.cjs.map +1 -0
- package/dist/encoder/index.cjs +14 -14
- package/dist/encoder/index.d.cts +5 -4
- package/dist/encoder/index.d.ts +5 -4
- package/dist/encoder/index.js +2 -2
- package/dist/index.cjs +58 -39
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +40 -21
- package/dist/index.d.ts +40 -21
- package/dist/index.js +37 -17
- package/dist/index.js.map +1 -1
- package/dist/metafile-cjs.json +1 -1
- package/dist/metafile-esm.json +1 -1
- package/dist/parser/index.cjs +21 -21
- package/dist/parser/index.d.cts +4 -2
- package/dist/parser/index.d.ts +4 -2
- package/dist/parser/index.js +2 -2
- package/dist/{types-DvNlfbKB.d.cts → types-eG2qalpr.d.cts} +27 -1
- package/dist/{types-DvNlfbKB.d.ts → types-eG2qalpr.d.ts} +27 -1
- package/dist/{useCborSimpleEncoder-TVxzNJ_9.d.ts → useCborSimpleEncoder-CamvS-_N.d.ts} +7 -3
- package/dist/{useCborSimpleEncoder-ButVU988.d.cts → useCborSimpleEncoder-DXgPx62d.d.cts} +7 -3
- package/dist/{useCborTag-xV2Pz2VY.d.ts → useCborTag-D4d7xG3-.d.cts} +9 -4
- package/dist/{useCborTag-Cs1CZuXZ.d.cts → useCborTag-TYst1KR6.d.ts} +9 -4
- package/package.json +1 -1
- package/src/__tests__/audit-fixes.test.ts +141 -0
- package/src/__tests__/public-api.test.ts +153 -0
- package/src/__tests__/roundtrip.test.ts +5 -6
- package/src/encoder/__tests__/cbor-collection-encoder.test.ts +103 -5
- package/src/encoder/__tests__/cbor-encoder-errors.test.ts +40 -5
- package/src/encoder/__tests__/cbor-simple-encoder.test.ts +126 -0
- package/src/encoder/composables/useCborCollectionEncoder.ts +30 -26
- package/src/encoder/composables/useCborEncoder.ts +40 -0
- package/src/encoder/composables/useCborSimpleEncoder.ts +40 -9
- package/src/encoder/types.ts +9 -4
- package/src/encoder/utils.ts +33 -1
- package/src/index.ts +39 -20
- package/src/parser/__tests__/buffer-native-parsing.test.ts +338 -0
- package/src/parser/__tests__/cbor-map-duplicate-keys.test.ts +97 -7
- package/src/parser/__tests__/cbor-security-dos-protection.test.ts +164 -31
- package/src/parser/__tests__/cbor-standard-tags.test.ts +75 -7
- package/src/parser/__tests__/cbor-tag-reparse-fix.test.ts +268 -0
- package/src/parser/__tests__/utils-errors.test.ts +11 -3
- package/src/parser/composables/useCborCollection.ts +51 -45
- package/src/parser/composables/useCborDiagnostic.ts +28 -0
- package/src/parser/composables/useCborFloat.ts +2 -1
- package/src/parser/composables/useCborInteger.ts +24 -10
- package/src/parser/composables/useCborParser.ts +448 -208
- package/src/parser/composables/useCborTag.ts +53 -38
- package/src/parser/types.ts +32 -1
- package/src/parser/utils.ts +52 -0
- package/dist/chunk-2MTLSQ7E.js.map +0 -1
- package/dist/chunk-5A5T56JB.js.map +0 -1
- package/dist/chunk-PD72MVTX.cjs.map +0 -1
- package/dist/chunk-PTWN7K3Y.cjs.map +0 -1
- package/dist/chunk-R62CQQNI.cjs.map +0 -1
- package/dist/chunk-ZDZ2B5PE.js.map +0 -1
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
import { useCborByteString, useCborTextString, INDEFINITE_SYMBOL, ALL_ENTRIES_SYMBOL } from './chunk-
|
|
1
|
+
import { useCborByteString, useCborTextString, INDEFINITE_SYMBOL, ALL_ENTRIES_SYMBOL } from './chunk-JESIF5IF.js';
|
|
2
2
|
|
|
3
3
|
// src/encoder/types.ts
|
|
4
4
|
var DEFAULT_ENCODE_OPTIONS = {
|
|
5
5
|
canonical: false,
|
|
6
6
|
allowIndefinite: true,
|
|
7
7
|
rejectDuplicateKeys: false,
|
|
8
|
+
mapKeyOrder: "length-first",
|
|
8
9
|
maxDepth: 64,
|
|
9
10
|
maxOutputSize: 100 * 1024 * 1024
|
|
10
11
|
// 100 MB
|
|
@@ -40,6 +41,20 @@ function compareBytes(a, b) {
|
|
|
40
41
|
}
|
|
41
42
|
return 0;
|
|
42
43
|
}
|
|
44
|
+
function compareBytesLexicographic(a, b) {
|
|
45
|
+
const min = Math.min(a.length, b.length);
|
|
46
|
+
for (let i = 0; i < min; i++) {
|
|
47
|
+
const byteA = a[i];
|
|
48
|
+
const byteB = b[i];
|
|
49
|
+
if (byteA !== byteB) {
|
|
50
|
+
return byteA - byteB;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return a.length - b.length;
|
|
54
|
+
}
|
|
55
|
+
function compareMapKeys(a, b, order = "length-first") {
|
|
56
|
+
return order === "bytewise" ? compareBytesLexicographic(a, b) : compareBytes(a, b);
|
|
57
|
+
}
|
|
43
58
|
function writeUint(value, bytes) {
|
|
44
59
|
const result = new Uint8Array(bytes);
|
|
45
60
|
for (let i = bytes - 1; i >= 0; i--) {
|
|
@@ -259,11 +274,172 @@ function useCborStringEncoder(globalOptions) {
|
|
|
259
274
|
};
|
|
260
275
|
}
|
|
261
276
|
|
|
277
|
+
// src/encoder/composables/useCborSimpleEncoder.ts
|
|
278
|
+
function useCborSimpleEncoder(_globalOptions) {
|
|
279
|
+
const { encodeInteger } = useCborIntegerEncoder();
|
|
280
|
+
const encodeSimple = (value) => {
|
|
281
|
+
let byte;
|
|
282
|
+
if (value === false) {
|
|
283
|
+
byte = 244;
|
|
284
|
+
} else if (value === true) {
|
|
285
|
+
byte = 245;
|
|
286
|
+
} else if (value === null) {
|
|
287
|
+
byte = 246;
|
|
288
|
+
} else if (value === void 0) {
|
|
289
|
+
byte = 247;
|
|
290
|
+
} else {
|
|
291
|
+
throw new Error(`Unsupported simple value: ${value}`);
|
|
292
|
+
}
|
|
293
|
+
return {
|
|
294
|
+
bytes: new Uint8Array([byte]),
|
|
295
|
+
hex: bytesToHex(new Uint8Array([byte]))
|
|
296
|
+
};
|
|
297
|
+
};
|
|
298
|
+
const encodeFloat16Bytes = (value) => {
|
|
299
|
+
if (Object.is(value, -0)) return new Uint8Array([128, 0]);
|
|
300
|
+
if (value === 0) return new Uint8Array([0, 0]);
|
|
301
|
+
if (Number.isNaN(value)) return new Uint8Array([126, 0]);
|
|
302
|
+
if (value === Infinity) return new Uint8Array([124, 0]);
|
|
303
|
+
if (value === -Infinity) return new Uint8Array([252, 0]);
|
|
304
|
+
const sign = value < 0 ? 1 : 0;
|
|
305
|
+
const absValue = Math.abs(value);
|
|
306
|
+
const buffer = new ArrayBuffer(8);
|
|
307
|
+
const view = new DataView(buffer);
|
|
308
|
+
view.setFloat64(0, absValue, false);
|
|
309
|
+
const bits = view.getBigUint64(0, false);
|
|
310
|
+
const exp64 = Number(bits >> 52n & 0x7ffn) - 1023;
|
|
311
|
+
const mant64 = Number(bits & 0xfffffffffffffn);
|
|
312
|
+
const mant64n = BigInt(mant64);
|
|
313
|
+
let exp16;
|
|
314
|
+
let mant16;
|
|
315
|
+
if (exp64 < -24) {
|
|
316
|
+
exp16 = 0;
|
|
317
|
+
mant16 = 0;
|
|
318
|
+
} else if (exp64 < -14) {
|
|
319
|
+
exp16 = 0;
|
|
320
|
+
const shift = -14 - exp64;
|
|
321
|
+
const fullMant = 1n << 10n | mant64n >> 42n;
|
|
322
|
+
const lostFromExtract = mant64n & (1n << 42n) - 1n;
|
|
323
|
+
const shiftN = BigInt(shift);
|
|
324
|
+
const guardBit = Number(fullMant >> shiftN - 1n & 1n);
|
|
325
|
+
const stickyBitsBelow = shiftN > 1n ? fullMant & (1n << shiftN - 1n) - 1n : 0n;
|
|
326
|
+
const sticky = stickyBitsBelow !== 0n || lostFromExtract !== 0n ? 1 : 0;
|
|
327
|
+
const truncated = Number(fullMant >> shiftN);
|
|
328
|
+
const lsb = truncated & 1;
|
|
329
|
+
mant16 = truncated + (guardBit & (sticky | lsb));
|
|
330
|
+
} else if (exp64 > 15) {
|
|
331
|
+
exp16 = 31;
|
|
332
|
+
mant16 = 0;
|
|
333
|
+
} else {
|
|
334
|
+
exp16 = exp64 + 15;
|
|
335
|
+
const truncated = Number(mant64n >> 42n);
|
|
336
|
+
const guardBit = Number(mant64n >> 41n & 1n);
|
|
337
|
+
const stickyBits = (mant64n & (1n << 41n) - 1n) !== 0n ? 1 : 0;
|
|
338
|
+
const lsb = truncated & 1;
|
|
339
|
+
mant16 = truncated + (guardBit & (stickyBits | lsb));
|
|
340
|
+
if (mant16 > 1023) {
|
|
341
|
+
mant16 = 0;
|
|
342
|
+
exp16 += 1;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
const float16 = sign << 15 | exp16 << 10 | mant16;
|
|
346
|
+
return new Uint8Array([
|
|
347
|
+
float16 >> 8 & 255,
|
|
348
|
+
float16 & 255
|
|
349
|
+
]);
|
|
350
|
+
};
|
|
351
|
+
const encodeFloat32Bytes = (value) => {
|
|
352
|
+
const buffer = new ArrayBuffer(4);
|
|
353
|
+
const view = new DataView(buffer);
|
|
354
|
+
view.setFloat32(0, value, false);
|
|
355
|
+
return new Uint8Array(buffer);
|
|
356
|
+
};
|
|
357
|
+
const encodeFloat64Bytes = (value) => {
|
|
358
|
+
const buffer = new ArrayBuffer(8);
|
|
359
|
+
const view = new DataView(buffer);
|
|
360
|
+
view.setFloat64(0, value, false);
|
|
361
|
+
return new Uint8Array(buffer);
|
|
362
|
+
};
|
|
363
|
+
const canBeFloat16 = (value) => {
|
|
364
|
+
if (!Number.isFinite(value) || Object.is(value, 0) || Object.is(value, -0)) {
|
|
365
|
+
return true;
|
|
366
|
+
}
|
|
367
|
+
const absValue = Math.abs(value);
|
|
368
|
+
if (absValue < 5960464477539063e-23 || absValue > 65504) {
|
|
369
|
+
return false;
|
|
370
|
+
}
|
|
371
|
+
const bytes = encodeFloat16Bytes(value);
|
|
372
|
+
const view = new DataView(bytes.buffer);
|
|
373
|
+
const bits = view.getUint16(0, false);
|
|
374
|
+
const sign = bits >> 15 & 1;
|
|
375
|
+
const exp = bits >> 10 & 31;
|
|
376
|
+
const mant = bits & 1023;
|
|
377
|
+
let decoded;
|
|
378
|
+
if (exp === 0) {
|
|
379
|
+
decoded = (sign ? -1 : 1) * Math.pow(2, -14) * (mant / 1024);
|
|
380
|
+
} else if (exp === 31) {
|
|
381
|
+
decoded = mant === 0 ? sign ? -Infinity : Infinity : NaN;
|
|
382
|
+
} else {
|
|
383
|
+
decoded = (sign ? -1 : 1) * Math.pow(2, exp - 15) * (1 + mant / 1024);
|
|
384
|
+
}
|
|
385
|
+
return decoded === value;
|
|
386
|
+
};
|
|
387
|
+
const canBeFloat32 = (value) => {
|
|
388
|
+
if (!Number.isFinite(value) || Object.is(value, 0) || Object.is(value, -0)) {
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
const buffer = new ArrayBuffer(4);
|
|
392
|
+
const view = new DataView(buffer);
|
|
393
|
+
view.setFloat32(0, value, false);
|
|
394
|
+
const decoded = view.getFloat32(0, false);
|
|
395
|
+
return decoded === value;
|
|
396
|
+
};
|
|
397
|
+
const isInteger = (value) => {
|
|
398
|
+
return Number.isInteger(value) && Number.isSafeInteger(value);
|
|
399
|
+
};
|
|
400
|
+
const encodeFloat = (value, precision) => {
|
|
401
|
+
let bytes;
|
|
402
|
+
if (isInteger(value) && !precision) {
|
|
403
|
+
return encodeInteger(value);
|
|
404
|
+
}
|
|
405
|
+
if (precision === 16) {
|
|
406
|
+
const floatBytes = encodeFloat16Bytes(value);
|
|
407
|
+
bytes = new Uint8Array([249, ...floatBytes]);
|
|
408
|
+
} else if (precision === 32) {
|
|
409
|
+
const floatBytes = encodeFloat32Bytes(value);
|
|
410
|
+
bytes = new Uint8Array([250, ...floatBytes]);
|
|
411
|
+
} else if (precision === 64) {
|
|
412
|
+
const floatBytes = encodeFloat64Bytes(value);
|
|
413
|
+
bytes = new Uint8Array([251, ...floatBytes]);
|
|
414
|
+
} else {
|
|
415
|
+
if (canBeFloat16(value)) {
|
|
416
|
+
const floatBytes = encodeFloat16Bytes(value);
|
|
417
|
+
bytes = new Uint8Array([249, ...floatBytes]);
|
|
418
|
+
} else if (canBeFloat32(value)) {
|
|
419
|
+
const floatBytes = encodeFloat32Bytes(value);
|
|
420
|
+
bytes = new Uint8Array([250, ...floatBytes]);
|
|
421
|
+
} else {
|
|
422
|
+
const floatBytes = encodeFloat64Bytes(value);
|
|
423
|
+
bytes = new Uint8Array([251, ...floatBytes]);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
return {
|
|
427
|
+
bytes,
|
|
428
|
+
hex: bytesToHex(bytes)
|
|
429
|
+
};
|
|
430
|
+
};
|
|
431
|
+
return {
|
|
432
|
+
encodeSimple,
|
|
433
|
+
encodeFloat
|
|
434
|
+
};
|
|
435
|
+
}
|
|
436
|
+
|
|
262
437
|
// src/encoder/composables/useCborCollectionEncoder.ts
|
|
263
438
|
function useCborCollectionEncoder(globalOptions) {
|
|
264
439
|
const options = { ...DEFAULT_ENCODE_OPTIONS, ...globalOptions };
|
|
265
440
|
const { encodeInteger } = useCborIntegerEncoder();
|
|
266
441
|
const { encodeTextString, encodeByteString } = useCborStringEncoder(globalOptions);
|
|
442
|
+
const { encodeFloat } = useCborSimpleEncoder();
|
|
267
443
|
const { isCborByteString } = useCborByteString();
|
|
268
444
|
const { isCborTextString } = useCborTextString();
|
|
269
445
|
let mainEncode = null;
|
|
@@ -278,7 +454,15 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
278
454
|
return new Uint8Array([246]);
|
|
279
455
|
} else if (typeof value === "boolean") {
|
|
280
456
|
return new Uint8Array([value ? 245 : 244]);
|
|
281
|
-
} else if (typeof value === "number"
|
|
457
|
+
} else if (typeof value === "number") {
|
|
458
|
+
if (Object.is(value, -0)) {
|
|
459
|
+
return encodeFloat(value, 16).bytes;
|
|
460
|
+
}
|
|
461
|
+
if (Number.isInteger(value) && Number.isSafeInteger(value)) {
|
|
462
|
+
return encodeInteger(value).bytes;
|
|
463
|
+
}
|
|
464
|
+
return encodeFloat(value).bytes;
|
|
465
|
+
} else if (typeof value === "bigint") {
|
|
282
466
|
return encodeInteger(value).bytes;
|
|
283
467
|
} else if (typeof value === "string" || isCborTextString(value)) {
|
|
284
468
|
return encodeTextString(value).bytes;
|
|
@@ -358,10 +542,6 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
358
542
|
parts.push(encoded);
|
|
359
543
|
}
|
|
360
544
|
const result = concatenateUint8Arrays(parts);
|
|
361
|
-
ctx.bytesWritten += result.length;
|
|
362
|
-
if (ctx.bytesWritten > ctx.options.maxOutputSize) {
|
|
363
|
-
throw new Error("Encoded output exceeds maximum size");
|
|
364
|
-
}
|
|
365
545
|
return {
|
|
366
546
|
bytes: result,
|
|
367
547
|
hex: bytesToHex(result)
|
|
@@ -380,7 +560,6 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
380
560
|
}
|
|
381
561
|
const ctx = {
|
|
382
562
|
depth: 0,
|
|
383
|
-
bytesWritten: 0,
|
|
384
563
|
options
|
|
385
564
|
};
|
|
386
565
|
return encodeArrayInternal(array, ctx);
|
|
@@ -395,7 +574,6 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
395
574
|
const parts = [new Uint8Array([159])];
|
|
396
575
|
const ctx = {
|
|
397
576
|
depth: 0,
|
|
398
|
-
bytesWritten: 0,
|
|
399
577
|
options
|
|
400
578
|
};
|
|
401
579
|
for (const item of array) {
|
|
@@ -416,17 +594,22 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
416
594
|
} else {
|
|
417
595
|
entries = map instanceof Map ? Array.from(map.entries()) : Object.entries(map);
|
|
418
596
|
}
|
|
597
|
+
let preEncodedKeys = null;
|
|
419
598
|
if (ctx.options.canonical && !map[ALL_ENTRIES_SYMBOL]) {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
});
|
|
599
|
+
const childCtx = { ...ctx, depth: ctx.depth + 1 };
|
|
600
|
+
const withEncodedKeys = entries.map((entry) => ({
|
|
601
|
+
encodedKey: encodeValue(entry[0], childCtx),
|
|
602
|
+
entry
|
|
603
|
+
}));
|
|
604
|
+
const keyOrder = ctx.options.mapKeyOrder ?? "length-first";
|
|
605
|
+
withEncodedKeys.sort((a, b) => compareMapKeys(a.encodedKey, b.encodedKey, keyOrder));
|
|
606
|
+
entries = withEncodedKeys.map((t) => t.entry);
|
|
607
|
+
preEncodedKeys = withEncodedKeys.map((t) => t.encodedKey);
|
|
425
608
|
}
|
|
426
609
|
if (ctx.options.rejectDuplicateKeys) {
|
|
427
610
|
const seen = /* @__PURE__ */ new Set();
|
|
428
|
-
|
|
429
|
-
|
|
611
|
+
const keysForDupCheck = preEncodedKeys ?? entries.map((e) => encodeValue(e[0], { ...ctx, depth: ctx.depth + 1 }));
|
|
612
|
+
for (const keyBytes of keysForDupCheck) {
|
|
430
613
|
const keyHex = bytesToHex(keyBytes);
|
|
431
614
|
if (seen.has(keyHex)) {
|
|
432
615
|
throw new Error("Duplicate map key detected");
|
|
@@ -443,10 +626,6 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
443
626
|
parts.push(encodedValue);
|
|
444
627
|
}
|
|
445
628
|
const result = concatenateUint8Arrays(parts);
|
|
446
|
-
ctx.bytesWritten += result.length;
|
|
447
|
-
if (ctx.bytesWritten > ctx.options.maxOutputSize) {
|
|
448
|
-
throw new Error("Encoded output exceeds maximum size");
|
|
449
|
-
}
|
|
450
629
|
return {
|
|
451
630
|
bytes: result,
|
|
452
631
|
hex: bytesToHex(result)
|
|
@@ -465,7 +644,6 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
465
644
|
}
|
|
466
645
|
const ctx = {
|
|
467
646
|
depth: 0,
|
|
468
|
-
bytesWritten: 0,
|
|
469
647
|
options
|
|
470
648
|
};
|
|
471
649
|
return encodeMapInternal(map, ctx);
|
|
@@ -481,7 +659,6 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
481
659
|
const parts = [new Uint8Array([191])];
|
|
482
660
|
const ctx = {
|
|
483
661
|
depth: 0,
|
|
484
|
-
bytesWritten: 0,
|
|
485
662
|
options
|
|
486
663
|
};
|
|
487
664
|
for (const [key, value] of entries) {
|
|
@@ -506,149 +683,6 @@ function useCborCollectionEncoder(globalOptions) {
|
|
|
506
683
|
};
|
|
507
684
|
}
|
|
508
685
|
|
|
509
|
-
// src/encoder/composables/useCborSimpleEncoder.ts
|
|
510
|
-
function useCborSimpleEncoder(_globalOptions) {
|
|
511
|
-
const { encodeInteger } = useCborIntegerEncoder();
|
|
512
|
-
const encodeSimple = (value) => {
|
|
513
|
-
let byte;
|
|
514
|
-
if (value === false) {
|
|
515
|
-
byte = 244;
|
|
516
|
-
} else if (value === true) {
|
|
517
|
-
byte = 245;
|
|
518
|
-
} else if (value === null) {
|
|
519
|
-
byte = 246;
|
|
520
|
-
} else if (value === void 0) {
|
|
521
|
-
byte = 247;
|
|
522
|
-
} else {
|
|
523
|
-
throw new Error(`Unsupported simple value: ${value}`);
|
|
524
|
-
}
|
|
525
|
-
return {
|
|
526
|
-
bytes: new Uint8Array([byte]),
|
|
527
|
-
hex: bytesToHex(new Uint8Array([byte]))
|
|
528
|
-
};
|
|
529
|
-
};
|
|
530
|
-
const encodeFloat16Bytes = (value) => {
|
|
531
|
-
if (value === 0) return new Uint8Array([0, 0]);
|
|
532
|
-
if (value === -0) return new Uint8Array([128, 0]);
|
|
533
|
-
if (Number.isNaN(value)) return new Uint8Array([126, 0]);
|
|
534
|
-
if (value === Infinity) return new Uint8Array([124, 0]);
|
|
535
|
-
if (value === -Infinity) return new Uint8Array([252, 0]);
|
|
536
|
-
const sign = value < 0 ? 1 : 0;
|
|
537
|
-
const absValue = Math.abs(value);
|
|
538
|
-
const buffer = new ArrayBuffer(8);
|
|
539
|
-
const view = new DataView(buffer);
|
|
540
|
-
view.setFloat64(0, absValue, false);
|
|
541
|
-
const bits = view.getBigUint64(0, false);
|
|
542
|
-
const exp64 = Number(bits >> 52n & 0x7ffn) - 1023;
|
|
543
|
-
const mant64 = Number(bits & 0xfffffffffffffn);
|
|
544
|
-
let exp16;
|
|
545
|
-
let mant16;
|
|
546
|
-
if (exp64 < -24) {
|
|
547
|
-
exp16 = 0;
|
|
548
|
-
mant16 = 0;
|
|
549
|
-
} else if (exp64 < -14) {
|
|
550
|
-
exp16 = 0;
|
|
551
|
-
const shift = -14 - exp64;
|
|
552
|
-
mant16 = (1 << 10 | mant64 >> 42) + ((1 << shift - 1) - 1) >> shift;
|
|
553
|
-
} else if (exp64 > 15) {
|
|
554
|
-
exp16 = 31;
|
|
555
|
-
mant16 = 0;
|
|
556
|
-
} else {
|
|
557
|
-
exp16 = exp64 + 15;
|
|
558
|
-
mant16 = mant64 >> 42;
|
|
559
|
-
}
|
|
560
|
-
const float16 = sign << 15 | exp16 << 10 | mant16;
|
|
561
|
-
return new Uint8Array([
|
|
562
|
-
float16 >> 8 & 255,
|
|
563
|
-
float16 & 255
|
|
564
|
-
]);
|
|
565
|
-
};
|
|
566
|
-
const encodeFloat32Bytes = (value) => {
|
|
567
|
-
const buffer = new ArrayBuffer(4);
|
|
568
|
-
const view = new DataView(buffer);
|
|
569
|
-
view.setFloat32(0, value, false);
|
|
570
|
-
return new Uint8Array(buffer);
|
|
571
|
-
};
|
|
572
|
-
const encodeFloat64Bytes = (value) => {
|
|
573
|
-
const buffer = new ArrayBuffer(8);
|
|
574
|
-
const view = new DataView(buffer);
|
|
575
|
-
view.setFloat64(0, value, false);
|
|
576
|
-
return new Uint8Array(buffer);
|
|
577
|
-
};
|
|
578
|
-
const canBeFloat16 = (value) => {
|
|
579
|
-
if (!Number.isFinite(value) || value === 0 || value === -0) {
|
|
580
|
-
return true;
|
|
581
|
-
}
|
|
582
|
-
const absValue = Math.abs(value);
|
|
583
|
-
if (absValue < 6103515625e-14 || absValue > 65504) {
|
|
584
|
-
return false;
|
|
585
|
-
}
|
|
586
|
-
const bytes = encodeFloat16Bytes(value);
|
|
587
|
-
const view = new DataView(bytes.buffer);
|
|
588
|
-
const bits = view.getUint16(0, false);
|
|
589
|
-
const sign = bits >> 15 & 1;
|
|
590
|
-
const exp = bits >> 10 & 31;
|
|
591
|
-
const mant = bits & 1023;
|
|
592
|
-
let decoded;
|
|
593
|
-
if (exp === 0) {
|
|
594
|
-
decoded = (sign ? -1 : 1) * Math.pow(2, -14) * (mant / 1024);
|
|
595
|
-
} else if (exp === 31) {
|
|
596
|
-
decoded = mant === 0 ? sign ? -Infinity : Infinity : NaN;
|
|
597
|
-
} else {
|
|
598
|
-
decoded = (sign ? -1 : 1) * Math.pow(2, exp - 15) * (1 + mant / 1024);
|
|
599
|
-
}
|
|
600
|
-
return decoded === value;
|
|
601
|
-
};
|
|
602
|
-
const canBeFloat32 = (value) => {
|
|
603
|
-
if (!Number.isFinite(value) || value === 0 || value === -0) {
|
|
604
|
-
return true;
|
|
605
|
-
}
|
|
606
|
-
const buffer = new ArrayBuffer(4);
|
|
607
|
-
const view = new DataView(buffer);
|
|
608
|
-
view.setFloat32(0, value, false);
|
|
609
|
-
const decoded = view.getFloat32(0, false);
|
|
610
|
-
return decoded === value;
|
|
611
|
-
};
|
|
612
|
-
const isInteger = (value) => {
|
|
613
|
-
return Number.isInteger(value) && Number.isSafeInteger(value);
|
|
614
|
-
};
|
|
615
|
-
const encodeFloat = (value, precision) => {
|
|
616
|
-
let bytes;
|
|
617
|
-
if (isInteger(value) && !precision) {
|
|
618
|
-
return encodeInteger(value);
|
|
619
|
-
}
|
|
620
|
-
if (precision === 16) {
|
|
621
|
-
const floatBytes = encodeFloat16Bytes(value);
|
|
622
|
-
bytes = new Uint8Array([249, ...floatBytes]);
|
|
623
|
-
} else if (precision === 32) {
|
|
624
|
-
const floatBytes = encodeFloat32Bytes(value);
|
|
625
|
-
bytes = new Uint8Array([250, ...floatBytes]);
|
|
626
|
-
} else if (precision === 64) {
|
|
627
|
-
const floatBytes = encodeFloat64Bytes(value);
|
|
628
|
-
bytes = new Uint8Array([251, ...floatBytes]);
|
|
629
|
-
} else {
|
|
630
|
-
if (canBeFloat16(value)) {
|
|
631
|
-
const floatBytes = encodeFloat16Bytes(value);
|
|
632
|
-
bytes = new Uint8Array([249, ...floatBytes]);
|
|
633
|
-
} else if (canBeFloat32(value)) {
|
|
634
|
-
const floatBytes = encodeFloat32Bytes(value);
|
|
635
|
-
bytes = new Uint8Array([250, ...floatBytes]);
|
|
636
|
-
} else {
|
|
637
|
-
const floatBytes = encodeFloat64Bytes(value);
|
|
638
|
-
bytes = new Uint8Array([251, ...floatBytes]);
|
|
639
|
-
}
|
|
640
|
-
}
|
|
641
|
-
return {
|
|
642
|
-
bytes,
|
|
643
|
-
hex: bytesToHex(bytes)
|
|
644
|
-
};
|
|
645
|
-
};
|
|
646
|
-
return {
|
|
647
|
-
encodeSimple,
|
|
648
|
-
encodeFloat
|
|
649
|
-
};
|
|
650
|
-
}
|
|
651
|
-
|
|
652
686
|
// src/encoder/composables/useCborTagEncoder.ts
|
|
653
687
|
function useCborTagEncoder() {
|
|
654
688
|
const encodeTagNumber = (tagNumber) => {
|
|
@@ -713,10 +747,34 @@ function useCborEncoder(globalOptions) {
|
|
|
713
747
|
const { isCborByteString } = useCborByteString();
|
|
714
748
|
const { isCborTextString } = useCborTextString();
|
|
715
749
|
const encode = (value) => {
|
|
750
|
+
const result = encodeValue(value);
|
|
751
|
+
if (options.maxOutputSize && result.bytes.length > options.maxOutputSize) {
|
|
752
|
+
throw new Error(
|
|
753
|
+
`Encoded output size ${result.bytes.length} bytes exceeds limit of ${options.maxOutputSize} bytes`
|
|
754
|
+
);
|
|
755
|
+
}
|
|
756
|
+
return result;
|
|
757
|
+
};
|
|
758
|
+
let currentDepth = 0;
|
|
759
|
+
const encodeValue = (value) => {
|
|
760
|
+
if (currentDepth > options.maxDepth) {
|
|
761
|
+
throw new Error(`Maximum nesting depth ${options.maxDepth} exceeded`);
|
|
762
|
+
}
|
|
763
|
+
currentDepth++;
|
|
764
|
+
try {
|
|
765
|
+
return encodeValueInner(value);
|
|
766
|
+
} finally {
|
|
767
|
+
currentDepth--;
|
|
768
|
+
}
|
|
769
|
+
};
|
|
770
|
+
const encodeValueInner = (value) => {
|
|
716
771
|
if (value === null || value === void 0 || typeof value === "boolean") {
|
|
717
772
|
return encodeSimple(value);
|
|
718
773
|
}
|
|
719
774
|
if (typeof value === "number") {
|
|
775
|
+
if (Object.is(value, -0)) {
|
|
776
|
+
return encodeFloat(value, 16);
|
|
777
|
+
}
|
|
720
778
|
if (Number.isSafeInteger(value)) {
|
|
721
779
|
return encodeInteger(value);
|
|
722
780
|
}
|
|
@@ -786,5 +844,5 @@ function useCborEncoder(globalOptions) {
|
|
|
786
844
|
}
|
|
787
845
|
|
|
788
846
|
export { DEFAULT_ENCODE_OPTIONS, bytesToHex, compareBytes, concatenateUint8Arrays, useCborCollectionEncoder, useCborEncoder, useCborIntegerEncoder, useCborSimpleEncoder, useCborStringEncoder, useCborTagEncoder, writeBigUint, writeUint };
|
|
789
|
-
//# sourceMappingURL=chunk-
|
|
790
|
-
//# sourceMappingURL=chunk-
|
|
847
|
+
//# sourceMappingURL=chunk-EDXZTSIA.js.map
|
|
848
|
+
//# sourceMappingURL=chunk-EDXZTSIA.js.map
|