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 * @template MessageType 721 * @param {number} field The field number. 722 * @param {?MessageType} value The message to write. 723 * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value 724 * to write and the writer to write it with. 725 */ 726jspb.BinaryWriter.prototype.writeMessage = function( 727 field, value, writerCallback) { 728 if (value == null) return; 729 var bookmark = this.beginDelimited_(field); 730 writerCallback(value, this); 731 this.endDelimited_(bookmark); 732}; 733 734 735/** 736 * Writes a group message to the buffer. 737 * 738 * @template MessageType 739 * @param {number} field The field number. 740 * @param {?MessageType} value The message to write, wrapped with START_GROUP / 741 * END_GROUP tags. Will be a no-op if 'value' is null. 742 * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value 743 * to write and the writer to write it with. 744 */ 745jspb.BinaryWriter.prototype.writeGroup = function( 746 field, value, writerCallback) { 747 if (value == null) return; 748 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.START_GROUP); 749 writerCallback(value, this); 750 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.END_GROUP); 751}; 752 753 754/** 755 * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to 756 * the buffer. 757 * @param {number} field The field number. 758 * @param {string?} value The hash string. 759 */ 760jspb.BinaryWriter.prototype.writeFixedHash64 = function(field, value) { 761 if (value == null) return; 762 goog.asserts.assert(value.length == 8); 763 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64); 764 this.encoder_.writeFixedHash64(value); 765}; 766 767 768/** 769 * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to 770 * the buffer. 771 * @param {number} field The field number. 772 * @param {string?} value The hash string. 773 */ 774jspb.BinaryWriter.prototype.writeVarintHash64 = function(field, value) { 775 if (value == null) return; 776 goog.asserts.assert(value.length == 8); 777 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT); 778 this.encoder_.writeVarintHash64(value); 779}; 780 781 782/** 783 * Writes an array of numbers to the buffer as a repeated varint field. 784 * @param {number} field The field number. 785 * @param {?Array.<number>} value The array of ints to write. 786 * @private 787 */ 788jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint32_ = 789 function(field, value) { 790 if (value == null) return; 791 for (var i = 0; i < value.length; i++) { 792 this.writeUnsignedVarint32_(field, value[i]); 793 } 794}; 795 796 797/** 798 * Writes an array of numbers to the buffer as a repeated varint field. 799 * @param {number} field The field number. 800 * @param {?Array.<number>} value The array of ints to write. 801 * @private 802 */ 803jspb.BinaryWriter.prototype.writeRepeatedSignedVarint32_ = 804 function(field, value) { 805 if (value == null) return; 806 for (var i = 0; i < value.length; i++) { 807 this.writeSignedVarint32_(field, value[i]); 808 } 809}; 810 811 812/** 813 * Writes an array of numbers to the buffer as a repeated varint field. 814 * @param {number} field The field number. 815 * @param {?Array.<number>} value The array of ints to write. 816 * @private 817 */ 818jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint64_ = 819 function(field, value) { 820 if (value == null) return; 821 for (var i = 0; i < value.length; i++) { 822 this.writeUnsignedVarint64_(field, value[i]); 823 } 824}; 825 826 827/** 828 * Writes an array of numbers to the buffer as a repeated varint field. 829 * @param {number} field The field number. 830 * @param {?Array.<number>} value The array of ints to write. 831 * @private 832 */ 833jspb.BinaryWriter.prototype.writeRepeatedSignedVarint64_ = 834 function(field, value) { 835 if (value == null) return; 836 for (var i = 0; i < value.length; i++) { 837 this.writeSignedVarint64_(field, value[i]); 838 } 839}; 840 841 842/** 843 * Writes an array of numbers to the buffer as a repeated zigzag field. 844 * @param {number} field The field number. 845 * @param {?Array.<number>} value The array of ints to write. 846 * @private 847 */ 848jspb.BinaryWriter.prototype.writeRepeatedZigzag32_ = function(field, value) { 849 if (value == null) return; 850 for (var i = 0; i < value.length; i++) { 851 this.writeZigzagVarint32_(field, value[i]); 852 } 853}; 854 855 856/** 857 * Writes an array of numbers to the buffer as a repeated zigzag field. 858 * @param {number} field The field number. 859 * @param {?Array.<number>} value The array of ints to write. 860 * @private 861 */ 862jspb.BinaryWriter.prototype.writeRepeatedZigzag_ = function(field, value) { 863 if (value == null) return; 864 for (var i = 0; i < value.length; i++) { 865 this.writeZigzagVarint64_(field, value[i]); 866 } 867}; 868 869 870/** 871 * Writes an array of numbers to the buffer as a repeated 32-bit int field. 872 * @param {number} field The field number. 873 * @param {?Array.<number>} value The array of ints to write. 874 */ 875jspb.BinaryWriter.prototype.writeRepeatedInt32 = 876 jspb.BinaryWriter.prototype.writeRepeatedSignedVarint32_; 877 878 879/** 880 * Writes an array of numbers formatted as strings to the buffer as a repeated 881 * 32-bit int field. 882 * @param {number} field The field number. 883 * @param {?Array.<string>} value The array of ints to write. 884 */ 885jspb.BinaryWriter.prototype.writeRepeatedInt32String = 886 function(field, value) { 887 if (value == null) return; 888 for (var i = 0; i < value.length; i++) { 889 this.writeInt32String(field, value[i]); 890 } 891}; 892 893 894/** 895 * Writes an array of numbers to the buffer as a repeated 64-bit int field. 896 * @param {number} field The field number. 897 * @param {?Array.<number>} value The array of ints to write. 898 */ 899jspb.BinaryWriter.prototype.writeRepeatedInt64 = 900 jspb.BinaryWriter.prototype.writeRepeatedSignedVarint64_; 901 902 903/** 904 * Writes an array of numbers formatted as strings to the buffer as a repeated 905 * 64-bit int field. 906 * @param {number} field The field number. 907 * @param {?Array.<string>} value The array of ints to write. 908 */ 909jspb.BinaryWriter.prototype.writeRepeatedInt64String = 910 function(field, value) { 911 if (value == null) return; 912 for (var i = 0; i < value.length; i++) { 913 this.writeInt64String(field, value[i]); 914 } 915}; 916 917 918/** 919 * Writes an array numbers to the buffer as a repeated unsigned 32-bit int 920 * field. 921 * @param {number} field The field number. 922 * @param {?Array.<number>} value The array of ints to write. 923 */ 924jspb.BinaryWriter.prototype.writeRepeatedUint32 = 925 jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint32_; 926 927 928/** 929 * Writes an array of numbers formatted as strings to the buffer as a repeated 930 * unsigned 32-bit int field. 931 * @param {number} field The field number. 932 * @param {?Array.<string>} value The array of ints to write. 933 */ 934jspb.BinaryWriter.prototype.writeRepeatedUint32String = 935 function(field, value) { 936 if (value == null) return; 937 for (var i = 0; i < value.length; i++) { 938 this.writeUint32String(field, value[i]); 939 } 940}; 941 942 943/** 944 * Writes an array numbers to the buffer as a repeated unsigned 64-bit int 945 * field. 946 * @param {number} field The field number. 947 * @param {?Array.<number>} value The array of ints to write. 948 */ 949jspb.BinaryWriter.prototype.writeRepeatedUint64 = 950 jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint64_; 951 952 953/** 954 * Writes an array of numbers formatted as strings to the buffer as a repeated 955 * unsigned 64-bit int field. 956 * @param {number} field The field number. 957 * @param {?Array.<string>} value The array of ints to write. 958 */ 959jspb.BinaryWriter.prototype.writeRepeatedUint64String = 960 function(field, value) { 961 if (value == null) return; 962 for (var i = 0; i < value.length; i++) { 963 this.writeUint64String(field, value[i]); 964 } 965}; 966 967 968/** 969 * Writes an array numbers to the buffer as a repeated signed 32-bit int field. 970 * @param {number} field The field number. 971 * @param {?Array.<number>} value The array of ints to write. 972 */ 973jspb.BinaryWriter.prototype.writeRepeatedSint32 = 974 jspb.BinaryWriter.prototype.writeRepeatedZigzag32_; 975 976 977/** 978 * Writes an array numbers to the buffer as a repeated signed 64-bit int field. 979 * @param {number} field The field number. 980 * @param {?Array.<number>} value The array of ints to write. 981 */ 982jspb.BinaryWriter.prototype.writeRepeatedSint64 = 983 jspb.BinaryWriter.prototype.writeRepeatedZigzag_; 984 985 986/** 987 * Writes an array of numbers to the buffer as a repeated fixed32 field. This 988 * works for both signed and unsigned fixed32s. 989 * @param {number} field The field number. 990 * @param {?Array.<number>} value The array of ints to write. 991 */ 992jspb.BinaryWriter.prototype.writeRepeatedFixed32 = function(field, value) { 993 if (value == null) return; 994 for (var i = 0; i < value.length; i++) { 995 this.writeFixed32(field, value[i]); 996 } 997}; 998 999 1000/** 1001 * Writes an array of numbers to the buffer as a repeated fixed64 field. This 1002 * works for both signed and unsigned fixed64s. 1003 * @param {number} field The field number. 1004 * @param {?Array.<number>} value The array of ints to write. 1005 */ 1006jspb.BinaryWriter.prototype.writeRepeatedFixed64 = function(field, value) { 1007 if (value == null) return; 1008 for (var i = 0; i < value.length; i++) { 1009 this.writeFixed64(field, value[i]); 1010 } 1011}; 1012 1013 1014/** 1015 * Writes an array of numbers to the buffer as a repeated sfixed32 field. 1016 * @param {number} field The field number. 1017 * @param {?Array.<number>} value The array of ints to write. 1018 */ 1019jspb.BinaryWriter.prototype.writeRepeatedSfixed32 = function(field, value) { 1020 if (value == null) return; 1021 for (var i = 0; i < value.length; i++) { 1022 this.writeSfixed32(field, value[i]); 1023 } 1024}; 1025 1026 1027/** 1028 * Writes an array of numbers to the buffer as a repeated sfixed64 field. 1029 * @param {number} field The field number. 1030 * @param {?Array.<number>} value The array of ints to write. 1031 */ 1032jspb.BinaryWriter.prototype.writeRepeatedSfixed64 = function(field, value) { 1033 if (value == null) return; 1034 for (var i = 0; i < value.length; i++) { 1035 this.writeSfixed64(field, value[i]); 1036 } 1037}; 1038 1039 1040/** 1041 * Writes an array of numbers to the buffer as a repeated float field. 1042 * @param {number} field The field number. 1043 * @param {?Array.<number>} value The array of ints to write. 1044 */ 1045jspb.BinaryWriter.prototype.writeRepeatedFloat = function(field, value) { 1046 if (value == null) return; 1047 for (var i = 0; i < value.length; i++) { 1048 this.writeFloat(field, value[i]); 1049 } 1050}; 1051 1052 1053/** 1054 * Writes an array of numbers to the buffer as a repeated double field. 1055 * @param {number} field The field number. 1056 * @param {?Array.<number>} value The array of ints to write. 1057 */ 1058jspb.BinaryWriter.prototype.writeRepeatedDouble = function(field, value) { 1059 if (value == null) return; 1060 for (var i = 0; i < value.length; i++) { 1061 this.writeDouble(field, value[i]); 1062 } 1063}; 1064 1065 1066/** 1067 * Writes an array of booleans to the buffer as a repeated bool field. 1068 * @param {number} field The field number. 1069 * @param {?Array.<boolean>} value The array of ints to write. 1070 */ 1071jspb.BinaryWriter.prototype.writeRepeatedBool = function(field, value) { 1072 if (value == null) return; 1073 for (var i = 0; i < value.length; i++) { 1074 this.writeBool(field, value[i]); 1075 } 1076}; 1077 1078 1079/** 1080 * Writes an array of enums to the buffer as a repeated enum field. 1081 * @param {number} field The field number. 1082 * @param {?Array.<number>} value The array of ints to write. 1083 */ 1084jspb.BinaryWriter.prototype.writeRepeatedEnum = function(field, value) { 1085 if (value == null) return; 1086 for (var i = 0; i < value.length; i++) { 1087 this.writeEnum(field, value[i]); 1088 } 1089}; 1090 1091 1092/** 1093 * Writes an array of strings to the buffer as a repeated string field. 1094 * @param {number} field The field number. 1095 * @param {?Array.<string>} value The array of strings to write. 1096 */ 1097jspb.BinaryWriter.prototype.writeRepeatedString = function(field, value) { 1098 if (value == null) return; 1099 for (var i = 0; i < value.length; i++) { 1100 this.writeString(field, value[i]); 1101 } 1102}; 1103 1104 1105/** 1106 * Writes an array of arbitrary byte fields to the buffer. 1107 * @param {number} field The field number. 1108 * @param {?Array.<!jspb.ByteSource>} value The arrays of arrays of bytes to 1109 * write. 1110 */ 1111jspb.BinaryWriter.prototype.writeRepeatedBytes = function(field, value) { 1112 if (value == null) return; 1113 for (var i = 0; i < value.length; i++) { 1114 this.writeBytes(field, value[i]); 1115 } 1116}; 1117 1118 1119/** 1120 * Writes an array of messages to the buffer. 1121 * @template MessageType 1122 * @param {number} field The field number. 1123 * @param {?Array.<MessageType>} value The array of messages to 1124 * write. 1125 * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value 1126 * to write and the writer to write it with. 1127 */ 1128jspb.BinaryWriter.prototype.writeRepeatedMessage = function( 1129 field, value, writerCallback) { 1130 if (value == null) return; 1131 for (var i = 0; i < value.length; i++) { 1132 var bookmark = this.beginDelimited_(field); 1133 writerCallback(value[i], this); 1134 this.endDelimited_(bookmark); 1135 } 1136}; 1137 1138 1139/** 1140 * Writes an array of group messages to the buffer. 1141 * @template MessageType 1142 * @param {number} field The field number. 1143 * @param {?Array.<MessageType>} value The array of messages to 1144 * write. 1145 * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value 1146 * to write and the writer to write it with. 1147 */ 1148jspb.BinaryWriter.prototype.writeRepeatedGroup = function( 1149 field, value, writerCallback) { 1150 if (value == null) return; 1151 for (var i = 0; i < value.length; i++) { 1152 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.START_GROUP); 1153 writerCallback(value[i], this); 1154 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.END_GROUP); 1155 } 1156}; 1157 1158 1159/** 1160 * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to 1161 * the buffer. 1162 * @param {number} field The field number. 1163 * @param {?Array.<string>} value The array of hashes to write. 1164 */ 1165jspb.BinaryWriter.prototype.writeRepeatedFixedHash64 = 1166 function(field, value) { 1167 if (value == null) return; 1168 for (var i = 0; i < value.length; i++) { 1169 this.writeFixedHash64(field, value[i]); 1170 } 1171}; 1172 1173 1174/** 1175 * Writes a repeated 64-bit hash string field (8 characters @ 8 bits of data 1176 * each) to the buffer. 1177 * @param {number} field The field number. 1178 * @param {?Array.<string>} value The array of hashes to write. 1179 */ 1180jspb.BinaryWriter.prototype.writeRepeatedVarintHash64 = 1181 function(field, value) { 1182 if (value == null) return; 1183 for (var i = 0; i < value.length; i++) { 1184 this.writeVarintHash64(field, value[i]); 1185 } 1186}; 1187 1188 1189/** 1190 * Writes an array of numbers to the buffer as a packed varint field. 1191 * @param {number} field The field number. 1192 * @param {?Array.<number>} value The array of ints to write. 1193 * @private 1194 */ 1195jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_ = function( 1196 field, value) { 1197 if (value == null || !value.length) return; 1198 var bookmark = this.beginDelimited_(field); 1199 for (var i = 0; i < value.length; i++) { 1200 this.encoder_.writeUnsignedVarint32(value[i]); 1201 } 1202 this.endDelimited_(bookmark); 1203}; 1204 1205 1206/** 1207 * Writes an array of numbers to the buffer as a packed varint field. 1208 * @param {number} field The field number. 1209 * @param {?Array.<number>} value The array of ints to write. 1210 * @private 1211 */ 1212jspb.BinaryWriter.prototype.writePackedSignedVarint32_ = function( 1213 field, value) { 1214 if (value == null || !value.length) return; 1215 var bookmark = this.beginDelimited_(field); 1216 for (var i = 0; i < value.length; i++) { 1217 this.encoder_.writeSignedVarint32(value[i]); 1218 } 1219 this.endDelimited_(bookmark); 1220}; 1221 1222 1223/** 1224 * Writes an array of numbers to the buffer as a packed varint field. 1225 * @param {number} field The field number. 1226 * @param {?Array.<number>} value The array of ints to write. 1227 * @private 1228 */ 1229jspb.BinaryWriter.prototype.writePackedUnsignedVarint64_ = function( 1230 field, value) { 1231 if (value == null || !value.length) return; 1232 var bookmark = this.beginDelimited_(field); 1233 for (var i = 0; i < value.length; i++) { 1234 this.encoder_.writeUnsignedVarint64(value[i]); 1235 } 1236 this.endDelimited_(bookmark); 1237}; 1238 1239 1240/** 1241 * Writes an array of numbers to the buffer as a packed varint field. 1242 * @param {number} field The field number. 1243 * @param {?Array.<number>} value The array of ints to write. 1244 * @private 1245 */ 1246jspb.BinaryWriter.prototype.writePackedSignedVarint64_ = function( 1247 field, value) { 1248 if (value == null || !value.length) return; 1249 var bookmark = this.beginDelimited_(field); 1250 for (var i = 0; i < value.length; i++) { 1251 this.encoder_.writeSignedVarint64(value[i]); 1252 } 1253 this.endDelimited_(bookmark); 1254}; 1255 1256 1257/** 1258 * Writes an array of numbers to the buffer as a packed zigzag field. 1259 * @param {number} field The field number. 1260 * @param {?Array.<number>} value The array of ints to write. 1261 * @private 1262 */ 1263jspb.BinaryWriter.prototype.writePackedZigzag32_ = function(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_.writeZigzagVarint32(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.writePackedZigzag64_ = 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_.writeZigzagVarint64(value[i]); 1284 } 1285 this.endDelimited_(bookmark); 1286}; 1287 1288 1289/** 1290 * Writes an array of numbers to the buffer as a packed 32-bit int field. 1291 * @param {number} field The field number. 1292 * @param {?Array.<number>} value The array of ints to write. 1293 */ 1294jspb.BinaryWriter.prototype.writePackedInt32 = 1295 jspb.BinaryWriter.prototype.writePackedSignedVarint32_; 1296 1297 1298/** 1299 * Writes an array of numbers represented as strings to the buffer as a packed 1300 * 32-bit int field. 1301 * @param {number} field 1302 * @param {?Array.<string>} value 1303 */ 1304jspb.BinaryWriter.prototype.writePackedInt32String = function(field, value) { 1305 if (value == null || !value.length) return; 1306 var bookmark = this.beginDelimited_(field); 1307 for (var i = 0; i < value.length; i++) { 1308 this.encoder_.writeSignedVarint32(parseInt(value[i], 10)); 1309 } 1310 this.endDelimited_(bookmark); 1311}; 1312 1313 1314/** 1315 * Writes an array of numbers to the buffer as a packed 64-bit int field. 1316 * @param {number} field The field number. 1317 * @param {?Array.<number>} value The array of ints to write. 1318 */ 1319jspb.BinaryWriter.prototype.writePackedInt64 = 1320 jspb.BinaryWriter.prototype.writePackedSignedVarint64_; 1321 1322 1323/** 1324 * Writes an array of numbers represented as strings to the buffer as a packed 1325 * 64-bit int field. 1326 * @param {number} field 1327 * @param {?Array.<string>} value 1328 */ 1329jspb.BinaryWriter.prototype.writePackedInt64String = 1330 function(field, value) { 1331 if (value == null || !value.length) return; 1332 var bookmark = this.beginDelimited_(field); 1333 for (var i = 0; i < value.length; i++) { 1334 var num = jspb.arith.Int64.fromString(value[i]); 1335 this.encoder_.writeSplitVarint64(num.lo, num.hi); 1336 } 1337 this.endDelimited_(bookmark); 1338}; 1339 1340 1341/** 1342 * Writes an array numbers to the buffer as a packed unsigned 32-bit int field. 1343 * @param {number} field The field number. 1344 * @param {?Array.<number>} value The array of ints to write. 1345 */ 1346jspb.BinaryWriter.prototype.writePackedUint32 = 1347 jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_; 1348 1349 1350/** 1351 * Writes an array of numbers represented as strings to the buffer as a packed 1352 * unsigned 32-bit int field. 1353 * @param {number} field 1354 * @param {?Array.<string>} value 1355 */ 1356jspb.BinaryWriter.prototype.writePackedUint32String = 1357 function(field, value) { 1358 if (value == null || !value.length) return; 1359 var bookmark = this.beginDelimited_(field); 1360 for (var i = 0; i < value.length; i++) { 1361 this.encoder_.writeUnsignedVarint32(parseInt(value[i], 10)); 1362 } 1363 this.endDelimited_(bookmark); 1364}; 1365 1366 1367/** 1368 * Writes an array numbers to the buffer as a packed unsigned 64-bit int field. 1369 * @param {number} field The field number. 1370 * @param {?Array.<number>} value The array of ints to write. 1371 */ 1372jspb.BinaryWriter.prototype.writePackedUint64 = 1373 jspb.BinaryWriter.prototype.writePackedUnsignedVarint64_; 1374 1375 1376/** 1377 * Writes an array of numbers represented as strings to the buffer as a packed 1378 * unsigned 64-bit int field. 1379 * @param {number} field 1380 * @param {?Array.<string>} value 1381 */ 1382jspb.BinaryWriter.prototype.writePackedUint64String = 1383 function(field, value) { 1384 if (value == null || !value.length) return; 1385 var bookmark = this.beginDelimited_(field); 1386 for (var i = 0; i < value.length; i++) { 1387 var num = jspb.arith.UInt64.fromString(value[i]); 1388 this.encoder_.writeSplitVarint64(num.lo, num.hi); 1389 } 1390 this.endDelimited_(bookmark); 1391}; 1392 1393 1394/** 1395 * Writes an array numbers to the buffer as a packed signed 32-bit int field. 1396 * @param {number} field The field number. 1397 * @param {?Array.<number>} value The array of ints to write. 1398 */ 1399jspb.BinaryWriter.prototype.writePackedSint32 = 1400 jspb.BinaryWriter.prototype.writePackedZigzag32_; 1401 1402 1403/** 1404 * Writes an array numbers to the buffer as a packed signed 64-bit int field. 1405 * @param {number} field The field number. 1406 * @param {?Array.<number>} value The array of ints to write. 1407 */ 1408jspb.BinaryWriter.prototype.writePackedSint64 = 1409 jspb.BinaryWriter.prototype.writePackedZigzag64_; 1410 1411 1412/** 1413 * Writes an array of numbers to the buffer as a packed fixed32 field. 1414 * @param {number} field The field number. 1415 * @param {?Array.<number>} value The array of ints to write. 1416 */ 1417jspb.BinaryWriter.prototype.writePackedFixed32 = function(field, value) { 1418 if (value == null || !value.length) return; 1419 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1420 this.encoder_.writeUnsignedVarint32(value.length * 4); 1421 for (var i = 0; i < value.length; i++) { 1422 this.encoder_.writeUint32(value[i]); 1423 } 1424}; 1425 1426 1427/** 1428 * Writes an array of numbers to the buffer as a packed fixed64 field. 1429 * @param {number} field The field number. 1430 * @param {?Array.<number>} value The array of ints to write. 1431 */ 1432jspb.BinaryWriter.prototype.writePackedFixed64 = function(field, value) { 1433 if (value == null || !value.length) return; 1434 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1435 this.encoder_.writeUnsignedVarint32(value.length * 8); 1436 for (var i = 0; i < value.length; i++) { 1437 this.encoder_.writeUint64(value[i]); 1438 } 1439}; 1440 1441 1442/** 1443 * Writes an array of numbers to the buffer as a packed sfixed32 field. 1444 * @param {number} field The field number. 1445 * @param {?Array.<number>} value The array of ints to write. 1446 */ 1447jspb.BinaryWriter.prototype.writePackedSfixed32 = function(field, value) { 1448 if (value == null || !value.length) return; 1449 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1450 this.encoder_.writeUnsignedVarint32(value.length * 4); 1451 for (var i = 0; i < value.length; i++) { 1452 this.encoder_.writeInt32(value[i]); 1453 } 1454}; 1455 1456 1457/** 1458 * Writes an array of numbers to the buffer as a packed sfixed64 field. 1459 * @param {number} field The field number. 1460 * @param {?Array.<number>} value The array of ints to write. 1461 */ 1462jspb.BinaryWriter.prototype.writePackedSfixed64 = function(field, value) { 1463 if (value == null || !value.length) return; 1464 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1465 this.encoder_.writeUnsignedVarint32(value.length * 8); 1466 for (var i = 0; i < value.length; i++) { 1467 this.encoder_.writeInt64(value[i]); 1468 } 1469}; 1470 1471 1472/** 1473 * Writes an array of numbers to the buffer as a packed float field. 1474 * @param {number} field The field number. 1475 * @param {?Array.<number>} value The array of ints to write. 1476 */ 1477jspb.BinaryWriter.prototype.writePackedFloat = function(field, value) { 1478 if (value == null || !value.length) return; 1479 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1480 this.encoder_.writeUnsignedVarint32(value.length * 4); 1481 for (var i = 0; i < value.length; i++) { 1482 this.encoder_.writeFloat(value[i]); 1483 } 1484}; 1485 1486 1487/** 1488 * Writes an array of numbers to the buffer as a packed double field. 1489 * @param {number} field The field number. 1490 * @param {?Array.<number>} value The array of ints to write. 1491 */ 1492jspb.BinaryWriter.prototype.writePackedDouble = function(field, value) { 1493 if (value == null || !value.length) return; 1494 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1495 this.encoder_.writeUnsignedVarint32(value.length * 8); 1496 for (var i = 0; i < value.length; i++) { 1497 this.encoder_.writeDouble(value[i]); 1498 } 1499}; 1500 1501 1502/** 1503 * Writes an array of booleans to the buffer as a packed bool field. 1504 * @param {number} field The field number. 1505 * @param {?Array.<boolean>} value The array of ints to write. 1506 */ 1507jspb.BinaryWriter.prototype.writePackedBool = function(field, value) { 1508 if (value == null || !value.length) return; 1509 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1510 this.encoder_.writeUnsignedVarint32(value.length); 1511 for (var i = 0; i < value.length; i++) { 1512 this.encoder_.writeBool(value[i]); 1513 } 1514}; 1515 1516 1517/** 1518 * Writes an array of enums to the buffer as a packed enum field. 1519 * @param {number} field The field number. 1520 * @param {?Array.<number>} value The array of ints to write. 1521 */ 1522jspb.BinaryWriter.prototype.writePackedEnum = function(field, value) { 1523 if (value == null || !value.length) return; 1524 var bookmark = this.beginDelimited_(field); 1525 for (var i = 0; i < value.length; i++) { 1526 this.encoder_.writeEnum(value[i]); 1527 } 1528 this.endDelimited_(bookmark); 1529}; 1530 1531 1532/** 1533 * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to 1534 * the buffer. 1535 * @param {number} field The field number. 1536 * @param {?Array.<string>} value The array of hashes to write. 1537 */ 1538jspb.BinaryWriter.prototype.writePackedFixedHash64 = function(field, value) { 1539 if (value == null || !value.length) return; 1540 this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED); 1541 this.encoder_.writeUnsignedVarint32(value.length * 8); 1542 for (var i = 0; i < value.length; i++) { 1543 this.encoder_.writeFixedHash64(value[i]); 1544 } 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.writePackedVarintHash64 = function(field, value) { 1555 if (value == null || !value.length) return; 1556 var bookmark = this.beginDelimited_(field); 1557 for (var i = 0; i < value.length; i++) { 1558 this.encoder_.writeVarintHash64(value[i]); 1559 } 1560 this.endDelimited_(bookmark); 1561}; 1562