365 lines
11 KiB
JavaScript
365 lines
11 KiB
JavaScript
/**
|
|
* @fileoverview Helper methods for reading data from the binary wire format.
|
|
*/
|
|
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 value from the binary bytes.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {boolean}
|
|
* @package
|
|
*/
|
|
function readBool(bufferDecoder, start) {
|
|
const {lowBits, highBits} = bufferDecoder.getVarint(start);
|
|
return lowBits !== 0 || highBits !== 0;
|
|
}
|
|
|
|
/**
|
|
* Reads a ByteString value from the binary bytes.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!ByteString}
|
|
* @package
|
|
*/
|
|
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} start Start of the data.
|
|
* @return {number}
|
|
* @package
|
|
*/
|
|
function readInt32(bufferDecoder, start) {
|
|
// 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;
|
|
}
|
|
|
|
/**
|
|
* Reads a int32 value from the binary bytes encoded as varint.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!Int64}
|
|
* @package
|
|
*/
|
|
function readInt64(bufferDecoder, start) {
|
|
const {lowBits, highBits} = bufferDecoder.getVarint(start);
|
|
return Int64.fromBits(lowBits, highBits);
|
|
}
|
|
|
|
/**
|
|
* Reads a fixed int32 value from the binary bytes.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {number}
|
|
* @package
|
|
*/
|
|
function readFixed32(bufferDecoder, start) {
|
|
return bufferDecoder.getUint32(start);
|
|
}
|
|
|
|
/**
|
|
* Reads a float value from the binary bytes.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {number}
|
|
* @package
|
|
*/
|
|
function readFloat(bufferDecoder, start) {
|
|
return bufferDecoder.getFloat32(start);
|
|
}
|
|
|
|
/**
|
|
* Reads a fixed int64 value from the binary bytes.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!Int64}
|
|
* @package
|
|
*/
|
|
function readSfixed64(bufferDecoder, start) {
|
|
const lowBits = bufferDecoder.getInt32(start);
|
|
const highBits = bufferDecoder.getInt32(start + 4);
|
|
return Int64.fromBits(lowBits, highBits);
|
|
}
|
|
|
|
/**
|
|
* Reads a sint64 value from the binary bytes encoded as varint.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!Int64}
|
|
* @package
|
|
*/
|
|
function readSint64(bufferDecoder, start) {
|
|
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);
|
|
}
|
|
|
|
/**
|
|
* Reads a sint32 value from the binary bytes encoded as varint.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {number}
|
|
* @package
|
|
*/
|
|
function readSint32(bufferDecoder, start) {
|
|
return readSint64(bufferDecoder, start).getLowBits();
|
|
}
|
|
|
|
/**
|
|
* Read a subarray of bytes representing a length delimited field.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!BufferDecoder}
|
|
* @package
|
|
*/
|
|
function readDelimited(bufferDecoder, start) {
|
|
const unsignedLength = bufferDecoder.getUnsignedVarint32At(start);
|
|
return bufferDecoder.subBufferDecoder(bufferDecoder.cursor(), unsignedLength);
|
|
}
|
|
|
|
/**
|
|
* Reads a string value from the binary bytes.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {string}
|
|
* @package
|
|
*/
|
|
function readString(bufferDecoder, start) {
|
|
return readDelimited(bufferDecoder, start).asString();
|
|
}
|
|
|
|
/**
|
|
* Reads a uint32 value from the binary bytes encoded as varint.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {number}
|
|
* @package
|
|
*/
|
|
function readUint32(bufferDecoder, start) {
|
|
return bufferDecoder.getUnsignedVarint32At(start);
|
|
}
|
|
|
|
/**
|
|
* Reads a double value from the binary bytes.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {number}
|
|
* @package
|
|
*/
|
|
function readDouble(bufferDecoder, start) {
|
|
return bufferDecoder.getFloat64(start);
|
|
}
|
|
|
|
/**
|
|
* Reads a fixed int32 value from the binary bytes.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {number}
|
|
* @package
|
|
*/
|
|
function readSfixed32(bufferDecoder, start) {
|
|
return bufferDecoder.getInt32(start);
|
|
}
|
|
|
|
/******************************************************************************
|
|
* REPEATED FUNCTIONS
|
|
******************************************************************************/
|
|
|
|
/**
|
|
* Reads a packed bool field, which consists of a length header and a list of
|
|
* unsigned varints.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!Array<boolean>}
|
|
* @package
|
|
*/
|
|
function readPackedBool(bufferDecoder, start) {
|
|
return readPacked(bufferDecoder, start, readBool);
|
|
}
|
|
|
|
/**
|
|
* Reads a packed double field, which consists of a length header and a list of
|
|
* fixed64.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!Array<number>}
|
|
* @package
|
|
*/
|
|
function readPackedDouble(bufferDecoder, start) {
|
|
return readPacked(bufferDecoder, start, readDouble);
|
|
}
|
|
|
|
/**
|
|
* Reads a packed fixed32 field, which consists of a length header and a list of
|
|
* fixed32.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!Array<number>}
|
|
* @package
|
|
*/
|
|
function readPackedFixed32(bufferDecoder, start) {
|
|
return readPacked(bufferDecoder, start, readFixed32);
|
|
}
|
|
|
|
/**
|
|
* Reads a packed float field, which consists of a length header and a list of
|
|
* fixed64.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!Array<number>}
|
|
* @package
|
|
*/
|
|
function readPackedFloat(bufferDecoder, start) {
|
|
return readPacked(bufferDecoder, start, readFloat);
|
|
}
|
|
|
|
/**
|
|
* Reads a packed int32 field, which consists of a length header and a list of
|
|
* varint.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!Array<number>}
|
|
* @package
|
|
*/
|
|
function readPackedInt32(bufferDecoder, start) {
|
|
return readPacked(bufferDecoder, start, readInt32);
|
|
}
|
|
|
|
/**
|
|
* Reads a packed int64 field, which consists of a length header and a list
|
|
* of int64.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!Array<!Int64>}
|
|
* @package
|
|
*/
|
|
function readPackedInt64(bufferDecoder, start) {
|
|
return readPacked(bufferDecoder, start, readInt64);
|
|
}
|
|
|
|
/**
|
|
* Reads a packed sfixed32 field, which consists of a length header and a list
|
|
* of sfixed32.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!Array<number>}
|
|
* @package
|
|
*/
|
|
function readPackedSfixed32(bufferDecoder, start) {
|
|
return readPacked(bufferDecoder, start, readSfixed32);
|
|
}
|
|
|
|
/**
|
|
* Reads a packed sfixed64 field, which consists of a length header and a list
|
|
* of sfixed64.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!Array<!Int64>}
|
|
* @package
|
|
*/
|
|
function readPackedSfixed64(bufferDecoder, start) {
|
|
return readPacked(bufferDecoder, start, readSfixed64);
|
|
}
|
|
|
|
/**
|
|
* Reads a packed sint32 field, which consists of a length header and a list of
|
|
* varint.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!Array<number>}
|
|
* @package
|
|
*/
|
|
function readPackedSint32(bufferDecoder, start) {
|
|
return readPacked(bufferDecoder, start, readSint32);
|
|
}
|
|
|
|
/**
|
|
* Reads a packed sint64 field, which consists of a length header and a list
|
|
* of sint64.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!Array<!Int64>}
|
|
* @package
|
|
*/
|
|
function readPackedSint64(bufferDecoder, start) {
|
|
return readPacked(bufferDecoder, start, readSint64);
|
|
}
|
|
|
|
/**
|
|
* Reads a packed uint32 field, which consists of a length header and a list of
|
|
* varint.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @return {!Array<number>}
|
|
* @package
|
|
*/
|
|
function readPackedUint32(bufferDecoder, start) {
|
|
return readPacked(bufferDecoder, start, readUint32);
|
|
}
|
|
|
|
/**
|
|
* Read packed values.
|
|
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
|
* @param {number} start Start of the data.
|
|
* @param {function(!BufferDecoder, number):T} valueFunction
|
|
* @return {!Array<T>}
|
|
* @package
|
|
* @template T
|
|
*/
|
|
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;
|
|
}
|
|
|
|
exports = {
|
|
readBool,
|
|
readBytes,
|
|
readDelimited,
|
|
readDouble,
|
|
readFixed32,
|
|
readFloat,
|
|
readInt32,
|
|
readInt64,
|
|
readSint32,
|
|
readSint64,
|
|
readSfixed32,
|
|
readSfixed64,
|
|
readString,
|
|
readUint32,
|
|
readPackedBool,
|
|
readPackedDouble,
|
|
readPackedFixed32,
|
|
readPackedFloat,
|
|
readPackedInt32,
|
|
readPackedInt64,
|
|
readPackedSfixed32,
|
|
readPackedSfixed64,
|
|
readPackedSint32,
|
|
readPackedSint64,
|
|
readPackedUint32,
|
|
};
|