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