Protocol Buffers - Google's data interchange format (grpc依赖)
https://developers.google.com/protocol-buffers/
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
743 lines
21 KiB
743 lines
21 KiB
/** |
|
* @fileoverview Implements Writer for writing data as the binary wire format |
|
* bytes array. |
|
*/ |
|
goog.module('protobuf.binary.Writer'); |
|
|
|
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder'); |
|
const ByteString = goog.require('protobuf.ByteString'); |
|
const Int64 = goog.require('protobuf.Int64'); |
|
const WireType = goog.require('protobuf.binary.WireType'); |
|
const {POLYFILL_TEXT_ENCODING, checkFieldNumber, checkTypeUnsignedInt32, checkWireType} = goog.require('protobuf.internal.checks'); |
|
const {concatenateByteArrays} = goog.require('protobuf.binary.uint8arrays'); |
|
const {createTag, getTagLength} = goog.require('protobuf.binary.tag'); |
|
const {encode} = goog.require('protobuf.binary.textencoding'); |
|
|
|
/** |
|
* Returns a valid utf-8 encoder function based on TextEncoder if available or |
|
* a polyfill. |
|
* Some of the environments we run in do not have TextEncoder defined. |
|
* TextEncoder is faster than our polyfill so we prefer it over the polyfill. |
|
* @return {function(string):!Uint8Array} |
|
*/ |
|
function getEncoderFunction() { |
|
if (goog.global['TextEncoder']) { |
|
const textEncoder = new goog.global['TextEncoder']('utf-8'); |
|
return s => s.length === 0 ? new Uint8Array(0) : textEncoder.encode(s); |
|
} |
|
if (POLYFILL_TEXT_ENCODING) { |
|
return encode; |
|
} else { |
|
throw new Error( |
|
'TextEncoder is missing. ' + |
|
'Enable protobuf.defines.POLYFILL_TEXT_ENCODING'); |
|
} |
|
} |
|
|
|
/** @const {function(string): !Uint8Array} */ |
|
const encoderFunction = getEncoderFunction(); |
|
|
|
/** |
|
* Writer provides methods for encoding all protobuf supported type into a |
|
* binary format bytes array. |
|
* Check https://developers.google.com/protocol-buffers/docs/encoding for binary |
|
* format definition. |
|
* @final |
|
* @package |
|
*/ |
|
class Writer { |
|
constructor() { |
|
/** |
|
* Blocks of data that needs to be serialized. After writing all the data, |
|
* the blocks are concatenated into a single Uint8Array. |
|
* @private {!Array<!Uint8Array>} |
|
*/ |
|
this.blocks_ = []; |
|
|
|
/** |
|
* A buffer for writing varint data (tag number + field number for each |
|
* field, int32, uint32 etc.). Before writing a non-varint data block |
|
* (string, fixed32 etc.), the buffer is appended to the block array as a |
|
* new block, and a new buffer is started. |
|
* |
|
* We could've written each varint as a new block instead of writing |
|
* multiple varints in this buffer. But this will increase the number of |
|
* blocks, and concatenating many small blocks is slower than concatenating |
|
* few large blocks. |
|
* |
|
* TODO: Experiment with writing data in a fixed-length |
|
* Uint8Array instead of using a growing buffer. |
|
* |
|
* @private {!Array<number>} |
|
*/ |
|
this.currentBuffer_ = []; |
|
} |
|
|
|
/** |
|
* Converts the encoded data into a Uint8Array. |
|
* The writer is also reset. |
|
* @return {!ArrayBuffer} |
|
*/ |
|
getAndResetResultBuffer() { |
|
this.closeAndStartNewBuffer_(); |
|
const result = concatenateByteArrays(this.blocks_); |
|
this.blocks_ = []; |
|
return result.buffer; |
|
} |
|
|
|
/** |
|
* Encodes a (field number, wire type) tuple into a wire-format field header. |
|
* @param {number} fieldNumber |
|
* @param {!WireType} wireType |
|
*/ |
|
writeTag(fieldNumber, wireType) { |
|
checkFieldNumber(fieldNumber); |
|
checkWireType(wireType); |
|
const tag = createTag(wireType, fieldNumber); |
|
this.writeUnsignedVarint32_(tag); |
|
} |
|
|
|
/** |
|
* Appends the current buffer into the blocks array and starts a new buffer. |
|
* @private |
|
*/ |
|
closeAndStartNewBuffer_() { |
|
this.blocks_.push(new Uint8Array(this.currentBuffer_)); |
|
this.currentBuffer_ = []; |
|
} |
|
|
|
/** |
|
* Encodes a 32-bit integer into its wire-format varint representation and |
|
* stores it in the buffer. |
|
* @param {number} value |
|
* @private |
|
*/ |
|
writeUnsignedVarint32_(value) { |
|
checkTypeUnsignedInt32(value); |
|
while (value > 0x7f) { |
|
this.currentBuffer_.push((value & 0x7f) | 0x80); |
|
value = value >>> 7; |
|
} |
|
this.currentBuffer_.push(value); |
|
} |
|
|
|
/**************************************************************************** |
|
* OPTIONAL METHODS |
|
****************************************************************************/ |
|
|
|
/** |
|
* Writes a boolean value field to the buffer as a varint. |
|
* @param {boolean} value |
|
* @private |
|
*/ |
|
writeBoolValue_(value) { |
|
this.currentBuffer_.push(value ? 1 : 0); |
|
} |
|
|
|
/** |
|
* Writes a boolean value field to the buffer as a varint. |
|
* @param {number} fieldNumber |
|
* @param {boolean} value |
|
*/ |
|
writeBool(fieldNumber, value) { |
|
this.writeTag(fieldNumber, WireType.VARINT); |
|
this.writeBoolValue_(value); |
|
} |
|
|
|
/** |
|
* Writes a bytes value field to the buffer as a length delimited field. |
|
* @param {number} fieldNumber |
|
* @param {!ByteString} value |
|
*/ |
|
writeBytes(fieldNumber, value) { |
|
this.writeTag(fieldNumber, WireType.DELIMITED); |
|
const buffer = value.toArrayBuffer(); |
|
this.writeUnsignedVarint32_(buffer.byteLength); |
|
this.writeRaw_(buffer); |
|
} |
|
|
|
/** |
|
* Writes a double value field to the buffer without tag. |
|
* @param {number} value |
|
* @private |
|
*/ |
|
writeDoubleValue_(value) { |
|
const buffer = new ArrayBuffer(8); |
|
const view = new DataView(buffer); |
|
view.setFloat64(0, value, true); |
|
this.writeRaw_(buffer); |
|
} |
|
|
|
/** |
|
* Writes a double value field to the buffer. |
|
* @param {number} fieldNumber |
|
* @param {number} value |
|
*/ |
|
writeDouble(fieldNumber, value) { |
|
this.writeTag(fieldNumber, WireType.FIXED64); |
|
this.writeDoubleValue_(value); |
|
} |
|
|
|
/** |
|
* Writes a fixed32 value field to the buffer without tag. |
|
* @param {number} value |
|
* @private |
|
*/ |
|
writeFixed32Value_(value) { |
|
const buffer = new ArrayBuffer(4); |
|
const view = new DataView(buffer); |
|
view.setUint32(0, value, true); |
|
this.writeRaw_(buffer); |
|
} |
|
|
|
/** |
|
* Writes a fixed32 value field to the buffer. |
|
* @param {number} fieldNumber |
|
* @param {number} value |
|
*/ |
|
writeFixed32(fieldNumber, value) { |
|
this.writeTag(fieldNumber, WireType.FIXED32); |
|
this.writeFixed32Value_(value); |
|
} |
|
|
|
/** |
|
* Writes a float value field to the buffer without tag. |
|
* @param {number} value |
|
* @private |
|
*/ |
|
writeFloatValue_(value) { |
|
const buffer = new ArrayBuffer(4); |
|
const view = new DataView(buffer); |
|
view.setFloat32(0, value, true); |
|
this.writeRaw_(buffer); |
|
} |
|
|
|
/** |
|
* Writes a float value field to the buffer. |
|
* @param {number} fieldNumber |
|
* @param {number} value |
|
*/ |
|
writeFloat(fieldNumber, value) { |
|
this.writeTag(fieldNumber, WireType.FIXED32); |
|
this.writeFloatValue_(value); |
|
} |
|
|
|
/** |
|
* Writes a int32 value field to the buffer as a varint without tag. |
|
* @param {number} value |
|
* @private |
|
*/ |
|
writeInt32Value_(value) { |
|
if (value >= 0) { |
|
this.writeVarint64_(0, value); |
|
} else { |
|
this.writeVarint64_(0xFFFFFFFF, value); |
|
} |
|
} |
|
|
|
/** |
|
* Writes a int32 value field to the buffer as a varint. |
|
* @param {number} fieldNumber |
|
* @param {number} value |
|
*/ |
|
writeInt32(fieldNumber, value) { |
|
this.writeTag(fieldNumber, WireType.VARINT); |
|
this.writeInt32Value_(value); |
|
} |
|
|
|
/** |
|
* Writes a int64 value field to the buffer as a varint. |
|
* @param {number} fieldNumber |
|
* @param {!Int64} value |
|
*/ |
|
writeInt64(fieldNumber, value) { |
|
this.writeTag(fieldNumber, WireType.VARINT); |
|
this.writeVarint64_(value.getHighBits(), value.getLowBits()); |
|
} |
|
|
|
/** |
|
* Writes a sfixed32 value field to the buffer. |
|
* @param {number} value |
|
* @private |
|
*/ |
|
writeSfixed32Value_(value) { |
|
const buffer = new ArrayBuffer(4); |
|
const view = new DataView(buffer); |
|
view.setInt32(0, value, true); |
|
this.writeRaw_(buffer); |
|
} |
|
|
|
/** |
|
* Writes a sfixed32 value field to the buffer. |
|
* @param {number} fieldNumber |
|
* @param {number} value |
|
*/ |
|
writeSfixed32(fieldNumber, value) { |
|
this.writeTag(fieldNumber, WireType.FIXED32); |
|
this.writeSfixed32Value_(value); |
|
} |
|
|
|
/** |
|
* Writes a sfixed64 value field to the buffer without tag. |
|
* @param {!Int64} value |
|
* @private |
|
*/ |
|
writeSfixed64Value_(value) { |
|
const buffer = new ArrayBuffer(8); |
|
const view = new DataView(buffer); |
|
view.setInt32(0, value.getLowBits(), true); |
|
view.setInt32(4, value.getHighBits(), true); |
|
this.writeRaw_(buffer); |
|
} |
|
|
|
/** |
|
* Writes a sfixed64 value field to the buffer. |
|
* @param {number} fieldNumber |
|
* @param {!Int64} value |
|
*/ |
|
writeSfixed64(fieldNumber, value) { |
|
this.writeTag(fieldNumber, WireType.FIXED64); |
|
this.writeSfixed64Value_(value); |
|
} |
|
|
|
/** |
|
* Writes a sfixed64 value field to the buffer. |
|
* @param {number} fieldNumber |
|
*/ |
|
writeStartGroup(fieldNumber) { |
|
this.writeTag(fieldNumber, WireType.START_GROUP); |
|
} |
|
|
|
/** |
|
* Writes a sfixed64 value field to the buffer. |
|
* @param {number} fieldNumber |
|
*/ |
|
writeEndGroup(fieldNumber) { |
|
this.writeTag(fieldNumber, WireType.END_GROUP); |
|
} |
|
|
|
/** |
|
* Writes a uint32 value field to the buffer as a varint without tag. |
|
* @param {number} value |
|
* @private |
|
*/ |
|
writeUint32Value_(value) { |
|
this.writeVarint64_(0, value); |
|
} |
|
|
|
/** |
|
* Writes a uint32 value field to the buffer as a varint. |
|
* @param {number} fieldNumber |
|
* @param {number} value |
|
*/ |
|
writeUint32(fieldNumber, value) { |
|
this.writeTag(fieldNumber, WireType.VARINT); |
|
this.writeUint32Value_(value); |
|
} |
|
|
|
/** |
|
* Writes the bits of a 64 bit number to the buffer as a varint. |
|
* @param {number} highBits |
|
* @param {number} lowBits |
|
* @private |
|
*/ |
|
writeVarint64_(highBits, lowBits) { |
|
for (let i = 0; i < 28; i = i + 7) { |
|
const shift = lowBits >>> i; |
|
const hasNext = !((shift >>> 7) === 0 && highBits === 0); |
|
const byte = (hasNext ? shift | 0x80 : shift) & 0xFF; |
|
this.currentBuffer_.push(byte); |
|
if (!hasNext) { |
|
return; |
|
} |
|
} |
|
|
|
const splitBits = ((lowBits >>> 28) & 0x0F) | ((highBits & 0x07) << 4); |
|
const hasMoreBits = !((highBits >> 3) === 0); |
|
this.currentBuffer_.push( |
|
(hasMoreBits ? splitBits | 0x80 : splitBits) & 0xFF); |
|
|
|
if (!hasMoreBits) { |
|
return; |
|
} |
|
|
|
for (let i = 3; i < 31; i = i + 7) { |
|
const shift = highBits >>> i; |
|
const hasNext = !((shift >>> 7) === 0); |
|
const byte = (hasNext ? shift | 0x80 : shift) & 0xFF; |
|
this.currentBuffer_.push(byte); |
|
if (!hasNext) { |
|
return; |
|
} |
|
} |
|
|
|
this.currentBuffer_.push((highBits >>> 31) & 0x01); |
|
} |
|
|
|
/** |
|
* Writes a sint32 value field to the buffer as a varint without tag. |
|
* @param {number} value |
|
* @private |
|
*/ |
|
writeSint32Value_(value) { |
|
value = (value << 1) ^ (value >> 31); |
|
this.writeVarint64_(0, value); |
|
} |
|
|
|
/** |
|
* Writes a sint32 value field to the buffer as a varint. |
|
* @param {number} fieldNumber |
|
* @param {number} value |
|
*/ |
|
writeSint32(fieldNumber, value) { |
|
this.writeTag(fieldNumber, WireType.VARINT); |
|
this.writeSint32Value_(value); |
|
} |
|
|
|
/** |
|
* Writes a sint64 value field to the buffer as a varint without tag. |
|
* @param {!Int64} value |
|
* @private |
|
*/ |
|
writeSint64Value_(value) { |
|
const highBits = value.getHighBits(); |
|
const lowBits = value.getLowBits(); |
|
|
|
const sign = highBits >> 31; |
|
const encodedLowBits = (lowBits << 1) ^ sign; |
|
const encodedHighBits = ((highBits << 1) | (lowBits >>> 31)) ^ sign; |
|
this.writeVarint64_(encodedHighBits, encodedLowBits); |
|
} |
|
|
|
/** |
|
* Writes a sint64 value field to the buffer as a varint. |
|
* @param {number} fieldNumber |
|
* @param {!Int64} value |
|
*/ |
|
writeSint64(fieldNumber, value) { |
|
this.writeTag(fieldNumber, WireType.VARINT); |
|
this.writeSint64Value_(value); |
|
} |
|
|
|
/** |
|
* Writes a string value field to the buffer as a varint. |
|
* @param {number} fieldNumber |
|
* @param {string} value |
|
*/ |
|
writeString(fieldNumber, value) { |
|
this.writeTag(fieldNumber, WireType.DELIMITED); |
|
const array = encoderFunction(value); |
|
this.writeUnsignedVarint32_(array.length); |
|
this.closeAndStartNewBuffer_(); |
|
this.blocks_.push(array); |
|
} |
|
|
|
/** |
|
* Writes raw bytes to the buffer. |
|
* @param {!ArrayBuffer} arrayBuffer |
|
* @private |
|
*/ |
|
writeRaw_(arrayBuffer) { |
|
this.closeAndStartNewBuffer_(); |
|
this.blocks_.push(new Uint8Array(arrayBuffer)); |
|
} |
|
|
|
/** |
|
* Writes raw bytes to the buffer. |
|
* @param {!BufferDecoder} bufferDecoder |
|
* @param {number} start |
|
* @param {!WireType} wireType |
|
* @param {number} fieldNumber |
|
* @package |
|
*/ |
|
writeBufferDecoder(bufferDecoder, start, wireType, fieldNumber) { |
|
this.closeAndStartNewBuffer_(); |
|
const dataLength = |
|
getTagLength(bufferDecoder, start, wireType, fieldNumber); |
|
this.blocks_.push( |
|
bufferDecoder.subBufferDecoder(start, dataLength).asUint8Array()); |
|
} |
|
|
|
/** |
|
* Write the whole bytes as a length delimited field. |
|
* @param {number} fieldNumber |
|
* @param {!ArrayBuffer} arrayBuffer |
|
*/ |
|
writeDelimited(fieldNumber, arrayBuffer) { |
|
this.writeTag(fieldNumber, WireType.DELIMITED); |
|
this.writeUnsignedVarint32_(arrayBuffer.byteLength); |
|
this.writeRaw_(arrayBuffer); |
|
} |
|
|
|
/**************************************************************************** |
|
* REPEATED METHODS |
|
****************************************************************************/ |
|
|
|
/** |
|
* Writes repeated boolean values to the buffer as unpacked varints. |
|
* @param {number} fieldNumber |
|
* @param {!Array<boolean>} values |
|
*/ |
|
writeRepeatedBool(fieldNumber, values) { |
|
values.forEach(val => this.writeBool(fieldNumber, val)); |
|
} |
|
|
|
/** |
|
* Writes repeated boolean values to the buffer as packed varints. |
|
* @param {number} fieldNumber |
|
* @param {!Array<boolean>} values |
|
*/ |
|
writePackedBool(fieldNumber, values) { |
|
this.writeFixedPacked_( |
|
fieldNumber, values, val => this.writeBoolValue_(val), 1); |
|
} |
|
|
|
/** |
|
* Writes repeated double values to the buffer as unpacked fixed64. |
|
* @param {number} fieldNumber |
|
* @param {!Array<number>} values |
|
*/ |
|
writeRepeatedDouble(fieldNumber, values) { |
|
values.forEach(val => this.writeDouble(fieldNumber, val)); |
|
} |
|
|
|
/** |
|
* Writes repeated double values to the buffer as packed fixed64. |
|
* @param {number} fieldNumber |
|
* @param {!Array<number>} values |
|
*/ |
|
writePackedDouble(fieldNumber, values) { |
|
this.writeFixedPacked_( |
|
fieldNumber, values, val => this.writeDoubleValue_(val), 8); |
|
} |
|
|
|
/** |
|
* Writes repeated fixed32 values to the buffer as unpacked fixed32. |
|
* @param {number} fieldNumber |
|
* @param {!Array<number>} values |
|
*/ |
|
writeRepeatedFixed32(fieldNumber, values) { |
|
values.forEach(val => this.writeFixed32(fieldNumber, val)); |
|
} |
|
|
|
/** |
|
* Writes repeated fixed32 values to the buffer as packed fixed32. |
|
* @param {number} fieldNumber |
|
* @param {!Array<number>} values |
|
*/ |
|
writePackedFixed32(fieldNumber, values) { |
|
this.writeFixedPacked_( |
|
fieldNumber, values, val => this.writeFixed32Value_(val), 4); |
|
} |
|
|
|
/** |
|
* Writes repeated float values to the buffer as unpacked fixed64. |
|
* @param {number} fieldNumber |
|
* @param {!Array<number>} values |
|
*/ |
|
writeRepeatedFloat(fieldNumber, values) { |
|
values.forEach(val => this.writeFloat(fieldNumber, val)); |
|
} |
|
|
|
/** |
|
* Writes repeated float values to the buffer as packed fixed64. |
|
* @param {number} fieldNumber |
|
* @param {!Array<number>} values |
|
*/ |
|
writePackedFloat(fieldNumber, values) { |
|
this.writeFixedPacked_( |
|
fieldNumber, values, val => this.writeFloatValue_(val), 4); |
|
} |
|
|
|
/** |
|
* Writes repeated int32 values to the buffer as unpacked int32. |
|
* @param {number} fieldNumber |
|
* @param {!Array<number>} values |
|
*/ |
|
writeRepeatedInt32(fieldNumber, values) { |
|
values.forEach(val => this.writeInt32(fieldNumber, val)); |
|
} |
|
|
|
/** |
|
* Writes repeated int32 values to the buffer as packed int32. |
|
* @param {number} fieldNumber |
|
* @param {!Array<number>} values |
|
*/ |
|
writePackedInt32(fieldNumber, values) { |
|
this.writeVariablePacked_( |
|
fieldNumber, values, (writer, val) => writer.writeInt32Value_(val)); |
|
} |
|
|
|
/** |
|
* Writes repeated int64 values to the buffer as unpacked varint. |
|
* @param {number} fieldNumber |
|
* @param {!Array<!Int64>} values |
|
*/ |
|
writeRepeatedInt64(fieldNumber, values) { |
|
values.forEach(val => this.writeInt64(fieldNumber, val)); |
|
} |
|
|
|
/** |
|
* Writes repeated int64 values to the buffer as packed varint. |
|
* @param {number} fieldNumber |
|
* @param {!Array<!Int64>} values |
|
*/ |
|
writePackedInt64(fieldNumber, values) { |
|
this.writeVariablePacked_( |
|
fieldNumber, values, |
|
(writer, val) => |
|
writer.writeVarint64_(val.getHighBits(), val.getLowBits())); |
|
} |
|
|
|
/** |
|
* Writes repeated sfixed32 values to the buffer as unpacked fixed32. |
|
* @param {number} fieldNumber |
|
* @param {!Array<number>} values |
|
*/ |
|
writeRepeatedSfixed32(fieldNumber, values) { |
|
values.forEach(val => this.writeSfixed32(fieldNumber, val)); |
|
} |
|
|
|
/** |
|
* Writes repeated sfixed32 values to the buffer as packed fixed32. |
|
* @param {number} fieldNumber |
|
* @param {!Array<number>} values |
|
*/ |
|
writePackedSfixed32(fieldNumber, values) { |
|
this.writeFixedPacked_( |
|
fieldNumber, values, val => this.writeSfixed32Value_(val), 4); |
|
} |
|
|
|
/** |
|
* Writes repeated sfixed64 values to the buffer as unpacked fixed64. |
|
* @param {number} fieldNumber |
|
* @param {!Array<!Int64>} values |
|
*/ |
|
writeRepeatedSfixed64(fieldNumber, values) { |
|
values.forEach(val => this.writeSfixed64(fieldNumber, val)); |
|
} |
|
|
|
/** |
|
* Writes repeated sfixed64 values to the buffer as packed fixed64. |
|
* @param {number} fieldNumber |
|
* @param {!Array<!Int64>} values |
|
*/ |
|
writePackedSfixed64(fieldNumber, values) { |
|
this.writeFixedPacked_( |
|
fieldNumber, values, val => this.writeSfixed64Value_(val), 8); |
|
} |
|
|
|
/** |
|
* Writes repeated sint32 values to the buffer as unpacked sint32. |
|
* @param {number} fieldNumber |
|
* @param {!Array<number>} values |
|
*/ |
|
writeRepeatedSint32(fieldNumber, values) { |
|
values.forEach(val => this.writeSint32(fieldNumber, val)); |
|
} |
|
|
|
/** |
|
* Writes repeated sint32 values to the buffer as packed sint32. |
|
* @param {number} fieldNumber |
|
* @param {!Array<number>} values |
|
*/ |
|
writePackedSint32(fieldNumber, values) { |
|
this.writeVariablePacked_( |
|
fieldNumber, values, (writer, val) => writer.writeSint32Value_(val)); |
|
} |
|
|
|
/** |
|
* Writes repeated sint64 values to the buffer as unpacked varint. |
|
* @param {number} fieldNumber |
|
* @param {!Array<!Int64>} values |
|
*/ |
|
writeRepeatedSint64(fieldNumber, values) { |
|
values.forEach(val => this.writeSint64(fieldNumber, val)); |
|
} |
|
|
|
/** |
|
* Writes repeated sint64 values to the buffer as packed varint. |
|
* @param {number} fieldNumber |
|
* @param {!Array<!Int64>} values |
|
*/ |
|
writePackedSint64(fieldNumber, values) { |
|
this.writeVariablePacked_( |
|
fieldNumber, values, (writer, val) => writer.writeSint64Value_(val)); |
|
} |
|
|
|
/** |
|
* Writes repeated uint32 values to the buffer as unpacked uint32. |
|
* @param {number} fieldNumber |
|
* @param {!Array<number>} values |
|
*/ |
|
writeRepeatedUint32(fieldNumber, values) { |
|
values.forEach(val => this.writeUint32(fieldNumber, val)); |
|
} |
|
|
|
/** |
|
* Writes repeated uint32 values to the buffer as packed uint32. |
|
* @param {number} fieldNumber |
|
* @param {!Array<number>} values |
|
*/ |
|
writePackedUint32(fieldNumber, values) { |
|
this.writeVariablePacked_( |
|
fieldNumber, values, (writer, val) => writer.writeUint32Value_(val)); |
|
} |
|
|
|
/** |
|
* Writes repeated bytes values to the buffer. |
|
* @param {number} fieldNumber |
|
* @param {!Array<!ByteString>} values |
|
*/ |
|
writeRepeatedBytes(fieldNumber, values) { |
|
values.forEach(val => this.writeBytes(fieldNumber, val)); |
|
} |
|
|
|
/** |
|
* Writes packed fields with fixed length. |
|
* @param {number} fieldNumber |
|
* @param {!Array<T>} values |
|
* @param {function(T)} valueWriter |
|
* @param {number} entitySize |
|
* @template T |
|
* @private |
|
*/ |
|
writeFixedPacked_(fieldNumber, values, valueWriter, entitySize) { |
|
if (values.length === 0) { |
|
return; |
|
} |
|
this.writeTag(fieldNumber, WireType.DELIMITED); |
|
this.writeUnsignedVarint32_(values.length * entitySize); |
|
this.closeAndStartNewBuffer_(); |
|
values.forEach(value => valueWriter(value)); |
|
} |
|
|
|
/** |
|
* Writes packed fields with variable length. |
|
* @param {number} fieldNumber |
|
* @param {!Array<T>} values |
|
* @param {function(!Writer, T)} valueWriter |
|
* @template T |
|
* @private |
|
*/ |
|
writeVariablePacked_(fieldNumber, values, valueWriter) { |
|
if (values.length === 0) { |
|
return; |
|
} |
|
const writer = new Writer(); |
|
values.forEach(val => valueWriter(writer, val)); |
|
const bytes = writer.getAndResetResultBuffer(); |
|
this.writeDelimited(fieldNumber, bytes); |
|
} |
|
|
|
/** |
|
* Writes repeated string values to the buffer. |
|
* @param {number} fieldNumber |
|
* @param {!Array<string>} values |
|
*/ |
|
writeRepeatedString(fieldNumber, values) { |
|
values.forEach(val => this.writeString(fieldNumber, val)); |
|
} |
|
} |
|
|
|
exports = Writer;
|
|
|