@yume-chan/struct 2.0.0 → 2.3.2
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 +37 -25
- package/esm/buffer.d.ts +65 -20
- package/esm/buffer.d.ts.map +1 -1
- package/esm/buffer.js +114 -117
- package/esm/buffer.js.map +1 -1
- package/esm/field/types.d.ts +8 -2
- package/esm/field/types.d.ts.map +1 -1
- package/esm/struct.d.ts +2 -2
- package/esm/struct.d.ts.map +1 -1
- package/esm/struct.js +11 -6
- package/esm/struct.js.map +1 -1
- package/esm/types.d.ts +0 -2
- package/esm/types.d.ts.map +1 -1
- package/package.json +6 -6
- package/src/buffer.ts +226 -228
- package/src/field/types.ts +8 -2
- package/src/struct.ts +15 -7
- package/src/types.ts +0 -3
- package/tsconfig.build.tsbuildinfo +1 -1
package/esm/struct.js
CHANGED
|
@@ -18,25 +18,30 @@ export class StructEmptyError extends StructDeserializeError {
|
|
|
18
18
|
/* #__NO_SIDE_EFFECTS__ */
|
|
19
19
|
export function struct(fields, options) {
|
|
20
20
|
const fieldList = Object.entries(fields);
|
|
21
|
-
|
|
21
|
+
let size = 0;
|
|
22
|
+
let byob = true;
|
|
23
|
+
for (const [, field] of fieldList) {
|
|
24
|
+
size += field.size;
|
|
25
|
+
if (byob && field.type !== "byob") {
|
|
26
|
+
byob = false;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
22
29
|
const littleEndian = options.littleEndian;
|
|
23
30
|
const extra = options.extra
|
|
24
31
|
? Object.getOwnPropertyDescriptors(options.extra)
|
|
25
32
|
: undefined;
|
|
26
33
|
return {
|
|
27
34
|
littleEndian,
|
|
28
|
-
type: "byob",
|
|
29
35
|
fields,
|
|
30
|
-
size,
|
|
31
36
|
extra: options.extra,
|
|
37
|
+
type: byob ? "byob" : "default",
|
|
38
|
+
size,
|
|
32
39
|
serialize(source, bufferOrContext) {
|
|
33
40
|
const temp = { ...source };
|
|
34
41
|
for (const [key, field] of fieldList) {
|
|
35
42
|
if (key in temp && "init" in field) {
|
|
36
43
|
const result = field.init?.(temp[key], temp);
|
|
37
|
-
|
|
38
|
-
temp[key] = result;
|
|
39
|
-
}
|
|
44
|
+
temp[key] = result;
|
|
40
45
|
}
|
|
41
46
|
}
|
|
42
47
|
const sizes = new Array(fieldList.length);
|
package/esm/struct.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"struct.js","sourceRoot":"","sources":["../src/struct.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AASvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"struct.js","sourceRoot":"","sources":["../src/struct.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AASvC,OAAO,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAoCxD,MAAM,OAAO,sBAAuB,SAAQ,KAAK;IAC7C,YAAY,OAAe;QACvB,KAAK,CAAC,OAAO,CAAC,CAAC;IACnB,CAAC;CACJ;AAED,MAAM,OAAO,wBAAyB,SAAQ,sBAAsB;IAChE;QACI,KAAK,CACD,4EAA4E,CAC/E,CAAC;IACN,CAAC;CACJ;AAED,MAAM,OAAO,gBAAiB,SAAQ,sBAAsB;IACxD;QACI,KAAK,CAAC,yDAAyD,CAAC,CAAC;IACrE,CAAC;CACJ;AAiBD,0BAA0B;AAC1B,MAAM,UAAU,MAAM,CASlB,MAAc,EACd,OASC;IAED,MAAM,SAAS,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAEzC,IAAI,IAAI,GAAG,CAAC,CAAC;IACb,IAAI,IAAI,GAAG,IAAI,CAAC;IAChB,KAAK,MAAM,CAAC,EAAE,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;QAChC,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC;QACnB,IAAI,IAAI,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAChC,IAAI,GAAG,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED,MAAM,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAC1C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK;QACvB,CAAC,CAAC,MAAM,CAAC,yBAAyB,CAAC,OAAO,CAAC,KAAK,CAAC;QACjD,CAAC,CAAC,SAAS,CAAC;IAEhB,OAAO;QACH,YAAY;QACZ,MAAM;QACN,KAAK,EAAE,OAAO,CAAC,KAAK;QAEpB,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS;QAC/B,IAAI;QACJ,SAAS,CACL,MAA0B,EAC1B,eAAqD;YAErD,MAAM,IAAI,GAA4B,EAAE,GAAG,MAAM,EAAE,CAAC;YAEpD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;gBACnC,IAAI,GAAG,IAAI,IAAI,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;oBACjC,MAAM,MAAM,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,IAAa,CAAC,CAAC;oBACtD,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC;gBACvB,CAAC;YACL,CAAC;YAED,MAAM,KAAK,GAAG,IAAI,KAAK,CAAS,SAAS,CAAC,MAAM,CAAC,CAAC;YAClD,MAAM,OAAO,GAAG,IAAI,KAAK,CAAyB,SAAS,CAAC,MAAM,CAAC,CAAC;YACpE,CAAC;gBACG,MAAM,OAAO,GAAiC,EAAE,YAAY,EAAE,CAAC;gBAC/D,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;oBACtD,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;wBACxB,KAAK,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;oBAC9B,CAAC;yBAAM,CAAC;wBACJ,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;wBACrD,KAAK,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC;oBACzC,CAAC;gBACL,CAAC;YACL,CAAC;YAED,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,EAAE,CAAC,CAAC,CAAC;YAExD,IAAI,cAAuB,CAAC;YAC5B,IAAI,MAAkB,CAAC;YACvB,IAAI,KAAa,CAAC;YAClB,IAAI,eAAe,YAAY,UAAU,EAAE,CAAC;gBACxC,IAAI,eAAe,CAAC,MAAM,GAAG,IAAI,EAAE,CAAC;oBAChC,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;gBACxC,CAAC;gBACD,cAAc,GAAG,IAAI,CAAC;gBACtB,MAAM,GAAG,eAAe,CAAC;gBACzB,KAAK,GAAG,CAAC,CAAC;YACd,CAAC;iBAAM,IACH,OAAO,eAAe,KAAK,QAAQ;gBACnC,QAAQ,IAAI,eAAe,EAC7B,CAAC;gBACC,cAAc,GAAG,IAAI,CAAC;gBACtB,MAAM,GAAG,eAAe,CAAC,MAAM,CAAC;gBAChC,KAAK,GAAG,eAAe,CAAC,KAAK,IAAI,CAAC,CAAC;gBACnC,IAAI,MAAM,CAAC,MAAM,GAAG,KAAK,GAAG,IAAI,EAAE,CAAC;oBAC/B,MAAM,IAAI,KAAK,CAAC,kBAAkB,CAAC,CAAC;gBACxC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,cAAc,GAAG,KAAK,CAAC;gBACvB,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;gBAC9B,KAAK,GAAG,CAAC,CAAC;YACd,CAAC;YAED,MAAM,OAAO,GAAG;gBACZ,MAAM;gBACN,KAAK;gBACL,YAAY;aACqB,CAAC;YACtC,KAAK,MAAM,CAAC,KAAK,EAAE,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,IAAI,SAAS,CAAC,OAAO,EAAE,EAAE,CAAC;gBACtD,IAAI,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBACjB,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC9C,CAAC;qBAAM,CAAC;oBACJ,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,OAAO,CAAC,CAAC;gBACxC,CAAC;gBACD,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC,KAAK,CAAE,CAAC;YACnC,CAAC;YAED,IAAI,cAAc,EAAE,CAAC;gBACjB,OAAO,IAAI,CAAC;YAChB,CAAC;iBAAM,CAAC;gBACJ,OAAO,MAAM,CAAC;YAClB,CAAC;QACL,CAAC;QACD,WAAW,EAAE,OAAO,CAAC,QAAQ,CAAC,EAE1B,IAAI,EACJ,MAA0B;YAE1B,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,CAAC;YAEtC,MAAM,MAAM,GAAG,EAA6B,CAAC;YAC7C,MAAM,OAAO,GAET;gBACA,YAAY,EAAE,MAAe;gBAC7B,YAAY,EAAE,YAAY;aAC7B,CAAC;YAEF,IAAI,CAAC;gBACD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,SAAS,EAAE,CAAC;oBACnC,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,CAAC,IAAI,CACrB,KAAK,CAAC,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,CACrC,CAAC;gBACN,CAAC;YACL,CAAC;YAAC,OAAO,CAAC,EAAE,CAAC;gBACT,IAAI,CAAC,CAAC,CAAC,YAAY,uBAAuB,CAAC,EAAE,CAAC;oBAC1C,MAAM,CAAC,CAAC;gBACZ,CAAC;gBAED,IAAI,MAAM,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;oBACpC,MAAM,IAAI,gBAAgB,EAAE,CAAC;gBACjC,CAAC;qBAAM,CAAC;oBACJ,MAAM,IAAI,wBAAwB,EAAE,CAAC;gBACzC,CAAC;YACL,CAAC;YAED,IAAI,KAAK,EAAE,CAAC;gBACR,MAAM,CAAC,gBAAgB,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YAC3C,CAAC;YAED,IAAI,OAAO,CAAC,eAAe,EAAE,CAAC;gBAC1B,OAAO,OAAO,CAAC,eAAe,CAAC,IAAI,CAC/B,MAAe,EACf,MAAe,CAClB,CAAC;YACN,CAAC;iBAAM,CAAC;gBACJ,OAAO,MAAM,CAAC;YAClB,CAAC;QACL,CAAC,CAAC;KACI,CAAC;AACf,CAAC"}
|
package/esm/types.d.ts
CHANGED
|
@@ -3,8 +3,6 @@ import type { FieldByobSerializeContext, FieldDeserializer, FieldSerializer } fr
|
|
|
3
3
|
import type { AsyncExactReadable, ExactReadable } from "./readable.js";
|
|
4
4
|
export type StructSerializeContext = Omit<FieldByobSerializeContext, "littleEndian">;
|
|
5
5
|
export interface StructSerializer<T> extends FieldSerializer<T> {
|
|
6
|
-
type: "byob";
|
|
7
|
-
size: number;
|
|
8
6
|
serialize(source: T): Uint8Array;
|
|
9
7
|
serialize(source: T, buffer: Uint8Array): number;
|
|
10
8
|
serialize(source: T, context: StructSerializeContext): number;
|
package/esm/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,KAAK,EACR,yBAAyB,EACzB,iBAAiB,EACjB,eAAe,EAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEvE,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACrC,yBAAyB,EACzB,cAAc,CACjB,CAAC;AAEF,MAAM,WAAW,gBAAgB,CAAC,CAAC,CAAE,SAAQ,eAAe,CAAC,CAAC,CAAC;IAC3D,
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AAEzD,OAAO,KAAK,EACR,yBAAyB,EACzB,iBAAiB,EACjB,eAAe,EAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,KAAK,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEvE,MAAM,MAAM,sBAAsB,GAAG,IAAI,CACrC,yBAAyB,EACzB,cAAc,CACjB,CAAC;AAEF,MAAM,WAAW,gBAAgB,CAAC,CAAC,CAAE,SAAQ,eAAe,CAAC,CAAC,CAAC;IAC3D,SAAS,CAAC,MAAM,EAAE,CAAC,GAAG,UAAU,CAAC;IACjC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,UAAU,GAAG,MAAM,CAAC;IACjD,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,OAAO,EAAE,sBAAsB,GAAG,MAAM,CAAC;CACjE;AAED,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,gBAAgB,CAAC,OAAO,CAAC,IACtD,CAAC,SAAS,gBAAgB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEpD,MAAM,WAAW,kBAAkB,CAAC,CAAC,CAAE,SAAQ,iBAAiB,CAAC,CAAC,EAAE,KAAK,CAAC;IACtE,IAAI,EAAE,MAAM,CAAC;IAEb,WAAW,CAAC,MAAM,EAAE,aAAa,GAAG,CAAC,CAAC;IACtC,WAAW,CAAC,MAAM,EAAE,kBAAkB,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;CAChE;AAED,MAAM,MAAM,WAAW,CAAC,CAAC,SAAS,kBAAkB,CAAC,OAAO,CAAC,IACzD,CAAC,SAAS,kBAAkB,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;AAEtD,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,gBAAgB,CAAC,CAAC,CAAC,GAAG,kBAAkB,CAAC,CAAC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yume-chan/struct",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.3.2",
|
|
4
4
|
"description": "C-style structure serializer and deserializer.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"structure",
|
|
@@ -28,15 +28,15 @@
|
|
|
28
28
|
"types": "esm/index.d.ts",
|
|
29
29
|
"sideEffects": false,
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@yume-chan/async": "^4.
|
|
31
|
+
"@yume-chan/async": "^4.1.3",
|
|
32
32
|
"@yume-chan/no-data-view": "^2.0.0"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@types/node": "^
|
|
36
|
-
"prettier": "^3.
|
|
37
|
-
"typescript": "^5.
|
|
38
|
-
"@yume-chan/test-runner": "^1.0.0",
|
|
35
|
+
"@types/node": "^24.3.1",
|
|
36
|
+
"prettier": "^3.6.2",
|
|
37
|
+
"typescript": "^5.9.2",
|
|
39
38
|
"@yume-chan/eslint-config": "^1.0.0",
|
|
39
|
+
"@yume-chan/test-runner": "^1.0.0",
|
|
40
40
|
"@yume-chan/tsconfig": "^1.0.0"
|
|
41
41
|
},
|
|
42
42
|
"scripts": {
|
package/src/buffer.ts
CHANGED
|
@@ -1,8 +1,29 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
BipedalFieldDeserializer,
|
|
3
|
+
ByobFieldSerializer,
|
|
4
|
+
Field,
|
|
5
|
+
} from "./field/index.js";
|
|
2
6
|
import { field } from "./field/index.js";
|
|
3
7
|
|
|
4
8
|
export const EmptyUint8Array = new Uint8Array(0);
|
|
5
9
|
|
|
10
|
+
function copyMaybeDifferentLength(
|
|
11
|
+
dest: Uint8Array,
|
|
12
|
+
source: Uint8Array,
|
|
13
|
+
index: number,
|
|
14
|
+
length: number,
|
|
15
|
+
) {
|
|
16
|
+
if (source.length < length) {
|
|
17
|
+
dest.set(source, index);
|
|
18
|
+
// Clear trailing bytes
|
|
19
|
+
dest.fill(0, index + source.length, index + length);
|
|
20
|
+
} else if (source.length === length) {
|
|
21
|
+
dest.set(source, index);
|
|
22
|
+
} else {
|
|
23
|
+
dest.set(source.subarray(0, length), index);
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
6
27
|
export interface Converter<From, To> {
|
|
7
28
|
convert: (value: From) => To;
|
|
8
29
|
back: (value: To) => From;
|
|
@@ -12,70 +33,97 @@ export interface BufferLengthConverter<K, KT> extends Converter<KT, number> {
|
|
|
12
33
|
field: K;
|
|
13
34
|
}
|
|
14
35
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
<K extends string, KT>(
|
|
31
|
-
length: BufferLengthConverter<K, KT>,
|
|
32
|
-
): Field<Uint8Array, K, Record<K, KT>, Uint8Array>;
|
|
33
|
-
<K extends string, KT, U>(
|
|
34
|
-
length: BufferLengthConverter<K, KT>,
|
|
35
|
-
converter: Converter<Uint8Array, U>,
|
|
36
|
-
): Field<U, K, Record<K, KT>, Uint8Array>;
|
|
37
|
-
|
|
38
|
-
<LengthOmitInit extends string, LengthDependencies>(
|
|
39
|
-
length: Field<number, LengthOmitInit, LengthDependencies, number>,
|
|
40
|
-
): Field<Uint8Array, LengthOmitInit, LengthDependencies, Uint8Array>;
|
|
41
|
-
<LengthOmitInit extends string, LengthDependencies, U>(
|
|
42
|
-
length: Field<number, LengthOmitInit, LengthDependencies, number>,
|
|
43
|
-
converter: Converter<Uint8Array, U>,
|
|
44
|
-
): Field<U, LengthOmitInit, LengthDependencies, Uint8Array>;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
function _buffer(length: number): Field<Uint8Array, never, never, Uint8Array>;
|
|
48
|
-
function _buffer<U>(
|
|
36
|
+
/**
|
|
37
|
+
* Create a fixed-length `Uint8Array` field.
|
|
38
|
+
*
|
|
39
|
+
* @param length Length of the field
|
|
40
|
+
*/
|
|
41
|
+
export function buffer(
|
|
42
|
+
length: number,
|
|
43
|
+
): Field<Uint8Array, never, never, Uint8Array>;
|
|
44
|
+
/**
|
|
45
|
+
* Create a custom-typed field, backed by a fixed-length `Uint8Array`.
|
|
46
|
+
*
|
|
47
|
+
* @param length Length of the field
|
|
48
|
+
* @param converter A value converter to convert between `Uint8Array` and the target type
|
|
49
|
+
*/
|
|
50
|
+
export function buffer<U>(
|
|
49
51
|
length: number,
|
|
50
52
|
converter: Converter<Uint8Array, U>,
|
|
51
53
|
): Field<U, never, never, Uint8Array>;
|
|
52
54
|
|
|
53
|
-
|
|
55
|
+
/**
|
|
56
|
+
* Create a variable-length `Uint8Array` field.
|
|
57
|
+
* The length is determined by another number-typed field.
|
|
58
|
+
*
|
|
59
|
+
* @param lengthField Name of the length field. Must be declared before this field
|
|
60
|
+
*/
|
|
61
|
+
export function buffer<K extends string>(
|
|
54
62
|
lengthField: K,
|
|
55
63
|
): Field<Uint8Array, K, Record<K, number>, Uint8Array>;
|
|
56
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Create a custom-typed field, backed by a variable-length `Uint8Array`.
|
|
66
|
+
* The length is determined by another number-typed field.
|
|
67
|
+
*
|
|
68
|
+
* @param lengthField Name of the length field. Must be declared before this field
|
|
69
|
+
* @param converter A value converter to convert between `Uint8Array` and the target type
|
|
70
|
+
*/
|
|
71
|
+
export function buffer<K extends string, U>(
|
|
57
72
|
lengthField: K,
|
|
58
73
|
converter: Converter<Uint8Array, U>,
|
|
59
74
|
): Field<U, K, Record<K, number>, Uint8Array>;
|
|
60
75
|
|
|
61
|
-
|
|
76
|
+
/**
|
|
77
|
+
* Create a variable-length `Uint8Array` field.
|
|
78
|
+
* The length is determined by converting another field to `number`.
|
|
79
|
+
*
|
|
80
|
+
* @param length
|
|
81
|
+
* Name of the length field,
|
|
82
|
+
* and a converter to convert between source type and `number`.
|
|
83
|
+
* Must be declared before this field
|
|
84
|
+
*/
|
|
85
|
+
export function buffer<K extends string, KT>(
|
|
62
86
|
length: BufferLengthConverter<K, KT>,
|
|
63
87
|
): Field<Uint8Array, K, Record<K, KT>, Uint8Array>;
|
|
64
|
-
|
|
88
|
+
/**
|
|
89
|
+
* Create a custom-typed field, backed by a variable-length `Uint8Array`.
|
|
90
|
+
* The length is determined by converting another field to `number`.
|
|
91
|
+
*
|
|
92
|
+
* @param length
|
|
93
|
+
* Name of the length field,
|
|
94
|
+
* and a converter to convert between source type and `number`.
|
|
95
|
+
* Must be declared before this field
|
|
96
|
+
* @param converter
|
|
97
|
+
* A value converter to convert between `Uint8Array` and the target type
|
|
98
|
+
*/
|
|
99
|
+
export function buffer<K extends string, KT, U>(
|
|
65
100
|
length: BufferLengthConverter<K, KT>,
|
|
66
101
|
converter: Converter<Uint8Array, U>,
|
|
67
102
|
): Field<U, K, Record<K, KT>, Uint8Array>;
|
|
68
103
|
|
|
69
|
-
|
|
104
|
+
/**
|
|
105
|
+
* Create a length field, and a variable-length `Uint8Array` field.
|
|
106
|
+
* This is a shortcut when the length field is directly before the data field.
|
|
107
|
+
*
|
|
108
|
+
* @param length The length field declaration
|
|
109
|
+
*/
|
|
110
|
+
export function buffer<LengthOmitInit extends string, LengthDependencies>(
|
|
70
111
|
length: Field<number, LengthOmitInit, LengthDependencies, number>,
|
|
71
112
|
): Field<Uint8Array, LengthOmitInit, LengthDependencies, Uint8Array>;
|
|
72
|
-
|
|
113
|
+
/**
|
|
114
|
+
* Create a length field, and a custom-typed field, backed by a variable-length `Uint8Array`.
|
|
115
|
+
* This is a shortcut when the length field is directly before the data field.
|
|
116
|
+
*
|
|
117
|
+
* @param length The length field declaration
|
|
118
|
+
* @param converter A value converter to convert between `Uint8Array` and the target type
|
|
119
|
+
*/
|
|
120
|
+
export function buffer<LengthOmitInit extends string, LengthDependencies, U>(
|
|
73
121
|
length: Field<number, LengthOmitInit, LengthDependencies, number>,
|
|
74
122
|
converter: Converter<Uint8Array, U>,
|
|
75
123
|
): Field<U, LengthOmitInit, LengthDependencies, Uint8Array>;
|
|
76
124
|
|
|
77
125
|
/* #__NO_SIDE_EFFECTS__ */
|
|
78
|
-
function
|
|
126
|
+
export function buffer(
|
|
79
127
|
lengthOrField:
|
|
80
128
|
| string
|
|
81
129
|
| number
|
|
@@ -85,62 +133,47 @@ function _buffer(
|
|
|
85
133
|
): Field<unknown, string, Record<string, unknown>, Uint8Array> {
|
|
86
134
|
// Fixed length
|
|
87
135
|
if (typeof lengthOrField === "number") {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
// eslint-disable-next-line require-yield
|
|
95
|
-
function* () {
|
|
96
|
-
return converter.convert(EmptyUint8Array);
|
|
97
|
-
},
|
|
98
|
-
);
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
return field(
|
|
102
|
-
0,
|
|
103
|
-
"byob",
|
|
104
|
-
(value, { buffer, index }) => {
|
|
105
|
-
buffer.set(value.slice(0, lengthOrField), index);
|
|
106
|
-
},
|
|
107
|
-
function* (then, reader) {
|
|
108
|
-
const array = yield* then(
|
|
109
|
-
reader.readExactly(lengthOrField),
|
|
110
|
-
);
|
|
111
|
-
return converter.convert(array);
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
init(value) {
|
|
115
|
-
return converter.back(value);
|
|
116
|
-
},
|
|
117
|
-
},
|
|
118
|
-
);
|
|
119
|
-
}
|
|
136
|
+
let serialize: ByobFieldSerializer<Uint8Array>;
|
|
137
|
+
let deserialize: BipedalFieldDeserializer<
|
|
138
|
+
unknown,
|
|
139
|
+
Record<string, unknown>
|
|
140
|
+
>;
|
|
141
|
+
let init: ((value: unknown) => Uint8Array) | undefined;
|
|
120
142
|
|
|
121
143
|
if (lengthOrField === 0) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
144
|
+
serialize = () => {};
|
|
145
|
+
|
|
146
|
+
if (converter) {
|
|
147
|
+
// eslint-disable-next-line require-yield
|
|
148
|
+
deserialize = function* () {
|
|
149
|
+
return converter.convert(EmptyUint8Array);
|
|
150
|
+
};
|
|
151
|
+
} else {
|
|
126
152
|
// eslint-disable-next-line require-yield
|
|
127
|
-
function* () {
|
|
153
|
+
deserialize = function* () {
|
|
128
154
|
return EmptyUint8Array;
|
|
129
|
-
}
|
|
130
|
-
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
} else {
|
|
158
|
+
serialize = (value, { buffer, index }) =>
|
|
159
|
+
copyMaybeDifferentLength(buffer, value, index, lengthOrField);
|
|
160
|
+
|
|
161
|
+
if (converter) {
|
|
162
|
+
deserialize = function* (then, reader) {
|
|
163
|
+
const array = reader.readExactly(lengthOrField);
|
|
164
|
+
return converter.convert(yield* then(array));
|
|
165
|
+
};
|
|
166
|
+
init = (value) => converter.back(value);
|
|
167
|
+
} else {
|
|
168
|
+
// eslint-disable-next-line require-yield
|
|
169
|
+
deserialize = function* (_then, reader) {
|
|
170
|
+
const array = reader.readExactly(lengthOrField);
|
|
171
|
+
return array;
|
|
172
|
+
};
|
|
173
|
+
}
|
|
131
174
|
}
|
|
132
175
|
|
|
133
|
-
return field(
|
|
134
|
-
0,
|
|
135
|
-
"byob",
|
|
136
|
-
(value, { buffer, index }) => {
|
|
137
|
-
buffer.set(value.slice(0, lengthOrField), index);
|
|
138
|
-
},
|
|
139
|
-
// eslint-disable-next-line require-yield
|
|
140
|
-
function* (_then, reader) {
|
|
141
|
-
return reader.readExactly(lengthOrField);
|
|
142
|
-
},
|
|
143
|
-
);
|
|
176
|
+
return field(lengthOrField, "byob", serialize, deserialize, { init });
|
|
144
177
|
}
|
|
145
178
|
|
|
146
179
|
// Declare length field
|
|
@@ -150,48 +183,31 @@ function _buffer(
|
|
|
150
183
|
typeof lengthOrField === "function") &&
|
|
151
184
|
"serialize" in lengthOrField
|
|
152
185
|
) {
|
|
186
|
+
let deserialize: BipedalFieldDeserializer<
|
|
187
|
+
unknown,
|
|
188
|
+
Record<string, unknown>
|
|
189
|
+
>;
|
|
190
|
+
let init: ((value: unknown) => Uint8Array) | undefined;
|
|
191
|
+
|
|
153
192
|
if (converter) {
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
);
|
|
173
|
-
lengthOrField.serialize(value.length, {
|
|
174
|
-
buffer: result,
|
|
175
|
-
index: 0,
|
|
176
|
-
littleEndian,
|
|
177
|
-
});
|
|
178
|
-
result.set(value, lengthOrField.size);
|
|
179
|
-
return result;
|
|
180
|
-
}
|
|
181
|
-
},
|
|
182
|
-
function* (then, reader, context) {
|
|
183
|
-
const length = yield* then(
|
|
184
|
-
lengthOrField.deserialize(reader, context),
|
|
185
|
-
);
|
|
186
|
-
const array = yield* then(reader.readExactly(length));
|
|
187
|
-
return converter.convert(array);
|
|
188
|
-
},
|
|
189
|
-
{
|
|
190
|
-
init(value) {
|
|
191
|
-
return converter.back(value);
|
|
192
|
-
},
|
|
193
|
-
},
|
|
194
|
-
);
|
|
193
|
+
deserialize = function* (then, reader, context) {
|
|
194
|
+
const length = yield* then(
|
|
195
|
+
lengthOrField.deserialize(reader, context),
|
|
196
|
+
);
|
|
197
|
+
const array =
|
|
198
|
+
length !== 0 ? reader.readExactly(length) : EmptyUint8Array;
|
|
199
|
+
return converter.convert(yield* then(array));
|
|
200
|
+
};
|
|
201
|
+
init = (value) => converter.back(value);
|
|
202
|
+
} else {
|
|
203
|
+
deserialize = function* (then, reader, context) {
|
|
204
|
+
const length = yield* then(
|
|
205
|
+
lengthOrField.deserialize(reader, context),
|
|
206
|
+
);
|
|
207
|
+
const array =
|
|
208
|
+
length !== 0 ? reader.readExactly(length) : EmptyUint8Array;
|
|
209
|
+
return array;
|
|
210
|
+
};
|
|
195
211
|
}
|
|
196
212
|
|
|
197
213
|
return field(
|
|
@@ -202,6 +218,11 @@ function _buffer(
|
|
|
202
218
|
const lengthBuffer = lengthOrField.serialize(value.length, {
|
|
203
219
|
littleEndian,
|
|
204
220
|
});
|
|
221
|
+
|
|
222
|
+
if (value.length === 0) {
|
|
223
|
+
return lengthBuffer;
|
|
224
|
+
}
|
|
225
|
+
|
|
205
226
|
const result = new Uint8Array(
|
|
206
227
|
lengthBuffer.length + value.length,
|
|
207
228
|
);
|
|
@@ -221,114 +242,91 @@ function _buffer(
|
|
|
221
242
|
return result;
|
|
222
243
|
}
|
|
223
244
|
},
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
lengthOrField.deserialize(reader, context),
|
|
227
|
-
);
|
|
228
|
-
return yield* then(reader.readExactly(length));
|
|
229
|
-
},
|
|
245
|
+
deserialize,
|
|
246
|
+
{ init },
|
|
230
247
|
);
|
|
231
248
|
}
|
|
232
249
|
|
|
233
|
-
// Reference
|
|
250
|
+
// Reference existing length field
|
|
234
251
|
if (typeof lengthOrField === "string") {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
if (length === 0) {
|
|
244
|
-
return EmptyUint8Array;
|
|
245
|
-
}
|
|
252
|
+
let deserialize: BipedalFieldDeserializer<
|
|
253
|
+
unknown,
|
|
254
|
+
Record<string, unknown>
|
|
255
|
+
>;
|
|
256
|
+
let init: (
|
|
257
|
+
value: unknown,
|
|
258
|
+
dependencies: Record<string, unknown>,
|
|
259
|
+
) => Uint8Array;
|
|
246
260
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
0,
|
|
261
|
-
"default",
|
|
262
|
-
(source) => source,
|
|
261
|
+
if (converter) {
|
|
262
|
+
deserialize = function* (then, reader, { dependencies }) {
|
|
263
|
+
const length = dependencies[lengthOrField] as number;
|
|
264
|
+
const array =
|
|
265
|
+
length !== 0 ? reader.readExactly(length) : EmptyUint8Array;
|
|
266
|
+
return converter.convert(yield* then(array));
|
|
267
|
+
};
|
|
268
|
+
init = (value, dependencies) => {
|
|
269
|
+
const array = converter.back(value);
|
|
270
|
+
dependencies[lengthOrField] = array.length;
|
|
271
|
+
return array;
|
|
272
|
+
};
|
|
273
|
+
} else {
|
|
263
274
|
// eslint-disable-next-line require-yield
|
|
264
|
-
function* (_then, reader, { dependencies }) {
|
|
275
|
+
deserialize = function* (_then, reader, { dependencies }) {
|
|
265
276
|
const length = dependencies[lengthOrField] as number;
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
277
|
+
const array =
|
|
278
|
+
length !== 0 ? reader.readExactly(length) : EmptyUint8Array;
|
|
279
|
+
return array;
|
|
280
|
+
};
|
|
281
|
+
init = (value, dependencies) => {
|
|
282
|
+
const array = value as Uint8Array;
|
|
283
|
+
dependencies[lengthOrField] = array.length;
|
|
284
|
+
return array;
|
|
285
|
+
};
|
|
286
|
+
}
|
|
269
287
|
|
|
270
|
-
|
|
271
|
-
},
|
|
272
|
-
{
|
|
273
|
-
init(value, dependencies) {
|
|
274
|
-
dependencies[lengthOrField] = (value as Uint8Array).length;
|
|
275
|
-
return undefined;
|
|
276
|
-
},
|
|
277
|
-
},
|
|
278
|
-
);
|
|
288
|
+
return field(0, "default", (source) => source, deserialize, { init });
|
|
279
289
|
}
|
|
280
290
|
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
(source) => source,
|
|
287
|
-
// eslint-disable-next-line require-yield
|
|
288
|
-
function* (_then, reader, { dependencies }) {
|
|
289
|
-
const rawLength = dependencies[lengthOrField.field];
|
|
290
|
-
const length = lengthOrField.convert(rawLength);
|
|
291
|
-
if (length === 0) {
|
|
292
|
-
return EmptyUint8Array;
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
return reader.readExactly(length);
|
|
296
|
-
},
|
|
297
|
-
{
|
|
298
|
-
init(value, dependencies) {
|
|
299
|
-
const array = converter.back(value);
|
|
300
|
-
dependencies[lengthOrField.field] = lengthOrField.back(
|
|
301
|
-
array.length,
|
|
302
|
-
);
|
|
303
|
-
return array;
|
|
304
|
-
},
|
|
305
|
-
},
|
|
306
|
-
);
|
|
307
|
-
}
|
|
291
|
+
let deserialize: BipedalFieldDeserializer<unknown, Record<string, unknown>>;
|
|
292
|
+
let init: (
|
|
293
|
+
value: unknown,
|
|
294
|
+
dependencies: Record<string, unknown>,
|
|
295
|
+
) => Uint8Array;
|
|
308
296
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
297
|
+
// Reference existing length field + length converter
|
|
298
|
+
if (converter) {
|
|
299
|
+
deserialize = function* (then, reader, { dependencies }) {
|
|
300
|
+
const rawLength = dependencies[lengthOrField.field];
|
|
301
|
+
const length = lengthOrField.convert(rawLength);
|
|
302
|
+
const array =
|
|
303
|
+
length !== 0 ? reader.readExactly(length) : EmptyUint8Array;
|
|
304
|
+
return converter.convert(yield* then(array));
|
|
305
|
+
};
|
|
306
|
+
init = (value, dependencies) => {
|
|
307
|
+
const array = converter.back(value);
|
|
308
|
+
dependencies[lengthOrField.field] = lengthOrField.back(
|
|
309
|
+
array.length,
|
|
310
|
+
);
|
|
311
|
+
return array;
|
|
312
|
+
};
|
|
313
|
+
} else {
|
|
313
314
|
// eslint-disable-next-line require-yield
|
|
314
|
-
function* (_then, reader, { dependencies }) {
|
|
315
|
+
deserialize = function* (_then, reader, { dependencies }) {
|
|
315
316
|
const rawLength = dependencies[lengthOrField.field];
|
|
316
317
|
const length = lengthOrField.convert(rawLength);
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
318
|
+
const array =
|
|
319
|
+
length !== 0 ? reader.readExactly(length) : EmptyUint8Array;
|
|
320
|
+
return array;
|
|
321
|
+
};
|
|
322
|
+
init = (value, dependencies) => {
|
|
323
|
+
const array = value as Uint8Array;
|
|
324
|
+
dependencies[lengthOrField.field] = lengthOrField.back(
|
|
325
|
+
array.length,
|
|
326
|
+
);
|
|
327
|
+
return array;
|
|
328
|
+
};
|
|
329
|
+
}
|
|
320
330
|
|
|
321
|
-
|
|
322
|
-
},
|
|
323
|
-
{
|
|
324
|
-
init(value, dependencies) {
|
|
325
|
-
dependencies[lengthOrField.field] = lengthOrField.back(
|
|
326
|
-
(value as Uint8Array).length,
|
|
327
|
-
);
|
|
328
|
-
return undefined;
|
|
329
|
-
},
|
|
330
|
-
},
|
|
331
|
-
);
|
|
331
|
+
return field(0, "default", (source) => source, deserialize, { init });
|
|
332
332
|
}
|
|
333
|
-
|
|
334
|
-
export const buffer = _buffer;
|
package/src/field/types.ts
CHANGED
|
@@ -25,7 +25,10 @@ export interface Field<T, OmitInit extends string, D, Raw = T>
|
|
|
25
25
|
FieldDeserializer<T, D> {
|
|
26
26
|
omitInit: OmitInit | undefined;
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
/**
|
|
29
|
+
* A function to convert deserialized value back to raw value for serialization.
|
|
30
|
+
*/
|
|
31
|
+
init?(value: T, dependencies: D): Raw;
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
export interface FieldDeserializeContext<D> {
|
|
@@ -44,5 +47,8 @@ export interface FieldDeserializer<T, D> {
|
|
|
44
47
|
export interface FieldOptions<T, OmitInit extends string, D, Raw = T> {
|
|
45
48
|
omitInit?: OmitInit;
|
|
46
49
|
dependencies?: D;
|
|
47
|
-
|
|
50
|
+
/**
|
|
51
|
+
* A function to convert deserialized value back to raw value for serialization.
|
|
52
|
+
*/
|
|
53
|
+
init?: ((value: T, dependencies: D) => Raw) | undefined;
|
|
48
54
|
}
|