aboutsummaryrefslogtreecommitdiffhomepage
path: root/js
diff options
context:
space:
mode:
authorGravatar Jisi Liu <jisi.liu@gmail.com>2016-03-30 11:39:59 -0700
committerGravatar Jisi Liu <jisi.liu@gmail.com>2016-03-30 11:39:59 -0700
commit3b3c8abb9635eb3ea078a821a99c9ef29d66dff7 (patch)
tree7d2ec154f15c9f9153d890e76b6cf30e471ea488 /js
parent78105897a8f01c7be9cf8502b6c58d47eb1ccdd7 (diff)
Integrate google internal changes.
Diffstat (limited to 'js')
-rw-r--r--js/binary/constants.js46
-rw-r--r--js/binary/decoder.js12
-rw-r--r--js/binary/decoder_test.js120
-rw-r--r--js/binary/encoder.js430
-rw-r--r--js/binary/proto_test.js315
-rw-r--r--js/binary/reader.js8
-rw-r--r--js/binary/reader_test.js74
-rw-r--r--js/binary/utils.js64
-rw-r--r--js/binary/utils_test.js27
-rw-r--r--js/binary/writer.js1205
-rw-r--r--js/debug.js2
-rw-r--r--js/debug_test.js1
-rw-r--r--js/message.js284
-rw-r--r--js/message_test.js50
-rw-r--r--js/proto3_test.js89
-rw-r--r--js/test.proto12
16 files changed, 1500 insertions, 1239 deletions
diff --git a/js/binary/constants.js b/js/binary/constants.js
index a976e0b6..836216bf 100644
--- a/js/binary/constants.js
+++ b/js/binary/constants.js
@@ -41,11 +41,16 @@ goog.provide('jspb.BinaryMessage');
goog.provide('jspb.BuilderFunction');
goog.provide('jspb.ByteSource');
goog.provide('jspb.ClonerFunction');
+goog.provide('jspb.ComparerFunction');
goog.provide('jspb.ConstBinaryMessage');
+goog.provide('jspb.PrunerFunction');
goog.provide('jspb.ReaderFunction');
goog.provide('jspb.RecyclerFunction');
+goog.provide('jspb.RepeatedFieldType');
+goog.provide('jspb.ScalarFieldType');
goog.provide('jspb.WriterFunction');
+
goog.forwardDeclare('jspb.Message');
goog.forwardDeclare('jsproto.BinaryExtension');
@@ -79,11 +84,29 @@ jspb.ByteSource;
/**
+ * A scalar field in jspb can be a boolean, number, or string.
+ * @typedef {boolean|number|string}
+ */
+jspb.ScalarFieldType;
+
+
+/**
+ * A repeated field in jspb is an array of scalars, blobs, or messages.
+ * @typedef {!Array<jspb.ScalarFieldType>|
+ !Array<!Uint8Array>|
+ !Array<!jspb.BinaryMessage>}
+ */
+jspb.RepeatedFieldType;
+
+
+/**
* A field in jspb can be a scalar, a block of bytes, another proto, or an
* array of any of the above.
- * @typedef {boolean|number|string|Uint8Array|
- jspb.BinaryMessage|jsproto.BinaryExtension|
- Array<jspb.AnyFieldType>}
+ * @typedef {jspb.ScalarFieldType|
+ jspb.RepeatedFieldType|
+ !Uint8Array|
+ !jspb.BinaryMessage|
+ !jsproto.BinaryExtension}
*/
jspb.AnyFieldType;
@@ -125,6 +148,23 @@ jspb.WriterFunction;
/**
+ * A pruner function removes default-valued fields and empty submessages from a
+ * message and returns either the pruned message or null if the entire message
+ * was pruned away.
+ * @typedef {function(?jspb.BinaryMessage):?jspb.BinaryMessage}
+ */
+jspb.PrunerFunction;
+
+
+/**
+ * A comparer function returns true if two protos are equal.
+ * @typedef {!function(?jspb.ConstBinaryMessage,
+ * ?jspb.ConstBinaryMessage):boolean}
+ */
+jspb.ComparerFunction;
+
+
+/**
* Field type codes, taken from proto2/public/wire_format_lite.h.
* @enum {number}
*/
diff --git a/js/binary/decoder.js b/js/binary/decoder.js
index 9004eff0..41094a36 100644
--- a/js/binary/decoder.js
+++ b/js/binary/decoder.js
@@ -223,7 +223,7 @@ jspb.BinaryIterator.prototype.next = function() {
jspb.BinaryDecoder = function(opt_bytes, opt_start, opt_length) {
/**
* Typed byte-wise view of the source buffer.
- * @private {Uint8Array}
+ * @private {?Uint8Array}
*/
this.bytes_ = null;
@@ -335,7 +335,7 @@ jspb.BinaryDecoder.prototype.clear = function() {
/**
* Returns the raw buffer.
- * @return {Uint8Array} The raw buffer.
+ * @return {?Uint8Array} The raw buffer.
*/
jspb.BinaryDecoder.prototype.getBuffer = function() {
return this.bytes_;
@@ -631,6 +631,7 @@ jspb.BinaryDecoder.prototype.readUnsignedVarint32String = function() {
return value.toString();
};
+
/**
* Reads a 32-bit signed variant and returns its value as a string.
*
@@ -950,14 +951,15 @@ jspb.BinaryDecoder.prototype.readStringWithLength = function() {
* Reads a block of raw bytes from the binary stream.
*
* @param {number} length The number of bytes to read.
- * @return {Uint8Array} The decoded block of bytes, or null if the length was
- * invalid.
+ * @return {!Uint8Array} The decoded block of bytes, or an empty block if the
+ * length was invalid.
*/
jspb.BinaryDecoder.prototype.readBytes = function(length) {
if (length < 0 ||
this.cursor_ + length > this.bytes_.length) {
this.error_ = true;
- return null;
+ goog.asserts.fail('Invalid byte length!');
+ return new Uint8Array(0);
}
var result = this.bytes_.subarray(this.cursor_, this.cursor_ + length);
diff --git a/js/binary/decoder_test.js b/js/binary/decoder_test.js
index 27342e49..d045e912 100644
--- a/js/binary/decoder_test.js
+++ b/js/binary/decoder_test.js
@@ -44,11 +44,11 @@
goog.require('goog.testing.asserts');
goog.require('jspb.BinaryConstants');
goog.require('jspb.BinaryDecoder');
-goog.require('jspb.BinaryWriter');
+goog.require('jspb.BinaryEncoder');
/**
- * Tests raw encoding and decoding of unsigned types.
+ * Tests encoding and decoding of unsigned types.
* @param {Function} readValue
* @param {Function} writeValue
* @param {number} epsilon
@@ -58,34 +58,38 @@ goog.require('jspb.BinaryWriter');
*/
function doTestUnsignedValue(readValue,
writeValue, epsilon, upperLimit, filter) {
- var writer = new jspb.BinaryWriter();
+ var encoder = new jspb.BinaryEncoder();
// Encode zero and limits.
- writeValue.call(writer, filter(0));
- writeValue.call(writer, filter(epsilon));
- writeValue.call(writer, filter(upperLimit));
+ writeValue.call(encoder, filter(0));
+ writeValue.call(encoder, filter(epsilon));
+ writeValue.call(encoder, filter(upperLimit));
// Encode positive values.
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
- writeValue.call(writer, filter(cursor));
+ writeValue.call(encoder, filter(cursor));
}
- var reader = jspb.BinaryDecoder.alloc(writer.getResultBuffer());
+ var decoder = jspb.BinaryDecoder.alloc(encoder.end());
// Check zero and limits.
- assertEquals(filter(0), readValue.call(reader));
- assertEquals(filter(epsilon), readValue.call(reader));
- assertEquals(filter(upperLimit), readValue.call(reader));
+ assertEquals(filter(0), readValue.call(decoder));
+ assertEquals(filter(epsilon), readValue.call(decoder));
+ assertEquals(filter(upperLimit), readValue.call(decoder));
// Check positive values.
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
- if (filter(cursor) != readValue.call(reader)) throw 'fail!';
+ if (filter(cursor) != readValue.call(decoder)) throw 'fail!';
}
+
+ // Encoding values outside the valid range should assert.
+ assertThrows(function() {writeValue.call(encoder, -1);});
+ assertThrows(function() {writeValue.call(encoder, upperLimit * 1.1);});
}
/**
- * Tests raw encoding and decoding of signed types.
+ * Tests encoding and decoding of signed types.
* @param {Function} readValue
* @param {Function} writeValue
* @param {number} epsilon
@@ -96,44 +100,48 @@ function doTestUnsignedValue(readValue,
*/
function doTestSignedValue(readValue,
writeValue, epsilon, lowerLimit, upperLimit, filter) {
- var writer = new jspb.BinaryWriter();
+ var encoder = new jspb.BinaryEncoder();
// Encode zero and limits.
- writeValue.call(writer, filter(lowerLimit));
- writeValue.call(writer, filter(-epsilon));
- writeValue.call(writer, filter(0));
- writeValue.call(writer, filter(epsilon));
- writeValue.call(writer, filter(upperLimit));
+ writeValue.call(encoder, filter(lowerLimit));
+ writeValue.call(encoder, filter(-epsilon));
+ writeValue.call(encoder, filter(0));
+ writeValue.call(encoder, filter(epsilon));
+ writeValue.call(encoder, filter(upperLimit));
var inputValues = [];
// Encode negative values.
for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) {
var val = filter(cursor);
- writeValue.call(writer, val);
+ writeValue.call(encoder, val);
inputValues.push(val);
}
// Encode positive values.
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
var val = filter(cursor);
- writeValue.call(writer, val);
+ writeValue.call(encoder, val);
inputValues.push(val);
}
- var reader = jspb.BinaryDecoder.alloc(writer.getResultBuffer());
+ var decoder = jspb.BinaryDecoder.alloc(encoder.end());
// Check zero and limits.
- assertEquals(filter(lowerLimit), readValue.call(reader));
- assertEquals(filter(-epsilon), readValue.call(reader));
- assertEquals(filter(0), readValue.call(reader));
- assertEquals(filter(epsilon), readValue.call(reader));
- assertEquals(filter(upperLimit), readValue.call(reader));
+ assertEquals(filter(lowerLimit), readValue.call(decoder));
+ assertEquals(filter(-epsilon), readValue.call(decoder));
+ assertEquals(filter(0), readValue.call(decoder));
+ assertEquals(filter(epsilon), readValue.call(decoder));
+ assertEquals(filter(upperLimit), readValue.call(decoder));
// Verify decoded values.
for (var i = 0; i < inputValues.length; i++) {
- assertEquals(inputValues[i], readValue.call(reader));
+ assertEquals(inputValues[i], readValue.call(decoder));
}
+
+ // Encoding values outside the valid range should assert.
+ assertThrows(function() {writeValue.call(encoder, lowerLimit * 1.1);});
+ assertThrows(function() {writeValue.call(encoder, upperLimit * 1.1);});
}
describe('binaryDecoderTest', function() {
@@ -169,7 +177,7 @@ describe('binaryDecoderTest', function() {
* Tests reading 64-bit integers as hash strings.
*/
it('testHashStrings', function() {
- var writer = new jspb.BinaryWriter();
+ var encoder = new jspb.BinaryEncoder();
var hashA = String.fromCharCode(0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00);
@@ -180,17 +188,17 @@ describe('binaryDecoderTest', function() {
var hashD = String.fromCharCode(0xFF, 0xFF, 0xFF, 0xFF,
0xFF, 0xFF, 0xFF, 0xFF);
- writer.rawWriteVarintHash64(hashA);
- writer.rawWriteVarintHash64(hashB);
- writer.rawWriteVarintHash64(hashC);
- writer.rawWriteVarintHash64(hashD);
+ encoder.writeVarintHash64(hashA);
+ encoder.writeVarintHash64(hashB);
+ encoder.writeVarintHash64(hashC);
+ encoder.writeVarintHash64(hashD);
- writer.rawWriteFixedHash64(hashA);
- writer.rawWriteFixedHash64(hashB);
- writer.rawWriteFixedHash64(hashC);
- writer.rawWriteFixedHash64(hashD);
+ encoder.writeFixedHash64(hashA);
+ encoder.writeFixedHash64(hashB);
+ encoder.writeFixedHash64(hashC);
+ encoder.writeFixedHash64(hashD);
- var decoder = jspb.BinaryDecoder.alloc(writer.getResultBuffer());
+ var decoder = jspb.BinaryDecoder.alloc(encoder.end());
assertEquals(hashA, decoder.readVarintHash64());
assertEquals(hashB, decoder.readVarintHash64());
@@ -214,8 +222,8 @@ describe('binaryDecoderTest', function() {
assertThrows(function() {decoder.readUint64()});
// Overlong varints should trigger assertions.
- decoder.setBlock(
- [255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0]);
+ decoder.setBlock([255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 0]);
assertThrows(function() {decoder.readUnsignedVarint64()});
decoder.reset();
assertThrows(function() {decoder.readSignedVarint64()});
@@ -244,61 +252,61 @@ describe('binaryDecoderTest', function() {
/**
- * Tests raw encoding and decoding of unsigned integers.
+ * Tests encoding and decoding of unsigned integers.
*/
- it('testRawUnsigned', function() {
+ it('testUnsignedIntegers', function() {
doTestUnsignedValue(
jspb.BinaryDecoder.prototype.readUint8,
- jspb.BinaryWriter.prototype.rawWriteUint8,
+ jspb.BinaryEncoder.prototype.writeUint8,
1, 0xFF, Math.round);
doTestUnsignedValue(
jspb.BinaryDecoder.prototype.readUint16,
- jspb.BinaryWriter.prototype.rawWriteUint16,
+ jspb.BinaryEncoder.prototype.writeUint16,
1, 0xFFFF, Math.round);
doTestUnsignedValue(
jspb.BinaryDecoder.prototype.readUint32,
- jspb.BinaryWriter.prototype.rawWriteUint32,
+ jspb.BinaryEncoder.prototype.writeUint32,
1, 0xFFFFFFFF, Math.round);
doTestUnsignedValue(
jspb.BinaryDecoder.prototype.readUint64,
- jspb.BinaryWriter.prototype.rawWriteUint64,
+ jspb.BinaryEncoder.prototype.writeUint64,
1, Math.pow(2, 64) - 1025, Math.round);
});
/**
- * Tests raw encoding and decoding of signed integers.
+ * Tests encoding and decoding of signed integers.
*/
- it('testRawSigned', function() {
+ it('testSignedIntegers', function() {
doTestSignedValue(
jspb.BinaryDecoder.prototype.readInt8,
- jspb.BinaryWriter.prototype.rawWriteInt8,
+ jspb.BinaryEncoder.prototype.writeInt8,
1, -0x80, 0x7F, Math.round);
doTestSignedValue(
jspb.BinaryDecoder.prototype.readInt16,
- jspb.BinaryWriter.prototype.rawWriteInt16,
+ jspb.BinaryEncoder.prototype.writeInt16,
1, -0x8000, 0x7FFF, Math.round);
doTestSignedValue(
jspb.BinaryDecoder.prototype.readInt32,
- jspb.BinaryWriter.prototype.rawWriteInt32,
+ jspb.BinaryEncoder.prototype.writeInt32,
1, -0x80000000, 0x7FFFFFFF, Math.round);
doTestSignedValue(
jspb.BinaryDecoder.prototype.readInt64,
- jspb.BinaryWriter.prototype.rawWriteInt64,
+ jspb.BinaryEncoder.prototype.writeInt64,
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
});
/**
- * Tests raw encoding and decoding of floats.
+ * Tests encoding and decoding of floats.
*/
- it('testRawFloats', function() {
+ it('testFloats', function() {
/**
* @param {number} x
* @return {number}
@@ -310,7 +318,7 @@ describe('binaryDecoderTest', function() {
}
doTestSignedValue(
jspb.BinaryDecoder.prototype.readFloat,
- jspb.BinaryWriter.prototype.rawWriteFloat,
+ jspb.BinaryEncoder.prototype.writeFloat,
jspb.BinaryConstants.FLOAT32_EPS,
-jspb.BinaryConstants.FLOAT32_MAX,
jspb.BinaryConstants.FLOAT32_MAX,
@@ -318,7 +326,7 @@ describe('binaryDecoderTest', function() {
doTestSignedValue(
jspb.BinaryDecoder.prototype.readDouble,
- jspb.BinaryWriter.prototype.rawWriteDouble,
+ jspb.BinaryEncoder.prototype.writeDouble,
jspb.BinaryConstants.FLOAT64_EPS * 10,
-jspb.BinaryConstants.FLOAT64_MAX,
jspb.BinaryConstants.FLOAT64_MAX,
diff --git a/js/binary/encoder.js b/js/binary/encoder.js
new file mode 100644
index 00000000..c9b0c2ae
--- /dev/null
+++ b/js/binary/encoder.js
@@ -0,0 +1,430 @@
+// Protocol Buffers - Google's data interchange format
+// Copyright 2008 Google Inc. All rights reserved.
+// https://developers.google.com/protocol-buffers/
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+/**
+ * @fileoverview BinaryEncode defines methods for encoding Javascript values
+ * into arrays of bytes compatible with the Protocol Buffer wire format.
+ *
+ * @author aappleby@google.com (Austin Appleby)
+ */
+
+goog.provide('jspb.BinaryEncoder');
+
+goog.require('goog.asserts');
+goog.require('jspb.BinaryConstants');
+goog.require('jspb.utils');
+
+
+
+/**
+ * BinaryEncoder implements encoders for all the wire types specified in
+ * https://developers.google.com/protocol-buffers/docs/encoding.
+ *
+ * @constructor
+ * @struct
+ */
+jspb.BinaryEncoder = function() {
+ /** @private {!Array.<number>} */
+ this.buffer_ = [];
+};
+
+
+/**
+ * @return {number}
+ */
+jspb.BinaryEncoder.prototype.length = function() {
+ return this.buffer_.length;
+};
+
+
+/**
+ * @return {!Array.<number>}
+ */
+jspb.BinaryEncoder.prototype.end = function() {
+ var buffer = this.buffer_;
+ this.buffer_ = [];
+ return buffer;
+};
+
+
+/**
+ * Encodes a 64-bit integer in 32:32 split representation into its wire-format
+ * varint representation and stores it in the buffer.
+ * @param {number} lowBits The low 32 bits of the int.
+ * @param {number} highBits The high 32 bits of the int.
+ */
+jspb.BinaryEncoder.prototype.writeSplitVarint64 = function(lowBits, highBits) {
+ goog.asserts.assert(lowBits == Math.floor(lowBits));
+ goog.asserts.assert(highBits == Math.floor(highBits));
+ goog.asserts.assert((lowBits >= 0) &&
+ (lowBits < jspb.BinaryConstants.TWO_TO_32));
+ goog.asserts.assert((highBits >= 0) &&
+ (highBits < jspb.BinaryConstants.TWO_TO_32));
+
+ // Break the binary representation into chunks of 7 bits, set the 8th bit
+ // in each chunk if it's not the final chunk, and append to the result.
+ while (highBits > 0 || lowBits > 127) {
+ this.buffer_.push((lowBits & 0x7f) | 0x80);
+ lowBits = ((lowBits >>> 7) | (highBits << 25)) >>> 0;
+ highBits = highBits >>> 7;
+ }
+ this.buffer_.push(lowBits);
+};
+
+
+/**
+ * Encodes a 32-bit unsigned integer into its wire-format varint representation
+ * and stores it in the buffer.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryEncoder.prototype.writeUnsignedVarint32 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= 0) &&
+ (value < jspb.BinaryConstants.TWO_TO_32));
+
+ while (value > 127) {
+ this.buffer_.push((value & 0x7f) | 0x80);
+ value = value >>> 7;
+ }
+
+ this.buffer_.push(value);
+};
+
+
+/**
+ * Encodes a 32-bit signed integer into its wire-format varint representation
+ * and stores it in the buffer.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryEncoder.prototype.writeSignedVarint32 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+ (value < jspb.BinaryConstants.TWO_TO_31));
+
+ // Use the unsigned version if the value is not negative.
+ if (value >= 0) {
+ this.writeUnsignedVarint32(value);
+ return;
+ }
+
+ // Write nine bytes with a _signed_ right shift so we preserve the sign bit.
+ for (var i = 0; i < 9; i++) {
+ this.buffer_.push((value & 0x7f) | 0x80);
+ value = value >> 7;
+ }
+
+ // The above loop writes out 63 bits, so the last byte is always the sign bit
+ // which is always set for negative numbers.
+ this.buffer_.push(1);
+};
+
+
+/**
+ * Encodes a 64-bit unsigned integer into its wire-format varint representation
+ * and stores it in the buffer. Integers that are not representable in 64 bits
+ * will be truncated.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryEncoder.prototype.writeUnsignedVarint64 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= 0) &&
+ (value < jspb.BinaryConstants.TWO_TO_64));
+ jspb.utils.splitInt64(value);
+ this.writeSplitVarint64(jspb.utils.split64Low,
+ jspb.utils.split64High);
+};
+
+
+/**
+ * Encodes a 64-bit signed integer into its wire-format varint representation
+ * and stores it in the buffer. Integers that are not representable in 64 bits
+ * will be truncated.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryEncoder.prototype.writeSignedVarint64 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
+ (value < jspb.BinaryConstants.TWO_TO_63));
+ jspb.utils.splitInt64(value);
+ this.writeSplitVarint64(jspb.utils.split64Low,
+ jspb.utils.split64High);
+};
+
+
+/**
+ * Encodes a JavaScript integer into its wire-format, zigzag-encoded varint
+ * representation and stores it in the buffer.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryEncoder.prototype.writeZigzagVarint32 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+ (value < jspb.BinaryConstants.TWO_TO_31));
+ this.writeUnsignedVarint32(((value << 1) ^ (value >> 31)) >>> 0);
+};
+
+
+/**
+ * Encodes a JavaScript integer into its wire-format, zigzag-encoded varint
+ * representation and stores it in the buffer. Integers not representable in 64
+ * bits will be truncated.
+ * @param {number} value The integer to convert.
+ */
+jspb.BinaryEncoder.prototype.writeZigzagVarint64 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
+ (value < jspb.BinaryConstants.TWO_TO_63));
+ jspb.utils.splitZigzag64(value);
+ this.writeSplitVarint64(jspb.utils.split64Low,
+ jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a 8-bit unsigned integer to the buffer. Numbers outside the range
+ * [0,2^8) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeUint8 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= 0) && (value < 256));
+ this.buffer_.push((value >>> 0) & 0xFF);
+};
+
+
+/**
+ * Writes a 16-bit unsigned integer to the buffer. Numbers outside the
+ * range [0,2^16) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeUint16 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= 0) && (value < 65536));
+ this.buffer_.push((value >>> 0) & 0xFF);
+ this.buffer_.push((value >>> 8) & 0xFF);
+};
+
+
+/**
+ * Writes a 32-bit unsigned integer to the buffer. Numbers outside the
+ * range [0,2^32) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeUint32 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= 0) &&
+ (value < jspb.BinaryConstants.TWO_TO_32));
+ this.buffer_.push((value >>> 0) & 0xFF);
+ this.buffer_.push((value >>> 8) & 0xFF);
+ this.buffer_.push((value >>> 16) & 0xFF);
+ this.buffer_.push((value >>> 24) & 0xFF);
+};
+
+
+/**
+ * Writes a 64-bit unsigned integer to the buffer. Numbers outside the
+ * range [0,2^64) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeUint64 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= 0) &&
+ (value < jspb.BinaryConstants.TWO_TO_64));
+ jspb.utils.splitUint64(value);
+ this.writeUint32(jspb.utils.split64Low);
+ this.writeUint32(jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a 8-bit integer to the buffer. Numbers outside the range
+ * [-2^7,2^7) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeInt8 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -128) && (value < 128));
+ this.buffer_.push((value >>> 0) & 0xFF);
+};
+
+
+/**
+ * Writes a 16-bit integer to the buffer. Numbers outside the range
+ * [-2^15,2^15) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeInt16 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -32768) && (value < 32768));
+ this.buffer_.push((value >>> 0) & 0xFF);
+ this.buffer_.push((value >>> 8) & 0xFF);
+};
+
+
+/**
+ * Writes a 32-bit integer to the buffer. Numbers outside the range
+ * [-2^31,2^31) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeInt32 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+ (value < jspb.BinaryConstants.TWO_TO_31));
+ this.buffer_.push((value >>> 0) & 0xFF);
+ this.buffer_.push((value >>> 8) & 0xFF);
+ this.buffer_.push((value >>> 16) & 0xFF);
+ this.buffer_.push((value >>> 24) & 0xFF);
+};
+
+
+/**
+ * Writes a 64-bit integer to the buffer. Numbers outside the range
+ * [-2^63,2^63) will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeInt64 = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
+ (value < jspb.BinaryConstants.TWO_TO_63));
+ jspb.utils.splitInt64(value);
+ this.writeUint32(jspb.utils.split64Low);
+ this.writeUint32(jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a single-precision floating point value to the buffer. Numbers
+ * requiring more than 32 bits of precision will be truncated.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeFloat = function(value) {
+ goog.asserts.assert((value >= -jspb.BinaryConstants.FLOAT32_MAX) &&
+ (value <= jspb.BinaryConstants.FLOAT32_MAX));
+ jspb.utils.splitFloat32(value);
+ this.writeUint32(jspb.utils.split64Low);
+};
+
+
+/**
+ * Writes a double-precision floating point value to the buffer. As this is
+ * the native format used by JavaScript, no precision will be lost.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeDouble = function(value) {
+ goog.asserts.assert((value >= -jspb.BinaryConstants.FLOAT64_MAX) &&
+ (value <= jspb.BinaryConstants.FLOAT64_MAX));
+ jspb.utils.splitFloat64(value);
+ this.writeUint32(jspb.utils.split64Low);
+ this.writeUint32(jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a boolean value to the buffer as a varint.
+ * @param {boolean} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeBool = function(value) {
+ goog.asserts.assert(goog.isBoolean(value));
+ this.buffer_.push(value ? 1 : 0);
+};
+
+
+/**
+ * Writes an enum value to the buffer as a varint.
+ * @param {number} value The value to write.
+ */
+jspb.BinaryEncoder.prototype.writeEnum = function(value) {
+ goog.asserts.assert(value == Math.floor(value));
+ goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
+ (value < jspb.BinaryConstants.TWO_TO_31));
+ this.writeSignedVarint32(value);
+};
+
+
+/**
+ * Writes an arbitrary byte array to the buffer.
+ * @param {!Uint8Array} bytes The array of bytes to write.
+ */
+jspb.BinaryEncoder.prototype.writeBytes = function(bytes) {
+ this.buffer_.push.apply(this.buffer_, bytes);
+};
+
+
+/**
+ * Writes a 64-bit hash string (8 characters @ 8 bits of data each) to the
+ * buffer as a varint.
+ * @param {string} hash The hash to write.
+ */
+jspb.BinaryEncoder.prototype.writeVarintHash64 = function(hash) {
+ jspb.utils.splitHash64(hash);
+ this.writeSplitVarint64(jspb.utils.split64Low,
+ jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a 64-bit hash string (8 characters @ 8 bits of data each) to the
+ * buffer as a fixed64.
+ * @param {string} hash The hash to write.
+ */
+jspb.BinaryEncoder.prototype.writeFixedHash64 = function(hash) {
+ jspb.utils.splitHash64(hash);
+ this.writeUint32(jspb.utils.split64Low);
+ this.writeUint32(jspb.utils.split64High);
+};
+
+
+/**
+ * Writes a UTF16 Javascript string to the buffer encoded as UTF8.
+ * TODO(aappleby): Add support for surrogate pairs, reject unpaired surrogates.
+ * @param {string} value The string to write.
+ * @return {number} The number of bytes used to encode the string.
+ */
+jspb.BinaryEncoder.prototype.writeString = function(value) {
+ var oldLength = this.buffer_.length;
+
+ // UTF16 to UTF8 conversion loop swiped from goog.crypt.stringToUtf8ByteArray.
+ for (var i = 0; i < value.length; i++) {
+ var c = value.charCodeAt(i);
+ if (c < 128) {
+ this.buffer_.push(c);
+ } else if (c < 2048) {
+ this.buffer_.push((c >> 6) | 192);
+ this.buffer_.push((c & 63) | 128);
+ } else {
+ this.buffer_.push((c >> 12) | 224);
+ this.buffer_.push(((c >> 6) & 63) | 128);
+ this.buffer_.push((c & 63) | 128);
+ }
+ }
+
+ var length = this.buffer_.length - oldLength;
+ return length;
+};
diff --git a/js/binary/proto_test.js b/js/binary/proto_test.js
index 3b4aa17f..14d0f42e 100644
--- a/js/binary/proto_test.js
+++ b/js/binary/proto_test.js
@@ -30,7 +30,9 @@
// Test suite is written using Jasmine -- see http://jasmine.github.io/
+goog.require('goog.crypt.base64');
goog.require('goog.testing.asserts');
+goog.require('jspb.Message');
// CommonJS-LoadFromFile: ../testbinary_pb proto.jspb.test
goog.require('proto.jspb.test.ExtendsWithMessage');
@@ -38,9 +40,61 @@ goog.require('proto.jspb.test.ForeignEnum');
goog.require('proto.jspb.test.ForeignMessage');
goog.require('proto.jspb.test.TestAllTypes');
goog.require('proto.jspb.test.TestExtendable');
+goog.require('proto.jspb.test.extendOptionalBool');
+goog.require('proto.jspb.test.extendOptionalBytes');
+goog.require('proto.jspb.test.extendOptionalDouble');
+goog.require('proto.jspb.test.extendOptionalFixed32');
+goog.require('proto.jspb.test.extendOptionalFixed64');
+goog.require('proto.jspb.test.extendOptionalFloat');
+goog.require('proto.jspb.test.extendOptionalForeignEnum');
+goog.require('proto.jspb.test.extendOptionalInt32');
+goog.require('proto.jspb.test.extendOptionalInt64');
+goog.require('proto.jspb.test.extendOptionalSfixed32');
+goog.require('proto.jspb.test.extendOptionalSfixed64');
+goog.require('proto.jspb.test.extendOptionalSint32');
+goog.require('proto.jspb.test.extendOptionalSint64');
+goog.require('proto.jspb.test.extendOptionalString');
+goog.require('proto.jspb.test.extendOptionalUint32');
+goog.require('proto.jspb.test.extendOptionalUint64');
+goog.require('proto.jspb.test.extendPackedRepeatedBoolList');
+goog.require('proto.jspb.test.extendPackedRepeatedDoubleList');
+goog.require('proto.jspb.test.extendPackedRepeatedFixed32List');
+goog.require('proto.jspb.test.extendPackedRepeatedFixed64List');
+goog.require('proto.jspb.test.extendPackedRepeatedFloatList');
+goog.require('proto.jspb.test.extendPackedRepeatedForeignEnumList');
+goog.require('proto.jspb.test.extendPackedRepeatedInt32List');
+goog.require('proto.jspb.test.extendPackedRepeatedInt64List');
+goog.require('proto.jspb.test.extendPackedRepeatedSfixed32List');
+goog.require('proto.jspb.test.extendPackedRepeatedSfixed64List');
+goog.require('proto.jspb.test.extendPackedRepeatedSint32List');
+goog.require('proto.jspb.test.extendPackedRepeatedSint64List');
+goog.require('proto.jspb.test.extendPackedRepeatedUint32List');
+goog.require('proto.jspb.test.extendPackedRepeatedUint64List');
+goog.require('proto.jspb.test.extendRepeatedBoolList');
+goog.require('proto.jspb.test.extendRepeatedBytesList');
+goog.require('proto.jspb.test.extendRepeatedDoubleList');
+goog.require('proto.jspb.test.extendRepeatedFixed32List');
+goog.require('proto.jspb.test.extendRepeatedFixed64List');
+goog.require('proto.jspb.test.extendRepeatedFloatList');
+goog.require('proto.jspb.test.extendRepeatedForeignEnumList');
+goog.require('proto.jspb.test.extendRepeatedInt32List');
+goog.require('proto.jspb.test.extendRepeatedInt64List');
+goog.require('proto.jspb.test.extendRepeatedSfixed32List');
+goog.require('proto.jspb.test.extendRepeatedSfixed64List');
+goog.require('proto.jspb.test.extendRepeatedSint32List');
+goog.require('proto.jspb.test.extendRepeatedSint64List');
+goog.require('proto.jspb.test.extendRepeatedStringList');
+goog.require('proto.jspb.test.extendRepeatedUint32List');
+goog.require('proto.jspb.test.extendRepeatedUint64List');
+
var suite = {};
+var BYTES = new Uint8Array([1, 2, 8, 9]);
+
+var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES);
+
+
/**
* Helper: fill all fields on a TestAllTypes message.
* @param {proto.jspb.test.TestAllTypes} msg
@@ -62,7 +116,7 @@ function fillAllFields(msg) {
msg.setOptionalDouble(-1.5);
msg.setOptionalBool(true);
msg.setOptionalString('hello world');
- msg.setOptionalBytes('bytes');
+ msg.setOptionalBytes(BYTES);
msg.setOptionalGroup(new proto.jspb.test.TestAllTypes.OptionalGroup());
msg.getOptionalGroup().setA(100);
var submsg = new proto.jspb.test.ForeignMessage();
@@ -71,6 +125,7 @@ function fillAllFields(msg) {
msg.setOptionalForeignEnum(proto.jspb.test.ForeignEnum.FOREIGN_FOO);
msg.setOneofString('oneof');
+
msg.setRepeatedInt32List([-42]);
msg.setRepeatedInt64List([-0x7fffffff00000000]);
msg.setRepeatedUint32List([0x80000000]);
@@ -85,7 +140,7 @@ function fillAllFields(msg) {
msg.setRepeatedDoubleList([-1.5]);
msg.setRepeatedBoolList([true]);
msg.setRepeatedStringList(['hello world']);
- msg.setRepeatedBytesList(['bytes']);
+ msg.setRepeatedBytesList([BYTES, BYTES]);
msg.setRepeatedGroupList([new proto.jspb.test.TestAllTypes.RepeatedGroup()]);
msg.getRepeatedGroupList()[0].setA(100);
submsg = new proto.jspb.test.ForeignMessage();
@@ -106,106 +161,115 @@ function fillAllFields(msg) {
msg.setPackedRepeatedFloatList([1.5]);
msg.setPackedRepeatedDoubleList([-1.5]);
msg.setPackedRepeatedBoolList([true]);
+
}
/**
- * Helper: compare a bytes field to a string with codepoints 0--255.
+ * Helper: compare a bytes field to an expected value
* @param {Uint8Array|string} arr
- * @param {string} str
+ * @param {Uint8Array} expected
* @return {boolean}
*/
-function bytesCompare(arr, str) {
- if (arr.length != str.length) {
+function bytesCompare(arr, expected) {
+ if (goog.isString(arr)) {
+ arr = goog.crypt.base64.decodeStringToUint8Array(arr);
+ }
+ if (arr.length != expected.length) {
return false;
}
- if (typeof arr == 'string') {
- for (var i = 0; i < arr.length; i++) {
- if (arr.charCodeAt(i) != str.charCodeAt(i)) {
- return false;
- }
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i] != expected[i]) {
+ return false;
}
- return true;
- } else {
- for (var i = 0; i < arr.length; i++) {
- if (arr[i] != str.charCodeAt(i)) {
- return false;
- }
- }
- return true;
}
+ return true;
}
/**
* Helper: verify contents of given TestAllTypes message as set by
* fillAllFields().
- * @param {proto.jspb.test.TestAllTypes} msg
+ * @param {proto.jspb.test.TestAllTypes} original
+ * @param {proto.jspb.test.TestAllTypes} copy
*/
-function checkAllFields(msg) {
- assertEquals(msg.getOptionalInt32(), -42);
- assertEquals(msg.getOptionalInt64(), -0x7fffffff00000000);
- assertEquals(msg.getOptionalUint32(), 0x80000000);
- assertEquals(msg.getOptionalUint64(), 0xf000000000000000);
- assertEquals(msg.getOptionalSint32(), -100);
- assertEquals(msg.getOptionalSint64(), -0x8000000000000000);
- assertEquals(msg.getOptionalFixed32(), 1234);
- assertEquals(msg.getOptionalFixed64(), 0x1234567800000000);
- assertEquals(msg.getOptionalSfixed32(), -1234);
- assertEquals(msg.getOptionalSfixed64(), -0x1234567800000000);
- assertEquals(msg.getOptionalFloat(), 1.5);
- assertEquals(msg.getOptionalDouble(), -1.5);
- assertEquals(msg.getOptionalBool(), true);
- assertEquals(msg.getOptionalString(), 'hello world');
- assertEquals(true, bytesCompare(msg.getOptionalBytes(), 'bytes'));
- assertEquals(msg.getOptionalGroup().getA(), 100);
- assertEquals(msg.getOptionalForeignMessage().getC(), 16);
- assertEquals(msg.getOptionalForeignEnum(),
+function checkAllFields(original, copy) {
+ assertTrue(jspb.Message.equals(original, copy));
+
+ assertEquals(copy.getOptionalInt32(), -42);
+ assertEquals(copy.getOptionalInt64(), -0x7fffffff00000000);
+ assertEquals(copy.getOptionalUint32(), 0x80000000);
+ assertEquals(copy.getOptionalUint64(), 0xf000000000000000);
+ assertEquals(copy.getOptionalSint32(), -100);
+ assertEquals(copy.getOptionalSint64(), -0x8000000000000000);
+ assertEquals(copy.getOptionalFixed32(), 1234);
+ assertEquals(copy.getOptionalFixed64(), 0x1234567800000000);
+ assertEquals(copy.getOptionalSfixed32(), -1234);
+ assertEquals(copy.getOptionalSfixed64(), -0x1234567800000000);
+ assertEquals(copy.getOptionalFloat(), 1.5);
+ assertEquals(copy.getOptionalDouble(), -1.5);
+ assertEquals(copy.getOptionalBool(), true);
+ assertEquals(copy.getOptionalString(), 'hello world');
+ assertEquals(true, bytesCompare(copy.getOptionalBytes(), BYTES));
+ assertEquals(true, bytesCompare(copy.getOptionalBytes_asU8(), BYTES));
+ assertEquals(
+ copy.getOptionalBytes_asB64(), goog.crypt.base64.encodeByteArray(BYTES));
+
+ assertEquals(copy.getOptionalGroup().getA(), 100);
+ assertEquals(copy.getOptionalForeignMessage().getC(), 16);
+ assertEquals(copy.getOptionalForeignEnum(),
proto.jspb.test.ForeignEnum.FOREIGN_FOO);
- assertEquals(msg.getOneofString(), 'oneof');
- assertEquals(msg.getOneofFieldCase(),
+
+
+ assertEquals(copy.getOneofString(), 'oneof');
+ assertEquals(copy.getOneofFieldCase(),
proto.jspb.test.TestAllTypes.OneofFieldCase.ONEOF_STRING);
- assertElementsEquals(msg.getRepeatedInt32List(), [-42]);
- assertElementsEquals(msg.getRepeatedInt64List(), [-0x7fffffff00000000]);
- assertElementsEquals(msg.getRepeatedUint32List(), [0x80000000]);
- assertElementsEquals(msg.getRepeatedUint64List(), [0xf000000000000000]);
- assertElementsEquals(msg.getRepeatedSint32List(), [-100]);
- assertElementsEquals(msg.getRepeatedSint64List(), [-0x8000000000000000]);
- assertElementsEquals(msg.getRepeatedFixed32List(), [1234]);
- assertElementsEquals(msg.getRepeatedFixed64List(), [0x1234567800000000]);
- assertElementsEquals(msg.getRepeatedSfixed32List(), [-1234]);
- assertElementsEquals(msg.getRepeatedSfixed64List(), [-0x1234567800000000]);
- assertElementsEquals(msg.getRepeatedFloatList(), [1.5]);
- assertElementsEquals(msg.getRepeatedDoubleList(), [-1.5]);
- assertElementsEquals(msg.getRepeatedBoolList(), [true]);
- assertElementsEquals(msg.getRepeatedStringList(), ['hello world']);
- assertEquals(msg.getRepeatedBytesList().length, 1);
- assertEquals(true, bytesCompare(msg.getRepeatedBytesList()[0], 'bytes'));
- assertEquals(msg.getRepeatedGroupList().length, 1);
- assertEquals(msg.getRepeatedGroupList()[0].getA(), 100);
- assertEquals(msg.getRepeatedForeignMessageList().length, 1);
- assertEquals(msg.getRepeatedForeignMessageList()[0].getC(), 1000);
- assertElementsEquals(msg.getRepeatedForeignEnumList(),
+ assertElementsEquals(copy.getRepeatedInt32List(), [-42]);
+ assertElementsEquals(copy.getRepeatedInt64List(), [-0x7fffffff00000000]);
+ assertElementsEquals(copy.getRepeatedUint32List(), [0x80000000]);
+ assertElementsEquals(copy.getRepeatedUint64List(), [0xf000000000000000]);
+ assertElementsEquals(copy.getRepeatedSint32List(), [-100]);
+ assertElementsEquals(copy.getRepeatedSint64List(), [-0x8000000000000000]);
+ assertElementsEquals(copy.getRepeatedFixed32List(), [1234]);
+ assertElementsEquals(copy.getRepeatedFixed64List(), [0x1234567800000000]);
+ assertElementsEquals(copy.getRepeatedSfixed32List(), [-1234]);
+ assertElementsEquals(copy.getRepeatedSfixed64List(), [-0x1234567800000000]);
+ assertElementsEquals(copy.getRepeatedFloatList(), [1.5]);
+ assertElementsEquals(copy.getRepeatedDoubleList(), [-1.5]);
+ assertElementsEquals(copy.getRepeatedBoolList(), [true]);
+ assertElementsEquals(copy.getRepeatedStringList(), ['hello world']);
+ assertEquals(copy.getRepeatedBytesList().length, 2);
+ assertEquals(true, bytesCompare(copy.getRepeatedBytesList_asU8()[0], BYTES));
+ assertEquals(true, bytesCompare(copy.getRepeatedBytesList()[0], BYTES));
+ assertEquals(true, bytesCompare(copy.getRepeatedBytesList_asU8()[1], BYTES));
+ assertEquals(copy.getRepeatedBytesList_asB64()[0], BYTES_B64);
+ assertEquals(copy.getRepeatedBytesList_asB64()[1], BYTES_B64);
+ assertEquals(copy.getRepeatedGroupList().length, 1);
+ assertEquals(copy.getRepeatedGroupList()[0].getA(), 100);
+ assertEquals(copy.getRepeatedForeignMessageList().length, 1);
+ assertEquals(copy.getRepeatedForeignMessageList()[0].getC(), 1000);
+ assertElementsEquals(copy.getRepeatedForeignEnumList(),
[proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
- assertElementsEquals(msg.getPackedRepeatedInt32List(), [-42]);
- assertElementsEquals(msg.getPackedRepeatedInt64List(),
+ assertElementsEquals(copy.getPackedRepeatedInt32List(), [-42]);
+ assertElementsEquals(copy.getPackedRepeatedInt64List(),
[-0x7fffffff00000000]);
- assertElementsEquals(msg.getPackedRepeatedUint32List(), [0x80000000]);
- assertElementsEquals(msg.getPackedRepeatedUint64List(), [0xf000000000000000]);
- assertElementsEquals(msg.getPackedRepeatedSint32List(), [-100]);
- assertElementsEquals(msg.getPackedRepeatedSint64List(),
+ assertElementsEquals(copy.getPackedRepeatedUint32List(), [0x80000000]);
+ assertElementsEquals(copy.getPackedRepeatedUint64List(),
+ [0xf000000000000000]);
+ assertElementsEquals(copy.getPackedRepeatedSint32List(), [-100]);
+ assertElementsEquals(copy.getPackedRepeatedSint64List(),
[-0x8000000000000000]);
- assertElementsEquals(msg.getPackedRepeatedFixed32List(), [1234]);
- assertElementsEquals(msg.getPackedRepeatedFixed64List(),
+ assertElementsEquals(copy.getPackedRepeatedFixed32List(), [1234]);
+ assertElementsEquals(copy.getPackedRepeatedFixed64List(),
[0x1234567800000000]);
- assertElementsEquals(msg.getPackedRepeatedSfixed32List(), [-1234]);
- assertElementsEquals(msg.getPackedRepeatedSfixed64List(),
+ assertElementsEquals(copy.getPackedRepeatedSfixed32List(), [-1234]);
+ assertElementsEquals(copy.getPackedRepeatedSfixed64List(),
[-0x1234567800000000]);
- assertElementsEquals(msg.getPackedRepeatedFloatList(), [1.5]);
- assertElementsEquals(msg.getPackedRepeatedDoubleList(), [-1.5]);
- assertElementsEquals(msg.getPackedRepeatedBoolList(), [true]);
+ assertElementsEquals(copy.getPackedRepeatedFloatList(), [1.5]);
+ assertElementsEquals(copy.getPackedRepeatedDoubleList(), [-1.5]);
+
}
@@ -242,14 +306,13 @@ function checkExtensions(msg) {
msg.getExtension(proto.jspb.test.extendOptionalBool));
assertEquals('hello world',
msg.getExtension(proto.jspb.test.extendOptionalString));
- assertEquals(true,
- bytesCompare(msg.getExtension(proto.jspb.test.extendOptionalBytes),
- 'bytes'));
+ assertEquals(
+ true, bytesCompare(
+ msg.getExtension(proto.jspb.test.extendOptionalBytes), BYTES));
assertEquals(16,
msg.getExtension(
proto.jspb.test.ExtendsWithMessage.optionalExtension).getFoo());
- assertEquals(proto.jspb.test.ForeignEnum.FOREIGN_FOO,
- msg.getExtension(proto.jspb.test.extendOptionalForeignEnum));
+
assertElementsEquals(
msg.getExtension(proto.jspb.test.extendRepeatedInt32List),
@@ -293,10 +356,10 @@ function checkExtensions(msg) {
assertElementsEquals(
msg.getExtension(proto.jspb.test.extendRepeatedStringList),
['hello world']);
- assertEquals(true,
+ assertEquals(
+ true,
bytesCompare(
- msg.getExtension(proto.jspb.test.extendRepeatedBytesList)[0],
- 'bytes'));
+ msg.getExtension(proto.jspb.test.extendRepeatedBytesList)[0], BYTES));
assertEquals(1000,
msg.getExtension(
proto.jspb.test.ExtendsWithMessage.repeatedExtensionList)[0]
@@ -305,6 +368,7 @@ function checkExtensions(msg) {
msg.getExtension(proto.jspb.test.extendRepeatedForeignEnumList),
[proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+
assertElementsEquals(
msg.getExtension(proto.jspb.test.extendPackedRepeatedInt32List),
[-42]);
@@ -347,6 +411,7 @@ function checkExtensions(msg) {
assertElementsEquals(
msg.getExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList),
[proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+
}
@@ -360,9 +425,82 @@ describe('protoBinaryTest', function() {
fillAllFields(msg);
var encoded = msg.serializeBinary();
var decoded = proto.jspb.test.TestAllTypes.deserializeBinary(encoded);
- checkAllFields(decoded);
+ checkAllFields(msg, decoded);
});
+ /**
+ * Test that base64 string and Uint8Array are interchangeable in bytes fields.
+ */
+ it('testBytesFieldsGettersInterop', function() {
+ var msg = new proto.jspb.test.TestAllTypes();
+ // Set from a base64 string and check all the getters work.
+ msg.setOptionalBytes(BYTES_B64);
+ assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+
+ // Test binary serialize round trip doesn't break it.
+ msg = proto.jspb.test.TestAllTypes.deserializeBinary(msg.serializeBinary());
+ assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+
+ msg = new proto.jspb.test.TestAllTypes();
+ // Set from a Uint8Array and check all the getters work.
+ msg.setOptionalBytes(BYTES);
+ assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+
+ });
+
+ /**
+ * Test that bytes setters will receive result of any of the getters.
+ */
+ it('testBytesFieldsSettersInterop', function() {
+ var msg = new proto.jspb.test.TestAllTypes();
+ msg.setOptionalBytes(BYTES);
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+
+ msg.setOptionalBytes(msg.getOptionalBytes());
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+ msg.setOptionalBytes(msg.getOptionalBytes_asB64());
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+ msg.setOptionalBytes(msg.getOptionalBytes_asU8());
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+ });
+
+ /**
+ * Test that bytes setters will receive result of any of the getters.
+ */
+ it('testRepeatedBytesGetters', function() {
+ var msg = new proto.jspb.test.TestAllTypes();
+
+ function assertGetters() {
+ assertTrue(goog.isString(msg.getRepeatedBytesList_asB64()[0]));
+ assertTrue(goog.isString(msg.getRepeatedBytesList_asB64()[1]));
+ assertTrue(msg.getRepeatedBytesList_asU8()[0] instanceof Uint8Array);
+ assertTrue(msg.getRepeatedBytesList_asU8()[1] instanceof Uint8Array);
+
+ assertTrue(bytesCompare(msg.getRepeatedBytesList()[0], BYTES));
+ assertTrue(bytesCompare(msg.getRepeatedBytesList()[1], BYTES));
+ assertTrue(bytesCompare(msg.getRepeatedBytesList_asB64()[0], BYTES));
+ assertTrue(bytesCompare(msg.getRepeatedBytesList_asB64()[1], BYTES));
+ assertTrue(bytesCompare(msg.getRepeatedBytesList_asU8()[0], BYTES));
+ assertTrue(bytesCompare(msg.getRepeatedBytesList_asU8()[1], BYTES));
+ }
+
+ msg.setRepeatedBytesList([BYTES, BYTES]);
+ assertGetters();
+
+ msg.setRepeatedBytesList([BYTES_B64, BYTES_B64]);
+ assertGetters();
+
+ msg.setRepeatedBytesList(null);
+ assertEquals(0, msg.getRepeatedBytesList().length);
+ assertEquals(0, msg.getRepeatedBytesList_asB64().length);
+ assertEquals(0, msg.getRepeatedBytesList_asU8().length);
+ });
/**
* Helper: fill all extension values.
@@ -397,8 +535,7 @@ describe('protoBinaryTest', function() {
proto.jspb.test.extendOptionalBool, true);
msg.setExtension(
proto.jspb.test.extendOptionalString, 'hello world');
- msg.setExtension(
- proto.jspb.test.extendOptionalBytes, 'bytes');
+ msg.setExtension(proto.jspb.test.extendOptionalBytes, BYTES);
var submsg = new proto.jspb.test.ExtendsWithMessage();
submsg.setFoo(16);
msg.setExtension(
@@ -407,6 +544,7 @@ describe('protoBinaryTest', function() {
proto.jspb.test.extendOptionalForeignEnum,
proto.jspb.test.ForeignEnum.FOREIGN_FOO);
+
msg.setExtension(
proto.jspb.test.extendRepeatedInt32List, [-42]);
msg.setExtension(
@@ -435,8 +573,7 @@ describe('protoBinaryTest', function() {
proto.jspb.test.extendRepeatedBoolList, [true]);
msg.setExtension(
proto.jspb.test.extendRepeatedStringList, ['hello world']);
- msg.setExtension(
- proto.jspb.test.extendRepeatedBytesList, ['bytes']);
+ msg.setExtension(proto.jspb.test.extendRepeatedBytesList, [BYTES]);
submsg = new proto.jspb.test.ExtendsWithMessage();
submsg.setFoo(1000);
msg.setExtension(
@@ -444,6 +581,7 @@ describe('protoBinaryTest', function() {
msg.setExtension(proto.jspb.test.extendRepeatedForeignEnumList,
[proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+
msg.setExtension(
proto.jspb.test.extendPackedRepeatedInt32List, [-42]);
msg.setExtension(
@@ -473,6 +611,7 @@ describe('protoBinaryTest', function() {
proto.jspb.test.extendPackedRepeatedBoolList, [true]);
msg.setExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList,
[proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
+
}
diff --git a/js/binary/reader.js b/js/binary/reader.js
index abcd1660..15f90432 100644
--- a/js/binary/reader.js
+++ b/js/binary/reader.js
@@ -180,7 +180,7 @@ jspb.BinaryReader.prototype.getCursor = function() {
/**
* Returns the raw buffer.
- * @return {Uint8Array} The raw buffer.
+ * @return {?Uint8Array} The raw buffer.
*/
jspb.BinaryReader.prototype.getBuffer = function() {
return this.decoder_.getBuffer();
@@ -592,8 +592,8 @@ jspb.BinaryReader.prototype.getFieldDecoder = function() {
var start = this.decoder_.getCursor();
var end = start + length;
- var innerDecoder = jspb.BinaryDecoder.alloc(this.decoder_.getBuffer(),
- start, length);
+ var innerDecoder =
+ jspb.BinaryDecoder.alloc(this.decoder_.getBuffer(), start, length);
this.decoder_.setCursor(end);
return innerDecoder;
};
@@ -869,7 +869,7 @@ jspb.BinaryReader.prototype.readString = function() {
* Reads a length-prefixed block of bytes from the binary stream, or returns
* null if the next field in the stream has an invalid length value.
*
- * @return {Uint8Array} The block of bytes.
+ * @return {!Uint8Array} The block of bytes.
*/
jspb.BinaryReader.prototype.readBytes = function() {
goog.asserts.assert(
diff --git a/js/binary/reader_test.js b/js/binary/reader_test.js
index a6482610..6f7e5d45 100644
--- a/js/binary/reader_test.js
+++ b/js/binary/reader_test.js
@@ -366,28 +366,28 @@ describe('binaryReaderTest', function() {
var writer = new jspb.BinaryWriter();
var testSignedData = [
- '2730538252207801776',
- '-2688470994844604560',
- '3398529779486536359',
- '3568577411627971000',
- '272477188847484900',
- '-6649058714086158188',
- '-7695254765712060806',
- '-4525541438037104029',
- '-4993706538836508568',
- '4990160321893729138'
+ '2730538252207801776',
+ '-2688470994844604560',
+ '3398529779486536359',
+ '3568577411627971000',
+ '272477188847484900',
+ '-6649058714086158188',
+ '-7695254765712060806',
+ '-4525541438037104029',
+ '-4993706538836508568',
+ '4990160321893729138'
];
var testUnsignedData = [
- '7822732630241694882',
- '6753602971916687352',
- '2399935075244442116',
- '8724292567325338867',
- '16948784802625696584',
- '4136275908516066934',
- '3575388346793700364',
- '5167142028379259461',
- '1557573948689737699',
- '17100725280812548567'
+ '7822732630241694882',
+ '6753602971916687352',
+ '2399935075244442116',
+ '8724292567325338867',
+ '16948784802625696584',
+ '4136275908516066934',
+ '3575388346793700364',
+ '5167142028379259461',
+ '1557573948689737699',
+ '17100725280812548567'
];
for (var i = 0; i < testSignedData.length; i++) {
@@ -535,7 +535,7 @@ describe('binaryReaderTest', function() {
*/
it('testNesting', function() {
var writer = new jspb.BinaryWriter();
- var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+ var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
writer.writeInt32(1, 100);
@@ -626,31 +626,15 @@ describe('binaryReaderTest', function() {
writer.writeBytes(4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
writer.writeString(4, 'The quick brown fox jumps over the lazy dog');
- // Write a group with a nested group inside. We use the internal
- // .rawWriteVarint() to ensure the tested wire data is what we want,
- // independently of any serialization logic.
+ // Write a group with a nested group inside.
writer.writeInt32(5, sentinel);
- // Start group, field 5.
- writer.rawWriteVarint(
- (5 << 3) + jspb.BinaryConstants.WireType.START_GROUP);
- // Varint, field 42.
- writer.rawWriteVarint(
- (42 << 3) + jspb.BinaryConstants.WireType.VARINT);
- // Varint data.
- writer.rawWriteVarint(42);
- // Start group, field 6.
- writer.rawWriteVarint(
- (6 << 3) + jspb.BinaryConstants.WireType.START_GROUP);
- // Varint, field 84.
- writer.rawWriteVarint(
- (84 << 3) + jspb.BinaryConstants.WireType.VARINT);
- writer.rawWriteVarint(42);
- // End group, field 6.
- writer.rawWriteVarint(
- (6 << 3) + jspb.BinaryConstants.WireType.END_GROUP);
- // End group, field 5.
- writer.rawWriteVarint(
- (5 << 3) + jspb.BinaryConstants.WireType.END_GROUP);
+ var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
+ writer.writeGroup(5, dummyMessage, function() {
+ writer.writeInt64(42, 42);
+ writer.writeGroup(6, dummyMessage, function() {
+ writer.writeInt64(84, 42);
+ });
+ });
// Write final sentinel.
writer.writeInt32(6, sentinel);
diff --git a/js/binary/utils.js b/js/binary/utils.js
index 92600389..875ff955 100644
--- a/js/binary/utils.js
+++ b/js/binary/utils.js
@@ -839,62 +839,16 @@ jspb.utils.countDelimitedFields = function(buffer, start, end, field) {
/**
- * Clones a scalar field. Pulling this out to a helper method saves us a few
- * bytes of generated code.
- * @param {Array} array
- * @return {Array}
- */
-jspb.utils.cloneRepeatedScalarField = function(array) {
- return array ? array.slice() : null;
-};
-
-
-/**
- * Clones an array of messages using the provided cloner function.
- * @param {Array.<jspb.BinaryMessage>} messages
- * @param {jspb.ClonerFunction} cloner
- * @return {Array.<jspb.BinaryMessage>}
- */
-jspb.utils.cloneRepeatedMessageField = function(messages, cloner) {
- if (messages === null) return null;
- var result = [];
- for (var i = 0; i < messages.length; i++) {
- result.push(cloner(messages[i]));
- }
- return result;
-};
-
-
-/**
- * Clones an array of byte blobs.
- * @param {Array.<Uint8Array>} blobs
- * @return {Array.<Uint8Array>}
- */
-jspb.utils.cloneRepeatedBlobField = function(blobs) {
- if (blobs === null) return null;
- var result = [];
- for (var i = 0; i < blobs.length; i++) {
- result.push(new Uint8Array(blobs[i]));
- }
- return result;
-};
-
-
-/**
* String-ify bytes for text format. Should be optimized away in non-debug.
* The returned string uses \xXX escapes for all values and is itself quoted.
* [1, 31] serializes to '"\x01\x1f"'.
* @param {jspb.ByteSource} byteSource The bytes to serialize.
- * @param {boolean=} opt_stringIsRawBytes The string is interpreted as a series
- * of raw bytes rather than base64 data.
* @return {string} Stringified bytes for text format.
*/
-jspb.utils.debugBytesToTextFormat = function(byteSource,
- opt_stringIsRawBytes) {
+jspb.utils.debugBytesToTextFormat = function(byteSource) {
var s = '"';
if (byteSource) {
- var bytes =
- jspb.utils.byteSourceToUint8Array(byteSource, opt_stringIsRawBytes);
+ var bytes = jspb.utils.byteSourceToUint8Array(byteSource);
for (var i = 0; i < bytes.length; i++) {
s += '\\x';
if (bytes[i] < 16) s += '0';
@@ -925,9 +879,8 @@ jspb.utils.debugScalarToTextFormat = function(scalar) {
* exception.
* @param {string} str
* @return {!Uint8Array}
- * @private
*/
-jspb.utils.stringToByteArray_ = function(str) {
+jspb.utils.stringToByteArray = function(str) {
var arr = new Uint8Array(str.length);
for (var i = 0; i < str.length; i++) {
var codepoint = str.charCodeAt(i);
@@ -944,13 +897,10 @@ jspb.utils.stringToByteArray_ = function(str) {
/**
* Converts any type defined in jspb.ByteSource into a Uint8Array.
* @param {!jspb.ByteSource} data
- * @param {boolean=} opt_stringIsRawBytes Interpret a string as a series of raw
- * bytes (encoded as codepoints 0--255 inclusive) rather than base64 data
- * (default behavior).
* @return {!Uint8Array}
* @suppress {invalidCasts}
*/
-jspb.utils.byteSourceToUint8Array = function(data, opt_stringIsRawBytes) {
+jspb.utils.byteSourceToUint8Array = function(data) {
if (data.constructor === Uint8Array) {
return /** @type {!Uint8Array} */(data);
}
@@ -967,11 +917,7 @@ jspb.utils.byteSourceToUint8Array = function(data, opt_stringIsRawBytes) {
if (data.constructor === String) {
data = /** @type {string} */(data);
- if (opt_stringIsRawBytes) {
- return jspb.utils.stringToByteArray_(data);
- } else {
- return goog.crypt.base64.decodeStringToUint8Array(data);
- }
+ return goog.crypt.base64.decodeStringToUint8Array(data);
}
goog.asserts.fail('Type not convertible to Uint8Array.');
diff --git a/js/binary/utils_test.js b/js/binary/utils_test.js
index 5c330791..518d7597 100644
--- a/js/binary/utils_test.js
+++ b/js/binary/utils_test.js
@@ -310,7 +310,7 @@ describe('binaryUtilsTest', function() {
// NaN.
jspb.utils.splitFloat32(NaN);
if (!isNaN(jspb.utils.joinFloat32(jspb.utils.split64Low,
- jspb.utils.split64High))) {
+ jspb.utils.split64High))) {
throw 'fail!';
}
@@ -324,7 +324,7 @@ describe('binaryUtilsTest', function() {
if (opt_bits != jspb.utils.split64Low) throw 'fail!';
}
if (truncate(x) != jspb.utils.joinFloat32(jspb.utils.split64Low,
- jspb.utils.split64High)) {
+ jspb.utils.split64High)) {
throw 'fail!';
}
}
@@ -376,7 +376,7 @@ describe('binaryUtilsTest', function() {
// NaN.
jspb.utils.splitFloat64(NaN);
if (!isNaN(jspb.utils.joinFloat64(jspb.utils.split64Low,
- jspb.utils.split64High))) {
+ jspb.utils.split64High))) {
throw 'fail!';
}
@@ -394,7 +394,7 @@ describe('binaryUtilsTest', function() {
if (opt_lowBits != jspb.utils.split64Low) throw 'fail!';
}
if (x != jspb.utils.joinFloat64(jspb.utils.split64Low,
- jspb.utils.split64High)) {
+ jspb.utils.split64High)) {
throw 'fail!';
}
}
@@ -439,16 +439,20 @@ describe('binaryUtilsTest', function() {
* Tests counting packed varints.
*/
it('testCountVarints', function() {
- var writer = new jspb.BinaryWriter();
-
- var count = 0;
+ var values = [];
for (var i = 1; i < 1000000000; i *= 1.1) {
- writer.rawWriteVarint(Math.floor(i));
- count++;
+ values.push(Math.floor(i));
}
+ var writer = new jspb.BinaryWriter();
+ writer.writePackedUint64(1, values);
+
var buffer = new Uint8Array(writer.getResultBuffer());
- assertEquals(count, jspb.utils.countVarints(buffer, 0, buffer.length));
+
+ // We should have two more varints than we started with - one for the field
+ // tag, one for the packed length.
+ assertEquals(values.length + 2,
+ jspb.utils.countVarints(buffer, 0, buffer.length));
});
@@ -625,8 +629,5 @@ describe('binaryUtilsTest', function() {
// Converting base64-encoded strings into Uint8Arrays should work.
check(convert(sourceBase64));
-
- // Converting binary-data strings into Uint8Arrays should work.
- check(convert(sourceString, /* opt_stringIsRawBytes = */ true));
});
});
diff --git a/js/binary/writer.js b/js/binary/writer.js
index a1849457..be4478ee 100644
--- a/js/binary/writer.js
+++ b/js/binary/writer.js
@@ -60,12 +60,11 @@ goog.provide('jspb.BinaryWriter');
goog.require('goog.asserts');
goog.require('goog.crypt.base64');
goog.require('jspb.BinaryConstants');
+goog.require('jspb.BinaryEncoder');
goog.require('jspb.arith.Int64');
goog.require('jspb.arith.UInt64');
goog.require('jspb.utils');
-goog.forwardDeclare('jspb.Message');
-
/**
@@ -84,116 +83,109 @@ jspb.BinaryWriter = function() {
this.blocks_ = [];
/**
- * Total number of bytes in the blocks_ array. Does _not_ include the temp
- * buffer.
+ * Total number of bytes in the blocks_ array. Does _not_ include bytes in
+ * the encoder below.
* @private {number}
*/
this.totalLength_ = 0;
/**
- * Temporary buffer holding a message that we're still serializing. When we
- * get to a stopping point (either the start of a new submessage, or when we
- * need to append a raw Uint8Array), the temp buffer will be added to the
- * block array above and a new temp buffer will be created.
- * @private {!Array.<number>}
+ * Binary encoder holding pieces of a message that we're still serializing.
+ * When we get to a stopping point (either the start of a new submessage, or
+ * when we need to append a raw Uint8Array), the encoder's buffer will be
+ * added to the block array above and the encoder will be reset.
+ * @private {!jspb.BinaryEncoder}
*/
- this.temp_ = [];
+ this.encoder_ = new jspb.BinaryEncoder();
/**
* A stack of bookmarks containing the parent blocks for each message started
* via beginSubMessage(), needed as bookkeeping for endSubMessage().
* TODO(aappleby): Deprecated, users should be calling writeMessage().
- * @private {!Array.<!jspb.BinaryWriter.Bookmark_>}
+ * @private {!Array.<!Array.<number>>}
*/
this.bookmarks_ = [];
};
/**
- * @typedef {{block: !Array.<number>, length: number}}
- * @private
- */
-jspb.BinaryWriter.Bookmark_;
-
-
-/**
- * Saves the current temp buffer in the blocks_ array and starts a new one.
- * @return {!Array.<number>} Returns a reference to the old temp buffer.
- * @private
- */
-jspb.BinaryWriter.prototype.saveTempBuffer_ = function() {
- var oldTemp = this.temp_;
- this.blocks_.push(this.temp_);
- this.totalLength_ += this.temp_.length;
- this.temp_ = [];
- return oldTemp;
-};
-
-
-/**
* Append a typed array of bytes onto the buffer.
*
* @param {!Uint8Array} arr The byte array to append.
* @private
*/
jspb.BinaryWriter.prototype.appendUint8Array_ = function(arr) {
- if (this.temp_.length) {
- this.saveTempBuffer_();
- }
+ var temp = this.encoder_.end();
+ this.blocks_.push(temp);
this.blocks_.push(arr);
- this.totalLength_ += arr.length;
+ this.totalLength_ += temp.length + arr.length;
};
/**
- * Append an untyped array of bytes onto the buffer.
- *
- * @param {!Array.<number>} arr The byte array to append.
- * @private
- */
-jspb.BinaryWriter.prototype.appendArray_ = function(arr) {
- if (this.temp_.length) {
- this.saveTempBuffer_();
- }
- this.temp_ = arr;
-};
-
-
-/**
- * Begins a length-delimited section by writing the field header to the current
- * temp buffer and then saving it in the block array. Returns the saved block,
- * which we will append the length to in endDelimited_ below.
+ * Begins a new message by writing the field header and returning a bookmark
+ * which we will use to patch in the message length to in endDelimited_ below.
* @param {number} field
- * @return {!jspb.BinaryWriter.Bookmark_}
+ * @return {!Array.<number>}
* @private
*/
jspb.BinaryWriter.prototype.beginDelimited_ = function(field) {
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
- return {block: this.saveTempBuffer_(), length: this.totalLength_};
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ var bookmark = this.encoder_.end();
+ this.blocks_.push(bookmark);
+ this.totalLength_ += bookmark.length;
+ bookmark.push(this.totalLength_);
+ return bookmark;
};
/**
- * Ends a length-delimited block by encoding the _change_ in length of the
- * buffer to the parent block and adds the number of bytes needed to encode
- * that length to the total byte length. Note that 'parentLength' _must_ be the
- * total length _after_ the field header was written in beginDelimited_ above.
- * @param {!jspb.BinaryWriter.Bookmark_} bookmark
+ * Ends a message by encoding the _change_ in length of the buffer to the
+ * parent block and adds the number of bytes needed to encode that length to
+ * the total byte length.
+ * @param {!Array.<number>} bookmark
* @private
*/
jspb.BinaryWriter.prototype.endDelimited_ = function(bookmark) {
- var messageLength = this.totalLength_ + this.temp_.length - bookmark.length;
+ var oldLength = bookmark.pop();
+ var messageLength = this.totalLength_ + this.encoder_.length() - oldLength;
goog.asserts.assert(messageLength >= 0);
- var bytes = 1;
while (messageLength > 127) {
- bookmark.block.push((messageLength & 0x7f) | 0x80);
+ bookmark.push((messageLength & 0x7f) | 0x80);
messageLength = messageLength >>> 7;
- bytes++;
+ this.totalLength_++;
}
- bookmark.block.push(messageLength);
- this.totalLength_ += bytes;
+ bookmark.push(messageLength);
+ this.totalLength_++;
+};
+
+
+/**
+ * Writes a pre-serialized message to the buffer.
+ * @param {!Uint8Array} bytes The array of bytes to write.
+ * @param {number} start The start of the range to write.
+ * @param {number} end The end of the range to write.
+ */
+jspb.BinaryWriter.prototype.writeSerializedMessage = function(
+ bytes, start, end) {
+ this.appendUint8Array_(bytes.subarray(start, end));
+};
+
+
+/**
+ * Writes a pre-serialized message to the buffer if the message and endpoints
+ * are non-null.
+ * @param {?Uint8Array} bytes The array of bytes to write.
+ * @param {?number} start The start of the range to write.
+ * @param {?number} end The end of the range to write.
+ */
+jspb.BinaryWriter.prototype.maybeWriteSerializedMessage = function(
+ bytes, start, end) {
+ if (bytes != null && start != null && end != null) {
+ this.writeSerializedMessage(bytes, start, end);
+ }
};
@@ -202,7 +194,7 @@ jspb.BinaryWriter.prototype.endDelimited_ = function(bookmark) {
*/
jspb.BinaryWriter.prototype.reset = function() {
this.blocks_ = [];
- this.temp_ = [];
+ this.encoder_.end();
this.totalLength_ = 0;
this.bookmarks_ = [];
};
@@ -215,7 +207,7 @@ jspb.BinaryWriter.prototype.reset = function() {
jspb.BinaryWriter.prototype.getResultBuffer = function() {
goog.asserts.assert(this.bookmarks_.length == 0);
- var flat = new Uint8Array(this.totalLength_ + this.temp_.length);
+ var flat = new Uint8Array(this.totalLength_ + this.encoder_.length());
var blocks = this.blocks_;
var blockCount = blocks.length;
@@ -227,8 +219,9 @@ jspb.BinaryWriter.prototype.getResultBuffer = function() {
offset += block.length;
}
- flat.set(this.temp_, offset);
- offset += this.temp_.length;
+ var tail = this.encoder_.end();
+ flat.set(tail, offset);
+ offset += tail.length;
// Post condition: `flattened` must have had every byte written.
goog.asserts.assert(offset == flat.length);
@@ -236,7 +229,6 @@ jspb.BinaryWriter.prototype.getResultBuffer = function() {
// Replace our block list with the flattened block, which lets GC reclaim
// the temp blocks sooner.
this.blocks_ = [flat];
- this.temp_ = [];
return flat;
};
@@ -273,331 +265,6 @@ jspb.BinaryWriter.prototype.endSubMessage = function() {
/**
- * Encodes a 32-bit unsigned integer into its wire-format varint representation
- * and stores it in the buffer.
- * @param {number} value The integer to convert.
- */
-jspb.BinaryWriter.prototype.rawWriteUnsignedVarint32 = function(value) {
- goog.asserts.assert(value == Math.floor(value));
-
- while (value > 127) {
- this.temp_.push((value & 0x7f) | 0x80);
- value = value >>> 7;
- }
-
- this.temp_.push(value);
-};
-
-
-/**
- * Encodes a 32-bit signed integer into its wire-format varint representation
- * and stores it in the buffer.
- * @param {number} value The integer to convert.
- */
-jspb.BinaryWriter.prototype.rawWriteSignedVarint32 = function(value) {
- goog.asserts.assert(value == Math.floor(value));
- if (value >= 0) {
- this.rawWriteUnsignedVarint32(value);
- return;
- }
-
- // Write nine bytes with a _signed_ right shift so we preserve the sign bit.
- for (var i = 0; i < 9; i++) {
- this.temp_.push((value & 0x7f) | 0x80);
- value = value >> 7;
- }
-
- // The above loop writes out 63 bits, so the last byte is always the sign bit
- // which is always set for negative numbers.
- this.temp_.push(1);
-};
-
-
-/**
- * Encodes an unsigned 64-bit integer in 32:32 split representation into its
- * wire-format varint representation and stores it in the buffer.
- * @param {number} lowBits The low 32 bits of the int.
- * @param {number} highBits The high 32 bits of the int.
- */
-jspb.BinaryWriter.prototype.rawWriteSplitVarint =
- function(lowBits, highBits) {
- // Break the binary representation into chunks of 7 bits, set the 8th bit
- // in each chunk if it's not the final chunk, and append to the result.
- while (highBits > 0 || lowBits > 127) {
- this.temp_.push((lowBits & 0x7f) | 0x80);
- lowBits = ((lowBits >>> 7) | (highBits << 25)) >>> 0;
- highBits = highBits >>> 7;
- }
- this.temp_.push(lowBits);
-};
-
-
-/**
- * Encodes a JavaScript integer into its wire-format varint representation and
- * stores it in the buffer. Due to the way the varint encoding works this
- * behaves correctly for both signed and unsigned integers, though integers
- * that are not representable in 64 bits will still be truncated.
- * @param {number} value The integer to convert.
- */
-jspb.BinaryWriter.prototype.rawWriteVarint = function(value) {
- goog.asserts.assert(value == Math.floor(value));
- jspb.utils.splitInt64(value);
- this.rawWriteSplitVarint(jspb.utils.split64Low,
- jspb.utils.split64High);
-};
-
-
-/**
- * Encodes a jspb.arith.{Int64,UInt64} instance into its wire-format
- * varint representation and stores it in the buffer. Due to the way the varint
- * encoding works this behaves correctly for both signed and unsigned integers,
- * though integers that are not representable in 64 bits will still be
- * truncated.
- * @param {jspb.arith.Int64|jspb.arith.UInt64} value
- */
-jspb.BinaryWriter.prototype.rawWriteVarintFromNum = function(value) {
- this.rawWriteSplitVarint(value.lo, value.hi);
-};
-
-
-/**
- * Encodes a JavaScript integer into its wire-format, zigzag-encoded varint
- * representation and stores it in the buffer.
- * @param {number} value The integer to convert.
- */
-jspb.BinaryWriter.prototype.rawWriteZigzagVarint32 = function(value) {
- goog.asserts.assert(value == Math.floor(value));
- this.rawWriteUnsignedVarint32(((value << 1) ^ (value >> 31)) >>> 0);
-};
-
-
-/**
- * Encodes a JavaScript integer into its wire-format, zigzag-encoded varint
- * representation and stores it in the buffer. Integers not representable in 64
- * bits will be truncated.
- * @param {number} value The integer to convert.
- */
-jspb.BinaryWriter.prototype.rawWriteZigzagVarint = function(value) {
- goog.asserts.assert(value == Math.floor(value));
- jspb.utils.splitZigzag64(value);
- this.rawWriteSplitVarint(jspb.utils.split64Low,
- jspb.utils.split64High);
-};
-
-
-/**
- * Writes a raw 8-bit unsigned integer to the buffer. Numbers outside the range
- * [0,2^8) will be truncated.
- * @param {number} value The value to write.
- */
-jspb.BinaryWriter.prototype.rawWriteUint8 = function(value) {
- goog.asserts.assert(value == Math.floor(value));
- goog.asserts.assert((value >= 0) && (value < 256));
- this.temp_.push((value >>> 0) & 0xFF);
-};
-
-
-/**
- * Writes a raw 16-bit unsigned integer to the buffer. Numbers outside the
- * range [0,2^16) will be truncated.
- * @param {number} value The value to write.
- */
-jspb.BinaryWriter.prototype.rawWriteUint16 = function(value) {
- goog.asserts.assert(value == Math.floor(value));
- goog.asserts.assert((value >= 0) && (value < 65536));
- this.temp_.push((value >>> 0) & 0xFF);
- this.temp_.push((value >>> 8) & 0xFF);
-};
-
-
-/**
- * Writes a raw 32-bit unsigned integer to the buffer. Numbers outside the
- * range [0,2^32) will be truncated.
- * @param {number} value The value to write.
- */
-jspb.BinaryWriter.prototype.rawWriteUint32 = function(value) {
- goog.asserts.assert(value == Math.floor(value));
- goog.asserts.assert((value >= 0) &&
- (value < jspb.BinaryConstants.TWO_TO_32));
- this.temp_.push((value >>> 0) & 0xFF);
- this.temp_.push((value >>> 8) & 0xFF);
- this.temp_.push((value >>> 16) & 0xFF);
- this.temp_.push((value >>> 24) & 0xFF);
-};
-
-
-/**
- * Writes a raw 64-bit unsigned integer to the buffer. Numbers outside the
- * range [0,2^64) will be truncated.
- * @param {number} value The value to write.
- */
-jspb.BinaryWriter.prototype.rawWriteUint64 = function(value) {
- goog.asserts.assert(value == Math.floor(value));
- goog.asserts.assert((value >= 0) &&
- (value < jspb.BinaryConstants.TWO_TO_64));
- jspb.utils.splitUint64(value);
- this.rawWriteUint32(jspb.utils.split64Low);
- this.rawWriteUint32(jspb.utils.split64High);
-};
-
-
-/**
- * Writes a raw 8-bit integer to the buffer. Numbers outside the range
- * [-2^7,2^7) will be truncated.
- * @param {number} value The value to write.
- */
-jspb.BinaryWriter.prototype.rawWriteInt8 = function(value) {
- goog.asserts.assert(value == Math.floor(value));
- goog.asserts.assert((value >= -128) && (value < 128));
- this.temp_.push((value >>> 0) & 0xFF);
-};
-
-
-/**
- * Writes a raw 16-bit integer to the buffer. Numbers outside the range
- * [-2^15,2^15) will be truncated.
- * @param {number} value The value to write.
- */
-jspb.BinaryWriter.prototype.rawWriteInt16 = function(value) {
- goog.asserts.assert(value == Math.floor(value));
- goog.asserts.assert((value >= -32768) && (value < 32768));
- this.temp_.push((value >>> 0) & 0xFF);
- this.temp_.push((value >>> 8) & 0xFF);
-};
-
-
-/**
- * Writes a raw 32-bit integer to the buffer. Numbers outside the range
- * [-2^31,2^31) will be truncated.
- * @param {number} value The value to write.
- */
-jspb.BinaryWriter.prototype.rawWriteInt32 = function(value) {
- goog.asserts.assert(value == Math.floor(value));
- goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
- (value < jspb.BinaryConstants.TWO_TO_31));
- this.temp_.push((value >>> 0) & 0xFF);
- this.temp_.push((value >>> 8) & 0xFF);
- this.temp_.push((value >>> 16) & 0xFF);
- this.temp_.push((value >>> 24) & 0xFF);
-};
-
-
-/**
- * Writes a raw 64-bit integer to the buffer. Numbers outside the range
- * [-2^63,2^63) will be truncated.
- * @param {number} value The value to write.
- */
-jspb.BinaryWriter.prototype.rawWriteInt64 = function(value) {
- goog.asserts.assert(value == Math.floor(value));
- goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
- (value < jspb.BinaryConstants.TWO_TO_63));
- jspb.utils.splitInt64(value);
- this.rawWriteUint32(jspb.utils.split64Low);
- this.rawWriteUint32(jspb.utils.split64High);
-};
-
-
-/**
- * Writes a raw single-precision floating point value to the buffer. Numbers
- * requiring more than 32 bits of precision will be truncated.
- * @param {number} value The value to write.
- */
-jspb.BinaryWriter.prototype.rawWriteFloat = function(value) {
- jspb.utils.splitFloat32(value);
- this.rawWriteUint32(jspb.utils.split64Low);
-};
-
-
-/**
- * Writes a raw double-precision floating point value to the buffer. As this is
- * the native format used by JavaScript, no precision will be lost.
- * @param {number} value The value to write.
- */
-jspb.BinaryWriter.prototype.rawWriteDouble = function(value) {
- jspb.utils.splitFloat64(value);
- this.rawWriteUint32(jspb.utils.split64Low);
- this.rawWriteUint32(jspb.utils.split64High);
-};
-
-
-/**
- * Writes a raw boolean value to the buffer as a varint.
- * @param {boolean} value The value to write.
- */
-jspb.BinaryWriter.prototype.rawWriteBool = function(value) {
- goog.asserts.assert(goog.isBoolean(value));
- this.temp_.push(~~value);
-};
-
-
-/**
- * Writes an raw enum value to the buffer as a varint.
- * @param {number} value The value to write.
- */
-jspb.BinaryWriter.prototype.rawWriteEnum = function(value) {
- goog.asserts.assert(value == Math.floor(value));
- goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
- (value < jspb.BinaryConstants.TWO_TO_31));
- this.rawWriteSignedVarint32(value);
-};
-
-
-/**
- * Writes a raw string value to the buffer.
- * @param {string} string The string to write.
- */
-jspb.BinaryWriter.prototype.rawWriteUtf8String = function(string) {
- for (var i = 0; i < string.length; i++) {
- this.temp_.push(string.charCodeAt(i));
- }
-};
-
-
-/**
- * Writes an arbitrary raw byte array to the buffer.
- * @param {!Uint8Array} bytes The array of bytes to write.
- */
-jspb.BinaryWriter.prototype.rawWriteBytes = function(bytes) {
- this.appendUint8Array_(bytes);
-};
-
-
-/**
- * Writes an arbitrary raw byte array to the buffer.
- * @param {!Uint8Array} bytes The array of bytes to write.
- * @param {number} start The start of the range to write.
- * @param {number} end The end of the range to write.
- */
-jspb.BinaryWriter.prototype.rawWriteByteRange = function(bytes, start, end) {
- this.appendUint8Array_(bytes.subarray(start, end));
-};
-
-
-/**
- * Writes a 64-bit hash string (8 characters @ 8 bits of data each) to the
- * buffer as a varint.
- * @param {string} hash The hash to write.
- */
-jspb.BinaryWriter.prototype.rawWriteVarintHash64 = function(hash) {
- jspb.utils.splitHash64(hash);
- this.rawWriteSplitVarint(jspb.utils.split64Low,
- jspb.utils.split64High);
-};
-
-
-/**
- * Writes a 64-bit hash string (8 characters @ 8 bits of data each) to the
- * buffer as a fixed64.
- * @param {string} hash The hash to write.
- */
-jspb.BinaryWriter.prototype.rawWriteFixedHash64 = function(hash) {
- jspb.utils.splitHash64(hash);
- this.rawWriteUint32(jspb.utils.split64Low);
- this.rawWriteUint32(jspb.utils.split64High);
-};
-
-
-/**
* Encodes a (field number, wire type) tuple into a wire-format field header
* and stores it in the buffer as a varint.
* @param {number} field The field number.
@@ -605,11 +272,11 @@ jspb.BinaryWriter.prototype.rawWriteFixedHash64 = function(hash) {
* protocol buffer documentation.
* @private
*/
-jspb.BinaryWriter.prototype.rawWriteFieldHeader_ =
+jspb.BinaryWriter.prototype.writeFieldHeader_ =
function(field, wireType) {
goog.asserts.assert(field >= 1 && field == Math.floor(field));
var x = field * 8 + wireType;
- this.rawWriteUnsignedVarint32(x);
+ this.encoder_.writeUnsignedVarint32(x);
};
@@ -697,8 +364,8 @@ jspb.BinaryWriter.prototype.writeAny = function(fieldType, field, value) {
*/
jspb.BinaryWriter.prototype.writeUnsignedVarint32_ = function(field, value) {
if (value == null) return;
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
- this.rawWriteSignedVarint32(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeUnsignedVarint32(value);
};
@@ -710,8 +377,21 @@ jspb.BinaryWriter.prototype.writeUnsignedVarint32_ = function(field, value) {
*/
jspb.BinaryWriter.prototype.writeSignedVarint32_ = function(field, value) {
if (value == null) return;
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
- this.rawWriteSignedVarint32(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeSignedVarint32(value);
+};
+
+
+/**
+ * Writes a varint field to the buffer without range checking.
+ * @param {number} field The field number.
+ * @param {number?} value The value to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeUnsignedVarint64_ = function(field, value) {
+ if (value == null) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeUnsignedVarint64(value);
};
@@ -721,10 +401,10 @@ jspb.BinaryWriter.prototype.writeSignedVarint32_ = function(field, value) {
* @param {number?} value The value to write.
* @private
*/
-jspb.BinaryWriter.prototype.writeVarint_ = function(field, value) {
+jspb.BinaryWriter.prototype.writeSignedVarint64_ = function(field, value) {
if (value == null) return;
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
- this.rawWriteVarint(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeSignedVarint64(value);
};
@@ -736,8 +416,8 @@ jspb.BinaryWriter.prototype.writeVarint_ = function(field, value) {
*/
jspb.BinaryWriter.prototype.writeZigzagVarint32_ = function(field, value) {
if (value == null) return;
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
- this.rawWriteZigzagVarint32(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeZigzagVarint32(value);
};
@@ -747,10 +427,10 @@ jspb.BinaryWriter.prototype.writeZigzagVarint32_ = function(field, value) {
* @param {number?} value The value to write.
* @private
*/
-jspb.BinaryWriter.prototype.writeZigzagVarint_ = function(field, value) {
+jspb.BinaryWriter.prototype.writeZigzagVarint64_ = function(field, value) {
if (value == null) return;
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
- this.rawWriteZigzagVarint(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeZigzagVarint64(value);
};
@@ -793,7 +473,7 @@ jspb.BinaryWriter.prototype.writeInt64 = function(field, value) {
if (value == null) return;
goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
(value < jspb.BinaryConstants.TWO_TO_63));
- this.writeVarint_(field, value);
+ this.writeSignedVarint64_(field, value);
};
@@ -805,8 +485,8 @@ jspb.BinaryWriter.prototype.writeInt64 = function(field, value) {
jspb.BinaryWriter.prototype.writeInt64String = function(field, value) {
if (value == null) return;
var num = jspb.arith.Int64.fromString(value);
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
- this.rawWriteVarintFromNum(num);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeSplitVarint64(num.lo, num.hi);
};
@@ -849,7 +529,7 @@ jspb.BinaryWriter.prototype.writeUint64 = function(field, value) {
if (value == null) return;
goog.asserts.assert((value >= 0) &&
(value < jspb.BinaryConstants.TWO_TO_64));
- this.writeVarint_(field, value);
+ this.writeUnsignedVarint64_(field, value);
};
@@ -861,8 +541,8 @@ jspb.BinaryWriter.prototype.writeUint64 = function(field, value) {
jspb.BinaryWriter.prototype.writeUint64String = function(field, value) {
if (value == null) return;
var num = jspb.arith.UInt64.fromString(value);
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
- this.rawWriteVarintFromNum(num);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeSplitVarint64(num.lo, num.hi);
};
@@ -890,7 +570,7 @@ jspb.BinaryWriter.prototype.writeSint64 = function(field, value) {
if (value == null) return;
goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
(value < jspb.BinaryConstants.TWO_TO_63));
- this.writeZigzagVarint_(field, value);
+ this.writeZigzagVarint64_(field, value);
};
@@ -904,8 +584,8 @@ jspb.BinaryWriter.prototype.writeFixed32 = function(field, value) {
if (value == null) return;
goog.asserts.assert((value >= 0) &&
(value < jspb.BinaryConstants.TWO_TO_32));
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
- this.rawWriteUint32(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
+ this.encoder_.writeUint32(value);
};
@@ -919,8 +599,8 @@ jspb.BinaryWriter.prototype.writeFixed64 = function(field, value) {
if (value == null) return;
goog.asserts.assert((value >= 0) &&
(value < jspb.BinaryConstants.TWO_TO_64));
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
- this.rawWriteUint64(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
+ this.encoder_.writeUint64(value);
};
@@ -934,8 +614,8 @@ jspb.BinaryWriter.prototype.writeSfixed32 = function(field, value) {
if (value == null) return;
goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
(value < jspb.BinaryConstants.TWO_TO_31));
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
- this.rawWriteInt32(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
+ this.encoder_.writeInt32(value);
};
@@ -949,8 +629,8 @@ jspb.BinaryWriter.prototype.writeSfixed64 = function(field, value) {
if (value == null) return;
goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_63) &&
(value < jspb.BinaryConstants.TWO_TO_63));
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
- this.rawWriteInt64(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
+ this.encoder_.writeInt64(value);
};
@@ -962,8 +642,8 @@ jspb.BinaryWriter.prototype.writeSfixed64 = function(field, value) {
*/
jspb.BinaryWriter.prototype.writeFloat = function(field, value) {
if (value == null) return;
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
- this.rawWriteFloat(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED32);
+ this.encoder_.writeFloat(value);
};
@@ -975,8 +655,8 @@ jspb.BinaryWriter.prototype.writeFloat = function(field, value) {
*/
jspb.BinaryWriter.prototype.writeDouble = function(field, value) {
if (value == null) return;
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
- this.rawWriteDouble(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
+ this.encoder_.writeDouble(value);
};
@@ -988,8 +668,8 @@ jspb.BinaryWriter.prototype.writeDouble = function(field, value) {
jspb.BinaryWriter.prototype.writeBool = function(field, value) {
if (value == null) return;
goog.asserts.assert(goog.isBoolean(value));
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
- this.temp_.push(~~value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeBool(value);
};
@@ -1002,8 +682,8 @@ jspb.BinaryWriter.prototype.writeEnum = function(field, value) {
if (value == null) return;
goog.asserts.assert((value >= -jspb.BinaryConstants.TWO_TO_31) &&
(value < jspb.BinaryConstants.TWO_TO_31));
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
- this.rawWriteSignedVarint32(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeSignedVarint32(value);
};
@@ -1014,99 +694,41 @@ jspb.BinaryWriter.prototype.writeEnum = function(field, value) {
*/
jspb.BinaryWriter.prototype.writeString = function(field, value) {
if (value == null) return;
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
-
- // Conversion loop swiped from goog.crypt.stringToUtf8ByteArray. Note that
- // 'bytes' will be at least as long as 'value', but could be longer if we
- // need to unpack unicode characters.
- var bytes = [];
- for (var i = 0; i < value.length; i++) {
- var c = value.charCodeAt(i);
- if (c < 128) {
- bytes.push(c);
- } else if (c < 2048) {
- bytes.push((c >> 6) | 192);
- bytes.push((c & 63) | 128);
- } else {
- bytes.push((c >> 12) | 224);
- bytes.push(((c >> 6) & 63) | 128);
- bytes.push((c & 63) | 128);
- }
- }
-
- this.rawWriteUnsignedVarint32(bytes.length);
- this.appendArray_(bytes);
+ var bookmark = this.beginDelimited_(field);
+ this.encoder_.writeString(value);
+ this.endDelimited_(bookmark);
};
/**
* Writes an arbitrary byte field to the buffer. Note - to match the behavior
* of the C++ implementation, empty byte arrays _are_ serialized.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
- * @param {jspb.ByteSource} value The array of bytes to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
- * @param {boolean=} opt_stringIsRawBytes If `value` is a string, interpret it
- * as a series of raw bytes (codepoints 0--255 inclusive) rather than base64
- * data.
- */
-jspb.BinaryWriter.prototype.writeBytes =
- function(field, value, opt_buffer, opt_start, opt_end,
- opt_stringIsRawBytes) {
- if (value != null) {
- this.rawWriteFieldHeader_(field,
- jspb.BinaryConstants.WireType.DELIMITED);
- this.rawWriteUnsignedVarint32(value.length);
- this.rawWriteBytes(
- jspb.utils.byteSourceToUint8Array(value, opt_stringIsRawBytes));
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
- }
-};
-
-
-/**
- * Writes an arbitrary byte field to the buffer, with `opt_stringIsRawBytes`
- * flag implicitly true.
- * @param {number} field
- * @param {jspb.ByteSource} value The array of bytes to write.
+ * @param {?jspb.ByteSource} value The array of bytes to write.
*/
-jspb.BinaryWriter.prototype.writeBytesRawString = function(field, value) {
- this.writeBytes(field, value, null, null, null, true);
+jspb.BinaryWriter.prototype.writeBytes = function(field, value) {
+ if (value == null) return;
+ var bytes = jspb.utils.byteSourceToUint8Array(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(bytes.length);
+ this.appendUint8Array_(bytes);
};
/**
* Writes a message to the buffer.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @template MessageType
* @param {number} field The field number.
* @param {?MessageType} value The message to write.
* @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
* to write and the writer to write it with.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
*/
-jspb.BinaryWriter.prototype.writeMessage =
- function(field, value, writerCallback, opt_buffer, opt_start, opt_end) {
- if (value !== null) {
- var bookmark = this.beginDelimited_(field);
-
- writerCallback(value, this);
-
- this.endDelimited_(bookmark);
- } else if (opt_buffer && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
- }
+jspb.BinaryWriter.prototype.writeMessage = function(
+ field, value, writerCallback) {
+ if (value == null) return;
+ var bookmark = this.beginDelimited_(field);
+ writerCallback(value, this);
+ this.endDelimited_(bookmark);
};
@@ -1120,15 +742,12 @@ jspb.BinaryWriter.prototype.writeMessage =
* @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
* to write and the writer to write it with.
*/
-jspb.BinaryWriter.prototype.writeGroup =
- function(field, value, writerCallback) {
- if (value) {
- this.rawWriteFieldHeader_(
- field, jspb.BinaryConstants.WireType.START_GROUP);
- writerCallback(value, this);
- this.rawWriteFieldHeader_(
- field, jspb.BinaryConstants.WireType.END_GROUP);
- }
+jspb.BinaryWriter.prototype.writeGroup = function(
+ field, value, writerCallback) {
+ if (value == null) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.START_GROUP);
+ writerCallback(value, this);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.END_GROUP);
};
@@ -1141,8 +760,8 @@ jspb.BinaryWriter.prototype.writeGroup =
jspb.BinaryWriter.prototype.writeFixedHash64 = function(field, value) {
if (value == null) return;
goog.asserts.assert(value.length == 8);
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
- this.rawWriteFixedHash64(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.FIXED64);
+ this.encoder_.writeFixedHash64(value);
};
@@ -1155,8 +774,8 @@ jspb.BinaryWriter.prototype.writeFixedHash64 = function(field, value) {
jspb.BinaryWriter.prototype.writeVarintHash64 = function(field, value) {
if (value == null) return;
goog.asserts.assert(value.length == 8);
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
- this.rawWriteVarintHash64(value);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.VARINT);
+ this.encoder_.writeVarintHash64(value);
};
@@ -1196,10 +815,26 @@ jspb.BinaryWriter.prototype.writeRepeatedSignedVarint32_ =
* @param {?Array.<number>} value The array of ints to write.
* @private
*/
-jspb.BinaryWriter.prototype.writeRepeatedVarint_ = function(field, value) {
+jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint64_ =
+ function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeUnsignedVarint64_(field, value[i]);
+ }
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a repeated varint field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writeRepeatedSignedVarint64_ =
+ function(field, value) {
if (value == null) return;
for (var i = 0; i < value.length; i++) {
- this.writeVarint_(field, value[i]);
+ this.writeSignedVarint64_(field, value[i]);
}
};
@@ -1227,7 +862,7 @@ jspb.BinaryWriter.prototype.writeRepeatedZigzag32_ = function(field, value) {
jspb.BinaryWriter.prototype.writeRepeatedZigzag_ = function(field, value) {
if (value == null) return;
for (var i = 0; i < value.length; i++) {
- this.writeZigzagVarint_(field, value[i]);
+ this.writeZigzagVarint64_(field, value[i]);
}
};
@@ -1262,7 +897,7 @@ jspb.BinaryWriter.prototype.writeRepeatedInt32String =
* @param {?Array.<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedInt64 =
- jspb.BinaryWriter.prototype.writeRepeatedVarint_;
+ jspb.BinaryWriter.prototype.writeRepeatedSignedVarint64_;
/**
@@ -1312,7 +947,7 @@ jspb.BinaryWriter.prototype.writeRepeatedUint32String =
* @param {?Array.<number>} value The array of ints to write.
*/
jspb.BinaryWriter.prototype.writeRepeatedUint64 =
- jspb.BinaryWriter.prototype.writeRepeatedVarint_;
+ jspb.BinaryWriter.prototype.writeRepeatedUnsignedVarint64_;
/**
@@ -1469,96 +1104,54 @@ jspb.BinaryWriter.prototype.writeRepeatedString = function(field, value) {
/**
* Writes an array of arbitrary byte fields to the buffer.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
- * @param {?Array.<!Uint8Array|string>} value
- * The arrays of arrays of bytes to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
- * @param {boolean=} opt_stringIsRawBytes Any values that are strings are
- * interpreted as raw bytes rather than base64 data.
- */
-jspb.BinaryWriter.prototype.writeRepeatedBytes =
- function(field, value, opt_buffer, opt_start, opt_end,
- opt_stringIsRawBytes) {
- if (value != null) {
- for (var i = 0; i < value.length; i++) {
- this.writeBytes(field, value[i], null, null, null, opt_stringIsRawBytes);
- }
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
- }
-};
-
-
-/**
- * Writes an array of arbitrary byte fields to the buffer, with
- * `opt_stringIsRawBytes` implicitly true.
- * @param {number} field
- * @param {?Array.<string>} value
+ * @param {?Array.<!jspb.ByteSource>} value The arrays of arrays of bytes to
+ * write.
*/
-jspb.BinaryWriter.prototype.writeRepeatedBytesRawString =
- function(field, value) {
- this.writeRepeatedBytes(field, value, null, null, null, true);
+jspb.BinaryWriter.prototype.writeRepeatedBytes = function(field, value) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeBytes(field, value[i]);
+ }
};
/**
* Writes an array of messages to the buffer.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @template MessageType
* @param {number} field The field number.
- * @param {?Array.<!MessageType>} value The array of messages to
+ * @param {?Array.<MessageType>} value The array of messages to
* write.
* @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
* to write and the writer to write it with.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
- */
-jspb.BinaryWriter.prototype.writeRepeatedMessage =
- function(field, value, writerCallback, opt_buffer, opt_start, opt_end) {
- if (value) {
- for (var i = 0; i < value.length; i++) {
- var bookmark = this.beginDelimited_(field);
-
- writerCallback(value[i], this);
-
- this.endDelimited_(bookmark);
- }
- } else if (opt_buffer && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+ */
+jspb.BinaryWriter.prototype.writeRepeatedMessage = function(
+ field, value, writerCallback) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ var bookmark = this.beginDelimited_(field);
+ writerCallback(value[i], this);
+ this.endDelimited_(bookmark);
}
};
/**
* Writes an array of group messages to the buffer.
- *
* @template MessageType
* @param {number} field The field number.
- * @param {?Array.<!MessageType>} value The array of messages to
+ * @param {?Array.<MessageType>} value The array of messages to
* write.
* @param {!jspb.WriterFunction} writerCallback Will be invoked with the value
* to write and the writer to write it with.
*/
-jspb.BinaryWriter.prototype.writeRepeatedGroup =
- function(field, value, writerCallback) {
- if (value) {
- for (var i = 0; i < value.length; i++) {
- this.rawWriteFieldHeader_(
- field, jspb.BinaryConstants.WireType.START_GROUP);
- writerCallback(value[i], this);
- this.rawWriteFieldHeader_(
- field, jspb.BinaryConstants.WireType.END_GROUP);
- }
+jspb.BinaryWriter.prototype.writeRepeatedGroup = function(
+ field, value, writerCallback) {
+ if (value == null) return;
+ for (var i = 0; i < value.length; i++) {
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.START_GROUP);
+ writerCallback(value[i], this);
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.END_GROUP);
}
};
@@ -1595,123 +1188,108 @@ jspb.BinaryWriter.prototype.writeRepeatedVarintHash64 =
/**
* Writes an array of numbers to the buffer as a packed varint field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
* @private
*/
-jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_ =
- function(field, value, opt_buffer, opt_start, opt_end) {
- if (value != null && value.length) {
- var bookmark = this.beginDelimited_(field);
- for (var i = 0; i < value.length; i++) {
- this.rawWriteUnsignedVarint32(value[i]);
- }
- this.endDelimited_(bookmark);
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_ = function(
+ field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeUnsignedVarint32(value[i]);
}
+ this.endDelimited_(bookmark);
};
/**
* Writes an array of numbers to the buffer as a packed varint field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
* @private
*/
-jspb.BinaryWriter.prototype.writePackedSignedVarint32_ =
- function(field, value, opt_buffer, opt_start, opt_end) {
- if (value != null && value.length) {
- var bookmark = this.beginDelimited_(field);
- for (var i = 0; i < value.length; i++) {
- this.rawWriteSignedVarint32(value[i]);
- }
- this.endDelimited_(bookmark);
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+jspb.BinaryWriter.prototype.writePackedSignedVarint32_ = function(
+ field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeSignedVarint32(value[i]);
}
+ this.endDelimited_(bookmark);
};
/**
* Writes an array of numbers to the buffer as a packed varint field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
* @private
*/
-jspb.BinaryWriter.prototype.writePackedVarint_ =
- function(field, value, opt_buffer, opt_start, opt_end) {
- if (value != null && value.length) {
- var bookmark = this.beginDelimited_(field);
- for (var i = 0; i < value.length; i++) {
- this.rawWriteVarint(value[i]);
- }
- this.endDelimited_(bookmark);
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+jspb.BinaryWriter.prototype.writePackedUnsignedVarint64_ = function(
+ field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeUnsignedVarint64(value[i]);
}
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed varint field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writePackedSignedVarint64_ = function(
+ field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeSignedVarint64(value[i]);
+ }
+ this.endDelimited_(bookmark);
};
/**
* Writes an array of numbers to the buffer as a packed zigzag field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
* @private
*/
-jspb.BinaryWriter.prototype.writePackedZigzag_ =
- function(field, value, opt_buffer, opt_start, opt_end) {
- if (value != null && value.length) {
- var bookmark = this.beginDelimited_(field);
- for (var i = 0; i < value.length; i++) {
- this.rawWriteZigzagVarint(value[i]);
- }
- this.endDelimited_(bookmark);
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+jspb.BinaryWriter.prototype.writePackedZigzag32_ = function(field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeZigzagVarint32(value[i]);
+ }
+ this.endDelimited_(bookmark);
+};
+
+
+/**
+ * Writes an array of numbers to the buffer as a packed zigzag field.
+ * @param {number} field The field number.
+ * @param {?Array.<number>} value The array of ints to write.
+ * @private
+ */
+jspb.BinaryWriter.prototype.writePackedZigzag64_ = function(field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeZigzagVarint64(value[i]);
}
+ this.endDelimited_(bookmark);
};
/**
* Writes an array of numbers to the buffer as a packed 32-bit int field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
*/
jspb.BinaryWriter.prototype.writePackedInt32 =
jspb.BinaryWriter.prototype.writePackedSignedVarint32_;
@@ -1727,7 +1305,7 @@ jspb.BinaryWriter.prototype.writePackedInt32String = function(field, value) {
if (value == null || !value.length) return;
var bookmark = this.beginDelimited_(field);
for (var i = 0; i < value.length; i++) {
- this.rawWriteSignedVarint32(parseInt(value[i], 10));
+ this.encoder_.writeSignedVarint32(parseInt(value[i], 10));
}
this.endDelimited_(bookmark);
};
@@ -1737,12 +1315,9 @@ jspb.BinaryWriter.prototype.writePackedInt32String = function(field, value) {
* Writes an array of numbers to the buffer as a packed 64-bit int field.
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
*/
jspb.BinaryWriter.prototype.writePackedInt64 =
- jspb.BinaryWriter.prototype.writePackedVarint_;
+ jspb.BinaryWriter.prototype.writePackedSignedVarint64_;
/**
@@ -1757,7 +1332,7 @@ jspb.BinaryWriter.prototype.writePackedInt64String =
var bookmark = this.beginDelimited_(field);
for (var i = 0; i < value.length; i++) {
var num = jspb.arith.Int64.fromString(value[i]);
- this.rawWriteVarintFromNum(num);
+ this.encoder_.writeSplitVarint64(num.lo, num.hi);
}
this.endDelimited_(bookmark);
};
@@ -1765,15 +1340,8 @@ jspb.BinaryWriter.prototype.writePackedInt64String =
/**
* Writes an array numbers to the buffer as a packed unsigned 32-bit int field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
*/
jspb.BinaryWriter.prototype.writePackedUint32 =
jspb.BinaryWriter.prototype.writePackedUnsignedVarint32_;
@@ -1790,7 +1358,7 @@ jspb.BinaryWriter.prototype.writePackedUint32String =
if (value == null || !value.length) return;
var bookmark = this.beginDelimited_(field);
for (var i = 0; i < value.length; i++) {
- this.rawWriteUnsignedVarint32(parseInt(value[i], 10));
+ this.encoder_.writeUnsignedVarint32(parseInt(value[i], 10));
}
this.endDelimited_(bookmark);
};
@@ -1798,18 +1366,11 @@ jspb.BinaryWriter.prototype.writePackedUint32String =
/**
* Writes an array numbers to the buffer as a packed unsigned 64-bit int field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
*/
jspb.BinaryWriter.prototype.writePackedUint64 =
- jspb.BinaryWriter.prototype.writePackedVarint_;
+ jspb.BinaryWriter.prototype.writePackedUnsignedVarint64_;
/**
@@ -1824,7 +1385,7 @@ jspb.BinaryWriter.prototype.writePackedUint64String =
var bookmark = this.beginDelimited_(field);
for (var i = 0; i < value.length; i++) {
var num = jspb.arith.UInt64.fromString(value[i]);
- this.rawWriteVarintFromNum(num);
+ this.encoder_.writeSplitVarint64(num.lo, num.hi);
}
this.endDelimited_(bookmark);
};
@@ -1832,267 +1393,154 @@ jspb.BinaryWriter.prototype.writePackedUint64String =
/**
* Writes an array numbers to the buffer as a packed signed 32-bit int field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
*/
jspb.BinaryWriter.prototype.writePackedSint32 =
- jspb.BinaryWriter.prototype.writePackedZigzag_;
+ jspb.BinaryWriter.prototype.writePackedZigzag32_;
/**
* Writes an array numbers to the buffer as a packed signed 64-bit int field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
*/
jspb.BinaryWriter.prototype.writePackedSint64 =
- jspb.BinaryWriter.prototype.writePackedZigzag_;
+ jspb.BinaryWriter.prototype.writePackedZigzag64_;
/**
* Writes an array of numbers to the buffer as a packed fixed32 field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
- */
-jspb.BinaryWriter.prototype.writePackedFixed32 =
- function(field, value, opt_buffer, opt_start, opt_end) {
- if (value != null && value.length) {
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
- this.rawWriteUnsignedVarint32(value.length * 4);
- for (var i = 0; i < value.length; i++) {
- this.rawWriteUint32(value[i]);
- }
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+ */
+jspb.BinaryWriter.prototype.writePackedFixed32 = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length * 4);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeUint32(value[i]);
}
};
/**
* Writes an array of numbers to the buffer as a packed fixed64 field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
- */
-jspb.BinaryWriter.prototype.writePackedFixed64 =
- function(field, value, opt_buffer, opt_start, opt_end) {
- if (value != null && value.length) {
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
- this.rawWriteUnsignedVarint32(value.length * 8);
- for (var i = 0; i < value.length; i++) {
- this.rawWriteUint64(value[i]);
- }
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+ */
+jspb.BinaryWriter.prototype.writePackedFixed64 = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length * 8);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeUint64(value[i]);
}
};
/**
* Writes an array of numbers to the buffer as a packed sfixed32 field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
- */
-jspb.BinaryWriter.prototype.writePackedSfixed32 =
- function(field, value, opt_buffer, opt_start, opt_end) {
- if (value != null && value.length) {
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
- this.rawWriteUnsignedVarint32(value.length * 4);
- for (var i = 0; i < value.length; i++) {
- this.rawWriteInt32(value[i]);
- }
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+ */
+jspb.BinaryWriter.prototype.writePackedSfixed32 = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length * 4);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeInt32(value[i]);
}
};
/**
* Writes an array of numbers to the buffer as a packed sfixed64 field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
- */
-jspb.BinaryWriter.prototype.writePackedSfixed64 =
- function(field, value, opt_buffer, opt_start, opt_end) {
- if (value != null) {
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
- this.rawWriteUnsignedVarint32(value.length * 8);
- for (var i = 0; i < value.length; i++) {
- this.rawWriteInt64(value[i]);
- }
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+ */
+jspb.BinaryWriter.prototype.writePackedSfixed64 = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length * 8);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeInt64(value[i]);
}
};
/**
* Writes an array of numbers to the buffer as a packed float field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
- */
-jspb.BinaryWriter.prototype.writePackedFloat =
- function(field, value, opt_buffer, opt_start, opt_end) {
- if (value != null && value.length) {
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
- this.rawWriteUnsignedVarint32(value.length * 4);
- for (var i = 0; i < value.length; i++) {
- this.rawWriteFloat(value[i]);
- }
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+ */
+jspb.BinaryWriter.prototype.writePackedFloat = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length * 4);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeFloat(value[i]);
}
};
/**
* Writes an array of numbers to the buffer as a packed double field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
- */
-jspb.BinaryWriter.prototype.writePackedDouble =
- function(field, value, opt_buffer, opt_start, opt_end) {
- if (value != null && value.length) {
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
- this.rawWriteUnsignedVarint32(value.length * 8);
- for (var i = 0; i < value.length; i++) {
- this.rawWriteDouble(value[i]);
- }
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+ */
+jspb.BinaryWriter.prototype.writePackedDouble = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length * 8);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeDouble(value[i]);
}
};
/**
* Writes an array of booleans to the buffer as a packed bool field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<boolean>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
- */
-jspb.BinaryWriter.prototype.writePackedBool =
- function(field, value, opt_buffer, opt_start, opt_end) {
- if (value != null && value.length) {
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
- this.rawWriteUnsignedVarint32(value.length);
- for (var i = 0; i < value.length; i++) {
- this.rawWriteBool(value[i]);
- }
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+ */
+jspb.BinaryWriter.prototype.writePackedBool = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeBool(value[i]);
}
};
/**
* Writes an array of enums to the buffer as a packed enum field.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<number>} value The array of ints to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
*/
-jspb.BinaryWriter.prototype.writePackedEnum =
- function(field, value, opt_buffer, opt_start, opt_end) {
- if (value != null && value.length) {
- var bookmark = this.beginDelimited_(field);
- for (var i = 0; i < value.length; i++) {
- this.rawWriteEnum(value[i]);
- }
- this.endDelimited_(bookmark);
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+jspb.BinaryWriter.prototype.writePackedEnum = function(field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeEnum(value[i]);
}
+ this.endDelimited_(bookmark);
};
/**
* Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
* the buffer.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<string>} value The array of hashes to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
- */
-jspb.BinaryWriter.prototype.writePackedFixedHash64 =
- function(field, value, opt_buffer, opt_start, opt_end) {
- if (value != null && value.length) {
- this.rawWriteFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
- this.rawWriteUnsignedVarint32(value.length * 8);
- for (var i = 0; i < value.length; i++) {
- this.rawWriteFixedHash64(value[i]);
- }
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+ */
+jspb.BinaryWriter.prototype.writePackedFixedHash64 = function(field, value) {
+ if (value == null || !value.length) return;
+ this.writeFieldHeader_(field, jspb.BinaryConstants.WireType.DELIMITED);
+ this.encoder_.writeUnsignedVarint32(value.length * 8);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeFixedHash64(value[i]);
}
};
@@ -2100,25 +1548,14 @@ jspb.BinaryWriter.prototype.writePackedFixedHash64 =
/**
* Writes a 64-bit hash string field (8 characters @ 8 bits of data each) to
* the buffer.
- *
- * If 'value' is null, this method will try and copy the pre-serialized value
- * in 'opt_buffer' if present.
- *
* @param {number} field The field number.
* @param {?Array.<string>} value The array of hashes to write.
- * @param {?Uint8Array=} opt_buffer A buffer containing pre-packed values.
- * @param {?number=} opt_start The starting point in the above buffer.
- * @param {?number=} opt_end The ending point in the above buffer.
*/
-jspb.BinaryWriter.prototype.writePackedVarintHash64 =
- function(field, value, opt_buffer, opt_start, opt_end) {
- if (value != null && value.length) {
- var bookmark = this.beginDelimited_(field);
- for (var i = 0; i < value.length; i++) {
- this.rawWriteVarintHash64(value[i]);
- }
- this.endDelimited_(bookmark);
- } else if ((opt_buffer != null) && (opt_start != null) && (opt_end != null)) {
- this.rawWriteByteRange(opt_buffer, opt_start, opt_end);
+jspb.BinaryWriter.prototype.writePackedVarintHash64 = function(field, value) {
+ if (value == null || !value.length) return;
+ var bookmark = this.beginDelimited_(field);
+ for (var i = 0; i < value.length; i++) {
+ this.encoder_.writeVarintHash64(value[i]);
}
+ this.endDelimited_(bookmark);
};
diff --git a/js/debug.js b/js/debug.js
index 48389118..3701a095 100644
--- a/js/debug.js
+++ b/js/debug.js
@@ -68,7 +68,7 @@ jspb.debug.dump = function(message) {
* Recursively introspects a message and the values its getters return to
* make a best effort in creating a human readable representation of the
* message.
- * @param {*} thing A jspb.Message, Array or primitive type to dump.
+ * @param {?} thing A jspb.Message, Array or primitive type to dump.
* @return {*}
* @private
*/
diff --git a/js/debug_test.js b/js/debug_test.js
index d7bf3768..01cbf891 100644
--- a/js/debug_test.js
+++ b/js/debug_test.js
@@ -41,6 +41,7 @@ goog.require('proto.jspb.test.IsExtension');
goog.require('proto.jspb.test.Simple1');
+
describe('debugTest', function() {
it('testSimple1', function() {
if (COMPILED) {
diff --git a/js/message.js b/js/message.js
index cef9aefd..813e6b8c 100644
--- a/js/message.js
+++ b/js/message.js
@@ -39,8 +39,8 @@ goog.provide('jspb.Message');
goog.require('goog.array');
goog.require('goog.asserts');
+goog.require('goog.crypt.base64');
goog.require('goog.json');
-goog.require('goog.object');
// Not needed in compilation units that have no protos with xids.
goog.forwardDeclare('xid.String');
@@ -120,6 +120,14 @@ jspb.ExtensionFieldInfo = function(fieldNumber, fieldName, ctor, toObjectFn,
/**
+ * @return {boolean} Does this field represent a sub Message?
+ */
+jspb.ExtensionFieldInfo.prototype.isMessageType = function() {
+ return !!this.ctor;
+};
+
+
+/**
* Base class for all JsPb messages.
* @constructor
* @struct
@@ -166,6 +174,14 @@ goog.define('jspb.Message.MINIMIZE_MEMORY_ALLOCATIONS', COMPILED);
/**
+ * Does this browser support Uint8Aray typed arrays?
+ * @type {boolean}
+ * @private
+ */
+jspb.Message.SUPPORTS_UINT8ARRAY_ = (typeof Uint8Array == 'function');
+
+
+/**
* The internal data array.
* @type {!Array}
* @protected
@@ -211,6 +227,14 @@ jspb.Message.prototype.messageId_;
/**
+ * Repeated float or double fields which have been converted to include only
+ * numbers and not strings holding "NaN", "Infinity" and "-Infinity".
+ * @private {!Object<number,boolean>|undefined}
+ */
+jspb.Message.prototype.convertedFloatingPointFields_;
+
+
+/**
* The xid of this proto type (The same for all instances of a proto). Provides
* a way to identify a proto by stable obfuscated name.
* @see {xid}.
@@ -284,6 +308,8 @@ jspb.Message.initialize = function(
msg.arrayIndexOffset_ = messageId === 0 ? -1 : 0;
msg.array = data;
jspb.Message.materializeExtensionObject_(msg, suggestedPivot);
+ msg.convertedFloatingPointFields_ = {};
+
if (repeatedFields) {
for (var i = 0; i < repeatedFields.length; i++) {
var fieldNumber = repeatedFields[i];
@@ -419,8 +445,9 @@ jspb.Message.toObjectList = function(field, toObjectFn, opt_includeInstance) {
* @param {!jspb.Message} proto The proto whose extensions to convert.
* @param {!Object} obj The Soy object to add converted extension data to.
* @param {!Object} extensions The proto class' registered extensions.
- * @param {function(jspb.ExtensionFieldInfo) : *} getExtensionFn The proto
- * class' getExtension function. Passed for effective dead code removal.
+ * @param {function(this:?, jspb.ExtensionFieldInfo) : *} getExtensionFn
+ * The proto class' getExtension function. Passed for effective dead code
+ * removal.
* @param {boolean=} opt_includeInstance Whether to include the JSPB instance
* for transitional soy proto support: http://goto/soy-param-migration
*/
@@ -472,7 +499,7 @@ jspb.Message.serializeBinaryExtensions = function(proto, writer, extensions,
}
var value = getExtensionFn.call(proto, fieldInfo);
if (value) {
- if (fieldInfo.ctor) { // is this a message type?
+ if (fieldInfo.isMessageType()) {
// If the message type of the extension was generated without binary
// support, there may not be a binary message serializer function, and
// we can't know when we codegen the extending message that the extended
@@ -517,8 +544,7 @@ jspb.Message.readBinaryExtension = function(msg, reader, extensions,
}
var value;
- if (fieldInfo.ctor) {
- // Message type.
+ if (fieldInfo.isMessageType()) {
value = new fieldInfo.ctor();
fieldInfo.binaryReaderFn.call(
reader, value, fieldInfo.binaryMessageDeserializeFn);
@@ -567,6 +593,130 @@ jspb.Message.getField = function(msg, fieldNumber) {
/**
+ * Gets the value of an optional float or double field.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @return {?number|undefined} The field's value.
+ * @protected
+ */
+jspb.Message.getOptionalFloatingPointField = function(msg, fieldNumber) {
+ var value = jspb.Message.getField(msg, fieldNumber);
+ // Converts "NaN", "Infinity" and "-Infinity" to their corresponding numbers.
+ return value == null ? value : +value;
+};
+
+
+/**
+ * Gets the value of a repeated float or double field.
+ * @param {!jspb.Message} msg A jspb proto.
+ * @param {number} fieldNumber The field number.
+ * @return {!Array<number>} The field's value.
+ * @protected
+ */
+jspb.Message.getRepeatedFloatingPointField = function(msg, fieldNumber) {
+ var values = jspb.Message.getField(msg, fieldNumber);
+ if (!msg.convertedFloatingPointFields_) {
+ msg.convertedFloatingPointFields_ = {};
+ }
+ if (!msg.convertedFloatingPointFields_[fieldNumber]) {
+ for (var i = 0; i < values.length; i++) {
+ // Converts "NaN", "Infinity" and "-Infinity" to their corresponding
+ // numbers.
+ values[i] = +values[i];
+ }
+ msg.convertedFloatingPointFields_[fieldNumber] = true;
+ }
+ return /** @type {!Array<number>} */ (values);
+};
+
+
+/**
+ * Coerce a 'bytes' field to a base 64 string.
+ * @param {string|Uint8Array|null} value
+ * @return {?string} The field's coerced value.
+ */
+jspb.Message.bytesAsB64 = function(value) {
+ if (value == null || goog.isString(value)) {
+ return value;
+ }
+ if (jspb.Message.SUPPORTS_UINT8ARRAY_ && value instanceof Uint8Array) {
+ return goog.crypt.base64.encodeByteArray(value);
+ }
+ goog.asserts.fail('Cannot coerce to b64 string: ' + goog.typeOf(value));
+ return null;
+};
+
+
+/**
+ * Coerce a 'bytes' field to a Uint8Array byte buffer.
+ * Note that Uint8Array is not supported on IE versions before 10 nor on Opera
+ * Mini. @see http://caniuse.com/Uint8Array
+ * @param {string|Uint8Array|null} value
+ * @return {?Uint8Array} The field's coerced value.
+ */
+jspb.Message.bytesAsU8 = function(value) {
+ if (value == null || value instanceof Uint8Array) {
+ return value;
+ }
+ if (goog.isString(value)) {
+ return goog.crypt.base64.decodeStringToUint8Array(value);
+ }
+ goog.asserts.fail('Cannot coerce to Uint8Array: ' + goog.typeOf(value));
+ return null;
+};
+
+
+/**
+ * Coerce a repeated 'bytes' field to an array of base 64 strings.
+ * Note: the returned array should be treated as immutable.
+ * @param {!Array<string>|!Array<!Uint8Array>} value
+ * @return {!Array<string?>} The field's coerced value.
+ */
+jspb.Message.bytesListAsB64 = function(value) {
+ jspb.Message.assertConsistentTypes_(value);
+ if (!value.length || goog.isString(value[0])) {
+ return /** @type {!Array<string>} */ (value);
+ }
+ return goog.array.map(value, jspb.Message.bytesAsB64);
+};
+
+
+/**
+ * Coerce a repeated 'bytes' field to an array of Uint8Array byte buffers.
+ * Note: the returned array should be treated as immutable.
+ * Note that Uint8Array is not supported on IE versions before 10 nor on Opera
+ * Mini. @see http://caniuse.com/Uint8Array
+ * @param {!Array<string>|!Array<!Uint8Array>} value
+ * @return {!Array<Uint8Array?>} The field's coerced value.
+ */
+jspb.Message.bytesListAsU8 = function(value) {
+ jspb.Message.assertConsistentTypes_(value);
+ if (!value.length || value[0] instanceof Uint8Array) {
+ return /** @type {!Array<!Uint8Array>} */ (value);
+ }
+ return goog.array.map(value, jspb.Message.bytesAsU8);
+};
+
+
+/**
+ * Asserts that all elements of an array are of the same type.
+ * @param {Array?} array The array to test.
+ * @private
+ */
+jspb.Message.assertConsistentTypes_ = function(array) {
+ if (goog.DEBUG && array && array.length > 1) {
+ var expected = goog.typeOf(array[0]);
+ goog.array.forEach(array, function(e) {
+ if (goog.typeOf(e) != expected) {
+ goog.asserts.fail('Inconsistent type in JSPB repeated field array. ' +
+ 'Got ' + goog.typeOf(e) + ' expected ' + expected);
+ }
+ });
+ }
+};
+
+
+/**
* Gets the value of a non-extension primitive field, with proto3 (non-nullable
* primitives) semantics. Returns `defaultValue` if the field is not otherwise
* set.
@@ -841,7 +991,7 @@ jspb.Message.prototype.getExtension = function(fieldInfo) {
}
var fieldNumber = fieldInfo.fieldIndex;
if (fieldInfo.isRepeated) {
- if (fieldInfo.ctor) {
+ if (fieldInfo.isMessageType()) {
if (!this.wrappers_[fieldNumber]) {
this.wrappers_[fieldNumber] =
goog.array.map(this.extensionObject_[fieldNumber] || [],
@@ -854,7 +1004,7 @@ jspb.Message.prototype.getExtension = function(fieldInfo) {
return this.extensionObject_[fieldNumber];
}
} else {
- if (fieldInfo.ctor) {
+ if (fieldInfo.isMessageType()) {
if (!this.wrappers_[fieldNumber] && this.extensionObject_[fieldNumber]) {
this.wrappers_[fieldNumber] = new fieldInfo.ctor(
/** @type {Array|undefined} */ (
@@ -871,7 +1021,8 @@ jspb.Message.prototype.getExtension = function(fieldInfo) {
/**
* Sets the value of the extension field in the extended object.
* @param {jspb.ExtensionFieldInfo} fieldInfo Specifies the field to set.
- * @param {jspb.Message|string|number|boolean|Array} value The value to set.
+ * @param {jspb.Message|string|Uint8Array|number|boolean|Array?} value The value
+ * to set.
*/
jspb.Message.prototype.setExtension = function(fieldInfo, value) {
if (!this.wrappers_) {
@@ -881,7 +1032,7 @@ jspb.Message.prototype.setExtension = function(fieldInfo, value) {
var fieldNumber = fieldInfo.fieldIndex;
if (fieldInfo.isRepeated) {
value = value || [];
- if (fieldInfo.ctor) {
+ if (fieldInfo.isMessageType()) {
this.wrappers_[fieldNumber] = value;
this.extensionObject_[fieldNumber] = goog.array.map(
/** @type {Array<jspb.Message>} */ (value), function(msg) {
@@ -891,7 +1042,7 @@ jspb.Message.prototype.setExtension = function(fieldInfo, value) {
this.extensionObject_[fieldNumber] = value;
}
} else {
- if (fieldInfo.ctor) {
+ if (fieldInfo.isMessageType()) {
this.wrappers_[fieldNumber] = value;
this.extensionObject_[fieldNumber] = value ? value.toArray() : value;
} else {
@@ -958,49 +1109,110 @@ jspb.Message.equals = function(m1, m2) {
/**
+ * Compares two message extension fields recursively.
+ * @param {!Object} extension1 The first field.
+ * @param {!Object} extension2 The second field.
+ * @return {boolean} true if the extensions are null/undefined, or otherwise
+ * equal.
+ */
+jspb.Message.compareExtensions = function(extension1, extension2) {
+ extension1 = extension1 || {};
+ extension2 = extension2 || {};
+
+ var keys = {};
+ for (var name in extension1) {
+ keys[name] = 0;
+ }
+ for (var name in extension2) {
+ keys[name] = 0;
+ }
+ for (name in keys) {
+ if (!jspb.Message.compareFields(extension1[name], extension2[name])) {
+ return false;
+ }
+ }
+ return true;
+};
+
+
+/**
* Compares two message fields recursively.
* @param {*} field1 The first field.
* @param {*} field2 The second field.
* @return {boolean} true if the fields are null/undefined, or otherwise equal.
*/
jspb.Message.compareFields = function(field1, field2) {
- if (goog.isObject(field1) && goog.isObject(field2)) {
- var keys = {}, name, extensionObject1, extensionObject2;
- for (name in field1) {
- field1.hasOwnProperty(name) && (keys[name] = 0);
- }
- for (name in field2) {
- field2.hasOwnProperty(name) && (keys[name] = 0);
+ // If the fields are trivially equal, they're equal.
+ if (field1 == field2) return true;
+
+ // If the fields aren't trivially equal and one of them isn't an object,
+ // they can't possibly be equal.
+ if (!goog.isObject(field1) || !goog.isObject(field2)) {
+ return false;
+ }
+
+ // We have two objects. If they're different types, they're not equal.
+ field1 = /** @type {!Object} */(field1);
+ field2 = /** @type {!Object} */(field2);
+ if (field1.constructor != field2.constructor) return false;
+
+ // If both are Uint8Arrays, compare them element-by-element.
+ if (jspb.Message.SUPPORTS_UINT8ARRAY_ && field1.constructor === Uint8Array) {
+ var bytes1 = /** @type {!Uint8Array} */(field1);
+ var bytes2 = /** @type {!Uint8Array} */(field2);
+ if (bytes1.length != bytes2.length) return false;
+ for (var i = 0; i < bytes1.length; i++) {
+ if (bytes1[i] != bytes2[i]) return false;
}
- for (name in keys) {
- var val1 = field1[name], val2 = field2[name];
- if (goog.isObject(val1) && !goog.isArray(val1)) {
- if (extensionObject1 !== undefined) {
- throw new Error('invalid jspb state');
- }
- extensionObject1 = goog.object.isEmpty(val1) ? undefined : val1;
+ return true;
+ }
+
+ // If they're both Arrays, compare them element by element except for the
+ // optional extension objects at the end, which we compare separately.
+ if (field1.constructor === Array) {
+ var extension1 = undefined;
+ var extension2 = undefined;
+
+ var length = Math.max(field1.length, field2.length);
+ for (var i = 0; i < length; i++) {
+ var val1 = field1[i];
+ var val2 = field2[i];
+
+ if (val1 && (val1.constructor == Object)) {
+ goog.asserts.assert(extension1 === undefined);
+ goog.asserts.assert(i === field1.length - 1);
+ extension1 = val1;
val1 = undefined;
}
- if (goog.isObject(val2) && !goog.isArray(val2)) {
- if (extensionObject2 !== undefined) {
- throw new Error('invalid jspb state');
- }
- extensionObject2 = goog.object.isEmpty(val2) ? undefined : val2;
+
+ if (val2 && (val2.constructor == Object)) {
+ goog.asserts.assert(extension2 === undefined);
+ goog.asserts.assert(i === field2.length - 1);
+ extension2 = val2;
val2 = undefined;
}
+
if (!jspb.Message.compareFields(val1, val2)) {
return false;
}
}
- if (extensionObject1 || extensionObject2) {
- return jspb.Message.compareFields(extensionObject1, extensionObject2);
+
+ if (extension1 || extension2) {
+ extension1 = extension1 || {};
+ extension2 = extension2 || {};
+ return jspb.Message.compareExtensions(extension1, extension2);
}
+
return true;
}
- // Primitive fields, null and undefined compare as equal.
- // This also forces booleans and 0/1 to compare as equal to ensure
- // compatibility with the jspb serializer.
- return field1 == field2;
+
+ // If they're both plain Objects (i.e. extensions), compare them as
+ // extensions.
+ if (field1.constructor === Object) {
+ return jspb.Message.compareExtensions(field1, field2);
+ }
+
+ throw new Error('Invalid type in JSPB array');
};
diff --git a/js/message_test.js b/js/message_test.js
index f572188e..01add5f1 100644
--- a/js/message_test.js
+++ b/js/message_test.js
@@ -53,6 +53,8 @@ goog.require('proto.jspb.test.Complex');
goog.require('proto.jspb.test.DefaultValues');
goog.require('proto.jspb.test.Empty');
goog.require('proto.jspb.test.EnumContainer');
+goog.require('proto.jspb.test.floatingMsgField');
+goog.require('proto.jspb.test.FloatingPointFields');
goog.require('proto.jspb.test.floatingStrField');
goog.require('proto.jspb.test.HasExtensions');
goog.require('proto.jspb.test.IndirectExtension');
@@ -60,7 +62,6 @@ goog.require('proto.jspb.test.IsExtension');
goog.require('proto.jspb.test.OptionalFields');
goog.require('proto.jspb.test.OuterEnum');
goog.require('proto.jspb.test.OuterMessage.Complex');
-goog.require('proto.jspb.test.simple1');
goog.require('proto.jspb.test.Simple1');
goog.require('proto.jspb.test.Simple2');
goog.require('proto.jspb.test.SpecialCases');
@@ -74,7 +75,7 @@ goog.require('proto.jspb.test.TestReservedNamesExtension');
// CommonJS-LoadFromFile: test2_pb proto.jspb.test
goog.require('proto.jspb.test.ExtensionMessage');
goog.require('proto.jspb.test.TestExtensionsMessage');
-goog.require('proto.jspb.test.floatingMsgField');
+
@@ -98,12 +99,6 @@ describe('Message test suite', function() {
assertEquals('some_bytes', data.getBytesField());
});
- it('testNestedMessage', function() {
- var msg = new proto.jspb.test.OuterMessage.Complex();
- msg.setInnerComplexField(5);
- assertObjectEquals({innerComplexField: 5}, msg.toObject());
- });
-
it('testComplexConversion', function() {
var data1 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1];
var data2 = ['a',,, [, 11], [[, 22], [, 33]],, ['s1', 's2'],, 1];
@@ -160,6 +155,13 @@ describe('Message test suite', function() {
});
+ it('testNestedComplexMessage', function() {
+ // Instantiate the message and set a unique field, just to ensure that we
+ // are not getting jspb.test.Complex instead.
+ var msg = new proto.jspb.test.OuterMessage.Complex();
+ msg.setInnerComplexField(5);
+ });
+
it('testSpecialCases', function() {
// Note: Some property names are reserved in JavaScript.
// These names are converted to the Js property named pb_<reserved_name>.
@@ -544,12 +546,6 @@ describe('Message test suite', function() {
extendable.setExtension(proto.jspb.test.IndirectExtension.str, null);
assertNull(extendable.getExtension(proto.jspb.test.IndirectExtension.str));
- // These assertions will only work properly in uncompiled mode.
- // Extension fields defined on proto2 Descriptor messages are filtered out.
-
- // TODO(haberman): codegen changes to properly ignore descriptor.proto
- // extensions need to be merged from google3.
- // assertUndefined(proto.jspb.test.IsExtension['simpleOption']);
// Extension fields with jspb.ignore = true are ignored.
assertUndefined(proto.jspb.test.IndirectExtension['ignored']);
@@ -907,7 +903,7 @@ describe('Message test suite', function() {
message.getDefaultOneofACase());
message =
- new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567,890));
+ new proto.jspb.test.TestMessageWithOneof(new Array(9).concat(567, 890));
assertEquals(1234, message.getAone());
assertEquals(890, message.getAtwo());
assertEquals(
@@ -936,7 +932,7 @@ describe('Message test suite', function() {
message.getDefaultOneofBCase());
message = new proto.jspb.test.TestMessageWithOneof(
- new Array(11).concat(567,890));
+ new Array(11).concat(567, 890));
assertUndefined(message.getBone());
assertEquals(890, message.getBtwo());
assertEquals(
@@ -989,4 +985,26 @@ describe('Message test suite', function() {
assertEquals('y', array[4]);
});
+ it('testFloatingPointFieldsSupportNan', function() {
+ var assertNan = function(x) {
+ assertTrue('Expected ' + x + ' (' + goog.typeOf(x) + ') to be NaN.',
+ goog.isNumber(x) && isNaN(x));
+ };
+
+ var message = new proto.jspb.test.FloatingPointFields([
+ 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN',
+ 'NaN', 'NaN', ['NaN', 'NaN'], 'NaN'
+ ]);
+ assertNan(message.getOptionalFloatField());
+ assertNan(message.getRequiredFloatField());
+ assertNan(message.getRepeatedFloatFieldList()[0]);
+ assertNan(message.getRepeatedFloatFieldList()[1]);
+ assertNan(message.getDefaultFloatField());
+ assertNan(message.getOptionalDoubleField());
+ assertNan(message.getRequiredDoubleField());
+ assertNan(message.getRepeatedDoubleFieldList()[0]);
+ assertNan(message.getRepeatedDoubleFieldList()[1]);
+ assertNan(message.getDefaultDoubleField());
+ });
+
});
diff --git a/js/proto3_test.js b/js/proto3_test.js
index f8868716..4dd7790f 100644
--- a/js/proto3_test.js
+++ b/js/proto3_test.js
@@ -28,6 +28,7 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+goog.require('goog.crypt.base64');
goog.require('goog.testing.asserts');
// CommonJS-LoadFromFile: testbinary_pb proto.jspb.test
@@ -37,31 +38,30 @@ goog.require('proto.jspb.test.ForeignMessage');
goog.require('proto.jspb.test.Proto3Enum');
goog.require('proto.jspb.test.TestProto3');
+
+var BYTES = new Uint8Array([1, 2, 8, 9]);
+var BYTES_B64 = goog.crypt.base64.encodeByteArray(BYTES);
+
+
/**
- * Helper: compare a bytes field to a string with codepoints 0--255.
+ * Helper: compare a bytes field to an expected value
* @param {Uint8Array|string} arr
- * @param {string} str
+ * @param {Uint8Array} expected
* @return {boolean}
*/
-function bytesCompare(arr, str) {
- if (arr.length != str.length) {
+function bytesCompare(arr, expected) {
+ if (goog.isString(arr)) {
+ arr = goog.crypt.base64.decodeStringToUint8Array(arr);
+ }
+ if (arr.length != expected.length) {
return false;
}
- if (typeof arr == 'string') {
- for (var i = 0; i < arr.length; i++) {
- if (arr.charCodeAt(i) != str.charCodeAt(i)) {
- return false;
- }
+ for (var i = 0; i < arr.length; i++) {
+ if (arr[i] != expected[i]) {
+ return false;
}
- return true;
- } else {
- for (var i = 0; i < arr.length; i++) {
- if (arr[i] != str.charCodeAt(i)) {
- return false;
- }
- }
- return true;
}
+ return true;
}
@@ -86,13 +86,17 @@ describe('proto3Test', function() {
assertEquals(msg.getOptionalDouble(), 0);
assertEquals(msg.getOptionalString(), '');
- // If/when we change bytes fields to return Uint8Array, we'll want to switch
- // to this assertion instead:
- //assertEquals(msg.getOptionalBytes() instanceof Uint8Array, true);
+ // TODO(b/26173701): when we change bytes fields default getter to return
+ // Uint8Array, we'll want to switch this assertion to match the u8 case.
assertEquals(typeof msg.getOptionalBytes(), 'string');
-
+ assertEquals(msg.getOptionalBytes_asU8() instanceof Uint8Array, true);
+ assertEquals(typeof msg.getOptionalBytes_asB64(), 'string');
assertEquals(msg.getOptionalBytes().length, 0);
- assertEquals(msg.getOptionalForeignEnum(), proto.jspb.test.Proto3Enum.PROTO3_FOO);
+ assertEquals(msg.getOptionalBytes_asU8().length, 0);
+ assertEquals(msg.getOptionalBytes_asB64(), '');
+
+ assertEquals(msg.getOptionalForeignEnum(),
+ proto.jspb.test.Proto3Enum.PROTO3_FOO);
assertEquals(msg.getOptionalForeignMessage(), undefined);
assertEquals(msg.getOptionalForeignMessage(), undefined);
@@ -136,7 +140,7 @@ describe('proto3Test', function() {
msg.setOptionalDouble(-1.5);
msg.setOptionalBool(true);
msg.setOptionalString('hello world');
- msg.setOptionalBytes('bytes');
+ msg.setOptionalBytes(BYTES);
var submsg = new proto.jspb.test.ForeignMessage();
submsg.setC(16);
msg.setOptionalForeignMessage(submsg);
@@ -156,7 +160,7 @@ describe('proto3Test', function() {
msg.setRepeatedDoubleList([-1.5]);
msg.setRepeatedBoolList([true]);
msg.setRepeatedStringList(['hello world']);
- msg.setRepeatedBytesList(['bytes']);
+ msg.setRepeatedBytesList([BYTES]);
submsg = new proto.jspb.test.ForeignMessage();
submsg.setC(1000);
msg.setRepeatedForeignMessageList([submsg]);
@@ -181,7 +185,7 @@ describe('proto3Test', function() {
assertEquals(msg.getOptionalDouble(), -1.5);
assertEquals(msg.getOptionalBool(), true);
assertEquals(msg.getOptionalString(), 'hello world');
- assertEquals(true, bytesCompare(msg.getOptionalBytes(), 'bytes'));
+ assertEquals(true, bytesCompare(msg.getOptionalBytes(), BYTES));
assertEquals(msg.getOptionalForeignMessage().getC(), 16);
assertEquals(msg.getOptionalForeignEnum(),
proto.jspb.test.Proto3Enum.PROTO3_BAR);
@@ -201,7 +205,7 @@ describe('proto3Test', function() {
assertElementsEquals(msg.getRepeatedBoolList(), [true]);
assertElementsEquals(msg.getRepeatedStringList(), ['hello world']);
assertEquals(msg.getRepeatedBytesList().length, 1);
- assertEquals(true, bytesCompare(msg.getRepeatedBytesList()[0], 'bytes'));
+ assertEquals(true, bytesCompare(msg.getRepeatedBytesList()[0], BYTES));
assertEquals(msg.getRepeatedForeignMessageList().length, 1);
assertEquals(msg.getRepeatedForeignMessageList()[0].getC(), 1000);
assertElementsEquals(msg.getRepeatedForeignEnumList(),
@@ -242,11 +246,12 @@ describe('proto3Test', function() {
assertEquals(msg.getOneofString(), 'hello');
assertEquals(msg.getOneofBytes(), undefined);
- msg.setOneofBytes('\u00FF\u00FF');
+ msg.setOneofBytes(goog.crypt.base64.encodeString('\u00FF\u00FF'));
assertEquals(msg.getOneofUint32(), undefined);
assertEquals(msg.getOneofForeignMessage(), undefined);
assertEquals(msg.getOneofString(), undefined);
- assertEquals(msg.getOneofBytes(), '\u00FF\u00FF');
+ assertEquals(msg.getOneofBytes_asB64(),
+ goog.crypt.base64.encodeString('\u00FF\u00FF'));
});
@@ -267,7 +272,7 @@ describe('proto3Test', function() {
msg.setOptionalBool(false);
msg.setOptionalString('hello world');
msg.setOptionalString('');
- msg.setOptionalBytes('\u00FF\u00FF');
+ msg.setOptionalBytes(goog.crypt.base64.encodeString('\u00FF\u00FF'));
msg.setOptionalBytes('');
msg.setOptionalForeignMessage(new proto.jspb.test.ForeignMessage());
msg.setOptionalForeignMessage(null);
@@ -280,4 +285,30 @@ describe('proto3Test', function() {
var serialized = msg.serializeBinary();
assertEquals(0, serialized.length);
});
+
+ /**
+ * Test that base64 string and Uint8Array are interchangeable in bytes fields.
+ */
+ it('testBytesFieldsInterop', function() {
+ var msg = new proto.jspb.test.TestProto3();
+ // Set as a base64 string and check all the getters work.
+ msg.setOptionalBytes(BYTES_B64);
+ assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+
+ // Test binary serialize round trip doesn't break it.
+ msg = proto.jspb.test.TestProto3.deserializeBinary(msg.serializeBinary());
+ assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+
+ msg = new proto.jspb.test.TestProto3();
+ // Set as a Uint8Array and check all the getters work.
+ msg.setOptionalBytes(BYTES);
+ assertTrue(bytesCompare(msg.getOptionalBytes_asU8(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes_asB64(), BYTES));
+ assertTrue(bytesCompare(msg.getOptionalBytes(), BYTES));
+
+ });
});
diff --git a/js/test.proto b/js/test.proto
index 14418ac9..6b9dc891 100644
--- a/js/test.proto
+++ b/js/test.proto
@@ -145,6 +145,17 @@ message DefaultValues {
optional bytes bytes_field = 8 [default="moo"]; // Base64 encoding is "bW9v"
}
+message FloatingPointFields {
+ optional float optional_float_field = 1;
+ required float required_float_field = 2;
+ repeated float repeated_float_field = 3;
+ optional float default_float_field = 4 [default = 2.0];
+ optional double optional_double_field = 5;
+ required double required_double_field = 6;
+ repeated double repeated_double_field = 7;
+ optional double default_double_field = 8 [default = 2.0];
+}
+
message TestClone {
optional string str = 1;
optional Simple1 simple1 = 3;
@@ -216,3 +227,4 @@ message TestMessageWithOneof {
int32 btwo = 13 [default = 1234];
}
}
+