// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc.  All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
//     * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

/**
 * @fileoverview Test cases for jspb's binary protocol buffer reader.
 *
 * There are two particular magic numbers that need to be pointed out -
 * 2^64-1025 is the largest number representable as both a double and an
 * unsigned 64-bit integer, and 2^63-513 is the largest number representable as
 * both a double and a signed 64-bit integer.
 *
 * Test suite is written using Jasmine -- see http://jasmine.github.io/
 *
 * @author aappleby@google.com (Austin Appleby)
 */

goog.require('goog.testing.asserts');
goog.require('jspb.BinaryConstants');
goog.require('jspb.BinaryDecoder');
goog.require('jspb.BinaryReader');
goog.require('jspb.BinaryWriter');



describe('binaryReaderTest', function() {
  /**
   * Tests the reader instance cache.
   * @suppress {visibility}
   */
  it('testInstanceCaches', function() {
    var writer = new jspb.BinaryWriter();
    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
    writer.writeMessage(1, dummyMessage, goog.nullFunction);
    writer.writeMessage(2, dummyMessage, goog.nullFunction);

    var buffer = writer.getResultBuffer();

    // Empty the instance caches.
    jspb.BinaryReader.instanceCache_ = [];

    // Allocating and then freeing three decoders should leave us with three in
    // the cache.

    var decoder1 = jspb.BinaryDecoder.alloc();
    var decoder2 = jspb.BinaryDecoder.alloc();
    var decoder3 = jspb.BinaryDecoder.alloc();
    decoder1.free();
    decoder2.free();
    decoder3.free();

    assertEquals(3, jspb.BinaryDecoder.instanceCache_.length);
    assertEquals(0, jspb.BinaryReader.instanceCache_.length);

    // Allocating and then freeing a reader should remove one decoder from its
    // cache, but it should stay stuck to the reader afterwards since we can't
    // have a reader without a decoder.
    jspb.BinaryReader.alloc().free();

    assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
    assertEquals(1, jspb.BinaryReader.instanceCache_.length);

    // Allocating a reader should remove a reader from the cache.
    var reader = jspb.BinaryReader.alloc(buffer);

    assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
    assertEquals(0, jspb.BinaryReader.instanceCache_.length);

    // Processing the message reuses the current reader.
    reader.nextField();
    assertEquals(1, reader.getFieldNumber());
    reader.readMessage(dummyMessage, function() {
      assertEquals(0, jspb.BinaryReader.instanceCache_.length);
    });

    reader.nextField();
    assertEquals(2, reader.getFieldNumber());
    reader.readMessage(dummyMessage, function() {
      assertEquals(0, jspb.BinaryReader.instanceCache_.length);
    });

    assertEquals(false, reader.nextField());

    assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
    assertEquals(0, jspb.BinaryReader.instanceCache_.length);

    // Freeing the reader should put it back into the cache.
    reader.free();

    assertEquals(2, jspb.BinaryDecoder.instanceCache_.length);
    assertEquals(1, jspb.BinaryReader.instanceCache_.length);
  });


  /**
   * @param {number} x
   * @return {number}
   */
  function truncate(x) {
    var temp = new Float32Array(1);
    temp[0] = x;
    return temp[0];
  }


  /**
   * Verifies that misuse of the reader class triggers assertions.
   * @suppress {checkTypes|visibility}
   */
  it('testReadErrors', function() {
    // Calling readMessage on a non-delimited field should trigger an
    // assertion.
    var reader = jspb.BinaryReader.alloc([8, 1]);
    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});
    reader.nextField();
    assertThrows(function() {
      reader.readMessage(dummyMessage, goog.nullFunction);
    });

    // Reading past the end of the stream should trigger an assertion.
    reader = jspb.BinaryReader.alloc([9, 1]);
    reader.nextField();
    assertThrows(function() {reader.readFixed64()});

    // Reading past the end of a submessage should trigger an assertion.
    reader = jspb.BinaryReader.alloc([10, 4, 13, 1, 1, 1]);
    reader.nextField();
    reader.readMessage(dummyMessage, function() {
      reader.nextField();
      assertThrows(function() {reader.readFixed32()});
    });

    // Skipping an invalid field should trigger an assertion.
    reader = jspb.BinaryReader.alloc([12, 1]);
    reader.nextWireType_ = 1000;
    assertThrows(function() {reader.skipField()});

    // Reading fields with the wrong wire type should assert.
    reader = jspb.BinaryReader.alloc([9, 0, 0, 0, 0, 0, 0, 0, 0]);
    reader.nextField();
    assertThrows(function() {reader.readInt32()});
    assertThrows(function() {reader.readInt32String()});
    assertThrows(function() {reader.readInt64()});
    assertThrows(function() {reader.readInt64String()});
    assertThrows(function() {reader.readUint32()});
    assertThrows(function() {reader.readUint32String()});
    assertThrows(function() {reader.readUint64()});
    assertThrows(function() {reader.readUint64String()});
    assertThrows(function() {reader.readSint32()});
    assertThrows(function() {reader.readBool()});
    assertThrows(function() {reader.readEnum()});

    reader = jspb.BinaryReader.alloc([8, 1]);
    reader.nextField();
    assertThrows(function() {reader.readFixed32()});
    assertThrows(function() {reader.readFixed64()});
    assertThrows(function() {reader.readSfixed32()});
    assertThrows(function() {reader.readSfixed64()});
    assertThrows(function() {reader.readFloat()});
    assertThrows(function() {reader.readDouble()});

    assertThrows(function() {reader.readString()});
    assertThrows(function() {reader.readBytes()});
  });


  /**
   * Tests encoding and decoding of unsigned field types.
   * @param {Function} readField
   * @param {Function} writeField
   * @param {number} epsilon
   * @param {number} upperLimit
   * @param {Function} filter
   * @private
   * @suppress {missingProperties}
   */
  function doTestUnsignedField_(readField,
      writeField, epsilon, upperLimit, filter) {
    assertNotNull(readField);
    assertNotNull(writeField);

    var writer = new jspb.BinaryWriter();

    // Encode zero and limits.
    writeField.call(writer, 1, filter(0));
    writeField.call(writer, 2, filter(epsilon));
    writeField.call(writer, 3, filter(upperLimit));

    // Encode positive values.
    for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
      writeField.call(writer, 4, filter(cursor));
    }

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    // Check zero and limits.
    reader.nextField();
    assertEquals(1, reader.getFieldNumber());
    assertEquals(filter(0), readField.call(reader));

    reader.nextField();
    assertEquals(2, reader.getFieldNumber());
    assertEquals(filter(epsilon), readField.call(reader));

    reader.nextField();
    assertEquals(3, reader.getFieldNumber());
    assertEquals(filter(upperLimit), readField.call(reader));

    // Check positive values.
    for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
      reader.nextField();
      if (4 != reader.getFieldNumber()) throw 'fail!';
      if (filter(cursor) != readField.call(reader)) throw 'fail!';
    }
  };


  /**
   * Tests encoding and decoding of signed field types.
   * @param {Function} readField
   * @param {Function} writeField
   * @param {number} epsilon
   * @param {number} lowerLimit
   * @param {number} upperLimit
   * @param {Function} filter
   * @private
   * @suppress {missingProperties}
   */
  function doTestSignedField_(readField,
      writeField, epsilon, lowerLimit, upperLimit, filter) {
    var writer = new jspb.BinaryWriter();

    // Encode zero and limits.
    writeField.call(writer, 1, filter(lowerLimit));
    writeField.call(writer, 2, filter(-epsilon));
    writeField.call(writer, 3, filter(0));
    writeField.call(writer, 4, filter(epsilon));
    writeField.call(writer, 5, filter(upperLimit));

    var inputValues = [];

    // Encode negative values.
    for (var cursor = lowerLimit; cursor < -epsilon; cursor /= 1.1) {
      var val = filter(cursor);
      writeField.call(writer, 6, val);
      inputValues.push({
        fieldNumber: 6,
        value: val
      });
    }

    // Encode positive values.
    for (var cursor = epsilon; cursor < upperLimit; cursor *= 1.1) {
      var val = filter(cursor);
      writeField.call(writer, 7, val);
      inputValues.push({
        fieldNumber: 7,
        value: val
      });
    }

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    // Check zero and limits.
    reader.nextField();
    assertEquals(1, reader.getFieldNumber());
    assertEquals(filter(lowerLimit), readField.call(reader));

    reader.nextField();
    assertEquals(2, reader.getFieldNumber());
    assertEquals(filter(-epsilon), readField.call(reader));

    reader.nextField();
    assertEquals(3, reader.getFieldNumber());
    assertEquals(filter(0), readField.call(reader));

    reader.nextField();
    assertEquals(4, reader.getFieldNumber());
    assertEquals(filter(epsilon), readField.call(reader));

    reader.nextField();
    assertEquals(5, reader.getFieldNumber());
    assertEquals(filter(upperLimit), readField.call(reader));

    for (var i = 0; i < inputValues.length; i++) {
      var expected = inputValues[i];
      reader.nextField();
      assertEquals(expected.fieldNumber, reader.getFieldNumber());
      assertEquals(expected.value, readField.call(reader));
    }
  };


  /**
   * Tests fields that use varint encoding.
   */
  it('testVarintFields', function() {
    assertNotNull(jspb.BinaryReader.prototype.readUint32);
    assertNotNull(jspb.BinaryReader.prototype.writeUint32);
    assertNotNull(jspb.BinaryReader.prototype.readUint64);
    assertNotNull(jspb.BinaryReader.prototype.writeUint64);
    assertNotNull(jspb.BinaryReader.prototype.readBool);
    assertNotNull(jspb.BinaryReader.prototype.writeBool);
    doTestUnsignedField_(
        jspb.BinaryReader.prototype.readUint32,
        jspb.BinaryWriter.prototype.writeUint32,
        1, Math.pow(2, 32) - 1, Math.round);

    doTestUnsignedField_(
        jspb.BinaryReader.prototype.readUint64,
        jspb.BinaryWriter.prototype.writeUint64,
        1, Math.pow(2, 64) - 1025, Math.round);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readInt32,
        jspb.BinaryWriter.prototype.writeInt32,
        1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readInt64,
        jspb.BinaryWriter.prototype.writeInt64,
        1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readEnum,
        jspb.BinaryWriter.prototype.writeEnum,
        1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);

    doTestUnsignedField_(
        jspb.BinaryReader.prototype.readBool,
        jspb.BinaryWriter.prototype.writeBool,
        1, 1, function(x) { return !!x; });
  });


  /**
   * Tests 64-bit fields that are handled as strings.
   */
  it('testStringInt64Fields', function() {
    var writer = new jspb.BinaryWriter();

    var testSignedData = [
        '2730538252207801776',
        '-2688470994844604560',
        '3398529779486536359',
        '3568577411627971000',
        '272477188847484900',
        '-6649058714086158188',
        '-7695254765712060806',
        '-4525541438037104029',
        '-4993706538836508568',
        '4990160321893729138'
    ];
    var testUnsignedData = [
        '7822732630241694882',
        '6753602971916687352',
        '2399935075244442116',
        '8724292567325338867',
        '16948784802625696584',
        '4136275908516066934',
        '3575388346793700364',
        '5167142028379259461',
        '1557573948689737699',
        '17100725280812548567'
    ];

    for (var i = 0; i < testSignedData.length; i++) {
      writer.writeInt64String(2 * i + 1, testSignedData[i]);
      writer.writeUint64String(2 * i + 2, testUnsignedData[i]);
    }

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    for (var i = 0; i < testSignedData.length; i++) {
      reader.nextField();
      assertEquals(2 * i + 1, reader.getFieldNumber());
      assertEquals(testSignedData[i], reader.readInt64String());
      reader.nextField();
      assertEquals(2 * i + 2, reader.getFieldNumber());
      assertEquals(testUnsignedData[i], reader.readUint64String());
    }
  });


  /**
   * Tests fields that use zigzag encoding.
   */
  it('testZigzagFields', function() {
    doTestSignedField_(
        jspb.BinaryReader.prototype.readSint32,
        jspb.BinaryWriter.prototype.writeSint32,
        1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readSint64,
        jspb.BinaryWriter.prototype.writeSint64,
        1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
  });


  /**
   * Tests fields that use fixed-length encoding.
   */
  it('testFixedFields', function() {
    doTestUnsignedField_(
        jspb.BinaryReader.prototype.readFixed32,
        jspb.BinaryWriter.prototype.writeFixed32,
        1, Math.pow(2, 32) - 1, Math.round);

    doTestUnsignedField_(
        jspb.BinaryReader.prototype.readFixed64,
        jspb.BinaryWriter.prototype.writeFixed64,
        1, Math.pow(2, 64) - 1025, Math.round);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readSfixed32,
        jspb.BinaryWriter.prototype.writeSfixed32,
        1, -Math.pow(2, 31), Math.pow(2, 31) - 1, Math.round);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readSfixed64,
        jspb.BinaryWriter.prototype.writeSfixed64,
        1, -Math.pow(2, 63), Math.pow(2, 63) - 513, Math.round);
  });


  /**
   * Tests floating point fields.
   */
  it('testFloatFields', function() {
    doTestSignedField_(
        jspb.BinaryReader.prototype.readFloat,
        jspb.BinaryWriter.prototype.writeFloat,
        jspb.BinaryConstants.FLOAT32_MIN,
        -jspb.BinaryConstants.FLOAT32_MAX,
        jspb.BinaryConstants.FLOAT32_MAX,
        truncate);

    doTestSignedField_(
        jspb.BinaryReader.prototype.readDouble,
        jspb.BinaryWriter.prototype.writeDouble,
        jspb.BinaryConstants.FLOAT64_EPS * 10,
        -jspb.BinaryConstants.FLOAT64_MIN,
        jspb.BinaryConstants.FLOAT64_MIN,
        function(x) { return x; });
  });


  /**
   * Tests length-delimited string fields.
   */
  it('testStringFields', function() {
    var s1 = 'The quick brown fox jumps over the lazy dog.';
    var s2 = '人人生而自由，在尊嚴和權利上一律平等。';

    var writer = new jspb.BinaryWriter();

    writer.writeString(1, s1);
    writer.writeString(2, s2);

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    reader.nextField();
    assertEquals(1, reader.getFieldNumber());
    assertEquals(s1, reader.readString());

    reader.nextField();
    assertEquals(2, reader.getFieldNumber());
    assertEquals(s2, reader.readString());
  });


  /**
   * Tests length-delimited byte fields.
   */
  it('testByteFields', function() {
    var message = [];
    var lowerLimit = 1;
    var upperLimit = 256;
    var scale = 1.1;

    var writer = new jspb.BinaryWriter();

    for (var cursor = lowerLimit; cursor < upperLimit; cursor *= 1.1) {
      var len = Math.round(cursor);
      var bytes = [];
      for (var i = 0; i < len; i++) bytes.push(i % 256);

      writer.writeBytes(len, bytes);
    }

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    for (var cursor = lowerLimit; reader.nextField(); cursor *= 1.1) {
      var len = Math.round(cursor);
      if (len != reader.getFieldNumber()) throw 'fail!';

      var bytes = reader.readBytes();
      if (len != bytes.length) throw 'fail!';
      for (var i = 0; i < bytes.length; i++) {
        if (i % 256 != bytes[i]) throw 'fail!';
      }
    }
  });


  /**
   * Tests nested messages.
   */
  it('testNesting', function() {
    var writer = new jspb.BinaryWriter();
  var dummyMessage = /** @type {!jspb.BinaryMessage} */({});

    writer.writeInt32(1, 100);

    // Add one message with 3 int fields.
    writer.writeMessage(2, dummyMessage, function() {
      writer.writeInt32(3, 300);
      writer.writeInt32(4, 400);
      writer.writeInt32(5, 500);
    });

    // Add one empty message.
    writer.writeMessage(6, dummyMessage, goog.nullFunction);

    writer.writeInt32(7, 700);

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    // Validate outermost message.

    reader.nextField();
    assertEquals(1, reader.getFieldNumber());
    assertEquals(100, reader.readInt32());

    reader.nextField();
    assertEquals(2, reader.getFieldNumber());
    reader.readMessage(dummyMessage, function() {
      // Validate embedded message 1.
      reader.nextField();
      assertEquals(3, reader.getFieldNumber());
      assertEquals(300, reader.readInt32());

      reader.nextField();
      assertEquals(4, reader.getFieldNumber());
      assertEquals(400, reader.readInt32());

      reader.nextField();
      assertEquals(5, reader.getFieldNumber());
      assertEquals(500, reader.readInt32());

      assertEquals(false, reader.nextField());
    });

    reader.nextField();
    assertEquals(6, reader.getFieldNumber());
    reader.readMessage(dummyMessage, function() {
      // Validate embedded message 2.

      assertEquals(false, reader.nextField());
    });

    reader.nextField();
    assertEquals(7, reader.getFieldNumber());
    assertEquals(700, reader.readInt32());

    assertEquals(false, reader.nextField());
  });

  /**
   * Tests skipping fields of each type by interleaving them with sentinel
   * values and skipping everything that's not a sentinel.
   */
  it('testSkipField', function() {
    var writer = new jspb.BinaryWriter();

    var sentinel = 123456789;

    // Write varint fields of different sizes.
    writer.writeInt32(1, sentinel);
    writer.writeInt32(1, 1);
    writer.writeInt32(1, 1000);
    writer.writeInt32(1, 1000000);
    writer.writeInt32(1, 1000000000);

    // Write fixed 64-bit encoded fields.
    writer.writeInt32(2, sentinel);
    writer.writeDouble(2, 1);
    writer.writeFixed64(2, 1);
    writer.writeSfixed64(2, 1);

    // Write fixed 32-bit encoded fields.
    writer.writeInt32(3, sentinel);
    writer.writeFloat(3, 1);
    writer.writeFixed32(3, 1);
    writer.writeSfixed32(3, 1);

    // Write delimited fields.
    writer.writeInt32(4, sentinel);
    writer.writeBytes(4, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);
    writer.writeString(4, 'The quick brown fox jumps over the lazy dog');

    // Write a group with a nested group inside. We use the internal
    // .rawWriteVarint() to ensure the tested wire data is what we want,
    // independently of any serialization logic.
    writer.writeInt32(5, sentinel);
    // Start group, field 5.
    writer.rawWriteVarint(
        (5 << 3) + jspb.BinaryConstants.WireType.START_GROUP);
    // Varint, field 42.
    writer.rawWriteVarint(
        (42 << 3) + jspb.BinaryConstants.WireType.VARINT);
    // Varint data.
    writer.rawWriteVarint(42);
    // Start group, field 6.
    writer.rawWriteVarint(
        (6 << 3) + jspb.BinaryConstants.WireType.START_GROUP);
    // Varint, field 84.
    writer.rawWriteVarint(
        (84 << 3) + jspb.BinaryConstants.WireType.VARINT);
    writer.rawWriteVarint(42);
    // End group, field 6.
    writer.rawWriteVarint(
        (6 << 3) + jspb.BinaryConstants.WireType.END_GROUP);
    // End group, field 5.
    writer.rawWriteVarint(
        (5 << 3) + jspb.BinaryConstants.WireType.END_GROUP);

    // Write final sentinel.
    writer.writeInt32(6, sentinel);

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    function skip(field, count) {
      for (var i = 0; i < count; i++) {
        reader.nextField();
        if (field != reader.getFieldNumber()) throw 'fail!';
        reader.skipField();
      }
    }

    reader.nextField();
    assertEquals(1, reader.getFieldNumber());
    assertEquals(sentinel, reader.readInt32());
    skip(1, 4);

    reader.nextField();
    assertEquals(2, reader.getFieldNumber());
    assertEquals(sentinel, reader.readInt32());
    skip(2, 3);

    reader.nextField();
    assertEquals(3, reader.getFieldNumber());
    assertEquals(sentinel, reader.readInt32());
    skip(3, 3);

    reader.nextField();
    assertEquals(4, reader.getFieldNumber());
    assertEquals(sentinel, reader.readInt32());
    skip(4, 2);

    reader.nextField();
    assertEquals(5, reader.getFieldNumber());
    assertEquals(sentinel, reader.readInt32());
    skip(5, 1);

    reader.nextField();
    assertEquals(6, reader.getFieldNumber());
    assertEquals(sentinel, reader.readInt32());
  });


  /**
   * Tests packed fields.
   */
  it('testPackedFields', function() {
    var writer = new jspb.BinaryWriter();

    var sentinel = 123456789;

    var unsignedData = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
    var signedData = [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10];
    var floatData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10];
    var doubleData = [1.1, 2.2, 3.3, 4.4, 5.5, 6.6, 7.7, 8.8, 9.9, 10.10];
    var boolData = [true, false, true, true, false, false, true, false];

    for (var i = 0; i < floatData.length; i++) {
      floatData[i] = truncate(floatData[i]);
    }

    writer.writeInt32(1, sentinel);

    writer.writePackedInt32(2, signedData);
    writer.writePackedInt64(2, signedData);
    writer.writePackedUint32(2, unsignedData);
    writer.writePackedUint64(2, unsignedData);
    writer.writePackedSint32(2, signedData);
    writer.writePackedSint64(2, signedData);
    writer.writePackedFixed32(2, unsignedData);
    writer.writePackedFixed64(2, unsignedData);
    writer.writePackedSfixed32(2, signedData);
    writer.writePackedSfixed64(2, signedData);
    writer.writePackedFloat(2, floatData);
    writer.writePackedDouble(2, doubleData);
    writer.writePackedBool(2, boolData);
    writer.writePackedEnum(2, unsignedData);

    writer.writeInt32(3, sentinel);

    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    reader.nextField();
    assertEquals(sentinel, reader.readInt32());

    reader.nextField();
    assertElementsEquals(reader.readPackedInt32(), signedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedInt64(), signedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedUint32(), unsignedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedUint64(), unsignedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedSint32(), signedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedSint64(), signedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedFixed32(), unsignedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedFixed64(), unsignedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedSfixed32(), signedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedSfixed64(), signedData);

    reader.nextField();
    assertElementsEquals(reader.readPackedFloat(), floatData);

    reader.nextField();
    assertElementsEquals(reader.readPackedDouble(), doubleData);

    reader.nextField();
    assertElementsEquals(reader.readPackedBool(), boolData);

    reader.nextField();
    assertElementsEquals(reader.readPackedEnum(), unsignedData);

    reader.nextField();
    assertEquals(sentinel, reader.readInt32());
  });


  /**
   * Byte blobs inside nested messages should always have their byte offset set
   * relative to the start of the outermost blob, not the start of their parent
   * blob.
   */
  it('testNestedBlobs', function() {
    // Create a proto consisting of two nested messages, with the inner one
    // containing a blob of bytes.

    var fieldTag = (1 << 3) | jspb.BinaryConstants.WireType.DELIMITED;
    var blob = [1, 2, 3, 4, 5];
    var writer = new jspb.BinaryWriter();
    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});

    writer.writeMessage(1, dummyMessage, function() {
      writer.writeMessage(1, dummyMessage, function() {
        writer.writeBytes(1, blob);
      });
    });

    // Peel off the outer two message layers. Each layer should have two bytes
    // of overhead, one for the field tag and one for the length of the inner
    // blob.

    var decoder1 = new jspb.BinaryDecoder(writer.getResultBuffer());
    assertEquals(fieldTag, decoder1.readUnsignedVarint32());
    assertEquals(blob.length + 4, decoder1.readUnsignedVarint32());

    var decoder2 = new jspb.BinaryDecoder(decoder1.readBytes(blob.length + 4));
    assertEquals(fieldTag, decoder2.readUnsignedVarint32());
    assertEquals(blob.length + 2, decoder2.readUnsignedVarint32());

    assertEquals(fieldTag, decoder2.readUnsignedVarint32());
    assertEquals(blob.length, decoder2.readUnsignedVarint32());
    var bytes = decoder2.readBytes(blob.length);

    assertElementsEquals(bytes, blob);
  });


  /**
   * Tests read callbacks.
   */
  it('testReadCallbacks', function() {
    var writer = new jspb.BinaryWriter();
    var dummyMessage = /** @type {!jspb.BinaryMessage} */({});

    // Add an int, a submessage, and another int.
    writer.writeInt32(1, 100);

    writer.writeMessage(2, dummyMessage, function() {
      writer.writeInt32(3, 300);
      writer.writeInt32(4, 400);
      writer.writeInt32(5, 500);
    });

    writer.writeInt32(7, 700);

    // Create the reader and register a custom read callback.
    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    /**
     * @param {!jspb.BinaryReader} reader
     * @return {*}
     */
    function readCallback(reader) {
      reader.nextField();
      assertEquals(3, reader.getFieldNumber());
      assertEquals(300, reader.readInt32());

      reader.nextField();
      assertEquals(4, reader.getFieldNumber());
      assertEquals(400, reader.readInt32());

      reader.nextField();
      assertEquals(5, reader.getFieldNumber());
      assertEquals(500, reader.readInt32());

      assertEquals(false, reader.nextField());
    };

    reader.registerReadCallback('readCallback', readCallback);

    // Read the container message.
    reader.nextField();
    assertEquals(1, reader.getFieldNumber());
    assertEquals(100, reader.readInt32());

    reader.nextField();
    assertEquals(2, reader.getFieldNumber());
    reader.readMessage(dummyMessage, function() {
      // Decode the embedded message using the registered callback.
      reader.runReadCallback('readCallback');
    });

    reader.nextField();
    assertEquals(7, reader.getFieldNumber());
    assertEquals(700, reader.readInt32());

    assertEquals(false, reader.nextField());
  });
});
