protobufjs 8.6.6 → 8.7.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.
@@ -1,6 +1,6 @@
1
1
  /*!
2
- * protobuf.js v8.6.6 (c) 2016, daniel wirtz
3
- * compiled sat, 04 jul 2026 01:09:57 utc
2
+ * protobuf.js v8.7.0 (c) 2016, daniel wirtz
3
+ * compiled mon, 06 jul 2026 13:50:00 utc
4
4
  * licensed under the bsd-3-clause license
5
5
  * see: https://github.com/dcodeio/protobuf.js for details
6
6
  */
@@ -66,7 +66,6 @@ exports.configure = configure;
66
66
  * @returns {undefined}
67
67
  */
68
68
  function configure() {
69
- exports.util._configure();
70
69
  exports.Writer._configure(exports.BufferWriter);
71
70
  exports.Reader._configure(exports.BufferReader);
72
71
  }
@@ -92,7 +91,7 @@ function indexOutOfRange(reader, writeLength) {
92
91
 
93
92
  /**
94
93
  * Constructs a new reader instance using the specified buffer.
95
- * @classdesc Wire format reader using `Uint8Array` if available, otherwise `Array`.
94
+ * @classdesc Wire format reader using `Uint8Array`.
96
95
  * @constructor
97
96
  * @param {Uint8Array} buffer Buffer to read from
98
97
  */
@@ -116,6 +115,12 @@ function Reader(buffer) {
116
115
  */
117
116
  this.len = buffer.length;
118
117
 
118
+ /**
119
+ * Cached DataView for packed reads.
120
+ * @type {DataView|null}
121
+ */
122
+ this.view = null;
123
+
119
124
  /**
120
125
  * Whether to discard unknown fields while decoding.
121
126
  * @type {boolean}
@@ -123,18 +128,14 @@ function Reader(buffer) {
123
128
  this.discardUnknown = Reader.discardUnknown;
124
129
  }
125
130
 
126
- var create_array = typeof Uint8Array !== "undefined"
127
- ? function create_typed_array(buffer) {
128
- if (buffer instanceof Uint8Array || Array.isArray(buffer))
129
- return new Reader(buffer);
130
- throw Error("illegal buffer");
131
- }
132
- /* istanbul ignore next */
133
- : function create_array(buffer) {
134
- if (Array.isArray(buffer))
135
- return new Reader(buffer);
136
- throw Error("illegal buffer");
137
- };
131
+ function create_array(buffer) {
132
+ // TODO: Remove plain array reader support in the next major release.
133
+ if (Array.isArray(buffer))
134
+ buffer = new Uint8Array(buffer);
135
+ if (buffer instanceof Uint8Array)
136
+ return new Reader(buffer);
137
+ throw Error("illegal buffer");
138
+ }
138
139
 
139
140
  var create = function create() {
140
141
  return util.Buffer
@@ -159,8 +160,6 @@ var create = function create() {
159
160
  */
160
161
  Reader.create = create();
161
162
 
162
- Reader.prototype._slice = util.Array.prototype.subarray || /* istanbul ignore next */ util.Array.prototype.slice;
163
-
164
163
  /**
165
164
  * Returns raw bytes from the backing buffer without advancing the reader.
166
165
  * @param {number} start Start offset
@@ -168,12 +167,7 @@ Reader.prototype._slice = util.Array.prototype.subarray || /* istanbul ignore ne
168
167
  * @returns {Uint8Array} Raw bytes
169
168
  */
170
169
  Reader.prototype.raw = function read_raw(start, end) {
171
- if (Array.isArray(this.buf)) // plain array
172
- return this.buf.slice(start, end);
173
-
174
- if (start === end) // fix for IE 10/Win8 and others' subarray returning array of size 1
175
- return new this.buf.constructor(0);
176
- return this._slice.call(this.buf, start, end);
170
+ return this.buf.subarray(start, end);
177
171
  };
178
172
 
179
173
  /**
@@ -470,6 +464,241 @@ Reader.prototype.double = function read_double() {
470
464
  return value;
471
465
  };
472
466
 
467
+ /**
468
+ * Reads a packed repeated field of unsigned 32 bit varints.
469
+ * @param {number[]} [array] Array to read into; a new one is created if omitted
470
+ * @returns {number[]} Array read into
471
+ */
472
+ Reader.prototype.uint32s = function read_uint32s(array) {
473
+ if (array === undefined) array = [];
474
+ var end = this.uint32() + this.pos;
475
+ while (this.pos < end)
476
+ array.push(this.uint32());
477
+ return array;
478
+ };
479
+
480
+ /**
481
+ * Reads a packed repeated field of signed 32 bit varints.
482
+ * @param {number[]} [array] Array to read into; a new one is created if omitted
483
+ * @returns {number[]} Array read into
484
+ */
485
+ Reader.prototype.int32s = function read_int32s(array) {
486
+ if (array === undefined) array = [];
487
+ var end = this.uint32() + this.pos;
488
+ while (this.pos < end)
489
+ array.push(this.int32());
490
+ return array;
491
+ };
492
+
493
+ /**
494
+ * Reads a packed repeated field of zig-zag encoded signed 32 bit varints.
495
+ * @param {number[]} [array] Array to read into; a new one is created if omitted
496
+ * @returns {number[]} Array read into
497
+ */
498
+ Reader.prototype.sint32s = function read_sint32s(array) {
499
+ if (array === undefined) array = [];
500
+ var end = this.uint32() + this.pos;
501
+ while (this.pos < end)
502
+ array.push(this.sint32());
503
+ return array;
504
+ };
505
+
506
+ /**
507
+ * Reads a packed repeated field of booleans.
508
+ * @param {boolean[]} [array] Array to read into; a new one is created if omitted
509
+ * @returns {boolean[]} Array read into
510
+ */
511
+ Reader.prototype.bools = function read_bools(array) {
512
+ if (array === undefined) array = [];
513
+ var end = this.uint32() + this.pos;
514
+ while (this.pos < end)
515
+ array.push(this.bool());
516
+ return array;
517
+ };
518
+
519
+ // The view allocation only pays off when amortized over enough reads
520
+ var VIEW_THRESHOLD_FLOAT = 8,
521
+ VIEW_THRESHOLD_INT = 128;
522
+
523
+ function getLazyView(reader, count, threshold) {
524
+ var view = reader.view;
525
+ if (view || count < threshold)
526
+ return view;
527
+ var buf = reader.buf;
528
+ return reader.view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
529
+ }
530
+
531
+ /**
532
+ * Reads a packed repeated field of unsigned 32 bit fixed values.
533
+ * @param {number[]} [array] Array to read into; a new one is created if omitted
534
+ * @returns {number[]} Array read into
535
+ */
536
+ Reader.prototype.fixed32s = function read_fixed32s(array) {
537
+ if (array === undefined) array = [];
538
+ var len = this.uint32(), end = this.pos + len;
539
+ /* istanbul ignore if */
540
+ if (end > this.len) throw indexOutOfRange(this, len);
541
+ var count = len >>> 2, i = array.length, pos = this.pos;
542
+ array.length = i + count;
543
+ var dv = getLazyView(this, count, VIEW_THRESHOLD_INT);
544
+ if (dv)
545
+ for (var k = 0; k < count; ++k, pos += 4) array[i++] = dv.getUint32(pos, true);
546
+ else {
547
+ var buf = this.buf;
548
+ for (var j = 0; j < count; ++j, pos += 4) array[i++] = readFixed32_end(buf, pos + 4);
549
+ }
550
+ this.pos = pos;
551
+ if (pos !== end) throw indexOutOfRange(this, 4);
552
+ return array;
553
+ };
554
+
555
+ /**
556
+ * Reads a packed repeated field of signed 32 bit fixed values.
557
+ * @param {number[]} [array] Array to read into; a new one is created if omitted
558
+ * @returns {number[]} Array read into
559
+ */
560
+ Reader.prototype.sfixed32s = function read_sfixed32s(array) {
561
+ if (array === undefined) array = [];
562
+ var len = this.uint32(), end = this.pos + len;
563
+ /* istanbul ignore if */
564
+ if (end > this.len) throw indexOutOfRange(this, len);
565
+ var count = len >>> 2, i = array.length, pos = this.pos;
566
+ array.length = i + count;
567
+ var dv = getLazyView(this, count, VIEW_THRESHOLD_INT);
568
+ if (dv)
569
+ for (var k = 0; k < count; ++k, pos += 4) array[i++] = dv.getInt32(pos, true);
570
+ else {
571
+ var buf = this.buf;
572
+ for (var j = 0; j < count; ++j, pos += 4) array[i++] = readFixed32_end(buf, pos + 4) | 0;
573
+ }
574
+ this.pos = pos;
575
+ if (pos !== end) throw indexOutOfRange(this, 4);
576
+ return array;
577
+ };
578
+
579
+ /**
580
+ * Reads a packed repeated field of floats (32 bit).
581
+ * @param {number[]} [array] Array to read into; a new one is created if omitted
582
+ * @returns {number[]} Array read into
583
+ */
584
+ Reader.prototype.floats = function read_floats(array) {
585
+ if (array === undefined) array = [];
586
+ var len = this.uint32(), end = this.pos + len;
587
+ /* istanbul ignore if */
588
+ if (end > this.len) throw indexOutOfRange(this, len);
589
+ var count = len >>> 2, i = array.length, pos = this.pos;
590
+ array.length = i + count;
591
+ var dv = getLazyView(this, count, VIEW_THRESHOLD_FLOAT);
592
+ if (dv)
593
+ for (var k = 0; k < count; ++k, pos += 4) array[i++] = dv.getFloat32(pos, true);
594
+ else {
595
+ var buf = this.buf;
596
+ for (var j = 0; j < count; ++j, pos += 4) array[i++] = util.float.readFloatLE(buf, pos);
597
+ }
598
+ this.pos = pos;
599
+ if (pos !== end) throw indexOutOfRange(this, 4);
600
+ return array;
601
+ };
602
+
603
+ /**
604
+ * Reads a packed repeated field of doubles (64 bit float).
605
+ * @param {number[]} [array] Array to read into; a new one is created if omitted
606
+ * @returns {number[]} Array read into
607
+ */
608
+ Reader.prototype.doubles = function read_doubles(array) {
609
+ if (array === undefined) array = [];
610
+ var len = this.uint32(), end = this.pos + len;
611
+ /* istanbul ignore if */
612
+ if (end > this.len) throw indexOutOfRange(this, len);
613
+ var count = len >>> 3, i = array.length, pos = this.pos;
614
+ array.length = i + count;
615
+ var dv = getLazyView(this, count, VIEW_THRESHOLD_FLOAT);
616
+ if (dv)
617
+ for (var k = 0; k < count; ++k, pos += 8) array[i++] = dv.getFloat64(pos, true);
618
+ else {
619
+ var buf = this.buf;
620
+ for (var j = 0; j < count; ++j, pos += 8) array[i++] = util.float.readDoubleLE(buf, pos);
621
+ }
622
+ this.pos = pos;
623
+ if (pos !== end) throw indexOutOfRange(this, 8);
624
+ return array;
625
+ };
626
+
627
+ /**
628
+ * Reads a packed repeated field of unsigned 64 bit varints.
629
+ * @param {Array.<Long|number>} [array] Array to read into; a new one is created if omitted
630
+ * @returns {Array.<Long|number>} Array read into
631
+ */
632
+ Reader.prototype.uint64s = function read_uint64s(array) {
633
+ if (array === undefined) array = [];
634
+ var end = this.uint32() + this.pos;
635
+ while (this.pos < end)
636
+ array.push(this.uint64());
637
+ return array;
638
+ };
639
+
640
+ /**
641
+ * Reads a packed repeated field of signed 64 bit varints.
642
+ * @param {Array.<Long|number>} [array] Array to read into; a new one is created if omitted
643
+ * @returns {Array.<Long|number>} Array read into
644
+ */
645
+ Reader.prototype.int64s = function read_int64s(array) {
646
+ if (array === undefined) array = [];
647
+ var end = this.uint32() + this.pos;
648
+ while (this.pos < end)
649
+ array.push(this.int64());
650
+ return array;
651
+ };
652
+
653
+ /**
654
+ * Reads a packed repeated field of zig-zag encoded signed 64 bit varints.
655
+ * @param {Array.<Long|number>} [array] Array to read into; a new one is created if omitted
656
+ * @returns {Array.<Long|number>} Array read into
657
+ */
658
+ Reader.prototype.sint64s = function read_sint64s(array) {
659
+ if (array === undefined) array = [];
660
+ var end = this.uint32() + this.pos;
661
+ while (this.pos < end)
662
+ array.push(this.sint64());
663
+ return array;
664
+ };
665
+
666
+ /**
667
+ * Reads a packed repeated field of unsigned 64 bit fixed values.
668
+ * @param {Array.<Long|number>} [array] Array to read into; a new one is created if omitted
669
+ * @returns {Array.<Long|number>} Array read into
670
+ */
671
+ Reader.prototype.fixed64s = function read_fixed64s(array) {
672
+ if (array === undefined) array = [];
673
+ var len = this.uint32(), end = this.pos + len, i = array.length;
674
+ /* istanbul ignore if */
675
+ if (end > this.len) throw indexOutOfRange(this, len);
676
+ var count = len >>> 3;
677
+ array.length = i + count; // 8 bytes per value, count is known
678
+ for (var j = 0; j < count; ++j)
679
+ array[i++] = this.fixed64();
680
+ if (this.pos !== end) throw indexOutOfRange(this, 8);
681
+ return array;
682
+ };
683
+
684
+ /**
685
+ * Reads a packed repeated field of signed 64 bit fixed values.
686
+ * @param {Array.<Long|number>} [array] Array to read into; a new one is created if omitted
687
+ * @returns {Array.<Long|number>} Array read into
688
+ */
689
+ Reader.prototype.sfixed64s = function read_sfixed64s(array) {
690
+ if (array === undefined) array = [];
691
+ var len = this.uint32(), end = this.pos + len, i = array.length;
692
+ /* istanbul ignore if */
693
+ if (end > this.len) throw indexOutOfRange(this, len);
694
+ var count = len >>> 3;
695
+ array.length = i + count; // 8 bytes per value, count is known
696
+ for (var j = 0; j < count; ++j)
697
+ array[i++] = this.sfixed64();
698
+ if (this.pos !== end) throw indexOutOfRange(this, 8);
699
+ return array;
700
+ };
701
+
473
702
  /**
474
703
  * Reads a sequence of bytes preceeded by its length as a varint.
475
704
  * @returns {Uint8Array} Value read
@@ -665,7 +894,7 @@ function BufferReader(buffer) {
665
894
  * Read buffer.
666
895
  * @name BufferReader#buf
667
896
  * @type {Buffer}
668
- */
897
+ */
669
898
  }
670
899
 
671
900
  BufferReader._configure = function () {
@@ -683,8 +912,6 @@ BufferReader._configure = function () {
683
912
  * @returns {Buffer} Raw bytes
684
913
  */
685
914
  BufferReader.prototype.raw = function read_raw_buffer(start, end) {
686
- if (start === end)
687
- return util.Buffer.alloc(0);
688
915
  return this._slice.call(this.buf, start, end);
689
916
  };
690
917
 
@@ -1899,36 +2126,29 @@ util.isSet = function isSet(obj, prop) {
1899
2126
  util.Buffer = (function() {
1900
2127
  try {
1901
2128
  var Buffer = util.global.Buffer;
1902
- // refuse to use non-node buffers if not explicitly assigned (perf reasons):
1903
- return Buffer.prototype.utf8Write ? Buffer : /* istanbul ignore next */ null;
2129
+ // refuse to use non-node buffers if not explicitly assigned (perf reasons)
2130
+ return Buffer.prototype.utf8Write || util.isNode ? Buffer : /* istanbul ignore next */ null;
1904
2131
  } catch (e) {
1905
2132
  /* istanbul ignore next */
1906
2133
  return null;
1907
2134
  }
1908
2135
  })();
1909
2136
 
1910
- // Internal alias of or polyfull for Buffer.from.
1911
- util._Buffer_from = null;
1912
-
1913
- // Internal alias of or polyfill for Buffer.allocUnsafe.
1914
- util._Buffer_allocUnsafe = null;
1915
-
1916
2137
  /**
1917
2138
  * Creates a new buffer of whatever type supported by the environment.
1918
2139
  * @param {number|number[]} [sizeOrArray=0] Buffer size or number array
1919
2140
  * @returns {Uint8Array|Buffer} Buffer
1920
2141
  */
1921
2142
  util.newBuffer = function newBuffer(sizeOrArray) {
2143
+ var Buffer = util.Buffer;
1922
2144
  /* istanbul ignore next */
1923
2145
  return typeof sizeOrArray === "number"
1924
- ? util.Buffer
1925
- ? util._Buffer_allocUnsafe(sizeOrArray)
1926
- : new util.Array(sizeOrArray)
1927
- : util.Buffer
1928
- ? util._Buffer_from(sizeOrArray)
1929
- : typeof Uint8Array === "undefined"
1930
- ? sizeOrArray
1931
- : new Uint8Array(sizeOrArray);
2146
+ ? Buffer
2147
+ ? Buffer.allocUnsafe(sizeOrArray)
2148
+ : new Uint8Array(sizeOrArray)
2149
+ : Buffer
2150
+ ? Buffer.from(sizeOrArray)
2151
+ : new Uint8Array(sizeOrArray);
1932
2152
  };
1933
2153
 
1934
2154
  /**
@@ -1954,10 +2174,11 @@ util.rawField = function rawField(id, wireType, data) {
1954
2174
  };
1955
2175
 
1956
2176
  /**
1957
- * Array implementation used in the browser. `Uint8Array` if supported, otherwise `Array`.
2177
+ * Array implementation used in the browser.
1958
2178
  * @type {Constructor<Uint8Array>}
2179
+ * @deprecated Use `Uint8Array` instead.
1959
2180
  */
1960
- util.Array = typeof Uint8Array !== "undefined" ? Uint8Array /* istanbul ignore next */ : Array;
2181
+ util.Array = Uint8Array;
1961
2182
 
1962
2183
  /**
1963
2184
  * Any compatible Long instance.
@@ -2278,28 +2499,6 @@ util.toJSONOptions = {
2278
2499
  json: true
2279
2500
  };
2280
2501
 
2281
- // Sets up buffer utility according to the environment (called in index-minimal)
2282
- util._configure = function() {
2283
- var Buffer = util.Buffer;
2284
- /* istanbul ignore if */
2285
- if (!Buffer) {
2286
- util._Buffer_from = util._Buffer_allocUnsafe = null;
2287
- return;
2288
- }
2289
- // because node 4.x buffers are incompatible & immutable
2290
- // see: https://github.com/dcodeIO/protobuf.js/pull/665
2291
- util._Buffer_from = Buffer.from !== Uint8Array.from && Buffer.from ||
2292
- /* istanbul ignore next */
2293
- function Buffer_from(value, encoding) {
2294
- return new Buffer(value, encoding);
2295
- };
2296
- util._Buffer_allocUnsafe = Buffer.allocUnsafe ||
2297
- /* istanbul ignore next */
2298
- function Buffer_allocUnsafe(size) {
2299
- return new Buffer(size);
2300
- };
2301
- };
2302
-
2303
2502
  },{"10":10,"11":11,"13":13,"14":14,"7":7,"8":8,"9":9,"long":"long"}],13:[function(require,module,exports){
2304
2503
  "use strict";
2305
2504
  module.exports = pool;
@@ -2354,19 +2553,21 @@ function pool(alloc, slice, size) {
2354
2553
  "use strict";
2355
2554
 
2356
2555
  /**
2357
- * A minimal UTF8 implementation for number arrays.
2556
+ * A minimal UTF8 implementation.
2358
2557
  * @memberof util
2359
2558
  * @namespace
2360
2559
  */
2361
2560
  var utf8 = exports,
2362
2561
  replacementChar = "\ufffd",
2562
+ looseDecoder = new TextDecoder("utf-8", { ignoreBOM: true }),
2363
2563
  strictDecoder;
2564
+ var TEXT_DECODER_MIN_LENGTH = 64;
2364
2565
 
2365
2566
  try {
2366
2567
  strictDecoder = new TextDecoder("utf-8", { fatal: true, ignoreBOM: true });
2367
2568
  } catch (err) {
2368
2569
  // "fatal" option is not supported on Node.js compiled without ICU
2369
- strictDecoder = new TextDecoder("utf-8", { ignoreBOM: true });
2570
+ strictDecoder = looseDecoder;
2370
2571
  }
2371
2572
 
2372
2573
  /**
@@ -2417,6 +2618,13 @@ function utf8_read_js(buffer, start, end, str) {
2417
2618
  return str;
2418
2619
  }
2419
2620
 
2621
+ function utf8_read_decoder(decoder, buffer, start, end) {
2622
+ var source = start === 0 && end === buffer.length
2623
+ ? buffer
2624
+ : buffer.subarray(start, end);
2625
+ return decoder.decode(source);
2626
+ }
2627
+
2420
2628
  /**
2421
2629
  * Reads UTF8 bytes as a string.
2422
2630
  * @param {Uint8Array} buffer Source buffer
@@ -2424,9 +2632,11 @@ function utf8_read_js(buffer, start, end, str) {
2424
2632
  * @param {number} end Source end
2425
2633
  * @returns {string} String read
2426
2634
  */
2427
- utf8.read = function utf8_read_ascii(buffer, start, end) {
2635
+ utf8.read = function utf8_read_loose(buffer, start, end) {
2428
2636
  if (end - start < 1)
2429
2637
  return "";
2638
+ if (end - start >= TEXT_DECODER_MIN_LENGTH)
2639
+ return utf8_read_decoder(looseDecoder, buffer, start, end);
2430
2640
 
2431
2641
  var str = "",
2432
2642
  i = start,
@@ -2456,17 +2666,6 @@ utf8.read = function utf8_read_ascii(buffer, start, end) {
2456
2666
  return str;
2457
2667
  };
2458
2668
 
2459
- function utf8_read_strict(buffer, start, end) {
2460
- var source = start === 0 && end === buffer.length
2461
- ? buffer
2462
- : buffer.subarray
2463
- ? buffer.subarray(start, end)
2464
- : buffer.slice(start, end);
2465
- if (Array.isArray(source))
2466
- source = Uint8Array.from(source);
2467
- return strictDecoder.decode(source);
2468
- }
2469
-
2470
2669
  /**
2471
2670
  * Reads UTF8 bytes as a string, rejecting invalid UTF8.
2472
2671
  * @param {Uint8Array} buffer Source buffer
@@ -2474,9 +2673,11 @@ function utf8_read_strict(buffer, start, end) {
2474
2673
  * @param {number} end Source end
2475
2674
  * @returns {string} String read
2476
2675
  */
2477
- utf8.readStrict = function utf8_read_strict_ascii(buffer, start, end) {
2676
+ utf8.readStrict = function utf8_read_strict(buffer, start, end) {
2478
2677
  if (end - start < 1)
2479
2678
  return "";
2679
+ if (end - start >= TEXT_DECODER_MIN_LENGTH)
2680
+ return utf8_read_decoder(strictDecoder, buffer, start, end);
2480
2681
 
2481
2682
  var str = "",
2482
2683
  i = start,
@@ -2492,14 +2693,14 @@ utf8.readStrict = function utf8_read_strict_ascii(buffer, start, end) {
2492
2693
  c7 = buffer[i + 6];
2493
2694
  c8 = buffer[i + 7];
2494
2695
  if ((c1 | c2 | c3 | c4 | c5 | c6 | c7 | c8) & 0x80)
2495
- return str + utf8_read_strict(buffer, i, end);
2696
+ return str + utf8_read_decoder(strictDecoder, buffer, i, end);
2496
2697
  str += String.fromCharCode(c1, c2, c3, c4, c5, c6, c7, c8);
2497
2698
  }
2498
2699
 
2499
2700
  for (; i < end; ++i) {
2500
2701
  c1 = buffer[i];
2501
2702
  if (c1 & 0x80)
2502
- return str + utf8_read_strict(buffer, i, end);
2703
+ return str + utf8_read_decoder(strictDecoder, buffer, i, end);
2503
2704
  str += String.fromCharCode(c1);
2504
2705
  }
2505
2706
 
@@ -2552,118 +2753,52 @@ var LongBits = util.LongBits,
2552
2753
  base64 = util.base64,
2553
2754
  utf8 = util.utf8;
2554
2755
 
2555
- /**
2556
- * Constructs a new writer operation instance.
2557
- * @classdesc Scheduled writer operation.
2558
- * @constructor
2559
- * @param {function(*, Uint8Array, number)} fn Function to call
2560
- * @param {number} len Value byte length
2561
- * @param {*} val Value to write
2562
- * @ignore
2563
- */
2564
- function Op(fn, len, val) {
2565
-
2566
- /**
2567
- * Function to call.
2568
- * @type {function(Uint8Array, number, *)}
2569
- */
2570
- this.fn = fn;
2571
-
2572
- /**
2573
- * Value byte length.
2574
- * @type {number}
2575
- */
2576
- this.len = len;
2577
-
2578
- /**
2579
- * Next operation.
2580
- * @type {Writer.Op|undefined}
2581
- */
2582
- this.next = undefined;
2583
-
2584
- /**
2585
- * Value to write.
2586
- * @type {*}
2587
- */
2588
- this.val = val; // type varies
2589
- }
2590
-
2591
- /* istanbul ignore next */
2592
- function noop() {} // eslint-disable-line no-empty-function
2593
-
2594
- /**
2595
- * Constructs a new writer state instance.
2596
- * @classdesc Copied writer state.
2597
- * @memberof Writer
2598
- * @constructor
2599
- * @param {Writer} writer Writer to copy state from
2600
- * @ignore
2601
- */
2602
- function State(writer) {
2603
-
2604
- /**
2605
- * Current head.
2606
- * @type {Writer.Op}
2607
- */
2608
- this.head = writer.head;
2609
-
2610
- /**
2611
- * Current tail.
2612
- * @type {Writer.Op}
2613
- */
2614
- this.tail = writer.tail;
2615
-
2616
- /**
2617
- * Current buffer length.
2618
- * @type {number}
2619
- */
2620
- this.len = writer.len;
2621
-
2622
- /**
2623
- * Next state.
2624
- * @type {State|null}
2625
- */
2626
- this.next = writer.states;
2627
- }
2628
-
2629
2756
  /**
2630
2757
  * Constructs a new writer instance.
2631
- * @classdesc Wire format writer using `Uint8Array` if available, otherwise `Array`.
2758
+ * @classdesc Wire format writer using `Uint8Array`.
2632
2759
  * @constructor
2633
2760
  */
2634
2761
  function Writer() {
2635
2762
 
2636
2763
  /**
2637
- * Current length.
2764
+ * Write cursor into {@link Writer#buf}.
2638
2765
  * @type {number}
2639
2766
  */
2640
- this.len = 0;
2767
+ this.pos = 0;
2641
2768
 
2642
2769
  /**
2643
- * Operations head.
2644
- * @type {Object}
2770
+ * Backing buffer.
2771
+ * @type {Uint8Array}
2645
2772
  */
2646
- this.head = new Op(noop, 0, 0);
2773
+ this.buf = this.constructor.alloc(64);
2647
2774
 
2648
2775
  /**
2649
- * Operations tail
2650
- * @type {Object}
2776
+ * Cached DataView over {@link Writer#buf}.
2777
+ * @type {DataView|null}
2651
2778
  */
2652
- this.tail = this.head;
2779
+ this.view = null;
2653
2780
 
2654
2781
  /**
2655
- * Linked forked states.
2656
- * @type {Object|null}
2782
+ * Stack of forked length-prefix positions.
2783
+ * @type {Array<number>|null}
2657
2784
  */
2658
2785
  this.states = null;
2659
-
2660
- // When a value is written, the writer calculates its byte length and puts it into a linked
2661
- // list of operations to perform when finish() is called. This both allows us to allocate
2662
- // buffers of the exact required size and reduces the amount of work we have to do compared
2663
- // to first calculating over objects and then encoding over objects. In our case, the encoding
2664
- // part is just a linked list walk calling operations with already prepared values.
2665
2786
  }
2666
2787
 
2788
+ /**
2789
+ * Current write position.
2790
+ * @name Writer#len
2791
+ * @type {number}
2792
+ * @deprecated Use {@link Writer#pos} instead.
2793
+ */
2794
+ Object.defineProperty(Writer.prototype, "len", {
2795
+ configurable: true,
2796
+ enumerable: true,
2797
+ get: function get_len() {
2798
+ return this.pos;
2799
+ }
2800
+ });
2801
+
2667
2802
  var create = function create() {
2668
2803
  return util.Buffer
2669
2804
  ? function create_buffer_setup() {
@@ -2690,32 +2825,45 @@ Writer.create = create();
2690
2825
  * @returns {Uint8Array} Buffer
2691
2826
  */
2692
2827
  Writer.alloc = function alloc(size) {
2693
- return new util.Array(size);
2828
+ return new Uint8Array(size);
2694
2829
  };
2695
2830
 
2696
2831
  // Use Uint8Array buffer pool in the browser, just like node does with buffers
2697
- /* istanbul ignore else */
2698
- if (util.Array !== Array)
2699
- Writer.alloc = util.pool(Writer.alloc, util.Array.prototype.subarray);
2832
+ Writer.alloc = util.pool(Writer.alloc, Uint8Array.prototype.subarray);
2700
2833
 
2701
2834
  /**
2702
- * Pushes a new operation to the queue.
2703
- * @param {function(Uint8Array, number, *)} fn Function to call
2704
- * @param {number} len Value byte length
2705
- * @param {number} val Value to write
2706
- * @returns {Writer} `this`
2835
+ * Calculates the number of bytes a value occupies as a varint.
2836
+ * @param {number} value Value to size (unsigned)
2837
+ * @returns {number} Byte length (1..5)
2838
+ * @ignore
2839
+ */
2840
+ function sizeVarint32(value) {
2841
+ return value < 128 ? 1
2842
+ : value < 16384 ? 2
2843
+ : value < 2097152 ? 3
2844
+ : value < 268435456 ? 4
2845
+ : 5;
2846
+ }
2847
+
2848
+ /**
2849
+ * Ensures that at least `n` more bytes fit into the backing buffer, doubling it if not.
2850
+ * @param {number} n Number of additional bytes required
2851
+ * @returns {undefined}
2707
2852
  * @private
2708
2853
  */
2709
- Writer.prototype._push = function push(fn, len, val) {
2710
- this.tail = this.tail.next = new Op(fn, len, val);
2711
- this.len += len;
2712
- return this;
2854
+ Writer.prototype._reserve = function _reserve(n) {
2855
+ var need = this.pos + n;
2856
+ if (need > this.buf.length) {
2857
+ var size = this.buf.length << 1;
2858
+ if (size < need)
2859
+ size = need;
2860
+ var buf = this.constructor.alloc(size);
2861
+ buf.set(this.buf.subarray(0, this.pos), 0);
2862
+ this.buf = buf;
2863
+ this.view = null; // invalidate
2864
+ }
2713
2865
  };
2714
2866
 
2715
- function writeByte(val, buf, pos) {
2716
- buf[pos] = val & 255;
2717
- }
2718
-
2719
2867
  function writeStringAscii(val, buf, pos) {
2720
2868
  for (var i = 0; i < val.length;)
2721
2869
  buf[pos++] = val.charCodeAt(i++);
@@ -2727,42 +2875,19 @@ function writeVarint32(val, buf, pos) {
2727
2875
  val >>>= 7;
2728
2876
  }
2729
2877
  buf[pos] = val;
2878
+ return pos + 1;
2730
2879
  }
2731
2880
 
2732
- /**
2733
- * Constructs a new varint writer operation instance.
2734
- * @classdesc Scheduled varint writer operation.
2735
- * @extends Op
2736
- * @constructor
2737
- * @param {number} len Value byte length
2738
- * @param {number} val Value to write
2739
- * @ignore
2740
- */
2741
- function VarintOp(len, val) {
2742
- this.len = len;
2743
- this.next = undefined;
2744
- this.val = val;
2745
- }
2746
-
2747
- VarintOp.prototype = Object.create(Op.prototype);
2748
- VarintOp.prototype.fn = writeVarint32;
2749
-
2750
2881
  /**
2751
2882
  * Writes an unsigned 32 bit value as a varint.
2752
2883
  * @param {number} value Value to write
2753
2884
  * @returns {Writer} `this`
2754
2885
  */
2755
2886
  Writer.prototype.uint32 = function write_uint32(value) {
2756
- // here, the call to this.push has been inlined and a varint specific Op subclass is used.
2757
- // uint32 is by far the most frequently used operation and benefits significantly from this.
2758
- this.len += (this.tail = this.tail.next = new VarintOp(
2759
- (value = value >>> 0)
2760
- < 128 ? 1
2761
- : value < 16384 ? 2
2762
- : value < 2097152 ? 3
2763
- : value < 268435456 ? 4
2764
- : 5,
2765
- value)).len;
2887
+ value = value >>> 0;
2888
+ this._reserve(5);
2889
+ var pos = this.pos;
2890
+ this.pos = writeVarint32(value, this.buf, pos);
2766
2891
  return this;
2767
2892
  };
2768
2893
 
@@ -2773,9 +2898,13 @@ Writer.prototype.uint32 = function write_uint32(value) {
2773
2898
  * @returns {Writer} `this`
2774
2899
  */
2775
2900
  Writer.prototype.int32 = function write_int32(value) {
2776
- return (value |= 0) < 0
2777
- ? this._push(writeVarint64, 10, LongBits.fromNumber(value)) // 10 bytes per spec
2778
- : this.uint32(value);
2901
+ if ((value |= 0) < 0) { // 10 bytes per spec
2902
+ this._reserve(10);
2903
+ writeVarint64(LongBits.fromNumber(value), this.buf, this.pos);
2904
+ this.pos += 10;
2905
+ return this;
2906
+ }
2907
+ return this.uint32(value);
2779
2908
  };
2780
2909
 
2781
2910
  /**
@@ -2799,7 +2928,8 @@ function writeVarint64(val, buf, pos) {
2799
2928
  buf[pos++] = lo & 127 | 128;
2800
2929
  lo = lo >>> 7;
2801
2930
  }
2802
- buf[pos++] = lo;
2931
+ buf[pos] = lo;
2932
+ return pos + 1;
2803
2933
  }
2804
2934
 
2805
2935
  /**
@@ -2810,7 +2940,10 @@ function writeVarint64(val, buf, pos) {
2810
2940
  */
2811
2941
  Writer.prototype.uint64 = function write_uint64(value) {
2812
2942
  var bits = LongBits.from(value);
2813
- return this._push(writeVarint64, bits.length(), bits);
2943
+ this._reserve(10);
2944
+ var pos = this.pos;
2945
+ this.pos = writeVarint64(bits, this.buf, pos);
2946
+ return this;
2814
2947
  };
2815
2948
 
2816
2949
  /**
@@ -2830,7 +2963,10 @@ Writer.prototype.int64 = Writer.prototype.uint64;
2830
2963
  */
2831
2964
  Writer.prototype.sint64 = function write_sint64(value) {
2832
2965
  var bits = LongBits.from(value).zzEncode();
2833
- return this._push(writeVarint64, bits.length(), bits);
2966
+ this._reserve(10);
2967
+ var pos = this.pos;
2968
+ this.pos = writeVarint64(bits, this.buf, pos);
2969
+ return this;
2834
2970
  };
2835
2971
 
2836
2972
  /**
@@ -2839,7 +2975,9 @@ Writer.prototype.sint64 = function write_sint64(value) {
2839
2975
  * @returns {Writer} `this`
2840
2976
  */
2841
2977
  Writer.prototype.bool = function write_bool(value) {
2842
- return this._push(writeByte, 1, value ? 1 : 0);
2978
+ this._reserve(1);
2979
+ this.buf[this.pos++] = value ? 1 : 0;
2980
+ return this;
2843
2981
  };
2844
2982
 
2845
2983
  function writeFixed32(val, buf, pos) {
@@ -2855,7 +2993,10 @@ function writeFixed32(val, buf, pos) {
2855
2993
  * @returns {Writer} `this`
2856
2994
  */
2857
2995
  Writer.prototype.fixed32 = function write_fixed32(value) {
2858
- return this._push(writeFixed32, 4, value >>> 0);
2996
+ this._reserve(4);
2997
+ writeFixed32(value >>> 0, this.buf, this.pos);
2998
+ this.pos += 4;
2999
+ return this;
2859
3000
  };
2860
3001
 
2861
3002
  /**
@@ -2874,7 +3015,11 @@ Writer.prototype.sfixed32 = Writer.prototype.fixed32;
2874
3015
  */
2875
3016
  Writer.prototype.fixed64 = function write_fixed64(value) {
2876
3017
  var bits = LongBits.from(value);
2877
- return this._push(writeFixed32, 4, bits.lo)._push(writeFixed32, 4, bits.hi);
3018
+ this._reserve(8);
3019
+ writeFixed32(bits.lo, this.buf, this.pos);
3020
+ writeFixed32(bits.hi, this.buf, this.pos + 4);
3021
+ this.pos += 8;
3022
+ return this;
2878
3023
  };
2879
3024
 
2880
3025
  /**
@@ -2893,7 +3038,10 @@ Writer.prototype.sfixed64 = Writer.prototype.fixed64;
2893
3038
  * @returns {Writer} `this`
2894
3039
  */
2895
3040
  Writer.prototype.float = function write_float(value) {
2896
- return this._push(util.float.writeFloatLE, 4, value);
3041
+ this._reserve(4);
3042
+ util.float.writeFloatLE(value, this.buf, this.pos);
3043
+ this.pos += 4;
3044
+ return this;
2897
3045
  };
2898
3046
 
2899
3047
  /**
@@ -2903,19 +3051,12 @@ Writer.prototype.float = function write_float(value) {
2903
3051
  * @returns {Writer} `this`
2904
3052
  */
2905
3053
  Writer.prototype.double = function write_double(value) {
2906
- return this._push(util.float.writeDoubleLE, 8, value);
3054
+ this._reserve(8);
3055
+ util.float.writeDoubleLE(value, this.buf, this.pos);
3056
+ this.pos += 8;
3057
+ return this;
2907
3058
  };
2908
3059
 
2909
- var writeBytes = util.Array.prototype.set
2910
- ? function writeBytes_set(val, buf, pos) {
2911
- buf.set(val, pos); // also works for plain array values
2912
- }
2913
- /* istanbul ignore next */
2914
- : function writeBytes_for(val, buf, pos) {
2915
- for (var i = 0; i < val.length; ++i)
2916
- buf[pos + i] = val[i];
2917
- };
2918
-
2919
3060
  /**
2920
3061
  * Writes a sequence of bytes.
2921
3062
  * @param {Uint8Array|string} value Buffer or base64 encoded string to write
@@ -2923,14 +3064,21 @@ var writeBytes = util.Array.prototype.set
2923
3064
  */
2924
3065
  Writer.prototype.bytes = function write_bytes(value) {
2925
3066
  var len = value.length >>> 0;
2926
- if (!len)
2927
- return this._push(writeByte, 1, 0);
3067
+ if (!len) {
3068
+ this._reserve(1);
3069
+ this.buf[this.pos++] = 0;
3070
+ return this;
3071
+ }
2928
3072
  if (util.isString(value)) {
2929
3073
  var buf = Writer.alloc(len = base64.length(value));
2930
3074
  base64.decode(value, buf, 0);
2931
3075
  value = buf;
2932
3076
  }
2933
- return this.uint32(len)._push(writeBytes, len, value);
3077
+ this.uint32(len);
3078
+ this._reserve(len);
3079
+ this.buf.set(value, this.pos);
3080
+ this.pos += len;
3081
+ return this;
2934
3082
  };
2935
3083
 
2936
3084
  /**
@@ -2940,7 +3088,28 @@ Writer.prototype.bytes = function write_bytes(value) {
2940
3088
  */
2941
3089
  Writer.prototype.raw = function write_raw(value) {
2942
3090
  var len = value.length >>> 0;
2943
- return len ? this._push(writeBytes, len, value) : this;
3091
+ if (!len)
3092
+ return this;
3093
+ this._reserve(len);
3094
+ this.buf.set(value, this.pos);
3095
+ this.pos += len;
3096
+ return this;
3097
+ };
3098
+
3099
+ /**
3100
+ * Backfills the length varint.
3101
+ * @param {number} pos Position of reserved length byte
3102
+ * @param {number} len Length of content after length varint
3103
+ * @returns {Writer} `this`
3104
+ * @private
3105
+ */
3106
+ Writer.prototype._delim = function _delim(pos, len) {
3107
+ var n = sizeVarint32(len);
3108
+ if (n > 1)
3109
+ this.buf.copyWithin(pos + n, pos + 1, pos + 1 + len);
3110
+ writeVarint32(len, this.buf, pos);
3111
+ this.pos = pos + n + len;
3112
+ return this;
2944
3113
  };
2945
3114
 
2946
3115
  /**
@@ -2949,21 +3118,245 @@ Writer.prototype.raw = function write_raw(value) {
2949
3118
  * @returns {Writer} `this`
2950
3119
  */
2951
3120
  Writer.prototype.string = function write_string(value) {
3121
+ var n = value.length;
3122
+ if (!n) {
3123
+ this._reserve(1);
3124
+ this.buf[this.pos++] = 0;
3125
+ return this;
3126
+ }
3127
+ if (n < 0x80) {
3128
+ this._reserve(n * 3 + 5); // worst case
3129
+ var lenPos = this.pos;
3130
+ return this._delim(lenPos, utf8.write(value, this.buf, lenPos + 1));
3131
+ }
2952
3132
  var len = utf8.length(value);
2953
- return len
2954
- ? this.uint32(len)._push(len === value.length ? writeStringAscii : utf8.write, len, value)
2955
- : this._push(writeByte, 1, 0);
3133
+ this.uint32(len);
3134
+ this._reserve(len);
3135
+ if (len === value.length)
3136
+ writeStringAscii(value, this.buf, this.pos);
3137
+ else
3138
+ utf8.write(value, this.buf, this.pos);
3139
+ this.pos += len;
3140
+ return this;
3141
+ };
3142
+
3143
+ /**
3144
+ * Writes an array of unsigned 32 bit values as a packed repeated field.
3145
+ * @param {number[]} value Values to write
3146
+ * @returns {Writer} `this`
3147
+ */
3148
+ Writer.prototype.uint32s = function write_uint32s(value) {
3149
+ var n = value.length;
3150
+ this._reserve(n * 5 + 5); // worst case: 5 bytes per value + length varint
3151
+ var buf = this.buf, lenPos = this.pos, p = lenPos + 1;
3152
+ for (var i = 0; i < n; ++i)
3153
+ p = writeVarint32(value[i] >>> 0, buf, p);
3154
+ return this._delim(lenPos, p - lenPos - 1);
3155
+ };
3156
+
3157
+ /**
3158
+ * Writes an array of signed 32 bit values as a packed repeated field.
3159
+ * @param {number[]} value Values to write
3160
+ * @returns {Writer} `this`
3161
+ */
3162
+ Writer.prototype.int32s = function write_int32s(value) {
3163
+ var n = value.length;
3164
+ this._reserve(n * 10 + 5); // worst case: 10 bytes per negative value + length varint
3165
+ var buf = this.buf, lenPos = this.pos, pos = lenPos + 1, val;
3166
+ for (var i = 0; i < n; ++i) {
3167
+ if ((val = value[i] | 0) < 0) { // negatives are 10 bytes per spec
3168
+ pos = writeVarint64(LongBits.fromNumber(val), buf, pos);
3169
+ } else {
3170
+ pos = writeVarint32(val, buf, pos);
3171
+ }
3172
+ }
3173
+ return this._delim(lenPos, pos - lenPos - 1);
3174
+ };
3175
+
3176
+ /**
3177
+ * Writes an array of 32 bit values as packed, zig-zag encoded varints.
3178
+ * @param {number[]} value Values to write
3179
+ * @returns {Writer} `this`
3180
+ */
3181
+ Writer.prototype.sint32s = function write_sint32s(value) {
3182
+ var n = value.length;
3183
+ this._reserve(n * 5 + 5);
3184
+ var buf = this.buf, lenPos = this.pos, pos = lenPos + 1;
3185
+ for (var i = 0; i < n; ++i)
3186
+ pos = writeVarint32((value[i] << 1 ^ value[i] >> 31) >>> 0, buf, pos);
3187
+ return this._delim(lenPos, pos - lenPos - 1);
3188
+ };
3189
+
3190
+ /**
3191
+ * Writes an array of unsigned 64 bit values as a packed repeated field.
3192
+ * @param {Array.<Long|number|string>} value Values to write
3193
+ * @returns {Writer} `this`
3194
+ */
3195
+ Writer.prototype.uint64s = function write_uint64s(value) {
3196
+ var n = value.length;
3197
+ this._reserve(n * 10 + 5);
3198
+ var buf = this.buf, lenPos = this.pos, pos = lenPos + 1;
3199
+ for (var i = 0; i < n; ++i) {
3200
+ pos = writeVarint64(LongBits.from(value[i]), buf, pos);
3201
+ }
3202
+ return this._delim(lenPos, pos - lenPos - 1);
3203
+ };
3204
+
3205
+ /**
3206
+ * Writes an array of signed 64 bit values as a packed repeated field.
3207
+ * @function
3208
+ * @param {Array.<Long|number|string>} value Values to write
3209
+ * @returns {Writer} `this`
3210
+ */
3211
+ Writer.prototype.int64s = Writer.prototype.uint64s;
3212
+
3213
+ /**
3214
+ * Writes an array of 64 bit values as packed, zig-zag encoded varints.
3215
+ * @param {Array.<Long|number|string>} value Values to write
3216
+ * @returns {Writer} `this`
3217
+ */
3218
+ Writer.prototype.sint64s = function write_sint64s(value) {
3219
+ var n = value.length;
3220
+ this._reserve(n * 10 + 5);
3221
+ var buf = this.buf, lenPos = this.pos, pos = lenPos + 1;
3222
+ for (var i = 0; i < n; ++i) {
3223
+ pos = writeVarint64(LongBits.from(value[i]).zzEncode(), buf, pos);
3224
+ }
3225
+ return this._delim(lenPos, pos - lenPos - 1);
3226
+ };
3227
+
3228
+ /**
3229
+ * Writes an array of boolish values as a packed repeated field.
3230
+ * @param {boolean[]} value Values to write
3231
+ * @returns {Writer} `this`
3232
+ */
3233
+ Writer.prototype.bools = function write_bools(value) {
3234
+ var n = value.length;
3235
+ this.uint32(n); // one byte per value
3236
+ this._reserve(n);
3237
+ var buf = this.buf, p = this.pos;
3238
+ for (var i = 0; i < n; ++i)
3239
+ buf[p++] = value[i] ? 1 : 0;
3240
+ this.pos += n;
3241
+ return this;
3242
+ };
3243
+
3244
+ // The view allocation only pays off when amortized over enough writes
3245
+ var VIEW_THRESHOLD_FLOAT = 16,
3246
+ VIEW_THRESHOLD_INT = 128;
3247
+
3248
+ function getLazyView(writer, count, threshold) {
3249
+ var view = writer.view;
3250
+ if (view || count < threshold)
3251
+ return view;
3252
+ var buf = writer.buf;
3253
+ return writer.view = new DataView(buf.buffer, buf.byteOffset, buf.byteLength);
3254
+ }
3255
+
3256
+ /**
3257
+ * Writes an array of unsigned 32 bit values as packed, fixed 32 bits.
3258
+ * @param {number[]} value Values to write
3259
+ * @returns {Writer} `this`
3260
+ */
3261
+ Writer.prototype.fixed32s = function write_fixed32s(value) {
3262
+ var n = value.length, bytes = n * 4;
3263
+ this.uint32(bytes); // length is known exactly
3264
+ this._reserve(bytes);
3265
+ var p = this.pos, i, dv = getLazyView(this, n, VIEW_THRESHOLD_INT);
3266
+ if (dv)
3267
+ for (i = 0; i < n; ++i) { dv.setUint32(p, value[i] >>> 0, true); p += 4; }
3268
+ else {
3269
+ var buf = this.buf;
3270
+ for (i = 0; i < n; ++i) { writeFixed32(value[i] >>> 0, buf, p); p += 4; }
3271
+ }
3272
+ this.pos += bytes;
3273
+ return this;
3274
+ };
3275
+
3276
+ /**
3277
+ * Writes an array of signed 32 bit values as packed, fixed 32 bits.
3278
+ * @function
3279
+ * @param {number[]} value Values to write
3280
+ * @returns {Writer} `this`
3281
+ */
3282
+ Writer.prototype.sfixed32s = Writer.prototype.fixed32s;
3283
+
3284
+ /**
3285
+ * Writes an array of unsigned 64 bit values as packed, fixed 64 bits.
3286
+ * @param {Array.<Long|number|string>} value Values to write
3287
+ * @returns {Writer} `this`
3288
+ */
3289
+ Writer.prototype.fixed64s = function write_fixed64s(value) {
3290
+ var n = value.length, bytes = n * 8;
3291
+ this.uint32(bytes);
3292
+ this._reserve(bytes);
3293
+ var p = this.pos, i, bits, dv = getLazyView(this, n, VIEW_THRESHOLD_INT);
3294
+ if (dv)
3295
+ for (i = 0; i < n; ++i) { bits = LongBits.from(value[i]); dv.setUint32(p, bits.lo, true); dv.setUint32(p + 4, bits.hi, true); p += 8; }
3296
+ else {
3297
+ var buf = this.buf;
3298
+ for (i = 0; i < n; ++i) { bits = LongBits.from(value[i]); writeFixed32(bits.lo, buf, p); writeFixed32(bits.hi, buf, p + 4); p += 8; }
3299
+ }
3300
+ this.pos += bytes;
3301
+ return this;
3302
+ };
3303
+
3304
+ /**
3305
+ * Writes an array of signed 64 bit values as packed, fixed 64 bits.
3306
+ * @function
3307
+ * @param {Array.<Long|number|string>} value Values to write
3308
+ * @returns {Writer} `this`
3309
+ */
3310
+ Writer.prototype.sfixed64s = Writer.prototype.fixed64s;
3311
+
3312
+ /**
3313
+ * Writes an array of floats (32 bit) as a packed repeated field.
3314
+ * @param {number[]} value Values to write
3315
+ * @returns {Writer} `this`
3316
+ */
3317
+ Writer.prototype.floats = function write_floats(value) {
3318
+ var n = value.length, bytes = n * 4;
3319
+ this.uint32(bytes);
3320
+ this._reserve(bytes);
3321
+ var p = this.pos, i, dv = getLazyView(this, n, VIEW_THRESHOLD_FLOAT);
3322
+ if (dv)
3323
+ for (i = 0; i < n; ++i) { dv.setFloat32(p, value[i], true); p += 4; }
3324
+ else {
3325
+ var buf = this.buf;
3326
+ for (i = 0; i < n; ++i) { util.float.writeFloatLE(value[i], buf, p); p += 4; }
3327
+ }
3328
+ this.pos += bytes;
3329
+ return this;
3330
+ };
3331
+
3332
+ /**
3333
+ * Writes an array of doubles (64 bit float) as a packed repeated field.
3334
+ * @param {number[]} value Values to write
3335
+ * @returns {Writer} `this`
3336
+ */
3337
+ Writer.prototype.doubles = function write_doubles(value) {
3338
+ var n = value.length, bytes = n * 8;
3339
+ this.uint32(bytes);
3340
+ this._reserve(bytes);
3341
+ var p = this.pos, i, dv = getLazyView(this, n, VIEW_THRESHOLD_FLOAT);
3342
+ if (dv)
3343
+ for (i = 0; i < n; ++i) { dv.setFloat64(p, value[i], true); p += 8; }
3344
+ else {
3345
+ var buf = this.buf;
3346
+ for (i = 0; i < n; ++i) { util.float.writeDoubleLE(value[i], buf, p); p += 8; }
3347
+ }
3348
+ this.pos += bytes;
3349
+ return this;
2956
3350
  };
2957
3351
 
2958
3352
  /**
2959
3353
  * Forks this writer's state by pushing it to a stack.
2960
- * Calling {@link Writer#reset|reset} or {@link Writer#ldelim|ldelim} resets the writer to the previous state.
2961
3354
  * @returns {Writer} `this`
2962
3355
  */
2963
3356
  Writer.prototype.fork = function fork() {
2964
- this.states = new State(this);
2965
- this.head = this.tail = new Op(noop, 0, 0);
2966
- this.len = 0;
3357
+ this._reserve(1);
3358
+ (this.states || (this.states = [])).push(this.pos);
3359
+ this.pos += 1;
2967
3360
  return this;
2968
3361
  };
2969
3362
 
@@ -2972,47 +3365,66 @@ Writer.prototype.fork = function fork() {
2972
3365
  * @returns {Writer} `this`
2973
3366
  */
2974
3367
  Writer.prototype.reset = function reset() {
2975
- if (this.states) {
2976
- this.head = this.states.head;
2977
- this.tail = this.states.tail;
2978
- this.len = this.states.len;
2979
- this.states = this.states.next;
3368
+ var states = this.states;
3369
+ if (states && states.length) {
3370
+ this.pos = states.pop();
2980
3371
  } else {
2981
- this.head = this.tail = new Op(noop, 0, 0);
2982
- this.len = 0;
3372
+ this.pos = 0;
2983
3373
  }
2984
3374
  return this;
2985
3375
  };
2986
3376
 
2987
3377
  /**
2988
- * Resets to the last state and appends the fork state's current write length as a varint followed by its operations.
3378
+ * Resets to the last state and prepends the fork state's current write length as a varint.
2989
3379
  * @returns {Writer} `this`
2990
3380
  */
2991
3381
  Writer.prototype.ldelim = function ldelim() {
2992
- var head = this.head,
2993
- tail = this.tail,
2994
- len = this.len;
2995
- this.reset().uint32(len);
2996
- if (len) {
2997
- this.tail.next = head.next; // skip noop
2998
- this.tail = tail;
2999
- this.len += len;
3382
+ var states = this.states,
3383
+ len,
3384
+ vlen;
3385
+ if (states && states.length) {
3386
+ var lenPos = states.pop();
3387
+ len = this.pos - lenPos - 1;
3388
+ vlen = sizeVarint32(len);
3389
+ if (vlen > 1) { // grow the reserved single byte and shift content forward
3390
+ this._reserve(vlen - 1);
3391
+ this.buf.copyWithin(lenPos + vlen, lenPos + 1, lenPos + 1 + len);
3392
+ this.pos += vlen - 1;
3393
+ writeVarint32(len, this.buf, lenPos);
3394
+ } else {
3395
+ this.buf[lenPos] = len;
3396
+ }
3397
+ } else { // not forked: prefix the entire buffer with its length
3398
+ // TODO: Compatibility with older generated code.
3399
+ // Remove this branch in the next major release.
3400
+ len = this.pos;
3401
+ vlen = sizeVarint32(len);
3402
+ this._reserve(vlen);
3403
+ this.buf.copyWithin(vlen, 0, len);
3404
+ writeVarint32(len, this.buf, 0);
3405
+ this.pos += vlen;
3000
3406
  }
3001
3407
  return this;
3002
3408
  };
3003
3409
 
3004
3410
  /**
3005
3411
  * Finishes the write operation.
3412
+ * Returns a buffer sized to the written data by default.
3413
+ * @param {boolean} [shared=false] Whether to return a shared view instead of a unique copy
3006
3414
  * @returns {Uint8Array} Finished buffer
3007
3415
  */
3008
- Writer.prototype.finish = function finish() {
3009
- return this.finishInto(this.constructor.alloc(this.len), 0);
3416
+ Writer.prototype.finish = function finish(shared) {
3417
+ if (shared)
3418
+ return this.buf.subarray(0, this.pos);
3419
+ var buf = this.constructor.alloc(this.pos);
3420
+ buf.set(this.buf.subarray(0, this.pos), 0);
3421
+ return buf;
3010
3422
  };
3011
3423
 
3012
3424
  /**
3013
3425
  * Finishes the write operation, writing into the provided buffer.
3014
3426
  * The caller must ensure that `buf` has enough space starting at `offset`
3015
- * to hold {@link Writer#len} bytes.
3427
+ * to hold {@link Writer#pos} bytes.
3016
3428
  * @param {T} buf Target buffer
3017
3429
  * @param {number} [offset=0] Offset to start writing at
3018
3430
  * @returns {T} The provided buffer
@@ -3021,13 +3433,7 @@ Writer.prototype.finish = function finish() {
3021
3433
  Writer.prototype.finishInto = function finishInto(buf, offset) {
3022
3434
  if (offset === undefined)
3023
3435
  offset = 0;
3024
- var head = this.head.next,
3025
- pos = offset;
3026
- while (head) {
3027
- head.fn(head.val, buf, pos);
3028
- pos += head.len;
3029
- head = head.next;
3030
- }
3436
+ buf.set(this.buf.subarray(0, this.pos), offset);
3031
3437
  return buf;
3032
3438
  };
3033
3439
 
@@ -3064,6 +3470,8 @@ function BufferWriter() {
3064
3470
  Writer.call(this);
3065
3471
  }
3066
3472
 
3473
+ var writeStringBuffer;
3474
+
3067
3475
  BufferWriter._configure = function () {
3068
3476
  /**
3069
3477
  * Allocates a buffer of the specified size.
@@ -3071,19 +3479,14 @@ BufferWriter._configure = function () {
3071
3479
  * @param {number} size Buffer size
3072
3480
  * @returns {Buffer} Buffer
3073
3481
  */
3074
- BufferWriter.alloc = util._Buffer_allocUnsafe;
3482
+ BufferWriter.alloc = util.Buffer && util.Buffer.allocUnsafe;
3075
3483
 
3076
- BufferWriter.writeBytesBuffer = util.Buffer && util.Buffer.prototype instanceof Uint8Array && util.Buffer.prototype.set.name === "set"
3077
- ? function writeBytesBuffer_set(val, buf, pos) {
3078
- buf.set(val, pos); // faster than copy (requires node >= 4 where Buffers extend Uint8Array and set is properly inherited)
3079
- // also works for plain array values
3484
+ writeStringBuffer = util.Buffer && util.Buffer.prototype.utf8Write
3485
+ ? function writeStringBuffer_utf8Write(val, buf, pos) {
3486
+ return buf.utf8Write(val, pos);
3080
3487
  }
3081
- /* istanbul ignore next */
3082
- : function writeBytesBuffer_copy(val, buf, pos) {
3083
- if (val.copy) // Buffer values
3084
- val.copy(buf, pos, 0, val.length);
3085
- else for (var i = 0; i < val.length;) // plain array values
3086
- buf[pos++] = val[i++];
3488
+ : function writeStringBuffer_write(val, buf, pos) {
3489
+ return buf.write(val, pos);
3087
3490
  };
3088
3491
  };
3089
3492
 
@@ -3093,48 +3496,42 @@ BufferWriter._configure = function () {
3093
3496
  */
3094
3497
  BufferWriter.prototype.bytes = function write_bytes_buffer(value) {
3095
3498
  if (util.isString(value))
3096
- value = util._Buffer_from(value, "base64");
3499
+ value = util.Buffer.from(value, "base64");
3097
3500
  var len = value.length >>> 0;
3098
3501
  this.uint32(len);
3099
- if (len)
3100
- this._push(BufferWriter.writeBytesBuffer, len, value);
3502
+ if (len) {
3503
+ this._reserve(len);
3504
+ this.buf.set(value, this.pos);
3505
+ this.pos += len;
3506
+ }
3101
3507
  return this;
3102
3508
  };
3103
3509
 
3104
- /**
3105
- * Writes raw bytes without a tag or length prefix.
3106
- * @name BufferWriter#raw
3107
- * @function
3108
- * @param {Uint8Array} value Raw bytes
3109
- * @returns {BufferWriter} `this`
3110
- */
3111
- BufferWriter.prototype.raw = function write_raw_buffer(value) {
3112
- var len = value.length >>> 0;
3113
- return len ? this._push(BufferWriter.writeBytesBuffer, len, value) : this;
3114
- };
3115
-
3116
- function writeStringBufferAscii(val, buf, pos) {
3117
- for (var i = 0; i < val.length;)
3118
- buf[pos++] = val.charCodeAt(i++);
3119
- }
3120
-
3121
- function writeStringBuffer(val, buf, pos) {
3122
- if (val.length < 40) // plain js is faster for short strings (probably due to redundant assertions)
3123
- util.utf8.write(val, buf, pos);
3124
- else if (buf.utf8Write)
3125
- buf.utf8Write(val, pos);
3126
- else
3127
- buf.write(val, pos);
3128
- }
3129
-
3130
3510
  /**
3131
3511
  * @override
3132
3512
  */
3133
3513
  BufferWriter.prototype.string = function write_string_buffer(value) {
3514
+ var n = value.length;
3515
+ if (!n) {
3516
+ this._reserve(1);
3517
+ this.buf[this.pos++] = 0;
3518
+ return this;
3519
+ }
3520
+ if (n < 0x80) {
3521
+ this._reserve(n * 3 + 5); // worst case
3522
+ var pos = this.pos,
3523
+ buf = this.buf;
3524
+ return this._delim(pos,
3525
+ n < 40
3526
+ ? util.utf8.write(value, buf, pos + 1)
3527
+ : writeStringBuffer(value, buf, pos + 1)
3528
+ );
3529
+ }
3134
3530
  var len = util.Buffer.byteLength(value);
3135
3531
  this.uint32(len);
3136
- if (len)
3137
- this._push(len === value.length && len < 40 ? writeStringBufferAscii : writeStringBuffer, len, value);
3532
+ this._reserve(len);
3533
+ writeStringBuffer(value, this.buf, this.pos);
3534
+ this.pos += len;
3138
3535
  return this;
3139
3536
  };
3140
3537