@k67/kaitai-struct-ts 0.6.0 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -37
- package/dist/cli.js +2776 -0
- package/dist/index.d.mts +197 -229
- package/dist/index.d.ts +197 -229
- package/dist/index.js +5 -110
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +5 -110
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -1
package/dist/index.d.ts
CHANGED
@@ -1,3 +1,199 @@
|
|
1
|
+
/**
|
2
|
+
* @fileoverview Binary stream reader for Kaitai Struct
|
3
|
+
* @module stream/KaitaiStream
|
4
|
+
* @author Fabiano Pinto
|
5
|
+
* @license MIT
|
6
|
+
*/
|
7
|
+
/**
|
8
|
+
* KaitaiStream provides methods for reading binary data with proper type handling
|
9
|
+
* and endianness support. It's the core class for parsing binary formats.
|
10
|
+
*
|
11
|
+
* Supports reading:
|
12
|
+
* - Unsigned integers (u1, u2, u4, u8) in both little and big endian
|
13
|
+
* - Signed integers (s1, s2, s4, s8) in both little and big endian
|
14
|
+
* - Floating point numbers (f4, f8) in both little and big endian
|
15
|
+
* - Byte arrays (fixed length, until terminator, or all remaining)
|
16
|
+
* - Strings with various encodings
|
17
|
+
* - Bit-level data
|
18
|
+
*
|
19
|
+
* @class KaitaiStream
|
20
|
+
* @example
|
21
|
+
* ```typescript
|
22
|
+
* const buffer = new Uint8Array([0x01, 0x02, 0x03, 0x04])
|
23
|
+
* const stream = new KaitaiStream(buffer)
|
24
|
+
*
|
25
|
+
* const byte = stream.readU1() // Read 1 byte
|
26
|
+
* const word = stream.readU2le() // Read 2 bytes little-endian
|
27
|
+
* const str = stream.readStr(5, 'UTF-8') // Read 5-byte string
|
28
|
+
* ```
|
29
|
+
*/
|
30
|
+
declare class KaitaiStream {
|
31
|
+
private buffer;
|
32
|
+
private view;
|
33
|
+
private _pos;
|
34
|
+
private _bits;
|
35
|
+
private _bitsLeft;
|
36
|
+
/**
|
37
|
+
* Create a new KaitaiStream from a buffer
|
38
|
+
* @param buffer - ArrayBuffer or Uint8Array containing the binary data
|
39
|
+
*/
|
40
|
+
constructor(buffer: ArrayBuffer | Uint8Array);
|
41
|
+
/**
|
42
|
+
* Current position in the stream
|
43
|
+
*/
|
44
|
+
get pos(): number;
|
45
|
+
set pos(value: number);
|
46
|
+
/**
|
47
|
+
* Total size of the stream in bytes
|
48
|
+
*/
|
49
|
+
get size(): number;
|
50
|
+
/**
|
51
|
+
* Check if we've reached the end of the stream
|
52
|
+
*/
|
53
|
+
isEof(): boolean;
|
54
|
+
/**
|
55
|
+
* Seek to a specific position in the stream
|
56
|
+
* @param pos - Position to seek to
|
57
|
+
*/
|
58
|
+
seek(pos: number): void;
|
59
|
+
/**
|
60
|
+
* Ensure we have enough bytes available
|
61
|
+
* @param count - Number of bytes needed
|
62
|
+
*/
|
63
|
+
private ensureBytes;
|
64
|
+
/**
|
65
|
+
* Read 1-byte unsigned integer (0 to 255)
|
66
|
+
*/
|
67
|
+
readU1(): number;
|
68
|
+
/**
|
69
|
+
* Read 2-byte unsigned integer, little-endian
|
70
|
+
*/
|
71
|
+
readU2le(): number;
|
72
|
+
/**
|
73
|
+
* Read 2-byte unsigned integer, big-endian
|
74
|
+
*/
|
75
|
+
readU2be(): number;
|
76
|
+
/**
|
77
|
+
* Read 4-byte unsigned integer, little-endian
|
78
|
+
*/
|
79
|
+
readU4le(): number;
|
80
|
+
/**
|
81
|
+
* Read 4-byte unsigned integer, big-endian
|
82
|
+
*/
|
83
|
+
readU4be(): number;
|
84
|
+
/**
|
85
|
+
* Read 8-byte unsigned integer, little-endian
|
86
|
+
* Returns BigInt for values > Number.MAX_SAFE_INTEGER
|
87
|
+
*/
|
88
|
+
readU8le(): bigint;
|
89
|
+
/**
|
90
|
+
* Read 8-byte unsigned integer, big-endian
|
91
|
+
* Returns BigInt for values > Number.MAX_SAFE_INTEGER
|
92
|
+
*/
|
93
|
+
readU8be(): bigint;
|
94
|
+
/**
|
95
|
+
* Read 1-byte signed integer (-128 to 127)
|
96
|
+
*/
|
97
|
+
readS1(): number;
|
98
|
+
/**
|
99
|
+
* Read 2-byte signed integer, little-endian
|
100
|
+
*/
|
101
|
+
readS2le(): number;
|
102
|
+
/**
|
103
|
+
* Read 2-byte signed integer, big-endian
|
104
|
+
*/
|
105
|
+
readS2be(): number;
|
106
|
+
/**
|
107
|
+
* Read 4-byte signed integer, little-endian
|
108
|
+
*/
|
109
|
+
readS4le(): number;
|
110
|
+
/**
|
111
|
+
* Read 4-byte signed integer, big-endian
|
112
|
+
*/
|
113
|
+
readS4be(): number;
|
114
|
+
/**
|
115
|
+
* Read 8-byte signed integer, little-endian
|
116
|
+
* Returns BigInt for values outside Number.MAX_SAFE_INTEGER range
|
117
|
+
*/
|
118
|
+
readS8le(): bigint;
|
119
|
+
/**
|
120
|
+
* Read 8-byte signed integer, big-endian
|
121
|
+
* Returns BigInt for values outside Number.MAX_SAFE_INTEGER range
|
122
|
+
*/
|
123
|
+
readS8be(): bigint;
|
124
|
+
/**
|
125
|
+
* Read 4-byte IEEE 754 single-precision float, little-endian
|
126
|
+
*/
|
127
|
+
readF4le(): number;
|
128
|
+
/**
|
129
|
+
* Read 4-byte IEEE 754 single-precision float, big-endian
|
130
|
+
*/
|
131
|
+
readF4be(): number;
|
132
|
+
/**
|
133
|
+
* Read 8-byte IEEE 754 double-precision float, little-endian
|
134
|
+
*/
|
135
|
+
readF8le(): number;
|
136
|
+
/**
|
137
|
+
* Read 8-byte IEEE 754 double-precision float, big-endian
|
138
|
+
*/
|
139
|
+
readF8be(): number;
|
140
|
+
/**
|
141
|
+
* Read a fixed number of bytes
|
142
|
+
* @param length - Number of bytes to read
|
143
|
+
*/
|
144
|
+
readBytes(length: number): Uint8Array;
|
145
|
+
/**
|
146
|
+
* Read all remaining bytes until end of stream
|
147
|
+
*/
|
148
|
+
readBytesFull(): Uint8Array;
|
149
|
+
/**
|
150
|
+
* Read bytes until a terminator byte is found
|
151
|
+
* @param term - Terminator byte value
|
152
|
+
* @param include - Include terminator in result
|
153
|
+
* @param consume - Consume terminator from stream
|
154
|
+
* @param eosError - Throw error if EOS reached before terminator
|
155
|
+
*/
|
156
|
+
readBytesterm(term: number, include?: boolean, consume?: boolean, eosError?: boolean): Uint8Array;
|
157
|
+
/**
|
158
|
+
* Read a fixed-length string
|
159
|
+
* @param length - Number of bytes to read
|
160
|
+
* @param encoding - Character encoding (default: UTF-8)
|
161
|
+
*/
|
162
|
+
readStr(length: number, encoding?: string): string;
|
163
|
+
/**
|
164
|
+
* Read a null-terminated string
|
165
|
+
* @param encoding - Character encoding (default: UTF-8)
|
166
|
+
* @param term - Terminator byte (default: 0)
|
167
|
+
* @param include - Include terminator in result
|
168
|
+
* @param consume - Consume terminator from stream
|
169
|
+
* @param eosError - Throw error if EOS reached before terminator
|
170
|
+
*/
|
171
|
+
readStrz(encoding?: string, term?: number, include?: boolean, consume?: boolean, eosError?: boolean): string;
|
172
|
+
/**
|
173
|
+
* Align bit reading to byte boundary
|
174
|
+
*/
|
175
|
+
alignToByte(): void;
|
176
|
+
/**
|
177
|
+
* Read specified number of bits as unsigned integer (big-endian)
|
178
|
+
* @param n - Number of bits to read (1-64)
|
179
|
+
*/
|
180
|
+
readBitsIntBe(n: number): bigint;
|
181
|
+
/**
|
182
|
+
* Read specified number of bits as unsigned integer (little-endian)
|
183
|
+
* @param n - Number of bits to read (1-64)
|
184
|
+
*/
|
185
|
+
readBitsIntLe(n: number): bigint;
|
186
|
+
/**
|
187
|
+
* Get the underlying buffer
|
188
|
+
*/
|
189
|
+
getBuffer(): Uint8Array;
|
190
|
+
/**
|
191
|
+
* Create a substream from current position with specified size
|
192
|
+
* @param size - Size of the substream in bytes
|
193
|
+
*/
|
194
|
+
substream(size: number): KaitaiStream;
|
195
|
+
}
|
196
|
+
|
1
197
|
/**
|
2
198
|
* @fileoverview Type definitions for Kaitai Struct YAML schema (.ksy files)
|
3
199
|
* @module parser/schema
|
@@ -309,203 +505,6 @@ declare function isFloatType(type: string): boolean;
|
|
309
505
|
*/
|
310
506
|
declare function isStringType(type: string): boolean;
|
311
507
|
|
312
|
-
/**
|
313
|
-
* @fileoverview Binary stream reader for Kaitai Struct
|
314
|
-
* @module stream/KaitaiStream
|
315
|
-
* @author Fabiano Pinto
|
316
|
-
* @license MIT
|
317
|
-
*/
|
318
|
-
/**
|
319
|
-
* KaitaiStream provides methods for reading binary data with proper type handling
|
320
|
-
* and endianness support. It's the core class for parsing binary formats.
|
321
|
-
*
|
322
|
-
* Supports reading:
|
323
|
-
* - Unsigned integers (u1, u2, u4, u8) in both little and big endian
|
324
|
-
* - Signed integers (s1, s2, s4, s8) in both little and big endian
|
325
|
-
* - Floating point numbers (f4, f8) in both little and big endian
|
326
|
-
* - Byte arrays (fixed length, until terminator, or all remaining)
|
327
|
-
* - Strings with various encodings
|
328
|
-
* - Bit-level data
|
329
|
-
*
|
330
|
-
* @class KaitaiStream
|
331
|
-
* @example
|
332
|
-
* ```typescript
|
333
|
-
* const buffer = new Uint8Array([0x01, 0x02, 0x03, 0x04])
|
334
|
-
* const stream = new KaitaiStream(buffer)
|
335
|
-
*
|
336
|
-
* const byte = stream.readU1() // Read 1 byte
|
337
|
-
* const word = stream.readU2le() // Read 2 bytes little-endian
|
338
|
-
* const str = stream.readStr(5, 'UTF-8') // Read 5-byte string
|
339
|
-
* ```
|
340
|
-
*/
|
341
|
-
declare class KaitaiStream {
|
342
|
-
private buffer;
|
343
|
-
private view;
|
344
|
-
private _pos;
|
345
|
-
private _bits;
|
346
|
-
private _bitsLeft;
|
347
|
-
private _size;
|
348
|
-
/**
|
349
|
-
* Create a new KaitaiStream from a buffer
|
350
|
-
* @param buffer - ArrayBuffer or Uint8Array containing the binary data
|
351
|
-
*/
|
352
|
-
constructor(buffer: ArrayBuffer | Uint8Array);
|
353
|
-
/**
|
354
|
-
* Current position in the stream
|
355
|
-
*/
|
356
|
-
get pos(): number;
|
357
|
-
set pos(value: number);
|
358
|
-
/**
|
359
|
-
* Total size of the stream in bytes
|
360
|
-
*/
|
361
|
-
get size(): number;
|
362
|
-
/**
|
363
|
-
* Check if we've reached the end of the stream
|
364
|
-
*/
|
365
|
-
isEof(): boolean;
|
366
|
-
/**
|
367
|
-
* Seek to a specific position in the stream
|
368
|
-
* @param pos - Position to seek to
|
369
|
-
*/
|
370
|
-
seek(pos: number): void;
|
371
|
-
/**
|
372
|
-
* Ensure we have enough bytes available
|
373
|
-
* @param count - Number of bytes needed
|
374
|
-
*/
|
375
|
-
private ensureBytes;
|
376
|
-
/**
|
377
|
-
* Read 1-byte unsigned integer (0 to 255)
|
378
|
-
*/
|
379
|
-
readU1(): number;
|
380
|
-
/**
|
381
|
-
* Read 2-byte unsigned integer, little-endian
|
382
|
-
*/
|
383
|
-
readU2le(): number;
|
384
|
-
/**
|
385
|
-
* Read 2-byte unsigned integer, big-endian
|
386
|
-
*/
|
387
|
-
readU2be(): number;
|
388
|
-
/**
|
389
|
-
* Read 4-byte unsigned integer, little-endian
|
390
|
-
*/
|
391
|
-
readU4le(): number;
|
392
|
-
/**
|
393
|
-
* Read 4-byte unsigned integer, big-endian
|
394
|
-
*/
|
395
|
-
readU4be(): number;
|
396
|
-
/**
|
397
|
-
* Read 8-byte unsigned integer, little-endian
|
398
|
-
* Returns BigInt for values > Number.MAX_SAFE_INTEGER
|
399
|
-
*/
|
400
|
-
readU8le(): bigint;
|
401
|
-
/**
|
402
|
-
* Read 8-byte unsigned integer, big-endian
|
403
|
-
* Returns BigInt for values > Number.MAX_SAFE_INTEGER
|
404
|
-
*/
|
405
|
-
readU8be(): bigint;
|
406
|
-
/**
|
407
|
-
* Read 1-byte signed integer (-128 to 127)
|
408
|
-
*/
|
409
|
-
readS1(): number;
|
410
|
-
/**
|
411
|
-
* Read 2-byte signed integer, little-endian
|
412
|
-
*/
|
413
|
-
readS2le(): number;
|
414
|
-
/**
|
415
|
-
* Read 2-byte signed integer, big-endian
|
416
|
-
*/
|
417
|
-
readS2be(): number;
|
418
|
-
/**
|
419
|
-
* Read 4-byte signed integer, little-endian
|
420
|
-
*/
|
421
|
-
readS4le(): number;
|
422
|
-
/**
|
423
|
-
* Read 4-byte signed integer, big-endian
|
424
|
-
*/
|
425
|
-
readS4be(): number;
|
426
|
-
/**
|
427
|
-
* Read 8-byte signed integer, little-endian
|
428
|
-
* Returns BigInt for values outside Number.MAX_SAFE_INTEGER range
|
429
|
-
*/
|
430
|
-
readS8le(): bigint;
|
431
|
-
/**
|
432
|
-
* Read 8-byte signed integer, big-endian
|
433
|
-
* Returns BigInt for values outside Number.MAX_SAFE_INTEGER range
|
434
|
-
*/
|
435
|
-
readS8be(): bigint;
|
436
|
-
/**
|
437
|
-
* Read 4-byte IEEE 754 single-precision float, little-endian
|
438
|
-
*/
|
439
|
-
readF4le(): number;
|
440
|
-
/**
|
441
|
-
* Read 4-byte IEEE 754 single-precision float, big-endian
|
442
|
-
*/
|
443
|
-
readF4be(): number;
|
444
|
-
/**
|
445
|
-
* Read 8-byte IEEE 754 double-precision float, little-endian
|
446
|
-
*/
|
447
|
-
readF8le(): number;
|
448
|
-
/**
|
449
|
-
* Read 8-byte IEEE 754 double-precision float, big-endian
|
450
|
-
*/
|
451
|
-
readF8be(): number;
|
452
|
-
/**
|
453
|
-
* Read a fixed number of bytes
|
454
|
-
* @param length - Number of bytes to read
|
455
|
-
*/
|
456
|
-
readBytes(length: number): Uint8Array;
|
457
|
-
/**
|
458
|
-
* Read all remaining bytes until end of stream
|
459
|
-
*/
|
460
|
-
readBytesFull(): Uint8Array;
|
461
|
-
/**
|
462
|
-
* Read bytes until a terminator byte is found
|
463
|
-
* @param term - Terminator byte value
|
464
|
-
* @param include - Include terminator in result
|
465
|
-
* @param consume - Consume terminator from stream
|
466
|
-
* @param eosError - Throw error if EOS reached before terminator
|
467
|
-
*/
|
468
|
-
readBytesterm(term: number, include?: boolean, consume?: boolean, eosError?: boolean): Uint8Array;
|
469
|
-
/**
|
470
|
-
* Read a fixed-length string
|
471
|
-
* @param length - Number of bytes to read
|
472
|
-
* @param encoding - Character encoding (default: UTF-8)
|
473
|
-
*/
|
474
|
-
readStr(length: number, encoding?: string): string;
|
475
|
-
/**
|
476
|
-
* Read a null-terminated string
|
477
|
-
* @param encoding - Character encoding (default: UTF-8)
|
478
|
-
* @param term - Terminator byte (default: 0)
|
479
|
-
* @param include - Include terminator in result
|
480
|
-
* @param consume - Consume terminator from stream
|
481
|
-
* @param eosError - Throw error if EOS reached before terminator
|
482
|
-
*/
|
483
|
-
readStrz(encoding?: string, term?: number, include?: boolean, consume?: boolean, eosError?: boolean): string;
|
484
|
-
/**
|
485
|
-
* Align bit reading to byte boundary
|
486
|
-
*/
|
487
|
-
alignToByte(): void;
|
488
|
-
/**
|
489
|
-
* Read specified number of bits as unsigned integer (big-endian)
|
490
|
-
* @param n - Number of bits to read (1-64)
|
491
|
-
*/
|
492
|
-
readBitsIntBe(n: number): bigint;
|
493
|
-
/**
|
494
|
-
* Read specified number of bits as unsigned integer (little-endian)
|
495
|
-
* @param n - Number of bits to read (1-64)
|
496
|
-
*/
|
497
|
-
readBitsIntLe(n: number): bigint;
|
498
|
-
/**
|
499
|
-
* Get the underlying buffer
|
500
|
-
*/
|
501
|
-
getBuffer(): Uint8Array;
|
502
|
-
/**
|
503
|
-
* Create a substream from current position with specified size
|
504
|
-
* @param size - Size of the substream in bytes
|
505
|
-
*/
|
506
|
-
substream(size: number): KaitaiStream;
|
507
|
-
}
|
508
|
-
|
509
508
|
/**
|
510
509
|
* @fileoverview Parser for Kaitai Struct YAML (.ksy) files
|
511
510
|
* @module parser/KsyParser
|
@@ -535,22 +534,6 @@ declare class KsyParser {
|
|
535
534
|
* @throws {ValidationError} If schema validation fails
|
536
535
|
*/
|
537
536
|
parse(yaml: string, options?: ParseOptions$1): KsySchema;
|
538
|
-
/**
|
539
|
-
* Process parametric type syntax in schema.
|
540
|
-
* Converts "type_name(arg1, arg2)" to structured format.
|
541
|
-
*
|
542
|
-
* @param schema - Schema to process
|
543
|
-
* @private
|
544
|
-
*/
|
545
|
-
private processParametricTypes;
|
546
|
-
/**
|
547
|
-
* Parse parametric type syntax from a type string.
|
548
|
-
* Converts "type_name(arg1, arg2)" to type + type-args.
|
549
|
-
*
|
550
|
-
* @param attr - Attribute to process
|
551
|
-
* @private
|
552
|
-
*/
|
553
|
-
private parseParametricType;
|
554
537
|
/**
|
555
538
|
* Validate a schema object.
|
556
539
|
*
|
@@ -759,8 +742,6 @@ declare class Context {
|
|
759
742
|
declare class TypeInterpreter {
|
760
743
|
private schema;
|
761
744
|
private parentMeta?;
|
762
|
-
private expressionCache;
|
763
|
-
private readonly MAX_CACHE_SIZE;
|
764
745
|
/**
|
765
746
|
* Create a new type interpreter.
|
766
747
|
*
|
@@ -992,7 +973,7 @@ declare class NotImplementedError extends KaitaiError {
|
|
992
973
|
* @module kaitai-struct-ts
|
993
974
|
* @author Fabiano Pinto
|
994
975
|
* @license MIT
|
995
|
-
* @version 0.
|
976
|
+
* @version 0.2.0
|
996
977
|
*
|
997
978
|
* @description
|
998
979
|
* A runtime interpreter for Kaitai Struct binary format definitions in TypeScript.
|
@@ -1048,19 +1029,6 @@ interface ParseOptions {
|
|
1048
1029
|
validate?: boolean;
|
1049
1030
|
/** Whether to treat warnings as errors (default: false) */
|
1050
1031
|
strict?: boolean;
|
1051
|
-
/**
|
1052
|
-
* Imported schemas for type imports.
|
1053
|
-
* Map of schema IDs to their parsed schemas.
|
1054
|
-
* @example
|
1055
|
-
* ```typescript
|
1056
|
-
* const imports = {
|
1057
|
-
* 'common_types': parsedCommonSchema,
|
1058
|
-
* 'header': parsedHeaderSchema
|
1059
|
-
* }
|
1060
|
-
* parse(ksyYaml, buffer, { imports })
|
1061
|
-
* ```
|
1062
|
-
*/
|
1063
|
-
imports?: Record<string, KsySchema>;
|
1064
1032
|
}
|
1065
1033
|
|
1066
1034
|
export { type AttributeSpec, BUILTIN_TYPES, Context, EOFError, type EndianExpression, type Endianness, type EnumSpec, type InstanceSpec, KaitaiError, KaitaiStream, KsyParser, type KsySchema, type MetaSpec, NotImplementedError, type ParamSpec, ParseError, type ParseOptions, type ProcessObject, type ProcessSpec, type RepeatSpec, type ValidationError$1 as SchemaValidationError, type SwitchType, TypeInterpreter, ValidationError, type ValidationResult, type ValidationWarning, getBaseType, getTypeEndianness, isBuiltinType, isFloatType, isIntegerType, isStringType, parse };
|
package/dist/index.js
CHANGED
@@ -193,7 +193,6 @@ var KaitaiStream = class _KaitaiStream {
|
|
193
193
|
if (buffer instanceof ArrayBuffer) {
|
194
194
|
this.buffer = new Uint8Array(buffer);
|
195
195
|
this.view = new DataView(buffer);
|
196
|
-
this._size = buffer.byteLength;
|
197
196
|
} else {
|
198
197
|
this.buffer = buffer;
|
199
198
|
this.view = new DataView(
|
@@ -201,7 +200,6 @@ var KaitaiStream = class _KaitaiStream {
|
|
201
200
|
buffer.byteOffset,
|
202
201
|
buffer.byteLength
|
203
202
|
);
|
204
|
-
this._size = buffer.byteLength;
|
205
203
|
}
|
206
204
|
}
|
207
205
|
/**
|
@@ -218,13 +216,13 @@ var KaitaiStream = class _KaitaiStream {
|
|
218
216
|
* Total size of the stream in bytes
|
219
217
|
*/
|
220
218
|
get size() {
|
221
|
-
return this.
|
219
|
+
return this.buffer.length;
|
222
220
|
}
|
223
221
|
/**
|
224
222
|
* Check if we've reached the end of the stream
|
225
223
|
*/
|
226
224
|
isEof() {
|
227
|
-
return this._pos >= this.
|
225
|
+
return this._pos >= this.buffer.length;
|
228
226
|
}
|
229
227
|
/**
|
230
228
|
* Seek to a specific position in the stream
|
@@ -644,7 +642,6 @@ var KsyParser = class {
|
|
644
642
|
throw new ParseError("KSY file must contain an object");
|
645
643
|
}
|
646
644
|
const schema = parsed;
|
647
|
-
this.processParametricTypes(schema);
|
648
645
|
if (validate) {
|
649
646
|
const result = this.validate(schema, { strict });
|
650
647
|
if (!result.valid) {
|
@@ -662,65 +659,6 @@ var KsyParser = class {
|
|
662
659
|
}
|
663
660
|
return schema;
|
664
661
|
}
|
665
|
-
/**
|
666
|
-
* Process parametric type syntax in schema.
|
667
|
-
* Converts "type_name(arg1, arg2)" to structured format.
|
668
|
-
*
|
669
|
-
* @param schema - Schema to process
|
670
|
-
* @private
|
671
|
-
*/
|
672
|
-
processParametricTypes(schema) {
|
673
|
-
if (schema.seq) {
|
674
|
-
for (const attr of schema.seq) {
|
675
|
-
if (typeof attr.type === "string") {
|
676
|
-
this.parseParametricType(attr);
|
677
|
-
}
|
678
|
-
}
|
679
|
-
}
|
680
|
-
if (schema.instances) {
|
681
|
-
for (const instance of Object.values(schema.instances)) {
|
682
|
-
if (typeof instance.type === "string") {
|
683
|
-
this.parseParametricType(instance);
|
684
|
-
}
|
685
|
-
}
|
686
|
-
}
|
687
|
-
if (schema.types) {
|
688
|
-
for (const type of Object.values(schema.types)) {
|
689
|
-
this.processParametricTypes(type);
|
690
|
-
}
|
691
|
-
}
|
692
|
-
}
|
693
|
-
/**
|
694
|
-
* Parse parametric type syntax from a type string.
|
695
|
-
* Converts "type_name(arg1, arg2)" to type + type-args.
|
696
|
-
*
|
697
|
-
* @param attr - Attribute to process
|
698
|
-
* @private
|
699
|
-
*/
|
700
|
-
parseParametricType(attr) {
|
701
|
-
if (typeof attr.type !== "string") return;
|
702
|
-
const match = attr.type.match(/^([a-z_][a-z0-9_]*)\((.*)\)$/i);
|
703
|
-
if (!match) return;
|
704
|
-
const [, typeName, argsStr] = match;
|
705
|
-
const args = [];
|
706
|
-
if (argsStr.trim()) {
|
707
|
-
const argParts = argsStr.split(",").map((s) => s.trim());
|
708
|
-
for (const arg of argParts) {
|
709
|
-
const num = Number(arg);
|
710
|
-
if (!isNaN(num)) {
|
711
|
-
args.push(num);
|
712
|
-
} else if (arg === "true") {
|
713
|
-
args.push(true);
|
714
|
-
} else if (arg === "false") {
|
715
|
-
args.push(false);
|
716
|
-
} else {
|
717
|
-
args.push(arg);
|
718
|
-
}
|
719
|
-
}
|
720
|
-
}
|
721
|
-
attr.type = typeName;
|
722
|
-
attr["type-args"] = args;
|
723
|
-
}
|
724
662
|
/**
|
725
663
|
* Validate a schema object.
|
726
664
|
*
|
@@ -2016,10 +1954,6 @@ var TypeInterpreter = class _TypeInterpreter {
|
|
2016
1954
|
constructor(schema, parentMeta) {
|
2017
1955
|
this.schema = schema;
|
2018
1956
|
this.parentMeta = parentMeta;
|
2019
|
-
// Performance optimization: cache for constant expressions
|
2020
|
-
// Limited size to prevent memory leaks
|
2021
|
-
this.expressionCache = /* @__PURE__ */ new Map();
|
2022
|
-
this.MAX_CACHE_SIZE = 1e3;
|
2023
1957
|
if (!schema.meta && !parentMeta) {
|
2024
1958
|
throw new ParseError("Schema must have meta section");
|
2025
1959
|
}
|
@@ -2124,10 +2058,7 @@ var TypeInterpreter = class _TypeInterpreter {
|
|
2124
2058
|
);
|
2125
2059
|
}
|
2126
2060
|
}
|
2127
|
-
const value = this.parseAttribute(
|
2128
|
-
instance,
|
2129
|
-
context
|
2130
|
-
);
|
2061
|
+
const value = this.parseAttribute(instance, context);
|
2131
2062
|
return value;
|
2132
2063
|
} finally {
|
2133
2064
|
if (instance.pos !== void 0) {
|
@@ -2164,11 +2095,6 @@ var TypeInterpreter = class _TypeInterpreter {
|
|
2164
2095
|
if (attr.io) {
|
2165
2096
|
throw new NotImplementedError("Custom I/O streams");
|
2166
2097
|
}
|
2167
|
-
if (!attr.type && !attr.size && !attr["size-eos"] && !attr.contents) {
|
2168
|
-
throw new ParseError(
|
2169
|
-
`Attribute "${attr.id || "unknown"}" must have type, size, size-eos, or contents`
|
2170
|
-
);
|
2171
|
-
}
|
2172
2098
|
if (attr.repeat) {
|
2173
2099
|
return this.parseRepeated(attr, context);
|
2174
2100
|
}
|
@@ -2218,13 +2144,7 @@ var TypeInterpreter = class _TypeInterpreter {
|
|
2218
2144
|
throw new ParseError("repeat-until expression is required");
|
2219
2145
|
}
|
2220
2146
|
let index = 0;
|
2221
|
-
const maxIterations = 1e6;
|
2222
2147
|
while (true) {
|
2223
|
-
if (index >= maxIterations) {
|
2224
|
-
throw new ParseError(
|
2225
|
-
`repeat-until exceeded maximum iterations (${maxIterations}). Possible infinite loop.`
|
2226
|
-
);
|
2227
|
-
}
|
2228
2148
|
context.set("_index", index);
|
2229
2149
|
const value = this.parseAttribute(
|
2230
2150
|
{ ...attr, repeat: void 0, "repeat-until": void 0 },
|
@@ -2299,11 +2219,6 @@ var TypeInterpreter = class _TypeInterpreter {
|
|
2299
2219
|
if (size < 0) {
|
2300
2220
|
throw new ParseError(`size must be non-negative, got ${size}`);
|
2301
2221
|
}
|
2302
|
-
if (stream.pos + size > stream.size) {
|
2303
|
-
throw new ParseError(
|
2304
|
-
`Not enough data: need ${size} bytes at position ${stream.pos}, but only ${stream.size - stream.pos} bytes available`
|
2305
|
-
);
|
2306
|
-
}
|
2307
2222
|
if (type === "str" || !type) {
|
2308
2223
|
const encoding = attr.encoding || this.schema.meta.encoding || "UTF-8";
|
2309
2224
|
let data;
|
@@ -2425,13 +2340,6 @@ var TypeInterpreter = class _TypeInterpreter {
|
|
2425
2340
|
const meta = this.schema.meta || this.parentMeta;
|
2426
2341
|
const metaEndian = meta?.endian;
|
2427
2342
|
const endian = typeEndian || (typeof metaEndian === "string" ? metaEndian : "le");
|
2428
|
-
if (type.startsWith("b") && type.length > 1) {
|
2429
|
-
const bits = parseInt(type.substring(1), 10);
|
2430
|
-
if (!isNaN(bits) && bits >= 1 && bits <= 64) {
|
2431
|
-
const value = endian === "be" ? stream.readBitsIntBe(bits) : stream.readBitsIntLe(bits);
|
2432
|
-
return bits <= 32 ? Number(value) : value;
|
2433
|
-
}
|
2434
|
-
}
|
2435
2343
|
if (isIntegerType(type)) {
|
2436
2344
|
return this.readInteger(base, endian, stream);
|
2437
2345
|
}
|
@@ -2527,21 +2435,8 @@ var TypeInterpreter = class _TypeInterpreter {
|
|
2527
2435
|
return value;
|
2528
2436
|
}
|
2529
2437
|
if (typeof value === "string") {
|
2530
|
-
if (!value.includes("_") && !value.includes(".")) {
|
2531
|
-
const cached = this.expressionCache.get(value);
|
2532
|
-
if (cached !== void 0) {
|
2533
|
-
return cached;
|
2534
|
-
}
|
2535
|
-
}
|
2536
2438
|
try {
|
2537
|
-
|
2538
|
-
if (!value.includes("_") && !value.includes(".")) {
|
2539
|
-
if (this.expressionCache.size >= this.MAX_CACHE_SIZE) {
|
2540
|
-
this.expressionCache.clear();
|
2541
|
-
}
|
2542
|
-
this.expressionCache.set(value, result);
|
2543
|
-
}
|
2544
|
-
return result;
|
2439
|
+
return evaluateExpression(value, context);
|
2545
2440
|
} catch (error) {
|
2546
2441
|
throw new ParseError(
|
2547
2442
|
`Failed to evaluate expression "${value}": ${error instanceof Error ? error.message : String(error)}`
|
@@ -2682,7 +2577,7 @@ function parse(ksyYaml, buffer, options = {}) {
|
|
2682
2577
|
* @module kaitai-struct-ts
|
2683
2578
|
* @author Fabiano Pinto
|
2684
2579
|
* @license MIT
|
2685
|
-
* @version 0.
|
2580
|
+
* @version 0.2.0
|
2686
2581
|
*
|
2687
2582
|
* @description
|
2688
2583
|
* A runtime interpreter for Kaitai Struct binary format definitions in TypeScript.
|