@aioha/tx-digest 1.0.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,3401 @@
1
+ /**
2
+
3
+ * @license bytebuffer.js (c) 2015 Daniel Wirtz <dcode@dcode.io>
4
+
5
+ * Backing buffer: ArrayBuffer, Accessor: DataView
6
+
7
+ * Released under the Apache License, Version 2.0
8
+
9
+ * see: https://github.com/dcodeIO/bytebuffer.js for details
10
+
11
+ * modified by @xmcl/bytebuffer
12
+
13
+ * And customized for hive-tx
14
+
15
+ */
16
+
17
+ export class ByteBuffer {
18
+ /**
19
+
20
+ * ByteBuffer version.
21
+
22
+ * @type {string}
23
+
24
+ * @const
25
+
26
+ * @expose
27
+
28
+ */
29
+
30
+ static VERSION = '0.0.1'
31
+
32
+ /**
33
+
34
+ * Little endian constant that can be used instead of its boolean value. Evaluates to `true`.
35
+
36
+ * @type {boolean}
37
+
38
+ * @const
39
+
40
+ * @expose
41
+
42
+ */
43
+
44
+ static LITTLE_ENDIAN = true
45
+
46
+ /**
47
+
48
+ * Big endian constant that can be used instead of its boolean value. Evaluates to `false`.
49
+
50
+ * @type {boolean}
51
+
52
+ * @const
53
+
54
+ * @expose
55
+
56
+ */
57
+
58
+ static BIG_ENDIAN = false
59
+
60
+ /**
61
+
62
+ * Default initial capacity of `16`.
63
+
64
+ * @type {number}
65
+
66
+ * @expose
67
+
68
+ */
69
+
70
+ static DEFAULT_CAPACITY = 16
71
+
72
+ /**
73
+
74
+ * Default endianess of `false` for big endian.
75
+
76
+ * @type {boolean}
77
+
78
+ * @expose
79
+
80
+ */
81
+
82
+ static DEFAULT_ENDIAN = ByteBuffer.BIG_ENDIAN
83
+
84
+ /**
85
+
86
+ * Default no assertions flag of `false`.
87
+
88
+ * @type {boolean}
89
+
90
+ * @expose
91
+
92
+ */
93
+
94
+ static DEFAULT_NOASSERT = false
95
+
96
+ /**
97
+
98
+ * Backing ArrayBuffer.
99
+
100
+ * @type {!ArrayBuffer}
101
+
102
+ * @expose
103
+
104
+ */
105
+
106
+ /**
107
+ * Metrics representing number of bytes. Evaluates to `b`.
108
+ * @type {string}
109
+ * @const
110
+ * @expose
111
+ */
112
+ static METRICS_BYTES = 'b'
113
+
114
+ buffer
115
+
116
+ /**
117
+
118
+ * DataView utilized to manipulate the backing buffer. Becomes `null` if the backing buffer has a capacity of `0`.
119
+
120
+ * @type {?DataView}
121
+
122
+ * @expose
123
+
124
+ */
125
+
126
+ view
127
+
128
+ /**
129
+
130
+ * Absolute read/write offset.
131
+
132
+ * @type {number}
133
+
134
+ * @expose
135
+
136
+ * @see ByteBuffer#flip
137
+
138
+ * @see ByteBuffer#clear
139
+
140
+ */
141
+
142
+ offset
143
+
144
+ /**
145
+
146
+ * Marked offset.
147
+
148
+ * @type {number}
149
+
150
+ * @expose
151
+
152
+ * @see ByteBuffer#mark
153
+
154
+ * @see ByteBuffer#reset
155
+
156
+ */
157
+
158
+ markedOffset
159
+
160
+ /**
161
+
162
+ * Absolute limit of the contained data. Set to the backing buffer's capacity upon allocation.
163
+
164
+ * @type {number}
165
+
166
+ * @expose
167
+
168
+ * @see ByteBuffer#flip
169
+
170
+ * @see ByteBuffer#clear
171
+
172
+ */
173
+
174
+ limit
175
+
176
+ /**
177
+
178
+ * Whether to use little endian byte order, defaults to `false` for big endian.
179
+
180
+ * @type {boolean}
181
+
182
+ * @expose
183
+
184
+ */
185
+
186
+ littleEndian
187
+
188
+ /**
189
+
190
+ * Whether to skip assertions of offsets and values, defaults to `false`.
191
+
192
+ * @type {boolean}
193
+
194
+ * @expose
195
+
196
+ */
197
+
198
+ noAssert
199
+
200
+ /**
201
+
202
+ * Constructs a new ByteBuffer.
203
+
204
+ * @class The swiss army knife for binary data in JavaScript.
205
+
206
+ * @exports ByteBuffer
207
+
208
+ * @constructor
209
+
210
+ * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
211
+
212
+ * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
213
+
214
+ * {@link ByteBuffer.DEFAULT_ENDIAN}.
215
+
216
+ * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
217
+
218
+ * {@link ByteBuffer.DEFAULT_NOASSERT}.
219
+
220
+ * @expose
221
+
222
+ */
223
+
224
+ constructor(capacity, littleEndian, noAssert) {
225
+ if (typeof capacity === 'undefined') {
226
+ capacity = ByteBuffer.DEFAULT_CAPACITY
227
+ }
228
+
229
+ if (typeof littleEndian === 'undefined') {
230
+ littleEndian = ByteBuffer.DEFAULT_ENDIAN
231
+ }
232
+
233
+ if (typeof noAssert === 'undefined') {
234
+ noAssert = ByteBuffer.DEFAULT_NOASSERT
235
+ }
236
+
237
+ if (!noAssert) {
238
+ capacity = capacity | 0
239
+
240
+ if (capacity < 0) {
241
+ throw RangeError('Illegal capacity')
242
+ }
243
+
244
+ littleEndian = !!littleEndian
245
+
246
+ noAssert = !!noAssert
247
+ }
248
+
249
+ this.buffer = capacity === 0 ? EMPTY_BUFFER : new ArrayBuffer(capacity)
250
+
251
+ this.view = capacity === 0 ? new DataView(EMPTY_BUFFER) : new DataView(this.buffer)
252
+
253
+ this.offset = 0
254
+
255
+ this.markedOffset = -1
256
+
257
+ this.limit = capacity
258
+
259
+ this.littleEndian = littleEndian
260
+
261
+ this.noAssert = noAssert
262
+ }
263
+
264
+ /**
265
+
266
+ * Gets the accessor type.
267
+
268
+ * @returns {Function} `Buffer` under node.js, `Uint8Array` respectively `DataView` in the browser (classes)
269
+
270
+ * @expose
271
+
272
+ */
273
+
274
+ static accessor = function () {
275
+ return DataView
276
+ }
277
+
278
+ /**
279
+
280
+ * Allocates a new ByteBuffer backed by a buffer of the specified capacity.
281
+
282
+ * @param {number=} capacity Initial capacity. Defaults to {@link ByteBuffer.DEFAULT_CAPACITY}.
283
+
284
+ * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
285
+
286
+ * {@link ByteBuffer.DEFAULT_ENDIAN}.
287
+
288
+ * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
289
+
290
+ * {@link ByteBuffer.DEFAULT_NOASSERT}.
291
+
292
+ * @returns {!ByteBuffer}
293
+
294
+ * @expose
295
+
296
+ */
297
+
298
+ static allocate = function (capacity, littleEndian, noAssert) {
299
+ return new ByteBuffer(capacity, littleEndian, noAssert)
300
+ }
301
+
302
+ /**
303
+
304
+ * Concatenates multiple ByteBuffers into one.
305
+
306
+ * @param {!Array.<!ByteBuffer|!ArrayBuffer|!Uint8Array>} buffers Buffers to concatenate
307
+
308
+ * @param {(string|boolean)=} encoding String encoding if `buffers` contains a string ("base64", "hex", "binary",
309
+
310
+ * defaults to "utf8")
311
+
312
+ * @param {boolean=} littleEndian Whether to use little or big endian byte order for the resulting ByteBuffer. Defaults
313
+
314
+ * to {@link ByteBuffer.DEFAULT_ENDIAN}.
315
+
316
+ * @param {boolean=} noAssert Whether to skip assertions of offsets and values for the resulting ByteBuffer. Defaults to
317
+
318
+ * {@link ByteBuffer.DEFAULT_NOASSERT}.
319
+
320
+ * @returns {!ByteBuffer} Concatenated ByteBuffer
321
+
322
+ * @expose
323
+
324
+ */
325
+
326
+ static concat = function (buffers, littleEndian, noAssert) {
327
+ let capacity = 0
328
+
329
+ const k = buffers.length
330
+
331
+ let length
332
+
333
+ for (let i2 = 0, length2; i2 < k; ++i2) {
334
+ const buf = buffers[i2]
335
+
336
+ if (!(buf instanceof ByteBuffer)) {
337
+ buffers[i2] = ByteBuffer.wrap(buf)
338
+ }
339
+
340
+ length2 = buffers[i2].limit - buffers[i2].offset
341
+
342
+ if (length2 > 0) {
343
+ capacity += length2
344
+ }
345
+ }
346
+
347
+ if (capacity === 0) {
348
+ return new ByteBuffer(0, littleEndian, noAssert)
349
+ }
350
+
351
+ const bb = new ByteBuffer(capacity, littleEndian, noAssert)
352
+
353
+ let bi
354
+
355
+ const view = new Uint8Array(bb.buffer)
356
+
357
+ let i = 0
358
+
359
+ while (i < k) {
360
+ bi = buffers[i++]
361
+
362
+ length = bi.limit - bi.offset
363
+
364
+ if (length <= 0) {
365
+ continue
366
+ }
367
+
368
+ view.set(new Uint8Array(bi.buffer).subarray(bi.offset, bi.limit), bb.offset)
369
+
370
+ bb.offset += length
371
+ }
372
+
373
+ bb.limit = bb.offset
374
+
375
+ bb.offset = 0
376
+
377
+ return bb
378
+ }
379
+
380
+ /**
381
+
382
+ * Gets the backing buffer type.
383
+
384
+ * @returns {Function} `Buffer` under node.js, `ArrayBuffer` in the browser (classes)
385
+
386
+ * @expose
387
+
388
+ */
389
+
390
+ static type = function () {
391
+ return ArrayBuffer
392
+ }
393
+
394
+ /**
395
+
396
+ * Wraps a buffer or a string. Sets the allocated ByteBuffer's {@link ByteBuffer#offset} to `0` and its
397
+
398
+ * {@link ByteBuffer#limit} to the length of the wrapped data.
399
+
400
+ * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string|!Array.<number>} buffer Anything that can be wrapped
401
+
402
+ * @param {boolean=} littleEndian Whether to use little or big endian byte order. Defaults to
403
+
404
+ * {@link ByteBuffer.DEFAULT_ENDIAN}.
405
+
406
+ * @param {boolean=} noAssert Whether to skip assertions of offsets and values. Defaults to
407
+
408
+ * {@link ByteBuffer.DEFAULT_NOASSERT}.
409
+
410
+ * @returns {!ByteBuffer} A ByteBuffer wrapping `buffer`
411
+
412
+ * @expose
413
+
414
+ */
415
+
416
+ static wrap = function (buffer, littleEndian, noAssert) {
417
+ if (buffer === null || typeof buffer !== 'object') {
418
+ throw TypeError('Illegal buffer')
419
+ }
420
+
421
+ let bb
422
+
423
+ if (buffer instanceof ByteBuffer) {
424
+ bb = buffer.clone()
425
+
426
+ bb.markedOffset = -1
427
+
428
+ return bb
429
+ }
430
+
431
+ if (buffer instanceof Uint8Array) {
432
+ bb = new ByteBuffer(0, littleEndian, noAssert)
433
+
434
+ if (buffer.length > 0) {
435
+ bb.buffer = buffer.buffer
436
+
437
+ bb.offset = buffer.byteOffset
438
+
439
+ bb.limit = buffer.byteOffset + buffer.byteLength
440
+
441
+ bb.view = new DataView(buffer.buffer)
442
+ }
443
+ } else if (buffer instanceof ArrayBuffer) {
444
+ bb = new ByteBuffer(0, littleEndian, noAssert)
445
+
446
+ if (buffer.byteLength > 0) {
447
+ bb.buffer = buffer
448
+
449
+ bb.offset = 0
450
+
451
+ bb.limit = buffer.byteLength
452
+
453
+ bb.view = buffer.byteLength > 0 ? new DataView(buffer) : new DataView(EMPTY_BUFFER)
454
+ }
455
+ } else if (Object.prototype.toString.call(buffer) === '[object Array]') {
456
+ bb = new ByteBuffer(buffer.length, littleEndian, noAssert)
457
+
458
+ bb.limit = buffer.length
459
+
460
+ for (let i = 0; i < buffer.length; ++i) {
461
+ bb.view.setUint8(i, buffer[i])
462
+ }
463
+ } else {
464
+ throw TypeError('Illegal buffer')
465
+ }
466
+
467
+ return bb
468
+ }
469
+
470
+ /**
471
+
472
+ * Reads the specified number of bytes.
473
+
474
+ * @param {number} length Number of bytes to read
475
+
476
+ * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `length` if omitted.
477
+
478
+ * @returns {!ByteBuffer}
479
+
480
+ * @expose
481
+
482
+ */
483
+
484
+ readBytes(length, offset) {
485
+ const relative = typeof offset === 'undefined'
486
+
487
+ if (relative) {
488
+ offset = this.offset
489
+ }
490
+
491
+ if (!this.noAssert) {
492
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
493
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
494
+ }
495
+
496
+ offset >>>= 0
497
+
498
+ if (offset < 0 || offset + length > this.buffer.byteLength) {
499
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+' + length + ') <= ' + this.buffer.byteLength)
500
+ }
501
+ }
502
+
503
+ const slice = this.slice(offset, offset + length)
504
+
505
+ if (relative) {
506
+ this.offset += length
507
+ }
508
+
509
+ return slice
510
+ }
511
+
512
+ /**
513
+
514
+ * Writes a payload of bytes. This is an alias of {@link ByteBuffer#append}.
515
+
516
+ * @function
517
+
518
+ * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array|string} source Data to write. If `source` is a ByteBuffer, its offsets
519
+
520
+ * will be modified according to the performed read operation.
521
+
522
+ * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
523
+
524
+ * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
525
+
526
+ * written if omitted.
527
+
528
+ * @returns {!ByteBuffer} this
529
+
530
+ * @expose
531
+
532
+ */
533
+
534
+ writeBytes = this.append
535
+
536
+ // types/ints/int8
537
+
538
+ /**
539
+
540
+ * Writes an 8bit signed integer.
541
+
542
+ * @param {number} value Value to write
543
+
544
+ * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
545
+
546
+ * @returns {!ByteBuffer} this
547
+
548
+ * @expose
549
+
550
+ */
551
+
552
+ writeInt8(value, offset) {
553
+ const relative = typeof offset === 'undefined'
554
+
555
+ if (relative) {
556
+ offset = this.offset
557
+ }
558
+
559
+ if (!this.noAssert) {
560
+ if (typeof value !== 'number' || value % 1 !== 0) {
561
+ throw TypeError('Illegal value: ' + value + ' (not an integer)')
562
+ }
563
+
564
+ value |= 0
565
+
566
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
567
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
568
+ }
569
+
570
+ offset >>>= 0
571
+
572
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
573
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+0) <= ' + this.buffer.byteLength)
574
+ }
575
+ }
576
+
577
+ offset += 1
578
+
579
+ let capacity0 = this.buffer.byteLength
580
+
581
+ if (offset > capacity0) {
582
+ this.resize((capacity0 *= 2) > offset ? capacity0 : offset)
583
+ }
584
+
585
+ offset -= 1
586
+
587
+ this.view.setInt8(offset, value)
588
+
589
+ if (relative) {
590
+ this.offset += 1
591
+ }
592
+
593
+ return this
594
+ }
595
+
596
+ /**
597
+
598
+ * Writes an 8bit signed integer. This is an alias of {@link ByteBuffer#writeInt8}.
599
+
600
+ * @function
601
+
602
+ * @param {number} value Value to write
603
+
604
+ * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
605
+
606
+ * @returns {!ByteBuffer} this
607
+
608
+ * @expose
609
+
610
+ */
611
+
612
+ writeByte = this.writeInt8
613
+
614
+ /**
615
+
616
+ * Reads an 8bit signed integer.
617
+
618
+ * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
619
+
620
+ * @returns {number} Value read
621
+
622
+ * @expose
623
+
624
+ */
625
+
626
+ readInt8(offset) {
627
+ const relative = typeof offset === 'undefined'
628
+
629
+ if (relative) {
630
+ offset = this.offset
631
+ }
632
+
633
+ if (!this.noAssert) {
634
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
635
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
636
+ }
637
+
638
+ offset >>>= 0
639
+
640
+ if (offset < 0 || offset + 1 > this.buffer.byteLength) {
641
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+1) <= ' + this.buffer.byteLength)
642
+ }
643
+ }
644
+
645
+ const value = this.view.getInt8(offset)
646
+
647
+ if (relative) {
648
+ this.offset += 1
649
+ }
650
+
651
+ return value
652
+ }
653
+
654
+ /**
655
+
656
+ * Reads an 8bit signed integer. This is an alias of {@link ByteBuffer#readInt8}.
657
+
658
+ * @function
659
+
660
+ * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
661
+
662
+ * @returns {number} Value read
663
+
664
+ * @expose
665
+
666
+ */
667
+
668
+ readByte = this.readInt8
669
+
670
+ /**
671
+
672
+ * Writes an 8bit unsigned integer.
673
+
674
+ * @param {number} value Value to write
675
+
676
+ * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
677
+
678
+ * @returns {!ByteBuffer} this
679
+
680
+ * @expose
681
+
682
+ */
683
+
684
+ writeUint8(value, offset) {
685
+ const relative = typeof offset === 'undefined'
686
+
687
+ if (relative) {
688
+ offset = this.offset
689
+ }
690
+
691
+ if (!this.noAssert) {
692
+ if (typeof value !== 'number' || value % 1 !== 0) {
693
+ throw TypeError('Illegal value: ' + value + ' (not an integer)')
694
+ }
695
+
696
+ value >>>= 0
697
+
698
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
699
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
700
+ }
701
+
702
+ offset >>>= 0
703
+
704
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
705
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+0) <= ' + this.buffer.byteLength)
706
+ }
707
+ }
708
+
709
+ offset += 1
710
+
711
+ let capacity1 = this.buffer.byteLength
712
+
713
+ if (offset > capacity1) {
714
+ this.resize((capacity1 *= 2) > offset ? capacity1 : offset)
715
+ }
716
+
717
+ offset -= 1
718
+
719
+ this.view.setUint8(offset, value)
720
+
721
+ if (relative) {
722
+ this.offset += 1
723
+ }
724
+
725
+ return this
726
+ }
727
+
728
+ /**
729
+
730
+ * Writes an 8bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint8}.
731
+
732
+ * @function
733
+
734
+ * @param {number} value Value to write
735
+
736
+ * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
737
+
738
+ * @returns {!ByteBuffer} this
739
+
740
+ * @expose
741
+
742
+ */
743
+
744
+ writeUInt8 = this.writeUint8
745
+
746
+ /**
747
+
748
+ * Reads an 8bit unsigned integer.
749
+
750
+ * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
751
+
752
+ * @returns {number} Value read
753
+
754
+ * @expose
755
+
756
+ */
757
+
758
+ readUint8(offset) {
759
+ const relative = typeof offset === 'undefined'
760
+
761
+ if (relative) {
762
+ offset = this.offset
763
+ }
764
+
765
+ if (!this.noAssert) {
766
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
767
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
768
+ }
769
+
770
+ offset >>>= 0
771
+
772
+ if (offset < 0 || offset + 1 > this.buffer.byteLength) {
773
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+1) <= ' + this.buffer.byteLength)
774
+ }
775
+ }
776
+
777
+ const value = this.view.getUint8(offset)
778
+
779
+ if (relative) {
780
+ this.offset += 1
781
+ }
782
+
783
+ return value
784
+ }
785
+
786
+ /**
787
+
788
+ * Reads an 8bit unsigned integer. This is an alias of {@link ByteBuffer#readUint8}.
789
+
790
+ * @function
791
+
792
+ * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `1` if omitted.
793
+
794
+ * @returns {number} Value read
795
+
796
+ * @expose
797
+
798
+ */
799
+
800
+ readUInt8 = this.readUint8
801
+
802
+ // types/ints/int16
803
+
804
+ /**
805
+
806
+ * Writes a 16bit signed integer.
807
+
808
+ * @param {number} value Value to write
809
+
810
+ * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
811
+
812
+ * @throws {TypeError} If `offset` or `value` is not a valid number
813
+
814
+ * @throws {RangeError} If `offset` is out of bounds
815
+
816
+ * @expose
817
+
818
+ */
819
+
820
+ writeInt16(value, offset) {
821
+ const relative = typeof offset === 'undefined'
822
+
823
+ if (relative) {
824
+ offset = this.offset
825
+ }
826
+
827
+ if (!this.noAssert) {
828
+ if (typeof value !== 'number' || value % 1 !== 0) {
829
+ throw TypeError('Illegal value: ' + value + ' (not an integer)')
830
+ }
831
+
832
+ value |= 0
833
+
834
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
835
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
836
+ }
837
+
838
+ offset >>>= 0
839
+
840
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
841
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+0) <= ' + this.buffer.byteLength)
842
+ }
843
+ }
844
+
845
+ offset += 2
846
+
847
+ let capacity2 = this.buffer.byteLength
848
+
849
+ if (offset > capacity2) {
850
+ this.resize((capacity2 *= 2) > offset ? capacity2 : offset)
851
+ }
852
+
853
+ offset -= 2
854
+
855
+ this.view.setInt16(offset, value, this.littleEndian)
856
+
857
+ if (relative) {
858
+ this.offset += 2
859
+ }
860
+
861
+ return this
862
+ }
863
+
864
+ /**
865
+
866
+ * Writes a 16bit signed integer. This is an alias of {@link ByteBuffer#writeInt16}.
867
+
868
+ * @function
869
+
870
+ * @param {number} value Value to write
871
+
872
+ * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
873
+
874
+ * @throws {TypeError} If `offset` or `value` is not a valid number
875
+
876
+ * @throws {RangeError} If `offset` is out of bounds
877
+
878
+ * @expose
879
+
880
+ */
881
+
882
+ writeShort = this.writeInt16
883
+
884
+ /**
885
+
886
+ * Reads a 16bit signed integer.
887
+
888
+ * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
889
+
890
+ * @returns {number} Value read
891
+
892
+ * @throws {TypeError} If `offset` is not a valid number
893
+
894
+ * @throws {RangeError} If `offset` is out of bounds
895
+
896
+ * @expose
897
+
898
+ */
899
+
900
+ readInt16(offset) {
901
+ const relative = typeof offset === 'undefined'
902
+
903
+ if (typeof offset === 'undefined') {
904
+ offset = this.offset
905
+ }
906
+
907
+ if (!this.noAssert) {
908
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
909
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
910
+ }
911
+
912
+ offset >>>= 0
913
+
914
+ if (offset < 0 || offset + 2 > this.buffer.byteLength) {
915
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+2) <= ' + this.buffer.byteLength)
916
+ }
917
+ }
918
+
919
+ const value = this.view.getInt16(offset, this.littleEndian)
920
+
921
+ if (relative) {
922
+ this.offset += 2
923
+ }
924
+
925
+ return value
926
+ }
927
+
928
+ /**
929
+
930
+ * Reads a 16bit signed integer. This is an alias of {@link ByteBuffer#readInt16}.
931
+
932
+ * @function
933
+
934
+ * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
935
+
936
+ * @returns {number} Value read
937
+
938
+ * @throws {TypeError} If `offset` is not a valid number
939
+
940
+ * @throws {RangeError} If `offset` is out of bounds
941
+
942
+ * @expose
943
+
944
+ */
945
+
946
+ readShort = this.readInt16
947
+
948
+ /**
949
+
950
+ * Writes a 16bit unsigned integer.
951
+
952
+ * @param {number} value Value to write
953
+
954
+ * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
955
+
956
+ * @throws {TypeError} If `offset` or `value` is not a valid number
957
+
958
+ * @throws {RangeError} If `offset` is out of bounds
959
+
960
+ * @expose
961
+
962
+ */
963
+
964
+ writeUint16(value, offset) {
965
+ const relative = typeof offset === 'undefined'
966
+
967
+ if (relative) {
968
+ offset = this.offset
969
+ }
970
+
971
+ if (!this.noAssert) {
972
+ if (typeof value !== 'number' || value % 1 !== 0) {
973
+ throw TypeError('Illegal value: ' + value + ' (not an integer)')
974
+ }
975
+
976
+ value >>>= 0
977
+
978
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
979
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
980
+ }
981
+
982
+ offset >>>= 0
983
+
984
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
985
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+0) <= ' + this.buffer.byteLength)
986
+ }
987
+ }
988
+
989
+ offset += 2
990
+
991
+ let capacity3 = this.buffer.byteLength
992
+
993
+ if (offset > capacity3) {
994
+ this.resize((capacity3 *= 2) > offset ? capacity3 : offset)
995
+ }
996
+
997
+ offset -= 2
998
+
999
+ this.view.setUint16(offset, value, this.littleEndian)
1000
+
1001
+ if (relative) {
1002
+ this.offset += 2
1003
+ }
1004
+
1005
+ return this
1006
+ }
1007
+
1008
+ /**
1009
+
1010
+ * Writes a 16bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint16}.
1011
+
1012
+ * @function
1013
+
1014
+ * @param {number} value Value to write
1015
+
1016
+ * @param {number=} offset Offset to write to. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
1017
+
1018
+ * @throws {TypeError} If `offset` or `value` is not a valid number
1019
+
1020
+ * @throws {RangeError} If `offset` is out of bounds
1021
+
1022
+ * @expose
1023
+
1024
+ */
1025
+
1026
+ writeUInt16 = this.writeUint16
1027
+
1028
+ /**
1029
+
1030
+ * Reads a 16bit unsigned integer.
1031
+
1032
+ * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
1033
+
1034
+ * @returns {number} Value read
1035
+
1036
+ * @throws {TypeError} If `offset` is not a valid number
1037
+
1038
+ * @throws {RangeError} If `offset` is out of bounds
1039
+
1040
+ * @expose
1041
+
1042
+ */
1043
+
1044
+ readUint16(offset) {
1045
+ const relative = typeof offset === 'undefined'
1046
+
1047
+ if (relative) {
1048
+ offset = this.offset
1049
+ }
1050
+
1051
+ if (!this.noAssert) {
1052
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
1053
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
1054
+ }
1055
+
1056
+ offset >>>= 0
1057
+
1058
+ if (offset < 0 || offset + 2 > this.buffer.byteLength) {
1059
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+2) <= ' + this.buffer.byteLength)
1060
+ }
1061
+ }
1062
+
1063
+ const value = this.view.getUint16(offset, this.littleEndian)
1064
+
1065
+ if (relative) {
1066
+ this.offset += 2
1067
+ }
1068
+
1069
+ return value
1070
+ }
1071
+
1072
+ /**
1073
+
1074
+ * Reads a 16bit unsigned integer. This is an alias of {@link ByteBuffer#readUint16}.
1075
+
1076
+ * @function
1077
+
1078
+ * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `2` if omitted.
1079
+
1080
+ * @returns {number} Value read
1081
+
1082
+ * @throws {TypeError} If `offset` is not a valid number
1083
+
1084
+ * @throws {RangeError} If `offset` is out of bounds
1085
+
1086
+ * @expose
1087
+
1088
+ */
1089
+
1090
+ readUInt16 = this.readUint16
1091
+
1092
+ // types/ints/int32
1093
+
1094
+ /**
1095
+
1096
+ * Writes a 32bit signed integer.
1097
+
1098
+ * @param {number} value Value to write
1099
+
1100
+ * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1101
+
1102
+ * @expose
1103
+
1104
+ */
1105
+
1106
+ writeInt32(value, offset) {
1107
+ const relative = typeof offset === 'undefined'
1108
+
1109
+ if (relative) {
1110
+ offset = this.offset
1111
+ }
1112
+
1113
+ if (!this.noAssert) {
1114
+ if (typeof value !== 'number' || value % 1 !== 0) {
1115
+ throw TypeError('Illegal value: ' + value + ' (not an integer)')
1116
+ }
1117
+
1118
+ value |= 0
1119
+
1120
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
1121
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
1122
+ }
1123
+
1124
+ offset >>>= 0
1125
+
1126
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
1127
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+0) <= ' + this.buffer.byteLength)
1128
+ }
1129
+ }
1130
+
1131
+ offset += 4
1132
+
1133
+ let capacity4 = this.buffer.byteLength
1134
+
1135
+ if (offset > capacity4) {
1136
+ this.resize((capacity4 *= 2) > offset ? capacity4 : offset)
1137
+ }
1138
+
1139
+ offset -= 4
1140
+
1141
+ this.view.setInt32(offset, value, this.littleEndian)
1142
+
1143
+ if (relative) {
1144
+ this.offset += 4
1145
+ }
1146
+
1147
+ return this
1148
+ }
1149
+
1150
+ /**
1151
+
1152
+ * Writes a 32bit signed integer. This is an alias of {@link ByteBuffer#writeInt32}.
1153
+
1154
+ * @param {number} value Value to write
1155
+
1156
+ * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1157
+
1158
+ * @expose
1159
+
1160
+ */
1161
+
1162
+ writeInt = this.writeInt32
1163
+
1164
+ /**
1165
+
1166
+ * Reads a 32bit signed integer.
1167
+
1168
+ * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1169
+
1170
+ * @returns {number} Value read
1171
+
1172
+ * @expose
1173
+
1174
+ */
1175
+
1176
+ readInt32(offset) {
1177
+ const relative = typeof offset === 'undefined'
1178
+
1179
+ if (relative) {
1180
+ offset = this.offset
1181
+ }
1182
+
1183
+ if (!this.noAssert) {
1184
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
1185
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
1186
+ }
1187
+
1188
+ offset >>>= 0
1189
+
1190
+ if (offset < 0 || offset + 4 > this.buffer.byteLength) {
1191
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+4) <= ' + this.buffer.byteLength)
1192
+ }
1193
+ }
1194
+
1195
+ const value = this.view.getInt32(offset, this.littleEndian)
1196
+
1197
+ if (relative) {
1198
+ this.offset += 4
1199
+ }
1200
+
1201
+ return value
1202
+ }
1203
+
1204
+ /**
1205
+
1206
+ * Reads a 32bit signed integer. This is an alias of {@link ByteBuffer#readInt32}.
1207
+
1208
+ * @param {number=} offset Offset to read from. Will use and advance {@link ByteBuffer#offset} by `4` if omitted.
1209
+
1210
+ * @returns {number} Value read
1211
+
1212
+ * @expose
1213
+
1214
+ */
1215
+
1216
+ readInt = this.readInt32
1217
+
1218
+ /**
1219
+
1220
+ * Writes a 32bit unsigned integer.
1221
+
1222
+ * @param {number} value Value to write
1223
+
1224
+ * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1225
+
1226
+ * @expose
1227
+
1228
+ */
1229
+
1230
+ writeUint32(value, offset) {
1231
+ const relative = typeof offset === 'undefined'
1232
+
1233
+ if (relative) {
1234
+ offset = this.offset
1235
+ }
1236
+
1237
+ if (!this.noAssert) {
1238
+ if (typeof value !== 'number' || value % 1 !== 0) {
1239
+ throw TypeError('Illegal value: ' + value + ' (not an integer)')
1240
+ }
1241
+
1242
+ value >>>= 0
1243
+
1244
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
1245
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
1246
+ }
1247
+
1248
+ offset >>>= 0
1249
+
1250
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
1251
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+0) <= ' + this.buffer.byteLength)
1252
+ }
1253
+ }
1254
+
1255
+ offset += 4
1256
+
1257
+ let capacity5 = this.buffer.byteLength
1258
+
1259
+ if (offset > capacity5) {
1260
+ this.resize((capacity5 *= 2) > offset ? capacity5 : offset)
1261
+ }
1262
+
1263
+ offset -= 4
1264
+
1265
+ this.view.setUint32(offset, value, this.littleEndian)
1266
+
1267
+ if (relative) {
1268
+ this.offset += 4
1269
+ }
1270
+
1271
+ return this
1272
+ }
1273
+
1274
+ /**
1275
+
1276
+ * Writes a 32bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint32}.
1277
+
1278
+ * @function
1279
+
1280
+ * @param {number} value Value to write
1281
+
1282
+ * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1283
+
1284
+ * @expose
1285
+
1286
+ */
1287
+
1288
+ writeUInt32 = this.writeUint32
1289
+
1290
+ /**
1291
+
1292
+ * Reads a 32bit unsigned integer.
1293
+
1294
+ * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1295
+
1296
+ * @returns {number} Value read
1297
+
1298
+ * @expose
1299
+
1300
+ */
1301
+
1302
+ readUint32(offset) {
1303
+ const relative = typeof offset === 'undefined'
1304
+
1305
+ if (relative) {
1306
+ offset = this.offset
1307
+ }
1308
+
1309
+ if (!this.noAssert) {
1310
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
1311
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
1312
+ }
1313
+
1314
+ offset >>>= 0
1315
+
1316
+ if (offset < 0 || offset + 4 > this.buffer.byteLength) {
1317
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+4) <= ' + this.buffer.byteLength)
1318
+ }
1319
+ }
1320
+
1321
+ const value = this.view.getUint32(offset, this.littleEndian)
1322
+
1323
+ if (relative) {
1324
+ this.offset += 4
1325
+ }
1326
+
1327
+ return value
1328
+ }
1329
+
1330
+ /**
1331
+
1332
+ * Reads a 32bit unsigned integer. This is an alias of {@link ByteBuffer#readUint32}.
1333
+
1334
+ * @function
1335
+
1336
+ * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1337
+
1338
+ * @returns {number} Value read
1339
+
1340
+ * @expose
1341
+
1342
+ */
1343
+
1344
+ readUInt32 = this.readUint32
1345
+
1346
+ /**
1347
+
1348
+ * Writes a 32bit float.
1349
+
1350
+ * @param {number} value Value to write
1351
+
1352
+ * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1353
+
1354
+ * @returns {!ByteBuffer} this
1355
+
1356
+ * @expose
1357
+
1358
+ */
1359
+
1360
+ writeFloat32(value, offset) {
1361
+ const relative = typeof offset === 'undefined'
1362
+
1363
+ if (relative) {
1364
+ offset = this.offset
1365
+ }
1366
+
1367
+ if (!this.noAssert) {
1368
+ if (typeof value !== 'number') {
1369
+ throw TypeError('Illegal value: ' + value + ' (not a number)')
1370
+ }
1371
+
1372
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
1373
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
1374
+ }
1375
+
1376
+ offset >>>= 0
1377
+
1378
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
1379
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+0) <= ' + this.buffer.byteLength)
1380
+ }
1381
+ }
1382
+
1383
+ offset += 4
1384
+
1385
+ let capacity8 = this.buffer.byteLength
1386
+
1387
+ if (offset > capacity8) {
1388
+ this.resize((capacity8 *= 2) > offset ? capacity8 : offset)
1389
+ }
1390
+
1391
+ offset -= 4
1392
+
1393
+ this.view.setFloat32(offset, value, this.littleEndian)
1394
+
1395
+ if (relative) {
1396
+ this.offset += 4
1397
+ }
1398
+
1399
+ return this
1400
+ }
1401
+
1402
+ /**
1403
+
1404
+ * Writes a 32bit float. This is an alias of {@link ByteBuffer#writeFloat32}.
1405
+
1406
+ * @function
1407
+
1408
+ * @param {number} value Value to write
1409
+
1410
+ * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1411
+
1412
+ * @returns {!ByteBuffer} this
1413
+
1414
+ * @expose
1415
+
1416
+ */
1417
+
1418
+ writeFloat = this.writeFloat32
1419
+
1420
+ /**
1421
+
1422
+ * Reads a 32bit float.
1423
+
1424
+ * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1425
+
1426
+ * @returns {number}
1427
+
1428
+ * @expose
1429
+
1430
+ */
1431
+
1432
+ readFloat32(offset) {
1433
+ const relative = typeof offset === 'undefined'
1434
+
1435
+ if (relative) {
1436
+ offset = this.offset
1437
+ }
1438
+
1439
+ if (!this.noAssert) {
1440
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
1441
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
1442
+ }
1443
+
1444
+ offset >>>= 0
1445
+
1446
+ if (offset < 0 || offset + 4 > this.buffer.byteLength) {
1447
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+4) <= ' + this.buffer.byteLength)
1448
+ }
1449
+ }
1450
+
1451
+ const value = this.view.getFloat32(offset, this.littleEndian)
1452
+
1453
+ if (relative) {
1454
+ this.offset += 4
1455
+ }
1456
+
1457
+ return value
1458
+ }
1459
+
1460
+ /**
1461
+
1462
+ * Reads a 32bit float. This is an alias of {@link ByteBuffer#readFloat32}.
1463
+
1464
+ * @function
1465
+
1466
+ * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `4` if omitted.
1467
+
1468
+ * @returns {number}
1469
+
1470
+ * @expose
1471
+
1472
+ */
1473
+
1474
+ readFloat = this.readFloat32
1475
+
1476
+ // types/floats/float64
1477
+
1478
+ /**
1479
+
1480
+ * Writes a 64bit float.
1481
+
1482
+ * @param {number} value Value to write
1483
+
1484
+ * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1485
+
1486
+ * @returns {!ByteBuffer} this
1487
+
1488
+ * @expose
1489
+
1490
+ */
1491
+
1492
+ writeFloat64(value, offset) {
1493
+ const relative = typeof offset === 'undefined'
1494
+
1495
+ if (relative) {
1496
+ offset = this.offset
1497
+ }
1498
+
1499
+ if (!this.noAssert) {
1500
+ if (typeof value !== 'number') {
1501
+ throw TypeError('Illegal value: ' + value + ' (not a number)')
1502
+ }
1503
+
1504
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
1505
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
1506
+ }
1507
+
1508
+ offset >>>= 0
1509
+
1510
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
1511
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+0) <= ' + this.buffer.byteLength)
1512
+ }
1513
+ }
1514
+
1515
+ offset += 8
1516
+
1517
+ let capacity9 = this.buffer.byteLength
1518
+
1519
+ if (offset > capacity9) {
1520
+ this.resize((capacity9 *= 2) > offset ? capacity9 : offset)
1521
+ }
1522
+
1523
+ offset -= 8
1524
+
1525
+ this.view.setFloat64(offset, value, this.littleEndian)
1526
+
1527
+ if (relative) {
1528
+ this.offset += 8
1529
+ }
1530
+
1531
+ return this
1532
+ }
1533
+
1534
+ /**
1535
+
1536
+ * Writes a 64bit float. This is an alias of {@link ByteBuffer#writeFloat64}.
1537
+
1538
+ * @function
1539
+
1540
+ * @param {number} value Value to write
1541
+
1542
+ * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1543
+
1544
+ * @returns {!ByteBuffer} this
1545
+
1546
+ * @expose
1547
+
1548
+ */
1549
+
1550
+ writeDouble = this.writeFloat64
1551
+
1552
+ /**
1553
+
1554
+ * Reads a 64bit float.
1555
+
1556
+ * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1557
+
1558
+ * @returns {number}
1559
+
1560
+ * @expose
1561
+
1562
+ */
1563
+
1564
+ readFloat64(offset) {
1565
+ const relative = typeof offset === 'undefined'
1566
+
1567
+ if (relative) {
1568
+ offset = this.offset
1569
+ }
1570
+
1571
+ if (!this.noAssert) {
1572
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
1573
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
1574
+ }
1575
+
1576
+ offset >>>= 0
1577
+
1578
+ if (offset < 0 || offset + 8 > this.buffer.byteLength) {
1579
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+8) <= ' + this.buffer.byteLength)
1580
+ }
1581
+ }
1582
+
1583
+ const value = this.view.getFloat64(offset, this.littleEndian)
1584
+
1585
+ if (relative) {
1586
+ this.offset += 8
1587
+ }
1588
+
1589
+ return value
1590
+ }
1591
+
1592
+ /**
1593
+
1594
+ * Reads a 64bit float. This is an alias of {@link ByteBuffer#readFloat64}.
1595
+
1596
+ * @function
1597
+
1598
+ * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
1599
+
1600
+ * @returns {number}
1601
+
1602
+ * @expose
1603
+
1604
+ */
1605
+
1606
+ readDouble = this.readFloat64
1607
+
1608
+ /**
1609
+
1610
+ * Appends some data to this ByteBuffer. This will overwrite any contents behind the specified offset up to the appended
1611
+
1612
+ * data's length.
1613
+
1614
+ * @param {!ByteBuffer|!ArrayBuffer|!Uint8Array} source Data to append. If `source` is a ByteBuffer, its offsets
1615
+
1616
+ * will be modified according to the performed read operation.
1617
+
1618
+ * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
1619
+
1620
+ * @param {number=} offset Offset to append at. Will use and increase {@link ByteBuffer#offset} by the number of bytes
1621
+
1622
+ * written if omitted.
1623
+
1624
+ * @returns {!ByteBuffer} this
1625
+
1626
+ * @expose
1627
+
1628
+ * @example A relative `<01 02>03.append(<04 05>)` will result in `<01 02 04 05>, 04 05|`
1629
+
1630
+ * @example An absolute `<01 02>03.append(04 05>, 1)` will result in `<01 04>05, 04 05|`
1631
+
1632
+ */
1633
+
1634
+ append(source, offset) {
1635
+ const relative = typeof offset === 'undefined'
1636
+
1637
+ if (relative) {
1638
+ offset = this.offset
1639
+ }
1640
+
1641
+ if (!this.noAssert) {
1642
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
1643
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
1644
+ }
1645
+
1646
+ offset >>>= 0
1647
+
1648
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
1649
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+0) <= ' + this.buffer.byteLength)
1650
+ }
1651
+ }
1652
+
1653
+ if (!(source instanceof ByteBuffer)) {
1654
+ source = ByteBuffer.wrap(source)
1655
+ }
1656
+
1657
+ const length = source.limit - source.offset
1658
+
1659
+ if (length <= 0) {
1660
+ return this
1661
+ }
1662
+
1663
+ offset += length
1664
+
1665
+ let capacity16 = this.buffer.byteLength
1666
+
1667
+ if (offset > capacity16) {
1668
+ this.resize((capacity16 *= 2) > offset ? capacity16 : offset)
1669
+ }
1670
+
1671
+ offset -= length
1672
+
1673
+ new Uint8Array(this.buffer, offset).set(new Uint8Array(source.buffer).subarray(source.offset, source.limit))
1674
+
1675
+ source.offset += length
1676
+
1677
+ if (relative) {
1678
+ this.offset += length
1679
+ }
1680
+
1681
+ return this
1682
+ }
1683
+
1684
+ /**
1685
+
1686
+ * Appends this ByteBuffer's contents to another ByteBuffer. This will overwrite any contents at and after the
1687
+
1688
+ specified offset up to the length of this ByteBuffer's data.
1689
+
1690
+ * @param {!ByteBuffer} target Target ByteBuffer
1691
+
1692
+ * @param {number=} offset Offset to append to. Will use and increase {@link ByteBuffer#offset} by the number of bytes
1693
+
1694
+ * read if omitted.
1695
+
1696
+ * @returns {!ByteBuffer} this
1697
+
1698
+ * @expose
1699
+
1700
+ * @see ByteBuffer#append
1701
+
1702
+ */
1703
+
1704
+ appendTo(target, offset) {
1705
+ target.append(this, offset)
1706
+
1707
+ return this
1708
+ }
1709
+
1710
+ /**
1711
+
1712
+ * Enables or disables assertions of argument types and offsets. Assertions are enabled by default but you can opt to
1713
+
1714
+ * disable them if your code already makes sure that everything is valid.
1715
+
1716
+ * @param {boolean} assert `true` to enable assertions, otherwise `false`
1717
+
1718
+ * @returns {!ByteBuffer} this
1719
+
1720
+ * @expose
1721
+
1722
+ */
1723
+
1724
+ assert(assert) {
1725
+ this.noAssert = !assert
1726
+
1727
+ return this
1728
+ }
1729
+
1730
+ /**
1731
+
1732
+ * Gets the capacity of this ByteBuffer's backing buffer.
1733
+
1734
+ * @returns {number} Capacity of the backing buffer
1735
+
1736
+ * @expose
1737
+
1738
+ */
1739
+
1740
+ capacity() {
1741
+ return this.buffer.byteLength
1742
+ }
1743
+
1744
+ /**
1745
+
1746
+ * Clears this ByteBuffer's offsets by setting {@link ByteBuffer#offset} to `0` and {@link ByteBuffer#limit} to the
1747
+
1748
+ * backing buffer's capacity. Discards {@link ByteBuffer#markedOffset}.
1749
+
1750
+ * @returns {!ByteBuffer} this
1751
+
1752
+ * @expose
1753
+
1754
+ */
1755
+
1756
+ clear() {
1757
+ this.offset = 0
1758
+
1759
+ this.limit = this.buffer.byteLength
1760
+
1761
+ this.markedOffset = -1
1762
+
1763
+ return this
1764
+ }
1765
+
1766
+ /**
1767
+
1768
+ * Creates a cloned instance of this ByteBuffer, preset with this ByteBuffer's values for {@link ByteBuffer#offset},
1769
+
1770
+ * {@link ByteBuffer#markedOffset} and {@link ByteBuffer#limit}.
1771
+
1772
+ * @param {boolean=} copy Whether to copy the backing buffer or to return another view on the same, defaults to `false`
1773
+
1774
+ * @returns {!ByteBuffer} Cloned instance
1775
+
1776
+ * @expose
1777
+
1778
+ */
1779
+
1780
+ clone(copy) {
1781
+ const bb = new ByteBuffer(0, this.littleEndian, this.noAssert)
1782
+
1783
+ if (copy) {
1784
+ bb.buffer = new ArrayBuffer(this.buffer.byteLength)
1785
+
1786
+ new Uint8Array(bb.buffer).set(this.buffer)
1787
+
1788
+ bb.view = new DataView(bb.buffer)
1789
+ } else {
1790
+ bb.buffer = this.buffer
1791
+
1792
+ bb.view = this.view
1793
+ }
1794
+
1795
+ bb.offset = this.offset
1796
+
1797
+ bb.markedOffset = this.markedOffset
1798
+
1799
+ bb.limit = this.limit
1800
+
1801
+ return bb
1802
+ }
1803
+
1804
+ /**
1805
+
1806
+ * Compacts this ByteBuffer to be backed by a {@link ByteBuffer#buffer} of its contents' length. Contents are the bytes
1807
+
1808
+ * between {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. Will set `offset = 0` and `limit = capacity` and
1809
+
1810
+ * adapt {@link ByteBuffer#markedOffset} to the same relative position if set.
1811
+
1812
+ * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
1813
+
1814
+ * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
1815
+
1816
+ * @returns {!ByteBuffer} this
1817
+
1818
+ * @expose
1819
+
1820
+ */
1821
+
1822
+ compact(begin, end) {
1823
+ if (typeof begin === 'undefined') {
1824
+ begin = this.offset
1825
+ }
1826
+
1827
+ if (typeof end === 'undefined') {
1828
+ end = this.limit
1829
+ }
1830
+
1831
+ if (!this.noAssert) {
1832
+ if (typeof begin !== 'number' || begin % 1 !== 0) {
1833
+ throw TypeError('Illegal begin: Not an integer')
1834
+ }
1835
+
1836
+ begin >>>= 0
1837
+
1838
+ if (typeof end !== 'number' || end % 1 !== 0) {
1839
+ throw TypeError('Illegal end: Not an integer')
1840
+ }
1841
+
1842
+ end >>>= 0
1843
+
1844
+ if (begin < 0 || begin > end || end > this.buffer.byteLength) {
1845
+ throw RangeError('Illegal range: 0 <= ' + begin + ' <= ' + end + ' <= ' + this.buffer.byteLength)
1846
+ }
1847
+ }
1848
+
1849
+ if (begin === 0 && end === this.buffer.byteLength) {
1850
+ return this
1851
+ }
1852
+
1853
+ const len = end - begin
1854
+
1855
+ if (len === 0) {
1856
+ this.buffer = EMPTY_BUFFER
1857
+
1858
+ this.view = new DataView(EMPTY_BUFFER)
1859
+
1860
+ if (this.markedOffset >= 0) {
1861
+ this.markedOffset -= begin
1862
+ }
1863
+
1864
+ this.offset = 0
1865
+
1866
+ this.limit = 0
1867
+
1868
+ return this
1869
+ }
1870
+
1871
+ const buffer = new ArrayBuffer(len)
1872
+
1873
+ new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(begin, end))
1874
+
1875
+ this.buffer = buffer
1876
+
1877
+ this.view = new DataView(buffer)
1878
+
1879
+ if (this.markedOffset >= 0) {
1880
+ this.markedOffset -= begin
1881
+ }
1882
+
1883
+ this.offset = 0
1884
+
1885
+ this.limit = len
1886
+
1887
+ return this
1888
+ }
1889
+
1890
+ /**
1891
+
1892
+ * Creates a copy of this ByteBuffer's contents. Contents are the bytes between {@link ByteBuffer#offset} and
1893
+
1894
+ * {@link ByteBuffer#limit}.
1895
+
1896
+ * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
1897
+
1898
+ * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
1899
+
1900
+ * @returns {!ByteBuffer} Copy
1901
+
1902
+ * @expose
1903
+
1904
+ */
1905
+
1906
+ copy(begin, end) {
1907
+ if (typeof begin === 'undefined') {
1908
+ begin = this.offset
1909
+ }
1910
+
1911
+ if (typeof end === 'undefined') {
1912
+ end = this.limit
1913
+ }
1914
+
1915
+ if (!this.noAssert) {
1916
+ if (typeof begin !== 'number' || begin % 1 !== 0) {
1917
+ throw TypeError('Illegal begin: Not an integer')
1918
+ }
1919
+
1920
+ begin >>>= 0
1921
+
1922
+ if (typeof end !== 'number' || end % 1 !== 0) {
1923
+ throw TypeError('Illegal end: Not an integer')
1924
+ }
1925
+
1926
+ end >>>= 0
1927
+
1928
+ if (begin < 0 || begin > end || end > this.buffer.byteLength) {
1929
+ throw RangeError('Illegal range: 0 <= ' + begin + ' <= ' + end + ' <= ' + this.buffer.byteLength)
1930
+ }
1931
+ }
1932
+
1933
+ if (begin === end) {
1934
+ return new ByteBuffer(0, this.littleEndian, this.noAssert)
1935
+ }
1936
+
1937
+ const capacity = end - begin
1938
+
1939
+ const bb = new ByteBuffer(capacity, this.littleEndian, this.noAssert)
1940
+
1941
+ bb.offset = 0
1942
+
1943
+ bb.limit = capacity
1944
+
1945
+ if (bb.markedOffset >= 0) {
1946
+ bb.markedOffset -= begin
1947
+ }
1948
+
1949
+ this.copyTo(bb, 0, begin, end)
1950
+
1951
+ return bb
1952
+ }
1953
+
1954
+ /**
1955
+
1956
+ * Copies this ByteBuffer's contents to another ByteBuffer. Contents are the bytes between {@link ByteBuffer#offset} and
1957
+
1958
+ * {@link ByteBuffer#limit}.
1959
+
1960
+ * @param {!ByteBuffer} target Target ByteBuffer
1961
+
1962
+ * @param {number=} targetOffset Offset to copy to. Will use and increase the target's {@link ByteBuffer#offset}
1963
+
1964
+ * by the number of bytes copied if omitted.
1965
+
1966
+ * @param {number=} sourceOffset Offset to start copying from. Will use and increase {@link ByteBuffer#offset} by the
1967
+
1968
+ * number of bytes copied if omitted.
1969
+
1970
+ * @param {number=} sourceLimit Offset to end copying from, defaults to {@link ByteBuffer#limit}
1971
+
1972
+ * @returns {!ByteBuffer} this
1973
+
1974
+ * @expose
1975
+
1976
+ */
1977
+
1978
+ copyTo(target, targetOffset, sourceOffset, sourceLimit) {
1979
+ const targetRelative = typeof targetOffset === 'undefined'
1980
+ const relative = typeof sourceOffset === 'undefined'
1981
+
1982
+ if (!this.noAssert) {
1983
+ if (!(target instanceof ByteBuffer)) {
1984
+ throw TypeError('Illegal target: Not a ByteBuffer')
1985
+ }
1986
+ }
1987
+
1988
+ targetOffset = targetRelative ? target.offset : targetOffset | 0
1989
+
1990
+ sourceOffset = relative ? this.offset : sourceOffset | 0
1991
+
1992
+ sourceLimit = typeof sourceLimit === 'undefined' ? this.limit : sourceLimit | 0
1993
+
1994
+ if (targetOffset < 0 || targetOffset > target.buffer.byteLength) {
1995
+ throw RangeError('Illegal target range: 0 <= ' + targetOffset + ' <= ' + target.buffer.byteLength)
1996
+ }
1997
+
1998
+ if (sourceOffset < 0 || sourceLimit > this.buffer.byteLength) {
1999
+ throw RangeError('Illegal source range: 0 <= ' + sourceOffset + ' <= ' + this.buffer.byteLength)
2000
+ }
2001
+
2002
+ const len = sourceLimit - sourceOffset
2003
+
2004
+ if (len === 0) {
2005
+ return target
2006
+ }
2007
+
2008
+ target.ensureCapacity(targetOffset + len)
2009
+
2010
+ new Uint8Array(target.buffer).set(new Uint8Array(this.buffer).subarray(sourceOffset, sourceLimit), targetOffset)
2011
+
2012
+ if (relative) {
2013
+ this.offset += len
2014
+ }
2015
+
2016
+ if (targetRelative) {
2017
+ target.offset += len
2018
+ }
2019
+
2020
+ return this
2021
+ }
2022
+
2023
+ /**
2024
+
2025
+ * Makes sure that this ByteBuffer is backed by a {@link ByteBuffer#buffer} of at least the specified capacity. If the
2026
+
2027
+ * current capacity is exceeded, it will be doubled. If double the current capacity is less than the required capacity,
2028
+
2029
+ * the required capacity will be used instead.
2030
+
2031
+ * @param {number} capacity Required capacity
2032
+
2033
+ * @returns {!ByteBuffer} this
2034
+
2035
+ * @expose
2036
+
2037
+ */
2038
+
2039
+ ensureCapacity(capacity) {
2040
+ let current = this.buffer.byteLength
2041
+
2042
+ if (current < capacity) {
2043
+ return this.resize((current *= 2) > capacity ? current : capacity)
2044
+ }
2045
+
2046
+ return this
2047
+ }
2048
+
2049
+ /**
2050
+
2051
+ * Overwrites this ByteBuffer's contents with the specified value. Contents are the bytes between
2052
+
2053
+ * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
2054
+
2055
+ * @param {number|string} value Byte value to fill with. If given as a string, the first character is used.
2056
+
2057
+ * @param {number=} begin Begin offset. Will use and increase {@link ByteBuffer#offset} by the number of bytes
2058
+
2059
+ * written if omitted. defaults to {@link ByteBuffer#offset}.
2060
+
2061
+ * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
2062
+
2063
+ * @returns {!ByteBuffer} this
2064
+
2065
+ * @expose
2066
+
2067
+ * @example `someByteBuffer.clear().fill(0)` fills the entire backing buffer with zeroes
2068
+
2069
+ */
2070
+
2071
+ fill(value, begin, end) {
2072
+ const relative = typeof begin === 'undefined'
2073
+
2074
+ if (relative) {
2075
+ begin = this.offset
2076
+ }
2077
+
2078
+ if (typeof value === 'string' && value.length > 0) {
2079
+ value = value.charCodeAt(0)
2080
+ }
2081
+
2082
+ if (typeof begin === 'undefined') {
2083
+ begin = this.offset
2084
+ }
2085
+
2086
+ if (typeof end === 'undefined') {
2087
+ end = this.limit
2088
+ }
2089
+
2090
+ if (!this.noAssert) {
2091
+ if (typeof value !== 'number' || value % 1 !== 0) {
2092
+ throw TypeError('Illegal value: ' + value + ' (not an integer)')
2093
+ }
2094
+
2095
+ value |= 0
2096
+
2097
+ if (typeof begin !== 'number' || begin % 1 !== 0) {
2098
+ throw TypeError('Illegal begin: Not an integer')
2099
+ }
2100
+
2101
+ begin >>>= 0
2102
+
2103
+ if (typeof end !== 'number' || end % 1 !== 0) {
2104
+ throw TypeError('Illegal end: Not an integer')
2105
+ }
2106
+
2107
+ end >>>= 0
2108
+
2109
+ if (begin < 0 || begin > end || end > this.buffer.byteLength) {
2110
+ throw RangeError('Illegal range: 0 <= ' + begin + ' <= ' + end + ' <= ' + this.buffer.byteLength)
2111
+ }
2112
+ }
2113
+
2114
+ if (begin >= end) {
2115
+ return this
2116
+ }
2117
+
2118
+ while (begin < end) {
2119
+ this.view.setUint8(begin++, value)
2120
+ }
2121
+
2122
+ if (relative) {
2123
+ this.offset = begin
2124
+ }
2125
+
2126
+ return this
2127
+ }
2128
+
2129
+ /**
2130
+
2131
+ * Makes this ByteBuffer ready for a new sequence of write or relative read operations. Sets `limit = offset` and
2132
+
2133
+ * `offset = 0`. Make sure always to flip a ByteBuffer when all relative read or write operations are complete.
2134
+
2135
+ * @returns {!ByteBuffer} this
2136
+
2137
+ * @expose
2138
+
2139
+ */
2140
+
2141
+ flip() {
2142
+ this.limit = this.offset
2143
+
2144
+ this.offset = 0
2145
+
2146
+ return this
2147
+ }
2148
+
2149
+ /**
2150
+
2151
+ * Marks an offset on this ByteBuffer to be used later.
2152
+
2153
+ * @param {number=} offset Offset to mark. Defaults to {@link ByteBuffer#offset}.
2154
+
2155
+ * @returns {!ByteBuffer} this
2156
+
2157
+ * @throws {TypeError} If `offset` is not a valid number
2158
+
2159
+ * @throws {RangeError} If `offset` is out of bounds
2160
+
2161
+ * @see ByteBuffer#reset
2162
+
2163
+ * @expose
2164
+
2165
+ */
2166
+
2167
+ mark(offset) {
2168
+ offset = typeof offset === 'undefined' ? this.offset : offset
2169
+
2170
+ if (!this.noAssert) {
2171
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
2172
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
2173
+ }
2174
+
2175
+ offset >>>= 0
2176
+
2177
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
2178
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+0) <= ' + this.buffer.byteLength)
2179
+ }
2180
+ }
2181
+
2182
+ this.markedOffset = offset
2183
+
2184
+ return this
2185
+ }
2186
+
2187
+ /**
2188
+
2189
+ * Sets the byte order.
2190
+
2191
+ * @param {boolean} littleEndian `true` for little endian byte order, `false` for big endian
2192
+
2193
+ * @returns {!ByteBuffer} this
2194
+
2195
+ * @expose
2196
+
2197
+ */
2198
+
2199
+ order(littleEndian) {
2200
+ if (!this.noAssert) {
2201
+ if (typeof littleEndian !== 'boolean') {
2202
+ throw TypeError('Illegal littleEndian: Not a boolean')
2203
+ }
2204
+ }
2205
+
2206
+ this.littleEndian = !!littleEndian
2207
+
2208
+ return this
2209
+ }
2210
+
2211
+ /**
2212
+
2213
+ * Switches (to) little endian byte order.
2214
+
2215
+ * @param {boolean=} littleEndian Defaults to `true`, otherwise uses big endian
2216
+
2217
+ * @returns {!ByteBuffer} this
2218
+
2219
+ * @expose
2220
+
2221
+ */
2222
+
2223
+ LE(littleEndian) {
2224
+ this.littleEndian = typeof littleEndian !== 'undefined' ? !!littleEndian : true
2225
+
2226
+ return this
2227
+ }
2228
+
2229
+ /**
2230
+
2231
+ * Switches (to) big endian byte order.
2232
+
2233
+ * @param {boolean=} bigEndian Defaults to `true`, otherwise uses little endian
2234
+
2235
+ * @returns {!ByteBuffer} this
2236
+
2237
+ * @expose
2238
+
2239
+ */
2240
+
2241
+ BE(bigEndian) {
2242
+ this.littleEndian = typeof bigEndian !== 'undefined' ? !bigEndian : false
2243
+
2244
+ return this
2245
+ }
2246
+
2247
+ /**
2248
+
2249
+ * Prepends some data to this ByteBuffer. This will overwrite any contents before the specified offset up to the
2250
+
2251
+ * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
2252
+
2253
+ * will be resized and its contents moved accordingly.
2254
+
2255
+ * @param {!ByteBuffer|!ArrayBuffer} source Data to prepend. If `source` is a ByteBuffer, its offset will be
2256
+
2257
+ * modified according to the performed read operation.
2258
+
2259
+ * @param {(string|number)=} encoding Encoding if `data` is a string ("base64", "hex", "binary", defaults to "utf8")
2260
+
2261
+ * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
2262
+
2263
+ * prepended if omitted.
2264
+
2265
+ * @returns {!ByteBuffer} this
2266
+
2267
+ * @expose
2268
+
2269
+ * @example A relative `00<01 02 03>.prepend(<04 05>)` results in `<04 05 01 02 03>, 04 05|`
2270
+
2271
+ * @example An absolute `00<01 02 03>.prepend(<04 05>, 2)` results in `04<05 02 03>, 04 05|`
2272
+
2273
+ */
2274
+
2275
+ prepend(source, offset) {
2276
+ const relative = typeof offset === 'undefined'
2277
+
2278
+ if (relative) {
2279
+ offset = this.offset
2280
+ }
2281
+
2282
+ if (!this.noAssert) {
2283
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
2284
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
2285
+ }
2286
+
2287
+ offset >>>= 0
2288
+
2289
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
2290
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+0) <= ' + this.buffer.byteLength)
2291
+ }
2292
+ }
2293
+
2294
+ if (!(source instanceof ByteBuffer)) {
2295
+ source = ByteBuffer.wrap(source)
2296
+ }
2297
+
2298
+ const len = source.limit - source.offset
2299
+
2300
+ if (len <= 0) {
2301
+ return this
2302
+ }
2303
+
2304
+ const diff = len - offset
2305
+
2306
+ if (diff > 0) {
2307
+ const buffer = new ArrayBuffer(this.buffer.byteLength + diff)
2308
+
2309
+ const arrayView = new Uint8Array(buffer)
2310
+
2311
+ arrayView.set(new Uint8Array(this.buffer).subarray(offset, this.buffer.byteLength), len)
2312
+
2313
+ this.buffer = buffer
2314
+
2315
+ this.view = new DataView(buffer)
2316
+
2317
+ this.offset += diff
2318
+
2319
+ if (this.markedOffset >= 0) {
2320
+ this.markedOffset += diff
2321
+ }
2322
+
2323
+ this.limit += diff
2324
+
2325
+ offset += diff
2326
+ } else {
2327
+ const arrayView = new Uint8Array(this.buffer)
2328
+
2329
+ arrayView.set(new Uint8Array(source.buffer).subarray(source.offset, source.limit), offset - len)
2330
+ }
2331
+
2332
+ source.offset = source.limit
2333
+
2334
+ if (relative) {
2335
+ this.offset -= len
2336
+ }
2337
+
2338
+ return this
2339
+ }
2340
+
2341
+ /**
2342
+
2343
+ * Prepends this ByteBuffer to another ByteBuffer. This will overwrite any contents before the specified offset up to the
2344
+
2345
+ * prepended data's length. If there is not enough space available before the specified `offset`, the backing buffer
2346
+
2347
+ * will be resized and its contents moved accordingly.
2348
+
2349
+ * @param {!ByteBuffer} target Target ByteBuffer
2350
+
2351
+ * @param {number=} offset Offset to prepend at. Will use and decrease {@link ByteBuffer#offset} by the number of bytes
2352
+
2353
+ * prepended if omitted.
2354
+
2355
+ * @returns {!ByteBuffer} this
2356
+
2357
+ * @expose
2358
+
2359
+ * @see ByteBuffer#prepend
2360
+
2361
+ */
2362
+
2363
+ prependTo(target, offset) {
2364
+ target.prepend(this, offset)
2365
+
2366
+ return this
2367
+ }
2368
+
2369
+ /**
2370
+
2371
+ * Gets the number of remaining readable bytes. Contents are the bytes between {@link ByteBuffer#offset} and
2372
+
2373
+ * {@link ByteBuffer#limit}, so this returns `limit - offset`.
2374
+
2375
+ * @returns {number} Remaining readable bytes. May be negative if `offset > limit`.
2376
+
2377
+ * @expose
2378
+
2379
+ */
2380
+
2381
+ remaining() {
2382
+ return this.limit - this.offset
2383
+ }
2384
+
2385
+ /**
2386
+
2387
+ * Resets this ByteBuffer's {@link ByteBuffer#offset}. If an offset has been marked through {@link ByteBuffer#mark}
2388
+
2389
+ * before, `offset` will be set to {@link ByteBuffer#markedOffset}, which will then be discarded. If no offset has been
2390
+
2391
+ * marked, sets `offset = 0`.
2392
+
2393
+ * @returns {!ByteBuffer} this
2394
+
2395
+ * @see ByteBuffer#mark
2396
+
2397
+ * @expose
2398
+
2399
+ */
2400
+
2401
+ reset() {
2402
+ if (this.markedOffset >= 0) {
2403
+ this.offset = this.markedOffset
2404
+
2405
+ this.markedOffset = -1
2406
+ } else {
2407
+ this.offset = 0
2408
+ }
2409
+
2410
+ return this
2411
+ }
2412
+
2413
+ /**
2414
+
2415
+ * Resizes this ByteBuffer to be backed by a buffer of at least the given capacity. Will do nothing if already that
2416
+
2417
+ * large or larger.
2418
+
2419
+ * @param {number} capacity Capacity required
2420
+
2421
+ * @returns {!ByteBuffer} this
2422
+
2423
+ * @throws {TypeError} If `capacity` is not a number
2424
+
2425
+ * @throws {RangeError} If `capacity < 0`
2426
+
2427
+ * @expose
2428
+
2429
+ */
2430
+
2431
+ resize(capacity) {
2432
+ if (!this.noAssert) {
2433
+ if (typeof capacity !== 'number' || capacity % 1 !== 0) {
2434
+ throw TypeError('Illegal capacity: ' + capacity + ' (not an integer)')
2435
+ }
2436
+
2437
+ capacity |= 0
2438
+
2439
+ if (capacity < 0) {
2440
+ throw RangeError('Illegal capacity: 0 <= ' + capacity)
2441
+ }
2442
+ }
2443
+
2444
+ if (this.buffer.byteLength < capacity) {
2445
+ const buffer = new ArrayBuffer(capacity)
2446
+
2447
+ new Uint8Array(buffer).set(new Uint8Array(this.buffer))
2448
+
2449
+ this.buffer = buffer
2450
+
2451
+ this.view = new DataView(buffer)
2452
+ }
2453
+
2454
+ return this
2455
+ }
2456
+
2457
+ /**
2458
+
2459
+ * Reverses this ByteBuffer's contents.
2460
+
2461
+ * @param {number=} begin Offset to start at, defaults to {@link ByteBuffer#offset}
2462
+
2463
+ * @param {number=} end Offset to end at, defaults to {@link ByteBuffer#limit}
2464
+
2465
+ * @returns {!ByteBuffer} this
2466
+
2467
+ * @expose
2468
+
2469
+ */
2470
+
2471
+ reverse(begin, end) {
2472
+ if (typeof begin === 'undefined') {
2473
+ begin = this.offset
2474
+ }
2475
+
2476
+ if (typeof end === 'undefined') {
2477
+ end = this.limit
2478
+ }
2479
+
2480
+ if (!this.noAssert) {
2481
+ if (typeof begin !== 'number' || begin % 1 !== 0) {
2482
+ throw TypeError('Illegal begin: Not an integer')
2483
+ }
2484
+
2485
+ begin >>>= 0
2486
+
2487
+ if (typeof end !== 'number' || end % 1 !== 0) {
2488
+ throw TypeError('Illegal end: Not an integer')
2489
+ }
2490
+
2491
+ end >>>= 0
2492
+
2493
+ if (begin < 0 || begin > end || end > this.buffer.byteLength) {
2494
+ throw RangeError('Illegal range: 0 <= ' + begin + ' <= ' + end + ' <= ' + this.buffer.byteLength)
2495
+ }
2496
+ }
2497
+
2498
+ if (begin === end) {
2499
+ return this
2500
+ }
2501
+
2502
+ Array.prototype.reverse.call(new Uint8Array(this.buffer).subarray(begin, end))
2503
+
2504
+ this.view = new DataView(this.buffer)
2505
+
2506
+ return this
2507
+ }
2508
+
2509
+ /**
2510
+
2511
+ * Skips the next `length` bytes. This will just advance
2512
+
2513
+ * @param {number} length Number of bytes to skip. May also be negative to move the offset back.
2514
+
2515
+ * @returns {!ByteBuffer} this
2516
+
2517
+ * @expose
2518
+
2519
+ */
2520
+
2521
+ skip(length) {
2522
+ if (!this.noAssert) {
2523
+ if (typeof length !== 'number' || length % 1 !== 0) {
2524
+ throw TypeError('Illegal length: ' + length + ' (not an integer)')
2525
+ }
2526
+
2527
+ length |= 0
2528
+ }
2529
+
2530
+ const offset = this.offset + length
2531
+
2532
+ if (!this.noAssert) {
2533
+ if (offset < 0 || offset > this.buffer.byteLength) {
2534
+ throw RangeError('Illegal length: 0 <= ' + this.offset + ' + ' + length + ' <= ' + this.buffer.byteLength)
2535
+ }
2536
+ }
2537
+
2538
+ this.offset = offset
2539
+
2540
+ return this
2541
+ }
2542
+
2543
+ /**
2544
+
2545
+ * Slices this ByteBuffer by creating a cloned instance with `offset = begin` and `limit = end`.
2546
+
2547
+ * @param {number=} begin Begin offset, defaults to {@link ByteBuffer#offset}.
2548
+
2549
+ * @param {number=} end End offset, defaults to {@link ByteBuffer#limit}.
2550
+
2551
+ * @returns {!ByteBuffer} Clone of this ByteBuffer with slicing applied, backed by the same {@link ByteBuffer#buffer}
2552
+
2553
+ * @expose
2554
+
2555
+ */
2556
+
2557
+ slice(begin, end) {
2558
+ if (typeof begin === 'undefined') {
2559
+ begin = this.offset
2560
+ }
2561
+
2562
+ if (typeof end === 'undefined') {
2563
+ end = this.limit
2564
+ }
2565
+
2566
+ if (!this.noAssert) {
2567
+ if (typeof begin !== 'number' || begin % 1 !== 0) {
2568
+ throw TypeError('Illegal begin: Not an integer')
2569
+ }
2570
+
2571
+ begin >>>= 0
2572
+
2573
+ if (typeof end !== 'number' || end % 1 !== 0) {
2574
+ throw TypeError('Illegal end: Not an integer')
2575
+ }
2576
+
2577
+ end >>>= 0
2578
+
2579
+ if (begin < 0 || begin > end || end > this.buffer.byteLength) {
2580
+ throw RangeError('Illegal range: 0 <= ' + begin + ' <= ' + end + ' <= ' + this.buffer.byteLength)
2581
+ }
2582
+ }
2583
+
2584
+ const bb = this.clone()
2585
+
2586
+ bb.offset = begin
2587
+
2588
+ bb.limit = end
2589
+
2590
+ return bb
2591
+ }
2592
+
2593
+ /**
2594
+
2595
+ * Writes a 64bit signed integer.
2596
+
2597
+ * @param {number|bigint} value Value to write
2598
+
2599
+ * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2600
+
2601
+ * @returns {!ByteBuffer} this
2602
+
2603
+ * @expose
2604
+
2605
+ */
2606
+
2607
+ writeInt64(value, offset) {
2608
+ const relative = typeof offset === 'undefined'
2609
+
2610
+ if (typeof offset === 'undefined') {
2611
+ offset = this.offset
2612
+ }
2613
+
2614
+ if (!this.noAssert) {
2615
+ if (typeof value === 'number') {
2616
+ value = BigInt(value)
2617
+ }
2618
+
2619
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
2620
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
2621
+ }
2622
+
2623
+ offset >>>= 0
2624
+
2625
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
2626
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+0) <= ' + this.buffer.byteLength)
2627
+ }
2628
+ }
2629
+
2630
+ if (typeof value === 'number') {
2631
+ value = BigInt(value)
2632
+ }
2633
+
2634
+ offset += 8
2635
+
2636
+ let capacity6 = this.buffer.byteLength
2637
+
2638
+ if (offset > capacity6) {
2639
+ this.resize((capacity6 *= 2) > offset ? capacity6 : offset)
2640
+ }
2641
+
2642
+ offset -= 8
2643
+
2644
+ this.view.setBigInt64(offset, value, this.littleEndian)
2645
+
2646
+ if (relative) {
2647
+ this.offset += 8
2648
+ }
2649
+
2650
+ return this
2651
+ }
2652
+
2653
+ /**
2654
+
2655
+ * Writes a 64bit signed integer. This is an alias of {@link ByteBuffer#writeInt64}.
2656
+
2657
+ * @param {number|!bigint} value Value to write
2658
+
2659
+ * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2660
+
2661
+ * @returns {!ByteBuffer} this
2662
+
2663
+ * @expose
2664
+
2665
+ */
2666
+
2667
+ writeLong = this.writeInt64
2668
+
2669
+ /**
2670
+
2671
+ * Reads a 64bit signed integer.
2672
+
2673
+ * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2674
+
2675
+ * @returns {!bigint}
2676
+
2677
+ * @expose
2678
+
2679
+ */
2680
+
2681
+ readInt64(offset) {
2682
+ const relative = typeof offset === 'undefined'
2683
+
2684
+ if (relative) {
2685
+ offset = this.offset
2686
+ }
2687
+
2688
+ if (!this.noAssert) {
2689
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
2690
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
2691
+ }
2692
+
2693
+ offset >>>= 0
2694
+
2695
+ if (offset < 0 || offset + 8 > this.buffer.byteLength) {
2696
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+8) <= ' + this.buffer.byteLength)
2697
+ }
2698
+ }
2699
+
2700
+ const value = this.view.getBigInt64(offset, this.littleEndian)
2701
+
2702
+ if (relative) {
2703
+ this.offset += 8
2704
+ }
2705
+
2706
+ return value
2707
+ }
2708
+
2709
+ /**
2710
+
2711
+ * Reads a 64bit signed integer. This is an alias of {@link ByteBuffer#readInt64}.
2712
+
2713
+ * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2714
+
2715
+ * @returns {!bigint}
2716
+
2717
+ * @expose
2718
+
2719
+ */
2720
+
2721
+ readLong = this.readInt64
2722
+
2723
+ /**
2724
+
2725
+ * Writes a 64bit unsigned integer.
2726
+
2727
+ * @param {number|!bigint} value Value to write
2728
+
2729
+ * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2730
+
2731
+ * @returns {!ByteBuffer} this
2732
+
2733
+ * @expose
2734
+
2735
+ */
2736
+
2737
+ writeUint64(value, offset) {
2738
+ const relative = typeof offset === 'undefined'
2739
+
2740
+ if (typeof offset === 'undefined') {
2741
+ offset = this.offset
2742
+ }
2743
+
2744
+ if (!this.noAssert) {
2745
+ if (typeof value === 'number') {
2746
+ value = BigInt(value)
2747
+ }
2748
+
2749
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
2750
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
2751
+ }
2752
+
2753
+ offset >>>= 0
2754
+
2755
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
2756
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+0) <= ' + this.buffer.byteLength)
2757
+ }
2758
+ }
2759
+
2760
+ if (typeof value === 'number') {
2761
+ value = BigInt(value)
2762
+ }
2763
+
2764
+ offset += 8
2765
+
2766
+ let capacity7 = this.buffer.byteLength
2767
+
2768
+ if (offset > capacity7) {
2769
+ this.resize((capacity7 *= 2) > offset ? capacity7 : offset)
2770
+ }
2771
+
2772
+ offset -= 8
2773
+
2774
+ this.view.setBigUint64(offset, value, this.littleEndian)
2775
+
2776
+ if (relative) {
2777
+ this.offset += 8
2778
+ }
2779
+
2780
+ return this
2781
+ }
2782
+
2783
+ /**
2784
+
2785
+ * Writes a 64bit unsigned integer. This is an alias of {@link ByteBuffer#writeUint64}.
2786
+
2787
+ * @function
2788
+
2789
+ * @param {number|!bigint} value Value to write
2790
+
2791
+ * @param {number=} offset Offset to write to. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2792
+
2793
+ * @returns {!ByteBuffer} this
2794
+
2795
+ * @expose
2796
+
2797
+ */
2798
+
2799
+ writeUInt64 = this.writeUint64
2800
+
2801
+ /**
2802
+
2803
+ * Reads a 64bit unsigned integer.
2804
+
2805
+ * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2806
+
2807
+ * @returns {!bigint}
2808
+
2809
+ * @expose
2810
+
2811
+ */
2812
+
2813
+ readUint64(offset) {
2814
+ const relative = typeof offset === 'undefined'
2815
+
2816
+ if (relative) {
2817
+ offset = this.offset
2818
+ }
2819
+
2820
+ if (!this.noAssert) {
2821
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
2822
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
2823
+ }
2824
+
2825
+ offset >>>= 0
2826
+
2827
+ if (offset < 0 || offset + 8 > this.buffer.byteLength) {
2828
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+8) <= ' + this.buffer.byteLength)
2829
+ }
2830
+ }
2831
+
2832
+ const value = this.view.getBigUint64(offset, this.littleEndian)
2833
+
2834
+ if (relative) {
2835
+ this.offset += 8
2836
+ }
2837
+
2838
+ return value
2839
+ }
2840
+
2841
+ /**
2842
+
2843
+ * Reads a 64bit unsigned integer. This is an alias of {@link ByteBuffer#readUint64}.
2844
+
2845
+ * @function
2846
+
2847
+ * @param {number=} offset Offset to read from. Will use and increase {@link ByteBuffer#offset} by `8` if omitted.
2848
+
2849
+ * @returns {!Long}
2850
+
2851
+ * @expose
2852
+
2853
+ */
2854
+
2855
+ readUInt64 = this.readUint64
2856
+
2857
+ /**
2858
+
2859
+ * Returns a copy of the backing buffer that contains this ByteBuffer's contents. Contents are the bytes between
2860
+
2861
+ * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}.
2862
+
2863
+ * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory if
2864
+
2865
+ * possible. Defaults to `false`
2866
+
2867
+ * @returns {!ArrayBuffer} Contents as an ArrayBuffer
2868
+
2869
+ * @expose
2870
+
2871
+ */
2872
+
2873
+ toBuffer(forceCopy) {
2874
+ let offset = this.offset
2875
+
2876
+ let limit = this.limit
2877
+
2878
+ if (!this.noAssert) {
2879
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
2880
+ throw TypeError('Illegal offset: Not an integer')
2881
+ }
2882
+
2883
+ offset >>>= 0
2884
+
2885
+ if (typeof limit !== 'number' || limit % 1 !== 0) {
2886
+ throw TypeError('Illegal limit: Not an integer')
2887
+ }
2888
+
2889
+ limit >>>= 0
2890
+
2891
+ if (offset < 0 || offset > limit || limit > this.buffer.byteLength) {
2892
+ throw RangeError('Illegal range: 0 <= ' + offset + ' <= ' + limit + ' <= ' + this.buffer.byteLength)
2893
+ }
2894
+ }
2895
+
2896
+ if (!forceCopy) {
2897
+ if (offset === 0 && limit === this.buffer.byteLength) {
2898
+ return this.buffer
2899
+ }
2900
+
2901
+ return this.buffer.slice(offset, limit)
2902
+ }
2903
+
2904
+ if (offset === limit) {
2905
+ return EMPTY_BUFFER
2906
+ }
2907
+
2908
+ const buffer = new ArrayBuffer(limit - offset)
2909
+
2910
+ new Uint8Array(buffer).set(new Uint8Array(this.buffer).subarray(offset, limit), 0)
2911
+
2912
+ return buffer
2913
+ }
2914
+
2915
+ /**
2916
+
2917
+ * Returns a raw buffer compacted to contain this ByteBuffer's contents. Contents are the bytes between
2918
+
2919
+ * {@link ByteBuffer#offset} and {@link ByteBuffer#limit}. This is an alias of {@link ByteBuffer#toBuffer}.
2920
+
2921
+ * @function
2922
+
2923
+ * @param {boolean=} forceCopy If `true` returns a copy, otherwise returns a view referencing the same memory.
2924
+
2925
+ * Defaults to `false`
2926
+
2927
+ * @returns {!ArrayBuffer} Contents as an ArrayBuffer
2928
+
2929
+ * @expose
2930
+
2931
+ */
2932
+
2933
+ toArrayBuffer = this.toBuffer
2934
+
2935
+ writeVarint32(value, offset) {
2936
+ const relative = typeof offset === 'undefined'
2937
+ if (relative) offset = this.offset
2938
+ if (!this.noAssert) {
2939
+ if (typeof value !== 'number' || value % 1 !== 0) {
2940
+ throw TypeError('Illegal value: ' + value + ' (not an integer)')
2941
+ }
2942
+ value |= 0
2943
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
2944
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
2945
+ }
2946
+ offset >>>= 0
2947
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
2948
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+' + 0 + ') <= ' + this.buffer.byteLength)
2949
+ }
2950
+ }
2951
+ const size = this.calculateVarint32(value)
2952
+ let b
2953
+ offset += size
2954
+ let capacity10 = this.buffer.byteLength
2955
+ if (offset > capacity10) {
2956
+ this.resize((capacity10 *= 2) > offset ? capacity10 : offset)
2957
+ }
2958
+ offset -= size
2959
+ value >>>= 0
2960
+ while (value >= 0x80) {
2961
+ b = (value & 0x7f) | 0x80
2962
+ this.view.setUint8(offset++, b)
2963
+ value >>>= 7
2964
+ }
2965
+ this.view.setUint8(offset++, value)
2966
+ if (relative) {
2967
+ this.offset = offset
2968
+ return this
2969
+ }
2970
+ return size
2971
+ }
2972
+
2973
+ readVarint32 = function (offset) {
2974
+ const relative = typeof offset === 'undefined'
2975
+ if (relative) offset = this.offset
2976
+ if (!this.noAssert) {
2977
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
2978
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
2979
+ }
2980
+ offset >>>= 0
2981
+ if (offset < 0 || offset + 1 > this.buffer.byteLength) {
2982
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+' + 1 + ') <= ' + this.buffer.byteLength)
2983
+ }
2984
+ }
2985
+ let c = 0
2986
+ let value = 0 >>> 0
2987
+ let b
2988
+ do {
2989
+ if (!this.noAssert && offset > this.limit) {
2990
+ const err = Error('Truncated')
2991
+ err.truncated = true
2992
+ throw err
2993
+ }
2994
+ b = this.view.getUint8(offset++)
2995
+ if (c < 5) {
2996
+ value |= (b & 0x7f) << (7 * c)
2997
+ }
2998
+ ++c
2999
+ } while ((b & 0x80) !== 0)
3000
+ value |= 0
3001
+ if (relative) {
3002
+ this.offset = offset
3003
+ return value
3004
+ }
3005
+ return {
3006
+ value,
3007
+ length: c
3008
+ }
3009
+ }
3010
+
3011
+ calculateVarint32(value) {
3012
+ // ref: src/google/protobuf/io/coded_stream.cc
3013
+ value = value >>> 0
3014
+ if (value < 1 << 7) return 1
3015
+ else if (value < 1 << 14) return 2
3016
+ else if (value < 1 << 21) return 3
3017
+ else if (value < 1 << 28) return 4
3018
+ else return 5
3019
+ }
3020
+
3021
+ writeVString(str, offset) {
3022
+ const relative = typeof offset === 'undefined'
3023
+ if (relative) offset = this.offset
3024
+ if (!this.noAssert) {
3025
+ if (typeof str !== 'string') {
3026
+ throw TypeError('Illegal str: Not a string')
3027
+ }
3028
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
3029
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
3030
+ }
3031
+ offset >>>= 0
3032
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
3033
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+' + 0 + ') <= ' + this.buffer.byteLength)
3034
+ }
3035
+ }
3036
+ const start = offset
3037
+ const k = utfx.calculateUTF16asUTF8(stringSource(str), this.noAssert)[1]
3038
+ const l = this.calculateVarint32(k)
3039
+ offset += l + k
3040
+ let capacity15 = this.buffer.byteLength
3041
+ if (offset > capacity15) {
3042
+ this.resize((capacity15 *= 2) > offset ? capacity15 : offset)
3043
+ }
3044
+ offset -= l + k
3045
+ offset += this.writeVarint32(k, offset)
3046
+ utfx.encodeUTF16toUTF8(
3047
+ stringSource(str),
3048
+ function (b) {
3049
+ this.view.setUint8(offset++, b)
3050
+ }.bind(this)
3051
+ )
3052
+ if (offset !== start + k + l) {
3053
+ throw RangeError('Illegal range: Truncated data, ' + offset + ' == ' + (offset + k + l))
3054
+ }
3055
+ if (relative) {
3056
+ this.offset = offset
3057
+ return this
3058
+ }
3059
+ return offset - start
3060
+ }
3061
+
3062
+ readVString(offset) {
3063
+ const relative = typeof offset === 'undefined'
3064
+ if (relative) offset = this.offset
3065
+ if (!this.noAssert) {
3066
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
3067
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
3068
+ }
3069
+ offset >>>= 0
3070
+ if (offset < 0 || offset + 1 > this.buffer.byteLength) {
3071
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+' + 1 + ') <= ' + this.buffer.byteLength)
3072
+ }
3073
+ }
3074
+ const start = offset
3075
+ const len = this.readVarint32(offset)
3076
+ const str = this.readUTF8String(len.value, ByteBuffer.METRICS_BYTES, (offset += len.length))
3077
+ offset += str.length
3078
+ if (relative) {
3079
+ this.offset = offset
3080
+ return str.string
3081
+ } else {
3082
+ return {
3083
+ string: str.string,
3084
+ length: offset - start
3085
+ }
3086
+ }
3087
+ }
3088
+
3089
+ readUTF8String(length, metrics, offset) {
3090
+ if (typeof metrics === 'number') {
3091
+ offset = metrics
3092
+ metrics = undefined
3093
+ }
3094
+ const relative = typeof offset === 'undefined'
3095
+ if (relative) offset = this.offset
3096
+ if (typeof metrics === 'undefined') metrics = ByteBuffer.METRICS_CHARS
3097
+ if (!this.noAssert) {
3098
+ if (typeof length !== 'number' || length % 1 !== 0) {
3099
+ throw TypeError('Illegal length: ' + length + ' (not an integer)')
3100
+ }
3101
+ length |= 0
3102
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
3103
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
3104
+ }
3105
+ offset >>>= 0
3106
+ if (offset < 0 || offset + 0 > this.buffer.byteLength) {
3107
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+' + 0 + ') <= ' + this.buffer.byteLength)
3108
+ }
3109
+ }
3110
+ let i = 0
3111
+ const start = offset
3112
+ let sd
3113
+ if (metrics === ByteBuffer.METRICS_CHARS) {
3114
+ // The same for node and the browser
3115
+ sd = stringDestination()
3116
+ utfx.decodeUTF8(
3117
+ function () {
3118
+ return i < length && offset < this.limit ? this.view.getUint8(offset++) : null
3119
+ }.bind(this),
3120
+ function (cp) {
3121
+ ++i
3122
+ utfx.UTF8toUTF16(cp, sd)
3123
+ }
3124
+ )
3125
+ if (i !== length) {
3126
+ throw RangeError('Illegal range: Truncated data, ' + i + ' == ' + length)
3127
+ }
3128
+ if (relative) {
3129
+ this.offset = offset
3130
+ return sd()
3131
+ } else {
3132
+ return {
3133
+ string: sd(),
3134
+ length: offset - start
3135
+ }
3136
+ }
3137
+ } else if (metrics === ByteBuffer.METRICS_BYTES) {
3138
+ if (!this.noAssert) {
3139
+ if (typeof offset !== 'number' || offset % 1 !== 0) {
3140
+ throw TypeError('Illegal offset: ' + offset + ' (not an integer)')
3141
+ }
3142
+ offset >>>= 0
3143
+ if (offset < 0 || offset + length > this.buffer.byteLength) {
3144
+ throw RangeError('Illegal offset: 0 <= ' + offset + ' (+' + length + ') <= ' + this.buffer.byteLength)
3145
+ }
3146
+ }
3147
+ const k = offset + length
3148
+ utfx.decodeUTF8toUTF16(
3149
+ function () {
3150
+ return offset < k ? this.view.getUint8(offset++) : null
3151
+ }.bind(this),
3152
+ (sd = stringDestination()),
3153
+ this.noAssert
3154
+ )
3155
+ if (offset !== k) {
3156
+ throw RangeError('Illegal range: Truncated data, ' + offset + ' == ' + k)
3157
+ }
3158
+ if (relative) {
3159
+ this.offset = offset
3160
+ return sd()
3161
+ } else {
3162
+ return {
3163
+ string: sd(),
3164
+ length: offset - start
3165
+ }
3166
+ }
3167
+ } else {
3168
+ throw TypeError('Unsupported metrics: ' + metrics)
3169
+ }
3170
+ }
3171
+ }
3172
+ function stringDestination() {
3173
+ const cs = []
3174
+ const ps = []
3175
+ return function () {
3176
+ if (arguments.length === 0) {
3177
+ return ps.join('') + stringFromCharCode.apply(String, cs)
3178
+ }
3179
+ if (cs.length + arguments.length > 1024) {
3180
+ ps.push(stringFromCharCode.apply(String, cs))
3181
+ cs.length = 0
3182
+ }
3183
+ Array.prototype.push.apply(cs, arguments)
3184
+ }
3185
+ }
3186
+ const stringFromCharCode = String.fromCharCode
3187
+
3188
+ function stringSource(s) {
3189
+ let i = 0
3190
+ return function () {
3191
+ return i < s.length ? s.charCodeAt(i++) : null
3192
+ }
3193
+ }
3194
+
3195
+ const EMPTY_BUFFER = new ArrayBuffer(0)
3196
+
3197
+ /**
3198
+ * utfx namespace.
3199
+ * @inner
3200
+ * @type {!Object.<string,*>}
3201
+ */
3202
+ const utfx = {}
3203
+
3204
+ /**
3205
+ * Maximum valid code point.
3206
+ * @type {number}
3207
+ * @const
3208
+ */
3209
+ utfx.MAX_CODEPOINT = 0x10ffff
3210
+
3211
+ /**
3212
+ * Encodes UTF8 code points to UTF8 bytes.
3213
+ * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
3214
+ * respectively `null` if there are no more code points left or a single numeric code point.
3215
+ * @param {!function(number)} dst Bytes destination as a function successively called with the next byte
3216
+ */
3217
+ utfx.encodeUTF8 = function (src, dst) {
3218
+ let cp = null
3219
+ if (typeof src === 'number') {
3220
+ cp = src
3221
+ src = function () {
3222
+ return null
3223
+ }
3224
+ }
3225
+ while (cp !== null || (cp = src()) !== null) {
3226
+ if (cp < 0x80) {
3227
+ dst(cp & 0x7f)
3228
+ } else if (cp < 0x800) {
3229
+ dst(((cp >> 6) & 0x1f) | 0xc0)
3230
+ dst((cp & 0x3f) | 0x80)
3231
+ } else if (cp < 0x10000) {
3232
+ dst(((cp >> 12) & 0x0f) | 0xe0)
3233
+ dst(((cp >> 6) & 0x3f) | 0x80)
3234
+ dst((cp & 0x3f) | 0x80)
3235
+ } else {
3236
+ dst(((cp >> 18) & 0x07) | 0xf0)
3237
+ dst(((cp >> 12) & 0x3f) | 0x80)
3238
+ dst(((cp >> 6) & 0x3f) | 0x80)
3239
+ dst((cp & 0x3f) | 0x80)
3240
+ }
3241
+ cp = null
3242
+ }
3243
+ }
3244
+
3245
+ /**
3246
+ * Decodes UTF8 bytes to UTF8 code points.
3247
+ * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
3248
+ * are no more bytes left.
3249
+ * @param {!function(number)} dst Code points destination as a function successively called with each decoded code point.
3250
+ * @throws {RangeError} If a starting byte is invalid in UTF8
3251
+ * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the
3252
+ * remaining bytes.
3253
+ */
3254
+ utfx.decodeUTF8 = function (src, dst) {
3255
+ let a
3256
+ let b
3257
+ let c
3258
+ let d
3259
+ const fail = function (b) {
3260
+ b = b.slice(0, b.indexOf(null))
3261
+ const err = Error(b.toString())
3262
+ err.name = 'TruncatedError'
3263
+ err.bytes = b
3264
+ throw err
3265
+ }
3266
+ while ((a = src()) !== null) {
3267
+ if ((a & 0x80) === 0) {
3268
+ dst(a)
3269
+ } else if ((a & 0xe0) === 0xc0) {
3270
+ ;(b = src()) === null && fail([a, b])
3271
+ dst(((a & 0x1f) << 6) | (b & 0x3f))
3272
+ } else if ((a & 0xf0) === 0xe0) {
3273
+ ;((b = src()) === null || (c = src()) === null) && fail([a, b, c])
3274
+ dst(((a & 0x0f) << 12) | ((b & 0x3f) << 6) | (c & 0x3f))
3275
+ } else if ((a & 0xf8) === 0xf0) {
3276
+ ;((b = src()) === null || (c = src()) === null || (d = src()) === null) && fail([a, b, c, d])
3277
+ dst(((a & 0x07) << 18) | ((b & 0x3f) << 12) | ((c & 0x3f) << 6) | (d & 0x3f))
3278
+ } else throw RangeError('Illegal starting byte: ' + a)
3279
+ }
3280
+ }
3281
+
3282
+ /**
3283
+ * Converts UTF16 characters to UTF8 code points.
3284
+ * @param {!function():number|null} src Characters source as a function returning the next char code respectively
3285
+ * `null` if there are no more characters left.
3286
+ * @param {!function(number)} dst Code points destination as a function successively called with each converted code
3287
+ * point.
3288
+ */
3289
+ utfx.UTF16toUTF8 = function (src, dst) {
3290
+ let c1
3291
+ let c2 = null
3292
+ while (true) {
3293
+ if ((c1 = c2 !== null ? c2 : src()) === null) {
3294
+ break
3295
+ }
3296
+ if (c1 >= 0xd800 && c1 <= 0xdfff) {
3297
+ if ((c2 = src()) !== null) {
3298
+ if (c2 >= 0xdc00 && c2 <= 0xdfff) {
3299
+ dst((c1 - 0xd800) * 0x400 + c2 - 0xdc00 + 0x10000)
3300
+ c2 = null
3301
+ continue
3302
+ }
3303
+ }
3304
+ }
3305
+ dst(c1)
3306
+ }
3307
+ if (c2 !== null) dst(c2)
3308
+ }
3309
+
3310
+ /**
3311
+ * Converts UTF8 code points to UTF16 characters.
3312
+ * @param {(!function():number|null) | number} src Code points source, either as a function returning the next code point
3313
+ * respectively `null` if there are no more code points left or a single numeric code point.
3314
+ * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
3315
+ * @throws {RangeError} If a code point is out of range
3316
+ */
3317
+ utfx.UTF8toUTF16 = function (src, dst) {
3318
+ let cp = null
3319
+ if (typeof src === 'number') {
3320
+ cp = src
3321
+ src = function () {
3322
+ return null
3323
+ }
3324
+ }
3325
+ while (cp !== null || (cp = src()) !== null) {
3326
+ if (cp <= 0xffff) {
3327
+ dst(cp)
3328
+ } else {
3329
+ cp -= 0x10000
3330
+ dst((cp >> 10) + 0xd800)
3331
+ dst((cp % 0x400) + 0xdc00)
3332
+ }
3333
+ cp = null
3334
+ }
3335
+ }
3336
+
3337
+ /**
3338
+ * Converts and encodes UTF16 characters to UTF8 bytes.
3339
+ * @param {!function():number|null} src Characters source as a function returning the next char code respectively `null`
3340
+ * if there are no more characters left.
3341
+ * @param {!function(number)} dst Bytes destination as a function successively called with the next byte.
3342
+ */
3343
+ utfx.encodeUTF16toUTF8 = function (src, dst) {
3344
+ utfx.UTF16toUTF8(src, function (cp) {
3345
+ utfx.encodeUTF8(cp, dst)
3346
+ })
3347
+ }
3348
+
3349
+ /**
3350
+ * Decodes and converts UTF8 bytes to UTF16 characters.
3351
+ * @param {!function():number|null} src Bytes source as a function returning the next byte respectively `null` if there
3352
+ * are no more bytes left.
3353
+ * @param {!function(number)} dst Characters destination as a function successively called with each converted char code.
3354
+ * @throws {RangeError} If a starting byte is invalid in UTF8
3355
+ * @throws {Error} If the last sequence is truncated. Has an array property `bytes` holding the remaining bytes.
3356
+ */
3357
+ utfx.decodeUTF8toUTF16 = function (src, dst) {
3358
+ utfx.decodeUTF8(src, function (cp) {
3359
+ utfx.UTF8toUTF16(cp, dst)
3360
+ })
3361
+ }
3362
+
3363
+ /**
3364
+ * Calculates the byte length of an UTF8 code point.
3365
+ * @param {number} cp UTF8 code point
3366
+ * @returns {number} Byte length
3367
+ */
3368
+ utfx.calculateCodePoint = function (cp) {
3369
+ return cp < 0x80 ? 1 : cp < 0x800 ? 2 : cp < 0x10000 ? 3 : 4
3370
+ }
3371
+
3372
+ /**
3373
+ * Calculates the number of UTF8 bytes required to store UTF8 code points.
3374
+ * @param {(!function():number|null)} src Code points source as a function returning the next code point respectively
3375
+ * `null` if there are no more code points left.
3376
+ * @returns {number} The number of UTF8 bytes required
3377
+ */
3378
+ utfx.calculateUTF8 = function (src) {
3379
+ let cp
3380
+ let l = 0
3381
+ while ((cp = src()) !== null) {
3382
+ l += cp < 0x80 ? 1 : cp < 0x800 ? 2 : cp < 0x10000 ? 3 : 4
3383
+ }
3384
+ return l
3385
+ }
3386
+
3387
+ /**
3388
+ * Calculates the number of UTF8 code points respectively UTF8 bytes required to store UTF16 char codes.
3389
+ * @param {(!function():number|null)} src Characters source as a function returning the next char code respectively
3390
+ * `null` if there are no more characters left.
3391
+ * @returns {!Array.<number>} The number of UTF8 code points at index 0 and the number of UTF8 bytes required at index 1.
3392
+ */
3393
+ utfx.calculateUTF16asUTF8 = function (src) {
3394
+ let n = 0
3395
+ let l = 0
3396
+ utfx.UTF16toUTF8(src, function (cp) {
3397
+ ++n
3398
+ l += cp < 0x80 ? 1 : cp < 0x800 ? 2 : cp < 0x10000 ? 3 : 4
3399
+ })
3400
+ return [n, l]
3401
+ }