1ffe3c632Sopenharmony_ci// Protocol Buffers - Google's data interchange format 2ffe3c632Sopenharmony_ci// Copyright 2008 Google Inc. All rights reserved. 3ffe3c632Sopenharmony_ci// https://developers.google.com/protocol-buffers/ 4ffe3c632Sopenharmony_ci// 5ffe3c632Sopenharmony_ci// Redistribution and use in source and binary forms, with or without 6ffe3c632Sopenharmony_ci// modification, are permitted provided that the following conditions are 7ffe3c632Sopenharmony_ci// met: 8ffe3c632Sopenharmony_ci// 9ffe3c632Sopenharmony_ci// * Redistributions of source code must retain the above copyright 10ffe3c632Sopenharmony_ci// notice, this list of conditions and the following disclaimer. 11ffe3c632Sopenharmony_ci// * Redistributions in binary form must reproduce the above 12ffe3c632Sopenharmony_ci// copyright notice, this list of conditions and the following disclaimer 13ffe3c632Sopenharmony_ci// in the documentation and/or other materials provided with the 14ffe3c632Sopenharmony_ci// distribution. 15ffe3c632Sopenharmony_ci// * Neither the name of Google Inc. nor the names of its 16ffe3c632Sopenharmony_ci// contributors may be used to endorse or promote products derived from 17ffe3c632Sopenharmony_ci// this software without specific prior written permission. 18ffe3c632Sopenharmony_ci// 19ffe3c632Sopenharmony_ci// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20ffe3c632Sopenharmony_ci// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21ffe3c632Sopenharmony_ci// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22ffe3c632Sopenharmony_ci// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23ffe3c632Sopenharmony_ci// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24ffe3c632Sopenharmony_ci// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25ffe3c632Sopenharmony_ci// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26ffe3c632Sopenharmony_ci// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27ffe3c632Sopenharmony_ci// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28ffe3c632Sopenharmony_ci// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29ffe3c632Sopenharmony_ci// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30ffe3c632Sopenharmony_ci 31ffe3c632Sopenharmony_ci/** 32ffe3c632Sopenharmony_ci * @fileoverview Test cases for jspb's binary protocol buffer reader. 33ffe3c632Sopenharmony_ci * 34ffe3c632Sopenharmony_ci * There are two particular magic numbers that need to be pointed out - 35ffe3c632Sopenharmony_ci * 2^64-1025 is the largest number representable as both a double and an 36ffe3c632Sopenharmony_ci * unsigned 64-bit integer, and 2^63-513 is the largest number representable as 37ffe3c632Sopenharmony_ci * both a double and a signed 64-bit integer. 38ffe3c632Sopenharmony_ci * 39ffe3c632Sopenharmony_ci * Test suite is written using Jasmine -- see http://jasmine.github.io/ 40ffe3c632Sopenharmony_ci * 41ffe3c632Sopenharmony_ci * @author aappleby@google.com (Austin Appleby) 42ffe3c632Sopenharmony_ci */ 43ffe3c632Sopenharmony_ci 44ffe3c632Sopenharmony_cigoog.require('goog.testing.asserts'); 45ffe3c632Sopenharmony_cigoog.require('jspb.BinaryConstants'); 46ffe3c632Sopenharmony_cigoog.require('jspb.BinaryDecoder'); 47ffe3c632Sopenharmony_cigoog.require('jspb.BinaryReader'); 48ffe3c632Sopenharmony_cigoog.require('jspb.BinaryWriter'); 49ffe3c632Sopenharmony_ci 50ffe3c632Sopenharmony_ci 51ffe3c632Sopenharmony_ci 52ffe3c632Sopenharmony_cidescribe('binaryReaderTest', function() { 53ffe3c632Sopenharmony_ci /** 54ffe3c632Sopenharmony_ci * Tests the reader instance cache. 55ffe3c632Sopenharmony_ci */ 56ffe3c632Sopenharmony_ci it('testInstanceCaches', /** @suppress {visibility} */ function() { 57ffe3c632Sopenharmony_ci var writer = new jspb.BinaryWriter(); 58ffe3c632Sopenharmony_ci var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); 59ffe3c632Sopenharmony_ci writer.writeMessage(1, dummyMessage, goog.nullFunction); 60ffe3c632Sopenharmony_ci writer.writeMessage(2, dummyMessage, goog.nullFunction); 61ffe3c632Sopenharmony_ci 62ffe3c632Sopenharmony_ci var buffer = writer.getResultBuffer(); 63ffe3c632Sopenharmony_ci 64ffe3c632Sopenharmony_ci // Empty the instance caches. 65ffe3c632Sopenharmony_ci jspb.BinaryReader.instanceCache_ = []; 66ffe3c632Sopenharmony_ci 67ffe3c632Sopenharmony_ci // Allocating and then freeing three decoders should leave us with three in 68ffe3c632Sopenharmony_ci // the cache. 69ffe3c632Sopenharmony_ci 70ffe3c632Sopenharmony_ci var decoder1 = jspb.BinaryDecoder.alloc(); 71ffe3c632Sopenharmony_ci var decoder2 = jspb.BinaryDecoder.alloc(); 72ffe3c632Sopenharmony_ci var decoder3 = jspb.BinaryDecoder.alloc(); 73ffe3c632Sopenharmony_ci decoder1.free(); 74ffe3c632Sopenharmony_ci decoder2.free(); 75ffe3c632Sopenharmony_ci decoder3.free(); 76ffe3c632Sopenharmony_ci 77ffe3c632Sopenharmony_ci assertEquals(3, jspb.BinaryDecoder.instanceCache_.length); 78ffe3c632Sopenharmony_ci assertEquals(0, jspb.BinaryReader.instanceCache_.length); 79ffe3c632Sopenharmony_ci 80ffe3c632Sopenharmony_ci // Allocating and then freeing a reader should remove one decoder from its 81ffe3c632Sopenharmony_ci // cache, but it should stay stuck to the reader afterwards since we can't 82ffe3c632Sopenharmony_ci // have a reader without a decoder. 83ffe3c632Sopenharmony_ci jspb.BinaryReader.alloc().free(); 84ffe3c632Sopenharmony_ci 85ffe3c632Sopenharmony_ci assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); 86ffe3c632Sopenharmony_ci assertEquals(1, jspb.BinaryReader.instanceCache_.length); 87ffe3c632Sopenharmony_ci 88ffe3c632Sopenharmony_ci // Allocating a reader should remove a reader from the cache. 89ffe3c632Sopenharmony_ci var reader = jspb.BinaryReader.alloc(buffer); 90ffe3c632Sopenharmony_ci 91ffe3c632Sopenharmony_ci assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); 92ffe3c632Sopenharmony_ci assertEquals(0, jspb.BinaryReader.instanceCache_.length); 93ffe3c632Sopenharmony_ci 94ffe3c632Sopenharmony_ci // Processing the message reuses the current reader. 95ffe3c632Sopenharmony_ci reader.nextField(); 96ffe3c632Sopenharmony_ci assertEquals(1, reader.getFieldNumber()); 97ffe3c632Sopenharmony_ci reader.readMessage(dummyMessage, function() { 98ffe3c632Sopenharmony_ci assertEquals(0, jspb.BinaryReader.instanceCache_.length); 99ffe3c632Sopenharmony_ci }); 100ffe3c632Sopenharmony_ci 101ffe3c632Sopenharmony_ci reader.nextField(); 102ffe3c632Sopenharmony_ci assertEquals(2, reader.getFieldNumber()); 103ffe3c632Sopenharmony_ci reader.readMessage(dummyMessage, function() { 104ffe3c632Sopenharmony_ci assertEquals(0, jspb.BinaryReader.instanceCache_.length); 105ffe3c632Sopenharmony_ci }); 106ffe3c632Sopenharmony_ci 107ffe3c632Sopenharmony_ci assertEquals(false, reader.nextField()); 108ffe3c632Sopenharmony_ci 109ffe3c632Sopenharmony_ci assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); 110ffe3c632Sopenharmony_ci assertEquals(0, jspb.BinaryReader.instanceCache_.length); 111ffe3c632Sopenharmony_ci 112ffe3c632Sopenharmony_ci // Freeing the reader should put it back into the cache. 113ffe3c632Sopenharmony_ci reader.free(); 114ffe3c632Sopenharmony_ci 115ffe3c632Sopenharmony_ci assertEquals(2, jspb.BinaryDecoder.instanceCache_.length); 116ffe3c632Sopenharmony_ci assertEquals(1, jspb.BinaryReader.instanceCache_.length); 117ffe3c632Sopenharmony_ci }); 118ffe3c632Sopenharmony_ci 119ffe3c632Sopenharmony_ci 120ffe3c632Sopenharmony_ci /** 121ffe3c632Sopenharmony_ci * @param {number} x 122ffe3c632Sopenharmony_ci * @return {number} 123ffe3c632Sopenharmony_ci */ 124ffe3c632Sopenharmony_ci function truncate(x) { 125ffe3c632Sopenharmony_ci var temp = new Float32Array(1); 126ffe3c632Sopenharmony_ci temp[0] = x; 127ffe3c632Sopenharmony_ci return temp[0]; 128ffe3c632Sopenharmony_ci } 129ffe3c632Sopenharmony_ci 130ffe3c632Sopenharmony_ci 131ffe3c632Sopenharmony_ci /** 132ffe3c632Sopenharmony_ci * Verifies that misuse of the reader class triggers assertions. 133ffe3c632Sopenharmony_ci */ 134ffe3c632Sopenharmony_ci it('testReadErrors', /** @suppress {checkTypes|visibility} */ function() { 135ffe3c632Sopenharmony_ci // Calling readMessage on a non-delimited field should trigger an 136ffe3c632Sopenharmony_ci // assertion. 137ffe3c632Sopenharmony_ci var reader = jspb.BinaryReader.alloc([8, 1]); 138ffe3c632Sopenharmony_ci var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); 139ffe3c632Sopenharmony_ci reader.nextField(); 140ffe3c632Sopenharmony_ci assertThrows(function() { 141ffe3c632Sopenharmony_ci reader.readMessage(dummyMessage, goog.nullFunction); 142ffe3c632Sopenharmony_ci }); 143ffe3c632Sopenharmony_ci 144ffe3c632Sopenharmony_ci // Reading past the end of the stream should trigger an assertion. 145ffe3c632Sopenharmony_ci reader = jspb.BinaryReader.alloc([9, 1]); 146ffe3c632Sopenharmony_ci reader.nextField(); 147ffe3c632Sopenharmony_ci assertThrows(function() {reader.readFixed64()}); 148ffe3c632Sopenharmony_ci 149ffe3c632Sopenharmony_ci // Reading past the end of a submessage should trigger an assertion. 150ffe3c632Sopenharmony_ci reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]); 151ffe3c632Sopenharmony_ci reader.nextField(); 152ffe3c632Sopenharmony_ci reader.readMessage(dummyMessage, function() { 153ffe3c632Sopenharmony_ci reader.nextField(); 154ffe3c632Sopenharmony_ci assertThrows(function() {reader.readFixed32()}); 155ffe3c632Sopenharmony_ci }); 156ffe3c632Sopenharmony_ci 157ffe3c632Sopenharmony_ci // Skipping an invalid field should trigger an assertion. 158ffe3c632Sopenharmony_ci reader = jspb.BinaryReader.alloc([12, 1]); 159ffe3c632Sopenharmony_ci reader.nextWireType_ = 1000; 160ffe3c632Sopenharmony_ci assertThrows(function() {reader.skipField()}); 161ffe3c632Sopenharmony_ci 162ffe3c632Sopenharmony_ci // Reading fields with the wrong wire type should assert. 163ffe3c632Sopenharmony_ci reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]); 164ffe3c632Sopenharmony_ci reader.nextField(); 165ffe3c632Sopenharmony_ci assertThrows(function() {reader.readInt32()}); 166ffe3c632Sopenharmony_ci assertThrows(function() {reader.readInt32String()}); 167ffe3c632Sopenharmony_ci assertThrows(function() {reader.readInt64()}); 168ffe3c632Sopenharmony_ci assertThrows(function() {reader.readInt64String()}); 169ffe3c632Sopenharmony_ci assertThrows(function() {reader.readUint32()}); 170ffe3c632Sopenharmony_ci assertThrows(function() {reader.readUint32String()}); 171ffe3c632Sopenharmony_ci assertThrows(function() {reader.readUint64()}); 172ffe3c632Sopenharmony_ci assertThrows(function() {reader.readUint64String()}); 173ffe3c632Sopenharmony_ci assertThrows(function() {reader.readSint32()}); 174ffe3c632Sopenharmony_ci assertThrows(function() {reader.readBool()}); 175ffe3c632Sopenharmony_ci assertThrows(function() {reader.readEnum()}); 176ffe3c632Sopenharmony_ci 177ffe3c632Sopenharmony_ci reader = jspb.BinaryReader.alloc([8, 1]); 178ffe3c632Sopenharmony_ci reader.nextField(); 179ffe3c632Sopenharmony_ci assertThrows(function() {reader.readFixed32()}); 180ffe3c632Sopenharmony_ci assertThrows(function() {reader.readFixed64()}); 181ffe3c632Sopenharmony_ci assertThrows(function() {reader.readSfixed32()}); 182ffe3c632Sopenharmony_ci assertThrows(function() {reader.readSfixed64()}); 183ffe3c632Sopenharmony_ci assertThrows(function() {reader.readFloat()}); 184ffe3c632Sopenharmony_ci assertThrows(function() {reader.readDouble()}); 185ffe3c632Sopenharmony_ci 186ffe3c632Sopenharmony_ci assertThrows(function() {reader.readString()}); 187ffe3c632Sopenharmony_ci assertThrows(function() {reader.readBytes()}); 188ffe3c632Sopenharmony_ci }); 189ffe3c632Sopenharmony_ci 190ffe3c632Sopenharmony_ci 191ffe3c632Sopenharmony_ci /** 192ffe3c632Sopenharmony_ci * Tests encoding and decoding of unsigned field types. 193ffe3c632Sopenharmony_ci * @param {Function} readField 194ffe3c632Sopenharmony_ci * @param {Function} writeField 195ffe3c632Sopenharmony_ci * @param {number} epsilon 196ffe3c632Sopenharmony_ci * @param {number} upperLimit 197ffe3c632Sopenharmony_ci * @param {Function} filter 198ffe3c632Sopenharmony_ci * @private 199ffe3c632Sopenharmony_ci * @suppress {missingProperties} 200ffe3c632Sopenharmony_ci */ 201ffe3c632Sopenharmony_ci var doTestUnsignedField_ = function(readField, 202ffe3c632Sopenharmony_ci writeField, epsilon, upperLimit, filter) { 203ffe3c632Sopenharmony_ci assertNotNull(readField); 204ffe3c632Sopenharmony_ci assertNotNull(writeField); 205ffe3c632Sopenharmony_ci 206ffe3c632Sopenharmony_ci var writer = new jspb.BinaryWriter(); 207ffe3c632Sopenharmony_ci 208ffe3c632Sopenharmony_ci // Encode zero and limits. 209ffe3c632Sopenharmony_ci writeField.call(writer, 1, filter(0)); 210ffe3c632Sopenharmony_ci writeField.call(writer, 2, filter(epsilon)); 211ffe3c632Sopenharmony_ci writeField.call(writer, 3, filter(upperLimit)); 212ffe3c632Sopenharmony_ci 213ffe3c632Sopenharmony_ci // Encode positive values. 214ffe3c632Sopenharmony_ci for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { 215ffe3c632Sopenharmony_ci writeField.call(writer, 4, filter(cursor)); 216ffe3c632Sopenharmony_ci } 217ffe3c632Sopenharmony_ci 218ffe3c632Sopenharmony_ci var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); 219ffe3c632Sopenharmony_ci 220ffe3c632Sopenharmony_ci // Check zero and limits. 221ffe3c632Sopenharmony_ci reader.nextField(); 222ffe3c632Sopenharmony_ci assertEquals(1, reader.getFieldNumber()); 223ffe3c632Sopenharmony_ci assertEquals(filter(0), readField.call(reader)); 224ffe3c632Sopenharmony_ci 225ffe3c632Sopenharmony_ci reader.nextField(); 226ffe3c632Sopenharmony_ci assertEquals(2, reader.getFieldNumber()); 227ffe3c632Sopenharmony_ci assertEquals(filter(epsilon), readField.call(reader)); 228ffe3c632Sopenharmony_ci 229ffe3c632Sopenharmony_ci reader.nextField(); 230ffe3c632Sopenharmony_ci assertEquals(3, reader.getFieldNumber()); 231ffe3c632Sopenharmony_ci assertEquals(filter(upperLimit), readField.call(reader)); 232ffe3c632Sopenharmony_ci 233ffe3c632Sopenharmony_ci // Check positive values. 234ffe3c632Sopenharmony_ci for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { 235ffe3c632Sopenharmony_ci reader.nextField(); 236ffe3c632Sopenharmony_ci if (4 != reader.getFieldNumber()) throw 'fail!'; 237ffe3c632Sopenharmony_ci if (filter(cursor) != readField.call(reader)) throw 'fail!'; 238ffe3c632Sopenharmony_ci } 239ffe3c632Sopenharmony_ci }; 240ffe3c632Sopenharmony_ci 241ffe3c632Sopenharmony_ci 242ffe3c632Sopenharmony_ci /** 243ffe3c632Sopenharmony_ci * Tests encoding and decoding of signed field types. 244ffe3c632Sopenharmony_ci * @param {Function} readField 245ffe3c632Sopenharmony_ci * @param {Function} writeField 246ffe3c632Sopenharmony_ci * @param {number} epsilon 247ffe3c632Sopenharmony_ci * @param {number} lowerLimit 248ffe3c632Sopenharmony_ci * @param {number} upperLimit 249ffe3c632Sopenharmony_ci * @param {Function} filter 250ffe3c632Sopenharmony_ci * @private 251ffe3c632Sopenharmony_ci * @suppress {missingProperties} 252ffe3c632Sopenharmony_ci */ 253ffe3c632Sopenharmony_ci var doTestSignedField_ = function(readField, 254ffe3c632Sopenharmony_ci writeField, epsilon, lowerLimit, upperLimit, filter) { 255ffe3c632Sopenharmony_ci var writer = new jspb.BinaryWriter(); 256ffe3c632Sopenharmony_ci 257ffe3c632Sopenharmony_ci // Encode zero and limits. 258ffe3c632Sopenharmony_ci writeField.call(writer, 1, filter(lowerLimit)); 259ffe3c632Sopenharmony_ci writeField.call(writer, 2, filter(-epsilon)); 260ffe3c632Sopenharmony_ci writeField.call(writer, 3, filter(0)); 261ffe3c632Sopenharmony_ci writeField.call(writer, 4, filter(epsilon)); 262ffe3c632Sopenharmony_ci writeField.call(writer, 5, filter(upperLimit)); 263ffe3c632Sopenharmony_ci 264ffe3c632Sopenharmony_ci var inputValues = []; 265ffe3c632Sopenharmony_ci 266ffe3c632Sopenharmony_ci // Encode negative values. 267ffe3c632Sopenharmony_ci for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) { 268ffe3c632Sopenharmony_ci var val = filter(cursor); 269ffe3c632Sopenharmony_ci writeField.call(writer, 6, val); 270ffe3c632Sopenharmony_ci inputValues.push({ 271ffe3c632Sopenharmony_ci fieldNumber: 6, 272ffe3c632Sopenharmony_ci value: val 273ffe3c632Sopenharmony_ci }); 274ffe3c632Sopenharmony_ci } 275ffe3c632Sopenharmony_ci 276ffe3c632Sopenharmony_ci // Encode positive values. 277ffe3c632Sopenharmony_ci for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) { 278ffe3c632Sopenharmony_ci var val = filter(cursor); 279ffe3c632Sopenharmony_ci writeField.call(writer, 7, val); 280ffe3c632Sopenharmony_ci inputValues.push({ 281ffe3c632Sopenharmony_ci fieldNumber: 7, 282ffe3c632Sopenharmony_ci value: val 283ffe3c632Sopenharmony_ci }); 284ffe3c632Sopenharmony_ci } 285ffe3c632Sopenharmony_ci 286ffe3c632Sopenharmony_ci var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); 287ffe3c632Sopenharmony_ci 288ffe3c632Sopenharmony_ci // Check zero and limits. 289ffe3c632Sopenharmony_ci reader.nextField(); 290ffe3c632Sopenharmony_ci assertEquals(1, reader.getFieldNumber()); 291ffe3c632Sopenharmony_ci assertEquals(filter(lowerLimit), readField.call(reader)); 292ffe3c632Sopenharmony_ci 293ffe3c632Sopenharmony_ci reader.nextField(); 294ffe3c632Sopenharmony_ci assertEquals(2, reader.getFieldNumber()); 295ffe3c632Sopenharmony_ci assertEquals(filter(-epsilon), readField.call(reader)); 296ffe3c632Sopenharmony_ci 297ffe3c632Sopenharmony_ci reader.nextField(); 298ffe3c632Sopenharmony_ci assertEquals(3, reader.getFieldNumber()); 299ffe3c632Sopenharmony_ci assertEquals(filter(0), readField.call(reader)); 300ffe3c632Sopenharmony_ci 301ffe3c632Sopenharmony_ci reader.nextField(); 302ffe3c632Sopenharmony_ci assertEquals(4, reader.getFieldNumber()); 303ffe3c632Sopenharmony_ci assertEquals(filter(epsilon), readField.call(reader)); 304ffe3c632Sopenharmony_ci 305ffe3c632Sopenharmony_ci reader.nextField(); 306ffe3c632Sopenharmony_ci assertEquals(5, reader.getFieldNumber()); 307ffe3c632Sopenharmony_ci assertEquals(filter(upperLimit), readField.call(reader)); 308ffe3c632Sopenharmony_ci 309ffe3c632Sopenharmony_ci for (var i = 0; i < inputValues.length; i++) { 310ffe3c632Sopenharmony_ci var expected = inputValues[i]; 311ffe3c632Sopenharmony_ci reader.nextField(); 312ffe3c632Sopenharmony_ci assertEquals(expected.fieldNumber, reader.getFieldNumber()); 313ffe3c632Sopenharmony_ci assertEquals(expected.value, readField.call(reader)); 314ffe3c632Sopenharmony_ci } 315ffe3c632Sopenharmony_ci }; 316ffe3c632Sopenharmony_ci 317ffe3c632Sopenharmony_ci 318ffe3c632Sopenharmony_ci /** 319ffe3c632Sopenharmony_ci * Tests fields that use varint encoding. 320ffe3c632Sopenharmony_ci */ 321ffe3c632Sopenharmony_ci it('testVarintFields', function() { 322ffe3c632Sopenharmony_ci assertNotUndefined(jspb.BinaryReader.prototype.readUint32); 323ffe3c632Sopenharmony_ci assertNotUndefined(jspb.BinaryWriter.prototype.writeUint32); 324ffe3c632Sopenharmony_ci assertNotUndefined(jspb.BinaryReader.prototype.readUint64); 325ffe3c632Sopenharmony_ci assertNotUndefined(jspb.BinaryWriter.prototype.writeUint64); 326ffe3c632Sopenharmony_ci assertNotUndefined(jspb.BinaryReader.prototype.readBool); 327ffe3c632Sopenharmony_ci assertNotUndefined(jspb.BinaryWriter.prototype.writeBool); 328ffe3c632Sopenharmony_ci doTestUnsignedField_( 329ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readUint32, 330ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeUint32, 331ffe3c632Sopenharmony_ci 1, Math.pow(2, 32) - 1, Math.round); 332ffe3c632Sopenharmony_ci 333ffe3c632Sopenharmony_ci doTestUnsignedField_( 334ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readUint64, 335ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeUint64, 336ffe3c632Sopenharmony_ci 1, Math.pow(2, 64) - 1025, Math.round); 337ffe3c632Sopenharmony_ci 338ffe3c632Sopenharmony_ci doTestSignedField_( 339ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readInt32, 340ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeInt32, 341ffe3c632Sopenharmony_ci 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round); 342ffe3c632Sopenharmony_ci 343ffe3c632Sopenharmony_ci doTestSignedField_( 344ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readInt64, 345ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeInt64, 346ffe3c632Sopenharmony_ci 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round); 347ffe3c632Sopenharmony_ci 348ffe3c632Sopenharmony_ci doTestSignedField_( 349ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readEnum, 350ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeEnum, 351ffe3c632Sopenharmony_ci 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round); 352ffe3c632Sopenharmony_ci 353ffe3c632Sopenharmony_ci doTestUnsignedField_( 354ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readBool, 355ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeBool, 356ffe3c632Sopenharmony_ci 1, 1, function(x) { return !!x; }); 357ffe3c632Sopenharmony_ci }); 358ffe3c632Sopenharmony_ci 359ffe3c632Sopenharmony_ci 360ffe3c632Sopenharmony_ci /** 361ffe3c632Sopenharmony_ci * Tests reading a field from hexadecimal string (format: '08 BE EF'). 362ffe3c632Sopenharmony_ci * @param {Function} readField 363ffe3c632Sopenharmony_ci * @param {number} expected 364ffe3c632Sopenharmony_ci * @param {string} hexString 365ffe3c632Sopenharmony_ci */ 366ffe3c632Sopenharmony_ci function doTestHexStringVarint_(readField, expected, hexString) { 367ffe3c632Sopenharmony_ci var bytesCount = (hexString.length + 1) / 3; 368ffe3c632Sopenharmony_ci var bytes = new Uint8Array(bytesCount); 369ffe3c632Sopenharmony_ci for (var i = 0; i < bytesCount; i++) { 370ffe3c632Sopenharmony_ci bytes[i] = parseInt(hexString.substring(i * 3, i * 3 + 2), 16); 371ffe3c632Sopenharmony_ci } 372ffe3c632Sopenharmony_ci var reader = jspb.BinaryReader.alloc(bytes); 373ffe3c632Sopenharmony_ci reader.nextField(); 374ffe3c632Sopenharmony_ci assertEquals(expected, readField.call(reader)); 375ffe3c632Sopenharmony_ci } 376ffe3c632Sopenharmony_ci 377ffe3c632Sopenharmony_ci 378ffe3c632Sopenharmony_ci /** 379ffe3c632Sopenharmony_ci * Tests non-canonical redundant varint decoding. 380ffe3c632Sopenharmony_ci */ 381ffe3c632Sopenharmony_ci it('testRedundantVarintFields', function() { 382ffe3c632Sopenharmony_ci assertNotNull(jspb.BinaryReader.prototype.readUint32); 383ffe3c632Sopenharmony_ci assertNotNull(jspb.BinaryReader.prototype.readUint64); 384ffe3c632Sopenharmony_ci assertNotNull(jspb.BinaryReader.prototype.readSint32); 385ffe3c632Sopenharmony_ci assertNotNull(jspb.BinaryReader.prototype.readSint64); 386ffe3c632Sopenharmony_ci 387ffe3c632Sopenharmony_ci // uint32 and sint32 take no more than 5 bytes 388ffe3c632Sopenharmony_ci // 08 - field prefix (type = 0 means varint) 389ffe3c632Sopenharmony_ci doTestHexStringVarint_( 390ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readUint32, 391ffe3c632Sopenharmony_ci 12, '08 8C 80 80 80 00'); 392ffe3c632Sopenharmony_ci 393ffe3c632Sopenharmony_ci // 11 stands for -6 in zigzag encoding 394ffe3c632Sopenharmony_ci doTestHexStringVarint_( 395ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readSint32, 396ffe3c632Sopenharmony_ci -6, '08 8B 80 80 80 00'); 397ffe3c632Sopenharmony_ci 398ffe3c632Sopenharmony_ci // uint64 and sint64 take no more than 10 bytes 399ffe3c632Sopenharmony_ci // 08 - field prefix (type = 0 means varint) 400ffe3c632Sopenharmony_ci doTestHexStringVarint_( 401ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readUint64, 402ffe3c632Sopenharmony_ci 12, '08 8C 80 80 80 80 80 80 80 80 00'); 403ffe3c632Sopenharmony_ci 404ffe3c632Sopenharmony_ci // 11 stands for -6 in zigzag encoding 405ffe3c632Sopenharmony_ci doTestHexStringVarint_( 406ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readSint64, 407ffe3c632Sopenharmony_ci -6, '08 8B 80 80 80 80 80 80 80 80 00'); 408ffe3c632Sopenharmony_ci }); 409ffe3c632Sopenharmony_ci 410ffe3c632Sopenharmony_ci /** 411ffe3c632Sopenharmony_ci * Tests reading 64-bit integers as split values. 412ffe3c632Sopenharmony_ci */ 413ffe3c632Sopenharmony_ci it('handles split 64 fields', function() { 414ffe3c632Sopenharmony_ci var writer = new jspb.BinaryWriter(); 415ffe3c632Sopenharmony_ci writer.writeInt64String(1, '4294967296'); 416ffe3c632Sopenharmony_ci writer.writeSfixed64String(2, '4294967298'); 417ffe3c632Sopenharmony_ci writer.writeInt64String(3, '3'); // 3 is the zig-zag encoding of -2. 418ffe3c632Sopenharmony_ci var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); 419ffe3c632Sopenharmony_ci 420ffe3c632Sopenharmony_ci function rejoin(lowBits, highBits) { 421ffe3c632Sopenharmony_ci return highBits * 2 ** 32 + (lowBits >>> 0); 422ffe3c632Sopenharmony_ci } 423ffe3c632Sopenharmony_ci reader.nextField(); 424ffe3c632Sopenharmony_ci expect(reader.getFieldNumber()).toEqual(1); 425ffe3c632Sopenharmony_ci expect(reader.readSplitVarint64(rejoin)).toEqual(0x100000000); 426ffe3c632Sopenharmony_ci 427ffe3c632Sopenharmony_ci reader.nextField(); 428ffe3c632Sopenharmony_ci expect(reader.getFieldNumber()).toEqual(2); 429ffe3c632Sopenharmony_ci expect(reader.readSplitFixed64(rejoin)).toEqual(0x100000002); 430ffe3c632Sopenharmony_ci 431ffe3c632Sopenharmony_ci reader.nextField(); 432ffe3c632Sopenharmony_ci expect(reader.getFieldNumber()).toEqual(3); 433ffe3c632Sopenharmony_ci expect(reader.readSplitZigzagVarint64(rejoin)).toEqual(-2); 434ffe3c632Sopenharmony_ci }); 435ffe3c632Sopenharmony_ci 436ffe3c632Sopenharmony_ci /** 437ffe3c632Sopenharmony_ci * Tests 64-bit fields that are handled as strings. 438ffe3c632Sopenharmony_ci */ 439ffe3c632Sopenharmony_ci it('testStringInt64Fields', function() { 440ffe3c632Sopenharmony_ci var writer = new jspb.BinaryWriter(); 441ffe3c632Sopenharmony_ci 442ffe3c632Sopenharmony_ci var testSignedData = [ 443ffe3c632Sopenharmony_ci '2730538252207801776', 444ffe3c632Sopenharmony_ci '-2688470994844604560', 445ffe3c632Sopenharmony_ci '3398529779486536359', 446ffe3c632Sopenharmony_ci '3568577411627971000', 447ffe3c632Sopenharmony_ci '272477188847484900', 448ffe3c632Sopenharmony_ci '-6649058714086158188', 449ffe3c632Sopenharmony_ci '-7695254765712060806', 450ffe3c632Sopenharmony_ci '-4525541438037104029', 451ffe3c632Sopenharmony_ci '-4993706538836508568', 452ffe3c632Sopenharmony_ci '4990160321893729138' 453ffe3c632Sopenharmony_ci ]; 454ffe3c632Sopenharmony_ci var testUnsignedData = [ 455ffe3c632Sopenharmony_ci '7822732630241694882', 456ffe3c632Sopenharmony_ci '6753602971916687352', 457ffe3c632Sopenharmony_ci '2399935075244442116', 458ffe3c632Sopenharmony_ci '8724292567325338867', 459ffe3c632Sopenharmony_ci '16948784802625696584', 460ffe3c632Sopenharmony_ci '4136275908516066934', 461ffe3c632Sopenharmony_ci '3575388346793700364', 462ffe3c632Sopenharmony_ci '5167142028379259461', 463ffe3c632Sopenharmony_ci '1557573948689737699', 464ffe3c632Sopenharmony_ci '17100725280812548567' 465ffe3c632Sopenharmony_ci ]; 466ffe3c632Sopenharmony_ci 467ffe3c632Sopenharmony_ci for (var i = 0; i < testSignedData.length; i++) { 468ffe3c632Sopenharmony_ci writer.writeInt64String(2 * i + 1, testSignedData[i]); 469ffe3c632Sopenharmony_ci writer.writeUint64String(2 * i + 2, testUnsignedData[i]); 470ffe3c632Sopenharmony_ci } 471ffe3c632Sopenharmony_ci 472ffe3c632Sopenharmony_ci var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); 473ffe3c632Sopenharmony_ci 474ffe3c632Sopenharmony_ci for (var i = 0; i < testSignedData.length; i++) { 475ffe3c632Sopenharmony_ci reader.nextField(); 476ffe3c632Sopenharmony_ci assertEquals(2 * i + 1, reader.getFieldNumber()); 477ffe3c632Sopenharmony_ci assertEquals(testSignedData[i], reader.readInt64String()); 478ffe3c632Sopenharmony_ci reader.nextField(); 479ffe3c632Sopenharmony_ci assertEquals(2 * i + 2, reader.getFieldNumber()); 480ffe3c632Sopenharmony_ci assertEquals(testUnsignedData[i], reader.readUint64String()); 481ffe3c632Sopenharmony_ci } 482ffe3c632Sopenharmony_ci }); 483ffe3c632Sopenharmony_ci 484ffe3c632Sopenharmony_ci 485ffe3c632Sopenharmony_ci /** 486ffe3c632Sopenharmony_ci * Tests fields that use zigzag encoding. 487ffe3c632Sopenharmony_ci */ 488ffe3c632Sopenharmony_ci it('testZigzagFields', function() { 489ffe3c632Sopenharmony_ci doTestSignedField_( 490ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readSint32, 491ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeSint32, 492ffe3c632Sopenharmony_ci 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round); 493ffe3c632Sopenharmony_ci 494ffe3c632Sopenharmony_ci doTestSignedField_( 495ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readSint64, 496ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeSint64, 497ffe3c632Sopenharmony_ci 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round); 498ffe3c632Sopenharmony_ci 499ffe3c632Sopenharmony_ci doTestSignedField_( 500ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readSintHash64, 501ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeSintHash64, 1, -Math.pow(2, 63), 502ffe3c632Sopenharmony_ci Math.pow(2, 63) - 513, jspb.utils.numberToHash64); 503ffe3c632Sopenharmony_ci }); 504ffe3c632Sopenharmony_ci 505ffe3c632Sopenharmony_ci 506ffe3c632Sopenharmony_ci /** 507ffe3c632Sopenharmony_ci * Tests fields that use fixed-length encoding. 508ffe3c632Sopenharmony_ci */ 509ffe3c632Sopenharmony_ci it('testFixedFields', function() { 510ffe3c632Sopenharmony_ci doTestUnsignedField_( 511ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readFixed32, 512ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeFixed32, 513ffe3c632Sopenharmony_ci 1, Math.pow(2, 32) - 1, Math.round); 514ffe3c632Sopenharmony_ci 515ffe3c632Sopenharmony_ci doTestUnsignedField_( 516ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readFixed64, 517ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeFixed64, 518ffe3c632Sopenharmony_ci 1, Math.pow(2, 64) - 1025, Math.round); 519ffe3c632Sopenharmony_ci 520ffe3c632Sopenharmony_ci doTestSignedField_( 521ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readSfixed32, 522ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeSfixed32, 523ffe3c632Sopenharmony_ci 1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round); 524ffe3c632Sopenharmony_ci 525ffe3c632Sopenharmony_ci doTestSignedField_( 526ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readSfixed64, 527ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeSfixed64, 528ffe3c632Sopenharmony_ci 1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round); 529ffe3c632Sopenharmony_ci }); 530ffe3c632Sopenharmony_ci 531ffe3c632Sopenharmony_ci 532ffe3c632Sopenharmony_ci /** 533ffe3c632Sopenharmony_ci * Tests floating point fields. 534ffe3c632Sopenharmony_ci */ 535ffe3c632Sopenharmony_ci it('testFloatFields', function() { 536ffe3c632Sopenharmony_ci doTestSignedField_( 537ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readFloat, 538ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeFloat, 539ffe3c632Sopenharmony_ci jspb.BinaryConstants.FLOAT32_MIN, 540ffe3c632Sopenharmony_ci -jspb.BinaryConstants.FLOAT32_MAX, 541ffe3c632Sopenharmony_ci jspb.BinaryConstants.FLOAT32_MAX, 542ffe3c632Sopenharmony_ci truncate); 543ffe3c632Sopenharmony_ci 544ffe3c632Sopenharmony_ci doTestSignedField_( 545ffe3c632Sopenharmony_ci jspb.BinaryReader.prototype.readDouble, 546ffe3c632Sopenharmony_ci jspb.BinaryWriter.prototype.writeDouble, 547ffe3c632Sopenharmony_ci jspb.BinaryConstants.FLOAT64_EPS * 10, 548ffe3c632Sopenharmony_ci -jspb.BinaryConstants.FLOAT64_MIN, 549ffe3c632Sopenharmony_ci jspb.BinaryConstants.FLOAT64_MIN, 550ffe3c632Sopenharmony_ci function(x) { return x; }); 551ffe3c632Sopenharmony_ci }); 552ffe3c632Sopenharmony_ci 553ffe3c632Sopenharmony_ci 554ffe3c632Sopenharmony_ci /** 555ffe3c632Sopenharmony_ci * Tests length-delimited string fields. 556ffe3c632Sopenharmony_ci */ 557ffe3c632Sopenharmony_ci it('testStringFields', function() { 558ffe3c632Sopenharmony_ci var s1 = 'The quick brown fox jumps over the lazy dog.'; 559ffe3c632Sopenharmony_ci var s2 = '人人生而自由,在尊嚴和權利上一律平等。'; 560ffe3c632Sopenharmony_ci 561ffe3c632Sopenharmony_ci var writer = new jspb.BinaryWriter(); 562ffe3c632Sopenharmony_ci 563ffe3c632Sopenharmony_ci writer.writeString(1, s1); 564ffe3c632Sopenharmony_ci writer.writeString(2, s2); 565ffe3c632Sopenharmony_ci 566ffe3c632Sopenharmony_ci var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); 567ffe3c632Sopenharmony_ci 568ffe3c632Sopenharmony_ci reader.nextField(); 569ffe3c632Sopenharmony_ci assertEquals(1, reader.getFieldNumber()); 570ffe3c632Sopenharmony_ci assertEquals(s1, reader.readString()); 571ffe3c632Sopenharmony_ci 572ffe3c632Sopenharmony_ci reader.nextField(); 573ffe3c632Sopenharmony_ci assertEquals(2, reader.getFieldNumber()); 574ffe3c632Sopenharmony_ci assertEquals(s2, reader.readString()); 575ffe3c632Sopenharmony_ci }); 576ffe3c632Sopenharmony_ci 577ffe3c632Sopenharmony_ci 578ffe3c632Sopenharmony_ci /** 579ffe3c632Sopenharmony_ci * Tests length-delimited byte fields. 580ffe3c632Sopenharmony_ci */ 581ffe3c632Sopenharmony_ci it('testByteFields', function() { 582ffe3c632Sopenharmony_ci var message = []; 583ffe3c632Sopenharmony_ci var lowerLimit = 1; 584ffe3c632Sopenharmony_ci var upperLimit = 256; 585ffe3c632Sopenharmony_ci var scale = 1.1; 586ffe3c632Sopenharmony_ci 587ffe3c632Sopenharmony_ci var writer = new jspb.BinaryWriter(); 588ffe3c632Sopenharmony_ci 589ffe3c632Sopenharmony_ci for (var cursor = lowerLimit; cursor < upperLimit; cursor *= 1.1) { 590ffe3c632Sopenharmony_ci var len = Math.round(cursor); 591ffe3c632Sopenharmony_ci var bytes = []; 592ffe3c632Sopenharmony_ci for (var i = 0; i < len; i++) bytes.push(i % 256); 593ffe3c632Sopenharmony_ci 594ffe3c632Sopenharmony_ci writer.writeBytes(len, bytes); 595ffe3c632Sopenharmony_ci } 596ffe3c632Sopenharmony_ci 597ffe3c632Sopenharmony_ci var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); 598ffe3c632Sopenharmony_ci 599ffe3c632Sopenharmony_ci for (var cursor = lowerLimit; reader.nextField(); cursor *= 1.1) { 600ffe3c632Sopenharmony_ci var len = Math.round(cursor); 601ffe3c632Sopenharmony_ci if (len != reader.getFieldNumber()) throw 'fail!'; 602ffe3c632Sopenharmony_ci 603ffe3c632Sopenharmony_ci var bytes = reader.readBytes(); 604ffe3c632Sopenharmony_ci if (len != bytes.length) throw 'fail!'; 605ffe3c632Sopenharmony_ci for (var i = 0; i < bytes.length; i++) { 606ffe3c632Sopenharmony_ci if (i % 256 != bytes[i]) throw 'fail!'; 607ffe3c632Sopenharmony_ci } 608ffe3c632Sopenharmony_ci } 609ffe3c632Sopenharmony_ci }); 610ffe3c632Sopenharmony_ci 611ffe3c632Sopenharmony_ci 612ffe3c632Sopenharmony_ci /** 613ffe3c632Sopenharmony_ci * Tests nested messages. 614ffe3c632Sopenharmony_ci */ 615ffe3c632Sopenharmony_ci it('testNesting', function() { 616ffe3c632Sopenharmony_ci var writer = new jspb.BinaryWriter(); 617ffe3c632Sopenharmony_ci var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); 618ffe3c632Sopenharmony_ci 619ffe3c632Sopenharmony_ci writer.writeInt32(1, 100); 620ffe3c632Sopenharmony_ci 621ffe3c632Sopenharmony_ci // Add one message with 3 int fields. 622ffe3c632Sopenharmony_ci writer.writeMessage(2, dummyMessage, function() { 623ffe3c632Sopenharmony_ci writer.writeInt32(3, 300); 624ffe3c632Sopenharmony_ci writer.writeInt32(4, 400); 625ffe3c632Sopenharmony_ci writer.writeInt32(5, 500); 626ffe3c632Sopenharmony_ci }); 627ffe3c632Sopenharmony_ci 628ffe3c632Sopenharmony_ci // Add one empty message. 629ffe3c632Sopenharmony_ci writer.writeMessage(6, dummyMessage, goog.nullFunction); 630ffe3c632Sopenharmony_ci 631ffe3c632Sopenharmony_ci writer.writeInt32(7, 700); 632ffe3c632Sopenharmony_ci 633ffe3c632Sopenharmony_ci var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); 634ffe3c632Sopenharmony_ci 635ffe3c632Sopenharmony_ci // Validate outermost message. 636ffe3c632Sopenharmony_ci 637ffe3c632Sopenharmony_ci reader.nextField(); 638ffe3c632Sopenharmony_ci assertEquals(1, reader.getFieldNumber()); 639ffe3c632Sopenharmony_ci assertEquals(100, reader.readInt32()); 640ffe3c632Sopenharmony_ci 641ffe3c632Sopenharmony_ci reader.nextField(); 642ffe3c632Sopenharmony_ci assertEquals(2, reader.getFieldNumber()); 643ffe3c632Sopenharmony_ci reader.readMessage(dummyMessage, function() { 644ffe3c632Sopenharmony_ci // Validate embedded message 1. 645ffe3c632Sopenharmony_ci reader.nextField(); 646ffe3c632Sopenharmony_ci assertEquals(3, reader.getFieldNumber()); 647ffe3c632Sopenharmony_ci assertEquals(300, reader.readInt32()); 648ffe3c632Sopenharmony_ci 649ffe3c632Sopenharmony_ci reader.nextField(); 650ffe3c632Sopenharmony_ci assertEquals(4, reader.getFieldNumber()); 651ffe3c632Sopenharmony_ci assertEquals(400, reader.readInt32()); 652ffe3c632Sopenharmony_ci 653ffe3c632Sopenharmony_ci reader.nextField(); 654ffe3c632Sopenharmony_ci assertEquals(5, reader.getFieldNumber()); 655ffe3c632Sopenharmony_ci assertEquals(500, reader.readInt32()); 656ffe3c632Sopenharmony_ci 657ffe3c632Sopenharmony_ci assertEquals(false, reader.nextField()); 658ffe3c632Sopenharmony_ci }); 659ffe3c632Sopenharmony_ci 660ffe3c632Sopenharmony_ci reader.nextField(); 661ffe3c632Sopenharmony_ci assertEquals(6, reader.getFieldNumber()); 662ffe3c632Sopenharmony_ci reader.readMessage(dummyMessage, function() { 663ffe3c632Sopenharmony_ci // Validate embedded message 2. 664ffe3c632Sopenharmony_ci 665ffe3c632Sopenharmony_ci assertEquals(false, reader.nextField()); 666ffe3c632Sopenharmony_ci }); 667ffe3c632Sopenharmony_ci 668ffe3c632Sopenharmony_ci reader.nextField(); 669ffe3c632Sopenharmony_ci assertEquals(7, reader.getFieldNumber()); 670ffe3c632Sopenharmony_ci assertEquals(700, reader.readInt32()); 671ffe3c632Sopenharmony_ci 672ffe3c632Sopenharmony_ci assertEquals(false, reader.nextField()); 673ffe3c632Sopenharmony_ci }); 674ffe3c632Sopenharmony_ci 675ffe3c632Sopenharmony_ci /** 676ffe3c632Sopenharmony_ci * Tests skipping fields of each type by interleaving them with sentinel 677ffe3c632Sopenharmony_ci * values and skipping everything that's not a sentinel. 678ffe3c632Sopenharmony_ci */ 679ffe3c632Sopenharmony_ci it('testSkipField', function() { 680ffe3c632Sopenharmony_ci var writer = new jspb.BinaryWriter(); 681ffe3c632Sopenharmony_ci 682ffe3c632Sopenharmony_ci var sentinel = 123456789; 683ffe3c632Sopenharmony_ci 684ffe3c632Sopenharmony_ci // Write varint fields of different sizes. 685ffe3c632Sopenharmony_ci writer.writeInt32(1, sentinel); 686ffe3c632Sopenharmony_ci writer.writeInt32(1, 1); 687ffe3c632Sopenharmony_ci writer.writeInt32(1, 1000); 688ffe3c632Sopenharmony_ci writer.writeInt32(1, 1000000); 689ffe3c632Sopenharmony_ci writer.writeInt32(1, 1000000000); 690ffe3c632Sopenharmony_ci 691ffe3c632Sopenharmony_ci // Write fixed 64-bit encoded fields. 692ffe3c632Sopenharmony_ci writer.writeInt32(2, sentinel); 693ffe3c632Sopenharmony_ci writer.writeDouble(2, 1); 694ffe3c632Sopenharmony_ci writer.writeFixed64(2, 1); 695ffe3c632Sopenharmony_ci writer.writeSfixed64(2, 1); 696ffe3c632Sopenharmony_ci 697ffe3c632Sopenharmony_ci // Write fixed 32-bit encoded fields. 698ffe3c632Sopenharmony_ci writer.writeInt32(3, sentinel); 699ffe3c632Sopenharmony_ci writer.writeFloat(3, 1); 700ffe3c632Sopenharmony_ci writer.writeFixed32(3, 1); 701ffe3c632Sopenharmony_ci writer.writeSfixed32(3, 1); 702ffe3c632Sopenharmony_ci 703ffe3c632Sopenharmony_ci // Write delimited fields. 704ffe3c632Sopenharmony_ci writer.writeInt32(4, sentinel); 705ffe3c632Sopenharmony_ci writer.writeBytes(4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]); 706ffe3c632Sopenharmony_ci writer.writeString(4, 'The quick brown fox jumps over the lazy dog'); 707ffe3c632Sopenharmony_ci 708ffe3c632Sopenharmony_ci // Write a group with a nested group inside. 709ffe3c632Sopenharmony_ci writer.writeInt32(5, sentinel); 710ffe3c632Sopenharmony_ci var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); 711ffe3c632Sopenharmony_ci writer.writeGroup(5, dummyMessage, function() { 712ffe3c632Sopenharmony_ci // Previously the skipGroup implementation was wrong, which only consume 713ffe3c632Sopenharmony_ci // the decoder by nextField. This case is for making the previous 714ffe3c632Sopenharmony_ci // implementation failed in skipGroup by an early end group tag. 715ffe3c632Sopenharmony_ci // The reason is 44 = 5 * 8 + 4, this will be translated in to a field 716ffe3c632Sopenharmony_ci // with number 5 and with type 4 (end group) 717ffe3c632Sopenharmony_ci writer.writeInt64(44, 44); 718ffe3c632Sopenharmony_ci // This will make previous implementation failed by invalid tag (7). 719ffe3c632Sopenharmony_ci writer.writeInt64(42, 47); 720ffe3c632Sopenharmony_ci writer.writeInt64(42, 42); 721ffe3c632Sopenharmony_ci // This is for making the previous implementation failed by an invalid 722ffe3c632Sopenharmony_ci // varint. The bytes have at least 9 consecutive minus byte, which will 723ffe3c632Sopenharmony_ci // fail in this.nextField for previous implementation. 724ffe3c632Sopenharmony_ci writer.writeBytes(43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]); 725ffe3c632Sopenharmony_ci writer.writeGroup(6, dummyMessage, function() { 726ffe3c632Sopenharmony_ci writer.writeInt64(84, 42); 727ffe3c632Sopenharmony_ci writer.writeInt64(84, 44); 728ffe3c632Sopenharmony_ci writer.writeBytes( 729ffe3c632Sopenharmony_ci 43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]); 730ffe3c632Sopenharmony_ci }); 731ffe3c632Sopenharmony_ci }); 732ffe3c632Sopenharmony_ci 733ffe3c632Sopenharmony_ci // Write final sentinel. 734ffe3c632Sopenharmony_ci writer.writeInt32(6, sentinel); 735ffe3c632Sopenharmony_ci 736ffe3c632Sopenharmony_ci var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); 737ffe3c632Sopenharmony_ci 738ffe3c632Sopenharmony_ci function skip(field, count) { 739ffe3c632Sopenharmony_ci for (var i = 0; i < count; i++) { 740ffe3c632Sopenharmony_ci reader.nextField(); 741ffe3c632Sopenharmony_ci if (field != reader.getFieldNumber()) throw 'fail!'; 742ffe3c632Sopenharmony_ci reader.skipField(); 743ffe3c632Sopenharmony_ci } 744ffe3c632Sopenharmony_ci } 745ffe3c632Sopenharmony_ci 746ffe3c632Sopenharmony_ci reader.nextField(); 747ffe3c632Sopenharmony_ci assertEquals(1, reader.getFieldNumber()); 748ffe3c632Sopenharmony_ci assertEquals(sentinel, reader.readInt32()); 749ffe3c632Sopenharmony_ci skip(1, 4); 750ffe3c632Sopenharmony_ci 751ffe3c632Sopenharmony_ci reader.nextField(); 752ffe3c632Sopenharmony_ci assertEquals(2, reader.getFieldNumber()); 753ffe3c632Sopenharmony_ci assertEquals(sentinel, reader.readInt32()); 754ffe3c632Sopenharmony_ci skip(2, 3); 755ffe3c632Sopenharmony_ci 756ffe3c632Sopenharmony_ci reader.nextField(); 757ffe3c632Sopenharmony_ci assertEquals(3, reader.getFieldNumber()); 758ffe3c632Sopenharmony_ci assertEquals(sentinel, reader.readInt32()); 759ffe3c632Sopenharmony_ci skip(3, 3); 760ffe3c632Sopenharmony_ci 761ffe3c632Sopenharmony_ci reader.nextField(); 762ffe3c632Sopenharmony_ci assertEquals(4, reader.getFieldNumber()); 763ffe3c632Sopenharmony_ci assertEquals(sentinel, reader.readInt32()); 764ffe3c632Sopenharmony_ci skip(4, 2); 765ffe3c632Sopenharmony_ci 766ffe3c632Sopenharmony_ci reader.nextField(); 767ffe3c632Sopenharmony_ci assertEquals(5, reader.getFieldNumber()); 768ffe3c632Sopenharmony_ci assertEquals(sentinel, reader.readInt32()); 769ffe3c632Sopenharmony_ci skip(5, 1); 770ffe3c632Sopenharmony_ci 771ffe3c632Sopenharmony_ci reader.nextField(); 772ffe3c632Sopenharmony_ci assertEquals(6, reader.getFieldNumber()); 773ffe3c632Sopenharmony_ci assertEquals(sentinel, reader.readInt32()); 774ffe3c632Sopenharmony_ci }); 775ffe3c632Sopenharmony_ci 776ffe3c632Sopenharmony_ci 777ffe3c632Sopenharmony_ci /** 778ffe3c632Sopenharmony_ci * Tests packed fields. 779ffe3c632Sopenharmony_ci */ 780ffe3c632Sopenharmony_ci it('testPackedFields', function() { 781ffe3c632Sopenharmony_ci var writer = new jspb.BinaryWriter(); 782ffe3c632Sopenharmony_ci 783ffe3c632Sopenharmony_ci var sentinel = 123456789; 784ffe3c632Sopenharmony_ci 785ffe3c632Sopenharmony_ci var unsignedData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; 786ffe3c632Sopenharmony_ci var signedData = [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]; 787ffe3c632Sopenharmony_ci var floatData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10]; 788ffe3c632Sopenharmony_ci var doubleData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10]; 789ffe3c632Sopenharmony_ci var boolData = [true, false, true, true, false, false, true, false]; 790ffe3c632Sopenharmony_ci 791ffe3c632Sopenharmony_ci for (var i = 0; i < floatData.length; i++) { 792ffe3c632Sopenharmony_ci floatData[i] = truncate(floatData[i]); 793ffe3c632Sopenharmony_ci } 794ffe3c632Sopenharmony_ci 795ffe3c632Sopenharmony_ci writer.writeInt32(1, sentinel); 796ffe3c632Sopenharmony_ci 797ffe3c632Sopenharmony_ci writer.writePackedInt32(2, signedData); 798ffe3c632Sopenharmony_ci writer.writePackedInt64(2, signedData); 799ffe3c632Sopenharmony_ci writer.writePackedUint32(2, unsignedData); 800ffe3c632Sopenharmony_ci writer.writePackedUint64(2, unsignedData); 801ffe3c632Sopenharmony_ci writer.writePackedSint32(2, signedData); 802ffe3c632Sopenharmony_ci writer.writePackedSint64(2, signedData); 803ffe3c632Sopenharmony_ci writer.writePackedFixed32(2, unsignedData); 804ffe3c632Sopenharmony_ci writer.writePackedFixed64(2, unsignedData); 805ffe3c632Sopenharmony_ci writer.writePackedSfixed32(2, signedData); 806ffe3c632Sopenharmony_ci writer.writePackedSfixed64(2, signedData); 807ffe3c632Sopenharmony_ci writer.writePackedFloat(2, floatData); 808ffe3c632Sopenharmony_ci writer.writePackedDouble(2, doubleData); 809ffe3c632Sopenharmony_ci writer.writePackedBool(2, boolData); 810ffe3c632Sopenharmony_ci writer.writePackedEnum(2, unsignedData); 811ffe3c632Sopenharmony_ci 812ffe3c632Sopenharmony_ci writer.writeInt32(3, sentinel); 813ffe3c632Sopenharmony_ci 814ffe3c632Sopenharmony_ci var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); 815ffe3c632Sopenharmony_ci 816ffe3c632Sopenharmony_ci reader.nextField(); 817ffe3c632Sopenharmony_ci assertEquals(sentinel, reader.readInt32()); 818ffe3c632Sopenharmony_ci 819ffe3c632Sopenharmony_ci reader.nextField(); 820ffe3c632Sopenharmony_ci assertElementsEquals(reader.readPackedInt32(), signedData); 821ffe3c632Sopenharmony_ci 822ffe3c632Sopenharmony_ci reader.nextField(); 823ffe3c632Sopenharmony_ci assertElementsEquals(reader.readPackedInt64(), signedData); 824ffe3c632Sopenharmony_ci 825ffe3c632Sopenharmony_ci reader.nextField(); 826ffe3c632Sopenharmony_ci assertElementsEquals(reader.readPackedUint32(), unsignedData); 827ffe3c632Sopenharmony_ci 828ffe3c632Sopenharmony_ci reader.nextField(); 829ffe3c632Sopenharmony_ci assertElementsEquals(reader.readPackedUint64(), unsignedData); 830ffe3c632Sopenharmony_ci 831ffe3c632Sopenharmony_ci reader.nextField(); 832ffe3c632Sopenharmony_ci assertElementsEquals(reader.readPackedSint32(), signedData); 833ffe3c632Sopenharmony_ci 834ffe3c632Sopenharmony_ci reader.nextField(); 835ffe3c632Sopenharmony_ci assertElementsEquals(reader.readPackedSint64(), signedData); 836ffe3c632Sopenharmony_ci 837ffe3c632Sopenharmony_ci reader.nextField(); 838ffe3c632Sopenharmony_ci assertElementsEquals(reader.readPackedFixed32(), unsignedData); 839ffe3c632Sopenharmony_ci 840ffe3c632Sopenharmony_ci reader.nextField(); 841ffe3c632Sopenharmony_ci assertElementsEquals(reader.readPackedFixed64(), unsignedData); 842ffe3c632Sopenharmony_ci 843ffe3c632Sopenharmony_ci reader.nextField(); 844ffe3c632Sopenharmony_ci assertElementsEquals(reader.readPackedSfixed32(), signedData); 845ffe3c632Sopenharmony_ci 846ffe3c632Sopenharmony_ci reader.nextField(); 847ffe3c632Sopenharmony_ci assertElementsEquals(reader.readPackedSfixed64(), signedData); 848ffe3c632Sopenharmony_ci 849ffe3c632Sopenharmony_ci reader.nextField(); 850ffe3c632Sopenharmony_ci assertElementsEquals(reader.readPackedFloat(), floatData); 851ffe3c632Sopenharmony_ci 852ffe3c632Sopenharmony_ci reader.nextField(); 853ffe3c632Sopenharmony_ci assertElementsEquals(reader.readPackedDouble(), doubleData); 854ffe3c632Sopenharmony_ci 855ffe3c632Sopenharmony_ci reader.nextField(); 856ffe3c632Sopenharmony_ci assertElementsEquals(reader.readPackedBool(), boolData); 857ffe3c632Sopenharmony_ci 858ffe3c632Sopenharmony_ci reader.nextField(); 859ffe3c632Sopenharmony_ci assertElementsEquals(reader.readPackedEnum(), unsignedData); 860ffe3c632Sopenharmony_ci 861ffe3c632Sopenharmony_ci reader.nextField(); 862ffe3c632Sopenharmony_ci assertEquals(sentinel, reader.readInt32()); 863ffe3c632Sopenharmony_ci }); 864ffe3c632Sopenharmony_ci 865ffe3c632Sopenharmony_ci 866ffe3c632Sopenharmony_ci /** 867ffe3c632Sopenharmony_ci * Byte blobs inside nested messages should always have their byte offset set 868ffe3c632Sopenharmony_ci * relative to the start of the outermost blob, not the start of their parent 869ffe3c632Sopenharmony_ci * blob. 870ffe3c632Sopenharmony_ci */ 871ffe3c632Sopenharmony_ci it('testNestedBlobs', function() { 872ffe3c632Sopenharmony_ci // Create a proto consisting of two nested messages, with the inner one 873ffe3c632Sopenharmony_ci // containing a blob of bytes. 874ffe3c632Sopenharmony_ci 875ffe3c632Sopenharmony_ci var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED; 876ffe3c632Sopenharmony_ci var blob = [1, 2, 3, 4, 5]; 877ffe3c632Sopenharmony_ci var writer = new jspb.BinaryWriter(); 878ffe3c632Sopenharmony_ci var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); 879ffe3c632Sopenharmony_ci 880ffe3c632Sopenharmony_ci writer.writeMessage(1, dummyMessage, function() { 881ffe3c632Sopenharmony_ci writer.writeMessage(1, dummyMessage, function() { 882ffe3c632Sopenharmony_ci writer.writeBytes(1, blob); 883ffe3c632Sopenharmony_ci }); 884ffe3c632Sopenharmony_ci }); 885ffe3c632Sopenharmony_ci 886ffe3c632Sopenharmony_ci // Peel off the outer two message layers. Each layer should have two bytes 887ffe3c632Sopenharmony_ci // of overhead, one for the field tag and one for the length of the inner 888ffe3c632Sopenharmony_ci // blob. 889ffe3c632Sopenharmony_ci 890ffe3c632Sopenharmony_ci var decoder1 = new jspb.BinaryDecoder(writer.getResultBuffer()); 891ffe3c632Sopenharmony_ci assertEquals(fieldTag, decoder1.readUnsignedVarint32()); 892ffe3c632Sopenharmony_ci assertEquals(blob.length + 4, decoder1.readUnsignedVarint32()); 893ffe3c632Sopenharmony_ci 894ffe3c632Sopenharmony_ci var decoder2 = new jspb.BinaryDecoder(decoder1.readBytes(blob.length + 4)); 895ffe3c632Sopenharmony_ci assertEquals(fieldTag, decoder2.readUnsignedVarint32()); 896ffe3c632Sopenharmony_ci assertEquals(blob.length + 2, decoder2.readUnsignedVarint32()); 897ffe3c632Sopenharmony_ci 898ffe3c632Sopenharmony_ci assertEquals(fieldTag, decoder2.readUnsignedVarint32()); 899ffe3c632Sopenharmony_ci assertEquals(blob.length, decoder2.readUnsignedVarint32()); 900ffe3c632Sopenharmony_ci var bytes = decoder2.readBytes(blob.length); 901ffe3c632Sopenharmony_ci 902ffe3c632Sopenharmony_ci assertElementsEquals(bytes, blob); 903ffe3c632Sopenharmony_ci }); 904ffe3c632Sopenharmony_ci 905ffe3c632Sopenharmony_ci 906ffe3c632Sopenharmony_ci /** 907ffe3c632Sopenharmony_ci * Tests read callbacks. 908ffe3c632Sopenharmony_ci */ 909ffe3c632Sopenharmony_ci it('testReadCallbacks', function() { 910ffe3c632Sopenharmony_ci var writer = new jspb.BinaryWriter(); 911ffe3c632Sopenharmony_ci var dummyMessage = /** @type {!jspb.BinaryMessage} */({}); 912ffe3c632Sopenharmony_ci 913ffe3c632Sopenharmony_ci // Add an int, a submessage, and another int. 914ffe3c632Sopenharmony_ci writer.writeInt32(1, 100); 915ffe3c632Sopenharmony_ci 916ffe3c632Sopenharmony_ci writer.writeMessage(2, dummyMessage, function() { 917ffe3c632Sopenharmony_ci writer.writeInt32(3, 300); 918ffe3c632Sopenharmony_ci writer.writeInt32(4, 400); 919ffe3c632Sopenharmony_ci writer.writeInt32(5, 500); 920ffe3c632Sopenharmony_ci }); 921ffe3c632Sopenharmony_ci 922ffe3c632Sopenharmony_ci writer.writeInt32(7, 700); 923ffe3c632Sopenharmony_ci 924ffe3c632Sopenharmony_ci // Create the reader and register a custom read callback. 925ffe3c632Sopenharmony_ci var reader = jspb.BinaryReader.alloc(writer.getResultBuffer()); 926ffe3c632Sopenharmony_ci 927ffe3c632Sopenharmony_ci /** 928ffe3c632Sopenharmony_ci * @param {!jspb.BinaryReader} reader 929ffe3c632Sopenharmony_ci * @return {*} 930ffe3c632Sopenharmony_ci */ 931ffe3c632Sopenharmony_ci function readCallback(reader) { 932ffe3c632Sopenharmony_ci reader.nextField(); 933ffe3c632Sopenharmony_ci assertEquals(3, reader.getFieldNumber()); 934ffe3c632Sopenharmony_ci assertEquals(300, reader.readInt32()); 935ffe3c632Sopenharmony_ci 936ffe3c632Sopenharmony_ci reader.nextField(); 937ffe3c632Sopenharmony_ci assertEquals(4, reader.getFieldNumber()); 938ffe3c632Sopenharmony_ci assertEquals(400, reader.readInt32()); 939ffe3c632Sopenharmony_ci 940ffe3c632Sopenharmony_ci reader.nextField(); 941ffe3c632Sopenharmony_ci assertEquals(5, reader.getFieldNumber()); 942ffe3c632Sopenharmony_ci assertEquals(500, reader.readInt32()); 943ffe3c632Sopenharmony_ci 944ffe3c632Sopenharmony_ci assertEquals(false, reader.nextField()); 945ffe3c632Sopenharmony_ci }; 946ffe3c632Sopenharmony_ci 947ffe3c632Sopenharmony_ci reader.registerReadCallback('readCallback', readCallback); 948ffe3c632Sopenharmony_ci 949ffe3c632Sopenharmony_ci // Read the container message. 950ffe3c632Sopenharmony_ci reader.nextField(); 951ffe3c632Sopenharmony_ci assertEquals(1, reader.getFieldNumber()); 952ffe3c632Sopenharmony_ci assertEquals(100, reader.readInt32()); 953ffe3c632Sopenharmony_ci 954ffe3c632Sopenharmony_ci reader.nextField(); 955ffe3c632Sopenharmony_ci assertEquals(2, reader.getFieldNumber()); 956ffe3c632Sopenharmony_ci reader.readMessage(dummyMessage, function() { 957ffe3c632Sopenharmony_ci // Decode the embedded message using the registered callback. 958ffe3c632Sopenharmony_ci reader.runReadCallback('readCallback'); 959ffe3c632Sopenharmony_ci }); 960ffe3c632Sopenharmony_ci 961ffe3c632Sopenharmony_ci reader.nextField(); 962ffe3c632Sopenharmony_ci assertEquals(7, reader.getFieldNumber()); 963ffe3c632Sopenharmony_ci assertEquals(700, reader.readInt32()); 964ffe3c632Sopenharmony_ci 965ffe3c632Sopenharmony_ci assertEquals(false, reader.nextField()); 966ffe3c632Sopenharmony_ci }); 967ffe3c632Sopenharmony_ci}); 968