@cloudpss/ubjson 0.5.39 → 0.5.41

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.
Files changed (92) hide show
  1. package/dist/base/decoder.d.ts +1 -0
  2. package/dist/base/decoder.d.ts.map +1 -0
  3. package/dist/base/encoder.d.ts +5 -1
  4. package/dist/base/encoder.d.ts.map +1 -0
  5. package/dist/base/encoder.js +50 -188
  6. package/dist/base/encoder.js.map +1 -1
  7. package/dist/decoder.d.ts +1 -0
  8. package/dist/decoder.d.ts.map +1 -0
  9. package/dist/encoder.d.ts +7 -1
  10. package/dist/encoder.d.ts.map +1 -0
  11. package/dist/encoder.js +24 -15
  12. package/dist/encoder.js.map +1 -1
  13. package/dist/helper/constants.d.ts +1 -0
  14. package/dist/helper/constants.d.ts.map +1 -0
  15. package/dist/helper/decode-ae.d.ts +50 -0
  16. package/dist/helper/decode-ae.d.ts.map +1 -0
  17. package/dist/helper/decode-ae.js +584 -0
  18. package/dist/helper/decode-ae.js.map +1 -0
  19. package/dist/helper/decode.d.ts +6 -3
  20. package/dist/helper/decode.d.ts.map +1 -0
  21. package/dist/helper/decode.js +33 -20
  22. package/dist/helper/decode.js.map +1 -1
  23. package/dist/helper/encode.d.ts +19 -1
  24. package/dist/helper/encode.d.ts.map +1 -0
  25. package/dist/helper/encode.js +138 -16
  26. package/dist/helper/encode.js.map +1 -1
  27. package/dist/helper/errors.d.ts +1 -0
  28. package/dist/helper/errors.d.ts.map +1 -0
  29. package/dist/helper/string-decoder.d.ts +5 -2
  30. package/dist/helper/string-decoder.d.ts.map +1 -0
  31. package/dist/helper/string-decoder.js +10 -38
  32. package/dist/helper/string-decoder.js.map +1 -1
  33. package/dist/helper/string-encoder.d.ts +1 -0
  34. package/dist/helper/string-encoder.d.ts.map +1 -0
  35. package/dist/helper/utils.d.ts +1 -0
  36. package/dist/helper/utils.d.ts.map +1 -0
  37. package/dist/index.d.ts +5 -2
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +4 -4
  40. package/dist/index.js.map +1 -1
  41. package/dist/options.d.ts +6 -0
  42. package/dist/options.d.ts.map +1 -0
  43. package/dist/options.js +2 -0
  44. package/dist/options.js.map +1 -0
  45. package/dist/rxjs/decoder.d.ts +1 -0
  46. package/dist/rxjs/decoder.d.ts.map +1 -0
  47. package/dist/rxjs/decoder.js +66 -40
  48. package/dist/rxjs/decoder.js.map +1 -1
  49. package/dist/rxjs/encoder.d.ts +3 -1
  50. package/dist/rxjs/encoder.d.ts.map +1 -0
  51. package/dist/rxjs/encoder.js +2 -2
  52. package/dist/rxjs/encoder.js.map +1 -1
  53. package/dist/rxjs/index.d.ts +2 -0
  54. package/dist/rxjs/index.d.ts.map +1 -0
  55. package/dist/stream/decoder.d.ts +1 -0
  56. package/dist/stream/decoder.d.ts.map +1 -0
  57. package/dist/stream/encoder.d.ts +4 -2
  58. package/dist/stream/encoder.d.ts.map +1 -0
  59. package/dist/stream/encoder.js +2 -2
  60. package/dist/stream/encoder.js.map +1 -1
  61. package/dist/stream/index.d.ts +6 -3
  62. package/dist/stream/index.d.ts.map +1 -0
  63. package/dist/stream/index.js +6 -6
  64. package/dist/stream/index.js.map +1 -1
  65. package/dist/stream-helper/decoder.d.ts +1 -0
  66. package/dist/stream-helper/decoder.d.ts.map +1 -0
  67. package/dist/stream-helper/encoder.d.ts +5 -2
  68. package/dist/stream-helper/encoder.d.ts.map +1 -0
  69. package/dist/stream-helper/encoder.js +33 -31
  70. package/dist/stream-helper/encoder.js.map +1 -1
  71. package/jest.config.js +1 -1
  72. package/package.json +3 -4
  73. package/src/base/encoder.ts +58 -174
  74. package/src/encoder.ts +27 -15
  75. package/src/helper/decode-ae.ts +621 -0
  76. package/src/helper/decode.ts +36 -23
  77. package/src/helper/encode.ts +141 -15
  78. package/src/helper/string-decoder.ts +10 -39
  79. package/src/index.ts +7 -4
  80. package/src/options.ts +5 -0
  81. package/src/rxjs/decoder.ts +66 -40
  82. package/src/rxjs/encoder.ts +3 -2
  83. package/src/rxjs/index.ts +1 -0
  84. package/src/stream/encoder.ts +4 -3
  85. package/src/stream/index.ts +8 -6
  86. package/src/stream-helper/encoder.ts +39 -34
  87. package/tests/.utils.js +1 -0
  88. package/tests/e2e/stream.js +13 -1
  89. package/tests/encode.js +8 -0
  90. package/tests/string-encoding.js +1 -10
  91. package/tests/tsconfig.json +1 -7
  92. package/tsconfig.json +1 -1
