1/// @file
2/// @addtogroup flatbuffers_javascript_api
3/// @{
4/// @cond FLATBUFFERS_INTERNAL
5
6/**
7 * @fileoverview
8 *
9 * Need to suppress 'global this' error so the Node.js export line doesn't cause
10 * closure compile to error out.
11 * @suppress {globalThis}
12 */
13
14/**
15 * @const
16 * @namespace
17 */
18var flatbuffers = {};
19
20/**
21 * @typedef {number}
22 */
23flatbuffers.Offset;
24
25/**
26 * @typedef {{
27 *   bb: flatbuffers.ByteBuffer,
28 *   bb_pos: number
29 * }}
30 */
31flatbuffers.Table;
32
33/**
34 * @type {number}
35 * @const
36 */
37flatbuffers.SIZEOF_SHORT = 2;
38
39/**
40 * @type {number}
41 * @const
42 */
43flatbuffers.SIZEOF_INT = 4;
44
45/**
46 * @type {number}
47 * @const
48 */
49flatbuffers.FILE_IDENTIFIER_LENGTH = 4;
50
51/**
52 * @enum {number}
53 */
54flatbuffers.Encoding = {
55  UTF8_BYTES: 1,
56  UTF16_STRING: 2
57};
58
59/**
60 * @type {Int32Array}
61 * @const
62 */
63flatbuffers.int32 = new Int32Array(2);
64
65/**
66 * @type {Float32Array}
67 * @const
68 */
69flatbuffers.float32 = new Float32Array(flatbuffers.int32.buffer);
70
71/**
72 * @type {Float64Array}
73 * @const
74 */
75flatbuffers.float64 = new Float64Array(flatbuffers.int32.buffer);
76
77/**
78 * @type {boolean}
79 * @const
80 */
81flatbuffers.isLittleEndian = new Uint16Array(new Uint8Array([1, 0]).buffer)[0] === 1;
82
83////////////////////////////////////////////////////////////////////////////////
84
85/**
86 * @constructor
87 * @param {number} low
88 * @param {number} high
89 */
90flatbuffers.Long = function(low, high) {
91  /**
92   * @type {number}
93   * @const
94   */
95  this.low = low | 0;
96
97  /**
98   * @type {number}
99   * @const
100   */
101  this.high = high | 0;
102};
103
104/**
105 * @param {number} low
106 * @param {number} high
107 * @returns {flatbuffers.Long}
108 */
109flatbuffers.Long.create = function(low, high) {
110  // Special-case zero to avoid GC overhead for default values
111  return low == 0 && high == 0 ? flatbuffers.Long.ZERO : new flatbuffers.Long(low, high);
112};
113
114/**
115 * @returns {number}
116 */
117flatbuffers.Long.prototype.toFloat64 = function() {
118  return (this.low >>> 0) + this.high * 0x100000000;
119};
120
121/**
122 * @param {flatbuffers.Long} other
123 * @returns {boolean}
124 */
125flatbuffers.Long.prototype.equals = function(other) {
126  return this.low == other.low && this.high == other.high;
127};
128
129/**
130 * @type {flatbuffers.Long}
131 * @const
132 */
133flatbuffers.Long.ZERO = new flatbuffers.Long(0, 0);
134
135/// @endcond
136////////////////////////////////////////////////////////////////////////////////
137/**
138 * Create a FlatBufferBuilder.
139 *
140 * @constructor
141 * @param {number=} opt_initial_size
142 */
143flatbuffers.Builder = function(opt_initial_size) {
144  if (!opt_initial_size) {
145    var initial_size = 1024;
146  } else {
147    var initial_size = opt_initial_size;
148  }
149
150  /**
151   * @type {flatbuffers.ByteBuffer}
152   * @private
153   */
154  this.bb = flatbuffers.ByteBuffer.allocate(initial_size);
155
156  /**
157   * Remaining space in the ByteBuffer.
158   *
159   * @type {number}
160   * @private
161   */
162  this.space = initial_size;
163
164  /**
165   * Minimum alignment encountered so far.
166   *
167   * @type {number}
168   * @private
169   */
170  this.minalign = 1;
171
172  /**
173   * The vtable for the current table.
174   *
175   * @type {Array.<number>}
176   * @private
177   */
178  this.vtable = null;
179
180  /**
181   * The amount of fields we're actually using.
182   *
183   * @type {number}
184   * @private
185   */
186  this.vtable_in_use = 0;
187
188  /**
189   * Whether we are currently serializing a table.
190   *
191   * @type {boolean}
192   * @private
193   */
194  this.isNested = false;
195
196  /**
197   * Starting offset of the current struct/table.
198   *
199   * @type {number}
200   * @private
201   */
202  this.object_start = 0;
203
204  /**
205   * List of offsets of all vtables.
206   *
207   * @type {Array.<number>}
208   * @private
209   */
210  this.vtables = [];
211
212  /**
213   * For the current vector being built.
214   *
215   * @type {number}
216   * @private
217   */
218  this.vector_num_elems = 0;
219
220  /**
221   * False omits default values from the serialized data
222   *
223   * @type {boolean}
224   * @private
225   */
226  this.force_defaults = false;
227};
228
229/**
230 * In order to save space, fields that are set to their default value
231 * don't get serialized into the buffer. Forcing defaults provides a
232 * way to manually disable this optimization.
233 *
234 * @param {boolean} forceDefaults true always serializes default values
235 */
236flatbuffers.Builder.prototype.forceDefaults = function(forceDefaults) {
237  this.force_defaults = forceDefaults;
238};
239
240/**
241 * Get the ByteBuffer representing the FlatBuffer. Only call this after you've
242 * called finish(). The actual data starts at the ByteBuffer's current position,
243 * not necessarily at 0.
244 *
245 * @returns {flatbuffers.ByteBuffer}
246 */
247flatbuffers.Builder.prototype.dataBuffer = function() {
248  return this.bb;
249};
250
251/**
252 * Get the bytes representing the FlatBuffer. Only call this after you've
253 * called finish().
254 *
255 * @returns {Uint8Array}
256 */
257flatbuffers.Builder.prototype.asUint8Array = function() {
258  return this.bb.bytes().subarray(this.bb.position(), this.bb.position() + this.offset());
259};
260
261/// @cond FLATBUFFERS_INTERNAL
262/**
263 * Prepare to write an element of `size` after `additional_bytes` have been
264 * written, e.g. if you write a string, you need to align such the int length
265 * field is aligned to 4 bytes, and the string data follows it directly. If all
266 * you need to do is alignment, `additional_bytes` will be 0.
267 *
268 * @param {number} size This is the of the new element to write
269 * @param {number} additional_bytes The padding size
270 */
271flatbuffers.Builder.prototype.prep = function(size, additional_bytes) {
272  // Track the biggest thing we've ever aligned to.
273  if (size > this.minalign) {
274    this.minalign = size;
275  }
276
277  // Find the amount of alignment needed such that `size` is properly
278  // aligned after `additional_bytes`
279  var align_size = ((~(this.bb.capacity() - this.space + additional_bytes)) + 1) & (size - 1);
280
281  // Reallocate the buffer if needed.
282  while (this.space < align_size + size + additional_bytes) {
283    var old_buf_size = this.bb.capacity();
284    this.bb = flatbuffers.Builder.growByteBuffer(this.bb);
285    this.space += this.bb.capacity() - old_buf_size;
286  }
287
288  this.pad(align_size);
289};
290
291/**
292 * @param {number} byte_size
293 */
294flatbuffers.Builder.prototype.pad = function(byte_size) {
295  for (var i = 0; i < byte_size; i++) {
296    this.bb.writeInt8(--this.space, 0);
297  }
298};
299
300/**
301 * @param {number} value
302 */
303flatbuffers.Builder.prototype.writeInt8 = function(value) {
304  this.bb.writeInt8(this.space -= 1, value);
305};
306
307/**
308 * @param {number} value
309 */
310flatbuffers.Builder.prototype.writeInt16 = function(value) {
311  this.bb.writeInt16(this.space -= 2, value);
312};
313
314/**
315 * @param {number} value
316 */
317flatbuffers.Builder.prototype.writeInt32 = function(value) {
318  this.bb.writeInt32(this.space -= 4, value);
319};
320
321/**
322 * @param {flatbuffers.Long} value
323 */
324flatbuffers.Builder.prototype.writeInt64 = function(value) {
325  this.bb.writeInt64(this.space -= 8, value);
326};
327
328/**
329 * @param {number} value
330 */
331flatbuffers.Builder.prototype.writeFloat32 = function(value) {
332  this.bb.writeFloat32(this.space -= 4, value);
333};
334
335/**
336 * @param {number} value
337 */
338flatbuffers.Builder.prototype.writeFloat64 = function(value) {
339  this.bb.writeFloat64(this.space -= 8, value);
340};
341/// @endcond
342
343/**
344 * Add an `int8` to the buffer, properly aligned, and grows the buffer (if necessary).
345 * @param {number} value The `int8` to add the the buffer.
346 */
347flatbuffers.Builder.prototype.addInt8 = function(value) {
348  this.prep(1, 0);
349  this.writeInt8(value);
350};
351
352/**
353 * Add an `int16` to the buffer, properly aligned, and grows the buffer (if necessary).
354 * @param {number} value The `int16` to add the the buffer.
355 */
356flatbuffers.Builder.prototype.addInt16 = function(value) {
357  this.prep(2, 0);
358  this.writeInt16(value);
359};
360
361/**
362 * Add an `int32` to the buffer, properly aligned, and grows the buffer (if necessary).
363 * @param {number} value The `int32` to add the the buffer.
364 */
365flatbuffers.Builder.prototype.addInt32 = function(value) {
366  this.prep(4, 0);
367  this.writeInt32(value);
368};
369
370/**
371 * Add an `int64` to the buffer, properly aligned, and grows the buffer (if necessary).
372 * @param {flatbuffers.Long} value The `int64` to add the the buffer.
373 */
374flatbuffers.Builder.prototype.addInt64 = function(value) {
375  this.prep(8, 0);
376  this.writeInt64(value);
377};
378
379/**
380 * Add a `float32` to the buffer, properly aligned, and grows the buffer (if necessary).
381 * @param {number} value The `float32` to add the the buffer.
382 */
383flatbuffers.Builder.prototype.addFloat32 = function(value) {
384  this.prep(4, 0);
385  this.writeFloat32(value);
386};
387
388/**
389 * Add a `float64` to the buffer, properly aligned, and grows the buffer (if necessary).
390 * @param {number} value The `float64` to add the the buffer.
391 */
392flatbuffers.Builder.prototype.addFloat64 = function(value) {
393  this.prep(8, 0);
394  this.writeFloat64(value);
395};
396
397/// @cond FLATBUFFERS_INTERNAL
398/**
399 * @param {number} voffset
400 * @param {number} value
401 * @param {number} defaultValue
402 */
403flatbuffers.Builder.prototype.addFieldInt8 = function(voffset, value, defaultValue) {
404  if (this.force_defaults || value != defaultValue) {
405    this.addInt8(value);
406    this.slot(voffset);
407  }
408};
409
410/**
411 * @param {number} voffset
412 * @param {number} value
413 * @param {number} defaultValue
414 */
415flatbuffers.Builder.prototype.addFieldInt16 = function(voffset, value, defaultValue) {
416  if (this.force_defaults || value != defaultValue) {
417    this.addInt16(value);
418    this.slot(voffset);
419  }
420};
421
422/**
423 * @param {number} voffset
424 * @param {number} value
425 * @param {number} defaultValue
426 */
427flatbuffers.Builder.prototype.addFieldInt32 = function(voffset, value, defaultValue) {
428  if (this.force_defaults || value != defaultValue) {
429    this.addInt32(value);
430    this.slot(voffset);
431  }
432};
433
434/**
435 * @param {number} voffset
436 * @param {flatbuffers.Long} value
437 * @param {flatbuffers.Long} defaultValue
438 */
439flatbuffers.Builder.prototype.addFieldInt64 = function(voffset, value, defaultValue) {
440  if (this.force_defaults || !value.equals(defaultValue)) {
441    this.addInt64(value);
442    this.slot(voffset);
443  }
444};
445
446/**
447 * @param {number} voffset
448 * @param {number} value
449 * @param {number} defaultValue
450 */
451flatbuffers.Builder.prototype.addFieldFloat32 = function(voffset, value, defaultValue) {
452  if (this.force_defaults || value != defaultValue) {
453    this.addFloat32(value);
454    this.slot(voffset);
455  }
456};
457
458/**
459 * @param {number} voffset
460 * @param {number} value
461 * @param {number} defaultValue
462 */
463flatbuffers.Builder.prototype.addFieldFloat64 = function(voffset, value, defaultValue) {
464  if (this.force_defaults || value != defaultValue) {
465    this.addFloat64(value);
466    this.slot(voffset);
467  }
468};
469
470/**
471 * @param {number} voffset
472 * @param {flatbuffers.Offset} value
473 * @param {flatbuffers.Offset} defaultValue
474 */
475flatbuffers.Builder.prototype.addFieldOffset = function(voffset, value, defaultValue) {
476  if (this.force_defaults || value != defaultValue) {
477    this.addOffset(value);
478    this.slot(voffset);
479  }
480};
481
482/**
483 * Structs are stored inline, so nothing additional is being added. `d` is always 0.
484 *
485 * @param {number} voffset
486 * @param {flatbuffers.Offset} value
487 * @param {flatbuffers.Offset} defaultValue
488 */
489flatbuffers.Builder.prototype.addFieldStruct = function(voffset, value, defaultValue) {
490  if (value != defaultValue) {
491    this.nested(value);
492    this.slot(voffset);
493  }
494};
495
496/**
497 * Structures are always stored inline, they need to be created right
498 * where they're used.  You'll get this assertion failure if you
499 * created it elsewhere.
500 *
501 * @param {flatbuffers.Offset} obj The offset of the created object
502 */
503flatbuffers.Builder.prototype.nested = function(obj) {
504  if (obj != this.offset()) {
505    throw new Error('FlatBuffers: struct must be serialized inline.');
506  }
507};
508
509/**
510 * Should not be creating any other object, string or vector
511 * while an object is being constructed
512 */
513flatbuffers.Builder.prototype.notNested = function() {
514  if (this.isNested) {
515    throw new Error('FlatBuffers: object serialization must not be nested.');
516  }
517};
518
519/**
520 * Set the current vtable at `voffset` to the current location in the buffer.
521 *
522 * @param {number} voffset
523 */
524flatbuffers.Builder.prototype.slot = function(voffset) {
525  this.vtable[voffset] = this.offset();
526};
527
528/**
529 * @returns {flatbuffers.Offset} Offset relative to the end of the buffer.
530 */
531flatbuffers.Builder.prototype.offset = function() {
532  return this.bb.capacity() - this.space;
533};
534
535/**
536 * Doubles the size of the backing ByteBuffer and copies the old data towards
537 * the end of the new buffer (since we build the buffer backwards).
538 *
539 * @param {flatbuffers.ByteBuffer} bb The current buffer with the existing data
540 * @returns {flatbuffers.ByteBuffer} A new byte buffer with the old data copied
541 * to it. The data is located at the end of the buffer.
542 *
543 * uint8Array.set() formally takes {Array<number>|ArrayBufferView}, so to pass
544 * it a uint8Array we need to suppress the type check:
545 * @suppress {checkTypes}
546 */
547flatbuffers.Builder.growByteBuffer = function(bb) {
548  var old_buf_size = bb.capacity();
549
550  // Ensure we don't grow beyond what fits in an int.
551  if (old_buf_size & 0xC0000000) {
552    throw new Error('FlatBuffers: cannot grow buffer beyond 2 gigabytes.');
553  }
554
555  var new_buf_size = old_buf_size << 1;
556  var nbb = flatbuffers.ByteBuffer.allocate(new_buf_size);
557  nbb.setPosition(new_buf_size - old_buf_size);
558  nbb.bytes().set(bb.bytes(), new_buf_size - old_buf_size);
559  return nbb;
560};
561/// @endcond
562
563/**
564 * Adds on offset, relative to where it will be written.
565 *
566 * @param {flatbuffers.Offset} offset The offset to add.
567 */
568flatbuffers.Builder.prototype.addOffset = function(offset) {
569  this.prep(flatbuffers.SIZEOF_INT, 0); // Ensure alignment is already done.
570  this.writeInt32(this.offset() - offset + flatbuffers.SIZEOF_INT);
571};
572
573/// @cond FLATBUFFERS_INTERNAL
574/**
575 * Start encoding a new object in the buffer.  Users will not usually need to
576 * call this directly. The FlatBuffers compiler will generate helper methods
577 * that call this method internally.
578 *
579 * @param {number} numfields
580 */
581flatbuffers.Builder.prototype.startObject = function(numfields) {
582  this.notNested();
583  if (this.vtable == null) {
584    this.vtable = [];
585  }
586  this.vtable_in_use = numfields;
587  for (var i = 0; i < numfields; i++) {
588    this.vtable[i] = 0; // This will push additional elements as needed
589  }
590  this.isNested = true;
591  this.object_start = this.offset();
592};
593
594/**
595 * Finish off writing the object that is under construction.
596 *
597 * @returns {flatbuffers.Offset} The offset to the object inside `dataBuffer`
598 */
599flatbuffers.Builder.prototype.endObject = function() {
600  if (this.vtable == null || !this.isNested) {
601    throw new Error('FlatBuffers: endObject called without startObject');
602  }
603
604  this.addInt32(0);
605  var vtableloc = this.offset();
606
607  // Trim trailing zeroes.
608  var i = this.vtable_in_use - 1;
609  for (; i >= 0 && this.vtable[i] == 0; i--) {}
610  var trimmed_size = i + 1;
611
612  // Write out the current vtable.
613  for (; i >= 0; i--) {
614    // Offset relative to the start of the table.
615    this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0);
616  }
617
618  var standard_fields = 2; // The fields below:
619  this.addInt16(vtableloc - this.object_start);
620  var len = (trimmed_size + standard_fields) * flatbuffers.SIZEOF_SHORT;
621  this.addInt16(len);
622
623  // Search for an existing vtable that matches the current one.
624  var existing_vtable = 0;
625  var vt1 = this.space;
626outer_loop:
627  for (i = 0; i < this.vtables.length; i++) {
628    var vt2 = this.bb.capacity() - this.vtables[i];
629    if (len == this.bb.readInt16(vt2)) {
630      for (var j = flatbuffers.SIZEOF_SHORT; j < len; j += flatbuffers.SIZEOF_SHORT) {
631        if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) {
632          continue outer_loop;
633        }
634      }
635      existing_vtable = this.vtables[i];
636      break;
637    }
638  }
639
640  if (existing_vtable) {
641    // Found a match:
642    // Remove the current vtable.
643    this.space = this.bb.capacity() - vtableloc;
644
645    // Point table to existing vtable.
646    this.bb.writeInt32(this.space, existing_vtable - vtableloc);
647  } else {
648    // No match:
649    // Add the location of the current vtable to the list of vtables.
650    this.vtables.push(this.offset());
651
652    // Point table to current vtable.
653    this.bb.writeInt32(this.bb.capacity() - vtableloc, this.offset() - vtableloc);
654  }
655
656  this.isNested = false;
657  return vtableloc;
658};
659/// @endcond
660
661/**
662 * Finalize a buffer, poiting to the given `root_table`.
663 *
664 * @param {flatbuffers.Offset} root_table
665 * @param {string=} opt_file_identifier
666 */
667flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier) {
668  if (opt_file_identifier) {
669    var file_identifier = opt_file_identifier;
670    this.prep(this.minalign, flatbuffers.SIZEOF_INT +
671      flatbuffers.FILE_IDENTIFIER_LENGTH);
672    if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
673      throw new Error('FlatBuffers: file identifier must be length ' +
674        flatbuffers.FILE_IDENTIFIER_LENGTH);
675    }
676    for (var i = flatbuffers.FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) {
677      this.writeInt8(file_identifier.charCodeAt(i));
678    }
679  }
680  this.prep(this.minalign, flatbuffers.SIZEOF_INT);
681  this.addOffset(root_table);
682  this.bb.setPosition(this.space);
683};
684
685/// @cond FLATBUFFERS_INTERNAL
686/**
687 * This checks a required field has been set in a given table that has
688 * just been constructed.
689 *
690 * @param {flatbuffers.Offset} table
691 * @param {number} field
692 */
693flatbuffers.Builder.prototype.requiredField = function(table, field) {
694  var table_start = this.bb.capacity() - table;
695  var vtable_start = table_start - this.bb.readInt32(table_start);
696  var ok = this.bb.readInt16(vtable_start + field) != 0;
697
698  // If this fails, the caller will show what field needs to be set.
699  if (!ok) {
700    throw new Error('FlatBuffers: field ' + field + ' must be set');
701  }
702};
703
704/**
705 * Start a new array/vector of objects.  Users usually will not call
706 * this directly. The FlatBuffers compiler will create a start/end
707 * method for vector types in generated code.
708 *
709 * @param {number} elem_size The size of each element in the array
710 * @param {number} num_elems The number of elements in the array
711 * @param {number} alignment The alignment of the array
712 */
713flatbuffers.Builder.prototype.startVector = function(elem_size, num_elems, alignment) {
714  this.notNested();
715  this.vector_num_elems = num_elems;
716  this.prep(flatbuffers.SIZEOF_INT, elem_size * num_elems);
717  this.prep(alignment, elem_size * num_elems); // Just in case alignment > int.
718};
719
720/**
721 * Finish off the creation of an array and all its elements. The array must be
722 * created with `startVector`.
723 *
724 * @returns {flatbuffers.Offset} The offset at which the newly created array
725 * starts.
726 */
727flatbuffers.Builder.prototype.endVector = function() {
728  this.writeInt32(this.vector_num_elems);
729  return this.offset();
730};
731/// @endcond
732
733/**
734 * Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed
735 * instead of a string, it is assumed to contain valid UTF-8 encoded data.
736 *
737 * @param {string|Uint8Array} s The string to encode
738 * @return {flatbuffers.Offset} The offset in the buffer where the encoded string starts
739 */
740flatbuffers.Builder.prototype.createString = function(s) {
741  if (s instanceof Uint8Array) {
742    var utf8 = s;
743  } else {
744    var utf8 = [];
745    var i = 0;
746
747    while (i < s.length) {
748      var codePoint;
749
750      // Decode UTF-16
751      var a = s.charCodeAt(i++);
752      if (a < 0xD800 || a >= 0xDC00) {
753        codePoint = a;
754      } else {
755        var b = s.charCodeAt(i++);
756        codePoint = (a << 10) + b + (0x10000 - (0xD800 << 10) - 0xDC00);
757      }
758
759      // Encode UTF-8
760      if (codePoint < 0x80) {
761        utf8.push(codePoint);
762      } else {
763        if (codePoint < 0x800) {
764          utf8.push(((codePoint >> 6) & 0x1F) | 0xC0);
765        } else {
766          if (codePoint < 0x10000) {
767            utf8.push(((codePoint >> 12) & 0x0F) | 0xE0);
768          } else {
769            utf8.push(
770              ((codePoint >> 18) & 0x07) | 0xF0,
771              ((codePoint >> 12) & 0x3F) | 0x80);
772          }
773          utf8.push(((codePoint >> 6) & 0x3F) | 0x80);
774        }
775        utf8.push((codePoint & 0x3F) | 0x80);
776      }
777    }
778  }
779
780  this.addInt8(0);
781  this.startVector(1, utf8.length, 1);
782  this.bb.setPosition(this.space -= utf8.length);
783  for (var i = 0, offset = this.space, bytes = this.bb.bytes(); i < utf8.length; i++) {
784    bytes[offset++] = utf8[i];
785  }
786  return this.endVector();
787};
788
789/**
790 * A helper function to avoid generated code depending on this file directly.
791 *
792 * @param {number} low
793 * @param {number} high
794 * @returns {flatbuffers.Long}
795 */
796flatbuffers.Builder.prototype.createLong = function(low, high) {
797  return flatbuffers.Long.create(low, high);
798};
799////////////////////////////////////////////////////////////////////////////////
800/// @cond FLATBUFFERS_INTERNAL
801/**
802 * Create a new ByteBuffer with a given array of bytes (`Uint8Array`).
803 *
804 * @constructor
805 * @param {Uint8Array} bytes
806 */
807flatbuffers.ByteBuffer = function(bytes) {
808  /**
809   * @type {Uint8Array}
810   * @private
811   */
812  this.bytes_ = bytes;
813
814  /**
815   * @type {number}
816   * @private
817   */
818  this.position_ = 0;
819};
820
821/**
822 * Create and allocate a new ByteBuffer with a given size.
823 *
824 * @param {number} byte_size
825 * @returns {flatbuffers.ByteBuffer}
826 */
827flatbuffers.ByteBuffer.allocate = function(byte_size) {
828  return new flatbuffers.ByteBuffer(new Uint8Array(byte_size));
829};
830
831/**
832 * Get the underlying `Uint8Array`.
833 *
834 * @returns {Uint8Array}
835 */
836flatbuffers.ByteBuffer.prototype.bytes = function() {
837  return this.bytes_;
838};
839
840/**
841 * Get the buffer's position.
842 *
843 * @returns {number}
844 */
845flatbuffers.ByteBuffer.prototype.position = function() {
846  return this.position_;
847};
848
849/**
850 * Set the buffer's position.
851 *
852 * @param {number} position
853 */
854flatbuffers.ByteBuffer.prototype.setPosition = function(position) {
855  this.position_ = position;
856};
857
858/**
859 * Get the buffer's capacity.
860 *
861 * @returns {number}
862 */
863flatbuffers.ByteBuffer.prototype.capacity = function() {
864  return this.bytes_.length;
865};
866
867/**
868 * @param {number} offset
869 * @returns {number}
870 */
871flatbuffers.ByteBuffer.prototype.readInt8 = function(offset) {
872  return this.readUint8(offset) << 24 >> 24;
873};
874
875/**
876 * @param {number} offset
877 * @returns {number}
878 */
879flatbuffers.ByteBuffer.prototype.readUint8 = function(offset) {
880  return this.bytes_[offset];
881};
882
883/**
884 * @param {number} offset
885 * @returns {number}
886 */
887flatbuffers.ByteBuffer.prototype.readInt16 = function(offset) {
888  return this.readUint16(offset) << 16 >> 16;
889};
890
891/**
892 * @param {number} offset
893 * @returns {number}
894 */
895flatbuffers.ByteBuffer.prototype.readUint16 = function(offset) {
896  return this.bytes_[offset] | this.bytes_[offset + 1] << 8;
897};
898
899/**
900 * @param {number} offset
901 * @returns {number}
902 */
903flatbuffers.ByteBuffer.prototype.readInt32 = function(offset) {
904  return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24;
905};
906
907/**
908 * @param {number} offset
909 * @returns {number}
910 */
911flatbuffers.ByteBuffer.prototype.readUint32 = function(offset) {
912  return this.readInt32(offset) >>> 0;
913};
914
915/**
916 * @param {number} offset
917 * @returns {flatbuffers.Long}
918 */
919flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) {
920  return new flatbuffers.Long(this.readInt32(offset), this.readInt32(offset + 4));
921};
922
923/**
924 * @param {number} offset
925 * @returns {flatbuffers.Long}
926 */
927flatbuffers.ByteBuffer.prototype.readUint64 = function(offset) {
928  return new flatbuffers.Long(this.readUint32(offset), this.readUint32(offset + 4));
929};
930
931/**
932 * @param {number} offset
933 * @returns {number}
934 */
935flatbuffers.ByteBuffer.prototype.readFloat32 = function(offset) {
936  flatbuffers.int32[0] = this.readInt32(offset);
937  return flatbuffers.float32[0];
938};
939
940/**
941 * @param {number} offset
942 * @returns {number}
943 */
944flatbuffers.ByteBuffer.prototype.readFloat64 = function(offset) {
945  flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1] = this.readInt32(offset);
946  flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0] = this.readInt32(offset + 4);
947  return flatbuffers.float64[0];
948};
949
950/**
951 * @param {number} offset
952 * @param {number|boolean} value
953 */
954flatbuffers.ByteBuffer.prototype.writeInt8 = function(offset, value) {
955  this.bytes_[offset] = /** @type {number} */(value);
956};
957
958/**
959 * @param {number} offset
960 * @param {number} value
961 */
962flatbuffers.ByteBuffer.prototype.writeUint8 = function(offset, value) {
963  this.bytes_[offset] = value;
964};
965
966/**
967 * @param {number} offset
968 * @param {number} value
969 */
970flatbuffers.ByteBuffer.prototype.writeInt16 = function(offset, value) {
971  this.bytes_[offset] = value;
972  this.bytes_[offset + 1] = value >> 8;
973};
974
975/**
976 * @param {number} offset
977 * @param {number} value
978 */
979flatbuffers.ByteBuffer.prototype.writeUint16 = function(offset, value) {
980    this.bytes_[offset] = value;
981    this.bytes_[offset + 1] = value >> 8;
982};
983
984/**
985 * @param {number} offset
986 * @param {number} value
987 */
988flatbuffers.ByteBuffer.prototype.writeInt32 = function(offset, value) {
989  this.bytes_[offset] = value;
990  this.bytes_[offset + 1] = value >> 8;
991  this.bytes_[offset + 2] = value >> 16;
992  this.bytes_[offset + 3] = value >> 24;
993};
994
995/**
996 * @param {number} offset
997 * @param {number} value
998 */
999flatbuffers.ByteBuffer.prototype.writeUint32 = function(offset, value) {
1000    this.bytes_[offset] = value;
1001    this.bytes_[offset + 1] = value >> 8;
1002    this.bytes_[offset + 2] = value >> 16;
1003    this.bytes_[offset + 3] = value >> 24;
1004};
1005
1006/**
1007 * @param {number} offset
1008 * @param {flatbuffers.Long} value
1009 */
1010flatbuffers.ByteBuffer.prototype.writeInt64 = function(offset, value) {
1011  this.writeInt32(offset, value.low);
1012  this.writeInt32(offset + 4, value.high);
1013};
1014
1015/**
1016 * @param {number} offset
1017 * @param {flatbuffers.Long} value
1018 */
1019flatbuffers.ByteBuffer.prototype.writeUint64 = function(offset, value) {
1020    this.writeUint32(offset, value.low);
1021    this.writeUint32(offset + 4, value.high);
1022};
1023
1024/**
1025 * @param {number} offset
1026 * @param {number} value
1027 */
1028flatbuffers.ByteBuffer.prototype.writeFloat32 = function(offset, value) {
1029  flatbuffers.float32[0] = value;
1030  this.writeInt32(offset, flatbuffers.int32[0]);
1031};
1032
1033/**
1034 * @param {number} offset
1035 * @param {number} value
1036 */
1037flatbuffers.ByteBuffer.prototype.writeFloat64 = function(offset, value) {
1038  flatbuffers.float64[0] = value;
1039  this.writeInt32(offset, flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1]);
1040  this.writeInt32(offset + 4, flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0]);
1041};
1042
1043/**
1044 * Look up a field in the vtable, return an offset into the object, or 0 if the
1045 * field is not present.
1046 *
1047 * @param {number} bb_pos
1048 * @param {number} vtable_offset
1049 * @returns {number}
1050 */
1051flatbuffers.ByteBuffer.prototype.__offset = function(bb_pos, vtable_offset) {
1052  var vtable = bb_pos - this.readInt32(bb_pos);
1053  return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0;
1054};
1055
1056/**
1057 * Initialize any Table-derived type to point to the union at the given offset.
1058 *
1059 * @param {flatbuffers.Table} t
1060 * @param {number} offset
1061 * @returns {flatbuffers.Table}
1062 */
1063flatbuffers.ByteBuffer.prototype.__union = function(t, offset) {
1064  t.bb_pos = offset + this.readInt32(offset);
1065  t.bb = this;
1066  return t;
1067};
1068
1069/**
1070 * Create a JavaScript string from UTF-8 data stored inside the FlatBuffer.
1071 * This allocates a new string and converts to wide chars upon each access.
1072 *
1073 * To avoid the conversion to UTF-16, pass flatbuffers.Encoding.UTF8_BYTES as
1074 * the "optionalEncoding" argument. This is useful for avoiding conversion to
1075 * and from UTF-16 when the data will just be packaged back up in another
1076 * FlatBuffer later on.
1077 *
1078 * @param {number} offset
1079 * @param {flatbuffers.Encoding=} opt_encoding Defaults to UTF16_STRING
1080 * @returns {string|Uint8Array}
1081 */
1082flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) {
1083  offset += this.readInt32(offset);
1084
1085  var length = this.readInt32(offset);
1086  var result = '';
1087  var i = 0;
1088
1089  offset += flatbuffers.SIZEOF_INT;
1090
1091  if (opt_encoding === flatbuffers.Encoding.UTF8_BYTES) {
1092    return this.bytes_.subarray(offset, offset + length);
1093  }
1094
1095  while (i < length) {
1096    var codePoint;
1097
1098    // Decode UTF-8
1099    var a = this.readUint8(offset + i++);
1100    if (a < 0xC0) {
1101      codePoint = a;
1102    } else {
1103      var b = this.readUint8(offset + i++);
1104      if (a < 0xE0) {
1105        codePoint =
1106          ((a & 0x1F) << 6) |
1107          (b & 0x3F);
1108      } else {
1109        var c = this.readUint8(offset + i++);
1110        if (a < 0xF0) {
1111          codePoint =
1112            ((a & 0x0F) << 12) |
1113            ((b & 0x3F) << 6) |
1114            (c & 0x3F);
1115        } else {
1116          var d = this.readUint8(offset + i++);
1117          codePoint =
1118            ((a & 0x07) << 18) |
1119            ((b & 0x3F) << 12) |
1120            ((c & 0x3F) << 6) |
1121            (d & 0x3F);
1122        }
1123      }
1124    }
1125
1126    // Encode UTF-16
1127    if (codePoint < 0x10000) {
1128      result += String.fromCharCode(codePoint);
1129    } else {
1130      codePoint -= 0x10000;
1131      result += String.fromCharCode(
1132        (codePoint >> 10) + 0xD800,
1133        (codePoint & ((1 << 10) - 1)) + 0xDC00);
1134    }
1135  }
1136
1137  return result;
1138};
1139
1140/**
1141 * Retrieve the relative offset stored at "offset"
1142 * @param {number} offset
1143 * @returns {number}
1144 */
1145flatbuffers.ByteBuffer.prototype.__indirect = function(offset) {
1146  return offset + this.readInt32(offset);
1147};
1148
1149/**
1150 * Get the start of data of a vector whose offset is stored at "offset" in this object.
1151 *
1152 * @param {number} offset
1153 * @returns {number}
1154 */
1155flatbuffers.ByteBuffer.prototype.__vector = function(offset) {
1156  return offset + this.readInt32(offset) + flatbuffers.SIZEOF_INT; // data starts after the length
1157};
1158
1159/**
1160 * Get the length of a vector whose offset is stored at "offset" in this object.
1161 *
1162 * @param {number} offset
1163 * @returns {number}
1164 */
1165flatbuffers.ByteBuffer.prototype.__vector_len = function(offset) {
1166  return this.readInt32(offset + this.readInt32(offset));
1167};
1168
1169/**
1170 * @param {string} ident
1171 * @returns {boolean}
1172 */
1173flatbuffers.ByteBuffer.prototype.__has_identifier = function(ident) {
1174  if (ident.length != flatbuffers.FILE_IDENTIFIER_LENGTH) {
1175    throw new Error('FlatBuffers: file identifier must be length ' +
1176                    flatbuffers.FILE_IDENTIFIER_LENGTH);
1177  }
1178  for (var i = 0; i < flatbuffers.FILE_IDENTIFIER_LENGTH; i++) {
1179    if (ident.charCodeAt(i) != this.readInt8(this.position_ + flatbuffers.SIZEOF_INT + i)) {
1180      return false;
1181    }
1182  }
1183  return true;
1184};
1185
1186/**
1187 * A helper function to avoid generated code depending on this file directly.
1188 *
1189 * @param {number} low
1190 * @param {number} high
1191 * @returns {flatbuffers.Long}
1192 */
1193flatbuffers.ByteBuffer.prototype.createLong = function(low, high) {
1194  return flatbuffers.Long.create(low, high);
1195};
1196
1197// Exports for Node.js and RequireJS
1198this.flatbuffers = flatbuffers;
1199
1200/// @endcond
1201/// @}
1202