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 + 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 // Write out the current vtable. 608 for (var i = this.vtable_in_use - 1; i >= 0; i--) { 609 // Offset relative to the start of the table. 610 this.addInt16(this.vtable[i] != 0 ? vtableloc - this.vtable[i] : 0); 611 } 612 613 var standard_fields = 2; // The fields below: 614 this.addInt16(vtableloc - this.object_start); 615 this.addInt16((this.vtable_in_use + standard_fields) * flatbuffers.SIZEOF_SHORT); 616 617 // Search for an existing vtable that matches the current one. 618 var existing_vtable = 0; 619outer_loop: 620 for (var i = 0; i < this.vtables.length; i++) { 621 var vt1 = this.bb.capacity() - this.vtables[i]; 622 var vt2 = this.space; 623 var len = this.bb.readInt16(vt1); 624 if (len == this.bb.readInt16(vt2)) { 625 for (var j = flatbuffers.SIZEOF_SHORT; j < len; j += flatbuffers.SIZEOF_SHORT) { 626 if (this.bb.readInt16(vt1 + j) != this.bb.readInt16(vt2 + j)) { 627 continue outer_loop; 628 } 629 } 630 existing_vtable = this.vtables[i]; 631 break; 632 } 633 } 634 635 if (existing_vtable) { 636 // Found a match: 637 // Remove the current vtable. 638 this.space = this.bb.capacity() - vtableloc; 639 640 // Point table to existing vtable. 641 this.bb.writeInt32(this.space, existing_vtable - vtableloc); 642 } else { 643 // No match: 644 // Add the location of the current vtable to the list of vtables. 645 this.vtables.push(this.offset()); 646 647 // Point table to current vtable. 648 this.bb.writeInt32(this.bb.capacity() - vtableloc, this.offset() - vtableloc); 649 } 650 651 this.isNested = false; 652 return vtableloc; 653}; 654/// @endcond 655 656/** 657 * Finalize a buffer, poiting to the given `root_table`. 658 * 659 * @param {flatbuffers.Offset} root_table 660 * @param {string=} opt_file_identifier 661 */ 662flatbuffers.Builder.prototype.finish = function(root_table, opt_file_identifier) { 663 if (opt_file_identifier) { 664 var file_identifier = opt_file_identifier; 665 this.prep(this.minalign, flatbuffers.SIZEOF_INT + 666 flatbuffers.FILE_IDENTIFIER_LENGTH); 667 if (file_identifier.length != flatbuffers.FILE_IDENTIFIER_LENGTH) { 668 throw new Error('FlatBuffers: file identifier must be length ' + 669 flatbuffers.FILE_IDENTIFIER_LENGTH); 670 } 671 for (var i = flatbuffers.FILE_IDENTIFIER_LENGTH - 1; i >= 0; i--) { 672 this.writeInt8(file_identifier.charCodeAt(i)); 673 } 674 } 675 this.prep(this.minalign, flatbuffers.SIZEOF_INT); 676 this.addOffset(root_table); 677 this.bb.setPosition(this.space); 678}; 679 680/// @cond FLATBUFFERS_INTERNAL 681/** 682 * This checks a required field has been set in a given table that has 683 * just been constructed. 684 * 685 * @param {flatbuffers.Offset} table 686 * @param {number} field 687 */ 688flatbuffers.Builder.prototype.requiredField = function(table, field) { 689 var table_start = this.bb.capacity() - table; 690 var vtable_start = table_start - this.bb.readInt32(table_start); 691 var ok = this.bb.readInt16(vtable_start + field) != 0; 692 693 // If this fails, the caller will show what field needs to be set. 694 if (!ok) { 695 throw new Error('FlatBuffers: field ' + field + ' must be set'); 696 } 697}; 698 699/** 700 * Start a new array/vector of objects. Users usually will not call 701 * this directly. The FlatBuffers compiler will create a start/end 702 * method for vector types in generated code. 703 * 704 * @param {number} elem_size The size of each element in the array 705 * @param {number} num_elems The number of elements in the array 706 * @param {number} alignment The alignment of the array 707 */ 708flatbuffers.Builder.prototype.startVector = function(elem_size, num_elems, alignment) { 709 this.notNested(); 710 this.vector_num_elems = num_elems; 711 this.prep(flatbuffers.SIZEOF_INT, elem_size * num_elems); 712 this.prep(alignment, elem_size * num_elems); // Just in case alignment > int. 713}; 714 715/** 716 * Finish off the creation of an array and all its elements. The array must be 717 * created with `startVector`. 718 * 719 * @returns {flatbuffers.Offset} The offset at which the newly created array 720 * starts. 721 */ 722flatbuffers.Builder.prototype.endVector = function() { 723 this.writeInt32(this.vector_num_elems); 724 return this.offset(); 725}; 726/// @endcond 727 728/** 729 * Encode the string `s` in the buffer using UTF-8. If a Uint8Array is passed 730 * instead of a string, it is assumed to contain valid UTF-8 encoded data. 731 * 732 * @param {string|Uint8Array} s The string to encode 733 * @return {flatbuffers.Offset} The offset in the buffer where the encoded string starts 734 */ 735flatbuffers.Builder.prototype.createString = function(s) { 736 if (s instanceof Uint8Array) { 737 var utf8 = s; 738 } else { 739 var utf8 = []; 740 var i = 0; 741 742 while (i < s.length) { 743 var codePoint; 744 745 // Decode UTF-16 746 var a = s.charCodeAt(i++); 747 if (a < 0xD800 || a >= 0xDC00) { 748 codePoint = a; 749 } else { 750 var b = s.charCodeAt(i++); 751 codePoint = (a << 10) + b + (0x10000 - (0xD800 << 10) - 0xDC00); 752 } 753 754 // Encode UTF-8 755 if (codePoint < 0x80) { 756 utf8.push(codePoint); 757 } else { 758 if (codePoint < 0x800) { 759 utf8.push(((codePoint >> 6) & 0x1F) | 0xC0); 760 } else { 761 if (codePoint < 0x10000) { 762 utf8.push(((codePoint >> 12) & 0x0F) | 0xE0); 763 } else { 764 utf8.push( 765 ((codePoint >> 18) & 0x07) | 0xF0, 766 ((codePoint >> 12) & 0x3F) | 0x80); 767 } 768 utf8.push(((codePoint >> 6) & 0x3F) | 0x80); 769 } 770 utf8.push((codePoint & 0x3F) | 0x80); 771 } 772 } 773 } 774 775 this.addInt8(0); 776 this.startVector(1, utf8.length, 1); 777 this.bb.setPosition(this.space -= utf8.length); 778 for (var i = 0, offset = this.space, bytes = this.bb.bytes(); i < utf8.length; i++) { 779 bytes[offset++] = utf8[i]; 780 } 781 return this.endVector(); 782}; 783 784/** 785 * A helper function to avoid generated code depending on this file directly. 786 * 787 * @param {number} low 788 * @param {number} high 789 * @returns {flatbuffers.Long} 790 */ 791flatbuffers.Builder.prototype.createLong = function(low, high) { 792 return flatbuffers.Long.create(low, high); 793}; 794//////////////////////////////////////////////////////////////////////////////// 795/// @cond FLATBUFFERS_INTERNAL 796/** 797 * Create a new ByteBuffer with a given array of bytes (`Uint8Array`). 798 * 799 * @constructor 800 * @param {Uint8Array} bytes 801 */ 802flatbuffers.ByteBuffer = function(bytes) { 803 /** 804 * @type {Uint8Array} 805 * @private 806 */ 807 this.bytes_ = bytes; 808 809 /** 810 * @type {number} 811 * @private 812 */ 813 this.position_ = 0; 814}; 815 816/** 817 * Create and allocate a new ByteBuffer with a given size. 818 * 819 * @param {number} byte_size 820 * @returns {flatbuffers.ByteBuffer} 821 */ 822flatbuffers.ByteBuffer.allocate = function(byte_size) { 823 return new flatbuffers.ByteBuffer(new Uint8Array(byte_size)); 824}; 825 826/** 827 * Get the underlying `Uint8Array`. 828 * 829 * @returns {Uint8Array} 830 */ 831flatbuffers.ByteBuffer.prototype.bytes = function() { 832 return this.bytes_; 833}; 834 835/** 836 * Get the buffer's position. 837 * 838 * @returns {number} 839 */ 840flatbuffers.ByteBuffer.prototype.position = function() { 841 return this.position_; 842}; 843 844/** 845 * Set the buffer's position. 846 * 847 * @param {number} position 848 */ 849flatbuffers.ByteBuffer.prototype.setPosition = function(position) { 850 this.position_ = position; 851}; 852 853/** 854 * Get the buffer's capacity. 855 * 856 * @returns {number} 857 */ 858flatbuffers.ByteBuffer.prototype.capacity = function() { 859 return this.bytes_.length; 860}; 861 862/** 863 * @param {number} offset 864 * @returns {number} 865 */ 866flatbuffers.ByteBuffer.prototype.readInt8 = function(offset) { 867 return this.readUint8(offset) << 24 >> 24; 868}; 869 870/** 871 * @param {number} offset 872 * @returns {number} 873 */ 874flatbuffers.ByteBuffer.prototype.readUint8 = function(offset) { 875 return this.bytes_[offset]; 876}; 877 878/** 879 * @param {number} offset 880 * @returns {number} 881 */ 882flatbuffers.ByteBuffer.prototype.readInt16 = function(offset) { 883 return this.readUint16(offset) << 16 >> 16; 884}; 885 886/** 887 * @param {number} offset 888 * @returns {number} 889 */ 890flatbuffers.ByteBuffer.prototype.readUint16 = function(offset) { 891 return this.bytes_[offset] | this.bytes_[offset + 1] << 8; 892}; 893 894/** 895 * @param {number} offset 896 * @returns {number} 897 */ 898flatbuffers.ByteBuffer.prototype.readInt32 = function(offset) { 899 return this.bytes_[offset] | this.bytes_[offset + 1] << 8 | this.bytes_[offset + 2] << 16 | this.bytes_[offset + 3] << 24; 900}; 901 902/** 903 * @param {number} offset 904 * @returns {number} 905 */ 906flatbuffers.ByteBuffer.prototype.readUint32 = function(offset) { 907 return this.readInt32(offset) >>> 0; 908}; 909 910/** 911 * @param {number} offset 912 * @returns {flatbuffers.Long} 913 */ 914flatbuffers.ByteBuffer.prototype.readInt64 = function(offset) { 915 return new flatbuffers.Long(this.readInt32(offset), this.readInt32(offset + 4)); 916}; 917 918/** 919 * @param {number} offset 920 * @returns {flatbuffers.Long} 921 */ 922flatbuffers.ByteBuffer.prototype.readUint64 = function(offset) { 923 return new flatbuffers.Long(this.readUint32(offset), this.readUint32(offset + 4)); 924}; 925 926/** 927 * @param {number} offset 928 * @returns {number} 929 */ 930flatbuffers.ByteBuffer.prototype.readFloat32 = function(offset) { 931 flatbuffers.int32[0] = this.readInt32(offset); 932 return flatbuffers.float32[0]; 933}; 934 935/** 936 * @param {number} offset 937 * @returns {number} 938 */ 939flatbuffers.ByteBuffer.prototype.readFloat64 = function(offset) { 940 flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1] = this.readInt32(offset); 941 flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0] = this.readInt32(offset + 4); 942 return flatbuffers.float64[0]; 943}; 944 945/** 946 * @param {number} offset 947 * @param {number} value 948 */ 949flatbuffers.ByteBuffer.prototype.writeInt8 = function(offset, value) { 950 this.bytes_[offset] = value; 951}; 952 953/** 954 * @param {number} offset 955 * @param {number} value 956 */ 957flatbuffers.ByteBuffer.prototype.writeInt16 = function(offset, value) { 958 this.bytes_[offset] = value; 959 this.bytes_[offset + 1] = value >> 8; 960}; 961 962/** 963 * @param {number} offset 964 * @param {number} value 965 */ 966flatbuffers.ByteBuffer.prototype.writeInt32 = function(offset, value) { 967 this.bytes_[offset] = value; 968 this.bytes_[offset + 1] = value >> 8; 969 this.bytes_[offset + 2] = value >> 16; 970 this.bytes_[offset + 3] = value >> 24; 971}; 972 973/** 974 * @param {number} offset 975 * @param {flatbuffers.Long} value 976 */ 977flatbuffers.ByteBuffer.prototype.writeInt64 = function(offset, value) { 978 this.writeInt32(offset, value.low); 979 this.writeInt32(offset + 4, value.high); 980}; 981 982/** 983 * @param {number} offset 984 * @param {number} value 985 */ 986flatbuffers.ByteBuffer.prototype.writeFloat32 = function(offset, value) { 987 flatbuffers.float32[0] = value; 988 this.writeInt32(offset, flatbuffers.int32[0]); 989}; 990 991/** 992 * @param {number} offset 993 * @param {number} value 994 */ 995flatbuffers.ByteBuffer.prototype.writeFloat64 = function(offset, value) { 996 flatbuffers.float64[0] = value; 997 this.writeInt32(offset, flatbuffers.int32[flatbuffers.isLittleEndian ? 0 : 1]); 998 this.writeInt32(offset + 4, flatbuffers.int32[flatbuffers.isLittleEndian ? 1 : 0]); 999}; 1000 1001/** 1002 * Look up a field in the vtable, return an offset into the object, or 0 if the 1003 * field is not present. 1004 * 1005 * @param {number} bb_pos 1006 * @param {number} vtable_offset 1007 * @returns {number} 1008 */ 1009flatbuffers.ByteBuffer.prototype.__offset = function(bb_pos, vtable_offset) { 1010 var vtable = bb_pos - this.readInt32(bb_pos); 1011 return vtable_offset < this.readInt16(vtable) ? this.readInt16(vtable + vtable_offset) : 0; 1012}; 1013 1014/** 1015 * Initialize any Table-derived type to point to the union at the given offset. 1016 * 1017 * @param {flatbuffers.Table} t 1018 * @param {number} offset 1019 * @returns {flatbuffers.Table} 1020 */ 1021flatbuffers.ByteBuffer.prototype.__union = function(t, offset) { 1022 t.bb_pos = offset + this.readInt32(offset); 1023 t.bb = this; 1024 return t; 1025}; 1026 1027/** 1028 * Create a JavaScript string from UTF-8 data stored inside the FlatBuffer. 1029 * This allocates a new string and converts to wide chars upon each access. 1030 * 1031 * To avoid the conversion to UTF-16, pass flatbuffers.Encoding.UTF8_BYTES as 1032 * the "optionalEncoding" argument. This is useful for avoiding conversion to 1033 * and from UTF-16 when the data will just be packaged back up in another 1034 * FlatBuffer later on. 1035 * 1036 * @param {number} offset 1037 * @param {flatbuffers.Encoding=} opt_encoding Defaults to UTF16_STRING 1038 * @returns {string|Uint8Array} 1039 */ 1040flatbuffers.ByteBuffer.prototype.__string = function(offset, opt_encoding) { 1041 offset += this.readInt32(offset); 1042 1043 var length = this.readInt32(offset); 1044 var result = ''; 1045 var i = 0; 1046 1047 offset += flatbuffers.SIZEOF_INT; 1048 1049 if (opt_encoding === flatbuffers.Encoding.UTF8_BYTES) { 1050 return this.bytes_.subarray(offset, offset + length); 1051 } 1052 1053 while (i < length) { 1054 var codePoint; 1055 1056 // Decode UTF-8 1057 var a = this.readUint8(offset + i++); 1058 if (a < 0xC0) { 1059 codePoint = a; 1060 } else { 1061 var b = this.readUint8(offset + i++); 1062 if (a < 0xE0) { 1063 codePoint = 1064 ((a & 0x1F) << 6) | 1065 (b & 0x3F); 1066 } else { 1067 var c = this.readUint8(offset + i++); 1068 if (a < 0xF0) { 1069 codePoint = 1070 ((a & 0x0F) << 12) | 1071 ((b & 0x3F) << 6) | 1072 (c & 0x3F); 1073 } else { 1074 var d = this.readUint8(offset + i++); 1075 codePoint = 1076 ((a & 0x07) << 18) | 1077 ((b & 0x3F) << 12) | 1078 ((c & 0x3F) << 6) | 1079 (d & 0x3F); 1080 } 1081 } 1082 } 1083 1084 // Encode UTF-16 1085 if (codePoint < 0x10000) { 1086 result += String.fromCharCode(codePoint); 1087 } else { 1088 codePoint -= 0x10000; 1089 result += String.fromCharCode( 1090 (codePoint >> 10) + 0xD800, 1091 (codePoint & ((1 << 10) - 1)) + 0xDC00); 1092 } 1093 } 1094 1095 return result; 1096}; 1097 1098/** 1099 * Retrieve the relative offset stored at "offset" 1100 * @param {number} offset 1101 * @returns {number} 1102 */ 1103flatbuffers.ByteBuffer.prototype.__indirect = function(offset) { 1104 return offset + this.readInt32(offset); 1105}; 1106 1107/** 1108 * Get the start of data of a vector whose offset is stored at "offset" in this object. 1109 * 1110 * @param {number} offset 1111 * @returns {number} 1112 */ 1113flatbuffers.ByteBuffer.prototype.__vector = function(offset) { 1114 return offset + this.readInt32(offset) + flatbuffers.SIZEOF_INT; // data starts after the length 1115}; 1116 1117/** 1118 * Get the length of a vector whose offset is stored at "offset" in this object. 1119 * 1120 * @param {number} offset 1121 * @returns {number} 1122 */ 1123flatbuffers.ByteBuffer.prototype.__vector_len = function(offset) { 1124 return this.readInt32(offset + this.readInt32(offset)); 1125}; 1126 1127/** 1128 * @param {string} ident 1129 * @returns {boolean} 1130 */ 1131flatbuffers.ByteBuffer.prototype.__has_identifier = function(ident) { 1132 if (ident.length != flatbuffers.FILE_IDENTIFIER_LENGTH) { 1133 throw new Error('FlatBuffers: file identifier must be length ' + 1134 flatbuffers.FILE_IDENTIFIER_LENGTH); 1135 } 1136 for (var i = 0; i < flatbuffers.FILE_IDENTIFIER_LENGTH; i++) { 1137 if (ident.charCodeAt(i) != this.readInt8(this.position_ + flatbuffers.SIZEOF_INT + i)) { 1138 return false; 1139 } 1140 } 1141 return true; 1142}; 1143 1144/** 1145 * A helper function to avoid generated code depending on this file directly. 1146 * 1147 * @param {number} low 1148 * @param {number} high 1149 * @returns {flatbuffers.Long} 1150 */ 1151flatbuffers.ByteBuffer.prototype.createLong = function(low, high) { 1152 return flatbuffers.Long.create(low, high); 1153}; 1154 1155// Exports for Node.js and RequireJS 1156this.flatbuffers = flatbuffers; 1157 1158/// @endcond 1159/// @} 1160