@yume-chan/struct 0.0.24 → 2.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.
Files changed (150) hide show
  1. package/CHANGELOG.md +40 -1
  2. package/LICENSE +1 -1
  3. package/README.md +85 -714
  4. package/esm/bipedal.d.ts +6 -0
  5. package/esm/bipedal.d.ts.map +1 -0
  6. package/esm/bipedal.js +38 -0
  7. package/esm/bipedal.js.map +1 -0
  8. package/esm/buffer.d.ts +30 -0
  9. package/esm/buffer.d.ts.map +1 -0
  10. package/esm/buffer.js +170 -0
  11. package/esm/buffer.js.map +1 -0
  12. package/esm/concat.d.ts +13 -0
  13. package/esm/concat.d.ts.map +1 -0
  14. package/esm/concat.js +10 -0
  15. package/esm/concat.js.map +1 -0
  16. package/esm/extend.d.ts +6 -0
  17. package/esm/extend.d.ts.map +1 -0
  18. package/esm/extend.js +10 -0
  19. package/esm/extend.js.map +1 -0
  20. package/esm/field/factory.d.ts +13 -0
  21. package/esm/field/factory.d.ts.map +1 -0
  22. package/esm/field/factory.js +21 -0
  23. package/esm/field/factory.js.map +1 -0
  24. package/esm/field/index.d.ts +4 -0
  25. package/esm/field/index.d.ts.map +1 -0
  26. package/esm/field/index.js +4 -0
  27. package/esm/field/index.js.map +1 -0
  28. package/esm/field/serialize.d.ts +8 -0
  29. package/esm/field/serialize.d.ts.map +1 -0
  30. package/esm/field/serialize.js +33 -0
  31. package/esm/field/serialize.js.map +1 -0
  32. package/esm/field/types.d.ts +33 -0
  33. package/esm/field/types.d.ts.map +1 -0
  34. package/esm/field/types.js +2 -0
  35. package/esm/field/types.js.map +1 -0
  36. package/esm/index.d.ts +9 -4
  37. package/esm/index.d.ts.map +1 -1
  38. package/esm/index.js +9 -4
  39. package/esm/index.js.map +1 -1
  40. package/esm/number.d.ts +13 -0
  41. package/esm/number.d.ts.map +1 -0
  42. package/esm/number.js +57 -0
  43. package/esm/number.js.map +1 -0
  44. package/esm/{basic/stream.d.ts → readable.d.ts} +9 -3
  45. package/esm/readable.d.ts.map +1 -0
  46. package/esm/readable.js +26 -0
  47. package/esm/readable.js.map +1 -0
  48. package/esm/string.d.ts +16 -0
  49. package/esm/string.d.ts.map +1 -0
  50. package/esm/string.js +13 -0
  51. package/esm/string.js.map +1 -0
  52. package/esm/struct.d.ts +22 -140
  53. package/esm/struct.d.ts.map +1 -1
  54. package/esm/struct.js +109 -227
  55. package/esm/struct.js.map +1 -1
  56. package/esm/types.d.ts +20 -0
  57. package/esm/types.d.ts.map +1 -0
  58. package/esm/types.js +2 -0
  59. package/esm/types.js.map +1 -0
  60. package/esm/utils.d.ts +10 -45
  61. package/esm/utils.d.ts.map +1 -1
  62. package/esm/utils.js +8 -9
  63. package/esm/utils.js.map +1 -1
  64. package/package.json +11 -12
  65. package/src/bipedal.ts +65 -0
  66. package/src/buffer.ts +334 -0
  67. package/src/concat.ts +78 -0
  68. package/src/extend.ts +37 -0
  69. package/src/field/factory.ts +64 -0
  70. package/src/field/index.ts +3 -0
  71. package/src/field/serialize.ts +58 -0
  72. package/src/field/types.ts +48 -0
  73. package/src/index.ts +9 -4
  74. package/src/number.ts +134 -0
  75. package/src/{basic/stream.ts → readable.ts} +31 -4
  76. package/src/string.ts +41 -0
  77. package/src/struct.ts +200 -670
  78. package/src/types.ts +37 -0
  79. package/src/utils.ts +14 -67
  80. package/tsconfig.build.json +6 -1
  81. package/tsconfig.build.tsbuildinfo +1 -1
  82. package/CHANGELOG.json +0 -173
  83. package/esm/basic/definition.d.ts +0 -44
  84. package/esm/basic/definition.d.ts.map +0 -1
  85. package/esm/basic/definition.js +0 -24
  86. package/esm/basic/definition.js.map +0 -1
  87. package/esm/basic/field-value.d.ts +0 -39
  88. package/esm/basic/field-value.d.ts.map +0 -1
  89. package/esm/basic/field-value.js +0 -46
  90. package/esm/basic/field-value.js.map +0 -1
  91. package/esm/basic/index.d.ts +0 -6
  92. package/esm/basic/index.d.ts.map +0 -1
  93. package/esm/basic/index.js +0 -6
  94. package/esm/basic/index.js.map +0 -1
  95. package/esm/basic/options.d.ts +0 -10
  96. package/esm/basic/options.d.ts.map +0 -1
  97. package/esm/basic/options.js +0 -4
  98. package/esm/basic/options.js.map +0 -1
  99. package/esm/basic/stream.d.ts.map +0 -1
  100. package/esm/basic/stream.js +0 -8
  101. package/esm/basic/stream.js.map +0 -1
  102. package/esm/basic/struct-value.d.ts +0 -30
  103. package/esm/basic/struct-value.d.ts.map +0 -1
  104. package/esm/basic/struct-value.js +0 -62
  105. package/esm/basic/struct-value.js.map +0 -1
  106. package/esm/sync-promise.d.ts +0 -13
  107. package/esm/sync-promise.d.ts.map +0 -1
  108. package/esm/sync-promise.js +0 -71
  109. package/esm/sync-promise.js.map +0 -1
  110. package/esm/types/bigint.d.ts +0 -25
  111. package/esm/types/bigint.d.ts.map +0 -1
  112. package/esm/types/bigint.js +0 -46
  113. package/esm/types/bigint.js.map +0 -1
  114. package/esm/types/buffer/base.d.ts +0 -69
  115. package/esm/types/buffer/base.d.ts.map +0 -1
  116. package/esm/types/buffer/base.js +0 -100
  117. package/esm/types/buffer/base.js.map +0 -1
  118. package/esm/types/buffer/fixed-length.d.ts +0 -9
  119. package/esm/types/buffer/fixed-length.d.ts.map +0 -1
  120. package/esm/types/buffer/fixed-length.js +0 -7
  121. package/esm/types/buffer/fixed-length.js.map +0 -1
  122. package/esm/types/buffer/index.d.ts +0 -4
  123. package/esm/types/buffer/index.d.ts.map +0 -1
  124. package/esm/types/buffer/index.js +0 -4
  125. package/esm/types/buffer/index.js.map +0 -1
  126. package/esm/types/buffer/variable-length.d.ts +0 -46
  127. package/esm/types/buffer/variable-length.d.ts.map +0 -1
  128. package/esm/types/buffer/variable-length.js +0 -87
  129. package/esm/types/buffer/variable-length.js.map +0 -1
  130. package/esm/types/index.d.ts +0 -4
  131. package/esm/types/index.d.ts.map +0 -1
  132. package/esm/types/index.js +0 -4
  133. package/esm/types/index.js.map +0 -1
  134. package/esm/types/number.d.ts +0 -28
  135. package/esm/types/number.d.ts.map +0 -1
  136. package/esm/types/number.js +0 -99
  137. package/esm/types/number.js.map +0 -1
  138. package/src/basic/definition.ts +0 -68
  139. package/src/basic/field-value.ts +0 -75
  140. package/src/basic/index.ts +0 -5
  141. package/src/basic/options.ts +0 -19
  142. package/src/basic/struct-value.ts +0 -85
  143. package/src/sync-promise.ts +0 -134
  144. package/src/types/bigint.ts +0 -124
  145. package/src/types/buffer/base.ts +0 -198
  146. package/src/types/buffer/fixed-length.ts +0 -22
  147. package/src/types/buffer/index.ts +0 -3
  148. package/src/types/buffer/variable-length.ts +0 -198
  149. package/src/types/index.ts +0 -3
  150. package/src/types/number.ts +0 -166
