|
@@ -6,24 +6,13 @@ goog.module('protobuf.binary.reader');
|
|
|
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
|
|
const ByteString = goog.require('protobuf.ByteString');
|
|
|
const Int64 = goog.require('protobuf.Int64');
|
|
|
+const {checkState} = goog.require('protobuf.internal.checks');
|
|
|
|
|
|
|
|
|
/******************************************************************************
|
|
|
* OPTIONAL FUNCTIONS
|
|
|
******************************************************************************/
|
|
|
|
|
|
-/**
|
|
|
- * Reads a boolean from the binary bytes.
|
|
|
- * Also returns the first position after the boolean.
|
|
|
- * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
|
- * @param {number} index Start of the data.
|
|
|
- * @return {{value: boolean, nextCursor: number}}
|
|
|
- */
|
|
|
-function readBoolValue(bufferDecoder, index) {
|
|
|
- const {lowBits, highBits, dataStart} = bufferDecoder.getVarint(index);
|
|
|
- return {value: lowBits !== 0 || highBits !== 0, nextCursor: dataStart};
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* Reads a boolean value from the binary bytes.
|
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
@@ -32,11 +21,12 @@ function readBoolValue(bufferDecoder, index) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readBool(bufferDecoder, start) {
|
|
|
- return readBoolValue(bufferDecoder, start).value;
|
|
|
+ const {lowBits, highBits} = bufferDecoder.getVarint(start);
|
|
|
+ return lowBits !== 0 || highBits !== 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Reads a double value from the binary bytes.
|
|
|
+ * Reads a ByteString value from the binary bytes.
|
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
|
* @param {number} start Start of the data.
|
|
|
* @return {!ByteString}
|
|
@@ -46,21 +36,6 @@ function readBytes(bufferDecoder, start) {
|
|
|
return readDelimited(bufferDecoder, start).asByteString();
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * Reads a int32 value from the binary bytes encoded as varint.
|
|
|
- * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
|
- * @param {number} index Start of the data.
|
|
|
- * @return {{value: number, nextCursor: number}}
|
|
|
- * @package
|
|
|
- */
|
|
|
-function readInt32Value(bufferDecoder, index) {
|
|
|
- const {lowBits, dataStart} = bufferDecoder.getVarint(index);
|
|
|
- // Negative 32 bit integers are encoded with 64 bit values.
|
|
|
- // Clients are expected to truncate back to 32 bits.
|
|
|
- // This is why we are dropping the upper bytes here.
|
|
|
- return {value: lowBits | 0, nextCursor: dataStart};
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* Reads a int32 value from the binary bytes encoded as varint.
|
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
@@ -69,19 +44,10 @@ function readInt32Value(bufferDecoder, index) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readInt32(bufferDecoder, start) {
|
|
|
- return readInt32Value(bufferDecoder, start).value;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Reads a int32 value from the binary bytes encoded as varint.
|
|
|
- * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
|
- * @param {number} index Start of the data.
|
|
|
- * @return {{ value: !Int64, nextCursor: number}}
|
|
|
- * @package
|
|
|
- */
|
|
|
-function readInt64Value(bufferDecoder, index) {
|
|
|
- const {lowBits, highBits, dataStart} = bufferDecoder.getVarint(index);
|
|
|
- return {value: Int64.fromBits(lowBits, highBits), nextCursor: dataStart};
|
|
|
+ // Negative 32 bit integers are encoded with 64 bit values.
|
|
|
+ // Clients are expected to truncate back to 32 bits.
|
|
|
+ // This is why we are dropping the upper bytes here.
|
|
|
+ return bufferDecoder.getUnsignedVarint32At(start) | 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -92,7 +58,8 @@ function readInt64Value(bufferDecoder, index) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readInt64(bufferDecoder, start) {
|
|
|
- return readInt64Value(bufferDecoder, start).value;
|
|
|
+ const {lowBits, highBits} = bufferDecoder.getVarint(start);
|
|
|
+ return Int64.fromBits(lowBits, highBits);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -130,19 +97,6 @@ function readSfixed64(bufferDecoder, start) {
|
|
|
return Int64.fromBits(lowBits, highBits);
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * Reads a sint32 value from the binary bytes encoded as varint.
|
|
|
- * Also returns the first position after the boolean.
|
|
|
- * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
|
- * @param {number} index Start of the data.
|
|
|
- * @return {{value: number, nextCursor: number}}
|
|
|
- */
|
|
|
-function readSint32Value(bufferDecoder, index) {
|
|
|
- const {lowBits, dataStart} = bufferDecoder.getVarint(index);
|
|
|
- // Truncate upper bits and convert from zig zag to signd int
|
|
|
- return {value: (lowBits >>> 1) ^ -(lowBits & 0x01), nextCursor: dataStart};
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* Reads a sint32 value from the binary bytes encoded as varint.
|
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
@@ -151,26 +105,9 @@ function readSint32Value(bufferDecoder, index) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readSint32(bufferDecoder, start) {
|
|
|
- return readSint32Value(bufferDecoder, start).value;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Reads a sint64 value from the binary bytes encoded as varint.
|
|
|
- * Also returns the first position after the value.
|
|
|
- * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
|
- * @param {number} index Start of the data.
|
|
|
- * @return {{value: !Int64, nextCursor: number}}
|
|
|
- * @package
|
|
|
- */
|
|
|
-function readSint64Value(bufferDecoder, index) {
|
|
|
- const {lowBits, highBits, dataStart} = bufferDecoder.getVarint(index);
|
|
|
- const sign = -(lowBits & 0x01);
|
|
|
- const decodedLowerBits = ((lowBits >>> 1) | (highBits & 0x01) << 31) ^ sign;
|
|
|
- const decodedUpperBits = (highBits >>> 1) ^ sign;
|
|
|
- return {
|
|
|
- value: Int64.fromBits(decodedLowerBits, decodedUpperBits),
|
|
|
- nextCursor: dataStart
|
|
|
- };
|
|
|
+ const bits = bufferDecoder.getUnsignedVarint32At(start);
|
|
|
+ // Truncate upper bits and convert from zig zag to signd int
|
|
|
+ return (bits >>> 1) ^ -(bits & 0x01);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -181,7 +118,11 @@ function readSint64Value(bufferDecoder, index) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readSint64(bufferDecoder, start) {
|
|
|
- return readSint64Value(bufferDecoder, start).value;
|
|
|
+ const {lowBits, highBits} = bufferDecoder.getVarint(start);
|
|
|
+ const sign = -(lowBits & 0x01);
|
|
|
+ const decodedLowerBits = ((lowBits >>> 1) | (highBits & 0x01) << 31) ^ sign;
|
|
|
+ const decodedUpperBits = (highBits >>> 1) ^ sign;
|
|
|
+ return Int64.fromBits(decodedLowerBits, decodedUpperBits);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -192,9 +133,8 @@ function readSint64(bufferDecoder, start) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readDelimited(bufferDecoder, start) {
|
|
|
- const {lowBits, dataStart} = bufferDecoder.getVarint(start);
|
|
|
- const unsignedLength = lowBits >>> 0;
|
|
|
- return bufferDecoder.subBufferDecoder(dataStart, unsignedLength);
|
|
|
+ const unsignedLength = bufferDecoder.getUnsignedVarint32At(start);
|
|
|
+ return bufferDecoder.subBufferDecoder(bufferDecoder.cursor(), unsignedLength);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -208,18 +148,6 @@ function readString(bufferDecoder, start) {
|
|
|
return readDelimited(bufferDecoder, start).asString();
|
|
|
}
|
|
|
|
|
|
-/**
|
|
|
- * Reads a uint32 value from the binary bytes encoded as varint.
|
|
|
- * Also returns the first position after the value.
|
|
|
- * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
|
- * @param {number} index Start of the data.
|
|
|
- * @return {{value: number, nextCursor: number}}
|
|
|
- */
|
|
|
-function readUint32Value(bufferDecoder, index) {
|
|
|
- const {lowBits, dataStart} = bufferDecoder.getVarint(index);
|
|
|
- return {value: lowBits >>> 0, nextCursor: dataStart};
|
|
|
-}
|
|
|
-
|
|
|
/**
|
|
|
* Reads a uint32 value from the binary bytes encoded as varint.
|
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
@@ -228,7 +156,7 @@ function readUint32Value(bufferDecoder, index) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readUint32(bufferDecoder, start) {
|
|
|
- return readUint32Value(bufferDecoder, start).value;
|
|
|
+ return bufferDecoder.getUnsignedVarint32At(start);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -266,7 +194,7 @@ function readSfixed32(bufferDecoder, start) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readPackedBool(bufferDecoder, start) {
|
|
|
- return readPackedVariableLength(bufferDecoder, start, readBoolValue);
|
|
|
+ return readPacked(bufferDecoder, start, readBool);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -278,7 +206,7 @@ function readPackedBool(bufferDecoder, start) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readPackedDouble(bufferDecoder, start) {
|
|
|
- return readPackedFixed(bufferDecoder, start, 8, readDouble);
|
|
|
+ return readPacked(bufferDecoder, start, readDouble);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -290,7 +218,7 @@ function readPackedDouble(bufferDecoder, start) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readPackedFixed32(bufferDecoder, start) {
|
|
|
- return readPackedFixed(bufferDecoder, start, 4, readFixed32);
|
|
|
+ return readPacked(bufferDecoder, start, readFixed32);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -302,7 +230,7 @@ function readPackedFixed32(bufferDecoder, start) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readPackedFloat(bufferDecoder, start) {
|
|
|
- return readPackedFixed(bufferDecoder, start, 4, readFloat);
|
|
|
+ return readPacked(bufferDecoder, start, readFloat);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -314,7 +242,7 @@ function readPackedFloat(bufferDecoder, start) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readPackedInt32(bufferDecoder, start) {
|
|
|
- return readPackedVariableLength(bufferDecoder, start, readInt32Value);
|
|
|
+ return readPacked(bufferDecoder, start, readInt32);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -326,7 +254,7 @@ function readPackedInt32(bufferDecoder, start) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readPackedInt64(bufferDecoder, start) {
|
|
|
- return readPackedVariableLength(bufferDecoder, start, readInt64Value);
|
|
|
+ return readPacked(bufferDecoder, start, readInt64);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -338,7 +266,7 @@ function readPackedInt64(bufferDecoder, start) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readPackedSfixed32(bufferDecoder, start) {
|
|
|
- return readPackedFixed(bufferDecoder, start, 4, readSfixed32);
|
|
|
+ return readPacked(bufferDecoder, start, readSfixed32);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -350,7 +278,7 @@ function readPackedSfixed32(bufferDecoder, start) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readPackedSfixed64(bufferDecoder, start) {
|
|
|
- return readPackedFixed(bufferDecoder, start, 8, readSfixed64);
|
|
|
+ return readPacked(bufferDecoder, start, readSfixed64);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -362,7 +290,7 @@ function readPackedSfixed64(bufferDecoder, start) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readPackedSint32(bufferDecoder, start) {
|
|
|
- return readPackedVariableLength(bufferDecoder, start, readSint32Value);
|
|
|
+ return readPacked(bufferDecoder, start, readSint32);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -374,7 +302,7 @@ function readPackedSint32(bufferDecoder, start) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readPackedSint64(bufferDecoder, start) {
|
|
|
- return readPackedVariableLength(bufferDecoder, start, readSint64Value);
|
|
|
+ return readPacked(bufferDecoder, start, readSint64);
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -386,51 +314,25 @@ function readPackedSint64(bufferDecoder, start) {
|
|
|
* @package
|
|
|
*/
|
|
|
function readPackedUint32(bufferDecoder, start) {
|
|
|
- return readPackedVariableLength(bufferDecoder, start, readUint32Value);
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Read packed variable length values.
|
|
|
- * @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
|
- * @param {number} start Start of the data.
|
|
|
- * @param {function(!BufferDecoder, number):{value:T, nextCursor: number}}
|
|
|
- * valueFunction
|
|
|
- * @return {!Array<T>}
|
|
|
- * @package
|
|
|
- * @template T
|
|
|
- */
|
|
|
-function readPackedVariableLength(bufferDecoder, start, valueFunction) {
|
|
|
- const /** !Array<T> */ result = [];
|
|
|
- const {lowBits, dataStart} = bufferDecoder.getVarint(start);
|
|
|
- let cursor = dataStart;
|
|
|
- const unsignedLength = lowBits >>> 0;
|
|
|
- while (cursor < dataStart + unsignedLength) {
|
|
|
- const {value, nextCursor} = valueFunction(bufferDecoder, cursor);
|
|
|
- cursor = nextCursor;
|
|
|
- result.push(value);
|
|
|
- }
|
|
|
- return result;
|
|
|
+ return readPacked(bufferDecoder, start, readUint32);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * Read a packed fixed values.
|
|
|
+ * Read packed values.
|
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
|
* @param {number} start Start of the data.
|
|
|
- * @param {number} size End of the data.
|
|
|
* @param {function(!BufferDecoder, number):T} valueFunction
|
|
|
* @return {!Array<T>}
|
|
|
* @package
|
|
|
* @template T
|
|
|
*/
|
|
|
-function readPackedFixed(bufferDecoder, start, size, valueFunction) {
|
|
|
- const {lowBits, dataStart} = bufferDecoder.getVarint(start);
|
|
|
- const unsignedLength = lowBits >>> 0;
|
|
|
- const noOfEntries = unsignedLength / size;
|
|
|
- const /** !Array<T> */ result = new Array(noOfEntries);
|
|
|
- let cursor = dataStart;
|
|
|
- for (let i = 0; i < noOfEntries; i++) {
|
|
|
- result[i] = valueFunction(bufferDecoder, cursor);
|
|
|
- cursor += size;
|
|
|
+function readPacked(bufferDecoder, start, valueFunction) {
|
|
|
+ const /** !Array<T> */ result = [];
|
|
|
+ const unsignedLength = bufferDecoder.getUnsignedVarint32At(start);
|
|
|
+ const dataStart = bufferDecoder.cursor();
|
|
|
+ while (bufferDecoder.cursor() < dataStart + unsignedLength) {
|
|
|
+ checkState(bufferDecoder.cursor() > 0);
|
|
|
+ result.push(valueFunction(bufferDecoder, bufferDecoder.cursor()));
|
|
|
}
|
|
|
return result;
|
|
|
}
|