Add dependencies locally
This commit is contained in:
312
deps/protobuf/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto2.js
vendored
Normal file
312
deps/protobuf/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto2.js
vendored
Normal file
@ -0,0 +1,312 @@
|
||||
/**
|
||||
* @fileoverview The code size benchmark of apps JSPB for proto2 all types
|
||||
*/
|
||||
goog.module('protobuf.benchmark.code_size.apps_jspb.AllTypesProto2');
|
||||
|
||||
// const ForeignEnum = goog.require('proto.proto2_unittest.ForeignEnum');
|
||||
const ForeignMessage = goog.require('proto.proto2_unittest.ForeignMessage');
|
||||
const TestAllTypes = goog.require('proto.proto2_unittest.TestAllTypes');
|
||||
const TestPackedTypes = goog.require('proto.proto2_unittest.TestPackedTypes');
|
||||
const {ensureCommonBaseLine} = goog.require('protobuf.benchmark.codeSize.codeSizeBase');
|
||||
|
||||
ensureCommonBaseLine();
|
||||
|
||||
/**
|
||||
* The testing scenario is the same as kernel one.
|
||||
* We have
|
||||
* 1) add element to repeated fields
|
||||
* 2) add element list to repeated fields
|
||||
* 3) set fields
|
||||
* 4) set repeated fields element
|
||||
* 5) get fields
|
||||
* 6) get repeated fields element
|
||||
* 7) get repeated fields length
|
||||
* @return {string}
|
||||
*/
|
||||
function accessAllTypes() {
|
||||
const msgAllTypes = TestAllTypes.deserialize('');
|
||||
const msgPackedTypes = TestPackedTypes.deserialize('');
|
||||
|
||||
msgPackedTypes.addPackedBool(true);
|
||||
[true].forEach((e) => msgPackedTypes.addPackedBool(e));
|
||||
msgAllTypes.addRepeatedBool(true, 1);
|
||||
[true].forEach((e) => msgAllTypes.addRepeatedBool(e));
|
||||
msgAllTypes.addRepeatedBytes('1', 1);
|
||||
['1'].forEach((e) => msgAllTypes.addRepeatedBytes(e));
|
||||
msgPackedTypes.addPackedDouble(1.0);
|
||||
[1.0].forEach((e) => msgPackedTypes.addPackedDouble(e));
|
||||
msgAllTypes.addRepeatedDouble(1.0, 1);
|
||||
[1.0].forEach((e) => msgAllTypes.addRepeatedDouble(e));
|
||||
msgPackedTypes.addPackedFixed32(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedFixed32(e));
|
||||
msgAllTypes.addRepeatedFixed32(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedFixed32(e));
|
||||
msgPackedTypes.addPackedFixed64(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedFixed64(e));
|
||||
msgAllTypes.addRepeatedFixed64(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedFixed64(e));
|
||||
msgPackedTypes.addPackedFloat(1.0, 1);
|
||||
[1.0].forEach((e) => msgPackedTypes.addPackedFloat(e));
|
||||
msgAllTypes.addRepeatedFloat(1.0, 1);
|
||||
[1.0].forEach((e) => msgAllTypes.addRepeatedFloat(e));
|
||||
msgPackedTypes.addPackedInt32(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedInt32(e));
|
||||
msgAllTypes.addRepeatedInt32(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedInt32(e));
|
||||
msgPackedTypes.addPackedInt64(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedInt64(e));
|
||||
msgAllTypes.addRepeatedInt64(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedInt64(e));
|
||||
// msgPackedTypes.addPackedEnum(ForeignEnum.FOREIGN_BAR);
|
||||
// [ForeignEnum.FOREIGN_BAR].forEach((e) => msgPackedTypes.addPackedEnum(e));
|
||||
// msgAllTypes.addRepeatedForeignEnum(ForeignEnum.FOREIGN_BAR);
|
||||
// [ForeignEnum.FOREIGN_BAR].forEach(
|
||||
// (e) => msgAllTypes.addRepeatedForeignEnum(e));
|
||||
msgAllTypes.addRepeatedForeignMessage(ForeignMessage.deserialize(''), 1);
|
||||
[ForeignMessage.deserialize('')].forEach(
|
||||
(e) => msgAllTypes.addRepeatedForeignMessage(e));
|
||||
msgPackedTypes.addPackedSfixed32(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedSfixed32(e));
|
||||
msgAllTypes.addRepeatedSfixed32(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedSfixed32(e));
|
||||
msgPackedTypes.addPackedSfixed64(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedSfixed64(e));
|
||||
msgAllTypes.addRepeatedSfixed64(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedSfixed64(e));
|
||||
msgPackedTypes.addPackedSint32(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedSint32(e));
|
||||
msgAllTypes.addRepeatedSint32(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedSint32(e));
|
||||
msgPackedTypes.addPackedSint64(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedSint64(e));
|
||||
msgAllTypes.addRepeatedSint64(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedSint64(e));
|
||||
msgAllTypes.addRepeatedString('', 1);
|
||||
[''].forEach((e) => msgAllTypes.addRepeatedString(e));
|
||||
msgPackedTypes.addPackedUint32(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedUint32(e));
|
||||
msgAllTypes.addRepeatedUint32(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedUint32(e));
|
||||
msgPackedTypes.addPackedUint64(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedUint64(e));
|
||||
msgAllTypes.addRepeatedUint64(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedUint64(e));
|
||||
|
||||
msgAllTypes.setOptionalBool(true);
|
||||
msgAllTypes.setOptionalBytes('');
|
||||
msgAllTypes.setOptionalDouble(1.0);
|
||||
msgAllTypes.setOptionalFixed32(1);
|
||||
msgAllTypes.setOptionalFixed64(1);
|
||||
msgAllTypes.setOptionalFloat(1.0);
|
||||
msgAllTypes.setOptionalInt32(1);
|
||||
msgAllTypes.setOptionalInt64(1);
|
||||
// msgAllTypes.setOptionalForeignEnum(ForeignEnum.FOREIGN_BAR);
|
||||
msgAllTypes.setOptionalForeignMessage(ForeignMessage.deserialize(''));
|
||||
msgAllTypes.setOptionalSfixed32(1);
|
||||
msgAllTypes.setOptionalSfixed64(1);
|
||||
msgAllTypes.setOptionalSint32(1);
|
||||
msgAllTypes.setOptionalSint64(1);
|
||||
msgAllTypes.setOptionalString('');
|
||||
msgAllTypes.setOptionalUint32(1);
|
||||
msgAllTypes.setOptionalUint64(1);
|
||||
msgPackedTypes.setPackedBoolList([true]);
|
||||
let arrayVal;
|
||||
arrayVal = msgPackedTypes.getPackedBoolList();
|
||||
arrayVal[0] = true;
|
||||
msgPackedTypes.setPackedBoolList(arrayVal);
|
||||
msgAllTypes.setRepeatedBoolList([true]);
|
||||
arrayVal = msgAllTypes.getRepeatedBoolList();
|
||||
arrayVal[0] = true;
|
||||
msgAllTypes.setRepeatedBoolList(arrayVal);
|
||||
msgAllTypes.setRepeatedBytesList(['']);
|
||||
arrayVal = msgAllTypes.getRepeatedBytesList_asB64();
|
||||
arrayVal[0] = '';
|
||||
msgAllTypes.setRepeatedBytesList(arrayVal);
|
||||
msgPackedTypes.setPackedDoubleList([1.0]);
|
||||
arrayVal = msgPackedTypes.getPackedDoubleList();
|
||||
arrayVal[0] = 1.0;
|
||||
msgPackedTypes.setPackedDoubleList(arrayVal);
|
||||
msgAllTypes.setRepeatedDoubleList([1.0]);
|
||||
arrayVal = msgAllTypes.getRepeatedDoubleList();
|
||||
arrayVal[0] = 1.0;
|
||||
msgAllTypes.setRepeatedDoubleList(arrayVal);
|
||||
msgPackedTypes.setPackedFixed32List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedFixed32List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedFixed32List(arrayVal);
|
||||
msgAllTypes.setRepeatedFixed32List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedFixed32List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedFixed32List(arrayVal);
|
||||
msgPackedTypes.setPackedFixed64List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedFixed64List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedFixed64List(arrayVal);
|
||||
msgAllTypes.setRepeatedFixed64List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedFixed64List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedFixed64List(arrayVal);
|
||||
msgPackedTypes.setPackedFloatList([1.0]);
|
||||
arrayVal = msgPackedTypes.getPackedFloatList();
|
||||
arrayVal[0] = 1.0;
|
||||
msgPackedTypes.setPackedFloatList(arrayVal);
|
||||
msgAllTypes.setRepeatedFloatList([1.0]);
|
||||
arrayVal = msgAllTypes.getRepeatedFloatList();
|
||||
arrayVal[0] = 1.0;
|
||||
msgAllTypes.setRepeatedFloatList(arrayVal);
|
||||
msgPackedTypes.setPackedInt32List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedInt32List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedInt32List(arrayVal);
|
||||
msgAllTypes.setRepeatedInt32List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedInt32List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedInt32List(arrayVal);
|
||||
msgPackedTypes.setPackedInt64List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedInt64List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedInt64List(arrayVal);
|
||||
msgAllTypes.setRepeatedInt64List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedInt64List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedInt64List(arrayVal);
|
||||
// msgPackedTypes.setPackedEnumList([ForeignEnum.FOREIGN_BAR]);
|
||||
// arrayVal = msgPackedTypes.getPackedEnumList();
|
||||
// arrayVal[0] = ForeignEnum.FOREIGN_BAR;
|
||||
// msgPackedTypes.setPackedEnumList(arrayVal);
|
||||
// msgAllTypes.setRepeatedForeignEnumList([ForeignEnum.FOREIGN_BAR]);
|
||||
// arrayVal = msgAllTypes.getRepeatedForeignEnumList();
|
||||
// arrayVal[0] = ForeignEnum.FOREIGN_BAR;
|
||||
// msgAllTypes.setRepeatedForeignEnumList(arrayVal);
|
||||
msgAllTypes.setRepeatedForeignMessageList([ForeignMessage.deserialize('')]);
|
||||
arrayVal = msgAllTypes.getRepeatedForeignMessageList();
|
||||
arrayVal[0] = ForeignMessage.deserialize('');
|
||||
msgAllTypes.setRepeatedForeignMessageList(arrayVal);
|
||||
msgPackedTypes.setPackedSfixed32List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedSfixed32List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedSfixed32List(arrayVal);
|
||||
msgAllTypes.setRepeatedSfixed32List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedSfixed32List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedSfixed32List(arrayVal);
|
||||
msgPackedTypes.setPackedSfixed64List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedSfixed64List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedSfixed64List(arrayVal);
|
||||
msgAllTypes.setRepeatedSfixed64List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedSfixed64List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedSfixed64List(arrayVal);
|
||||
msgPackedTypes.setPackedSint32List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedSint32List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedSint32List(arrayVal);
|
||||
msgAllTypes.setRepeatedSint32List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedSint32List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedSint32List(arrayVal);
|
||||
msgPackedTypes.setPackedSint64List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedSint64List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedSint64List(arrayVal);
|
||||
msgAllTypes.setRepeatedSint64List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedSint64List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedSint64List(arrayVal);
|
||||
msgPackedTypes.setPackedUint32List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedUint32List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedUint32List(arrayVal);
|
||||
msgAllTypes.setRepeatedUint32List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedUint32List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedUint32List(arrayVal);
|
||||
msgPackedTypes.setPackedUint64List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedUint64List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedUint64List(arrayVal);
|
||||
msgAllTypes.setRepeatedUint64List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedUint64List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedUint64List(arrayVal);
|
||||
|
||||
let s = '';
|
||||
s += msgAllTypes.getOptionalBool() || false;
|
||||
s += msgAllTypes.getOptionalBytes_asB64() || '';
|
||||
// s += msgAllTypes.getOptionalBytes_asU8() || new Uint8Array([]);
|
||||
s += msgAllTypes.getOptionalDouble() || 0.0;
|
||||
s += msgAllTypes.getOptionalFixed32() || 0;
|
||||
s += msgAllTypes.getOptionalFixed64() || 0;
|
||||
s += msgAllTypes.getOptionalFloat() || 0.0;
|
||||
s += msgAllTypes.getOptionalInt32() || 0;
|
||||
s += msgAllTypes.getOptionalInt64() || 0;
|
||||
// s += msgAllTypes.getOptionalForeignEnum() || ForeignEnum.FOREIGN_BAR;
|
||||
s += msgAllTypes.getOptionalForeignMessage();
|
||||
s += msgAllTypes.getOptionalSfixed32() || 0;
|
||||
s += msgAllTypes.getOptionalSfixed64() || 0;
|
||||
s += msgAllTypes.getOptionalSint32() || 0;
|
||||
s += msgAllTypes.getOptionalSint64() || 0;
|
||||
s += msgAllTypes.getOptionalString() || '';
|
||||
s += msgAllTypes.getOptionalUint32() || 0;
|
||||
s += msgAllTypes.getOptionalUint64() || 0;
|
||||
s += msgAllTypes.getRepeatedBoolList();
|
||||
s += msgAllTypes.getRepeatedBoolList()[0];
|
||||
s += msgAllTypes.getRepeatedBoolList().length;
|
||||
s += msgAllTypes.getRepeatedBytesList_asB64();
|
||||
s += msgAllTypes.getRepeatedBytesList_asB64()[0];
|
||||
s += msgAllTypes.getRepeatedBytesList_asB64().length;
|
||||
s += msgAllTypes.getRepeatedBytesList_asU8();
|
||||
s += msgAllTypes.getRepeatedDoubleList();
|
||||
s += msgAllTypes.getRepeatedDoubleList()[0];
|
||||
s += msgAllTypes.getRepeatedDoubleList().length;
|
||||
s += msgAllTypes.getRepeatedFixed32List();
|
||||
s += msgAllTypes.getRepeatedFixed32List()[0];
|
||||
s += msgAllTypes.getRepeatedFixed32List().length;
|
||||
s += msgAllTypes.getRepeatedFixed64List();
|
||||
s += msgAllTypes.getRepeatedFixed64List()[0];
|
||||
s += msgAllTypes.getRepeatedFixed64List().length;
|
||||
s += msgAllTypes.getRepeatedFloatList();
|
||||
s += msgAllTypes.getRepeatedFloatList()[0];
|
||||
s += msgAllTypes.getRepeatedFloatList().length;
|
||||
s += msgAllTypes.getRepeatedInt32List();
|
||||
s += msgAllTypes.getRepeatedInt32List()[0];
|
||||
s += msgAllTypes.getRepeatedInt32List().length;
|
||||
s += msgAllTypes.getRepeatedInt64List();
|
||||
s += msgAllTypes.getRepeatedInt64List()[0];
|
||||
s += msgAllTypes.getRepeatedInt64List().length;
|
||||
// s += msgAllTypes.getRepeatedForeignEnumList();
|
||||
// s += msgAllTypes.getRepeatedForeignEnumList()[0];
|
||||
// s += msgAllTypes.getRepeatedForeignEnumList().length;
|
||||
s += msgAllTypes.getRepeatedForeignMessageList();
|
||||
s += msgAllTypes.getRepeatedForeignMessageList()[0];
|
||||
s += msgAllTypes.getRepeatedForeignMessageList().length;
|
||||
s += msgAllTypes.getRepeatedSfixed32List();
|
||||
s += msgAllTypes.getRepeatedSfixed32List()[0];
|
||||
s += msgAllTypes.getRepeatedSfixed32List().length;
|
||||
s += msgAllTypes.getRepeatedSfixed64List();
|
||||
s += msgAllTypes.getRepeatedSfixed64List()[0];
|
||||
s += msgAllTypes.getRepeatedSfixed64List().length;
|
||||
s += msgAllTypes.getRepeatedSint32List();
|
||||
s += msgAllTypes.getRepeatedSint32List()[0];
|
||||
s += msgAllTypes.getRepeatedSint32List().length;
|
||||
s += msgAllTypes.getRepeatedSint64List();
|
||||
s += msgAllTypes.getRepeatedSint64List()[0];
|
||||
s += msgAllTypes.getRepeatedSint64List().length;
|
||||
s += msgAllTypes.getRepeatedStringList();
|
||||
s += msgAllTypes.getRepeatedStringList()[0];
|
||||
s += msgAllTypes.getRepeatedStringList().length;
|
||||
s += msgAllTypes.getRepeatedUint32List();
|
||||
s += msgAllTypes.getRepeatedUint32List()[0];
|
||||
s += msgAllTypes.getRepeatedUint32List().length;
|
||||
s += msgAllTypes.getRepeatedUint64List();
|
||||
s += msgAllTypes.getRepeatedUint64List()[0];
|
||||
s += msgAllTypes.getRepeatedUint64List().length;
|
||||
|
||||
s += msgAllTypes.serialize();
|
||||
s += msgPackedTypes.serialize();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
goog.global['__hiddenTest'] += accessAllTypes();
|
312
deps/protobuf/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto3.js
vendored
Normal file
312
deps/protobuf/js/experimental/benchmarks/code_size/apps_jspb/all_types_proto3.js
vendored
Normal file
@ -0,0 +1,312 @@
|
||||
/**
|
||||
* @fileoverview The code size benchmark of apps JSPB for proto3 all types
|
||||
*/
|
||||
goog.module('protobuf.benchmark.code_size.apps_jspb.AllTypesProto3');
|
||||
|
||||
// const ForeignEnum = goog.require('proto.proto3_unittest.ForeignEnum');
|
||||
const ForeignMessage = goog.require('proto.proto3_unittest.ForeignMessage');
|
||||
const TestAllTypes = goog.require('proto.proto3_unittest.TestAllTypes');
|
||||
const TestPackedTypes = goog.require('proto.proto3_unittest.TestPackedTypes');
|
||||
const {ensureCommonBaseLine} = goog.require('protobuf.benchmark.codeSize.codeSizeBase');
|
||||
|
||||
ensureCommonBaseLine();
|
||||
|
||||
/**
|
||||
* The testing scenario is the same as kernel one.
|
||||
* We have
|
||||
* 1) add element to repeated fields
|
||||
* 2) add element list to repeated fields
|
||||
* 3) set fields
|
||||
* 4) set repeated fields element
|
||||
* 5) get fields
|
||||
* 6) get repeated fields element
|
||||
* 7) get repeated fields length
|
||||
* @return {string}
|
||||
*/
|
||||
function accessAllTypes() {
|
||||
const msgAllTypes = TestAllTypes.deserialize('');
|
||||
const msgPackedTypes = TestPackedTypes.deserialize('');
|
||||
|
||||
msgPackedTypes.addPackedBool(true);
|
||||
[true].forEach((e) => msgPackedTypes.addPackedBool(e));
|
||||
msgAllTypes.addRepeatedBool(true, 1);
|
||||
[true].forEach((e) => msgAllTypes.addRepeatedBool(e));
|
||||
msgAllTypes.addRepeatedBytes('1', 1);
|
||||
['1'].forEach((e) => msgAllTypes.addRepeatedBytes(e));
|
||||
msgPackedTypes.addPackedDouble(1.0);
|
||||
[1.0].forEach((e) => msgPackedTypes.addPackedDouble(e));
|
||||
msgAllTypes.addRepeatedDouble(1.0, 1);
|
||||
[1.0].forEach((e) => msgAllTypes.addRepeatedDouble(e));
|
||||
msgPackedTypes.addPackedFixed32(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedFixed32(e));
|
||||
msgAllTypes.addRepeatedFixed32(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedFixed32(e));
|
||||
msgPackedTypes.addPackedFixed64(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedFixed64(e));
|
||||
msgAllTypes.addRepeatedFixed64(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedFixed64(e));
|
||||
msgPackedTypes.addPackedFloat(1.0, 1);
|
||||
[1.0].forEach((e) => msgPackedTypes.addPackedFloat(e));
|
||||
msgAllTypes.addRepeatedFloat(1.0, 1);
|
||||
[1.0].forEach((e) => msgAllTypes.addRepeatedFloat(e));
|
||||
msgPackedTypes.addPackedInt32(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedInt32(e));
|
||||
msgAllTypes.addRepeatedInt32(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedInt32(e));
|
||||
msgPackedTypes.addPackedInt64(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedInt64(e));
|
||||
msgAllTypes.addRepeatedInt64(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedInt64(e));
|
||||
// msgPackedTypes.addPackedEnum(ForeignEnum.FOREIGN_BAR);
|
||||
// [ForeignEnum.FOREIGN_BAR].forEach((e) => msgPackedTypes.addPackedEnum(e));
|
||||
// msgAllTypes.addRepeatedForeignEnum(ForeignEnum.FOREIGN_BAR);
|
||||
// [ForeignEnum.FOREIGN_BAR].forEach(
|
||||
// (e) => msgAllTypes.addRepeatedForeignEnum(e));
|
||||
msgAllTypes.addRepeatedForeignMessage(ForeignMessage.deserialize(''), 1);
|
||||
[ForeignMessage.deserialize('')].forEach(
|
||||
(e) => msgAllTypes.addRepeatedForeignMessage(e));
|
||||
msgPackedTypes.addPackedSfixed32(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedSfixed32(e));
|
||||
msgAllTypes.addRepeatedSfixed32(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedSfixed32(e));
|
||||
msgPackedTypes.addPackedSfixed64(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedSfixed64(e));
|
||||
msgAllTypes.addRepeatedSfixed64(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedSfixed64(e));
|
||||
msgPackedTypes.addPackedSint32(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedSint32(e));
|
||||
msgAllTypes.addRepeatedSint32(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedSint32(e));
|
||||
msgPackedTypes.addPackedSint64(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedSint64(e));
|
||||
msgAllTypes.addRepeatedSint64(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedSint64(e));
|
||||
msgAllTypes.addRepeatedString('', 1);
|
||||
[''].forEach((e) => msgAllTypes.addRepeatedString(e));
|
||||
msgPackedTypes.addPackedUint32(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedUint32(e));
|
||||
msgAllTypes.addRepeatedUint32(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedUint32(e));
|
||||
msgPackedTypes.addPackedUint64(1, 1);
|
||||
[1].forEach((e) => msgPackedTypes.addPackedUint64(e));
|
||||
msgAllTypes.addRepeatedUint64(1, 1);
|
||||
[1].forEach((e) => msgAllTypes.addRepeatedUint64(e));
|
||||
|
||||
msgAllTypes.setOptionalBool(true);
|
||||
msgAllTypes.setOptionalBytes('');
|
||||
msgAllTypes.setOptionalDouble(1.0);
|
||||
msgAllTypes.setOptionalFixed32(1);
|
||||
msgAllTypes.setOptionalFixed64(1);
|
||||
msgAllTypes.setOptionalFloat(1.0);
|
||||
msgAllTypes.setOptionalInt32(1);
|
||||
msgAllTypes.setOptionalInt64(1);
|
||||
// msgAllTypes.setOptionalForeignEnum(ForeignEnum.FOREIGN_BAR);
|
||||
msgAllTypes.setOptionalForeignMessage(ForeignMessage.deserialize(''));
|
||||
msgAllTypes.setOptionalSfixed32(1);
|
||||
msgAllTypes.setOptionalSfixed64(1);
|
||||
msgAllTypes.setOptionalSint32(1);
|
||||
msgAllTypes.setOptionalSint64(1);
|
||||
msgAllTypes.setOptionalString('');
|
||||
msgAllTypes.setOptionalUint32(1);
|
||||
msgAllTypes.setOptionalUint64(1);
|
||||
msgPackedTypes.setPackedBoolList([true]);
|
||||
let arrayVal;
|
||||
arrayVal = msgPackedTypes.getPackedBoolList();
|
||||
arrayVal[0] = true;
|
||||
msgPackedTypes.setPackedBoolList(arrayVal);
|
||||
msgAllTypes.setRepeatedBoolList([true]);
|
||||
arrayVal = msgAllTypes.getRepeatedBoolList();
|
||||
arrayVal[0] = true;
|
||||
msgAllTypes.setRepeatedBoolList(arrayVal);
|
||||
msgAllTypes.setRepeatedBytesList(['']);
|
||||
arrayVal = msgAllTypes.getRepeatedBytesList_asB64();
|
||||
arrayVal[0] = '';
|
||||
msgAllTypes.setRepeatedBytesList(arrayVal);
|
||||
msgPackedTypes.setPackedDoubleList([1.0]);
|
||||
arrayVal = msgPackedTypes.getPackedDoubleList();
|
||||
arrayVal[0] = 1.0;
|
||||
msgPackedTypes.setPackedDoubleList(arrayVal);
|
||||
msgAllTypes.setRepeatedDoubleList([1.0]);
|
||||
arrayVal = msgAllTypes.getRepeatedDoubleList();
|
||||
arrayVal[0] = 1.0;
|
||||
msgAllTypes.setRepeatedDoubleList(arrayVal);
|
||||
msgPackedTypes.setPackedFixed32List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedFixed32List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedFixed32List(arrayVal);
|
||||
msgAllTypes.setRepeatedFixed32List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedFixed32List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedFixed32List(arrayVal);
|
||||
msgPackedTypes.setPackedFixed64List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedFixed64List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedFixed64List(arrayVal);
|
||||
msgAllTypes.setRepeatedFixed64List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedFixed64List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedFixed64List(arrayVal);
|
||||
msgPackedTypes.setPackedFloatList([1.0]);
|
||||
arrayVal = msgPackedTypes.getPackedFloatList();
|
||||
arrayVal[0] = 1.0;
|
||||
msgPackedTypes.setPackedFloatList(arrayVal);
|
||||
msgAllTypes.setRepeatedFloatList([1.0]);
|
||||
arrayVal = msgAllTypes.getRepeatedFloatList();
|
||||
arrayVal[0] = 1.0;
|
||||
msgAllTypes.setRepeatedFloatList(arrayVal);
|
||||
msgPackedTypes.setPackedInt32List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedInt32List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedInt32List(arrayVal);
|
||||
msgAllTypes.setRepeatedInt32List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedInt32List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedInt32List(arrayVal);
|
||||
msgPackedTypes.setPackedInt64List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedInt64List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedInt64List(arrayVal);
|
||||
msgAllTypes.setRepeatedInt64List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedInt64List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedInt64List(arrayVal);
|
||||
// msgPackedTypes.setPackedEnumList([ForeignEnum.FOREIGN_BAR]);
|
||||
// arrayVal = msgPackedTypes.getPackedEnumList();
|
||||
// arrayVal[0] = ForeignEnum.FOREIGN_BAR;
|
||||
// msgPackedTypes.setPackedEnumList(arrayVal);
|
||||
// msgAllTypes.setRepeatedForeignEnumList([ForeignEnum.FOREIGN_BAR]);
|
||||
// arrayVal = msgAllTypes.getRepeatedForeignEnumList();
|
||||
// arrayVal[0] = ForeignEnum.FOREIGN_BAR;
|
||||
// msgAllTypes.setRepeatedForeignEnumList(arrayVal);
|
||||
msgAllTypes.setRepeatedForeignMessageList([ForeignMessage.deserialize('')]);
|
||||
arrayVal = msgAllTypes.getRepeatedForeignMessageList();
|
||||
arrayVal[0] = ForeignMessage.deserialize('');
|
||||
msgAllTypes.setRepeatedForeignMessageList(arrayVal);
|
||||
msgPackedTypes.setPackedSfixed32List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedSfixed32List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedSfixed32List(arrayVal);
|
||||
msgAllTypes.setRepeatedSfixed32List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedSfixed32List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedSfixed32List(arrayVal);
|
||||
msgPackedTypes.setPackedSfixed64List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedSfixed64List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedSfixed64List(arrayVal);
|
||||
msgAllTypes.setRepeatedSfixed64List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedSfixed64List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedSfixed64List(arrayVal);
|
||||
msgPackedTypes.setPackedSint32List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedSint32List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedSint32List(arrayVal);
|
||||
msgAllTypes.setRepeatedSint32List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedSint32List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedSint32List(arrayVal);
|
||||
msgPackedTypes.setPackedSint64List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedSint64List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedSint64List(arrayVal);
|
||||
msgAllTypes.setRepeatedSint64List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedSint64List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedSint64List(arrayVal);
|
||||
msgPackedTypes.setPackedUint32List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedUint32List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedUint32List(arrayVal);
|
||||
msgAllTypes.setRepeatedUint32List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedUint32List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedUint32List(arrayVal);
|
||||
msgPackedTypes.setPackedUint64List([1]);
|
||||
arrayVal = msgPackedTypes.getPackedUint64List();
|
||||
arrayVal[0] = 1;
|
||||
msgPackedTypes.setPackedUint64List(arrayVal);
|
||||
msgAllTypes.setRepeatedUint64List([1]);
|
||||
arrayVal = msgAllTypes.getRepeatedUint64List();
|
||||
arrayVal[0] = 1;
|
||||
msgAllTypes.setRepeatedUint64List(arrayVal);
|
||||
|
||||
let s = '';
|
||||
s += msgAllTypes.getOptionalBool() || false;
|
||||
s += msgAllTypes.getOptionalBytes_asB64() || '';
|
||||
// s += msgAllTypes.getOptionalBytes_asU8() || new Uint8Array([]);
|
||||
s += msgAllTypes.getOptionalDouble() || 0.0;
|
||||
s += msgAllTypes.getOptionalFixed32() || 0;
|
||||
s += msgAllTypes.getOptionalFixed64() || 0;
|
||||
s += msgAllTypes.getOptionalFloat() || 0.0;
|
||||
s += msgAllTypes.getOptionalInt32() || 0;
|
||||
s += msgAllTypes.getOptionalInt64() || 0;
|
||||
// s += msgAllTypes.getOptionalForeignEnum() || ForeignEnum.FOREIGN_BAR;
|
||||
s += msgAllTypes.getOptionalForeignMessage();
|
||||
s += msgAllTypes.getOptionalSfixed32() || 0;
|
||||
s += msgAllTypes.getOptionalSfixed64() || 0;
|
||||
s += msgAllTypes.getOptionalSint32() || 0;
|
||||
s += msgAllTypes.getOptionalSint64() || 0;
|
||||
s += msgAllTypes.getOptionalString() || '';
|
||||
s += msgAllTypes.getOptionalUint32() || 0;
|
||||
s += msgAllTypes.getOptionalUint64() || 0;
|
||||
s += msgAllTypes.getRepeatedBoolList();
|
||||
s += msgAllTypes.getRepeatedBoolList()[0];
|
||||
s += msgAllTypes.getRepeatedBoolList().length;
|
||||
s += msgAllTypes.getRepeatedBytesList_asB64();
|
||||
s += msgAllTypes.getRepeatedBytesList_asB64()[0];
|
||||
s += msgAllTypes.getRepeatedBytesList_asB64().length;
|
||||
s += msgAllTypes.getRepeatedBytesList_asU8();
|
||||
s += msgAllTypes.getRepeatedDoubleList();
|
||||
s += msgAllTypes.getRepeatedDoubleList()[0];
|
||||
s += msgAllTypes.getRepeatedDoubleList().length;
|
||||
s += msgAllTypes.getRepeatedFixed32List();
|
||||
s += msgAllTypes.getRepeatedFixed32List()[0];
|
||||
s += msgAllTypes.getRepeatedFixed32List().length;
|
||||
s += msgAllTypes.getRepeatedFixed64List();
|
||||
s += msgAllTypes.getRepeatedFixed64List()[0];
|
||||
s += msgAllTypes.getRepeatedFixed64List().length;
|
||||
s += msgAllTypes.getRepeatedFloatList();
|
||||
s += msgAllTypes.getRepeatedFloatList()[0];
|
||||
s += msgAllTypes.getRepeatedFloatList().length;
|
||||
s += msgAllTypes.getRepeatedInt32List();
|
||||
s += msgAllTypes.getRepeatedInt32List()[0];
|
||||
s += msgAllTypes.getRepeatedInt32List().length;
|
||||
s += msgAllTypes.getRepeatedInt64List();
|
||||
s += msgAllTypes.getRepeatedInt64List()[0];
|
||||
s += msgAllTypes.getRepeatedInt64List().length;
|
||||
// s += msgAllTypes.getRepeatedForeignEnumList();
|
||||
// s += msgAllTypes.getRepeatedForeignEnumList()[0];
|
||||
// s += msgAllTypes.getRepeatedForeignEnumList().length;
|
||||
s += msgAllTypes.getRepeatedForeignMessageList();
|
||||
s += msgAllTypes.getRepeatedForeignMessageList()[0];
|
||||
s += msgAllTypes.getRepeatedForeignMessageList().length;
|
||||
s += msgAllTypes.getRepeatedSfixed32List();
|
||||
s += msgAllTypes.getRepeatedSfixed32List()[0];
|
||||
s += msgAllTypes.getRepeatedSfixed32List().length;
|
||||
s += msgAllTypes.getRepeatedSfixed64List();
|
||||
s += msgAllTypes.getRepeatedSfixed64List()[0];
|
||||
s += msgAllTypes.getRepeatedSfixed64List().length;
|
||||
s += msgAllTypes.getRepeatedSint32List();
|
||||
s += msgAllTypes.getRepeatedSint32List()[0];
|
||||
s += msgAllTypes.getRepeatedSint32List().length;
|
||||
s += msgAllTypes.getRepeatedSint64List();
|
||||
s += msgAllTypes.getRepeatedSint64List()[0];
|
||||
s += msgAllTypes.getRepeatedSint64List().length;
|
||||
s += msgAllTypes.getRepeatedStringList();
|
||||
s += msgAllTypes.getRepeatedStringList()[0];
|
||||
s += msgAllTypes.getRepeatedStringList().length;
|
||||
s += msgAllTypes.getRepeatedUint32List();
|
||||
s += msgAllTypes.getRepeatedUint32List()[0];
|
||||
s += msgAllTypes.getRepeatedUint32List().length;
|
||||
s += msgAllTypes.getRepeatedUint64List();
|
||||
s += msgAllTypes.getRepeatedUint64List()[0];
|
||||
s += msgAllTypes.getRepeatedUint64List().length;
|
||||
|
||||
s += msgAllTypes.serialize();
|
||||
s += msgPackedTypes.serialize();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
goog.global['__hiddenTest'] += accessAllTypes();
|
53
deps/protobuf/js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto2.js
vendored
Normal file
53
deps/protobuf/js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto2.js
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @fileoverview The code size benchmark of apps JSPB for proto2 popular types.
|
||||
*/
|
||||
goog.module('protobuf.benchmark.code_size.apps_jspb.PopularTypesProto2');
|
||||
|
||||
// const ForeignEnum = goog.require('proto.proto2_unittest.ForeignEnum');
|
||||
const ForeignMessage = goog.require('proto.proto2_unittest.ForeignMessage');
|
||||
const TestAllTypes = goog.require('proto.proto2_unittest.TestAllTypes');
|
||||
const {ensureCommonBaseLine} = goog.require('protobuf.benchmark.codeSize.codeSizeBase');
|
||||
|
||||
ensureCommonBaseLine();
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
function accessPopularTypes() {
|
||||
const msgAllTypes = TestAllTypes.deserialize('');
|
||||
msgAllTypes.addRepeatedForeignMessage(ForeignMessage.deserialize(''), 1);
|
||||
[ForeignMessage.deserialize('')].forEach(
|
||||
(e) => msgAllTypes.addRepeatedForeignMessage(e));
|
||||
|
||||
msgAllTypes.setOptionalString('');
|
||||
msgAllTypes.setOptionalInt32(1);
|
||||
msgAllTypes.setOptionalForeignMessage(ForeignMessage.deserialize(''));
|
||||
msgAllTypes.setOptionalBool(true);
|
||||
// msgAllTypes.setOptionalForeignEnum(ForeignEnum.FOREIGN_BAR);
|
||||
msgAllTypes.setOptionalInt64(1);
|
||||
msgAllTypes.setOptionalDouble(1.0);
|
||||
msgAllTypes.setRepeatedForeignMessageList([ForeignMessage.deserialize('')]);
|
||||
let arrayVal = msgAllTypes.getRepeatedForeignMessageList();
|
||||
arrayVal[0] = ForeignMessage.deserialize('');
|
||||
msgAllTypes.setRepeatedForeignMessageList(arrayVal);
|
||||
msgAllTypes.setOptionalUint64(1);
|
||||
|
||||
let s = '';
|
||||
s += msgAllTypes.getOptionalString();
|
||||
s += msgAllTypes.getOptionalInt32();
|
||||
s += msgAllTypes.getOptionalForeignMessage();
|
||||
s += msgAllTypes.getOptionalBool();
|
||||
// s += msgAllTypes.getOptionalForeignEnum();
|
||||
s += msgAllTypes.getOptionalInt64();
|
||||
s += msgAllTypes.getOptionalDouble();
|
||||
s += msgAllTypes.getRepeatedForeignMessageList();
|
||||
s += msgAllTypes.getRepeatedForeignMessageList()[0];
|
||||
s += msgAllTypes.getRepeatedForeignMessageList().length;
|
||||
s += msgAllTypes.getOptionalUint64();
|
||||
|
||||
s += msgAllTypes.serialize();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
goog.global['__hiddenTest'] += accessPopularTypes();
|
53
deps/protobuf/js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto3.js
vendored
Normal file
53
deps/protobuf/js/experimental/benchmarks/code_size/apps_jspb/popular_types_proto3.js
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
/**
|
||||
* @fileoverview The code size benchmark of apps JSPB for proto3 popular types.
|
||||
*/
|
||||
goog.module('protobuf.benchmark.code_size.apps_jspb.PopularTypesProto3');
|
||||
|
||||
// const ForeignEnum = goog.require('proto.proto3_unittest.ForeignEnum');
|
||||
const ForeignMessage = goog.require('proto.proto3_unittest.ForeignMessage');
|
||||
const TestAllTypes = goog.require('proto.proto3_unittest.TestAllTypes');
|
||||
const {ensureCommonBaseLine} = goog.require('protobuf.benchmark.codeSize.codeSizeBase');
|
||||
|
||||
ensureCommonBaseLine();
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
function accessPopularTypes() {
|
||||
const msgAllTypes = TestAllTypes.deserialize('');
|
||||
msgAllTypes.addRepeatedForeignMessage(ForeignMessage.deserialize(''), 1);
|
||||
[ForeignMessage.deserialize('')].forEach(
|
||||
(e) => msgAllTypes.addRepeatedForeignMessage(e));
|
||||
|
||||
msgAllTypes.setOptionalString('');
|
||||
msgAllTypes.setOptionalInt32(1);
|
||||
msgAllTypes.setOptionalForeignMessage(ForeignMessage.deserialize(''));
|
||||
msgAllTypes.setOptionalBool(true);
|
||||
// msgAllTypes.setOptionalForeignEnum(ForeignEnum.FOREIGN_BAR);
|
||||
msgAllTypes.setOptionalInt64(1);
|
||||
msgAllTypes.setOptionalDouble(1.0);
|
||||
msgAllTypes.setRepeatedForeignMessageList([ForeignMessage.deserialize('')]);
|
||||
let arrayVal = msgAllTypes.getRepeatedForeignMessageList();
|
||||
arrayVal[0] = ForeignMessage.deserialize('');
|
||||
msgAllTypes.setRepeatedForeignMessageList(arrayVal);
|
||||
msgAllTypes.setOptionalUint64(1);
|
||||
|
||||
let s = '';
|
||||
s += msgAllTypes.getOptionalString();
|
||||
s += msgAllTypes.getOptionalInt32();
|
||||
s += msgAllTypes.getOptionalForeignMessage();
|
||||
s += msgAllTypes.getOptionalBool();
|
||||
// s += msgAllTypes.getOptionalForeignEnum();
|
||||
s += msgAllTypes.getOptionalInt64();
|
||||
s += msgAllTypes.getOptionalDouble();
|
||||
s += msgAllTypes.getRepeatedForeignMessageList();
|
||||
s += msgAllTypes.getRepeatedForeignMessageList()[0];
|
||||
s += msgAllTypes.getRepeatedForeignMessageList().length;
|
||||
s += msgAllTypes.getOptionalUint64();
|
||||
|
||||
s += msgAllTypes.serialize();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
goog.global['__hiddenTest'] += accessPopularTypes();
|
57
deps/protobuf/js/experimental/benchmarks/code_size/code_size_base.js
vendored
Normal file
57
deps/protobuf/js/experimental/benchmarks/code_size/code_size_base.js
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @fileoverview Ensures types are live that would be live in a typical g3
|
||||
* JS program.
|
||||
*
|
||||
* Making certain constructs live ensures that we compare against the same
|
||||
* baseline for all code size benchmarks. This increases the size
|
||||
* of our benchmarks, but note that this size in a regular app would be
|
||||
* attributes to other places.
|
||||
*/
|
||||
goog.module('protobuf.benchmark.codeSize.codeSizeBase');
|
||||
|
||||
|
||||
/**
|
||||
* Ensures that the array iterator polyfill is live.
|
||||
* @return {string}
|
||||
*/
|
||||
function useArrayIterator() {
|
||||
let a = [];
|
||||
let s = '';
|
||||
for (let value of a) {
|
||||
s += value;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the symbol iterator polyfill is live.
|
||||
* @return {string}
|
||||
*/
|
||||
function useSymbolIterator() {
|
||||
/**
|
||||
* @implements {Iterable}
|
||||
*/
|
||||
class Foo {
|
||||
/** @return {!Iterator} */
|
||||
[Symbol.iterator]() {}
|
||||
}
|
||||
|
||||
let foo = new Foo();
|
||||
let s = '';
|
||||
for (let value of foo) {
|
||||
s += value;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures certain base libs are live so we can have an apples to apples
|
||||
* comparison for code size of different implementations
|
||||
*/
|
||||
function ensureCommonBaseLine() {
|
||||
goog.global['__hiddenTest'] += useArrayIterator();
|
||||
goog.global['__hiddenTest'] += useSymbolIterator();
|
||||
}
|
||||
|
||||
|
||||
exports = {ensureCommonBaseLine};
|
227
deps/protobuf/js/experimental/benchmarks/code_size/kernel/all_types.js
vendored
Normal file
227
deps/protobuf/js/experimental/benchmarks/code_size/kernel/all_types.js
vendored
Normal file
@ -0,0 +1,227 @@
|
||||
/**
|
||||
* @fileoverview The code size benchmark of binary kernel for accessing all
|
||||
* types setter and getter.
|
||||
*/
|
||||
goog.module('protobuf.benchmark.KernelCodeSizeBenchmarkAllTypes');
|
||||
|
||||
const ByteString = goog.require('protobuf.ByteString');
|
||||
const Int64 = goog.require('protobuf.Int64');
|
||||
const Kernel = goog.require('protobuf.runtime.Kernel');
|
||||
const TestMessage = goog.require('protobuf.testing.binary.TestMessage');
|
||||
const {ensureCommonBaseLine} = goog.require('protobuf.benchmark.codeSize.codeSizeBase');
|
||||
|
||||
ensureCommonBaseLine();
|
||||
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
function accessAllTypes() {
|
||||
const message = new TestMessage(Kernel.createEmpty());
|
||||
|
||||
message.addPackedBoolElement(1, true);
|
||||
message.addPackedBoolIterable(1, [true]);
|
||||
message.addUnpackedBoolElement(1, true);
|
||||
message.addUnpackedBoolIterable(1, [true]);
|
||||
message.addRepeatedBytesElement(1, ByteString.EMPTY);
|
||||
message.addRepeatedBytesIterable(1, [ByteString.EMPTY]);
|
||||
message.addPackedDoubleElement(1, 1.0);
|
||||
message.addPackedDoubleIterable(1, [1.0]);
|
||||
message.addUnpackedDoubleElement(1, 1.0);
|
||||
message.addUnpackedDoubleIterable(1, [1.0]);
|
||||
message.addPackedFixed32Element(1, 1);
|
||||
message.addPackedFixed32Iterable(1, [1]);
|
||||
message.addUnpackedFixed32Element(1, 1);
|
||||
message.addUnpackedFixed32Iterable(1, [1]);
|
||||
message.addPackedFixed64Element(1, Int64.fromBits(0, 1));
|
||||
message.addPackedFixed64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.addUnpackedFixed64Element(1, Int64.fromBits(0, 1));
|
||||
message.addUnpackedFixed64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.addPackedFloatElement(1, 1.0);
|
||||
message.addPackedFloatIterable(1, [1.0]);
|
||||
message.addUnpackedFloatElement(1, 1.0);
|
||||
message.addUnpackedFloatIterable(1, [1.0]);
|
||||
message.addPackedInt32Element(1, 1);
|
||||
message.addPackedInt32Iterable(1, [1]);
|
||||
message.addUnpackedInt32Element(1, 1);
|
||||
message.addUnpackedInt32Iterable(1, [1]);
|
||||
message.addPackedInt64Element(1, Int64.fromBits(0, 1));
|
||||
message.addPackedInt64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.addUnpackedInt64Element(1, Int64.fromBits(0, 1));
|
||||
message.addUnpackedInt64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.addRepeatedMessageElement(1, message, TestMessage.instanceCreator);
|
||||
message.addRepeatedMessageIterable(1, [message], TestMessage.instanceCreator);
|
||||
message.addPackedSfixed32Element(1, 1);
|
||||
message.addPackedSfixed32Iterable(1, [1]);
|
||||
message.addUnpackedSfixed32Element(1, 1);
|
||||
message.addUnpackedSfixed32Iterable(1, [1]);
|
||||
message.addPackedSfixed64Element(1, Int64.fromBits(0, 1));
|
||||
message.addPackedSfixed64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.addUnpackedSfixed64Element(1, Int64.fromBits(0, 1));
|
||||
message.addUnpackedSfixed64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.addPackedSint32Element(1, 1);
|
||||
message.addPackedSint32Iterable(1, [1]);
|
||||
message.addUnpackedSint32Element(1, 1);
|
||||
message.addUnpackedSint32Iterable(1, [1]);
|
||||
message.addPackedSint64Element(1, Int64.fromBits(0, 1));
|
||||
message.addPackedSint64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.addUnpackedSint64Element(1, Int64.fromBits(0, 1));
|
||||
message.addUnpackedSint64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.addRepeatedStringElement(1, '');
|
||||
message.addRepeatedStringIterable(1, ['']);
|
||||
message.addPackedUint32Element(1, 1);
|
||||
message.addPackedUint32Iterable(1, [1]);
|
||||
message.addUnpackedUint32Element(1, 1);
|
||||
message.addUnpackedUint32Iterable(1, [1]);
|
||||
message.addPackedUint64Element(1, Int64.fromBits(0, 1));
|
||||
message.addPackedUint64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.addUnpackedUint64Element(1, Int64.fromBits(0, 1));
|
||||
message.addUnpackedUint64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
|
||||
message.setBool(1, true);
|
||||
message.setBytes(1, ByteString.EMPTY);
|
||||
message.setDouble(1, 1.0);
|
||||
message.setFixed32(1, 1);
|
||||
message.setFixed64(1, Int64.fromBits(0, 1));
|
||||
message.setFloat(1, 1.0);
|
||||
message.setInt32(1, 1);
|
||||
message.setInt64(1, Int64.fromBits(0, 1));
|
||||
message.setMessage(1, message);
|
||||
message.setSfixed32(1, 1);
|
||||
message.setSfixed64(1, Int64.fromBits(0, 1));
|
||||
message.setSint32(1, 1);
|
||||
message.setSint64(1, Int64.fromBits(0, 1));
|
||||
message.setString(1, 'abc');
|
||||
message.setUint32(1, 1);
|
||||
message.setUint64(1, Int64.fromBits(0, 1));
|
||||
message.setPackedBoolElement(1, 0, true);
|
||||
message.setPackedBoolIterable(1, [true]);
|
||||
message.setUnpackedBoolElement(1, 0, true);
|
||||
message.setUnpackedBoolIterable(1, [true]);
|
||||
message.setRepeatedBytesElement(1, 0, ByteString.EMPTY);
|
||||
message.setRepeatedBytesIterable(1, [ByteString.EMPTY]);
|
||||
message.setPackedDoubleElement(1, 0, 1.0);
|
||||
message.setPackedDoubleIterable(1, [1.0]);
|
||||
message.setUnpackedDoubleElement(1, 0, 1.0);
|
||||
message.setUnpackedDoubleIterable(1, [1.0]);
|
||||
message.setPackedFixed32Element(1, 0, 1);
|
||||
message.setPackedFixed32Iterable(1, [1]);
|
||||
message.setUnpackedFixed32Element(1, 0, 1);
|
||||
message.setUnpackedFixed32Iterable(1, [1]);
|
||||
message.setPackedFixed64Element(1, 0, Int64.fromBits(0, 1));
|
||||
message.setPackedFixed64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.setUnpackedFixed64Element(1, 0, Int64.fromBits(0, 1));
|
||||
message.setUnpackedFixed64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.setPackedFloatElement(1, 0, 1.0);
|
||||
message.setPackedFloatIterable(1, [1.0]);
|
||||
message.setUnpackedFloatElement(1, 0, 1.0);
|
||||
message.setUnpackedFloatIterable(1, [1.0]);
|
||||
message.setPackedInt32Element(1, 0, 1);
|
||||
message.setPackedInt32Iterable(1, [1]);
|
||||
message.setUnpackedInt32Element(1, 0, 1);
|
||||
message.setUnpackedInt32Iterable(1, [1]);
|
||||
message.setPackedInt64Element(1, 0, Int64.fromBits(0, 1));
|
||||
message.setPackedInt64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.setUnpackedInt64Element(1, 0, Int64.fromBits(0, 1));
|
||||
message.setUnpackedInt64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.setRepeatedMessageElement(1, message, TestMessage.instanceCreator, 0);
|
||||
message.setRepeatedMessageIterable(1, [message]);
|
||||
message.setPackedSfixed32Element(1, 0, 1);
|
||||
message.setPackedSfixed32Iterable(1, [1]);
|
||||
message.setUnpackedSfixed32Element(1, 0, 1);
|
||||
message.setUnpackedSfixed32Iterable(1, [1]);
|
||||
message.setPackedSfixed64Element(1, 0, Int64.fromBits(0, 1));
|
||||
message.setPackedSfixed64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.setUnpackedSfixed64Element(1, 0, Int64.fromBits(0, 1));
|
||||
message.setUnpackedSfixed64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.setRepeatedStringElement(1, 0, '');
|
||||
message.setRepeatedStringIterable(1, ['']);
|
||||
message.setPackedSint32Element(1, 0, 1);
|
||||
message.setPackedSint32Iterable(1, [1]);
|
||||
message.setUnpackedSint32Element(1, 0, 1);
|
||||
message.setUnpackedSint32Iterable(1, [1]);
|
||||
message.setPackedSint64Element(1, 0, Int64.fromBits(0, 1));
|
||||
message.setPackedSint64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.setUnpackedSint64Element(1, 0, Int64.fromBits(0, 1));
|
||||
message.setUnpackedSint64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.setPackedUint32Element(1, 0, 1);
|
||||
message.setPackedUint32Iterable(1, [1]);
|
||||
message.setUnpackedUint32Element(1, 0, 1);
|
||||
message.setUnpackedUint32Iterable(1, [1]);
|
||||
message.setPackedUint64Element(1, 0, Int64.fromBits(0, 1));
|
||||
message.setPackedUint64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
message.setUnpackedUint64Element(1, 0, Int64.fromBits(0, 1));
|
||||
message.setUnpackedUint64Iterable(1, [Int64.fromBits(0, 1)]);
|
||||
|
||||
let s = '';
|
||||
s += message.getBoolWithDefault(1);
|
||||
s += message.getBytesWithDefault(1);
|
||||
s += message.getDoubleWithDefault(1);
|
||||
s += message.getFixed32WithDefault(1);
|
||||
s += message.getFixed64WithDefault(1);
|
||||
s += message.getFloatWithDefault(1);
|
||||
s += message.getInt32WithDefault(1);
|
||||
s += message.getInt64WithDefault(1);
|
||||
s += message.getMessage(1, TestMessage.instanceCreator);
|
||||
s += message.getSfixed32WithDefault(1);
|
||||
s += message.getSfixed64WithDefault(1);
|
||||
s += message.getSint32WithDefault(1);
|
||||
s += message.getSint64WithDefault(1);
|
||||
s += message.getStringWithDefault(1);
|
||||
s += message.getUint32WithDefault(1);
|
||||
s += message.getUint64WithDefault(1);
|
||||
s += message.getRepeatedBoolElement(1, 0);
|
||||
s += message.getRepeatedBoolIterable(1);
|
||||
s += message.getRepeatedBoolSize(1);
|
||||
s += message.getRepeatedBytesElement(1, 0);
|
||||
s += message.getRepeatedBytesIterable(1);
|
||||
s += message.getRepeatedBytesSize(1);
|
||||
s += message.getRepeatedDoubleElement(1, 0);
|
||||
s += message.getRepeatedDoubleIterable(1);
|
||||
s += message.getRepeatedDoubleSize(1);
|
||||
s += message.getRepeatedFixed32Element(1, 0);
|
||||
s += message.getRepeatedFixed32Iterable(1);
|
||||
s += message.getRepeatedFixed32Size(1);
|
||||
s += message.getRepeatedFixed64Element(1, 0);
|
||||
s += message.getRepeatedFixed64Iterable(1);
|
||||
s += message.getRepeatedFixed64Size(1);
|
||||
s += message.getRepeatedFloatElement(1, 0);
|
||||
s += message.getRepeatedFloatIterable(1);
|
||||
s += message.getRepeatedFloatSize(1);
|
||||
s += message.getRepeatedInt32Element(1, 0);
|
||||
s += message.getRepeatedInt32Iterable(1);
|
||||
s += message.getRepeatedInt32Size(1);
|
||||
s += message.getRepeatedInt64Element(1, 0);
|
||||
s += message.getRepeatedInt64Iterable(1);
|
||||
s += message.getRepeatedInt64Size(1);
|
||||
s += message.getRepeatedMessageElement(1, TestMessage.instanceCreator, 0);
|
||||
s += message.getRepeatedMessageIterable(1, TestMessage.instanceCreator);
|
||||
s += message.getRepeatedMessageSize(1, TestMessage.instanceCreator);
|
||||
s += message.getRepeatedSfixed32Element(1, 0);
|
||||
s += message.getRepeatedSfixed32Iterable(1);
|
||||
s += message.getRepeatedSfixed32Size(1);
|
||||
s += message.getRepeatedSfixed64Element(1, 0);
|
||||
s += message.getRepeatedSfixed64Iterable(1);
|
||||
s += message.getRepeatedSfixed64Size(1);
|
||||
s += message.getRepeatedSint32Element(1, 0);
|
||||
s += message.getRepeatedSint32Iterable(1);
|
||||
s += message.getRepeatedSint32Size(1);
|
||||
s += message.getRepeatedSint64Element(1, 0);
|
||||
s += message.getRepeatedSint64Iterable(1);
|
||||
s += message.getRepeatedSint64Size(1);
|
||||
s += message.getRepeatedStringElement(1, 0);
|
||||
s += message.getRepeatedStringIterable(1);
|
||||
s += message.getRepeatedStringSize(1);
|
||||
s += message.getRepeatedUint32Element(1, 0);
|
||||
s += message.getRepeatedUint32Iterable(1);
|
||||
s += message.getRepeatedUint32Size(1);
|
||||
s += message.getRepeatedUint64Element(1, 0);
|
||||
s += message.getRepeatedUint64Iterable(1);
|
||||
s += message.getRepeatedUint64Size(1);
|
||||
|
||||
s += message.serialize();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
goog.global['__hiddenTest'] += accessAllTypes();
|
68
deps/protobuf/js/experimental/benchmarks/code_size/kernel/popular_types.js
vendored
Normal file
68
deps/protobuf/js/experimental/benchmarks/code_size/kernel/popular_types.js
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @fileoverview The code size benchmark of binary kernel for accessing all
|
||||
* popular types setter and getter.
|
||||
*
|
||||
* The types are those whose usage are more than 1%:
|
||||
*
|
||||
* ('STRING__LABEL_OPTIONAL', '29.7214%')
|
||||
* ('INT32__LABEL_OPTIONAL', '17.7277%')
|
||||
* ('MESSAGE__LABEL_OPTIONAL', '15.6462%')
|
||||
* ('BOOL__LABEL_OPTIONAL', '13.0038%')
|
||||
* ('ENUM__LABEL_OPTIONAL', '11.4466%')
|
||||
* ('INT64__LABEL_OPTIONAL', '3.2198%')
|
||||
* ('DOUBLE__LABEL_OPTIONAL', '1.357%')
|
||||
* ('MESSAGE__LABEL_REPEATED', '1.2775%')
|
||||
* ('FIXED32__LABEL_REQUIRED', '1.2%')
|
||||
* ('UINT64__LABEL_OPTIONAL', '1.1771%')
|
||||
* ('STRING__LABEL_REQUIRED', '1.0785%')
|
||||
*
|
||||
*/
|
||||
goog.module('protobuf.benchmark.KernelCodeSizeBenchmarkPopularTypes');
|
||||
|
||||
const Int64 = goog.require('protobuf.Int64');
|
||||
const Kernel = goog.require('protobuf.runtime.Kernel');
|
||||
const TestMessage = goog.require('protobuf.testing.binary.TestMessage');
|
||||
const {ensureCommonBaseLine} = goog.require('protobuf.benchmark.codeSize.codeSizeBase');
|
||||
|
||||
ensureCommonBaseLine();
|
||||
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
*/
|
||||
function accessAllTypes() {
|
||||
const message = new TestMessage(Kernel.createEmpty());
|
||||
|
||||
message.addRepeatedMessageElement(1, message, TestMessage.instanceCreator);
|
||||
message.addRepeatedMessageIterable(1, [message], TestMessage.instanceCreator);
|
||||
|
||||
message.setString(1, 'abc');
|
||||
message.setInt32(1, 1);
|
||||
message.setMessage(1, message);
|
||||
message.setBool(1, true);
|
||||
message.setInt64(1, Int64.fromBits(0, 1));
|
||||
message.setDouble(1, 1.0);
|
||||
message.setRepeatedMessageElement(1, message, TestMessage.instanceCreator, 0);
|
||||
message.setRepeatedMessageIterable(1, [message]);
|
||||
message.setUint64(1, Int64.fromBits(0, 1));
|
||||
|
||||
|
||||
let s = '';
|
||||
s += message.getStringWithDefault(1);
|
||||
s += message.getInt32WithDefault(1);
|
||||
s += message.getMessage(1, TestMessage.instanceCreator);
|
||||
s += message.getMessageOrNull(1, TestMessage.instanceCreator);
|
||||
s += message.getBoolWithDefault(1);
|
||||
s += message.getInt64WithDefault(1);
|
||||
s += message.getDoubleWithDefault(1);
|
||||
s += message.getRepeatedMessageElement(1, TestMessage.instanceCreator, 0);
|
||||
s += message.getRepeatedMessageIterable(1, TestMessage.instanceCreator);
|
||||
s += message.getRepeatedMessageSize(1, TestMessage.instanceCreator);
|
||||
s += message.getUint64WithDefault(1);
|
||||
|
||||
s += message.serialize();
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
goog.global['__hiddenTest'] += accessAllTypes();
|
183
deps/protobuf/js/experimental/runtime/bytestring.js
vendored
Normal file
183
deps/protobuf/js/experimental/runtime/bytestring.js
vendored
Normal file
@ -0,0 +1,183 @@
|
||||
/**
|
||||
* @fileoverview Provides ByteString as a basic data type for protos.
|
||||
*/
|
||||
goog.module('protobuf.ByteString');
|
||||
|
||||
const base64 = goog.require('goog.crypt.base64');
|
||||
const {arrayBufferSlice, cloneArrayBufferView, hashUint8Array, uint8ArrayEqual} = goog.require('protobuf.binary.typedArrays');
|
||||
|
||||
/**
|
||||
* Immutable sequence of bytes.
|
||||
*
|
||||
* Bytes can be obtained as an ArrayBuffer or a base64 encoded string.
|
||||
* @final
|
||||
*/
|
||||
class ByteString {
|
||||
/**
|
||||
* @param {?Uint8Array} bytes
|
||||
* @param {?string} base64
|
||||
* @private
|
||||
*/
|
||||
constructor(bytes, base64) {
|
||||
/** @private {?Uint8Array}*/
|
||||
this.bytes_ = bytes;
|
||||
/** @private {?string} */
|
||||
this.base64_ = base64;
|
||||
/** @private {number} */
|
||||
this.hashCode_ = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ByteString instance from a base64 string.
|
||||
* @param {string} value
|
||||
* @return {!ByteString}
|
||||
*/
|
||||
static fromBase64String(value) {
|
||||
if (value == null) {
|
||||
throw new Error('value must not be null');
|
||||
}
|
||||
return new ByteString(/* bytes */ null, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ByteString from an array buffer.
|
||||
* @param {!ArrayBuffer} bytes
|
||||
* @param {number=} start
|
||||
* @param {number=} end
|
||||
* @return {!ByteString}
|
||||
*/
|
||||
static fromArrayBuffer(bytes, start = 0, end = undefined) {
|
||||
return new ByteString(
|
||||
new Uint8Array(arrayBufferSlice(bytes, start, end)), /* base64 */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ByteString from any ArrayBufferView (e.g. DataView,
|
||||
* TypedArray, Uint8Array, etc.).
|
||||
* @param {!ArrayBufferView} bytes
|
||||
* @return {!ByteString}
|
||||
*/
|
||||
static fromArrayBufferView(bytes) {
|
||||
return new ByteString(cloneArrayBufferView(bytes), /* base64 */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a ByteString from an Uint8Array. DON'T MODIFY the underlying
|
||||
* ArrayBuffer, since the ByteString directly uses it without making a copy.
|
||||
*
|
||||
* This method exists so that internal APIs can construct a ByteString without
|
||||
* paying the penalty of copying an ArrayBuffer when that ArrayBuffer is not
|
||||
* supposed to change. It is exposed to a limited number of internal classes
|
||||
* through bytestring_internal.js.
|
||||
*
|
||||
* @param {!Uint8Array} bytes
|
||||
* @return {!ByteString}
|
||||
* @package
|
||||
*/
|
||||
static fromUint8ArrayUnsafe(bytes) {
|
||||
return new ByteString(bytes, /* base64 */ null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this ByteString as an ArrayBuffer.
|
||||
* @return {!ArrayBuffer}
|
||||
*/
|
||||
toArrayBuffer() {
|
||||
const bytes = this.ensureBytes_();
|
||||
return arrayBufferSlice(
|
||||
bytes.buffer, bytes.byteOffset, bytes.byteOffset + bytes.byteLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this ByteString as an Uint8Array. DON'T MODIFY the returned array,
|
||||
* since the ByteString holds the reference to the same array.
|
||||
*
|
||||
* This method exists so that internal APIs can get contents of a ByteString
|
||||
* without paying the penalty of copying an ArrayBuffer. It is exposed to a
|
||||
* limited number of internal classes through bytestring_internal.js.
|
||||
* @return {!Uint8Array}
|
||||
* @package
|
||||
*/
|
||||
toUint8ArrayUnsafe() {
|
||||
return this.ensureBytes_();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this ByteString as a base64 encoded string.
|
||||
* @return {string}
|
||||
*/
|
||||
toBase64String() {
|
||||
return this.ensureBase64String_();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true for Bytestrings that contain identical values.
|
||||
* @param {*} other
|
||||
* @return {boolean}
|
||||
*/
|
||||
equals(other) {
|
||||
if (this === other) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!(other instanceof ByteString)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const otherByteString = /** @type {!ByteString} */ (other);
|
||||
return uint8ArrayEqual(this.ensureBytes_(), otherByteString.ensureBytes_());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a number (int32) that is suitable for using in hashed structures.
|
||||
* @return {number}
|
||||
*/
|
||||
hashCode() {
|
||||
if (this.hashCode_ == 0) {
|
||||
this.hashCode_ = hashUint8Array(this.ensureBytes_());
|
||||
}
|
||||
return this.hashCode_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the bytestring is empty.
|
||||
* @return {boolean}
|
||||
*/
|
||||
isEmpty() {
|
||||
if (this.bytes_ != null && this.bytes_.byteLength == 0) {
|
||||
return true;
|
||||
}
|
||||
if (this.base64_ != null && this.base64_.length == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Uint8Array}
|
||||
* @private
|
||||
*/
|
||||
ensureBytes_() {
|
||||
if (this.bytes_) {
|
||||
return this.bytes_;
|
||||
}
|
||||
return this.bytes_ = base64.decodeStringToUint8Array(
|
||||
/** @type {string} */ (this.base64_));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {string}
|
||||
* @private
|
||||
*/
|
||||
ensureBase64String_() {
|
||||
if (this.base64_ == null) {
|
||||
this.base64_ = base64.encodeByteArray(this.bytes_);
|
||||
}
|
||||
return this.base64_;
|
||||
}
|
||||
}
|
||||
|
||||
/** @const {!ByteString} */
|
||||
ByteString.EMPTY = new ByteString(new Uint8Array(0), null);
|
||||
|
||||
exports = ByteString;
|
33
deps/protobuf/js/experimental/runtime/bytestring_internal.js
vendored
Normal file
33
deps/protobuf/js/experimental/runtime/bytestring_internal.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
/**
|
||||
* @fileoverview Exposes internal only functions for ByteString. The
|
||||
* corresponding BUILD rule restricts access to this file to only the binary
|
||||
* kernel and APIs directly using the binary kernel.
|
||||
*/
|
||||
goog.module('protobuf.byteStringInternal');
|
||||
|
||||
const ByteString = goog.require('protobuf.ByteString');
|
||||
|
||||
/**
|
||||
* Constructs a ByteString from an Uint8Array. DON'T MODIFY the underlying
|
||||
* ArrayBuffer, since the ByteString directly uses it without making a copy.
|
||||
* @param {!Uint8Array} bytes
|
||||
* @return {!ByteString}
|
||||
*/
|
||||
function byteStringFromUint8ArrayUnsafe(bytes) {
|
||||
return ByteString.fromUint8ArrayUnsafe(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns this ByteString as an Uint8Array. DON'T MODIFY the returned array,
|
||||
* since the ByteString holds the reference to the same array.
|
||||
* @param {!ByteString} bytes
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function byteStringToUint8ArrayUnsafe(bytes) {
|
||||
return bytes.toUint8ArrayUnsafe();
|
||||
}
|
||||
|
||||
exports = {
|
||||
byteStringFromUint8ArrayUnsafe,
|
||||
byteStringToUint8ArrayUnsafe,
|
||||
};
|
277
deps/protobuf/js/experimental/runtime/bytestring_test.js
vendored
Normal file
277
deps/protobuf/js/experimental/runtime/bytestring_test.js
vendored
Normal file
@ -0,0 +1,277 @@
|
||||
goog.module('proto.im.integration.ByteStringFieldsTest');
|
||||
goog.setTestOnly();
|
||||
|
||||
const ByteString = goog.require('protobuf.ByteString');
|
||||
const {arrayBufferSlice} = goog.require('protobuf.binary.typedArrays');
|
||||
|
||||
const /** !ArrayBuffer */ TEST_BYTES = new Uint8Array([1, 2, 3, 4]).buffer;
|
||||
const /** !ByteString */ TEST_STRING = ByteString.fromArrayBuffer(TEST_BYTES);
|
||||
const /** !ArrayBuffer */ PREFIXED_TEST_BYTES =
|
||||
new Uint8Array([0, 1, 2, 3, 4]).buffer;
|
||||
const /** string */ HALLO_IN_BASE64 = 'aGFsbG8=';
|
||||
const /** string */ HALLO_IN_BASE64_WITH_SPACES = 'a G F s b G 8=';
|
||||
const /** !ArrayBufferView */ BYTES_WITH_HALLO = new Uint8Array([
|
||||
'h'.charCodeAt(0),
|
||||
'a'.charCodeAt(0),
|
||||
'l'.charCodeAt(0),
|
||||
'l'.charCodeAt(0),
|
||||
'o'.charCodeAt(0),
|
||||
]);
|
||||
|
||||
describe('ByteString does', () => {
|
||||
it('create bytestring from buffer', () => {
|
||||
const byteString =
|
||||
ByteString.fromArrayBuffer(arrayBufferSlice(TEST_BYTES, 0));
|
||||
expect(byteString.toArrayBuffer()).toEqual(TEST_BYTES);
|
||||
expect(byteString.toUint8ArrayUnsafe()).toEqual(new Uint8Array(TEST_BYTES));
|
||||
});
|
||||
|
||||
it('create bytestring from ArrayBufferView', () => {
|
||||
const byteString =
|
||||
ByteString.fromArrayBufferView(new Uint8Array(TEST_BYTES));
|
||||
expect(byteString.toArrayBuffer()).toEqual(TEST_BYTES);
|
||||
expect(byteString.toUint8ArrayUnsafe()).toEqual(new Uint8Array(TEST_BYTES));
|
||||
});
|
||||
|
||||
it('create bytestring from subarray', () => {
|
||||
const byteString = ByteString.fromArrayBufferView(
|
||||
new Uint8Array(TEST_BYTES, /* offset */ 1, /* length */ 2));
|
||||
const expected = new Uint8Array([2, 3]);
|
||||
expect(new Uint8Array(byteString.toArrayBuffer())).toEqual(expected);
|
||||
expect(byteString.toUint8ArrayUnsafe()).toEqual(expected);
|
||||
});
|
||||
|
||||
it('create bytestring from Uint8Array (unsafe)', () => {
|
||||
const array = new Uint8Array(TEST_BYTES);
|
||||
const byteString = ByteString.fromUint8ArrayUnsafe(array);
|
||||
expect(byteString.toArrayBuffer()).toEqual(array.buffer);
|
||||
expect(byteString.toUint8ArrayUnsafe()).toBe(array);
|
||||
});
|
||||
|
||||
it('create bytestring from base64 string', () => {
|
||||
const byteString = ByteString.fromBase64String(HALLO_IN_BASE64);
|
||||
expect(byteString.toBase64String()).toEqual(HALLO_IN_BASE64);
|
||||
expect(byteString.toArrayBuffer()).toEqual(BYTES_WITH_HALLO.buffer);
|
||||
expect(byteString.toUint8ArrayUnsafe()).toEqual(BYTES_WITH_HALLO);
|
||||
});
|
||||
|
||||
it('preserve immutability if underlying buffer changes: from buffer', () => {
|
||||
const buffer = new ArrayBuffer(4);
|
||||
const array = new Uint8Array(buffer);
|
||||
array[0] = 1;
|
||||
array[1] = 2;
|
||||
array[2] = 3;
|
||||
array[3] = 4;
|
||||
|
||||
const byteString = ByteString.fromArrayBuffer(buffer);
|
||||
const otherBuffer = byteString.toArrayBuffer();
|
||||
|
||||
expect(otherBuffer).not.toBe(buffer);
|
||||
expect(new Uint8Array(otherBuffer)).toEqual(array);
|
||||
|
||||
// modify the original buffer
|
||||
array[0] = 5;
|
||||
// Are we still returning the original bytes?
|
||||
expect(new Uint8Array(byteString.toArrayBuffer())).toEqual(new Uint8Array([
|
||||
1, 2, 3, 4
|
||||
]));
|
||||
});
|
||||
|
||||
it('preserve immutability if underlying buffer changes: from ArrayBufferView',
|
||||
() => {
|
||||
const buffer = new ArrayBuffer(4);
|
||||
const array = new Uint8Array(buffer);
|
||||
array[0] = 1;
|
||||
array[1] = 2;
|
||||
array[2] = 3;
|
||||
array[3] = 4;
|
||||
|
||||
const byteString = ByteString.fromArrayBufferView(array);
|
||||
const otherBuffer = byteString.toArrayBuffer();
|
||||
|
||||
expect(otherBuffer).not.toBe(buffer);
|
||||
expect(new Uint8Array(otherBuffer)).toEqual(array);
|
||||
|
||||
// modify the original buffer
|
||||
array[0] = 5;
|
||||
// Are we still returning the original bytes?
|
||||
expect(new Uint8Array(byteString.toArrayBuffer()))
|
||||
.toEqual(new Uint8Array([1, 2, 3, 4]));
|
||||
});
|
||||
|
||||
it('mutate if underlying buffer changes: from Uint8Array (unsafe)', () => {
|
||||
const buffer = new ArrayBuffer(4);
|
||||
const array = new Uint8Array(buffer);
|
||||
array[0] = 1;
|
||||
array[1] = 2;
|
||||
array[2] = 3;
|
||||
array[3] = 4;
|
||||
|
||||
const byteString = ByteString.fromUint8ArrayUnsafe(array);
|
||||
const otherBuffer = byteString.toArrayBuffer();
|
||||
|
||||
expect(otherBuffer).not.toBe(buffer);
|
||||
expect(new Uint8Array(otherBuffer)).toEqual(array);
|
||||
|
||||
// modify the original buffer
|
||||
array[0] = 5;
|
||||
// We are no longer returning the original bytes
|
||||
expect(new Uint8Array(byteString.toArrayBuffer())).toEqual(new Uint8Array([
|
||||
5, 2, 3, 4
|
||||
]));
|
||||
});
|
||||
|
||||
it('preserve immutability for returned buffers: toArrayBuffer', () => {
|
||||
const byteString = ByteString.fromArrayBufferView(new Uint8Array(4));
|
||||
const buffer1 = byteString.toArrayBuffer();
|
||||
const buffer2 = byteString.toArrayBuffer();
|
||||
|
||||
expect(buffer1).toEqual(buffer2);
|
||||
|
||||
const array1 = new Uint8Array(buffer1);
|
||||
array1[0] = 1;
|
||||
|
||||
expect(buffer1).not.toEqual(buffer2);
|
||||
});
|
||||
|
||||
it('does not preserve immutability for returned buffers: toUint8ArrayUnsafe',
|
||||
() => {
|
||||
const byteString = ByteString.fromUint8ArrayUnsafe(new Uint8Array(4));
|
||||
const array1 = byteString.toUint8ArrayUnsafe();
|
||||
const array2 = byteString.toUint8ArrayUnsafe();
|
||||
|
||||
expect(array1).toEqual(array2);
|
||||
array1[0] = 1;
|
||||
|
||||
expect(array1).toEqual(array2);
|
||||
});
|
||||
|
||||
it('throws when created with null ArrayBufferView', () => {
|
||||
expect(
|
||||
() => ByteString.fromArrayBufferView(
|
||||
/** @type {!ArrayBufferView} */ (/** @type{*} */ (null))))
|
||||
.toThrow();
|
||||
});
|
||||
|
||||
it('throws when created with null buffer', () => {
|
||||
expect(
|
||||
() => ByteString.fromBase64String(
|
||||
/** @type {string} */ (/** @type{*} */ (null))))
|
||||
.toThrow();
|
||||
});
|
||||
|
||||
it('convert base64 to ArrayBuffer', () => {
|
||||
const other = ByteString.fromBase64String(HALLO_IN_BASE64);
|
||||
expect(BYTES_WITH_HALLO).toEqual(new Uint8Array(other.toArrayBuffer()));
|
||||
});
|
||||
|
||||
it('convert base64 with spaces to ArrayBuffer', () => {
|
||||
const other = ByteString.fromBase64String(HALLO_IN_BASE64_WITH_SPACES);
|
||||
expect(new Uint8Array(other.toArrayBuffer())).toEqual(BYTES_WITH_HALLO);
|
||||
});
|
||||
|
||||
it('convert bytes to base64', () => {
|
||||
const other = ByteString.fromArrayBufferView(BYTES_WITH_HALLO);
|
||||
expect(HALLO_IN_BASE64).toEqual(other.toBase64String());
|
||||
});
|
||||
|
||||
it('equal empty bytetring', () => {
|
||||
const empty = ByteString.fromArrayBuffer(new ArrayBuffer(0));
|
||||
expect(ByteString.EMPTY.equals(empty)).toEqual(true);
|
||||
});
|
||||
|
||||
it('equal empty bytestring constructed from ArrayBufferView', () => {
|
||||
const empty = ByteString.fromArrayBufferView(new Uint8Array(0));
|
||||
expect(ByteString.EMPTY.equals(empty)).toEqual(true);
|
||||
});
|
||||
|
||||
it('equal empty bytestring constructed from Uint8Array (unsafe)', () => {
|
||||
const empty = ByteString.fromUint8ArrayUnsafe(new Uint8Array(0));
|
||||
expect(ByteString.EMPTY.equals(empty)).toEqual(true);
|
||||
});
|
||||
|
||||
it('equal empty bytestring constructed from base64', () => {
|
||||
const empty = ByteString.fromBase64String('');
|
||||
expect(ByteString.EMPTY.equals(empty)).toEqual(true);
|
||||
});
|
||||
|
||||
it('equal other instance', () => {
|
||||
const other = ByteString.fromArrayBuffer(arrayBufferSlice(TEST_BYTES, 0));
|
||||
expect(TEST_STRING.equals(other)).toEqual(true);
|
||||
});
|
||||
|
||||
it('not equal different instance', () => {
|
||||
const other =
|
||||
ByteString.fromArrayBuffer(new Uint8Array([1, 2, 3, 4, 5]).buffer);
|
||||
expect(TEST_STRING.equals(other)).toEqual(false);
|
||||
});
|
||||
|
||||
it('equal other instance constructed from ArrayBufferView', () => {
|
||||
const other =
|
||||
ByteString.fromArrayBufferView(new Uint8Array(PREFIXED_TEST_BYTES, 1));
|
||||
expect(TEST_STRING.equals(other)).toEqual(true);
|
||||
});
|
||||
|
||||
it('not equal different instance constructed from ArrayBufferView', () => {
|
||||
const other =
|
||||
ByteString.fromArrayBufferView(new Uint8Array([1, 2, 3, 4, 5]));
|
||||
expect(TEST_STRING.equals(other)).toEqual(false);
|
||||
});
|
||||
|
||||
it('equal other instance constructed from Uint8Array (unsafe)', () => {
|
||||
const other =
|
||||
ByteString.fromUint8ArrayUnsafe(new Uint8Array(PREFIXED_TEST_BYTES, 1));
|
||||
expect(TEST_STRING.equals(other)).toEqual(true);
|
||||
});
|
||||
|
||||
it('not equal different instance constructed from Uint8Array (unsafe)',
|
||||
() => {
|
||||
const other =
|
||||
ByteString.fromUint8ArrayUnsafe(new Uint8Array([1, 2, 3, 4, 5]));
|
||||
expect(TEST_STRING.equals(other)).toEqual(false);
|
||||
});
|
||||
|
||||
it('have same hashcode for empty bytes', () => {
|
||||
const empty = ByteString.fromArrayBuffer(new ArrayBuffer(0));
|
||||
expect(ByteString.EMPTY.hashCode()).toEqual(empty.hashCode());
|
||||
});
|
||||
|
||||
it('have same hashcode for test bytes', () => {
|
||||
const other = ByteString.fromArrayBuffer(arrayBufferSlice(TEST_BYTES, 0));
|
||||
expect(TEST_STRING.hashCode()).toEqual(other.hashCode());
|
||||
});
|
||||
|
||||
it('have same hashcode for test bytes', () => {
|
||||
const other = ByteString.fromArrayBufferView(
|
||||
new Uint8Array(arrayBufferSlice(TEST_BYTES, 0)));
|
||||
expect(TEST_STRING.hashCode()).toEqual(other.hashCode());
|
||||
});
|
||||
|
||||
it('have same hashcode for different instance constructed with base64',
|
||||
() => {
|
||||
const other = ByteString.fromBase64String(HALLO_IN_BASE64);
|
||||
expect(ByteString.fromArrayBufferView(BYTES_WITH_HALLO).hashCode())
|
||||
.toEqual(other.hashCode());
|
||||
});
|
||||
|
||||
it('preserves the length of a Uint8Array', () => {
|
||||
const original = new Uint8Array([105, 183, 51, 251, 253, 118, 247]);
|
||||
const afterByteString = new Uint8Array(
|
||||
ByteString.fromArrayBufferView(original).toArrayBuffer());
|
||||
expect(afterByteString).toEqual(original);
|
||||
});
|
||||
|
||||
it('preserves the length of a base64 value', () => {
|
||||
const expected = new Uint8Array([105, 183, 51, 251, 253, 118, 247]);
|
||||
const afterByteString = new Uint8Array(
|
||||
ByteString.fromBase64String('abcz+/129w').toArrayBuffer());
|
||||
expect(afterByteString).toEqual(expected);
|
||||
});
|
||||
|
||||
it('preserves the length of a base64 value with padding', () => {
|
||||
const expected = new Uint8Array([105, 183, 51, 251, 253, 118, 247]);
|
||||
const afterByteString = new Uint8Array(
|
||||
ByteString.fromBase64String('abcz+/129w==').toArrayBuffer());
|
||||
expect(afterByteString).toEqual(expected);
|
||||
});
|
||||
});
|
403
deps/protobuf/js/experimental/runtime/int64.js
vendored
Normal file
403
deps/protobuf/js/experimental/runtime/int64.js
vendored
Normal file
@ -0,0 +1,403 @@
|
||||
/**
|
||||
* @fileoverview Protobufs Int64 representation.
|
||||
*/
|
||||
goog.module('protobuf.Int64');
|
||||
|
||||
const Long = goog.require('goog.math.Long');
|
||||
const {assert} = goog.require('goog.asserts');
|
||||
|
||||
/**
|
||||
* A container for protobufs Int64/Uint64 data type.
|
||||
* @final
|
||||
*/
|
||||
class Int64 {
|
||||
/** @return {!Int64} */
|
||||
static getZero() {
|
||||
return ZERO;
|
||||
}
|
||||
|
||||
/** @return {!Int64} */
|
||||
static getMinValue() {
|
||||
return MIN_VALUE;
|
||||
}
|
||||
|
||||
/** @return {!Int64} */
|
||||
static getMaxValue() {
|
||||
return MAX_VALUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a Int64 given two 32 bit numbers
|
||||
* @param {number} lowBits
|
||||
* @param {number} highBits
|
||||
* @return {!Int64}
|
||||
*/
|
||||
static fromBits(lowBits, highBits) {
|
||||
return new Int64(lowBits, highBits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an Int64 from a signed 32 bit number.
|
||||
* @param {number} value
|
||||
* @return {!Int64}
|
||||
*/
|
||||
static fromInt(value) {
|
||||
// TODO: Use our own checking system here.
|
||||
assert(value === (value | 0), 'value should be a 32-bit integer');
|
||||
// Right shift 31 bits so all high bits are equal to the sign bit.
|
||||
// Note: cannot use >> 32, because (1 >> 32) = 1 (!).
|
||||
const signExtendedHighBits = value >> 31;
|
||||
return new Int64(value, signExtendedHighBits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs an Int64 from a number (over 32 bits).
|
||||
* @param {number} value
|
||||
* @return {!Int64}
|
||||
*/
|
||||
static fromNumber(value) {
|
||||
if (value > 0) {
|
||||
return new Int64(value, value / TWO_PWR_32_DBL);
|
||||
} else if (value < 0) {
|
||||
return negate(-value, -value / TWO_PWR_32_DBL);
|
||||
}
|
||||
return ZERO;
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an Int64 from a signed decimal string.
|
||||
* @param {string} value
|
||||
* @return {!Int64}
|
||||
*/
|
||||
static fromDecimalString(value) {
|
||||
// TODO: Use our own checking system here.
|
||||
assert(value.length > 0);
|
||||
// The basic Number conversion loses precision, but we can use it for
|
||||
// a quick validation that the format is correct and it is an integer.
|
||||
assert(Math.floor(Number(value)).toString().length == value.length);
|
||||
return decimalStringToInt64(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct an Int64 from a signed hexadecimal string.
|
||||
* @param {string} value
|
||||
* @return {!Int64}
|
||||
*/
|
||||
static fromHexString(value) {
|
||||
// TODO: Use our own checking system here.
|
||||
assert(value.length > 0);
|
||||
assert(value.slice(0, 2) == '0x' || value.slice(0, 3) == '-0x');
|
||||
const minus = value[0] === '-';
|
||||
// Strip the 0x or -0x prefix.
|
||||
value = value.slice(minus ? 3 : 2);
|
||||
const lowBits = parseInt(value.slice(-8), 16);
|
||||
const highBits = parseInt(value.slice(-16, -8) || '', 16);
|
||||
return (minus ? negate : Int64.fromBits)(lowBits, highBits);
|
||||
}
|
||||
|
||||
// Note to the reader:
|
||||
// goog.math.Long suffers from a code size issue. JsCompiler almost always
|
||||
// considers toString methods to be alive in a program. So if you are
|
||||
// constructing a Long instance the toString method is assumed to be live.
|
||||
// Unfortunately Long's toString method makes a large chunk of code alive
|
||||
// of the entire class adding 1.3kB (gzip) of extra code size.
|
||||
// Callers that are sensitive to code size and are not using Long already
|
||||
// should avoid calling this method.
|
||||
/**
|
||||
* Creates an Int64 instance from a Long value.
|
||||
* @param {!Long} value
|
||||
* @return {!Int64}
|
||||
*/
|
||||
static fromLong(value) {
|
||||
return new Int64(value.getLowBits(), value.getHighBits());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} lowBits
|
||||
* @param {number} highBits
|
||||
* @private
|
||||
*/
|
||||
constructor(lowBits, highBits) {
|
||||
/** @const @private {number} */
|
||||
this.lowBits_ = lowBits | 0;
|
||||
/** @const @private {number} */
|
||||
this.highBits_ = highBits | 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the int64 value as a JavaScript number. This will lose precision
|
||||
* if the number is outside of the safe range for JavaScript of 53 bits
|
||||
* precision.
|
||||
* @return {number}
|
||||
*/
|
||||
asNumber() {
|
||||
const result = this.highBits_ * TWO_PWR_32_DBL + this.getLowBitsUnsigned();
|
||||
// TODO: Use our own checking system here.
|
||||
assert(
|
||||
Number.isSafeInteger(result), 'conversion to number loses precision.');
|
||||
return result;
|
||||
}
|
||||
|
||||
// Note to the reader:
|
||||
// goog.math.Long suffers from a code size issue. JsCompiler almost always
|
||||
// considers toString methods to be alive in a program. So if you are
|
||||
// constructing a Long instance the toString method is assumed to be live.
|
||||
// Unfortunately Long's toString method makes a large chunk of code alive
|
||||
// of the entire class adding 1.3kB (gzip) of extra code size.
|
||||
// Callers that are sensitive to code size and are not using Long already
|
||||
// should avoid calling this method.
|
||||
/** @return {!Long} */
|
||||
asLong() {
|
||||
return Long.fromBits(this.lowBits_, this.highBits_);
|
||||
}
|
||||
|
||||
/** @return {number} Signed 32-bit integer value. */
|
||||
getLowBits() {
|
||||
return this.lowBits_;
|
||||
}
|
||||
|
||||
/** @return {number} Signed 32-bit integer value. */
|
||||
getHighBits() {
|
||||
return this.highBits_;
|
||||
}
|
||||
|
||||
/** @return {number} Unsigned 32-bit integer. */
|
||||
getLowBitsUnsigned() {
|
||||
return this.lowBits_ >>> 0;
|
||||
}
|
||||
|
||||
/** @return {number} Unsigned 32-bit integer. */
|
||||
getHighBitsUnsigned() {
|
||||
return this.highBits_ >>> 0;
|
||||
}
|
||||
|
||||
/** @return {string} */
|
||||
toSignedDecimalString() {
|
||||
return joinSignedDecimalString(this);
|
||||
}
|
||||
|
||||
/** @return {string} */
|
||||
toUnsignedDecimalString() {
|
||||
return joinUnsignedDecimalString(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unsigned hexadecimal string representation of the Int64.
|
||||
* @return {string}
|
||||
*/
|
||||
toHexString() {
|
||||
let nibbles = new Array(16);
|
||||
let lowBits = this.lowBits_;
|
||||
let highBits = this.highBits_;
|
||||
for (let highIndex = 7, lowIndex = 15; lowIndex > 7;
|
||||
highIndex--, lowIndex--) {
|
||||
nibbles[highIndex] = HEX_DIGITS[highBits & 0xF];
|
||||
nibbles[lowIndex] = HEX_DIGITS[lowBits & 0xF];
|
||||
highBits = highBits >>> 4;
|
||||
lowBits = lowBits >>> 4;
|
||||
}
|
||||
// Always leave the least significant hex digit.
|
||||
while (nibbles.length > 1 && nibbles[0] == '0') {
|
||||
nibbles.shift();
|
||||
}
|
||||
return `0x${nibbles.join('')}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {*} other object to compare against.
|
||||
* @return {boolean} Whether this Int64 equals the other.
|
||||
*/
|
||||
equals(other) {
|
||||
if (this === other) {
|
||||
return true;
|
||||
}
|
||||
if (!(other instanceof Int64)) {
|
||||
return false;
|
||||
}
|
||||
// Compare low parts first as there is higher chance they are different.
|
||||
const otherInt64 = /** @type{!Int64} */ (other);
|
||||
return (this.lowBits_ === otherInt64.lowBits_) &&
|
||||
(this.highBits_ === otherInt64.highBits_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a number (int32) that is suitable for using in hashed structures.
|
||||
* @return {number}
|
||||
*/
|
||||
hashCode() {
|
||||
return (31 * this.lowBits_ + 17 * this.highBits_) | 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Losslessly converts a 64-bit unsigned integer in 32:32 split representation
|
||||
* into a decimal string.
|
||||
* @param {!Int64} int64
|
||||
* @return {string} The binary number represented as a string.
|
||||
*/
|
||||
const joinUnsignedDecimalString = (int64) => {
|
||||
const lowBits = int64.getLowBitsUnsigned();
|
||||
const highBits = int64.getHighBitsUnsigned();
|
||||
// Skip the expensive conversion if the number is small enough to use the
|
||||
// built-in conversions.
|
||||
// Number.MAX_SAFE_INTEGER = 0x001FFFFF FFFFFFFF, thus any number with
|
||||
// highBits <= 0x1FFFFF can be safely expressed with a double and retain
|
||||
// integer precision.
|
||||
// Proven by: Number.isSafeInteger(0x1FFFFF * 2**32 + 0xFFFFFFFF) == true.
|
||||
if (highBits <= 0x1FFFFF) {
|
||||
return String(TWO_PWR_32_DBL * highBits + lowBits);
|
||||
}
|
||||
|
||||
// What this code is doing is essentially converting the input number from
|
||||
// base-2 to base-1e7, which allows us to represent the 64-bit range with
|
||||
// only 3 (very large) digits. Those digits are then trivial to convert to
|
||||
// a base-10 string.
|
||||
|
||||
// The magic numbers used here are -
|
||||
// 2^24 = 16777216 = (1,6777216) in base-1e7.
|
||||
// 2^48 = 281474976710656 = (2,8147497,6710656) in base-1e7.
|
||||
|
||||
// Split 32:32 representation into 16:24:24 representation so our
|
||||
// intermediate digits don't overflow.
|
||||
const low = lowBits & LOW_24_BITS;
|
||||
const mid = ((lowBits >>> 24) | (highBits << 8)) & LOW_24_BITS;
|
||||
const high = (highBits >> 16) & LOW_16_BITS;
|
||||
|
||||
// Assemble our three base-1e7 digits, ignoring carries. The maximum
|
||||
// value in a digit at this step is representable as a 48-bit integer, which
|
||||
// can be stored in a 64-bit floating point number.
|
||||
let digitA = low + (mid * 6777216) + (high * 6710656);
|
||||
let digitB = mid + (high * 8147497);
|
||||
let digitC = (high * 2);
|
||||
|
||||
// Apply carries from A to B and from B to C.
|
||||
const base = 10000000;
|
||||
if (digitA >= base) {
|
||||
digitB += Math.floor(digitA / base);
|
||||
digitA %= base;
|
||||
}
|
||||
|
||||
if (digitB >= base) {
|
||||
digitC += Math.floor(digitB / base);
|
||||
digitB %= base;
|
||||
}
|
||||
|
||||
// If digitC is 0, then we should have returned in the trivial code path
|
||||
// at the top for non-safe integers. Given this, we can assume both digitB
|
||||
// and digitA need leading zeros.
|
||||
// TODO: Use our own checking system here.
|
||||
assert(digitC);
|
||||
return digitC + decimalFrom1e7WithLeadingZeros(digitB) +
|
||||
decimalFrom1e7WithLeadingZeros(digitA);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} digit1e7 Number < 1e7
|
||||
* @return {string} Decimal representation of digit1e7 with leading zeros.
|
||||
*/
|
||||
const decimalFrom1e7WithLeadingZeros = (digit1e7) => {
|
||||
const partial = String(digit1e7);
|
||||
return '0000000'.slice(partial.length) + partial;
|
||||
};
|
||||
|
||||
/**
|
||||
* Losslessly converts a 64-bit signed integer in 32:32 split representation
|
||||
* into a decimal string.
|
||||
* @param {!Int64} int64
|
||||
* @return {string} The binary number represented as a string.
|
||||
*/
|
||||
const joinSignedDecimalString = (int64) => {
|
||||
// If we're treating the input as a signed value and the high bit is set, do
|
||||
// a manual two's complement conversion before the decimal conversion.
|
||||
const negative = (int64.getHighBits() & 0x80000000);
|
||||
if (negative) {
|
||||
int64 = negate(int64.getLowBits(), int64.getHighBits());
|
||||
}
|
||||
|
||||
const result = joinUnsignedDecimalString(int64);
|
||||
return negative ? '-' + result : result;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {string} dec
|
||||
* @return {!Int64}
|
||||
*/
|
||||
const decimalStringToInt64 = (dec) => {
|
||||
// Check for minus sign.
|
||||
const minus = dec[0] === '-';
|
||||
if (minus) {
|
||||
dec = dec.slice(1);
|
||||
}
|
||||
|
||||
// Work 6 decimal digits at a time, acting like we're converting base 1e6
|
||||
// digits to binary. This is safe to do with floating point math because
|
||||
// Number.isSafeInteger(ALL_32_BITS * 1e6) == true.
|
||||
const base = 1e6;
|
||||
let lowBits = 0;
|
||||
let highBits = 0;
|
||||
function add1e6digit(begin, end = undefined) {
|
||||
// Note: Number('') is 0.
|
||||
const digit1e6 = Number(dec.slice(begin, end));
|
||||
highBits *= base;
|
||||
lowBits = lowBits * base + digit1e6;
|
||||
// Carry bits from lowBits to
|
||||
if (lowBits >= TWO_PWR_32_DBL) {
|
||||
highBits = highBits + ((lowBits / TWO_PWR_32_DBL) | 0);
|
||||
lowBits = lowBits % TWO_PWR_32_DBL;
|
||||
}
|
||||
}
|
||||
add1e6digit(-24, -18);
|
||||
add1e6digit(-18, -12);
|
||||
add1e6digit(-12, -6);
|
||||
add1e6digit(-6);
|
||||
|
||||
return (minus ? negate : Int64.fromBits)(lowBits, highBits);
|
||||
};
|
||||
|
||||
/**
|
||||
* @param {number} lowBits
|
||||
* @param {number} highBits
|
||||
* @return {!Int64} Two's compliment negation of input.
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Signed_32-bit_integers
|
||||
*/
|
||||
const negate = (lowBits, highBits) => {
|
||||
highBits = ~highBits;
|
||||
if (lowBits) {
|
||||
lowBits = ~lowBits + 1;
|
||||
} else {
|
||||
// If lowBits is 0, then bitwise-not is 0xFFFFFFFF,
|
||||
// adding 1 to that, results in 0x100000000, which leaves
|
||||
// the low bits 0x0 and simply adds one to the high bits.
|
||||
highBits += 1;
|
||||
}
|
||||
return Int64.fromBits(lowBits, highBits);
|
||||
};
|
||||
|
||||
/** @const {!Int64} */
|
||||
const ZERO = new Int64(0, 0);
|
||||
|
||||
/** @const @private {number} */
|
||||
const LOW_16_BITS = 0xFFFF;
|
||||
|
||||
/** @const @private {number} */
|
||||
const LOW_24_BITS = 0xFFFFFF;
|
||||
|
||||
/** @const @private {number} */
|
||||
const LOW_31_BITS = 0x7FFFFFFF;
|
||||
|
||||
/** @const @private {number} */
|
||||
const ALL_32_BITS = 0xFFFFFFFF;
|
||||
|
||||
/** @const {!Int64} */
|
||||
const MAX_VALUE = Int64.fromBits(ALL_32_BITS, LOW_31_BITS);
|
||||
|
||||
/** @const {!Int64} */
|
||||
const MIN_VALUE = Int64.fromBits(0, 0x80000000);
|
||||
|
||||
/** @const {number} */
|
||||
const TWO_PWR_32_DBL = 0x100000000;
|
||||
|
||||
/** @const {string} */
|
||||
const HEX_DIGITS = '0123456789abcdef';
|
||||
|
||||
exports = Int64;
|
213
deps/protobuf/js/experimental/runtime/int64_test.js
vendored
Normal file
213
deps/protobuf/js/experimental/runtime/int64_test.js
vendored
Normal file
@ -0,0 +1,213 @@
|
||||
/**
|
||||
* @fileoverview Tests for Int64.
|
||||
*/
|
||||
goog.module('protobuf.Int64Test');
|
||||
goog.setTestOnly();
|
||||
|
||||
const Int64 = goog.require('protobuf.Int64');
|
||||
const Long = goog.require('goog.math.Long');
|
||||
|
||||
describe('Int64', () => {
|
||||
it('can be constructed from bits', () => {
|
||||
const int64 = Int64.fromBits(0, 1);
|
||||
expect(int64.getLowBits()).toEqual(0);
|
||||
expect(int64.getHighBits()).toEqual(1);
|
||||
});
|
||||
|
||||
it('zero is defined', () => {
|
||||
const int64 = Int64.getZero();
|
||||
expect(int64.getLowBits()).toEqual(0);
|
||||
expect(int64.getHighBits()).toEqual(0);
|
||||
});
|
||||
|
||||
it('max value is defined', () => {
|
||||
const int64 = Int64.getMaxValue();
|
||||
expect(int64).toEqual(Int64.fromBits(0xFFFFFFFF, 0x7FFFFFFF));
|
||||
expect(int64.asLong()).toEqual(Long.getMaxValue());
|
||||
});
|
||||
|
||||
it('min value is defined', () => {
|
||||
const int64 = Int64.getMinValue();
|
||||
expect(int64).toEqual(Int64.fromBits(0, 0x80000000));
|
||||
expect(int64.asLong()).toEqual(Long.getMinValue());
|
||||
});
|
||||
|
||||
it('Can be converted to long', () => {
|
||||
const int64 = Int64.fromInt(1);
|
||||
expect(int64.asLong()).toEqual(Long.fromInt(1));
|
||||
});
|
||||
|
||||
it('Negative value can be converted to long', () => {
|
||||
const int64 = Int64.fromInt(-1);
|
||||
expect(int64.getLowBits()).toEqual(0xFFFFFFFF | 0);
|
||||
expect(int64.getHighBits()).toEqual(0xFFFFFFFF | 0);
|
||||
expect(int64.asLong()).toEqual(Long.fromInt(-1));
|
||||
});
|
||||
|
||||
it('Can be converted to number', () => {
|
||||
const int64 = Int64.fromInt(1);
|
||||
expect(int64.asNumber()).toEqual(1);
|
||||
});
|
||||
|
||||
it('Can convert negative value to number', () => {
|
||||
const int64 = Int64.fromInt(-1);
|
||||
expect(int64.asNumber()).toEqual(-1);
|
||||
});
|
||||
|
||||
it('MAX_SAFE_INTEGER can be used.', () => {
|
||||
const int64 = Int64.fromNumber(Number.MAX_SAFE_INTEGER);
|
||||
expect(int64.getLowBitsUnsigned()).toEqual(0xFFFFFFFF);
|
||||
expect(int64.getHighBits()).toEqual(0x1FFFFF);
|
||||
expect(int64.asNumber()).toEqual(Number.MAX_SAFE_INTEGER);
|
||||
});
|
||||
|
||||
it('MIN_SAFE_INTEGER can be used.', () => {
|
||||
const int64 = Int64.fromNumber(Number.MIN_SAFE_INTEGER);
|
||||
expect(int64.asNumber()).toEqual(Number.MIN_SAFE_INTEGER);
|
||||
});
|
||||
|
||||
it('constructs fromInt', () => {
|
||||
const int64 = Int64.fromInt(1);
|
||||
expect(int64.getLowBits()).toEqual(1);
|
||||
expect(int64.getHighBits()).toEqual(0);
|
||||
});
|
||||
|
||||
it('constructs fromLong', () => {
|
||||
const int64 = Int64.fromLong(Long.fromInt(1));
|
||||
expect(int64.getLowBits()).toEqual(1);
|
||||
expect(int64.getHighBits()).toEqual(0);
|
||||
});
|
||||
|
||||
// TODO: Use our own checking system here.
|
||||
if (goog.DEBUG) {
|
||||
it('asNumber throws for MAX_SAFE_INTEGER + 1', () => {
|
||||
expect(() => Int64.fromNumber(Number.MAX_SAFE_INTEGER + 1).asNumber())
|
||||
.toThrow();
|
||||
});
|
||||
|
||||
it('fromInt(MAX_SAFE_INTEGER) throws', () => {
|
||||
expect(() => Int64.fromInt(Number.MAX_SAFE_INTEGER)).toThrow();
|
||||
});
|
||||
|
||||
it('fromInt(1.5) throws', () => {
|
||||
expect(() => Int64.fromInt(1.5)).toThrow();
|
||||
});
|
||||
}
|
||||
|
||||
const decimalHexPairs = {
|
||||
'0x0000000000000000': {signed: '0'},
|
||||
'0x0000000000000001': {signed: '1'},
|
||||
'0x00000000ffffffff': {signed: '4294967295'},
|
||||
'0x0000000100000000': {signed: '4294967296'},
|
||||
'0xffffffffffffffff': {signed: '-1', unsigned: '18446744073709551615'},
|
||||
'0x8000000000000000':
|
||||
{signed: '-9223372036854775808', unsigned: '9223372036854775808'},
|
||||
'0x8000000080000000':
|
||||
{signed: '-9223372034707292160', unsigned: '9223372039002259456'},
|
||||
'0x01b69b4bacd05f15': {signed: '123456789123456789'},
|
||||
'0xfe4964b4532fa0eb':
|
||||
{signed: '-123456789123456789', unsigned: '18323287284586094827'},
|
||||
'0xa5a5a5a5a5a5a5a5':
|
||||
{signed: '-6510615555426900571', unsigned: '11936128518282651045'},
|
||||
'0x5a5a5a5a5a5a5a5a': {signed: '6510615555426900570'},
|
||||
'0xffffffff00000000':
|
||||
{signed: '-4294967296', unsigned: '18446744069414584320'},
|
||||
};
|
||||
|
||||
it('serializes to signed decimal strings', () => {
|
||||
for (const [hex, decimals] of Object.entries(decimalHexPairs)) {
|
||||
const int64 = hexToInt64(hex);
|
||||
expect(int64.toSignedDecimalString()).toEqual(decimals.signed);
|
||||
}
|
||||
});
|
||||
|
||||
it('serializes to unsigned decimal strings', () => {
|
||||
for (const [hex, decimals] of Object.entries(decimalHexPairs)) {
|
||||
const int64 = hexToInt64(hex);
|
||||
expect(int64.toUnsignedDecimalString())
|
||||
.toEqual(decimals.unsigned || decimals.signed);
|
||||
}
|
||||
});
|
||||
|
||||
it('serializes to unsigned hex strings', () => {
|
||||
for (const [hex, decimals] of Object.entries(decimalHexPairs)) {
|
||||
const int64 = hexToInt64(hex);
|
||||
let shortHex = hex.replace(/0x0*/, '0x');
|
||||
if (shortHex == '0x') {
|
||||
shortHex = '0x0';
|
||||
}
|
||||
expect(int64.toHexString()).toEqual(shortHex);
|
||||
}
|
||||
});
|
||||
|
||||
it('parses decimal strings', () => {
|
||||
for (const [hex, decimals] of Object.entries(decimalHexPairs)) {
|
||||
const signed = Int64.fromDecimalString(decimals.signed);
|
||||
expect(int64ToHex(signed)).toEqual(hex);
|
||||
if (decimals.unsigned) {
|
||||
const unsigned = Int64.fromDecimalString(decimals.unsigned);
|
||||
expect(int64ToHex(unsigned)).toEqual(hex);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
it('parses hex strings', () => {
|
||||
for (const [hex, decimals] of Object.entries(decimalHexPairs)) {
|
||||
expect(int64ToHex(Int64.fromHexString(hex))).toEqual(hex);
|
||||
}
|
||||
expect(int64ToHex(Int64.fromHexString('-0x1')))
|
||||
.toEqual('0xffffffffffffffff');
|
||||
});
|
||||
|
||||
// TODO: Use our own checking system here.
|
||||
if (goog.DEBUG) {
|
||||
it('throws when parsing empty string', () => {
|
||||
expect(() => Int64.fromDecimalString('')).toThrow();
|
||||
});
|
||||
|
||||
it('throws when parsing float string', () => {
|
||||
expect(() => Int64.fromDecimalString('1.5')).toThrow();
|
||||
});
|
||||
|
||||
it('throws when parsing non-numeric string', () => {
|
||||
expect(() => Int64.fromDecimalString('0xa')).toThrow();
|
||||
});
|
||||
}
|
||||
|
||||
it('checks if equal', () => {
|
||||
const low = Int64.fromInt(1);
|
||||
const high = Int64.getMaxValue();
|
||||
expect(low.equals(Int64.fromInt(1))).toEqual(true);
|
||||
expect(low.equals(high)).toEqual(false);
|
||||
expect(high.equals(Int64.getMaxValue())).toEqual(true);
|
||||
});
|
||||
|
||||
it('returns unique hashcode', () => {
|
||||
expect(Int64.fromInt(1).hashCode()).toEqual(Int64.fromInt(1).hashCode());
|
||||
expect(Int64.fromInt(1).hashCode())
|
||||
.not.toEqual(Int64.fromInt(2).hashCode());
|
||||
});
|
||||
});
|
||||
|
||||
/**
|
||||
* @param {string} hexString
|
||||
* @return {!Int64}
|
||||
*/
|
||||
function hexToInt64(hexString) {
|
||||
const high = hexString.slice(2, 10);
|
||||
const low = hexString.slice(10);
|
||||
return Int64.fromBits(parseInt(low, 16), parseInt(high, 16));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Int64} int64
|
||||
* @return {string}
|
||||
*/
|
||||
function int64ToHex(int64) {
|
||||
const ZEROS_32_BIT = '00000000';
|
||||
const highPartialHex = int64.getHighBitsUnsigned().toString(16);
|
||||
const lowPartialHex = int64.getLowBitsUnsigned().toString(16);
|
||||
const highHex = ZEROS_32_BIT.slice(highPartialHex.length) + highPartialHex;
|
||||
const lowHex = ZEROS_32_BIT.slice(lowPartialHex.length) + lowPartialHex;
|
||||
return `0x${highHex}${lowHex}`;
|
||||
}
|
708
deps/protobuf/js/experimental/runtime/internal/checks.js
vendored
Normal file
708
deps/protobuf/js/experimental/runtime/internal/checks.js
vendored
Normal file
@ -0,0 +1,708 @@
|
||||
/**
|
||||
* @fileoverview Proto internal runtime checks.
|
||||
*
|
||||
* Checks are grouped into different severity, see:
|
||||
* http://g3doc/third_party/protobuf/javascript/README.md#configurable-check-support-in-protocol-buffers
|
||||
*
|
||||
* Checks are also grouped into different sections:
|
||||
* - CHECK_BOUNDS:
|
||||
* Checks that ensure that indexed access is within bounds
|
||||
* (e.g. an array being accessed past its size).
|
||||
* - CHECK_STATE
|
||||
* Checks related to the state of an object
|
||||
* (e.g. a parser hitting an invalid case).
|
||||
* - CHECK_TYPE:
|
||||
* Checks that relate to type errors (e.g. code receives a number instead
|
||||
* of a string).
|
||||
*/
|
||||
goog.module('protobuf.internal.checks');
|
||||
|
||||
const ByteString = goog.require('protobuf.ByteString');
|
||||
const Int64 = goog.require('protobuf.Int64');
|
||||
const WireType = goog.require('protobuf.binary.WireType');
|
||||
|
||||
//
|
||||
// See
|
||||
// http://g3doc/third_party/protobuf/javascript/README.md#configurable-check-support-in-protocol-buffers
|
||||
//
|
||||
/** @define{string} */
|
||||
const CHECK_LEVEL_DEFINE = goog.define('protobuf.defines.CHECK_LEVEL', '');
|
||||
|
||||
/** @define{boolean} */
|
||||
const POLYFILL_TEXT_ENCODING =
|
||||
goog.define('protobuf.defines.POLYFILL_TEXT_ENCODING', true);
|
||||
|
||||
/**
|
||||
* @const {number}
|
||||
*/
|
||||
const MAX_FIELD_NUMBER = Math.pow(2, 29) - 1;
|
||||
|
||||
/**
|
||||
* The largest finite float32 value.
|
||||
* @const {number}
|
||||
*/
|
||||
const FLOAT32_MAX = 3.4028234663852886e+38;
|
||||
|
||||
/** @enum {number} */
|
||||
const CheckLevel = {
|
||||
DEBUG: 0,
|
||||
CRITICAL: 1,
|
||||
OFF: 2
|
||||
};
|
||||
|
||||
|
||||
/** @return {!CheckLevel} */
|
||||
function calculateCheckLevel() {
|
||||
const definedLevel = CHECK_LEVEL_DEFINE.toUpperCase();
|
||||
if (definedLevel === '') {
|
||||
// user did not set a value, value now just depends on goog.DEBUG
|
||||
return goog.DEBUG ? CheckLevel.DEBUG : CheckLevel.CRITICAL;
|
||||
}
|
||||
|
||||
if (definedLevel === 'CRITICAL') {
|
||||
return CheckLevel.CRITICAL;
|
||||
}
|
||||
|
||||
if (definedLevel === 'OFF') {
|
||||
return CheckLevel.OFF;
|
||||
}
|
||||
|
||||
if (definedLevel === 'DEBUG') {
|
||||
return CheckLevel.DEBUG;
|
||||
}
|
||||
|
||||
throw new Error(`Unknown value for CHECK_LEVEL: ${CHECK_LEVEL_DEFINE}`);
|
||||
}
|
||||
|
||||
const /** !CheckLevel */ CHECK_LEVEL = calculateCheckLevel();
|
||||
|
||||
const /** boolean */ CHECK_STATE = CHECK_LEVEL === CheckLevel.DEBUG;
|
||||
|
||||
const /** boolean */ CHECK_CRITICAL_STATE =
|
||||
CHECK_LEVEL === CheckLevel.CRITICAL || CHECK_LEVEL === CheckLevel.DEBUG;
|
||||
|
||||
const /** boolean */ CHECK_BOUNDS = CHECK_LEVEL === CheckLevel.DEBUG;
|
||||
|
||||
const /** boolean */ CHECK_CRITICAL_BOUNDS =
|
||||
CHECK_LEVEL === CheckLevel.CRITICAL || CHECK_LEVEL === CheckLevel.DEBUG;
|
||||
|
||||
const /** boolean */ CHECK_TYPE = CHECK_LEVEL === CheckLevel.DEBUG;
|
||||
|
||||
const /** boolean */ CHECK_CRITICAL_TYPE =
|
||||
CHECK_LEVEL === CheckLevel.CRITICAL || CHECK_LEVEL === CheckLevel.DEBUG;
|
||||
|
||||
/**
|
||||
* Ensures the truth of an expression involving the state of the calling
|
||||
* instance, but not involving any parameters to the calling method.
|
||||
*
|
||||
* For cases where failing fast is pretty important and not failing early could
|
||||
* cause bugs that are much harder to debug.
|
||||
* @param {boolean} state
|
||||
* @param {string=} message
|
||||
* @throws {!Error} If the state is false and the check state is critical.
|
||||
*/
|
||||
function checkCriticalState(state, message = '') {
|
||||
if (!CHECK_CRITICAL_STATE) {
|
||||
return;
|
||||
}
|
||||
if (!state) {
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the truth of an expression involving the state of the calling
|
||||
* instance, but not involving any parameters to the calling method.
|
||||
*
|
||||
* @param {boolean} state
|
||||
* @param {string=} message
|
||||
* @throws {!Error} If the state is false and the check state is debug.
|
||||
*/
|
||||
function checkState(state, message = '') {
|
||||
if (!CHECK_STATE) {
|
||||
return;
|
||||
}
|
||||
checkCriticalState(state, message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that `index` specifies a valid position in an indexable object of
|
||||
* size `size`. A position index may range from zero to size, inclusive.
|
||||
* @param {number} index
|
||||
* @param {number} size
|
||||
* @throws {!Error} If the index is out of range and the check state is debug.
|
||||
*/
|
||||
function checkPositionIndex(index, size) {
|
||||
if (!CHECK_BOUNDS) {
|
||||
return;
|
||||
}
|
||||
checkCriticalPositionIndex(index, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that `index` specifies a valid position in an indexable object of
|
||||
* size `size`. A position index may range from zero to size, inclusive.
|
||||
* @param {number} index
|
||||
* @param {number} size
|
||||
* @throws {!Error} If the index is out of range and the check state is
|
||||
* critical.
|
||||
*/
|
||||
function checkCriticalPositionIndex(index, size) {
|
||||
if (!CHECK_CRITICAL_BOUNDS) {
|
||||
return;
|
||||
}
|
||||
if (index < 0 || index > size) {
|
||||
throw new Error(`Index out of bounds: index: ${index} size: ${size}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that `index` specifies a valid element in an indexable object of
|
||||
* size `size`. A element index may range from zero to size, exclusive.
|
||||
* @param {number} index
|
||||
* @param {number} size
|
||||
* @throws {!Error} If the index is out of range and the check state is
|
||||
* debug.
|
||||
*/
|
||||
function checkElementIndex(index, size) {
|
||||
if (!CHECK_BOUNDS) {
|
||||
return;
|
||||
}
|
||||
checkCriticalElementIndex(index, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that `index` specifies a valid element in an indexable object of
|
||||
* size `size`. A element index may range from zero to size, exclusive.
|
||||
* @param {number} index
|
||||
* @param {number} size
|
||||
* @throws {!Error} If the index is out of range and the check state is
|
||||
* critical.
|
||||
*/
|
||||
function checkCriticalElementIndex(index, size) {
|
||||
if (!CHECK_CRITICAL_BOUNDS) {
|
||||
return;
|
||||
}
|
||||
if (index < 0 || index >= size) {
|
||||
throw new Error(`Index out of bounds: index: ${index} size: ${size}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the range of [start, end) is with the range of [0, size).
|
||||
* @param {number} start
|
||||
* @param {number} end
|
||||
* @param {number} size
|
||||
* @throws {!Error} If start and end are out of range and the check state is
|
||||
* debug.
|
||||
*/
|
||||
function checkRange(start, end, size) {
|
||||
if (!CHECK_BOUNDS) {
|
||||
return;
|
||||
}
|
||||
checkCriticalRange(start, end, size);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the range of [start, end) is with the range of [0, size).
|
||||
* @param {number} start
|
||||
* @param {number} end
|
||||
* @param {number} size
|
||||
* @throws {!Error} If start and end are out of range and the check state is
|
||||
* critical.
|
||||
*/
|
||||
function checkCriticalRange(start, end, size) {
|
||||
if (!CHECK_CRITICAL_BOUNDS) {
|
||||
return;
|
||||
}
|
||||
if (start < 0 || end < 0 || start > size || end > size) {
|
||||
throw new Error(`Range error: start: ${start} end: ${end} size: ${size}`);
|
||||
}
|
||||
if (start > end) {
|
||||
throw new Error(`Start > end: ${start} > ${end}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that field number is an integer and within the range of
|
||||
* [1, MAX_FIELD_NUMBER].
|
||||
* @param {number} fieldNumber
|
||||
* @throws {!Error} If the field number is out of range and the check state is
|
||||
* debug.
|
||||
*/
|
||||
function checkFieldNumber(fieldNumber) {
|
||||
if (!CHECK_TYPE) {
|
||||
return;
|
||||
}
|
||||
checkCriticalFieldNumber(fieldNumber);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the value is neither null nor undefined.
|
||||
*
|
||||
* @param {T} value
|
||||
* @return {R}
|
||||
*
|
||||
* @template T
|
||||
* @template R :=
|
||||
* mapunion(T, (V) =>
|
||||
* cond(eq(V, 'null'),
|
||||
* none(),
|
||||
* cond(eq(V, 'undefined'),
|
||||
* none(),
|
||||
* V)))
|
||||
* =:
|
||||
*/
|
||||
function checkDefAndNotNull(value) {
|
||||
if (CHECK_TYPE) {
|
||||
// Note that undefined == null.
|
||||
if (value == null) {
|
||||
throw new Error(`Value can't be null`);
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that the value exists and is a function.
|
||||
*
|
||||
* @param {function(?): ?} func
|
||||
*/
|
||||
function checkFunctionExists(func) {
|
||||
if (CHECK_TYPE) {
|
||||
if (typeof func !== 'function') {
|
||||
throw new Error(`${func} is not a function`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that field number is an integer and within the range of
|
||||
* [1, MAX_FIELD_NUMBER].
|
||||
* @param {number} fieldNumber
|
||||
* @throws {!Error} If the field number is out of range and the check state is
|
||||
* critical.
|
||||
*/
|
||||
function checkCriticalFieldNumber(fieldNumber) {
|
||||
if (!CHECK_CRITICAL_TYPE) {
|
||||
return;
|
||||
}
|
||||
if (fieldNumber <= 0 || fieldNumber > MAX_FIELD_NUMBER) {
|
||||
throw new Error(`Field number is out of range: ${fieldNumber}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that wire type is valid.
|
||||
* @param {!WireType} wireType
|
||||
* @throws {!Error} If the wire type is invalid and the check state is debug.
|
||||
*/
|
||||
function checkWireType(wireType) {
|
||||
if (!CHECK_TYPE) {
|
||||
return;
|
||||
}
|
||||
checkCriticalWireType(wireType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that wire type is valid.
|
||||
* @param {!WireType} wireType
|
||||
* @throws {!Error} If the wire type is invalid and the check state is critical.
|
||||
*/
|
||||
function checkCriticalWireType(wireType) {
|
||||
if (!CHECK_CRITICAL_TYPE) {
|
||||
return;
|
||||
}
|
||||
if (wireType < WireType.VARINT || wireType > WireType.FIXED32) {
|
||||
throw new Error(`Invalid wire type: ${wireType}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures the given value has the correct type.
|
||||
* @param {boolean} expression
|
||||
* @param {string} errorMsg
|
||||
* @throws {!Error} If the value has the wrong type and the check state is
|
||||
* critical.
|
||||
*/
|
||||
function checkCriticalType(expression, errorMsg) {
|
||||
if (!CHECK_CRITICAL_TYPE) {
|
||||
return;
|
||||
}
|
||||
if (!expression) {
|
||||
throw new Error(errorMsg);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is an array.
|
||||
* @param {*} value
|
||||
* @return {!Array<*>}
|
||||
*/
|
||||
function checkCriticalTypeArray(value) {
|
||||
checkCriticalType(
|
||||
Array.isArray(value), `Must be an array, but got: ${value}`);
|
||||
return /** @type {!Array<*>} */ (value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is an iterable.
|
||||
* @param {*} value
|
||||
* @return {!Iterable<*>}
|
||||
*/
|
||||
function checkCriticalTypeIterable(value) {
|
||||
checkCriticalType(
|
||||
!!value[Symbol.iterator], `Must be an iterable, but got: ${value}`);
|
||||
return /** @type {!Iterable<*>} */ (value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is a boolean.
|
||||
* @param {*} value
|
||||
*/
|
||||
function checkCriticalTypeBool(value) {
|
||||
checkCriticalType(
|
||||
typeof value === 'boolean', `Must be a boolean, but got: ${value}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is an array of boolean.
|
||||
* @param {*} values
|
||||
*/
|
||||
function checkCriticalTypeBoolArray(values) {
|
||||
// TODO(b/134765672)
|
||||
if (!CHECK_CRITICAL_TYPE) {
|
||||
return;
|
||||
}
|
||||
const array = checkCriticalTypeArray(values);
|
||||
for (const value of array) {
|
||||
checkCriticalTypeBool(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is a ByteString.
|
||||
* @param {*} value
|
||||
*/
|
||||
function checkCriticalTypeByteString(value) {
|
||||
checkCriticalType(
|
||||
value instanceof ByteString, `Must be a ByteString, but got: ${value}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is an array of ByteString.
|
||||
* @param {*} values
|
||||
*/
|
||||
function checkCriticalTypeByteStringArray(values) {
|
||||
// TODO(b/134765672)
|
||||
if (!CHECK_CRITICAL_TYPE) {
|
||||
return;
|
||||
}
|
||||
const array = checkCriticalTypeArray(values);
|
||||
for (const value of array) {
|
||||
checkCriticalTypeByteString(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is a number.
|
||||
* @param {*} value
|
||||
* @throws {!Error} If the value is not float and the check state is debug.
|
||||
*/
|
||||
function checkTypeDouble(value) {
|
||||
if (!CHECK_TYPE) {
|
||||
return;
|
||||
}
|
||||
checkCriticalTypeDouble(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is a number.
|
||||
* @param {*} value
|
||||
* @throws {!Error} If the value is not float and the check state is critical.
|
||||
*/
|
||||
function checkCriticalTypeDouble(value) {
|
||||
checkCriticalType(
|
||||
typeof value === 'number', `Must be a number, but got: ${value}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is an array of double.
|
||||
* @param {*} values
|
||||
*/
|
||||
function checkCriticalTypeDoubleArray(values) {
|
||||
// TODO(b/134765672)
|
||||
if (!CHECK_CRITICAL_TYPE) {
|
||||
return;
|
||||
}
|
||||
const array = checkCriticalTypeArray(values);
|
||||
for (const value of array) {
|
||||
checkCriticalTypeDouble(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is a number.
|
||||
* @param {*} value
|
||||
* @throws {!Error} If the value is not signed int32 and the check state is
|
||||
* debug.
|
||||
*/
|
||||
function checkTypeSignedInt32(value) {
|
||||
if (!CHECK_TYPE) {
|
||||
return;
|
||||
}
|
||||
checkCriticalTypeSignedInt32(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is a number.
|
||||
* @param {*} value
|
||||
* @throws {!Error} If the value is not signed int32 and the check state is
|
||||
* critical.
|
||||
*/
|
||||
function checkCriticalTypeSignedInt32(value) {
|
||||
checkCriticalTypeDouble(value);
|
||||
const valueAsNumber = /** @type {number} */ (value);
|
||||
if (CHECK_CRITICAL_TYPE) {
|
||||
if (valueAsNumber < -Math.pow(2, 31) || valueAsNumber > Math.pow(2, 31) ||
|
||||
!Number.isInteger(valueAsNumber)) {
|
||||
throw new Error(`Must be int32, but got: ${valueAsNumber}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is an array of numbers.
|
||||
* @param {*} values
|
||||
*/
|
||||
function checkCriticalTypeSignedInt32Array(values) {
|
||||
// TODO(b/134765672)
|
||||
if (!CHECK_CRITICAL_TYPE) {
|
||||
return;
|
||||
}
|
||||
const array = checkCriticalTypeArray(values);
|
||||
for (const value of array) {
|
||||
checkCriticalTypeSignedInt32(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that value is a long instance.
|
||||
* @param {*} value
|
||||
* @throws {!Error} If the value is not a long instance and check state is
|
||||
* debug.
|
||||
*/
|
||||
function checkTypeSignedInt64(value) {
|
||||
if (!CHECK_TYPE) {
|
||||
return;
|
||||
}
|
||||
checkCriticalTypeSignedInt64(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that value is a long instance.
|
||||
* @param {*} value
|
||||
* @throws {!Error} If the value is not a long instance and check state is
|
||||
* critical.
|
||||
*/
|
||||
function checkCriticalTypeSignedInt64(value) {
|
||||
if (!CHECK_CRITICAL_TYPE) {
|
||||
return;
|
||||
}
|
||||
if (!(value instanceof Int64)) {
|
||||
throw new Error(`Must be Int64 instance, but got: ${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is an array of long instances.
|
||||
* @param {*} values
|
||||
* @throws {!Error} If values is not an array of long instances.
|
||||
*/
|
||||
function checkCriticalTypeSignedInt64Array(values) {
|
||||
// TODO(b/134765672)
|
||||
if (!CHECK_CRITICAL_TYPE) {
|
||||
return;
|
||||
}
|
||||
const array = checkCriticalTypeArray(values);
|
||||
for (const value of array) {
|
||||
checkCriticalTypeSignedInt64(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is a number and within float32 precision.
|
||||
* @param {*} value
|
||||
* @throws {!Error} If the value is not float and the check state is debug.
|
||||
*/
|
||||
function checkTypeFloat(value) {
|
||||
if (!CHECK_TYPE) {
|
||||
return;
|
||||
}
|
||||
checkCriticalTypeFloat(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is a number and within float32 precision.
|
||||
* @param {*} value
|
||||
* @throws {!Error} If the value is not float and the check state is critical.
|
||||
*/
|
||||
function checkCriticalTypeFloat(value) {
|
||||
checkCriticalTypeDouble(value);
|
||||
if (CHECK_CRITICAL_TYPE) {
|
||||
const valueAsNumber = /** @type {number} */ (value);
|
||||
if (Number.isFinite(valueAsNumber) &&
|
||||
(valueAsNumber > FLOAT32_MAX || valueAsNumber < -FLOAT32_MAX)) {
|
||||
throw new Error(
|
||||
`Given number does not fit into float precision: ${value}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is an iterable of floats.
|
||||
* @param {*} values
|
||||
*/
|
||||
function checkCriticalTypeFloatIterable(values) {
|
||||
// TODO(b/134765672)
|
||||
if (!CHECK_CRITICAL_TYPE) {
|
||||
return;
|
||||
}
|
||||
const iterable = checkCriticalTypeIterable(values);
|
||||
for (const value of iterable) {
|
||||
checkCriticalTypeFloat(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is a string.
|
||||
* @param {*} value
|
||||
*/
|
||||
function checkCriticalTypeString(value) {
|
||||
checkCriticalType(
|
||||
typeof value === 'string', `Must be string, but got: ${value}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is an array of string.
|
||||
* @param {*} values
|
||||
*/
|
||||
function checkCriticalTypeStringArray(values) {
|
||||
// TODO(b/134765672)
|
||||
if (!CHECK_CRITICAL_TYPE) {
|
||||
return;
|
||||
}
|
||||
const array = checkCriticalTypeArray(values);
|
||||
for (const value of array) {
|
||||
checkCriticalTypeString(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that value is a valid unsigned int32.
|
||||
* @param {*} value
|
||||
* @throws {!Error} If the value is out of range and the check state is debug.
|
||||
*/
|
||||
function checkTypeUnsignedInt32(value) {
|
||||
if (!CHECK_TYPE) {
|
||||
return;
|
||||
}
|
||||
checkCriticalTypeUnsignedInt32(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that value is a valid unsigned int32.
|
||||
* @param {*} value
|
||||
* @throws {!Error} If the value is out of range and the check state
|
||||
* is critical.
|
||||
*/
|
||||
function checkCriticalTypeUnsignedInt32(value) {
|
||||
if (!CHECK_CRITICAL_TYPE) {
|
||||
return;
|
||||
}
|
||||
checkCriticalTypeDouble(value);
|
||||
const valueAsNumber = /** @type {number} */ (value);
|
||||
if (valueAsNumber < 0 || valueAsNumber > Math.pow(2, 32) - 1 ||
|
||||
!Number.isInteger(valueAsNumber)) {
|
||||
throw new Error(`Must be uint32, but got: ${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is an array of unsigned int32.
|
||||
* @param {*} values
|
||||
*/
|
||||
function checkCriticalTypeUnsignedInt32Array(values) {
|
||||
// TODO(b/134765672)
|
||||
if (!CHECK_CRITICAL_TYPE) {
|
||||
return;
|
||||
}
|
||||
const array = checkCriticalTypeArray(values);
|
||||
for (const value of array) {
|
||||
checkCriticalTypeUnsignedInt32(value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether a given object is an array of message.
|
||||
* @param {*} values
|
||||
*/
|
||||
function checkCriticalTypeMessageArray(values) {
|
||||
// TODO(b/134765672)
|
||||
if (!CHECK_CRITICAL_TYPE) {
|
||||
return;
|
||||
}
|
||||
const array = checkCriticalTypeArray(values);
|
||||
for (const value of array) {
|
||||
checkCriticalType(
|
||||
value !== null, 'Given value is not a message instance: null');
|
||||
}
|
||||
}
|
||||
|
||||
exports = {
|
||||
checkDefAndNotNull,
|
||||
checkCriticalElementIndex,
|
||||
checkCriticalFieldNumber,
|
||||
checkCriticalPositionIndex,
|
||||
checkCriticalRange,
|
||||
checkCriticalState,
|
||||
checkCriticalTypeBool,
|
||||
checkCriticalTypeBoolArray,
|
||||
checkCriticalTypeByteString,
|
||||
checkCriticalTypeByteStringArray,
|
||||
checkCriticalTypeDouble,
|
||||
checkTypeDouble,
|
||||
checkCriticalTypeDoubleArray,
|
||||
checkTypeFloat,
|
||||
checkCriticalTypeFloat,
|
||||
checkCriticalTypeFloatIterable,
|
||||
checkCriticalTypeMessageArray,
|
||||
checkCriticalTypeSignedInt32,
|
||||
checkCriticalTypeSignedInt32Array,
|
||||
checkCriticalTypeSignedInt64,
|
||||
checkTypeSignedInt64,
|
||||
checkCriticalTypeSignedInt64Array,
|
||||
checkCriticalTypeString,
|
||||
checkCriticalTypeStringArray,
|
||||
checkCriticalTypeUnsignedInt32,
|
||||
checkCriticalTypeUnsignedInt32Array,
|
||||
checkCriticalType,
|
||||
checkCriticalWireType,
|
||||
checkElementIndex,
|
||||
checkFieldNumber,
|
||||
checkFunctionExists,
|
||||
checkPositionIndex,
|
||||
checkRange,
|
||||
checkState,
|
||||
checkTypeUnsignedInt32,
|
||||
checkTypeSignedInt32,
|
||||
checkWireType,
|
||||
CHECK_BOUNDS,
|
||||
CHECK_CRITICAL_BOUNDS,
|
||||
CHECK_STATE,
|
||||
CHECK_CRITICAL_STATE,
|
||||
CHECK_TYPE,
|
||||
CHECK_CRITICAL_TYPE,
|
||||
MAX_FIELD_NUMBER,
|
||||
POLYFILL_TEXT_ENCODING,
|
||||
};
|
58
deps/protobuf/js/experimental/runtime/internal/checks_test.js
vendored
Normal file
58
deps/protobuf/js/experimental/runtime/internal/checks_test.js
vendored
Normal file
@ -0,0 +1,58 @@
|
||||
/**
|
||||
* @fileoverview Tests for checks.js.
|
||||
*/
|
||||
goog.module('protobuf.internal.checksTest');
|
||||
|
||||
const {CHECK_TYPE, checkDefAndNotNull, checkFunctionExists} = goog.require('protobuf.internal.checks');
|
||||
|
||||
describe('checkDefAndNotNull', () => {
|
||||
it('throws if undefined', () => {
|
||||
let value;
|
||||
if (CHECK_TYPE) {
|
||||
expect(() => checkDefAndNotNull(value)).toThrow();
|
||||
} else {
|
||||
expect(checkDefAndNotNull(value)).toBeUndefined();
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if null', () => {
|
||||
const value = null;
|
||||
if (CHECK_TYPE) {
|
||||
expect(() => checkDefAndNotNull(value)).toThrow();
|
||||
} else {
|
||||
expect(checkDefAndNotNull(value)).toBeNull();
|
||||
}
|
||||
});
|
||||
|
||||
it('does not throw if empty string', () => {
|
||||
const value = '';
|
||||
expect(checkDefAndNotNull(value)).toEqual('');
|
||||
});
|
||||
});
|
||||
|
||||
describe('checkFunctionExists', () => {
|
||||
it('throws if the function is undefined', () => {
|
||||
let foo = /** @type {function()} */ (/** @type {*} */ (undefined));
|
||||
if (CHECK_TYPE) {
|
||||
expect(() => checkFunctionExists(foo)).toThrow();
|
||||
} else {
|
||||
checkFunctionExists(foo);
|
||||
}
|
||||
});
|
||||
|
||||
it('throws if the property is defined but not a function', () => {
|
||||
let foo = /** @type {function()} */ (/** @type {*} */ (1));
|
||||
if (CHECK_TYPE) {
|
||||
expect(() => checkFunctionExists(foo)).toThrow();
|
||||
} else {
|
||||
checkFunctionExists(foo);
|
||||
}
|
||||
});
|
||||
|
||||
it('does not throw if the function is defined', () => {
|
||||
function foo(x) {
|
||||
return x;
|
||||
}
|
||||
checkFunctionExists(foo);
|
||||
});
|
||||
});
|
130
deps/protobuf/js/experimental/runtime/kernel/binary_storage.js
vendored
Normal file
130
deps/protobuf/js/experimental/runtime/kernel/binary_storage.js
vendored
Normal file
@ -0,0 +1,130 @@
|
||||
goog.module('protobuf.runtime.BinaryStorage');
|
||||
|
||||
const Storage = goog.require('protobuf.runtime.Storage');
|
||||
const {checkDefAndNotNull} = goog.require('protobuf.internal.checks');
|
||||
|
||||
/**
|
||||
* Class storing all the fields of a binary protobuf message.
|
||||
*
|
||||
* @package
|
||||
* @template FieldType
|
||||
* @implements {Storage}
|
||||
*/
|
||||
class BinaryStorage {
|
||||
/**
|
||||
* @param {number=} pivot
|
||||
*/
|
||||
constructor(pivot = Storage.DEFAULT_PIVOT) {
|
||||
/**
|
||||
* Fields having a field number no greater than the pivot value are stored
|
||||
* into an array for fast access. A field with field number X is stored into
|
||||
* the array position X - 1.
|
||||
*
|
||||
* @private @const {!Array<!FieldType|undefined>}
|
||||
*/
|
||||
this.array_ = new Array(pivot);
|
||||
|
||||
/**
|
||||
* Fields having a field number higher than the pivot value are stored into
|
||||
* the map. We create the map only when it's needed, since even an empty map
|
||||
* takes up a significant amount of memory.
|
||||
*
|
||||
* @private {?Map<number, !FieldType>}
|
||||
*/
|
||||
this.map_ = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fields having a field number no greater than the pivot value are stored
|
||||
* into an array for fast access. A field with field number X is stored into
|
||||
* the array position X - 1.
|
||||
* @return {number}
|
||||
* @override
|
||||
*/
|
||||
getPivot() {
|
||||
return this.array_.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a field in the specified field number.
|
||||
*
|
||||
* @param {number} fieldNumber
|
||||
* @param {!FieldType} field
|
||||
* @override
|
||||
*/
|
||||
set(fieldNumber, field) {
|
||||
if (fieldNumber <= this.getPivot()) {
|
||||
this.array_[fieldNumber - 1] = field;
|
||||
} else {
|
||||
if (this.map_) {
|
||||
this.map_.set(fieldNumber, field);
|
||||
} else {
|
||||
this.map_ = new Map([[fieldNumber, field]]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a field at the specified field number.
|
||||
*
|
||||
* @param {number} fieldNumber
|
||||
* @return {!FieldType|undefined}
|
||||
* @override
|
||||
*/
|
||||
get(fieldNumber) {
|
||||
if (fieldNumber <= this.getPivot()) {
|
||||
return this.array_[fieldNumber - 1];
|
||||
} else {
|
||||
return this.map_ ? this.map_.get(fieldNumber) : undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes a field from the specified field number.
|
||||
*
|
||||
* @param {number} fieldNumber
|
||||
* @override
|
||||
*/
|
||||
delete(fieldNumber) {
|
||||
if (fieldNumber <= this.getPivot()) {
|
||||
delete this.array_[fieldNumber - 1];
|
||||
} else {
|
||||
if (this.map_) {
|
||||
this.map_.delete(fieldNumber);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the provided function once for each field.
|
||||
*
|
||||
* @param {function(!FieldType, number): void} callback
|
||||
* @override
|
||||
*/
|
||||
forEach(callback) {
|
||||
this.array_.forEach((field, fieldNumber) => {
|
||||
if (field) {
|
||||
callback(checkDefAndNotNull(field), fieldNumber + 1);
|
||||
}
|
||||
});
|
||||
if (this.map_) {
|
||||
this.map_.forEach(callback);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a shallow copy of the storage.
|
||||
*
|
||||
* @return {!BinaryStorage}
|
||||
* @override
|
||||
*/
|
||||
shallowCopy() {
|
||||
const copy = new BinaryStorage(this.getPivot());
|
||||
this.forEach(
|
||||
(field, fieldNumber) =>
|
||||
void copy.set(fieldNumber, field.shallowCopy()));
|
||||
return copy;
|
||||
}
|
||||
}
|
||||
|
||||
exports = BinaryStorage;
|
165
deps/protobuf/js/experimental/runtime/kernel/binary_storage_test.js
vendored
Normal file
165
deps/protobuf/js/experimental/runtime/kernel/binary_storage_test.js
vendored
Normal file
@ -0,0 +1,165 @@
|
||||
/**
|
||||
* @fileoverview Tests for storage.js.
|
||||
*/
|
||||
goog.module('protobuf.runtime.BinaryStorageTest');
|
||||
|
||||
goog.setTestOnly();
|
||||
|
||||
const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage');
|
||||
const {Field} = goog.require('protobuf.binary.field');
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
const DEFAULT_PIVOT = 24;
|
||||
|
||||
const /** !Field */ field1 =
|
||||
Field.fromDecodedValue(/* decodedValue= */ 1, /* encoder= */ () => {});
|
||||
const /** !Field */ field2 =
|
||||
Field.fromDecodedValue(/* decodedValue= */ 2, /* encoder= */ () => {});
|
||||
const /** !Field */ field3 =
|
||||
Field.fromDecodedValue(/* decodedValue= */ 3, /* encoder= */ () => {});
|
||||
const /** !Field */ field4 =
|
||||
Field.fromDecodedValue(/* decodedValue= */ 4, /* encoder= */ () => {});
|
||||
|
||||
/**
|
||||
* Returns the number of fields stored.
|
||||
*
|
||||
* @param {!BinaryStorage} storage
|
||||
* @return {number}
|
||||
*/
|
||||
function getStorageSize(storage) {
|
||||
let size = 0;
|
||||
storage.forEach(() => void size++);
|
||||
return size;
|
||||
}
|
||||
|
||||
describe('BinaryStorage', () => {
|
||||
it('sets and gets a field not greater than the pivot', () => {
|
||||
const storage = new BinaryStorage(DEFAULT_PIVOT);
|
||||
|
||||
storage.set(1, field1);
|
||||
storage.set(DEFAULT_PIVOT, field2);
|
||||
|
||||
expect(storage.getPivot()).toBe(DEFAULT_PIVOT);
|
||||
expect(storage.get(1)).toBe(field1);
|
||||
expect(storage.get(DEFAULT_PIVOT)).toBe(field2);
|
||||
});
|
||||
|
||||
it('sets and gets a field greater than the pivot', () => {
|
||||
const storage = new BinaryStorage(DEFAULT_PIVOT);
|
||||
|
||||
storage.set(DEFAULT_PIVOT + 1, field1);
|
||||
storage.set(100000, field2);
|
||||
|
||||
expect(storage.get(DEFAULT_PIVOT + 1)).toBe(field1);
|
||||
expect(storage.get(100000)).toBe(field2);
|
||||
});
|
||||
|
||||
it('sets and gets a field when pivot is zero', () => {
|
||||
const storage = new BinaryStorage(0);
|
||||
|
||||
storage.set(0, field1);
|
||||
storage.set(100000, field2);
|
||||
|
||||
expect(storage.getPivot()).toBe(0);
|
||||
expect(storage.get(0)).toBe(field1);
|
||||
expect(storage.get(100000)).toBe(field2);
|
||||
});
|
||||
|
||||
it('sets and gets a field when pivot is undefined', () => {
|
||||
const storage = new BinaryStorage();
|
||||
|
||||
storage.set(0, field1);
|
||||
storage.set(DEFAULT_PIVOT, field2);
|
||||
storage.set(DEFAULT_PIVOT + 1, field3);
|
||||
|
||||
expect(storage.getPivot()).toBe(DEFAULT_PIVOT);
|
||||
expect(storage.get(0)).toBe(field1);
|
||||
expect(storage.get(DEFAULT_PIVOT)).toBe(field2);
|
||||
expect(storage.get(DEFAULT_PIVOT + 1)).toBe(field3);
|
||||
});
|
||||
|
||||
it('returns undefined for nonexistent fields', () => {
|
||||
const storage = new BinaryStorage(DEFAULT_PIVOT);
|
||||
|
||||
expect(storage.get(1)).toBeUndefined();
|
||||
expect(storage.get(DEFAULT_PIVOT)).toBeUndefined();
|
||||
expect(storage.get(DEFAULT_PIVOT + 1)).toBeUndefined();
|
||||
expect(storage.get(100000)).toBeUndefined();
|
||||
});
|
||||
|
||||
it('returns undefined for nonexistent fields after map initialization',
|
||||
() => {
|
||||
const storage = new BinaryStorage(DEFAULT_PIVOT);
|
||||
storage.set(100001, field1);
|
||||
|
||||
expect(storage.get(1)).toBeUndefined();
|
||||
expect(storage.get(DEFAULT_PIVOT)).toBeUndefined();
|
||||
expect(storage.get(DEFAULT_PIVOT + 1)).toBeUndefined();
|
||||
expect(storage.get(100000)).toBeUndefined();
|
||||
});
|
||||
|
||||
it('deletes a field in delete() when values are only in array', () => {
|
||||
const storage = new BinaryStorage(DEFAULT_PIVOT);
|
||||
storage.set(1, field1);
|
||||
|
||||
storage.delete(1);
|
||||
|
||||
expect(storage.get(1)).toBeUndefined();
|
||||
});
|
||||
|
||||
it('deletes a field in delete() when values are both in array and map',
|
||||
() => {
|
||||
const storage = new BinaryStorage(DEFAULT_PIVOT);
|
||||
storage.set(DEFAULT_PIVOT, field2);
|
||||
storage.set(DEFAULT_PIVOT + 1, field3);
|
||||
|
||||
storage.delete(DEFAULT_PIVOT);
|
||||
storage.delete(DEFAULT_PIVOT + 1);
|
||||
|
||||
expect(storage.get(DEFAULT_PIVOT)).toBeUndefined();
|
||||
expect(storage.get(DEFAULT_PIVOT + 1)).toBeUndefined();
|
||||
});
|
||||
|
||||
it('deletes a field in delete() when values are only in map', () => {
|
||||
const storage = new BinaryStorage(DEFAULT_PIVOT);
|
||||
storage.set(100000, field4);
|
||||
|
||||
storage.delete(100000);
|
||||
|
||||
expect(storage.get(100000)).toBeUndefined();
|
||||
});
|
||||
|
||||
it('loops over all the elements in forEach()', () => {
|
||||
const storage = new BinaryStorage(DEFAULT_PIVOT);
|
||||
storage.set(1, field1);
|
||||
storage.set(DEFAULT_PIVOT, field2);
|
||||
storage.set(DEFAULT_PIVOT + 1, field3);
|
||||
storage.set(100000, field4);
|
||||
|
||||
const fields = new Map();
|
||||
storage.forEach(
|
||||
(field, fieldNumber) => void fields.set(fieldNumber, field));
|
||||
|
||||
expect(fields.size).toEqual(4);
|
||||
expect(fields.get(1)).toBe(field1);
|
||||
expect(storage.get(DEFAULT_PIVOT)).toBe(field2);
|
||||
expect(storage.get(DEFAULT_PIVOT + 1)).toBe(field3);
|
||||
expect(fields.get(100000)).toBe(field4);
|
||||
});
|
||||
|
||||
it('creates a shallow copy of the storage in shallowCopy()', () => {
|
||||
const storage = new BinaryStorage(DEFAULT_PIVOT);
|
||||
storage.set(1, field1);
|
||||
storage.set(100000, field2);
|
||||
|
||||
const copy = storage.shallowCopy();
|
||||
|
||||
expect(getStorageSize(copy)).toEqual(2);
|
||||
expect(copy.get(1)).not.toBe(field1);
|
||||
expect(copy.get(1).getDecodedValue()).toEqual(1);
|
||||
expect(copy.get(100000)).not.toBe(field1);
|
||||
expect(copy.get(100000).getDecodedValue()).toEqual(2);
|
||||
});
|
||||
});
|
79
deps/protobuf/js/experimental/runtime/kernel/bool_test_pairs.js
vendored
Normal file
79
deps/protobuf/js/experimental/runtime/kernel/bool_test_pairs.js
vendored
Normal file
@ -0,0 +1,79 @@
|
||||
/**
|
||||
* @fileoverview Test data for bool encoding and decoding.
|
||||
*/
|
||||
goog.module('protobuf.binary.boolTestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of boolean values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, boolValue: boolean, bufferDecoder:
|
||||
* !BufferDecoder, error: ?boolean, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getBoolPairs() {
|
||||
const boolPairs = [
|
||||
{
|
||||
name: 'true',
|
||||
boolValue: true,
|
||||
bufferDecoder: createBufferDecoder(0x01),
|
||||
},
|
||||
{
|
||||
name: 'false',
|
||||
boolValue: false,
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
},
|
||||
{
|
||||
name: 'two-byte true',
|
||||
boolValue: true,
|
||||
bufferDecoder: createBufferDecoder(0x80, 0x01),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'two-byte false',
|
||||
boolValue: false,
|
||||
bufferDecoder: createBufferDecoder(0x80, 0x00),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'minus one',
|
||||
boolValue: true,
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'max signed int 2^63 - 1',
|
||||
boolValue: true,
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'min signed int -2^63',
|
||||
boolValue: true,
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'overflowed but valid varint',
|
||||
boolValue: false,
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x02),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'errors out for 11 bytes',
|
||||
boolValue: true,
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
error: true,
|
||||
skip_writer: true,
|
||||
},
|
||||
];
|
||||
return [...boolPairs];
|
||||
}
|
||||
|
||||
exports = {getBoolPairs};
|
343
deps/protobuf/js/experimental/runtime/kernel/buffer_decoder.js
vendored
Normal file
343
deps/protobuf/js/experimental/runtime/kernel/buffer_decoder.js
vendored
Normal file
@ -0,0 +1,343 @@
|
||||
/**
|
||||
* @fileoverview A buffer implementation that can decode data for protobufs.
|
||||
*/
|
||||
|
||||
goog.module('protobuf.binary.BufferDecoder');
|
||||
|
||||
const ByteString = goog.require('protobuf.ByteString');
|
||||
const functions = goog.require('goog.functions');
|
||||
const {POLYFILL_TEXT_ENCODING, checkCriticalPositionIndex, checkCriticalState, checkState} = goog.require('protobuf.internal.checks');
|
||||
const {byteStringFromUint8ArrayUnsafe} = goog.require('protobuf.byteStringInternal');
|
||||
const {concatenateByteArrays} = goog.require('protobuf.binary.uint8arrays');
|
||||
const {decode} = goog.require('protobuf.binary.textencoding');
|
||||
|
||||
/**
|
||||
* Returns a valid utf-8 decoder function based on TextDecoder if available or
|
||||
* a polyfill.
|
||||
* Some of the environments we run in do not have TextDecoder defined.
|
||||
* TextDecoder is faster than our polyfill so we prefer it over the polyfill.
|
||||
* @return {function(!DataView): string}
|
||||
*/
|
||||
function getStringDecoderFunction() {
|
||||
if (goog.global['TextDecoder']) {
|
||||
const textDecoder = new goog.global['TextDecoder']('utf-8', {fatal: true});
|
||||
return bytes => textDecoder.decode(bytes);
|
||||
}
|
||||
if (POLYFILL_TEXT_ENCODING) {
|
||||
return decode;
|
||||
} else {
|
||||
throw new Error(
|
||||
'TextDecoder is missing. ' +
|
||||
'Enable protobuf.defines.POLYFILL_TEXT_ENCODING.');
|
||||
}
|
||||
}
|
||||
|
||||
/** @type {function(): function(!DataView): string} */
|
||||
const stringDecoderFunction =
|
||||
functions.cacheReturnValue(() => getStringDecoderFunction());
|
||||
|
||||
/** @type {function(): !DataView} */
|
||||
const emptyDataView =
|
||||
functions.cacheReturnValue(() => new DataView(new ArrayBuffer(0)));
|
||||
|
||||
class BufferDecoder {
|
||||
/**
|
||||
* @param {!Array<!BufferDecoder>} bufferDecoders
|
||||
* @return {!BufferDecoder}
|
||||
*/
|
||||
static merge(bufferDecoders) {
|
||||
const uint8Arrays = bufferDecoders.map(b => b.asUint8Array());
|
||||
const bytesArray = concatenateByteArrays(uint8Arrays);
|
||||
return BufferDecoder.fromArrayBuffer(bytesArray.buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!ArrayBuffer} arrayBuffer
|
||||
* @return {!BufferDecoder}
|
||||
*/
|
||||
static fromArrayBuffer(arrayBuffer) {
|
||||
return new BufferDecoder(
|
||||
new DataView(arrayBuffer), 0, arrayBuffer.byteLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!DataView} dataView
|
||||
* @param {number} startIndex
|
||||
* @param {number} length
|
||||
* @private
|
||||
*/
|
||||
constructor(dataView, startIndex, length) {
|
||||
/** @private @const {!DataView} */
|
||||
this.dataView_ = dataView;
|
||||
/** @private @const {number} */
|
||||
this.startIndex_ = startIndex;
|
||||
/** @private @const {number} */
|
||||
this.endIndex_ = startIndex + length;
|
||||
/** @private {number} */
|
||||
this.cursor_ = startIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start index of the underlying buffer.
|
||||
* @return {number}
|
||||
*/
|
||||
startIndex() {
|
||||
return this.startIndex_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the end index of the underlying buffer.
|
||||
* @return {number}
|
||||
*/
|
||||
endIndex() {
|
||||
return this.endIndex_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length of the underlying buffer.
|
||||
* @return {number}
|
||||
*/
|
||||
length() {
|
||||
return this.endIndex_ - this.startIndex_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the start position of the next data, i.e. end position of the last
|
||||
* read data + 1.
|
||||
* @return {number}
|
||||
*/
|
||||
cursor() {
|
||||
return this.cursor_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the cursor to the specified position.
|
||||
* @param {number} position
|
||||
*/
|
||||
setCursor(position) {
|
||||
this.cursor_ = position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if there is more data to read after the current cursor position.
|
||||
* @return {boolean}
|
||||
*/
|
||||
hasNext() {
|
||||
return this.cursor_ < this.endIndex_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a float32 from a given index
|
||||
* @param {number} index
|
||||
* @return {number}
|
||||
*/
|
||||
getFloat32(index) {
|
||||
this.cursor_ = index + 4;
|
||||
return this.dataView_.getFloat32(index, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a float64 from a given index
|
||||
* @param {number} index
|
||||
* @return {number}
|
||||
*/
|
||||
getFloat64(index) {
|
||||
this.cursor_ = index + 8;
|
||||
return this.dataView_.getFloat64(index, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an int32 from a given index
|
||||
* @param {number} index
|
||||
* @return {number}
|
||||
*/
|
||||
getInt32(index) {
|
||||
this.cursor_ = index + 4;
|
||||
return this.dataView_.getInt32(index, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a uint32 from a given index
|
||||
* @param {number} index
|
||||
* @return {number}
|
||||
*/
|
||||
getUint32(index) {
|
||||
this.cursor_ = index + 4;
|
||||
return this.dataView_.getUint32(index, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns two JS numbers each representing 32 bits of a 64 bit number. Also
|
||||
* sets the cursor to the start of the next block of data.
|
||||
* @param {number} index
|
||||
* @return {{lowBits: number, highBits: number}}
|
||||
*/
|
||||
getVarint(index) {
|
||||
this.cursor_ = index;
|
||||
let lowBits = 0;
|
||||
let highBits = 0;
|
||||
|
||||
for (let shift = 0; shift < 28; shift += 7) {
|
||||
const b = this.dataView_.getUint8(this.cursor_++);
|
||||
lowBits |= (b & 0x7F) << shift;
|
||||
if ((b & 0x80) === 0) {
|
||||
return {lowBits, highBits};
|
||||
}
|
||||
}
|
||||
|
||||
const middleByte = this.dataView_.getUint8(this.cursor_++);
|
||||
|
||||
// last four bits of the first 32 bit number
|
||||
lowBits |= (middleByte & 0x0F) << 28;
|
||||
|
||||
// 3 upper bits are part of the next 32 bit number
|
||||
highBits = (middleByte & 0x70) >> 4;
|
||||
|
||||
if ((middleByte & 0x80) === 0) {
|
||||
return {lowBits, highBits};
|
||||
}
|
||||
|
||||
|
||||
for (let shift = 3; shift <= 31; shift += 7) {
|
||||
const b = this.dataView_.getUint8(this.cursor_++);
|
||||
highBits |= (b & 0x7F) << shift;
|
||||
if ((b & 0x80) === 0) {
|
||||
return {lowBits, highBits};
|
||||
}
|
||||
}
|
||||
|
||||
checkCriticalState(false, 'Data is longer than 10 bytes');
|
||||
|
||||
return {lowBits, highBits};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unsigned int32 number at the current cursor position. The upper
|
||||
* bits are discarded if the varint is longer than 32 bits. Also sets the
|
||||
* cursor to the start of the next block of data.
|
||||
* @return {number}
|
||||
*/
|
||||
getUnsignedVarint32() {
|
||||
let b = this.dataView_.getUint8(this.cursor_++);
|
||||
let result = b & 0x7F;
|
||||
if ((b & 0x80) === 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b = this.dataView_.getUint8(this.cursor_++);
|
||||
result |= (b & 0x7F) << 7;
|
||||
if ((b & 0x80) === 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b = this.dataView_.getUint8(this.cursor_++);
|
||||
result |= (b & 0x7F) << 14;
|
||||
if ((b & 0x80) === 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
b = this.dataView_.getUint8(this.cursor_++);
|
||||
result |= (b & 0x7F) << 21;
|
||||
if ((b & 0x80) === 0) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Extract only last 4 bits
|
||||
b = this.dataView_.getUint8(this.cursor_++);
|
||||
result |= (b & 0x0F) << 28;
|
||||
|
||||
for (let readBytes = 5; ((b & 0x80) !== 0) && readBytes < 10; readBytes++) {
|
||||
b = this.dataView_.getUint8(this.cursor_++);
|
||||
}
|
||||
|
||||
checkCriticalState((b & 0x80) === 0, 'Data is longer than 10 bytes');
|
||||
|
||||
// Result can be have 32 bits, convert it to unsigned
|
||||
return result >>> 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unsigned int32 number at the specified index. The upper bits are
|
||||
* discarded if the varint is longer than 32 bits. Also sets the cursor to the
|
||||
* start of the next block of data.
|
||||
* @param {number} index
|
||||
* @return {number}
|
||||
*/
|
||||
getUnsignedVarint32At(index) {
|
||||
this.cursor_ = index;
|
||||
return this.getUnsignedVarint32();
|
||||
}
|
||||
|
||||
/**
|
||||
* Seeks forward by the given amount.
|
||||
* @param {number} skipAmount
|
||||
* @package
|
||||
*/
|
||||
skip(skipAmount) {
|
||||
this.cursor_ += skipAmount;
|
||||
checkCriticalPositionIndex(this.cursor_, this.endIndex_);
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips over a varint from the current cursor position.
|
||||
* @package
|
||||
*/
|
||||
skipVarint() {
|
||||
const startIndex = this.cursor_;
|
||||
while (this.dataView_.getUint8(this.cursor_++) & 0x80) {
|
||||
}
|
||||
checkCriticalPositionIndex(this.cursor_, startIndex + 10);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} startIndex
|
||||
* @param {number} length
|
||||
* @return {!BufferDecoder}
|
||||
*/
|
||||
subBufferDecoder(startIndex, length) {
|
||||
checkState(
|
||||
startIndex >= this.startIndex(),
|
||||
`Current start: ${this.startIndex()}, subBufferDecoder start: ${
|
||||
startIndex}`);
|
||||
checkState(length >= 0, `Length: ${length}`);
|
||||
checkState(
|
||||
startIndex + length <= this.endIndex(),
|
||||
`Current end: ${this.endIndex()}, subBufferDecoder start: ${
|
||||
startIndex}, subBufferDecoder length: ${length}`);
|
||||
return new BufferDecoder(this.dataView_, startIndex, length);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the buffer as a string.
|
||||
* @return {string}
|
||||
*/
|
||||
asString() {
|
||||
// TODO: Remove this check when we no longer need to support IE
|
||||
const stringDataView = this.length() === 0 ?
|
||||
emptyDataView() :
|
||||
new DataView(this.dataView_.buffer, this.startIndex_, this.length());
|
||||
return stringDecoderFunction()(stringDataView);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the buffer as a ByteString.
|
||||
* @return {!ByteString}
|
||||
*/
|
||||
asByteString() {
|
||||
return byteStringFromUint8ArrayUnsafe(this.asUint8Array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the DataView as an Uint8Array. DO NOT MODIFY or expose the
|
||||
* underlying buffer.
|
||||
*
|
||||
* @package
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
asUint8Array() {
|
||||
return new Uint8Array(
|
||||
this.dataView_.buffer, this.startIndex_, this.length());
|
||||
}
|
||||
}
|
||||
|
||||
exports = BufferDecoder;
|
18
deps/protobuf/js/experimental/runtime/kernel/buffer_decoder_helper.js
vendored
Normal file
18
deps/protobuf/js/experimental/runtime/kernel/buffer_decoder_helper.js
vendored
Normal file
@ -0,0 +1,18 @@
|
||||
/**
|
||||
* @fileoverview Helper methods to create BufferDecoders.
|
||||
*/
|
||||
goog.module('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
|
||||
/**
|
||||
* @param {...number} bytes
|
||||
* @return {!BufferDecoder}
|
||||
*/
|
||||
function createBufferDecoder(...bytes) {
|
||||
return BufferDecoder.fromArrayBuffer(new Uint8Array(bytes).buffer);
|
||||
}
|
||||
|
||||
exports = {
|
||||
createBufferDecoder,
|
||||
};
|
242
deps/protobuf/js/experimental/runtime/kernel/buffer_decoder_test.js
vendored
Normal file
242
deps/protobuf/js/experimental/runtime/kernel/buffer_decoder_test.js
vendored
Normal file
@ -0,0 +1,242 @@
|
||||
/**
|
||||
* @fileoverview Tests for BufferDecoder.
|
||||
*/
|
||||
|
||||
goog.module('protobuf.binary.varintsTest');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {CHECK_CRITICAL_STATE, CHECK_STATE} = goog.require('protobuf.internal.checks');
|
||||
|
||||
goog.setTestOnly();
|
||||
|
||||
/**
|
||||
* @param {...number} bytes
|
||||
* @return {!ArrayBuffer}
|
||||
*/
|
||||
function createArrayBuffer(...bytes) {
|
||||
return new Uint8Array(bytes).buffer;
|
||||
}
|
||||
|
||||
describe('setCursor does', () => {
|
||||
it('set the cursor at the position specified', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x0, 0x1));
|
||||
expect(bufferDecoder.cursor()).toBe(0);
|
||||
bufferDecoder.setCursor(1);
|
||||
expect(bufferDecoder.cursor()).toBe(1);
|
||||
});
|
||||
});
|
||||
|
||||
describe('skip does', () => {
|
||||
it('advance the cursor', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x0, 0x1, 0x2));
|
||||
bufferDecoder.setCursor(1);
|
||||
bufferDecoder.skip(1);
|
||||
expect(bufferDecoder.cursor()).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Skip varint does', () => {
|
||||
it('skip a varint', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01));
|
||||
bufferDecoder.skipVarint();
|
||||
expect(bufferDecoder.cursor()).toBe(1);
|
||||
});
|
||||
|
||||
it('fail when varint is larger than 10 bytes', () => {
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer(
|
||||
0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00));
|
||||
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => bufferDecoder.skipVarint()).toThrow();
|
||||
} else {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
bufferDecoder.skipVarint();
|
||||
expect(bufferDecoder.cursor()).toBe(11);
|
||||
}
|
||||
});
|
||||
|
||||
it('fail when varint is beyond end of underlying array', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x80));
|
||||
expect(() => bufferDecoder.skipVarint()).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('readVarint64 does', () => {
|
||||
it('read zero', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00));
|
||||
const {lowBits, highBits} = bufferDecoder.getVarint(0);
|
||||
expect(lowBits).toBe(0);
|
||||
expect(highBits).toBe(0);
|
||||
expect(bufferDecoder.cursor()).toBe(1);
|
||||
});
|
||||
|
||||
it('read one', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01));
|
||||
const {lowBits, highBits} = bufferDecoder.getVarint(0);
|
||||
expect(lowBits).toBe(1);
|
||||
expect(highBits).toBe(0);
|
||||
expect(bufferDecoder.cursor()).toBe(1);
|
||||
});
|
||||
|
||||
it('read max value', () => {
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer(
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01));
|
||||
const {lowBits, highBits} = bufferDecoder.getVarint(0);
|
||||
expect(lowBits).toBe(-1);
|
||||
expect(highBits).toBe(-1);
|
||||
expect(bufferDecoder.cursor()).toBe(10);
|
||||
});
|
||||
});
|
||||
|
||||
describe('readUnsignedVarint32 does', () => {
|
||||
it('read zero', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00));
|
||||
const result = bufferDecoder.getUnsignedVarint32();
|
||||
expect(result).toBe(0);
|
||||
expect(bufferDecoder.cursor()).toBe(1);
|
||||
});
|
||||
|
||||
it('read one', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01));
|
||||
const result = bufferDecoder.getUnsignedVarint32();
|
||||
expect(result).toBe(1);
|
||||
expect(bufferDecoder.cursor()).toBe(1);
|
||||
});
|
||||
|
||||
it('read max int32', () => {
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(
|
||||
createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF, 0x0F));
|
||||
const result = bufferDecoder.getUnsignedVarint32();
|
||||
expect(result).toBe(4294967295);
|
||||
expect(bufferDecoder.cursor()).toBe(5);
|
||||
});
|
||||
|
||||
it('read max value', () => {
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer(
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01));
|
||||
const result = bufferDecoder.getUnsignedVarint32();
|
||||
expect(result).toBe(4294967295);
|
||||
expect(bufferDecoder.cursor()).toBe(10);
|
||||
});
|
||||
|
||||
it('fail if data is longer than 10 bytes', () => {
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(createArrayBuffer(
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01));
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => bufferDecoder.getUnsignedVarint32()).toThrow();
|
||||
} else {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
const result = bufferDecoder.getUnsignedVarint32();
|
||||
expect(result).toBe(4294967295);
|
||||
expect(bufferDecoder.cursor()).toBe(10);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe('readUnsignedVarint32At does', () => {
|
||||
it('reads from a specific index', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x1, 0x2));
|
||||
const result = bufferDecoder.getUnsignedVarint32At(1);
|
||||
expect(result).toBe(2);
|
||||
expect(bufferDecoder.cursor()).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getFloat32 does', () => {
|
||||
it('read one', () => {
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(
|
||||
createArrayBuffer(0x00, 0x00, 0x80, 0x3F));
|
||||
const result = bufferDecoder.getFloat32(0);
|
||||
expect(result).toBe(1);
|
||||
expect(bufferDecoder.cursor()).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getFloat64 does', () => {
|
||||
it('read one', () => {
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(
|
||||
createArrayBuffer(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F));
|
||||
const result = bufferDecoder.getFloat64(0);
|
||||
expect(result).toBe(1);
|
||||
expect(bufferDecoder.cursor()).toBe(8);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getInt32 does', () => {
|
||||
it('read one', () => {
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(
|
||||
createArrayBuffer(0x01, 0x00, 0x00, 0x00));
|
||||
const result = bufferDecoder.getInt32(0);
|
||||
expect(result).toBe(1);
|
||||
expect(bufferDecoder.cursor()).toBe(4);
|
||||
});
|
||||
|
||||
it('read minus one', () => {
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(
|
||||
createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF));
|
||||
const result = bufferDecoder.getInt32(0);
|
||||
expect(result).toBe(-1);
|
||||
expect(bufferDecoder.cursor()).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getUint32 does', () => {
|
||||
it('read one', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01, 0x00, 0x00, 0x0));
|
||||
const result = bufferDecoder.getUint32(0);
|
||||
expect(result).toBe(1);
|
||||
expect(bufferDecoder.cursor()).toBe(4);
|
||||
});
|
||||
|
||||
it('read max uint32', () => {
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(
|
||||
createArrayBuffer(0xFF, 0xFF, 0xFF, 0xFF));
|
||||
const result = bufferDecoder.getUint32(0);
|
||||
expect(result).toBe(4294967295);
|
||||
expect(bufferDecoder.cursor()).toBe(4);
|
||||
});
|
||||
});
|
||||
|
||||
describe('subBufferDecoder does', () => {
|
||||
it('can create valid sub buffers', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00, 0x01, 0x02));
|
||||
|
||||
expect(bufferDecoder.subBufferDecoder(0, 0))
|
||||
.toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer()));
|
||||
expect(bufferDecoder.subBufferDecoder(0, 1))
|
||||
.toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00)));
|
||||
expect(bufferDecoder.subBufferDecoder(1, 0))
|
||||
.toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer()));
|
||||
expect(bufferDecoder.subBufferDecoder(1, 1))
|
||||
.toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01)));
|
||||
expect(bufferDecoder.subBufferDecoder(1, 2))
|
||||
.toEqual(BufferDecoder.fromArrayBuffer(createArrayBuffer(0x01, 0x02)));
|
||||
});
|
||||
|
||||
it('can not create invalid', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x00, 0x01, 0x02));
|
||||
if (CHECK_STATE) {
|
||||
expect(() => bufferDecoder.subBufferDecoder(-1, 1)).toThrow();
|
||||
expect(() => bufferDecoder.subBufferDecoder(0, -4)).toThrow();
|
||||
expect(() => bufferDecoder.subBufferDecoder(0, 4)).toThrow();
|
||||
}
|
||||
});
|
||||
});
|
91
deps/protobuf/js/experimental/runtime/kernel/conformance/conformance_request.js
vendored
Normal file
91
deps/protobuf/js/experimental/runtime/kernel/conformance/conformance_request.js
vendored
Normal file
@ -0,0 +1,91 @@
|
||||
/**
|
||||
* @fileoverview Handwritten code of ConformanceRequest.
|
||||
*/
|
||||
goog.module('proto.conformance.ConformanceRequest');
|
||||
|
||||
const Kernel = goog.require('protobuf.runtime.Kernel');
|
||||
const WireFormat = goog.require('proto.conformance.WireFormat');
|
||||
|
||||
/**
|
||||
* Handwritten code of conformance.ConformanceRequest.
|
||||
* This is used to send request from the conformance test runner to the testee.
|
||||
* Check //third_party/protobuf/testing/protobuf/conformance/conformance.proto
|
||||
* for more details.
|
||||
* @final
|
||||
*/
|
||||
class ConformanceRequest {
|
||||
/**
|
||||
* @param {!ArrayBuffer} bytes
|
||||
* @private
|
||||
*/
|
||||
constructor(bytes) {
|
||||
/** @private @const {!Kernel} */
|
||||
this.accessor_ = Kernel.fromArrayBuffer(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a request instance with the given bytes data.
|
||||
* @param {!ArrayBuffer} bytes
|
||||
* @return {!ConformanceRequest}
|
||||
*/
|
||||
static deserialize(bytes) {
|
||||
return new ConformanceRequest(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the protobuf_payload.
|
||||
* @return {!ArrayBuffer}
|
||||
*/
|
||||
getProtobufPayload() {
|
||||
return this.accessor_.getBytesWithDefault(1).toArrayBuffer();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the requested_output_format.
|
||||
* @return {!WireFormat}
|
||||
*/
|
||||
getRequestedOutputFormat() {
|
||||
return /** @type {!WireFormat} */ (this.accessor_.getInt32WithDefault(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the message_type.
|
||||
* @return {string}
|
||||
*/
|
||||
getMessageType() {
|
||||
return this.accessor_.getStringWithDefault(4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the oneof case for payload field.
|
||||
* This implementation assumes only one field in a oneof group is set.
|
||||
* @return {!ConformanceRequest.PayloadCase}
|
||||
*/
|
||||
getPayloadCase() {
|
||||
if (this.accessor_.hasFieldNumber(1)) {
|
||||
return /** @type {!ConformanceRequest.PayloadCase} */ (
|
||||
ConformanceRequest.PayloadCase.PROTOBUF_PAYLOAD);
|
||||
} else if (this.accessor_.hasFieldNumber(2)) {
|
||||
return /** @type {!ConformanceRequest.PayloadCase} */ (
|
||||
ConformanceRequest.PayloadCase.JSON_PAYLOAD);
|
||||
} else if (this.accessor_.hasFieldNumber(8)) {
|
||||
return /** @type {!ConformanceRequest.PayloadCase} */ (
|
||||
ConformanceRequest.PayloadCase.TEXT_PAYLOAD);
|
||||
} else {
|
||||
return /** @type {!ConformanceRequest.PayloadCase} */ (
|
||||
ConformanceRequest.PayloadCase.PAYLOAD_NOT_SET);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
ConformanceRequest.PayloadCase = {
|
||||
PAYLOAD_NOT_SET: 0,
|
||||
PROTOBUF_PAYLOAD: 1,
|
||||
JSON_PAYLOAD: 2,
|
||||
TEXT_PAYLOAD: 8,
|
||||
};
|
||||
|
||||
exports = ConformanceRequest;
|
76
deps/protobuf/js/experimental/runtime/kernel/conformance/conformance_response.js
vendored
Normal file
76
deps/protobuf/js/experimental/runtime/kernel/conformance/conformance_response.js
vendored
Normal file
@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @fileoverview Handwritten code of ConformanceResponse.
|
||||
*/
|
||||
goog.module('proto.conformance.ConformanceResponse');
|
||||
|
||||
const ByteString = goog.require('protobuf.ByteString');
|
||||
const Kernel = goog.require('protobuf.runtime.Kernel');
|
||||
|
||||
/**
|
||||
* Handwritten code of conformance.ConformanceResponse.
|
||||
* This is used to send response from the conformance testee to the test runner.
|
||||
* Check //third_party/protobuf/testing/protobuf/conformance/conformance.proto
|
||||
* for more details.
|
||||
* @final
|
||||
*/
|
||||
class ConformanceResponse {
|
||||
/**
|
||||
* @param {!ArrayBuffer} bytes
|
||||
* @private
|
||||
*/
|
||||
constructor(bytes) {
|
||||
/** @private @const {!Kernel} */
|
||||
this.accessor_ = Kernel.fromArrayBuffer(bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create an empty response instance.
|
||||
* @return {!ConformanceResponse}
|
||||
*/
|
||||
static createEmpty() {
|
||||
return new ConformanceResponse(new ArrayBuffer(0));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets parse_error field.
|
||||
* @param {string} value
|
||||
*/
|
||||
setParseError(value) {
|
||||
this.accessor_.setString(1, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets runtime_error field.
|
||||
* @param {string} value
|
||||
*/
|
||||
setRuntimeError(value) {
|
||||
this.accessor_.setString(2, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets protobuf_payload field.
|
||||
* @param {!ArrayBuffer} value
|
||||
*/
|
||||
setProtobufPayload(value) {
|
||||
const bytesString = ByteString.fromArrayBuffer(value);
|
||||
this.accessor_.setBytes(3, bytesString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets skipped field.
|
||||
* @param {string} value
|
||||
*/
|
||||
setSkipped(value) {
|
||||
this.accessor_.setString(5, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes into binary data.
|
||||
* @return {!ArrayBuffer}
|
||||
*/
|
||||
serialize() {
|
||||
return this.accessor_.serialize();
|
||||
}
|
||||
}
|
||||
|
||||
exports = ConformanceResponse;
|
103
deps/protobuf/js/experimental/runtime/kernel/conformance/conformance_testee.js
vendored
Normal file
103
deps/protobuf/js/experimental/runtime/kernel/conformance/conformance_testee.js
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
goog.module('javascript.protobuf.conformance');
|
||||
|
||||
const ConformanceRequest = goog.require('proto.conformance.ConformanceRequest');
|
||||
const ConformanceResponse = goog.require('proto.conformance.ConformanceResponse');
|
||||
const TestAllTypesProto2 = goog.require('proto.conformance.TestAllTypesProto2');
|
||||
const TestAllTypesProto3 = goog.require('proto.conformance.TestAllTypesProto3');
|
||||
const WireFormat = goog.require('proto.conformance.WireFormat');
|
||||
const base64 = goog.require('goog.crypt.base64');
|
||||
|
||||
/**
|
||||
* Creates a `proto.conformance.ConformanceResponse` response according to the
|
||||
* `proto.conformance.ConformanceRequest` request.
|
||||
* @param {!ConformanceRequest} request
|
||||
* @return {!ConformanceResponse} response
|
||||
*/
|
||||
function doTest(request) {
|
||||
const response = ConformanceResponse.createEmpty();
|
||||
|
||||
if(request.getPayloadCase() === ConformanceRequest.PayloadCase.JSON_PAYLOAD) {
|
||||
response.setSkipped('Json is not supported as input format.');
|
||||
return response;
|
||||
}
|
||||
|
||||
if(request.getPayloadCase() === ConformanceRequest.PayloadCase.TEXT_PAYLOAD) {
|
||||
response.setSkipped('Text format is not supported as input format.');
|
||||
return response;
|
||||
}
|
||||
|
||||
if(request.getPayloadCase() === ConformanceRequest.PayloadCase.PAYLOAD_NOT_SET) {
|
||||
response.setRuntimeError('Request didn\'t have payload.');
|
||||
return response;
|
||||
}
|
||||
|
||||
if(request.getPayloadCase() !== ConformanceRequest.PayloadCase.PROTOBUF_PAYLOAD) {
|
||||
throw new Error('Request didn\'t have accepted input format.');
|
||||
}
|
||||
|
||||
if (request.getRequestedOutputFormat() === WireFormat.JSON) {
|
||||
response.setSkipped('Json is not supported as output format.');
|
||||
return response;
|
||||
}
|
||||
|
||||
if (request.getRequestedOutputFormat() === WireFormat.TEXT_FORMAT) {
|
||||
response.setSkipped('Text format is not supported as output format.');
|
||||
return response;
|
||||
}
|
||||
|
||||
if (request.getRequestedOutputFormat() === WireFormat.TEXT_FORMAT) {
|
||||
response.setRuntimeError('Unspecified output format');
|
||||
return response;
|
||||
}
|
||||
|
||||
if (request.getRequestedOutputFormat() !== WireFormat.PROTOBUF) {
|
||||
throw new Error('Request didn\'t have accepted output format.');
|
||||
}
|
||||
|
||||
if (request.getMessageType() === 'conformance.FailureSet') {
|
||||
response.setProtobufPayload(new ArrayBuffer(0));
|
||||
} else if (
|
||||
request.getMessageType() ===
|
||||
'protobuf_test_messages.proto2.TestAllTypesProto2') {
|
||||
try {
|
||||
const testMessage =
|
||||
TestAllTypesProto2.deserialize(request.getProtobufPayload());
|
||||
response.setProtobufPayload(testMessage.serialize());
|
||||
} catch (err) {
|
||||
response.setParseError(err.toString());
|
||||
}
|
||||
} else if (
|
||||
request.getMessageType() ===
|
||||
'protobuf_test_messages.proto3.TestAllTypesProto3') {
|
||||
try {
|
||||
const testMessage =
|
||||
TestAllTypesProto3.deserialize(request.getProtobufPayload());
|
||||
response.setProtobufPayload(testMessage.serialize());
|
||||
} catch (err) {
|
||||
response.setParseError(err.toString());
|
||||
}
|
||||
} else {
|
||||
throw new Error(
|
||||
`Payload message not supported: ${request.getMessageType()}.`);
|
||||
}
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Same as doTest, but both request and response are in base64.
|
||||
* @param {string} base64Request
|
||||
* @return {string} response
|
||||
*/
|
||||
function runConformanceTest(base64Request) {
|
||||
const request =
|
||||
ConformanceRequest.deserialize(
|
||||
base64.decodeStringToUint8Array(base64Request).buffer);
|
||||
const response = doTest(request);
|
||||
return base64.encodeByteArray(new Uint8Array(response.serialize()));
|
||||
}
|
||||
|
||||
// Needed for node test
|
||||
exports.doTest = doTest;
|
||||
// Needed for browser test
|
||||
goog.exportSymbol('runConformanceTest', runConformanceTest);
|
62
deps/protobuf/js/experimental/runtime/kernel/conformance/conformance_testee_runner_node.js
vendored
Normal file
62
deps/protobuf/js/experimental/runtime/kernel/conformance/conformance_testee_runner_node.js
vendored
Normal file
@ -0,0 +1,62 @@
|
||||
const ConformanceRequest = goog.require('proto.conformance.ConformanceRequest');
|
||||
const {doTest} = goog.require('javascript.protobuf.conformance');
|
||||
const fs = require('fs');
|
||||
|
||||
|
||||
/**
|
||||
* Reads a buffer of N bytes.
|
||||
* @param {number} bytes Number of bytes to read.
|
||||
* @return {!Buffer} Buffer which contains data.
|
||||
*/
|
||||
function readBuffer(bytes) {
|
||||
// Linux cannot use process.stdin.fd (which isn't set up as sync)
|
||||
const buf = new Buffer.alloc(bytes);
|
||||
const fd = fs.openSync('/dev/stdin', 'r');
|
||||
fs.readSync(fd, buf, 0, bytes);
|
||||
fs.closeSync(fd);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes all data in buffer.
|
||||
* @param {!Buffer} buffer Buffer which contains data.
|
||||
*/
|
||||
function writeBuffer(buffer) {
|
||||
// Under linux, process.stdout.fd is async. Needs to open stdout in a synced
|
||||
// way for sync write.
|
||||
const fd = fs.openSync('/dev/stdout', 'w');
|
||||
fs.writeSync(fd, buffer, 0, buffer.length);
|
||||
fs.closeSync(fd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the test ran successfully, false on legitimate EOF.
|
||||
* @return {boolean} Whether to continue test.
|
||||
*/
|
||||
function runConformanceTest() {
|
||||
const requestLengthBuf = readBuffer(4);
|
||||
const requestLength = requestLengthBuf.readInt32LE(0);
|
||||
if (!requestLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const serializedRequest = readBuffer(requestLength);
|
||||
const array = new Uint8Array(serializedRequest);
|
||||
const request = ConformanceRequest.deserialize(array.buffer);
|
||||
const response = doTest(request);
|
||||
|
||||
const serializedResponse = response.serialize();
|
||||
|
||||
const responseLengthBuf = new Buffer.alloc(4);
|
||||
responseLengthBuf.writeInt32LE(serializedResponse.byteLength, 0);
|
||||
writeBuffer(responseLengthBuf);
|
||||
writeBuffer(new Buffer.from(serializedResponse));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (!runConformanceTest()) {
|
||||
break;
|
||||
}
|
||||
}
|
309
deps/protobuf/js/experimental/runtime/kernel/conformance/test_all_types_proto2.js
vendored
Normal file
309
deps/protobuf/js/experimental/runtime/kernel/conformance/test_all_types_proto2.js
vendored
Normal file
@ -0,0 +1,309 @@
|
||||
/**
|
||||
* @fileoverview Handwritten code of TestAllTypesProto2.
|
||||
*/
|
||||
goog.module('proto.conformance.TestAllTypesProto2');
|
||||
|
||||
const InternalMessage = goog.require('protobuf.binary.InternalMessage');
|
||||
const Kernel = goog.require('protobuf.runtime.Kernel');
|
||||
|
||||
/**
|
||||
* Handwritten code of conformance.TestAllTypesProto2.
|
||||
* Check google/protobuf/test_messages_proto3.proto for more details.
|
||||
* @implements {InternalMessage}
|
||||
* @final
|
||||
*/
|
||||
class TestAllTypesProto2 {
|
||||
/**
|
||||
* @param {!Kernel=} accessor
|
||||
* @private
|
||||
*/
|
||||
constructor(accessor = Kernel.createEmpty()) {
|
||||
/** @private @const {!Kernel} */
|
||||
this.accessor_ = accessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @package
|
||||
* @return {!Kernel}
|
||||
*/
|
||||
internalGetKernel() {
|
||||
return this.accessor_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a request instance with the given bytes data.
|
||||
* If we directly use the accessor created by the binary decoding, the
|
||||
* Kernel instance will only copy the same data over for encoding. By
|
||||
* explicitly fetching data from the previous accessor and setting all fields
|
||||
* into a new accessor, we will actually test encoding/decoding for the binary
|
||||
* format.
|
||||
* @param {!ArrayBuffer} bytes
|
||||
* @return {!TestAllTypesProto2}
|
||||
*/
|
||||
static deserialize(bytes) {
|
||||
const msg = new TestAllTypesProto2();
|
||||
const requestAccessor = Kernel.fromArrayBuffer(bytes);
|
||||
|
||||
if (requestAccessor.hasFieldNumber(1)) {
|
||||
const value = requestAccessor.getInt32WithDefault(1);
|
||||
msg.accessor_.setInt32(1, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(2)) {
|
||||
const value = requestAccessor.getInt64WithDefault(2);
|
||||
msg.accessor_.setInt64(2, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(3)) {
|
||||
const value = requestAccessor.getUint32WithDefault(3);
|
||||
msg.accessor_.setUint32(3, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(4)) {
|
||||
const value = requestAccessor.getUint64WithDefault(4);
|
||||
msg.accessor_.setUint64(4, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(5)) {
|
||||
const value = requestAccessor.getSint32WithDefault(5);
|
||||
msg.accessor_.setSint32(5, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(6)) {
|
||||
const value = requestAccessor.getSint64WithDefault(6);
|
||||
msg.accessor_.setSint64(6, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(7)) {
|
||||
const value = requestAccessor.getFixed32WithDefault(7);
|
||||
msg.accessor_.setFixed32(7, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(8)) {
|
||||
const value = requestAccessor.getFixed64WithDefault(8);
|
||||
msg.accessor_.setFixed64(8, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(9)) {
|
||||
const value = requestAccessor.getSfixed32WithDefault(9);
|
||||
msg.accessor_.setSfixed32(9, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(10)) {
|
||||
const value = requestAccessor.getSfixed64WithDefault(10);
|
||||
msg.accessor_.setSfixed64(10, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(11)) {
|
||||
const value = requestAccessor.getFloatWithDefault(11);
|
||||
msg.accessor_.setFloat(11, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(12)) {
|
||||
const value = requestAccessor.getDoubleWithDefault(12);
|
||||
msg.accessor_.setDouble(12, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(13)) {
|
||||
const value = requestAccessor.getBoolWithDefault(13);
|
||||
msg.accessor_.setBool(13, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(14)) {
|
||||
const value = requestAccessor.getStringWithDefault(14);
|
||||
msg.accessor_.setString(14, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(15)) {
|
||||
const value = requestAccessor.getBytesWithDefault(15);
|
||||
msg.accessor_.setBytes(15, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(18)) {
|
||||
const value = requestAccessor.getMessage(
|
||||
18, (accessor) => new TestAllTypesProto2(accessor));
|
||||
msg.accessor_.setMessage(18, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(21)) {
|
||||
// Unknown enum is not checked here, because even if an enum is unknown,
|
||||
// it should be kept during encoding. For the purpose of wire format test,
|
||||
// we can simplify the implementation by treating it as an int32 field,
|
||||
// which has the same semantic except for the unknown value checking.
|
||||
const value = requestAccessor.getInt32WithDefault(21);
|
||||
msg.accessor_.setInt32(21, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(31)) {
|
||||
const value = requestAccessor.getRepeatedInt32Iterable(31);
|
||||
msg.accessor_.setUnpackedInt32Iterable(31, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(32)) {
|
||||
const value = requestAccessor.getRepeatedInt64Iterable(32);
|
||||
msg.accessor_.setUnpackedInt64Iterable(32, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(33)) {
|
||||
const value = requestAccessor.getRepeatedUint32Iterable(33);
|
||||
msg.accessor_.setUnpackedUint32Iterable(33, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(34)) {
|
||||
const value = requestAccessor.getRepeatedUint64Iterable(34);
|
||||
msg.accessor_.setUnpackedUint64Iterable(34, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(35)) {
|
||||
const value = requestAccessor.getRepeatedSint32Iterable(35);
|
||||
msg.accessor_.setUnpackedSint32Iterable(35, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(36)) {
|
||||
const value = requestAccessor.getRepeatedSint64Iterable(36);
|
||||
msg.accessor_.setUnpackedSint64Iterable(36, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(37)) {
|
||||
const value = requestAccessor.getRepeatedFixed32Iterable(37);
|
||||
msg.accessor_.setUnpackedFixed32Iterable(37, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(38)) {
|
||||
const value = requestAccessor.getRepeatedFixed64Iterable(38);
|
||||
msg.accessor_.setUnpackedFixed64Iterable(38, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(39)) {
|
||||
const value = requestAccessor.getRepeatedSfixed32Iterable(39);
|
||||
msg.accessor_.setUnpackedSfixed32Iterable(39, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(40)) {
|
||||
const value = requestAccessor.getRepeatedSfixed64Iterable(40);
|
||||
msg.accessor_.setUnpackedSfixed64Iterable(40, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(41)) {
|
||||
const value = requestAccessor.getRepeatedFloatIterable(41);
|
||||
msg.accessor_.setUnpackedFloatIterable(41, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(42)) {
|
||||
const value = requestAccessor.getRepeatedDoubleIterable(42);
|
||||
msg.accessor_.setUnpackedDoubleIterable(42, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(43)) {
|
||||
const value = requestAccessor.getRepeatedBoolIterable(43);
|
||||
msg.accessor_.setUnpackedBoolIterable(43, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(44)) {
|
||||
const value = requestAccessor.getRepeatedStringIterable(44);
|
||||
msg.accessor_.setRepeatedStringIterable(44, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(45)) {
|
||||
const value = requestAccessor.getRepeatedBytesIterable(45);
|
||||
msg.accessor_.setRepeatedBytesIterable(45, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(48)) {
|
||||
const value = requestAccessor.getRepeatedMessageIterable(
|
||||
48, (accessor) => new TestAllTypesProto2(accessor));
|
||||
msg.accessor_.setRepeatedMessageIterable(48, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(51)) {
|
||||
// Unknown enum is not checked here, because even if an enum is unknown,
|
||||
// it should be kept during encoding. For the purpose of wire format test,
|
||||
// we can simplify the implementation by treating it as an int32 field,
|
||||
// which has the same semantic except for the unknown value checking.
|
||||
const value = requestAccessor.getRepeatedInt32Iterable(51);
|
||||
msg.accessor_.setUnpackedInt32Iterable(51, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(75)) {
|
||||
const value = requestAccessor.getRepeatedInt32Iterable(75);
|
||||
msg.accessor_.setPackedInt32Iterable(75, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(76)) {
|
||||
const value = requestAccessor.getRepeatedInt64Iterable(76);
|
||||
msg.accessor_.setPackedInt64Iterable(76, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(77)) {
|
||||
const value = requestAccessor.getRepeatedUint32Iterable(77);
|
||||
msg.accessor_.setPackedUint32Iterable(77, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(78)) {
|
||||
const value = requestAccessor.getRepeatedUint64Iterable(78);
|
||||
msg.accessor_.setPackedUint64Iterable(78, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(79)) {
|
||||
const value = requestAccessor.getRepeatedSint32Iterable(79);
|
||||
msg.accessor_.setPackedSint32Iterable(79, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(80)) {
|
||||
const value = requestAccessor.getRepeatedSint64Iterable(80);
|
||||
msg.accessor_.setPackedSint64Iterable(80, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(81)) {
|
||||
const value = requestAccessor.getRepeatedFixed32Iterable(81);
|
||||
msg.accessor_.setPackedFixed32Iterable(81, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(82)) {
|
||||
const value = requestAccessor.getRepeatedFixed64Iterable(82);
|
||||
msg.accessor_.setPackedFixed64Iterable(82, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(83)) {
|
||||
const value = requestAccessor.getRepeatedSfixed32Iterable(83);
|
||||
msg.accessor_.setPackedSfixed32Iterable(83, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(84)) {
|
||||
const value = requestAccessor.getRepeatedSfixed64Iterable(84);
|
||||
msg.accessor_.setPackedSfixed64Iterable(84, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(85)) {
|
||||
const value = requestAccessor.getRepeatedFloatIterable(85);
|
||||
msg.accessor_.setPackedFloatIterable(85, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(86)) {
|
||||
const value = requestAccessor.getRepeatedDoubleIterable(86);
|
||||
msg.accessor_.setPackedDoubleIterable(86, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(87)) {
|
||||
const value = requestAccessor.getRepeatedBoolIterable(87);
|
||||
msg.accessor_.setPackedBoolIterable(87, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(88)) {
|
||||
const value = requestAccessor.getRepeatedInt32Iterable(88);
|
||||
msg.accessor_.setPackedInt32Iterable(88, value);
|
||||
}
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes into binary data.
|
||||
* @return {!ArrayBuffer}
|
||||
*/
|
||||
serialize() {
|
||||
return this.accessor_.serialize();
|
||||
}
|
||||
}
|
||||
|
||||
exports = TestAllTypesProto2;
|
310
deps/protobuf/js/experimental/runtime/kernel/conformance/test_all_types_proto3.js
vendored
Normal file
310
deps/protobuf/js/experimental/runtime/kernel/conformance/test_all_types_proto3.js
vendored
Normal file
@ -0,0 +1,310 @@
|
||||
/**
|
||||
* @fileoverview Handwritten code of TestAllTypesProto3.
|
||||
*/
|
||||
goog.module('proto.conformance.TestAllTypesProto3');
|
||||
|
||||
const InternalMessage = goog.require('protobuf.binary.InternalMessage');
|
||||
const Kernel = goog.require('protobuf.runtime.Kernel');
|
||||
|
||||
/**
|
||||
* Handwritten code of conformance.TestAllTypesProto3.
|
||||
* Check google/protobuf/test_messages_proto3.proto for more details.
|
||||
* @implements {InternalMessage}
|
||||
* @final
|
||||
*/
|
||||
class TestAllTypesProto3 {
|
||||
/**
|
||||
* @param {!Kernel=} accessor
|
||||
* @private
|
||||
*/
|
||||
constructor(accessor = Kernel.createEmpty()) {
|
||||
/** @private @const {!Kernel} */
|
||||
this.accessor_ = accessor;
|
||||
}
|
||||
|
||||
/**
|
||||
* @override
|
||||
* @package
|
||||
* @return {!Kernel}
|
||||
*/
|
||||
internalGetKernel() {
|
||||
return this.accessor_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a request instance with the given bytes data.
|
||||
* If we directly use the accessor created by the binary decoding, the
|
||||
* Kernel instance will only copy the same data over for encoding. By
|
||||
* explicitly fetching data from the previous accessor and setting all fields
|
||||
* into a new accessor, we will actually test encoding/decoding for the binary
|
||||
* format.
|
||||
* @param {!ArrayBuffer} bytes
|
||||
* @return {!TestAllTypesProto3}
|
||||
*/
|
||||
static deserialize(bytes) {
|
||||
const msg = new TestAllTypesProto3();
|
||||
const requestAccessor = Kernel.fromArrayBuffer(bytes);
|
||||
|
||||
if (requestAccessor.hasFieldNumber(1)) {
|
||||
const value = requestAccessor.getInt32WithDefault(1);
|
||||
msg.accessor_.setInt32(1, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(2)) {
|
||||
const value = requestAccessor.getInt64WithDefault(2);
|
||||
msg.accessor_.setInt64(2, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(3)) {
|
||||
const value = requestAccessor.getUint32WithDefault(3);
|
||||
msg.accessor_.setUint32(3, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(4)) {
|
||||
const value = requestAccessor.getUint64WithDefault(4);
|
||||
msg.accessor_.setUint64(4, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(5)) {
|
||||
const value = requestAccessor.getSint32WithDefault(5);
|
||||
msg.accessor_.setSint32(5, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(6)) {
|
||||
const value = requestAccessor.getSint64WithDefault(6);
|
||||
msg.accessor_.setSint64(6, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(7)) {
|
||||
const value = requestAccessor.getFixed32WithDefault(7);
|
||||
msg.accessor_.setFixed32(7, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(8)) {
|
||||
const value = requestAccessor.getFixed64WithDefault(8);
|
||||
msg.accessor_.setFixed64(8, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(9)) {
|
||||
const value = requestAccessor.getSfixed32WithDefault(9);
|
||||
msg.accessor_.setSfixed32(9, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(10)) {
|
||||
const value = requestAccessor.getSfixed64WithDefault(10);
|
||||
msg.accessor_.setSfixed64(10, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(11)) {
|
||||
const value = requestAccessor.getFloatWithDefault(11);
|
||||
msg.accessor_.setFloat(11, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(12)) {
|
||||
const value = requestAccessor.getDoubleWithDefault(12);
|
||||
msg.accessor_.setDouble(12, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(13)) {
|
||||
const value = requestAccessor.getBoolWithDefault(13);
|
||||
msg.accessor_.setBool(13, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(14)) {
|
||||
const value = requestAccessor.getStringWithDefault(14);
|
||||
msg.accessor_.setString(14, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(15)) {
|
||||
const value = requestAccessor.getBytesWithDefault(15);
|
||||
msg.accessor_.setBytes(15, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(18)) {
|
||||
const value = requestAccessor.getMessage(
|
||||
18, (accessor) => new TestAllTypesProto3(accessor));
|
||||
msg.accessor_.setMessage(18, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(21)) {
|
||||
// Unknown enum is not checked here, because even if an enum is unknown,
|
||||
// it should be kept during encoding. For the purpose of wire format test,
|
||||
// we can simplify the implementation by treating it as an int32 field,
|
||||
// which has the same semantic except for the unknown value checking.
|
||||
const value = requestAccessor.getInt32WithDefault(21);
|
||||
msg.accessor_.setInt32(21, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(31)) {
|
||||
const value = requestAccessor.getRepeatedInt32Iterable(31);
|
||||
msg.accessor_.setPackedInt32Iterable(31, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(32)) {
|
||||
const value = requestAccessor.getRepeatedInt64Iterable(32);
|
||||
msg.accessor_.setPackedInt64Iterable(32, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(33)) {
|
||||
const value = requestAccessor.getRepeatedUint32Iterable(33);
|
||||
msg.accessor_.setPackedUint32Iterable(33, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(34)) {
|
||||
const value = requestAccessor.getRepeatedUint64Iterable(34);
|
||||
msg.accessor_.setPackedUint64Iterable(34, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(35)) {
|
||||
const value = requestAccessor.getRepeatedSint32Iterable(35);
|
||||
msg.accessor_.setPackedSint32Iterable(35, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(36)) {
|
||||
const value = requestAccessor.getRepeatedSint64Iterable(36);
|
||||
msg.accessor_.setPackedSint64Iterable(36, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(37)) {
|
||||
const value = requestAccessor.getRepeatedFixed32Iterable(37);
|
||||
msg.accessor_.setPackedFixed32Iterable(37, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(38)) {
|
||||
const value = requestAccessor.getRepeatedFixed64Iterable(38);
|
||||
msg.accessor_.setPackedFixed64Iterable(38, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(39)) {
|
||||
const value = requestAccessor.getRepeatedSfixed32Iterable(39);
|
||||
msg.accessor_.setPackedSfixed32Iterable(39, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(40)) {
|
||||
const value = requestAccessor.getRepeatedSfixed64Iterable(40);
|
||||
msg.accessor_.setPackedSfixed64Iterable(40, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(41)) {
|
||||
const value = requestAccessor.getRepeatedFloatIterable(41);
|
||||
msg.accessor_.setPackedFloatIterable(41, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(42)) {
|
||||
const value = requestAccessor.getRepeatedDoubleIterable(42);
|
||||
msg.accessor_.setPackedDoubleIterable(42, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(43)) {
|
||||
const value = requestAccessor.getRepeatedBoolIterable(43);
|
||||
msg.accessor_.setPackedBoolIterable(43, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(44)) {
|
||||
const value = requestAccessor.getRepeatedStringIterable(44);
|
||||
msg.accessor_.setRepeatedStringIterable(44, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(45)) {
|
||||
const value = requestAccessor.getRepeatedBytesIterable(45);
|
||||
msg.accessor_.setRepeatedBytesIterable(45, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(48)) {
|
||||
const value = requestAccessor.getRepeatedMessageIterable(
|
||||
48, (accessor) => new TestAllTypesProto3(accessor));
|
||||
msg.accessor_.setRepeatedMessageIterable(48, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(51)) {
|
||||
// Unknown enum is not checked here, because even if an enum is unknown,
|
||||
// it should be kept during encoding. For the purpose of wire format test,
|
||||
// we can simplify the implementation by treating it as an int32 field,
|
||||
// which has the same semantic except for the unknown value checking.
|
||||
const value = requestAccessor.getRepeatedInt32Iterable(51);
|
||||
msg.accessor_.setPackedInt32Iterable(51, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(89)) {
|
||||
const value = requestAccessor.getRepeatedInt32Iterable(89);
|
||||
msg.accessor_.setUnpackedInt32Iterable(89, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(90)) {
|
||||
const value = requestAccessor.getRepeatedInt64Iterable(90);
|
||||
msg.accessor_.setUnpackedInt64Iterable(90, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(91)) {
|
||||
const value = requestAccessor.getRepeatedUint32Iterable(91);
|
||||
msg.accessor_.setUnpackedUint32Iterable(91, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(92)) {
|
||||
const value = requestAccessor.getRepeatedUint64Iterable(92);
|
||||
msg.accessor_.setUnpackedUint64Iterable(92, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(93)) {
|
||||
const value = requestAccessor.getRepeatedSint32Iterable(93);
|
||||
msg.accessor_.setUnpackedSint32Iterable(93, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(94)) {
|
||||
const value = requestAccessor.getRepeatedSint64Iterable(94);
|
||||
msg.accessor_.setUnpackedSint64Iterable(94, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(95)) {
|
||||
const value = requestAccessor.getRepeatedFixed32Iterable(95);
|
||||
msg.accessor_.setUnpackedFixed32Iterable(95, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(96)) {
|
||||
const value = requestAccessor.getRepeatedFixed64Iterable(96);
|
||||
msg.accessor_.setUnpackedFixed64Iterable(96, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(97)) {
|
||||
const value = requestAccessor.getRepeatedSfixed32Iterable(97);
|
||||
msg.accessor_.setUnpackedSfixed32Iterable(97, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(98)) {
|
||||
const value = requestAccessor.getRepeatedSfixed64Iterable(98);
|
||||
msg.accessor_.setUnpackedSfixed64Iterable(98, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(99)) {
|
||||
const value = requestAccessor.getRepeatedFloatIterable(99);
|
||||
msg.accessor_.setUnpackedFloatIterable(99, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(100)) {
|
||||
const value = requestAccessor.getRepeatedDoubleIterable(100);
|
||||
msg.accessor_.setUnpackedDoubleIterable(100, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(101)) {
|
||||
const value = requestAccessor.getRepeatedBoolIterable(101);
|
||||
msg.accessor_.setUnpackedBoolIterable(101, value);
|
||||
}
|
||||
|
||||
if (requestAccessor.hasFieldNumber(102)) {
|
||||
const value = requestAccessor.getRepeatedInt32Iterable(102);
|
||||
msg.accessor_.setUnpackedInt32Iterable(102, value);
|
||||
}
|
||||
|
||||
return msg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes into binary data.
|
||||
* @return {!ArrayBuffer}
|
||||
*/
|
||||
serialize() {
|
||||
return this.accessor_.serialize();
|
||||
}
|
||||
}
|
||||
|
||||
exports = TestAllTypesProto3;
|
16
deps/protobuf/js/experimental/runtime/kernel/conformance/wire_format.js
vendored
Normal file
16
deps/protobuf/js/experimental/runtime/kernel/conformance/wire_format.js
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* @fileoverview Handwritten code of WireFormat.
|
||||
*/
|
||||
goog.module('proto.conformance.WireFormat');
|
||||
|
||||
/**
|
||||
* @enum {number}
|
||||
*/
|
||||
const WireFormat = {
|
||||
UNSPECIFIED: 0,
|
||||
PROTOBUF: 1,
|
||||
JSON: 2,
|
||||
TEXT_FORMAT: 4,
|
||||
};
|
||||
|
||||
exports = WireFormat;
|
89
deps/protobuf/js/experimental/runtime/kernel/double_test_pairs.js
vendored
Normal file
89
deps/protobuf/js/experimental/runtime/kernel/double_test_pairs.js
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
/**
|
||||
* @fileoverview Test data for double encoding and decoding.
|
||||
*/
|
||||
goog.module('protobuf.binary.doubleTestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of double values and their bit representation.
|
||||
* This is used to test encoding and decoding from the protobuf wire format.
|
||||
* @return {!Array<{name: string, doubleValue:number, bufferDecoder:
|
||||
* !BufferDecoder}>}
|
||||
*/
|
||||
function getDoublePairs() {
|
||||
const doublePairs = [
|
||||
{
|
||||
name: 'zero',
|
||||
doubleValue: 0,
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
|
||||
},
|
||||
{
|
||||
name: 'minus zero',
|
||||
doubleValue: -0,
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80)
|
||||
},
|
||||
{
|
||||
name: 'one',
|
||||
doubleValue: 1,
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F)
|
||||
},
|
||||
{
|
||||
name: 'minus one',
|
||||
doubleValue: -1,
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xBF)
|
||||
},
|
||||
|
||||
{
|
||||
name: 'PI',
|
||||
doubleValue: Math.PI,
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0x18, 0x2D, 0x44, 0x54, 0xFB, 0x21, 0x09, 0x40)
|
||||
|
||||
},
|
||||
{
|
||||
name: 'max value',
|
||||
doubleValue: Number.MAX_VALUE,
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xEF, 0x7F)
|
||||
},
|
||||
{
|
||||
name: 'min value',
|
||||
doubleValue: Number.MIN_VALUE,
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
|
||||
},
|
||||
{
|
||||
name: 'Infinity',
|
||||
doubleValue: Infinity,
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x7F)
|
||||
},
|
||||
{
|
||||
name: 'minus Infinity',
|
||||
doubleValue: -Infinity,
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0xFF)
|
||||
},
|
||||
{
|
||||
name: 'Number.MAX_SAFE_INTEGER',
|
||||
doubleValue: Number.MAX_SAFE_INTEGER,
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0x43)
|
||||
},
|
||||
{
|
||||
name: 'Number.MIN_SAFE_INTEGER',
|
||||
doubleValue: Number.MIN_SAFE_INTEGER,
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x3F, 0xC3)
|
||||
},
|
||||
];
|
||||
return [...doublePairs];
|
||||
}
|
||||
|
||||
exports = {getDoublePairs};
|
196
deps/protobuf/js/experimental/runtime/kernel/field.js
vendored
Normal file
196
deps/protobuf/js/experimental/runtime/kernel/field.js
vendored
Normal file
@ -0,0 +1,196 @@
|
||||
/**
|
||||
* @fileoverview Contains classes that hold data for a protobuf field.
|
||||
*/
|
||||
|
||||
goog.module('protobuf.binary.field');
|
||||
|
||||
const WireType = goog.requireType('protobuf.binary.WireType');
|
||||
const Writer = goog.requireType('protobuf.binary.Writer');
|
||||
const {checkDefAndNotNull, checkState} = goog.require('protobuf.internal.checks');
|
||||
|
||||
/**
|
||||
* Number of bits taken to represent a wire type.
|
||||
* @const {number}
|
||||
*/
|
||||
const WIRE_TYPE_LENGTH_BITS = 3;
|
||||
|
||||
/** @const {number} */
|
||||
const WIRE_TYPE_EXTRACTOR = (1 << WIRE_TYPE_LENGTH_BITS) - 1;
|
||||
|
||||
/**
|
||||
* An IndexEntry consists of the wire type and the position of a field in the
|
||||
* binary data. The wire type and the position are encoded into a single number
|
||||
* to save memory, which can be decoded using Field.getWireType() and
|
||||
* Field.getStartIndex() methods.
|
||||
* @typedef {number}
|
||||
*/
|
||||
let IndexEntry;
|
||||
|
||||
/**
|
||||
* An entry containing the index into the binary data and/or the corresponding
|
||||
* cached JS object(s) for a field.
|
||||
* @template T
|
||||
* @final
|
||||
* @package
|
||||
*/
|
||||
class Field {
|
||||
/**
|
||||
* Creates a field and inserts the wireType and position of the first
|
||||
* occurrence of a field.
|
||||
* @param {!WireType} wireType
|
||||
* @param {number} startIndex
|
||||
* @return {!Field}
|
||||
*/
|
||||
static fromFirstIndexEntry(wireType, startIndex) {
|
||||
return new Field([Field.encodeIndexEntry(wireType, startIndex)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {T} decodedValue The cached JS object decoded from the binary data.
|
||||
* @param {function(!Writer, number, T):void|undefined} encoder Write function
|
||||
* to encode the cache into binary bytes.
|
||||
* @return {!Field}
|
||||
* @template T
|
||||
*/
|
||||
static fromDecodedValue(decodedValue, encoder) {
|
||||
return new Field(null, decodedValue, encoder);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!WireType} wireType
|
||||
* @param {number} startIndex
|
||||
* @return {!IndexEntry}
|
||||
*/
|
||||
static encodeIndexEntry(wireType, startIndex) {
|
||||
return startIndex << WIRE_TYPE_LENGTH_BITS | wireType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!IndexEntry} indexEntry
|
||||
* @return {!WireType}
|
||||
*/
|
||||
static getWireType(indexEntry) {
|
||||
return /** @type {!WireType} */ (indexEntry & WIRE_TYPE_EXTRACTOR);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!IndexEntry} indexEntry
|
||||
* @return {number}
|
||||
*/
|
||||
static getStartIndex(indexEntry) {
|
||||
return indexEntry >> WIRE_TYPE_LENGTH_BITS;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?Array<!IndexEntry>} indexArray
|
||||
* @param {T=} decodedValue
|
||||
* @param {function(!Writer, number, T):void=} encoder
|
||||
* @private
|
||||
*/
|
||||
constructor(indexArray, decodedValue = undefined, encoder = undefined) {
|
||||
checkState(
|
||||
!!indexArray || decodedValue !== undefined,
|
||||
'At least one of indexArray and decodedValue must be set');
|
||||
|
||||
/** @private {?Array<!IndexEntry>} */
|
||||
this.indexArray_ = indexArray;
|
||||
/** @private {T|undefined} */
|
||||
this.decodedValue_ = decodedValue;
|
||||
// TODO: Consider storing an enum to represent encoder
|
||||
/** @private {function(!Writer, number, T)|undefined} */
|
||||
this.encoder_ = encoder;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a new IndexEntry.
|
||||
* @param {!WireType} wireType
|
||||
* @param {number} startIndex
|
||||
*/
|
||||
addIndexEntry(wireType, startIndex) {
|
||||
checkDefAndNotNull(this.indexArray_)
|
||||
.push(Field.encodeIndexEntry(wireType, startIndex));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the array of IndexEntry.
|
||||
* @return {?Array<!IndexEntry>}
|
||||
*/
|
||||
getIndexArray() {
|
||||
return this.indexArray_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Caches the decoded value and sets the write function to encode cache into
|
||||
* binary bytes.
|
||||
* @param {T} decodedValue
|
||||
* @param {function(!Writer, number, T):void|undefined} encoder
|
||||
*/
|
||||
setCache(decodedValue, encoder) {
|
||||
this.decodedValue_ = decodedValue;
|
||||
this.encoder_ = encoder;
|
||||
this.maybeRemoveIndexArray_();
|
||||
}
|
||||
|
||||
/**
|
||||
* If the decoded value has been set.
|
||||
* @return {boolean}
|
||||
*/
|
||||
hasDecodedValue() {
|
||||
return this.decodedValue_ !== undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the cached decoded value. The value needs to be set when this
|
||||
* method is called.
|
||||
* @return {T}
|
||||
*/
|
||||
getDecodedValue() {
|
||||
// Makes sure that the decoded value in the cache has already been set. This
|
||||
// prevents callers from doing `if (field.getDecodedValue()) {...}` to check
|
||||
// if a value exist in the cache, because the check might return false even
|
||||
// if the cache has a valid value set (e.g. 0 or empty string).
|
||||
checkState(this.decodedValue_ !== undefined);
|
||||
return this.decodedValue_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the write function to encode cache into binary bytes.
|
||||
* @return {function(!Writer, number, T)|undefined}
|
||||
*/
|
||||
getEncoder() {
|
||||
return this.encoder_;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a copy of the field, containing the original index entries and a
|
||||
* shallow copy of the cache.
|
||||
* @return {!Field}
|
||||
*/
|
||||
shallowCopy() {
|
||||
// Repeated fields are arrays in the cache.
|
||||
// We have to copy the array to make sure that modifications to a repeated
|
||||
// field (e.g. add) are not seen on a cloned accessor.
|
||||
const copiedCache = this.hasDecodedValue() ?
|
||||
(Array.isArray(this.getDecodedValue()) ? [...this.getDecodedValue()] :
|
||||
this.getDecodedValue()) :
|
||||
undefined;
|
||||
return new Field(this.getIndexArray(), copiedCache, this.getEncoder());
|
||||
}
|
||||
|
||||
/**
|
||||
* @private
|
||||
*/
|
||||
maybeRemoveIndexArray_() {
|
||||
checkState(
|
||||
this.encoder_ === undefined || this.decodedValue_ !== undefined,
|
||||
'Encoder exists but decoded value doesn\'t');
|
||||
if (this.encoder_ !== undefined) {
|
||||
this.indexArray_ = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
exports = {
|
||||
IndexEntry,
|
||||
Field,
|
||||
};
|
36
deps/protobuf/js/experimental/runtime/kernel/fixed32_test_pairs.js
vendored
Normal file
36
deps/protobuf/js/experimental/runtime/kernel/fixed32_test_pairs.js
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* @fileoverview Test data for float encoding and decoding.
|
||||
*/
|
||||
goog.module('protobuf.binary.fixed32TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of float values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, intValue: number, bufferDecoder:
|
||||
* !BufferDecoder}>}
|
||||
*/
|
||||
function getFixed32Pairs() {
|
||||
const fixed32Pairs = [
|
||||
{
|
||||
name: 'zero',
|
||||
intValue: 0,
|
||||
bufferDecoder: createBufferDecoder(0x00, 0x00, 0x00, 0x00),
|
||||
},
|
||||
{
|
||||
name: 'one ',
|
||||
intValue: 1,
|
||||
bufferDecoder: createBufferDecoder(0x01, 0x00, 0x00, 0x00)
|
||||
},
|
||||
{
|
||||
name: 'max int 2^32 -1',
|
||||
intValue: Math.pow(2, 32) - 1,
|
||||
bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF)
|
||||
},
|
||||
];
|
||||
return [...fixed32Pairs];
|
||||
}
|
||||
|
||||
exports = {getFixed32Pairs};
|
78
deps/protobuf/js/experimental/runtime/kernel/float_test_pairs.js
vendored
Normal file
78
deps/protobuf/js/experimental/runtime/kernel/float_test_pairs.js
vendored
Normal file
@ -0,0 +1,78 @@
|
||||
/**
|
||||
* @fileoverview Test data for float encoding and decoding.
|
||||
*/
|
||||
goog.module('protobuf.binary.floatTestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of float values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, floatValue:number, bufferDecoder:
|
||||
* !BufferDecoder}>}
|
||||
*/
|
||||
function getFloatPairs() {
|
||||
const floatPairs = [
|
||||
{
|
||||
name: 'zero',
|
||||
floatValue: 0,
|
||||
bufferDecoder: createBufferDecoder(0x00, 0x00, 0x00, 0x00),
|
||||
},
|
||||
{
|
||||
name: 'minus zero',
|
||||
floatValue: -0,
|
||||
bufferDecoder: createBufferDecoder(0x00, 0x00, 0x00, 0x80)
|
||||
},
|
||||
{
|
||||
name: 'one ',
|
||||
floatValue: 1,
|
||||
bufferDecoder: createBufferDecoder(0x00, 0x00, 0x80, 0x3F)
|
||||
},
|
||||
{
|
||||
name: 'minus one',
|
||||
floatValue: -1,
|
||||
bufferDecoder: createBufferDecoder(0x00, 0x00, 0x80, 0xBF)
|
||||
},
|
||||
{
|
||||
name: 'two',
|
||||
floatValue: 2,
|
||||
bufferDecoder: createBufferDecoder(0x00, 0x00, 0x00, 0x40)
|
||||
},
|
||||
{
|
||||
name: 'max float32',
|
||||
floatValue: Math.pow(2, 127) * (2 - 1 / Math.pow(2, 23)),
|
||||
bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0x7F, 0x7F)
|
||||
},
|
||||
|
||||
{
|
||||
name: 'min float32',
|
||||
floatValue: 1 / Math.pow(2, 127 - 1),
|
||||
bufferDecoder: createBufferDecoder(0x00, 0x00, 0x80, 0x00)
|
||||
},
|
||||
|
||||
{
|
||||
name: 'Infinity',
|
||||
floatValue: Infinity,
|
||||
bufferDecoder: createBufferDecoder(0x00, 0x00, 0x80, 0x7F)
|
||||
},
|
||||
{
|
||||
name: 'minus Infinity',
|
||||
floatValue: -Infinity,
|
||||
bufferDecoder: createBufferDecoder(0x00, 0x00, 0x80, 0xFF)
|
||||
},
|
||||
{
|
||||
name: '1.5',
|
||||
floatValue: 1.5,
|
||||
bufferDecoder: createBufferDecoder(0x00, 0x00, 0xC0, 0x3F)
|
||||
},
|
||||
{
|
||||
name: '1.6',
|
||||
floatValue: 1.6,
|
||||
bufferDecoder: createBufferDecoder(0xCD, 0xCC, 0xCC, 0x3F)
|
||||
},
|
||||
];
|
||||
return [...floatPairs];
|
||||
}
|
||||
|
||||
exports = {getFloatPairs};
|
55
deps/protobuf/js/experimental/runtime/kernel/indexer.js
vendored
Normal file
55
deps/protobuf/js/experimental/runtime/kernel/indexer.js
vendored
Normal file
@ -0,0 +1,55 @@
|
||||
/**
|
||||
* @fileoverview Utilities to index a binary proto by fieldnumbers without
|
||||
* relying on strutural proto information.
|
||||
*/
|
||||
goog.module('protobuf.binary.indexer');
|
||||
|
||||
const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage');
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const WireType = goog.require('protobuf.binary.WireType');
|
||||
const {Field} = goog.require('protobuf.binary.field');
|
||||
const {checkCriticalState} = goog.require('protobuf.internal.checks');
|
||||
const {skipField, tagToFieldNumber, tagToWireType} = goog.require('protobuf.binary.tag');
|
||||
|
||||
/**
|
||||
* Appends a new entry in the index array for the given field number.
|
||||
* @param {!BinaryStorage<!Field>} storage
|
||||
* @param {number} fieldNumber
|
||||
* @param {!WireType} wireType
|
||||
* @param {number} startIndex
|
||||
*/
|
||||
function addIndexEntry(storage, fieldNumber, wireType, startIndex) {
|
||||
const field = storage.get(fieldNumber);
|
||||
if (field !== undefined) {
|
||||
field.addIndexEntry(wireType, startIndex);
|
||||
} else {
|
||||
storage.set(fieldNumber, Field.fromFirstIndexEntry(wireType, startIndex));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an index of field locations in a given binary protobuf.
|
||||
* @param {!BufferDecoder} bufferDecoder
|
||||
* @param {number|undefined} pivot
|
||||
* @return {!BinaryStorage<!Field>}
|
||||
* @package
|
||||
*/
|
||||
function buildIndex(bufferDecoder, pivot) {
|
||||
bufferDecoder.setCursor(bufferDecoder.startIndex());
|
||||
|
||||
const storage = new BinaryStorage(pivot);
|
||||
while (bufferDecoder.hasNext()) {
|
||||
const tag = bufferDecoder.getUnsignedVarint32();
|
||||
const wireType = tagToWireType(tag);
|
||||
const fieldNumber = tagToFieldNumber(tag);
|
||||
checkCriticalState(fieldNumber > 0, `Invalid field number ${fieldNumber}`);
|
||||
addIndexEntry(storage, fieldNumber, wireType, bufferDecoder.cursor());
|
||||
skipField(bufferDecoder, wireType, fieldNumber);
|
||||
}
|
||||
return storage;
|
||||
}
|
||||
|
||||
exports = {
|
||||
buildIndex,
|
||||
tagToWireType,
|
||||
};
|
334
deps/protobuf/js/experimental/runtime/kernel/indexer_test.js
vendored
Normal file
334
deps/protobuf/js/experimental/runtime/kernel/indexer_test.js
vendored
Normal file
@ -0,0 +1,334 @@
|
||||
/**
|
||||
* @fileoverview Tests for indexer.js.
|
||||
*/
|
||||
goog.module('protobuf.binary.IndexerTest');
|
||||
|
||||
goog.setTestOnly();
|
||||
|
||||
// Note to the reader:
|
||||
// Since the index behavior changes with the checking level some of the tests
|
||||
// in this file have to know which checking level is enabled to make correct
|
||||
// assertions.
|
||||
// Test are run in all checking levels.
|
||||
const BinaryStorage = goog.require('protobuf.runtime.BinaryStorage');
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const WireType = goog.require('protobuf.binary.WireType');
|
||||
const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks');
|
||||
const {Field, IndexEntry} = goog.require('protobuf.binary.field');
|
||||
const {buildIndex} = goog.require('protobuf.binary.indexer');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* Returns the number of fields stored.
|
||||
*
|
||||
* @param {!BinaryStorage} storage
|
||||
* @return {number}
|
||||
*/
|
||||
function getStorageSize(storage) {
|
||||
let size = 0;
|
||||
storage.forEach(() => void size++);
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {number}
|
||||
*/
|
||||
const PIVOT = 1;
|
||||
|
||||
/**
|
||||
* Asserts a single IndexEntry at a given field number.
|
||||
* @param {!BinaryStorage} storage
|
||||
* @param {number} fieldNumber
|
||||
* @param {...!IndexEntry} expectedEntries
|
||||
*/
|
||||
function assertStorageEntries(storage, fieldNumber, ...expectedEntries) {
|
||||
expect(getStorageSize(storage)).toBe(1);
|
||||
|
||||
const entryArray = storage.get(fieldNumber).getIndexArray();
|
||||
expect(entryArray).not.toBeUndefined();
|
||||
expect(entryArray.length).toBe(expectedEntries.length);
|
||||
|
||||
for (let i = 0; i < entryArray.length; i++) {
|
||||
const storageEntry = entryArray[i];
|
||||
const expectedEntry = expectedEntries[i];
|
||||
|
||||
expect(storageEntry).toBe(expectedEntry);
|
||||
}
|
||||
}
|
||||
|
||||
describe('Indexer does', () => {
|
||||
it('return empty storage for empty array', () => {
|
||||
const storage = buildIndex(createBufferDecoder(), PIVOT);
|
||||
expect(storage).not.toBeNull();
|
||||
expect(getStorageSize(storage)).toBe(0);
|
||||
});
|
||||
|
||||
it('throw for null array', () => {
|
||||
expect(
|
||||
() => buildIndex(
|
||||
/** @type {!BufferDecoder} */ (/** @type {*} */ (null)), PIVOT))
|
||||
.toThrow();
|
||||
});
|
||||
|
||||
it('fail for invalid wire type (6)', () => {
|
||||
expect(() => buildIndex(createBufferDecoder(0x0E, 0x01), PIVOT))
|
||||
.toThrowError('Unexpected wire type: 6');
|
||||
});
|
||||
|
||||
it('fail for invalid wire type (7)', () => {
|
||||
expect(() => buildIndex(createBufferDecoder(0x0F, 0x01), PIVOT))
|
||||
.toThrowError('Unexpected wire type: 7');
|
||||
});
|
||||
|
||||
it('index varint', () => {
|
||||
const data = createBufferDecoder(0x08, 0x01, 0x08, 0x01);
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.VARINT, /* startIndex= */ 1),
|
||||
Field.encodeIndexEntry(WireType.VARINT, /* startIndex= */ 3));
|
||||
});
|
||||
|
||||
it('index varint with two bytes field number', () => {
|
||||
const data = createBufferDecoder(0xF8, 0x01, 0x01);
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 31,
|
||||
Field.encodeIndexEntry(WireType.VARINT, /* startIndex= */ 2));
|
||||
});
|
||||
|
||||
it('fail for varints that are longer than 10 bytes', () => {
|
||||
const data = createBufferDecoder(
|
||||
0x08, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00);
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => buildIndex(data, PIVOT))
|
||||
.toThrowError('Index out of bounds: index: 12 size: 11');
|
||||
} else {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.VARINT, /* startIndex= */ 1));
|
||||
}
|
||||
});
|
||||
|
||||
it('fail for varints with no data', () => {
|
||||
const data = createBufferDecoder(0x08);
|
||||
expect(() => buildIndex(data, PIVOT)).toThrow();
|
||||
});
|
||||
|
||||
it('index fixed64', () => {
|
||||
const data = createBufferDecoder(
|
||||
/* first= */ 0x09, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
|
||||
/* second= */ 0x09, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08);
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.FIXED64, /* startIndex= */ 1),
|
||||
Field.encodeIndexEntry(WireType.FIXED64, /* startIndex= */ 10));
|
||||
});
|
||||
|
||||
it('fail for fixed64 data missing in input', () => {
|
||||
const data =
|
||||
createBufferDecoder(0x09, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07);
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => buildIndex(data, PIVOT))
|
||||
.toThrowError('Index out of bounds: index: 9 size: 8');
|
||||
} else {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.FIXED64, /* startIndex= */ 1));
|
||||
}
|
||||
});
|
||||
|
||||
it('fail for fixed64 tag that has no data after it', () => {
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
const data = createBufferDecoder(0x09);
|
||||
expect(() => buildIndex(data, PIVOT))
|
||||
.toThrowError('Index out of bounds: index: 9 size: 1');
|
||||
} else {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
const data = createBufferDecoder(0x09);
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.FIXED64, /* startIndex= */ 1));
|
||||
}
|
||||
});
|
||||
|
||||
it('index delimited', () => {
|
||||
const data = createBufferDecoder(
|
||||
/* first= */ 0x0A, 0x02, 0x00, 0x01, /* second= */ 0x0A, 0x02, 0x00,
|
||||
0x01);
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.DELIMITED, /* startIndex= */ 1),
|
||||
Field.encodeIndexEntry(WireType.DELIMITED, /* startIndex= */ 5));
|
||||
});
|
||||
|
||||
it('fail for length deliimted field data missing in input', () => {
|
||||
const data = createBufferDecoder(0x0A, 0x04, 0x00, 0x01);
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => buildIndex(data, PIVOT))
|
||||
.toThrowError('Index out of bounds: index: 6 size: 4');
|
||||
} else {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.DELIMITED, /* startIndex= */ 1));
|
||||
}
|
||||
});
|
||||
|
||||
it('fail for delimited tag that has no data after it', () => {
|
||||
const data = createBufferDecoder(0x0A);
|
||||
expect(() => buildIndex(data, PIVOT)).toThrow();
|
||||
});
|
||||
|
||||
it('index fixed32', () => {
|
||||
const data = createBufferDecoder(
|
||||
/* first= */ 0x0D, 0x01, 0x02, 0x03, 0x04, /* second= */ 0x0D, 0x01,
|
||||
0x02, 0x03, 0x04);
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.FIXED32, /* startIndex= */ 1),
|
||||
Field.encodeIndexEntry(WireType.FIXED32, /* startIndex= */ 6));
|
||||
});
|
||||
|
||||
it('fail for fixed32 data missing in input', () => {
|
||||
const data = createBufferDecoder(0x0D, 0x01, 0x02, 0x03);
|
||||
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => buildIndex(data, PIVOT))
|
||||
.toThrowError('Index out of bounds: index: 5 size: 4');
|
||||
} else {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.FIXED32, /* startIndex= */ 1));
|
||||
}
|
||||
});
|
||||
|
||||
it('fail for fixed32 tag that has no data after it', () => {
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
const data = createBufferDecoder(0x0D);
|
||||
expect(() => buildIndex(data, PIVOT))
|
||||
.toThrowError('Index out of bounds: index: 5 size: 1');
|
||||
} else {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
const data = createBufferDecoder(0x0D);
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.FIXED32, /* startIndex= */ 1));
|
||||
}
|
||||
});
|
||||
|
||||
it('index group', () => {
|
||||
const data = createBufferDecoder(
|
||||
/* first= */ 0x0B, 0x08, 0x01, 0x0C, /* second= */ 0x0B, 0x08, 0x01,
|
||||
0x0C);
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1),
|
||||
Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 5));
|
||||
});
|
||||
|
||||
it('index group and skips inner group', () => {
|
||||
const data =
|
||||
createBufferDecoder(0x0B, 0x0B, 0x08, 0x01, 0x0C, 0x08, 0x01, 0x0C);
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1));
|
||||
});
|
||||
|
||||
it('fail on unmatched stop group', () => {
|
||||
const data = createBufferDecoder(0x0C, 0x01);
|
||||
expect(() => buildIndex(data, PIVOT))
|
||||
.toThrowError('Unexpected wire type: 4');
|
||||
});
|
||||
|
||||
it('fail for groups without matching stop group', () => {
|
||||
const data = createBufferDecoder(0x0B, 0x08, 0x01, 0x1C);
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => buildIndex(data, PIVOT))
|
||||
.toThrowError('Expected stop group for fieldnumber 1 not found.');
|
||||
} else {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1));
|
||||
}
|
||||
});
|
||||
|
||||
it('fail for groups without stop group', () => {
|
||||
const data = createBufferDecoder(0x0B, 0x08, 0x01);
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => buildIndex(data, PIVOT)).toThrowError('No end group found.');
|
||||
} else {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1));
|
||||
}
|
||||
});
|
||||
|
||||
it('fail for group tag that has no data after it', () => {
|
||||
const data = createBufferDecoder(0x0B);
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => buildIndex(data, PIVOT)).toThrowError('No end group found.');
|
||||
} else {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
const storage = buildIndex(data, PIVOT);
|
||||
assertStorageEntries(
|
||||
storage, /* fieldNumber= */ 1,
|
||||
Field.encodeIndexEntry(WireType.START_GROUP, /* startIndex= */ 1));
|
||||
}
|
||||
});
|
||||
|
||||
it('index too large tag', () => {
|
||||
const data = createBufferDecoder(0xF8, 0xFF, 0xFF, 0xFF, 0xFF);
|
||||
expect(() => buildIndex(data, PIVOT)).toThrow();
|
||||
});
|
||||
|
||||
it('fail for varint tag that has no data after it', () => {
|
||||
const data = createBufferDecoder(0x08);
|
||||
expect(() => buildIndex(data, PIVOT)).toThrow();
|
||||
});
|
||||
});
|
71
deps/protobuf/js/experimental/runtime/kernel/int32_test_pairs.js
vendored
Normal file
71
deps/protobuf/js/experimental/runtime/kernel/int32_test_pairs.js
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
/**
|
||||
* @fileoverview Test data for int32 encoding and decoding.
|
||||
*/
|
||||
goog.module('protobuf.binary.int32TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of float values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, intValue:number, bufferDecoder:
|
||||
* !BufferDecoder, error: ?boolean, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getInt32Pairs() {
|
||||
const int32Pairs = [
|
||||
{
|
||||
name: 'zero',
|
||||
intValue: 0,
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
},
|
||||
{
|
||||
name: 'one ',
|
||||
intValue: 1,
|
||||
bufferDecoder: createBufferDecoder(0x01),
|
||||
},
|
||||
{
|
||||
name: 'minus one',
|
||||
intValue: -1,
|
||||
bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x0F),
|
||||
// The writer will encode this with 64 bits, see below
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'minus one (64bits)',
|
||||
intValue: -1,
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01),
|
||||
},
|
||||
{
|
||||
name: 'max signed int 2^31 - 1',
|
||||
intValue: Math.pow(2, 31) - 1,
|
||||
bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x07),
|
||||
|
||||
},
|
||||
{
|
||||
name: 'min signed int -2^31',
|
||||
intValue: -Math.pow(2, 31),
|
||||
bufferDecoder: createBufferDecoder(0x80, 0x80, 0x80, 0x80, 0x08),
|
||||
// The writer will encode this with 64 bits, see below
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'value min signed int -2^31 (64 bit)',
|
||||
intValue: -Math.pow(2, 31),
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0x80, 0x80, 0x80, 0x80, 0xF8, 0xFF, 0xFF, 0xFF, 0xFF, 0x01),
|
||||
},
|
||||
{
|
||||
name: 'errors out for 11 bytes',
|
||||
intValue: -1,
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
error: true,
|
||||
skip_writer: true,
|
||||
},
|
||||
];
|
||||
return [...int32Pairs];
|
||||
}
|
||||
|
||||
exports = {getInt32Pairs};
|
59
deps/protobuf/js/experimental/runtime/kernel/int64_test_pairs.js
vendored
Normal file
59
deps/protobuf/js/experimental/runtime/kernel/int64_test_pairs.js
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
/**
|
||||
* @fileoverview Test data for int64 encoding and decoding.
|
||||
*/
|
||||
goog.module('protobuf.binary.int64TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const Int64 = goog.require('protobuf.Int64');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of float values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, longValue: !Int64, bufferDecoder:
|
||||
* !BufferDecoder, error: ?boolean, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getInt64Pairs() {
|
||||
const int64Pairs = [
|
||||
{
|
||||
name: 'zero',
|
||||
longValue: Int64.fromInt(0),
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
},
|
||||
{
|
||||
name: 'one ',
|
||||
longValue: Int64.fromInt(1),
|
||||
bufferDecoder: createBufferDecoder(0x01),
|
||||
},
|
||||
{
|
||||
name: 'minus one',
|
||||
longValue: Int64.fromInt(-1),
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01),
|
||||
},
|
||||
{
|
||||
name: 'max signed int 2^63 - 1',
|
||||
longValue: Int64.fromBits(0xFFFFFFFF, 0x7FFFFFFF),
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F),
|
||||
|
||||
},
|
||||
{
|
||||
name: 'value min signed int -2^63 (64 bit)',
|
||||
longValue: Int64.fromBits(0xFFFFFFFF, 0xFFFFFFFF),
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01),
|
||||
},
|
||||
{
|
||||
name: 'errors out for 11 bytes',
|
||||
longValue: Int64.fromInt(-1),
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
error: true,
|
||||
skip_writer: true,
|
||||
},
|
||||
];
|
||||
return [...int64Pairs];
|
||||
}
|
||||
|
||||
exports = {getInt64Pairs};
|
24
deps/protobuf/js/experimental/runtime/kernel/internal_message.js
vendored
Normal file
24
deps/protobuf/js/experimental/runtime/kernel/internal_message.js
vendored
Normal file
@ -0,0 +1,24 @@
|
||||
/**
|
||||
* @fileoverview Internal interface for messages implemented with the binary
|
||||
* kernel.
|
||||
*/
|
||||
goog.module('protobuf.binary.InternalMessage');
|
||||
|
||||
const Kernel = goog.requireType('protobuf.runtime.Kernel');
|
||||
|
||||
/**
|
||||
* Interface that needs to be implemented by messages implemented with the
|
||||
* binary kernel. This is an internal only interface and should be used only by
|
||||
* the classes in binary kernel.
|
||||
*
|
||||
* @interface
|
||||
*/
|
||||
class InternalMessage {
|
||||
/**
|
||||
* @package
|
||||
* @return {!Kernel}
|
||||
*/
|
||||
internalGetKernel() {}
|
||||
}
|
||||
|
||||
exports = InternalMessage;
|
4122
deps/protobuf/js/experimental/runtime/kernel/kernel.js
vendored
Normal file
4122
deps/protobuf/js/experimental/runtime/kernel/kernel.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
266
deps/protobuf/js/experimental/runtime/kernel/kernel_compatibility_test.js
vendored
Normal file
266
deps/protobuf/js/experimental/runtime/kernel/kernel_compatibility_test.js
vendored
Normal file
@ -0,0 +1,266 @@
|
||||
/**
|
||||
* @fileoverview Tests to make sure Kernel can read data in a backward
|
||||
* compatible way even when protobuf schema changes according to the rules
|
||||
* defined in
|
||||
* https://developers.google.com/protocol-buffers/docs/proto#updating and
|
||||
* https://developers.google.com/protocol-buffers/docs/proto3#updating.
|
||||
*
|
||||
* third_party/protobuf/conformance/binary_json_conformance_suite.cc already
|
||||
* covers many compatibility tests, this file covers only the tests not covered
|
||||
* by binary_json_conformance_suite. Ultimately all of the tests in this file
|
||||
* should be moved to binary_json_conformance_suite.
|
||||
*/
|
||||
goog.module('protobuf.runtime.KernelCompatibilityTest');
|
||||
|
||||
goog.setTestOnly();
|
||||
|
||||
const ByteString = goog.require('protobuf.ByteString');
|
||||
const Int64 = goog.require('protobuf.Int64');
|
||||
const Kernel = goog.require('protobuf.runtime.Kernel');
|
||||
const TestMessage = goog.require('protobuf.testing.binary.TestMessage');
|
||||
const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks');
|
||||
|
||||
/**
|
||||
* @param {...number} bytes
|
||||
* @return {!ArrayBuffer}
|
||||
*/
|
||||
function createArrayBuffer(...bytes) {
|
||||
return new Uint8Array(bytes).buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Unicode character codes of a string.
|
||||
* @param {string} str
|
||||
* @return {!Array<number>}
|
||||
*/
|
||||
function getCharacterCodes(str) {
|
||||
return Array.from(str, (c) => c.charCodeAt(0));
|
||||
}
|
||||
|
||||
describe('optional -> repeated compatibility', () => {
|
||||
it('is maintained for scalars', () => {
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
oldAccessor.setInt32(1, 1);
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData).toEqual(createArrayBuffer(0x8, 0x1));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
expect(newAccessor.getRepeatedInt32Size(1)).toEqual(1);
|
||||
expect(newAccessor.getRepeatedInt32Element(1, 0)).toEqual(1);
|
||||
});
|
||||
|
||||
it('is maintained for messages', () => {
|
||||
const message = new TestMessage(Kernel.createEmpty());
|
||||
message.setInt32(1, 1);
|
||||
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
oldAccessor.setMessage(1, message);
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x8, 0x1));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
expect(newAccessor.getRepeatedMessageSize(1, TestMessage.instanceCreator))
|
||||
.toEqual(1);
|
||||
expect(
|
||||
newAccessor.getRepeatedMessageElement(1, TestMessage.instanceCreator, 0)
|
||||
.serialize())
|
||||
.toEqual(message.serialize());
|
||||
});
|
||||
|
||||
it('is maintained for bytes', () => {
|
||||
const message = new TestMessage(Kernel.createEmpty());
|
||||
message.setInt32(1, 1);
|
||||
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
oldAccessor.setBytes(
|
||||
1, ByteString.fromArrayBuffer(createArrayBuffer(0xA, 0xB)));
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0xA, 0xB));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
expect(newAccessor.getRepeatedBytesSize(1)).toEqual(1);
|
||||
expect(newAccessor.getRepeatedBoolElement(1, 0))
|
||||
.toEqual(ByteString.fromArrayBuffer(createArrayBuffer(0xA, 0xB)));
|
||||
});
|
||||
|
||||
it('is maintained for strings', () => {
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
oldAccessor.setString(1, 'hello');
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData)
|
||||
.toEqual(createArrayBuffer(0xA, 0x5, 0x68, 0x65, 0x6C, 0x6C, 0x6F));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
expect(newAccessor.getRepeatedStringSize(1)).toEqual(1);
|
||||
expect(newAccessor.getRepeatedStringElement(1, 0)).toEqual('hello');
|
||||
});
|
||||
});
|
||||
|
||||
describe('Kernel repeated -> optional compatibility', () => {
|
||||
it('is maintained for unpacked scalars', () => {
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
oldAccessor.addUnpackedInt32Element(1, 0);
|
||||
oldAccessor.addUnpackedInt32Element(1, 1);
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData).toEqual(createArrayBuffer(0x8, 0x0, 0x8, 0x1));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
expect(newAccessor.getInt32WithDefault(1)).toEqual(1);
|
||||
expect(newAccessor.serialize()).toEqual(serializedData);
|
||||
});
|
||||
|
||||
// repeated -> optional transformation is not supported for packed fields yet:
|
||||
// go/proto-schema-repeated
|
||||
it('is not maintained for packed scalars', () => {
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
oldAccessor.addPackedInt32Element(1, 0);
|
||||
oldAccessor.addPackedInt32Element(1, 1);
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x0, 0x1));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => newAccessor.getInt32WithDefault(1)).toThrow();
|
||||
}
|
||||
});
|
||||
|
||||
it('is maintained for messages', () => {
|
||||
const message1 = new TestMessage(Kernel.createEmpty());
|
||||
message1.setInt32(1, 1);
|
||||
const message2 = new TestMessage(Kernel.createEmpty());
|
||||
message2.setInt32(1, 2);
|
||||
message2.setInt32(2, 3);
|
||||
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
oldAccessor.addRepeatedMessageElement(
|
||||
1, message1, TestMessage.instanceCreator);
|
||||
oldAccessor.addRepeatedMessageElement(
|
||||
1, message2, TestMessage.instanceCreator);
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData)
|
||||
.toEqual(createArrayBuffer(
|
||||
0xA, 0x2, 0x8, 0x1, 0xA, 0x4, 0x8, 0x2, 0x10, 0x3));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
// Values from message1 and message2 have been merged
|
||||
const newMessage = newAccessor.getMessage(1, TestMessage.instanceCreator);
|
||||
expect(newMessage.getRepeatedInt32Size(1)).toEqual(2);
|
||||
expect(newMessage.getRepeatedInt32Element(1, 0)).toEqual(1);
|
||||
expect(newMessage.getRepeatedInt32Element(1, 1)).toEqual(2);
|
||||
expect(newMessage.getInt32WithDefault(2)).toEqual(3);
|
||||
expect(newMessage.serialize())
|
||||
.toEqual(createArrayBuffer(0x8, 0x1, 0x8, 0x2, 0x10, 0x3));
|
||||
});
|
||||
|
||||
it('is maintained for bytes', () => {
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
oldAccessor.addRepeatedBytesElement(
|
||||
1, ByteString.fromArrayBuffer(createArrayBuffer(0xA, 0xB)));
|
||||
oldAccessor.addRepeatedBytesElement(
|
||||
1, ByteString.fromArrayBuffer(createArrayBuffer(0xC, 0xD)));
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData)
|
||||
.toEqual(createArrayBuffer(0xA, 0x2, 0xA, 0xB, 0xA, 0x2, 0xC, 0xD));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
expect(newAccessor.getBytesWithDefault(1))
|
||||
.toEqual(ByteString.fromArrayBuffer(createArrayBuffer(0xC, 0xD)));
|
||||
expect(newAccessor.serialize()).toEqual(serializedData);
|
||||
});
|
||||
|
||||
it('is maintained for strings', () => {
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
oldAccessor.addRepeatedStringElement(1, 'hello');
|
||||
oldAccessor.addRepeatedStringElement(1, 'world');
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData)
|
||||
.toEqual(createArrayBuffer(
|
||||
0xA, 0x5, ...getCharacterCodes('hello'), 0xA, 0x5,
|
||||
...getCharacterCodes('world')));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
expect(newAccessor.getStringWithDefault(1)).toEqual('world');
|
||||
expect(newAccessor.serialize()).toEqual(serializedData);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Type change', () => {
|
||||
it('is supported for fixed32 -> sfixed32', () => {
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
oldAccessor.setFixed32(1, 4294967295);
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData)
|
||||
.toEqual(createArrayBuffer(0xD, 0xFF, 0xFF, 0xFF, 0xFF));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
expect(newAccessor.getSfixed32WithDefault(1)).toEqual(-1);
|
||||
expect(newAccessor.serialize()).toEqual(serializedData);
|
||||
});
|
||||
|
||||
it('is supported for sfixed32 -> fixed32', () => {
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
oldAccessor.setSfixed32(1, -1);
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData)
|
||||
.toEqual(createArrayBuffer(0xD, 0xFF, 0xFF, 0xFF, 0xFF));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
expect(newAccessor.getFixed32WithDefault(1)).toEqual(4294967295);
|
||||
expect(newAccessor.serialize()).toEqual(serializedData);
|
||||
});
|
||||
|
||||
it('is supported for fixed64 -> sfixed64', () => {
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
oldAccessor.setFixed64(1, Int64.fromHexString('0xFFFFFFFFFFFFFFFF'));
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData)
|
||||
.toEqual(createArrayBuffer(
|
||||
0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
expect(newAccessor.getSfixed64WithDefault(1)).toEqual(Int64.fromInt(-1));
|
||||
expect(newAccessor.serialize()).toEqual(serializedData);
|
||||
});
|
||||
|
||||
it('is supported for sfixed64 -> fixed64', () => {
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
oldAccessor.setSfixed64(1, Int64.fromInt(-1));
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData)
|
||||
.toEqual(createArrayBuffer(
|
||||
0x9, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
expect(newAccessor.getFixed64WithDefault(1))
|
||||
.toEqual(Int64.fromHexString('0xFFFFFFFFFFFFFFFF'));
|
||||
expect(newAccessor.serialize()).toEqual(serializedData);
|
||||
});
|
||||
|
||||
it('is supported for bytes -> message', () => {
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
oldAccessor.setBytes(
|
||||
1, ByteString.fromArrayBuffer(createArrayBuffer(0x8, 0x1)));
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x8, 0x1));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
const message = newAccessor.getMessage(1, TestMessage.instanceCreator);
|
||||
expect(message.getInt32WithDefault(1)).toEqual(1);
|
||||
expect(message.serialize()).toEqual(createArrayBuffer(0x8, 0x1));
|
||||
expect(newAccessor.serialize()).toEqual(serializedData);
|
||||
});
|
||||
|
||||
it('is supported for message -> bytes', () => {
|
||||
const oldAccessor = Kernel.createEmpty();
|
||||
const message = new TestMessage(Kernel.createEmpty());
|
||||
message.setInt32(1, 1);
|
||||
oldAccessor.setMessage(1, message);
|
||||
const serializedData = oldAccessor.serialize();
|
||||
expect(serializedData).toEqual(createArrayBuffer(0xA, 0x2, 0x8, 0x1));
|
||||
|
||||
const newAccessor = Kernel.fromArrayBuffer(serializedData);
|
||||
expect(newAccessor.getBytesWithDefault(1))
|
||||
.toEqual(ByteString.fromArrayBuffer(createArrayBuffer(0x8, 0x1)));
|
||||
expect(newAccessor.serialize()).toEqual(serializedData);
|
||||
});
|
||||
});
|
7807
deps/protobuf/js/experimental/runtime/kernel/kernel_repeated_test.js
vendored
Normal file
7807
deps/protobuf/js/experimental/runtime/kernel/kernel_repeated_test.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
2329
deps/protobuf/js/experimental/runtime/kernel/kernel_test.js
vendored
Normal file
2329
deps/protobuf/js/experimental/runtime/kernel/kernel_test.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
285
deps/protobuf/js/experimental/runtime/kernel/message_set.js
vendored
Normal file
285
deps/protobuf/js/experimental/runtime/kernel/message_set.js
vendored
Normal file
@ -0,0 +1,285 @@
|
||||
/*
|
||||
##########################################################
|
||||
# #
|
||||
# __ __ _____ _ _ _____ _ _ _____ #
|
||||
# \ \ / /\ | __ \| \ | |_ _| \ | |/ ____| #
|
||||
# \ \ /\ / / \ | |__) | \| | | | | \| | | __ #
|
||||
# \ \/ \/ / /\ \ | _ /| . ` | | | | . ` | | |_ | #
|
||||
# \ /\ / ____ \| | \ \| |\ |_| |_| |\ | |__| | #
|
||||
# \/ \/_/ \_\_| \_\_| \_|_____|_| \_|\_____| #
|
||||
# #
|
||||
# #
|
||||
##########################################################
|
||||
# Do not use this class in your code. This class purely #
|
||||
# exists to make proto code generation easier. #
|
||||
##########################################################
|
||||
*/
|
||||
goog.module('protobuf.runtime.MessageSet');
|
||||
|
||||
const InternalMessage = goog.require('protobuf.binary.InternalMessage');
|
||||
const Kernel = goog.require('protobuf.runtime.Kernel');
|
||||
|
||||
// These are the tags for the old MessageSet format, which was defined as:
|
||||
// message MessageSet {
|
||||
// repeated group Item = 1 {
|
||||
// required uint32 type_id = 2;
|
||||
// optional bytes message = 3;
|
||||
// }
|
||||
// }
|
||||
/** @const {number} */
|
||||
const MSET_GROUP_FIELD_NUMBER = 1;
|
||||
/** @const {number} */
|
||||
const MSET_TYPE_ID_FIELD_NUMBER = 2;
|
||||
/** @const {number} */
|
||||
const MSET_MESSAGE_FIELD_NUMBER = 3;
|
||||
|
||||
/**
|
||||
* @param {!Kernel} kernel
|
||||
* @return {!Map<number, !Item>}
|
||||
*/
|
||||
function createItemMap(kernel) {
|
||||
const itemMap = new Map();
|
||||
let totalCount = 0;
|
||||
for (const item of kernel.getRepeatedGroupIterable(
|
||||
MSET_GROUP_FIELD_NUMBER, Item.fromKernel)) {
|
||||
itemMap.set(item.getTypeId(), item);
|
||||
totalCount++;
|
||||
}
|
||||
|
||||
// Normalize the entries.
|
||||
if (totalCount > itemMap.size) {
|
||||
writeItemMap(kernel, itemMap);
|
||||
}
|
||||
return itemMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Kernel} kernel
|
||||
* @param {!Map<number, !Item>} itemMap
|
||||
*/
|
||||
function writeItemMap(kernel, itemMap) {
|
||||
kernel.setRepeatedGroupIterable(MSET_GROUP_FIELD_NUMBER, itemMap.values());
|
||||
}
|
||||
|
||||
/**
|
||||
* @implements {InternalMessage}
|
||||
* @final
|
||||
*/
|
||||
class MessageSet {
|
||||
/**
|
||||
* @param {!Kernel} kernel
|
||||
* @return {!MessageSet}
|
||||
*/
|
||||
static fromKernel(kernel) {
|
||||
const itemMap = createItemMap(kernel);
|
||||
return new MessageSet(kernel, itemMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!MessageSet}
|
||||
*/
|
||||
static createEmpty() {
|
||||
return MessageSet.fromKernel(Kernel.createEmpty());
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Kernel} kernel
|
||||
* @param {!Map<number, !Item>} itemMap
|
||||
* @private
|
||||
*/
|
||||
constructor(kernel, itemMap) {
|
||||
/** @const {!Kernel} @private */
|
||||
this.kernel_ = kernel;
|
||||
/** @const {!Map<number, !Item>} @private */
|
||||
this.itemMap_ = itemMap;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// code helpers for code gen
|
||||
|
||||
/**
|
||||
* @param {number} typeId
|
||||
* @param {function(!Kernel):T} instanceCreator
|
||||
* @param {number=} pivot
|
||||
* @return {?T}
|
||||
* @template T
|
||||
*/
|
||||
getMessageOrNull(typeId, instanceCreator, pivot) {
|
||||
const item = this.itemMap_.get(typeId);
|
||||
return item ? item.getMessageOrNull(instanceCreator, pivot) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} typeId
|
||||
* @param {function(!Kernel):T} instanceCreator
|
||||
* @param {number=} pivot
|
||||
* @return {T}
|
||||
* @template T
|
||||
*/
|
||||
getMessageAttach(typeId, instanceCreator, pivot) {
|
||||
let item = this.itemMap_.get(typeId);
|
||||
if (item) {
|
||||
return item.getMessageAttach(instanceCreator, pivot);
|
||||
}
|
||||
const message = instanceCreator(Kernel.createEmpty());
|
||||
this.setMessage(typeId, message);
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} typeId
|
||||
* @param {number=} pivot
|
||||
* @return {?Kernel}
|
||||
*/
|
||||
getMessageAccessorOrNull(typeId, pivot) {
|
||||
const item = this.itemMap_.get(typeId);
|
||||
return item ? item.getMessageAccessorOrNull(pivot) : null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {number} typeId
|
||||
*/
|
||||
clearMessage(typeId) {
|
||||
if (this.itemMap_.delete(typeId)) {
|
||||
writeItemMap(this.kernel_, this.itemMap_);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} typeId
|
||||
* @return {boolean}
|
||||
*/
|
||||
hasMessage(typeId) {
|
||||
return this.itemMap_.has(typeId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} typeId
|
||||
* @param {!InternalMessage} value
|
||||
*/
|
||||
setMessage(typeId, value) {
|
||||
const item = this.itemMap_.get(typeId);
|
||||
if (item) {
|
||||
item.setMessage(value);
|
||||
} else {
|
||||
this.itemMap_.set(typeId, Item.create(typeId, value));
|
||||
writeItemMap(this.kernel_, this.itemMap_);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Kernel}
|
||||
* @override
|
||||
*/
|
||||
internalGetKernel() {
|
||||
return this.kernel_;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @implements {InternalMessage}
|
||||
* @final
|
||||
*/
|
||||
class Item {
|
||||
/**
|
||||
* @param {number} typeId
|
||||
* @param {!InternalMessage} message
|
||||
* @return {!Item}
|
||||
*/
|
||||
static create(typeId, message) {
|
||||
const messageSet = Item.fromKernel(Kernel.createEmpty());
|
||||
messageSet.setTypeId_(typeId);
|
||||
messageSet.setMessage(message);
|
||||
return messageSet;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param {!Kernel} kernel
|
||||
* @return {!Item}
|
||||
*/
|
||||
static fromKernel(kernel) {
|
||||
return new Item(kernel);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Kernel} kernel
|
||||
* @private
|
||||
*/
|
||||
constructor(kernel) {
|
||||
/** @const {!Kernel} @private */
|
||||
this.kernel_ = kernel;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function(!Kernel):T} instanceCreator
|
||||
* @param {number=} pivot
|
||||
* @return {T}
|
||||
* @template T
|
||||
*/
|
||||
getMessage(instanceCreator, pivot) {
|
||||
return this.kernel_.getMessage(
|
||||
MSET_MESSAGE_FIELD_NUMBER, instanceCreator, pivot);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function(!Kernel):T} instanceCreator
|
||||
* @param {number=} pivot
|
||||
* @return {?T}
|
||||
* @template T
|
||||
*/
|
||||
getMessageOrNull(instanceCreator, pivot) {
|
||||
return this.kernel_.getMessageOrNull(
|
||||
MSET_MESSAGE_FIELD_NUMBER, instanceCreator, pivot);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {function(!Kernel):T} instanceCreator
|
||||
* @param {number=} pivot
|
||||
* @return {T}
|
||||
* @template T
|
||||
*/
|
||||
getMessageAttach(instanceCreator, pivot) {
|
||||
return this.kernel_.getMessageAttach(
|
||||
MSET_MESSAGE_FIELD_NUMBER, instanceCreator, pivot);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number=} pivot
|
||||
* @return {?Kernel}
|
||||
*/
|
||||
getMessageAccessorOrNull(pivot) {
|
||||
return this.kernel_.getMessageAccessorOrNull(
|
||||
MSET_MESSAGE_FIELD_NUMBER, pivot);
|
||||
}
|
||||
|
||||
/** @param {!InternalMessage} value */
|
||||
setMessage(value) {
|
||||
this.kernel_.setMessage(MSET_MESSAGE_FIELD_NUMBER, value);
|
||||
}
|
||||
|
||||
/** @return {number} */
|
||||
getTypeId() {
|
||||
return this.kernel_.getUint32WithDefault(MSET_TYPE_ID_FIELD_NUMBER);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} value
|
||||
* @private
|
||||
*/
|
||||
setTypeId_(value) {
|
||||
this.kernel_.setUint32(MSET_TYPE_ID_FIELD_NUMBER, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {!Kernel}
|
||||
* @override
|
||||
*/
|
||||
internalGetKernel() {
|
||||
return this.kernel_;
|
||||
}
|
||||
}
|
||||
|
||||
exports = MessageSet;
|
262
deps/protobuf/js/experimental/runtime/kernel/message_set_test.js
vendored
Normal file
262
deps/protobuf/js/experimental/runtime/kernel/message_set_test.js
vendored
Normal file
@ -0,0 +1,262 @@
|
||||
/**
|
||||
* @fileoverview Tests for message_set.js.
|
||||
*/
|
||||
goog.module('protobuf.runtime.MessageSetTest');
|
||||
|
||||
goog.setTestOnly();
|
||||
|
||||
const Kernel = goog.require('protobuf.runtime.Kernel');
|
||||
const MessageSet = goog.require('protobuf.runtime.MessageSet');
|
||||
const TestMessage = goog.require('protobuf.testing.binary.TestMessage');
|
||||
|
||||
/**
|
||||
* @param {...number} bytes
|
||||
* @return {!ArrayBuffer}
|
||||
*/
|
||||
function createArrayBuffer(...bytes) {
|
||||
return new Uint8Array(bytes).buffer;
|
||||
}
|
||||
|
||||
describe('MessageSet does', () => {
|
||||
it('returns no messages for empty set', () => {
|
||||
const messageSet = MessageSet.createEmpty();
|
||||
expect(messageSet.getMessageOrNull(12345, TestMessage.instanceCreator))
|
||||
.toBeNull();
|
||||
});
|
||||
|
||||
it('returns no kernel for empty set', () => {
|
||||
const messageSet = MessageSet.createEmpty();
|
||||
expect(messageSet.getMessageAccessorOrNull(12345)).toBeNull();
|
||||
});
|
||||
|
||||
it('returns message that has been set', () => {
|
||||
const messageSet = MessageSet.createEmpty();
|
||||
const message = TestMessage.createEmpty();
|
||||
messageSet.setMessage(12345, message);
|
||||
expect(messageSet.getMessageOrNull(12345, TestMessage.instanceCreator))
|
||||
.toBe(message);
|
||||
});
|
||||
|
||||
it('returns null for cleared message', () => {
|
||||
const messageSet = MessageSet.createEmpty();
|
||||
const message = TestMessage.createEmpty();
|
||||
messageSet.setMessage(12345, message);
|
||||
messageSet.clearMessage(12345);
|
||||
expect(messageSet.getMessageAccessorOrNull(12345)).toBeNull();
|
||||
});
|
||||
|
||||
it('returns false for not present message', () => {
|
||||
const messageSet = MessageSet.createEmpty();
|
||||
expect(messageSet.hasMessage(12345)).toBe(false);
|
||||
});
|
||||
|
||||
it('returns true for present message', () => {
|
||||
const messageSet = MessageSet.createEmpty();
|
||||
const message = TestMessage.createEmpty();
|
||||
messageSet.setMessage(12345, message);
|
||||
expect(messageSet.hasMessage(12345)).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false for cleared message', () => {
|
||||
const messageSet = MessageSet.createEmpty();
|
||||
const message = TestMessage.createEmpty();
|
||||
messageSet.setMessage(12345, message);
|
||||
messageSet.clearMessage(12345);
|
||||
expect(messageSet.hasMessage(12345)).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false for cleared message without it being present', () => {
|
||||
const messageSet = MessageSet.createEmpty();
|
||||
messageSet.clearMessage(12345);
|
||||
expect(messageSet.hasMessage(12345)).toBe(false);
|
||||
});
|
||||
|
||||
const createMessageSet = () => {
|
||||
const messageSet = MessageSet.createEmpty();
|
||||
const message = TestMessage.createEmpty();
|
||||
message.setInt32(1, 2);
|
||||
messageSet.setMessage(12345, message);
|
||||
|
||||
|
||||
const parsedKernel =
|
||||
Kernel.fromArrayBuffer(messageSet.internalGetKernel().serialize());
|
||||
return MessageSet.fromKernel(parsedKernel);
|
||||
};
|
||||
|
||||
it('pass through pivot for getMessageOrNull', () => {
|
||||
const messageSet = createMessageSet();
|
||||
const message =
|
||||
messageSet.getMessageOrNull(12345, TestMessage.instanceCreator, 2);
|
||||
expect(message.internalGetKernel().getPivot()).toBe(2);
|
||||
});
|
||||
|
||||
it('pass through pivot for getMessageAttach', () => {
|
||||
const messageSet = createMessageSet();
|
||||
const message =
|
||||
messageSet.getMessageAttach(12345, TestMessage.instanceCreator, 2);
|
||||
expect(message.internalGetKernel().getPivot()).toBe(2);
|
||||
});
|
||||
|
||||
it('pass through pivot for getMessageAccessorOrNull', () => {
|
||||
const messageSet = createMessageSet();
|
||||
const kernel = messageSet.getMessageAccessorOrNull(12345, 2);
|
||||
expect(kernel.getPivot()).toBe(2);
|
||||
});
|
||||
|
||||
it('pick the last value in the stream', () => {
|
||||
const arrayBuffer = createArrayBuffer(
|
||||
0x52, // Tag (field:10, length delimited)
|
||||
0x14, // Length of 20 bytes
|
||||
0x0B, // Start group fieldnumber 1
|
||||
0x10, // Tag (field 2, varint)
|
||||
0xB9, // 12345
|
||||
0x60, // 12345
|
||||
0x1A, // Tag (field 3, length delimited)
|
||||
0x03, // length 3
|
||||
0xA0, // Tag (fieldnumber 20, varint)
|
||||
0x01, // Tag (fieldnumber 20, varint)
|
||||
0x1E, // 30
|
||||
0x0C, // Stop Group field number 1
|
||||
// second group
|
||||
0x0B, // Start group fieldnumber 1
|
||||
0x10, // Tag (field 2, varint)
|
||||
0xB9, // 12345
|
||||
0x60, // 12345
|
||||
0x1A, // Tag (field 3, length delimited)
|
||||
0x03, // length 3
|
||||
0xA0, // Tag (fieldnumber 20, varint)
|
||||
0x01, // Tag (fieldnumber 20, varint)
|
||||
0x01, // 1
|
||||
0x0C // Stop Group field number 1
|
||||
);
|
||||
|
||||
const outerMessage = Kernel.fromArrayBuffer(arrayBuffer);
|
||||
|
||||
const messageSet = outerMessage.getMessage(10, MessageSet.fromKernel);
|
||||
|
||||
const message =
|
||||
messageSet.getMessageOrNull(12345, TestMessage.instanceCreator);
|
||||
expect(message.getInt32WithDefault(20)).toBe(1);
|
||||
});
|
||||
|
||||
it('removes duplicates when read', () => {
|
||||
const arrayBuffer = createArrayBuffer(
|
||||
0x52, // Tag (field:10, length delimited)
|
||||
0x14, // Length of 20 bytes
|
||||
0x0B, // Start group fieldnumber 1
|
||||
0x10, // Tag (field 2, varint)
|
||||
0xB9, // 12345
|
||||
0x60, // 12345
|
||||
0x1A, // Tag (field 3, length delimited)
|
||||
0x03, // length 3
|
||||
0xA0, // Tag (fieldnumber 20, varint)
|
||||
0x01, // Tag (fieldnumber 20, varint)
|
||||
0x1E, // 30
|
||||
0x0C, // Stop Group field number 1
|
||||
// second group
|
||||
0x0B, // Start group fieldnumber 1
|
||||
0x10, // Tag (field 2, varint)
|
||||
0xB9, // 12345
|
||||
0x60, // 12345
|
||||
0x1A, // Tag (field 3, length delimited)
|
||||
0x03, // length 3
|
||||
0xA0, // Tag (fieldnumber 20, varint)
|
||||
0x01, // Tag (fieldnumber 20, varint)
|
||||
0x01, // 1
|
||||
0x0C // Stop Group field number 1
|
||||
);
|
||||
|
||||
|
||||
const outerMessage = Kernel.fromArrayBuffer(arrayBuffer);
|
||||
outerMessage.getMessageAttach(10, MessageSet.fromKernel);
|
||||
|
||||
expect(outerMessage.serialize())
|
||||
.toEqual(createArrayBuffer(
|
||||
0x52, // Tag (field:10, length delimited)
|
||||
0x0A, // Length of 10 bytes
|
||||
0x0B, // Start group fieldnumber 1
|
||||
0x10, // Tag (field 2, varint)
|
||||
0xB9, // 12345
|
||||
0x60, // 12345
|
||||
0x1A, // Tag (field 3, length delimited)
|
||||
0x03, // length 3
|
||||
0xA0, // Tag (fieldnumber 20, varint)
|
||||
0x01, // Tag (fieldnumber 20, varint)
|
||||
0x01, // 1
|
||||
0x0C // Stop Group field number 1
|
||||
));
|
||||
});
|
||||
|
||||
it('allow for large typeIds', () => {
|
||||
const messageSet = MessageSet.createEmpty();
|
||||
const message = TestMessage.createEmpty();
|
||||
messageSet.setMessage(0xFFFFFFFE >>> 0, message);
|
||||
expect(messageSet.hasMessage(0xFFFFFFFE >>> 0)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Optional MessageSet does', () => {
|
||||
// message Bar {
|
||||
// optional MessageSet mset = 10;
|
||||
//}
|
||||
//
|
||||
// message Foo {
|
||||
// extend proto2.bridge.MessageSet {
|
||||
// optional Foo message_set_extension = 12345;
|
||||
// }
|
||||
// optional int32 f20 = 20;
|
||||
//}
|
||||
|
||||
it('encode as a field', () => {
|
||||
const fooMessage = Kernel.createEmpty();
|
||||
fooMessage.setInt32(20, 30);
|
||||
|
||||
const messageSet = MessageSet.createEmpty();
|
||||
messageSet.setMessage(12345, TestMessage.instanceCreator(fooMessage));
|
||||
|
||||
const barMessage = Kernel.createEmpty();
|
||||
barMessage.setMessage(10, messageSet);
|
||||
|
||||
expect(barMessage.serialize())
|
||||
.toEqual(createArrayBuffer(
|
||||
0x52, // Tag (field:10, length delimited)
|
||||
0x0A, // Length of 10 bytes
|
||||
0x0B, // Start group fieldnumber 1
|
||||
0x10, // Tag (field 2, varint)
|
||||
0xB9, // 12345
|
||||
0x60, // 12345
|
||||
0x1A, // Tag (field 3, length delimited)
|
||||
0x03, // length 3
|
||||
0xA0, // Tag (fieldnumber 20, varint)
|
||||
0x01, // Tag (fieldnumber 20, varint)
|
||||
0x1E, // 30
|
||||
0x0C // Stop Group field number 1
|
||||
));
|
||||
});
|
||||
|
||||
it('deserializes', () => {
|
||||
const fooMessage = Kernel.createEmpty();
|
||||
fooMessage.setInt32(20, 30);
|
||||
|
||||
const messageSet = MessageSet.createEmpty();
|
||||
messageSet.setMessage(12345, TestMessage.instanceCreator(fooMessage));
|
||||
|
||||
|
||||
const barMessage = Kernel.createEmpty();
|
||||
barMessage.setMessage(10, messageSet);
|
||||
|
||||
const arrayBuffer = barMessage.serialize();
|
||||
|
||||
const barMessageParsed = Kernel.fromArrayBuffer(arrayBuffer);
|
||||
expect(barMessageParsed.hasFieldNumber(10)).toBe(true);
|
||||
|
||||
const messageSetParsed =
|
||||
barMessageParsed.getMessage(10, MessageSet.fromKernel);
|
||||
|
||||
const fooMessageParsed =
|
||||
messageSetParsed.getMessageOrNull(12345, TestMessage.instanceCreator)
|
||||
.internalGetKernel();
|
||||
|
||||
expect(fooMessageParsed.getInt32WithDefault(20)).toBe(30);
|
||||
});
|
||||
});
|
59
deps/protobuf/js/experimental/runtime/kernel/packed_bool_test_pairs.js
vendored
Normal file
59
deps/protobuf/js/experimental/runtime/kernel/packed_bool_test_pairs.js
vendored
Normal file
@ -0,0 +1,59 @@
|
||||
goog.module('protobuf.binary.packedBoolTestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of packed bool values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, boolValues: !Array<boolean>,
|
||||
* bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getPackedBoolPairs() {
|
||||
return [
|
||||
{
|
||||
name: 'empty value',
|
||||
boolValues: [],
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'single value',
|
||||
boolValues: [true],
|
||||
bufferDecoder: createBufferDecoder(0x01, 0x01),
|
||||
},
|
||||
{
|
||||
name: 'single multi-bytes value',
|
||||
boolValues: [true],
|
||||
bufferDecoder: createBufferDecoder(0x02, 0x80, 0x01),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'multiple values',
|
||||
boolValues: [true, false],
|
||||
bufferDecoder: createBufferDecoder(0x02, 0x01, 0x00),
|
||||
},
|
||||
{
|
||||
name: 'multiple multi-bytes values',
|
||||
boolValues: [true, false],
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0x0C, // length
|
||||
0x80,
|
||||
0x80,
|
||||
0x80,
|
||||
0x80,
|
||||
0x80,
|
||||
0x01, // true
|
||||
0x80,
|
||||
0x80,
|
||||
0x80,
|
||||
0x80,
|
||||
0x80,
|
||||
0x00, // false
|
||||
),
|
||||
skip_writer: true,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
exports = {getPackedBoolPairs};
|
52
deps/protobuf/js/experimental/runtime/kernel/packed_double_test_pairs.js
vendored
Normal file
52
deps/protobuf/js/experimental/runtime/kernel/packed_double_test_pairs.js
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
goog.module('protobuf.binary.packedDoubleTestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of packed double values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, doubleValues: !Array<number>,
|
||||
* bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getPackedDoublePairs() {
|
||||
return [
|
||||
{
|
||||
name: 'empty value',
|
||||
doubleValues: [],
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'single value',
|
||||
doubleValues: [1],
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF0, 0x3F),
|
||||
},
|
||||
{
|
||||
name: 'multiple values',
|
||||
doubleValues: [1, 0],
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0x10, // length
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0xF0,
|
||||
0x3F, // 1
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00, // 0
|
||||
),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
exports = {getPackedDoublePairs};
|
34
deps/protobuf/js/experimental/runtime/kernel/packed_fixed32_test_pairs.js
vendored
Normal file
34
deps/protobuf/js/experimental/runtime/kernel/packed_fixed32_test_pairs.js
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
goog.module('protobuf.binary.packedFixed32TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of packed fixed32 values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, fixed32Values: !Array<number>,
|
||||
* bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getPackedFixed32Pairs() {
|
||||
return [
|
||||
{
|
||||
name: 'empty value',
|
||||
fixed32Values: [],
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'single value',
|
||||
fixed32Values: [1],
|
||||
bufferDecoder: createBufferDecoder(0x04, 0x01, 0x00, 0x00, 0x00),
|
||||
},
|
||||
{
|
||||
name: 'multiple values',
|
||||
fixed32Values: [1, 0],
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
exports = {getPackedFixed32Pairs};
|
34
deps/protobuf/js/experimental/runtime/kernel/packed_float_test_pairs.js
vendored
Normal file
34
deps/protobuf/js/experimental/runtime/kernel/packed_float_test_pairs.js
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
goog.module('protobuf.binary.packedFloatTestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of packed float values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, floatValues: !Array<number>,
|
||||
* bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getPackedFloatPairs() {
|
||||
return [
|
||||
{
|
||||
name: 'empty value',
|
||||
floatValues: [],
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'single value',
|
||||
floatValues: [1],
|
||||
bufferDecoder: createBufferDecoder(0x04, 0x00, 0x00, 0x80, 0x3F),
|
||||
},
|
||||
{
|
||||
name: 'multiple values',
|
||||
floatValues: [1, 0],
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0x08, 0x00, 0x00, 0x80, 0x3F, 0x00, 0x00, 0x00, 0x00),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
exports = {getPackedFloatPairs};
|
33
deps/protobuf/js/experimental/runtime/kernel/packed_int32_test_pairs.js
vendored
Normal file
33
deps/protobuf/js/experimental/runtime/kernel/packed_int32_test_pairs.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
goog.module('protobuf.binary.packedInt32TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of packed int32 values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, int32Values: !Array<number>,
|
||||
* bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getPackedInt32Pairs() {
|
||||
return [
|
||||
{
|
||||
name: 'empty value',
|
||||
int32Values: [],
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'single value',
|
||||
int32Values: [1],
|
||||
bufferDecoder: createBufferDecoder(0x01, 0x01),
|
||||
},
|
||||
{
|
||||
name: 'multiple values',
|
||||
int32Values: [1, 0],
|
||||
bufferDecoder: createBufferDecoder(0x02, 0x01, 0x00),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
exports = {getPackedInt32Pairs};
|
34
deps/protobuf/js/experimental/runtime/kernel/packed_int64_test_pairs.js
vendored
Normal file
34
deps/protobuf/js/experimental/runtime/kernel/packed_int64_test_pairs.js
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
goog.module('protobuf.binary.packedInt64TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const Int64 = goog.require('protobuf.Int64');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of packed int64 values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, int64Values: !Array<!Int64>,
|
||||
* bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getPackedInt64Pairs() {
|
||||
return [
|
||||
{
|
||||
name: 'empty value',
|
||||
int64Values: [],
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'single value',
|
||||
int64Values: [Int64.fromInt(1)],
|
||||
bufferDecoder: createBufferDecoder(0x01, 0x01),
|
||||
},
|
||||
{
|
||||
name: 'multiple values',
|
||||
int64Values: [Int64.fromInt(1), Int64.fromInt(0)],
|
||||
bufferDecoder: createBufferDecoder(0x02, 0x01, 0x00),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
exports = {getPackedInt64Pairs};
|
34
deps/protobuf/js/experimental/runtime/kernel/packed_sfixed32_test_pairs.js
vendored
Normal file
34
deps/protobuf/js/experimental/runtime/kernel/packed_sfixed32_test_pairs.js
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
goog.module('protobuf.binary.packedSfixed32TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of packed sfixed32 values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, sfixed32Values: !Array<number>,
|
||||
* bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getPackedSfixed32Pairs() {
|
||||
return [
|
||||
{
|
||||
name: 'empty value',
|
||||
sfixed32Values: [],
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'single value',
|
||||
sfixed32Values: [1],
|
||||
bufferDecoder: createBufferDecoder(0x04, 0x01, 0x00, 0x00, 0x00),
|
||||
},
|
||||
{
|
||||
name: 'multiple values',
|
||||
sfixed32Values: [1, 0],
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
exports = {getPackedSfixed32Pairs};
|
53
deps/protobuf/js/experimental/runtime/kernel/packed_sfixed64_test_pairs.js
vendored
Normal file
53
deps/protobuf/js/experimental/runtime/kernel/packed_sfixed64_test_pairs.js
vendored
Normal file
@ -0,0 +1,53 @@
|
||||
goog.module('protobuf.binary.packedSfixed64TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const Int64 = goog.require('protobuf.Int64');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of packed sfixed64 values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, sfixed64Values: !Array<!Int64>,
|
||||
* bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getPackedSfixed64Pairs() {
|
||||
return [
|
||||
{
|
||||
name: 'empty value',
|
||||
sfixed64Values: [],
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'single value',
|
||||
sfixed64Values: [Int64.fromInt(1)],
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0x08, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
},
|
||||
{
|
||||
name: 'multiple values',
|
||||
sfixed64Values: [Int64.fromInt(1), Int64.fromInt(0)],
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0x10, // length
|
||||
0x01,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00, // 1
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00,
|
||||
0x00, // 2
|
||||
),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
exports = {getPackedSfixed64Pairs};
|
33
deps/protobuf/js/experimental/runtime/kernel/packed_sint32_test_pairs.js
vendored
Normal file
33
deps/protobuf/js/experimental/runtime/kernel/packed_sint32_test_pairs.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
goog.module('protobuf.binary.packedSint32TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of packed sint32 values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, sint32Values: !Array<number>,
|
||||
* bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getPackedSint32Pairs() {
|
||||
return [
|
||||
{
|
||||
name: 'empty value',
|
||||
sint32Values: [],
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'single value',
|
||||
sint32Values: [-1],
|
||||
bufferDecoder: createBufferDecoder(0x01, 0x01),
|
||||
},
|
||||
{
|
||||
name: 'multiple values',
|
||||
sint32Values: [-1, 0],
|
||||
bufferDecoder: createBufferDecoder(0x02, 0x01, 0x00),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
exports = {getPackedSint32Pairs};
|
34
deps/protobuf/js/experimental/runtime/kernel/packed_sint64_test_pairs.js
vendored
Normal file
34
deps/protobuf/js/experimental/runtime/kernel/packed_sint64_test_pairs.js
vendored
Normal file
@ -0,0 +1,34 @@
|
||||
goog.module('protobuf.binary.packedSint64TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const Int64 = goog.require('protobuf.Int64');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of packed sint64 values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, sint64Values: !Array<number>,
|
||||
* bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getPackedSint64Pairs() {
|
||||
return [
|
||||
{
|
||||
name: 'empty value',
|
||||
sint64Values: [],
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'single value',
|
||||
sint64Values: [Int64.fromInt(-1)],
|
||||
bufferDecoder: createBufferDecoder(0x01, 0x01),
|
||||
},
|
||||
{
|
||||
name: 'multiple values',
|
||||
sint64Values: [Int64.fromInt(-1), Int64.fromInt(0)],
|
||||
bufferDecoder: createBufferDecoder(0x02, 0x01, 0x00),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
exports = {getPackedSint64Pairs};
|
33
deps/protobuf/js/experimental/runtime/kernel/packed_uint32_test_pairs.js
vendored
Normal file
33
deps/protobuf/js/experimental/runtime/kernel/packed_uint32_test_pairs.js
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
goog.module('protobuf.binary.packedUint32TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of packed uint32 values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, uint32Values: !Array<number>,
|
||||
* bufferDecoder: !BufferDecoder, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getPackedUint32Pairs() {
|
||||
return [
|
||||
{
|
||||
name: 'empty value',
|
||||
uint32Values: [],
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'single value',
|
||||
uint32Values: [1],
|
||||
bufferDecoder: createBufferDecoder(0x01, 0x01),
|
||||
},
|
||||
{
|
||||
name: 'multiple values',
|
||||
uint32Values: [1, 0],
|
||||
bufferDecoder: createBufferDecoder(0x02, 0x01, 0x00),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
exports = {getPackedUint32Pairs};
|
364
deps/protobuf/js/experimental/runtime/kernel/reader.js
vendored
Normal file
364
deps/protobuf/js/experimental/runtime/kernel/reader.js
vendored
Normal file
@ -0,0 +1,364 @@
|
||||
/**
|
||||
* @fileoverview Helper methods for reading data from the binary wire format.
|
||||
*/
|
||||
goog.module('protobuf.binary.reader');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const ByteString = goog.require('protobuf.ByteString');
|
||||
const Int64 = goog.require('protobuf.Int64');
|
||||
const {checkState} = goog.require('protobuf.internal.checks');
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* OPTIONAL FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Reads a boolean value from the binary bytes.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {boolean}
|
||||
* @package
|
||||
*/
|
||||
function readBool(bufferDecoder, start) {
|
||||
const {lowBits, highBits} = bufferDecoder.getVarint(start);
|
||||
return lowBits !== 0 || highBits !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a ByteString value from the binary bytes.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!ByteString}
|
||||
* @package
|
||||
*/
|
||||
function readBytes(bufferDecoder, start) {
|
||||
return readDelimited(bufferDecoder, start).asByteString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a int32 value from the binary bytes encoded as varint.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {number}
|
||||
* @package
|
||||
*/
|
||||
function readInt32(bufferDecoder, start) {
|
||||
// Negative 32 bit integers are encoded with 64 bit values.
|
||||
// Clients are expected to truncate back to 32 bits.
|
||||
// This is why we are dropping the upper bytes here.
|
||||
return bufferDecoder.getUnsignedVarint32At(start) | 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a int32 value from the binary bytes encoded as varint.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!Int64}
|
||||
* @package
|
||||
*/
|
||||
function readInt64(bufferDecoder, start) {
|
||||
const {lowBits, highBits} = bufferDecoder.getVarint(start);
|
||||
return Int64.fromBits(lowBits, highBits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a fixed int32 value from the binary bytes.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {number}
|
||||
* @package
|
||||
*/
|
||||
function readFixed32(bufferDecoder, start) {
|
||||
return bufferDecoder.getUint32(start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a float value from the binary bytes.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {number}
|
||||
* @package
|
||||
*/
|
||||
function readFloat(bufferDecoder, start) {
|
||||
return bufferDecoder.getFloat32(start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a fixed int64 value from the binary bytes.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!Int64}
|
||||
* @package
|
||||
*/
|
||||
function readSfixed64(bufferDecoder, start) {
|
||||
const lowBits = bufferDecoder.getInt32(start);
|
||||
const highBits = bufferDecoder.getInt32(start + 4);
|
||||
return Int64.fromBits(lowBits, highBits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a sint64 value from the binary bytes encoded as varint.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!Int64}
|
||||
* @package
|
||||
*/
|
||||
function readSint64(bufferDecoder, start) {
|
||||
const {lowBits, highBits} = bufferDecoder.getVarint(start);
|
||||
const sign = -(lowBits & 0x01);
|
||||
const decodedLowerBits = ((lowBits >>> 1) | (highBits & 0x01) << 31) ^ sign;
|
||||
const decodedUpperBits = (highBits >>> 1) ^ sign;
|
||||
return Int64.fromBits(decodedLowerBits, decodedUpperBits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a sint32 value from the binary bytes encoded as varint.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {number}
|
||||
* @package
|
||||
*/
|
||||
function readSint32(bufferDecoder, start) {
|
||||
return readSint64(bufferDecoder, start).getLowBits();
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a subarray of bytes representing a length delimited field.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!BufferDecoder}
|
||||
* @package
|
||||
*/
|
||||
function readDelimited(bufferDecoder, start) {
|
||||
const unsignedLength = bufferDecoder.getUnsignedVarint32At(start);
|
||||
return bufferDecoder.subBufferDecoder(bufferDecoder.cursor(), unsignedLength);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a string value from the binary bytes.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {string}
|
||||
* @package
|
||||
*/
|
||||
function readString(bufferDecoder, start) {
|
||||
return readDelimited(bufferDecoder, start).asString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a uint32 value from the binary bytes encoded as varint.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {number}
|
||||
* @package
|
||||
*/
|
||||
function readUint32(bufferDecoder, start) {
|
||||
return bufferDecoder.getUnsignedVarint32At(start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a double value from the binary bytes.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {number}
|
||||
* @package
|
||||
*/
|
||||
function readDouble(bufferDecoder, start) {
|
||||
return bufferDecoder.getFloat64(start);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a fixed int32 value from the binary bytes.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {number}
|
||||
* @package
|
||||
*/
|
||||
function readSfixed32(bufferDecoder, start) {
|
||||
return bufferDecoder.getInt32(start);
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* REPEATED FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
/**
|
||||
* Reads a packed bool field, which consists of a length header and a list of
|
||||
* unsigned varints.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!Array<boolean>}
|
||||
* @package
|
||||
*/
|
||||
function readPackedBool(bufferDecoder, start) {
|
||||
return readPacked(bufferDecoder, start, readBool);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a packed double field, which consists of a length header and a list of
|
||||
* fixed64.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!Array<number>}
|
||||
* @package
|
||||
*/
|
||||
function readPackedDouble(bufferDecoder, start) {
|
||||
return readPacked(bufferDecoder, start, readDouble);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a packed fixed32 field, which consists of a length header and a list of
|
||||
* fixed32.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!Array<number>}
|
||||
* @package
|
||||
*/
|
||||
function readPackedFixed32(bufferDecoder, start) {
|
||||
return readPacked(bufferDecoder, start, readFixed32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a packed float field, which consists of a length header and a list of
|
||||
* fixed64.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!Array<number>}
|
||||
* @package
|
||||
*/
|
||||
function readPackedFloat(bufferDecoder, start) {
|
||||
return readPacked(bufferDecoder, start, readFloat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a packed int32 field, which consists of a length header and a list of
|
||||
* varint.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!Array<number>}
|
||||
* @package
|
||||
*/
|
||||
function readPackedInt32(bufferDecoder, start) {
|
||||
return readPacked(bufferDecoder, start, readInt32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a packed int64 field, which consists of a length header and a list
|
||||
* of int64.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!Array<!Int64>}
|
||||
* @package
|
||||
*/
|
||||
function readPackedInt64(bufferDecoder, start) {
|
||||
return readPacked(bufferDecoder, start, readInt64);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a packed sfixed32 field, which consists of a length header and a list
|
||||
* of sfixed32.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!Array<number>}
|
||||
* @package
|
||||
*/
|
||||
function readPackedSfixed32(bufferDecoder, start) {
|
||||
return readPacked(bufferDecoder, start, readSfixed32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a packed sfixed64 field, which consists of a length header and a list
|
||||
* of sfixed64.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!Array<!Int64>}
|
||||
* @package
|
||||
*/
|
||||
function readPackedSfixed64(bufferDecoder, start) {
|
||||
return readPacked(bufferDecoder, start, readSfixed64);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a packed sint32 field, which consists of a length header and a list of
|
||||
* varint.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!Array<number>}
|
||||
* @package
|
||||
*/
|
||||
function readPackedSint32(bufferDecoder, start) {
|
||||
return readPacked(bufferDecoder, start, readSint32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a packed sint64 field, which consists of a length header and a list
|
||||
* of sint64.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!Array<!Int64>}
|
||||
* @package
|
||||
*/
|
||||
function readPackedSint64(bufferDecoder, start) {
|
||||
return readPacked(bufferDecoder, start, readSint64);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a packed uint32 field, which consists of a length header and a list of
|
||||
* varint.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @return {!Array<number>}
|
||||
* @package
|
||||
*/
|
||||
function readPackedUint32(bufferDecoder, start) {
|
||||
return readPacked(bufferDecoder, start, readUint32);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read packed values.
|
||||
* @param {!BufferDecoder} bufferDecoder Binary format encoded bytes.
|
||||
* @param {number} start Start of the data.
|
||||
* @param {function(!BufferDecoder, number):T} valueFunction
|
||||
* @return {!Array<T>}
|
||||
* @package
|
||||
* @template T
|
||||
*/
|
||||
function readPacked(bufferDecoder, start, valueFunction) {
|
||||
const /** !Array<T> */ result = [];
|
||||
const unsignedLength = bufferDecoder.getUnsignedVarint32At(start);
|
||||
const dataStart = bufferDecoder.cursor();
|
||||
while (bufferDecoder.cursor() < dataStart + unsignedLength) {
|
||||
checkState(bufferDecoder.cursor() > 0);
|
||||
result.push(valueFunction(bufferDecoder, bufferDecoder.cursor()));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
exports = {
|
||||
readBool,
|
||||
readBytes,
|
||||
readDelimited,
|
||||
readDouble,
|
||||
readFixed32,
|
||||
readFloat,
|
||||
readInt32,
|
||||
readInt64,
|
||||
readSint32,
|
||||
readSint64,
|
||||
readSfixed32,
|
||||
readSfixed64,
|
||||
readString,
|
||||
readUint32,
|
||||
readPackedBool,
|
||||
readPackedDouble,
|
||||
readPackedFixed32,
|
||||
readPackedFloat,
|
||||
readPackedInt32,
|
||||
readPackedInt64,
|
||||
readPackedSfixed32,
|
||||
readPackedSfixed64,
|
||||
readPackedSint32,
|
||||
readPackedSint64,
|
||||
readPackedUint32,
|
||||
};
|
425
deps/protobuf/js/experimental/runtime/kernel/reader_test.js
vendored
Normal file
425
deps/protobuf/js/experimental/runtime/kernel/reader_test.js
vendored
Normal file
@ -0,0 +1,425 @@
|
||||
/**
|
||||
* @fileoverview Tests for reader.js.
|
||||
*/
|
||||
goog.module('protobuf.binary.ReaderTest');
|
||||
|
||||
goog.setTestOnly();
|
||||
|
||||
// Note to the reader:
|
||||
// Since the reader behavior changes with the checking level some of the
|
||||
// tests in this file have to know which checking level is enable to make
|
||||
// correct assertions.
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const ByteString = goog.require('protobuf.ByteString');
|
||||
const reader = goog.require('protobuf.binary.reader');
|
||||
const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
const {encode} = goog.require('protobuf.binary.textencoding');
|
||||
const {getBoolPairs} = goog.require('protobuf.binary.boolTestPairs');
|
||||
const {getDoublePairs} = goog.require('protobuf.binary.doubleTestPairs');
|
||||
const {getFixed32Pairs} = goog.require('protobuf.binary.fixed32TestPairs');
|
||||
const {getFloatPairs} = goog.require('protobuf.binary.floatTestPairs');
|
||||
const {getInt32Pairs} = goog.require('protobuf.binary.int32TestPairs');
|
||||
const {getInt64Pairs} = goog.require('protobuf.binary.int64TestPairs');
|
||||
const {getPackedBoolPairs} = goog.require('protobuf.binary.packedBoolTestPairs');
|
||||
const {getPackedDoublePairs} = goog.require('protobuf.binary.packedDoubleTestPairs');
|
||||
const {getPackedFixed32Pairs} = goog.require('protobuf.binary.packedFixed32TestPairs');
|
||||
const {getPackedFloatPairs} = goog.require('protobuf.binary.packedFloatTestPairs');
|
||||
const {getPackedInt32Pairs} = goog.require('protobuf.binary.packedInt32TestPairs');
|
||||
const {getPackedInt64Pairs} = goog.require('protobuf.binary.packedInt64TestPairs');
|
||||
const {getPackedSfixed32Pairs} = goog.require('protobuf.binary.packedSfixed32TestPairs');
|
||||
const {getPackedSfixed64Pairs} = goog.require('protobuf.binary.packedSfixed64TestPairs');
|
||||
const {getPackedSint32Pairs} = goog.require('protobuf.binary.packedSint32TestPairs');
|
||||
const {getPackedSint64Pairs} = goog.require('protobuf.binary.packedSint64TestPairs');
|
||||
const {getPackedUint32Pairs} = goog.require('protobuf.binary.packedUint32TestPairs');
|
||||
const {getSfixed32Pairs} = goog.require('protobuf.binary.sfixed32TestPairs');
|
||||
const {getSfixed64Pairs} = goog.require('protobuf.binary.sfixed64TestPairs');
|
||||
const {getSint32Pairs} = goog.require('protobuf.binary.sint32TestPairs');
|
||||
const {getSint64Pairs} = goog.require('protobuf.binary.sint64TestPairs');
|
||||
const {getUint32Pairs} = goog.require('protobuf.binary.uint32TestPairs');
|
||||
|
||||
/******************************************************************************
|
||||
* Optional FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
describe('Read bool does', () => {
|
||||
for (const pair of getBoolPairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
if (pair.error && CHECK_CRITICAL_STATE) {
|
||||
expect(() => reader.readBool(pair.bufferDecoder, 0)).toThrow();
|
||||
} else {
|
||||
const d = reader.readBool(
|
||||
pair.bufferDecoder, pair.bufferDecoder.startIndex());
|
||||
expect(d).toEqual(pair.boolValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readBytes does', () => {
|
||||
it('throw exception if data is too short', () => {
|
||||
const bufferDecoder = createBufferDecoder();
|
||||
expect(() => reader.readBytes(bufferDecoder, 0)).toThrow();
|
||||
});
|
||||
|
||||
it('read bytes by index', () => {
|
||||
const bufferDecoder = createBufferDecoder(3, 1, 2, 3);
|
||||
const byteString = reader.readBytes(bufferDecoder, 0);
|
||||
expect(ByteString.fromArrayBuffer(new Uint8Array([1, 2, 3]).buffer))
|
||||
.toEqual(byteString);
|
||||
});
|
||||
});
|
||||
|
||||
describe('readDouble does', () => {
|
||||
it('throw exception if data is too short', () => {
|
||||
const bufferDecoder = createBufferDecoder();
|
||||
expect(() => reader.readDouble(bufferDecoder, 0)).toThrow();
|
||||
});
|
||||
|
||||
for (const pair of getDoublePairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readDouble(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.doubleValue);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readFixed32 does', () => {
|
||||
it('throw exception if data is too short', () => {
|
||||
const bufferDecoder = createBufferDecoder();
|
||||
expect(() => reader.readFixed32(bufferDecoder, 0)).toThrow();
|
||||
});
|
||||
|
||||
for (const pair of getFixed32Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readFixed32(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.intValue);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readFloat does', () => {
|
||||
it('throw exception if data is too short', () => {
|
||||
const bufferDecoder = createBufferDecoder();
|
||||
expect(() => reader.readFloat(bufferDecoder, 0)).toThrow();
|
||||
});
|
||||
|
||||
for (const pair of getFloatPairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readFloat(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(Math.fround(pair.floatValue));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readInt32 does', () => {
|
||||
it('throw exception if data is too short', () => {
|
||||
const bufferDecoder = createBufferDecoder(0x80);
|
||||
expect(() => reader.readInt32(bufferDecoder, 0)).toThrow();
|
||||
});
|
||||
|
||||
for (const pair of getInt32Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
if (pair.error && CHECK_CRITICAL_STATE) {
|
||||
expect(() => reader.readInt32(pair.bufferDecoder, 0)).toThrow();
|
||||
} else {
|
||||
const d = reader.readInt32(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.intValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readSfixed32 does', () => {
|
||||
it('throw exception if data is too short', () => {
|
||||
const bufferDecoder = createBufferDecoder(0x80);
|
||||
expect(() => reader.readSfixed32(bufferDecoder, 0)).toThrow();
|
||||
});
|
||||
|
||||
for (const pair of getSfixed32Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readSfixed32(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.intValue);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readSfixed64 does', () => {
|
||||
it('throw exception if data is too short', () => {
|
||||
const bufferDecoder = createBufferDecoder(0x80);
|
||||
expect(() => reader.readSfixed64(bufferDecoder, 0)).toThrow();
|
||||
});
|
||||
|
||||
for (const pair of getSfixed64Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readSfixed64(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.longValue);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readSint32 does', () => {
|
||||
it('throw exception if data is too short', () => {
|
||||
const bufferDecoder = createBufferDecoder(0x80);
|
||||
expect(() => reader.readSint32(bufferDecoder, 0)).toThrow();
|
||||
});
|
||||
|
||||
for (const pair of getSint32Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
if (pair.error && CHECK_CRITICAL_STATE) {
|
||||
expect(() => reader.readSint32(pair.bufferDecoder, 0)).toThrow();
|
||||
} else {
|
||||
const d = reader.readSint32(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.intValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readInt64 does', () => {
|
||||
it('throw exception if data is too short', () => {
|
||||
const bufferDecoder = createBufferDecoder(0x80);
|
||||
expect(() => reader.readInt64(bufferDecoder, 0)).toThrow();
|
||||
});
|
||||
|
||||
for (const pair of getInt64Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
if (pair.error && CHECK_CRITICAL_STATE) {
|
||||
expect(() => reader.readInt64(pair.bufferDecoder, 0)).toThrow();
|
||||
} else {
|
||||
const d = reader.readInt64(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.longValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readSint64 does', () => {
|
||||
it('throw exception if data is too short', () => {
|
||||
const bufferDecoder = createBufferDecoder(0x80);
|
||||
expect(() => reader.readSint64(bufferDecoder, 0)).toThrow();
|
||||
});
|
||||
|
||||
for (const pair of getSint64Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
if (pair.error && CHECK_CRITICAL_STATE) {
|
||||
expect(() => reader.readSint64(pair.bufferDecoder, 0)).toThrow();
|
||||
} else {
|
||||
const d = reader.readSint64(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.longValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readUint32 does', () => {
|
||||
it('throw exception if data is too short', () => {
|
||||
const bufferDecoder = createBufferDecoder(0x80);
|
||||
expect(() => reader.readUint32(bufferDecoder, 0)).toThrow();
|
||||
});
|
||||
|
||||
for (const pair of getUint32Pairs()) {
|
||||
if (!pair.skip_reader) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
if (pair.error && CHECK_CRITICAL_STATE) {
|
||||
expect(() => reader.readUint32(pair.bufferDecoder, 0)).toThrow();
|
||||
} else {
|
||||
const d = reader.readUint32(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.intValue);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} s
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function encodeString(s) {
|
||||
if (typeof TextEncoder !== 'undefined') {
|
||||
const textEncoder = new TextEncoder('utf-8');
|
||||
return textEncoder.encode(s);
|
||||
} else {
|
||||
return encode(s);
|
||||
}
|
||||
}
|
||||
|
||||
/** @param {string} s */
|
||||
function expectEncodedStringToMatch(s) {
|
||||
const array = encodeString(s);
|
||||
const length = array.length;
|
||||
if (length > 127) {
|
||||
throw new Error('Test only works for strings shorter than 128');
|
||||
}
|
||||
const encodedArray = new Uint8Array(length + 1);
|
||||
encodedArray[0] = length;
|
||||
encodedArray.set(array, 1);
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(encodedArray.buffer);
|
||||
expect(reader.readString(bufferDecoder, 0)).toEqual(s);
|
||||
}
|
||||
|
||||
describe('readString does', () => {
|
||||
it('return empty string for zero length string', () => {
|
||||
const s = reader.readString(createBufferDecoder(0x00), 0);
|
||||
expect(s).toEqual('');
|
||||
});
|
||||
|
||||
it('decode random strings', () => {
|
||||
// 1 byte strings
|
||||
expectEncodedStringToMatch('hello');
|
||||
expectEncodedStringToMatch('HELLO1!');
|
||||
|
||||
// 2 byte String
|
||||
expectEncodedStringToMatch('©');
|
||||
|
||||
// 3 byte string
|
||||
expectEncodedStringToMatch('❄');
|
||||
|
||||
// 4 byte string
|
||||
expectEncodedStringToMatch('😁');
|
||||
});
|
||||
|
||||
it('decode 1 byte strings', () => {
|
||||
for (let i = 0; i < 0x80; i++) {
|
||||
const s = String.fromCharCode(i);
|
||||
expectEncodedStringToMatch(s);
|
||||
}
|
||||
});
|
||||
|
||||
it('decode 2 byte strings', () => {
|
||||
for (let i = 0xC0; i < 0x7FF; i++) {
|
||||
const s = String.fromCharCode(i);
|
||||
expectEncodedStringToMatch(s);
|
||||
}
|
||||
});
|
||||
|
||||
it('decode 3 byte strings', () => {
|
||||
for (let i = 0x7FF; i < 0x8FFF; i++) {
|
||||
const s = String.fromCharCode(i);
|
||||
expectEncodedStringToMatch(s);
|
||||
}
|
||||
});
|
||||
|
||||
it('throw exception on invalid bytes', () => {
|
||||
// This test will only succeed with the native TextDecoder since
|
||||
// our polyfill does not do any validation. IE10 and IE11 don't support
|
||||
// TextDecoder.
|
||||
// TODO: Remove this check once we no longer need to support IE
|
||||
if (typeof TextDecoder !== 'undefined') {
|
||||
expect(
|
||||
() => reader.readString(
|
||||
createBufferDecoder(0x01, /* invalid utf data point*/ 0xFF), 0))
|
||||
.toThrow();
|
||||
}
|
||||
});
|
||||
|
||||
it('throw exception if data is too short', () => {
|
||||
const array = createBufferDecoder(0x02, '?'.charCodeAt(0));
|
||||
expect(() => reader.readString(array, 0)).toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
/******************************************************************************
|
||||
* REPEATED FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
describe('readPackedBool does', () => {
|
||||
for (const pair of getPackedBoolPairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readPackedBool(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.boolValues);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readPackedDouble does', () => {
|
||||
for (const pair of getPackedDoublePairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readPackedDouble(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.doubleValues);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readPackedFixed32 does', () => {
|
||||
for (const pair of getPackedFixed32Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readPackedFixed32(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.fixed32Values);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readPackedFloat does', () => {
|
||||
for (const pair of getPackedFloatPairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readPackedFloat(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.floatValues);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readPackedInt32 does', () => {
|
||||
for (const pair of getPackedInt32Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readPackedInt32(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.int32Values);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readPackedInt64 does', () => {
|
||||
for (const pair of getPackedInt64Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readPackedInt64(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.int64Values);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readPackedSfixed32 does', () => {
|
||||
for (const pair of getPackedSfixed32Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readPackedSfixed32(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.sfixed32Values);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readPackedSfixed64 does', () => {
|
||||
for (const pair of getPackedSfixed64Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readPackedSfixed64(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.sfixed64Values);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readPackedSint32 does', () => {
|
||||
for (const pair of getPackedSint32Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readPackedSint32(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.sint32Values);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readPackedSint64 does', () => {
|
||||
for (const pair of getPackedSint64Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readPackedSint64(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.sint64Values);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('readPackedUint32 does', () => {
|
||||
for (const pair of getPackedUint32Pairs()) {
|
||||
it(`decode ${pair.name}`, () => {
|
||||
const d = reader.readPackedUint32(pair.bufferDecoder, 0);
|
||||
expect(d).toEqual(pair.uint32Values);
|
||||
});
|
||||
}
|
||||
});
|
46
deps/protobuf/js/experimental/runtime/kernel/sfixed32_test_pairs.js
vendored
Normal file
46
deps/protobuf/js/experimental/runtime/kernel/sfixed32_test_pairs.js
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
/**
|
||||
* @fileoverview Test data for sfixed32 encoding and decoding.
|
||||
*/
|
||||
goog.module('protobuf.binary.sfixed32TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of int values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, intValue: number, bufferDecoder:
|
||||
* !BufferDecoder}>}
|
||||
*/
|
||||
function getSfixed32Pairs() {
|
||||
const sfixed32Pairs = [
|
||||
{
|
||||
name: 'zero',
|
||||
intValue: 0,
|
||||
bufferDecoder: createBufferDecoder(0x00, 0x00, 0x00, 0x00),
|
||||
},
|
||||
{
|
||||
name: 'one',
|
||||
intValue: 1,
|
||||
bufferDecoder: createBufferDecoder(0x01, 0x00, 0x00, 0x00)
|
||||
},
|
||||
{
|
||||
name: 'minus one',
|
||||
intValue: -1,
|
||||
bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF),
|
||||
},
|
||||
{
|
||||
name: 'max int 2^31 -1',
|
||||
intValue: Math.pow(2, 31) - 1,
|
||||
bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0x7F)
|
||||
},
|
||||
{
|
||||
name: 'min int -2^31',
|
||||
intValue: -Math.pow(2, 31),
|
||||
bufferDecoder: createBufferDecoder(0x00, 0x00, 0x00, 0x80)
|
||||
},
|
||||
];
|
||||
return [...sfixed32Pairs];
|
||||
}
|
||||
|
||||
exports = {getSfixed32Pairs};
|
52
deps/protobuf/js/experimental/runtime/kernel/sfixed64_test_pairs.js
vendored
Normal file
52
deps/protobuf/js/experimental/runtime/kernel/sfixed64_test_pairs.js
vendored
Normal file
@ -0,0 +1,52 @@
|
||||
/**
|
||||
* @fileoverview Test data for sfixed32 encoding and decoding.
|
||||
*/
|
||||
goog.module('protobuf.binary.sfixed64TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const Int64 = goog.require('protobuf.Int64');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of int values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, longValue: !Int64, bufferDecoder:
|
||||
* !BufferDecoder}>}
|
||||
*/
|
||||
function getSfixed64Pairs() {
|
||||
const sfixed64Pairs = [
|
||||
{
|
||||
name: 'zero',
|
||||
longValue: Int64.fromInt(0),
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00),
|
||||
},
|
||||
{
|
||||
name: 'one',
|
||||
longValue: Int64.fromInt(1),
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00)
|
||||
},
|
||||
{
|
||||
name: 'minus one',
|
||||
longValue: Int64.fromInt(-1),
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
},
|
||||
{
|
||||
name: 'max int 2^63 -1',
|
||||
longValue: Int64.getMaxValue(),
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F)
|
||||
},
|
||||
{
|
||||
name: 'min int -2^63',
|
||||
longValue: Int64.getMinValue(),
|
||||
bufferDecoder:
|
||||
createBufferDecoder(0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80)
|
||||
},
|
||||
];
|
||||
return [...sfixed64Pairs];
|
||||
}
|
||||
|
||||
exports = {getSfixed64Pairs};
|
57
deps/protobuf/js/experimental/runtime/kernel/sint32_test_pairs.js
vendored
Normal file
57
deps/protobuf/js/experimental/runtime/kernel/sint32_test_pairs.js
vendored
Normal file
@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @fileoverview Test data for int32 encoding and decoding.
|
||||
*/
|
||||
goog.module('protobuf.binary.sint32TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of float values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, intValue:number, bufferDecoder:
|
||||
* !BufferDecoder, error: ?boolean, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getSint32Pairs() {
|
||||
const sint32Pairs = [
|
||||
{
|
||||
name: 'zero',
|
||||
intValue: 0,
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
},
|
||||
{
|
||||
name: 'one ',
|
||||
intValue: 1,
|
||||
bufferDecoder: createBufferDecoder(0x02),
|
||||
},
|
||||
{
|
||||
name: 'minus one',
|
||||
intValue: -1,
|
||||
bufferDecoder: createBufferDecoder(0x01),
|
||||
},
|
||||
{
|
||||
name: 'two',
|
||||
intValue: 2,
|
||||
bufferDecoder: createBufferDecoder(0x04),
|
||||
},
|
||||
{
|
||||
name: 'minus two',
|
||||
intValue: -2,
|
||||
bufferDecoder: createBufferDecoder(0x03),
|
||||
},
|
||||
{
|
||||
name: 'int 2^31 - 1',
|
||||
intValue: Math.pow(2, 31) - 1,
|
||||
bufferDecoder: createBufferDecoder(0xFE, 0xFF, 0xFF, 0xFF, 0x0F),
|
||||
|
||||
},
|
||||
{
|
||||
name: '-2^31',
|
||||
intValue: -Math.pow(2, 31),
|
||||
bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x0F),
|
||||
},
|
||||
];
|
||||
return [...sint32Pairs];
|
||||
}
|
||||
|
||||
exports = {getSint32Pairs};
|
60
deps/protobuf/js/experimental/runtime/kernel/sint64_test_pairs.js
vendored
Normal file
60
deps/protobuf/js/experimental/runtime/kernel/sint64_test_pairs.js
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
/**
|
||||
* @fileoverview Test data for sint64 encoding and decoding.
|
||||
*/
|
||||
goog.module('protobuf.binary.sint64TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const Int64 = goog.require('protobuf.Int64');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of float values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, longValue: !Int64, bufferDecoder:
|
||||
* !BufferDecoder, error: ?boolean, skip_writer: ?boolean}>}
|
||||
*/
|
||||
function getSint64Pairs() {
|
||||
const sint64Pairs = [
|
||||
{
|
||||
name: 'zero',
|
||||
longValue: Int64.fromInt(0),
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
},
|
||||
{
|
||||
name: 'one ',
|
||||
longValue: Int64.fromInt(1),
|
||||
bufferDecoder: createBufferDecoder(0x02),
|
||||
},
|
||||
{
|
||||
name: 'minus one',
|
||||
longValue: Int64.fromInt(-1),
|
||||
bufferDecoder: createBufferDecoder(0x01),
|
||||
},
|
||||
{
|
||||
name: 'two',
|
||||
longValue: Int64.fromInt(2),
|
||||
bufferDecoder: createBufferDecoder(0x04),
|
||||
},
|
||||
{
|
||||
name: 'minus two',
|
||||
longValue: Int64.fromInt(-2),
|
||||
bufferDecoder: createBufferDecoder(0x03),
|
||||
},
|
||||
{
|
||||
name: 'min value',
|
||||
longValue: Int64.getMinValue(),
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01),
|
||||
},
|
||||
|
||||
{
|
||||
name: 'max value',
|
||||
longValue: Int64.getMaxValue(),
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01),
|
||||
},
|
||||
];
|
||||
return [...sint64Pairs];
|
||||
}
|
||||
|
||||
exports = {getSint64Pairs};
|
67
deps/protobuf/js/experimental/runtime/kernel/storage.js
vendored
Normal file
67
deps/protobuf/js/experimental/runtime/kernel/storage.js
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
goog.module('protobuf.runtime.Storage');
|
||||
|
||||
/**
|
||||
* Interface for getting and storing fields of a protobuf message.
|
||||
*
|
||||
* @interface
|
||||
* @package
|
||||
* @template FieldType
|
||||
*/
|
||||
class Storage {
|
||||
/**
|
||||
* Returns the pivot value.
|
||||
*
|
||||
* @return {number}
|
||||
*/
|
||||
getPivot() {}
|
||||
|
||||
/**
|
||||
* Sets a field in the specified field number.
|
||||
*
|
||||
* @param {number} fieldNumber
|
||||
* @param {!FieldType} field
|
||||
*/
|
||||
set(fieldNumber, field) {}
|
||||
|
||||
/**
|
||||
* Returns a field at the specified field number.
|
||||
*
|
||||
* @param {number} fieldNumber
|
||||
* @return {!FieldType|undefined}
|
||||
*/
|
||||
get(fieldNumber) {}
|
||||
|
||||
/**
|
||||
* Deletes a field from the specified field number.
|
||||
*
|
||||
* @param {number} fieldNumber
|
||||
*/
|
||||
delete(fieldNumber) {}
|
||||
|
||||
/**
|
||||
* Executes the provided function once for each field.
|
||||
*
|
||||
* @param {function(!FieldType, number): void} callback
|
||||
*/
|
||||
forEach(callback) {}
|
||||
|
||||
/**
|
||||
* Creates a shallow copy of the storage.
|
||||
*
|
||||
* @return {!Storage}
|
||||
*/
|
||||
shallowCopy() {}
|
||||
}
|
||||
|
||||
/**
|
||||
* 85% of the proto fields have a field number <= 24:
|
||||
* https://plx.corp.google.com/scripts2/script_5d._f02af6_0000_23b1_a15f_001a1139dd02
|
||||
*
|
||||
* @type {number}
|
||||
*/
|
||||
// LINT.IfChange
|
||||
Storage.DEFAULT_PIVOT = 24;
|
||||
// LINT.ThenChange(//depot/google3/third_party/protobuf/javascript/runtime/kernel/binary_storage_test.js,
|
||||
// //depot/google3/net/proto2/contrib/js_proto/internal/kernel_message_generator.cc)
|
||||
|
||||
exports = Storage;
|
144
deps/protobuf/js/experimental/runtime/kernel/tag.js
vendored
Normal file
144
deps/protobuf/js/experimental/runtime/kernel/tag.js
vendored
Normal file
@ -0,0 +1,144 @@
|
||||
goog.module('protobuf.binary.tag');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const WireType = goog.require('protobuf.binary.WireType');
|
||||
const {checkCriticalElementIndex, checkCriticalState} = goog.require('protobuf.internal.checks');
|
||||
|
||||
/**
|
||||
* Returns wire type stored in a tag.
|
||||
* Protos store the wire type as the first 3 bit of a tag.
|
||||
* @param {number} tag
|
||||
* @return {!WireType}
|
||||
*/
|
||||
function tagToWireType(tag) {
|
||||
return /** @type {!WireType} */ (tag & 0x07);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the field number stored in a tag.
|
||||
* Protos store the field number in the upper 29 bits of a 32 bit number.
|
||||
* @param {number} tag
|
||||
* @return {number}
|
||||
*/
|
||||
function tagToFieldNumber(tag) {
|
||||
return tag >>> 3;
|
||||
}
|
||||
|
||||
/**
|
||||
* Combines wireType and fieldNumber into a tag.
|
||||
* @param {!WireType} wireType
|
||||
* @param {number} fieldNumber
|
||||
* @return {number}
|
||||
*/
|
||||
function createTag(wireType, fieldNumber) {
|
||||
return (fieldNumber << 3 | wireType) >>> 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the length, in bytes, of the field in the tag stream, less the tag
|
||||
* itself.
|
||||
* Note: This moves the cursor in the bufferDecoder.
|
||||
* @param {!BufferDecoder} bufferDecoder
|
||||
* @param {number} start
|
||||
* @param {!WireType} wireType
|
||||
* @param {number} fieldNumber
|
||||
* @return {number}
|
||||
* @private
|
||||
*/
|
||||
function getTagLength(bufferDecoder, start, wireType, fieldNumber) {
|
||||
bufferDecoder.setCursor(start);
|
||||
skipField(bufferDecoder, wireType, fieldNumber);
|
||||
return bufferDecoder.cursor() - start;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} value
|
||||
* @return {number}
|
||||
*/
|
||||
function get32BitVarintLength(value) {
|
||||
if (value < 0) {
|
||||
return 5;
|
||||
}
|
||||
let size = 1;
|
||||
while (value >= 128) {
|
||||
size++;
|
||||
value >>>= 7;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips over a field.
|
||||
* Note: If the field is a start group the entire group will be skipped, placing
|
||||
* the cursor onto the next field.
|
||||
* @param {!BufferDecoder} bufferDecoder
|
||||
* @param {!WireType} wireType
|
||||
* @param {number} fieldNumber
|
||||
*/
|
||||
function skipField(bufferDecoder, wireType, fieldNumber) {
|
||||
switch (wireType) {
|
||||
case WireType.VARINT:
|
||||
checkCriticalElementIndex(
|
||||
bufferDecoder.cursor(), bufferDecoder.endIndex());
|
||||
bufferDecoder.skipVarint();
|
||||
return;
|
||||
case WireType.FIXED64:
|
||||
bufferDecoder.skip(8);
|
||||
return;
|
||||
case WireType.DELIMITED:
|
||||
checkCriticalElementIndex(
|
||||
bufferDecoder.cursor(), bufferDecoder.endIndex());
|
||||
const length = bufferDecoder.getUnsignedVarint32();
|
||||
bufferDecoder.skip(length);
|
||||
return;
|
||||
case WireType.START_GROUP:
|
||||
const foundGroup = skipGroup_(bufferDecoder, fieldNumber);
|
||||
checkCriticalState(foundGroup, 'No end group found.');
|
||||
return;
|
||||
case WireType.FIXED32:
|
||||
bufferDecoder.skip(4);
|
||||
return;
|
||||
default:
|
||||
throw new Error(`Unexpected wire type: ${wireType}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Skips over fields until it finds the end of a given group consuming the stop
|
||||
* group tag.
|
||||
* @param {!BufferDecoder} bufferDecoder
|
||||
* @param {number} groupFieldNumber
|
||||
* @return {boolean} Whether the end group tag was found.
|
||||
* @private
|
||||
*/
|
||||
function skipGroup_(bufferDecoder, groupFieldNumber) {
|
||||
// On a start group we need to keep skipping fields until we find a
|
||||
// corresponding stop group
|
||||
// Note: Since we are calling skipField from here nested groups will be
|
||||
// handled by recursion of this method and thus we will not see a nested
|
||||
// STOP GROUP here unless there is something wrong with the input data.
|
||||
while (bufferDecoder.hasNext()) {
|
||||
const tag = bufferDecoder.getUnsignedVarint32();
|
||||
const wireType = tagToWireType(tag);
|
||||
const fieldNumber = tagToFieldNumber(tag);
|
||||
|
||||
if (wireType === WireType.END_GROUP) {
|
||||
checkCriticalState(
|
||||
groupFieldNumber === fieldNumber,
|
||||
`Expected stop group for fieldnumber ${groupFieldNumber} not found.`);
|
||||
return true;
|
||||
} else {
|
||||
skipField(bufferDecoder, wireType, fieldNumber);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
exports = {
|
||||
createTag,
|
||||
get32BitVarintLength,
|
||||
getTagLength,
|
||||
skipField,
|
||||
tagToWireType,
|
||||
tagToFieldNumber,
|
||||
};
|
221
deps/protobuf/js/experimental/runtime/kernel/tag_test.js
vendored
Normal file
221
deps/protobuf/js/experimental/runtime/kernel/tag_test.js
vendored
Normal file
@ -0,0 +1,221 @@
|
||||
/**
|
||||
* @fileoverview Tests for tag.js.
|
||||
*/
|
||||
goog.module('protobuf.binary.TagTests');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const WireType = goog.require('protobuf.binary.WireType');
|
||||
const {CHECK_CRITICAL_STATE} = goog.require('protobuf.internal.checks');
|
||||
const {createTag, get32BitVarintLength, skipField, tagToFieldNumber, tagToWireType} = goog.require('protobuf.binary.tag');
|
||||
|
||||
|
||||
goog.setTestOnly();
|
||||
|
||||
/**
|
||||
* @param {...number} bytes
|
||||
* @return {!ArrayBuffer}
|
||||
*/
|
||||
function createArrayBuffer(...bytes) {
|
||||
return new Uint8Array(bytes).buffer;
|
||||
}
|
||||
|
||||
describe('skipField', () => {
|
||||
it('skips varints', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x00));
|
||||
skipField(bufferDecoder, WireType.VARINT, 1);
|
||||
expect(bufferDecoder.cursor()).toBe(2);
|
||||
});
|
||||
|
||||
it('throws for out of bounds varints', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x00));
|
||||
bufferDecoder.setCursor(2);
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => skipField(bufferDecoder, WireType.VARINT, 1)).toThrowError();
|
||||
}
|
||||
});
|
||||
|
||||
it('skips fixed64', () => {
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(
|
||||
createArrayBuffer(0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00));
|
||||
skipField(bufferDecoder, WireType.FIXED64, 1);
|
||||
expect(bufferDecoder.cursor()).toBe(8);
|
||||
});
|
||||
|
||||
it('throws for fixed64 if length is too short', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x00));
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => skipField(bufferDecoder, WireType.FIXED64, 1))
|
||||
.toThrowError();
|
||||
}
|
||||
});
|
||||
|
||||
it('skips fixed32', () => {
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(
|
||||
createArrayBuffer(0x80, 0x00, 0x00, 0x00));
|
||||
skipField(bufferDecoder, WireType.FIXED32, 1);
|
||||
expect(bufferDecoder.cursor()).toBe(4);
|
||||
});
|
||||
|
||||
it('throws for fixed32 if length is too short', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x80, 0x00));
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => skipField(bufferDecoder, WireType.FIXED32, 1))
|
||||
.toThrowError();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
it('skips length delimited', () => {
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(
|
||||
createArrayBuffer(0x03, 0x00, 0x00, 0x00));
|
||||
skipField(bufferDecoder, WireType.DELIMITED, 1);
|
||||
expect(bufferDecoder.cursor()).toBe(4);
|
||||
});
|
||||
|
||||
it('throws for length delimited if length is too short', () => {
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x03, 0x00, 0x00));
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => skipField(bufferDecoder, WireType.DELIMITED, 1))
|
||||
.toThrowError();
|
||||
}
|
||||
});
|
||||
|
||||
it('skips groups', () => {
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(
|
||||
createArrayBuffer(0x0B, 0x08, 0x01, 0x0C));
|
||||
bufferDecoder.setCursor(1);
|
||||
skipField(bufferDecoder, WireType.START_GROUP, 1);
|
||||
expect(bufferDecoder.cursor()).toBe(4);
|
||||
});
|
||||
|
||||
it('skips group in group', () => {
|
||||
const buffer = createArrayBuffer(
|
||||
0x0B, // start outer
|
||||
0x10, 0x01, // field: 2, value: 1
|
||||
0x0B, // start inner group
|
||||
0x10, 0x01, // payload inner group
|
||||
0x0C, // stop inner group
|
||||
0x0C // end outer
|
||||
);
|
||||
const bufferDecoder = BufferDecoder.fromArrayBuffer(buffer);
|
||||
bufferDecoder.setCursor(1);
|
||||
skipField(bufferDecoder, WireType.START_GROUP, 1);
|
||||
expect(bufferDecoder.cursor()).toBe(8);
|
||||
});
|
||||
|
||||
it('throws for group if length is too short', () => {
|
||||
// no closing group
|
||||
const bufferDecoder =
|
||||
BufferDecoder.fromArrayBuffer(createArrayBuffer(0x0B, 0x00, 0x00));
|
||||
if (CHECK_CRITICAL_STATE) {
|
||||
expect(() => skipField(bufferDecoder, WireType.START_GROUP, 1))
|
||||
.toThrowError();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
describe('tagToWireType', () => {
|
||||
it('decodes numbers ', () => {
|
||||
// simple numbers
|
||||
expect(tagToWireType(0x00)).toBe(WireType.VARINT);
|
||||
expect(tagToWireType(0x01)).toBe(WireType.FIXED64);
|
||||
expect(tagToWireType(0x02)).toBe(WireType.DELIMITED);
|
||||
expect(tagToWireType(0x03)).toBe(WireType.START_GROUP);
|
||||
expect(tagToWireType(0x04)).toBe(WireType.END_GROUP);
|
||||
expect(tagToWireType(0x05)).toBe(WireType.FIXED32);
|
||||
|
||||
// upper bits should not matter
|
||||
expect(tagToWireType(0x08)).toBe(WireType.VARINT);
|
||||
expect(tagToWireType(0x09)).toBe(WireType.FIXED64);
|
||||
expect(tagToWireType(0x0A)).toBe(WireType.DELIMITED);
|
||||
expect(tagToWireType(0x0B)).toBe(WireType.START_GROUP);
|
||||
expect(tagToWireType(0x0C)).toBe(WireType.END_GROUP);
|
||||
expect(tagToWireType(0x0D)).toBe(WireType.FIXED32);
|
||||
|
||||
// upper bits should not matter
|
||||
expect(tagToWireType(0xF8)).toBe(WireType.VARINT);
|
||||
expect(tagToWireType(0xF9)).toBe(WireType.FIXED64);
|
||||
expect(tagToWireType(0xFA)).toBe(WireType.DELIMITED);
|
||||
expect(tagToWireType(0xFB)).toBe(WireType.START_GROUP);
|
||||
expect(tagToWireType(0xFC)).toBe(WireType.END_GROUP);
|
||||
expect(tagToWireType(0xFD)).toBe(WireType.FIXED32);
|
||||
|
||||
// negative numbers work
|
||||
expect(tagToWireType(-8)).toBe(WireType.VARINT);
|
||||
expect(tagToWireType(-7)).toBe(WireType.FIXED64);
|
||||
expect(tagToWireType(-6)).toBe(WireType.DELIMITED);
|
||||
expect(tagToWireType(-5)).toBe(WireType.START_GROUP);
|
||||
expect(tagToWireType(-4)).toBe(WireType.END_GROUP);
|
||||
expect(tagToWireType(-3)).toBe(WireType.FIXED32);
|
||||
});
|
||||
});
|
||||
|
||||
describe('tagToFieldNumber', () => {
|
||||
it('returns fieldNumber', () => {
|
||||
expect(tagToFieldNumber(0x08)).toBe(1);
|
||||
expect(tagToFieldNumber(0x09)).toBe(1);
|
||||
expect(tagToFieldNumber(0x10)).toBe(2);
|
||||
expect(tagToFieldNumber(0x12)).toBe(2);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createTag', () => {
|
||||
it('combines fieldNumber and wireType', () => {
|
||||
expect(createTag(WireType.VARINT, 1)).toBe(0x08);
|
||||
expect(createTag(WireType.FIXED64, 1)).toBe(0x09);
|
||||
expect(createTag(WireType.DELIMITED, 1)).toBe(0x0A);
|
||||
expect(createTag(WireType.START_GROUP, 1)).toBe(0x0B);
|
||||
expect(createTag(WireType.END_GROUP, 1)).toBe(0x0C);
|
||||
expect(createTag(WireType.FIXED32, 1)).toBe(0x0D);
|
||||
|
||||
expect(createTag(WireType.VARINT, 2)).toBe(0x10);
|
||||
expect(createTag(WireType.FIXED64, 2)).toBe(0x11);
|
||||
expect(createTag(WireType.DELIMITED, 2)).toBe(0x12);
|
||||
expect(createTag(WireType.START_GROUP, 2)).toBe(0x13);
|
||||
expect(createTag(WireType.END_GROUP, 2)).toBe(0x14);
|
||||
expect(createTag(WireType.FIXED32, 2)).toBe(0x15);
|
||||
|
||||
expect(createTag(WireType.VARINT, 0x1FFFFFFF)).toBe(0xFFFFFFF8 >>> 0);
|
||||
expect(createTag(WireType.FIXED64, 0x1FFFFFFF)).toBe(0xFFFFFFF9 >>> 0);
|
||||
expect(createTag(WireType.DELIMITED, 0x1FFFFFFF)).toBe(0xFFFFFFFA >>> 0);
|
||||
expect(createTag(WireType.START_GROUP, 0x1FFFFFFF)).toBe(0xFFFFFFFB >>> 0);
|
||||
expect(createTag(WireType.END_GROUP, 0x1FFFFFFF)).toBe(0xFFFFFFFC >>> 0);
|
||||
expect(createTag(WireType.FIXED32, 0x1FFFFFFF)).toBe(0xFFFFFFFD >>> 0);
|
||||
});
|
||||
});
|
||||
|
||||
describe('get32BitVarintLength', () => {
|
||||
it('length of tag', () => {
|
||||
expect(get32BitVarintLength(0)).toBe(1);
|
||||
expect(get32BitVarintLength(1)).toBe(1);
|
||||
expect(get32BitVarintLength(1)).toBe(1);
|
||||
|
||||
expect(get32BitVarintLength(Math.pow(2, 7) - 1)).toBe(1);
|
||||
expect(get32BitVarintLength(Math.pow(2, 7))).toBe(2);
|
||||
|
||||
expect(get32BitVarintLength(Math.pow(2, 14) - 1)).toBe(2);
|
||||
expect(get32BitVarintLength(Math.pow(2, 14))).toBe(3);
|
||||
|
||||
expect(get32BitVarintLength(Math.pow(2, 21) - 1)).toBe(3);
|
||||
expect(get32BitVarintLength(Math.pow(2, 21))).toBe(4);
|
||||
|
||||
expect(get32BitVarintLength(Math.pow(2, 28) - 1)).toBe(4);
|
||||
expect(get32BitVarintLength(Math.pow(2, 28))).toBe(5);
|
||||
|
||||
expect(get32BitVarintLength(Math.pow(2, 31) - 1)).toBe(5);
|
||||
|
||||
expect(get32BitVarintLength(-1)).toBe(5);
|
||||
expect(get32BitVarintLength(-Math.pow(2, 31))).toBe(5);
|
||||
|
||||
expect(get32BitVarintLength(createTag(WireType.VARINT, 0x1fffffff)))
|
||||
.toBe(5);
|
||||
expect(get32BitVarintLength(createTag(WireType.FIXED32, 0x1fffffff)))
|
||||
.toBe(5);
|
||||
});
|
||||
});
|
116
deps/protobuf/js/experimental/runtime/kernel/textencoding.js
vendored
Normal file
116
deps/protobuf/js/experimental/runtime/kernel/textencoding.js
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @fileoverview A UTF8 decoder.
|
||||
*/
|
||||
goog.module('protobuf.binary.textencoding');
|
||||
|
||||
const {checkElementIndex} = goog.require('protobuf.internal.checks');
|
||||
|
||||
/**
|
||||
* Combines an array of codePoints into a string.
|
||||
* @param {!Array<number>} codePoints
|
||||
* @return {string}
|
||||
*/
|
||||
function codePointsToString(codePoints) {
|
||||
// Performance: http://jsperf.com/string-fromcharcode-test/13
|
||||
let s = '', i = 0;
|
||||
const length = codePoints.length;
|
||||
const BATCH_SIZE = 10000;
|
||||
while (i < length) {
|
||||
const end = Math.min(i + BATCH_SIZE, length);
|
||||
s += String.fromCharCode.apply(null, codePoints.slice(i, end));
|
||||
i = end;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decodes raw bytes into a string.
|
||||
* Supports codepoints from U+0000 up to U+10FFFF.
|
||||
* (http://en.wikipedia.org/wiki/UTF-8).
|
||||
* @param {!DataView} bytes
|
||||
* @return {string}
|
||||
*/
|
||||
function decode(bytes) {
|
||||
let cursor = 0;
|
||||
const codePoints = [];
|
||||
|
||||
while (cursor < bytes.byteLength) {
|
||||
const c = bytes.getUint8(cursor++);
|
||||
if (c < 0x80) { // Regular 7-bit ASCII.
|
||||
codePoints.push(c);
|
||||
} else if (c < 0xC0) {
|
||||
// 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 < 0xE0) { // UTF-8 with two bytes.
|
||||
checkElementIndex(cursor, bytes.byteLength);
|
||||
const c2 = bytes.getUint8(cursor++);
|
||||
codePoints.push(((c & 0x1F) << 6) | (c2 & 0x3F));
|
||||
} else if (c < 0xF0) { // UTF-8 with three bytes.
|
||||
checkElementIndex(cursor + 1, bytes.byteLength);
|
||||
const c2 = bytes.getUint8(cursor++);
|
||||
const c3 = bytes.getUint8(cursor++);
|
||||
codePoints.push(((c & 0xF) << 12) | ((c2 & 0x3F) << 6) | (c3 & 0x3F));
|
||||
} else if (c < 0xF8) { // UTF-8 with 4 bytes.
|
||||
checkElementIndex(cursor + 2, bytes.byteLength);
|
||||
const c2 = bytes.getUint8(cursor++);
|
||||
const c3 = bytes.getUint8(cursor++);
|
||||
const c4 = bytes.getUint8(cursor++);
|
||||
// Characters written on 4 bytes have 21 bits for a codepoint.
|
||||
// We can't fit that on 16bit characters, so we use surrogates.
|
||||
let codepoint = ((c & 0x07) << 18) | ((c2 & 0x3F) << 12) |
|
||||
((c3 & 0x3F) << 6) | (c4 & 0x3F);
|
||||
// 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:
|
||||
const low = (codepoint & 0x3FF) + 0xDC00;
|
||||
const high = ((codepoint >> 10) & 0x3FF) + 0xD800;
|
||||
codePoints.push(high, low);
|
||||
}
|
||||
}
|
||||
return codePointsToString(codePoints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a UTF16 JavaScript string to the buffer encoded as UTF8.
|
||||
* @param {string} value The string to write.
|
||||
* @return {!Uint8Array} An array containing the encoded bytes.
|
||||
*/
|
||||
function encode(value) {
|
||||
const buffer = [];
|
||||
|
||||
for (let i = 0; i < value.length; i++) {
|
||||
const c1 = value.charCodeAt(i);
|
||||
|
||||
if (c1 < 0x80) {
|
||||
buffer.push(c1);
|
||||
} else if (c1 < 0x800) {
|
||||
buffer.push((c1 >> 6) | 0xC0);
|
||||
buffer.push((c1 & 0x3F) | 0x80);
|
||||
} else if (c1 < 0xD800 || c1 >= 0xE000) {
|
||||
buffer.push((c1 >> 12) | 0xE0);
|
||||
buffer.push(((c1 >> 6) & 0x3F) | 0x80);
|
||||
buffer.push((c1 & 0x3F) | 0x80);
|
||||
} else {
|
||||
// surrogate pair
|
||||
i++;
|
||||
checkElementIndex(i, value.length);
|
||||
const c2 = value.charCodeAt(i);
|
||||
const paired = 0x10000 + (((c1 & 0x3FF) << 10) | (c2 & 0x3FF));
|
||||
buffer.push((paired >> 18) | 0xF0);
|
||||
buffer.push(((paired >> 12) & 0x3F) | 0x80);
|
||||
buffer.push(((paired >> 6) & 0x3F) | 0x80);
|
||||
buffer.push((paired & 0x3F) | 0x80);
|
||||
}
|
||||
}
|
||||
return new Uint8Array(buffer);
|
||||
}
|
||||
|
||||
exports = {
|
||||
decode,
|
||||
encode,
|
||||
};
|
113
deps/protobuf/js/experimental/runtime/kernel/textencoding_test.js
vendored
Normal file
113
deps/protobuf/js/experimental/runtime/kernel/textencoding_test.js
vendored
Normal file
@ -0,0 +1,113 @@
|
||||
/**
|
||||
* @fileoverview Tests for textdecoder.js.
|
||||
*/
|
||||
goog.module('protobuf.binary.TextDecoderTest');
|
||||
|
||||
goog.setTestOnly();
|
||||
|
||||
const {decode, encode} = goog.require('protobuf.binary.textencoding');
|
||||
|
||||
describe('Decode does', () => {
|
||||
it('return empty string for empty array', () => {
|
||||
expect(decode(new DataView(new ArrayBuffer(0)))).toEqual('');
|
||||
});
|
||||
|
||||
it('throw on null being passed', () => {
|
||||
expect(() => decode(/** @type {!DataView} */ (/** @type {*} */ (null))))
|
||||
.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Encode does', () => {
|
||||
it('return empty array for empty string', () => {
|
||||
expect(encode('')).toEqual(new Uint8Array(0));
|
||||
});
|
||||
|
||||
it('throw on null being passed', () => {
|
||||
expect(() => encode(/** @type {string} */ (/** @type {*} */ (null))))
|
||||
.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
/** @const {!TextEncoder} */
|
||||
const textEncoder = new TextEncoder('utf-8');
|
||||
|
||||
/**
|
||||
* A Pair of string and Uint8Array representing the same data.
|
||||
* Each pair has the string value and its utf-8 bytes.
|
||||
*/
|
||||
class Pair {
|
||||
/**
|
||||
* Constructs a pair from a given string.
|
||||
* @param {string} s
|
||||
* @return {!Pair}
|
||||
*/
|
||||
static fromString(s) {
|
||||
return new Pair(s, textEncoder.encode(s).buffer);
|
||||
}
|
||||
/**
|
||||
* Constructs a pair from a given charCode.
|
||||
* @param {number} charCode
|
||||
* @return {!Pair}
|
||||
*/
|
||||
static fromCharCode(charCode) {
|
||||
return Pair.fromString(String.fromCharCode(charCode));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} stringValue
|
||||
* @param {!ArrayBuffer} bytes
|
||||
* @private
|
||||
*/
|
||||
constructor(stringValue, bytes) {
|
||||
/** @const @private {string} */
|
||||
this.stringValue_ = stringValue;
|
||||
/** @const @private {!ArrayBuffer} */
|
||||
this.bytes_ = bytes;
|
||||
}
|
||||
|
||||
/** Ensures that a given pair encodes and decodes round trip*/
|
||||
expectPairToMatch() {
|
||||
expect(decode(new DataView(this.bytes_))).toEqual(this.stringValue_);
|
||||
expect(encode(this.stringValue_)).toEqual(new Uint8Array(this.bytes_));
|
||||
}
|
||||
}
|
||||
|
||||
describe('textencoding does', () => {
|
||||
it('works for empty string', () => {
|
||||
Pair.fromString('').expectPairToMatch();
|
||||
});
|
||||
|
||||
it('decode and encode random strings', () => {
|
||||
// 1 byte strings
|
||||
Pair.fromString('hello').expectPairToMatch();
|
||||
Pair.fromString('HELLO1!');
|
||||
|
||||
// 2 byte String
|
||||
Pair.fromString('©').expectPairToMatch();
|
||||
|
||||
// 3 byte string
|
||||
Pair.fromString('❄').expectPairToMatch();
|
||||
|
||||
// 4 byte string
|
||||
Pair.fromString('😁').expectPairToMatch();
|
||||
});
|
||||
|
||||
it('decode and encode 1 byte strings', () => {
|
||||
for (let i = 0; i < 0x80; i++) {
|
||||
Pair.fromCharCode(i).expectPairToMatch();
|
||||
}
|
||||
});
|
||||
|
||||
it('decode and encode 2 byte strings', () => {
|
||||
for (let i = 0xC0; i < 0x7FF; i++) {
|
||||
Pair.fromCharCode(i).expectPairToMatch();
|
||||
}
|
||||
});
|
||||
|
||||
it('decode and encode 3 byte strings', () => {
|
||||
for (let i = 0x7FF; i < 0x8FFF; i++) {
|
||||
Pair.fromCharCode(i).expectPairToMatch();
|
||||
}
|
||||
});
|
||||
});
|
116
deps/protobuf/js/experimental/runtime/kernel/typed_arrays.js
vendored
Normal file
116
deps/protobuf/js/experimental/runtime/kernel/typed_arrays.js
vendored
Normal file
@ -0,0 +1,116 @@
|
||||
/**
|
||||
* @fileoverview Helper methods for typed arrays.
|
||||
*/
|
||||
goog.module('protobuf.binary.typedArrays');
|
||||
|
||||
const {assert} = goog.require('goog.asserts');
|
||||
|
||||
/**
|
||||
* @param {!ArrayBuffer} buffer1
|
||||
* @param {!ArrayBuffer} buffer2
|
||||
* @return {boolean}
|
||||
*/
|
||||
function arrayBufferEqual(buffer1, buffer2) {
|
||||
if (!buffer1 || !buffer2) {
|
||||
throw new Error('Buffer shouldn\'t be empty');
|
||||
}
|
||||
|
||||
const array1 = new Uint8Array(buffer1);
|
||||
const array2 = new Uint8Array(buffer2);
|
||||
|
||||
return uint8ArrayEqual(array1, array2);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {!Uint8Array} array1
|
||||
* @param {!Uint8Array} array2
|
||||
* @return {boolean}
|
||||
*/
|
||||
function uint8ArrayEqual(array1, array2) {
|
||||
if (array1 === array2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (array1.byteLength !== array2.byteLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < array1.byteLength; i++) {
|
||||
if (array1[i] !== array2[i]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* ArrayBuffer.prototype.slice, but fallback to manual copy if missing.
|
||||
* @param {!ArrayBuffer} buffer
|
||||
* @param {number} start
|
||||
* @param {number=} end
|
||||
* @return {!ArrayBuffer} New array buffer with given the contents of `buffer`.
|
||||
*/
|
||||
function arrayBufferSlice(buffer, start, end = undefined) {
|
||||
// The fallback isn't fully compatible with ArrayBuffer.slice, enforce
|
||||
// strict requirements on start/end.
|
||||
// Spec:
|
||||
// https://www.ecma-international.org/ecma-262/6.0/#sec-arraybuffer.prototype.slice
|
||||
assert(start >= 0);
|
||||
assert(end === undefined || (end >= 0 && end <= buffer.byteLength));
|
||||
assert((end === undefined ? buffer.byteLength : end) >= start);
|
||||
if (buffer.slice) {
|
||||
const slicedBuffer = buffer.slice(start, end);
|
||||
// The ArrayBuffer.prototype.slice function was flawed before iOS 12.2. This
|
||||
// causes 0-length results when passing undefined or a number greater
|
||||
// than 32 bits for the optional end value. In these cases, we fall back to
|
||||
// using our own slice implementation.
|
||||
// More details: https://bugs.webkit.org/show_bug.cgi?id=185127
|
||||
if (slicedBuffer.byteLength !== 0 || (start === end)) {
|
||||
return slicedBuffer;
|
||||
}
|
||||
}
|
||||
const realEnd = end == null ? buffer.byteLength : end;
|
||||
const length = realEnd - start;
|
||||
assert(length >= 0);
|
||||
const view = new Uint8Array(buffer, start, length);
|
||||
// A TypedArray constructed from another Typed array copies the data.
|
||||
const clone = new Uint8Array(view);
|
||||
|
||||
return clone.buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new Uint8Array with the size and contents of the given
|
||||
* ArrayBufferView. ArrayBufferView is an interface implemented by DataView,
|
||||
* Uint8Array and all typed arrays.
|
||||
* @param {!ArrayBufferView} view
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function cloneArrayBufferView(view) {
|
||||
return new Uint8Array(arrayBufferSlice(
|
||||
view.buffer, view.byteOffset, view.byteOffset + view.byteLength));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a 32 bit number for the corresponding Uint8Array.
|
||||
* @param {!Uint8Array} array
|
||||
* @return {number}
|
||||
*/
|
||||
function hashUint8Array(array) {
|
||||
const prime = 31;
|
||||
let result = 17;
|
||||
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
// '| 0' ensures signed 32 bits
|
||||
result = (result * prime + array[i]) | 0;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
exports = {
|
||||
arrayBufferEqual,
|
||||
uint8ArrayEqual,
|
||||
arrayBufferSlice,
|
||||
cloneArrayBufferView,
|
||||
hashUint8Array,
|
||||
};
|
191
deps/protobuf/js/experimental/runtime/kernel/typed_arrays_test.js
vendored
Normal file
191
deps/protobuf/js/experimental/runtime/kernel/typed_arrays_test.js
vendored
Normal file
@ -0,0 +1,191 @@
|
||||
/**
|
||||
* @fileoverview Tests for typed_arrays.js.
|
||||
*/
|
||||
goog.module('protobuf.binary.typedArraysTest');
|
||||
|
||||
const {arrayBufferEqual, arrayBufferSlice, cloneArrayBufferView, hashUint8Array, uint8ArrayEqual} = goog.require('protobuf.binary.typedArrays');
|
||||
|
||||
describe('arrayBufferEqual', () => {
|
||||
it('returns true for empty buffers', () => {
|
||||
const buffer1 = new ArrayBuffer(0);
|
||||
const buffer2 = new ArrayBuffer(0);
|
||||
expect(arrayBufferEqual(buffer1, buffer2)).toBe(true);
|
||||
});
|
||||
|
||||
it('throws for first null buffers', () => {
|
||||
const buffer = new ArrayBuffer(0);
|
||||
expect(
|
||||
() => arrayBufferEqual(
|
||||
/** @type {!ArrayBuffer} */ (/** @type {*} */ (null)), buffer))
|
||||
.toThrow();
|
||||
});
|
||||
|
||||
it('throws for second null buffers', () => {
|
||||
const buffer = new ArrayBuffer(0);
|
||||
expect(
|
||||
() => arrayBufferEqual(
|
||||
buffer, /** @type {!ArrayBuffer} */ (/** @type {*} */ (null))))
|
||||
.toThrow();
|
||||
});
|
||||
|
||||
it('returns true for arrays with same values', () => {
|
||||
const array1 = new Uint8Array(4);
|
||||
array1[0] = 1;
|
||||
const array2 = new Uint8Array(4);
|
||||
array2[0] = 1;
|
||||
expect(arrayBufferEqual(array1.buffer, array2.buffer)).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false for arrays with different values', () => {
|
||||
const array1 = new Uint8Array(4);
|
||||
array1[0] = 1;
|
||||
const array2 = new Uint8Array(4);
|
||||
array2[0] = 2;
|
||||
expect(arrayBufferEqual(array1.buffer, array2.buffer)).toBe(false);
|
||||
});
|
||||
|
||||
it('returns true same instance', () => {
|
||||
const array1 = new Uint8Array(4);
|
||||
array1[0] = 1;
|
||||
expect(arrayBufferEqual(array1.buffer, array1.buffer)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('uint8ArrayEqual', () => {
|
||||
it('returns true for empty arrays', () => {
|
||||
const array1 = new Uint8Array(0);
|
||||
const array2 = new Uint8Array(0);
|
||||
expect(uint8ArrayEqual(array1, array2)).toBe(true);
|
||||
});
|
||||
|
||||
it('throws for first Uint8Array array', () => {
|
||||
const array = new Uint8Array(0);
|
||||
expect(
|
||||
() => uint8ArrayEqual(
|
||||
/** @type {!Uint8Array} */ (/** @type {*} */ (null)), array))
|
||||
.toThrow();
|
||||
});
|
||||
|
||||
it('throws for second null array', () => {
|
||||
const array = new Uint8Array(0);
|
||||
expect(
|
||||
() => uint8ArrayEqual(
|
||||
array, /** @type {!Uint8Array} */ (/** @type {*} */ (null))))
|
||||
.toThrow();
|
||||
});
|
||||
|
||||
it('returns true for arrays with same values', () => {
|
||||
const buffer1 = new Uint8Array([0, 1, 2, 3]).buffer;
|
||||
const buffer2 = new Uint8Array([1, 2, 3, 4]).buffer;
|
||||
const array1 = new Uint8Array(buffer1, 1, 3);
|
||||
const array2 = new Uint8Array(buffer2, 0, 3);
|
||||
expect(uint8ArrayEqual(array1, array2)).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false for arrays with different values', () => {
|
||||
const array1 = new Uint8Array(4);
|
||||
array1[0] = 1;
|
||||
const array2 = new Uint8Array(4);
|
||||
array2[0] = 2;
|
||||
expect(uint8ArrayEqual(array1, array2)).toBe(false);
|
||||
});
|
||||
|
||||
it('returns true same instance', () => {
|
||||
const array1 = new Uint8Array(4);
|
||||
array1[0] = 1;
|
||||
expect(uint8ArrayEqual(array1, array1)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('arrayBufferSlice', () => {
|
||||
it('Returns a new instance.', () => {
|
||||
const buffer1 = new ArrayBuffer(0);
|
||||
const buffer2 = arrayBufferSlice(buffer1, 0);
|
||||
expect(buffer2).not.toBe(buffer1);
|
||||
expect(arrayBufferEqual(buffer1, buffer2)).toBe(true);
|
||||
});
|
||||
|
||||
it('Copies data with positive start/end.', () => {
|
||||
const buffer1 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).buffer;
|
||||
expect(buffer1.byteLength).toEqual(10);
|
||||
|
||||
const buffer2 = arrayBufferSlice(buffer1, 2, 6);
|
||||
expect(buffer2.byteLength).toEqual(4);
|
||||
expect(buffer2).not.toBe(buffer1);
|
||||
const expected = new Uint8Array([2, 3, 4, 5]).buffer;
|
||||
expect(arrayBufferEqual(expected, buffer2)).toBe(true);
|
||||
});
|
||||
|
||||
it('Copies all data without end.', () => {
|
||||
const buffer1 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).buffer;
|
||||
expect(buffer1.byteLength).toEqual(10);
|
||||
|
||||
const buffer2 = arrayBufferSlice(buffer1, 0);
|
||||
expect(buffer2.byteLength).toEqual(10);
|
||||
expect(arrayBufferEqual(buffer1, buffer2)).toBe(true);
|
||||
});
|
||||
|
||||
if (goog.DEBUG) {
|
||||
it('Fails with negative end.', () => {
|
||||
const buffer1 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).buffer;
|
||||
expect(() => void arrayBufferSlice(buffer1, 2, -1)).toThrow();
|
||||
});
|
||||
|
||||
it('Fails with negative start.', () => {
|
||||
const buffer1 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).buffer;
|
||||
expect(() => void arrayBufferSlice(buffer1, 2, -1)).toThrow();
|
||||
});
|
||||
|
||||
it('Fails when start > end.', () => {
|
||||
const buffer1 = new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).buffer;
|
||||
expect(() => void arrayBufferSlice(buffer1, 2, 1)).toThrow();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('cloneArrayBufferView', () => {
|
||||
it('Returns a new instance.', () => {
|
||||
const array1 = new Uint8Array(0);
|
||||
const array2 = cloneArrayBufferView(new Uint8Array(array1));
|
||||
expect(array2).not.toBe(array1);
|
||||
expect(uint8ArrayEqual(array1, array2)).toBe(true);
|
||||
});
|
||||
|
||||
it('Returns an array of the exact size.', () => {
|
||||
const array1 =
|
||||
new Uint8Array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]).subarray(2, 5);
|
||||
expect(array1.length).toEqual(3);
|
||||
expect(array1.buffer.byteLength).toEqual(10);
|
||||
const array2 = cloneArrayBufferView(array1);
|
||||
expect(array2.byteLength).toEqual(3);
|
||||
expect(array2).toEqual(new Uint8Array([2, 3, 4]));
|
||||
});
|
||||
});
|
||||
|
||||
describe('hashUint8Array', () => {
|
||||
it('returns same hashcode for empty Uint8Arrays', () => {
|
||||
const array1 = new Uint8Array(0);
|
||||
const array2 = new Uint8Array(0);
|
||||
expect(hashUint8Array(array1)).toBe(hashUint8Array(array2));
|
||||
});
|
||||
|
||||
it('returns same hashcode for Uint8Arrays with same values', () => {
|
||||
const array1 = new Uint8Array(4);
|
||||
array1[0] = 1;
|
||||
const array2 = new Uint8Array(4);
|
||||
array2[0] = 1;
|
||||
expect(hashUint8Array(array1)).toBe(hashUint8Array(array2));
|
||||
});
|
||||
|
||||
it('returns different hashcode for Uint8Arrays with different values', () => {
|
||||
// This test might fail in the future if the hashing algorithm is updated
|
||||
// and we end up with a collision here.
|
||||
// We still need this test to make sure that we are not just returning
|
||||
// the same number for all buffers.
|
||||
const array1 = new Uint8Array(4);
|
||||
array1[0] = 1;
|
||||
const array2 = new Uint8Array(4);
|
||||
array2[0] = 2;
|
||||
expect(hashUint8Array(array1)).not.toBe(hashUint8Array(array2));
|
||||
});
|
||||
});
|
68
deps/protobuf/js/experimental/runtime/kernel/uint32_test_pairs.js
vendored
Normal file
68
deps/protobuf/js/experimental/runtime/kernel/uint32_test_pairs.js
vendored
Normal file
@ -0,0 +1,68 @@
|
||||
/**
|
||||
* @fileoverview Test data for int32 encoding and decoding.
|
||||
*/
|
||||
goog.module('protobuf.binary.uint32TestPairs');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const {createBufferDecoder} = goog.require('protobuf.binary.bufferDecoderHelper');
|
||||
|
||||
/**
|
||||
* An array of Pairs of float values and their bit representation.
|
||||
* This is used to test encoding and decoding from/to the protobuf wire format.
|
||||
* @return {!Array<{name: string, intValue:number, bufferDecoder:
|
||||
* !BufferDecoder, error: (boolean|undefined),
|
||||
* skip_reader: (boolean|undefined), skip_writer: (boolean|undefined)}>}
|
||||
*/
|
||||
function getUint32Pairs() {
|
||||
const uint32Pairs = [
|
||||
{
|
||||
name: 'zero',
|
||||
intValue: 0,
|
||||
bufferDecoder: createBufferDecoder(0x00),
|
||||
},
|
||||
{
|
||||
name: 'one ',
|
||||
intValue: 1,
|
||||
bufferDecoder: createBufferDecoder(0x01),
|
||||
},
|
||||
{
|
||||
name: 'max signed int 2^31 - 1',
|
||||
intValue: Math.pow(2, 31) - 1,
|
||||
bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x07),
|
||||
},
|
||||
{
|
||||
name: 'max unsigned int 2^32 - 1',
|
||||
intValue: Math.pow(2, 32) - 1,
|
||||
bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x0F),
|
||||
},
|
||||
{
|
||||
name: 'negative one',
|
||||
intValue: -1,
|
||||
bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x0F),
|
||||
skip_reader: true,
|
||||
},
|
||||
{
|
||||
name: 'truncates more than 32 bits',
|
||||
intValue: Math.pow(2, 32) - 1,
|
||||
bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'truncates more than 32 bits (bit 33 set)',
|
||||
intValue: Math.pow(2, 28) - 1,
|
||||
bufferDecoder: createBufferDecoder(0xFF, 0xFF, 0xFF, 0xFF, 0x10),
|
||||
skip_writer: true,
|
||||
},
|
||||
{
|
||||
name: 'errors out for 11 bytes',
|
||||
intValue: Math.pow(2, 32) - 1,
|
||||
bufferDecoder: createBufferDecoder(
|
||||
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF),
|
||||
error: true,
|
||||
skip_writer: true,
|
||||
},
|
||||
];
|
||||
return [...uint32Pairs];
|
||||
}
|
||||
|
||||
exports = {getUint32Pairs};
|
28
deps/protobuf/js/experimental/runtime/kernel/uint8arrays.js
vendored
Normal file
28
deps/protobuf/js/experimental/runtime/kernel/uint8arrays.js
vendored
Normal file
@ -0,0 +1,28 @@
|
||||
/**
|
||||
* @fileoverview Helper methods for Uint8Arrays.
|
||||
*/
|
||||
goog.module('protobuf.binary.uint8arrays');
|
||||
|
||||
/**
|
||||
* Combines multiple bytes arrays (either Uint8Array or number array whose
|
||||
* values are bytes) into a single Uint8Array.
|
||||
* @param {!Array<!Uint8Array>|!Array<!Array<number>>} arrays
|
||||
* @return {!Uint8Array}
|
||||
*/
|
||||
function concatenateByteArrays(arrays) {
|
||||
let totalLength = 0;
|
||||
for (const array of arrays) {
|
||||
totalLength += array.length;
|
||||
}
|
||||
const result = new Uint8Array(totalLength);
|
||||
let offset = 0;
|
||||
for (const array of arrays) {
|
||||
result.set(array, offset);
|
||||
offset += array.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
exports = {
|
||||
concatenateByteArrays,
|
||||
};
|
47
deps/protobuf/js/experimental/runtime/kernel/uint8arrays_test.js
vendored
Normal file
47
deps/protobuf/js/experimental/runtime/kernel/uint8arrays_test.js
vendored
Normal file
@ -0,0 +1,47 @@
|
||||
/**
|
||||
* @fileoverview Tests for uint8arrays.js.
|
||||
*/
|
||||
goog.module('protobuf.binary.Uint8ArraysTest');
|
||||
|
||||
goog.setTestOnly();
|
||||
|
||||
const {concatenateByteArrays} = goog.require('protobuf.binary.uint8arrays');
|
||||
|
||||
describe('concatenateByteArrays does', () => {
|
||||
it('concatenate empty array', () => {
|
||||
const byteArrays = [];
|
||||
expect(concatenateByteArrays(byteArrays)).toEqual(new Uint8Array(0));
|
||||
});
|
||||
|
||||
it('concatenate Uint8Arrays', () => {
|
||||
const byteArrays = [new Uint8Array([0x01]), new Uint8Array([0x02])];
|
||||
expect(concatenateByteArrays(byteArrays)).toEqual(new Uint8Array([
|
||||
0x01, 0x02
|
||||
]));
|
||||
});
|
||||
|
||||
it('concatenate array of bytes', () => {
|
||||
const byteArrays = [[0x01], [0x02]];
|
||||
expect(concatenateByteArrays(byteArrays)).toEqual(new Uint8Array([
|
||||
0x01, 0x02
|
||||
]));
|
||||
});
|
||||
|
||||
it('concatenate array of non-bytes', () => {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
const byteArrays = [[40.0], [256]];
|
||||
expect(concatenateByteArrays(byteArrays)).toEqual(new Uint8Array([
|
||||
0x28, 0x00
|
||||
]));
|
||||
});
|
||||
|
||||
it('throw for null array', () => {
|
||||
expect(
|
||||
() => concatenateByteArrays(
|
||||
/** @type {!Array<!Uint8Array>} */ (/** @type {*} */ (null))))
|
||||
.toThrow();
|
||||
});
|
||||
});
|
17
deps/protobuf/js/experimental/runtime/kernel/wire_type.js
vendored
Normal file
17
deps/protobuf/js/experimental/runtime/kernel/wire_type.js
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
goog.module('protobuf.binary.WireType');
|
||||
|
||||
/**
|
||||
* Wire-format type codes, taken from proto2/public/wire_format_lite.h.
|
||||
* @enum {number}
|
||||
*/
|
||||
const WireType = {
|
||||
VARINT: 0,
|
||||
FIXED64: 1,
|
||||
DELIMITED: 2,
|
||||
START_GROUP: 3,
|
||||
END_GROUP: 4,
|
||||
FIXED32: 5,
|
||||
INVALID: 6
|
||||
};
|
||||
|
||||
exports = WireType;
|
743
deps/protobuf/js/experimental/runtime/kernel/writer.js
vendored
Normal file
743
deps/protobuf/js/experimental/runtime/kernel/writer.js
vendored
Normal file
@ -0,0 +1,743 @@
|
||||
/**
|
||||
* @fileoverview Implements Writer for writing data as the binary wire format
|
||||
* bytes array.
|
||||
*/
|
||||
goog.module('protobuf.binary.Writer');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const ByteString = goog.require('protobuf.ByteString');
|
||||
const Int64 = goog.require('protobuf.Int64');
|
||||
const WireType = goog.require('protobuf.binary.WireType');
|
||||
const {POLYFILL_TEXT_ENCODING, checkFieldNumber, checkTypeUnsignedInt32, checkWireType} = goog.require('protobuf.internal.checks');
|
||||
const {concatenateByteArrays} = goog.require('protobuf.binary.uint8arrays');
|
||||
const {createTag, getTagLength} = goog.require('protobuf.binary.tag');
|
||||
const {encode} = goog.require('protobuf.binary.textencoding');
|
||||
|
||||
/**
|
||||
* Returns a valid utf-8 encoder function based on TextEncoder if available or
|
||||
* a polyfill.
|
||||
* Some of the environments we run in do not have TextEncoder defined.
|
||||
* TextEncoder is faster than our polyfill so we prefer it over the polyfill.
|
||||
* @return {function(string):!Uint8Array}
|
||||
*/
|
||||
function getEncoderFunction() {
|
||||
if (goog.global['TextEncoder']) {
|
||||
const textEncoder = new goog.global['TextEncoder']('utf-8');
|
||||
return s => s.length === 0 ? new Uint8Array(0) : textEncoder.encode(s);
|
||||
}
|
||||
if (POLYFILL_TEXT_ENCODING) {
|
||||
return encode;
|
||||
} else {
|
||||
throw new Error(
|
||||
'TextEncoder is missing. ' +
|
||||
'Enable protobuf.defines.POLYFILL_TEXT_ENCODING');
|
||||
}
|
||||
}
|
||||
|
||||
/** @const {function(string): !Uint8Array} */
|
||||
const encoderFunction = getEncoderFunction();
|
||||
|
||||
/**
|
||||
* Writer provides methods for encoding all protobuf supported type into a
|
||||
* binary format bytes array.
|
||||
* Check https://developers.google.com/protocol-buffers/docs/encoding for binary
|
||||
* format definition.
|
||||
* @final
|
||||
* @package
|
||||
*/
|
||||
class Writer {
|
||||
constructor() {
|
||||
/**
|
||||
* Blocks of data that needs to be serialized. After writing all the data,
|
||||
* the blocks are concatenated into a single Uint8Array.
|
||||
* @private {!Array<!Uint8Array>}
|
||||
*/
|
||||
this.blocks_ = [];
|
||||
|
||||
/**
|
||||
* A buffer for writing varint data (tag number + field number for each
|
||||
* field, int32, uint32 etc.). Before writing a non-varint data block
|
||||
* (string, fixed32 etc.), the buffer is appended to the block array as a
|
||||
* new block, and a new buffer is started.
|
||||
*
|
||||
* We could've written each varint as a new block instead of writing
|
||||
* multiple varints in this buffer. But this will increase the number of
|
||||
* blocks, and concatenating many small blocks is slower than concatenating
|
||||
* few large blocks.
|
||||
*
|
||||
* TODO: Experiment with writing data in a fixed-length
|
||||
* Uint8Array instead of using a growing buffer.
|
||||
*
|
||||
* @private {!Array<number>}
|
||||
*/
|
||||
this.currentBuffer_ = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts the encoded data into a Uint8Array.
|
||||
* The writer is also reset.
|
||||
* @return {!ArrayBuffer}
|
||||
*/
|
||||
getAndResetResultBuffer() {
|
||||
this.closeAndStartNewBuffer_();
|
||||
const result = concatenateByteArrays(this.blocks_);
|
||||
this.blocks_ = [];
|
||||
return result.buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a (field number, wire type) tuple into a wire-format field header.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!WireType} wireType
|
||||
*/
|
||||
writeTag(fieldNumber, wireType) {
|
||||
checkFieldNumber(fieldNumber);
|
||||
checkWireType(wireType);
|
||||
const tag = createTag(wireType, fieldNumber);
|
||||
this.writeUnsignedVarint32_(tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the current buffer into the blocks array and starts a new buffer.
|
||||
* @private
|
||||
*/
|
||||
closeAndStartNewBuffer_() {
|
||||
this.blocks_.push(new Uint8Array(this.currentBuffer_));
|
||||
this.currentBuffer_ = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes a 32-bit integer into its wire-format varint representation and
|
||||
* stores it in the buffer.
|
||||
* @param {number} value
|
||||
* @private
|
||||
*/
|
||||
writeUnsignedVarint32_(value) {
|
||||
checkTypeUnsignedInt32(value);
|
||||
while (value > 0x7f) {
|
||||
this.currentBuffer_.push((value & 0x7f) | 0x80);
|
||||
value = value >>> 7;
|
||||
}
|
||||
this.currentBuffer_.push(value);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* OPTIONAL METHODS
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* Writes a boolean value field to the buffer as a varint.
|
||||
* @param {boolean} value
|
||||
* @private
|
||||
*/
|
||||
writeBoolValue_(value) {
|
||||
this.currentBuffer_.push(value ? 1 : 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a boolean value field to the buffer as a varint.
|
||||
* @param {number} fieldNumber
|
||||
* @param {boolean} value
|
||||
*/
|
||||
writeBool(fieldNumber, value) {
|
||||
this.writeTag(fieldNumber, WireType.VARINT);
|
||||
this.writeBoolValue_(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a bytes value field to the buffer as a length delimited field.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!ByteString} value
|
||||
*/
|
||||
writeBytes(fieldNumber, value) {
|
||||
this.writeTag(fieldNumber, WireType.DELIMITED);
|
||||
const buffer = value.toArrayBuffer();
|
||||
this.writeUnsignedVarint32_(buffer.byteLength);
|
||||
this.writeRaw_(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a double value field to the buffer without tag.
|
||||
* @param {number} value
|
||||
* @private
|
||||
*/
|
||||
writeDoubleValue_(value) {
|
||||
const buffer = new ArrayBuffer(8);
|
||||
const view = new DataView(buffer);
|
||||
view.setFloat64(0, value, true);
|
||||
this.writeRaw_(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a double value field to the buffer.
|
||||
* @param {number} fieldNumber
|
||||
* @param {number} value
|
||||
*/
|
||||
writeDouble(fieldNumber, value) {
|
||||
this.writeTag(fieldNumber, WireType.FIXED64);
|
||||
this.writeDoubleValue_(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a fixed32 value field to the buffer without tag.
|
||||
* @param {number} value
|
||||
* @private
|
||||
*/
|
||||
writeFixed32Value_(value) {
|
||||
const buffer = new ArrayBuffer(4);
|
||||
const view = new DataView(buffer);
|
||||
view.setUint32(0, value, true);
|
||||
this.writeRaw_(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a fixed32 value field to the buffer.
|
||||
* @param {number} fieldNumber
|
||||
* @param {number} value
|
||||
*/
|
||||
writeFixed32(fieldNumber, value) {
|
||||
this.writeTag(fieldNumber, WireType.FIXED32);
|
||||
this.writeFixed32Value_(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a float value field to the buffer without tag.
|
||||
* @param {number} value
|
||||
* @private
|
||||
*/
|
||||
writeFloatValue_(value) {
|
||||
const buffer = new ArrayBuffer(4);
|
||||
const view = new DataView(buffer);
|
||||
view.setFloat32(0, value, true);
|
||||
this.writeRaw_(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a float value field to the buffer.
|
||||
* @param {number} fieldNumber
|
||||
* @param {number} value
|
||||
*/
|
||||
writeFloat(fieldNumber, value) {
|
||||
this.writeTag(fieldNumber, WireType.FIXED32);
|
||||
this.writeFloatValue_(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a int32 value field to the buffer as a varint without tag.
|
||||
* @param {number} value
|
||||
* @private
|
||||
*/
|
||||
writeInt32Value_(value) {
|
||||
if (value >= 0) {
|
||||
this.writeVarint64_(0, value);
|
||||
} else {
|
||||
this.writeVarint64_(0xFFFFFFFF, value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a int32 value field to the buffer as a varint.
|
||||
* @param {number} fieldNumber
|
||||
* @param {number} value
|
||||
*/
|
||||
writeInt32(fieldNumber, value) {
|
||||
this.writeTag(fieldNumber, WireType.VARINT);
|
||||
this.writeInt32Value_(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a int64 value field to the buffer as a varint.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Int64} value
|
||||
*/
|
||||
writeInt64(fieldNumber, value) {
|
||||
this.writeTag(fieldNumber, WireType.VARINT);
|
||||
this.writeVarint64_(value.getHighBits(), value.getLowBits());
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a sfixed32 value field to the buffer.
|
||||
* @param {number} value
|
||||
* @private
|
||||
*/
|
||||
writeSfixed32Value_(value) {
|
||||
const buffer = new ArrayBuffer(4);
|
||||
const view = new DataView(buffer);
|
||||
view.setInt32(0, value, true);
|
||||
this.writeRaw_(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a sfixed32 value field to the buffer.
|
||||
* @param {number} fieldNumber
|
||||
* @param {number} value
|
||||
*/
|
||||
writeSfixed32(fieldNumber, value) {
|
||||
this.writeTag(fieldNumber, WireType.FIXED32);
|
||||
this.writeSfixed32Value_(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a sfixed64 value field to the buffer without tag.
|
||||
* @param {!Int64} value
|
||||
* @private
|
||||
*/
|
||||
writeSfixed64Value_(value) {
|
||||
const buffer = new ArrayBuffer(8);
|
||||
const view = new DataView(buffer);
|
||||
view.setInt32(0, value.getLowBits(), true);
|
||||
view.setInt32(4, value.getHighBits(), true);
|
||||
this.writeRaw_(buffer);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a sfixed64 value field to the buffer.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Int64} value
|
||||
*/
|
||||
writeSfixed64(fieldNumber, value) {
|
||||
this.writeTag(fieldNumber, WireType.FIXED64);
|
||||
this.writeSfixed64Value_(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a sfixed64 value field to the buffer.
|
||||
* @param {number} fieldNumber
|
||||
*/
|
||||
writeStartGroup(fieldNumber) {
|
||||
this.writeTag(fieldNumber, WireType.START_GROUP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a sfixed64 value field to the buffer.
|
||||
* @param {number} fieldNumber
|
||||
*/
|
||||
writeEndGroup(fieldNumber) {
|
||||
this.writeTag(fieldNumber, WireType.END_GROUP);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a uint32 value field to the buffer as a varint without tag.
|
||||
* @param {number} value
|
||||
* @private
|
||||
*/
|
||||
writeUint32Value_(value) {
|
||||
this.writeVarint64_(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a uint32 value field to the buffer as a varint.
|
||||
* @param {number} fieldNumber
|
||||
* @param {number} value
|
||||
*/
|
||||
writeUint32(fieldNumber, value) {
|
||||
this.writeTag(fieldNumber, WireType.VARINT);
|
||||
this.writeUint32Value_(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes the bits of a 64 bit number to the buffer as a varint.
|
||||
* @param {number} highBits
|
||||
* @param {number} lowBits
|
||||
* @private
|
||||
*/
|
||||
writeVarint64_(highBits, lowBits) {
|
||||
for (let i = 0; i < 28; i = i + 7) {
|
||||
const shift = lowBits >>> i;
|
||||
const hasNext = !((shift >>> 7) === 0 && highBits === 0);
|
||||
const byte = (hasNext ? shift | 0x80 : shift) & 0xFF;
|
||||
this.currentBuffer_.push(byte);
|
||||
if (!hasNext) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const splitBits = ((lowBits >>> 28) & 0x0F) | ((highBits & 0x07) << 4);
|
||||
const hasMoreBits = !((highBits >> 3) === 0);
|
||||
this.currentBuffer_.push(
|
||||
(hasMoreBits ? splitBits | 0x80 : splitBits) & 0xFF);
|
||||
|
||||
if (!hasMoreBits) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (let i = 3; i < 31; i = i + 7) {
|
||||
const shift = highBits >>> i;
|
||||
const hasNext = !((shift >>> 7) === 0);
|
||||
const byte = (hasNext ? shift | 0x80 : shift) & 0xFF;
|
||||
this.currentBuffer_.push(byte);
|
||||
if (!hasNext) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.currentBuffer_.push((highBits >>> 31) & 0x01);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a sint32 value field to the buffer as a varint without tag.
|
||||
* @param {number} value
|
||||
* @private
|
||||
*/
|
||||
writeSint32Value_(value) {
|
||||
value = (value << 1) ^ (value >> 31);
|
||||
this.writeVarint64_(0, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a sint32 value field to the buffer as a varint.
|
||||
* @param {number} fieldNumber
|
||||
* @param {number} value
|
||||
*/
|
||||
writeSint32(fieldNumber, value) {
|
||||
this.writeTag(fieldNumber, WireType.VARINT);
|
||||
this.writeSint32Value_(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a sint64 value field to the buffer as a varint without tag.
|
||||
* @param {!Int64} value
|
||||
* @private
|
||||
*/
|
||||
writeSint64Value_(value) {
|
||||
const highBits = value.getHighBits();
|
||||
const lowBits = value.getLowBits();
|
||||
|
||||
const sign = highBits >> 31;
|
||||
const encodedLowBits = (lowBits << 1) ^ sign;
|
||||
const encodedHighBits = ((highBits << 1) | (lowBits >>> 31)) ^ sign;
|
||||
this.writeVarint64_(encodedHighBits, encodedLowBits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a sint64 value field to the buffer as a varint.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Int64} value
|
||||
*/
|
||||
writeSint64(fieldNumber, value) {
|
||||
this.writeTag(fieldNumber, WireType.VARINT);
|
||||
this.writeSint64Value_(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes a string value field to the buffer as a varint.
|
||||
* @param {number} fieldNumber
|
||||
* @param {string} value
|
||||
*/
|
||||
writeString(fieldNumber, value) {
|
||||
this.writeTag(fieldNumber, WireType.DELIMITED);
|
||||
const array = encoderFunction(value);
|
||||
this.writeUnsignedVarint32_(array.length);
|
||||
this.closeAndStartNewBuffer_();
|
||||
this.blocks_.push(array);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes raw bytes to the buffer.
|
||||
* @param {!ArrayBuffer} arrayBuffer
|
||||
* @private
|
||||
*/
|
||||
writeRaw_(arrayBuffer) {
|
||||
this.closeAndStartNewBuffer_();
|
||||
this.blocks_.push(new Uint8Array(arrayBuffer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes raw bytes to the buffer.
|
||||
* @param {!BufferDecoder} bufferDecoder
|
||||
* @param {number} start
|
||||
* @param {!WireType} wireType
|
||||
* @param {number} fieldNumber
|
||||
* @package
|
||||
*/
|
||||
writeBufferDecoder(bufferDecoder, start, wireType, fieldNumber) {
|
||||
this.closeAndStartNewBuffer_();
|
||||
const dataLength =
|
||||
getTagLength(bufferDecoder, start, wireType, fieldNumber);
|
||||
this.blocks_.push(
|
||||
bufferDecoder.subBufferDecoder(start, dataLength).asUint8Array());
|
||||
}
|
||||
|
||||
/**
|
||||
* Write the whole bytes as a length delimited field.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!ArrayBuffer} arrayBuffer
|
||||
*/
|
||||
writeDelimited(fieldNumber, arrayBuffer) {
|
||||
this.writeTag(fieldNumber, WireType.DELIMITED);
|
||||
this.writeUnsignedVarint32_(arrayBuffer.byteLength);
|
||||
this.writeRaw_(arrayBuffer);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* REPEATED METHODS
|
||||
****************************************************************************/
|
||||
|
||||
/**
|
||||
* Writes repeated boolean values to the buffer as unpacked varints.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<boolean>} values
|
||||
*/
|
||||
writeRepeatedBool(fieldNumber, values) {
|
||||
values.forEach(val => this.writeBool(fieldNumber, val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated boolean values to the buffer as packed varints.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<boolean>} values
|
||||
*/
|
||||
writePackedBool(fieldNumber, values) {
|
||||
this.writeFixedPacked_(
|
||||
fieldNumber, values, val => this.writeBoolValue_(val), 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated double values to the buffer as unpacked fixed64.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<number>} values
|
||||
*/
|
||||
writeRepeatedDouble(fieldNumber, values) {
|
||||
values.forEach(val => this.writeDouble(fieldNumber, val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated double values to the buffer as packed fixed64.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<number>} values
|
||||
*/
|
||||
writePackedDouble(fieldNumber, values) {
|
||||
this.writeFixedPacked_(
|
||||
fieldNumber, values, val => this.writeDoubleValue_(val), 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated fixed32 values to the buffer as unpacked fixed32.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<number>} values
|
||||
*/
|
||||
writeRepeatedFixed32(fieldNumber, values) {
|
||||
values.forEach(val => this.writeFixed32(fieldNumber, val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated fixed32 values to the buffer as packed fixed32.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<number>} values
|
||||
*/
|
||||
writePackedFixed32(fieldNumber, values) {
|
||||
this.writeFixedPacked_(
|
||||
fieldNumber, values, val => this.writeFixed32Value_(val), 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated float values to the buffer as unpacked fixed64.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<number>} values
|
||||
*/
|
||||
writeRepeatedFloat(fieldNumber, values) {
|
||||
values.forEach(val => this.writeFloat(fieldNumber, val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated float values to the buffer as packed fixed64.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<number>} values
|
||||
*/
|
||||
writePackedFloat(fieldNumber, values) {
|
||||
this.writeFixedPacked_(
|
||||
fieldNumber, values, val => this.writeFloatValue_(val), 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated int32 values to the buffer as unpacked int32.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<number>} values
|
||||
*/
|
||||
writeRepeatedInt32(fieldNumber, values) {
|
||||
values.forEach(val => this.writeInt32(fieldNumber, val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated int32 values to the buffer as packed int32.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<number>} values
|
||||
*/
|
||||
writePackedInt32(fieldNumber, values) {
|
||||
this.writeVariablePacked_(
|
||||
fieldNumber, values, (writer, val) => writer.writeInt32Value_(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated int64 values to the buffer as unpacked varint.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<!Int64>} values
|
||||
*/
|
||||
writeRepeatedInt64(fieldNumber, values) {
|
||||
values.forEach(val => this.writeInt64(fieldNumber, val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated int64 values to the buffer as packed varint.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<!Int64>} values
|
||||
*/
|
||||
writePackedInt64(fieldNumber, values) {
|
||||
this.writeVariablePacked_(
|
||||
fieldNumber, values,
|
||||
(writer, val) =>
|
||||
writer.writeVarint64_(val.getHighBits(), val.getLowBits()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated sfixed32 values to the buffer as unpacked fixed32.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<number>} values
|
||||
*/
|
||||
writeRepeatedSfixed32(fieldNumber, values) {
|
||||
values.forEach(val => this.writeSfixed32(fieldNumber, val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated sfixed32 values to the buffer as packed fixed32.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<number>} values
|
||||
*/
|
||||
writePackedSfixed32(fieldNumber, values) {
|
||||
this.writeFixedPacked_(
|
||||
fieldNumber, values, val => this.writeSfixed32Value_(val), 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated sfixed64 values to the buffer as unpacked fixed64.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<!Int64>} values
|
||||
*/
|
||||
writeRepeatedSfixed64(fieldNumber, values) {
|
||||
values.forEach(val => this.writeSfixed64(fieldNumber, val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated sfixed64 values to the buffer as packed fixed64.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<!Int64>} values
|
||||
*/
|
||||
writePackedSfixed64(fieldNumber, values) {
|
||||
this.writeFixedPacked_(
|
||||
fieldNumber, values, val => this.writeSfixed64Value_(val), 8);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated sint32 values to the buffer as unpacked sint32.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<number>} values
|
||||
*/
|
||||
writeRepeatedSint32(fieldNumber, values) {
|
||||
values.forEach(val => this.writeSint32(fieldNumber, val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated sint32 values to the buffer as packed sint32.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<number>} values
|
||||
*/
|
||||
writePackedSint32(fieldNumber, values) {
|
||||
this.writeVariablePacked_(
|
||||
fieldNumber, values, (writer, val) => writer.writeSint32Value_(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated sint64 values to the buffer as unpacked varint.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<!Int64>} values
|
||||
*/
|
||||
writeRepeatedSint64(fieldNumber, values) {
|
||||
values.forEach(val => this.writeSint64(fieldNumber, val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated sint64 values to the buffer as packed varint.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<!Int64>} values
|
||||
*/
|
||||
writePackedSint64(fieldNumber, values) {
|
||||
this.writeVariablePacked_(
|
||||
fieldNumber, values, (writer, val) => writer.writeSint64Value_(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated uint32 values to the buffer as unpacked uint32.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<number>} values
|
||||
*/
|
||||
writeRepeatedUint32(fieldNumber, values) {
|
||||
values.forEach(val => this.writeUint32(fieldNumber, val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated uint32 values to the buffer as packed uint32.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<number>} values
|
||||
*/
|
||||
writePackedUint32(fieldNumber, values) {
|
||||
this.writeVariablePacked_(
|
||||
fieldNumber, values, (writer, val) => writer.writeUint32Value_(val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated bytes values to the buffer.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<!ByteString>} values
|
||||
*/
|
||||
writeRepeatedBytes(fieldNumber, values) {
|
||||
values.forEach(val => this.writeBytes(fieldNumber, val));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes packed fields with fixed length.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<T>} values
|
||||
* @param {function(T)} valueWriter
|
||||
* @param {number} entitySize
|
||||
* @template T
|
||||
* @private
|
||||
*/
|
||||
writeFixedPacked_(fieldNumber, values, valueWriter, entitySize) {
|
||||
if (values.length === 0) {
|
||||
return;
|
||||
}
|
||||
this.writeTag(fieldNumber, WireType.DELIMITED);
|
||||
this.writeUnsignedVarint32_(values.length * entitySize);
|
||||
this.closeAndStartNewBuffer_();
|
||||
values.forEach(value => valueWriter(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes packed fields with variable length.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<T>} values
|
||||
* @param {function(!Writer, T)} valueWriter
|
||||
* @template T
|
||||
* @private
|
||||
*/
|
||||
writeVariablePacked_(fieldNumber, values, valueWriter) {
|
||||
if (values.length === 0) {
|
||||
return;
|
||||
}
|
||||
const writer = new Writer();
|
||||
values.forEach(val => valueWriter(writer, val));
|
||||
const bytes = writer.getAndResetResultBuffer();
|
||||
this.writeDelimited(fieldNumber, bytes);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes repeated string values to the buffer.
|
||||
* @param {number} fieldNumber
|
||||
* @param {!Array<string>} values
|
||||
*/
|
||||
writeRepeatedString(fieldNumber, values) {
|
||||
values.forEach(val => this.writeString(fieldNumber, val));
|
||||
}
|
||||
}
|
||||
|
||||
exports = Writer;
|
927
deps/protobuf/js/experimental/runtime/kernel/writer_test.js
vendored
Normal file
927
deps/protobuf/js/experimental/runtime/kernel/writer_test.js
vendored
Normal file
@ -0,0 +1,927 @@
|
||||
/**
|
||||
* @fileoverview Tests for writer.js.
|
||||
*/
|
||||
goog.module('protobuf.binary.WriterTest');
|
||||
|
||||
goog.setTestOnly();
|
||||
|
||||
// Note to the reader:
|
||||
// Since the writer behavior changes with the checking level some of the tests
|
||||
// in this file have to know which checking level is enable to make correct
|
||||
// assertions.
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const ByteString = goog.require('protobuf.ByteString');
|
||||
const WireType = goog.require('protobuf.binary.WireType');
|
||||
const Writer = goog.require('protobuf.binary.Writer');
|
||||
const {CHECK_BOUNDS, CHECK_TYPE, MAX_FIELD_NUMBER} = goog.require('protobuf.internal.checks');
|
||||
const {arrayBufferSlice} = goog.require('protobuf.binary.typedArrays');
|
||||
const {getDoublePairs} = goog.require('protobuf.binary.doubleTestPairs');
|
||||
const {getFixed32Pairs} = goog.require('protobuf.binary.fixed32TestPairs');
|
||||
const {getFloatPairs} = goog.require('protobuf.binary.floatTestPairs');
|
||||
const {getInt32Pairs} = goog.require('protobuf.binary.int32TestPairs');
|
||||
const {getInt64Pairs} = goog.require('protobuf.binary.int64TestPairs');
|
||||
const {getPackedBoolPairs} = goog.require('protobuf.binary.packedBoolTestPairs');
|
||||
const {getPackedDoublePairs} = goog.require('protobuf.binary.packedDoubleTestPairs');
|
||||
const {getPackedFixed32Pairs} = goog.require('protobuf.binary.packedFixed32TestPairs');
|
||||
const {getPackedFloatPairs} = goog.require('protobuf.binary.packedFloatTestPairs');
|
||||
const {getPackedInt32Pairs} = goog.require('protobuf.binary.packedInt32TestPairs');
|
||||
const {getPackedInt64Pairs} = goog.require('protobuf.binary.packedInt64TestPairs');
|
||||
const {getPackedSfixed32Pairs} = goog.require('protobuf.binary.packedSfixed32TestPairs');
|
||||
const {getPackedSfixed64Pairs} = goog.require('protobuf.binary.packedSfixed64TestPairs');
|
||||
const {getPackedSint32Pairs} = goog.require('protobuf.binary.packedSint32TestPairs');
|
||||
const {getPackedSint64Pairs} = goog.require('protobuf.binary.packedSint64TestPairs');
|
||||
const {getPackedUint32Pairs} = goog.require('protobuf.binary.packedUint32TestPairs');
|
||||
const {getSfixed32Pairs} = goog.require('protobuf.binary.sfixed32TestPairs');
|
||||
const {getSfixed64Pairs} = goog.require('protobuf.binary.sfixed64TestPairs');
|
||||
const {getSint32Pairs} = goog.require('protobuf.binary.sint32TestPairs');
|
||||
const {getSint64Pairs} = goog.require('protobuf.binary.sint64TestPairs');
|
||||
const {getUint32Pairs} = goog.require('protobuf.binary.uint32TestPairs');
|
||||
|
||||
|
||||
/**
|
||||
* @param {...number} bytes
|
||||
* @return {!ArrayBuffer}
|
||||
*/
|
||||
function createArrayBuffer(...bytes) {
|
||||
return new Uint8Array(bytes).buffer;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* OPTIONAL FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
describe('Writer does', () => {
|
||||
it('return an empty ArrayBuffer when nothing is encoded', () => {
|
||||
const writer = new Writer();
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
it('encode tag', () => {
|
||||
const writer = new Writer();
|
||||
writer.writeTag(1, WireType.VARINT);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer(0x08));
|
||||
|
||||
writer.writeTag(0x0FFFFFFF, WireType.VARINT);
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x7));
|
||||
|
||||
writer.writeTag(0x10000000, WireType.VARINT);
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(0x80, 0x80, 0x80, 0x80, 0x08));
|
||||
|
||||
writer.writeTag(0x1FFFFFFF, WireType.VARINT);
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0x0F));
|
||||
});
|
||||
|
||||
it('reset after calling getAndResetResultBuffer', () => {
|
||||
const writer = new Writer();
|
||||
writer.writeTag(1, WireType.VARINT);
|
||||
writer.getAndResetResultBuffer();
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
it('fail when field number is too large for writeTag', () => {
|
||||
const writer = new Writer();
|
||||
if (CHECK_TYPE) {
|
||||
expect(() => writer.writeTag(MAX_FIELD_NUMBER + 1, WireType.VARINT))
|
||||
.toThrowError('Field number is out of range: 536870912');
|
||||
} else {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
writer.writeTag(MAX_FIELD_NUMBER + 1, WireType.VARINT);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer(0));
|
||||
}
|
||||
});
|
||||
|
||||
it('fail when field number is negative for writeTag', () => {
|
||||
const writer = new Writer();
|
||||
if (CHECK_TYPE) {
|
||||
expect(() => writer.writeTag(-1, WireType.VARINT))
|
||||
.toThrowError('Field number is out of range: -1');
|
||||
} else {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
writer.writeTag(-1, WireType.VARINT);
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(0xF8, 0xFF, 0xFF, 0xFF, 0xF));
|
||||
}
|
||||
});
|
||||
|
||||
it('fail when wire type is invalid for writeTag', () => {
|
||||
const writer = new Writer();
|
||||
if (CHECK_TYPE) {
|
||||
expect(() => writer.writeTag(1, /** @type {!WireType} */ (0x08)))
|
||||
.toThrowError('Invalid wire type: 8');
|
||||
} else {
|
||||
// Note in unchecked mode we produce invalid output for invalid inputs.
|
||||
// This test just documents our behavior in those cases.
|
||||
// These values might change at any point and are not considered
|
||||
// what the implementation should be doing here.
|
||||
writer.writeTag(1, /** @type {!WireType} */ (0x08));
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer(0x08));
|
||||
}
|
||||
});
|
||||
|
||||
it('encode singular boolean value', () => {
|
||||
const writer = new Writer();
|
||||
writer.writeBool(1, true);
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(0x08, 0x01));
|
||||
});
|
||||
|
||||
it('encode length delimited', () => {
|
||||
const writer = new Writer();
|
||||
writer.writeDelimited(1, createArrayBuffer(0x01, 0x02));
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(0x0A, 0x02, 0x01, 0x02));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Writer.writeBufferDecoder does', () => {
|
||||
it('encode BufferDecoder containing a varint value', () => {
|
||||
const writer = new Writer();
|
||||
const expected = createArrayBuffer(
|
||||
0x08, /* varint start= */ 0xFF, /* varint end= */ 0x01, 0x08, 0x01);
|
||||
writer.writeBufferDecoder(
|
||||
BufferDecoder.fromArrayBuffer(expected), 1, WireType.VARINT, 1);
|
||||
const result = writer.getAndResetResultBuffer();
|
||||
expect(result).toEqual(arrayBufferSlice(expected, 1, 3));
|
||||
});
|
||||
|
||||
it('encode BufferDecoder containing a fixed64 value', () => {
|
||||
const writer = new Writer();
|
||||
const expected = createArrayBuffer(
|
||||
0x09, /* fixed64 start= */ 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
/* fixed64 end= */ 0x08, 0x08, 0x01);
|
||||
writer.writeBufferDecoder(
|
||||
BufferDecoder.fromArrayBuffer(expected), 1, WireType.FIXED64, 1);
|
||||
const result = writer.getAndResetResultBuffer();
|
||||
expect(result).toEqual(arrayBufferSlice(expected, 1, 9));
|
||||
});
|
||||
|
||||
it('encode BufferDecoder containing a length delimited value', () => {
|
||||
const writer = new Writer();
|
||||
const expected = createArrayBuffer(
|
||||
0xA, /* length= */ 0x03, /* data start= */ 0x01, 0x02,
|
||||
/* data end= */ 0x03, 0x08, 0x01);
|
||||
writer.writeBufferDecoder(
|
||||
BufferDecoder.fromArrayBuffer(expected), 1, WireType.DELIMITED, 1);
|
||||
const result = writer.getAndResetResultBuffer();
|
||||
expect(result).toEqual(arrayBufferSlice(expected, 1, 5));
|
||||
});
|
||||
|
||||
it('encode BufferDecoder containing a group', () => {
|
||||
const writer = new Writer();
|
||||
const expected = createArrayBuffer(
|
||||
0xB, /* group start= */ 0x08, 0x01, /* nested group start= */ 0x0B,
|
||||
/* nested group end= */ 0x0C, /* group end= */ 0x0C, 0x08, 0x01);
|
||||
writer.writeBufferDecoder(
|
||||
BufferDecoder.fromArrayBuffer(expected), 1, WireType.START_GROUP, 1);
|
||||
const result = writer.getAndResetResultBuffer();
|
||||
expect(result).toEqual(arrayBufferSlice(expected, 1, 6));
|
||||
});
|
||||
|
||||
it('encode BufferDecoder containing a fixed32 value', () => {
|
||||
const writer = new Writer();
|
||||
const expected = createArrayBuffer(
|
||||
0x09, /* fixed64 start= */ 0x01, 0x02, 0x03, /* fixed64 end= */ 0x04,
|
||||
0x08, 0x01);
|
||||
writer.writeBufferDecoder(
|
||||
BufferDecoder.fromArrayBuffer(expected), 1, WireType.FIXED32, 1);
|
||||
const result = writer.getAndResetResultBuffer();
|
||||
expect(result).toEqual(arrayBufferSlice(expected, 1, 5));
|
||||
});
|
||||
|
||||
it('fail when encoding out of bound data', () => {
|
||||
const writer = new Writer();
|
||||
const buffer = createArrayBuffer(0x4, 0x0, 0x1, 0x2, 0x3);
|
||||
const subBuffer = arrayBufferSlice(buffer, 0, 2);
|
||||
expect(
|
||||
() => writer.writeBufferDecoder(
|
||||
BufferDecoder.fromArrayBuffer(subBuffer), 0, WireType.DELIMITED, 1))
|
||||
.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Writer.writeBytes does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encodes empty ByteString', () => {
|
||||
writer.writeBytes(1, ByteString.EMPTY);
|
||||
const buffer = writer.getAndResetResultBuffer();
|
||||
expect(buffer.byteLength).toBe(2);
|
||||
});
|
||||
|
||||
it('encodes empty array', () => {
|
||||
writer.writeBytes(1, ByteString.fromArrayBuffer(new ArrayBuffer(0)));
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(
|
||||
1 << 3 | 0x02, // tag (fieldnumber << 3 | (length delimited))
|
||||
0, // length of the bytes
|
||||
));
|
||||
});
|
||||
|
||||
it('encodes ByteString', () => {
|
||||
const array = createArrayBuffer(1, 2, 3);
|
||||
writer.writeBytes(1, ByteString.fromArrayBuffer(array));
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(
|
||||
1 << 3 | 0x02, // tag (fieldnumber << 3 | (length delimited))
|
||||
3, // length of the bytes
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Writer.writeDouble does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
for (const pair of getDoublePairs()) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writeDouble(1, pair.doubleValue);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
expect(buffer.length).toBe(9);
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x09);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, 9))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* NaN may have different value in different browsers. Thus, we need to make
|
||||
* the test lenient.
|
||||
*/
|
||||
it('encode NaN', () => {
|
||||
writer.writeDouble(1, NaN);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
expect(buffer.length).toBe(9);
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x09);
|
||||
// Encoded values are stored right after the tag
|
||||
const float64 = new DataView(buffer.buffer);
|
||||
expect(float64.getFloat64(1, true)).toBeNaN();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Writer.writeFixed32 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
for (const pair of getFixed32Pairs()) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writeFixed32(1, pair.intValue);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
expect(buffer.length).toBe(5);
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0D);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, 5)).toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writeFloat does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
for (const pair of getFloatPairs()) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writeFloat(1, pair.floatValue);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
expect(buffer.length).toBe(5);
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0D);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, 5)).toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* NaN may have different value in different browsers. Thus, we need to make
|
||||
* the test lenient.
|
||||
*/
|
||||
it('encode NaN', () => {
|
||||
writer.writeFloat(1, NaN);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
expect(buffer.length).toBe(5);
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0D);
|
||||
// Encoded values are stored right after the tag
|
||||
const float32 = new DataView(buffer.buffer);
|
||||
expect(float32.getFloat32(1, true)).toBeNaN();
|
||||
});
|
||||
});
|
||||
|
||||
describe('Writer.writeInt32 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
for (const pair of getInt32Pairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writeInt32(1, pair.intValue);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x08);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writeSfixed32 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writePackedSfixed32(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
for (const pair of getSfixed32Pairs()) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writeSfixed32(1, pair.intValue);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
expect(buffer.length).toBe(5);
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0D);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, 5)).toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writeSfixed64 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
for (const pair of getSfixed64Pairs()) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writeSfixed64(1, pair.longValue);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
expect(buffer.length).toBe(9);
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x09);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, 9)).toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writeSint32 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
for (const pair of getSint32Pairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writeSint32(1, pair.intValue);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x08);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writeSint64 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
for (const pair of getSint64Pairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writeSint64(1, pair.longValue);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x08);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writeInt64 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
for (const pair of getInt64Pairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writeInt64(1, pair.longValue);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x08);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writeUint32 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
for (const pair of getUint32Pairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writeUint32(1, pair.intValue);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x08);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writeString does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty string', () => {
|
||||
writer.writeString(1, '');
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(
|
||||
1 << 3 | 0x02, // tag (fieldnumber << 3 | (length delimited))
|
||||
0, // length of the string
|
||||
));
|
||||
});
|
||||
|
||||
it('encode simple string', () => {
|
||||
writer.writeString(1, 'hello');
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(
|
||||
1 << 3 | 0x02, // tag (fieldnumber << 3 | (length delimited))
|
||||
5, // length of the string
|
||||
'h'.charCodeAt(0),
|
||||
'e'.charCodeAt(0),
|
||||
'l'.charCodeAt(0),
|
||||
'l'.charCodeAt(0),
|
||||
'o'.charCodeAt(0),
|
||||
));
|
||||
});
|
||||
|
||||
it('throw for invalid fieldnumber', () => {
|
||||
if (CHECK_BOUNDS) {
|
||||
expect(() => writer.writeString(-1, 'a'))
|
||||
.toThrowError('Field number is out of range: -1');
|
||||
} else {
|
||||
writer.writeString(-1, 'a');
|
||||
expect(new Uint8Array(writer.getAndResetResultBuffer()))
|
||||
.toEqual(new Uint8Array(createArrayBuffer(
|
||||
-6, // invalid tag
|
||||
0xff,
|
||||
0xff,
|
||||
0xff,
|
||||
0x0f,
|
||||
1, // string length
|
||||
'a'.charCodeAt(0),
|
||||
)));
|
||||
}
|
||||
});
|
||||
|
||||
it('throw for null string value', () => {
|
||||
expect(
|
||||
() => writer.writeString(
|
||||
1, /** @type {string} */ (/** @type {*} */ (null))))
|
||||
.toThrow();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* REPEATED FUNCTIONS
|
||||
******************************************************************************/
|
||||
|
||||
describe('Writer.writePackedBool does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writePackedBool(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
for (const pair of getPackedBoolPairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writePackedBool(1, pair.boolValues);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0A);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writeRepeatedBool does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writeRepeatedBool(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
it('encode repeated unpacked boolean values', () => {
|
||||
const writer = new Writer();
|
||||
writer.writeRepeatedBool(1, [true, false]);
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(
|
||||
1 << 3 | 0x00, // tag (fieldnumber << 3 | (varint))
|
||||
0x01, // value[0]
|
||||
1 << 3 | 0x00, // tag (fieldnumber << 3 | (varint))
|
||||
0x00, // value[1]
|
||||
));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Writer.writePackedDouble does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writePackedDouble(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
for (const pair of getPackedDoublePairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writePackedDouble(1, pair.doubleValues);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0A);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writePackedFixed32 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writePackedFixed32(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
for (const pair of getPackedFixed32Pairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writePackedFixed32(1, pair.fixed32Values);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0A);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writePackedFloat does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writePackedFloat(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
for (const pair of getPackedFloatPairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writePackedFloat(1, pair.floatValues);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0A);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writePackedInt32 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writePackedInt32(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
for (const pair of getPackedInt32Pairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writePackedInt32(1, pair.int32Values);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0A);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writePackedInt64 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writePackedInt64(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
for (const pair of getPackedInt64Pairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writePackedInt64(1, pair.int64Values);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0A);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writePackedSfixed32 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writePackedSfixed32(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
for (const pair of getPackedSfixed32Pairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writePackedSfixed32(1, pair.sfixed32Values);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0A);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writePackedSfixed64 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writePackedSfixed64(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
for (const pair of getPackedSfixed64Pairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writePackedSfixed64(1, pair.sfixed64Values);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0A);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writePackedSint32 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writePackedSint32(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
for (const pair of getPackedSint32Pairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writePackedSint32(1, pair.sint32Values);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0A);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writePackedSint64 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writePackedSint64(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
for (const pair of getPackedSint64Pairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writePackedSint64(1, pair.sint64Values);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0A);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writePackedUint32 does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writePackedUint32(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
for (const pair of getPackedUint32Pairs()) {
|
||||
if (!pair.skip_writer) {
|
||||
it(`encode ${pair.name}`, () => {
|
||||
writer.writePackedUint32(1, pair.uint32Values);
|
||||
const buffer = new Uint8Array(writer.getAndResetResultBuffer());
|
||||
// ensure we have a correct tag
|
||||
expect(buffer[0]).toEqual(0x0A);
|
||||
// Encoded values are stored right after the tag
|
||||
expect(buffer.subarray(1, buffer.length))
|
||||
.toEqual(pair.bufferDecoder.asUint8Array());
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
describe('Writer.writeRepeatedBytes does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writeRepeatedBytes(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
it('encode single value', () => {
|
||||
const value = createArrayBuffer(0x61);
|
||||
writer.writeRepeatedBytes(1, [ByteString.fromArrayBuffer(value)]);
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(
|
||||
0x0A,
|
||||
0x01,
|
||||
0x61, // a
|
||||
));
|
||||
});
|
||||
|
||||
it('encode multiple values', () => {
|
||||
const value1 = createArrayBuffer(0x61);
|
||||
const value2 = createArrayBuffer(0x62);
|
||||
writer.writeRepeatedBytes(1, [
|
||||
ByteString.fromArrayBuffer(value1),
|
||||
ByteString.fromArrayBuffer(value2),
|
||||
]);
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(
|
||||
0x0A,
|
||||
0x01,
|
||||
0x61, // a
|
||||
0x0A,
|
||||
0x01,
|
||||
0x62, // b
|
||||
));
|
||||
});
|
||||
});
|
||||
|
||||
describe('Writer.writeRepeatedString does', () => {
|
||||
let writer;
|
||||
beforeEach(() => {
|
||||
writer = new Writer();
|
||||
});
|
||||
|
||||
it('encode empty array', () => {
|
||||
writer.writeRepeatedString(1, []);
|
||||
expect(writer.getAndResetResultBuffer()).toEqual(createArrayBuffer());
|
||||
});
|
||||
|
||||
it('encode single value', () => {
|
||||
writer.writeRepeatedString(1, ['a']);
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(
|
||||
0x0A,
|
||||
0x01,
|
||||
0x61, // a
|
||||
));
|
||||
});
|
||||
|
||||
it('encode multiple values', () => {
|
||||
writer.writeRepeatedString(1, ['a', 'b']);
|
||||
expect(writer.getAndResetResultBuffer())
|
||||
.toEqual(createArrayBuffer(
|
||||
0x0A,
|
||||
0x01,
|
||||
0x61, // a
|
||||
0x0A,
|
||||
0x01,
|
||||
0x62, // b
|
||||
));
|
||||
});
|
||||
});
|
1769
deps/protobuf/js/experimental/runtime/testing/binary/test_message.js
vendored
Normal file
1769
deps/protobuf/js/experimental/runtime/testing/binary/test_message.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
44
deps/protobuf/js/experimental/runtime/testing/ensure_custom_equality_test.js
vendored
Normal file
44
deps/protobuf/js/experimental/runtime/testing/ensure_custom_equality_test.js
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
/**
|
||||
* @fileoverview Tests in this file will fail if our custom equality have not
|
||||
* been installed.
|
||||
* see b/131864652
|
||||
*/
|
||||
|
||||
goog.module('protobuf.testing.ensureCustomEqualityTest');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const ByteString = goog.require('protobuf.ByteString');
|
||||
|
||||
describe('Custom equality', () => {
|
||||
it('ensure that custom equality for ArrayBuffer is installed', () => {
|
||||
const buffer1 = new ArrayBuffer(4);
|
||||
const buffer2 = new ArrayBuffer(4);
|
||||
const array = new Uint8Array(buffer1);
|
||||
array[0] = 1;
|
||||
expect(buffer1).not.toEqual(buffer2);
|
||||
});
|
||||
|
||||
it('ensure that custom equality for ByteString is installed', () => {
|
||||
const HALLO_IN_BASE64 = 'aGFsbG8=';
|
||||
const BYTES_WITH_HALLO = new Uint8Array([
|
||||
'h'.charCodeAt(0),
|
||||
'a'.charCodeAt(0),
|
||||
'l'.charCodeAt(0),
|
||||
'l'.charCodeAt(0),
|
||||
'o'.charCodeAt(0),
|
||||
]);
|
||||
|
||||
const byteString1 = ByteString.fromBase64String(HALLO_IN_BASE64);
|
||||
const byteString2 = ByteString.fromArrayBufferView(BYTES_WITH_HALLO);
|
||||
expect(byteString1).toEqual(byteString2);
|
||||
});
|
||||
|
||||
it('ensure that custom equality for BufferDecoder is installed', () => {
|
||||
const arrayBuffer1 = new Uint8Array([0, 1, 2]).buffer;
|
||||
const arrayBuffer2 = new Uint8Array([0, 1, 2]).buffer;
|
||||
|
||||
const bufferDecoder1 = BufferDecoder.fromArrayBuffer(arrayBuffer1);
|
||||
const bufferDecoder2 = BufferDecoder.fromArrayBuffer(arrayBuffer2);
|
||||
expect(bufferDecoder1).toEqual(bufferDecoder2);
|
||||
});
|
||||
});
|
88
deps/protobuf/js/experimental/runtime/testing/jasmine_protobuf.js
vendored
Normal file
88
deps/protobuf/js/experimental/runtime/testing/jasmine_protobuf.js
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
/**
|
||||
* @fileoverview Installs our custom equality matchers in Jasmine.
|
||||
*/
|
||||
goog.module('protobuf.testing.jasmineProtoBuf');
|
||||
|
||||
const BufferDecoder = goog.require('protobuf.binary.BufferDecoder');
|
||||
const ByteString = goog.require('protobuf.ByteString');
|
||||
const {arrayBufferEqual} = goog.require('protobuf.binary.typedArrays');
|
||||
|
||||
/**
|
||||
* A function that ensures custom equality for ByteStrings.
|
||||
* Since Jasmine compare structure by default Bytestrings might be equal that
|
||||
* are not equal since ArrayBuffers still compare content in g3.
|
||||
* (Jasmine fix upstream: https://github.com/jasmine/jasmine/issues/1687)
|
||||
* Also ByteStrings that are equal might compare non equal in jasmine of the
|
||||
* base64 string has been initialized.
|
||||
* @param {*} first
|
||||
* @param {*} second
|
||||
* @return {boolean|undefined}
|
||||
*/
|
||||
const byteStringEquality = (first, second) => {
|
||||
if (second instanceof ByteString) {
|
||||
return second.equals(first);
|
||||
}
|
||||
|
||||
// Intentionally not returning anything, this signals to jasmine that we
|
||||
// did not perform any equality on the given objects.
|
||||
};
|
||||
|
||||
/**
|
||||
* A function that ensures custom equality for ArrayBuffers.
|
||||
* By default Jasmine does not compare the content of an ArrayBuffer and thus
|
||||
* will return true for buffers with the same length but different content.
|
||||
* @param {*} first
|
||||
* @param {*} second
|
||||
* @return {boolean|undefined}
|
||||
*/
|
||||
const arrayBufferCustomEquality = (first, second) => {
|
||||
if (first instanceof ArrayBuffer && second instanceof ArrayBuffer) {
|
||||
return arrayBufferEqual(first, second);
|
||||
}
|
||||
// Intentionally not returning anything, this signals to jasmine that we
|
||||
// did not perform any equality on the given objects.
|
||||
};
|
||||
|
||||
/**
|
||||
* A function that ensures custom equality for ArrayBuffers.
|
||||
* By default Jasmine does not compare the content of an ArrayBuffer and thus
|
||||
* will return true for buffers with the same length but different content.
|
||||
* @param {*} first
|
||||
* @param {*} second
|
||||
* @return {boolean|undefined}
|
||||
*/
|
||||
const bufferDecoderCustomEquality = (first, second) => {
|
||||
if (first instanceof BufferDecoder && second instanceof BufferDecoder) {
|
||||
return first.asByteString().equals(second.asByteString());
|
||||
}
|
||||
// Intentionally not returning anything, this signals to jasmine that we
|
||||
// did not perform any equality on the given objects.
|
||||
};
|
||||
|
||||
/**
|
||||
* Overrides the default ArrayBuffer toString method ([object ArrayBuffer]) with
|
||||
* a more readable representation.
|
||||
*/
|
||||
function overrideArrayBufferToString() {
|
||||
/**
|
||||
* Returns the hex values of the underlying bytes of the ArrayBuffer.
|
||||
*
|
||||
* @override
|
||||
* @return {string}
|
||||
*/
|
||||
ArrayBuffer.prototype.toString = function() {
|
||||
const arr = Array.from(new Uint8Array(this));
|
||||
return 'ArrayBuffer[' +
|
||||
arr.map((b) => '0x' + (b & 0xFF).toString(16).toUpperCase())
|
||||
.join(', ') +
|
||||
']';
|
||||
};
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
jasmine.addCustomEqualityTester(arrayBufferCustomEquality);
|
||||
jasmine.addCustomEqualityTester(bufferDecoderCustomEquality);
|
||||
jasmine.addCustomEqualityTester(byteStringEquality);
|
||||
|
||||
overrideArrayBufferToString();
|
||||
});
|
Reference in New Issue
Block a user