1/** 2 * @fileoverview Helper methods for reading data from the binary wire format. 3 */ 4goog.module('protobuf.binary.reader'); 5 6const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); 7const ByteString = goog.require('protobuf.ByteString'); 8const Int64 = goog.require('protobuf.Int64'); 9const {checkState} = goog.require('protobuf.internal.checks'); 10 11 12/****************************************************************************** 13 * OPTIONAL FUNCTIONS 14 ******************************************************************************/ 15 16/** 17 * Reads a boolean value from the binary bytes. 18 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 19 * @param {number} start Start of the data. 20 * @return {boolean} 21 * @package 22 */ 23function readBool(bufferDecoder, start) { 24 const {lowBits, highBits} = bufferDecoder.getVarint(start); 25 return lowBits !== 0 || highBits !== 0; 26} 27 28/** 29 * Reads a ByteString value from the binary bytes. 30 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 31 * @param {number} start Start of the data. 32 * @return {!ByteString} 33 * @package 34 */ 35function readBytes(bufferDecoder, start) { 36 return readDelimited(bufferDecoder, start).asByteString(); 37} 38 39/** 40 * Reads a int32 value from the binary bytes encoded as varint. 41 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 42 * @param {number} start Start of the data. 43 * @return {number} 44 * @package 45 */ 46function readInt32(bufferDecoder, start) { 47 // Negative 32 bit integers are encoded with 64 bit values. 48 // Clients are expected to truncate back to 32 bits. 49 // This is why we are dropping the upper bytes here. 50 return bufferDecoder.getUnsignedVarint32At(start) | 0; 51} 52 53/** 54 * Reads a int32 value from the binary bytes encoded as varint. 55 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 56 * @param {number} start Start of the data. 57 * @return {!Int64} 58 * @package 59 */ 60function readInt64(bufferDecoder, start) { 61 const {lowBits, highBits} = bufferDecoder.getVarint(start); 62 return Int64.fromBits(lowBits, highBits); 63} 64 65/** 66 * Reads a fixed int32 value from the binary bytes. 67 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 68 * @param {number} start Start of the data. 69 * @return {number} 70 * @package 71 */ 72function readFixed32(bufferDecoder, start) { 73 return bufferDecoder.getUint32(start); 74} 75 76/** 77 * Reads a float value from the binary bytes. 78 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 79 * @param {number} start Start of the data. 80 * @return {number} 81 * @package 82 */ 83function readFloat(bufferDecoder, start) { 84 return bufferDecoder.getFloat32(start); 85} 86 87/** 88 * Reads a fixed int64 value from the binary bytes. 89 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 90 * @param {number} start Start of the data. 91 * @return {!Int64} 92 * @package 93 */ 94function readSfixed64(bufferDecoder, start) { 95 const lowBits = bufferDecoder.getInt32(start); 96 const highBits = bufferDecoder.getInt32(start + 4); 97 return Int64.fromBits(lowBits, highBits); 98} 99 100/** 101 * Reads a sint64 value from the binary bytes encoded as varint. 102 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 103 * @param {number} start Start of the data. 104 * @return {!Int64} 105 * @package 106 */ 107function readSint64(bufferDecoder, start) { 108 const {lowBits, highBits} = bufferDecoder.getVarint(start); 109 const sign = -(lowBits & 0x01); 110 const decodedLowerBits = ((lowBits >>> 1) | (highBits & 0x01) << 31) ^ sign; 111 const decodedUpperBits = (highBits >>> 1) ^ sign; 112 return Int64.fromBits(decodedLowerBits, decodedUpperBits); 113} 114 115/** 116 * Reads a sint32 value from the binary bytes encoded as varint. 117 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 118 * @param {number} start Start of the data. 119 * @return {number} 120 * @package 121 */ 122function readSint32(bufferDecoder, start) { 123 return readSint64(bufferDecoder, start).getLowBits(); 124} 125 126/** 127 * Read a subarray of bytes representing a length delimited field. 128 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 129 * @param {number} start Start of the data. 130 * @return {!BufferDecoder} 131 * @package 132 */ 133function readDelimited(bufferDecoder, start) { 134 const unsignedLength = bufferDecoder.getUnsignedVarint32At(start); 135 return bufferDecoder.subBufferDecoder(bufferDecoder.cursor(), unsignedLength); 136} 137 138/** 139 * Reads a string value from the binary bytes. 140 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 141 * @param {number} start Start of the data. 142 * @return {string} 143 * @package 144 */ 145function readString(bufferDecoder, start) { 146 return readDelimited(bufferDecoder, start).asString(); 147} 148 149/** 150 * Reads a uint32 value from the binary bytes encoded as varint. 151 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 152 * @param {number} start Start of the data. 153 * @return {number} 154 * @package 155 */ 156function readUint32(bufferDecoder, start) { 157 return bufferDecoder.getUnsignedVarint32At(start); 158} 159 160/** 161 * Reads a double value from the binary bytes. 162 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 163 * @param {number} start Start of the data. 164 * @return {number} 165 * @package 166 */ 167function readDouble(bufferDecoder, start) { 168 return bufferDecoder.getFloat64(start); 169} 170 171/** 172 * Reads a fixed int32 value from the binary bytes. 173 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 174 * @param {number} start Start of the data. 175 * @return {number} 176 * @package 177 */ 178function readSfixed32(bufferDecoder, start) { 179 return bufferDecoder.getInt32(start); 180} 181 182/****************************************************************************** 183 * REPEATED FUNCTIONS 184 ******************************************************************************/ 185 186/** 187 * Reads a packed bool field, which consists of a length header and a list of 188 * unsigned varints. 189 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 190 * @param {number} start Start of the data. 191 * @return {!Array<boolean>} 192 * @package 193 */ 194function readPackedBool(bufferDecoder, start) { 195 return readPacked(bufferDecoder, start, readBool); 196} 197 198/** 199 * Reads a packed double field, which consists of a length header and a list of 200 * fixed64. 201 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 202 * @param {number} start Start of the data. 203 * @return {!Array<number>} 204 * @package 205 */ 206function readPackedDouble(bufferDecoder, start) { 207 return readPacked(bufferDecoder, start, readDouble); 208} 209 210/** 211 * Reads a packed fixed32 field, which consists of a length header and a list of 212 * fixed32. 213 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 214 * @param {number} start Start of the data. 215 * @return {!Array<number>} 216 * @package 217 */ 218function readPackedFixed32(bufferDecoder, start) { 219 return readPacked(bufferDecoder, start, readFixed32); 220} 221 222/** 223 * Reads a packed float field, which consists of a length header and a list of 224 * fixed64. 225 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 226 * @param {number} start Start of the data. 227 * @return {!Array<number>} 228 * @package 229 */ 230function readPackedFloat(bufferDecoder, start) { 231 return readPacked(bufferDecoder, start, readFloat); 232} 233 234/** 235 * Reads a packed int32 field, which consists of a length header and a list of 236 * varint. 237 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 238 * @param {number} start Start of the data. 239 * @return {!Array<number>} 240 * @package 241 */ 242function readPackedInt32(bufferDecoder, start) { 243 return readPacked(bufferDecoder, start, readInt32); 244} 245 246/** 247 * Reads a packed int64 field, which consists of a length header and a list 248 * of int64. 249 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 250 * @param {number} start Start of the data. 251 * @return {!Array<!Int64>} 252 * @package 253 */ 254function readPackedInt64(bufferDecoder, start) { 255 return readPacked(bufferDecoder, start, readInt64); 256} 257 258/** 259 * Reads a packed sfixed32 field, which consists of a length header and a list 260 * of sfixed32. 261 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 262 * @param {number} start Start of the data. 263 * @return {!Array<number>} 264 * @package 265 */ 266function readPackedSfixed32(bufferDecoder, start) { 267 return readPacked(bufferDecoder, start, readSfixed32); 268} 269 270/** 271 * Reads a packed sfixed64 field, which consists of a length header and a list 272 * of sfixed64. 273 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 274 * @param {number} start Start of the data. 275 * @return {!Array<!Int64>} 276 * @package 277 */ 278function readPackedSfixed64(bufferDecoder, start) { 279 return readPacked(bufferDecoder, start, readSfixed64); 280} 281 282/** 283 * Reads a packed sint32 field, which consists of a length header and a list of 284 * varint. 285 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 286 * @param {number} start Start of the data. 287 * @return {!Array<number>} 288 * @package 289 */ 290function readPackedSint32(bufferDecoder, start) { 291 return readPacked(bufferDecoder, start, readSint32); 292} 293 294/** 295 * Reads a packed sint64 field, which consists of a length header and a list 296 * of sint64. 297 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 298 * @param {number} start Start of the data. 299 * @return {!Array<!Int64>} 300 * @package 301 */ 302function readPackedSint64(bufferDecoder, start) { 303 return readPacked(bufferDecoder, start, readSint64); 304} 305 306/** 307 * Reads a packed uint32 field, which consists of a length header and a list of 308 * varint. 309 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 310 * @param {number} start Start of the data. 311 * @return {!Array<number>} 312 * @package 313 */ 314function readPackedUint32(bufferDecoder, start) { 315 return readPacked(bufferDecoder, start, readUint32); 316} 317 318/** 319 * Read packed values. 320 * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes. 321 * @param {number} start Start of the data. 322 * @param {function(!BufferDecoder, number):T} valueFunction 323 * @return {!Array<T>} 324 * @package 325 * @template T 326 */ 327function readPacked(bufferDecoder, start, valueFunction) { 328 const /** !Array<T> */ result = []; 329 const unsignedLength = bufferDecoder.getUnsignedVarint32At(start); 330 const dataStart = bufferDecoder.cursor(); 331 while (bufferDecoder.cursor() < dataStart + unsignedLength) { 332 checkState(bufferDecoder.cursor() > 0); 333 result.push(valueFunction(bufferDecoder, bufferDecoder.cursor())); 334 } 335 return result; 336} 337 338exports = { 339 readBool, 340 readBytes, 341 readDelimited, 342 readDouble, 343 readFixed32, 344 readFloat, 345 readInt32, 346 readInt64, 347 readSint32, 348 readSint64, 349 readSfixed32, 350 readSfixed64, 351 readString, 352 readUint32, 353 readPackedBool, 354 readPackedDouble, 355 readPackedFixed32, 356 readPackedFloat, 357 readPackedInt32, 358 readPackedInt64, 359 readPackedSfixed32, 360 readPackedSfixed64, 361 readPackedSint32, 362 readPackedSint64, 363 readPackedUint32, 364}; 365