writer.js 69 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124
  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. * @fileoverview This file contains utilities for encoding Javascript objects
  32. * into binary, wire-format protocol buffers (in the form of Uint8Arrays) that
  33. * a server can consume directly.
  34. *
  35. * jspb's BinaryWriter class defines methods for efficiently encoding
  36. * Javascript objects into binary, wire-format protocol buffers and supports
  37. * all the fundamental field types used in protocol buffers.
  38. *
  39. * Major caveat 1 - Users of this library _must_ keep their Javascript proto
  40. * parsing code in sync with the original .proto file - presumably you'll be
  41. * using the typed jspb code generator, but if you bypass that you'll need
  42. * to keep things in sync by hand.
  43. *
  44. * Major caveat 2 - Javascript is unable to accurately represent integers
  45. * larger than 2^53 due to its use of a double-precision floating point format
  46. * for all numbers. BinaryWriter does not make any special effort to preserve
  47. * precision for values above this limit - if you need to pass 64-bit integers
  48. * (hash codes, for example) between the client and server without precision
  49. * loss, do _not_ use this library.
  50. *
  51. * Major caveat 3 - This class uses typed arrays and must not be used on older
  52. * browsers that do not support them.
  53. *
  54. * @author aappleby@google.com (Austin Appleby)
  55. */
  56. goog.provide('jspb.BinaryWriter');
  57. goog.require('goog.asserts');
  58. goog.require('goog.crypt.base64');
  59. goog.require('jspb.BinaryConstants');
  60. goog.require('jspb.arith.Int64');
  61. goog.require('jspb.arith.UInt64');
  62. goog.require('jspb.utils');
  63. goog.forwardDeclare('jspb.Message');
  64. /**
  65. * BinaryWriter implements encoders for all the wire types specified in
  66. * https://developers.google.com/protocol-buffers/docs/encoding.
  67. *
  68. * @constructor
  69. * @struct
  70. */
  71. jspb.BinaryWriter = function() {
  72. /**
  73. * Blocks of serialized data that will be concatenated once all messages have
  74. * been written.
  75. * @private {!Array<!Uint8Array|!Array<number>>}
  76. */
  77. this.blocks_ = [];
  78. /**
  79. * Total number of bytes in the blocks_ array. Does _not_ include the temp
  80. * buffer.
  81. * @private {number}
  82. */
  83. this.totalLength_ = 0;
  84. /**
  85. * Temporary buffer holding a message that we're still serializing. When we
  86. * get to a stopping point (either the start of a new submessage, or when we
  87. * need to append a raw Uint8Array), the temp buffer will be added to the
  88. * block array above and a new temp buffer will be created.
  89. * @private {!Array.<number>}
  90. */
  91. this.temp_ = [];
  92. /**
  93. * A stack of bookmarks containing the parent blocks for each message started
  94. * via beginSubMessage(), needed as bookkeeping for endSubMessage().
  95. * TODO(aappleby): Deprecated, users should be calling writeMessage().
  96. * @private {!Array.<!jspb.BinaryWriter.Bookmark_>}
  97. */
  98. this.bookmarks_ = [];
  99. };
  100. /**
  101. * @typedef {{block: !Array.<number>, length: number}}
  102. * @private
  103. */
  104. jspb.BinaryWriter.Bookmark_;
  105. /**
  106. * Saves the current temp buffer in the blocks_ array and starts a new one.
  107. * @return {!Array.<number>} Returns a reference to the old temp buffer.
  108. * @private
  109. */
  110. jspb.BinaryWriter.prototype.saveTempBuffer_ = function() {
  111. var oldTemp = this.temp_;
  112. this.blocks_.push(this.temp_);
  113. this.totalLength_ += this.temp_.length;
  114. this.temp_ = [];
  115. return oldTemp;
  116. };
  117. /**
  118. * Append a typed array of bytes onto the buffer.
  119. *
  120. * @param {!Uint8Array} arr The byte array to append.
  121. * @private
  122. */
  123. jspb.BinaryWriter.prototype.appendUint8Array_ = function(arr) {
  124. if (this.temp_.length) {
  125. this.saveTempBuffer_();
  126. }
  127. this.blocks_.push(arr);
  128. this.totalLength_ += arr.length;
  129. };
  130. /**
  131. * Append an untyped array of bytes onto the buffer.
  132. *
  133. * @param {!Array.<number>} arr The byte array to append.
  134. * @private
  135. */
  136. jspb.BinaryWriter.prototype.appendArray_ = function(arr) {
  137. if (this.temp_.length) {
  138. this.saveTempBuffer_();
  139. }
  140. this.temp_ = arr;
  141. };
  142. /**
  143. * Begins a length-delimited section by writing the field header to the current
  144. * temp buffer and then saving it in the block array. Returns the saved block,
  145. * which we will append the length to in endDelimited_ below.
  146. * @param {number} field
  147. * @return {!jspb.BinaryWriter.Bookmark_}
  148. * @private
  149. */
  150. jspb.BinaryWriter.prototype.beginDelimited_ = function(field) {
  151. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
  152. return {block: this.saveTempBuffer_(), length: this.totalLength_};
  153. };
  154. /**
  155. * Ends a length-delimited block by encoding the _change_ in length of the
  156. * buffer to the parent block and adds the number of bytes needed to encode
  157. * that length to the total byte length. Note that 'parentLength' _must_ be the
  158. * total length _after_ the field header was written in beginDelimited_ above.
  159. * @param {!jspb.BinaryWriter.Bookmark_} bookmark
  160. * @private
  161. */
  162. jspb.BinaryWriter.prototype.endDelimited_ = function(bookmark) {
  163. var messageLength = this.totalLength_ + this.temp_.length - bookmark.length;
  164. goog.asserts.assert(messageLength >= 0);
  165. var bytes = 1;
  166. while (messageLength > 127) {
  167. bookmark.block.push((messageLength & 0x7f) | 0x80);
  168. messageLength = messageLength >>> 7;
  169. bytes++;
  170. }
  171. bookmark.block.push(messageLength);
  172. this.totalLength_ += bytes;
  173. };
  174. /**
  175. * Resets the writer, throwing away any accumulated buffers.
  176. */
  177. jspb.BinaryWriter.prototype.reset = function() {
  178. this.blocks_ = [];
  179. this.temp_ = [];
  180. this.totalLength_ = 0;
  181. this.bookmarks_ = [];
  182. };
  183. /**
  184. * Converts the encoded data into a Uint8Array.
  185. * @return {!Uint8Array}
  186. */
  187. jspb.BinaryWriter.prototype.getResultBuffer = function() {
  188. goog.asserts.assert(this.bookmarks_.length == 0);
  189. var flat = new Uint8Array(this.totalLength_ + this.temp_.length);
  190. var blocks = this.blocks_;
  191. var blockCount = blocks.length;
  192. var offset = 0;
  193. for (var i = 0; i < blockCount; i++) {
  194. var block = blocks[i];
  195. flat.set(block, offset);
  196. offset += block.length;
  197. }
  198. flat.set(this.temp_, offset);
  199. offset += this.temp_.length;
  200. // Post condition: `flattened` must have had every byte written.
  201. goog.asserts.assert(offset == flat.length);
  202. // Replace our block list with the flattened block, which lets GC reclaim
  203. // the temp blocks sooner.
  204. this.blocks_ = [flat];
  205. this.temp_ = [];
  206. return flat;
  207. };
  208. /**
  209. * Converts the encoded data into a bas64-encoded string.
  210. * @return {string}
  211. */
  212. jspb.BinaryWriter.prototype.getResultBase64String = function() {
  213. return goog.crypt.base64.encodeByteArray(this.getResultBuffer());
  214. };
  215. /**
  216. * Begins a new sub-message. The client must call endSubMessage() when they're
  217. * done.
  218. * TODO(aappleby): Deprecated. Move callers to writeMessage().
  219. * @param {number} field The field number of the sub-message.
  220. */
  221. jspb.BinaryWriter.prototype.beginSubMessage = function(field) {
  222. this.bookmarks_.push(this.beginDelimited_(field));
  223. };
  224. /**
  225. * Finishes a sub-message and packs it into the parent messages' buffer.
  226. * TODO(aappleby): Deprecated. Move callers to writeMessage().
  227. */
  228. jspb.BinaryWriter.prototype.endSubMessage = function() {
  229. goog.asserts.assert(this.bookmarks_.length >= 0);
  230. this.endDelimited_(this.bookmarks_.pop());
  231. };
  232. /**
  233. * Encodes a 32-bit unsigned integer into its wire-format varint representation
  234. * and stores it in the buffer.
  235. * @param {number} value The integer to convert.
  236. */
  237. jspb.BinaryWriter.prototype.rawWriteUnsignedVarint32 = function(value) {
  238. goog.asserts.assert(value == Math.floor(value));
  239. while (value > 127) {
  240. this.temp_.push((value & 0x7f) | 0x80);
  241. value = value >>> 7;
  242. }
  243. this.temp_.push(value);
  244. };
  245. /**
  246. * Encodes a 32-bit signed integer into its wire-format varint representation
  247. * and stores it in the buffer.
  248. * @param {number} value The integer to convert.
  249. */
  250. jspb.BinaryWriter.prototype.rawWriteSignedVarint32 = function(value) {
  251. goog.asserts.assert(value == Math.floor(value));
  252. if (value >= 0) {
  253. this.rawWriteUnsignedVarint32(value);
  254. return;
  255. }
  256. // Write nine bytes with a _signed_ right shift so we preserve the sign bit.
  257. for (var i = 0; i < 9; i++) {
  258. this.temp_.push((value & 0x7f) | 0x80);
  259. value = value >> 7;
  260. }
  261. // The above loop writes out 63 bits, so the last byte is always the sign bit
  262. // which is always set for negative numbers.
  263. this.temp_.push(1);
  264. };
  265. /**
  266. * Encodes an unsigned 64-bit integer in 32:32 split representation into its
  267. * wire-format varint representation and stores it in the buffer.
  268. * @param {number} lowBits The low 32 bits of the int.
  269. * @param {number} highBits The high 32 bits of the int.
  270. */
  271. jspb.BinaryWriter.prototype.rawWriteSplitVarint =
  272. function(lowBits, highBits) {
  273. // Break the binary representation into chunks of 7 bits, set the 8th bit
  274. // in each chunk if it's not the final chunk, and append to the result.
  275. while (highBits > 0 || lowBits > 127) {
  276. this.temp_.push((lowBits & 0x7f) | 0x80);
  277. lowBits = ((lowBits >>> 7) | (highBits << 25)) >>> 0;
  278. highBits = highBits >>> 7;
  279. }
  280. this.temp_.push(lowBits);
  281. };
  282. /**
  283. * Encodes a JavaScript integer into its wire-format varint representation and
  284. * stores it in the buffer. Due to the way the varint encoding works this
  285. * behaves correctly for both signed and unsigned integers, though integers
  286. * that are not representable in 64 bits will still be truncated.
  287. * @param {number} value The integer to convert.
  288. */
  289. jspb.BinaryWriter.prototype.rawWriteVarint = function(value) {
  290. goog.asserts.assert(value == Math.floor(value));
  291. jspb.utils.splitInt64(value);
  292. this.rawWriteSplitVarint(jspb.utils.split64Low,
  293. jspb.utils.split64High);
  294. };
  295. /**
  296. * Encodes a jspb.arith.{Int64,UInt64} instance into its wire-format
  297. * varint representation and stores it in the buffer. Due to the way the varint
  298. * encoding works this behaves correctly for both signed and unsigned integers,
  299. * though integers that are not representable in 64 bits will still be
  300. * truncated.
  301. * @param {jspb.arith.Int64|jspb.arith.UInt64} value
  302. */
  303. jspb.BinaryWriter.prototype.rawWriteVarintFromNum = function(value) {
  304. this.rawWriteSplitVarint(value.lo, value.hi);
  305. };
  306. /**
  307. * Encodes a JavaScript integer into its wire-format, zigzag-encoded varint
  308. * representation and stores it in the buffer.
  309. * @param {number} value The integer to convert.
  310. */
  311. jspb.BinaryWriter.prototype.rawWriteZigzagVarint32 = function(value) {
  312. goog.asserts.assert(value == Math.floor(value));
  313. this.rawWriteUnsignedVarint32(((value << 1) ^ (value >> 31)) >>> 0);
  314. };
  315. /**
  316. * Encodes a JavaScript integer into its wire-format, zigzag-encoded varint
  317. * representation and stores it in the buffer. Integers not representable in 64
  318. * bits will be truncated.
  319. * @param {number} value The integer to convert.
  320. */
  321. jspb.BinaryWriter.prototype.rawWriteZigzagVarint = function(value) {
  322. goog.asserts.assert(value == Math.floor(value));
  323. jspb.utils.splitZigzag64(value);
  324. this.rawWriteSplitVarint(jspb.utils.split64Low,
  325. jspb.utils.split64High);
  326. };
  327. /**
  328. * Writes a raw 8-bit unsigned integer to the buffer. Numbers outside the range
  329. * [0,2^8) will be truncated.
  330. * @param {number} value The value to write.
  331. */
  332. jspb.BinaryWriter.prototype.rawWriteUint8 = function(value) {
  333. goog.asserts.assert(value == Math.floor(value));
  334. goog.asserts.assert((value >= 0) && (value < 256));
  335. this.temp_.push((value >>> 0) & 0xFF);
  336. };
  337. /**
  338. * Writes a raw 16-bit unsigned integer to the buffer. Numbers outside the
  339. * range [0,2^16) will be truncated.
  340. * @param {number} value The value to write.
  341. */
  342. jspb.BinaryWriter.prototype.rawWriteUint16 = function(value) {
  343. goog.asserts.assert(value == Math.floor(value));
  344. goog.asserts.assert((value >= 0) && (value < 65536));
  345. this.temp_.push((value >>> 0) & 0xFF);
  346. this.temp_.push((value >>> 8) & 0xFF);
  347. };
  348. /**
  349. * Writes a raw 32-bit unsigned integer to the buffer. Numbers outside the
  350. * range [0,2^32) will be truncated.
  351. * @param {number} value The value to write.
  352. */
  353. jspb.BinaryWriter.prototype.rawWriteUint32 = function(value) {
  354. goog.asserts.assert(value == Math.floor(value));
  355. goog.asserts.assert((value >= 0) &&
  356. (value < jspb.BinaryConstants.TWO_TO_32));
  357. this.temp_.push((value >>> 0) & 0xFF);
  358. this.temp_.push((value >>> 8) & 0xFF);
  359. this.temp_.push((value >>> 16) & 0xFF);
  360. this.temp_.push((value >>> 24) & 0xFF);
  361. };
  362. /**
  363. * Writes a raw 64-bit unsigned integer to the buffer. Numbers outside the
  364. * range [0,2^64) will be truncated.
  365. * @param {number} value The value to write.
  366. */
  367. jspb.BinaryWriter.prototype.rawWriteUint64 = function(value) {
  368. goog.asserts.assert(value == Math.floor(value));
  369. goog.asserts.assert((value >= 0) &&
  370. (value < jspb.BinaryConstants.TWO_TO_64));
  371. jspb.utils.splitUint64(value);
  372. this.rawWriteUint32(jspb.utils.split64Low);
  373. this.rawWriteUint32(jspb.utils.split64High);
  374. };
  375. /**
  376. * Writes a raw 8-bit integer to the buffer. Numbers outside the range
  377. * [-2^7,2^7) will be truncated.
  378. * @param {number} value The value to write.
  379. */
  380. jspb.BinaryWriter.prototype.rawWriteInt8 = function(value) {
  381. goog.asserts.assert(value == Math.floor(value));
  382. goog.asserts.assert((value >= -128) && (value < 128));
  383. this.temp_.push((value >>> 0) & 0xFF);
  384. };
  385. /**
  386. * Writes a raw 16-bit integer to the buffer. Numbers outside the range
  387. * [-2^15,2^15) will be truncated.
  388. * @param {number} value The value to write.
  389. */
  390. jspb.BinaryWriter.prototype.rawWriteInt16 = function(value) {
  391. goog.asserts.assert(value == Math.floor(value));
  392. goog.asserts.assert((value >= -32768) && (value < 32768));
  393. this.temp_.push((value >>> 0) & 0xFF);
  394. this.temp_.push((value >>> 8) & 0xFF);
  395. };
  396. /**
  397. * Writes a raw 32-bit integer to the buffer. Numbers outside the range
  398. * [-2^31,2^31) will be truncated.
  399. * @param {number} value The value to write.
  400. */
  401. jspb.BinaryWriter.prototype.rawWriteInt32 = function(value) {
  402. goog.asserts.assert(value == Math.floor(value));
  403. goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
  404. (value < jspb.BinaryConstants.TWO_TO_31));
  405. this.temp_.push((value >>> 0) & 0xFF);
  406. this.temp_.push((value >>> 8) & 0xFF);
  407. this.temp_.push((value >>> 16) & 0xFF);
  408. this.temp_.push((value >>> 24) & 0xFF);
  409. };
  410. /**
  411. * Writes a raw 64-bit integer to the buffer. Numbers outside the range
  412. * [-2^63,2^63) will be truncated.
  413. * @param {number} value The value to write.
  414. */
  415. jspb.BinaryWriter.prototype.rawWriteInt64 = function(value) {
  416. goog.asserts.assert(value == Math.floor(value));
  417. goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
  418. (value < jspb.BinaryConstants.TWO_TO_63));
  419. jspb.utils.splitInt64(value);
  420. this.rawWriteUint32(jspb.utils.split64Low);
  421. this.rawWriteUint32(jspb.utils.split64High);
  422. };
  423. /**
  424. * Writes a raw single-precision floating point value to the buffer. Numbers
  425. * requiring more than 32 bits of precision will be truncated.
  426. * @param {number} value The value to write.
  427. */
  428. jspb.BinaryWriter.prototype.rawWriteFloat = function(value) {
  429. jspb.utils.splitFloat32(value);
  430. this.rawWriteUint32(jspb.utils.split64Low);
  431. };
  432. /**
  433. * Writes a raw double-precision floating point value to the buffer. As this is
  434. * the native format used by JavaScript, no precision will be lost.
  435. * @param {number} value The value to write.
  436. */
  437. jspb.BinaryWriter.prototype.rawWriteDouble = function(value) {
  438. jspb.utils.splitFloat64(value);
  439. this.rawWriteUint32(jspb.utils.split64Low);
  440. this.rawWriteUint32(jspb.utils.split64High);
  441. };
  442. /**
  443. * Writes a raw boolean value to the buffer as a varint.
  444. * @param {boolean} value The value to write.
  445. */
  446. jspb.BinaryWriter.prototype.rawWriteBool = function(value) {
  447. goog.asserts.assert(goog.isBoolean(value));
  448. this.temp_.push(~~value);
  449. };
  450. /**
  451. * Writes an raw enum value to the buffer as a varint.
  452. * @param {number} value The value to write.
  453. */
  454. jspb.BinaryWriter.prototype.rawWriteEnum = function(value) {
  455. goog.asserts.assert(value == Math.floor(value));
  456. goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
  457. (value < jspb.BinaryConstants.TWO_TO_31));
  458. this.rawWriteSignedVarint32(value);
  459. };
  460. /**
  461. * Writes a raw string value to the buffer.
  462. * @param {string} string The string to write.
  463. */
  464. jspb.BinaryWriter.prototype.rawWriteUtf8String = function(string) {
  465. for (var i = 0; i < string.length; i++) {
  466. this.temp_.push(string.charCodeAt(i));
  467. }
  468. };
  469. /**
  470. * Writes an arbitrary raw byte array to the buffer.
  471. * @param {!Uint8Array} bytes The array of bytes to write.
  472. */
  473. jspb.BinaryWriter.prototype.rawWriteBytes = function(bytes) {
  474. this.appendUint8Array_(bytes);
  475. };
  476. /**
  477. * Writes an arbitrary raw byte array to the buffer.
  478. * @param {!Uint8Array} bytes The array of bytes to write.
  479. * @param {number} start The start of the range to write.
  480. * @param {number} end The end of the range to write.
  481. */
  482. jspb.BinaryWriter.prototype.rawWriteByteRange = function(bytes, start, end) {
  483. this.appendUint8Array_(bytes.subarray(start, end));
  484. };
  485. /**
  486. * Writes a 64-bit hash string (8 characters @ 8 bits of data each) to the
  487. * buffer as a varint.
  488. * @param {string} hash The hash to write.
  489. */
  490. jspb.BinaryWriter.prototype.rawWriteVarintHash64 = function(hash) {
  491. jspb.utils.splitHash64(hash);
  492. this.rawWriteSplitVarint(jspb.utils.split64Low,
  493. jspb.utils.split64High);
  494. };
  495. /**
  496. * Writes a 64-bit hash string (8 characters @ 8 bits of data each) to the
  497. * buffer as a fixed64.
  498. * @param {string} hash The hash to write.
  499. */
  500. jspb.BinaryWriter.prototype.rawWriteFixedHash64 = function(hash) {
  501. jspb.utils.splitHash64(hash);
  502. this.rawWriteUint32(jspb.utils.split64Low);
  503. this.rawWriteUint32(jspb.utils.split64High);
  504. };
  505. /**
  506. * Encodes a (field number, wire type) tuple into a wire-format field header
  507. * and stores it in the buffer as a varint.
  508. * @param {number} field The field number.
  509. * @param {number} wireType The wire-type of the field, as specified in the
  510. * protocol buffer documentation.
  511. * @private
  512. */
  513. jspb.BinaryWriter.prototype.rawWriteFieldHeader_ =
  514. function(field, wireType) {
  515. goog.asserts.assert(field >= 1 && field == Math.floor(field));
  516. var x = field * 8 + wireType;
  517. this.rawWriteUnsignedVarint32(x);
  518. };
  519. /**
  520. * Writes a field of any valid scalar type to the binary stream.
  521. * @param {jspb.BinaryConstants.FieldType} fieldType
  522. * @param {number} field
  523. * @param {jspb.AnyFieldType} value
  524. */
  525. jspb.BinaryWriter.prototype.writeAny = function(fieldType, field, value) {
  526. var fieldTypes = jspb.BinaryConstants.FieldType;
  527. switch (fieldType) {
  528. case fieldTypes.DOUBLE:
  529. this.writeDouble(field, /** @type {number} */(value));
  530. return;
  531. case fieldTypes.FLOAT:
  532. this.writeFloat(field, /** @type {number} */(value));
  533. return;
  534. case fieldTypes.INT64:
  535. this.writeInt64(field, /** @type {number} */(value));
  536. return;
  537. case fieldTypes.UINT64:
  538. this.writeUint64(field, /** @type {number} */(value));
  539. return;
  540. case fieldTypes.INT32:
  541. this.writeInt32(field, /** @type {number} */(value));
  542. return;
  543. case fieldTypes.FIXED64:
  544. this.writeFixed64(field, /** @type {number} */(value));
  545. return;
  546. case fieldTypes.FIXED32:
  547. this.writeFixed32(field, /** @type {number} */(value));
  548. return;
  549. case fieldTypes.BOOL:
  550. this.writeBool(field, /** @type {boolean} */(value));
  551. return;
  552. case fieldTypes.STRING:
  553. this.writeString(field, /** @type {string} */(value));
  554. return;
  555. case fieldTypes.GROUP:
  556. goog.asserts.fail('Group field type not supported in writeAny()');
  557. return;
  558. case fieldTypes.MESSAGE:
  559. goog.asserts.fail('Message field type not supported in writeAny()');
  560. return;
  561. case fieldTypes.BYTES:
  562. this.writeBytes(field, /** @type {?Uint8Array} */(value));
  563. return;
  564. case fieldTypes.UINT32:
  565. this.writeUint32(field, /** @type {number} */(value));
  566. return;
  567. case fieldTypes.ENUM:
  568. this.writeEnum(field, /** @type {number} */(value));
  569. return;
  570. case fieldTypes.SFIXED32:
  571. this.writeSfixed32(field, /** @type {number} */(value));
  572. return;
  573. case fieldTypes.SFIXED64:
  574. this.writeSfixed64(field, /** @type {number} */(value));
  575. return;
  576. case fieldTypes.SINT32:
  577. this.writeSint32(field, /** @type {number} */(value));
  578. return;
  579. case fieldTypes.SINT64:
  580. this.writeSint64(field, /** @type {number} */(value));
  581. return;
  582. case fieldTypes.FHASH64:
  583. this.writeFixedHash64(field, /** @type {string} */(value));
  584. return;
  585. case fieldTypes.VHASH64:
  586. this.writeVarintHash64(field, /** @type {string} */(value));
  587. return;
  588. default:
  589. goog.asserts.fail('Invalid field type in writeAny()');
  590. return;
  591. }
  592. };
  593. /**
  594. * Writes a varint field to the buffer without range checking.
  595. * @param {number} field The field number.
  596. * @param {number?} value The value to write.
  597. * @private
  598. */
  599. jspb.BinaryWriter.prototype.writeUnsignedVarint32_ = function(field, value) {
  600. if (value == null) return;
  601. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
  602. this.rawWriteSignedVarint32(value);
  603. };
  604. /**
  605. * Writes a varint field to the buffer without range checking.
  606. * @param {number} field The field number.
  607. * @param {number?} value The value to write.
  608. * @private
  609. */
  610. jspb.BinaryWriter.prototype.writeSignedVarint32_ = function(field, value) {
  611. if (value == null) return;
  612. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
  613. this.rawWriteSignedVarint32(value);
  614. };
  615. /**
  616. * Writes a varint field to the buffer without range checking.
  617. * @param {number} field The field number.
  618. * @param {number?} value The value to write.
  619. * @private
  620. */
  621. jspb.BinaryWriter.prototype.writeVarint_ = function(field, value) {
  622. if (value == null) return;
  623. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
  624. this.rawWriteVarint(value);
  625. };
  626. /**
  627. * Writes a zigzag varint field to the buffer without range checking.
  628. * @param {number} field The field number.
  629. * @param {number?} value The value to write.
  630. * @private
  631. */
  632. jspb.BinaryWriter.prototype.writeZigzagVarint32_ = function(field, value) {
  633. if (value == null) return;
  634. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
  635. this.rawWriteZigzagVarint32(value);
  636. };
  637. /**
  638. * Writes a zigzag varint field to the buffer without range checking.
  639. * @param {number} field The field number.
  640. * @param {number?} value The value to write.
  641. * @private
  642. */
  643. jspb.BinaryWriter.prototype.writeZigzagVarint_ = function(field, value) {
  644. if (value == null) return;
  645. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
  646. this.rawWriteZigzagVarint(value);
  647. };
  648. /**
  649. * Writes an int32 field to the buffer. Numbers outside the range [-2^31,2^31)
  650. * will be truncated.
  651. * @param {number} field The field number.
  652. * @param {number?} value The value to write.
  653. */
  654. jspb.BinaryWriter.prototype.writeInt32 = function(field, value) {
  655. if (value == null) return;
  656. goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
  657. (value < jspb.BinaryConstants.TWO_TO_31));
  658. this.writeSignedVarint32_(field, value);
  659. };
  660. /**
  661. * Writes an int32 field represented as a string to the buffer. Numbers outside
  662. * the range [-2^31,2^31) will be truncated.
  663. * @param {number} field The field number.
  664. * @param {string?} value The value to write.
  665. */
  666. jspb.BinaryWriter.prototype.writeInt32String = function(field, value) {
  667. if (value == null) return;
  668. var intValue = /** {number} */ parseInt(value, 10);
  669. goog.asserts.assert((intValue >= -jspb.BinaryConstants.TWO_TO_31) &&
  670. (intValue < jspb.BinaryConstants.TWO_TO_31));
  671. this.writeSignedVarint32_(field, intValue);
  672. };
  673. /**
  674. * Writes an int64 field to the buffer. Numbers outside the range [-2^63,2^63)
  675. * will be truncated.
  676. * @param {number} field The field number.
  677. * @param {number?} value The value to write.
  678. */
  679. jspb.BinaryWriter.prototype.writeInt64 = function(field, value) {
  680. if (value == null) return;
  681. goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
  682. (value < jspb.BinaryConstants.TWO_TO_63));
  683. this.writeVarint_(field, value);
  684. };
  685. /**
  686. * Writes a int64 field (with value as a string) to the buffer.
  687. * @param {number} field The field number.
  688. * @param {string?} value The value to write.
  689. */
  690. jspb.BinaryWriter.prototype.writeInt64String = function(field, value) {
  691. if (value == null) return;
  692. var num = jspb.arith.Int64.fromString(value);
  693. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
  694. this.rawWriteVarintFromNum(num);
  695. };
  696. /**
  697. * Writes a uint32 field to the buffer. Numbers outside the range [0,2^32)
  698. * will be truncated.
  699. * @param {number} field The field number.
  700. * @param {number?} value The value to write.
  701. */
  702. jspb.BinaryWriter.prototype.writeUint32 = function(field, value) {
  703. if (value == null) return;
  704. goog.asserts.assert((value >= 0) &&
  705. (value < jspb.BinaryConstants.TWO_TO_32));
  706. this.writeUnsignedVarint32_(field, value);
  707. };
  708. /**
  709. * Writes a uint32 field represented as a string to the buffer. Numbers outside
  710. * the range [0,2^32) will be truncated.
  711. * @param {number} field The field number.
  712. * @param {string?} value The value to write.
  713. */
  714. jspb.BinaryWriter.prototype.writeUint32String = function(field, value) {
  715. if (value == null) return;
  716. var intValue = /** {number} */ parseInt(value, 10);
  717. goog.asserts.assert((intValue >= 0) &&
  718. (intValue < jspb.BinaryConstants.TWO_TO_32));
  719. this.writeUnsignedVarint32_(field, intValue);
  720. };
  721. /**
  722. * Writes a uint64 field to the buffer. Numbers outside the range [0,2^64)
  723. * will be truncated.
  724. * @param {number} field The field number.
  725. * @param {number?} value The value to write.
  726. */
  727. jspb.BinaryWriter.prototype.writeUint64 = function(field, value) {
  728. if (value == null) return;
  729. goog.asserts.assert((value >= 0) &&
  730. (value < jspb.BinaryConstants.TWO_TO_64));
  731. this.writeVarint_(field, value);
  732. };
  733. /**
  734. * Writes a uint64 field (with value as a string) to the buffer.
  735. * @param {number} field The field number.
  736. * @param {string?} value The value to write.
  737. */
  738. jspb.BinaryWriter.prototype.writeUint64String = function(field, value) {
  739. if (value == null) return;
  740. var num = jspb.arith.UInt64.fromString(value);
  741. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
  742. this.rawWriteVarintFromNum(num);
  743. };
  744. /**
  745. * Writes a sint32 field to the buffer. Numbers outside the range [-2^31,2^31)
  746. * will be truncated.
  747. * @param {number} field The field number.
  748. * @param {number?} value The value to write.
  749. */
  750. jspb.BinaryWriter.prototype.writeSint32 = function(field, value) {
  751. if (value == null) return;
  752. goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
  753. (value < jspb.BinaryConstants.TWO_TO_31));
  754. this.writeZigzagVarint32_(field, value);
  755. };
  756. /**
  757. * Writes a sint64 field to the buffer. Numbers outside the range [-2^63,2^63)
  758. * will be truncated.
  759. * @param {number} field The field number.
  760. * @param {number?} value The value to write.
  761. */
  762. jspb.BinaryWriter.prototype.writeSint64 = function(field, value) {
  763. if (value == null) return;
  764. goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
  765. (value < jspb.BinaryConstants.TWO_TO_63));
  766. this.writeZigzagVarint_(field, value);
  767. };
  768. /**
  769. * Writes a fixed32 field to the buffer. Numbers outside the range [0,2^32)
  770. * will be truncated.
  771. * @param {number} field The field number.
  772. * @param {number?} value The value to write.
  773. */
  774. jspb.BinaryWriter.prototype.writeFixed32 = function(field, value) {
  775. if (value == null) return;
  776. goog.asserts.assert((value >= 0) &&
  777. (value < jspb.BinaryConstants.TWO_TO_32));
  778. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
  779. this.rawWriteUint32(value);
  780. };
  781. /**
  782. * Writes a fixed64 field to the buffer. Numbers outside the range [0,2^64)
  783. * will be truncated.
  784. * @param {number} field The field number.
  785. * @param {number?} value The value to write.
  786. */
  787. jspb.BinaryWriter.prototype.writeFixed64 = function(field, value) {
  788. if (value == null) return;
  789. goog.asserts.assert((value >= 0) &&
  790. (value < jspb.BinaryConstants.TWO_TO_64));
  791. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
  792. this.rawWriteUint64(value);
  793. };
  794. /**
  795. * Writes a sfixed32 field to the buffer. Numbers outside the range
  796. * [-2^31,2^31) will be truncated.
  797. * @param {number} field The field number.
  798. * @param {number?} value The value to write.
  799. */
  800. jspb.BinaryWriter.prototype.writeSfixed32 = function(field, value) {
  801. if (value == null) return;
  802. goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
  803. (value < jspb.BinaryConstants.TWO_TO_31));
  804. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
  805. this.rawWriteInt32(value);
  806. };
  807. /**
  808. * Writes a sfixed64 field to the buffer. Numbers outside the range
  809. * [-2^63,2^63) will be truncated.
  810. * @param {number} field The field number.
  811. * @param {number?} value The value to write.
  812. */
  813. jspb.BinaryWriter.prototype.writeSfixed64 = function(field, value) {
  814. if (value == null) return;
  815. goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
  816. (value < jspb.BinaryConstants.TWO_TO_63));
  817. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
  818. this.rawWriteInt64(value);
  819. };
  820. /**
  821. * Writes a single-precision floating point field to the buffer. Numbers
  822. * requiring more than 32 bits of precision will be truncated.
  823. * @param {number} field The field number.
  824. * @param {number?} value The value to write.
  825. */
  826. jspb.BinaryWriter.prototype.writeFloat = function(field, value) {
  827. if (value == null) return;
  828. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
  829. this.rawWriteFloat(value);
  830. };
  831. /**
  832. * Writes a double-precision floating point field to the buffer. As this is the
  833. * native format used by JavaScript, no precision will be lost.
  834. * @param {number} field The field number.
  835. * @param {number?} value The value to write.
  836. */
  837. jspb.BinaryWriter.prototype.writeDouble = function(field, value) {
  838. if (value == null) return;
  839. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
  840. this.rawWriteDouble(value);
  841. };
  842. /**
  843. * Writes a boolean field to the buffer.
  844. * @param {number} field The field number.
  845. * @param {boolean?} value The value to write.
  846. */
  847. jspb.BinaryWriter.prototype.writeBool = function(field, value) {
  848. if (value == null) return;
  849. goog.asserts.assert(goog.isBoolean(value));
  850. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
  851. this.temp_.push(~~value);
  852. };
  853. /**
  854. * Writes an enum field to the buffer.
  855. * @param {number} field The field number.
  856. * @param {number?} value The value to write.
  857. */
  858. jspb.BinaryWriter.prototype.writeEnum = function(field, value) {
  859. if (value == null) return;
  860. goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
  861. (value < jspb.BinaryConstants.TWO_TO_31));
  862. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
  863. this.rawWriteSignedVarint32(value);
  864. };
  865. /**
  866. * Writes a string field to the buffer.
  867. * @param {number} field The field number.
  868. * @param {string?} value The string to write.
  869. */
  870. jspb.BinaryWriter.prototype.writeString = function(field, value) {
  871. if (value == null) return;
  872. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
  873. // Conversion loop swiped from goog.crypt.stringToUtf8ByteArray. Note that
  874. // 'bytes' will be at least as long as 'value', but could be longer if we
  875. // need to unpack unicode characters.
  876. var bytes = [];
  877. for (var i = 0; i < value.length; i++) {
  878. var c = value.charCodeAt(i);
  879. if (c < 128) {
  880. bytes.push(c);
  881. } else if (c < 2048) {
  882. bytes.push((c >> 6) | 192);
  883. bytes.push((c & 63) | 128);
  884. } else {
  885. bytes.push((c >> 12) | 224);
  886. bytes.push(((c >> 6) & 63) | 128);
  887. bytes.push((c & 63) | 128);
  888. }
  889. }
  890. this.rawWriteUnsignedVarint32(bytes.length);
  891. this.appendArray_(bytes);
  892. };
  893. /**
  894. * Writes an arbitrary byte field to the buffer. Note - to match the behavior
  895. * of the C++ implementation, empty byte arrays _are_ serialized.
  896. *
  897. * If 'value' is null, this method will try and copy the pre-serialized value
  898. * in 'opt_buffer' if present.
  899. *
  900. * @param {number} field The field number.
  901. * @param {jspb.ByteSource} value The array of bytes to write.
  902. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  903. * @param {?number=} opt_start The starting point in the above buffer.
  904. * @param {?number=} opt_end The ending point in the above buffer.
  905. * @param {boolean=} opt_stringIsRawBytes If `value` is a string, interpret it
  906. * as a series of raw bytes (codepoints 0--255 inclusive) rather than base64
  907. * data.
  908. */
  909. jspb.BinaryWriter.prototype.writeBytes =
  910. function(field, value, opt_buffer, opt_start, opt_end,
  911. opt_stringIsRawBytes) {
  912. if (value != null) {
  913. this.rawWriteFieldHeader_(field,
  914. jspb.BinaryConstants.WireType.DELIMITED);
  915. this.rawWriteUnsignedVarint32(value.length);
  916. this.rawWriteBytes(
  917. jspb.utils.byteSourceToUint8Array(value, opt_stringIsRawBytes));
  918. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  919. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  920. }
  921. };
  922. /**
  923. * Writes an arbitrary byte field to the buffer, with `opt_stringIsRawBytes`
  924. * flag implicitly true.
  925. * @param {number} field
  926. * @param {jspb.ByteSource} value The array of bytes to write.
  927. */
  928. jspb.BinaryWriter.prototype.writeBytesRawString = function(field, value) {
  929. this.writeBytes(field, value, null, null, null, true);
  930. };
  931. /**
  932. * Writes a message to the buffer.
  933. *
  934. * If 'value' is null, this method will try and copy the pre-serialized value
  935. * in 'opt_buffer' if present.
  936. *
  937. * @template MessageType
  938. * @param {number} field The field number.
  939. * @param {?MessageType} value The message to write.
  940. * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
  941. * to write and the writer to write it with.
  942. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  943. * @param {?number=} opt_start The starting point in the above buffer.
  944. * @param {?number=} opt_end The ending point in the above buffer.
  945. */
  946. jspb.BinaryWriter.prototype.writeMessage =
  947. function(field, value, writerCallback, opt_buffer, opt_start, opt_end) {
  948. if (value !== null) {
  949. var bookmark = this.beginDelimited_(field);
  950. writerCallback(value, this);
  951. this.endDelimited_(bookmark);
  952. } else if (opt_buffer && (opt_start != null) && (opt_end != null)) {
  953. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  954. }
  955. };
  956. /**
  957. * Writes a group message to the buffer.
  958. *
  959. * @template MessageType
  960. * @param {number} field The field number.
  961. * @param {?MessageType} value The message to write, wrapped with START_GROUP /
  962. * END_GROUP tags. Will be a no-op if 'value' is null.
  963. * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
  964. * to write and the writer to write it with.
  965. */
  966. jspb.BinaryWriter.prototype.writeGroup =
  967. function(field, value, writerCallback) {
  968. if (value) {
  969. this.rawWriteFieldHeader_(
  970. field, jspb.BinaryConstants.WireType.START_GROUP);
  971. writerCallback(value, this);
  972. this.rawWriteFieldHeader_(
  973. field, jspb.BinaryConstants.WireType.END_GROUP);
  974. }
  975. };
  976. /**
  977. * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
  978. * the buffer.
  979. * @param {number} field The field number.
  980. * @param {string?} value The hash string.
  981. */
  982. jspb.BinaryWriter.prototype.writeFixedHash64 = function(field, value) {
  983. if (value == null) return;
  984. goog.asserts.assert(value.length == 8);
  985. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
  986. this.rawWriteFixedHash64(value);
  987. };
  988. /**
  989. * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
  990. * the buffer.
  991. * @param {number} field The field number.
  992. * @param {string?} value The hash string.
  993. */
  994. jspb.BinaryWriter.prototype.writeVarintHash64 = function(field, value) {
  995. if (value == null) return;
  996. goog.asserts.assert(value.length == 8);
  997. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
  998. this.rawWriteVarintHash64(value);
  999. };
  1000. /**
  1001. * Writes an array of numbers to the buffer as a repeated varint field.
  1002. * @param {number} field The field number.
  1003. * @param {?Array.<number>} value The array of ints to write.
  1004. * @private
  1005. */
  1006. jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint32_ =
  1007. function(field, value) {
  1008. if (value == null) return;
  1009. for (var i = 0; i < value.length; i++) {
  1010. this.writeUnsignedVarint32_(field, value[i]);
  1011. }
  1012. };
  1013. /**
  1014. * Writes an array of numbers to the buffer as a repeated varint field.
  1015. * @param {number} field The field number.
  1016. * @param {?Array.<number>} value The array of ints to write.
  1017. * @private
  1018. */
  1019. jspb.BinaryWriter.prototype.writeRepeatedSignedVarint32_ =
  1020. function(field, value) {
  1021. if (value == null) return;
  1022. for (var i = 0; i < value.length; i++) {
  1023. this.writeSignedVarint32_(field, value[i]);
  1024. }
  1025. };
  1026. /**
  1027. * Writes an array of numbers to the buffer as a repeated varint field.
  1028. * @param {number} field The field number.
  1029. * @param {?Array.<number>} value The array of ints to write.
  1030. * @private
  1031. */
  1032. jspb.BinaryWriter.prototype.writeRepeatedVarint_ = function(field, value) {
  1033. if (value == null) return;
  1034. for (var i = 0; i < value.length; i++) {
  1035. this.writeVarint_(field, value[i]);
  1036. }
  1037. };
  1038. /**
  1039. * Writes an array of numbers to the buffer as a repeated zigzag field.
  1040. * @param {number} field The field number.
  1041. * @param {?Array.<number>} value The array of ints to write.
  1042. * @private
  1043. */
  1044. jspb.BinaryWriter.prototype.writeRepeatedZigzag32_ = function(field, value) {
  1045. if (value == null) return;
  1046. for (var i = 0; i < value.length; i++) {
  1047. this.writeZigzagVarint32_(field, value[i]);
  1048. }
  1049. };
  1050. /**
  1051. * Writes an array of numbers to the buffer as a repeated zigzag field.
  1052. * @param {number} field The field number.
  1053. * @param {?Array.<number>} value The array of ints to write.
  1054. * @private
  1055. */
  1056. jspb.BinaryWriter.prototype.writeRepeatedZigzag_ = function(field, value) {
  1057. if (value == null) return;
  1058. for (var i = 0; i < value.length; i++) {
  1059. this.writeZigzagVarint_(field, value[i]);
  1060. }
  1061. };
  1062. /**
  1063. * Writes an array of numbers to the buffer as a repeated 32-bit int field.
  1064. * @param {number} field The field number.
  1065. * @param {?Array.<number>} value The array of ints to write.
  1066. */
  1067. jspb.BinaryWriter.prototype.writeRepeatedInt32 =
  1068. jspb.BinaryWriter.prototype.writeRepeatedSignedVarint32_;
  1069. /**
  1070. * Writes an array of numbers formatted as strings to the buffer as a repeated
  1071. * 32-bit int field.
  1072. * @param {number} field The field number.
  1073. * @param {?Array.<string>} value The array of ints to write.
  1074. */
  1075. jspb.BinaryWriter.prototype.writeRepeatedInt32String =
  1076. function(field, value) {
  1077. if (value == null) return;
  1078. for (var i = 0; i < value.length; i++) {
  1079. this.writeInt32String(field, value[i]);
  1080. }
  1081. };
  1082. /**
  1083. * Writes an array of numbers to the buffer as a repeated 64-bit int field.
  1084. * @param {number} field The field number.
  1085. * @param {?Array.<number>} value The array of ints to write.
  1086. */
  1087. jspb.BinaryWriter.prototype.writeRepeatedInt64 =
  1088. jspb.BinaryWriter.prototype.writeRepeatedVarint_;
  1089. /**
  1090. * Writes an array of numbers formatted as strings to the buffer as a repeated
  1091. * 64-bit int field.
  1092. * @param {number} field The field number.
  1093. * @param {?Array.<string>} value The array of ints to write.
  1094. */
  1095. jspb.BinaryWriter.prototype.writeRepeatedInt64String =
  1096. function(field, value) {
  1097. if (value == null) return;
  1098. for (var i = 0; i < value.length; i++) {
  1099. this.writeInt64String(field, value[i]);
  1100. }
  1101. };
  1102. /**
  1103. * Writes an array numbers to the buffer as a repeated unsigned 32-bit int
  1104. * field.
  1105. * @param {number} field The field number.
  1106. * @param {?Array.<number>} value The array of ints to write.
  1107. */
  1108. jspb.BinaryWriter.prototype.writeRepeatedUint32 =
  1109. jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint32_;
  1110. /**
  1111. * Writes an array of numbers formatted as strings to the buffer as a repeated
  1112. * unsigned 32-bit int field.
  1113. * @param {number} field The field number.
  1114. * @param {?Array.<string>} value The array of ints to write.
  1115. */
  1116. jspb.BinaryWriter.prototype.writeRepeatedUint32String =
  1117. function(field, value) {
  1118. if (value == null) return;
  1119. for (var i = 0; i < value.length; i++) {
  1120. this.writeUint32String(field, value[i]);
  1121. }
  1122. };
  1123. /**
  1124. * Writes an array numbers to the buffer as a repeated unsigned 64-bit int
  1125. * field.
  1126. * @param {number} field The field number.
  1127. * @param {?Array.<number>} value The array of ints to write.
  1128. */
  1129. jspb.BinaryWriter.prototype.writeRepeatedUint64 =
  1130. jspb.BinaryWriter.prototype.writeRepeatedVarint_;
  1131. /**
  1132. * Writes an array of numbers formatted as strings to the buffer as a repeated
  1133. * unsigned 64-bit int field.
  1134. * @param {number} field The field number.
  1135. * @param {?Array.<string>} value The array of ints to write.
  1136. */
  1137. jspb.BinaryWriter.prototype.writeRepeatedUint64String =
  1138. function(field, value) {
  1139. if (value == null) return;
  1140. for (var i = 0; i < value.length; i++) {
  1141. this.writeUint64String(field, value[i]);
  1142. }
  1143. };
  1144. /**
  1145. * Writes an array numbers to the buffer as a repeated signed 32-bit int field.
  1146. * @param {number} field The field number.
  1147. * @param {?Array.<number>} value The array of ints to write.
  1148. */
  1149. jspb.BinaryWriter.prototype.writeRepeatedSint32 =
  1150. jspb.BinaryWriter.prototype.writeRepeatedZigzag32_;
  1151. /**
  1152. * Writes an array numbers to the buffer as a repeated signed 64-bit int field.
  1153. * @param {number} field The field number.
  1154. * @param {?Array.<number>} value The array of ints to write.
  1155. */
  1156. jspb.BinaryWriter.prototype.writeRepeatedSint64 =
  1157. jspb.BinaryWriter.prototype.writeRepeatedZigzag_;
  1158. /**
  1159. * Writes an array of numbers to the buffer as a repeated fixed32 field. This
  1160. * works for both signed and unsigned fixed32s.
  1161. * @param {number} field The field number.
  1162. * @param {?Array.<number>} value The array of ints to write.
  1163. */
  1164. jspb.BinaryWriter.prototype.writeRepeatedFixed32 = function(field, value) {
  1165. if (value == null) return;
  1166. for (var i = 0; i < value.length; i++) {
  1167. this.writeFixed32(field, value[i]);
  1168. }
  1169. };
  1170. /**
  1171. * Writes an array of numbers to the buffer as a repeated fixed64 field. This
  1172. * works for both signed and unsigned fixed64s.
  1173. * @param {number} field The field number.
  1174. * @param {?Array.<number>} value The array of ints to write.
  1175. */
  1176. jspb.BinaryWriter.prototype.writeRepeatedFixed64 = function(field, value) {
  1177. if (value == null) return;
  1178. for (var i = 0; i < value.length; i++) {
  1179. this.writeFixed64(field, value[i]);
  1180. }
  1181. };
  1182. /**
  1183. * Writes an array of numbers to the buffer as a repeated sfixed32 field.
  1184. * @param {number} field The field number.
  1185. * @param {?Array.<number>} value The array of ints to write.
  1186. */
  1187. jspb.BinaryWriter.prototype.writeRepeatedSfixed32 = function(field, value) {
  1188. if (value == null) return;
  1189. for (var i = 0; i < value.length; i++) {
  1190. this.writeSfixed32(field, value[i]);
  1191. }
  1192. };
  1193. /**
  1194. * Writes an array of numbers to the buffer as a repeated sfixed64 field.
  1195. * @param {number} field The field number.
  1196. * @param {?Array.<number>} value The array of ints to write.
  1197. */
  1198. jspb.BinaryWriter.prototype.writeRepeatedSfixed64 = function(field, value) {
  1199. if (value == null) return;
  1200. for (var i = 0; i < value.length; i++) {
  1201. this.writeSfixed64(field, value[i]);
  1202. }
  1203. };
  1204. /**
  1205. * Writes an array of numbers to the buffer as a repeated float field.
  1206. * @param {number} field The field number.
  1207. * @param {?Array.<number>} value The array of ints to write.
  1208. */
  1209. jspb.BinaryWriter.prototype.writeRepeatedFloat = function(field, value) {
  1210. if (value == null) return;
  1211. for (var i = 0; i < value.length; i++) {
  1212. this.writeFloat(field, value[i]);
  1213. }
  1214. };
  1215. /**
  1216. * Writes an array of numbers to the buffer as a repeated double field.
  1217. * @param {number} field The field number.
  1218. * @param {?Array.<number>} value The array of ints to write.
  1219. */
  1220. jspb.BinaryWriter.prototype.writeRepeatedDouble = function(field, value) {
  1221. if (value == null) return;
  1222. for (var i = 0; i < value.length; i++) {
  1223. this.writeDouble(field, value[i]);
  1224. }
  1225. };
  1226. /**
  1227. * Writes an array of booleans to the buffer as a repeated bool field.
  1228. * @param {number} field The field number.
  1229. * @param {?Array.<boolean>} value The array of ints to write.
  1230. */
  1231. jspb.BinaryWriter.prototype.writeRepeatedBool = function(field, value) {
  1232. if (value == null) return;
  1233. for (var i = 0; i < value.length; i++) {
  1234. this.writeBool(field, value[i]);
  1235. }
  1236. };
  1237. /**
  1238. * Writes an array of enums to the buffer as a repeated enum field.
  1239. * @param {number} field The field number.
  1240. * @param {?Array.<number>} value The array of ints to write.
  1241. */
  1242. jspb.BinaryWriter.prototype.writeRepeatedEnum = function(field, value) {
  1243. if (value == null) return;
  1244. for (var i = 0; i < value.length; i++) {
  1245. this.writeEnum(field, value[i]);
  1246. }
  1247. };
  1248. /**
  1249. * Writes an array of strings to the buffer as a repeated string field.
  1250. * @param {number} field The field number.
  1251. * @param {?Array.<string>} value The array of strings to write.
  1252. */
  1253. jspb.BinaryWriter.prototype.writeRepeatedString = function(field, value) {
  1254. if (value == null) return;
  1255. for (var i = 0; i < value.length; i++) {
  1256. this.writeString(field, value[i]);
  1257. }
  1258. };
  1259. /**
  1260. * Writes an array of arbitrary byte fields to the buffer.
  1261. *
  1262. * If 'value' is null, this method will try and copy the pre-serialized value
  1263. * in 'opt_buffer' if present.
  1264. *
  1265. * @param {number} field The field number.
  1266. * @param {?Array.<!Uint8Array|string>} value
  1267. * The arrays of arrays of bytes to write.
  1268. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1269. * @param {?number=} opt_start The starting point in the above buffer.
  1270. * @param {?number=} opt_end The ending point in the above buffer.
  1271. * @param {boolean=} opt_stringIsRawBytes Any values that are strings are
  1272. * interpreted as raw bytes rather than base64 data.
  1273. */
  1274. jspb.BinaryWriter.prototype.writeRepeatedBytes =
  1275. function(field, value, opt_buffer, opt_start, opt_end,
  1276. opt_stringIsRawBytes) {
  1277. if (value != null) {
  1278. for (var i = 0; i < value.length; i++) {
  1279. this.writeBytes(field, value[i], null, null, null, opt_stringIsRawBytes);
  1280. }
  1281. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1282. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1283. }
  1284. };
  1285. /**
  1286. * Writes an array of arbitrary byte fields to the buffer, with
  1287. * `opt_stringIsRawBytes` implicitly true.
  1288. * @param {number} field
  1289. * @param {?Array.<string>} value
  1290. */
  1291. jspb.BinaryWriter.prototype.writeRepeatedBytesRawString =
  1292. function(field, value) {
  1293. this.writeRepeatedBytes(field, value, null, null, null, true);
  1294. };
  1295. /**
  1296. * Writes an array of messages to the buffer.
  1297. *
  1298. * If 'value' is null, this method will try and copy the pre-serialized value
  1299. * in 'opt_buffer' if present.
  1300. *
  1301. * @template MessageType
  1302. * @param {number} field The field number.
  1303. * @param {?Array.<!MessageType>} value The array of messages to
  1304. * write.
  1305. * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
  1306. * to write and the writer to write it with.
  1307. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1308. * @param {?number=} opt_start The starting point in the above buffer.
  1309. * @param {?number=} opt_end The ending point in the above buffer.
  1310. */
  1311. jspb.BinaryWriter.prototype.writeRepeatedMessage =
  1312. function(field, value, writerCallback, opt_buffer, opt_start, opt_end) {
  1313. if (value) {
  1314. for (var i = 0; i < value.length; i++) {
  1315. var bookmark = this.beginDelimited_(field);
  1316. writerCallback(value[i], this);
  1317. this.endDelimited_(bookmark);
  1318. }
  1319. } else if (opt_buffer && (opt_start != null) && (opt_end != null)) {
  1320. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1321. }
  1322. };
  1323. /**
  1324. * Writes an array of group messages to the buffer.
  1325. *
  1326. * @template MessageType
  1327. * @param {number} field The field number.
  1328. * @param {?Array.<!MessageType>} value The array of messages to
  1329. * write.
  1330. * @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
  1331. * to write and the writer to write it with.
  1332. */
  1333. jspb.BinaryWriter.prototype.writeRepeatedGroup =
  1334. function(field, value, writerCallback) {
  1335. if (value) {
  1336. for (var i = 0; i < value.length; i++) {
  1337. this.rawWriteFieldHeader_(
  1338. field, jspb.BinaryConstants.WireType.START_GROUP);
  1339. writerCallback(value[i], this);
  1340. this.rawWriteFieldHeader_(
  1341. field, jspb.BinaryConstants.WireType.END_GROUP);
  1342. }
  1343. }
  1344. };
  1345. /**
  1346. * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
  1347. * the buffer.
  1348. * @param {number} field The field number.
  1349. * @param {?Array.<string>} value The array of hashes to write.
  1350. */
  1351. jspb.BinaryWriter.prototype.writeRepeatedFixedHash64 =
  1352. function(field, value) {
  1353. if (value == null) return;
  1354. for (var i = 0; i < value.length; i++) {
  1355. this.writeFixedHash64(field, value[i]);
  1356. }
  1357. };
  1358. /**
  1359. * Writes a repeated 64-bit hash string field (8 characters @ 8 bits of data
  1360. * each) to the buffer.
  1361. * @param {number} field The field number.
  1362. * @param {?Array.<string>} value The array of hashes to write.
  1363. */
  1364. jspb.BinaryWriter.prototype.writeRepeatedVarintHash64 =
  1365. function(field, value) {
  1366. if (value == null) return;
  1367. for (var i = 0; i < value.length; i++) {
  1368. this.writeVarintHash64(field, value[i]);
  1369. }
  1370. };
  1371. /**
  1372. * Writes an array of numbers to the buffer as a packed varint field.
  1373. *
  1374. * If 'value' is null, this method will try and copy the pre-serialized value
  1375. * in 'opt_buffer' if present.
  1376. *
  1377. * @param {number} field The field number.
  1378. * @param {?Array.<number>} value The array of ints to write.
  1379. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1380. * @param {?number=} opt_start The starting point in the above buffer.
  1381. * @param {?number=} opt_end The ending point in the above buffer.
  1382. * @private
  1383. */
  1384. jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_ =
  1385. function(field, value, opt_buffer, opt_start, opt_end) {
  1386. if (value != null && value.length) {
  1387. var bookmark = this.beginDelimited_(field);
  1388. for (var i = 0; i < value.length; i++) {
  1389. this.rawWriteUnsignedVarint32(value[i]);
  1390. }
  1391. this.endDelimited_(bookmark);
  1392. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1393. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1394. }
  1395. };
  1396. /**
  1397. * Writes an array of numbers to the buffer as a packed varint field.
  1398. *
  1399. * If 'value' is null, this method will try and copy the pre-serialized value
  1400. * in 'opt_buffer' if present.
  1401. *
  1402. * @param {number} field The field number.
  1403. * @param {?Array.<number>} value The array of ints to write.
  1404. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1405. * @param {?number=} opt_start The starting point in the above buffer.
  1406. * @param {?number=} opt_end The ending point in the above buffer.
  1407. * @private
  1408. */
  1409. jspb.BinaryWriter.prototype.writePackedSignedVarint32_ =
  1410. function(field, value, opt_buffer, opt_start, opt_end) {
  1411. if (value != null && value.length) {
  1412. var bookmark = this.beginDelimited_(field);
  1413. for (var i = 0; i < value.length; i++) {
  1414. this.rawWriteSignedVarint32(value[i]);
  1415. }
  1416. this.endDelimited_(bookmark);
  1417. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1418. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1419. }
  1420. };
  1421. /**
  1422. * Writes an array of numbers to the buffer as a packed varint field.
  1423. *
  1424. * If 'value' is null, this method will try and copy the pre-serialized value
  1425. * in 'opt_buffer' if present.
  1426. *
  1427. * @param {number} field The field number.
  1428. * @param {?Array.<number>} value The array of ints to write.
  1429. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1430. * @param {?number=} opt_start The starting point in the above buffer.
  1431. * @param {?number=} opt_end The ending point in the above buffer.
  1432. * @private
  1433. */
  1434. jspb.BinaryWriter.prototype.writePackedVarint_ =
  1435. function(field, value, opt_buffer, opt_start, opt_end) {
  1436. if (value != null && value.length) {
  1437. var bookmark = this.beginDelimited_(field);
  1438. for (var i = 0; i < value.length; i++) {
  1439. this.rawWriteVarint(value[i]);
  1440. }
  1441. this.endDelimited_(bookmark);
  1442. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1443. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1444. }
  1445. };
  1446. /**
  1447. * Writes an array of numbers to the buffer as a packed zigzag field.
  1448. *
  1449. * If 'value' is null, this method will try and copy the pre-serialized value
  1450. * in 'opt_buffer' if present.
  1451. *
  1452. * @param {number} field The field number.
  1453. * @param {?Array.<number>} value The array of ints to write.
  1454. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1455. * @param {?number=} opt_start The starting point in the above buffer.
  1456. * @param {?number=} opt_end The ending point in the above buffer.
  1457. * @private
  1458. */
  1459. jspb.BinaryWriter.prototype.writePackedZigzag_ =
  1460. function(field, value, opt_buffer, opt_start, opt_end) {
  1461. if (value != null && value.length) {
  1462. var bookmark = this.beginDelimited_(field);
  1463. for (var i = 0; i < value.length; i++) {
  1464. this.rawWriteZigzagVarint(value[i]);
  1465. }
  1466. this.endDelimited_(bookmark);
  1467. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1468. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1469. }
  1470. };
  1471. /**
  1472. * Writes an array of numbers to the buffer as a packed 32-bit int field.
  1473. *
  1474. * If 'value' is null, this method will try and copy the pre-serialized value
  1475. * in 'opt_buffer' if present.
  1476. *
  1477. * @param {number} field The field number.
  1478. * @param {?Array.<number>} value The array of ints to write.
  1479. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1480. * @param {?number=} opt_start The starting point in the above buffer.
  1481. * @param {?number=} opt_end The ending point in the above buffer.
  1482. */
  1483. jspb.BinaryWriter.prototype.writePackedInt32 =
  1484. jspb.BinaryWriter.prototype.writePackedSignedVarint32_;
  1485. /**
  1486. * Writes an array of numbers represented as strings to the buffer as a packed
  1487. * 32-bit int field.
  1488. * @param {number} field
  1489. * @param {?Array.<string>} value
  1490. */
  1491. jspb.BinaryWriter.prototype.writePackedInt32String = function(field, value) {
  1492. if (value == null || !value.length) return;
  1493. var bookmark = this.beginDelimited_(field);
  1494. for (var i = 0; i < value.length; i++) {
  1495. this.rawWriteSignedVarint32(parseInt(value[i], 10));
  1496. }
  1497. this.endDelimited_(bookmark);
  1498. };
  1499. /**
  1500. * Writes an array of numbers to the buffer as a packed 64-bit int field.
  1501. * @param {number} field The field number.
  1502. * @param {?Array.<number>} value The array of ints to write.
  1503. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1504. * @param {?number=} opt_start The starting point in the above buffer.
  1505. * @param {?number=} opt_end The ending point in the above buffer.
  1506. */
  1507. jspb.BinaryWriter.prototype.writePackedInt64 =
  1508. jspb.BinaryWriter.prototype.writePackedVarint_;
  1509. /**
  1510. * Writes an array of numbers represented as strings to the buffer as a packed
  1511. * 64-bit int field.
  1512. * @param {number} field
  1513. * @param {?Array.<string>} value
  1514. */
  1515. jspb.BinaryWriter.prototype.writePackedInt64String =
  1516. function(field, value) {
  1517. if (value == null || !value.length) return;
  1518. var bookmark = this.beginDelimited_(field);
  1519. for (var i = 0; i < value.length; i++) {
  1520. var num = jspb.arith.Int64.fromString(value[i]);
  1521. this.rawWriteVarintFromNum(num);
  1522. }
  1523. this.endDelimited_(bookmark);
  1524. };
  1525. /**
  1526. * Writes an array numbers to the buffer as a packed unsigned 32-bit int field.
  1527. *
  1528. * If 'value' is null, this method will try and copy the pre-serialized value
  1529. * in 'opt_buffer' if present.
  1530. *
  1531. * @param {number} field The field number.
  1532. * @param {?Array.<number>} value The array of ints to write.
  1533. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1534. * @param {?number=} opt_start The starting point in the above buffer.
  1535. * @param {?number=} opt_end The ending point in the above buffer.
  1536. */
  1537. jspb.BinaryWriter.prototype.writePackedUint32 =
  1538. jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_;
  1539. /**
  1540. * Writes an array of numbers represented as strings to the buffer as a packed
  1541. * unsigned 32-bit int field.
  1542. * @param {number} field
  1543. * @param {?Array.<string>} value
  1544. */
  1545. jspb.BinaryWriter.prototype.writePackedUint32String =
  1546. function(field, value) {
  1547. if (value == null || !value.length) return;
  1548. var bookmark = this.beginDelimited_(field);
  1549. for (var i = 0; i < value.length; i++) {
  1550. this.rawWriteUnsignedVarint32(parseInt(value[i], 10));
  1551. }
  1552. this.endDelimited_(bookmark);
  1553. };
  1554. /**
  1555. * Writes an array numbers to the buffer as a packed unsigned 64-bit int field.
  1556. *
  1557. * If 'value' is null, this method will try and copy the pre-serialized value
  1558. * in 'opt_buffer' if present.
  1559. *
  1560. * @param {number} field The field number.
  1561. * @param {?Array.<number>} value The array of ints to write.
  1562. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1563. * @param {?number=} opt_start The starting point in the above buffer.
  1564. * @param {?number=} opt_end The ending point in the above buffer.
  1565. */
  1566. jspb.BinaryWriter.prototype.writePackedUint64 =
  1567. jspb.BinaryWriter.prototype.writePackedVarint_;
  1568. /**
  1569. * Writes an array of numbers represented as strings to the buffer as a packed
  1570. * unsigned 64-bit int field.
  1571. * @param {number} field
  1572. * @param {?Array.<string>} value
  1573. */
  1574. jspb.BinaryWriter.prototype.writePackedUint64String =
  1575. function(field, value) {
  1576. if (value == null || !value.length) return;
  1577. var bookmark = this.beginDelimited_(field);
  1578. for (var i = 0; i < value.length; i++) {
  1579. var num = jspb.arith.UInt64.fromString(value[i]);
  1580. this.rawWriteVarintFromNum(num);
  1581. }
  1582. this.endDelimited_(bookmark);
  1583. };
  1584. /**
  1585. * Writes an array numbers to the buffer as a packed signed 32-bit int field.
  1586. *
  1587. * If 'value' is null, this method will try and copy the pre-serialized value
  1588. * in 'opt_buffer' if present.
  1589. *
  1590. * @param {number} field The field number.
  1591. * @param {?Array.<number>} value The array of ints to write.
  1592. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1593. * @param {?number=} opt_start The starting point in the above buffer.
  1594. * @param {?number=} opt_end The ending point in the above buffer.
  1595. */
  1596. jspb.BinaryWriter.prototype.writePackedSint32 =
  1597. jspb.BinaryWriter.prototype.writePackedZigzag_;
  1598. /**
  1599. * Writes an array numbers to the buffer as a packed signed 64-bit int field.
  1600. *
  1601. * If 'value' is null, this method will try and copy the pre-serialized value
  1602. * in 'opt_buffer' if present.
  1603. *
  1604. * @param {number} field The field number.
  1605. * @param {?Array.<number>} value The array of ints to write.
  1606. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1607. * @param {?number=} opt_start The starting point in the above buffer.
  1608. * @param {?number=} opt_end The ending point in the above buffer.
  1609. */
  1610. jspb.BinaryWriter.prototype.writePackedSint64 =
  1611. jspb.BinaryWriter.prototype.writePackedZigzag_;
  1612. /**
  1613. * Writes an array of numbers to the buffer as a packed fixed32 field.
  1614. *
  1615. * If 'value' is null, this method will try and copy the pre-serialized value
  1616. * in 'opt_buffer' if present.
  1617. *
  1618. * @param {number} field The field number.
  1619. * @param {?Array.<number>} value The array of ints to write.
  1620. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1621. * @param {?number=} opt_start The starting point in the above buffer.
  1622. * @param {?number=} opt_end The ending point in the above buffer.
  1623. */
  1624. jspb.BinaryWriter.prototype.writePackedFixed32 =
  1625. function(field, value, opt_buffer, opt_start, opt_end) {
  1626. if (value != null && value.length) {
  1627. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
  1628. this.rawWriteUnsignedVarint32(value.length * 4);
  1629. for (var i = 0; i < value.length; i++) {
  1630. this.rawWriteUint32(value[i]);
  1631. }
  1632. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1633. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1634. }
  1635. };
  1636. /**
  1637. * Writes an array of numbers to the buffer as a packed fixed64 field.
  1638. *
  1639. * If 'value' is null, this method will try and copy the pre-serialized value
  1640. * in 'opt_buffer' if present.
  1641. *
  1642. * @param {number} field The field number.
  1643. * @param {?Array.<number>} value The array of ints to write.
  1644. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1645. * @param {?number=} opt_start The starting point in the above buffer.
  1646. * @param {?number=} opt_end The ending point in the above buffer.
  1647. */
  1648. jspb.BinaryWriter.prototype.writePackedFixed64 =
  1649. function(field, value, opt_buffer, opt_start, opt_end) {
  1650. if (value != null && value.length) {
  1651. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
  1652. this.rawWriteUnsignedVarint32(value.length * 8);
  1653. for (var i = 0; i < value.length; i++) {
  1654. this.rawWriteUint64(value[i]);
  1655. }
  1656. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1657. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1658. }
  1659. };
  1660. /**
  1661. * Writes an array of numbers to the buffer as a packed sfixed32 field.
  1662. *
  1663. * If 'value' is null, this method will try and copy the pre-serialized value
  1664. * in 'opt_buffer' if present.
  1665. *
  1666. * @param {number} field The field number.
  1667. * @param {?Array.<number>} value The array of ints to write.
  1668. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1669. * @param {?number=} opt_start The starting point in the above buffer.
  1670. * @param {?number=} opt_end The ending point in the above buffer.
  1671. */
  1672. jspb.BinaryWriter.prototype.writePackedSfixed32 =
  1673. function(field, value, opt_buffer, opt_start, opt_end) {
  1674. if (value != null && value.length) {
  1675. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
  1676. this.rawWriteUnsignedVarint32(value.length * 4);
  1677. for (var i = 0; i < value.length; i++) {
  1678. this.rawWriteInt32(value[i]);
  1679. }
  1680. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1681. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1682. }
  1683. };
  1684. /**
  1685. * Writes an array of numbers to the buffer as a packed sfixed64 field.
  1686. *
  1687. * If 'value' is null, this method will try and copy the pre-serialized value
  1688. * in 'opt_buffer' if present.
  1689. *
  1690. * @param {number} field The field number.
  1691. * @param {?Array.<number>} value The array of ints to write.
  1692. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1693. * @param {?number=} opt_start The starting point in the above buffer.
  1694. * @param {?number=} opt_end The ending point in the above buffer.
  1695. */
  1696. jspb.BinaryWriter.prototype.writePackedSfixed64 =
  1697. function(field, value, opt_buffer, opt_start, opt_end) {
  1698. if (value != null) {
  1699. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
  1700. this.rawWriteUnsignedVarint32(value.length * 8);
  1701. for (var i = 0; i < value.length; i++) {
  1702. this.rawWriteInt64(value[i]);
  1703. }
  1704. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1705. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1706. }
  1707. };
  1708. /**
  1709. * Writes an array of numbers to the buffer as a packed float field.
  1710. *
  1711. * If 'value' is null, this method will try and copy the pre-serialized value
  1712. * in 'opt_buffer' if present.
  1713. *
  1714. * @param {number} field The field number.
  1715. * @param {?Array.<number>} value The array of ints to write.
  1716. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1717. * @param {?number=} opt_start The starting point in the above buffer.
  1718. * @param {?number=} opt_end The ending point in the above buffer.
  1719. */
  1720. jspb.BinaryWriter.prototype.writePackedFloat =
  1721. function(field, value, opt_buffer, opt_start, opt_end) {
  1722. if (value != null && value.length) {
  1723. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
  1724. this.rawWriteUnsignedVarint32(value.length * 4);
  1725. for (var i = 0; i < value.length; i++) {
  1726. this.rawWriteFloat(value[i]);
  1727. }
  1728. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1729. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1730. }
  1731. };
  1732. /**
  1733. * Writes an array of numbers to the buffer as a packed double field.
  1734. *
  1735. * If 'value' is null, this method will try and copy the pre-serialized value
  1736. * in 'opt_buffer' if present.
  1737. *
  1738. * @param {number} field The field number.
  1739. * @param {?Array.<number>} value The array of ints to write.
  1740. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1741. * @param {?number=} opt_start The starting point in the above buffer.
  1742. * @param {?number=} opt_end The ending point in the above buffer.
  1743. */
  1744. jspb.BinaryWriter.prototype.writePackedDouble =
  1745. function(field, value, opt_buffer, opt_start, opt_end) {
  1746. if (value != null && value.length) {
  1747. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
  1748. this.rawWriteUnsignedVarint32(value.length * 8);
  1749. for (var i = 0; i < value.length; i++) {
  1750. this.rawWriteDouble(value[i]);
  1751. }
  1752. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1753. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1754. }
  1755. };
  1756. /**
  1757. * Writes an array of booleans to the buffer as a packed bool field.
  1758. *
  1759. * If 'value' is null, this method will try and copy the pre-serialized value
  1760. * in 'opt_buffer' if present.
  1761. *
  1762. * @param {number} field The field number.
  1763. * @param {?Array.<boolean>} value The array of ints to write.
  1764. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1765. * @param {?number=} opt_start The starting point in the above buffer.
  1766. * @param {?number=} opt_end The ending point in the above buffer.
  1767. */
  1768. jspb.BinaryWriter.prototype.writePackedBool =
  1769. function(field, value, opt_buffer, opt_start, opt_end) {
  1770. if (value != null && value.length) {
  1771. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
  1772. this.rawWriteUnsignedVarint32(value.length);
  1773. for (var i = 0; i < value.length; i++) {
  1774. this.rawWriteBool(value[i]);
  1775. }
  1776. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1777. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1778. }
  1779. };
  1780. /**
  1781. * Writes an array of enums to the buffer as a packed enum field.
  1782. *
  1783. * If 'value' is null, this method will try and copy the pre-serialized value
  1784. * in 'opt_buffer' if present.
  1785. *
  1786. * @param {number} field The field number.
  1787. * @param {?Array.<number>} value The array of ints to write.
  1788. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1789. * @param {?number=} opt_start The starting point in the above buffer.
  1790. * @param {?number=} opt_end The ending point in the above buffer.
  1791. */
  1792. jspb.BinaryWriter.prototype.writePackedEnum =
  1793. function(field, value, opt_buffer, opt_start, opt_end) {
  1794. if (value != null && value.length) {
  1795. var bookmark = this.beginDelimited_(field);
  1796. for (var i = 0; i < value.length; i++) {
  1797. this.rawWriteEnum(value[i]);
  1798. }
  1799. this.endDelimited_(bookmark);
  1800. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1801. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1802. }
  1803. };
  1804. /**
  1805. * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
  1806. * the buffer.
  1807. *
  1808. * If 'value' is null, this method will try and copy the pre-serialized value
  1809. * in 'opt_buffer' if present.
  1810. *
  1811. * @param {number} field The field number.
  1812. * @param {?Array.<string>} value The array of hashes to write.
  1813. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1814. * @param {?number=} opt_start The starting point in the above buffer.
  1815. * @param {?number=} opt_end The ending point in the above buffer.
  1816. */
  1817. jspb.BinaryWriter.prototype.writePackedFixedHash64 =
  1818. function(field, value, opt_buffer, opt_start, opt_end) {
  1819. if (value != null && value.length) {
  1820. this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
  1821. this.rawWriteUnsignedVarint32(value.length * 8);
  1822. for (var i = 0; i < value.length; i++) {
  1823. this.rawWriteFixedHash64(value[i]);
  1824. }
  1825. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1826. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1827. }
  1828. };
  1829. /**
  1830. * Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
  1831. * the buffer.
  1832. *
  1833. * If 'value' is null, this method will try and copy the pre-serialized value
  1834. * in 'opt_buffer' if present.
  1835. *
  1836. * @param {number} field The field number.
  1837. * @param {?Array.<string>} value The array of hashes to write.
  1838. * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
  1839. * @param {?number=} opt_start The starting point in the above buffer.
  1840. * @param {?number=} opt_end The ending point in the above buffer.
  1841. */
  1842. jspb.BinaryWriter.prototype.writePackedVarintHash64 =
  1843. function(field, value, opt_buffer, opt_start, opt_end) {
  1844. if (value != null && value.length) {
  1845. var bookmark = this.beginDelimited_(field);
  1846. for (var i = 0; i < value.length; i++) {
  1847. this.rawWriteVarintHash64(value[i]);
  1848. }
  1849. this.endDelimited_(bookmark);
  1850. } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
  1851. this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
  1852. }
  1853. };