@robotical/raftjs 2.0.3 → 2.0.4
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/dist/react-native/RaftDeviceInfo.js +17 -3
- package/dist/react-native/RaftDeviceInfo.js.map +1 -1
- package/dist/react-native/RaftStruct.js +197 -147
- package/dist/react-native/RaftStruct.js.map +1 -1
- package/dist/web/RaftDeviceInfo.js +17 -3
- package/dist/web/RaftDeviceInfo.js.map +1 -1
- package/dist/web/RaftStruct.js +197 -147
- package/dist/web/RaftStruct.js.map +1 -1
- package/package.json +1 -1
- package/src/RaftDeviceInfo.ts +19 -3
- package/src/RaftStruct.ts +220 -147
package/src/RaftStruct.ts
CHANGED
|
@@ -8,77 +8,124 @@
|
|
|
8
8
|
//
|
|
9
9
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
10
10
|
|
|
11
|
+
type FormatInstruction =
|
|
12
|
+
| { kind: "endian"; littleEndian: boolean }
|
|
13
|
+
| { kind: "spec"; code: string; repeat: number };
|
|
14
|
+
|
|
15
|
+
function parseFormatInstructions(format: string): FormatInstruction[] {
|
|
16
|
+
const instructions: FormatInstruction[] = [];
|
|
17
|
+
let idx = 0;
|
|
18
|
+
|
|
19
|
+
while (idx < format.length) {
|
|
20
|
+
|
|
21
|
+
const char = format[idx];
|
|
22
|
+
|
|
23
|
+
// Endianness specifiers
|
|
24
|
+
if (char === "<" || char === ">") {
|
|
25
|
+
instructions.push({ kind: "endian", littleEndian: char === "<" });
|
|
26
|
+
idx++;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Ignore whitespace
|
|
31
|
+
if (/\s/.test(char)) {
|
|
32
|
+
idx++;
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Attribute code
|
|
37
|
+
const code = char;
|
|
38
|
+
idx++;
|
|
39
|
+
|
|
40
|
+
// Check for repeat count using [N] syntax
|
|
41
|
+
let repeat = 1;
|
|
42
|
+
if (idx < format.length && format[idx] === "[") {
|
|
43
|
+
const endIdx = format.indexOf("]", idx + 1);
|
|
44
|
+
if (endIdx === -1) {
|
|
45
|
+
throw new Error(`Invalid format string: missing closing ] in "${format}"`);
|
|
46
|
+
}
|
|
47
|
+
const repeatStr = format.slice(idx + 1, endIdx);
|
|
48
|
+
repeat = parseInt(repeatStr, 10);
|
|
49
|
+
if (!Number.isFinite(repeat) || repeat <= 0) {
|
|
50
|
+
throw new Error(`Invalid repeat count "${repeatStr}" in format string "${format}"`);
|
|
51
|
+
}
|
|
52
|
+
idx = endIdx + 1;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
instructions.push({ kind: "spec", code, repeat });
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return instructions;
|
|
59
|
+
}
|
|
60
|
+
|
|
11
61
|
export function structUnpack(format: string, data: Uint8Array): number[] {
|
|
12
62
|
const view = new DataView(data.buffer, data.byteOffset, data.byteLength);
|
|
13
63
|
const results: number[] = [];
|
|
14
64
|
let offset = 0;
|
|
15
65
|
let littleEndian = false;
|
|
16
66
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
results.push(view.
|
|
62
|
-
offset +=
|
|
63
|
-
break;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
break;
|
|
80
|
-
default:
|
|
81
|
-
throw new Error(`Unknown format character: ${char}`);
|
|
67
|
+
const instructions = parseFormatInstructions(format);
|
|
68
|
+
|
|
69
|
+
for (const instruction of instructions) {
|
|
70
|
+
if (instruction.kind === "endian") {
|
|
71
|
+
littleEndian = instruction.littleEndian;
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const { code, repeat } = instruction;
|
|
76
|
+
|
|
77
|
+
for (let count = 0; count < repeat; count++) {
|
|
78
|
+
switch (code) {
|
|
79
|
+
case "x": // Padding byte
|
|
80
|
+
offset += 1;
|
|
81
|
+
break;
|
|
82
|
+
case "c": // Char
|
|
83
|
+
case "B": // Unsigned 8-bit integer
|
|
84
|
+
case "?": // Boolean (stored as uint8)
|
|
85
|
+
results.push(view.getUint8(offset));
|
|
86
|
+
offset += 1;
|
|
87
|
+
break;
|
|
88
|
+
case "b": // Signed 8-bit integer
|
|
89
|
+
results.push(view.getInt8(offset));
|
|
90
|
+
offset += 1;
|
|
91
|
+
break;
|
|
92
|
+
case "h": // Signed 16-bit integer
|
|
93
|
+
results.push(view.getInt16(offset, littleEndian));
|
|
94
|
+
offset += 2;
|
|
95
|
+
break;
|
|
96
|
+
case "H": // Unsigned 16-bit integer
|
|
97
|
+
results.push(view.getUint16(offset, littleEndian));
|
|
98
|
+
offset += 2;
|
|
99
|
+
break;
|
|
100
|
+
case "i": // Signed 32-bit integer
|
|
101
|
+
case "l": // Signed 32-bit integer
|
|
102
|
+
results.push(view.getInt32(offset, littleEndian));
|
|
103
|
+
offset += 4;
|
|
104
|
+
break;
|
|
105
|
+
case "I": // Unsigned 32-bit integer
|
|
106
|
+
case "L": // Unsigned 32-bit integer
|
|
107
|
+
results.push(view.getUint32(offset, littleEndian));
|
|
108
|
+
offset += 4;
|
|
109
|
+
break;
|
|
110
|
+
// case "q": // Signed 64-bit integer
|
|
111
|
+
// results.push(Number(view.getBigInt64(offset, littleEndian)));
|
|
112
|
+
// offset += 8;
|
|
113
|
+
// break;
|
|
114
|
+
// case "Q": // Unsigned 64-bit integer
|
|
115
|
+
// results.push(Number(view.getBigUint64(offset, littleEndian)));
|
|
116
|
+
// offset += 8;
|
|
117
|
+
// break;
|
|
118
|
+
case "f": // 32-bit float
|
|
119
|
+
results.push(view.getFloat32(offset, littleEndian));
|
|
120
|
+
offset += 4;
|
|
121
|
+
break;
|
|
122
|
+
case "d": // 64-bit float
|
|
123
|
+
results.push(view.getFloat64(offset, littleEndian));
|
|
124
|
+
offset += 8;
|
|
125
|
+
break;
|
|
126
|
+
default:
|
|
127
|
+
throw new Error(`Unknown format character: ${code}`);
|
|
128
|
+
}
|
|
82
129
|
}
|
|
83
130
|
}
|
|
84
131
|
|
|
@@ -87,42 +134,49 @@ export function structUnpack(format: string, data: Uint8Array): number[] {
|
|
|
87
134
|
|
|
88
135
|
export function structSizeOf(format: string): number {
|
|
89
136
|
let size = 0;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
137
|
+
const instructions = parseFormatInstructions(format);
|
|
138
|
+
|
|
139
|
+
for (const instruction of instructions) {
|
|
140
|
+
if (instruction.kind === "endian") {
|
|
141
|
+
continue;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const { code, repeat } = instruction;
|
|
145
|
+
let unitSize: number;
|
|
146
|
+
|
|
147
|
+
switch (code) {
|
|
95
148
|
case "x": // Padding byte
|
|
96
|
-
size += 1;
|
|
97
|
-
break;
|
|
98
149
|
case "c": // Char
|
|
99
150
|
case "b": // Signed 8-bit integer
|
|
100
151
|
case "B": // Unsigned 8-bit integer
|
|
101
|
-
|
|
152
|
+
case "?": // Boolean (uint8)
|
|
153
|
+
unitSize = 1;
|
|
102
154
|
break;
|
|
103
155
|
case "h": // Signed 16-bit integer
|
|
104
156
|
case "H": // Unsigned 16-bit integer
|
|
105
|
-
|
|
157
|
+
unitSize = 2;
|
|
106
158
|
break;
|
|
107
159
|
case "i": // Signed 32-bit integer
|
|
108
160
|
case "I": // Unsigned 32-bit integer
|
|
109
161
|
case "l": // Signed 32-bit integer
|
|
110
162
|
case "L": // Unsigned 32-bit integer
|
|
111
|
-
|
|
163
|
+
unitSize = 4;
|
|
112
164
|
break;
|
|
113
165
|
// case "q": // Signed 64-bit integer
|
|
114
166
|
// case "Q": // Unsigned 64-bit integer
|
|
115
|
-
//
|
|
167
|
+
// unitSize = 8;
|
|
116
168
|
// break;
|
|
117
169
|
case "f": // 32-bit float
|
|
118
|
-
|
|
170
|
+
unitSize = 4;
|
|
119
171
|
break;
|
|
120
172
|
case "d": // 64-bit float
|
|
121
|
-
|
|
173
|
+
unitSize = 8;
|
|
122
174
|
break;
|
|
123
175
|
default:
|
|
124
|
-
throw new Error(`Unknown format character: ${
|
|
176
|
+
throw new Error(`Unknown format character: ${code}`);
|
|
125
177
|
}
|
|
178
|
+
|
|
179
|
+
size += unitSize * repeat;
|
|
126
180
|
}
|
|
127
181
|
return size;
|
|
128
182
|
}
|
|
@@ -134,74 +188,93 @@ export function structPack(format: string, values: number[]): Uint8Array {
|
|
|
134
188
|
let offset = 0;
|
|
135
189
|
let littleEndian = false;
|
|
136
190
|
|
|
137
|
-
const
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
view.
|
|
201
|
-
offset += 8;
|
|
202
|
-
break;
|
|
203
|
-
|
|
204
|
-
|
|
191
|
+
const instructions = parseFormatInstructions(format);
|
|
192
|
+
let valueIdx = 0;
|
|
193
|
+
|
|
194
|
+
for (const instruction of instructions) {
|
|
195
|
+
if (instruction.kind === "endian") {
|
|
196
|
+
littleEndian = instruction.littleEndian;
|
|
197
|
+
continue;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
const { code, repeat } = instruction;
|
|
201
|
+
|
|
202
|
+
for (let count = 0; count < repeat; count++) {
|
|
203
|
+
switch (code) {
|
|
204
|
+
case "x": // Padding byte
|
|
205
|
+
offset += 1;
|
|
206
|
+
break;
|
|
207
|
+
case "c": // Char
|
|
208
|
+
case "b": // Signed 8-bit integer
|
|
209
|
+
if (valueIdx >= values.length) {
|
|
210
|
+
throw new Error("Insufficient values provided for structPack");
|
|
211
|
+
}
|
|
212
|
+
view.setInt8(offset, values[valueIdx++]);
|
|
213
|
+
offset += 1;
|
|
214
|
+
break;
|
|
215
|
+
case "B": // Unsigned 8-bit integer
|
|
216
|
+
case "?": // Boolean (uint8)
|
|
217
|
+
if (valueIdx >= values.length) {
|
|
218
|
+
throw new Error("Insufficient values provided for structPack");
|
|
219
|
+
}
|
|
220
|
+
view.setUint8(offset, values[valueIdx++]);
|
|
221
|
+
offset += 1;
|
|
222
|
+
break;
|
|
223
|
+
case "h": // Signed 16-bit integer
|
|
224
|
+
if (valueIdx >= values.length) {
|
|
225
|
+
throw new Error("Insufficient values provided for structPack");
|
|
226
|
+
}
|
|
227
|
+
view.setInt16(offset, values[valueIdx++], littleEndian);
|
|
228
|
+
offset += 2;
|
|
229
|
+
break;
|
|
230
|
+
case "H": // Unsigned 16-bit integer
|
|
231
|
+
if (valueIdx >= values.length) {
|
|
232
|
+
throw new Error("Insufficient values provided for structPack");
|
|
233
|
+
}
|
|
234
|
+
view.setUint16(offset, values[valueIdx++], littleEndian);
|
|
235
|
+
offset += 2;
|
|
236
|
+
break;
|
|
237
|
+
case "i": // Signed 32-bit integer
|
|
238
|
+
case "l": // Signed 32-bit integer
|
|
239
|
+
if (valueIdx >= values.length) {
|
|
240
|
+
throw new Error("Insufficient values provided for structPack");
|
|
241
|
+
}
|
|
242
|
+
view.setInt32(offset, values[valueIdx++], littleEndian);
|
|
243
|
+
offset += 4;
|
|
244
|
+
break;
|
|
245
|
+
case "I": // Unsigned 32-bit integer
|
|
246
|
+
case "L": // Unsigned 32-bit integer
|
|
247
|
+
if (valueIdx >= values.length) {
|
|
248
|
+
throw new Error("Insufficient values provided for structPack");
|
|
249
|
+
}
|
|
250
|
+
view.setUint32(offset, values[valueIdx++], littleEndian);
|
|
251
|
+
offset += 4;
|
|
252
|
+
break;
|
|
253
|
+
// case "q": // Signed 64-bit integer
|
|
254
|
+
// view.setBigInt64(offset, BigInt(values[valueIdx++]), littleEndian);
|
|
255
|
+
// offset += 8;
|
|
256
|
+
// break;
|
|
257
|
+
// case "Q": // Unsigned 64-bit integer
|
|
258
|
+
// view.setBigUint64(offset, BigInt(values[valueIdx++]), littleEndian);
|
|
259
|
+
// offset += 8;
|
|
260
|
+
// break;
|
|
261
|
+
case "f": // 32-bit float
|
|
262
|
+
if (valueIdx >= values.length) {
|
|
263
|
+
throw new Error("Insufficient values provided for structPack");
|
|
264
|
+
}
|
|
265
|
+
view.setFloat32(offset, values[valueIdx++], littleEndian);
|
|
266
|
+
offset += 4;
|
|
267
|
+
break;
|
|
268
|
+
case "d": // 64-bit float
|
|
269
|
+
if (valueIdx >= values.length) {
|
|
270
|
+
throw new Error("Insufficient values provided for structPack");
|
|
271
|
+
}
|
|
272
|
+
view.setFloat64(offset, values[valueIdx++], littleEndian);
|
|
273
|
+
offset += 8;
|
|
274
|
+
break;
|
|
275
|
+
default:
|
|
276
|
+
throw new Error(`Unknown format character: ${code}`);
|
|
277
|
+
}
|
|
205
278
|
}
|
|
206
279
|
}
|
|
207
280
|
|