• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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