@@ -0,0 +1,621 @@
1
+ import { constants } from './constants.js';
2
+ import { unsupportedType } from './errors.js';
3
+ import { decode } from './string-decoder.js';
4
+ import { toUint8Array } from './utils.js';
5
+ const { defineProperty } = Object;
6
+ const { fromCharCode } = String;
7
+
8
+ /**
9
+ * 数据读取函数
10
+ * `yield` 返回需要的字节数,`return` 返回解析结果
11
+ */
12
+ export type DecodeFuncAe<T = unknown> = Generator<number, T, void>;
13
+
14
+ /** 数据包装 */
15
+ export interface DecodeCursorAe {
16
+ /** 当前数据块 */
17
+ readonly view: DataView;
18
+ /** 当前数据块 */
19
+ readonly data: Uint8Array;
20
+ /** 当前数据大小 */
21
+ readonly size: number;
22
+ /** 当前读指针位置 */
23
+ offset: number;
24
+ }
25
+
26
+ /** 创建数据包装 */
27
+ export function DecodeCursor(data: BinaryData): DecodeCursorAe {
28
+ const d = toUint8Array(data);
29
+ const v = new DataView(d.buffer, d.byteOffset, d.byteLength);
30
+ return {
31
+ data: d,
32
+ view: v,
33
+ size: v.byteLength,
34
+ offset: 0,
35
+ };
36
+ }
37
+
38
+ /**
39
+ * 读取第一个非 NOOP 的字节
40
+ */
41
+ export function* readMarker(cursor: DecodeCursorAe): DecodeFuncAe<number> {
42
+ let marker: number;
43
+ do {
44
+ if (cursor.offset + 1 > cursor.size) {
45
+ yield cursor.offset - cursor.size + 1;
46
+ }
47
+ marker = cursor.data[cursor.offset++]!;
48
+ } while (marker === constants.NO_OP);
49
+ return marker;
50
+ }
51
+
52
+ /** 读取一个大于 0 的整数 */
53
+ export function* readLength(cursor: DecodeCursorAe): DecodeFuncAe<number> {
54
+ let marker: number;
55
+ do {
56
+ if (cursor.offset + 1 > cursor.size) {
57
+ yield cursor.offset - cursor.size + 1;
58
+ }
59
+ marker = cursor.data[cursor.offset++]!;
60
+ } while (marker === constants.NO_OP);
61
+ let length: number;
62
+ switch (marker) {
63
+ case constants.INT8:
64
+ if (cursor.offset + 1 > cursor.size) {
65
+ yield cursor.offset - cursor.size + 1;
66
+ }
67
+ length = cursor.view.getInt8(cursor.offset++);
68
+ break;
69
+ case constants.UINT8:
70
+ length = yield* readUint8Data(cursor);
71
+ break;
72
+ case constants.INT16:
73
+ length = yield* readInt16Data(cursor);
74
+ break;
75
+ case constants.INT32:
76
+ length = yield* readInt32Data(cursor);
77
+ break;
78
+ case constants.INT64: {
79
+ const l = yield* readInt64Data(cursor);
80
+ if (l < 0 || l > Number.MAX_SAFE_INTEGER) {
81
+ throw new Error('Invalid length');
82
+ }
83
+ length = Number(l);
84
+ break;
85
+ }
86
+ default:
87
+ throw new Error(`Unexpected marker '${fromCharCode(marker)}'(${marker}) for int length`);
88
+ }
89
+ if (length < 0) {
90
+ throw new Error('Invalid length');
91
+ }
92
+ return length;
93
+ }
94
+
95
+ /** readInt8Data */
96
+ export function* readInt8Data(cursor: DecodeCursorAe): DecodeFuncAe<number> {
97
+ if (cursor.offset + 1 > cursor.size) {
98
+ yield cursor.offset - cursor.size + 1;
99
+ }
100
+ return cursor.view.getInt8(cursor.offset++);
101
+ }
102
+ /** readUint8Data */
103
+ export function* readUint8Data(cursor: DecodeCursorAe): DecodeFuncAe<number> {
104
+ if (cursor.offset + 1 > cursor.size) {
105
+ yield cursor.offset - cursor.size + 1;
106
+ }
107
+ return cursor.data[cursor.offset++]!;
108
+ }
109
+ /** readInt16Data */
110
+ export function* readInt16Data(cursor: DecodeCursorAe): DecodeFuncAe<number> {
111
+ if (cursor.offset + 2 > cursor.size) {
112
+ yield cursor.offset - cursor.size + 2;
113
+ }
114
+ const value = cursor.view.getInt16(cursor.offset);
115
+ cursor.offset += 2;
116
+ return value;
117
+ }
118
+ /** readInt32Data */
119
+ export function* readInt32Data(cursor: DecodeCursorAe): DecodeFuncAe<number> {
120
+ if (cursor.offset + 4 > cursor.size) {
121
+ yield cursor.offset - cursor.size + 4;
122
+ }
123
+ const value = cursor.view.getInt32(cursor.offset);
124
+ cursor.offset += 4;
125
+ return value;
126
+ }
127
+ /** readInt64Data */
128
+ export function* readInt64Data(cursor: DecodeCursorAe): DecodeFuncAe<bigint> {
129
+ if (cursor.offset + 8 > cursor.size) {
130
+ yield cursor.offset - cursor.size + 8;
131
+ }
132
+ const value = cursor.view.getBigInt64(cursor.offset);
133
+ cursor.offset += 8;
134
+ return value;
135
+ }
136
+ /** readFloat32Data */
137
+ export function* readFloat32Data(cursor: DecodeCursorAe): DecodeFuncAe<number> {
138
+ if (cursor.offset + 4 > cursor.size) {
139
+ yield cursor.offset - cursor.size + 4;
140
+ }
141
+ const value = cursor.view.getFloat32(cursor.offset);
142
+ cursor.offset += 4;
143
+ return value;
144
+ }
145
+ /** readFloat64Data */
146
+ export function* readFloat64Data(cursor: DecodeCursorAe): DecodeFuncAe<number> {
147
+ if (cursor.offset + 8 > cursor.size) {
148
+ yield cursor.offset - cursor.size + 8;
149
+ }
150
+ const value = cursor.view.getFloat64(cursor.offset);
151
+ cursor.offset += 8;
152
+ return value;
153
+ }
154
+
155
+ /** 读取数据 */
156
+ export function* read(cursor: DecodeCursorAe): DecodeFuncAe<unknown> {
157
+ let marker: number;
158
+ do {
159
+ if (cursor.offset + 1 > cursor.size) {
160
+ yield cursor.offset - cursor.size + 1;
161
+ }
162
+ marker = cursor.data[cursor.offset++]!;
163
+ } while (marker === constants.NO_OP);
164
+ return yield* readData(cursor, marker);
165
+ }
166
+
167
+ /** 读取优化对象数据 */
168
+ function* readObjectOptimizedData(cursor: DecodeCursorAe, marker: OptimizedFormatMarkers): DecodeFuncAe<unknown> {
169
+ const { count, type } = marker;
170
+ const object: Record<string, unknown> = {};
171
+ for (let i = 0; i < count; i++) {
172
+ const key = yield* readKey(cursor);
173
+ const value = yield* readData(cursor, type ?? (yield* readMarker(cursor)));
174
+ if (key === '__proto__') {
175
+ defineProperty(object, key, { value, enumerable: true, configurable: true, writable: true });
176
+ }
177
+ object[key] = value;
178
+ }
179
+ return object;
180
+ }
181
+
182
+ /** 根据标签读取后续数据 */
183
+ export function* readData(cursor: DecodeCursorAe, marker: number): DecodeFuncAe<unknown> {
184
+ // 按照出现频率排序
185
+ switch (marker) {
186
+ case constants.STRING: {
187
+ let marker: number;
188
+ do {
189
+ if (cursor.offset + 1 > cursor.size) {
190
+ yield cursor.offset - cursor.size + 1;
191
+ }
192
+ marker = cursor.data[cursor.offset++]!;
193
+ } while (marker === constants.NO_OP);
194
+ let length: number;
195
+ switch (marker) {
196
+ case constants.INT8:
197
+ if (cursor.offset + 1 > cursor.size) {
198
+ yield cursor.offset - cursor.size + 1;
199
+ }
200
+ length = cursor.view.getInt8(cursor.offset++);
201
+ break;
202
+ case constants.UINT8:
203
+ length = yield* readUint8Data(cursor);
204
+ break;
205
+ case constants.INT16:
206
+ length = yield* readInt16Data(cursor);
207
+ break;
208
+ case constants.INT32:
209
+ length = yield* readInt32Data(cursor);
210
+ break;
211
+ case constants.INT64: {
212
+ const l = yield* readInt64Data(cursor);
213
+ if (l < 0 || l > Number.MAX_SAFE_INTEGER) {
214
+ throw new Error('Invalid length');
215
+ }
216
+ length = Number(l);
217
+ break;
218
+ }
219
+ default:
220
+ throw new Error(`Unexpected marker '${fromCharCode(marker)}'(${marker}) for int length`);
221
+ }
222
+ if (length < 0) {
223
+ throw new Error('Invalid length');
224
+ }
225
+ if (cursor.offset + length > cursor.size) {
226
+ yield cursor.offset - cursor.size + length;
227
+ }
228
+ const begin = cursor.offset;
229
+ const end = begin + length;
230
+ cursor.offset = end;
231
+ const { data } = cursor;
232
+ return decode(data, begin, end);
233
+ }
234
+ case constants.OBJECT: {
235
+ let type;
236
+ let count;
237
+ let marker: number;
238
+ do {
239
+ if (cursor.offset + 1 > cursor.size) {
240
+ yield cursor.offset - cursor.size + 1;
241
+ }
242
+ marker = cursor.data[cursor.offset++]!;
243
+ } while (marker === constants.NO_OP);
244
+ switch (marker) {
245
+ case constants.TYPE_MARKER: {
246
+ do {
247
+ if (cursor.offset + 1 > cursor.size) {
248
+ yield cursor.offset - cursor.size + 1;
249
+ }
250
+ type = cursor.data[cursor.offset++]!;
251
+ } while (type === constants.NO_OP);
252
+ let marker2;
253
+ do {
254
+ if (cursor.offset + 1 > cursor.size) {
255
+ yield cursor.offset - cursor.size + 1;
256
+ }
257
+ marker2 = cursor.data[cursor.offset++]!;
258
+ } while (marker2 === constants.NO_OP);
259
+ if (marker2 !== constants.COUNT_MARKER) {
260
+ throw new Error('Expected count marker');
261
+ }
262
+ }
263
+ /* fall through */
264
+ case constants.COUNT_MARKER: {
265
+ count = yield* readLength(cursor);
266
+ break;
267
+ }
268
+ default: {
269
+ // 不是 '$' 或 '#'
270
+ // 直到 '}'
271
+ const object: Record<string, unknown> = {};
272
+ for (;;) {
273
+ while (marker === constants.NO_OP) {
274
+ if (cursor.offset + 1 > cursor.size) {
275
+ yield cursor.offset - cursor.size + 1;
276
+ }
277
+ marker = cursor.data[cursor.offset++]!;
278
+ }
279
+ if (marker === constants.OBJECT_END) break;
280
+ let length: number;
281
+ switch (marker) {
282
+ case constants.INT8:
283
+ if (cursor.offset + 1 > cursor.size) {
284
+ yield cursor.offset - cursor.size + 1;
285
+ }
286
+ length = cursor.view.getInt8(cursor.offset++);
287
+ break;
288
+ case constants.UINT8:
289
+ length = yield* readUint8Data(cursor);
290
+ break;
291
+ case constants.INT16:
292
+ length = yield* readInt16Data(cursor);
293
+ break;
294
+ case constants.INT32:
295
+ length = yield* readInt32Data(cursor);
296
+ break;
297
+ case constants.INT64: {
298
+ const l = yield* readInt64Data(cursor);
299
+ if (l < 0 || l > Number.MAX_SAFE_INTEGER) {
300
+ throw new Error('Invalid length');
301
+ }
302
+ length = Number(l);
303
+ break;
304
+ }
305
+ default:
306
+ throw new Error(
307
+ `Unexpected marker '${fromCharCode(marker)}'(${marker}) for int length`,
308
+ );
309
+ }
310
+ if (length < 0) {
311
+ throw new Error('Invalid length');
312
+ }
313
+ if (cursor.offset + length > cursor.size) {
314
+ yield cursor.offset - cursor.size + length;
315
+ }
316
+ marker = constants.NO_OP;
317
+ const begin = cursor.offset;
318
+ const end = begin + length;
319
+ cursor.offset = end;
320
+ const { data } = cursor;
321
+ const key = decode(data, begin, end);
322
+ let valueMarker: number;
323
+ do {
324
+ if (cursor.offset + 1 > cursor.size) {
325
+ yield cursor.offset - cursor.size + 1;
326
+ }
327
+ valueMarker = cursor.data[cursor.offset++]!;
328
+ } while (valueMarker === constants.NO_OP);
329
+ const value = yield* readData(cursor, valueMarker);
330
+ if (key === '__proto__') {
331
+ defineProperty(object, key, {
332
+ value,
333
+ enumerable: true,
334
+ configurable: true,
335
+ writable: true,
336
+ });
337
+ }
338
+ object[key] = value;
339
+ }
340
+ return object;
341
+ }
342
+ }
343
+ return yield* readObjectOptimizedData(cursor, { type, count });
344
+ }
345
+ case constants.ARRAY: {
346
+ let type;
347
+ let count;
348
+ let marker: number;
349
+ do {
350
+ if (cursor.offset + 1 > cursor.size) {
351
+ yield cursor.offset - cursor.size + 1;
352
+ }
353
+ marker = cursor.data[cursor.offset++]!;
354
+ } while (marker === constants.NO_OP);
355
+ switch (marker) {
356
+ case constants.TYPE_MARKER: {
357
+ do {
358
+ if (cursor.offset + 1 > cursor.size) {
359
+ yield cursor.offset - cursor.size + 1;
360
+ }
361
+ type = cursor.data[cursor.offset++]!;
362
+ } while (type === constants.NO_OP);
363
+ let marker2;
364
+ do {
365
+ if (cursor.offset + 1 > cursor.size) {
366
+ yield cursor.offset - cursor.size + 1;
367
+ }
368
+ marker2 = cursor.data[cursor.offset++]!;
369
+ } while (marker2 === constants.NO_OP);
370
+ if (marker2 !== constants.COUNT_MARKER) {
371
+ throw new Error('Expected count marker');
372
+ }
373
+ }
374
+ /* fall through */
375
+ case constants.COUNT_MARKER: {
376
+ count = yield* readLength(cursor);
377
+ break;
378
+ }
379
+ default: {
380
+ // 不是 '$' 或 '#'
381
+ const array = [];
382
+ for (;;) {
383
+ while (marker === constants.NO_OP) {
384
+ if (cursor.offset + 1 > cursor.size) {
385
+ yield cursor.offset - cursor.size + 1;
386
+ }
387
+ marker = cursor.data[cursor.offset++]!;
388
+ }
389
+ // 直到 ']'
390
+ if (marker === constants.ARRAY_END) break;
391
+ array.push(yield* readData(cursor, marker));
392
+ marker = constants.NO_OP;
393
+ }
394
+ return array;
395
+ }
396
+ }
397
+ switch (type) {
398
+ case constants.UINT8: {
399
+ if (cursor.offset + count > cursor.size) {
400
+ yield cursor.offset - cursor.size + count;
401
+ }
402
+ const buf = new Uint8Array(
403
+ cursor.data.buffer,
404
+ cursor.data.byteOffset + cursor.offset,
405
+ count,
406
+ ).slice();
407
+ cursor.offset += count;
408
+ return buf;
409
+ }
410
+ case constants.INT8: {
411
+ if (cursor.offset + count > cursor.size) {
412
+ yield cursor.offset - cursor.size + count;
413
+ }
414
+ const buf = new Int8Array(
415
+ cursor.data.buffer,
416
+ cursor.data.byteOffset + cursor.offset,
417
+ count,
418
+ ).slice();
419
+ cursor.offset += count;
420
+ return buf;
421
+ }
422
+ case constants.INT16: {
423
+ if (cursor.offset + count * 2 > cursor.size) {
424
+ yield cursor.offset - cursor.size + count * 2;
425
+ }
426
+ const result = new Int16Array(count);
427
+ for (let i = 0; i < count; i++) {
428
+ result[i] = yield* readInt16Data(cursor);
429
+ }
430
+ return result;
431
+ }
432
+ case constants.INT32: {
433
+ if (cursor.offset + count * 4 > cursor.size) {
434
+ yield cursor.offset - cursor.size + count * 4;
435
+ }
436
+ const result = new Int32Array(count);
437
+ for (let i = 0; i < count; i++) {
438
+ result[i] = yield* readInt32Data(cursor);
439
+ }
440
+ return result;
441
+ }
442
+ case constants.FLOAT32: {
443
+ if (cursor.offset + count * 4 > cursor.size) {
444
+ yield cursor.offset - cursor.size + count * 4;
445
+ }
446
+ const result = new Float32Array(count);
447
+ for (let i = 0; i < count; i++) {
448
+ result[i] = yield* readFloat32Data(cursor);
449
+ }
450
+ return result;
451
+ }
452
+ case constants.FLOAT64: {
453
+ if (cursor.offset + count * 8 > cursor.size) {
454
+ yield cursor.offset - cursor.size + count * 8;
455
+ }
456
+ const result = new Float64Array(count);
457
+ for (let i = 0; i < count; i++) {
458
+ result[i] = yield* readFloat64Data(cursor);
459
+ }
460
+ return result;
461
+ }
462
+ case constants.INT64: {
463
+ if (cursor.offset + count * 8 > cursor.size) {
464
+ yield cursor.offset - cursor.size + count * 8;
465
+ }
466
+ const result = new BigInt64Array(count);
467
+ for (let i = 0; i < count; i++) {
468
+ result[i] = yield* readInt64Data(cursor);
469
+ }
470
+ return result;
471
+ }
472
+ case constants.NULL:
473
+ return Array.from({ length: count }).fill(null);
474
+ case constants.TRUE:
475
+ return Array.from({ length: count }).fill(true);
476
+ case constants.FALSE:
477
+ return Array.from({ length: count }).fill(false);
478
+ default:
479
+ break;
480
+ }
481
+ const array: unknown[] = [];
482
+ array.length = count;
483
+ for (let i = 0; i < count; i++) {
484
+ array[i] = type === undefined ? yield* read(cursor) : yield* readData(cursor, type);
485
+ }
486
+ return array;
487
+ }
488
+ case constants.FLOAT64: {
489
+ if (cursor.offset + 8 > cursor.size) {
490
+ yield cursor.offset - cursor.size + 8;
491
+ }
492
+ const value = cursor.view.getFloat64(cursor.offset);
493
+ cursor.offset += 8;
494
+ return value;
495
+ }
496
+ case constants.UINT8: {
497
+ if (cursor.offset + 1 > cursor.size) {
498
+ yield cursor.offset - cursor.size + 1;
499
+ }
500
+ return cursor.data[cursor.offset++]!;
501
+ }
502
+ case constants.INT16: {
503
+ if (cursor.offset + 2 > cursor.size) {
504
+ yield cursor.offset - cursor.size + 2;
505
+ }
506
+ const value = cursor.view.getInt16(cursor.offset);
507
+ cursor.offset += 2;
508
+ return value;
509
+ }
510
+ case constants.FLOAT32: {
511
+ if (cursor.offset + 4 > cursor.size) {
512
+ yield cursor.offset - cursor.size + 4;
513
+ }
514
+ const value = cursor.view.getFloat32(cursor.offset);
515
+ cursor.offset += 4;
516
+ return value;
517
+ }
518
+ case constants.CHAR: {
519
+ if (cursor.offset + 1 > cursor.size) {
520
+ yield cursor.offset - cursor.size + 1;
521
+ }
522
+ return fromCharCode(cursor.data[cursor.offset++]!);
523
+ }
524
+ case constants.INT32: {
525
+ if (cursor.offset + 4 > cursor.size) {
526
+ yield cursor.offset - cursor.size + 4;
527
+ }
528
+ const value = cursor.view.getInt32(cursor.offset);
529
+ cursor.offset += 4;
530
+ return value;
531
+ }
532
+ case constants.INT8: {
533
+ if (cursor.offset + 1 > cursor.size) {
534
+ yield cursor.offset - cursor.size + 1;
535
+ }
536
+ return cursor.view.getInt8(cursor.offset++);
537
+ }
538
+ case constants.NULL:
539
+ return null;
540
+ case constants.TRUE:
541
+ return true;
542
+ case constants.FALSE:
543
+ return false;
544
+ case constants.INT64: {
545
+ if (cursor.offset + 8 > cursor.size) {
546
+ yield cursor.offset - cursor.size + 8;
547
+ }
548
+ const value = cursor.view.getBigInt64(cursor.offset);
549
+ cursor.offset += 8;
550
+ if (value < Number.MIN_SAFE_INTEGER || value > Number.MAX_SAFE_INTEGER) {
551
+ return value;
552
+ }
553
+ return Number(value);
554
+ }
555
+ case constants.HIGH_PRECISION_NUMBER: {
556
+ const length = yield* readLength(cursor);
557
+ if (cursor.offset + length > cursor.size) {
558
+ yield cursor.offset - cursor.size + length;
559
+ }
560
+ const begin = cursor.offset;
561
+ const _buffer = new Uint8Array(cursor.data.buffer, begin, length).slice();
562
+ cursor.offset = begin + length;
563
+ // return _buffer
564
+ unsupportedType('high precision number');
565
+ }
566
+ }
567
+ throw new Error(`Unexpected marker '${fromCharCode(marker)}'(${marker})`);
568
+ }
569
+
570
+ /** readKey */
571
+ export function* readKey(cursor: DecodeCursorAe): DecodeFuncAe<string> {
572
+ let marker: number;
573
+ do {
574
+ if (cursor.offset + 1 > cursor.size) {
575
+ yield cursor.offset - cursor.size + 1;
576
+ }
577
+ marker = cursor.data[cursor.offset++]!;
578
+ } while (marker === constants.NO_OP);
579
+ let length: number;
580
+ switch (marker) {
581
+ case constants.INT8:
582
+ if (cursor.offset + 1 > cursor.size) {
583
+ yield cursor.offset - cursor.size + 1;
584
+ }
585
+ length = cursor.view.getInt8(cursor.offset++);
586
+ break;
587
+ case constants.UINT8:
588
+ length = yield* readUint8Data(cursor);
589
+ break;
590
+ case constants.INT16:
591
+ length = yield* readInt16Data(cursor);
592
+ break;
593
+ case constants.INT32:
594
+ length = yield* readInt32Data(cursor);
595
+ break;
596
+ case constants.INT64: {
597
+ const l = yield* readInt64Data(cursor);
598
+ if (l < 0 || l > Number.MAX_SAFE_INTEGER) {
599
+ throw new Error('Invalid length');
600
+ }
601
+ length = Number(l);
602
+ break;
603
+ }
604
+ default:
605
+ throw new Error(`Unexpected marker '${fromCharCode(marker)}'(${marker}) for int length`);
606
+ }
607
+ if (length < 0) {
608
+ throw new Error('Invalid length');
609
+ }
610
+ if (cursor.offset + length > cursor.size) {
611
+ yield cursor.offset - cursor.size + length;
612
+ }
613
+ const begin = cursor.offset;
614
+ const end = begin + length;
615
+ cursor.offset = end;
616
+ const { data } = cursor;
617
+ return decode(data, begin, end);
618
+ }
619
+
620
+ /** Optimized Format 数据 */
621
+ export type OptimizedFormatMarkers = { type?: number; count: number };