@naeemo/capnp 0.8.1 → 0.9.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.
@@ -0,0 +1,848 @@
1
+ #!/usr/bin/env node
2
+ //#region src/core/pointer.ts
3
+ /**
4
+ * Cap'n Proto 指针编解码
5
+ * 纯 TypeScript 实现
6
+ */
7
+ let PointerTag = /* @__PURE__ */ function(PointerTag) {
8
+ PointerTag[PointerTag["STRUCT"] = 0] = "STRUCT";
9
+ PointerTag[PointerTag["LIST"] = 1] = "LIST";
10
+ PointerTag[PointerTag["FAR"] = 2] = "FAR";
11
+ PointerTag[PointerTag["OTHER"] = 3] = "OTHER";
12
+ return PointerTag;
13
+ }({});
14
+ let ElementSize = /* @__PURE__ */ function(ElementSize) {
15
+ ElementSize[ElementSize["VOID"] = 0] = "VOID";
16
+ ElementSize[ElementSize["BIT"] = 1] = "BIT";
17
+ ElementSize[ElementSize["BYTE"] = 2] = "BYTE";
18
+ ElementSize[ElementSize["TWO_BYTES"] = 3] = "TWO_BYTES";
19
+ ElementSize[ElementSize["FOUR_BYTES"] = 4] = "FOUR_BYTES";
20
+ ElementSize[ElementSize["EIGHT_BYTES"] = 5] = "EIGHT_BYTES";
21
+ ElementSize[ElementSize["POINTER"] = 6] = "POINTER";
22
+ ElementSize[ElementSize["COMPOSITE"] = 7] = "COMPOSITE";
23
+ ElementSize[ElementSize["INLINE_COMPOSITE"] = 7] = "INLINE_COMPOSITE";
24
+ return ElementSize;
25
+ }({});
26
+ /**
27
+ * 解码指针(64位)
28
+ */
29
+ function decodePointer(ptr) {
30
+ const tag = Number(ptr & BigInt(3));
31
+ switch (tag) {
32
+ case PointerTag.STRUCT: {
33
+ const offset = Number(ptr >> BigInt(2)) & 1073741823;
34
+ return {
35
+ tag,
36
+ offset: offset >= 536870912 ? offset - 1073741824 : offset,
37
+ dataWords: Number(ptr >> BigInt(32) & BigInt(65535)),
38
+ pointerCount: Number(ptr >> BigInt(48) & BigInt(65535))
39
+ };
40
+ }
41
+ case PointerTag.LIST: {
42
+ const offset = Number(ptr >> BigInt(2)) & 1073741823;
43
+ return {
44
+ tag,
45
+ offset: offset >= 536870912 ? offset - 1073741824 : offset,
46
+ elementSize: Number(ptr >> BigInt(32) & BigInt(7)),
47
+ elementCount: Number(ptr >> BigInt(35) & BigInt(536870911))
48
+ };
49
+ }
50
+ case PointerTag.FAR: {
51
+ const doubleFar = Boolean(ptr >> BigInt(2) & BigInt(1));
52
+ const targetOffset = Number(ptr >> BigInt(3) & BigInt(536870911));
53
+ return {
54
+ tag,
55
+ doubleFar,
56
+ targetSegment: Number(ptr >> BigInt(32) & BigInt(4294967295)),
57
+ targetOffset
58
+ };
59
+ }
60
+ default: return { tag: PointerTag.OTHER };
61
+ }
62
+ }
63
+ /**
64
+ * 编码 Struct 指针
65
+ */
66
+ function encodeStructPointer(offset, dataWords, pointerCount) {
67
+ return (BigInt(offset < 0 ? offset + 1073741824 : offset) & BigInt(1073741823)) << BigInt(2) | BigInt(dataWords) << BigInt(32) | BigInt(pointerCount) << BigInt(48);
68
+ }
69
+ /**
70
+ * 编码 List 指针
71
+ */
72
+ function encodeListPointer(offset, elementSize, elementCount) {
73
+ return (BigInt(offset < 0 ? offset + 1073741824 : offset) & BigInt(1073741823)) << BigInt(2) | BigInt(1) | BigInt(elementSize) << BigInt(32) | BigInt(elementCount) << BigInt(35);
74
+ }
75
+
76
+ //#endregion
77
+ //#region src/core/segment.ts
78
+ /**
79
+ * Cap'n Proto Segment 管理
80
+ * 纯 TypeScript 实现
81
+ */
82
+ const WORD_SIZE = 8;
83
+ var Segment = class Segment {
84
+ buffer;
85
+ view;
86
+ _size;
87
+ constructor(initialCapacity = 1024) {
88
+ this.buffer = new ArrayBuffer(initialCapacity);
89
+ this.view = new DataView(this.buffer);
90
+ this._size = 0;
91
+ }
92
+ /**
93
+ * 从现有 buffer 创建(用于读取)
94
+ */
95
+ static fromBuffer(buffer) {
96
+ const seg = new Segment(0);
97
+ seg.buffer = buffer;
98
+ seg.view = new DataView(buffer);
99
+ seg._size = buffer.byteLength;
100
+ return seg;
101
+ }
102
+ /**
103
+ * 确保容量足够
104
+ */
105
+ ensureCapacity(minBytes) {
106
+ if (this.buffer.byteLength >= minBytes) return;
107
+ let newCapacity = this.buffer.byteLength * 2;
108
+ while (newCapacity < minBytes) newCapacity *= 2;
109
+ const newBuffer = new ArrayBuffer(newCapacity);
110
+ new Uint8Array(newBuffer).set(new Uint8Array(this.buffer, 0, this._size));
111
+ this.buffer = newBuffer;
112
+ this.view = new DataView(newBuffer);
113
+ }
114
+ /**
115
+ * 分配空间,返回字偏移
116
+ */
117
+ allocate(words) {
118
+ const bytes = words * WORD_SIZE;
119
+ const offset = this._size;
120
+ this.ensureCapacity(offset + bytes);
121
+ this._size = offset + bytes;
122
+ return offset / WORD_SIZE;
123
+ }
124
+ /**
125
+ * 获取字(64位)
126
+ */
127
+ getWord(wordOffset) {
128
+ const byteOffset = wordOffset * WORD_SIZE;
129
+ if (byteOffset + 8 > this._size) throw new Error(`Offset ${wordOffset} is outside the bounds of the segment (${this.wordCount} words)`);
130
+ const low = BigInt(this.view.getUint32(byteOffset, true));
131
+ return BigInt(this.view.getUint32(byteOffset + 4, true)) << BigInt(32) | low;
132
+ }
133
+ /**
134
+ * 设置字(64位)
135
+ */
136
+ setWord(wordOffset, value) {
137
+ const byteOffset = wordOffset * WORD_SIZE;
138
+ if (byteOffset + 8 > this.buffer.byteLength) throw new Error(`Offset ${wordOffset} is outside the bounds of the segment`);
139
+ this.view.setUint32(byteOffset, Number(value & BigInt(4294967295)), true);
140
+ this.view.setUint32(byteOffset + 4, Number(value >> BigInt(32)), true);
141
+ }
142
+ /**
143
+ * 获取原始 buffer(只读到 _size)
144
+ */
145
+ asUint8Array() {
146
+ return new Uint8Array(this.buffer, 0, this._size);
147
+ }
148
+ /**
149
+ * 获取底层 ArrayBuffer
150
+ */
151
+ getArrayBuffer() {
152
+ return this.buffer;
153
+ }
154
+ /**
155
+ * 获取字数量
156
+ */
157
+ get wordCount() {
158
+ return this._size / WORD_SIZE;
159
+ }
160
+ /**
161
+ * 获取字节数量
162
+ */
163
+ get byteLength() {
164
+ return this._size;
165
+ }
166
+ /**
167
+ * 获取 DataView
168
+ */
169
+ get dataView() {
170
+ return this.view;
171
+ }
172
+ };
173
+
174
+ //#endregion
175
+ //#region src/core/message-builder.ts
176
+ /**
177
+ * Cap'n Proto MessageBuilder
178
+ * 纯 TypeScript 实现
179
+ */
180
+ var MessageBuilder = class {
181
+ segment;
182
+ rootSet = false;
183
+ constructor() {
184
+ this.segment = new Segment(1024);
185
+ this.segment.allocate(1);
186
+ }
187
+ /**
188
+ * 初始化根结构
189
+ */
190
+ initRoot(dataWords, pointerCount) {
191
+ if (this.rootSet) throw new Error("Root already initialized");
192
+ const size = dataWords + pointerCount;
193
+ const structOffset = this.segment.allocate(size);
194
+ const rootPtr = encodeStructPointer(structOffset - 1, dataWords, pointerCount);
195
+ this.segment.setWord(0, rootPtr);
196
+ this.rootSet = true;
197
+ return new StructBuilder(this, 0, structOffset, dataWords, pointerCount);
198
+ }
199
+ /**
200
+ * 序列化为 ArrayBuffer
201
+ */
202
+ toArrayBuffer() {
203
+ const segmentData = this.segment.asUint8Array();
204
+ const wordCount = this.segment.wordCount;
205
+ const header = /* @__PURE__ */ new ArrayBuffer(8);
206
+ const headerView = new DataView(header);
207
+ headerView.setUint32(0, 0, true);
208
+ headerView.setUint32(4, wordCount, true);
209
+ const result = new Uint8Array(8 + segmentData.byteLength);
210
+ result.set(new Uint8Array(header), 0);
211
+ result.set(segmentData, 8);
212
+ return result.buffer;
213
+ }
214
+ /**
215
+ * 获取段(内部使用)
216
+ */
217
+ getSegment() {
218
+ return this.segment;
219
+ }
220
+ };
221
+ /**
222
+ * 结构构建器
223
+ */
224
+ var StructBuilder = class StructBuilder {
225
+ constructor(message, segmentIndex, wordOffset, dataWords, pointerCount) {
226
+ this.message = message;
227
+ this.segmentIndex = segmentIndex;
228
+ this.wordOffset = wordOffset;
229
+ this.dataWords = dataWords;
230
+ this.pointerCount = pointerCount;
231
+ }
232
+ /**
233
+ * 设置 bool 字段
234
+ */
235
+ setBool(bitOffset, value) {
236
+ const byteOffset = Math.floor(bitOffset / 8);
237
+ const bitInByte = bitOffset % 8;
238
+ const view = this.message.getSegment().dataView;
239
+ const offset = this.wordOffset * WORD_SIZE + byteOffset;
240
+ const current = view.getUint8(offset);
241
+ const newValue = value ? current | 1 << bitInByte : current & ~(1 << bitInByte);
242
+ view.setUint8(offset, newValue);
243
+ }
244
+ /**
245
+ * 设置 int8 字段
246
+ */
247
+ setInt8(byteOffset, value) {
248
+ this.message.getSegment().dataView.setInt8(this.wordOffset * WORD_SIZE + byteOffset, value);
249
+ }
250
+ /**
251
+ * 设置 int16 字段
252
+ */
253
+ setInt16(byteOffset, value) {
254
+ this.message.getSegment().dataView.setInt16(this.wordOffset * WORD_SIZE + byteOffset, value, true);
255
+ }
256
+ /**
257
+ * 设置 int32 字段
258
+ */
259
+ setInt32(byteOffset, value) {
260
+ this.message.getSegment().dataView.setInt32(this.wordOffset * WORD_SIZE + byteOffset, value, true);
261
+ }
262
+ /**
263
+ * 设置 int64 字段
264
+ */
265
+ setInt64(byteOffset, value) {
266
+ const segment = this.message.getSegment();
267
+ const offset = this.wordOffset * WORD_SIZE + byteOffset;
268
+ segment.dataView.setUint32(offset, Number(value & BigInt(4294967295)), true);
269
+ segment.dataView.setInt32(offset + 4, Number(value >> BigInt(32)), true);
270
+ }
271
+ /**
272
+ * 设置 uint8 字段
273
+ */
274
+ setUint8(byteOffset, value) {
275
+ this.message.getSegment().dataView.setUint8(this.wordOffset * WORD_SIZE + byteOffset, value);
276
+ }
277
+ /**
278
+ * 设置 uint16 字段
279
+ */
280
+ setUint16(byteOffset, value) {
281
+ this.message.getSegment().dataView.setUint16(this.wordOffset * WORD_SIZE + byteOffset, value, true);
282
+ }
283
+ /**
284
+ * 设置 uint32 字段
285
+ */
286
+ setUint32(byteOffset, value) {
287
+ this.message.getSegment().dataView.setUint32(this.wordOffset * WORD_SIZE + byteOffset, value, true);
288
+ }
289
+ /**
290
+ * 设置 uint64 字段
291
+ */
292
+ setUint64(byteOffset, value) {
293
+ const segment = this.message.getSegment();
294
+ const offset = this.wordOffset * WORD_SIZE + byteOffset;
295
+ segment.dataView.setUint32(offset, Number(value & BigInt(4294967295)), true);
296
+ segment.dataView.setUint32(offset + 4, Number(value >> BigInt(32)), true);
297
+ }
298
+ /**
299
+ * 设置 float32 字段
300
+ */
301
+ setFloat32(byteOffset, value) {
302
+ this.message.getSegment().dataView.setFloat32(this.wordOffset * WORD_SIZE + byteOffset, value, true);
303
+ }
304
+ /**
305
+ * 设置 float64 字段
306
+ */
307
+ setFloat64(byteOffset, value) {
308
+ this.message.getSegment().dataView.setFloat64(this.wordOffset * WORD_SIZE + byteOffset, value, true);
309
+ }
310
+ /**
311
+ * 获取 uint16 字段(用于 UnionBuilder 读取 tag)
312
+ */
313
+ getUint16(byteOffset) {
314
+ return this.message.getSegment().dataView.getUint16(this.wordOffset * WORD_SIZE + byteOffset, true);
315
+ }
316
+ /**
317
+ * 设置文本字段
318
+ */
319
+ setText(pointerIndex, value) {
320
+ const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;
321
+ const segment = this.message.getSegment();
322
+ const bytes = new TextEncoder().encode(`${value}\0`);
323
+ const wordCount = Math.ceil(bytes.length / WORD_SIZE);
324
+ const listOffset = segment.allocate(wordCount);
325
+ new Uint8Array(segment.dataView.buffer, listOffset * WORD_SIZE, bytes.length).set(bytes);
326
+ const ptr = encodeListPointer(listOffset - ptrOffset - 1, ElementSize.BYTE, bytes.length);
327
+ segment.setWord(ptrOffset, ptr);
328
+ }
329
+ /**
330
+ * 设置数据字段(Uint8Array)
331
+ * @param pointerIndex - 指针索引
332
+ * @param value - Uint8Array 数据
333
+ */
334
+ setData(pointerIndex, value) {
335
+ const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;
336
+ const segment = this.message.getSegment();
337
+ if (value.length === 0) {
338
+ const ptr = encodeListPointer(0, ElementSize.BYTE, 0);
339
+ segment.setWord(ptrOffset, ptr);
340
+ return;
341
+ }
342
+ const wordCount = Math.ceil(value.length / WORD_SIZE);
343
+ const listOffset = segment.allocate(wordCount);
344
+ new Uint8Array(segment.dataView.buffer, listOffset * WORD_SIZE, value.length).set(value);
345
+ const ptr = encodeListPointer(listOffset - ptrOffset - 1, ElementSize.BYTE, value.length);
346
+ segment.setWord(ptrOffset, ptr);
347
+ }
348
+ /**
349
+ * 初始化嵌套结构
350
+ */
351
+ initStruct(pointerIndex, dataWords, pointerCount) {
352
+ const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;
353
+ const segment = this.message.getSegment();
354
+ const size = dataWords + pointerCount;
355
+ const structOffset = segment.allocate(size);
356
+ const ptr = encodeStructPointer(structOffset - ptrOffset - 1, dataWords, pointerCount);
357
+ segment.setWord(ptrOffset, ptr);
358
+ return new StructBuilder(this.message, 0, structOffset, dataWords, pointerCount);
359
+ }
360
+ /**
361
+ * 初始化列表
362
+ */
363
+ initList(pointerIndex, elementSize, elementCount, structSize) {
364
+ const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;
365
+ const segment = this.message.getSegment();
366
+ let elementWords = 1;
367
+ if (elementSize === ElementSize.BYTE) elementWords = 1;
368
+ else if (elementSize === ElementSize.TWO_BYTES) elementWords = 1;
369
+ else if (elementSize === ElementSize.FOUR_BYTES) elementWords = 1;
370
+ else if (elementSize === ElementSize.EIGHT_BYTES) elementWords = 1;
371
+ else if (elementSize === ElementSize.COMPOSITE && structSize) elementWords = structSize.dataWords + structSize.pointerCount;
372
+ const totalWords = elementWords * elementCount;
373
+ const listOffset = segment.allocate(totalWords);
374
+ const ptr = encodeListPointer(listOffset - ptrOffset - 1, elementSize, elementCount);
375
+ segment.setWord(ptrOffset, ptr);
376
+ return new ListBuilder(this.message, elementSize, elementCount, structSize, listOffset);
377
+ }
378
+ };
379
+
380
+ //#endregion
381
+ //#region src/core/list.ts
382
+ /**
383
+ * Cap'n Proto List 实现
384
+ * 纯 TypeScript
385
+ */
386
+ /**
387
+ * ListReader - 读取列表
388
+ */
389
+ var ListReader = class {
390
+ segment;
391
+ startOffset;
392
+ segmentIndex;
393
+ constructor(message, segmentIndex, elementSize, elementCount, structSize, wordOffset) {
394
+ this.message = message;
395
+ this.elementSize = elementSize;
396
+ this.elementCount = elementCount;
397
+ this.structSize = structSize;
398
+ this.segmentIndex = segmentIndex;
399
+ this.segment = message.getSegment(segmentIndex);
400
+ this.startOffset = wordOffset;
401
+ }
402
+ /**
403
+ * 列表长度
404
+ */
405
+ get length() {
406
+ return this.elementCount;
407
+ }
408
+ /**
409
+ * 获取元素(基础类型)
410
+ */
411
+ getPrimitive(index) {
412
+ if (index < 0 || index >= this.elementCount) throw new RangeError("Index out of bounds");
413
+ switch (this.elementSize) {
414
+ case ElementSize.BIT: {
415
+ const byteOffset = Math.floor(index / 8);
416
+ const bitInByte = index % 8;
417
+ return (this.segment.dataView.getUint8(this.startOffset * WORD_SIZE + byteOffset) & 1 << bitInByte) !== 0 ? 1 : 0;
418
+ }
419
+ case ElementSize.BYTE: return this.segment.dataView.getUint8(this.startOffset * WORD_SIZE + index);
420
+ case ElementSize.TWO_BYTES: return this.segment.dataView.getUint16(this.startOffset * WORD_SIZE + index * 2, true);
421
+ case ElementSize.FOUR_BYTES: return this.segment.dataView.getUint32(this.startOffset * WORD_SIZE + index * 4, true);
422
+ case ElementSize.EIGHT_BYTES: {
423
+ const offset = this.startOffset * WORD_SIZE + index * 8;
424
+ const low = BigInt(this.segment.dataView.getUint32(offset, true));
425
+ return BigInt(this.segment.dataView.getUint32(offset + 4, true)) << BigInt(32) | low;
426
+ }
427
+ default: throw new Error(`Unsupported element size: ${this.elementSize}`);
428
+ }
429
+ }
430
+ /**
431
+ * 获取结构元素
432
+ */
433
+ getStruct(index) {
434
+ if (!this.structSize) throw new Error("Not a struct list");
435
+ const { dataWords, pointerCount } = this.structSize;
436
+ const size = dataWords + pointerCount;
437
+ const offset = this.startOffset + index * size;
438
+ return new StructReader(this.message, this.segmentIndex, offset, dataWords, pointerCount);
439
+ }
440
+ /**
441
+ * 迭代器
442
+ */
443
+ *[Symbol.iterator]() {
444
+ for (let i = 0; i < this.elementCount; i++) yield this.getPrimitive(i);
445
+ }
446
+ };
447
+ /**
448
+ * ListBuilder - 构建列表
449
+ */
450
+ var ListBuilder = class {
451
+ segment;
452
+ startOffset;
453
+ constructor(message, elementSize, elementCount, structSize, wordOffset) {
454
+ this.message = message;
455
+ this.elementSize = elementSize;
456
+ this.elementCount = elementCount;
457
+ this.structSize = structSize;
458
+ this.segment = message.getSegment();
459
+ this.startOffset = wordOffset;
460
+ }
461
+ /**
462
+ * 列表长度
463
+ */
464
+ get length() {
465
+ return this.elementCount;
466
+ }
467
+ /**
468
+ * 设置基础类型元素
469
+ */
470
+ setPrimitive(index, value) {
471
+ if (index < 0 || index >= this.elementCount) throw new RangeError("Index out of bounds");
472
+ switch (this.elementSize) {
473
+ case ElementSize.BIT: {
474
+ const byteOffset = Math.floor(index / 8);
475
+ const bitInByte = index % 8;
476
+ const offset = this.startOffset * WORD_SIZE + byteOffset;
477
+ const current = this.segment.dataView.getUint8(offset);
478
+ const newValue = value ? current | 1 << bitInByte : current & ~(1 << bitInByte);
479
+ this.segment.dataView.setUint8(offset, newValue);
480
+ break;
481
+ }
482
+ case ElementSize.BYTE:
483
+ this.segment.dataView.setUint8(this.startOffset * WORD_SIZE + index, Number(value));
484
+ break;
485
+ case ElementSize.TWO_BYTES:
486
+ this.segment.dataView.setUint16(this.startOffset * WORD_SIZE + index * 2, Number(value), true);
487
+ break;
488
+ case ElementSize.FOUR_BYTES:
489
+ this.segment.dataView.setUint32(this.startOffset * WORD_SIZE + index * 4, Number(value), true);
490
+ break;
491
+ case ElementSize.EIGHT_BYTES: {
492
+ const offset = this.startOffset * WORD_SIZE + index * 8;
493
+ const bigValue = value;
494
+ this.segment.dataView.setUint32(offset, Number(bigValue & BigInt(4294967295)), true);
495
+ this.segment.dataView.setUint32(offset + 4, Number(bigValue >> BigInt(32)), true);
496
+ break;
497
+ }
498
+ default: throw new Error(`Unsupported element size: ${this.elementSize}`);
499
+ }
500
+ }
501
+ /**
502
+ * 获取结构元素(用于修改)
503
+ */
504
+ getStruct(index) {
505
+ if (!this.structSize) throw new Error("Not a struct list");
506
+ const { dataWords, pointerCount } = this.structSize;
507
+ const size = dataWords + pointerCount;
508
+ const offset = this.startOffset + index * size;
509
+ return new StructBuilder(this.message, 0, offset, dataWords, pointerCount);
510
+ }
511
+ };
512
+
513
+ //#endregion
514
+ //#region src/core/message-reader.ts
515
+ /**
516
+ * Cap'n Proto MessageReader
517
+ * 纯 TypeScript 实现
518
+ */
519
+ var MessageReader = class {
520
+ segments;
521
+ constructor(buffer) {
522
+ const uint8Array = buffer instanceof ArrayBuffer ? new Uint8Array(buffer) : buffer;
523
+ this.segments = [];
524
+ if (uint8Array.byteLength < 8) return;
525
+ const view = new DataView(uint8Array.buffer, uint8Array.byteOffset, uint8Array.byteLength);
526
+ const firstWordLow = view.getUint32(0, true);
527
+ const firstWordHigh = view.getUint32(4, true);
528
+ const segmentCount = (firstWordLow & 4294967295) + 1;
529
+ const firstSegmentSize = firstWordHigh;
530
+ let offset = 8;
531
+ const segmentSizes = [firstSegmentSize];
532
+ for (let i = 1; i < segmentCount; i++) {
533
+ if (offset + 4 > uint8Array.byteLength) {
534
+ this.segments = [];
535
+ return;
536
+ }
537
+ segmentSizes.push(view.getUint32(offset, true));
538
+ offset += 4;
539
+ }
540
+ offset = offset + 7 & -8;
541
+ if (offset > uint8Array.byteLength) {
542
+ this.segments = [];
543
+ return;
544
+ }
545
+ this.segments = [];
546
+ for (const size of segmentSizes) {
547
+ if (offset + size * WORD_SIZE > uint8Array.byteLength) break;
548
+ const segmentBuffer = uint8Array.slice(offset, offset + size * WORD_SIZE);
549
+ this.segments.push(Segment.fromBuffer(segmentBuffer.buffer));
550
+ offset += size * WORD_SIZE;
551
+ }
552
+ }
553
+ /**
554
+ * 获取根结构
555
+ */
556
+ getRoot(_dataWords, _pointerCount) {
557
+ const segment = this.segments[0];
558
+ const ptr = decodePointer(segment.getWord(0));
559
+ if (ptr.tag === PointerTag.STRUCT) {
560
+ const structPtr = ptr;
561
+ const dataOffset = 1 + structPtr.offset;
562
+ return new StructReader(this, 0, dataOffset, structPtr.dataWords, structPtr.pointerCount);
563
+ }
564
+ if (ptr.tag === PointerTag.FAR) {
565
+ const farPtr = ptr;
566
+ const targetSegment = this.getSegment(farPtr.targetSegment);
567
+ if (!targetSegment) throw new Error(`Far pointer references non-existent segment ${farPtr.targetSegment}`);
568
+ if (farPtr.doubleFar) {
569
+ const landingPadPtr = decodePointer(targetSegment.getWord(farPtr.targetOffset));
570
+ if (landingPadPtr.tag !== PointerTag.FAR) throw new Error("Double-far landing pad is not a far pointer");
571
+ const innerFarPtr = landingPadPtr;
572
+ const finalSegment = this.getSegment(innerFarPtr.targetSegment);
573
+ if (!finalSegment) throw new Error(`Double-far references non-existent segment ${innerFarPtr.targetSegment}`);
574
+ const structPtr = decodePointer(finalSegment.getWord(innerFarPtr.targetOffset));
575
+ const dataOffset = innerFarPtr.targetOffset + 1 + structPtr.offset;
576
+ return new StructReader(this, innerFarPtr.targetSegment, dataOffset, structPtr.dataWords, structPtr.pointerCount);
577
+ }
578
+ const structPtr = decodePointer(targetSegment.getWord(farPtr.targetOffset));
579
+ const dataOffset = farPtr.targetOffset + 1 + structPtr.offset;
580
+ return new StructReader(this, farPtr.targetSegment, dataOffset, structPtr.dataWords, structPtr.pointerCount);
581
+ }
582
+ throw new Error(`Root pointer is not a struct or far pointer: ${ptr.tag}`);
583
+ }
584
+ /**
585
+ * 获取段
586
+ */
587
+ getSegment(index) {
588
+ return this.segments[index];
589
+ }
590
+ /**
591
+ * 解析指针,处理 far pointer 间接寻址
592
+ * 返回 { segmentIndex, wordOffset, pointer },其中 pointer 是实际的 struct/list 指针
593
+ */
594
+ resolvePointer(segmentIndex, wordOffset) {
595
+ const segment = this.getSegment(segmentIndex);
596
+ if (!segment) return null;
597
+ const ptrValue = segment.getWord(wordOffset);
598
+ if (ptrValue === 0n) return null;
599
+ const ptr = decodePointer(ptrValue);
600
+ if (ptr.tag === PointerTag.STRUCT || ptr.tag === PointerTag.LIST) return {
601
+ segmentIndex,
602
+ wordOffset: wordOffset + 1 + ptr.offset,
603
+ pointer: ptr
604
+ };
605
+ if (ptr.tag === PointerTag.FAR) {
606
+ const farPtr = ptr;
607
+ const targetSegment = this.getSegment(farPtr.targetSegment);
608
+ if (!targetSegment) return null;
609
+ if (farPtr.doubleFar) {
610
+ const landingPadPtr = decodePointer(targetSegment.getWord(farPtr.targetOffset));
611
+ if (landingPadPtr.tag !== PointerTag.FAR) return null;
612
+ const innerFarPtr = landingPadPtr;
613
+ const finalSegment = this.getSegment(innerFarPtr.targetSegment);
614
+ if (!finalSegment) return null;
615
+ const finalPtr = decodePointer(finalSegment.getWord(innerFarPtr.targetOffset));
616
+ if (finalPtr.tag !== PointerTag.STRUCT && finalPtr.tag !== PointerTag.LIST) return null;
617
+ const targetOffset = innerFarPtr.targetOffset + 1 + finalPtr.offset;
618
+ return {
619
+ segmentIndex: innerFarPtr.targetSegment,
620
+ wordOffset: targetOffset,
621
+ pointer: finalPtr
622
+ };
623
+ }
624
+ const landingPadPtr = decodePointer(targetSegment.getWord(farPtr.targetOffset));
625
+ if (landingPadPtr.tag !== PointerTag.STRUCT && landingPadPtr.tag !== PointerTag.LIST) return null;
626
+ const targetOffset = farPtr.targetOffset + 1 + landingPadPtr.offset;
627
+ return {
628
+ segmentIndex: farPtr.targetSegment,
629
+ wordOffset: targetOffset,
630
+ pointer: landingPadPtr
631
+ };
632
+ }
633
+ return null;
634
+ }
635
+ /**
636
+ * 段数量
637
+ */
638
+ get segmentCount() {
639
+ return this.segments.length;
640
+ }
641
+ };
642
+ /**
643
+ * 结构读取器
644
+ */
645
+ var StructReader = class StructReader {
646
+ constructor(message, segmentIndex, wordOffset, dataWords, pointerCount) {
647
+ this.message = message;
648
+ this.segmentIndex = segmentIndex;
649
+ this.wordOffset = wordOffset;
650
+ this.dataWords = dataWords;
651
+ this.pointerCount = pointerCount;
652
+ }
653
+ /**
654
+ * 获取 bool 字段
655
+ */
656
+ getBool(bitOffset) {
657
+ const byteOffset = Math.floor(bitOffset / 8);
658
+ const bitInByte = bitOffset % 8;
659
+ const segment = this.message.getSegment(this.segmentIndex);
660
+ const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;
661
+ const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;
662
+ if (dataOffset < 0 || dataOffset >= dataSectionEnd) return false;
663
+ return (segment.dataView.getUint8(dataOffset) & 1 << bitInByte) !== 0;
664
+ }
665
+ /**
666
+ * 获取 int8 字段
667
+ */
668
+ getInt8(byteOffset) {
669
+ const segment = this.message.getSegment(this.segmentIndex);
670
+ const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;
671
+ const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;
672
+ if (dataOffset < 0 || dataOffset >= dataSectionEnd) return 0;
673
+ return segment.dataView.getInt8(dataOffset);
674
+ }
675
+ /**
676
+ * 获取 int16 字段
677
+ */
678
+ getInt16(byteOffset) {
679
+ const segment = this.message.getSegment(this.segmentIndex);
680
+ const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;
681
+ const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;
682
+ if (dataOffset < 0 || dataOffset + 2 > dataSectionEnd) return 0;
683
+ return segment.dataView.getInt16(dataOffset, true);
684
+ }
685
+ /**
686
+ * 获取 int32 字段
687
+ */
688
+ getInt32(byteOffset) {
689
+ const segment = this.message.getSegment(this.segmentIndex);
690
+ const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;
691
+ const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;
692
+ if (dataOffset < 0 || dataOffset + 4 > dataSectionEnd) return 0;
693
+ return segment.dataView.getInt32(dataOffset, true);
694
+ }
695
+ /**
696
+ * 获取 int64 字段
697
+ */
698
+ getInt64(byteOffset) {
699
+ const segment = this.message.getSegment(this.segmentIndex);
700
+ const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;
701
+ const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;
702
+ if (dataOffset < 0 || dataOffset + 8 > dataSectionEnd) return BigInt(0);
703
+ const low = BigInt(segment.dataView.getUint32(dataOffset, true));
704
+ return BigInt(segment.dataView.getInt32(dataOffset + 4, true)) << BigInt(32) | low;
705
+ }
706
+ /**
707
+ * 获取 uint8 字段
708
+ */
709
+ getUint8(byteOffset) {
710
+ const segment = this.message.getSegment(this.segmentIndex);
711
+ const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;
712
+ const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;
713
+ if (dataOffset < 0 || dataOffset >= dataSectionEnd) return 0;
714
+ return segment.dataView.getUint8(dataOffset);
715
+ }
716
+ /**
717
+ * 获取 uint16 字段
718
+ */
719
+ getUint16(byteOffset) {
720
+ const segment = this.message.getSegment(this.segmentIndex);
721
+ const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;
722
+ const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;
723
+ if (dataOffset < 0 || dataOffset + 2 > dataSectionEnd) return 0;
724
+ return segment.dataView.getUint16(dataOffset, true);
725
+ }
726
+ /**
727
+ * 获取 uint32 字段
728
+ */
729
+ getUint32(byteOffset) {
730
+ const segment = this.message.getSegment(this.segmentIndex);
731
+ const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;
732
+ const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;
733
+ if (dataOffset < 0 || dataOffset + 4 > dataSectionEnd) return 0;
734
+ return segment.dataView.getUint32(dataOffset, true);
735
+ }
736
+ /**
737
+ * 获取 uint64 字段
738
+ */
739
+ getUint64(byteOffset) {
740
+ const segment = this.message.getSegment(this.segmentIndex);
741
+ const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;
742
+ const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;
743
+ if (dataOffset < 0 || dataOffset + 8 > dataSectionEnd) return BigInt(0);
744
+ const low = BigInt(segment.dataView.getUint32(dataOffset, true));
745
+ return BigInt(segment.dataView.getUint32(dataOffset + 4, true)) << BigInt(32) | low;
746
+ }
747
+ /**
748
+ * 获取 float32 字段
749
+ */
750
+ getFloat32(byteOffset) {
751
+ const segment = this.message.getSegment(this.segmentIndex);
752
+ const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;
753
+ const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;
754
+ if (dataOffset < 0 || dataOffset + 4 > dataSectionEnd) return 0;
755
+ return segment.dataView.getFloat32(dataOffset, true);
756
+ }
757
+ /**
758
+ * 获取 float64 字段
759
+ */
760
+ getFloat64(byteOffset) {
761
+ const segment = this.message.getSegment(this.segmentIndex);
762
+ const dataOffset = this.wordOffset * WORD_SIZE + byteOffset;
763
+ const dataSectionEnd = this.wordOffset * WORD_SIZE + this.dataWords * WORD_SIZE;
764
+ if (dataOffset < 0 || dataOffset + 8 > dataSectionEnd) return 0;
765
+ return segment.dataView.getFloat64(dataOffset, true);
766
+ }
767
+ /**
768
+ * 获取文本字段
769
+ */
770
+ getText(pointerIndex) {
771
+ const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;
772
+ const resolved = this.message.resolvePointer(this.segmentIndex, ptrOffset);
773
+ if (!resolved) return "";
774
+ const { segmentIndex, wordOffset, pointer } = resolved;
775
+ if (pointer.tag !== PointerTag.LIST) return "";
776
+ const listPtr = pointer;
777
+ const segment = this.message.getSegment(segmentIndex);
778
+ const byteLength = listPtr.elementCount > 0 ? listPtr.elementCount - 1 : 0;
779
+ if (byteLength === 0) return "";
780
+ const bytes = new Uint8Array(segment.dataView.buffer, wordOffset * WORD_SIZE, byteLength);
781
+ return new TextDecoder().decode(bytes);
782
+ }
783
+ /**
784
+ * 获取数据字段
785
+ * Data is stored as List(UInt8) without NUL terminator
786
+ * @param pointerIndex - The index of the pointer in the pointer section
787
+ * @returns Uint8Array of the data content, or undefined if null pointer
788
+ */
789
+ getData(pointerIndex) {
790
+ const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;
791
+ const resolved = this.message.resolvePointer(this.segmentIndex, ptrOffset);
792
+ if (!resolved) return void 0;
793
+ const { segmentIndex, wordOffset, pointer } = resolved;
794
+ if (pointer.tag !== PointerTag.LIST) return void 0;
795
+ const listPtr = pointer;
796
+ const segment = this.message.getSegment(segmentIndex);
797
+ const byteLength = listPtr.elementCount;
798
+ if (byteLength === 0) return new Uint8Array(0);
799
+ const bytes = new Uint8Array(segment.dataView.buffer, wordOffset * WORD_SIZE, byteLength);
800
+ return new Uint8Array(bytes);
801
+ }
802
+ /**
803
+ * 获取嵌套结构
804
+ */
805
+ getStruct(pointerIndex, _dataWords, _pointerCount) {
806
+ const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;
807
+ const resolved = this.message.resolvePointer(this.segmentIndex, ptrOffset);
808
+ if (!resolved) return void 0;
809
+ const { segmentIndex, wordOffset, pointer } = resolved;
810
+ if (pointer.tag !== PointerTag.STRUCT) return void 0;
811
+ const structPtr = pointer;
812
+ return new StructReader(this.message, segmentIndex, wordOffset, structPtr.dataWords, structPtr.pointerCount);
813
+ }
814
+ /**
815
+ * 获取列表
816
+ */
817
+ getList(pointerIndex, _elementSize, structSize) {
818
+ const ptrOffset = this.wordOffset + this.dataWords + pointerIndex;
819
+ const resolved = this.message.resolvePointer(this.segmentIndex, ptrOffset);
820
+ if (!resolved) return void 0;
821
+ const { segmentIndex, wordOffset, pointer } = resolved;
822
+ if (pointer.tag !== PointerTag.LIST) return void 0;
823
+ const listPtr = pointer;
824
+ let targetOffset = wordOffset;
825
+ let elementCount = listPtr.elementCount;
826
+ let actualStructSize = structSize;
827
+ const segment = this.message.getSegment(segmentIndex);
828
+ if (listPtr.elementSize === ElementSize.COMPOSITE) {
829
+ if (targetOffset < 0 || targetOffset >= segment.wordCount) return;
830
+ try {
831
+ const tagWord = segment.getWord(targetOffset);
832
+ elementCount = Number(tagWord & BigInt(4294967295));
833
+ actualStructSize = {
834
+ dataWords: Number(tagWord >> BigInt(32) & BigInt(65535)),
835
+ pointerCount: Number(tagWord >> BigInt(48) & BigInt(65535))
836
+ };
837
+ targetOffset += 1;
838
+ } catch {
839
+ return;
840
+ }
841
+ }
842
+ return new ListReader(this.message, segmentIndex, listPtr.elementSize, elementCount, actualStructSize, targetOffset);
843
+ }
844
+ };
845
+
846
+ //#endregion
847
+ export { MessageBuilder as n, ElementSize as r, MessageReader as t };
848
+ //# sourceMappingURL=message-reader-fw2PY8sU.js.map