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

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

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


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

    var buffer = writer.getResultBuffer();

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

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

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

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

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

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

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

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

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

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

    assertEquals(false, reader.nextField());

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

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

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


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


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

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

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

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

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

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

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


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

    var writer = new jspb.BinaryWriter();

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

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

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

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

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

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

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


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

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

    var inputValues = [];

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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


  /**
   * Tests reading a field from hexadecimal string (format: '08 BE EF').
   * @param {Function} readField
   * @param {number} expected
   * @param {string} hexString
   */
  function doTestHexStringVarint_(readField, expected, hexString) {
    var bytesCount = (hexString.length + 1) / 3;
    var bytes = new Uint8Array(bytesCount);
    for (var i = 0; i < bytesCount; i++) {
      bytes[i] = parseInt(hexString.substring(i * 3, i * 3 + 2), 16);
    }
    var reader = jspb.BinaryReader.alloc(bytes);
    reader.nextField();
    assertEquals(expected, readField.call(reader));
  }


  /**
   * Tests non-canonical redundant varint decoding.
   */
  it('testRedundantVarintFields', function() {
    assertNotNull(jspb.BinaryReader.prototype.readUint32);
    assertNotNull(jspb.BinaryReader.prototype.readUint64);
    assertNotNull(jspb.BinaryReader.prototype.readSint32);
    assertNotNull(jspb.BinaryReader.prototype.readSint64);

    // uint32 and sint32 take no more than 5 bytes
    // 08 - field prefix (type = 0 means varint)
    doTestHexStringVarint_(
        jspb.BinaryReader.prototype.readUint32, 12, '08 8C 80 80 80 00');

    // 11 stands for -6 in zigzag encoding
    doTestHexStringVarint_(
        jspb.BinaryReader.prototype.readSint32, -6, '08 8B 80 80 80 00');

    // uint64 and sint64 take no more than 10 bytes
    // 08 - field prefix (type = 0 means varint)
    doTestHexStringVarint_(
        jspb.BinaryReader.prototype.readUint64, 12,
        '08 8C 80 80 80 80 80 80 80 80 00');

    // 11 stands for -6 in zigzag encoding
    doTestHexStringVarint_(
        jspb.BinaryReader.prototype.readSint64, -6,
        '08 8B 80 80 80 80 80 80 80 80 00');
  });

  /**
   * Tests reading 64-bit integers as split values.
   */
  it('handles split 64 fields', function() {
    var writer = new jspb.BinaryWriter();
    writer.writeInt64String(1, '4294967296');
    writer.writeSfixed64String(2, '4294967298');
    writer.writeInt64String(3, '3');  // 3 is the zig-zag encoding of -2.
    var reader = jspb.BinaryReader.alloc(writer.getResultBuffer());

    function rejoin(lowBits, highBits) {
      return highBits * 2 ** 32 + (lowBits >>> 0);
    }
    reader.nextField();
    expect(reader.getFieldNumber()).toEqual(1);
    expect(reader.readSplitVarint64(rejoin)).toEqual(0x100000000);

    reader.nextField();
    expect(reader.getFieldNumber()).toEqual(2);
    expect(reader.readSplitFixed64(rejoin)).toEqual(0x100000002);

    reader.nextField();
    expect(reader.getFieldNumber()).toEqual(3);
    expect(reader.readSplitZigzagVarint64(rejoin)).toEqual(-2);
  });

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

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

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

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

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


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

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

    doTestSignedField_(
        jspb.BinaryReader.prototype.readSintHash64,
        jspb.BinaryWriter.prototype.writeSintHash64, 1, -Math.pow(2, 63),
        Math.pow(2, 63) - 513, jspb.utils.numberToHash64);
  });


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

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

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

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


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

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


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

    var writer = new jspb.BinaryWriter();

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

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

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

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


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

    var writer = new jspb.BinaryWriter();

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

      writer.writeBytes(len, bytes);
    }

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

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

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


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

    writer.writeInt32(1, 100);

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

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

    writer.writeInt32(7, 700);

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

    // Validate outermost message.

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

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

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

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

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

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

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

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

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

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

    var sentinel = 123456789;

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

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

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

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

    // Write a group with a nested group inside.
    writer.writeInt32(5, sentinel);
    var dummyMessage = /** @type {!jspb.BinaryMessage} */ ({});
    writer.writeGroup(5, dummyMessage, function() {
      // Previously the skipGroup implementation was wrong, which only consume
      // the decoder by nextField. This case is for making the previous
      // implementation failed in skipGroup by an early end group tag.
      // The reason is 44 = 5 * 8 + 4, this will be translated in to a field
      // with number 5 and with type 4 (end group)
      writer.writeInt64(44, 44);
      // This will make previous implementation failed by invalid tag (7).
      writer.writeInt64(42, 47);
      writer.writeInt64(42, 42);
      // This is for making the previous implementation failed by an invalid
      // varint. The bytes have at least 9 consecutive minus byte, which will
      // fail in this.nextField for previous implementation.
      writer.writeBytes(43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]);
      writer.writeGroup(6, dummyMessage, function() {
        writer.writeInt64(84, 42);
        writer.writeInt64(84, 44);
        writer.writeBytes(
            43, [255, 255, 255, 255, 255, 255, 255, 255, 255, 255]);
      });
    });

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

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

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

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

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

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

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

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

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


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

    var sentinel = 123456789;

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

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

    writer.writeInt32(1, sentinel);

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

    writer.writeInt32(3, sentinel);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

    assertElementsEquals(bytes, blob);
  });


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

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

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

    writer.writeInt32(7, 700);

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

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

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

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

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

    reader.registerReadCallback('readCallback', readCallback);

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

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

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

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