package/src/index.ts CHANGED
@@ -10,9 +10,14 @@ declare global {
10
10
  }
11
11
  }
12
12
 
13
- export * from "./basic/index.js";
13
+ export * from "./bipedal.js";
14
+ export * from "./buffer.js";
15
+ export * from "./concat.js";
16
+ export * from "./extend.js";
17
+ export * from "./field/index.js";
18
+ export * from "./number.js";
19
+ export * from "./readable.js";
20
+ export * from "./string.js";
14
21
  export * from "./struct.js";
15
- export { Struct as default } from "./struct.js";
16
- export * from "./sync-promise.js";
17
- export * from "./types/index.js";
22
+ export * from "./types.js";
18
23
  export * from "./utils.js";
package/src/number.ts ADDED
@@ -0,0 +1,134 @@
1
+ import type { MaybePromiseLike } from "@yume-chan/async";
2
+ import {
3
+ getInt16,
4
+ getInt32,
5
+ getInt64,
6
+ getInt8,
7
+ getUint16,
8
+ getUint32,
9
+ getUint64,
10
+ setInt16,
11
+ setInt32,
12
+ setInt64,
13
+ setUint16,
14
+ setUint32,
15
+ setUint64,
16
+ } from "@yume-chan/no-data-view";
17
+
18
+ import type {
19
+ Field,
20
+ FieldByobSerializeContext,
21
+ FieldDeserializeContext,
22
+ } from "./field/index.js";
23
+ import { field } from "./field/index.js";
24
+ import type { AsyncExactReadable } from "./readable.js";
25
+
26
+ export interface NumberField<T> extends Field<T, never, never, T> {
27
+ <const U>(infer?: U): Field<U, never, never, T>;
28
+ }
29
+
30
+ /* #__NO_SIDE_EFFECTS__ */
31
+ function number<T>(
32
+ size: number,
33
+ serialize: (
34
+ source: T,
35
+ context: FieldByobSerializeContext & { index: number },
36
+ ) => void,
37
+ deserialize: (
38
+ then: <U>(value: MaybePromiseLike<U>) => Iterable<unknown, U, unknown>,
39
+ reader: AsyncExactReadable,
40
+ context: FieldDeserializeContext<never>,
41
+ ) => Generator<unknown, T, unknown>,
42
+ ) {
43
+ const fn: NumberField<T> = (() => fn) as never;
44
+ Object.assign(fn, field(size, "byob", serialize, deserialize));
45
+ return fn;
46
+ }
47
+
48
+ export const u8: NumberField<number> = number(
49
+ 1,
50
+ (value, { buffer, index }) => {
51
+ buffer[index] = value;
52
+ },
53
+ function* (then, reader) {
54
+ const data = yield* then(reader.readExactly(1));
55
+ return data[0]!;
56
+ },
57
+ );
58
+
59
+ export const s8: NumberField<number> = number(
60
+ 1,
61
+ (value, { buffer, index }) => {
62
+ buffer[index] = value;
63
+ },
64
+ function* (then, reader) {
65
+ const data = yield* then(reader.readExactly(1));
66
+ return getInt8(data, 0);
67
+ },
68
+ );
69
+
70
+ export const u16: NumberField<number> = number(
71
+ 2,
72
+ (value, { buffer, index, littleEndian }) => {
73
+ setUint16(buffer, index, value, littleEndian);
74
+ },
75
+ function* (then, reader, { littleEndian }) {
76
+ const data = yield* then(reader.readExactly(2));
77
+ return getUint16(data, 0, littleEndian);
78
+ },
79
+ );
80
+
81
+ export const s16: NumberField<number> = number(
82
+ 2,
83
+ (value, { buffer, index, littleEndian }) => {
84
+ setInt16(buffer, index, value, littleEndian);
85
+ },
86
+ function* (then, reader, { littleEndian }) {
87
+ const data = yield* then(reader.readExactly(2));
88
+ return getInt16(data, 0, littleEndian);
89
+ },
90
+ );
91
+
92
+ export const u32: NumberField<number> = number(
93
+ 4,
94
+ (value, { buffer, index, littleEndian }) => {
95
+ setUint32(buffer, index, value, littleEndian);
96
+ },
97
+ function* (then, reader, { littleEndian }) {
98
+ const data = yield* then(reader.readExactly(4));
99
+ return getUint32(data, 0, littleEndian);
100
+ },
101
+ );
102
+
103
+ export const s32: NumberField<number> = number(
104
+ 4,
105
+ (value, { buffer, index, littleEndian }) => {
106
+ setInt32(buffer, index, value, littleEndian);
107
+ },
108
+ function* (then, reader, { littleEndian }) {
109
+ const data = yield* then(reader.readExactly(4));
110
+ return getInt32(data, 0, littleEndian);
111
+ },
112
+ );
113
+
114
+ export const u64: NumberField<bigint> = number(
115
+ 8,
116
+ (value, { buffer, index, littleEndian }) => {
117
+ setUint64(buffer, index, value, littleEndian);
118
+ },
119
+ function* (then, reader, { littleEndian }) {
120
+ const data = yield* then(reader.readExactly(8));
121
+ return getUint64(data, 0, littleEndian);
122
+ },
123
+ );
124
+
125
+ export const s64: NumberField<bigint> = number(
126
+ 8,
127
+ (value, { buffer, index, littleEndian }) => {
128
+ setInt64(buffer, index, value, littleEndian);
129
+ },
130
+ function* (then, reader, { littleEndian }) {
131
+ const data = yield* then(reader.readExactly(8));
132
+ return getInt64(data, 0, littleEndian);
133
+ },
134
+ );
@@ -1,11 +1,10 @@
1
- import type { ValueOrPromise } from "../utils.js";
2
-
3
1
  // TODO: allow over reading (returning a `Uint8Array`, an `offset` and a `length`) to avoid copying
