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