@k67/kaitai-struct-ts 0.3.0 → 0.5.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 +34 -17
- package/dist/index.d.mts +47 -5
- package/dist/index.d.ts +47 -5
- package/dist/index.js +167 -16
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +167 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
@@ -1815,9 +1815,7 @@ var Evaluator = class {
|
|
1815
1815
|
evaluateEnumAccess(enumName, valueName, context) {
|
1816
1816
|
const value = context.getEnumValue(enumName, valueName);
|
1817
1817
|
if (value === void 0) {
|
1818
|
-
throw new ParseError(
|
1819
|
-
`Enum value "${enumName}::${valueName}" not found`
|
1820
|
-
);
|
1818
|
+
throw new ParseError(`Enum value "${enumName}::${valueName}" not found`);
|
1821
1819
|
}
|
1822
1820
|
return value;
|
1823
1821
|
}
|
@@ -1926,12 +1924,21 @@ var TypeInterpreter = class _TypeInterpreter {
|
|
1926
1924
|
*
|
1927
1925
|
* @param stream - Binary stream to parse
|
1928
1926
|
* @param parent - Parent object (for nested types)
|
1927
|
+
* @param typeArgs - Arguments for parametric types
|
1929
1928
|
* @returns Parsed object
|
1930
1929
|
*/
|
1931
|
-
parse(stream, parent) {
|
1930
|
+
parse(stream, parent, typeArgs) {
|
1932
1931
|
const result = {};
|
1933
1932
|
const context = new Context(stream, result, parent, this.schema.enums);
|
1934
1933
|
context.current = result;
|
1934
|
+
if (typeArgs && this.schema.params) {
|
1935
|
+
for (let i = 0; i < this.schema.params.length && i < typeArgs.length; i++) {
|
1936
|
+
const param = this.schema.params[i];
|
1937
|
+
const argValue = typeArgs[i];
|
1938
|
+
const evaluatedArg = typeof argValue === "string" ? this.evaluateValue(argValue, context) : argValue;
|
1939
|
+
context.set(param.id, evaluatedArg);
|
1940
|
+
}
|
1941
|
+
}
|
1935
1942
|
if (this.schema.seq) {
|
1936
1943
|
for (const attr of this.schema.seq) {
|
1937
1944
|
const value = this.parseAttribute(attr, context);
|
@@ -1940,8 +1947,83 @@ var TypeInterpreter = class _TypeInterpreter {
|
|
1940
1947
|
}
|
1941
1948
|
}
|
1942
1949
|
}
|
1950
|
+
if (this.schema.instances) {
|
1951
|
+
this.setupInstances(result, stream, context);
|
1952
|
+
}
|
1943
1953
|
return result;
|
1944
1954
|
}
|
1955
|
+
/**
|
1956
|
+
* Set up lazy-evaluated instance getters.
|
1957
|
+
* Instances are computed on first access and cached.
|
1958
|
+
*
|
1959
|
+
* @param result - Result object to add getters to
|
1960
|
+
* @param stream - Stream for parsing
|
1961
|
+
* @param context - Execution context
|
1962
|
+
* @private
|
1963
|
+
*/
|
1964
|
+
setupInstances(result, stream, context) {
|
1965
|
+
if (!this.schema.instances) return;
|
1966
|
+
for (const [name, instance] of Object.entries(this.schema.instances)) {
|
1967
|
+
let cached = void 0;
|
1968
|
+
let evaluated = false;
|
1969
|
+
Object.defineProperty(result, name, {
|
1970
|
+
get: () => {
|
1971
|
+
if (!evaluated) {
|
1972
|
+
cached = this.parseInstance(
|
1973
|
+
instance,
|
1974
|
+
stream,
|
1975
|
+
context
|
1976
|
+
);
|
1977
|
+
evaluated = true;
|
1978
|
+
}
|
1979
|
+
return cached;
|
1980
|
+
},
|
1981
|
+
enumerable: true,
|
1982
|
+
configurable: true
|
1983
|
+
});
|
1984
|
+
}
|
1985
|
+
}
|
1986
|
+
/**
|
1987
|
+
* Parse an instance (lazy-evaluated field).
|
1988
|
+
*
|
1989
|
+
* @param instance - Instance specification
|
1990
|
+
* @param stream - Stream to read from
|
1991
|
+
* @param context - Execution context
|
1992
|
+
* @returns Parsed or calculated value
|
1993
|
+
* @private
|
1994
|
+
*/
|
1995
|
+
parseInstance(instance, stream, context) {
|
1996
|
+
if ("value" in instance) {
|
1997
|
+
return this.evaluateValue(
|
1998
|
+
instance.value,
|
1999
|
+
context
|
2000
|
+
);
|
2001
|
+
}
|
2002
|
+
const savedPos = stream.pos;
|
2003
|
+
try {
|
2004
|
+
if (instance.pos !== void 0) {
|
2005
|
+
const pos = this.evaluateValue(
|
2006
|
+
instance.pos,
|
2007
|
+
context
|
2008
|
+
);
|
2009
|
+
if (typeof pos === "number") {
|
2010
|
+
stream.seek(pos);
|
2011
|
+
} else if (typeof pos === "bigint") {
|
2012
|
+
stream.seek(Number(pos));
|
2013
|
+
} else {
|
2014
|
+
throw new ParseError(
|
2015
|
+
`pos must evaluate to a number, got ${typeof pos}`
|
2016
|
+
);
|
2017
|
+
}
|
2018
|
+
}
|
2019
|
+
const value = this.parseAttribute(instance, context);
|
2020
|
+
return value;
|
2021
|
+
} finally {
|
2022
|
+
if (instance.pos !== void 0) {
|
2023
|
+
stream.seek(savedPos);
|
2024
|
+
}
|
2025
|
+
}
|
2026
|
+
}
|
1945
2027
|
/**
|
1946
2028
|
* Parse a single attribute according to its specification.
|
1947
2029
|
*
|
@@ -2097,14 +2179,27 @@ var TypeInterpreter = class _TypeInterpreter {
|
|
2097
2179
|
}
|
2098
2180
|
if (type === "str" || !type) {
|
2099
2181
|
const encoding = attr.encoding || this.schema.meta.encoding || "UTF-8";
|
2182
|
+
let data;
|
2100
2183
|
if (type === "str") {
|
2101
|
-
|
2184
|
+
data = stream.readBytes(size);
|
2185
|
+
if (attr.process) {
|
2186
|
+
data = this.applyProcessing(data, attr.process);
|
2187
|
+
}
|
2188
|
+
return new TextDecoder(encoding).decode(data);
|
2102
2189
|
} else {
|
2103
|
-
|
2190
|
+
data = stream.readBytes(size);
|
2191
|
+
if (attr.process) {
|
2192
|
+
data = this.applyProcessing(data, attr.process);
|
2193
|
+
}
|
2194
|
+
return data;
|
2104
2195
|
}
|
2105
2196
|
} else {
|
2106
|
-
|
2107
|
-
|
2197
|
+
let data = stream.readBytes(size);
|
2198
|
+
if (attr.process) {
|
2199
|
+
data = this.applyProcessing(data, attr.process);
|
2200
|
+
}
|
2201
|
+
const substream = new KaitaiStream(data);
|
2202
|
+
return this.parseType(type, substream, context, attr["type-args"]);
|
2108
2203
|
}
|
2109
2204
|
}
|
2110
2205
|
if (attr["size-eos"]) {
|
@@ -2119,7 +2214,7 @@ var TypeInterpreter = class _TypeInterpreter {
|
|
2119
2214
|
if (!type) {
|
2120
2215
|
throw new ParseError("Attribute must have either type, size, or contents");
|
2121
2216
|
}
|
2122
|
-
return this.parseType(type, stream, context);
|
2217
|
+
return this.parseType(type, stream, context, attr["type-args"]);
|
2123
2218
|
}
|
2124
2219
|
/**
|
2125
2220
|
* Parse a value of a specific type.
|
@@ -2127,12 +2222,17 @@ var TypeInterpreter = class _TypeInterpreter {
|
|
2127
2222
|
* @param type - Type name or switch specification
|
2128
2223
|
* @param stream - Stream to read from
|
2129
2224
|
* @param context - Execution context
|
2225
|
+
* @param typeArgs - Arguments for parametric types
|
2130
2226
|
* @returns Parsed value
|
2131
2227
|
* @private
|
2132
2228
|
*/
|
2133
|
-
parseType(type, stream, context) {
|
2229
|
+
parseType(type, stream, context, typeArgs) {
|
2134
2230
|
if (typeof type === "object") {
|
2135
|
-
|
2231
|
+
return this.parseSwitchType(
|
2232
|
+
type,
|
2233
|
+
stream,
|
2234
|
+
context
|
2235
|
+
);
|
2136
2236
|
}
|
2137
2237
|
if (isBuiltinType(type)) {
|
2138
2238
|
return this.parseBuiltinType(type, stream, context);
|
@@ -2143,11 +2243,46 @@ var TypeInterpreter = class _TypeInterpreter {
|
|
2143
2243
|
if (this.schema.enums && !typeSchema.enums) {
|
2144
2244
|
typeSchema.enums = this.schema.enums;
|
2145
2245
|
}
|
2246
|
+
if (this.schema.types && !typeSchema.types) {
|
2247
|
+
typeSchema.types = this.schema.types;
|
2248
|
+
}
|
2146
2249
|
const interpreter = new _TypeInterpreter(typeSchema, meta);
|
2147
|
-
return interpreter.parse(stream, context.current);
|
2250
|
+
return interpreter.parse(stream, context.current, typeArgs);
|
2148
2251
|
}
|
2149
2252
|
throw new ParseError(`Unknown type: ${type}`);
|
2150
2253
|
}
|
2254
|
+
/**
|
2255
|
+
* Parse a switch type (type selection based on expression).
|
2256
|
+
*
|
2257
|
+
* @param switchType - Switch type specification
|
2258
|
+
* @param stream - Stream to read from
|
2259
|
+
* @param context - Execution context
|
2260
|
+
* @returns Parsed value
|
2261
|
+
* @private
|
2262
|
+
*/
|
2263
|
+
parseSwitchType(switchType, stream, context) {
|
2264
|
+
const switchOn = switchType["switch-on"];
|
2265
|
+
const cases = switchType["cases"];
|
2266
|
+
const defaultType = switchType["default"];
|
2267
|
+
if (!switchOn || typeof switchOn !== "string") {
|
2268
|
+
throw new ParseError("switch-on expression is required for switch types");
|
2269
|
+
}
|
2270
|
+
if (!cases) {
|
2271
|
+
throw new ParseError("cases are required for switch types");
|
2272
|
+
}
|
2273
|
+
const switchValue = this.evaluateValue(switchOn, context);
|
2274
|
+
const switchKey = String(switchValue);
|
2275
|
+
let selectedType = cases[switchKey];
|
2276
|
+
if (selectedType === void 0 && defaultType) {
|
2277
|
+
selectedType = defaultType;
|
2278
|
+
}
|
2279
|
+
if (selectedType === void 0) {
|
2280
|
+
throw new ParseError(
|
2281
|
+
`No matching case for switch value "${switchKey}" and no default type specified`
|
2282
|
+
);
|
2283
|
+
}
|
2284
|
+
return this.parseType(selectedType, stream, context);
|
2285
|
+
}
|
2151
2286
|
/**
|
2152
2287
|
* Parse a built-in type.
|
2153
2288
|
*
|
@@ -2225,11 +2360,27 @@ var TypeInterpreter = class _TypeInterpreter {
|
|
2225
2360
|
}
|
2226
2361
|
}
|
2227
2362
|
/**
|
2228
|
-
*
|
2229
|
-
*
|
2230
|
-
*
|
2363
|
+
* Apply processing transformation to data.
|
2364
|
+
* Supports basic transformations like zlib decompression.
|
2365
|
+
*
|
2366
|
+
* @param data - Data to process
|
2367
|
+
* @param process - Processing specification
|
2368
|
+
* @returns Processed data
|
2369
|
+
* @private
|
2370
|
+
*/
|
2371
|
+
applyProcessing(data, process) {
|
2372
|
+
const processType = typeof process === "string" ? process : process.algorithm;
|
2373
|
+
if (processType) {
|
2374
|
+
throw new NotImplementedError(
|
2375
|
+
`Processing type "${processType}" is not yet implemented. Supported in future versions with zlib, encryption, etc.`
|
2376
|
+
);
|
2377
|
+
}
|
2378
|
+
return data;
|
2379
|
+
}
|
2380
|
+
/**
|
2381
|
+
* Evaluate a value that can be an expression or literal.
|
2231
2382
|
*
|
2232
|
-
* @param value -
|
2383
|
+
* @param value - Value to evaluate (expression string, number, or boolean)
|
2233
2384
|
* @param context - Execution context
|
2234
2385
|
* @returns Evaluated result
|
2235
2386
|
* @private
|