4
2
 
3
+ import type { MaybePromiseLike } from "@yume-chan/async";
4
+
5
5
  export class ExactReadableEndedError extends Error {
6
6
  constructor() {
7
7
  super("ExactReadable ended");
8
- Object.setPrototypeOf(this, new.target.prototype);
9
8
  }
10
9
  }
11
10
 
@@ -21,6 +20,34 @@ export interface ExactReadable {
21
20
  readExactly(length: number): Uint8Array;
22
21
  }
23
22
 
23
+ export class Uint8ArrayExactReadable implements ExactReadable {
24
+ #data: Uint8Array;
25
+ #position: number;
26
+
27
+ get position() {
28
+ return this.#position;
29
+ }
30
+
31
+ constructor(data: Uint8Array) {
32
+ this.#data = data;
33
+ this.#position = 0;
34
+ }
35
+
36
+ readExactly(length: number): Uint8Array {
37
+ if (this.#position + length > this.#data.length) {
38
+ throw new ExactReadableEndedError();
39
+ }
40
+
41
+ const result = this.#data.subarray(
42
+ this.#position,
43
+ this.#position + length,
44
+ );
45
+
46
+ this.#position += length;
47
+ return result;
48
+ }
49
+ }
50
+
24
51
  export interface AsyncExactReadable {
25
52
  readonly position: number;
26
53
 
@@ -30,5 +57,5 @@ export interface AsyncExactReadable {
30
57
  * The stream must return exactly `length` bytes or data. If that's not possible
31
58
  * (due to end of file or other error condition), it must throw an {@link ExactReadableEndedError}.
32
59
  */
33
- readExactly(length: number): ValueOrPromise<Uint8Array>;
60
+ readExactly(length: number): MaybePromiseLike<Uint8Array>;
34
61
  }
package/src/string.ts ADDED
@@ -0,0 +1,41 @@
1
+ import type { BufferLengthConverter } from "./buffer.js";
2
+ import { buffer } from "./buffer.js";
3
+ import type { Field } from "./field/index.js";
4
+ import { decodeUtf8, encodeUtf8 } from "./utils.js";
5
+
6
+ export interface String {
7
+ (length: number): Field<string, never, never> & {
8
+ as: <T>(infer: T) => Field<T, never, never>;
9
+ };
10
+
11
+ <K extends string>(
12
+ lengthField: K,
13
+ ): Field<string, K, Record<K, number>> & {
14
+ as: <T>(infer: T) => Field<T, K, Record<K, number>>;
15
+ };
16
+
17
+ <const K extends string, KT>(
18
+ length: BufferLengthConverter<K, KT>,
19
+ ): Field<string, K, Record<K, KT>> & {
20
+ as: <T>(infer: T) => Field<T, K, Record<K, KT>>;
21
+ };
22
+
23
+ <KOmitInit extends string, KS>(
24
+ length: Field<number, KOmitInit, KS>,
25
+ ): Field<string, KOmitInit, KS>;
26
+ }
27
+
28
+ // Prettier will move the annotation and make it invalid
29
+ // prettier-ignore
30
+ export const string: String = (/* #__NO_SIDE_EFFECTS__ */ (
31
+ lengthOrField: string | number | BufferLengthConverter<string, unknown>,
32
+ ): Field<string, string, Record<string, unknown>> & {
33
+ as: <T>(infer: T) => Field<T, string, Record<string, unknown>>;
34
+ } => {
35
+ const field = buffer(lengthOrField as never, {
36
+ convert: decodeUtf8,
37
+ back: encodeUtf8,
38
+ });
39
+ (field as never as { as: unknown }).as = () => field;
40
+ return field as never;
41
+ }) as never;