libshv-js 3.17.0 → 3.20.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,562 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CHAINPACK_PROTOCOL_TYPE = exports.ChainPackWriter = exports.ChainPackReader = exports.fromChainPack = exports.toChainPack = void 0;
4
+ /* eslint-disable no-bitwise */
5
+ const cpon_1 = require("./cpon");
6
+ const rpcvalue_1 = require("./rpcvalue");
7
+ const cpcontext_1 = require("./cpcontext");
8
+ var PackingSchema;
9
+ (function (PackingSchema) {
10
+ PackingSchema[PackingSchema["IntThreshold"] = 64] = "IntThreshold";
11
+ PackingSchema[PackingSchema["Null"] = 128] = "Null";
12
+ PackingSchema[PackingSchema["UInt"] = 129] = "UInt";
13
+ PackingSchema[PackingSchema["Int"] = 130] = "Int";
14
+ PackingSchema[PackingSchema["Double"] = 131] = "Double";
15
+ PackingSchema[PackingSchema["Bool"] = 132] = "Bool";
16
+ PackingSchema[PackingSchema["Blob"] = 133] = "Blob";
17
+ PackingSchema[PackingSchema["String"] = 134] = "String";
18
+ PackingSchema[PackingSchema["List"] = 136] = "List";
19
+ PackingSchema[PackingSchema["Map"] = 137] = "Map";
20
+ PackingSchema[PackingSchema["IMap"] = 138] = "IMap";
21
+ PackingSchema[PackingSchema["MetaMap"] = 139] = "MetaMap";
22
+ PackingSchema[PackingSchema["Decimal"] = 140] = "Decimal";
23
+ PackingSchema[PackingSchema["DateTime"] = 141] = "DateTime";
24
+ PackingSchema[PackingSchema["CString"] = 142] = "CString";
25
+ PackingSchema[PackingSchema["False"] = 253] = "False";
26
+ PackingSchema[PackingSchema["True"] = 254] = "True";
27
+ PackingSchema[PackingSchema["Term"] = 255] = "Term";
28
+ })(PackingSchema || (PackingSchema = {}));
29
+ const SHV_EPOCH_MSEC = 1_517_529_600_000;
30
+ const INVALID_MIN_OFFSET_FROM_UTC = (-64 * 15);
31
+ const divInt = (n, d) => {
32
+ const r = n % d;
33
+ return [(n - r) / d, r];
34
+ };
35
+ const uint8ArrayBoBigint = (bytes, type) => {
36
+ let isNeg = false;
37
+ if (type === 'Int') {
38
+ if (bytes.length < 5) {
39
+ const signMask = 0x80 >> bytes.length;
40
+ isNeg = Boolean(bytes[0] & signMask);
41
+ bytes[0] &= ~signMask;
42
+ }
43
+ else {
44
+ isNeg = Boolean(bytes[1] & 128);
45
+ bytes[1] &= ~128;
46
+ }
47
+ }
48
+ let ret = 0n;
49
+ for (const byte of bytes) {
50
+ ret = (ret * BigInt(256)) + BigInt(byte);
51
+ }
52
+ if (isNeg) {
53
+ ret = -ret;
54
+ }
55
+ return ret;
56
+ };
57
+ const numberToUint8Array = (num) => {
58
+ let bytes = new Uint8Array(8);
59
+ let len = 0;
60
+ do {
61
+ const res = divInt(num, 256n);
62
+ num = res[0];
63
+ bytes[len++] = Number(res[1]);
64
+ } while (num !== 0n);
65
+ bytes = bytes.subarray(0, len);
66
+ bytes.reverse();
67
+ return bytes;
68
+ };
69
+ const significantBitsCount = (num) => {
70
+ let ret = 0;
71
+ while (num > 0) {
72
+ ret++;
73
+ num >>= 1n;
74
+ }
75
+ return ret;
76
+ };
77
+ class ChainPackReader {
78
+ ctx;
79
+ constructor(data) {
80
+ this.ctx = data instanceof cpcontext_1.UnpackContext ? data : new cpcontext_1.UnpackContext(data);
81
+ }
82
+ /* eslint-disable complexity */
83
+ read() {
84
+ let meta;
85
+ let codePointAt = this.ctx.getByte();
86
+ if (codePointAt === PackingSchema.MetaMap) {
87
+ meta = this.readMetaMap();
88
+ codePointAt = this.ctx.getByte();
89
+ }
90
+ const implReturn = (x) => {
91
+ const ret = meta !== undefined ? new rpcvalue_1.RpcValueWithMetaData(meta, x) : x;
92
+ return ret;
93
+ };
94
+ if (codePointAt < PackingSchema.Null) {
95
+ if (codePointAt >= PackingSchema.IntThreshold) {
96
+ return implReturn(codePointAt - 64);
97
+ }
98
+ return implReturn(new rpcvalue_1.UInt(codePointAt));
99
+ }
100
+ switch (codePointAt) {
101
+ case PackingSchema.Null: {
102
+ return implReturn(undefined);
103
+ }
104
+ case PackingSchema.True: {
105
+ return implReturn(true);
106
+ }
107
+ case PackingSchema.False: {
108
+ return implReturn(false);
109
+ }
110
+ case PackingSchema.Int: {
111
+ return implReturn(this.readIntData());
112
+ }
113
+ case PackingSchema.UInt: {
114
+ return implReturn(new rpcvalue_1.UInt(this.readUIntData()));
115
+ }
116
+ case PackingSchema.Double: {
117
+ const data = new Uint8Array(8);
118
+ for (let i = 0; i < 8; i++) {
119
+ data[i] = this.ctx.getByte();
120
+ }
121
+ return implReturn(new rpcvalue_1.Double(new DataView(data.buffer).getFloat64(0, true))); // little endian
122
+ }
123
+ case PackingSchema.Decimal: {
124
+ const mant = this.readIntData();
125
+ const exp = this.readIntData();
126
+ return implReturn(new rpcvalue_1.Decimal(mant, exp));
127
+ }
128
+ case PackingSchema.DateTime: {
129
+ let bi = this.readUIntDataHelper('UInt');
130
+ const hasTzOffset = bi & 1n;
131
+ const hasNotMsec = bi & 2n;
132
+ bi >>= 2n;
133
+ let offset = 0;
134
+ if (hasTzOffset !== 0n) {
135
+ offset = Number(bi & 0x7fn);
136
+ if ((offset & 0x40) !== 0) {
137
+ // sign extension
138
+ offset -= 128;
139
+ }
140
+ bi >>= 7n;
141
+ }
142
+ offset *= 15;
143
+ if (offset === INVALID_MIN_OFFSET_FROM_UTC) {
144
+ return implReturn(undefined);
145
+ }
146
+ let msec = Number(bi);
147
+ if (hasNotMsec !== 0n) {
148
+ msec *= 1000;
149
+ }
150
+ msec += SHV_EPOCH_MSEC;
151
+ msec -= offset * 60_000;
152
+ return (0, rpcvalue_1.withOffset)(new Date(msec), offset ?? undefined);
153
+ }
154
+ case PackingSchema.Map: {
155
+ return implReturn(this.readMap());
156
+ }
157
+ case PackingSchema.IMap: {
158
+ return implReturn(this.readIMap());
159
+ }
160
+ case PackingSchema.List: {
161
+ return implReturn(this.readList());
162
+ }
163
+ case PackingSchema.Blob: {
164
+ const strLen = this.readUIntData();
165
+ const arr = new Uint8Array(strLen);
166
+ for (let i = 0; i < strLen; i++) {
167
+ arr[i] = this.ctx.getByte();
168
+ }
169
+ return implReturn(arr.buffer);
170
+ }
171
+ case PackingSchema.String: {
172
+ const strLen = this.readUIntData();
173
+ const arr = new Uint8Array(strLen);
174
+ for (let i = 0; i < strLen; i++) {
175
+ arr[i] = this.ctx.getByte();
176
+ }
177
+ return implReturn((0, cpon_1.utf8ToString)(arr.buffer));
178
+ }
179
+ case PackingSchema.CString: {
180
+ // variation of CponReader.readCString()
181
+ const pctx = new cpcontext_1.PackContext();
182
+ while (true) {
183
+ let b = this.ctx.getByte();
184
+ if (b === '\\'.codePointAt(0)) {
185
+ b = this.ctx.getByte();
186
+ switch (b) {
187
+ case '\\'.codePointAt(0):
188
+ pctx.putByte('\\'.codePointAt(0));
189
+ break;
190
+ case '0'.codePointAt(0):
191
+ pctx.putByte(0);
192
+ break;
193
+ default:
194
+ pctx.putByte(b);
195
+ break;
196
+ }
197
+ }
198
+ else if (b === 0) {
199
+ // end of string
200
+ break;
201
+ }
202
+ else {
203
+ pctx.putByte(b);
204
+ }
205
+ }
206
+ return implReturn((0, cpon_1.utf8ToString)(pctx.buffer()));
207
+ }
208
+ default:
209
+ throw new TypeError('ChainPack - Invalid type info: ' + codePointAt);
210
+ }
211
+ }
212
+ /* eslint-enable complexity */
213
+ readUIntDataHelper(type) {
214
+ let num = 0;
215
+ const head = this.ctx.getByte();
216
+ let bytesToReadCnt;
217
+ switch (0) {
218
+ case head & 128: {
219
+ bytesToReadCnt = 0;
220
+ num = head & 127;
221
+ break;
222
+ }
223
+ case head & 64: {
224
+ bytesToReadCnt = 1;
225
+ num = head & 63;
226
+ break;
227
+ }
228
+ case head & 32: {
229
+ bytesToReadCnt = 2;
230
+ num = head & 31;
231
+ break;
232
+ }
233
+ case head & 16: {
234
+ bytesToReadCnt = 3;
235
+ num = head & 15;
236
+ break;
237
+ }
238
+ default: {
239
+ bytesToReadCnt = (head & 0xF) + 4;
240
+ }
241
+ }
242
+ const bytes = new Uint8Array(bytesToReadCnt + 1);
243
+ bytes[0] = num;
244
+ for (let i = 0; i < bytesToReadCnt; i++) {
245
+ const r = this.ctx.getByte();
246
+ bytes[i + 1] = r;
247
+ }
248
+ return uint8ArrayBoBigint(bytes, type);
249
+ }
250
+ readIntData() {
251
+ const val = this.readUIntDataHelper('Int');
252
+ if (val <= Number.MIN_SAFE_INTEGER) {
253
+ return Number.MIN_SAFE_INTEGER;
254
+ }
255
+ if (val >= Number.MAX_SAFE_INTEGER) {
256
+ return Number.MAX_SAFE_INTEGER;
257
+ }
258
+ return Number(val);
259
+ }
260
+ readUIntData() {
261
+ const val = this.readUIntDataHelper('UInt');
262
+ if (val >= Number.MAX_SAFE_INTEGER) {
263
+ return Number.MAX_SAFE_INTEGER;
264
+ }
265
+ return Number(val);
266
+ }
267
+ readList() {
268
+ const lst = [];
269
+ while (true) {
270
+ const b = this.ctx.peekByte();
271
+ if (b === PackingSchema.Term) {
272
+ this.ctx.getByte();
273
+ break;
274
+ }
275
+ lst.push(this.read());
276
+ }
277
+ return lst;
278
+ }
279
+ readMetaMap() {
280
+ return this.implReadMap('metamap');
281
+ }
282
+ readMap() {
283
+ return this.implReadMap('map');
284
+ }
285
+ readIMap() {
286
+ return this.implReadMap('imap');
287
+ }
288
+ implReadMap(mapType) {
289
+ const map = {
290
+ [rpcvalue_1.shvMapType]: mapType,
291
+ };
292
+ while (true) {
293
+ const b = this.ctx.peekByte();
294
+ if (b === PackingSchema.Term) {
295
+ this.ctx.getByte();
296
+ break;
297
+ }
298
+ const key = this.read();
299
+ const val = this.read();
300
+ if (map[rpcvalue_1.shvMapType] === 'metamap' && typeof key === 'string') {
301
+ map[key] = val;
302
+ }
303
+ else if (map[rpcvalue_1.shvMapType] === 'metamap' && typeof key === 'number') {
304
+ map[Number(key)] = val;
305
+ }
306
+ else if (map[rpcvalue_1.shvMapType] === 'map' && typeof key === 'string') {
307
+ map[key] = val;
308
+ }
309
+ else if (map[rpcvalue_1.shvMapType] === 'imap' && typeof key === 'number') {
310
+ map[Number(key)] = val;
311
+ }
312
+ else {
313
+ throw new TypeError('Malformed map, invalid key');
314
+ }
315
+ }
316
+ return map;
317
+ }
318
+ }
319
+ exports.ChainPackReader = ChainPackReader;
320
+ class ChainPackWriter {
321
+ ctx;
322
+ constructor() {
323
+ this.ctx = new cpcontext_1.PackContext();
324
+ }
325
+ write(rpcVal) {
326
+ if (rpcVal instanceof rpcvalue_1.RpcValueWithMetaData) {
327
+ this.writeMeta(rpcVal.meta);
328
+ rpcVal = rpcVal.value;
329
+ }
330
+ switch (true) {
331
+ case rpcVal === undefined:
332
+ this.ctx.putByte(PackingSchema.Null);
333
+ break;
334
+ case typeof rpcVal === 'boolean':
335
+ this.ctx.putByte(rpcVal ? PackingSchema.True : PackingSchema.False);
336
+ break;
337
+ case typeof rpcVal === 'string':
338
+ this.writeJSString(rpcVal);
339
+ break;
340
+ case rpcVal instanceof ArrayBuffer:
341
+ this.writeBlob(rpcVal);
342
+ break;
343
+ case rpcVal instanceof rpcvalue_1.UInt:
344
+ this.writeUInt(rpcVal);
345
+ break;
346
+ case typeof rpcVal === 'number':
347
+ this.writeInt(rpcVal);
348
+ break;
349
+ case rpcVal instanceof rpcvalue_1.Decimal:
350
+ this.writeDecimal(rpcVal);
351
+ break;
352
+ case Array.isArray(rpcVal):
353
+ this.writeList(rpcVal);
354
+ break;
355
+ case rpcVal instanceof Date:
356
+ this.writeDateTime(rpcVal);
357
+ break;
358
+ case rpcVal instanceof rpcvalue_1.Double:
359
+ this.writeDouble(rpcVal);
360
+ break;
361
+ case typeof rpcVal === 'object':
362
+ switch (rpcVal[rpcvalue_1.shvMapType]) {
363
+ case 'imap':
364
+ this.writeIMap(rpcVal);
365
+ break;
366
+ case 'map':
367
+ this.writeMap(rpcVal);
368
+ break;
369
+ }
370
+ break;
371
+ default:
372
+ console.log('Can\'t serialize', rpcVal);
373
+ throw new Error('Can\'t serialize');
374
+ }
375
+ }
376
+ writeUIntDataHelper(num, type) {
377
+ const isNegative = num < 0;
378
+ if (isNegative) {
379
+ num = -num;
380
+ }
381
+ const significantBits = significantBitsCount(num) + ( /* one more needed for sign bit */type === 'Int' ? 1 : 0);
382
+ const bytesNeeded = significantBits <= 28 ? Math.trunc((significantBits - 1) / 7) + 1 : Math.trunc((significantBits - 1) / 8) + 2;
383
+ switch (bytesNeeded) {
384
+ case 0:
385
+ throw new Error(`Failed to count bytes needed for ${num}`);
386
+ case 1:
387
+ if (isNegative) {
388
+ num |= 64n;
389
+ }
390
+ break;
391
+ case 2:
392
+ num |= 128n << 8n;
393
+ if (isNegative) {
394
+ num |= 32n << 8n;
395
+ }
396
+ break;
397
+ case 3:
398
+ num |= 192n << 16n;
399
+ if (isNegative) {
400
+ num |= 16n << 16n;
401
+ }
402
+ break;
403
+ case 4:
404
+ num |= 224n << 24n;
405
+ if (isNegative) {
406
+ num |= 8n << 24n;
407
+ }
408
+ break;
409
+ default:
410
+ num |= 240n << BigInt((bytesNeeded - 1) * 8);
411
+ num |= BigInt(bytesNeeded - 4 /* n is offset by 4 */ - 1 /* for the control byte */) << BigInt((bytesNeeded - 1) * 8);
412
+ if (isNegative) {
413
+ num |= 128n << BigInt((bytesNeeded - 2) * 8);
414
+ }
415
+ break;
416
+ }
417
+ const bytes = numberToUint8Array(num);
418
+ for (const byte of bytes) {
419
+ this.ctx.putByte(byte);
420
+ }
421
+ }
422
+ writeUIntData(num) {
423
+ this.writeUIntDataHelper(BigInt(num), 'UInt');
424
+ }
425
+ writeIntData(snum) {
426
+ this.writeUIntDataHelper(BigInt(snum), 'Int');
427
+ }
428
+ writeInt(n) {
429
+ if (Number(n) >= 0 && Number(n) < 64) {
430
+ this.ctx.putByte(Number(n) + 64);
431
+ return;
432
+ }
433
+ this.ctx.putByte(PackingSchema.Int);
434
+ this.writeIntData(Number(n));
435
+ }
436
+ writeUInt(n) {
437
+ if (Number(n) < 64) {
438
+ this.ctx.putByte(Number(n));
439
+ return;
440
+ }
441
+ this.ctx.putByte(PackingSchema.UInt);
442
+ this.writeUIntData(Number(n));
443
+ }
444
+ writeJSString(str) {
445
+ this.ctx.putByte(PackingSchema.String);
446
+ const pctx = new cpcontext_1.PackContext();
447
+ pctx.writeStringUtf8(str);
448
+ this.writeUIntData(pctx.length);
449
+ for (let i = 0; i < pctx.length; i++) {
450
+ this.ctx.putByte(pctx.data[i]);
451
+ }
452
+ }
453
+ writeDecimal(val) {
454
+ this.ctx.putByte(PackingSchema.Decimal);
455
+ this.writeIntData(val.mantisa);
456
+ this.writeIntData(val.exponent);
457
+ }
458
+ writeBlob(blob) {
459
+ this.ctx.putByte(PackingSchema.Blob);
460
+ const arr = new Uint8Array(blob);
461
+ this.writeUIntData(arr.length);
462
+ for (const element of arr) {
463
+ this.ctx.putByte(element);
464
+ }
465
+ }
466
+ writeDateTime(dt) {
467
+ this.ctx.putByte(PackingSchema.DateTime);
468
+ let msecs = (dt.getTime() + (60_000 * (dt.utc_offset ?? 0))) - SHV_EPOCH_MSEC;
469
+ if (msecs < 0) {
470
+ throw new RangeError('DateTime prior to 2018-02-02 are not supported in current ChainPack implementation.');
471
+ }
472
+ const ms = msecs % 1000;
473
+ if (ms === 0) {
474
+ msecs /= 1000;
475
+ }
476
+ let bi = BigInt(msecs);
477
+ if (dt.utc_offset !== undefined && dt.utc_offset !== 0) {
478
+ bi <<= 7n;
479
+ bi |= BigInt((dt.utc_offset / 15) & 0x7F);
480
+ }
481
+ bi <<= 2n;
482
+ if (dt.utc_offset !== undefined && dt.utc_offset !== 0) {
483
+ bi |= 1n;
484
+ }
485
+ if (ms === 0) {
486
+ bi |= 2n;
487
+ }
488
+ // save as signed int
489
+ this.writeUIntDataHelper(bi, 'UInt');
490
+ }
491
+ writeDouble(double) {
492
+ this.ctx.putByte(PackingSchema.Double);
493
+ const buffer = new ArrayBuffer(8);
494
+ const view = new DataView(buffer);
495
+ view.setFloat64(0, double.value, true);
496
+ const data = new Uint8Array(buffer);
497
+ for (let i = 0; i < 8; i++) {
498
+ this.ctx.putByte(data[i]);
499
+ }
500
+ }
501
+ writeList(lst) {
502
+ this.ctx.putByte(PackingSchema.List);
503
+ for (const element of lst) {
504
+ this.write(element);
505
+ }
506
+ this.ctx.putByte(PackingSchema.Term);
507
+ }
508
+ writeMeta(map) {
509
+ this.ctx.putByte(PackingSchema.MetaMap);
510
+ this.writeMapContent(map);
511
+ }
512
+ writeIMap(map) {
513
+ this.ctx.putByte(PackingSchema.IMap);
514
+ this.writeMapContent(map);
515
+ }
516
+ writeMap(map) {
517
+ this.ctx.putByte(PackingSchema.Map);
518
+ this.writeMapContent(map);
519
+ }
520
+ writeMapContent(map) {
521
+ for (const [key, value] of Object.entries(map)) {
522
+ if (value === undefined) {
523
+ continue;
524
+ }
525
+ if (map[rpcvalue_1.shvMapType] === 'imap') {
526
+ const intKey = Number(key);
527
+ if (Number.isNaN(intKey)) {
528
+ throw new TypeError('Invalid NaN IMap key');
529
+ }
530
+ this.writeInt(intKey);
531
+ }
532
+ else if (map[rpcvalue_1.shvMapType] === 'metamap') {
533
+ const intKey = Number(key);
534
+ if (Number.isNaN(intKey)) {
535
+ this.writeJSString(key.toString());
536
+ }
537
+ else {
538
+ this.writeInt(intKey);
539
+ }
540
+ }
541
+ else {
542
+ this.writeJSString(key.toString());
543
+ }
544
+ this.write(value);
545
+ }
546
+ this.ctx.putByte(PackingSchema.Term);
547
+ }
548
+ }
549
+ exports.ChainPackWriter = ChainPackWriter;
550
+ const toChainPack = (value) => {
551
+ const wr = new ChainPackWriter();
552
+ wr.write(value);
553
+ return wr.ctx.buffer();
554
+ };
555
+ exports.toChainPack = toChainPack;
556
+ const fromChainPack = (buffer) => {
557
+ const reader = new ChainPackReader(buffer);
558
+ return reader.read();
559
+ };
560
+ exports.fromChainPack = fromChainPack;
561
+ const CHAINPACK_PROTOCOL_TYPE = 1;
562
+ exports.CHAINPACK_PROTOCOL_TYPE = CHAINPACK_PROTOCOL_TYPE;
@@ -0,0 +1,18 @@
1
+ declare class UnpackContext {
2
+ index: number;
3
+ private readonly data;
4
+ constructor(buf: ArrayBufferLike);
5
+ getByte(): number;
6
+ peekByte(): number;
7
+ getBytes(str: string): void;
8
+ }
9
+ declare class PackContext {
10
+ static CHUNK_LEN: number;
11
+ data: Uint8Array<ArrayBuffer>;
12
+ length: number;
13
+ putByte(b: number): void;
14
+ writeStringUtf8(str: string): void;
15
+ writeCharCodeUtf8(charcode: number): void;
16
+ buffer(): ArrayBuffer;
17
+ }
18
+ export { PackContext, UnpackContext };
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UnpackContext = exports.PackContext = void 0;
4
+ class UnpackContext {
5
+ index;
6
+ data;
7
+ constructor(buf) {
8
+ this.data = new Uint8Array(buf);
9
+ this.index = 0;
10
+ }
11
+ getByte() {
12
+ if (this.index >= this.data.length) {
13
+ throw new RangeError('unexpected end of data');
14
+ }
15
+ return this.data[this.index++];
16
+ }
17
+ peekByte() {
18
+ if (this.index >= this.data.length) {
19
+ return -1;
20
+ }
21
+ return this.data[this.index];
22
+ }
23
+ getBytes(str) {
24
+ for (let i = 0; i < str.length; i++) {
25
+ if (str.codePointAt(i) !== this.getByte()) {
26
+ throw new TypeError(`'${str}' expected`);
27
+ }
28
+ }
29
+ }
30
+ }
31
+ exports.UnpackContext = UnpackContext;
32
+ const transfer = (source, length) => {
33
+ if (length <= source.byteLength) {
34
+ return source.slice(0, length);
35
+ }
36
+ const sourceView = new Uint8Array(source);
37
+ const destView = new Uint8Array(new ArrayBuffer(length));
38
+ destView.set(sourceView);
39
+ return destView.buffer;
40
+ };
41
+ class PackContext {
42
+ static CHUNK_LEN = 1024;
43
+ data = new Uint8Array(0);
44
+ length = 0;
45
+ putByte(b) {
46
+ if (this.length >= this.data.length) {
47
+ const buffer = transfer(this.data.buffer, this.data.length + PackContext.CHUNK_LEN);
48
+ this.data = new Uint8Array(buffer);
49
+ }
50
+ this.data[this.length++] = b;
51
+ }
52
+ writeStringUtf8(str) {
53
+ for (let i = 0; i < str.length; i++) {
54
+ const charcode = str.codePointAt(i);
55
+ this.writeCharCodeUtf8(charcode);
56
+ }
57
+ }
58
+ writeCharCodeUtf8(charcode) {
59
+ /* eslint-disable no-bitwise */
60
+ if (charcode < 0x80) {
61
+ this.putByte(charcode);
62
+ }
63
+ else if (charcode < 0x8_00) {
64
+ this.putByte(0xC0 | (charcode >> 6));
65
+ this.putByte(0x80 | (charcode & 0x3F));
66
+ }
67
+ else if (charcode < 0xD8_00 || charcode >= 0xE0_00) {
68
+ this.putByte(0xE0 | (charcode >> 12));
69
+ this.putByte(0x80 | ((charcode >> 6) & 0x3F));
70
+ this.putByte(0x80 | (charcode & 0x3F));
71
+ }
72
+ /* eslint-enable no-bitwise */
73
+ }
74
+ buffer() {
75
+ return this.data.buffer.slice(0, this.length);
76
+ }
77
+ }
78
+ exports.PackContext = PackContext;