1// Protocol Buffers - Google's data interchange format 2// Copyright 2008 Google Inc. All rights reserved. 3// https://developers.google.com/protocol-buffers/ 4// 5// Redistribution and use in source and binary forms, with or without 6// modification, are permitted provided that the following conditions are 7// met: 8// 9// * Redistributions of source code must retain the above copyright 10// notice, this list of conditions and the following disclaimer. 11// * Redistributions in binary form must reproduce the above 12// copyright notice, this list of conditions and the following disclaimer 13// in the documentation and/or other materials provided with the 14// distribution. 15// * Neither the name of Google Inc. nor the names of its 16// contributors may be used to endorse or promote products derived from 17// this software without specific prior written permission. 18// 19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 31/** 32 * @fileoverview This file contains utilities for encoding Javascript objects 33 * into binary, wire-format protocol buffers (in the form of Uint8Arrays) that 34 * a server can consume directly. 35 * 36 * jspb's BinaryWriter class defines methods for efficiently encoding 37 * Javascript objects into binary, wire-format protocol buffers and supports 38 * all the fundamental field types used in protocol buffers. 39 * 40 * Major caveat 1 - Users of this library _must_ keep their Javascript proto 41 * parsing code in sync with the original .proto file - presumably you'll be 42 * using the typed jspb code generator, but if you bypass that you'll need 43 * to keep things in sync by hand. 44 * 45 * Major caveat 2 - Javascript is unable to accurately represent integers 46 * larger than 2^53 due to its use of a double-precision floating point format 47 * for all numbers. BinaryWriter does not make any special effort to preserve 48 * precision for values above this limit - if you need to pass 64-bit integers 49 * (hash codes, for example) between the client and server without precision 50 * loss, do _not_ use this library. 51 * 52 * Major caveat 3 - This class uses typed arrays and must not be used on older 53 * browsers that do not support them. 54 * 55 * @author aappleby@google.com (Austin Appleby) 56 */ 57 58goog.provide('jspb.BinaryWriter'); 59 60goog.require('goog.asserts'); 61goog.require('goog.crypt.base64'); 62goog.require('jspb.BinaryConstants'); 63goog.require('jspb.BinaryEncoder'); 64goog.require('jspb.arith.Int64'); 65goog.require('jspb.arith.UInt64'); 66goog.require('jspb.utils'); 67 68 69 70/** 71 * BinaryWriter implements encoders for all the wire types specified in 72 * https://developers.google.com/protocol-buffers/docs/encoding. 73 * 74 * @constructor 75 * @struct 76 */ 77jspb.BinaryWriter = function() { 78 /** 79 * Blocks of serialized data that will be concatenated once all messages have 80 * been written. 81 * @private {!Array<!Uint8Array|!Array<number>>} 82 */ 83 this.blocks_ = []; 84 85 /** 86 * Total number of bytes in the blocks_ array. Does _not_ include bytes in 87 * the encoder below. 88 * @private {number} 89 */ 90 this.totalLength_ = 0; 91 92 /** 93 * Binary encoder holding pieces of a message that we're still serializing. 94 * When we get to a stopping point (either the start of a new submessage, or 95 * when we need to append a raw Uint8Array), the encoder's buffer will be 96 * added to the block array above and the encoder will be reset. 97 * @private {!jspb.BinaryEncoder} 98 */ 99 this.encoder_ = new jspb.BinaryEncoder(); 100 101 /** 102 * A stack of bookmarks containing the parent blocks for each message started 103 * via beginSubMessage(), needed as bookkeeping for endSubMessage(). 104 * TODO(aappleby): Deprecated, users should be calling writeMessage(). 105 * @private {!Array.<!Array.<number>>} 106 */ 107 this.bookmarks_ = []; 108}; 109 110 111/** 112 * Append a typed array of bytes onto the buffer. 113 * 114 * @param {!Uint8Array} arr The byte array to append. 115 * @private 116 */ 117jspb.BinaryWriter.prototype.appendUint8Array_ = function(arr) { 118 var temp = this.encoder_.end(); 119 this.blocks_.push(temp); 120 this.blocks_.push(arr); 121 this.totalLength_ += temp.length + arr.length; 122}; 123 124 125/** 126 * Begins a new message by writing the field header and returning a bookmark 127 * which we will use to patch in the message length to in endDelimited_ below. 128 * @param {number} field 129 * @return {!Array.<number>} 130 * @private 131 */ 132jspb.BinaryWriter.prototype.beginDelimited_ = function(field) { 133 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 134 var bookmark = this.encoder_.end(); 135 this.blocks_.push(bookmark); 136 this.totalLength_ += bookmark.length; 137 bookmark.push(this.totalLength_); 138 return bookmark; 139}; 140 141 142/** 143 * Ends a message by encoding the _change_ in length of the buffer to the 144 * parent block and adds the number of bytes needed to encode that length to 145 * the total byte length. 146 * @param {!Array.<number>} bookmark 147 * @private 148 */ 149jspb.BinaryWriter.prototype.endDelimited_ = function(bookmark) { 150 var oldLength = bookmark.pop(); 151 var messageLength = this.totalLength_ + this.encoder_.length() - oldLength; 152 goog.asserts.assert(messageLength >= 0); 153 154 while (messageLength > 127) { 155 bookmark.push((messageLength & 0x7f) | 0x80); 156 messageLength = messageLength >>> 7; 157 this.totalLength_++; 158 } 159 160 bookmark.push(messageLength); 161 this.totalLength_++; 162}; 163 164 165/** 166 * Writes a pre-serialized message to the buffer. 167 * @param {!Uint8Array} bytes The array of bytes to write. 168 * @param {number} start The start of the range to write. 169 * @param {number} end The end of the range to write. 170 */ 171jspb.BinaryWriter.prototype.writeSerializedMessage = function( 172 bytes, start, end) { 173 this.appendUint8Array_(bytes.subarray(start, end)); 174}; 175 176 177/** 178 * Writes a pre-serialized message to the buffer if the message and endpoints 179 * are non-null. 180 * @param {?Uint8Array} bytes The array of bytes to write. 181 * @param {?number} start The start of the range to write. 182 * @param {?number} end The end of the range to write. 183 */ 184jspb.BinaryWriter.prototype.maybeWriteSerializedMessage = function( 185 bytes, start, end) { 186 if (bytes != null && start != null && end != null) { 187 this.writeSerializedMessage(bytes, start, end); 188 } 189}; 190 191 192/** 193 * Resets the writer, throwing away any accumulated buffers. 194 */ 195jspb.BinaryWriter.prototype.reset = function() { 196 this.blocks_ = []; 197 this.encoder_.end(); 198 this.totalLength_ = 0; 199 this.bookmarks_ = []; 200}; 201 202 203/** 204 * Converts the encoded data into a Uint8Array. 205 * @return {!Uint8Array} 206 */ 207jspb.BinaryWriter.prototype.getResultBuffer = function() { 208 goog.asserts.assert(this.bookmarks_.length == 0); 209 210 var flat = new Uint8Array(this.totalLength_ + this.encoder_.length()); 211 212 var blocks = this.blocks_; 213 var blockCount = blocks.length; 214 var offset = 0; 215 216 for (var i = 0; i < blockCount; i++) { 217 var block = blocks[i]; 218 flat.set(block, offset); 219 offset += block.length; 220 } 221 222 var tail = this.encoder_.end(); 223 flat.set(tail, offset); 224 offset += tail.length; 225 226 // Post condition: `flattened` must have had every byte written. 227 goog.asserts.assert(offset == flat.length); 228 229 // Replace our block list with the flattened block, which lets GC reclaim 230 // the temp blocks sooner. 231 this.blocks_ = [flat]; 232 233 return flat; 234}; 235 236 237/** 238 * Converts the encoded data into a bas64-encoded string. 239 * @return {string} 240 */ 241jspb.BinaryWriter.prototype.getResultBase64String = function() { 242 return goog.crypt.base64.encodeByteArray(this.getResultBuffer()); 243}; 244 245 246/** 247 * Begins a new sub-message. The client must call endSubMessage() when they're 248 * done. 249 * TODO(aappleby): Deprecated. Move callers to writeMessage(). 250 * @param {number} field The field number of the sub-message. 251 */ 252jspb.BinaryWriter.prototype.beginSubMessage = function(field) { 253 this.bookmarks_.push(this.beginDelimited_(field)); 254}; 255 256 257/** 258 * Finishes a sub-message and packs it into the parent messages' buffer. 259 * TODO(aappleby): Deprecated. Move callers to writeMessage(). 260 */ 261jspb.BinaryWriter.prototype.endSubMessage = function() { 262 goog.asserts.assert(this.bookmarks_.length >= 0); 263 this.endDelimited_(this.bookmarks_.pop()); 264}; 265 266 267/** 268 * Encodes a (field number, wire type) tuple into a wire-format field header 269 * and stores it in the buffer as a varint. 270 * @param {number} field The field number. 271 * @param {number} wireType The wire-type of the field, as specified in the 272 * protocol buffer documentation. 273 * @private 274 */ 275jspb.BinaryWriter.prototype.writeFieldHeader_ = 276 function(field, wireType) { 277 goog.asserts.assert(field >= 1 && field == Math.floor(field)); 278 var x = field * 8 + wireType; 279 this.encoder_.writeUnsignedVarint32(x); 280}; 281 282 283/** 284 * Writes a field of any valid scalar type to the binary stream. 285 * @param {jspb.BinaryConstants.FieldType} fieldType 286 * @param {number} field 287 * @param {jspb.AnyFieldType} value 288 */ 289jspb.BinaryWriter.prototype.writeAny = function(fieldType, field, value) { 290 var fieldTypes = jspb.BinaryConstants.FieldType; 291 switch (fieldType) { 292 case fieldTypes.DOUBLE: 293 this.writeDouble(field, /** @type {number} */(value)); 294 return; 295 case fieldTypes.FLOAT: 296 this.writeFloat(field, /** @type {number} */(value)); 297 return; 298 case fieldTypes.INT64: 299 this.writeInt64(field, /** @type {number} */(value)); 300 return; 301 case fieldTypes.UINT64: 302 this.writeUint64(field, /** @type {number} */(value)); 303 return; 304 case fieldTypes.INT32: 305 this.writeInt32(field, /** @type {number} */(value)); 306 return; 307 case fieldTypes.FIXED64: 308 this.writeFixed64(field, /** @type {number} */(value)); 309 return; 310 case fieldTypes.FIXED32: 311 this.writeFixed32(field, /** @type {number} */(value)); 312 return; 313 case fieldTypes.BOOL: 314 this.writeBool(field, /** @type {boolean} */(value)); 315 return; 316 case fieldTypes.STRING: 317 this.writeString(field, /** @type {string} */(value)); 318 return; 319 case fieldTypes.GROUP: 320 goog.asserts.fail('Group field type not supported in writeAny()'); 321 return; 322 case fieldTypes.MESSAGE: 323 goog.asserts.fail('Message field type not supported in writeAny()'); 324 return; 325 case fieldTypes.BYTES: 326 this.writeBytes(field, /** @type {?Uint8Array} */(value)); 327 return; 328 case fieldTypes.UINT32: 329 this.writeUint32(field, /** @type {number} */(value)); 330 return; 331 case fieldTypes.ENUM: 332 this.writeEnum(field, /** @type {number} */(value)); 333 return; 334 case fieldTypes.SFIXED32: 335 this.writeSfixed32(field, /** @type {number} */(value)); 336 return; 337 case fieldTypes.SFIXED64: 338 this.writeSfixed64(field, /** @type {number} */(value)); 339 return; 340 case fieldTypes.SINT32: 341 this.writeSint32(field, /** @type {number} */(value)); 342 return; 343 case fieldTypes.SINT64: 344 this.writeSint64(field, /** @type {number} */(value)); 345 return; 346 case fieldTypes.FHASH64: 347 this.writeFixedHash64(field, /** @type {string} */(value)); 348 return; 349 case fieldTypes.VHASH64: 350 this.writeVarintHash64(field, /** @type {string} */(value)); 351 return; 352 default: 353 goog.asserts.fail('Invalid field type in writeAny()'); 354 return; 355 } 356}; 357 358 359/** 360 * Writes a varint field to the buffer without range checking. 361 * @param {number} field The field number. 362 * @param {number?} value The value to write. 363 * @private 364 */ 365jspb.BinaryWriter.prototype.writeUnsignedVarint32_ = function(field, value) { 366 if (value == null) return; 367 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); 368 this.encoder_.writeUnsignedVarint32(value); 369}; 370 371 372/** 373 * Writes a varint field to the buffer without range checking. 374 * @param {number} field The field number. 375 * @param {number?} value The value to write. 376 * @private 377 */ 378jspb.BinaryWriter.prototype.writeSignedVarint32_ = function(field, value) { 379 if (value == null) return; 380 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); 381 this.encoder_.writeSignedVarint32(value); 382}; 383 384 385/** 386 * Writes a varint field to the buffer without range checking. 387 * @param {number} field The field number. 388 * @param {number?} value The value to write. 389 * @private 390 */ 391jspb.BinaryWriter.prototype.writeUnsignedVarint64_ = function(field, value) { 392 if (value == null) return; 393 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); 394 this.encoder_.writeUnsignedVarint64(value); 395}; 396 397 398/** 399 * Writes a varint field to the buffer without range checking. 400 * @param {number} field The field number. 401 * @param {number?} value The value to write. 402 * @private 403 */ 404jspb.BinaryWriter.prototype.writeSignedVarint64_ = function(field, value) { 405 if (value == null) return; 406 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); 407 this.encoder_.writeSignedVarint64(value); 408}; 409 410 411/** 412 * Writes a zigzag varint field to the buffer without range checking. 413 * @param {number} field The field number. 414 * @param {number?} value The value to write. 415 * @private 416 */ 417jspb.BinaryWriter.prototype.writeZigzagVarint32_ = function(field, value) { 418 if (value == null) return; 419 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); 420 this.encoder_.writeZigzagVarint32(value); 421}; 422 423 424/** 425 * Writes a zigzag varint field to the buffer without range checking. 426 * @param {number} field The field number. 427 * @param {number?} value The value to write. 428 * @private 429 */ 430jspb.BinaryWriter.prototype.writeZigzagVarint64_ = function(field, value) { 431 if (value == null) return; 432 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); 433 this.encoder_.writeZigzagVarint64(value); 434}; 435 436 437/** 438 * Writes an int32 field to the buffer. Numbers outside the range [-2^31,2^31) 439 * will be truncated. 440 * @param {number} field The field number. 441 * @param {number?} value The value to write. 442 */ 443jspb.BinaryWriter.prototype.writeInt32 = function(field, value) { 444 if (value == null) return; 445 goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) && 446 (value < jspb.BinaryConstants.TWO_TO_31)); 447 this.writeSignedVarint32_(field, value); 448}; 449 450 451/** 452 * Writes an int32 field represented as a string to the buffer. Numbers outside 453 * the range [-2^31,2^31) will be truncated. 454 * @param {number} field The field number. 455 * @param {string?} value The value to write. 456 */ 457jspb.BinaryWriter.prototype.writeInt32String = function(field, value) { 458 if (value == null) return; 459 var intValue = /** {number} */ parseInt(value, 10); 460 goog.asserts.assert((intValue >= -jspb.BinaryConstants.TWO_TO_31) && 461 (intValue < jspb.BinaryConstants.TWO_TO_31)); 462 this.writeSignedVarint32_(field, intValue); 463}; 464 465 466/** 467 * Writes an int64 field to the buffer. Numbers outside the range [-2^63,2^63) 468 * will be truncated. 469 * @param {number} field The field number. 470 * @param {number?} value The value to write. 471 */ 472jspb.BinaryWriter.prototype.writeInt64 = function(field, value) { 473 if (value == null) return; 474 goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) && 475 (value < jspb.BinaryConstants.TWO_TO_63)); 476 this.writeSignedVarint64_(field, value); 477}; 478 479 480/** 481 * Writes a int64 field (with value as a string) to the buffer. 482 * @param {number} field The field number. 483 * @param {string?} value The value to write. 484 */ 485jspb.BinaryWriter.prototype.writeInt64String = function(field, value) { 486 if (value == null) return; 487 var num = jspb.arith.Int64.fromString(value); 488 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); 489 this.encoder_.writeSplitVarint64(num.lo, num.hi); 490}; 491 492 493/** 494 * Writes a uint32 field to the buffer. Numbers outside the range [0,2^32) 495 * will be truncated. 496 * @param {number} field The field number. 497 * @param {number?} value The value to write. 498 */ 499jspb.BinaryWriter.prototype.writeUint32 = function(field, value) { 500 if (value == null) return; 501 goog.asserts.assert((value >= 0) && 502 (value < jspb.BinaryConstants.TWO_TO_32)); 503 this.writeUnsignedVarint32_(field, value); 504}; 505 506 507/** 508 * Writes a uint32 field represented as a string to the buffer. Numbers outside 509 * the range [0,2^32) will be truncated. 510 * @param {number} field The field number. 511 * @param {string?} value The value to write. 512 */ 513jspb.BinaryWriter.prototype.writeUint32String = function(field, value) { 514 if (value == null) return; 515 var intValue = /** {number} */ parseInt(value, 10); 516 goog.asserts.assert((intValue >= 0) && 517 (intValue < jspb.BinaryConstants.TWO_TO_32)); 518 this.writeUnsignedVarint32_(field, intValue); 519}; 520 521 522/** 523 * Writes a uint64 field to the buffer. Numbers outside the range [0,2^64) 524 * will be truncated. 525 * @param {number} field The field number. 526 * @param {number?} value The value to write. 527 */ 528jspb.BinaryWriter.prototype.writeUint64 = function(field, value) { 529 if (value == null) return; 530 goog.asserts.assert((value >= 0) && 531 (value < jspb.BinaryConstants.TWO_TO_64)); 532 this.writeUnsignedVarint64_(field, value); 533}; 534 535 536/** 537 * Writes a uint64 field (with value as a string) to the buffer. 538 * @param {number} field The field number. 539 * @param {string?} value The value to write. 540 */ 541jspb.BinaryWriter.prototype.writeUint64String = function(field, value) { 542 if (value == null) return; 543 var num = jspb.arith.UInt64.fromString(value); 544 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); 545 this.encoder_.writeSplitVarint64(num.lo, num.hi); 546}; 547 548 549/** 550 * Writes a sint32 field to the buffer. Numbers outside the range [-2^31,2^31) 551 * will be truncated. 552 * @param {number} field The field number. 553 * @param {number?} value The value to write. 554 */ 555jspb.BinaryWriter.prototype.writeSint32 = function(field, value) { 556 if (value == null) return; 557 goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) && 558 (value < jspb.BinaryConstants.TWO_TO_31)); 559 this.writeZigzagVarint32_(field, value); 560}; 561 562 563/** 564 * Writes a sint64 field to the buffer. Numbers outside the range [-2^63,2^63) 565 * will be truncated. 566 * @param {number} field The field number. 567 * @param {number?} value The value to write. 568 */ 569jspb.BinaryWriter.prototype.writeSint64 = function(field, value) { 570 if (value == null) return; 571 goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) && 572 (value < jspb.BinaryConstants.TWO_TO_63)); 573 this.writeZigzagVarint64_(field, value); 574}; 575 576 577/** 578 * Writes a fixed32 field to the buffer. Numbers outside the range [0,2^32) 579 * will be truncated. 580 * @param {number} field The field number. 581 * @param {number?} value The value to write. 582 */ 583jspb.BinaryWriter.prototype.writeFixed32 = function(field, value) { 584 if (value == null) return; 585 goog.asserts.assert((value >= 0) && 586 (value < jspb.BinaryConstants.TWO_TO_32)); 587 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32); 588 this.encoder_.writeUint32(value); 589}; 590 591 592/** 593 * Writes a fixed64 field to the buffer. Numbers outside the range [0,2^64) 594 * will be truncated. 595 * @param {number} field The field number. 596 * @param {number?} value The value to write. 597 */ 598jspb.BinaryWriter.prototype.writeFixed64 = function(field, value) { 599 if (value == null) return; 600 goog.asserts.assert((value >= 0) && 601 (value < jspb.BinaryConstants.TWO_TO_64)); 602 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64); 603 this.encoder_.writeUint64(value); 604}; 605 606 607/** 608 * Writes a sfixed32 field to the buffer. Numbers outside the range 609 * [-2^31,2^31) will be truncated. 610 * @param {number} field The field number. 611 * @param {number?} value The value to write. 612 */ 613jspb.BinaryWriter.prototype.writeSfixed32 = function(field, value) { 614 if (value == null) return; 615 goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) && 616 (value < jspb.BinaryConstants.TWO_TO_31)); 617 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32); 618 this.encoder_.writeInt32(value); 619}; 620 621 622/** 623 * Writes a sfixed64 field to the buffer. Numbers outside the range 624 * [-2^63,2^63) will be truncated. 625 * @param {number} field The field number. 626 * @param {number?} value The value to write. 627 */ 628jspb.BinaryWriter.prototype.writeSfixed64 = function(field, value) { 629 if (value == null) return; 630 goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) && 631 (value < jspb.BinaryConstants.TWO_TO_63)); 632 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64); 633 this.encoder_.writeInt64(value); 634}; 635 636 637/** 638 * Writes a single-precision floating point field to the buffer. Numbers 639 * requiring more than 32 bits of precision will be truncated. 640 * @param {number} field The field number. 641 * @param {number?} value The value to write. 642 */ 643jspb.BinaryWriter.prototype.writeFloat = function(field, value) { 644 if (value == null) return; 645 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32); 646 this.encoder_.writeFloat(value); 647}; 648 649 650/** 651 * Writes a double-precision floating point field to the buffer. As this is the 652 * native format used by JavaScript, no precision will be lost. 653 * @param {number} field The field number. 654 * @param {number?} value The value to write. 655 */ 656jspb.BinaryWriter.prototype.writeDouble = function(field, value) { 657 if (value == null) return; 658 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64); 659 this.encoder_.writeDouble(value); 660}; 661 662 663/** 664 * Writes a boolean field to the buffer. 665 * @param {number} field The field number. 666 * @param {boolean?} value The value to write. 667 */ 668jspb.BinaryWriter.prototype.writeBool = function(field, value) { 669 if (value == null) return; 670 goog.asserts.assert(goog.isBoolean(value)); 671 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); 672 this.encoder_.writeBool(value); 673}; 674 675 676/** 677 * Writes an enum field to the buffer. 678 * @param {number} field The field number. 679 * @param {number?} value The value to write. 680 */ 681jspb.BinaryWriter.prototype.writeEnum = function(field, value) { 682 if (value == null) return; 683 goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) && 684 (value < jspb.BinaryConstants.TWO_TO_31)); 685 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); 686 this.encoder_.writeSignedVarint32(value); 687}; 688 689 690/** 691 * Writes a string field to the buffer. 692 * @param {number} field The field number. 693 * @param {string?} value The string to write. 694 */ 695jspb.BinaryWriter.prototype.writeString = function(field, value) { 696 if (value == null) return; 697 var bookmark = this.beginDelimited_(field); 698 this.encoder_.writeString(value); 699 this.endDelimited_(bookmark); 700}; 701 702 703/** 704 * Writes an arbitrary byte field to the buffer. Note - to match the behavior 705 * of the C++ implementation, empty byte arrays _are_ serialized. 706 * @param {number} field The field number. 707 * @param {?jspb.ByteSource} value The array of bytes to write. 708 */ 709jspb.BinaryWriter.prototype.writeBytes = function(field, value) { 710 if (value == null) return; 711 var bytes = jspb.utils.byteSourceToUint8Array(value); 712 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 713 this.encoder_.writeUnsignedVarint32(bytes.length); 714 this.appendUint8Array_(bytes); 715}; 716 717 718/** 719 * Writes a message to the buffer. 720 * @param {number} field The field number. 721 * @param {?MessageType} value The message to write. 722 * @param {function(MessageTypeNonNull, !jspb.BinaryWriter)} writerCallback 723 * Will be invoked with the value to write and the writer to write it with. 724 * @template MessageType 725 * Use go/closure-ttl to declare a non-nullable version of MessageType. Replace 726 * the null in blah|null with none. This is necessary because the compiler will 727 * infer MessageType to be nullable if the value parameter is nullable. 728 * @template MessageTypeNonNull := 729 * cond(isUnknown(MessageType), unknown(), 730 * mapunion(MessageType, (X) => 731 * cond(eq(X, 'null'), none(), X))) 732 * =: 733 */ 734jspb.BinaryWriter.prototype.writeMessage = function( 735 field, value, writerCallback) { 736 if (value == null) return; 737 var bookmark = this.beginDelimited_(field); 738 writerCallback(value, this); 739 this.endDelimited_(bookmark); 740}; 741 742 743/** 744 * Writes a group message to the buffer. 745 * 746 * @param {number} field The field number. 747 * @param {?MessageType} value The message to write, wrapped with START_GROUP / 748 * END_GROUP tags. Will be a no-op if 'value' is null. 749 * @param {function(MessageTypeNonNull, !jspb.BinaryWriter)} writerCallback 750 * Will be invoked with the value to write and the writer to write it with. 751 * @template MessageType 752 * Use go/closure-ttl to declare a non-nullable version of MessageType. Replace 753 * the null in blah|null with none. This is necessary because the compiler will 754 * infer MessageType to be nullable if the value parameter is nullable. 755 * @template MessageTypeNonNull := 756 * cond(isUnknown(MessageType), unknown(), 757 * mapunion(MessageType, (X) => 758 * cond(eq(X, 'null'), none(), X))) 759 * =: 760 */ 761jspb.BinaryWriter.prototype.writeGroup = function( 762 field, value, writerCallback) { 763 if (value == null) return; 764 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.START_GROUP); 765 writerCallback(value, this); 766 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.END_GROUP); 767}; 768 769 770/** 771 * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to 772 * the buffer. 773 * @param {number} field The field number. 774 * @param {string?} value The hash string. 775 */ 776jspb.BinaryWriter.prototype.writeFixedHash64 = function(field, value) { 777 if (value == null) return; 778 goog.asserts.assert(value.length == 8); 779 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64); 780 this.encoder_.writeFixedHash64(value); 781}; 782 783 784/** 785 * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to 786 * the buffer. 787 * @param {number} field The field number. 788 * @param {string?} value The hash string. 789 */ 790jspb.BinaryWriter.prototype.writeVarintHash64 = function(field, value) { 791 if (value == null) return; 792 goog.asserts.assert(value.length == 8); 793 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); 794 this.encoder_.writeVarintHash64(value); 795}; 796 797 798/** 799 * Writes an array of numbers to the buffer as a repeated varint field. 800 * @param {number} field The field number. 801 * @param {?Array.<number>} value The array of ints to write. 802 * @private 803 */ 804jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint32_ = 805 function(field, value) { 806 if (value == null) return; 807 for (var i = 0; i < value.length; i++) { 808 this.writeUnsignedVarint32_(field, value[i]); 809 } 810}; 811 812 813/** 814 * Writes an array of numbers to the buffer as a repeated varint field. 815 * @param {number} field The field number. 816 * @param {?Array.<number>} value The array of ints to write. 817 * @private 818 */ 819jspb.BinaryWriter.prototype.writeRepeatedSignedVarint32_ = 820 function(field, value) { 821 if (value == null) return; 822 for (var i = 0; i < value.length; i++) { 823 this.writeSignedVarint32_(field, value[i]); 824 } 825}; 826 827 828/** 829 * Writes an array of numbers to the buffer as a repeated varint field. 830 * @param {number} field The field number. 831 * @param {?Array.<number>} value The array of ints to write. 832 * @private 833 */ 834jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint64_ = 835 function(field, value) { 836 if (value == null) return; 837 for (var i = 0; i < value.length; i++) { 838 this.writeUnsignedVarint64_(field, value[i]); 839 } 840}; 841 842 843/** 844 * Writes an array of numbers to the buffer as a repeated varint field. 845 * @param {number} field The field number. 846 * @param {?Array.<number>} value The array of ints to write. 847 * @private 848 */ 849jspb.BinaryWriter.prototype.writeRepeatedSignedVarint64_ = 850 function(field, value) { 851 if (value == null) return; 852 for (var i = 0; i < value.length; i++) { 853 this.writeSignedVarint64_(field, value[i]); 854 } 855}; 856 857 858/** 859 * Writes an array of numbers to the buffer as a repeated zigzag field. 860 * @param {number} field The field number. 861 * @param {?Array.<number>} value The array of ints to write. 862 * @private 863 */ 864jspb.BinaryWriter.prototype.writeRepeatedZigzag32_ = function(field, value) { 865 if (value == null) return; 866 for (var i = 0; i < value.length; i++) { 867 this.writeZigzagVarint32_(field, value[i]); 868 } 869}; 870 871 872/** 873 * Writes an array of numbers to the buffer as a repeated zigzag field. 874 * @param {number} field The field number. 875 * @param {?Array.<number>} value The array of ints to write. 876 * @private 877 */ 878jspb.BinaryWriter.prototype.writeRepeatedZigzag_ = function(field, value) { 879 if (value == null) return; 880 for (var i = 0; i < value.length; i++) { 881 this.writeZigzagVarint64_(field, value[i]); 882 } 883}; 884 885 886/** 887 * Writes an array of numbers to the buffer as a repeated 32-bit int field. 888 * @param {number} field The field number. 889 * @param {?Array.<number>} value The array of ints to write. 890 */ 891jspb.BinaryWriter.prototype.writeRepeatedInt32 = 892 jspb.BinaryWriter.prototype.writeRepeatedSignedVarint32_; 893 894 895/** 896 * Writes an array of numbers formatted as strings to the buffer as a repeated 897 * 32-bit int field. 898 * @param {number} field The field number. 899 * @param {?Array.<string>} value The array of ints to write. 900 */ 901jspb.BinaryWriter.prototype.writeRepeatedInt32String = 902 function(field, value) { 903 if (value == null) return; 904 for (var i = 0; i < value.length; i++) { 905 this.writeInt32String(field, value[i]); 906 } 907}; 908 909 910/** 911 * Writes an array of numbers to the buffer as a repeated 64-bit int field. 912 * @param {number} field The field number. 913 * @param {?Array.<number>} value The array of ints to write. 914 */ 915jspb.BinaryWriter.prototype.writeRepeatedInt64 = 916 jspb.BinaryWriter.prototype.writeRepeatedSignedVarint64_; 917 918 919/** 920 * Writes an array of numbers formatted as strings to the buffer as a repeated 921 * 64-bit int field. 922 * @param {number} field The field number. 923 * @param {?Array.<string>} value The array of ints to write. 924 */ 925jspb.BinaryWriter.prototype.writeRepeatedInt64String = 926 function(field, value) { 927 if (value == null) return; 928 for (var i = 0; i < value.length; i++) { 929 this.writeInt64String(field, value[i]); 930 } 931}; 932 933 934/** 935 * Writes an array numbers to the buffer as a repeated unsigned 32-bit int 936 * field. 937 * @param {number} field The field number. 938 * @param {?Array.<number>} value The array of ints to write. 939 */ 940jspb.BinaryWriter.prototype.writeRepeatedUint32 = 941 jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint32_; 942 943 944/** 945 * Writes an array of numbers formatted as strings to the buffer as a repeated 946 * unsigned 32-bit int field. 947 * @param {number} field The field number. 948 * @param {?Array.<string>} value The array of ints to write. 949 */ 950jspb.BinaryWriter.prototype.writeRepeatedUint32String = 951 function(field, value) { 952 if (value == null) return; 953 for (var i = 0; i < value.length; i++) { 954 this.writeUint32String(field, value[i]); 955 } 956}; 957 958 959/** 960 * Writes an array numbers to the buffer as a repeated unsigned 64-bit int 961 * field. 962 * @param {number} field The field number. 963 * @param {?Array.<number>} value The array of ints to write. 964 */ 965jspb.BinaryWriter.prototype.writeRepeatedUint64 = 966 jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint64_; 967 968 969/** 970 * Writes an array of numbers formatted as strings to the buffer as a repeated 971 * unsigned 64-bit int field. 972 * @param {number} field The field number. 973 * @param {?Array.<string>} value The array of ints to write. 974 */ 975jspb.BinaryWriter.prototype.writeRepeatedUint64String = 976 function(field, value) { 977 if (value == null) return; 978 for (var i = 0; i < value.length; i++) { 979 this.writeUint64String(field, value[i]); 980 } 981}; 982 983 984/** 985 * Writes an array numbers to the buffer as a repeated signed 32-bit int field. 986 * @param {number} field The field number. 987 * @param {?Array.<number>} value The array of ints to write. 988 */ 989jspb.BinaryWriter.prototype.writeRepeatedSint32 = 990 jspb.BinaryWriter.prototype.writeRepeatedZigzag32_; 991 992 993/** 994 * Writes an array numbers to the buffer as a repeated signed 64-bit int field. 995 * @param {number} field The field number. 996 * @param {?Array.<number>} value The array of ints to write. 997 */ 998jspb.BinaryWriter.prototype.writeRepeatedSint64 = 999 jspb.BinaryWriter.prototype.writeRepeatedZigzag_; 1000 1001 1002/** 1003 * Writes an array of numbers to the buffer as a repeated fixed32 field. This 1004 * works for both signed and unsigned fixed32s. 1005 * @param {number} field The field number. 1006 * @param {?Array.<number>} value The array of ints to write. 1007 */ 1008jspb.BinaryWriter.prototype.writeRepeatedFixed32 = function(field, value) { 1009 if (value == null) return; 1010 for (var i = 0; i < value.length; i++) { 1011 this.writeFixed32(field, value[i]); 1012 } 1013}; 1014 1015 1016/** 1017 * Writes an array of numbers to the buffer as a repeated fixed64 field. This 1018 * works for both signed and unsigned fixed64s. 1019 * @param {number} field The field number. 1020 * @param {?Array.<number>} value The array of ints to write. 1021 */ 1022jspb.BinaryWriter.prototype.writeRepeatedFixed64 = function(field, value) { 1023 if (value == null) return; 1024 for (var i = 0; i < value.length; i++) { 1025 this.writeFixed64(field, value[i]); 1026 } 1027}; 1028 1029 1030/** 1031 * Writes an array of numbers to the buffer as a repeated sfixed32 field. 1032 * @param {number} field The field number. 1033 * @param {?Array.<number>} value The array of ints to write. 1034 */ 1035jspb.BinaryWriter.prototype.writeRepeatedSfixed32 = function(field, value) { 1036 if (value == null) return; 1037 for (var i = 0; i < value.length; i++) { 1038 this.writeSfixed32(field, value[i]); 1039 } 1040}; 1041 1042 1043/** 1044 * Writes an array of numbers to the buffer as a repeated sfixed64 field. 1045 * @param {number} field The field number. 1046 * @param {?Array.<number>} value The array of ints to write. 1047 */ 1048jspb.BinaryWriter.prototype.writeRepeatedSfixed64 = function(field, value) { 1049 if (value == null) return; 1050 for (var i = 0; i < value.length; i++) { 1051 this.writeSfixed64(field, value[i]); 1052 } 1053}; 1054 1055 1056/** 1057 * Writes an array of numbers to the buffer as a repeated float field. 1058 * @param {number} field The field number. 1059 * @param {?Array.<number>} value The array of ints to write. 1060 */ 1061jspb.BinaryWriter.prototype.writeRepeatedFloat = function(field, value) { 1062 if (value == null) return; 1063 for (var i = 0; i < value.length; i++) { 1064 this.writeFloat(field, value[i]); 1065 } 1066}; 1067 1068 1069/** 1070 * Writes an array of numbers to the buffer as a repeated double field. 1071 * @param {number} field The field number. 1072 * @param {?Array.<number>} value The array of ints to write. 1073 */ 1074jspb.BinaryWriter.prototype.writeRepeatedDouble = function(field, value) { 1075 if (value == null) return; 1076 for (var i = 0; i < value.length; i++) { 1077 this.writeDouble(field, value[i]); 1078 } 1079}; 1080 1081 1082/** 1083 * Writes an array of booleans to the buffer as a repeated bool field. 1084 * @param {number} field The field number. 1085 * @param {?Array.<boolean>} value The array of ints to write. 1086 */ 1087jspb.BinaryWriter.prototype.writeRepeatedBool = function(field, value) { 1088 if (value == null) return; 1089 for (var i = 0; i < value.length; i++) { 1090 this.writeBool(field, value[i]); 1091 } 1092}; 1093 1094 1095/** 1096 * Writes an array of enums to the buffer as a repeated enum field. 1097 * @param {number} field The field number. 1098 * @param {?Array.<number>} value The array of ints to write. 1099 */ 1100jspb.BinaryWriter.prototype.writeRepeatedEnum = function(field, value) { 1101 if (value == null) return; 1102 for (var i = 0; i < value.length; i++) { 1103 this.writeEnum(field, value[i]); 1104 } 1105}; 1106 1107 1108/** 1109 * Writes an array of strings to the buffer as a repeated string field. 1110 * @param {number} field The field number. 1111 * @param {?Array.<string>} value The array of strings to write. 1112 */ 1113jspb.BinaryWriter.prototype.writeRepeatedString = function(field, value) { 1114 if (value == null) return; 1115 for (var i = 0; i < value.length; i++) { 1116 this.writeString(field, value[i]); 1117 } 1118}; 1119 1120 1121/** 1122 * Writes an array of arbitrary byte fields to the buffer. 1123 * @param {number} field The field number. 1124 * @param {?Array.<!jspb.ByteSource>} value The arrays of arrays of bytes to 1125 * write. 1126 */ 1127jspb.BinaryWriter.prototype.writeRepeatedBytes = function(field, value) { 1128 if (value == null) return; 1129 for (var i = 0; i < value.length; i++) { 1130 this.writeBytes(field, value[i]); 1131 } 1132}; 1133 1134 1135/** 1136 * Writes an array of messages to the buffer. 1137 * @template MessageType 1138 * @param {number} field The field number. 1139 * @param {?Array.<MessageType>} value The array of messages to 1140 * write. 1141 * @param {function(MessageType, !jspb.BinaryWriter)} writerCallback 1142 * Will be invoked with the value to write and the writer to write it with. 1143 */ 1144jspb.BinaryWriter.prototype.writeRepeatedMessage = function( 1145 field, value, writerCallback) { 1146 if (value == null) return; 1147 for (var i = 0; i < value.length; i++) { 1148 var bookmark = this.beginDelimited_(field); 1149 writerCallback(value[i], this); 1150 this.endDelimited_(bookmark); 1151 } 1152}; 1153 1154 1155/** 1156 * Writes an array of group messages to the buffer. 1157 * @template MessageType 1158 * @param {number} field The field number. 1159 * @param {?Array.<MessageType>} value The array of messages to 1160 * write. 1161 * @param {function(MessageType, !jspb.BinaryWriter)} writerCallback 1162 * Will be invoked with the value to write and the writer to write it with. 1163 */ 1164jspb.BinaryWriter.prototype.writeRepeatedGroup = function( 1165 field, value, writerCallback) { 1166 if (value == null) return; 1167 for (var i = 0; i < value.length; i++) { 1168 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.START_GROUP); 1169 writerCallback(value[i], this); 1170 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.END_GROUP); 1171 } 1172}; 1173 1174 1175/** 1176 * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to 1177 * the buffer. 1178 * @param {number} field The field number. 1179 * @param {?Array.<string>} value The array of hashes to write. 1180 */ 1181jspb.BinaryWriter.prototype.writeRepeatedFixedHash64 = 1182 function(field, value) { 1183 if (value == null) return; 1184 for (var i = 0; i < value.length; i++) { 1185 this.writeFixedHash64(field, value[i]); 1186 } 1187}; 1188 1189 1190/** 1191 * Writes a repeated 64-bit hash string field (8 characters @ 8 bits of data 1192 * each) to the buffer. 1193 * @param {number} field The field number. 1194 * @param {?Array.<string>} value The array of hashes to write. 1195 */ 1196jspb.BinaryWriter.prototype.writeRepeatedVarintHash64 = 1197 function(field, value) { 1198 if (value == null) return; 1199 for (var i = 0; i < value.length; i++) { 1200 this.writeVarintHash64(field, value[i]); 1201 } 1202}; 1203 1204 1205/** 1206 * Writes an array of numbers to the buffer as a packed varint field. 1207 * @param {number} field The field number. 1208 * @param {?Array.<number>} value The array of ints to write. 1209 * @private 1210 */ 1211jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_ = function( 1212 field, value) { 1213 if (value == null || !value.length) return; 1214 var bookmark = this.beginDelimited_(field); 1215 for (var i = 0; i < value.length; i++) { 1216 this.encoder_.writeUnsignedVarint32(value[i]); 1217 } 1218 this.endDelimited_(bookmark); 1219}; 1220 1221 1222/** 1223 * Writes an array of numbers to the buffer as a packed varint field. 1224 * @param {number} field The field number. 1225 * @param {?Array.<number>} value The array of ints to write. 1226 * @private 1227 */ 1228jspb.BinaryWriter.prototype.writePackedSignedVarint32_ = function( 1229 field, value) { 1230 if (value == null || !value.length) return; 1231 var bookmark = this.beginDelimited_(field); 1232 for (var i = 0; i < value.length; i++) { 1233 this.encoder_.writeSignedVarint32(value[i]); 1234 } 1235 this.endDelimited_(bookmark); 1236}; 1237 1238 1239/** 1240 * Writes an array of numbers to the buffer as a packed varint field. 1241 * @param {number} field The field number. 1242 * @param {?Array.<number>} value The array of ints to write. 1243 * @private 1244 */ 1245jspb.BinaryWriter.prototype.writePackedUnsignedVarint64_ = function( 1246 field, value) { 1247 if (value == null || !value.length) return; 1248 var bookmark = this.beginDelimited_(field); 1249 for (var i = 0; i < value.length; i++) { 1250 this.encoder_.writeUnsignedVarint64(value[i]); 1251 } 1252 this.endDelimited_(bookmark); 1253}; 1254 1255 1256/** 1257 * Writes an array of numbers to the buffer as a packed varint field. 1258 * @param {number} field The field number. 1259 * @param {?Array.<number>} value The array of ints to write. 1260 * @private 1261 */ 1262jspb.BinaryWriter.prototype.writePackedSignedVarint64_ = function( 1263 field, value) { 1264 if (value == null || !value.length) return; 1265 var bookmark = this.beginDelimited_(field); 1266 for (var i = 0; i < value.length; i++) { 1267 this.encoder_.writeSignedVarint64(value[i]); 1268 } 1269 this.endDelimited_(bookmark); 1270}; 1271 1272 1273/** 1274 * Writes an array of numbers to the buffer as a packed zigzag field. 1275 * @param {number} field The field number. 1276 * @param {?Array.<number>} value The array of ints to write. 1277 * @private 1278 */ 1279jspb.BinaryWriter.prototype.writePackedZigzag32_ = function(field, value) { 1280 if (value == null || !value.length) return; 1281 var bookmark = this.beginDelimited_(field); 1282 for (var i = 0; i < value.length; i++) { 1283 this.encoder_.writeZigzagVarint32(value[i]); 1284 } 1285 this.endDelimited_(bookmark); 1286}; 1287 1288 1289/** 1290 * Writes an array of numbers to the buffer as a packed zigzag field. 1291 * @param {number} field The field number. 1292 * @param {?Array.<number>} value The array of ints to write. 1293 * @private 1294 */ 1295jspb.BinaryWriter.prototype.writePackedZigzag64_ = function(field, value) { 1296 if (value == null || !value.length) return; 1297 var bookmark = this.beginDelimited_(field); 1298 for (var i = 0; i < value.length; i++) { 1299 this.encoder_.writeZigzagVarint64(value[i]); 1300 } 1301 this.endDelimited_(bookmark); 1302}; 1303 1304 1305/** 1306 * Writes an array of numbers to the buffer as a packed 32-bit int field. 1307 * @param {number} field The field number. 1308 * @param {?Array.<number>} value The array of ints to write. 1309 */ 1310jspb.BinaryWriter.prototype.writePackedInt32 = 1311 jspb.BinaryWriter.prototype.writePackedSignedVarint32_; 1312 1313 1314/** 1315 * Writes an array of numbers represented as strings to the buffer as a packed 1316 * 32-bit int field. 1317 * @param {number} field 1318 * @param {?Array.<string>} value 1319 */ 1320jspb.BinaryWriter.prototype.writePackedInt32String = function(field, value) { 1321 if (value == null || !value.length) return; 1322 var bookmark = this.beginDelimited_(field); 1323 for (var i = 0; i < value.length; i++) { 1324 this.encoder_.writeSignedVarint32(parseInt(value[i], 10)); 1325 } 1326 this.endDelimited_(bookmark); 1327}; 1328 1329 1330/** 1331 * Writes an array of numbers to the buffer as a packed 64-bit int field. 1332 * @param {number} field The field number. 1333 * @param {?Array.<number>} value The array of ints to write. 1334 */ 1335jspb.BinaryWriter.prototype.writePackedInt64 = 1336 jspb.BinaryWriter.prototype.writePackedSignedVarint64_; 1337 1338 1339/** 1340 * Writes an array of numbers represented as strings to the buffer as a packed 1341 * 64-bit int field. 1342 * @param {number} field 1343 * @param {?Array.<string>} value 1344 */ 1345jspb.BinaryWriter.prototype.writePackedInt64String = 1346 function(field, value) { 1347 if (value == null || !value.length) return; 1348 var bookmark = this.beginDelimited_(field); 1349 for (var i = 0; i < value.length; i++) { 1350 var num = jspb.arith.Int64.fromString(value[i]); 1351 this.encoder_.writeSplitVarint64(num.lo, num.hi); 1352 } 1353 this.endDelimited_(bookmark); 1354}; 1355 1356 1357/** 1358 * Writes an array numbers to the buffer as a packed unsigned 32-bit int field. 1359 * @param {number} field The field number. 1360 * @param {?Array.<number>} value The array of ints to write. 1361 */ 1362jspb.BinaryWriter.prototype.writePackedUint32 = 1363 jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_; 1364 1365 1366/** 1367 * Writes an array of numbers represented as strings to the buffer as a packed 1368 * unsigned 32-bit int field. 1369 * @param {number} field 1370 * @param {?Array.<string>} value 1371 */ 1372jspb.BinaryWriter.prototype.writePackedUint32String = 1373 function(field, value) { 1374 if (value == null || !value.length) return; 1375 var bookmark = this.beginDelimited_(field); 1376 for (var i = 0; i < value.length; i++) { 1377 this.encoder_.writeUnsignedVarint32(parseInt(value[i], 10)); 1378 } 1379 this.endDelimited_(bookmark); 1380}; 1381 1382 1383/** 1384 * Writes an array numbers to the buffer as a packed unsigned 64-bit int field. 1385 * @param {number} field The field number. 1386 * @param {?Array.<number>} value The array of ints to write. 1387 */ 1388jspb.BinaryWriter.prototype.writePackedUint64 = 1389 jspb.BinaryWriter.prototype.writePackedUnsignedVarint64_; 1390 1391 1392/** 1393 * Writes an array of numbers represented as strings to the buffer as a packed 1394 * unsigned 64-bit int field. 1395 * @param {number} field 1396 * @param {?Array.<string>} value 1397 */ 1398jspb.BinaryWriter.prototype.writePackedUint64String = 1399 function(field, value) { 1400 if (value == null || !value.length) return; 1401 var bookmark = this.beginDelimited_(field); 1402 for (var i = 0; i < value.length; i++) { 1403 var num = jspb.arith.UInt64.fromString(value[i]); 1404 this.encoder_.writeSplitVarint64(num.lo, num.hi); 1405 } 1406 this.endDelimited_(bookmark); 1407}; 1408 1409 1410/** 1411 * Writes an array numbers to the buffer as a packed signed 32-bit int field. 1412 * @param {number} field The field number. 1413 * @param {?Array.<number>} value The array of ints to write. 1414 */ 1415jspb.BinaryWriter.prototype.writePackedSint32 = 1416 jspb.BinaryWriter.prototype.writePackedZigzag32_; 1417 1418 1419/** 1420 * Writes an array numbers to the buffer as a packed signed 64-bit int field. 1421 * @param {number} field The field number. 1422 * @param {?Array.<number>} value The array of ints to write. 1423 */ 1424jspb.BinaryWriter.prototype.writePackedSint64 = 1425 jspb.BinaryWriter.prototype.writePackedZigzag64_; 1426 1427 1428/** 1429 * Writes an array of numbers to the buffer as a packed fixed32 field. 1430 * @param {number} field The field number. 1431 * @param {?Array.<number>} value The array of ints to write. 1432 */ 1433jspb.BinaryWriter.prototype.writePackedFixed32 = function(field, value) { 1434 if (value == null || !value.length) return; 1435 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1436 this.encoder_.writeUnsignedVarint32(value.length * 4); 1437 for (var i = 0; i < value.length; i++) { 1438 this.encoder_.writeUint32(value[i]); 1439 } 1440}; 1441 1442 1443/** 1444 * Writes an array of numbers to the buffer as a packed fixed64 field. 1445 * @param {number} field The field number. 1446 * @param {?Array.<number>} value The array of ints to write. 1447 */ 1448jspb.BinaryWriter.prototype.writePackedFixed64 = function(field, value) { 1449 if (value == null || !value.length) return; 1450 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1451 this.encoder_.writeUnsignedVarint32(value.length * 8); 1452 for (var i = 0; i < value.length; i++) { 1453 this.encoder_.writeUint64(value[i]); 1454 } 1455}; 1456 1457 1458/** 1459 * Writes an array of numbers to the buffer as a packed sfixed32 field. 1460 * @param {number} field The field number. 1461 * @param {?Array.<number>} value The array of ints to write. 1462 */ 1463jspb.BinaryWriter.prototype.writePackedSfixed32 = function(field, value) { 1464 if (value == null || !value.length) return; 1465 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1466 this.encoder_.writeUnsignedVarint32(value.length * 4); 1467 for (var i = 0; i < value.length; i++) { 1468 this.encoder_.writeInt32(value[i]); 1469 } 1470}; 1471 1472 1473/** 1474 * Writes an array of numbers to the buffer as a packed sfixed64 field. 1475 * @param {number} field The field number. 1476 * @param {?Array.<number>} value The array of ints to write. 1477 */ 1478jspb.BinaryWriter.prototype.writePackedSfixed64 = function(field, value) { 1479 if (value == null || !value.length) return; 1480 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1481 this.encoder_.writeUnsignedVarint32(value.length * 8); 1482 for (var i = 0; i < value.length; i++) { 1483 this.encoder_.writeInt64(value[i]); 1484 } 1485}; 1486 1487 1488/** 1489 * Writes an array of numbers to the buffer as a packed float field. 1490 * @param {number} field The field number. 1491 * @param {?Array.<number>} value The array of ints to write. 1492 */ 1493jspb.BinaryWriter.prototype.writePackedFloat = function(field, value) { 1494 if (value == null || !value.length) return; 1495 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1496 this.encoder_.writeUnsignedVarint32(value.length * 4); 1497 for (var i = 0; i < value.length; i++) { 1498 this.encoder_.writeFloat(value[i]); 1499 } 1500}; 1501 1502 1503/** 1504 * Writes an array of numbers to the buffer as a packed double field. 1505 * @param {number} field The field number. 1506 * @param {?Array.<number>} value The array of ints to write. 1507 */ 1508jspb.BinaryWriter.prototype.writePackedDouble = function(field, value) { 1509 if (value == null || !value.length) return; 1510 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1511 this.encoder_.writeUnsignedVarint32(value.length * 8); 1512 for (var i = 0; i < value.length; i++) { 1513 this.encoder_.writeDouble(value[i]); 1514 } 1515}; 1516 1517 1518/** 1519 * Writes an array of booleans to the buffer as a packed bool field. 1520 * @param {number} field The field number. 1521 * @param {?Array.<boolean>} value The array of ints to write. 1522 */ 1523jspb.BinaryWriter.prototype.writePackedBool = function(field, value) { 1524 if (value == null || !value.length) return; 1525 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1526 this.encoder_.writeUnsignedVarint32(value.length); 1527 for (var i = 0; i < value.length; i++) { 1528 this.encoder_.writeBool(value[i]); 1529 } 1530}; 1531 1532 1533/** 1534 * Writes an array of enums to the buffer as a packed enum field. 1535 * @param {number} field The field number. 1536 * @param {?Array.<number>} value The array of ints to write. 1537 */ 1538jspb.BinaryWriter.prototype.writePackedEnum = function(field, value) { 1539 if (value == null || !value.length) return; 1540 var bookmark = this.beginDelimited_(field); 1541 for (var i = 0; i < value.length; i++) { 1542 this.encoder_.writeEnum(value[i]); 1543 } 1544 this.endDelimited_(bookmark); 1545}; 1546 1547 1548/** 1549 * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to 1550 * the buffer. 1551 * @param {number} field The field number. 1552 * @param {?Array.<string>} value The array of hashes to write. 1553 */ 1554jspb.BinaryWriter.prototype.writePackedFixedHash64 = function(field, value) { 1555 if (value == null || !value.length) return; 1556 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1557 this.encoder_.writeUnsignedVarint32(value.length * 8); 1558 for (var i = 0; i < value.length; i++) { 1559 this.encoder_.writeFixedHash64(value[i]); 1560 } 1561}; 1562 1563 1564/** 1565 * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to 1566 * the buffer. 1567 * @param {number} field The field number. 1568 * @param {?Array.<string>} value The array of hashes to write. 1569 */ 1570jspb.BinaryWriter.prototype.writePackedVarintHash64 = function(field, value) { 1571 if (value == null || !value.length) return; 1572 var bookmark = this.beginDelimited_(field); 1573 for (var i = 0; i < value.length; i++) { 1574 this.encoder_.writeVarintHash64(value[i]); 1575 } 1576 this.endDelimited_(bookmark); 1577}; 1578