@chr33s/pdf-restructure 5.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 (93) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +323 -0
  3. package/dist/array.d.ts +15 -0
  4. package/dist/array.js +95 -0
  5. package/dist/array.js.map +1 -0
  6. package/dist/base.d.ts +4 -0
  7. package/dist/base.js +16 -0
  8. package/dist/base.js.map +1 -0
  9. package/dist/bitfield.d.ts +11 -0
  10. package/dist/bitfield.js +37 -0
  11. package/dist/bitfield.js.map +1 -0
  12. package/dist/boolean.d.ts +10 -0
  13. package/dist/boolean.js +18 -0
  14. package/dist/boolean.js.map +1 -0
  15. package/dist/buffer.d.ts +11 -0
  16. package/dist/buffer.js +31 -0
  17. package/dist/buffer.js.map +1 -0
  18. package/dist/decode-stream.d.ts +26 -0
  19. package/dist/decode-stream.js +84 -0
  20. package/dist/decode-stream.js.map +1 -0
  21. package/dist/encode-stream.d.ts +19 -0
  22. package/dist/encode-stream.js +137 -0
  23. package/dist/encode-stream.js.map +1 -0
  24. package/dist/enum.d.ts +11 -0
  25. package/dist/enum.js +25 -0
  26. package/dist/enum.js.map +1 -0
  27. package/dist/index.d.ts +17 -0
  28. package/dist/index.js +18 -0
  29. package/dist/index.js.map +1 -0
  30. package/dist/lazy-array.d.ts +22 -0
  31. package/dist/lazy-array.js +75 -0
  32. package/dist/lazy-array.js.map +1 -0
  33. package/dist/number.d.ts +51 -0
  34. package/dist/number.js +76 -0
  35. package/dist/number.js.map +1 -0
  36. package/dist/optional.d.ts +14 -0
  37. package/dist/optional.js +34 -0
  38. package/dist/optional.js.map +1 -0
  39. package/dist/pointer.d.ts +28 -0
  40. package/dist/pointer.js +160 -0
  41. package/dist/pointer.js.map +1 -0
  42. package/dist/reserved.d.ts +12 -0
  43. package/dist/reserved.js +23 -0
  44. package/dist/reserved.js.map +1 -0
  45. package/dist/string.d.ts +14 -0
  46. package/dist/string.js +123 -0
  47. package/dist/string.js.map +1 -0
  48. package/dist/struct.d.ts +15 -0
  49. package/dist/struct.js +93 -0
  50. package/dist/struct.js.map +1 -0
  51. package/dist/utils.d.ts +13 -0
  52. package/dist/utils.js +45 -0
  53. package/dist/utils.js.map +1 -0
  54. package/dist/versioned-struct.d.ts +18 -0
  55. package/dist/versioned-struct.js +129 -0
  56. package/dist/versioned-struct.js.map +1 -0
  57. package/package.json +47 -0
  58. package/src/array.ts +113 -0
  59. package/src/base.ts +17 -0
  60. package/src/bitfield.ts +46 -0
  61. package/src/boolean.ts +24 -0
  62. package/src/buffer.ts +40 -0
  63. package/src/decode-stream.ts +97 -0
  64. package/src/encode-stream.ts +161 -0
  65. package/src/enum.ts +32 -0
  66. package/src/index.ts +17 -0
  67. package/src/lazy-array.ts +91 -0
  68. package/src/number.ts +88 -0
  69. package/src/optional.ts +46 -0
  70. package/src/pointer.ts +204 -0
  71. package/src/reserved.ts +29 -0
  72. package/src/string.ts +154 -0
  73. package/src/struct.ts +127 -0
  74. package/src/utils.ts +55 -0
  75. package/src/versioned-struct.ts +174 -0
  76. package/test/array.test.ts +95 -0
  77. package/test/bitfield.test.ts +52 -0
  78. package/test/boolean.test.ts +35 -0
  79. package/test/buffer.test.ts +49 -0
  80. package/test/decode-stream.test.ts +104 -0
  81. package/test/encode-stream.test.ts +111 -0
  82. package/test/enum.test.ts +30 -0
  83. package/test/lazy-array.test.ts +70 -0
  84. package/test/number.test.ts +222 -0
  85. package/test/optional.test.ts +105 -0
  86. package/test/pointer.test.ts +248 -0
  87. package/test/reserved.test.ts +28 -0
  88. package/test/string.test.ts +114 -0
  89. package/test/struct.test.ts +164 -0
  90. package/test/versioned-struct.test.ts +462 -0
  91. package/tsconfig.json +9 -0
  92. package/tsconfig.typecheck.json +14 -0
  93. package/vitest.config.ts +12 -0
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2018 Andrew Dillon
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,323 @@
1
+ # @chr33s/pdf-restructure
2
+
3
+ > Declarative binary encoding and decoding primitives packaged as modern ES modules.
4
+
5
+ `@chr33s/pdf-restructure` lives in the [`chr33s/pdf`](https://github.com/chr33s/pdf) monorepo and carries forward the
6
+ [`Hopding/restructure`](https://github.com/Hopding/restructure) fork of Devon Govett’s original project. This edition provides:
7
+
8
+ - native ES modules targeting NodeNext (Node.js 18+ or a modern bundler required),
9
+ - TypeScript sources with generated declaration files for first-class editor support, and
10
+ - updated test coverage powered by Vitest.
11
+
12
+ ## Installation
13
+
14
+ ```bash
15
+ npm install @chr33s/pdf-restructure
16
+ ```
17
+
18
+ Use Node.js 18+ or configure your bundler to resolve NodeNext-style ES modules.
19
+
20
+ ## Overview
21
+
22
+ Restructure allows you to declaratively encode and decode binary data.
23
+ It supports a wide variety of types to enable you to express a multitude
24
+ of binary formats without writing any parsing code.
25
+
26
+ Some of the supported features are C-like structures, versioned structures,
27
+ pointers, arrays of any type, strings of a large number of encodings, enums,
28
+ bitfields, and more. See the documentation below for more details.
29
+
30
+ ## Example
31
+
32
+ This is just a small example of what Restructure can do. Check out the API documentation
33
+ below for more information.
34
+
35
+ ```ts
36
+ import fs from "node:fs";
37
+ import {
38
+ DecodeStream,
39
+ EncodeStream,
40
+ Struct,
41
+ String,
42
+ uint8,
43
+ } from "@chr33s/pdf-restructure";
44
+
45
+ const Person = new Struct({
46
+ name: new String(uint8, "utf8"),
47
+ age: uint8,
48
+ });
49
+
50
+ // decode a person from a buffer
51
+ const decodeStream = new DecodeStream(buffer);
52
+ const person = Person.decode(decodeStream);
53
+
54
+ // encode a person back to a stream
55
+ const encodeStream = new EncodeStream();
56
+ encodeStream.pipe(fs.createWriteStream("out.bin"));
57
+
58
+ Person.encode(encodeStream, person);
59
+ encodeStream.end();
60
+ ```
61
+
62
+
63
+ ## API
64
+
65
+ All of the following types support three standard methods:
66
+
67
+ * `decode(stream)` - decodes an instance of the type from the given DecodeStream
68
+ * `size(value)` - returns the amount of space the value would take if encoded
69
+ * `encode(stream, value)` - encodes the given value into the given EncodeStream
70
+
71
+ Restructure supports a wide variety of types, but if you need to write your own for
72
+ some custom use that cannot be represented by them, you can do so by just implementing
73
+ the above methods. Then you can use your type just as you would any other type, in structures
74
+ and whatnot.
75
+
76
+ ### Number Types
77
+
78
+ The following built-in number types are available:
79
+
80
+ ```javascript
81
+ uint8, uint16, uint24, uint32, int8, int16, int24, int32, float, double, fixed16, fixed32
82
+ ```
83
+
84
+ Numbers are big-endian (network order) by default, but little-endian is supported, too:
85
+
86
+ ```javascript
87
+ uint16le, uint24le, uint32le, int16le, int24le, int32le, floatle, doublele, fixed16le, fixed32le
88
+ ```
89
+
90
+ To avoid ambiguity, big-endian may be used explicitly:
91
+
92
+ ```javascript
93
+ uint16be, uint24be, uint32be, int16be, int24be, int32be, floatbe, doublebe, fixed16be, fixed32be
94
+ ```
95
+
96
+ ### Boolean
97
+
98
+ Booleans are encoded as `0` or `1` using one of the above number types.
99
+
100
+ ```javascript
101
+ let bool = new r.Boolean(r.uint32);
102
+ ```
103
+
104
+ ### Reserved
105
+
106
+ The `Reserved` type simply skips data in a structure, where there are reserved fields.
107
+ Encoding produces zeros.
108
+
109
+ ```javascript
110
+ // 10 reserved uint8s (default is 1)
111
+ let reserved = new r.Reserved(r.uint8, 10);
112
+ ```
113
+
114
+ ### Optional
115
+
116
+ The `Optional` type only encodes or decodes when given condition is truthy.
117
+
118
+ ```javascript
119
+ // includes field
120
+ let optional = new r.Optional(r.uint8, true);
121
+
122
+ // excludes field
123
+ let optional = new r.Optional(r.uint8, false);
124
+
125
+ // determine whether field is to be included at runtime with a function
126
+ let optional = new r.Optional(r.uint8, function() {
127
+ return this.flags & 0x50;
128
+ });
129
+ ```
130
+
131
+ ### Enum
132
+
133
+ The `Enum` type maps a number to the value at that index in an array.
134
+
135
+ ```javascript
136
+ let color = new r.Enum(r.uint8, ['red', 'orange', 'yellow', 'green', 'blue', 'purple']);
137
+ ```
138
+
139
+ ### Bitfield
140
+
141
+ The `Bitfield` type maps a number to an object with boolean keys mapping to each bit in that number,
142
+ as defined in an array.
143
+
144
+ ```javascript
145
+ let bitfield = new r.Bitfield(r.uint8, ['Jack', 'Kack', 'Lack', 'Mack', 'Nack', 'Oack', 'Pack', 'Quack']);
146
+ bitfield.decode(stream);
147
+
148
+ let result = {
149
+ Jack: true,
150
+ Kack: false,
151
+ Lack: false,
152
+ Mack: true,
153
+ Nack: true,
154
+ Oack: false,
155
+ Pack: true,
156
+ Quack: true
157
+ };
158
+
159
+ bitfield.encode(stream, result);
160
+ ```
161
+
162
+ ### Buffer
163
+
164
+ Extracts a slice of the buffer to a Node `Buffer`. The length can be a constant, or taken from
165
+ a previous field in the parent structure.
166
+
167
+ ```javascript
168
+ // fixed length
169
+ let buf = new r.Buffer(2);
170
+
171
+ // length from parent structure
172
+ let struct = new r.Struct({
173
+ bufLen: r.uint8,
174
+ buf: new r.Buffer('bufLen')
175
+ });
176
+ ```
177
+
178
+ ### String
179
+
180
+ A `String` maps a JavaScript string to and from binary encodings. The length can be a constant, taken
181
+ from a previous field in the parent structure, or encoded using a number type immediately before the string.
182
+
183
+ Supported encodings include `'ascii'`, `'utf8'`, `'ucs2'`, `'utf16le'`, `'utf16be'`, and if you also install
184
+ [iconv-lite](https://github.com/ashtuchkin/iconv-lite), many other legacy codecs.
185
+
186
+ ```javascript
187
+ // fixed length, ascii encoding by default
188
+ let str = new r.String(2);
189
+
190
+ // length encoded as number before the string, utf8 encoding
191
+ let str = new r.String(r.uint8, 'utf8');
192
+
193
+ // length from parent structure
194
+ let struct = new r.Struct({
195
+ len: r.uint8,
196
+ str: new r.String('len', 'utf16be')
197
+ });
198
+
199
+ // null-terminated string (also known as C string)
200
+ let str = new r.String(null, 'utf8')
201
+ ```
202
+
203
+ ### Array
204
+
205
+ An `Array` maps to and from a JavaScript array containing instances of a sub-type. The length can be a constant,
206
+ taken from a previous field in the parent structure, encoded using a number type immediately
207
+ before the string, or computed by a function.
208
+
209
+ ```javascript
210
+ // fixed length, containing numbers
211
+ let arr = new r.Array(r.uint16, 2);
212
+
213
+ // length encoded as number before the array containing strings
214
+ let arr = new r.Array(new r.String(10), r.uint8);
215
+
216
+ // length computed by a function
217
+ let arr = new r.Array(r.uint8, function() { return 5 });
218
+
219
+ // length from parent structure
220
+ let struct = new r.Struct({
221
+ len: r.uint8,
222
+ arr: new r.Array(r.uint8, 'len')
223
+ });
224
+
225
+ // treat as amount of bytes instead (may be used in all the above scenarios)
226
+ let arr = new r.Array(r.uint16, 6, 'bytes');
227
+ ```
228
+
229
+ ### LazyArray
230
+
231
+ The `LazyArray` type extends from the `Array` type, and is useful for large arrays that you do not need to access sequentially.
232
+ It avoids decoding the entire array upfront, and instead only decodes and caches individual items as needed. It only works when
233
+ the elements inside the array have a fixed size.
234
+
235
+ Instead of returning a JavaScript array, the `LazyArray` type returns a custom object that can be used to access the elements.
236
+
237
+ ```javascript
238
+ let arr = new r.LazyArray(r.uint16, 2048);
239
+ let res = arr.decode(stream);
240
+
241
+ // get a single element
242
+ let el = res.get(2);
243
+
244
+ // convert to a normal array (decode all elements)
245
+ let array = res.toArray();
246
+ ```
247
+
248
+ ### Struct
249
+
250
+ A `Struct` maps to and from JavaScript objects, containing keys of various previously discussed types. Sub structures,
251
+ arrays of structures, and pointers to other types (discussed below) are supported.
252
+
253
+ ```javascript
254
+ let Person = new r.Struct({
255
+ name: new r.String(r.uint8, 'utf8'),
256
+ age: r.uint8
257
+ });
258
+ ```
259
+
260
+ ### VersionedStruct
261
+
262
+ A `VersionedStruct` is a `Struct` that has multiple versions. The version is typically encoded at
263
+ the beginning of the structure, or as a field in a parent structure. There is an optional `header`
264
+ common to all versions, and separate fields listed for each version number.
265
+
266
+ ```javascript
267
+ // the version is read as a uint8 in this example
268
+ // you could also get the version from a key on the parent struct
269
+ let Person = new r.VersionedStruct(r.uint8, {
270
+ // optional header common to all versions
271
+ header: {
272
+ name: new r.String(r.uint8, 'utf8')
273
+ },
274
+ 0: {
275
+ age: r.uint8
276
+ },
277
+ 1: {
278
+ hairColor: r.Enum(r.uint8, ['black', 'brown', 'blonde'])
279
+ }
280
+ });
281
+ ```
282
+
283
+ ### Pointer
284
+
285
+ Pointers map an address or offset encoded as a number, to a value encoded elsewhere in the buffer.
286
+ There are a few options you can use: `type`, `relativeTo`, `allowNull`, and `nullValue`.
287
+ The `type` option has these possible values:
288
+
289
+ * `local` (default) - the encoded offset is relative to the start of the containing structure
290
+ * `immediate` - the encoded offset is relative to the position of the pointer itself
291
+ * `parent` - the encoded offset is relative to the parent structure of the immediate container
292
+ * `global` - the encoded offset is global to the start of the file
293
+
294
+ The `relativeTo` option specifies that the encoded offset is relative to a field on the containing structure.
295
+ By default, pointers are relative to the start of the containing structure (`local`).
296
+
297
+ The `allowNull` option lets you specify whether zero offsets are allowed or should produce `null`. This is
298
+ set to `true` by default. The `nullValue` option is related, and lets you override the encoded value that
299
+ represents `null`. By default, the `nullValue` is zero.
300
+
301
+ The `lazy` option allows lazy decoding of the pointer's value by defining a getter on the parent object.
302
+ This only works when the pointer is contained within a Struct, but can be used to speed up decoding
303
+ quite a bit when not all of the data is needed right away.
304
+
305
+ ```javascript
306
+ let Address = new r.Struct({
307
+ street: new r.String(r.uint8),
308
+ zip: new r.String(5)
309
+ });
310
+
311
+ let Person = new r.Struct({
312
+ name: new r.String(r.uint8, 'utf8'),
313
+ age: r.uint8,
314
+ ptrStart: r.uint8,
315
+ address: new r.Pointer(r.uint8, Address)
316
+ });
317
+ ```
318
+
319
+ If the type of a pointer is set to 'void', it is not decoded and the computed address in the buffer
320
+ is simply returned. To encode a void pointer, create a `new r.VoidPointer(type, value)`.
321
+
322
+ ## License
323
+ [MIT](https://choosealicense.com/licenses/mit/)
@@ -0,0 +1,15 @@
1
+ import Base from "./base.js";
2
+ import type DecodeStream from "./decode-stream.js";
3
+ import type EncodeStream from "./encode-stream.js";
4
+ import { type LengthLike } from "./utils.js";
5
+ type LengthType = "count" | "bytes";
6
+ export default class ArrayT<T = unknown, TResult = T[]> extends Base<TResult> {
7
+ type: any;
8
+ length?: LengthLike;
9
+ lengthType: LengthType;
10
+ constructor(type: any, length?: LengthLike, lengthType?: LengthType);
11
+ decode(stream: DecodeStream, parent?: any): TResult;
12
+ size(array?: T[], ctx?: any, includePointers?: boolean): number;
13
+ encode(stream: EncodeStream, array: T[], parent?: any): void;
14
+ }
15
+ export {};
package/dist/array.js ADDED
@@ -0,0 +1,95 @@
1
+ import Base from "./base.js";
2
+ import { Number as NumberT } from "./number.js";
3
+ import { resolveLength } from "./utils.js";
4
+ export default class ArrayT extends Base {
5
+ type;
6
+ length;
7
+ lengthType;
8
+ constructor(type, length, lengthType = "count") {
9
+ super();
10
+ this.type = type;
11
+ this.length = length;
12
+ this.lengthType = lengthType;
13
+ }
14
+ decode(stream, parent) {
15
+ const pos = stream.pos;
16
+ const result = [];
17
+ let ctx = parent;
18
+ let length;
19
+ if (typeof this.length !== "undefined") {
20
+ length = resolveLength(this.length, stream, parent);
21
+ }
22
+ if (this.length instanceof NumberT) {
23
+ Object.defineProperties(result, {
24
+ parent: { value: parent },
25
+ _startOffset: { value: pos },
26
+ _currentOffset: { value: 0, writable: true },
27
+ _length: { value: length },
28
+ });
29
+ ctx = result;
30
+ }
31
+ if (typeof length === "undefined" || this.lengthType === "bytes") {
32
+ let target;
33
+ if (typeof length === "number") {
34
+ target = stream.pos + length;
35
+ }
36
+ else if (parent?._length) {
37
+ target = parent._startOffset + parent._length;
38
+ }
39
+ else {
40
+ target = stream.length;
41
+ }
42
+ while (stream.pos < target) {
43
+ result.push(this.type.decode(stream, ctx));
44
+ }
45
+ }
46
+ else {
47
+ for (let i = 0; i < length; i += 1) {
48
+ result.push(this.type.decode(stream, ctx));
49
+ }
50
+ }
51
+ return result;
52
+ }
53
+ size(array, ctx, includePointers = true) {
54
+ if (!array) {
55
+ return this.type.size(null, ctx) * resolveLength(this.length, undefined, ctx);
56
+ }
57
+ let total = 0;
58
+ let context = ctx;
59
+ if (this.length instanceof NumberT) {
60
+ total += this.length.size();
61
+ context = { parent: ctx, pointerSize: 0 };
62
+ }
63
+ for (const item of array) {
64
+ total += this.type.size(item, context);
65
+ }
66
+ if (includePointers && this.length instanceof NumberT && context) {
67
+ total += context.pointerSize ?? 0;
68
+ }
69
+ return total;
70
+ }
71
+ encode(stream, array, parent) {
72
+ let ctx = parent;
73
+ if (this.length instanceof NumberT) {
74
+ ctx = {
75
+ pointers: [],
76
+ startOffset: stream.pos,
77
+ parent,
78
+ pointerSize: 0,
79
+ };
80
+ ctx.pointerOffset = stream.pos + this.size(array, ctx, false);
81
+ this.length.encode(stream, array.length);
82
+ }
83
+ for (const item of array) {
84
+ this.type.encode(stream, item, ctx);
85
+ }
86
+ if (this.length instanceof NumberT) {
87
+ let i = 0;
88
+ while (i < ctx.pointers.length) {
89
+ const ptr = ctx.pointers[i++];
90
+ ptr.type.encode(stream, ptr.val, ptr.parent);
91
+ }
92
+ }
93
+ }
94
+ }
95
+ //# sourceMappingURL=array.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"array.js","sourceRoot":"","sources":["../src/array.ts"],"names":[],"mappings":"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"}
package/dist/base.d.ts ADDED
@@ -0,0 +1,4 @@
1
+ export default abstract class Base<T = unknown> {
2
+ fromBuffer(buffer: Uint8Array): T;
3
+ toBuffer(value: T): Uint8Array;
4
+ }
package/dist/base.js ADDED
@@ -0,0 +1,16 @@
1
+ import DecodeStream from "./decode-stream.js";
2
+ import EncodeStream from "./encode-stream.js";
3
+ export default class Base {
4
+ fromBuffer(buffer) {
5
+ const stream = new DecodeStream(buffer);
6
+ return this.decode(stream);
7
+ }
8
+ toBuffer(value) {
9
+ const size = typeof this.size === "function" ? this.size(value) : 0;
10
+ const buffer = new Uint8Array(size);
11
+ const stream = new EncodeStream(buffer);
12
+ this.encode(stream, value);
13
+ return buffer;
14
+ }
15
+ }
16
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAC9C,OAAO,YAAY,MAAM,oBAAoB,CAAC;AAE9C,MAAM,CAAC,OAAO,OAAgB,IAAI;IAChC,UAAU,CAAC,MAAkB;QAC3B,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;QACxC,OAAQ,IAAY,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACtC,CAAC;IAED,QAAQ,CAAC,KAAQ;QACf,MAAM,IAAI,GAAG,OAAQ,IAAY,CAAC,IAAI,KAAK,UAAU,CAAC,CAAC,CAAE,IAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACtF,MAAM,MAAM,GAAG,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,MAAM,CAAC,CAAC;QACvC,IAAY,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QACpC,OAAO,MAAM,CAAC;IAChB,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ import Base from "./base.js";
2
+ import type DecodeStream from "./decode-stream.js";
3
+ import type EncodeStream from "./encode-stream.js";
4
+ export default class Bitfield extends Base<Record<string, boolean>> {
5
+ type: any;
6
+ flags: Array<string | null | undefined>;
7
+ constructor(type: any, flags?: Array<string | null | undefined>);
8
+ decode(stream: DecodeStream): Record<string, boolean>;
9
+ size(): number;
10
+ encode(stream: EncodeStream, keys: Record<string, boolean>): void;
11
+ }
@@ -0,0 +1,37 @@
1
+ import Base from "./base.js";
2
+ export default class Bitfield extends Base {
3
+ type;
4
+ flags;
5
+ constructor(type, flags = []) {
6
+ super();
7
+ this.type = type;
8
+ this.flags = flags;
9
+ }
10
+ decode(stream) {
11
+ const value = this.type.decode(stream);
12
+ const result = {};
13
+ this.flags.forEach((flag, index) => {
14
+ if (!flag) {
15
+ return;
16
+ }
17
+ result[flag] = Boolean(value & (1 << index));
18
+ });
19
+ return result;
20
+ }
21
+ size() {
22
+ return this.type.size();
23
+ }
24
+ encode(stream, keys) {
25
+ let value = 0;
26
+ this.flags.forEach((flag, index) => {
27
+ if (!flag) {
28
+ return;
29
+ }
30
+ if (keys[flag]) {
31
+ value |= 1 << index;
32
+ }
33
+ });
34
+ this.type.encode(stream, value);
35
+ }
36
+ }
37
+ //# sourceMappingURL=bitfield.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bitfield.js","sourceRoot":"","sources":["../src/bitfield.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,IAA6B;IAC1D,IAAI,CAAM;IACV,KAAK,CAAmC;IAE/C,YAAY,IAAS,EAAE,QAA0C,EAAE;QACjE,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;IAED,MAAM,CAAC,MAAoB;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,MAAM,GAA4B,EAAE,CAAC;QAE3C,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACjC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO;YACT,CAAC;YACD,MAAM,CAAC,IAAI,CAAC,GAAG,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC;QAC/C,CAAC,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,IAAI;QACF,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;IAC1B,CAAC;IAED,MAAM,CAAC,MAAoB,EAAE,IAA6B;QACxD,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;YACjC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,OAAO;YACT,CAAC;YACD,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACf,KAAK,IAAI,CAAC,IAAI,KAAK,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;IAClC,CAAC;CACF"}
@@ -0,0 +1,10 @@
1
+ import Base from "./base.js";
2
+ import type DecodeStream from "./decode-stream.js";
3
+ import type EncodeStream from "./encode-stream.js";
4
+ export default class BooleanT extends Base<boolean> {
5
+ type: any;
6
+ constructor(type: any);
7
+ decode(stream: DecodeStream, parent?: any): boolean;
8
+ size(value?: any, parent?: any): number;
9
+ encode(stream: EncodeStream, value: boolean, parent?: any): void;
10
+ }
@@ -0,0 +1,18 @@
1
+ import Base from "./base.js";
2
+ export default class BooleanT extends Base {
3
+ type;
4
+ constructor(type) {
5
+ super();
6
+ this.type = type;
7
+ }
8
+ decode(stream, parent) {
9
+ return Boolean(this.type.decode(stream, parent));
10
+ }
11
+ size(value, parent) {
12
+ return this.type.size(value, parent);
13
+ }
14
+ encode(stream, value, parent) {
15
+ this.type.encode(stream, Number(value), parent);
16
+ }
17
+ }
18
+ //# sourceMappingURL=boolean.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boolean.js","sourceRoot":"","sources":["../src/boolean.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAI7B,MAAM,CAAC,OAAO,OAAO,QAAS,SAAQ,IAAa;IAC1C,IAAI,CAAM;IAEjB,YAAY,IAAS;QACnB,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,MAAM,CAAC,MAAoB,EAAE,MAAY;QACvC,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACnD,CAAC;IAED,IAAI,CAAC,KAAW,EAAE,MAAY;QAC5B,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;IACvC,CAAC;IAED,MAAM,CAAC,MAAoB,EAAE,KAAc,EAAE,MAAY;QACvD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,CAAC;IAClD,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ import Base from "./base.js";
2
+ import type DecodeStream from "./decode-stream.js";
3
+ import type EncodeStream from "./encode-stream.js";
4
+ import { type LengthLike } from "./utils.js";
5
+ export default class BufferT extends Base<Uint8Array> {
6
+ length: LengthLike;
7
+ constructor(length: LengthLike);
8
+ decode(stream: DecodeStream, parent?: any): Uint8Array;
9
+ size(value?: Uint8Array, parent?: any): number;
10
+ encode(stream: EncodeStream, value: Uint8Array, _parent?: any): void;
11
+ }
package/dist/buffer.js ADDED
@@ -0,0 +1,31 @@
1
+ import Base from "./base.js";
2
+ import { Number as NumberT } from "./number.js";
3
+ import { resolveLength } from "./utils.js";
4
+ export default class BufferT extends Base {
5
+ length;
6
+ constructor(length) {
7
+ super();
8
+ this.length = length;
9
+ }
10
+ decode(stream, parent) {
11
+ const length = resolveLength(this.length, stream, parent);
12
+ return stream.readBuffer(length);
13
+ }
14
+ size(value, parent) {
15
+ if (value == null) {
16
+ return resolveLength(this.length, undefined, parent);
17
+ }
18
+ let length = value.length;
19
+ if (this.length instanceof NumberT) {
20
+ length += this.length.size();
21
+ }
22
+ return length;
23
+ }
24
+ encode(stream, value, _parent) {
25
+ if (this.length instanceof NumberT) {
26
+ this.length.encode(stream, value.length);
27
+ }
28
+ stream.writeBuffer(value);
29
+ }
30
+ }
31
+ //# sourceMappingURL=buffer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"buffer.js","sourceRoot":"","sources":["../src/buffer.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,EAAE,MAAM,IAAI,OAAO,EAAE,MAAM,aAAa,CAAC;AAChD,OAAO,EAAE,aAAa,EAAmB,MAAM,YAAY,CAAC;AAE5D,MAAM,CAAC,OAAO,OAAO,OAAQ,SAAQ,IAAgB;IAC5C,MAAM,CAAa;IAE1B,YAAY,MAAkB;QAC5B,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,MAAM,CAAC,MAAoB,EAAE,MAAY;QACvC,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1D,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,CAAC,KAAkB,EAAE,MAAY;QACnC,IAAI,KAAK,IAAI,IAAI,EAAE,CAAC;YAClB,OAAO,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC1B,IAAI,IAAI,CAAC,MAAM,YAAY,OAAO,EAAE,CAAC;YACnC,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC/B,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,MAAM,CAAC,MAAoB,EAAE,KAAiB,EAAE,OAAa;QAC3D,IAAI,IAAI,CAAC,MAAM,YAAY,OAAO,EAAE,CAAC;YACnC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;QAC3C,CAAC;QAED,MAAM,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC5B,CAAC;CACF"}
@@ -0,0 +1,26 @@
1
+ export default class DecodeStream {
2
+ static readonly TYPES: {
3
+ readonly UInt8: 1;
4
+ readonly UInt16: 2;
5
+ readonly UInt24: 3;
6
+ readonly UInt32: 4;
7
+ readonly Int8: 1;
8
+ readonly Int16: 2;
9
+ readonly Int24: 3;
10
+ readonly Int32: 4;
11
+ readonly Float: 4;
12
+ readonly Double: 8;
13
+ };
14
+ pos: number;
15
+ length: number;
16
+ buffer: Uint8Array;
17
+ view: DataView;
18
+ [key: string]: any;
19
+ constructor(buffer: Uint8Array | Buffer);
20
+ readString(length: number, encoding?: string): string | Uint8Array;
21
+ readBuffer(length: number): Uint8Array;
22
+ readUInt24BE(): number;
23
+ readUInt24LE(): number;
24
+ readInt24BE(): number;
25
+ readInt24LE(): number;
26
+ }