@bare-ts/lib 0.5.0 → 0.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/codec/data.d.ts +1 -1
- package/dist/codec/data.js +10 -14
- package/dist/codec/f32-array.d.ts +5 -0
- package/dist/codec/f32-array.js +51 -0
- package/dist/codec/f64-array.d.ts +5 -0
- package/dist/codec/f64-array.js +51 -0
- package/dist/codec/{primitive.d.ts → fixed-primitive.d.ts} +1 -11
- package/dist/codec/fixed-primitive.js +197 -0
- package/dist/codec/i16-array.d.ts +1 -1
- package/dist/codec/i16-array.js +31 -32
- package/dist/codec/i32-array.d.ts +1 -1
- package/dist/codec/i32-array.js +31 -32
- package/dist/codec/i64-array.d.ts +1 -1
- package/dist/codec/i64-array.js +31 -32
- package/dist/codec/i8-array.d.ts +1 -1
- package/dist/codec/i8-array.js +11 -10
- package/dist/codec/int.d.ts +5 -0
- package/dist/codec/int.js +78 -0
- package/dist/codec/string.d.ts +1 -1
- package/dist/codec/string.js +143 -114
- package/dist/codec/u16-array.d.ts +1 -1
- package/dist/codec/u16-array.js +31 -32
- package/dist/codec/u32-array.d.ts +1 -1
- package/dist/codec/u32-array.js +31 -32
- package/dist/codec/u64-array.d.ts +1 -1
- package/dist/codec/u64-array.js +31 -32
- package/dist/codec/u8-array.d.ts +1 -1
- package/dist/codec/u8-array.js +25 -19
- package/dist/codec/u8-clamped-array.d.ts +1 -1
- package/dist/codec/u8-clamped-array.js +11 -10
- package/dist/codec/uint.d.ts +8 -0
- package/dist/codec/uint.js +138 -0
- package/dist/core/bare-error.js +12 -8
- package/dist/core/byte-cursor.d.ts +1 -1
- package/dist/core/byte-cursor.js +102 -30
- package/dist/core/config.js +12 -17
- package/dist/index.cjs +147 -90
- package/dist/index.d.cts +21 -16
- package/dist/index.d.ts +21 -16
- package/dist/index.js +9 -3
- package/dist/util/assert.d.ts +10 -1
- package/dist/util/assert.js +24 -13
- package/dist/util/constants.js +6 -2
- package/dist/util/validator.d.ts +27 -0
- package/dist/util/validator.js +38 -10
- package/imports/dev.d.ts +4 -0
- package/imports/dev.development.d.ts +4 -0
- package/imports/dev.development.js +4 -0
- package/imports/dev.js +4 -0
- package/imports/dev.node.d.ts +4 -0
- package/imports/dev.node.js +4 -0
- package/package.json +20 -16
- package/dist/codec/float-array.d.ts +0 -9
- package/dist/codec/float-array.js +0 -93
- package/dist/codec/primitive.js +0 -423
- package/dist/env/dev.d.ts +0 -1
- package/dist/env/dev.development.d.ts +0 -1
- package/dist/env/dev.development.js +0 -2
- package/dist/env/dev.js +0 -2
- package/dist/env/dev.node.d.ts +0 -1
- package/dist/env/dev.node.js +0 -2
package/dist/codec/u64-array.js
CHANGED
|
@@ -1,51 +1,50 @@
|
|
|
1
|
-
|
|
1
|
+
//! Copyright (c) 2022 Victorien Elvinger
|
|
2
|
+
//! Licensed under the MIT License (https://mit-license.org/)
|
|
2
3
|
import { check, reserve } from "../core/byte-cursor.js";
|
|
3
4
|
import { assert, DEV } from "../util/assert.js";
|
|
4
5
|
import { IS_LITTLE_ENDIAN_PLATFORM } from "../util/constants.js";
|
|
5
6
|
import { isU32 } from "../util/validator.js";
|
|
6
7
|
import { readFixedData } from "./data.js";
|
|
7
|
-
import {
|
|
8
|
-
readU64,
|
|
9
|
-
readUintSafe32,
|
|
10
|
-
writeU64,
|
|
11
|
-
writeUintSafe32
|
|
12
|
-
} from "./primitive.js";
|
|
8
|
+
import { readU64, writeU64 } from "./fixed-primitive.js";
|
|
13
9
|
import { writeU8FixedArray } from "./u8-array.js";
|
|
14
|
-
|
|
10
|
+
import { readUintSafe32, writeUintSafe32 } from "./uint.js";
|
|
11
|
+
export const readU64FixedArray = IS_LITTLE_ENDIAN_PLATFORM
|
|
12
|
+
? readU64FixedArrayLe
|
|
13
|
+
: readU64FixedArrayBe;
|
|
15
14
|
export function readU64Array(bc) {
|
|
16
|
-
|
|
15
|
+
return readU64FixedArray(bc, readUintSafe32(bc));
|
|
17
16
|
}
|
|
18
17
|
function readU64FixedArrayLe(bc, len) {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
if (DEV) {
|
|
19
|
+
assert(isU32(len));
|
|
20
|
+
}
|
|
21
|
+
const byteCount = len * 8;
|
|
22
|
+
return new BigUint64Array(readFixedData(bc, byteCount));
|
|
24
23
|
}
|
|
25
24
|
function readU64FixedArrayBe(bc, len) {
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
25
|
+
if (DEV) {
|
|
26
|
+
assert(isU32(len));
|
|
27
|
+
}
|
|
28
|
+
check(bc, len * 8);
|
|
29
|
+
const result = new BigUint64Array(len);
|
|
30
|
+
for (let i = 0; i < len; i++) {
|
|
31
|
+
result[i] = readU64(bc);
|
|
32
|
+
}
|
|
33
|
+
return result;
|
|
35
34
|
}
|
|
36
35
|
export const writeU64FixedArray = IS_LITTLE_ENDIAN_PLATFORM ? writeU64FixedArrayLe : writeU64FixedArrayBe;
|
|
37
36
|
export function writeU64Array(bc, x) {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
37
|
+
writeUintSafe32(bc, x.length);
|
|
38
|
+
if (x.length > 0) {
|
|
39
|
+
writeU64FixedArray(bc, x);
|
|
40
|
+
}
|
|
42
41
|
}
|
|
43
42
|
function writeU64FixedArrayLe(bc, x) {
|
|
44
|
-
|
|
43
|
+
writeU8FixedArray(bc, new Uint8Array(x.buffer, x.byteOffset, x.byteLength));
|
|
45
44
|
}
|
|
46
45
|
function writeU64FixedArrayBe(bc, x) {
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
46
|
+
reserve(bc, x.length * 8);
|
|
47
|
+
for (let i = 0; i < x.length; i++) {
|
|
48
|
+
writeU64(bc, x[i]);
|
|
49
|
+
}
|
|
51
50
|
}
|
package/dist/codec/u8-array.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type ByteCursor } from "../core/byte-cursor.
|
|
1
|
+
import { type ByteCursor } from "../core/byte-cursor.ts";
|
|
2
2
|
export declare function readU8Array(bc: ByteCursor): Uint8Array<ArrayBuffer>;
|
|
3
3
|
export declare function writeU8Array(bc: ByteCursor, x: Uint8Array): void;
|
|
4
4
|
export declare function readU8FixedArray(bc: ByteCursor, len: number): Uint8Array<ArrayBuffer>;
|
package/dist/codec/u8-array.js
CHANGED
|
@@ -1,32 +1,38 @@
|
|
|
1
|
-
|
|
1
|
+
//! Copyright (c) 2022 Victorien Elvinger
|
|
2
|
+
//! Licensed under the MIT License (https://mit-license.org/)
|
|
2
3
|
import { check, reserve } from "../core/byte-cursor.js";
|
|
3
4
|
import { assert, DEV } from "../util/assert.js";
|
|
4
5
|
import { isU32 } from "../util/validator.js";
|
|
5
|
-
import { readUintSafe32, writeUintSafe32 } from "./
|
|
6
|
+
import { readUintSafe32, writeUintSafe32 } from "./uint.js";
|
|
6
7
|
export function readU8Array(bc) {
|
|
7
|
-
|
|
8
|
+
return readU8FixedArray(bc, readUintSafe32(bc));
|
|
8
9
|
}
|
|
9
10
|
export function writeU8Array(bc, x) {
|
|
10
|
-
|
|
11
|
-
|
|
11
|
+
writeUintSafe32(bc, x.length);
|
|
12
|
+
writeU8FixedArray(bc, x);
|
|
12
13
|
}
|
|
13
14
|
export function readU8FixedArray(bc, len) {
|
|
14
|
-
|
|
15
|
+
return readUnsafeU8FixedArray(bc, len).slice();
|
|
15
16
|
}
|
|
16
17
|
export function writeU8FixedArray(bc, x) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
const len = x.length;
|
|
19
|
+
if (len > 0) {
|
|
20
|
+
reserve(bc, len);
|
|
21
|
+
bc.bytes.set(x, bc.offset);
|
|
22
|
+
bc.offset += len;
|
|
23
|
+
}
|
|
23
24
|
}
|
|
25
|
+
/**
|
|
26
|
+
* Advance `bc` by `len` bytes and return a view of the read bytes.
|
|
27
|
+
*
|
|
28
|
+
* WARNING: The returned array should not be modified.
|
|
29
|
+
*/
|
|
24
30
|
export function readUnsafeU8FixedArray(bc, len) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
31
|
+
if (DEV) {
|
|
32
|
+
assert(isU32(len));
|
|
33
|
+
}
|
|
34
|
+
check(bc, len);
|
|
35
|
+
const offset = bc.offset;
|
|
36
|
+
bc.offset += len;
|
|
37
|
+
return bc.bytes.subarray(offset, offset + len);
|
|
32
38
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ByteCursor } from "../core/byte-cursor.
|
|
1
|
+
import type { ByteCursor } from "../core/byte-cursor.ts";
|
|
2
2
|
export declare function readU8ClampedArray(bc: ByteCursor): Uint8ClampedArray<ArrayBuffer>;
|
|
3
3
|
export declare function writeU8ClampedArray(bc: ByteCursor, x: Uint8ClampedArray): void;
|
|
4
4
|
export declare function readU8ClampedFixedArray(bc: ByteCursor, len: number): Uint8ClampedArray<ArrayBuffer>;
|
|
@@ -1,22 +1,23 @@
|
|
|
1
|
-
|
|
1
|
+
//! Copyright (c) 2022 Victorien Elvinger
|
|
2
|
+
//! Licensed under the MIT License (https://mit-license.org/)
|
|
2
3
|
import { assert, DEV } from "../util/assert.js";
|
|
3
4
|
import { isU32 } from "../util/validator.js";
|
|
4
5
|
import { readFixedData } from "./data.js";
|
|
5
|
-
import { readUintSafe32, writeUintSafe32 } from "./primitive.js";
|
|
6
6
|
import { writeU8FixedArray } from "./u8-array.js";
|
|
7
|
+
import { readUintSafe32, writeUintSafe32 } from "./uint.js";
|
|
7
8
|
export function readU8ClampedArray(bc) {
|
|
8
|
-
|
|
9
|
+
return readU8ClampedFixedArray(bc, readUintSafe32(bc));
|
|
9
10
|
}
|
|
10
11
|
export function writeU8ClampedArray(bc, x) {
|
|
11
|
-
|
|
12
|
-
|
|
12
|
+
writeUintSafe32(bc, x.length);
|
|
13
|
+
writeU8ClampedFixedArray(bc, x);
|
|
13
14
|
}
|
|
14
15
|
export function readU8ClampedFixedArray(bc, len) {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
if (DEV) {
|
|
17
|
+
assert(isU32(len));
|
|
18
|
+
}
|
|
19
|
+
return new Uint8ClampedArray(readFixedData(bc, len));
|
|
19
20
|
}
|
|
20
21
|
export function writeU8ClampedFixedArray(bc, x) {
|
|
21
|
-
|
|
22
|
+
writeU8FixedArray(bc, new Uint8Array(x.buffer, x.byteOffset, x.byteLength));
|
|
22
23
|
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ByteCursor } from "../core/byte-cursor.ts";
|
|
2
|
+
export declare function readUint(bc: ByteCursor): bigint;
|
|
3
|
+
export declare function writeUint(bc: ByteCursor, x: bigint): void;
|
|
4
|
+
export declare function writeUintTruncated(bc: ByteCursor, x: bigint): void;
|
|
5
|
+
export declare function readUintSafe32(bc: ByteCursor): number;
|
|
6
|
+
export declare function writeUintSafe32(bc: ByteCursor, x: number): void;
|
|
7
|
+
export declare function readUintSafe(bc: ByteCursor): number;
|
|
8
|
+
export declare function writeUintSafe(bc: ByteCursor, x: number): void;
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { BareError } from "../core/bare-error.js";
|
|
2
|
+
import { assert, DEV } from "../util/assert.js";
|
|
3
|
+
import { INT_SAFE_MAX_BYTE_COUNT, NON_CANONICAL_REPRESENTATION, TOO_LARGE_NUMBER, UINT_MAX_BYTE_COUNT, UINT_SAFE32_MAX_BYTE_COUNT, } from "../util/constants.js";
|
|
4
|
+
import { isU32, isU64Safe } from "../util/validator.js";
|
|
5
|
+
import { readU8, writeU8 } from "./fixed-primitive.js";
|
|
6
|
+
export function readUint(bc) {
|
|
7
|
+
let low = readU8(bc);
|
|
8
|
+
if (low >= 0x80) {
|
|
9
|
+
low &= 0x7f;
|
|
10
|
+
let shiftMul = 0x80;
|
|
11
|
+
let byteCount = 1;
|
|
12
|
+
let byte;
|
|
13
|
+
do {
|
|
14
|
+
byte = readU8(bc);
|
|
15
|
+
low += (byte & 0x7f) * shiftMul;
|
|
16
|
+
shiftMul *= /* 2**7 */ 0x80;
|
|
17
|
+
byteCount++;
|
|
18
|
+
} while (byte >= 0x80 && byteCount < 7);
|
|
19
|
+
let height = 0;
|
|
20
|
+
shiftMul = 1;
|
|
21
|
+
while (byte >= 0x80 && byteCount < UINT_MAX_BYTE_COUNT) {
|
|
22
|
+
byte = readU8(bc);
|
|
23
|
+
height += (byte & 0x7f) * shiftMul;
|
|
24
|
+
shiftMul *= /* 2**7 */ 0x80;
|
|
25
|
+
byteCount++;
|
|
26
|
+
}
|
|
27
|
+
if (byte === 0 || (byteCount === UINT_MAX_BYTE_COUNT && byte > 1)) {
|
|
28
|
+
bc.offset -= byteCount;
|
|
29
|
+
throw new BareError(bc.offset, NON_CANONICAL_REPRESENTATION);
|
|
30
|
+
}
|
|
31
|
+
return BigInt(low) + (BigInt(height) << BigInt(7 * 7));
|
|
32
|
+
}
|
|
33
|
+
return BigInt(low);
|
|
34
|
+
}
|
|
35
|
+
export function writeUint(bc, x) {
|
|
36
|
+
// truncate to mimic DataView#setBigUint64
|
|
37
|
+
// this is useful when assertions are skipped
|
|
38
|
+
const truncated = BigInt.asUintN(64, x);
|
|
39
|
+
if (DEV) {
|
|
40
|
+
assert(truncated === x, TOO_LARGE_NUMBER);
|
|
41
|
+
}
|
|
42
|
+
writeUintTruncated(bc, truncated);
|
|
43
|
+
}
|
|
44
|
+
export function writeUintTruncated(bc, x) {
|
|
45
|
+
// For better performances, we decompose `x` into two safe uint.
|
|
46
|
+
let tmp = Number(BigInt.asUintN(7 * 7, x));
|
|
47
|
+
let rest = Number(x >> BigInt(7 * 7));
|
|
48
|
+
let byteCount = 0;
|
|
49
|
+
while (tmp >= 0x80 || rest > 0) {
|
|
50
|
+
writeU8(bc, 0x80 | (tmp & 0x7f));
|
|
51
|
+
tmp = Math.floor(tmp / /* 2**7 */ 0x80);
|
|
52
|
+
byteCount++;
|
|
53
|
+
if (byteCount === 7) {
|
|
54
|
+
tmp = rest;
|
|
55
|
+
rest = 0;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
writeU8(bc, tmp);
|
|
59
|
+
}
|
|
60
|
+
export function readUintSafe32(bc) {
|
|
61
|
+
let result = readU8(bc);
|
|
62
|
+
if (result >= 0x80) {
|
|
63
|
+
result &= 0x7f;
|
|
64
|
+
let shift = 7;
|
|
65
|
+
let byteCount = 1;
|
|
66
|
+
let byte;
|
|
67
|
+
do {
|
|
68
|
+
byte = readU8(bc);
|
|
69
|
+
result += ((byte & 0x7f) << shift) >>> 0;
|
|
70
|
+
shift += 7;
|
|
71
|
+
byteCount++;
|
|
72
|
+
} while (byte >= 0x80 && byteCount < UINT_SAFE32_MAX_BYTE_COUNT);
|
|
73
|
+
if (byte === 0) {
|
|
74
|
+
bc.offset -= byteCount - 1;
|
|
75
|
+
throw new BareError(bc.offset - byteCount + 1, NON_CANONICAL_REPRESENTATION);
|
|
76
|
+
}
|
|
77
|
+
if (byteCount === UINT_SAFE32_MAX_BYTE_COUNT && byte > 0xf) {
|
|
78
|
+
bc.offset -= byteCount - 1;
|
|
79
|
+
throw new BareError(bc.offset, TOO_LARGE_NUMBER);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return result;
|
|
83
|
+
}
|
|
84
|
+
export function writeUintSafe32(bc, x) {
|
|
85
|
+
if (DEV) {
|
|
86
|
+
assert(isU32(x), TOO_LARGE_NUMBER);
|
|
87
|
+
}
|
|
88
|
+
// truncate to mimic other int encoders
|
|
89
|
+
// this is useful when assertions are skipped
|
|
90
|
+
let zigZag = x >>> 0;
|
|
91
|
+
while (zigZag >= 0x80) {
|
|
92
|
+
writeU8(bc, 0x80 | (zigZag & 0x7f));
|
|
93
|
+
zigZag >>>= 7;
|
|
94
|
+
}
|
|
95
|
+
writeU8(bc, zigZag);
|
|
96
|
+
}
|
|
97
|
+
export function readUintSafe(bc) {
|
|
98
|
+
let result = readU8(bc);
|
|
99
|
+
if (result >= 0x80) {
|
|
100
|
+
result &= 0x7f;
|
|
101
|
+
let shiftMul = /* 2**7 */ 0x80;
|
|
102
|
+
let byteCount = 1;
|
|
103
|
+
let byte;
|
|
104
|
+
do {
|
|
105
|
+
byte = readU8(bc);
|
|
106
|
+
result += (byte & 0x7f) * shiftMul;
|
|
107
|
+
shiftMul *= /* 2**7 */ 0x80;
|
|
108
|
+
byteCount++;
|
|
109
|
+
} while (byte >= 0x80 && byteCount < INT_SAFE_MAX_BYTE_COUNT);
|
|
110
|
+
if (byte === 0) {
|
|
111
|
+
bc.offset -= byteCount - 1;
|
|
112
|
+
throw new BareError(bc.offset - byteCount + 1, NON_CANONICAL_REPRESENTATION);
|
|
113
|
+
}
|
|
114
|
+
if (byteCount === INT_SAFE_MAX_BYTE_COUNT && byte > 0xf) {
|
|
115
|
+
bc.offset -= byteCount - 1;
|
|
116
|
+
throw new BareError(bc.offset, TOO_LARGE_NUMBER);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return result;
|
|
120
|
+
}
|
|
121
|
+
export function writeUintSafe(bc, x) {
|
|
122
|
+
if (DEV) {
|
|
123
|
+
assert(isU64Safe(x), TOO_LARGE_NUMBER);
|
|
124
|
+
}
|
|
125
|
+
let byteCount = 1;
|
|
126
|
+
let zigZag = x;
|
|
127
|
+
while (zigZag >= 0x80 && byteCount < INT_SAFE_MAX_BYTE_COUNT) {
|
|
128
|
+
writeU8(bc, 0x80 | (zigZag & 0x7f));
|
|
129
|
+
zigZag = Math.floor(zigZag / /* 2**7 */ 0x80);
|
|
130
|
+
byteCount++;
|
|
131
|
+
}
|
|
132
|
+
if (byteCount === INT_SAFE_MAX_BYTE_COUNT) {
|
|
133
|
+
// truncate to mimic other int encoders
|
|
134
|
+
// this is useful when assertions are skipped
|
|
135
|
+
zigZag &= 0x0f;
|
|
136
|
+
}
|
|
137
|
+
writeU8(bc, zigZag);
|
|
138
|
+
}
|
package/dist/core/bare-error.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
|
|
1
|
+
//! Copyright (c) 2022 Victorien Elvinger
|
|
2
|
+
//! Licensed under the MIT License (https://mit-license.org/)
|
|
3
|
+
/**
|
|
4
|
+
* @sealed
|
|
5
|
+
*/
|
|
2
6
|
export class BareError extends Error {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
constructor(offset, issue, opts) {
|
|
8
|
+
super(`(byte:${offset}) ${issue}`);
|
|
9
|
+
this.name = "BareError";
|
|
10
|
+
this.issue = issue;
|
|
11
|
+
this.offset = offset;
|
|
12
|
+
this.cause = opts?.cause;
|
|
13
|
+
}
|
|
10
14
|
}
|
package/dist/core/byte-cursor.js
CHANGED
|
@@ -1,46 +1,118 @@
|
|
|
1
|
-
|
|
1
|
+
//! Copyright (c) 2022 Victorien Elvinger
|
|
2
|
+
//! Licensed under the MIT License (https://mit-license.org/)
|
|
2
3
|
import { assert, DEV } from "../util/assert.js";
|
|
3
4
|
import { TOO_LARGE_BUFFER } from "../util/constants.js";
|
|
4
5
|
import { isU32 } from "../util/validator.js";
|
|
5
6
|
import { BareError } from "./bare-error.js";
|
|
7
|
+
/**
|
|
8
|
+
* @invariant `bytes.buffer === view.buffer`
|
|
9
|
+
* @invariant `bytes.byteOffset === view.byteOffset`
|
|
10
|
+
* @invariant `bytes.byteLength === view.byteLength`
|
|
11
|
+
* @invariant `0 <= offset <= bytes.byteLength`
|
|
12
|
+
* @invariant `bytes.byteLength <= config.maxBufferLength`
|
|
13
|
+
*
|
|
14
|
+
* ```txt
|
|
15
|
+
* | {bytes,view}.buffer |
|
|
16
|
+
* | bytes |
|
|
17
|
+
* | view |
|
|
18
|
+
* |<------ offset ------>|
|
|
19
|
+
* |<----------- config.maxBufferLength ------------>|
|
|
20
|
+
* ```
|
|
21
|
+
*
|
|
22
|
+
* @sealed
|
|
23
|
+
*/
|
|
6
24
|
export class ByteCursor {
|
|
7
|
-
/**
|
|
8
|
-
* @throws {BareError} Buffer exceeds `config.maxBufferLength`
|
|
9
|
-
*/
|
|
10
|
-
constructor(bytes, config) {
|
|
11
25
|
/**
|
|
12
|
-
*
|
|
26
|
+
* @throws {BareError} Buffer exceeds `config.maxBufferLength`
|
|
13
27
|
*/
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
28
|
+
constructor(bytes, config) {
|
|
29
|
+
/**
|
|
30
|
+
* Read and write Offset in {@link view} and {@link bytes}
|
|
31
|
+
*/
|
|
32
|
+
this.offset = 0;
|
|
33
|
+
if (bytes.length > config.maxBufferLength) {
|
|
34
|
+
throw new BareError(0, TOO_LARGE_BUFFER);
|
|
35
|
+
}
|
|
36
|
+
this.bytes = bytes;
|
|
37
|
+
this.config = config;
|
|
38
|
+
this.view = new DataView(bytes.buffer, bytes.byteOffset, bytes.length);
|
|
39
|
+
}
|
|
22
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Check that `min` number of bytes are available.
|
|
43
|
+
*
|
|
44
|
+
* @throws {BareError} bytes are missing.
|
|
45
|
+
*/
|
|
23
46
|
export function check(bc, min) {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
47
|
+
// We try to keep this function as small as possible to allow inling.
|
|
48
|
+
if (DEV) {
|
|
49
|
+
assert(isU32(min));
|
|
50
|
+
}
|
|
51
|
+
if (bc.offset + min > bc.bytes.length) {
|
|
52
|
+
throw new BareError(bc.offset, "missing bytes");
|
|
53
|
+
}
|
|
30
54
|
}
|
|
55
|
+
/**
|
|
56
|
+
* Reserve `min` number of bytes.
|
|
57
|
+
*
|
|
58
|
+
* @throws {BareError} Buffer exceeds `config.maxBufferLength`.
|
|
59
|
+
*/
|
|
31
60
|
export function reserve(bc, min) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
61
|
+
// We try to keep this function as small as possible to allow inling.
|
|
62
|
+
if (DEV) {
|
|
63
|
+
assert(isU32(min));
|
|
64
|
+
}
|
|
65
|
+
const minLen = (bc.offset + min) | 0;
|
|
66
|
+
if (minLen > bc.bytes.length) {
|
|
67
|
+
grow(bc, minLen);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Grow the underlying buffer of `bc` such that its length is
|
|
72
|
+
* greater or equal to `minLen`.
|
|
73
|
+
*
|
|
74
|
+
* @throws {BareError} Buffer exceeds `config.maxBufferLength`.
|
|
75
|
+
*/
|
|
76
|
+
function grow(bc, minLen) {
|
|
37
77
|
if (minLen > bc.config.maxBufferLength) {
|
|
38
|
-
|
|
78
|
+
throw new BareError(0, TOO_LARGE_BUFFER);
|
|
79
|
+
}
|
|
80
|
+
//
|
|
81
|
+
// | bytes,view}.buffer |
|
|
82
|
+
// | bytes |
|
|
83
|
+
// | view |
|
|
84
|
+
// |<-- offset -->|<-- min -->|
|
|
85
|
+
// |<-------- minLen -------->|
|
|
86
|
+
// | new view |
|
|
87
|
+
// | new bytes |
|
|
88
|
+
// | new {bytes,view}.buffer |
|
|
89
|
+
// |<------------- config.maxBufferLength -------------->|
|
|
90
|
+
//
|
|
91
|
+
const buffer = bc.bytes.buffer;
|
|
92
|
+
let newBytes;
|
|
93
|
+
if (isEs2024ArrayBufferLike(buffer) &&
|
|
94
|
+
// Make sure that the view covers the end of the buffer.
|
|
95
|
+
// If it is not the case, this indicates that the user don't want
|
|
96
|
+
// to override the trailing bytes.
|
|
97
|
+
bc.bytes.byteOffset + bc.bytes.byteLength === buffer.byteLength &&
|
|
98
|
+
bc.bytes.byteLength + minLen <= buffer.maxByteLength) {
|
|
99
|
+
const newLen = Math.min(minLen << 1, bc.config.maxBufferLength, buffer.maxByteLength);
|
|
100
|
+
if (buffer instanceof ArrayBuffer) {
|
|
101
|
+
buffer.resize(newLen);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
buffer.grow(newLen);
|
|
105
|
+
}
|
|
106
|
+
newBytes = new Uint8Array(buffer, bc.bytes.byteOffset, newLen);
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
const newLen = Math.min(minLen << 1, bc.config.maxBufferLength);
|
|
110
|
+
newBytes = new Uint8Array(newLen);
|
|
111
|
+
newBytes.set(bc.bytes);
|
|
39
112
|
}
|
|
40
|
-
const newLen = Math.min(minLen << 1, bc.config.maxBufferLength);
|
|
41
|
-
const newBytes = new Uint8Array(newLen);
|
|
42
|
-
newBytes.set(bc.bytes);
|
|
43
113
|
bc.bytes = newBytes;
|
|
44
114
|
bc.view = new DataView(newBytes.buffer);
|
|
45
|
-
|
|
115
|
+
}
|
|
116
|
+
function isEs2024ArrayBufferLike(buffer) {
|
|
117
|
+
return "maxByteLength" in buffer;
|
|
46
118
|
}
|
package/dist/core/config.js
CHANGED
|
@@ -1,22 +1,17 @@
|
|
|
1
|
-
|
|
1
|
+
//! Copyright (c) 2022 Victorien Elvinger
|
|
2
|
+
//! Licensed under the MIT License (https://mit-license.org/)
|
|
2
3
|
import { assert, DEV } from "../util/assert.js";
|
|
3
4
|
import { TOO_LARGE_NUMBER } from "../util/constants.js";
|
|
4
5
|
import { isU32 } from "../util/validator.js";
|
|
5
|
-
export function Config({
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
);
|
|
16
|
-
}
|
|
17
|
-
return {
|
|
18
|
-
initialBufferLength,
|
|
19
|
-
maxBufferLength
|
|
20
|
-
};
|
|
6
|
+
export function Config({ initialBufferLength = 1024, maxBufferLength = 1024 * 1024 * 32 /* 32 MiB */, }) {
|
|
7
|
+
if (DEV) {
|
|
8
|
+
assert(isU32(initialBufferLength), TOO_LARGE_NUMBER);
|
|
9
|
+
assert(isU32(maxBufferLength), TOO_LARGE_NUMBER);
|
|
10
|
+
assert(initialBufferLength <= maxBufferLength, "initialBufferLength must be lower than or equal to maxBufferLength");
|
|
11
|
+
}
|
|
12
|
+
return {
|
|
13
|
+
initialBufferLength,
|
|
14
|
+
maxBufferLength,
|
|
15
|
+
};
|
|
21
16
|
}
|
|
22
17
|
export const DEFAULT_CONFIG = /* @__PURE__ */ Config({});
|