Add dependencies locally
This commit is contained in:
413
deps/protobuf/js/binary/arith.js
vendored
Normal file
413
deps/protobuf/js/binary/arith.js
vendored
Normal file
@ -0,0 +1,413 @@
|
||||
// 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 This file contains helper code used by jspb.utils to
|
||||
* handle 64-bit integer conversion to/from strings.
|
||||
*
|
||||
* @author cfallin@google.com (Chris Fallin)
|
||||
*
|
||||
* TODO(haberman): move this to javascript/closure/math?
|
||||
*/
|
||||
|
||||
goog.provide('jspb.arith.Int64');
|
||||
goog.provide('jspb.arith.UInt64');
|
||||
|
||||
/**
|
||||
* UInt64 implements some 64-bit arithmetic routines necessary for properly
|
||||
* handling 64-bit integer fields. It implements lossless integer arithmetic on
|
||||
* top of JavaScript's number type, which has only 53 bits of precision, by
|
||||
* representing 64-bit integers as two 32-bit halves.
|
||||
*
|
||||
* @param {number} lo The low 32 bits.
|
||||
* @param {number} hi The high 32 bits.
|
||||
* @constructor
|
||||
*/
|
||||
jspb.arith.UInt64 = function(lo, hi) {
|
||||
/**
|
||||
* The low 32 bits.
|
||||
* @public {number}
|
||||
*/
|
||||
this.lo = lo;
|
||||
/**
|
||||
* The high 32 bits.
|
||||
* @public {number}
|
||||
*/
|
||||
this.hi = hi;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Compare two 64-bit numbers. Returns -1 if the first is
|
||||
* less, +1 if the first is greater, or 0 if both are equal.
|
||||
* @param {!jspb.arith.UInt64} other
|
||||
* @return {number}
|
||||
*/
|
||||
jspb.arith.UInt64.prototype.cmp = function(other) {
|
||||
if (this.hi < other.hi || (this.hi == other.hi && this.lo < other.lo)) {
|
||||
return -1;
|
||||
} else if (this.hi == other.hi && this.lo == other.lo) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Right-shift this number by one bit.
|
||||
* @return {!jspb.arith.UInt64}
|
||||
*/
|
||||
jspb.arith.UInt64.prototype.rightShift = function() {
|
||||
var hi = this.hi >>> 1;
|
||||
var lo = (this.lo >>> 1) | ((this.hi & 1) << 31);
|
||||
return new jspb.arith.UInt64(lo >>> 0, hi >>> 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Left-shift this number by one bit.
|
||||
* @return {!jspb.arith.UInt64}
|
||||
*/
|
||||
jspb.arith.UInt64.prototype.leftShift = function() {
|
||||
var lo = this.lo << 1;
|
||||
var hi = (this.hi << 1) | (this.lo >>> 31);
|
||||
return new jspb.arith.UInt64(lo >>> 0, hi >>> 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Test the MSB.
|
||||
* @return {boolean}
|
||||
*/
|
||||
jspb.arith.UInt64.prototype.msb = function() {
|
||||
return !!(this.hi & 0x80000000);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Test the LSB.
|
||||
* @return {boolean}
|
||||
*/
|
||||
jspb.arith.UInt64.prototype.lsb = function() {
|
||||
return !!(this.lo & 1);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Test whether this number is zero.
|
||||
* @return {boolean}
|
||||
*/
|
||||
jspb.arith.UInt64.prototype.zero = function() {
|
||||
return this.lo == 0 && this.hi == 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add two 64-bit numbers to produce a 64-bit number.
|
||||
* @param {!jspb.arith.UInt64} other
|
||||
* @return {!jspb.arith.UInt64}
|
||||
*/
|
||||
jspb.arith.UInt64.prototype.add = function(other) {
|
||||
var lo = ((this.lo + other.lo) & 0xffffffff) >>> 0;
|
||||
var hi =
|
||||
(((this.hi + other.hi) & 0xffffffff) >>> 0) +
|
||||
(((this.lo + other.lo) >= 0x100000000) ? 1 : 0);
|
||||
return new jspb.arith.UInt64(lo >>> 0, hi >>> 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Subtract two 64-bit numbers to produce a 64-bit number.
|
||||
* @param {!jspb.arith.UInt64} other
|
||||
* @return {!jspb.arith.UInt64}
|
||||
*/
|
||||
jspb.arith.UInt64.prototype.sub = function(other) {
|
||||
var lo = ((this.lo - other.lo) & 0xffffffff) >>> 0;
|
||||
var hi =
|
||||
(((this.hi - other.hi) & 0xffffffff) >>> 0) -
|
||||
(((this.lo - other.lo) < 0) ? 1 : 0);
|
||||
return new jspb.arith.UInt64(lo >>> 0, hi >>> 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Multiply two 32-bit numbers to produce a 64-bit number.
|
||||
* @param {number} a The first integer: must be in [0, 2^32-1).
|
||||
* @param {number} b The second integer: must be in [0, 2^32-1).
|
||||
* @return {!jspb.arith.UInt64}
|
||||
*/
|
||||
jspb.arith.UInt64.mul32x32 = function(a, b) {
|
||||
// Directly multiplying two 32-bit numbers may produce up to 64 bits of
|
||||
// precision, thus losing precision because of the 53-bit mantissa of
|
||||
// JavaScript numbers. So we multiply with 16-bit digits (radix 65536)
|
||||
// instead.
|
||||
var aLow = (a & 0xffff);
|
||||
var aHigh = (a >>> 16);
|
||||
var bLow = (b & 0xffff);
|
||||
var bHigh = (b >>> 16);
|
||||
var productLow =
|
||||
// 32-bit result, result bits 0-31, take all 32 bits
|
||||
(aLow * bLow) +
|
||||
// 32-bit result, result bits 16-47, take bottom 16 as our top 16
|
||||
((aLow * bHigh) & 0xffff) * 0x10000 +
|
||||
// 32-bit result, result bits 16-47, take bottom 16 as our top 16
|
||||
((aHigh * bLow) & 0xffff) * 0x10000;
|
||||
var productHigh =
|
||||
// 32-bit result, result bits 32-63, take all 32 bits
|
||||
(aHigh * bHigh) +
|
||||
// 32-bit result, result bits 16-47, take top 16 as our bottom 16
|
||||
((aLow * bHigh) >>> 16) +
|
||||
// 32-bit result, result bits 16-47, take top 16 as our bottom 16
|
||||
((aHigh * bLow) >>> 16);
|
||||
|
||||
// Carry. Note that we actually have up to *two* carries due to addition of
|
||||
// three terms.
|
||||
while (productLow >= 0x100000000) {
|
||||
productLow -= 0x100000000;
|
||||
productHigh += 1;
|
||||
}
|
||||
|
||||
return new jspb.arith.UInt64(productLow >>> 0, productHigh >>> 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Multiply this number by a 32-bit number, producing a 96-bit number, then
|
||||
* truncate the top 32 bits.
|
||||
* @param {number} a The multiplier.
|
||||
* @return {!jspb.arith.UInt64}
|
||||
*/
|
||||
jspb.arith.UInt64.prototype.mul = function(a) {
|
||||
// Produce two parts: at bits 0-63, and 32-95.
|
||||
var lo = jspb.arith.UInt64.mul32x32(this.lo, a);
|
||||
var hi = jspb.arith.UInt64.mul32x32(this.hi, a);
|
||||
// Left-shift hi by 32 bits, truncating its top bits. The parts will then be
|
||||
// aligned for addition.
|
||||
hi.hi = hi.lo;
|
||||
hi.lo = 0;
|
||||
return lo.add(hi);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Divide a 64-bit number by a 32-bit number to produce a
|
||||
* 64-bit quotient and a 32-bit remainder.
|
||||
* @param {number} _divisor
|
||||
* @return {Array<jspb.arith.UInt64>} array of [quotient, remainder],
|
||||
* unless divisor is 0, in which case an empty array is returned.
|
||||
*/
|
||||
jspb.arith.UInt64.prototype.div = function(_divisor) {
|
||||
if (_divisor == 0) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// We perform long division using a radix-2 algorithm, for simplicity (i.e.,
|
||||
// one bit at a time). TODO: optimize to a radix-2^32 algorithm, taking care
|
||||
// to get the variable shifts right.
|
||||
var quotient = new jspb.arith.UInt64(0, 0);
|
||||
var remainder = new jspb.arith.UInt64(this.lo, this.hi);
|
||||
var divisor = new jspb.arith.UInt64(_divisor, 0);
|
||||
var unit = new jspb.arith.UInt64(1, 0);
|
||||
|
||||
// Left-shift the divisor and unit until the high bit of divisor is set.
|
||||
while (!divisor.msb()) {
|
||||
divisor = divisor.leftShift();
|
||||
unit = unit.leftShift();
|
||||
}
|
||||
|
||||
// Perform long division one bit at a time.
|
||||
while (!unit.zero()) {
|
||||
// If divisor < remainder, add unit to quotient and subtract divisor from
|
||||
// remainder.
|
||||
if (divisor.cmp(remainder) <= 0) {
|
||||
quotient = quotient.add(unit);
|
||||
remainder = remainder.sub(divisor);
|
||||
}
|
||||
// Right-shift the divisor and unit.
|
||||
divisor = divisor.rightShift();
|
||||
unit = unit.rightShift();
|
||||
}
|
||||
|
||||
return [quotient, remainder];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Convert a 64-bit number to a string.
|
||||
* @return {string}
|
||||
* @override
|
||||
*/
|
||||
jspb.arith.UInt64.prototype.toString = function() {
|
||||
var result = '';
|
||||
var num = this;
|
||||
while (!num.zero()) {
|
||||
var divResult = num.div(10);
|
||||
var quotient = divResult[0], remainder = divResult[1];
|
||||
result = remainder.lo + result;
|
||||
num = quotient;
|
||||
}
|
||||
if (result == '') {
|
||||
result = '0';
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parse a string into a 64-bit number. Returns `null` on a parse error.
|
||||
* @param {string} s
|
||||
* @return {?jspb.arith.UInt64}
|
||||
*/
|
||||
jspb.arith.UInt64.fromString = function(s) {
|
||||
var result = new jspb.arith.UInt64(0, 0);
|
||||
// optimization: reuse this instance for each digit.
|
||||
var digit64 = new jspb.arith.UInt64(0, 0);
|
||||
for (var i = 0; i < s.length; i++) {
|
||||
if (s[i] < '0' || s[i] > '9') {
|
||||
return null;
|
||||
}
|
||||
var digit = parseInt(s[i], 10);
|
||||
digit64.lo = digit;
|
||||
result = result.mul(10).add(digit64);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Make a copy of the uint64.
|
||||
* @return {!jspb.arith.UInt64}
|
||||
*/
|
||||
jspb.arith.UInt64.prototype.clone = function() {
|
||||
return new jspb.arith.UInt64(this.lo, this.hi);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Int64 is like UInt64, but modifies string conversions to interpret the stored
|
||||
* 64-bit value as a twos-complement-signed integer. It does *not* support the
|
||||
* full range of operations that UInt64 does: only add, subtract, and string
|
||||
* conversions.
|
||||
*
|
||||
* N.B. that multiply and divide routines are *NOT* supported. They will throw
|
||||
* exceptions. (They are not necessary to implement string conversions, which
|
||||
* are the only operations we really need in jspb.)
|
||||
*
|
||||
* @param {number} lo The low 32 bits.
|
||||
* @param {number} hi The high 32 bits.
|
||||
* @constructor
|
||||
*/
|
||||
jspb.arith.Int64 = function(lo, hi) {
|
||||
/**
|
||||
* The low 32 bits.
|
||||
* @public {number}
|
||||
*/
|
||||
this.lo = lo;
|
||||
/**
|
||||
* The high 32 bits.
|
||||
* @public {number}
|
||||
*/
|
||||
this.hi = hi;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Add two 64-bit numbers to produce a 64-bit number.
|
||||
* @param {!jspb.arith.Int64} other
|
||||
* @return {!jspb.arith.Int64}
|
||||
*/
|
||||
jspb.arith.Int64.prototype.add = function(other) {
|
||||
var lo = ((this.lo + other.lo) & 0xffffffff) >>> 0;
|
||||
var hi =
|
||||
(((this.hi + other.hi) & 0xffffffff) >>> 0) +
|
||||
(((this.lo + other.lo) >= 0x100000000) ? 1 : 0);
|
||||
return new jspb.arith.Int64(lo >>> 0, hi >>> 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Subtract two 64-bit numbers to produce a 64-bit number.
|
||||
* @param {!jspb.arith.Int64} other
|
||||
* @return {!jspb.arith.Int64}
|
||||
*/
|
||||
jspb.arith.Int64.prototype.sub = function(other) {
|
||||
var lo = ((this.lo - other.lo) & 0xffffffff) >>> 0;
|
||||
var hi =
|
||||
(((this.hi - other.hi) & 0xffffffff) >>> 0) -
|
||||
(((this.lo - other.lo) < 0) ? 1 : 0);
|
||||
return new jspb.arith.Int64(lo >>> 0, hi >>> 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Make a copy of the int64.
|
||||
* @return {!jspb.arith.Int64}
|
||||
*/
|
||||
jspb.arith.Int64.prototype.clone = function() {
|
||||
return new jspb.arith.Int64(this.lo, this.hi);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Convert a 64-bit number to a string.
|
||||
* @return {string}
|
||||
* @override
|
||||
*/
|
||||
jspb.arith.Int64.prototype.toString = function() {
|
||||
// If the number is negative, find its twos-complement inverse.
|
||||
var sign = (this.hi & 0x80000000) != 0;
|
||||
var num = new jspb.arith.UInt64(this.lo, this.hi);
|
||||
if (sign) {
|
||||
num = new jspb.arith.UInt64(0, 0).sub(num);
|
||||
}
|
||||
return (sign ? '-' : '') + num.toString();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parse a string into a 64-bit number. Returns `null` on a parse error.
|
||||
* @param {string} s
|
||||
* @return {?jspb.arith.Int64}
|
||||
*/
|
||||
jspb.arith.Int64.fromString = function(s) {
|
||||
var hasNegative = (s.length > 0 && s[0] == '-');
|
||||
if (hasNegative) {
|
||||
s = s.substring(1);
|
||||
}
|
||||
var num = jspb.arith.UInt64.fromString(s);
|
||||
if (num === null) {
|
||||
return null;
|
||||
}
|
||||
if (hasNegative) {
|
||||
num = new jspb.arith.UInt64(0, 0).sub(num);
|
||||
}
|
||||
return new jspb.arith.Int64(num.lo, num.hi);
|
||||
};
|
354
deps/protobuf/js/binary/arith_test.js
vendored
Normal file
354
deps/protobuf/js/binary/arith_test.js
vendored
Normal file
@ -0,0 +1,354 @@
|
||||
// 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 Test cases for Int64-manipulation functions.
|
||||
*
|
||||
* Test suite is written using Jasmine -- see http://jasmine.github.io/
|
||||
*
|
||||
* @author cfallin@google.com (Chris Fallin)
|
||||
*/
|
||||
|
||||
goog.require('jspb.arith.Int64');
|
||||
goog.require('jspb.arith.UInt64');
|
||||
|
||||
|
||||
describe('binaryArithTest', function() {
|
||||
/**
|
||||
* Tests comparison operations.
|
||||
*/
|
||||
it('testCompare', function() {
|
||||
var a = new jspb.arith.UInt64(1234, 5678);
|
||||
var b = new jspb.arith.UInt64(1234, 5678);
|
||||
expect(a.cmp(b)).toEqual(0);
|
||||
expect(b.cmp(a)).toEqual(0);
|
||||
b.lo -= 1;
|
||||
expect(a.cmp(b)).toEqual(1);
|
||||
expect(b.cmp(a)).toEqual(-1);
|
||||
b.lo += 2;
|
||||
expect(a.cmp(b)).toEqual(-1);
|
||||
expect(b.cmp(a)).toEqual(1);
|
||||
b.lo = a.lo;
|
||||
b.hi = a.hi - 1;
|
||||
expect(a.cmp(b)).toEqual(1);
|
||||
expect(b.cmp(a)).toEqual(-1);
|
||||
|
||||
expect(a.zero()).toEqual(false);
|
||||
expect(a.msb()).toEqual(false);
|
||||
expect(a.lsb()).toEqual(false);
|
||||
a.hi = 0;
|
||||
a.lo = 0;
|
||||
expect(a.zero()).toEqual(true);
|
||||
a.hi = 0x80000000;
|
||||
expect(a.zero()).toEqual(false);
|
||||
expect(a.msb()).toEqual(true);
|
||||
a.lo = 0x00000001;
|
||||
expect(a.lsb()).toEqual(true);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests shifts.
|
||||
*/
|
||||
it('testShifts', function() {
|
||||
var a = new jspb.arith.UInt64(1, 0);
|
||||
expect(a.lo).toEqual(1);
|
||||
expect(a.hi).toEqual(0);
|
||||
var orig = a;
|
||||
a = a.leftShift();
|
||||
expect(orig.lo).toEqual(1); // original unmodified.
|
||||
expect(orig.hi).toEqual(0);
|
||||
expect(a.lo).toEqual(2);
|
||||
expect(a.hi).toEqual(0);
|
||||
a = a.leftShift();
|
||||
expect(a.lo).toEqual(4);
|
||||
expect(a.hi).toEqual(0);
|
||||
for (var i = 0; i < 29; i++) {
|
||||
a = a.leftShift();
|
||||
}
|
||||
expect(a.lo).toEqual(0x80000000);
|
||||
expect(a.hi).toEqual(0);
|
||||
a = a.leftShift();
|
||||
expect(a.lo).toEqual(0);
|
||||
expect(a.hi).toEqual(1);
|
||||
a = a.leftShift();
|
||||
expect(a.lo).toEqual(0);
|
||||
expect(a.hi).toEqual(2);
|
||||
a = a.rightShift();
|
||||
a = a.rightShift();
|
||||
expect(a.lo).toEqual(0x80000000);
|
||||
expect(a.hi).toEqual(0);
|
||||
a = a.rightShift();
|
||||
expect(a.lo).toEqual(0x40000000);
|
||||
expect(a.hi).toEqual(0);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests additions.
|
||||
*/
|
||||
it('testAdd', function() {
|
||||
var a = new jspb.arith.UInt64(/* lo = */ 0x89abcdef,
|
||||
/* hi = */ 0x01234567);
|
||||
var b = new jspb.arith.UInt64(/* lo = */ 0xff52ab91,
|
||||
/* hi = */ 0x92fa2123);
|
||||
// Addition with carry.
|
||||
var c = a.add(b);
|
||||
expect(a.lo).toEqual(0x89abcdef); // originals unmodified.
|
||||
expect(a.hi).toEqual(0x01234567);
|
||||
expect(b.lo).toEqual(0xff52ab91);
|
||||
expect(b.hi).toEqual(0x92fa2123);
|
||||
expect(c.lo).toEqual(0x88fe7980);
|
||||
expect(c.hi).toEqual(0x941d668b);
|
||||
|
||||
// Simple addition without carry.
|
||||
a.lo = 2;
|
||||
a.hi = 0;
|
||||
b.lo = 3;
|
||||
b.hi = 0;
|
||||
c = a.add(b);
|
||||
expect(c.lo).toEqual(5);
|
||||
expect(c.hi).toEqual(0);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Test subtractions.
|
||||
*/
|
||||
it('testSub', function() {
|
||||
var kLength = 10;
|
||||
var hiValues = [0x1682ef32,
|
||||
0x583902f7,
|
||||
0xb62f5955,
|
||||
0x6ea99bbf,
|
||||
0x25a39c20,
|
||||
0x0700a08b,
|
||||
0x00f7304d,
|
||||
0x91a5b5af,
|
||||
0x89077fd2,
|
||||
0xe09e347c];
|
||||
var loValues = [0xe1538b18,
|
||||
0xbeacd556,
|
||||
0x74100758,
|
||||
0x96e3cb26,
|
||||
0x56c37c3f,
|
||||
0xe00b3f7d,
|
||||
0x859f25d7,
|
||||
0xc2ee614a,
|
||||
0xe1d21cd7,
|
||||
0x30aae6a4];
|
||||
for (var i = 0; i < kLength; i++) {
|
||||
for (var j = 0; j < kLength; j++) {
|
||||
var a = new jspb.arith.UInt64(loValues[i], hiValues[j]);
|
||||
var b = new jspb.arith.UInt64(loValues[j], hiValues[i]);
|
||||
var c = a.add(b).sub(b);
|
||||
expect(c.hi).toEqual(a.hi);
|
||||
expect(c.lo).toEqual(a.lo);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests 32-by-32 multiplication.
|
||||
*/
|
||||
it('testMul32x32', function() {
|
||||
var testData = [
|
||||
// a b low(a*b) high(a*b)
|
||||
[0xc0abe2f8, 0x1607898a, 0x5de711b0, 0x109471b8],
|
||||
[0x915eb3cb, 0x4fb66d0e, 0xbd0d441a, 0x2d43d0bc],
|
||||
[0xfe4efe70, 0x80b48c37, 0xbcddea10, 0x7fdada0c],
|
||||
[0xe222fd4a, 0xe43d524a, 0xd5e0eb64, 0xc99d549c],
|
||||
[0xd171f469, 0xb94ebd01, 0x4be17969, 0x979bc4fa],
|
||||
[0x829cc1df, 0xe2598b38, 0xf4157dc8, 0x737c12ad],
|
||||
[0xf10c3767, 0x8382881e, 0x942b3612, 0x7bd428b8],
|
||||
[0xb0f6dd24, 0x232597e1, 0x079c98a4, 0x184bbce7],
|
||||
[0xfcdb05a7, 0x902f55bc, 0x636199a4, 0x8e69f412],
|
||||
[0x0dd0bfa9, 0x916e27b1, 0x6e2542d9, 0x07d92e65]
|
||||
];
|
||||
|
||||
for (var i = 0; i < testData.length; i++) {
|
||||
var a = testData[i][0] >>> 0;
|
||||
var b = testData[i][1] >>> 0;
|
||||
var cLow = testData[i][2] >>> 0;
|
||||
var cHigh = testData[i][3] >>> 0;
|
||||
var c = jspb.arith.UInt64.mul32x32(a, b);
|
||||
expect(c.lo).toEqual(cLow);
|
||||
expect(c.hi).toEqual(cHigh);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests 64-by-32 multiplication.
|
||||
*/
|
||||
it('testMul', function() {
|
||||
// 64x32 bits produces 96 bits of product. The multiplication function under
|
||||
// test truncates the top 32 bits, so we compare against a 64-bit expected
|
||||
// product.
|
||||
var testData = [
|
||||
// low(a) high(a) low(a*b) high(a*b)
|
||||
[0xec10955b, 0x360eb168, 0x4b7f3f5b, 0xbfcb7c59, 0x9517da5f],
|
||||
[0x42b000fc, 0x9d101642, 0x6fa1ab72, 0x2584c438, 0x6a9e6d2b],
|
||||
[0xf42d4fb4, 0xae366403, 0xa65a1000, 0x92434000, 0x1ff978df],
|
||||
[0x17e2f56b, 0x25487693, 0xf13f98c7, 0x73794e2d, 0xa96b0c6a],
|
||||
[0x492f241f, 0x76c0eb67, 0x7377ac44, 0xd4336c3c, 0xfc4b1ebe],
|
||||
[0xd6b92321, 0xe184fa48, 0xd6e76904, 0x93141584, 0xcbf44da1],
|
||||
[0x4bf007ea, 0x968c0a9e, 0xf5e4026a, 0x4fdb1ae4, 0x61b9fb7d],
|
||||
[0x10a83be7, 0x2d685ba6, 0xc9e5fb7f, 0x2ad43499, 0x3742473d],
|
||||
[0x2f261829, 0x1aca681a, 0x3d3494e3, 0x8213205b, 0x283719f8],
|
||||
[0xe4f2ce21, 0x2e74b7bd, 0xd801b38b, 0xbc17feeb, 0xc6c44e0f]
|
||||
];
|
||||
|
||||
for (var i = 0; i < testData.length; i++) {
|
||||
var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]);
|
||||
var prod = a.mul(testData[i][2]);
|
||||
expect(prod.lo).toEqual(testData[i][3]);
|
||||
expect(prod.hi).toEqual(testData[i][4]);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests 64-div-by-32 division.
|
||||
*/
|
||||
it('testDiv', function() {
|
||||
// Compute a/b, yielding quot = a/b and rem = a%b.
|
||||
var testData = [
|
||||
// --- divisors in (0, 2^32-1) to test full divisor range
|
||||
// low(a) high(a) b low(quot) high(quot) rem
|
||||
[0x712443f1, 0xe85cefcc, 0xc1a7050b, 0x332c79ad, 0x00000001, 0x92ffa882],
|
||||
[0x11912915, 0xb2699eb5, 0x30467cbe, 0xb21b4be4, 0x00000003, 0x283465dd],
|
||||
[0x0d917982, 0x201f2a6e, 0x3f35bf03, 0x8217c8e4, 0x00000000, 0x153402d6],
|
||||
[0xa072c108, 0x74020c96, 0xc60568fd, 0x95f9613e, 0x00000000, 0x3f4676c2],
|
||||
[0xd845d5d8, 0xcdd235c4, 0x20426475, 0x6154e78b, 0x00000006, 0x202fb751],
|
||||
[0xa4dbf71f, 0x9e90465e, 0xf08e022f, 0xa8be947f, 0x00000000, 0xbe43b5ce],
|
||||
[0x3dbe627f, 0xa791f4b9, 0x28a5bd89, 0x1f5dfe93, 0x00000004, 0x02bf9ed4],
|
||||
[0x5c1c53ee, 0xccf5102e, 0x198576e7, 0x07e3ae31, 0x00000008, 0x02ea8fb7],
|
||||
[0xfef1e581, 0x04714067, 0xca6540c1, 0x059e73ec, 0x00000000, 0x31658095],
|
||||
[0x1e2dd90c, 0x13dd6667, 0x8b2184c3, 0x248d1a42, 0x00000000, 0x4ca6d0c6],
|
||||
// --- divisors in (0, 2^16-1) to test larger quotient high-words
|
||||
// low(a) high(a) b low(quot) high(quot) rem
|
||||
[0x86722b47, 0x2cd57c9a, 0x00003123, 0x2ae41b7a, 0x0000e995, 0x00000f99],
|
||||
[0x1dd7884c, 0xf5e839bc, 0x00009eeb, 0x5c886242, 0x00018c21, 0x000099b6],
|
||||
[0x5c53d625, 0x899fc7e5, 0x000087d7, 0xd625007a, 0x0001035c, 0x000019af],
|
||||
[0x6932d932, 0x9d0a5488, 0x000051fb, 0x9d976143, 0x0001ea63, 0x00004981],
|
||||
[0x4d18bb85, 0x0c92fb31, 0x00001d9f, 0x03265ab4, 0x00006cac, 0x000001b9],
|
||||
[0xbe756768, 0xdea67ccb, 0x00008a03, 0x58add442, 0x00019cff, 0x000056a2],
|
||||
[0xe2466f9a, 0x2521f114, 0x0000c350, 0xa0c0860d, 0x000030ab, 0x0000a48a],
|
||||
[0xf00ddad1, 0xe2f5446a, 0x00002cfc, 0x762697a6, 0x00050b96, 0x00000b69],
|
||||
[0xa879152a, 0x0a70e0a5, 0x00007cdf, 0xb44151b3, 0x00001567, 0x0000363d],
|
||||
[0x7179a74c, 0x46083fff, 0x0000253c, 0x4d39ba6e, 0x0001e17f, 0x00000f84]
|
||||
];
|
||||
|
||||
for (var i = 0; i < testData.length; i++) {
|
||||
var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]);
|
||||
var result = a.div(testData[i][2]);
|
||||
var quotient = result[0];
|
||||
var remainder = result[1];
|
||||
expect(quotient.lo).toEqual(testData[i][3]);
|
||||
expect(quotient.hi).toEqual(testData[i][4]);
|
||||
expect(remainder.lo).toEqual(testData[i][5]);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests .toString() and .fromString().
|
||||
*/
|
||||
it('testStrings', function() {
|
||||
var testData = [
|
||||
[0x5e84c935, 0xcae33d0e, '14619595947299359029'],
|
||||
[0x62b3b8b8, 0x93480544, '10612738313170434232'],
|
||||
[0x319bfb13, 0xc01c4172, '13843011313344445203'],
|
||||
[0x5b8a65fb, 0xa5885b31, '11927883880638080507'],
|
||||
[0x6bdb80f1, 0xb0d1b16b, '12741159895737008369'],
|
||||
[0x4b82b442, 0x2e0d8c97, '3318463081876730946'],
|
||||
[0x780d5208, 0x7d76752c, '9040542135845999112'],
|
||||
[0x2e46800f, 0x0993778d, '690026616168284175'],
|
||||
[0xf00a7e32, 0xcd8e3931, '14811839111111540274'],
|
||||
[0x1baeccd6, 0x923048c4, '10533999535534820566'],
|
||||
[0x03669d29, 0xbff3ab72, '13831587386756603177'],
|
||||
[0x2526073e, 0x01affc81, '121593346566522686'],
|
||||
[0xc24244e0, 0xd7f40d0e, '15561076969511732448'],
|
||||
[0xc56a341e, 0xa68b66a7, '12000798502816461854'],
|
||||
[0x8738d64d, 0xbfe78604, '13828168534871037517'],
|
||||
[0x5baff03b, 0xd7572aea, '15516918227177304123'],
|
||||
[0x4a843d8a, 0x864e132b, '9677693725920476554'],
|
||||
[0x25b4e94d, 0x22b54dc6, '2500990681505655117'],
|
||||
[0x6bbe664b, 0x55a5cc0e, '6171563226690381387'],
|
||||
[0xee916c81, 0xb00aabb3, '12685140089732426881']
|
||||
];
|
||||
|
||||
for (var i = 0; i < testData.length; i++) {
|
||||
var a = new jspb.arith.UInt64(testData[i][0], testData[i][1]);
|
||||
var roundtrip = jspb.arith.UInt64.fromString(a.toString());
|
||||
expect(roundtrip.lo).toEqual(a.lo);
|
||||
expect(roundtrip.hi).toEqual(a.hi);
|
||||
expect(a.toString()).toEqual(testData[i][2]);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests signed Int64s. These are built on UInt64s, so we only need to test
|
||||
* the explicit overrides: .toString() and .fromString().
|
||||
*/
|
||||
it('testSignedInt64', function() {
|
||||
var testStrings = [
|
||||
'-7847499644178593666',
|
||||
'3771946501229139523',
|
||||
'2872856549054995060',
|
||||
'-5780049594274350904',
|
||||
'3383785956695105201',
|
||||
'2973055184857072610',
|
||||
'-3879428459215627206',
|
||||
'4589812431064156631',
|
||||
'8484075557333689940',
|
||||
'1075325817098092407',
|
||||
'-4346697501012292314',
|
||||
'2488620459718316637',
|
||||
'6112655187423520672',
|
||||
'-3655278273928612104',
|
||||
'3439154019435803196',
|
||||
'1004112478843763757',
|
||||
'-6587790776614368413',
|
||||
'664320065099714586',
|
||||
'4760412909973292912',
|
||||
'-7911903989602274672'
|
||||
];
|
||||
|
||||
for (var i = 0; i < testStrings.length; i++) {
|
||||
var roundtrip =
|
||||
jspb.arith.Int64.fromString(testStrings[i]).toString();
|
||||
expect(roundtrip).toEqual(testStrings[i]);
|
||||
}
|
||||
});
|
||||
});
|
377
deps/protobuf/js/binary/constants.js
vendored
Normal file
377
deps/protobuf/js/binary/constants.js
vendored
Normal file
@ -0,0 +1,377 @@
|
||||
// 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 This file contains constants and typedefs used by
|
||||
* jspb.BinaryReader and BinaryWriter.
|
||||
* @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed
|
||||
*
|
||||
* @author aappleby@google.com (Austin Appleby)
|
||||
*/
|
||||
|
||||
goog.provide('jspb.AnyFieldType');
|
||||
goog.provide('jspb.BinaryConstants');
|
||||
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.BinaryMessage');
|
||||
goog.forwardDeclare('jspb.BinaryReader');
|
||||
goog.forwardDeclare('jspb.BinaryWriter');
|
||||
goog.forwardDeclare('jspb.Message');
|
||||
goog.forwardDeclare('jsprotolib.BinaryExtension');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Base interface class for all const messages.
|
||||
* @interface
|
||||
*/
|
||||
jspb.ConstBinaryMessage = function() {};
|
||||
|
||||
/**
|
||||
* Generate a debug string for this proto that is in proto2 text format.
|
||||
* @return {string} The debug string.
|
||||
*/
|
||||
jspb.ConstBinaryMessage.prototype.toDebugString;
|
||||
|
||||
/**
|
||||
* Helper to generate a debug string for this proto at some indent level. The
|
||||
* first line is not indented.
|
||||
* @param {number} indentLevel The number of spaces by which to indent lines.
|
||||
* @return {string} The debug string.
|
||||
* @protected
|
||||
*/
|
||||
jspb.ConstBinaryMessage.prototype.toDebugStringInternal;
|
||||
|
||||
/**
|
||||
* Base interface class for all messages. Does __not__ define any methods, as
|
||||
* doing so on a widely-used interface defeats dead-code elimination.
|
||||
* @interface
|
||||
* @extends {jspb.ConstBinaryMessage}
|
||||
*/
|
||||
jspb.BinaryMessage = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* The types convertible to Uint8Arrays. Strings are assumed to be
|
||||
* base64-encoded.
|
||||
* @typedef {ArrayBuffer|Uint8Array|Array<number>|string}
|
||||
*/
|
||||
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.ConstBinaryMessage>|
|
||||
!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 {jspb.ScalarFieldType|
|
||||
jspb.RepeatedFieldType|
|
||||
!Uint8Array|
|
||||
!jspb.ConstBinaryMessage|
|
||||
!jspb.BinaryMessage|
|
||||
!jsprotolib.BinaryExtension}
|
||||
*/
|
||||
jspb.AnyFieldType;
|
||||
|
||||
|
||||
/**
|
||||
* A builder function creates an instance of a message object.
|
||||
* @typedef {function():!jspb.BinaryMessage}
|
||||
*/
|
||||
jspb.BuilderFunction;
|
||||
|
||||
|
||||
/**
|
||||
* A cloner function creates a deep copy of a message object.
|
||||
* @typedef {function(jspb.ConstBinaryMessage):jspb.BinaryMessage}
|
||||
*/
|
||||
jspb.ClonerFunction;
|
||||
|
||||
|
||||
/**
|
||||
* A recycler function destroys an instance of a message object.
|
||||
* @typedef {function(!jspb.BinaryMessage):void}
|
||||
*/
|
||||
jspb.RecyclerFunction;
|
||||
|
||||
|
||||
/**
|
||||
* A reader function initializes a message using data from a BinaryReader.
|
||||
* @typedef {function(!jspb.BinaryMessage, !jspb.BinaryReader):void}
|
||||
*/
|
||||
jspb.ReaderFunction;
|
||||
|
||||
|
||||
/**
|
||||
* A writer function serializes a message to a BinaryWriter.
|
||||
* @typedef {function((!jspb.Message|!jspb.ConstBinaryMessage),
|
||||
* !jspb.BinaryWriter):void}
|
||||
*/
|
||||
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}
|
||||
*/
|
||||
jspb.BinaryConstants.FieldType = {
|
||||
INVALID: -1,
|
||||
DOUBLE: 1,
|
||||
FLOAT: 2,
|
||||
INT64: 3,
|
||||
UINT64: 4,
|
||||
INT32: 5,
|
||||
FIXED64: 6,
|
||||
FIXED32: 7,
|
||||
BOOL: 8,
|
||||
STRING: 9,
|
||||
GROUP: 10,
|
||||
MESSAGE: 11,
|
||||
BYTES: 12,
|
||||
UINT32: 13,
|
||||
ENUM: 14,
|
||||
SFIXED32: 15,
|
||||
SFIXED64: 16,
|
||||
SINT32: 17,
|
||||
SINT64: 18,
|
||||
|
||||
// Extended types for Javascript
|
||||
|
||||
FHASH64: 30, // 64-bit hash string, fixed-length encoding.
|
||||
VHASH64: 31 // 64-bit hash string, varint encoding.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Wire-format type codes, taken from proto2/public/wire_format_lite.h.
|
||||
* @enum {number}
|
||||
*/
|
||||
jspb.BinaryConstants.WireType = {
|
||||
INVALID: -1,
|
||||
VARINT: 0,
|
||||
FIXED64: 1,
|
||||
DELIMITED: 2,
|
||||
START_GROUP: 3,
|
||||
END_GROUP: 4,
|
||||
FIXED32: 5
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Translates field type to wire type.
|
||||
* @param {jspb.BinaryConstants.FieldType} fieldType
|
||||
* @return {jspb.BinaryConstants.WireType}
|
||||
*/
|
||||
jspb.BinaryConstants.FieldTypeToWireType = function(fieldType) {
|
||||
var fieldTypes = jspb.BinaryConstants.FieldType;
|
||||
var wireTypes = jspb.BinaryConstants.WireType;
|
||||
switch (fieldType) {
|
||||
case fieldTypes.INT32:
|
||||
case fieldTypes.INT64:
|
||||
case fieldTypes.UINT32:
|
||||
case fieldTypes.UINT64:
|
||||
case fieldTypes.SINT32:
|
||||
case fieldTypes.SINT64:
|
||||
case fieldTypes.BOOL:
|
||||
case fieldTypes.ENUM:
|
||||
case fieldTypes.VHASH64:
|
||||
return wireTypes.VARINT;
|
||||
|
||||
case fieldTypes.DOUBLE:
|
||||
case fieldTypes.FIXED64:
|
||||
case fieldTypes.SFIXED64:
|
||||
case fieldTypes.FHASH64:
|
||||
return wireTypes.FIXED64;
|
||||
|
||||
case fieldTypes.STRING:
|
||||
case fieldTypes.MESSAGE:
|
||||
case fieldTypes.BYTES:
|
||||
return wireTypes.DELIMITED;
|
||||
|
||||
case fieldTypes.FLOAT:
|
||||
case fieldTypes.FIXED32:
|
||||
case fieldTypes.SFIXED32:
|
||||
return wireTypes.FIXED32;
|
||||
|
||||
case fieldTypes.INVALID:
|
||||
case fieldTypes.GROUP:
|
||||
default:
|
||||
return wireTypes.INVALID;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Flag to indicate a missing field.
|
||||
* @const {number}
|
||||
*/
|
||||
jspb.BinaryConstants.INVALID_FIELD_NUMBER = -1;
|
||||
|
||||
|
||||
/**
|
||||
* The smallest denormal float32 value.
|
||||
* @const {number}
|
||||
*/
|
||||
jspb.BinaryConstants.FLOAT32_EPS = 1.401298464324817e-45;
|
||||
|
||||
|
||||
/**
|
||||
* The smallest normal float64 value.
|
||||
* @const {number}
|
||||
*/
|
||||
jspb.BinaryConstants.FLOAT32_MIN = 1.1754943508222875e-38;
|
||||
|
||||
|
||||
/**
|
||||
* The largest finite float32 value.
|
||||
* @const {number}
|
||||
*/
|
||||
jspb.BinaryConstants.FLOAT32_MAX = 3.4028234663852886e+38;
|
||||
|
||||
|
||||
/**
|
||||
* The smallest denormal float64 value.
|
||||
* @const {number}
|
||||
*/
|
||||
jspb.BinaryConstants.FLOAT64_EPS = 5e-324;
|
||||
|
||||
|
||||
/**
|
||||
* The smallest normal float64 value.
|
||||
* @const {number}
|
||||
*/
|
||||
jspb.BinaryConstants.FLOAT64_MIN = 2.2250738585072014e-308;
|
||||
|
||||
|
||||
/**
|
||||
* The largest finite float64 value.
|
||||
* @const {number}
|
||||
*/
|
||||
jspb.BinaryConstants.FLOAT64_MAX = 1.7976931348623157e+308;
|
||||
|
||||
|
||||
/**
|
||||
* Convenience constant equal to 2^20.
|
||||
* @const {number}
|
||||
*/
|
||||
jspb.BinaryConstants.TWO_TO_20 = 1048576;
|
||||
|
||||
|
||||
/**
|
||||
* Convenience constant equal to 2^23.
|
||||
* @const {number}
|
||||
*/
|
||||
jspb.BinaryConstants.TWO_TO_23 = 8388608;
|
||||
|
||||
|
||||
/**
|
||||
* Convenience constant equal to 2^31.
|
||||
* @const {number}
|
||||
*/
|
||||
jspb.BinaryConstants.TWO_TO_31 = 2147483648;
|
||||
|
||||
|
||||
/**
|
||||
* Convenience constant equal to 2^32.
|
||||
* @const {number}
|
||||
*/
|
||||
jspb.BinaryConstants.TWO_TO_32 = 4294967296;
|
||||
|
||||
|
||||
/**
|
||||
* Convenience constant equal to 2^52.
|
||||
* @const {number}
|
||||
*/
|
||||
jspb.BinaryConstants.TWO_TO_52 = 4503599627370496;
|
||||
|
||||
|
||||
/**
|
||||
* Convenience constant equal to 2^63.
|
||||
* @const {number}
|
||||
*/
|
||||
jspb.BinaryConstants.TWO_TO_63 = 9223372036854775808;
|
||||
|
||||
|
||||
/**
|
||||
* Convenience constant equal to 2^64.
|
||||
* @const {number}
|
||||
*/
|
||||
jspb.BinaryConstants.TWO_TO_64 = 18446744073709551616;
|
||||
|
||||
|
||||
/**
|
||||
* Eight-character string of zeros, used as the default 64-bit hash value.
|
||||
* @const {string}
|
||||
*/
|
||||
jspb.BinaryConstants.ZERO_HASH = '\0\0\0\0\0\0\0\0';
|
951
deps/protobuf/js/binary/decoder.js
vendored
Normal file
951
deps/protobuf/js/binary/decoder.js
vendored
Normal file
@ -0,0 +1,951 @@
|
||||
// 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 This file contains utilities for decoding primitive values
|
||||
* (signed and unsigned integers, varints, booleans, enums, hashes, strings,
|
||||
* and raw bytes) embedded in Uint8Arrays into their corresponding Javascript
|
||||
* types.
|
||||
*
|
||||
* Major caveat - Javascript is unable to accurately represent integers larger
|
||||
* than 2^53 due to its use of a double-precision floating point format or all
|
||||
* numbers. If you need to guarantee that 64-bit values survive with all bits
|
||||
* intact, you _must_ read them using one of the Hash64 methods, which return
|
||||
* an 8-character string.
|
||||
*
|
||||
* @suppress {missingRequire} TODO(b/152540451): this shouldn't be needed
|
||||
* @author aappleby@google.com (Austin Appleby)
|
||||
*/
|
||||
|
||||
goog.provide('jspb.BinaryDecoder');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.crypt');
|
||||
goog.require('jspb.utils');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* BinaryDecoder implements the decoders for all the wire types specified in
|
||||
* https://developers.google.com/protocol-buffers/docs/encoding.
|
||||
*
|
||||
* @param {jspb.ByteSource=} opt_bytes The bytes we're reading from.
|
||||
* @param {number=} opt_start The optional offset to start reading at.
|
||||
* @param {number=} opt_length The optional length of the block to read -
|
||||
* we'll throw an assertion if we go off the end of the block.
|
||||
* @constructor
|
||||
* @struct
|
||||
*/
|
||||
jspb.BinaryDecoder = function(opt_bytes, opt_start, opt_length) {
|
||||
/**
|
||||
* Typed byte-wise view of the source buffer.
|
||||
* @private {?Uint8Array}
|
||||
*/
|
||||
this.bytes_ = null;
|
||||
|
||||
/**
|
||||
* Start point of the block to read.
|
||||
* @private {number}
|
||||
*/
|
||||
this.start_ = 0;
|
||||
|
||||
/**
|
||||
* End point of the block to read.
|
||||
* @private {number}
|
||||
*/
|
||||
this.end_ = 0;
|
||||
|
||||
/**
|
||||
* Current read location in bytes_.
|
||||
* @private {number}
|
||||
*/
|
||||
this.cursor_ = 0;
|
||||
|
||||
/**
|
||||
* Set to true if this decoder encountered an error due to corrupt data.
|
||||
* @private {boolean}
|
||||
*/
|
||||
this.error_ = false;
|
||||
|
||||
if (opt_bytes) {
|
||||
this.setBlock(opt_bytes, opt_start, opt_length);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Global pool of BinaryDecoder instances.
|
||||
* @private {!Array<!jspb.BinaryDecoder>}
|
||||
*/
|
||||
jspb.BinaryDecoder.instanceCache_ = [];
|
||||
|
||||
|
||||
/**
|
||||
* Pops an instance off the instance cache, or creates one if the cache is
|
||||
* empty.
|
||||
* @param {jspb.ByteSource=} opt_bytes The bytes we're reading from.
|
||||
* @param {number=} opt_start The optional offset to start reading at.
|
||||
* @param {number=} opt_length The optional length of the block to read -
|
||||
* we'll throw an assertion if we go off the end of the block.
|
||||
* @return {!jspb.BinaryDecoder}
|
||||
*/
|
||||
jspb.BinaryDecoder.alloc = function(opt_bytes, opt_start, opt_length) {
|
||||
if (jspb.BinaryDecoder.instanceCache_.length) {
|
||||
var newDecoder = jspb.BinaryDecoder.instanceCache_.pop();
|
||||
if (opt_bytes) {
|
||||
newDecoder.setBlock(opt_bytes, opt_start, opt_length);
|
||||
}
|
||||
return newDecoder;
|
||||
} else {
|
||||
return new jspb.BinaryDecoder(opt_bytes, opt_start, opt_length);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Puts this instance back in the instance cache.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.free = function() {
|
||||
this.clear();
|
||||
if (jspb.BinaryDecoder.instanceCache_.length < 100) {
|
||||
jspb.BinaryDecoder.instanceCache_.push(this);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Makes a copy of this decoder.
|
||||
* @return {!jspb.BinaryDecoder}
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.clone = function() {
|
||||
return jspb.BinaryDecoder.alloc(this.bytes_,
|
||||
this.start_, this.end_ - this.start_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Clears the decoder.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.clear = function() {
|
||||
this.bytes_ = null;
|
||||
this.start_ = 0;
|
||||
this.end_ = 0;
|
||||
this.cursor_ = 0;
|
||||
this.error_ = false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the raw buffer.
|
||||
* @return {?Uint8Array} The raw buffer.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.getBuffer = function() {
|
||||
return this.bytes_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Changes the block of bytes we're decoding.
|
||||
* @param {!jspb.ByteSource} data The bytes we're reading from.
|
||||
* @param {number=} opt_start The optional offset to start reading at.
|
||||
* @param {number=} opt_length The optional length of the block to read -
|
||||
* we'll throw an assertion if we go off the end of the block.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.setBlock =
|
||||
function(data, opt_start, opt_length) {
|
||||
this.bytes_ = jspb.utils.byteSourceToUint8Array(data);
|
||||
this.start_ = (opt_start !== undefined) ? opt_start : 0;
|
||||
this.end_ = (opt_length !== undefined) ? this.start_ + opt_length :
|
||||
this.bytes_.length;
|
||||
this.cursor_ = this.start_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number}
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.getEnd = function() {
|
||||
return this.end_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} end
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.setEnd = function(end) {
|
||||
this.end_ = end;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Moves the read cursor back to the start of the block.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.reset = function() {
|
||||
this.cursor_ = this.start_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the internal read cursor.
|
||||
* @return {number} The internal read cursor.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.getCursor = function() {
|
||||
return this.cursor_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the internal read cursor.
|
||||
* @param {number} cursor The new cursor.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.setCursor = function(cursor) {
|
||||
this.cursor_ = cursor;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Advances the stream cursor by the given number of bytes.
|
||||
* @param {number} count The number of bytes to advance by.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.advance = function(count) {
|
||||
this.cursor_ += count;
|
||||
goog.asserts.assert(this.cursor_ <= this.end_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this decoder is at the end of the block.
|
||||
* @return {boolean}
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.atEnd = function() {
|
||||
return this.cursor_ == this.end_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this decoder is at the end of the block.
|
||||
* @return {boolean}
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.pastEnd = function() {
|
||||
return this.cursor_ > this.end_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if this decoder encountered an error due to corrupt data.
|
||||
* @return {boolean}
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.getError = function() {
|
||||
return this.error_ ||
|
||||
(this.cursor_ < 0) ||
|
||||
(this.cursor_ > this.end_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads an unsigned varint from the binary stream and invokes the conversion
|
||||
* function with the value in two signed 32 bit integers to produce the result.
|
||||
* Since this does not convert the value to a number, no precision is lost.
|
||||
*
|
||||
* It's possible for an unsigned varint to be incorrectly encoded - more than
|
||||
* 64 bits' worth of data could be present. If this happens, this method will
|
||||
* throw an error.
|
||||
*
|
||||
* Decoding varints requires doing some funny base-128 math - for more
|
||||
* details on the format, see
|
||||
* https://developers.google.com/protocol-buffers/docs/encoding
|
||||
*
|
||||
* @param {function(number, number): T} convert Conversion function to produce
|
||||
* the result value, takes parameters (lowBits, highBits).
|
||||
* @return {T}
|
||||
* @template T
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readSplitVarint64 = function(convert) {
|
||||
var temp = 128;
|
||||
var lowBits = 0;
|
||||
var highBits = 0;
|
||||
|
||||
// Read the first four bytes of the varint, stopping at the terminator if we
|
||||
// see it.
|
||||
for (var i = 0; i < 4 && temp >= 128; i++) {
|
||||
temp = this.bytes_[this.cursor_++];
|
||||
lowBits |= (temp & 0x7F) << (i * 7);
|
||||
}
|
||||
|
||||
if (temp >= 128) {
|
||||
// Read the fifth byte, which straddles the low and high dwords.
|
||||
temp = this.bytes_[this.cursor_++];
|
||||
lowBits |= (temp & 0x7F) << 28;
|
||||
highBits |= (temp & 0x7F) >> 4;
|
||||
}
|
||||
|
||||
if (temp >= 128) {
|
||||
// Read the sixth through tenth byte.
|
||||
for (var i = 0; i < 5 && temp >= 128; i++) {
|
||||
temp = this.bytes_[this.cursor_++];
|
||||
highBits |= (temp & 0x7F) << (i * 7 + 3);
|
||||
}
|
||||
}
|
||||
|
||||
if (temp < 128) {
|
||||
return convert(lowBits >>> 0, highBits >>> 0);
|
||||
}
|
||||
|
||||
// If we did not see the terminator, the encoding was invalid.
|
||||
goog.asserts.fail('Failed to read varint, encoding is invalid.');
|
||||
this.error_ = true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a signed zigzag encoded varint from the binary stream and invokes
|
||||
* the conversion function with the value in two signed 32 bit integers to
|
||||
* produce the result. Since this does not convert the value to a number, no
|
||||
* precision is lost.
|
||||
*
|
||||
* It's possible for an unsigned varint to be incorrectly encoded - more than
|
||||
* 64 bits' worth of data could be present. If this happens, this method will
|
||||
* throw an error.
|
||||
*
|
||||
* Zigzag encoding is a modification of varint encoding that reduces the
|
||||
* storage overhead for small negative integers - for more details on the
|
||||
* format, see https://developers.google.com/protocol-buffers/docs/encoding
|
||||
*
|
||||
* @param {function(number, number): T} convert Conversion function to produce
|
||||
* the result value, takes parameters (lowBits, highBits).
|
||||
* @return {T}
|
||||
* @template T
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readSplitZigzagVarint64 = function(convert) {
|
||||
return this.readSplitVarint64(function(low, high) {
|
||||
return jspb.utils.fromZigzag64(low, high, convert);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a 64-bit fixed-width value from the stream and invokes the conversion
|
||||
* function with the value in two signed 32 bit integers to produce the result.
|
||||
* Since this does not convert the value to a number, no precision is lost.
|
||||
*
|
||||
* @param {function(number, number): T} convert Conversion function to produce
|
||||
* the result value, takes parameters (lowBits, highBits).
|
||||
* @return {T}
|
||||
* @template T
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readSplitFixed64 = function(convert) {
|
||||
var bytes = this.bytes_;
|
||||
var cursor = this.cursor_;
|
||||
this.cursor_ += 8;
|
||||
var lowBits = 0;
|
||||
var highBits = 0;
|
||||
for (var i = cursor + 7; i >= cursor; i--) {
|
||||
lowBits = (lowBits << 8) | bytes[i];
|
||||
highBits = (highBits << 8) | bytes[i + 4];
|
||||
}
|
||||
return convert(lowBits, highBits);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Skips over a varint in the block without decoding it.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.skipVarint = function() {
|
||||
while (this.bytes_[this.cursor_] & 0x80) {
|
||||
this.cursor_++;
|
||||
}
|
||||
this.cursor_++;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Skips backwards over a varint in the block - to do this correctly, we have
|
||||
* to know the value we're skipping backwards over or things are ambiguous.
|
||||
* @param {number} value The varint value to unskip.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.unskipVarint = function(value) {
|
||||
while (value > 128) {
|
||||
this.cursor_--;
|
||||
value = value >>> 7;
|
||||
}
|
||||
this.cursor_--;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a 32-bit varint from the binary stream. Due to a quirk of the encoding
|
||||
* format and Javascript's handling of bitwise math, this actually works
|
||||
* correctly for both signed and unsigned 32-bit varints.
|
||||
*
|
||||
* This function is called vastly more frequently than any other in
|
||||
* BinaryDecoder, so it has been unrolled and tweaked for performance.
|
||||
*
|
||||
* If there are more than 32 bits of data in the varint, it _must_ be due to
|
||||
* sign-extension. If we're in debug mode and the high 32 bits don't match the
|
||||
* expected sign extension, this method will throw an error.
|
||||
*
|
||||
* Decoding varints requires doing some funny base-128 math - for more
|
||||
* details on the format, see
|
||||
* https://developers.google.com/protocol-buffers/docs/encoding
|
||||
*
|
||||
* @return {number} The decoded unsigned 32-bit varint.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readUnsignedVarint32 = function() {
|
||||
var temp;
|
||||
var bytes = this.bytes_;
|
||||
|
||||
temp = bytes[this.cursor_ + 0];
|
||||
var x = (temp & 0x7F);
|
||||
if (temp < 128) {
|
||||
this.cursor_ += 1;
|
||||
goog.asserts.assert(this.cursor_ <= this.end_);
|
||||
return x;
|
||||
}
|
||||
|
||||
temp = bytes[this.cursor_ + 1];
|
||||
x |= (temp & 0x7F) << 7;
|
||||
if (temp < 128) {
|
||||
this.cursor_ += 2;
|
||||
goog.asserts.assert(this.cursor_ <= this.end_);
|
||||
return x;
|
||||
}
|
||||
|
||||
temp = bytes[this.cursor_ + 2];
|
||||
x |= (temp & 0x7F) << 14;
|
||||
if (temp < 128) {
|
||||
this.cursor_ += 3;
|
||||
goog.asserts.assert(this.cursor_ <= this.end_);
|
||||
return x;
|
||||
}
|
||||
|
||||
temp = bytes[this.cursor_ + 3];
|
||||
x |= (temp & 0x7F) << 21;
|
||||
if (temp < 128) {
|
||||
this.cursor_ += 4;
|
||||
goog.asserts.assert(this.cursor_ <= this.end_);
|
||||
return x;
|
||||
}
|
||||
|
||||
temp = bytes[this.cursor_ + 4];
|
||||
x |= (temp & 0x0F) << 28;
|
||||
if (temp < 128) {
|
||||
// We're reading the high bits of an unsigned varint. The byte we just read
|
||||
// also contains bits 33 through 35, which we're going to discard.
|
||||
this.cursor_ += 5;
|
||||
goog.asserts.assert(this.cursor_ <= this.end_);
|
||||
return x >>> 0;
|
||||
}
|
||||
|
||||
// If we get here, we need to truncate coming bytes. However we need to make
|
||||
// sure cursor place is correct.
|
||||
this.cursor_ += 5;
|
||||
if (bytes[this.cursor_++] >= 128 &&
|
||||
bytes[this.cursor_++] >= 128 &&
|
||||
bytes[this.cursor_++] >= 128 &&
|
||||
bytes[this.cursor_++] >= 128 &&
|
||||
bytes[this.cursor_++] >= 128) {
|
||||
// If we get here, the varint is too long.
|
||||
goog.asserts.assert(false);
|
||||
}
|
||||
|
||||
goog.asserts.assert(this.cursor_ <= this.end_);
|
||||
return x;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The readUnsignedVarint32 above deals with signed 32-bit varints correctly,
|
||||
* so this is just an alias.
|
||||
*
|
||||
* @return {number} The decoded signed 32-bit varint.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readSignedVarint32 =
|
||||
jspb.BinaryDecoder.prototype.readUnsignedVarint32;
|
||||
|
||||
|
||||
/**
|
||||
* Reads a 32-bit unsigned variant and returns its value as a string.
|
||||
*
|
||||
* @return {string} The decoded unsigned 32-bit varint as a string.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readUnsignedVarint32String = function() {
|
||||
// 32-bit integers fit in JavaScript numbers without loss of precision, so
|
||||
// string variants of 32-bit varint readers can simply delegate then convert
|
||||
// to string.
|
||||
var value = this.readUnsignedVarint32();
|
||||
return value.toString();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a 32-bit signed variant and returns its value as a string.
|
||||
*
|
||||
* @return {string} The decoded signed 32-bit varint as a string.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readSignedVarint32String = function() {
|
||||
// 32-bit integers fit in JavaScript numbers without loss of precision, so
|
||||
// string variants of 32-bit varint readers can simply delegate then convert
|
||||
// to string.
|
||||
var value = this.readSignedVarint32();
|
||||
return value.toString();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a signed, zigzag-encoded 32-bit varint from the binary stream.
|
||||
*
|
||||
* Zigzag encoding is a modification of varint encoding that reduces the
|
||||
* storage overhead for small negative integers - for more details on the
|
||||
* format, see https://developers.google.com/protocol-buffers/docs/encoding
|
||||
*
|
||||
* @return {number} The decoded signed, zigzag-encoded 32-bit varint.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readZigzagVarint32 = function() {
|
||||
var result = this.readUnsignedVarint32();
|
||||
return (result >>> 1) ^ - (result & 1);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads an unsigned 64-bit varint from the binary stream. Note that since
|
||||
* Javascript represents all numbers as double-precision floats, there will be
|
||||
* precision lost if the absolute value of the varint is larger than 2^53.
|
||||
*
|
||||
* @return {number} The decoded unsigned varint. Precision will be lost if the
|
||||
* integer exceeds 2^53.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readUnsignedVarint64 = function() {
|
||||
return this.readSplitVarint64(jspb.utils.joinUint64);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads an unsigned 64-bit varint from the binary stream and returns the value
|
||||
* as a decimal string.
|
||||
*
|
||||
* @return {string} The decoded unsigned varint as a decimal string.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readUnsignedVarint64String = function() {
|
||||
return this.readSplitVarint64(jspb.utils.joinUnsignedDecimalString);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a signed 64-bit varint from the binary stream. Note that since
|
||||
* Javascript represents all numbers as double-precision floats, there will be
|
||||
* precision lost if the absolute value of the varint is larger than 2^53.
|
||||
*
|
||||
* @return {number} The decoded signed varint. Precision will be lost if the
|
||||
* integer exceeds 2^53.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readSignedVarint64 = function() {
|
||||
return this.readSplitVarint64(jspb.utils.joinInt64);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads an signed 64-bit varint from the binary stream and returns the value
|
||||
* as a decimal string.
|
||||
*
|
||||
* @return {string} The decoded signed varint as a decimal string.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readSignedVarint64String = function() {
|
||||
return this.readSplitVarint64(jspb.utils.joinSignedDecimalString);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a signed, zigzag-encoded 64-bit varint from the binary stream. Note
|
||||
* that since Javascript represents all numbers as double-precision floats,
|
||||
* there will be precision lost if the absolute value of the varint is larger
|
||||
* than 2^53.
|
||||
*
|
||||
* Zigzag encoding is a modification of varint encoding that reduces the
|
||||
* storage overhead for small negative integers - for more details on the
|
||||
* format, see https://developers.google.com/protocol-buffers/docs/encoding
|
||||
*
|
||||
* @return {number} The decoded zigzag varint. Precision will be lost if the
|
||||
* integer exceeds 2^53.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readZigzagVarint64 = function() {
|
||||
return this.readSplitVarint64(jspb.utils.joinZigzag64);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a signed, zigzag-encoded 64-bit varint from the binary stream
|
||||
* losslessly and returns it as an 8-character Unicode string for use as a hash
|
||||
* table key.
|
||||
*
|
||||
* Zigzag encoding is a modification of varint encoding that reduces the
|
||||
* storage overhead for small negative integers - for more details on the
|
||||
* format, see https://developers.google.com/protocol-buffers/docs/encoding
|
||||
*
|
||||
* @return {string} The decoded zigzag varint in hash64 format.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readZigzagVarintHash64 = function() {
|
||||
return this.readSplitZigzagVarint64(jspb.utils.joinHash64);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a signed, zigzag-encoded 64-bit varint from the binary stream and
|
||||
* returns its value as a string.
|
||||
*
|
||||
* Zigzag encoding is a modification of varint encoding that reduces the
|
||||
* storage overhead for small negative integers - for more details on the
|
||||
* format, see https://developers.google.com/protocol-buffers/docs/encoding
|
||||
*
|
||||
* @return {string} The decoded signed, zigzag-encoded 64-bit varint as a
|
||||
* string.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readZigzagVarint64String = function() {
|
||||
return this.readSplitZigzagVarint64(jspb.utils.joinSignedDecimalString);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a raw unsigned 8-bit integer from the binary stream.
|
||||
*
|
||||
* @return {number} The unsigned 8-bit integer read from the binary stream.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readUint8 = function() {
|
||||
var a = this.bytes_[this.cursor_ + 0];
|
||||
this.cursor_ += 1;
|
||||
goog.asserts.assert(this.cursor_ <= this.end_);
|
||||
return a;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a raw unsigned 16-bit integer from the binary stream.
|
||||
*
|
||||
* @return {number} The unsigned 16-bit integer read from the binary stream.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readUint16 = function() {
|
||||
var a = this.bytes_[this.cursor_ + 0];
|
||||
var b = this.bytes_[this.cursor_ + 1];
|
||||
this.cursor_ += 2;
|
||||
goog.asserts.assert(this.cursor_ <= this.end_);
|
||||
return (a << 0) | (b << 8);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a raw unsigned 32-bit integer from the binary stream.
|
||||
*
|
||||
* @return {number} The unsigned 32-bit integer read from the binary stream.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readUint32 = function() {
|
||||
var a = this.bytes_[this.cursor_ + 0];
|
||||
var b = this.bytes_[this.cursor_ + 1];
|
||||
var c = this.bytes_[this.cursor_ + 2];
|
||||
var d = this.bytes_[this.cursor_ + 3];
|
||||
this.cursor_ += 4;
|
||||
goog.asserts.assert(this.cursor_ <= this.end_);
|
||||
return ((a << 0) | (b << 8) | (c << 16) | (d << 24)) >>> 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a raw unsigned 64-bit integer from the binary stream. Note that since
|
||||
* Javascript represents all numbers as double-precision floats, there will be
|
||||
* precision lost if the absolute value of the integer is larger than 2^53.
|
||||
*
|
||||
* @return {number} The unsigned 64-bit integer read from the binary stream.
|
||||
* Precision will be lost if the integer exceeds 2^53.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readUint64 = function() {
|
||||
var bitsLow = this.readUint32();
|
||||
var bitsHigh = this.readUint32();
|
||||
return jspb.utils.joinUint64(bitsLow, bitsHigh);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a raw unsigned 64-bit integer from the binary stream. Note that since
|
||||
* Javascript represents all numbers as double-precision floats, there will be
|
||||
* precision lost if the absolute value of the integer is larger than 2^53.
|
||||
*
|
||||
* @return {string} The unsigned 64-bit integer read from the binary stream.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readUint64String = function() {
|
||||
var bitsLow = this.readUint32();
|
||||
var bitsHigh = this.readUint32();
|
||||
return jspb.utils.joinUnsignedDecimalString(bitsLow, bitsHigh);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a raw signed 8-bit integer from the binary stream.
|
||||
*
|
||||
* @return {number} The signed 8-bit integer read from the binary stream.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readInt8 = function() {
|
||||
var a = this.bytes_[this.cursor_ + 0];
|
||||
this.cursor_ += 1;
|
||||
goog.asserts.assert(this.cursor_ <= this.end_);
|
||||
return (a << 24) >> 24;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a raw signed 16-bit integer from the binary stream.
|
||||
*
|
||||
* @return {number} The signed 16-bit integer read from the binary stream.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readInt16 = function() {
|
||||
var a = this.bytes_[this.cursor_ + 0];
|
||||
var b = this.bytes_[this.cursor_ + 1];
|
||||
this.cursor_ += 2;
|
||||
goog.asserts.assert(this.cursor_ <= this.end_);
|
||||
return (((a << 0) | (b << 8)) << 16) >> 16;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a raw signed 32-bit integer from the binary stream.
|
||||
*
|
||||
* @return {number} The signed 32-bit integer read from the binary stream.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readInt32 = function() {
|
||||
var a = this.bytes_[this.cursor_ + 0];
|
||||
var b = this.bytes_[this.cursor_ + 1];
|
||||
var c = this.bytes_[this.cursor_ + 2];
|
||||
var d = this.bytes_[this.cursor_ + 3];
|
||||
this.cursor_ += 4;
|
||||
goog.asserts.assert(this.cursor_ <= this.end_);
|
||||
return (a << 0) | (b << 8) | (c << 16) | (d << 24);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a raw signed 64-bit integer from the binary stream. Note that since
|
||||
* Javascript represents all numbers as double-precision floats, there will be
|
||||
* precision lost if the absolute value of the integer is larger than 2^53.
|
||||
*
|
||||
* @return {number} The signed 64-bit integer read from the binary stream.
|
||||
* Precision will be lost if the integer exceeds 2^53.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readInt64 = function() {
|
||||
var bitsLow = this.readUint32();
|
||||
var bitsHigh = this.readUint32();
|
||||
return jspb.utils.joinInt64(bitsLow, bitsHigh);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a raw signed 64-bit integer from the binary stream and returns it as a
|
||||
* string.
|
||||
*
|
||||
* @return {string} The signed 64-bit integer read from the binary stream.
|
||||
* Precision will be lost if the integer exceeds 2^53.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readInt64String = function() {
|
||||
var bitsLow = this.readUint32();
|
||||
var bitsHigh = this.readUint32();
|
||||
return jspb.utils.joinSignedDecimalString(bitsLow, bitsHigh);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a 32-bit floating-point number from the binary stream, using the
|
||||
* temporary buffer to realign the data.
|
||||
*
|
||||
* @return {number} The float read from the binary stream.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readFloat = function() {
|
||||
var bitsLow = this.readUint32();
|
||||
var bitsHigh = 0;
|
||||
return jspb.utils.joinFloat32(bitsLow, bitsHigh);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a 64-bit floating-point number from the binary stream, using the
|
||||
* temporary buffer to realign the data.
|
||||
*
|
||||
* @return {number} The double read from the binary stream.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readDouble = function() {
|
||||
var bitsLow = this.readUint32();
|
||||
var bitsHigh = this.readUint32();
|
||||
return jspb.utils.joinFloat64(bitsLow, bitsHigh);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a boolean value from the binary stream.
|
||||
* @return {boolean} The boolean read from the binary stream.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readBool = function() {
|
||||
return !!this.bytes_[this.cursor_++];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads an enum value from the binary stream, which are always encoded as
|
||||
* signed varints.
|
||||
* @return {number} The enum value read from the binary stream.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readEnum = function() {
|
||||
return this.readSignedVarint32();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads and parses a UTF-8 encoded unicode string from the stream.
|
||||
* The code is inspired by maps.vectortown.parse.StreamedDataViewReader.
|
||||
* Supports codepoints from U+0000 up to U+10FFFF.
|
||||
* (http://en.wikipedia.org/wiki/UTF-8).
|
||||
* @param {number} length The length of the string to read.
|
||||
* @return {string} The decoded string.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readString = function(length) {
|
||||
var bytes = this.bytes_;
|
||||
var cursor = this.cursor_;
|
||||
var end = cursor + length;
|
||||
var codeUnits = [];
|
||||
|
||||
var result = '';
|
||||
while (cursor < end) {
|
||||
var c = bytes[cursor++];
|
||||
if (c < 128) { // Regular 7-bit ASCII.
|
||||
codeUnits.push(c);
|
||||
} else if (c < 192) {
|
||||
// UTF-8 continuation mark. We are out of sync. This
|
||||
// might happen if we attempted to read a character
|
||||
// with more than four bytes.
|
||||
continue;
|
||||
} else if (c < 224) { // UTF-8 with two bytes.
|
||||
var c2 = bytes[cursor++];
|
||||
codeUnits.push(((c & 31) << 6) | (c2 & 63));
|
||||
} else if (c < 240) { // UTF-8 with three bytes.
|
||||
var c2 = bytes[cursor++];
|
||||
var c3 = bytes[cursor++];
|
||||
codeUnits.push(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
|
||||
} else if (c < 248) { // UTF-8 with 4 bytes.
|
||||
var c2 = bytes[cursor++];
|
||||
var c3 = bytes[cursor++];
|
||||
var c4 = bytes[cursor++];
|
||||
// Characters written on 4 bytes have 21 bits for a codepoint.
|
||||
// We can't fit that on 16bit characters, so we use surrogates.
|
||||
var codepoint = ((c & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63);
|
||||
// Surrogates formula from wikipedia.
|
||||
// 1. Subtract 0x10000 from codepoint
|
||||
codepoint -= 0x10000;
|
||||
// 2. Split this into the high 10-bit value and the low 10-bit value
|
||||
// 3. Add 0xD800 to the high value to form the high surrogate
|
||||
// 4. Add 0xDC00 to the low value to form the low surrogate:
|
||||
var low = (codepoint & 1023) + 0xDC00;
|
||||
var high = ((codepoint >> 10) & 1023) + 0xD800;
|
||||
codeUnits.push(high, low);
|
||||
}
|
||||
|
||||
// Avoid exceeding the maximum stack size when calling `apply`.
|
||||
if (codeUnits.length >= 8192) {
|
||||
result += String.fromCharCode.apply(null, codeUnits);
|
||||
codeUnits.length = 0;
|
||||
}
|
||||
}
|
||||
result += goog.crypt.byteArrayToString(codeUnits);
|
||||
this.cursor_ = cursor;
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads and parses a UTF-8 encoded unicode string (with length prefix) from
|
||||
* the stream.
|
||||
* @return {string} The decoded string.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readStringWithLength = function() {
|
||||
var length = this.readUnsignedVarint32();
|
||||
return this.readString(length);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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 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;
|
||||
goog.asserts.fail('Invalid byte length!');
|
||||
return new Uint8Array(0);
|
||||
}
|
||||
|
||||
var result = this.bytes_.subarray(this.cursor_, this.cursor_ + length);
|
||||
|
||||
this.cursor_ += length;
|
||||
goog.asserts.assert(this.cursor_ <= this.end_);
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a 64-bit varint from the stream and returns it as an 8-character
|
||||
* Unicode string for use as a hash table key.
|
||||
*
|
||||
* @return {string} The hash value.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readVarintHash64 = function() {
|
||||
return this.readSplitVarint64(jspb.utils.joinHash64);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Reads a 64-bit fixed-width value from the stream and returns it as an
|
||||
* 8-character Unicode string for use as a hash table key.
|
||||
*
|
||||
* @return {string} The hash value.
|
||||
*/
|
||||
jspb.BinaryDecoder.prototype.readFixedHash64 = function() {
|
||||
var bytes = this.bytes_;
|
||||
var cursor = this.cursor_;
|
||||
|
||||
var a = bytes[cursor + 0];
|
||||
var b = bytes[cursor + 1];
|
||||
var c = bytes[cursor + 2];
|
||||
var d = bytes[cursor + 3];
|
||||
var e = bytes[cursor + 4];
|
||||
var f = bytes[cursor + 5];
|
||||
var g = bytes[cursor + 6];
|
||||
var h = bytes[cursor + 7];
|
||||
|
||||
this.cursor_ += 8;
|
||||
|
||||
return String.fromCharCode(a, b, c, d, e, f, g, h);
|
||||
};
|
481
deps/protobuf/js/binary/decoder_test.js
vendored
Normal file
481
deps/protobuf/js/binary/decoder_test.js
vendored
Normal file
@ -0,0 +1,481 @@
|
||||
// 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 Test cases for jspb's binary protocol buffer decoder.
|
||||
*
|
||||
* There are two particular magic numbers that need to be pointed out -
|
||||
* 2^64-1025 is the largest number representable as both a double and an
|
||||
* unsigned 64-bit integer, and 2^63-513 is the largest number representable as
|
||||
* both a double and a signed 64-bit integer.
|
||||
*
|
||||
* Test suite is written using Jasmine -- see http://jasmine.github.io/
|
||||
*
|
||||
* @author aappleby@google.com (Austin Appleby)
|
||||
*/
|
||||
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('jspb.BinaryConstants');
|
||||
goog.require('jspb.BinaryDecoder');
|
||||
goog.require('jspb.BinaryEncoder');
|
||||
goog.require('jspb.utils');
|
||||
|
||||
|
||||
/**
|
||||
* Tests encoding and decoding of unsigned types.
|
||||
* @param {Function} readValue
|
||||
* @param {Function} writeValue
|
||||
* @param {number} epsilon
|
||||
* @param {number} upperLimit
|
||||
* @param {Function} filter
|
||||
* @suppress {missingProperties|visibility}
|
||||
*/
|
||||
function doTestUnsignedValue(readValue,
|
||||
writeValue, epsilon, upperLimit, filter) {
|
||||
var encoder = new jspb.BinaryEncoder();
|
||||
|
||||
// Encode zero and limits.
|
||||
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(encoder, filter(cursor));
|
||||
}
|
||||
|
||||
var decoder = jspb.BinaryDecoder.alloc(encoder.end());
|
||||
|
||||
// Check zero and limits.
|
||||
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(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 encoding and decoding of signed types.
|
||||
* @param {Function} readValue
|
||||
* @param {Function} writeValue
|
||||
* @param {number} epsilon
|
||||
* @param {number} lowerLimit
|
||||
* @param {number} upperLimit
|
||||
* @param {Function} filter
|
||||
* @suppress {missingProperties}
|
||||
*/
|
||||
function doTestSignedValue(readValue,
|
||||
writeValue, epsilon, lowerLimit, upperLimit, filter) {
|
||||
var encoder = new jspb.BinaryEncoder();
|
||||
|
||||
// Encode zero and limits.
|
||||
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(encoder, val);
|
||||
inputValues.push(val);
|
||||
}
|
||||
|
||||
// Encode positive values.
|
||||
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
|
||||
var val = filter(cursor);
|
||||
writeValue.call(encoder, val);
|
||||
inputValues.push(val);
|
||||
}
|
||||
|
||||
var decoder = jspb.BinaryDecoder.alloc(encoder.end());
|
||||
|
||||
// Check zero and limits.
|
||||
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(decoder));
|
||||
}
|
||||
|
||||
// Encoding values outside the valid range should assert.
|
||||
var pastLowerLimit = lowerLimit * 1.1;
|
||||
var pastUpperLimit = upperLimit * 1.1;
|
||||
if (pastLowerLimit !== -Infinity) {
|
||||
expect(() => void writeValue.call(encoder, pastLowerLimit)).toThrow();
|
||||
}
|
||||
if (pastUpperLimit !== Infinity) {
|
||||
expect(() => void writeValue.call(encoder, pastUpperLimit)).toThrow();
|
||||
}
|
||||
}
|
||||
|
||||
describe('binaryDecoderTest', function() {
|
||||
/**
|
||||
* Tests the decoder instance cache.
|
||||
*/
|
||||
it('testInstanceCache', /** @suppress {visibility} */ function() {
|
||||
// Empty the instance caches.
|
||||
jspb.BinaryDecoder.instanceCache_ = [];
|
||||
|
||||
// Allocating and then freeing a decoder should put it in the instance
|
||||
// cache.
|
||||
jspb.BinaryDecoder.alloc().free();
|
||||
|
||||
assertEquals(1, jspb.BinaryDecoder.instanceCache_.length);
|
||||
|
||||
// Allocating and then freeing three decoders should leave us with three in
|
||||
// the cache.
|
||||
|
||||
var decoder1 = jspb.BinaryDecoder.alloc();
|
||||
var decoder2 = jspb.BinaryDecoder.alloc();
|
||||
var decoder3 = jspb.BinaryDecoder.alloc();
|
||||
decoder1.free();
|
||||
decoder2.free();
|
||||
decoder3.free();
|
||||
|
||||
assertEquals(3, jspb.BinaryDecoder.instanceCache_.length);
|
||||
});
|
||||
|
||||
|
||||
describe('varint64', function() {
|
||||
var /** !jspb.BinaryEncoder */ encoder;
|
||||
var /** !jspb.BinaryDecoder */ decoder;
|
||||
|
||||
var hashA = String.fromCharCode(0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00);
|
||||
var hashB = String.fromCharCode(0x12, 0x34, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00);
|
||||
var hashC = String.fromCharCode(0x12, 0x34, 0x56, 0x78,
|
||||
0x87, 0x65, 0x43, 0x21);
|
||||
var hashD = String.fromCharCode(0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0xFF, 0xFF, 0xFF, 0xFF);
|
||||
beforeEach(function() {
|
||||
encoder = new jspb.BinaryEncoder();
|
||||
|
||||
encoder.writeVarintHash64(hashA);
|
||||
encoder.writeVarintHash64(hashB);
|
||||
encoder.writeVarintHash64(hashC);
|
||||
encoder.writeVarintHash64(hashD);
|
||||
|
||||
encoder.writeFixedHash64(hashA);
|
||||
encoder.writeFixedHash64(hashB);
|
||||
encoder.writeFixedHash64(hashC);
|
||||
encoder.writeFixedHash64(hashD);
|
||||
|
||||
decoder = jspb.BinaryDecoder.alloc(encoder.end());
|
||||
});
|
||||
|
||||
it('reads 64-bit integers as hash strings', function() {
|
||||
assertEquals(hashA, decoder.readVarintHash64());
|
||||
assertEquals(hashB, decoder.readVarintHash64());
|
||||
assertEquals(hashC, decoder.readVarintHash64());
|
||||
assertEquals(hashD, decoder.readVarintHash64());
|
||||
|
||||
assertEquals(hashA, decoder.readFixedHash64());
|
||||
assertEquals(hashB, decoder.readFixedHash64());
|
||||
assertEquals(hashC, decoder.readFixedHash64());
|
||||
assertEquals(hashD, decoder.readFixedHash64());
|
||||
});
|
||||
|
||||
it('reads split 64 bit integers', function() {
|
||||
function hexJoin(bitsLow, bitsHigh) {
|
||||
return `0x${(bitsHigh >>> 0).toString(16)}:0x${
|
||||
(bitsLow >>> 0).toString(16)}`;
|
||||
}
|
||||
function hexJoinHash(hash64) {
|
||||
jspb.utils.splitHash64(hash64);
|
||||
return hexJoin(jspb.utils.split64Low, jspb.utils.split64High);
|
||||
}
|
||||
|
||||
expect(decoder.readSplitVarint64(hexJoin)).toEqual(hexJoinHash(hashA));
|
||||
expect(decoder.readSplitVarint64(hexJoin)).toEqual(hexJoinHash(hashB));
|
||||
expect(decoder.readSplitVarint64(hexJoin)).toEqual(hexJoinHash(hashC));
|
||||
expect(decoder.readSplitVarint64(hexJoin)).toEqual(hexJoinHash(hashD));
|
||||
|
||||
expect(decoder.readSplitFixed64(hexJoin)).toEqual(hexJoinHash(hashA));
|
||||
expect(decoder.readSplitFixed64(hexJoin)).toEqual(hexJoinHash(hashB));
|
||||
expect(decoder.readSplitFixed64(hexJoin)).toEqual(hexJoinHash(hashC));
|
||||
expect(decoder.readSplitFixed64(hexJoin)).toEqual(hexJoinHash(hashD));
|
||||
});
|
||||
});
|
||||
|
||||
describe('sint64', function() {
|
||||
var /** !jspb.BinaryDecoder */ decoder;
|
||||
|
||||
var hashA =
|
||||
String.fromCharCode(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
var hashB =
|
||||
String.fromCharCode(0x12, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00);
|
||||
var hashC =
|
||||
String.fromCharCode(0x12, 0x34, 0x56, 0x78, 0x87, 0x65, 0x43, 0x21);
|
||||
var hashD =
|
||||
String.fromCharCode(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||
beforeEach(function() {
|
||||
var encoder = new jspb.BinaryEncoder();
|
||||
|
||||
encoder.writeZigzagVarintHash64(hashA);
|
||||
encoder.writeZigzagVarintHash64(hashB);
|
||||
encoder.writeZigzagVarintHash64(hashC);
|
||||
encoder.writeZigzagVarintHash64(hashD);
|
||||
|
||||
decoder = jspb.BinaryDecoder.alloc(encoder.end());
|
||||
});
|
||||
|
||||
it('reads 64-bit integers as decimal strings', function() {
|
||||
const signed = true;
|
||||
expect(decoder.readZigzagVarint64String())
|
||||
.toEqual(jspb.utils.hash64ToDecimalString(hashA, signed));
|
||||
expect(decoder.readZigzagVarint64String())
|
||||
.toEqual(jspb.utils.hash64ToDecimalString(hashB, signed));
|
||||
expect(decoder.readZigzagVarint64String())
|
||||
.toEqual(jspb.utils.hash64ToDecimalString(hashC, signed));
|
||||
expect(decoder.readZigzagVarint64String())
|
||||
.toEqual(jspb.utils.hash64ToDecimalString(hashD, signed));
|
||||
});
|
||||
|
||||
it('reads 64-bit integers as hash strings', function() {
|
||||
expect(decoder.readZigzagVarintHash64()).toEqual(hashA);
|
||||
expect(decoder.readZigzagVarintHash64()).toEqual(hashB);
|
||||
expect(decoder.readZigzagVarintHash64()).toEqual(hashC);
|
||||
expect(decoder.readZigzagVarintHash64()).toEqual(hashD);
|
||||
});
|
||||
|
||||
it('reads split 64 bit zigzag integers', function() {
|
||||
function hexJoin(bitsLow, bitsHigh) {
|
||||
return `0x${(bitsHigh >>> 0).toString(16)}:0x${
|
||||
(bitsLow >>> 0).toString(16)}`;
|
||||
}
|
||||
function hexJoinHash(hash64) {
|
||||
jspb.utils.splitHash64(hash64);
|
||||
return hexJoin(jspb.utils.split64Low, jspb.utils.split64High);
|
||||
}
|
||||
|
||||
expect(decoder.readSplitZigzagVarint64(hexJoin))
|
||||
.toEqual(hexJoinHash(hashA));
|
||||
expect(decoder.readSplitZigzagVarint64(hexJoin))
|
||||
.toEqual(hexJoinHash(hashB));
|
||||
expect(decoder.readSplitZigzagVarint64(hexJoin))
|
||||
.toEqual(hexJoinHash(hashC));
|
||||
expect(decoder.readSplitZigzagVarint64(hexJoin))
|
||||
.toEqual(hexJoinHash(hashD));
|
||||
});
|
||||
|
||||
it('does zigzag encoding properly', function() {
|
||||
// Test cases directly from the protobuf dev guide.
|
||||
// https://engdoc.corp.google.com/eng/howto/protocolbuffers/developerguide/encoding.shtml?cl=head#types
|
||||
var testCases = [
|
||||
{original: '0', zigzag: '0'},
|
||||
{original: '-1', zigzag: '1'},
|
||||
{original: '1', zigzag: '2'},
|
||||
{original: '-2', zigzag: '3'},
|
||||
{original: '2147483647', zigzag: '4294967294'},
|
||||
{original: '-2147483648', zigzag: '4294967295'},
|
||||
// 64-bit extremes, not in dev guide.
|
||||
{original: '9223372036854775807', zigzag: '18446744073709551614'},
|
||||
{original: '-9223372036854775808', zigzag: '18446744073709551615'},
|
||||
// None of the above catch: bitsLow < 0 && bitsHigh > 0 && bitsHigh <
|
||||
// 0x1FFFFF. The following used to be broken.
|
||||
{original: '72000000000', zigzag: '144000000000'},
|
||||
];
|
||||
var encoder = new jspb.BinaryEncoder();
|
||||
testCases.forEach(function(c) {
|
||||
encoder.writeZigzagVarint64String(c.original);
|
||||
});
|
||||
var buffer = encoder.end();
|
||||
var zigzagDecoder = jspb.BinaryDecoder.alloc(buffer);
|
||||
var varintDecoder = jspb.BinaryDecoder.alloc(buffer);
|
||||
testCases.forEach(function(c) {
|
||||
expect(zigzagDecoder.readZigzagVarint64String()).toEqual(c.original);
|
||||
expect(varintDecoder.readUnsignedVarint64String()).toEqual(c.zigzag);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests reading and writing large strings
|
||||
*/
|
||||
it('testLargeStrings', function() {
|
||||
var encoder = new jspb.BinaryEncoder();
|
||||
|
||||
var len = 150000;
|
||||
var long_string = '';
|
||||
for (var i = 0; i < len; i++) {
|
||||
long_string += 'a';
|
||||
}
|
||||
|
||||
encoder.writeString(long_string);
|
||||
|
||||
var decoder = jspb.BinaryDecoder.alloc(encoder.end());
|
||||
|
||||
assertEquals(long_string, decoder.readString(len));
|
||||
});
|
||||
|
||||
/**
|
||||
* Test encoding and decoding utf-8.
|
||||
*/
|
||||
it('testUtf8', function() {
|
||||
var encoder = new jspb.BinaryEncoder();
|
||||
|
||||
var ascii = "ASCII should work in 3, 2, 1...";
|
||||
var utf8_two_bytes = "©";
|
||||
var utf8_three_bytes = "❄";
|
||||
var utf8_four_bytes = "😁";
|
||||
|
||||
encoder.writeString(ascii);
|
||||
encoder.writeString(utf8_two_bytes);
|
||||
encoder.writeString(utf8_three_bytes);
|
||||
encoder.writeString(utf8_four_bytes);
|
||||
|
||||
var decoder = jspb.BinaryDecoder.alloc(encoder.end());
|
||||
|
||||
assertEquals(ascii, decoder.readString(ascii.length));
|
||||
assertEquals(utf8_two_bytes, decoder.readString(utf8_two_bytes.length));
|
||||
assertEquals(utf8_three_bytes, decoder.readString(utf8_three_bytes.length));
|
||||
assertEquals(utf8_four_bytes, decoder.readString(utf8_four_bytes.length));
|
||||
});
|
||||
|
||||
/**
|
||||
* Verifies that misuse of the decoder class triggers assertions.
|
||||
*/
|
||||
it('testDecodeErrors', function() {
|
||||
// Reading a value past the end of the stream should trigger an assertion.
|
||||
var decoder = jspb.BinaryDecoder.alloc([0, 1, 2]);
|
||||
assertThrows(function() {decoder.readUint64()});
|
||||
|
||||
// Overlong varints should trigger assertions.
|
||||
decoder.setBlock([255, 255, 255, 255, 255, 255,
|
||||
255, 255, 255, 255, 255, 0]);
|
||||
assertThrows(function() {decoder.readUnsignedVarint64()});
|
||||
decoder.reset();
|
||||
assertThrows(function() {decoder.readSignedVarint64()});
|
||||
decoder.reset();
|
||||
assertThrows(function() {decoder.readZigzagVarint64()});
|
||||
decoder.reset();
|
||||
assertThrows(function() {decoder.readUnsignedVarint32()});
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests encoding and decoding of unsigned integers.
|
||||
*/
|
||||
it('testUnsignedIntegers', function() {
|
||||
doTestUnsignedValue(
|
||||
jspb.BinaryDecoder.prototype.readUint8,
|
||||
jspb.BinaryEncoder.prototype.writeUint8,
|
||||
1, 0xFF, Math.round);
|
||||
|
||||
doTestUnsignedValue(
|
||||
jspb.BinaryDecoder.prototype.readUint16,
|
||||
jspb.BinaryEncoder.prototype.writeUint16,
|
||||
1, 0xFFFF, Math.round);
|
||||
|
||||
doTestUnsignedValue(
|
||||
jspb.BinaryDecoder.prototype.readUint32,
|
||||
jspb.BinaryEncoder.prototype.writeUint32,
|
||||
1, 0xFFFFFFFF, Math.round);
|
||||
|
||||
doTestUnsignedValue(
|
||||
jspb.BinaryDecoder.prototype.readUint64,
|
||||
jspb.BinaryEncoder.prototype.writeUint64,
|
||||
1, Math.pow(2, 64) - 1025, Math.round);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests encoding and decoding of signed integers.
|
||||
*/
|
||||
it('testSignedIntegers', function() {
|
||||
doTestSignedValue(
|
||||
jspb.BinaryDecoder.prototype.readInt8,
|
||||
jspb.BinaryEncoder.prototype.writeInt8,
|
||||
1, -0x80, 0x7F, Math.round);
|
||||
|
||||
doTestSignedValue(
|
||||
jspb.BinaryDecoder.prototype.readInt16,
|
||||
jspb.BinaryEncoder.prototype.writeInt16,
|
||||
1, -0x8000, 0x7FFF, Math.round);
|
||||
|
||||
doTestSignedValue(
|
||||
jspb.BinaryDecoder.prototype.readInt32,
|
||||
jspb.BinaryEncoder.prototype.writeInt32,
|
||||
1, -0x80000000, 0x7FFFFFFF, Math.round);
|
||||
|
||||
doTestSignedValue(
|
||||
jspb.BinaryDecoder.prototype.readInt64,
|
||||
jspb.BinaryEncoder.prototype.writeInt64,
|
||||
1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests encoding and decoding of floats.
|
||||
*/
|
||||
it('testFloats', function() {
|
||||
/**
|
||||
* @param {number} x
|
||||
* @return {number}
|
||||
*/
|
||||
function truncate(x) {
|
||||
var temp = new Float32Array(1);
|
||||
temp[0] = x;
|
||||
return temp[0];
|
||||
}
|
||||
doTestSignedValue(
|
||||
jspb.BinaryDecoder.prototype.readFloat,
|
||||
jspb.BinaryEncoder.prototype.writeFloat,
|
||||
jspb.BinaryConstants.FLOAT32_EPS,
|
||||
-jspb.BinaryConstants.FLOAT32_MAX,
|
||||
jspb.BinaryConstants.FLOAT32_MAX,
|
||||
truncate);
|
||||
|
||||
doTestSignedValue(
|
||||
jspb.BinaryDecoder.prototype.readDouble,
|
||||
jspb.BinaryEncoder.prototype.writeDouble,
|
||||
jspb.BinaryConstants.FLOAT64_EPS * 10,
|
||||
-jspb.BinaryConstants.FLOAT64_MAX,
|
||||
jspb.BinaryConstants.FLOAT64_MAX,
|
||||
function(x) { return x; });
|
||||
});
|
||||
});
|
510
deps/protobuf/js/binary/encoder.js
vendored
Normal file
510
deps/protobuf/js/binary/encoder.js
vendored
Normal file
@ -0,0 +1,510 @@
|
||||
// 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 64-bit integer in 32:32 split representation into its wire-format
|
||||
* fixed 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.writeSplitFixed64 = 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));
|
||||
this.writeUint32(lowBits);
|
||||
this.writeUint32(highBits);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* 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);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Encodes a JavaScript decimal string into its wire-format, zigzag-encoded
|
||||
* varint representation and stores it in the buffer. Integers not representable
|
||||
* in 64 bits will be truncated.
|
||||
* @param {string} value The integer to convert.
|
||||
*/
|
||||
jspb.BinaryEncoder.prototype.writeZigzagVarint64String = function(value) {
|
||||
this.writeZigzagVarintHash64(jspb.utils.decimalStringToHash64(value));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes a 64-bit hash string (8 characters @ 8 bits of data each) to the
|
||||
* buffer as a zigzag varint.
|
||||
* @param {string} hash The hash to write.
|
||||
*/
|
||||
jspb.BinaryEncoder.prototype.writeZigzagVarintHash64 = function(hash) {
|
||||
var self = this;
|
||||
jspb.utils.splitHash64(hash);
|
||||
jspb.utils.toZigzag64(
|
||||
jspb.utils.split64Low, jspb.utils.split64High, function(lo, hi) {
|
||||
self.writeSplitVarint64(lo >>> 0, hi >>> 0);
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes an 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 an 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.writeSplitFixed64(jspb.utils.split64Low, jspb.utils.split64High);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Writes a 64-bit integer decimal strings to the buffer. Numbers outside the
|
||||
* range [-2^63,2^63) will be truncated.
|
||||
* @param {string} value The value to write.
|
||||
*/
|
||||
jspb.BinaryEncoder.prototype.writeInt64String = 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.splitHash64(jspb.utils.decimalStringToHash64(value));
|
||||
this.writeSplitFixed64(jspb.utils.split64Low, 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 === Infinity || value === -Infinity || isNaN(value) ||
|
||||
((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 === Infinity || value === -Infinity || isNaN(value) ||
|
||||
((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. We allow numbers as input
|
||||
* because the JSPB code generator uses 0/1 instead of true/false to save space
|
||||
* in the string representation of the proto.
|
||||
* @param {boolean|number} value The value to write.
|
||||
*/
|
||||
jspb.BinaryEncoder.prototype.writeBool = function(value) {
|
||||
goog.asserts.assert(typeof value === 'boolean' || typeof value === 'number');
|
||||
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;
|
||||
|
||||
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 if (c < 65536) {
|
||||
// Look for surrogates
|
||||
if (c >= 0xD800 && c <= 0xDBFF && i + 1 < value.length) {
|
||||
var second = value.charCodeAt(i + 1);
|
||||
if (second >= 0xDC00 && second <= 0xDFFF) { // low surrogate
|
||||
// http://mathiasbynens.be/notes/javascript-encoding#surrogate-formulae
|
||||
c = (c - 0xD800) * 0x400 + second - 0xDC00 + 0x10000;
|
||||
|
||||
this.buffer_.push((c >> 18) | 240);
|
||||
this.buffer_.push(((c >> 12) & 63 ) | 128);
|
||||
this.buffer_.push(((c >> 6) & 63) | 128);
|
||||
this.buffer_.push((c & 63) | 128);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
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;
|
||||
};
|
60
deps/protobuf/js/binary/message_test.js
vendored
Normal file
60
deps/protobuf/js/binary/message_test.js
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
// 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.
|
||||
|
||||
// Test suite is written using Jasmine -- see http://jasmine.github.io/
|
||||
|
||||
goog.setTestOnly();
|
||||
|
||||
goog.require('goog.testing.asserts');
|
||||
|
||||
// CommonJS-LoadFromFile: test_pb proto.jspb.test
|
||||
goog.require('proto.jspb.test.Deeply.Nested.Message');
|
||||
|
||||
// CommonJS-LoadFromFile: test2_pb proto.jspb.test
|
||||
goog.require('proto.jspb.test.ForeignNestedFieldMessage');
|
||||
|
||||
describe('Message test suite', function() {
|
||||
// Verify that we can successfully use a field referring to a nested message
|
||||
// from a different .proto file.
|
||||
it('testForeignNestedMessage', function() {
|
||||
var msg = new proto.jspb.test.ForeignNestedFieldMessage();
|
||||
var nested = new proto.jspb.test.Deeply.Nested.Message();
|
||||
nested.setCount(5);
|
||||
msg.setDeeplyNestedMessage(nested);
|
||||
assertEquals(5, msg.getDeeplyNestedMessage().getCount());
|
||||
|
||||
// After a serialization-deserialization round trip we should get back the
|
||||
// same data we started with.
|
||||
var serialized = msg.serializeBinary();
|
||||
var deserialized =
|
||||
proto.jspb.test.ForeignNestedFieldMessage.deserializeBinary(serialized);
|
||||
assertEquals(5, deserialized.getDeeplyNestedMessage().getCount());
|
||||
});
|
||||
});
|
665
deps/protobuf/js/binary/proto_test.js
vendored
Normal file
665
deps/protobuf/js/binary/proto_test.js
vendored
Normal file
@ -0,0 +1,665 @@
|
||||
// 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.
|
||||
|
||||
// Test suite is written using Jasmine -- see http://jasmine.github.io/
|
||||
|
||||
goog.require('goog.crypt.base64');
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('jspb.BinaryWriter');
|
||||
goog.require('jspb.Message');
|
||||
|
||||
// CommonJS-LoadFromFile: ../testbinary_pb proto.jspb.test
|
||||
goog.require('proto.jspb.test.ExtendsWithMessage');
|
||||
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');
|
||||
|
||||
// CommonJS-LoadFromFile: ../node_modules/google-protobuf/google/protobuf/any_pb proto.google.protobuf
|
||||
goog.require('proto.google.protobuf.Any');
|
||||
|
||||
|
||||
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
|
||||
*/
|
||||
function fillAllFields(msg) {
|
||||
msg.setOptionalInt32(-42);
|
||||
// can be exactly represented by JS number (64-bit double, i.e., 52-bit
|
||||
// mantissa).
|
||||
msg.setOptionalInt64(-0x7fffffff00000000);
|
||||
msg.setOptionalUint32(0x80000000);
|
||||
msg.setOptionalUint64(0xf000000000000000);
|
||||
msg.setOptionalSint32(-100);
|
||||
msg.setOptionalSint64(-0x8000000000000000);
|
||||
msg.setOptionalFixed32(1234);
|
||||
msg.setOptionalFixed64(0x1234567800000000);
|
||||
msg.setOptionalSfixed32(-1234);
|
||||
msg.setOptionalSfixed64(-0x1234567800000000);
|
||||
msg.setOptionalFloat(1.5);
|
||||
msg.setOptionalDouble(-1.5);
|
||||
msg.setOptionalBool(true);
|
||||
msg.setOptionalString('hello world');
|
||||
msg.setOptionalBytes(BYTES);
|
||||
msg.setOptionalGroup(new proto.jspb.test.TestAllTypes.OptionalGroup());
|
||||
msg.getOptionalGroup().setA(100);
|
||||
var submsg = new proto.jspb.test.ForeignMessage();
|
||||
submsg.setC(16);
|
||||
msg.setOptionalForeignMessage(submsg);
|
||||
msg.setOptionalForeignEnum(proto.jspb.test.ForeignEnum.FOREIGN_FOO);
|
||||
msg.setOneofString('oneof');
|
||||
|
||||
|
||||
msg.setRepeatedInt32List([-42]);
|
||||
msg.setRepeatedInt64List([-0x7fffffff00000000]);
|
||||
msg.setRepeatedUint32List([0x80000000]);
|
||||
msg.setRepeatedUint64List([0xf000000000000000]);
|
||||
msg.setRepeatedSint32List([-100]);
|
||||
msg.setRepeatedSint64List([-0x8000000000000000]);
|
||||
msg.setRepeatedFixed32List([1234]);
|
||||
msg.setRepeatedFixed64List([0x1234567800000000]);
|
||||
msg.setRepeatedSfixed32List([-1234]);
|
||||
msg.setRepeatedSfixed64List([-0x1234567800000000]);
|
||||
msg.setRepeatedFloatList([1.5]);
|
||||
msg.setRepeatedDoubleList([-1.5]);
|
||||
msg.setRepeatedBoolList([true]);
|
||||
msg.setRepeatedStringList(['hello world']);
|
||||
msg.setRepeatedBytesList([BYTES, BYTES]);
|
||||
msg.setRepeatedGroupList([new proto.jspb.test.TestAllTypes.RepeatedGroup()]);
|
||||
msg.getRepeatedGroupList()[0].setA(100);
|
||||
submsg = new proto.jspb.test.ForeignMessage();
|
||||
submsg.setC(1000);
|
||||
msg.setRepeatedForeignMessageList([submsg]);
|
||||
msg.setRepeatedForeignEnumList([proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
|
||||
|
||||
msg.setPackedRepeatedInt32List([-42]);
|
||||
msg.setPackedRepeatedInt64List([-0x7fffffff00000000]);
|
||||
msg.setPackedRepeatedUint32List([0x80000000]);
|
||||
msg.setPackedRepeatedUint64List([0xf000000000000000]);
|
||||
msg.setPackedRepeatedSint32List([-100]);
|
||||
msg.setPackedRepeatedSint64List([-0x8000000000000000]);
|
||||
msg.setPackedRepeatedFixed32List([1234]);
|
||||
msg.setPackedRepeatedFixed64List([0x1234567800000000]);
|
||||
msg.setPackedRepeatedSfixed32List([-1234]);
|
||||
msg.setPackedRepeatedSfixed64List([-0x1234567800000000]);
|
||||
msg.setPackedRepeatedFloatList([1.5]);
|
||||
msg.setPackedRepeatedDoubleList([-1.5]);
|
||||
msg.setPackedRepeatedBoolList([true]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper: compare a bytes field to an expected value
|
||||
* @param {Uint8Array|string} arr
|
||||
* @param {Uint8Array} expected
|
||||
* @return {boolean}
|
||||
*/
|
||||
function bytesCompare(arr, expected) {
|
||||
if (typeof arr === 'string') {
|
||||
arr = goog.crypt.base64.decodeStringToUint8Array(arr);
|
||||
}
|
||||
if (arr.length != expected.length) {
|
||||
return false;
|
||||
}
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
if (arr[i] != expected[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper: verify contents of given TestAllTypes message as set by
|
||||
* fillAllFields().
|
||||
* @param {proto.jspb.test.TestAllTypes} original
|
||||
* @param {proto.jspb.test.TestAllTypes} copy
|
||||
*/
|
||||
function checkAllFields(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(copy.getOneofString(), 'oneof');
|
||||
assertEquals(copy.getOneofFieldCase(),
|
||||
proto.jspb.test.TestAllTypes.OneofFieldCase.ONEOF_STRING);
|
||||
|
||||
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(copy.getPackedRepeatedInt32List(), [-42]);
|
||||
assertElementsEquals(copy.getPackedRepeatedInt64List(),
|
||||
[-0x7fffffff00000000]);
|
||||
assertElementsEquals(copy.getPackedRepeatedUint32List(), [0x80000000]);
|
||||
assertElementsEquals(copy.getPackedRepeatedUint64List(),
|
||||
[0xf000000000000000]);
|
||||
assertElementsEquals(copy.getPackedRepeatedSint32List(), [-100]);
|
||||
assertElementsEquals(copy.getPackedRepeatedSint64List(),
|
||||
[-0x8000000000000000]);
|
||||
assertElementsEquals(copy.getPackedRepeatedFixed32List(), [1234]);
|
||||
assertElementsEquals(copy.getPackedRepeatedFixed64List(),
|
||||
[0x1234567800000000]);
|
||||
assertElementsEquals(copy.getPackedRepeatedSfixed32List(), [-1234]);
|
||||
assertElementsEquals(copy.getPackedRepeatedSfixed64List(),
|
||||
[-0x1234567800000000]);
|
||||
assertElementsEquals(copy.getPackedRepeatedFloatList(), [1.5]);
|
||||
assertElementsEquals(copy.getPackedRepeatedDoubleList(), [-1.5]);
|
||||
|
||||
|
||||
// Check last so we get more granular errors first.
|
||||
assertTrue(jspb.Message.equals(original, copy));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper: verify that all expected extensions are present.
|
||||
* @param {!proto.jspb.test.TestExtendable} msg
|
||||
*/
|
||||
function checkExtensions(msg) {
|
||||
assertEquals(0, msg.getExtension(proto.jspb.test.extendOptionalInt32));
|
||||
assertEquals(-0x7fffffff00000000,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalInt64));
|
||||
assertEquals(0x80000000,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalUint32));
|
||||
assertEquals(0xf000000000000000,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalUint64));
|
||||
assertEquals(-100,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalSint32));
|
||||
assertEquals(-0x8000000000000000,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalSint64));
|
||||
assertEquals(1234,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalFixed32));
|
||||
assertEquals(0x1234567800000000,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalFixed64));
|
||||
assertEquals(-1234,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalSfixed32));
|
||||
assertEquals(-0x1234567800000000,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalSfixed64));
|
||||
assertEquals(1.5,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalFloat));
|
||||
assertEquals(-1.5,
|
||||
msg.getExtension(proto.jspb.test.extendOptionalDouble));
|
||||
assertEquals(true,
|
||||
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(16,
|
||||
msg.getExtension(
|
||||
proto.jspb.test.ExtendsWithMessage.optionalExtension).getFoo());
|
||||
|
||||
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedInt32List),
|
||||
[-42]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedInt64List),
|
||||
[-0x7fffffff00000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedUint32List),
|
||||
[0x80000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedUint64List),
|
||||
[0xf000000000000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedSint32List),
|
||||
[-100]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedSint64List),
|
||||
[-0x8000000000000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedFixed32List),
|
||||
[1234]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedFixed64List),
|
||||
[0x1234567800000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedSfixed32List),
|
||||
[-1234]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedSfixed64List),
|
||||
[-0x1234567800000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedFloatList),
|
||||
[1.5]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedDoubleList),
|
||||
[-1.5]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedBoolList),
|
||||
[true]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedStringList),
|
||||
['hello world']);
|
||||
assertEquals(
|
||||
true,
|
||||
bytesCompare(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedBytesList)[0], BYTES));
|
||||
assertEquals(1000,
|
||||
msg.getExtension(
|
||||
proto.jspb.test.ExtendsWithMessage.repeatedExtensionList)[0]
|
||||
.getFoo());
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendRepeatedForeignEnumList),
|
||||
[proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
|
||||
|
||||
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedInt32List),
|
||||
[-42]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedInt64List),
|
||||
[-0x7fffffff00000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedUint32List),
|
||||
[0x80000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedUint64List),
|
||||
[0xf000000000000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedSint32List),
|
||||
[-100]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedSint64List),
|
||||
[-0x8000000000000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed32List),
|
||||
[1234]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedFixed64List),
|
||||
[0x1234567800000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed32List),
|
||||
[-1234]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedSfixed64List),
|
||||
[-0x1234567800000000]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedFloatList),
|
||||
[1.5]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedDoubleList),
|
||||
[-1.5]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedBoolList),
|
||||
[true]);
|
||||
assertElementsEquals(
|
||||
msg.getExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList),
|
||||
[proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
describe('protoBinaryTest', function() {
|
||||
/**
|
||||
* Tests a basic serialization-deserializaton round-trip with all supported
|
||||
* field types (on the TestAllTypes message type).
|
||||
*/
|
||||
it('testRoundTrip', function() {
|
||||
var msg = new proto.jspb.test.TestAllTypes();
|
||||
fillAllFields(msg);
|
||||
var encoded = msg.serializeBinary();
|
||||
var decoded = proto.jspb.test.TestAllTypes.deserializeBinary(encoded);
|
||||
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(typeof msg.getRepeatedBytesList_asB64()[0] === 'string');
|
||||
assertTrue(typeof msg.getRepeatedBytesList_asB64()[1] === 'string');
|
||||
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([]);
|
||||
assertEquals(0, msg.getRepeatedBytesList().length);
|
||||
assertEquals(0, msg.getRepeatedBytesList_asB64().length);
|
||||
assertEquals(0, msg.getRepeatedBytesList_asU8().length);
|
||||
});
|
||||
|
||||
/**
|
||||
* Helper: fill all extension values.
|
||||
* @param {proto.jspb.test.TestExtendable} msg
|
||||
*/
|
||||
function fillExtensions(msg) {
|
||||
msg.setExtension(proto.jspb.test.extendOptionalInt32, 0);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalInt64, -0x7fffffff00000000);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalUint32, 0x80000000);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalUint64, 0xf000000000000000);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalSint32, -100);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalSint64, -0x8000000000000000);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalFixed32, 1234);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalFixed64, 0x1234567800000000);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalSfixed32, -1234);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalSfixed64, -0x1234567800000000);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalFloat, 1.5);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalDouble, -1.5);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalBool, true);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalString, 'hello world');
|
||||
msg.setExtension(proto.jspb.test.extendOptionalBytes, BYTES);
|
||||
var submsg = new proto.jspb.test.ExtendsWithMessage();
|
||||
submsg.setFoo(16);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.ExtendsWithMessage.optionalExtension, submsg);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendOptionalForeignEnum,
|
||||
proto.jspb.test.ForeignEnum.FOREIGN_FOO);
|
||||
|
||||
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedInt32List, [-42]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedInt64List, [-0x7fffffff00000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedUint32List, [0x80000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedUint64List, [0xf000000000000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedSint32List, [-100]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedSint64List, [-0x8000000000000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedFixed32List, [1234]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedFixed64List, [0x1234567800000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedSfixed32List, [-1234]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedSfixed64List, [-0x1234567800000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedFloatList, [1.5]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedDoubleList, [-1.5]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedBoolList, [true]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendRepeatedStringList, ['hello world']);
|
||||
msg.setExtension(proto.jspb.test.extendRepeatedBytesList, [BYTES]);
|
||||
submsg = new proto.jspb.test.ExtendsWithMessage();
|
||||
submsg.setFoo(1000);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.ExtendsWithMessage.repeatedExtensionList, [submsg]);
|
||||
msg.setExtension(proto.jspb.test.extendRepeatedForeignEnumList,
|
||||
[proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
|
||||
|
||||
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedInt32List, [-42]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedInt64List, [-0x7fffffff00000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedUint32List, [0x80000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedUint64List, [0xf000000000000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedSint32List, [-100]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedSint64List, [-0x8000000000000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedFixed32List, [1234]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedFixed64List, [0x1234567800000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedSfixed32List, [-1234]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedSfixed64List,
|
||||
[-0x1234567800000000]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedFloatList, [1.5]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedDoubleList, [-1.5]);
|
||||
msg.setExtension(
|
||||
proto.jspb.test.extendPackedRepeatedBoolList, [true]);
|
||||
msg.setExtension(proto.jspb.test.extendPackedRepeatedForeignEnumList,
|
||||
[proto.jspb.test.ForeignEnum.FOREIGN_FOO]);
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests extension serialization and deserialization.
|
||||
*/
|
||||
it('testExtensions', function() {
|
||||
var msg = new proto.jspb.test.TestExtendable();
|
||||
fillExtensions(msg);
|
||||
var encoded = msg.serializeBinary();
|
||||
var decoded = proto.jspb.test.TestExtendable.deserializeBinary(encoded);
|
||||
checkExtensions(decoded);
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests that unknown extensions don't cause deserialization failure.
|
||||
*/
|
||||
it('testUnknownExtension', function() {
|
||||
var msg = new proto.jspb.test.TestExtendable();
|
||||
fillExtensions(msg);
|
||||
var writer = new jspb.BinaryWriter();
|
||||
writer.writeBool((1 << 29) - 1, true);
|
||||
proto.jspb.test.TestExtendable.serializeBinaryToWriter(msg, writer);
|
||||
var encoded = writer.getResultBuffer();
|
||||
var decoded = proto.jspb.test.TestExtendable.deserializeBinary(encoded);
|
||||
checkExtensions(decoded);
|
||||
});
|
||||
|
||||
it('testAnyWellKnownType', function() {
|
||||
var any = new proto.google.protobuf.Any();
|
||||
var msg = new proto.jspb.test.TestAllTypes();
|
||||
|
||||
fillAllFields(msg);
|
||||
|
||||
any.pack(msg.serializeBinary(), 'jspb.test.TestAllTypes');
|
||||
|
||||
assertEquals('type.googleapis.com/jspb.test.TestAllTypes',
|
||||
any.getTypeUrl());
|
||||
|
||||
var msg2 = any.unpack(
|
||||
proto.jspb.test.TestAllTypes.deserializeBinary,
|
||||
'jspb.test.TestAllTypes');
|
||||
|
||||
checkAllFields(msg, msg2);
|
||||
|
||||
});
|
||||
|
||||
});
|
1296
deps/protobuf/js/binary/reader.js
vendored
Normal file
1296
deps/protobuf/js/binary/reader.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
992
deps/protobuf/js/binary/reader_test.js
vendored
Normal file
992
deps/protobuf/js/binary/reader_test.js
vendored
Normal file
@ -0,0 +1,992 @@
|
||||
// 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 Test cases for jspb's binary protocol buffer reader.
|
||||
*
|
||||
* There are two particular magic numbers that need to be pointed out -
|
||||
* 2^64-1025 is the largest number representable as both a double and an
|
||||
* unsigned 64-bit integer, and 2^63-513 is the largest number representable as
|
||||
* both a double and a signed 64-bit integer.
|
||||
*
|
||||
* Test suite is written using Jasmine -- see http://jasmine.github.io/
|
||||
*
|
||||
* @author aappleby@google.com (Austin Appleby)
|
||||
*/
|
||||
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('jspb.BinaryConstants');
|
||||
goog.require('jspb.BinaryDecoder');
|
||||
goog.require('jspb.BinaryReader');
|
||||
goog.require('jspb.BinaryWriter');
|
||||
goog.require('jspb.utils');
|
||||
goog.requireType('jspb.BinaryMessage');
|
||||
|
||||
|
||||
describe('binaryReaderTest', function() {
|
||||
/**
|
||||
* Tests the reader instance cache.
|
||||
*/
|
||||
it('testInstanceCaches', /** @suppress {visibility} */ function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
writer.writeMessage(1, dummyMessage, goog.nullFunction);
|
||||
writer.writeMessage(2, dummyMessage, goog.nullFunction);
|
||||
|
||||
var buffer = writer.getResultBuffer();
|
||||
|
||||
// Empty the instance caches.
|
||||
jspb.BinaryReader.instanceCache_ = [];
|
||||
|
||||
// Allocating and then freeing three decoders should leave us with three in
|
||||
// the cache.
|
||||
|
||||
var decoder1 = jspb.BinaryDecoder.alloc();
|
||||
var decoder2 = jspb.BinaryDecoder.alloc();
|
||||
var decoder3 = jspb.BinaryDecoder.alloc();
|
||||
decoder1.free();
|
||||
decoder2.free();
|
||||
decoder3.free();
|
||||
|
||||
assertEquals(3, jspb.BinaryDecoder.instanceCache_.length);
|
||||
assertEquals(0, jspb.BinaryReader.instanceCache_.length);
|
||||
|
||||
// Allocating and then freeing a reader should remove one decoder from its
|
||||
// cache, but it should stay stuck to the reader afterwards since we can't
|
||||
// have a reader without a decoder.
|
||||
jspb.BinaryReader.alloc().free();
|
||||
|
||||
assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
|
||||
assertEquals(1, jspb.BinaryReader.instanceCache_.length);
|
||||
|
||||
// Allocating a reader should remove a reader from the cache.
|
||||
var reader = jspb.BinaryReader.alloc(buffer);
|
||||
|
||||
assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
|
||||
assertEquals(0, jspb.BinaryReader.instanceCache_.length);
|
||||
|
||||
// Processing the message reuses the current reader.
|
||||
reader.nextField();
|
||||
assertEquals(1, reader.getFieldNumber());
|
||||
reader.readMessage(dummyMessage, function() {
|
||||
assertEquals(0, jspb.BinaryReader.instanceCache_.length);
|
||||
});
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(2, reader.getFieldNumber());
|
||||
reader.readMessage(dummyMessage, function() {
|
||||
assertEquals(0, jspb.BinaryReader.instanceCache_.length);
|
||||
});
|
||||
|
||||
assertEquals(false, reader.nextField());
|
||||
|
||||
assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
|
||||
assertEquals(0, jspb.BinaryReader.instanceCache_.length);
|
||||
|
||||
// Freeing the reader should put it back into the cache.
|
||||
reader.free();
|
||||
|
||||
assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
|
||||
assertEquals(1, jspb.BinaryReader.instanceCache_.length);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @return {number}
|
||||
*/
|
||||
function truncate(x) {
|
||||
var temp = new Float32Array(1);
|
||||
temp[0] = x;
|
||||
return temp[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Verifies that misuse of the reader class triggers assertions.
|
||||
*/
|
||||
it('testReadErrors', /** @suppress {checkTypes|visibility} */ function() {
|
||||
// Calling readMessage on a non-delimited field should trigger an
|
||||
// assertion.
|
||||
var reader = jspb.BinaryReader.alloc([8, 1]);
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
reader.nextField();
|
||||
assertThrows(function() {
|
||||
reader.readMessage(dummyMessage, goog.nullFunction);
|
||||
});
|
||||
|
||||
// Reading past the end of the stream should trigger an assertion.
|
||||
reader = jspb.BinaryReader.alloc([9, 1]);
|
||||
reader.nextField();
|
||||
assertThrows(function() {
|
||||
reader.readFixed64()
|
||||
});
|
||||
|
||||
// Reading past the end of a submessage should trigger an assertion.
|
||||
reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]);
|
||||
reader.nextField();
|
||||
reader.readMessage(dummyMessage, function() {
|
||||
reader.nextField();
|
||||
assertThrows(function() {
|
||||
reader.readFixed32()
|
||||
});
|
||||
});
|
||||
|
||||
// Skipping an invalid field should trigger an assertion.
|
||||
reader = jspb.BinaryReader.alloc([12, 1]);
|
||||
reader.nextWireType_ = 1000;
|
||||
assertThrows(function() {
|
||||
reader.skipField()
|
||||
});
|
||||
|
||||
// Reading fields with the wrong wire type should assert.
|
||||
reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]);
|
||||
reader.nextField();
|
||||
assertThrows(function() {
|
||||
reader.readInt32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readInt32String()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readInt64()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readInt64String()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readUint32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readUint32String()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readUint64()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readUint64String()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readSint32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readBool()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readEnum()
|
||||
});
|
||||
|
||||
reader = jspb.BinaryReader.alloc([8, 1]);
|
||||
reader.nextField();
|
||||
assertThrows(function() {
|
||||
reader.readFixed32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readFixed64()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readSfixed32()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readSfixed64()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readFloat()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readDouble()
|
||||
});
|
||||
|
||||
assertThrows(function() {
|
||||
reader.readString()
|
||||
});
|
||||
assertThrows(function() {
|
||||
reader.readBytes()
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests encoding and decoding of unsigned field types.
|
||||
* @param {Function} readField
|
||||
* @param {Function} writeField
|
||||
* @param {number} epsilon
|
||||
* @param {number} upperLimit
|
||||
* @param {Function} filter
|
||||
* @private
|
||||
* @suppress {missingProperties}
|
||||
*/
|
||||
var doTestUnsignedField_ = function(
|
||||
readField, writeField, epsilon, upperLimit, filter) {
|
||||
assertNotNull(readField);
|
||||
assertNotNull(writeField);
|
||||
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
// Encode zero and limits.
|
||||
writeField.call(writer, 1, filter(0));
|
||||
writeField.call(writer, 2, filter(epsilon));
|
||||
writeField.call(writer, 3, filter(upperLimit));
|
||||
|
||||
// Encode positive values.
|
||||
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
|
||||
writeField.call(writer, 4, filter(cursor));
|
||||
}
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
// Check zero and limits.
|
||||
reader.nextField();
|
||||
assertEquals(1, reader.getFieldNumber());
|
||||
assertEquals(filter(0), readField.call(reader));
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(2, reader.getFieldNumber());
|
||||
assertEquals(filter(epsilon), readField.call(reader));
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(3, reader.getFieldNumber());
|
||||
assertEquals(filter(upperLimit), readField.call(reader));
|
||||
|
||||
// Check positive values.
|
||||
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
|
||||
reader.nextField();
|
||||
if (4 != reader.getFieldNumber()) throw 'fail!';
|
||||
if (filter(cursor) != readField.call(reader)) throw 'fail!';
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tests encoding and decoding of signed field types.
|
||||
* @param {Function} readField
|
||||
* @param {Function} writeField
|
||||
* @param {number} epsilon
|
||||
* @param {number} lowerLimit
|
||||
* @param {number} upperLimit
|
||||
* @param {Function} filter
|
||||
* @private
|
||||
* @suppress {missingProperties}
|
||||
*/
|
||||
var doTestSignedField_ = function(
|
||||
readField, writeField, epsilon, lowerLimit, upperLimit, filter) {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
// Encode zero and limits.
|
||||
writeField.call(writer, 1, filter(lowerLimit));
|
||||
writeField.call(writer, 2, filter(-epsilon));
|
||||
writeField.call(writer, 3, filter(0));
|
||||
writeField.call(writer, 4, filter(epsilon));
|
||||
writeField.call(writer, 5, filter(upperLimit));
|
||||
|
||||
var inputValues = [];
|
||||
|
||||
// Encode negative values.
|
||||
for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) {
|
||||
var val = filter(cursor);
|
||||
writeField.call(writer, 6, val);
|
||||
inputValues.push({fieldNumber: 6, value: val});
|
||||
}
|
||||
|
||||
// Encode positive values.
|
||||
for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
|
||||
var val = filter(cursor);
|
||||
writeField.call(writer, 7, val);
|
||||
inputValues.push({fieldNumber: 7, value: val});
|
||||
}
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
// Check zero and limits.
|
||||
reader.nextField();
|
||||
assertEquals(1, reader.getFieldNumber());
|
||||
assertEquals(filter(lowerLimit), readField.call(reader));
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(2, reader.getFieldNumber());
|
||||
assertEquals(filter(-epsilon), readField.call(reader));
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(3, reader.getFieldNumber());
|
||||
assertEquals(filter(0), readField.call(reader));
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(4, reader.getFieldNumber());
|
||||
assertEquals(filter(epsilon), readField.call(reader));
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(5, reader.getFieldNumber());
|
||||
assertEquals(filter(upperLimit), readField.call(reader));
|
||||
|
||||
for (var i = 0; i < inputValues.length; i++) {
|
||||
var expected = inputValues[i];
|
||||
reader.nextField();
|
||||
assertEquals(expected.fieldNumber, reader.getFieldNumber());
|
||||
assertEquals(expected.value, readField.call(reader));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Tests fields that use varint encoding.
|
||||
*/
|
||||
it('testVarintFields', function() {
|
||||
assertNotUndefined(jspb.BinaryReader.prototype.readUint32);
|
||||
assertNotUndefined(jspb.BinaryWriter.prototype.writeUint32);
|
||||
assertNotUndefined(jspb.BinaryReader.prototype.readUint64);
|
||||
assertNotUndefined(jspb.BinaryWriter.prototype.writeUint64);
|
||||
assertNotUndefined(jspb.BinaryReader.prototype.readBool);
|
||||
assertNotUndefined(jspb.BinaryWriter.prototype.writeBool);
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readUint32,
|
||||
jspb.BinaryWriter.prototype.writeUint32, 1, Math.pow(2, 32) - 1,
|
||||
Math.round);
|
||||
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readUint64,
|
||||
jspb.BinaryWriter.prototype.writeUint64, 1, Math.pow(2, 64) - 1025,
|
||||
Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readInt32,
|
||||
jspb.BinaryWriter.prototype.writeInt32, 1, -Math.pow(2, 31),
|
||||
Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readInt64,
|
||||
jspb.BinaryWriter.prototype.writeInt64, 1, -Math.pow(2, 63),
|
||||
Math.pow(2, 63) - 513, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readEnum,
|
||||
jspb.BinaryWriter.prototype.writeEnum, 1, -Math.pow(2, 31),
|
||||
Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readBool,
|
||||
jspb.BinaryWriter.prototype.writeBool, 1, 1, function(x) {
|
||||
return !!x;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests reading a field from hexadecimal string (format: '08 BE EF').
|
||||
* @param {Function} readField
|
||||
* @param {number} expected
|
||||
* @param {string} hexString
|
||||
*/
|
||||
function doTestHexStringVarint_(readField, expected, hexString) {
|
||||
var bytesCount = (hexString.length + 1) / 3;
|
||||
var bytes = new Uint8Array(bytesCount);
|
||||
for (var i = 0; i < bytesCount; i++) {
|
||||
bytes[i] = parseInt(hexString.substring(i * 3, i * 3 + 2), 16);
|
||||
}
|
||||
var reader = jspb.BinaryReader.alloc(bytes);
|
||||
reader.nextField();
|
||||
assertEquals(expected, readField.call(reader));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Tests non-canonical redundant varint decoding.
|
||||
*/
|
||||
it('testRedundantVarintFields', function() {
|
||||
assertNotNull(jspb.BinaryReader.prototype.readUint32);
|
||||
assertNotNull(jspb.BinaryReader.prototype.readUint64);
|
||||
assertNotNull(jspb.BinaryReader.prototype.readSint32);
|
||||
assertNotNull(jspb.BinaryReader.prototype.readSint64);
|
||||
|
||||
// uint32 and sint32 take no more than 5 bytes
|
||||
// 08 - field prefix (type = 0 means varint)
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readUint32, 12, '08 8C 80 80 80 00');
|
||||
|
||||
// 11 stands for -6 in zigzag encoding
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readSint32, -6, '08 8B 80 80 80 00');
|
||||
|
||||
// uint64 and sint64 take no more than 10 bytes
|
||||
// 08 - field prefix (type = 0 means varint)
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readUint64, 12,
|
||||
'08 8C 80 80 80 80 80 80 80 80 00');
|
||||
|
||||
// 11 stands for -6 in zigzag encoding
|
||||
doTestHexStringVarint_(
|
||||
jspb.BinaryReader.prototype.readSint64, -6,
|
||||
'08 8B 80 80 80 80 80 80 80 80 00');
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests reading 64-bit integers as split values.
|
||||
*/
|
||||
it('handles split 64 fields', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
writer.writeInt64String(1, '4294967296');
|
||||
writer.writeSfixed64String(2, '4294967298');
|
||||
writer.writeInt64String(3, '3'); // 3 is the zig-zag encoding of -2.
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
function rejoin(lowBits, highBits) {
|
||||
return highBits * 2 ** 32 + (lowBits >>> 0);
|
||||
}
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(1);
|
||||
expect(reader.readSplitVarint64(rejoin)).toEqual(0x100000000);
|
||||
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(2);
|
||||
expect(reader.readSplitFixed64(rejoin)).toEqual(0x100000002);
|
||||
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(3);
|
||||
expect(reader.readSplitZigzagVarint64(rejoin)).toEqual(-2);
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests 64-bit fields that are handled as strings.
|
||||
*/
|
||||
it('testStringInt64Fields', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var testSignedData = [
|
||||
'2730538252207801776', '-2688470994844604560', '3398529779486536359',
|
||||
'3568577411627971000', '272477188847484900', '-6649058714086158188',
|
||||
'-7695254765712060806', '-4525541438037104029', '-4993706538836508568',
|
||||
'4990160321893729138'
|
||||
];
|
||||
var testUnsignedData = [
|
||||
'7822732630241694882', '6753602971916687352', '2399935075244442116',
|
||||
'8724292567325338867', '16948784802625696584', '4136275908516066934',
|
||||
'3575388346793700364', '5167142028379259461', '1557573948689737699',
|
||||
'17100725280812548567'
|
||||
];
|
||||
|
||||
for (var i = 0; i < testSignedData.length; i++) {
|
||||
writer.writeInt64String(2 * i + 1, testSignedData[i]);
|
||||
writer.writeUint64String(2 * i + 2, testUnsignedData[i]);
|
||||
}
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
for (var i = 0; i < testSignedData.length; i++) {
|
||||
reader.nextField();
|
||||
assertEquals(2 * i + 1, reader.getFieldNumber());
|
||||
assertEquals(testSignedData[i], reader.readInt64String());
|
||||
reader.nextField();
|
||||
assertEquals(2 * i + 2, reader.getFieldNumber());
|
||||
assertEquals(testUnsignedData[i], reader.readUint64String());
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests fields that use zigzag encoding.
|
||||
*/
|
||||
it('testZigzagFields', function() {
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSint32,
|
||||
jspb.BinaryWriter.prototype.writeSint32, 1, -Math.pow(2, 31),
|
||||
Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSint64,
|
||||
jspb.BinaryWriter.prototype.writeSint64, 1, -Math.pow(2, 63),
|
||||
Math.pow(2, 63) - 513, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSintHash64,
|
||||
jspb.BinaryWriter.prototype.writeSintHash64, 1, -Math.pow(2, 63),
|
||||
Math.pow(2, 63) - 513, jspb.utils.numberToHash64);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests fields that use fixed-length encoding.
|
||||
*/
|
||||
it('testFixedFields', function() {
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readFixed32,
|
||||
jspb.BinaryWriter.prototype.writeFixed32, 1, Math.pow(2, 32) - 1,
|
||||
Math.round);
|
||||
|
||||
doTestUnsignedField_(
|
||||
jspb.BinaryReader.prototype.readFixed64,
|
||||
jspb.BinaryWriter.prototype.writeFixed64, 1, Math.pow(2, 64) - 1025,
|
||||
Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSfixed32,
|
||||
jspb.BinaryWriter.prototype.writeSfixed32, 1, -Math.pow(2, 31),
|
||||
Math.pow(2, 31) - 1, Math.round);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readSfixed64,
|
||||
jspb.BinaryWriter.prototype.writeSfixed64, 1, -Math.pow(2, 63),
|
||||
Math.pow(2, 63) - 513, Math.round);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests floating point fields.
|
||||
*/
|
||||
it('testFloatFields', function() {
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readFloat,
|
||||
jspb.BinaryWriter.prototype.writeFloat,
|
||||
jspb.BinaryConstants.FLOAT32_MIN, -jspb.BinaryConstants.FLOAT32_MAX,
|
||||
jspb.BinaryConstants.FLOAT32_MAX, truncate);
|
||||
|
||||
doTestSignedField_(
|
||||
jspb.BinaryReader.prototype.readDouble,
|
||||
jspb.BinaryWriter.prototype.writeDouble,
|
||||
jspb.BinaryConstants.FLOAT64_EPS * 10,
|
||||
-jspb.BinaryConstants.FLOAT64_MIN, jspb.BinaryConstants.FLOAT64_MIN,
|
||||
function(x) {
|
||||
return x;
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests length-delimited string fields.
|
||||
*/
|
||||
it('testStringFields', function() {
|
||||
var s1 = 'The quick brown fox jumps over the lazy dog.';
|
||||
var s2 = '人人生而自由,在尊嚴和權利上一律平等。';
|
||||
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
writer.writeString(1, s1);
|
||||
writer.writeString(2, s2);
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(1, reader.getFieldNumber());
|
||||
assertEquals(s1, reader.readString());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(2, reader.getFieldNumber());
|
||||
assertEquals(s2, reader.readString());
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests length-delimited byte fields.
|
||||
*/
|
||||
it('testByteFields', function() {
|
||||
var message = [];
|
||||
var lowerLimit = 1;
|
||||
var upperLimit = 256;
|
||||
var scale = 1.1;
|
||||
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
for (var cursor = lowerLimit; cursor < upperLimit; cursor *= 1.1) {
|
||||
var len = Math.round(cursor);
|
||||
var bytes = [];
|
||||
for (var i = 0; i < len; i++) bytes.push(i % 256);
|
||||
|
||||
writer.writeBytes(len, bytes);
|
||||
}
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
for (var cursor = lowerLimit; reader.nextField(); cursor *= 1.1) {
|
||||
var len = Math.round(cursor);
|
||||
if (len != reader.getFieldNumber()) throw 'fail!';
|
||||
|
||||
var bytes = reader.readBytes();
|
||||
if (len != bytes.length) throw 'fail!';
|
||||
for (var i = 0; i < bytes.length; i++) {
|
||||
if (i % 256 != bytes[i]) throw 'fail!';
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests nested messages.
|
||||
*/
|
||||
it('testNesting', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
|
||||
writer.writeInt32(1, 100);
|
||||
|
||||
// Add one message with 3 int fields.
|
||||
writer.writeMessage(2, dummyMessage, function() {
|
||||
writer.writeInt32(3, 300);
|
||||
writer.writeInt32(4, 400);
|
||||
writer.writeInt32(5, 500);
|
||||
});
|
||||
|
||||
// Add one empty message.
|
||||
writer.writeMessage(6, dummyMessage, goog.nullFunction);
|
||||
|
||||
writer.writeInt32(7, 700);
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
// Validate outermost message.
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(1, reader.getFieldNumber());
|
||||
assertEquals(100, reader.readInt32());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(2, reader.getFieldNumber());
|
||||
reader.readMessage(dummyMessage, function() {
|
||||
// Validate embedded message 1.
|
||||
reader.nextField();
|
||||
assertEquals(3, reader.getFieldNumber());
|
||||
assertEquals(300, reader.readInt32());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(4, reader.getFieldNumber());
|
||||
assertEquals(400, reader.readInt32());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(5, reader.getFieldNumber());
|
||||
assertEquals(500, reader.readInt32());
|
||||
|
||||
assertEquals(false, reader.nextField());
|
||||
});
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(6, reader.getFieldNumber());
|
||||
reader.readMessage(dummyMessage, function() {
|
||||
// Validate embedded message 2.
|
||||
|
||||
assertEquals(false, reader.nextField());
|
||||
});
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(7, reader.getFieldNumber());
|
||||
assertEquals(700, reader.readInt32());
|
||||
|
||||
assertEquals(false, reader.nextField());
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests skipping fields of each type by interleaving them with sentinel
|
||||
* values and skipping everything that's not a sentinel.
|
||||
*/
|
||||
it('testSkipField', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var sentinel = 123456789;
|
||||
|
||||
// Write varint fields of different sizes.
|
||||
writer.writeInt32(1, sentinel);
|
||||
writer.writeInt32(1, 1);
|
||||
writer.writeInt32(1, 1000);
|
||||
writer.writeInt32(1, 1000000);
|
||||
writer.writeInt32(1, 1000000000);
|
||||
|
||||
// Write fixed 64-bit encoded fields.
|
||||
writer.writeInt32(2, sentinel);
|
||||
writer.writeDouble(2, 1);
|
||||
writer.writeFixed64(2, 1);
|
||||
writer.writeSfixed64(2, 1);
|
||||
|
||||
// Write fixed 32-bit encoded fields.
|
||||
writer.writeInt32(3, sentinel);
|
||||
writer.writeFloat(3, 1);
|
||||
writer.writeFixed32(3, 1);
|
||||
writer.writeSfixed32(3, 1);
|
||||
|
||||
// Write delimited fields.
|
||||
writer.writeInt32(4, sentinel);
|
||||
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.
|
||||
writer.writeInt32(5, sentinel);
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
writer.writeGroup(5, dummyMessage, function() {
|
||||
// Previously the skipGroup implementation was wrong, which only consume
|
||||
// the decoder by nextField. This case is for making the previous
|
||||
// implementation failed in skipGroup by an early end group tag.
|
||||
// The reason is 44 = 5 * 8 + 4, this will be translated in to a field
|
||||
// with number 5 and with type 4 (end group)
|
||||
writer.writeInt64(44, 44);
|
||||
// This will make previous implementation failed by invalid tag (7).
|
||||
writer.writeInt64(42, 47);
|
||||
writer.writeInt64(42, 42);
|
||||
// This is for making the previous implementation failed by an invalid
|
||||
// varint. The bytes have at least 9 consecutive minus byte, which will
|
||||
// fail in this.nextField for previous implementation.
|
||||
writer.writeBytes(43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]);
|
||||
writer.writeGroup(6, dummyMessage, function() {
|
||||
writer.writeInt64(84, 42);
|
||||
writer.writeInt64(84, 44);
|
||||
writer.writeBytes(
|
||||
43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]);
|
||||
});
|
||||
});
|
||||
|
||||
// Write final sentinel.
|
||||
writer.writeInt32(6, sentinel);
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
function skip(field, count) {
|
||||
for (var i = 0; i < count; i++) {
|
||||
reader.nextField();
|
||||
if (field != reader.getFieldNumber()) throw 'fail!';
|
||||
reader.skipField();
|
||||
}
|
||||
}
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(1, reader.getFieldNumber());
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
skip(1, 4);
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(2, reader.getFieldNumber());
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
skip(2, 3);
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(3, reader.getFieldNumber());
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
skip(3, 3);
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(4, reader.getFieldNumber());
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
skip(4, 2);
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(5, reader.getFieldNumber());
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
skip(5, 1);
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(6, reader.getFieldNumber());
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests packed fields.
|
||||
*/
|
||||
it('testPackedFields', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var sentinel = 123456789;
|
||||
|
||||
var unsignedData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
|
||||
var signedData = [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10];
|
||||
var floatData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10];
|
||||
var doubleData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10];
|
||||
var boolData = [true, false, true, true, false, false, true, false];
|
||||
|
||||
for (var i = 0; i < floatData.length; i++) {
|
||||
floatData[i] = truncate(floatData[i]);
|
||||
}
|
||||
|
||||
writer.writeInt32(1, sentinel);
|
||||
|
||||
writer.writePackedInt32(2, signedData);
|
||||
writer.writePackedInt64(2, signedData);
|
||||
writer.writePackedUint32(2, unsignedData);
|
||||
writer.writePackedUint64(2, unsignedData);
|
||||
writer.writePackedSint32(2, signedData);
|
||||
writer.writePackedSint64(2, signedData);
|
||||
writer.writePackedFixed32(2, unsignedData);
|
||||
writer.writePackedFixed64(2, unsignedData);
|
||||
writer.writePackedSfixed32(2, signedData);
|
||||
writer.writePackedSfixed64(2, signedData);
|
||||
writer.writePackedFloat(2, floatData);
|
||||
writer.writePackedDouble(2, doubleData);
|
||||
writer.writePackedBool(2, boolData);
|
||||
writer.writePackedEnum(2, unsignedData);
|
||||
|
||||
writer.writeInt32(3, sentinel);
|
||||
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedInt32(), signedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedInt64(), signedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedUint32(), unsignedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedUint64(), unsignedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedSint32(), signedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedSint64(), signedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedFixed32(), unsignedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedFixed64(), unsignedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedSfixed32(), signedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedSfixed64(), signedData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedFloat(), floatData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedDouble(), doubleData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedBool(), boolData);
|
||||
|
||||
reader.nextField();
|
||||
assertElementsEquals(reader.readPackedEnum(), unsignedData);
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(sentinel, reader.readInt32());
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Byte blobs inside nested messages should always have their byte offset set
|
||||
* relative to the start of the outermost blob, not the start of their parent
|
||||
* blob.
|
||||
*/
|
||||
it('testNestedBlobs', function() {
|
||||
// Create a proto consisting of two nested messages, with the inner one
|
||||
// containing a blob of bytes.
|
||||
|
||||
var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED;
|
||||
var blob = [1, 2, 3, 4, 5];
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
|
||||
writer.writeMessage(1, dummyMessage, function() {
|
||||
writer.writeMessage(1, dummyMessage, function() {
|
||||
writer.writeBytes(1, blob);
|
||||
});
|
||||
});
|
||||
|
||||
// Peel off the outer two message layers. Each layer should have two bytes
|
||||
// of overhead, one for the field tag and one for the length of the inner
|
||||
// blob.
|
||||
|
||||
var decoder1 = new jspb.BinaryDecoder(writer.getResultBuffer());
|
||||
assertEquals(fieldTag, decoder1.readUnsignedVarint32());
|
||||
assertEquals(blob.length + 4, decoder1.readUnsignedVarint32());
|
||||
|
||||
var decoder2 = new jspb.BinaryDecoder(decoder1.readBytes(blob.length + 4));
|
||||
assertEquals(fieldTag, decoder2.readUnsignedVarint32());
|
||||
assertEquals(blob.length + 2, decoder2.readUnsignedVarint32());
|
||||
|
||||
assertEquals(fieldTag, decoder2.readUnsignedVarint32());
|
||||
assertEquals(blob.length, decoder2.readUnsignedVarint32());
|
||||
var bytes = decoder2.readBytes(blob.length);
|
||||
|
||||
assertElementsEquals(bytes, blob);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests read callbacks.
|
||||
*/
|
||||
it('testReadCallbacks', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
|
||||
// Add an int, a submessage, and another int.
|
||||
writer.writeInt32(1, 100);
|
||||
|
||||
writer.writeMessage(2, dummyMessage, function() {
|
||||
writer.writeInt32(3, 300);
|
||||
writer.writeInt32(4, 400);
|
||||
writer.writeInt32(5, 500);
|
||||
});
|
||||
|
||||
writer.writeInt32(7, 700);
|
||||
|
||||
// Create the reader and register a custom read callback.
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
|
||||
/**
|
||||
* @param {!jspb.BinaryReader} reader
|
||||
* @return {*}
|
||||
*/
|
||||
function readCallback(reader) {
|
||||
reader.nextField();
|
||||
assertEquals(3, reader.getFieldNumber());
|
||||
assertEquals(300, reader.readInt32());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(4, reader.getFieldNumber());
|
||||
assertEquals(400, reader.readInt32());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(5, reader.getFieldNumber());
|
||||
assertEquals(500, reader.readInt32());
|
||||
|
||||
assertEquals(false, reader.nextField());
|
||||
};
|
||||
|
||||
reader.registerReadCallback('readCallback', readCallback);
|
||||
|
||||
// Read the container message.
|
||||
reader.nextField();
|
||||
assertEquals(1, reader.getFieldNumber());
|
||||
assertEquals(100, reader.readInt32());
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(2, reader.getFieldNumber());
|
||||
reader.readMessage(dummyMessage, function() {
|
||||
// Decode the embedded message using the registered callback.
|
||||
reader.runReadCallback('readCallback');
|
||||
});
|
||||
|
||||
reader.nextField();
|
||||
assertEquals(7, reader.getFieldNumber());
|
||||
assertEquals(700, reader.readInt32());
|
||||
|
||||
assertEquals(false, reader.nextField());
|
||||
});
|
||||
});
|
1071
deps/protobuf/js/binary/utils.js
vendored
Normal file
1071
deps/protobuf/js/binary/utils.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
744
deps/protobuf/js/binary/utils_test.js
vendored
Normal file
744
deps/protobuf/js/binary/utils_test.js
vendored
Normal file
@ -0,0 +1,744 @@
|
||||
// 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 Test cases for jspb's helper functions.
|
||||
*
|
||||
* Test suite is written using Jasmine -- see http://jasmine.github.io/
|
||||
*
|
||||
* @author aappleby@google.com (Austin Appleby)
|
||||
*/
|
||||
|
||||
goog.require('goog.crypt');
|
||||
goog.require('goog.crypt.base64');
|
||||
goog.require('jspb.BinaryConstants');
|
||||
goog.require('jspb.BinaryWriter');
|
||||
goog.require('jspb.utils');
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @return {number}
|
||||
*/
|
||||
function truncate(x) {
|
||||
var temp = new Float32Array(1);
|
||||
temp[0] = x;
|
||||
return temp[0];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts an 64-bit integer in split representation to a 64-bit hash string
|
||||
* (8 bits encoded per character).
|
||||
* @param {number} bitsLow The low 32 bits of the split 64-bit integer.
|
||||
* @param {number} bitsHigh The high 32 bits of the split 64-bit integer.
|
||||
* @return {string} The encoded hash string, 8 bits per character.
|
||||
*/
|
||||
function toHashString(bitsLow, bitsHigh) {
|
||||
return String.fromCharCode((bitsLow >>> 0) & 0xFF,
|
||||
(bitsLow >>> 8) & 0xFF,
|
||||
(bitsLow >>> 16) & 0xFF,
|
||||
(bitsLow >>> 24) & 0xFF,
|
||||
(bitsHigh >>> 0) & 0xFF,
|
||||
(bitsHigh >>> 8) & 0xFF,
|
||||
(bitsHigh >>> 16) & 0xFF,
|
||||
(bitsHigh >>> 24) & 0xFF);
|
||||
}
|
||||
|
||||
|
||||
describe('binaryUtilsTest', function() {
|
||||
/**
|
||||
* Tests lossless binary-to-decimal conversion.
|
||||
*/
|
||||
it('testDecimalConversion', function() {
|
||||
// Check some magic numbers.
|
||||
var result =
|
||||
jspb.utils.joinUnsignedDecimalString(0x89e80001, 0x8ac72304);
|
||||
expect(result).toEqual('10000000000000000001');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0xacd05f15, 0x1b69b4b);
|
||||
expect(result).toEqual('123456789123456789');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0xeb1f0ad2, 0xab54a98c);
|
||||
expect(result).toEqual('12345678901234567890');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0xe3b70cb1, 0x891087b8);
|
||||
expect(result).toEqual('9876543210987654321');
|
||||
|
||||
// Check limits.
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00000000);
|
||||
expect(result).toEqual('0');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0xFFFFFFFF, 0xFFFFFFFF);
|
||||
expect(result).toEqual('18446744073709551615');
|
||||
|
||||
// Check each bit of the low dword.
|
||||
for (var i = 0; i < 32; i++) {
|
||||
var low = (1 << i) >>> 0;
|
||||
result = jspb.utils.joinUnsignedDecimalString(low, 0);
|
||||
expect(result).toEqual('' + Math.pow(2, i));
|
||||
}
|
||||
|
||||
// Check the first 20 bits of the high dword.
|
||||
for (var i = 0; i < 20; i++) {
|
||||
var high = (1 << i) >>> 0;
|
||||
result = jspb.utils.joinUnsignedDecimalString(0, high);
|
||||
expect(result).toEqual('' + Math.pow(2, 32 + i));
|
||||
}
|
||||
|
||||
// V8's internal double-to-string conversion is inaccurate for values above
|
||||
// 2^52, even if they're representable integers - check the rest of the bits
|
||||
// manually against the correct string representations of 2^N.
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00100000);
|
||||
expect(result).toEqual('4503599627370496');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00200000);
|
||||
expect(result).toEqual('9007199254740992');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00400000);
|
||||
expect(result).toEqual('18014398509481984');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x00800000);
|
||||
expect(result).toEqual('36028797018963968');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x01000000);
|
||||
expect(result).toEqual('72057594037927936');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x02000000);
|
||||
expect(result).toEqual('144115188075855872');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x04000000);
|
||||
expect(result).toEqual('288230376151711744');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x08000000);
|
||||
expect(result).toEqual('576460752303423488');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x10000000);
|
||||
expect(result).toEqual('1152921504606846976');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x20000000);
|
||||
expect(result).toEqual('2305843009213693952');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x40000000);
|
||||
expect(result).toEqual('4611686018427387904');
|
||||
|
||||
result = jspb.utils.joinUnsignedDecimalString(0x00000000, 0x80000000);
|
||||
expect(result).toEqual('9223372036854775808');
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Going from hash strings to decimal strings should also be lossless.
|
||||
*/
|
||||
it('testHashToDecimalConversion', function() {
|
||||
var result;
|
||||
var convert = jspb.utils.hash64ToDecimalString;
|
||||
|
||||
result = convert(toHashString(0x00000000, 0x00000000), false);
|
||||
expect(result).toEqual('0');
|
||||
|
||||
result = convert(toHashString(0x00000000, 0x00000000), true);
|
||||
expect(result).toEqual('0');
|
||||
|
||||
result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), false);
|
||||
expect(result).toEqual('18446744073709551615');
|
||||
|
||||
result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF), true);
|
||||
expect(result).toEqual('-1');
|
||||
|
||||
result = convert(toHashString(0x00000000, 0x80000000), false);
|
||||
expect(result).toEqual('9223372036854775808');
|
||||
|
||||
result = convert(toHashString(0x00000000, 0x80000000), true);
|
||||
expect(result).toEqual('-9223372036854775808');
|
||||
|
||||
result = convert(toHashString(0xacd05f15, 0x01b69b4b), false);
|
||||
expect(result).toEqual('123456789123456789');
|
||||
|
||||
result = convert(toHashString(~0xacd05f15 + 1, ~0x01b69b4b), true);
|
||||
expect(result).toEqual('-123456789123456789');
|
||||
|
||||
// And converting arrays of hashes should work the same way.
|
||||
result = jspb.utils.hash64ArrayToDecimalStrings([
|
||||
toHashString(0xFFFFFFFF, 0xFFFFFFFF),
|
||||
toHashString(0x00000000, 0x80000000),
|
||||
toHashString(0xacd05f15, 0x01b69b4b)], false);
|
||||
expect(result.length).toEqual(3);
|
||||
expect(result[0]).toEqual('18446744073709551615');
|
||||
expect(result[1]).toEqual('9223372036854775808');
|
||||
expect(result[2]).toEqual('123456789123456789');
|
||||
});
|
||||
|
||||
/*
|
||||
* Going from decimal strings to hash strings should be lossless.
|
||||
*/
|
||||
it('testDecimalToHashConversion', function() {
|
||||
var result;
|
||||
var convert = jspb.utils.decimalStringToHash64;
|
||||
|
||||
result = convert('0');
|
||||
expect(result).toEqual(goog.crypt.byteArrayToString(
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]));
|
||||
|
||||
result = convert('-1');
|
||||
expect(result).toEqual(goog.crypt.byteArrayToString(
|
||||
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]));
|
||||
|
||||
result = convert('18446744073709551615');
|
||||
expect(result).toEqual(goog.crypt.byteArrayToString(
|
||||
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]));
|
||||
|
||||
result = convert('9223372036854775808');
|
||||
expect(result).toEqual(goog.crypt.byteArrayToString(
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]));
|
||||
|
||||
result = convert('-9223372036854775808');
|
||||
expect(result).toEqual(goog.crypt.byteArrayToString(
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80]));
|
||||
|
||||
result = convert('123456789123456789');
|
||||
expect(result).toEqual(goog.crypt.byteArrayToString(
|
||||
[0x15, 0x5F, 0xD0, 0xAC, 0x4B, 0x9B, 0xB6, 0x01]));
|
||||
|
||||
result = convert('-123456789123456789');
|
||||
expect(result).toEqual(goog.crypt.byteArrayToString(
|
||||
[0xEB, 0xA0, 0x2F, 0x53, 0xB4, 0x64, 0x49, 0xFE]));
|
||||
});
|
||||
|
||||
/**
|
||||
* Going from hash strings to hex strings should be lossless.
|
||||
*/
|
||||
it('testHashToHexConversion', function() {
|
||||
var result;
|
||||
var convert = jspb.utils.hash64ToHexString;
|
||||
|
||||
result = convert(toHashString(0x00000000, 0x00000000));
|
||||
expect(result).toEqual('0x0000000000000000');
|
||||
|
||||
result = convert(toHashString(0xFFFFFFFF, 0xFFFFFFFF));
|
||||
expect(result).toEqual('0xffffffffffffffff');
|
||||
|
||||
result = convert(toHashString(0x12345678, 0x9ABCDEF0));
|
||||
expect(result).toEqual('0x9abcdef012345678');
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Going from hex strings to hash strings should be lossless.
|
||||
*/
|
||||
it('testHexToHashConversion', function() {
|
||||
var result;
|
||||
var convert = jspb.utils.hexStringToHash64;
|
||||
|
||||
result = convert('0x0000000000000000');
|
||||
expect(result).toEqual(goog.crypt.byteArrayToString(
|
||||
[0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00]));
|
||||
|
||||
result = convert('0xffffffffffffffff');
|
||||
expect(result).toEqual(goog.crypt.byteArrayToString(
|
||||
[0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF]));
|
||||
|
||||
// Hex string is big-endian, hash string is little-endian.
|
||||
result = convert('0x123456789ABCDEF0');
|
||||
expect(result).toEqual(goog.crypt.byteArrayToString(
|
||||
[0xF0, 0xDE, 0xBC, 0x9A, 0x78, 0x56, 0x34, 0x12]));
|
||||
|
||||
// Capitalization should not matter.
|
||||
result = convert('0x0000abcdefABCDEF');
|
||||
expect(result).toEqual(goog.crypt.byteArrayToString(
|
||||
[0xEF, 0xCD, 0xAB, 0xEF, 0xCD, 0xAB, 0x00, 0x00]));
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Going from numbers to hash strings should be lossless for up to 53 bits of
|
||||
* precision.
|
||||
*/
|
||||
it('testNumberToHashConversion', function() {
|
||||
var result;
|
||||
var convert = jspb.utils.numberToHash64;
|
||||
|
||||
result = convert(0x0000000000000);
|
||||
expect(jspb.utils.hash64ToHexString(result)).toEqual('0x0000000000000000');
|
||||
|
||||
result = convert(0xFFFFFFFFFFFFF);
|
||||
expect(jspb.utils.hash64ToHexString(result)).toEqual('0x000fffffffffffff');
|
||||
|
||||
result = convert(0x123456789ABCD);
|
||||
expect(jspb.utils.hash64ToHexString(result)).toEqual('0x000123456789abcd');
|
||||
|
||||
result = convert(0xDCBA987654321);
|
||||
expect(jspb.utils.hash64ToHexString(result)).toEqual('0x000dcba987654321');
|
||||
|
||||
// 53 bits of precision should not be truncated.
|
||||
result = convert(0x10000000000001);
|
||||
expect(jspb.utils.hash64ToHexString(result)).toEqual('0x0010000000000001');
|
||||
|
||||
// 54 bits of precision should be truncated.
|
||||
result = convert(0x20000000000001);
|
||||
expect(jspb.utils.hash64ToHexString(result))
|
||||
.not.toEqual('0x0020000000000001');
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Sanity check the behavior of Javascript's strings when doing funny things
|
||||
* with unicode characters.
|
||||
*/
|
||||
it('sanityCheckUnicodeStrings', function() {
|
||||
var strings = new Array(65536);
|
||||
|
||||
// All possible unsigned 16-bit values should be storable in a string, they
|
||||
// shouldn't do weird things with the length of the string, and they should
|
||||
// come back out of the string unchanged.
|
||||
for (var i = 0; i < 65536; i++) {
|
||||
strings[i] = 'a' + String.fromCharCode(i) + 'a';
|
||||
expect(strings[i].length).toEqual(3);
|
||||
expect(strings[i].charCodeAt(1)).toEqual(i);
|
||||
}
|
||||
|
||||
// Each unicode character should compare equal to itself and not equal to a
|
||||
// different unicode character.
|
||||
for (var i = 0; i < 65536; i++) {
|
||||
expect(strings[i] == strings[i]).toEqual(true);
|
||||
expect(strings[i] == strings[(i + 1) % 65536]).toEqual(false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests conversion from 32-bit floating point numbers to split64 numbers.
|
||||
*/
|
||||
it('testFloat32ToSplit64', function() {
|
||||
var f32_eps = jspb.BinaryConstants.FLOAT32_EPS;
|
||||
var f32_min = jspb.BinaryConstants.FLOAT32_MIN;
|
||||
var f32_max = jspb.BinaryConstants.FLOAT32_MAX;
|
||||
var f32_max_safe_int = jspb.utils.joinFloat32(0x4b7fffff, 0);
|
||||
var f32_pi = Math.fround(Math.PI);
|
||||
|
||||
// NaN.
|
||||
jspb.utils.splitFloat32(NaN);
|
||||
expect(isNaN(jspb.utils.joinFloat32(
|
||||
jspb.utils.split64Low, jspb.utils.split64High)))
|
||||
.toEqual(true);
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number=} opt_bits
|
||||
*/
|
||||
function test(x, opt_bits) {
|
||||
jspb.utils.splitFloat32(x);
|
||||
if (opt_bits !== undefined) {
|
||||
if (opt_bits != jspb.utils.split64Low) throw 'fail!';
|
||||
}
|
||||
expect(truncate(x))
|
||||
.toEqual(jspb.utils.joinFloat32(
|
||||
jspb.utils.split64Low, jspb.utils.split64High));
|
||||
}
|
||||
|
||||
// Positive and negative infinity.
|
||||
test(Infinity, 0x7f800000);
|
||||
test(-Infinity, 0xff800000);
|
||||
|
||||
// Positive and negative zero.
|
||||
test(0, 0x00000000);
|
||||
test(-0, 0x80000000);
|
||||
|
||||
// Positive and negative epsilon.
|
||||
test(f32_eps, 0x00000001);
|
||||
test(-f32_eps, 0x80000001);
|
||||
|
||||
// Positive and negative min.
|
||||
test(f32_min, 0x00800000);
|
||||
test(-f32_min, 0x80800000);
|
||||
|
||||
// Positive and negative max.
|
||||
test(f32_max, 0x7F7FFFFF);
|
||||
test(-f32_max, 0xFF7FFFFF);
|
||||
|
||||
// Positive and negative max_safe_int.
|
||||
test(f32_max_safe_int, 0x4B7FFFFF);
|
||||
test(-f32_max_safe_int, 0xCB7FFFFF);
|
||||
|
||||
// Pi.
|
||||
test(f32_pi, 0x40490fdb);
|
||||
|
||||
// corner cases
|
||||
test(0.9999999762949594, 0x3f800000);
|
||||
test(7.99999999999999, 0x41000000);
|
||||
test(Math.sin(30 * Math.PI / 180), 0x3f000000); // sin(30 degrees)
|
||||
|
||||
// Various positive values.
|
||||
var cursor = f32_eps * 10;
|
||||
while (cursor != Infinity) {
|
||||
test(cursor);
|
||||
cursor *= 1.1;
|
||||
}
|
||||
|
||||
// Various negative values.
|
||||
cursor = -f32_eps * 10;
|
||||
while (cursor != -Infinity) {
|
||||
test(cursor);
|
||||
cursor *= 1.1;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests conversion from 64-bit floating point numbers to split64 numbers.
|
||||
*/
|
||||
it('testFloat64ToSplit64', function() {
|
||||
var f64_eps = jspb.BinaryConstants.FLOAT64_EPS;
|
||||
var f64_min = jspb.BinaryConstants.FLOAT64_MIN;
|
||||
var f64_max = jspb.BinaryConstants.FLOAT64_MAX;
|
||||
|
||||
// NaN.
|
||||
jspb.utils.splitFloat64(NaN);
|
||||
expect(isNaN(jspb.utils.joinFloat64(
|
||||
jspb.utils.split64Low, jspb.utils.split64High)))
|
||||
.toEqual(true);
|
||||
|
||||
/**
|
||||
* @param {number} x
|
||||
* @param {number=} opt_highBits
|
||||
* @param {number=} opt_lowBits
|
||||
*/
|
||||
function test(x, opt_highBits, opt_lowBits) {
|
||||
jspb.utils.splitFloat64(x);
|
||||
if (opt_highBits !== undefined) {
|
||||
var split64High = jspb.utils.split64High;
|
||||
expect(opt_highBits.toString(16)).toEqual(split64High.toString(16));
|
||||
}
|
||||
if (opt_lowBits !== undefined) {
|
||||
var split64Low = jspb.utils.split64Low;
|
||||
expect(opt_lowBits.toString(16)).toEqual(split64Low.toString(16));
|
||||
}
|
||||
expect(
|
||||
jspb.utils.joinFloat64(jspb.utils.split64Low, jspb.utils.split64High))
|
||||
.toEqual(x);
|
||||
}
|
||||
|
||||
// Positive and negative infinity.
|
||||
test(Infinity, 0x7ff00000, 0x00000000);
|
||||
test(-Infinity, 0xfff00000, 0x00000000);
|
||||
|
||||
// Positive and negative zero.
|
||||
test(0, 0x00000000, 0x00000000);
|
||||
test(-0, 0x80000000, 0x00000000);
|
||||
|
||||
test(1, 0x3FF00000, 0x00000000);
|
||||
test(2, 0x40000000, 0x00000000);
|
||||
|
||||
// Positive and negative epsilon.
|
||||
test(f64_eps, 0x00000000, 0x00000001);
|
||||
test(-f64_eps, 0x80000000, 0x00000001);
|
||||
|
||||
// Positive and negative min.
|
||||
test(f64_min, 0x00100000, 0x00000000);
|
||||
test(-f64_min, 0x80100000, 0x00000000);
|
||||
|
||||
// Positive and negative max.
|
||||
test(f64_max, 0x7FEFFFFF, 0xFFFFFFFF);
|
||||
test(-f64_max, 0xFFEFFFFF, 0xFFFFFFFF);
|
||||
|
||||
test(Number.MAX_SAFE_INTEGER, 0x433FFFFF, 0xFFFFFFFF);
|
||||
test(Number.MIN_SAFE_INTEGER, 0xC33FFFFF, 0xFFFFFFFF);
|
||||
|
||||
// Test various edge cases with mantissa of all 1, all 0, or just the
|
||||
// highest or lowest significant bit.
|
||||
test(4503599627370497, 0x43300000, 0x00000001);
|
||||
test(6755399441055744, 0x43380000, 0x00000000);
|
||||
test(1.348269851146737e+308, 0x7FE80000, 0x00000000);
|
||||
test(1.9999999999999998, 0x3FFFFFFF, 0xFFFFFFFF);
|
||||
test(2.225073858507201e-308, 0x000FFFFF, 0xFFFFFFFF);
|
||||
test(Math.PI, 0x400921fb, 0x54442d18);
|
||||
test(jspb.BinaryConstants.FLOAT32_MIN, 0x38100000, 0x00000000);
|
||||
|
||||
// Various positive values.
|
||||
var cursor = f64_eps * 10;
|
||||
while (cursor != Infinity) {
|
||||
test(cursor);
|
||||
cursor *= 1.1;
|
||||
}
|
||||
|
||||
// Various negative values.
|
||||
cursor = -f64_eps * 10;
|
||||
while (cursor != -Infinity) {
|
||||
test(cursor);
|
||||
cursor *= 1.1;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Tests zigzag conversions.
|
||||
*/
|
||||
it('can encode and decode zigzag 64', function() {
|
||||
function stringToHiLoPair(str) {
|
||||
jspb.utils.splitDecimalString(str);
|
||||
return {
|
||||
lo: jspb.utils.split64Low >>> 0,
|
||||
hi: jspb.utils.split64High >>> 0
|
||||
};
|
||||
}
|
||||
function makeHiLoPair(lo, hi) {
|
||||
return {lo: lo >>> 0, hi: hi >>> 0};
|
||||
}
|
||||
// Test cases directly from the protobuf dev guide.
|
||||
// https://engdoc.corp.google.com/eng/howto/protocolbuffers/developerguide/encoding.shtml?cl=head#types
|
||||
var testCases = [
|
||||
{original: stringToHiLoPair('0'), zigzag: stringToHiLoPair('0')},
|
||||
{original: stringToHiLoPair('-1'), zigzag: stringToHiLoPair('1')},
|
||||
{original: stringToHiLoPair('1'), zigzag: stringToHiLoPair('2')},
|
||||
{original: stringToHiLoPair('-2'), zigzag: stringToHiLoPair('3')},
|
||||
{
|
||||
original: stringToHiLoPair('2147483647'),
|
||||
zigzag: stringToHiLoPair('4294967294')
|
||||
},
|
||||
{
|
||||
original: stringToHiLoPair('-2147483648'),
|
||||
zigzag: stringToHiLoPair('4294967295')
|
||||
},
|
||||
// 64-bit extremes
|
||||
{
|
||||
original: stringToHiLoPair('9223372036854775807'),
|
||||
zigzag: stringToHiLoPair('18446744073709551614')
|
||||
},
|
||||
{
|
||||
original: stringToHiLoPair('-9223372036854775808'),
|
||||
zigzag: stringToHiLoPair('18446744073709551615')
|
||||
},
|
||||
];
|
||||
for (const c of testCases) {
|
||||
expect(jspb.utils.toZigzag64(c.original.lo, c.original.hi, makeHiLoPair))
|
||||
.toEqual(c.zigzag);
|
||||
expect(jspb.utils.fromZigzag64(c.zigzag.lo, c.zigzag.hi, makeHiLoPair))
|
||||
.toEqual(c.original);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests counting packed varints.
|
||||
*/
|
||||
it('testCountVarints', function() {
|
||||
var values = [];
|
||||
for (var i = 1; i < 1000000000; i *= 1.1) {
|
||||
values.push(Math.floor(i));
|
||||
}
|
||||
|
||||
var writer = new jspb.BinaryWriter();
|
||||
writer.writePackedUint64(1, values);
|
||||
|
||||
var buffer = new Uint8Array(writer.getResultBuffer());
|
||||
|
||||
// We should have two more varints than we started with - one for the field
|
||||
// tag, one for the packed length.
|
||||
expect(jspb.utils.countVarints(buffer, 0, buffer.length))
|
||||
.toEqual(values.length + 2);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests counting matching varint fields.
|
||||
*/
|
||||
it('testCountVarintFields', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var count = 0;
|
||||
for (var i = 1; i < 1000000000; i *= 1.1) {
|
||||
writer.writeUint64(1, Math.floor(i));
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
var buffer = new Uint8Array(writer.getResultBuffer());
|
||||
expect(jspb.utils.countVarintFields(buffer, 0, buffer.length, 1))
|
||||
.toEqual(count);
|
||||
|
||||
writer = new jspb.BinaryWriter();
|
||||
|
||||
count = 0;
|
||||
for (var i = 1; i < 1000000000; i *= 1.1) {
|
||||
writer.writeUint64(123456789, Math.floor(i));
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
buffer = new Uint8Array(writer.getResultBuffer());
|
||||
expect(jspb.utils.countVarintFields(buffer, 0, buffer.length, 123456789))
|
||||
.toEqual(count);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests counting matching fixed32 fields.
|
||||
*/
|
||||
it('testCountFixed32Fields', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var count = 0;
|
||||
for (var i = 1; i < 1000000000; i *= 1.1) {
|
||||
writer.writeFixed32(1, Math.floor(i));
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
var buffer = new Uint8Array(writer.getResultBuffer());
|
||||
expect(jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 1))
|
||||
.toEqual(count);
|
||||
|
||||
writer = new jspb.BinaryWriter();
|
||||
|
||||
count = 0;
|
||||
for (var i = 1; i < 1000000000; i *= 1.1) {
|
||||
writer.writeFixed32(123456789, Math.floor(i));
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
buffer = new Uint8Array(writer.getResultBuffer());
|
||||
expect(jspb.utils.countFixed32Fields(buffer, 0, buffer.length, 123456789))
|
||||
.toEqual(count);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests counting matching fixed64 fields.
|
||||
*/
|
||||
it('testCountFixed64Fields', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var count = 0;
|
||||
for (var i = 1; i < 1000000000; i *= 1.1) {
|
||||
writer.writeDouble(1, i);
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
var buffer = new Uint8Array(writer.getResultBuffer());
|
||||
expect(jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 1))
|
||||
.toEqual(count);
|
||||
|
||||
writer = new jspb.BinaryWriter();
|
||||
|
||||
count = 0;
|
||||
for (var i = 1; i < 1000000000; i *= 1.1) {
|
||||
writer.writeDouble(123456789, i);
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
buffer = new Uint8Array(writer.getResultBuffer());
|
||||
expect(jspb.utils.countFixed64Fields(buffer, 0, buffer.length, 123456789))
|
||||
.toEqual(count);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests counting matching delimited fields.
|
||||
*/
|
||||
it('testCountDelimitedFields', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
|
||||
var count = 0;
|
||||
for (var i = 1; i < 1000; i *= 1.1) {
|
||||
writer.writeBytes(1, [Math.floor(i)]);
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
var buffer = new Uint8Array(writer.getResultBuffer());
|
||||
expect(jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 1))
|
||||
.toEqual(count);
|
||||
|
||||
writer = new jspb.BinaryWriter();
|
||||
|
||||
count = 0;
|
||||
for (var i = 1; i < 1000; i *= 1.1) {
|
||||
writer.writeBytes(123456789, [Math.floor(i)]);
|
||||
count++;
|
||||
}
|
||||
writer.writeString(2, 'terminator');
|
||||
|
||||
buffer = new Uint8Array(writer.getResultBuffer());
|
||||
expect(jspb.utils.countDelimitedFields(buffer, 0, buffer.length, 123456789))
|
||||
.toEqual(count);
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests byte format for debug strings.
|
||||
*/
|
||||
it('testDebugBytesToTextFormat', function() {
|
||||
expect(jspb.utils.debugBytesToTextFormat(null)).toEqual('""');
|
||||
expect(jspb.utils.debugBytesToTextFormat([
|
||||
0, 16, 255
|
||||
])).toEqual('"\\x00\\x10\\xff"');
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests converting byte blob sources into byte blobs.
|
||||
*/
|
||||
it('testByteSourceToUint8Array', function() {
|
||||
var convert = jspb.utils.byteSourceToUint8Array;
|
||||
|
||||
var sourceData = [];
|
||||
for (var i = 0; i < 256; i++) {
|
||||
sourceData.push(i);
|
||||
}
|
||||
|
||||
var sourceBytes = new Uint8Array(sourceData);
|
||||
var sourceBuffer = sourceBytes.buffer;
|
||||
var sourceBase64 = goog.crypt.base64.encodeByteArray(sourceData);
|
||||
var sourceString = goog.crypt.byteArrayToString(sourceData);
|
||||
|
||||
function check(result) {
|
||||
expect(result.constructor).toEqual(Uint8Array);
|
||||
expect(result.length).toEqual(sourceData.length);
|
||||
for (var i = 0; i < result.length; i++) {
|
||||
expect(result[i]).toEqual(sourceData[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Converting Uint8Arrays into Uint8Arrays should be a no-op.
|
||||
expect(convert(sourceBytes)).toEqual(sourceBytes);
|
||||
|
||||
// Converting Array<numbers> into Uint8Arrays should work.
|
||||
check(convert(sourceData));
|
||||
|
||||
// Converting ArrayBuffers into Uint8Arrays should work.
|
||||
check(convert(sourceBuffer));
|
||||
|
||||
// Converting base64-encoded strings into Uint8Arrays should work.
|
||||
check(convert(sourceBase64));
|
||||
});
|
||||
});
|
1833
deps/protobuf/js/binary/writer.js
vendored
Normal file
1833
deps/protobuf/js/binary/writer.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
412
deps/protobuf/js/binary/writer_test.js
vendored
Normal file
412
deps/protobuf/js/binary/writer_test.js
vendored
Normal file
@ -0,0 +1,412 @@
|
||||
// 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 Test cases for jspb's binary protocol buffer writer. In
|
||||
* practice BinaryWriter is used to drive the Decoder and Reader test cases,
|
||||
* so only writer-specific tests are here.
|
||||
*
|
||||
* Test suite is written using Jasmine -- see http://jasmine.github.io/
|
||||
*
|
||||
* @author aappleby@google.com (Austin Appleby)
|
||||
*/
|
||||
|
||||
goog.require('goog.crypt');
|
||||
goog.require('goog.testing.asserts');
|
||||
goog.require('jspb.BinaryConstants');
|
||||
goog.require('jspb.BinaryReader');
|
||||
goog.require('jspb.BinaryWriter');
|
||||
goog.require('jspb.utils');
|
||||
goog.require('goog.crypt.base64');
|
||||
goog.requireType('jspb.BinaryMessage');
|
||||
|
||||
/**
|
||||
* @param {function()} func This function should throw an error when run.
|
||||
*/
|
||||
function assertFails(func) {
|
||||
assertThrows(func);
|
||||
}
|
||||
|
||||
|
||||
describe('binaryWriterTest', function() {
|
||||
/**
|
||||
* Verifies that misuse of the writer class triggers assertions.
|
||||
*/
|
||||
it('testWriteErrors', function() {
|
||||
// Submessages with invalid field indices should assert.
|
||||
var writer = new jspb.BinaryWriter();
|
||||
var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
|
||||
|
||||
assertFails(function() {
|
||||
writer.writeMessage(-1, dummyMessage, goog.nullFunction);
|
||||
});
|
||||
|
||||
// Writing invalid field indices should assert.
|
||||
writer = new jspb.BinaryWriter();
|
||||
assertFails(function() {
|
||||
writer.writeUint64(-1, 1);
|
||||
});
|
||||
|
||||
// Writing out-of-range field values should assert.
|
||||
writer = new jspb.BinaryWriter();
|
||||
|
||||
assertFails(function() {
|
||||
writer.writeInt32(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeInt32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {
|
||||
writer.writeInt64(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeInt64(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {
|
||||
writer.writeUint32(1, -1);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeUint32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {
|
||||
writer.writeUint64(1, -1);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeUint64(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {
|
||||
writer.writeSint32(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeSint32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {
|
||||
writer.writeSint64(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeSint64(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {
|
||||
writer.writeFixed32(1, -1);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeFixed32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {
|
||||
writer.writeFixed64(1, -1);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeFixed64(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {
|
||||
writer.writeSfixed32(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeSfixed32(1, Infinity);
|
||||
});
|
||||
|
||||
assertFails(function() {
|
||||
writer.writeSfixed64(1, -Infinity);
|
||||
});
|
||||
assertFails(function() {
|
||||
writer.writeSfixed64(1, Infinity);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Basic test of retrieving the result as a Uint8Array buffer
|
||||
*/
|
||||
it('testGetResultBuffer', function() {
|
||||
var expected = '0864120b48656c6c6f20776f726c641a0301020320c801';
|
||||
|
||||
var writer = new jspb.BinaryWriter();
|
||||
writer.writeUint32(1, 100);
|
||||
writer.writeString(2, 'Hello world');
|
||||
writer.writeBytes(3, new Uint8Array([1, 2, 3]));
|
||||
writer.writeUint32(4, 200);
|
||||
|
||||
var buffer = writer.getResultBuffer();
|
||||
assertEquals(expected, goog.crypt.byteArrayToHex(buffer));
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* Tests websafe encodings for base64 strings.
|
||||
*/
|
||||
it('testWebSafeOption', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
writer.writeBytes(1, new Uint8Array([127]));
|
||||
assertEquals('CgF/', writer.getResultBase64String());
|
||||
assertEquals(
|
||||
'CgF/',
|
||||
writer.getResultBase64String(goog.crypt.base64.Alphabet.DEFAULT));
|
||||
assertEquals(
|
||||
'CgF_',
|
||||
writer.getResultBase64String(
|
||||
goog.crypt.base64.Alphabet.WEBSAFE_NO_PADDING));
|
||||
});
|
||||
|
||||
it('writes split 64 fields', function() {
|
||||
var writer = new jspb.BinaryWriter();
|
||||
writer.writeSplitVarint64(1, 0x1, 0x2);
|
||||
writer.writeSplitVarint64(1, 0xFFFFFFFF, 0xFFFFFFFF);
|
||||
writer.writeSplitFixed64(2, 0x1, 0x2);
|
||||
writer.writeSplitFixed64(2, 0xFFFFFFF0, 0xFFFFFFFF);
|
||||
function lo(i) {
|
||||
return i + 1;
|
||||
}
|
||||
function hi(i) {
|
||||
return i + 2;
|
||||
}
|
||||
writer.writeRepeatedSplitVarint64(3, [0, 1, 2], lo, hi);
|
||||
writer.writeRepeatedSplitFixed64(4, [0, 1, 2], lo, hi);
|
||||
writer.writePackedSplitVarint64(5, [0, 1, 2], lo, hi);
|
||||
writer.writePackedSplitFixed64(6, [0, 1, 2], lo, hi);
|
||||
|
||||
function bitsAsArray(lowBits, highBits) {
|
||||
return [lowBits >>> 0, highBits >>> 0];
|
||||
}
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(1);
|
||||
expect(reader.readSplitVarint64(bitsAsArray)).toEqual([0x1, 0x2]);
|
||||
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(1);
|
||||
expect(reader.readSplitVarint64(bitsAsArray)).toEqual([
|
||||
0xFFFFFFFF, 0xFFFFFFFF
|
||||
]);
|
||||
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(2);
|
||||
expect(reader.readSplitFixed64(bitsAsArray)).toEqual([0x1, 0x2]);
|
||||
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(2);
|
||||
expect(reader.readSplitFixed64(bitsAsArray)).toEqual([
|
||||
0xFFFFFFF0, 0xFFFFFFFF
|
||||
]);
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(3);
|
||||
expect(reader.readSplitVarint64(bitsAsArray)).toEqual([i + 1, i + 2]);
|
||||
}
|
||||
|
||||
for (let i = 0; i < 3; i++) {
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(4);
|
||||
expect(reader.readSplitFixed64(bitsAsArray)).toEqual([i + 1, i + 2]);
|
||||
}
|
||||
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(5);
|
||||
expect(reader.readPackedInt64String()).toEqual([
|
||||
String(2 * 2 ** 32 + 1),
|
||||
String(3 * 2 ** 32 + 2),
|
||||
String(4 * 2 ** 32 + 3),
|
||||
]);
|
||||
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(6);
|
||||
expect(reader.readPackedFixed64String()).toEqual([
|
||||
String(2 * 2 ** 32 + 1),
|
||||
String(3 * 2 ** 32 + 2),
|
||||
String(4 * 2 ** 32 + 3),
|
||||
]);
|
||||
});
|
||||
|
||||
it('writes zigzag 64 fields', function() {
|
||||
// Test cases directly from the protobuf dev guide.
|
||||
// https://engdoc.corp.google.com/eng/howto/protocolbuffers/developerguide/encoding.shtml?cl=head#types
|
||||
var testCases = [
|
||||
{original: '0', zigzag: '0'},
|
||||
{original: '-1', zigzag: '1'},
|
||||
{original: '1', zigzag: '2'},
|
||||
{original: '-2', zigzag: '3'},
|
||||
{original: '2147483647', zigzag: '4294967294'},
|
||||
{original: '-2147483648', zigzag: '4294967295'},
|
||||
// 64-bit extremes, not in dev guide.
|
||||
{original: '9223372036854775807', zigzag: '18446744073709551614'},
|
||||
{original: '-9223372036854775808', zigzag: '18446744073709551615'},
|
||||
];
|
||||
function decimalToLowBits(v) {
|
||||
jspb.utils.splitDecimalString(v);
|
||||
return jspb.utils.split64Low >>> 0;
|
||||
}
|
||||
function decimalToHighBits(v) {
|
||||
jspb.utils.splitDecimalString(v);
|
||||
return jspb.utils.split64High >>> 0;
|
||||
}
|
||||
|
||||
var writer = new jspb.BinaryWriter();
|
||||
testCases.forEach(function(c) {
|
||||
writer.writeSint64String(1, c.original);
|
||||
writer.writeSintHash64(1, jspb.utils.decimalStringToHash64(c.original));
|
||||
jspb.utils.splitDecimalString(c.original);
|
||||
writer.writeSplitZigzagVarint64(
|
||||
1, jspb.utils.split64Low, jspb.utils.split64High);
|
||||
});
|
||||
|
||||
writer.writeRepeatedSint64String(2, testCases.map(function(c) {
|
||||
return c.original;
|
||||
}));
|
||||
|
||||
writer.writeRepeatedSintHash64(3, testCases.map(function(c) {
|
||||
return jspb.utils.decimalStringToHash64(c.original);
|
||||
}));
|
||||
|
||||
writer.writeRepeatedSplitZigzagVarint64(
|
||||
4, testCases.map(function(c) {
|
||||
return c.original;
|
||||
}),
|
||||
decimalToLowBits, decimalToHighBits);
|
||||
|
||||
writer.writePackedSint64String(5, testCases.map(function(c) {
|
||||
return c.original;
|
||||
}));
|
||||
|
||||
writer.writePackedSintHash64(6, testCases.map(function(c) {
|
||||
return jspb.utils.decimalStringToHash64(c.original);
|
||||
}));
|
||||
|
||||
writer.writePackedSplitZigzagVarint64(
|
||||
7, testCases.map(function(c) {
|
||||
return c.original;
|
||||
}),
|
||||
decimalToLowBits, decimalToHighBits);
|
||||
|
||||
// Verify by reading the stream as normal int64 fields and checking with
|
||||
// the canonical zigzag encoding of each value.
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
testCases.forEach(function(c) {
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(1);
|
||||
expect(reader.readUint64String()).toEqual(c.zigzag);
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(1);
|
||||
expect(reader.readUint64String()).toEqual(c.zigzag);
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(1);
|
||||
expect(reader.readUint64String()).toEqual(c.zigzag);
|
||||
});
|
||||
|
||||
testCases.forEach(function(c) {
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(2);
|
||||
expect(reader.readUint64String()).toEqual(c.zigzag);
|
||||
});
|
||||
|
||||
testCases.forEach(function(c) {
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(3);
|
||||
expect(reader.readUint64String()).toEqual(c.zigzag);
|
||||
});
|
||||
|
||||
testCases.forEach(function(c) {
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(4);
|
||||
expect(reader.readUint64String()).toEqual(c.zigzag);
|
||||
});
|
||||
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(5);
|
||||
expect(reader.readPackedUint64String()).toEqual(testCases.map(function(c) {
|
||||
return c.zigzag;
|
||||
}));
|
||||
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(6);
|
||||
expect(reader.readPackedUint64String()).toEqual(testCases.map(function(c) {
|
||||
return c.zigzag;
|
||||
}));
|
||||
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(7);
|
||||
expect(reader.readPackedUint64String()).toEqual(testCases.map(function(c) {
|
||||
return c.zigzag;
|
||||
}));
|
||||
});
|
||||
|
||||
it('writes float32 fields', function() {
|
||||
var testCases = [
|
||||
0, 1, -1, jspb.BinaryConstants.FLOAT32_MIN,
|
||||
-jspb.BinaryConstants.FLOAT32_MIN, jspb.BinaryConstants.FLOAT32_MAX,
|
||||
-jspb.BinaryConstants.FLOAT32_MAX, 3.1415927410125732, Infinity,
|
||||
-Infinity, NaN
|
||||
];
|
||||
var writer = new jspb.BinaryWriter();
|
||||
testCases.forEach(function(f) {
|
||||
writer.writeFloat(1, f);
|
||||
});
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
testCases.forEach(function(f) {
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(1);
|
||||
if (isNaN(f)) {
|
||||
expect(isNaN(reader.readFloat())).toEqual(true);
|
||||
} else {
|
||||
expect(reader.readFloat()).toEqual(f);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('writes double fields', function() {
|
||||
var testCases = [
|
||||
0, 1, -1, Number.MAX_SAFE_INTEGER, Number.MIN_SAFE_INTEGER,
|
||||
Number.MAX_VALUE, Number.MIN_VALUE, jspb.BinaryConstants.FLOAT32_MIN,
|
||||
-jspb.BinaryConstants.FLOAT32_MIN, jspb.BinaryConstants.FLOAT32_MAX,
|
||||
-jspb.BinaryConstants.FLOAT32_MAX, Math.PI, Infinity, -Infinity, NaN
|
||||
];
|
||||
var writer = new jspb.BinaryWriter();
|
||||
testCases.forEach(function(f) {
|
||||
writer.writeDouble(1, f);
|
||||
});
|
||||
var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());
|
||||
testCases.forEach(function(f) {
|
||||
reader.nextField();
|
||||
expect(reader.getFieldNumber()).toEqual(1);
|
||||
if (isNaN(f)) {
|
||||
expect(isNaN(reader.readDouble())).toEqual(true);
|
||||
} else {
|
||||
expect(reader.readDouble()).toEqual(f);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
Reference in New Issue
Block a user