@reversense/dxc-struct 1.0.7

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 ADDED
@@ -0,0 +1,169 @@
1
+ # dxc-struct
2
+
3
+ Node.js equivalent of Python's Struct library for parsing and writing binary data.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm i @dexcalibur/dxc-struct
9
+ ```
10
+
11
+ ## Description
12
+
13
+ `dxc-struct` provides a TypeScript/JavaScript implementation for converting between binary data and JavaScript values, similar to Python's `struct` module. It supports encoding and decoding various data types including integers, floats, strings, and byte arrays with configurable endianness.
14
+
15
+ ## Features
16
+
17
+ - **Binary data parsing** and encoding
18
+ - **Multiple data types**: integers (signed/unsigned), floats, doubles, strings, byte arrays
19
+ - **Endianness control**: Big-endian and little-endian support
20
+ - **Format strings**: Python-like format strings for structured data
21
+ - **TypeScript support**: Fully typed for type safety
22
+
23
+ ## Usage
24
+
25
+ ### Basic Example
26
+
27
+ ```typescript
28
+ import { Struct } from '@dexcalibur/dxc-struct';
29
+
30
+ // Pack data into binary format
31
+ const data = Struct.pack('<IHB', [0x12345678, 0xABCD, 0xFF]);
32
+
33
+ // Unpack binary data
34
+ const values = Struct.unpack('<IHB', data);
35
+ console.log(values); // [305419896, 43981, 255]
36
+ ```
37
+
38
+ ### Format Strings
39
+
40
+ Format strings define the data structure with the following syntax:
41
+
42
+ #### Endianness
43
+ - `<` - Little-endian (default for native)
44
+ - No prefix - Big-endian
45
+
46
+ #### Data Types
47
+
48
+ | Format | Type | Size (bytes) | Description |
49
+ |--------|------|--------------|-------------|
50
+ | `c` | char | 1 | Single character |
51
+ | `b` | signed byte | 1 | Signed integer (-128 to 127) |
52
+ | `B` | unsigned byte | 1 | Unsigned integer (0 to 255) |
53
+ | `h` | short | 2 | Signed integer (-32768 to 32767) |
54
+ | `H` | unsigned short | 2 | Unsigned integer (0 to 65535) |
55
+ | `i` / `l` | int/long | 4 | Signed integer (-2³¹ to 2³¹-1) |
56
+ | `I` / `L` | unsigned int/long | 4 | Unsigned integer (0 to 2³²-1) |
57
+ | `q` | long long | 8 | Signed 64-bit integer (BigInt) |
58
+ | `Q` | unsigned long long | 8 | Unsigned 64-bit integer (BigInt) |
59
+ | `f` | float | 4 | IEEE 754 single-precision |
60
+ | `d` | double | 8 | IEEE 754 double-precision |
61
+ | `s` | string | variable | Fixed-length string |
62
+ | `S` | string | variable | Null-terminated string |
63
+ | `A` | byte array | variable | Byte array |
64
+ | `x` | padding | 1 | Padding byte |
65
+
66
+ #### Count Prefix
67
+ Add a number before the format character to specify count: `4I` = four integers
68
+
69
+ #### Named Fields
70
+ Add field names in parentheses: `I(id)H(value)` returns an object with named fields
71
+
72
+ ### Examples
73
+
74
+ #### Unpacking with Named Fields
75
+
76
+ ```typescript
77
+ const buffer = Buffer.from([0x78, 0x56, 0x34, 0x12, 0xCD, 0xAB]);
78
+ const result = Struct.unpack('<I(id)H(value)', buffer);
79
+ console.log(result); // { id: 305419896, value: 43981 }
80
+ ```
81
+
82
+ #### Packing Multiple Values
83
+
84
+ ```typescript
85
+ const buffer = Struct.pack('<3H', [0x1234, 0x5678, 0x9ABC]);
86
+ ```
87
+
88
+ #### Working with Strings
89
+
90
+ ```typescript
91
+ // Fixed-length string
92
+ const data = Struct.pack('<5s', ['hello']);
93
+
94
+ // Null-terminated string
95
+ const nullTerm = Struct.pack('<S', ['hello']);
96
+ ```
97
+
98
+ #### 64-bit Integers (BigInt)
99
+
100
+ ```typescript
101
+ const data = Struct.pack('<Q', [BigInt('0xFFFFFFFFFFFFFFFF')]);
102
+ const values = Struct.unpack('<Q', data);
103
+ console.log(values[0]); // 18446744073709551615n
104
+ ```
105
+
106
+ ## API Reference
107
+
108
+ ### `Struct.pack(format, values)`
109
+ Packs values into a new Buffer according to the format string.
110
+
111
+ **Parameters:**
112
+ - `format` (string): Format string defining data layout
113
+ - `values` (any[]): Array of values to pack
114
+
115
+ **Returns:** Buffer containing packed binary data
116
+
117
+ ### `Struct.packTo(format, buffer, offset, values)`
118
+ Packs values into an existing Buffer at a specific offset.
119
+
120
+ **Parameters:**
121
+ - `format` (string): Format string defining data layout
122
+ - `buffer` (Buffer | any[]): Target buffer
123
+ - `offset` (number): Starting offset in buffer
124
+ - `values` (any[]): Array of values to pack
125
+
126
+ **Returns:** Modified buffer
127
+
128
+ ### `Struct.unpack(format, data, offset?)`
129
+ Unpacks binary data according to the format string.
130
+
131
+ **Parameters:**
132
+ - `format` (string): Format string defining data layout
133
+ - `data` (Buffer | any[] | string): Binary data to unpack
134
+ - `offset` (number, optional): Starting offset (default: 0)
135
+
136
+ **Returns:** Array of unpacked values or object with named fields
137
+
138
+ ### `Struct.calcLength(format, values)`
139
+ Calculates the byte length required for packing the given values.
140
+
141
+ **Parameters:**
142
+ - `format` (string): Format string
143
+ - `values` (any): Values to be packed
144
+
145
+ **Returns:** Number of bytes required
146
+
147
+ ## Development
148
+
149
+ ### Build
150
+
151
+ ```bash
152
+ npm run build
153
+ ```
154
+
155
+ ### Test
156
+
157
+ ```bash
158
+ npm test
159
+ ```
160
+
161
+ ## License
162
+
163
+ AGPL-3.0-only
164
+
165
+ Copyright (C) 2026 Reversense SAS
166
+
167
+ This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
168
+
169
+ See [LICENSE](LICENSE) for more details.
@@ -0,0 +1,2 @@
1
+ import { Struct } from "./src/Struct.js";
2
+ export { Struct };
package/dist/index.js ADDED
@@ -0,0 +1,24 @@
1
+ import { StructEncoder } from "./src/StructEncoder.js";
2
+ import { StructDecoder } from "./src/StructDecoder.js";
3
+ import { Struct } from "./src/Struct.js";
4
+ [
5
+ { token: 'A', en: StructEncoder.byteArray, de: StructDecoder.byteArray, opts: { size: 1 } },
6
+ { token: 'c', en: StructEncoder.chr, de: StructDecoder.chr, opts: { size: 1 } },
7
+ { token: 'b', en: StructEncoder.int, de: StructDecoder.int, opts: { size: 1, bSigned: true, min: -Math.pow(2, 7), max: Math.pow(2, 7) - 1 } },
8
+ { token: 'B', en: StructEncoder.int, de: StructDecoder.int, opts: { size: 1, bSigned: false, min: 0, max: Math.pow(2, 8) - 1 } },
9
+ { token: 'h', en: StructEncoder.int, de: StructDecoder.int, opts: { size: 2, bSigned: true, min: -Math.pow(2, 15), max: Math.pow(2, 15) - 1 } },
10
+ { token: 'H', en: StructEncoder.int, de: StructDecoder.int, opts: { size: 2, bSigned: false, min: 0, max: Math.pow(2, 16) - 1 } },
11
+ { token: 's', en: StructEncoder.str, de: StructDecoder.str, opts: { size: 1 } },
12
+ { token: 'S', en: StructEncoder.str, de: StructDecoder.nullTerminatedStr, opts: { size: 1 } },
13
+ { token: 'f', en: StructEncoder.ieee754_fp, de: StructDecoder.ieee754_fp, opts: { size: 4, mLen: 23, rt: Math.pow(2, -24) - Math.pow(2, -77) } },
14
+ { token: 'd', en: StructEncoder.ieee754_fp, de: StructDecoder.ieee754_fp, opts: { size: 8, mLen: 52, rt: 0 } },
15
+ { token: 'i', en: StructEncoder.int, de: StructDecoder.int, opts: { size: 4, bSigned: true, min: -Math.pow(2, 31), max: Math.pow(2, 31) - 1 } },
16
+ { token: 'I', en: StructEncoder.int, de: StructDecoder.int, opts: { size: 4, bSigned: false, min: 0, max: Math.pow(2, 32) - 1 } },
17
+ { token: 'l', en: StructEncoder.int, de: StructDecoder.int, opts: { size: 4, bSigned: true, min: -Math.pow(2, 31), max: Math.pow(2, 31) - 1 } },
18
+ { token: 'L', en: StructEncoder.int, de: StructDecoder.int, opts: { size: 4, bSigned: false, min: 0, max: Math.pow(2, 32) - 1 } },
19
+ { token: 'q', en: StructEncoder.bigintEncoder, de: StructDecoder.bigintDecoder, opts: { size: 8, bSigned: true, min: -Math.pow(2, 63), max: Math.pow(2, 63) - 1 } },
20
+ { token: 'Q', en: StructEncoder.bigintEncoder, de: StructDecoder.bigintDecoder, opts: { size: 8, bSigned: false, min: 0, max: Math.pow(2, 64) - 1 } },
21
+ ].map((vOp) => {
22
+ Struct.OP[vOp.token] = vOp;
23
+ });
24
+ export { Struct };
@@ -0,0 +1,49 @@
1
+ import { Endianness } from "./common.js";
2
+ export type Token = string;
3
+ export interface TransformerOpts {
4
+ size: number;
5
+ mLen?: number;
6
+ min?: number;
7
+ max?: number;
8
+ rt?: number;
9
+ bSigned?: boolean;
10
+ }
11
+ export interface Operation {
12
+ token: Token;
13
+ en: ((...args: any) => any);
14
+ de: ((...args: any) => any);
15
+ opts: TransformerOpts;
16
+ }
17
+ export declare class Struct {
18
+ static NATIVE_ENDIANNESS: Endianness;
19
+ static PADDING_TOK: string;
20
+ static BE_FLAG: string;
21
+ static OP: Record<Token, Operation>;
22
+ static FORMAT: string;
23
+ static _lenLut: {
24
+ A: number;
25
+ x: number;
26
+ c: number;
27
+ b: number;
28
+ B: number;
29
+ h: number;
30
+ H: number;
31
+ s: number;
32
+ S: number;
33
+ f: number;
34
+ d: number;
35
+ i: number;
36
+ I: number;
37
+ l: number;
38
+ L: number;
39
+ q: number;
40
+ Q: number;
41
+ };
42
+ static _UnpackSeries(pEndian: Endianness, pOpe: Operation, pElCount: number, pElSize: number, pArr: any[] | Buffer | string, pOffset: number): any[];
43
+ static _PackSeries(pEndian: Endianness, pOp: Operation, pElCount: number, pElSize: number, pDestArr: any[] | Buffer, pOffset: number, pSourceArr: any[] | Buffer, i: any): void;
44
+ static _zip(keys: any, values: any): any;
45
+ static unpack(pFmt: string, pArr: any[] | Buffer | string, pOffset?: number): any;
46
+ static packTo(pFmt: string, pArr: any[] | Buffer, pStartAt: number, pSource: any[]): any[] | Buffer<ArrayBufferLike>;
47
+ static pack(pFmt: string, pBinaryData: any[]): any;
48
+ static calcLength(pFmt: string, pValues: any): number;
49
+ }
@@ -0,0 +1,140 @@
1
+ import { RuntimeException } from "./error/RuntimeException.js";
2
+ import { Endianness } from "./common.js";
3
+ const NOT_NULL_TERM_STRING = 'S';
4
+ export class Struct {
5
+ static _UnpackSeries(pEndian, pOpe, pElCount, pElSize, pArr, pOffset) {
6
+ let res = [];
7
+ for (let i = 0; i < pElCount; i++) {
8
+ res.push(pOpe.de.apply(null, [pEndian, pOpe, pArr, pOffset + i * pElSize]));
9
+ }
10
+ return res;
11
+ }
12
+ static _PackSeries(pEndian, pOp, pElCount, pElSize, pDestArr, pOffset, pSourceArr, i) {
13
+ for (let o = 0; o < pElCount; o++) {
14
+ pOp.en.apply(null, [pEndian, pOp, pDestArr, pOffset + o * pElSize, pSourceArr[i + o]]);
15
+ }
16
+ }
17
+ ;
18
+ static _zip(keys, values) {
19
+ let result = {};
20
+ for (var i = 0; i < keys.length; i++) {
21
+ result[keys[i]] = values[i];
22
+ }
23
+ return result;
24
+ }
25
+ static unpack(pFmt, pArr, pOffset = 0) {
26
+ let endian = (pFmt.charAt(0) != '<') ? Endianness.BIG_ENDIAN : Struct.NATIVE_ENDIANNESS;
27
+ const re = new RegExp(Struct.FORMAT, 'g');
28
+ let m;
29
+ let elCount;
30
+ let elSz = 0;
31
+ let rk = [];
32
+ let rv = [];
33
+ while (m = re.exec(pFmt)) {
34
+ elCount = ((m[1] == undefined) || (m[1] == '')) ? 1 : parseInt(m[1]);
35
+ if (m[2] === NOT_NULL_TERM_STRING) {
36
+ elCount = 0;
37
+ while (pArr[pOffset + elCount] !== 0) {
38
+ elCount++;
39
+ }
40
+ elCount++;
41
+ }
42
+ elSz = Struct.OP[m[2]].opts.size;
43
+ if ((pOffset + elCount * elSz) > pArr.length) {
44
+ throw RuntimeException.READ_OOB();
45
+ }
46
+ if ('SAs'.indexOf(m[2]) != -1) {
47
+ rv.push(Struct.OP[m[2]].de(pArr, pOffset, elCount));
48
+ }
49
+ else {
50
+ rv.push(Struct._UnpackSeries(endian, Struct.OP[m[2]], elCount, elSz, pArr, pOffset));
51
+ }
52
+ rk.push(m[4]);
53
+ pOffset += elCount * elSz;
54
+ }
55
+ rv = Array.prototype.concat.apply([], rv);
56
+ if (rk.indexOf(undefined) !== -1) {
57
+ return rv;
58
+ }
59
+ else {
60
+ return Struct._zip(rk, rv);
61
+ }
62
+ }
63
+ ;
64
+ static packTo(pFmt, pArr, pStartAt, pSource) {
65
+ let bigEndian = (pFmt.charAt(0) != '<') ? Endianness.BIG_ENDIAN : Struct.NATIVE_ENDIANNESS;
66
+ const re = new RegExp(Struct.FORMAT, 'g');
67
+ let offset = pStartAt;
68
+ let m;
69
+ let sz, dataLen = 0, i = 0, j = 0;
70
+ let opType;
71
+ while (m = re.exec(pFmt)) {
72
+ opType = m[2];
73
+ dataLen = ((m[1] == undefined) || (m[1] == '')) ? 1 : parseInt(m[1]);
74
+ if (opType === NOT_NULL_TERM_STRING) {
75
+ dataLen = pSource[i].length + 1;
76
+ }
77
+ sz = Struct.OP[m[2]].opts.size;
78
+ if ((offset + dataLen * sz) > pArr.length) {
79
+ throw RuntimeException.WRITE_OOB();
80
+ }
81
+ switch (opType) {
82
+ case 'A':
83
+ case 's':
84
+ case 'S':
85
+ if ((i + 1) > pSource.length) {
86
+ throw RuntimeException.READ_OOB();
87
+ }
88
+ Struct.OP[opType].en(pArr, offset, dataLen, pSource[i]);
89
+ i += 1;
90
+ break;
91
+ case Struct.PADDING_TOK:
92
+ for (j = 0; j < dataLen; j++) {
93
+ pArr[offset + j] = 0;
94
+ }
95
+ break;
96
+ default:
97
+ if ((i + dataLen) > pSource.length) {
98
+ throw RuntimeException.READ_OOB();
99
+ }
100
+ Struct._PackSeries(bigEndian, Struct.OP[opType], dataLen, sz, pArr, offset, pSource, i);
101
+ i += dataLen;
102
+ break;
103
+ }
104
+ offset += dataLen * sz;
105
+ }
106
+ return pArr;
107
+ }
108
+ ;
109
+ static pack(pFmt, pBinaryData) {
110
+ return Struct.packTo(pFmt, new Buffer(this.calcLength(pFmt, pBinaryData)), 0, pBinaryData);
111
+ }
112
+ static calcLength(pFmt, pValues) {
113
+ const re = new RegExp(Struct.FORMAT, 'g');
114
+ let m, n, sum = 0, i = 0;
115
+ while (m = re.exec(pFmt)) {
116
+ if ((m[1] == undefined) || (m[1] == '')) {
117
+ n = Struct.OP[m[2]].opts.size;
118
+ }
119
+ else {
120
+ n = parseInt(m[1]) * Struct.OP[m[2]].opts.size;
121
+ }
122
+ if (m[2] === NOT_NULL_TERM_STRING) {
123
+ n = pValues[i].length + 1;
124
+ }
125
+ sum += n;
126
+ if (m[2] !== Struct.PADDING_TOK) {
127
+ i++;
128
+ }
129
+ }
130
+ return sum;
131
+ }
132
+ ;
133
+ }
134
+ Struct.NATIVE_ENDIANNESS = Endianness.LITTLE_ENDIAN;
135
+ Struct.PADDING_TOK = 'x';
136
+ Struct.BE_FLAG = '<';
137
+ Struct.OP = {};
138
+ Struct.FORMAT = '(\\d+)?([AxcbBhHsSfdiIlLqQ])(\\(([a-zA-Z0-9]+)\\))?';
139
+ Struct._lenLut = { 'A': 1, 'x': 1, 'c': 1, 'b': 1, 'B': 1, 'h': 2, 'H': 2, 's': 1,
140
+ 'S': 1, 'f': 4, 'd': 8, 'i': 4, 'I': 4, 'l': 4, 'L': 4, 'q': 8, 'Q': 8 };
@@ -0,0 +1,11 @@
1
+ import { Endianness } from "./common.js";
2
+ import { Operation } from "./Struct.js";
3
+ export declare class StructDecoder {
4
+ static byteArray(pArr: any[], pOffset: number, pLength: number): any[];
5
+ static chr(pArr: number[], pOffset: number): string;
6
+ static int(pEndianness: Endianness, pOp: Operation, pArr: any, pOffset: number): number;
7
+ static bigintDecoder(pEndianness: Endianness, pOp: Operation, pArr: any, pOffset: number): bigint;
8
+ static str(pArr: number[], pOffset: number, pLen: number): string;
9
+ static nullTerminatedStr(pArr: number[], pOffset: number, pLen: number): string;
10
+ static ieee754_fp(pEndianness: Endianness, pOp: Operation, pArr: any[], pOffset: number): number;
11
+ }
@@ -0,0 +1,90 @@
1
+ import { Endianness } from "./common.js";
2
+ export class StructDecoder {
3
+ static byteArray(pArr, pOffset, pLength) {
4
+ return [pArr.slice(pOffset, pOffset + pLength)];
5
+ }
6
+ static chr(pArr, pOffset) {
7
+ return String.fromCharCode(pArr[pOffset]);
8
+ }
9
+ static int(pEndianness, pOp, pArr, pOffset) {
10
+ let lsb, nsb;
11
+ if (pEndianness == Endianness.BIG_ENDIAN) {
12
+ lsb = pOp.opts.size - 1;
13
+ nsb = -1;
14
+ }
15
+ else {
16
+ lsb = 0;
17
+ nsb = 1;
18
+ }
19
+ let stop = lsb + nsb * pOp.opts.size, rv, i, f;
20
+ for (rv = 0, i = lsb, f = 1; i != stop; rv += (pArr[pOffset + i] * f), i += nsb, f *= 256)
21
+ ;
22
+ if (pOp.opts.bSigned && (rv & Math.pow(2, pOp.opts.size * 8 - 1))) {
23
+ rv -= Math.pow(2, pOp.opts.size * 8);
24
+ }
25
+ return rv;
26
+ }
27
+ ;
28
+ static bigintDecoder(pEndianness, pOp, pArr, pOffset) {
29
+ let lsb, nsb;
30
+ if (pEndianness == Endianness.BIG_ENDIAN) {
31
+ lsb = pOp.opts.size - 1;
32
+ nsb = -1;
33
+ }
34
+ else {
35
+ lsb = 0;
36
+ nsb = 1;
37
+ }
38
+ let stop = lsb + nsb * pOp.opts.size;
39
+ let i;
40
+ let rv = BigInt(0);
41
+ let f = BigInt(1);
42
+ for (i = lsb; i != stop; i += nsb) {
43
+ rv += BigInt(pArr[pOffset + i]) * f;
44
+ f *= BigInt(256);
45
+ }
46
+ if (pOp.opts.bSigned && (rv >> BigInt(pOp.opts.size * 8 - 1)) == BigInt(1)) {
47
+ rv -= BigInt(1) << BigInt(pOp.opts.size * 8);
48
+ }
49
+ return rv;
50
+ }
51
+ ;
52
+ static str(pArr, pOffset, pLen) {
53
+ let s = new Array(pLen);
54
+ for (let i = 0; i < pLen; s[i] = String.fromCharCode(pArr[pOffset + i]), i++)
55
+ ;
56
+ return s.join('');
57
+ }
58
+ ;
59
+ static nullTerminatedStr(pArr, pOffset, pLen) {
60
+ let str = StructDecoder.str(pArr, pOffset, pLen);
61
+ return str.substring(0, str.length - 1);
62
+ }
63
+ ;
64
+ static ieee754_fp(pEndianness, pOp, pArr, pOffset) {
65
+ let s, e, m, i, d, nBits, mLen, eLen, eBias, eMax;
66
+ mLen = pOp.opts.mLen, eLen = pOp.opts.size * 8 - pOp.opts.mLen - 1, eMax = (1 << eLen) - 1, eBias = eMax >> 1;
67
+ i = (pEndianness == Endianness.BIG_ENDIAN) ? 0 : (pOp.opts.size - 1);
68
+ d = (pEndianness == Endianness.BIG_ENDIAN) ? 1 : -1;
69
+ s = pArr[pOffset + i];
70
+ i += d;
71
+ nBits = -7;
72
+ for (e = s & ((1 << (-nBits)) - 1), s >>= (-nBits), nBits += eLen; nBits > 0; e = e * 256 + pArr[pOffset + i], i += d, nBits -= 8)
73
+ ;
74
+ for (m = e & ((1 << (-nBits)) - 1), e >>= (-nBits), nBits += mLen; nBits > 0; m = m * 256 + pArr[pOffset + i], i += d, nBits -= 8)
75
+ ;
76
+ switch (e) {
77
+ case 0:
78
+ e = 1 - eBias;
79
+ break;
80
+ case eMax:
81
+ return m ? NaN : ((s ? -1 : 1) * Infinity);
82
+ default:
83
+ m = m + Math.pow(2, mLen);
84
+ e = e - eBias;
85
+ break;
86
+ }
87
+ return (s ? -1 : 1) * m * Math.pow(2, e - mLen);
88
+ }
89
+ ;
90
+ }
@@ -0,0 +1,10 @@
1
+ import { Endianness } from "./common.js";
2
+ import { Operation } from "./Struct.js";
3
+ export declare class StructEncoder {
4
+ static byteArray(pDestArr: number[], pOffset: number, pLen: number, pSourceArr: number[]): void;
5
+ static chr(pDestArr: number[], pOffset: number, pChar: string): void;
6
+ static str(pDestArr: number[], pOffset: number, pLen: number, pSourceStr: string): void;
7
+ static int(pEndianness: Endianness, pOp: Operation, pArr: any[], pOffset: number, v: number): void;
8
+ static bigintEncoder(pEndianness: Endianness, pOp: Operation, pArr: any[], pOffset: number, v: bigint): void;
9
+ static ieee754_fp(pEndianness: Endianness, pOp: Operation, pDestArr: any[], pOffset: number, pValue: number): void;
10
+ }
@@ -0,0 +1,92 @@
1
+ import { Endianness } from "./common.js";
2
+ export class StructEncoder {
3
+ static byteArray(pDestArr, pOffset, pLen, pSourceArr) {
4
+ for (let i = 0; i < pLen; pDestArr[pOffset + i] = pSourceArr[i] ? pSourceArr[i] : 0, i++)
5
+ ;
6
+ }
7
+ static chr(pDestArr, pOffset, pChar) {
8
+ pDestArr[pOffset] = pChar.charCodeAt(0);
9
+ }
10
+ ;
11
+ static str(pDestArr, pOffset, pLen, pSourceStr) {
12
+ for (let t, i = 0; i < pLen; pDestArr[pOffset + i] = (t = pSourceStr.charCodeAt(i)) ? t : 0, i++)
13
+ ;
14
+ }
15
+ ;
16
+ static int(pEndianness, pOp, pArr, pOffset, v) {
17
+ let lsb, nsb;
18
+ if (pEndianness == Endianness.BIG_ENDIAN) {
19
+ lsb = pOp.opts.size - 1;
20
+ nsb = -1;
21
+ }
22
+ else {
23
+ lsb = 0;
24
+ nsb = 1;
25
+ }
26
+ let stop = lsb + nsb * pOp.opts.size, i;
27
+ v = (v < pOp.opts.min) ? pOp.opts.min : (v > pOp.opts.max) ? pOp.opts.max : v;
28
+ for (i = lsb; i != stop; pArr[pOffset + i] = v & 0xff, i += nsb, v >>= 8)
29
+ ;
30
+ }
31
+ ;
32
+ static bigintEncoder(pEndianness, pOp, pArr, pOffset, v) {
33
+ let lsb, nsb;
34
+ if (pEndianness == Endianness.BIG_ENDIAN) {
35
+ lsb = pOp.opts.size - 1;
36
+ nsb = -1;
37
+ }
38
+ else {
39
+ lsb = 0;
40
+ nsb = 1;
41
+ }
42
+ let stop = lsb + nsb * pOp.opts.size, i;
43
+ v = BigInt((v < pOp.opts.min) ? pOp.opts.min : (v > pOp.opts.max) ? pOp.opts.max : v);
44
+ for (i = lsb; i != stop; pArr[pOffset + i] = v & BigInt(0xff), i += nsb, v >>= BigInt(8))
45
+ ;
46
+ }
47
+ static ieee754_fp(pEndianness, pOp, pDestArr, pOffset, pValue) {
48
+ let s, e, m, i, d, c, mLen, eLen, eBias, eMax, abs;
49
+ mLen = pOp.opts.mLen, eLen = pOp.opts.size * 8 - pOp.opts.mLen - 1, eMax = (1 << eLen) - 1, eBias = eMax >> 1;
50
+ s = pValue < 0 ? 1 : 0;
51
+ abs = Math.abs(pValue);
52
+ if (isNaN(abs) || (abs == Infinity)) {
53
+ m = isNaN(abs) ? 1 : 0;
54
+ e = eMax;
55
+ }
56
+ else {
57
+ e = Math.floor(Math.log(abs) / Math.LN2);
58
+ if (abs * (c = Math.pow(2, -e)) < 1) {
59
+ e--;
60
+ c *= 2;
61
+ }
62
+ if (e + eBias >= 1) {
63
+ abs += pOp.opts.rt / c;
64
+ }
65
+ else {
66
+ abs += pOp.opts.rt * Math.pow(2, 1 - eBias);
67
+ }
68
+ if (abs * c >= 2) {
69
+ e++;
70
+ c /= 2;
71
+ }
72
+ if (e + eBias >= eMax) {
73
+ m = 0;
74
+ e = eMax;
75
+ }
76
+ else if (e + eBias >= 1) {
77
+ m = (abs * c - 1) * Math.pow(2, mLen);
78
+ e = e + eBias;
79
+ }
80
+ else {
81
+ m = abs * Math.pow(2, eBias - 1) * Math.pow(2, mLen);
82
+ e = 0;
83
+ }
84
+ }
85
+ for (i = (pEndianness == Endianness.BIG_ENDIAN) ? (pOp.opts.size - 1) : 0, d = (pEndianness == Endianness.BIG_ENDIAN) ? -1 : 1; mLen >= 8; pDestArr[pOffset + i] = m & 0xff, i += d, m /= 256, mLen -= 8)
86
+ ;
87
+ for (e = (e << mLen) | m, eLen += mLen; eLen > 0; pDestArr[pOffset + i] = e & 0xff, i += d, e /= 256, eLen -= 8)
88
+ ;
89
+ pDestArr[pOffset + i - d] |= s * 128;
90
+ }
91
+ ;
92
+ }
@@ -0,0 +1,4 @@
1
+ export declare enum Endianness {
2
+ LITTLE_ENDIAN = 0,
3
+ BIG_ENDIAN = 1
4
+ }
@@ -0,0 +1,5 @@
1
+ export var Endianness;
2
+ (function (Endianness) {
3
+ Endianness[Endianness["LITTLE_ENDIAN"] = 0] = "LITTLE_ENDIAN";
4
+ Endianness[Endianness["BIG_ENDIAN"] = 1] = "BIG_ENDIAN";
5
+ })(Endianness || (Endianness = {}));
@@ -0,0 +1,14 @@
1
+ export declare class MonitoredError extends Error {
2
+ static ERR_CODE_BASE: number;
3
+ static NEW_HOOK: ((pErr: MonitoredError | null) => void);
4
+ cmp: string;
5
+ code: number;
6
+ extra: any;
7
+ constructor(pCmp: string, pMsg: string, pCode?: number, pExtra?: any);
8
+ getCode(): number;
9
+ getMessage(): string;
10
+ getExtra(): any;
11
+ toString(): string;
12
+ protected _triggerNewHook(): void;
13
+ toObject(pIncludeExtra?: boolean): any;
14
+ }
@@ -0,0 +1,33 @@
1
+ export class MonitoredError extends Error {
2
+ constructor(pCmp, pMsg, pCode = -1, pExtra = null) {
3
+ super(pMsg);
4
+ this.cmp = pCmp;
5
+ this.code = pCode;
6
+ this.extra = pExtra;
7
+ }
8
+ getCode() {
9
+ return this.code;
10
+ }
11
+ getMessage() {
12
+ return `[${this.cmp}][#${this.code}] ${this.message} `;
13
+ }
14
+ getExtra() {
15
+ return this.extra;
16
+ }
17
+ toString() {
18
+ return `[${this.cmp}] [#${this.code != null ? this.code : "<null>"} ${this.message}`;
19
+ }
20
+ _triggerNewHook() {
21
+ MonitoredError.NEW_HOOK.apply(null, [this]);
22
+ }
23
+ toObject(pIncludeExtra = false) {
24
+ return {
25
+ cmp: this.cmp,
26
+ code: this.code,
27
+ msg: this.message,
28
+ extra: pIncludeExtra ? this.extra : null
29
+ };
30
+ }
31
+ }
32
+ MonitoredError.ERR_CODE_BASE = 1000;
33
+ MonitoredError.NEW_HOOK = (() => { });
@@ -0,0 +1,7 @@
1
+ import { MonitoredError } from "./MonitoredError.js";
2
+ export declare class RuntimeException extends MonitoredError {
3
+ static WRITE_OOB: () => RuntimeException;
4
+ static READ_OOB: () => RuntimeException;
5
+ static UNKNOWN_FORMAT: (pToken: string) => RuntimeException;
6
+ constructor(pMsg: string, pCode?: number, pExtra?: any);
7
+ }
@@ -0,0 +1,15 @@
1
+ import { MonitoredError } from "./MonitoredError.js";
2
+ export class RuntimeException extends MonitoredError {
3
+ constructor(pMsg, pCode = null, pExtra = null) {
4
+ super('DXC-STRUCT', pMsg, pCode, pExtra);
5
+ }
6
+ }
7
+ RuntimeException.WRITE_OOB = () => {
8
+ return new RuntimeException("Write Out-of-Bound", MonitoredError.ERR_CODE_BASE + 1);
9
+ };
10
+ RuntimeException.READ_OOB = () => {
11
+ return new RuntimeException("Read Out-of-Bound", MonitoredError.ERR_CODE_BASE + 2);
12
+ };
13
+ RuntimeException.UNKNOWN_FORMAT = (pToken) => {
14
+ return new RuntimeException("Format is invalid. Following token is not recognized [token=" + pToken + "]", MonitoredError.ERR_CODE_BASE + 3);
15
+ };