15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc.  All rights reserved.
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met:
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions of source code must retain the above copyright
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer.
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Redistributions in binary form must reproduce the above
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution.
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//     * Neither the name of Google Inc. nor the names of its
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission.
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda)
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Based on original Protocol Buffers design by
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//  Sanjay Ghemawat, Jeff Dean, and others.
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This file contains tests and benchmarks.
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <vector>
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/coded_stream.h>
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <limits.h>
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/common.h>
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/testing/googletest.h>
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtest/gtest.h>
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/zero_copy_stream_impl.h>
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This declares an unsigned long long integer literal in a portable way.
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (The original macro is way too big and ruins my formatting.)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#undef ULL
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define ULL(x) GOOGLE_ULONGLONG(x)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google {
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace io {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Data-Driven Test Infrastructure
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TEST_1D and TEST_2D are macros I'd eventually like to see added to
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// gTest.  These macros can be used to declare tests which should be
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// run multiple times, once for each item in some input array.  TEST_1D
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// tests all cases in a single input array.  TEST_2D tests all
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// combinations of cases from two arrays.  The arrays must be statically
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// defined such that the GOOGLE_ARRAYSIZE() macro works on them.  Example:
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// int kCases[] = {1, 2, 3, 4}
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TEST_1D(MyFixture, MyTest, kCases) {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   EXPECT_GT(kCases_case, 0);
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test iterates through the numbers 1, 2, 3, and 4 and tests that
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// they are all grater than zero.  In case of failure, the exact case
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// which failed will be printed.  The case type must be printable using
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ostream::operator<<.
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(kenton):  gTest now supports "parameterized tests" which would be
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   a better way to accomplish this.  Rewrite when time permits.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TEST_1D(FIXTURE, NAME, CASES)                                      \
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class FIXTURE##_##NAME##_DD : public FIXTURE {                           \
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   protected:                                                              \
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    template <typename CaseType>                                           \
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void DoSingleCase(const CaseType& CASES##_case);                       \
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };                                                                       \
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                                           \
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TEST_F(FIXTURE##_##NAME##_DD, NAME) {                                    \
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) {                           \
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      SCOPED_TRACE(testing::Message()                                      \
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        << #CASES " case #" << i << ": " << CASES[i]);                     \
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DoSingleCase(CASES[i]);                                              \
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }                                                                      \
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }                                                                        \
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                                           \
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename CaseType>                                             \
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define TEST_2D(FIXTURE, NAME, CASES1, CASES2)                             \
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class FIXTURE##_##NAME##_DD : public FIXTURE {                           \
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   protected:                                                              \
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    template <typename CaseType1, typename CaseType2>                      \
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    void DoSingleCase(const CaseType1& CASES1##_case,                      \
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                      const CaseType2& CASES2##_case);                     \
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  };                                                                       \
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                                           \
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TEST_F(FIXTURE##_##NAME##_DD, NAME) {                                    \
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) {                          \
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) {                        \
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        SCOPED_TRACE(testing::Message()                                    \
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << #CASES1 " case #" << i << ": " << CASES1[i] << ", "           \
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          << #CASES2 " case #" << j << ": " << CASES2[j]);                 \
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        DoSingleCase(CASES1[i], CASES2[j]);                                \
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      }                                                                    \
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }                                                                      \
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }                                                                        \
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                                           \
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  template <typename CaseType1, typename CaseType2>                        \
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                           const CaseType2& CASES2##_case)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CodedStreamTest : public testing::Test {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
127ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Helper method used by tests for bytes warning. See implementation comment
128ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // for further information.
129ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  static void SetupTotalBytesLimitWarningTest(
130ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      int total_bytes_limit, int warning_threshold,
131ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch      vector<string>* out_errors, vector<string>* out_warnings);
132ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
133ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Buffer used during most of the tests. This assumes tests run sequentially.
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static const int kBufferSize = 1024 * 64;
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  static uint8 buffer_[kBufferSize];
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)uint8 CodedStreamTest::buffer_[CodedStreamTest::kBufferSize];
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// We test each operation over a variety of block sizes to insure that
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we test cases where reads or writes cross buffer boundaries, cases
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// where they don't, and cases where there is so much buffer left that
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// we can use special optimized paths that don't worry about bounds
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// checks.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024};
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------------------------------------------------------------------
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Varint tests.
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct VarintCase {
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8 bytes[10];          // Encoded bytes.
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size;                 // Encoded size, in bytes.
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 value;             // Parsed value.
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline std::ostream& operator<<(std::ostream& os, const VarintCase& c) {
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return os << c.value;
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VarintCase kVarintCases[] = {
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 32-bit values
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0x00}      , 1, 0},
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0x01}      , 1, 1},
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0x7f}      , 1, 127},
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0xa2, 0x74}, 2, (0x22 << 0) | (0x74 << 7)},          // 14882
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0xbe, 0xf7, 0x92, 0x84, 0x0b}, 5,                    // 2961488830
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (ULL(0x0b) << 28)},
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 64-bit
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0xbe, 0xf7, 0x92, 0x84, 0x1b}, 5,                    // 7256456126
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (ULL(0x1b) << 28)},
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49}, 8,  // 41256202580718336
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (ULL(0x43) << 28) | (ULL(0x49) << 35) | (ULL(0x24) << 42) |
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (ULL(0x49) << 49)},
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // 11964378330978735131
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01}, 10,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (ULL(0x3b) << 28) | (ULL(0x56) << 35) | (ULL(0x00) << 42) |
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    (ULL(0x05) << 49) | (ULL(0x26) << 56) | (ULL(0x01) << 63)},
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_2D(CodedStreamTest, ReadVarint32, kVarintCases, kBlockSizes) {
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 value;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadVarint32(&value));
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(static_cast<uint32>(kVarintCases_case.value), value);
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_2D(CodedStreamTest, ReadTag, kVarintCases, kBlockSizes) {
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(expected_value, coded_input.ReadTag());
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.LastTagWas(expected_value));
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(coded_input.LastTagWas(expected_value + 1));
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This is the regression test that verifies that there is no issues
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// with the empty input buffers handling.
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CodedStreamTest, EmptyInputBeforeEos) {
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  class In : public ZeroCopyInputStream {
2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   public:
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    In() : count_(0) {}
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   private:
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual bool Next(const void** data, int* size) {
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *data = NULL;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *size = 0;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return count_++ < 2;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual void BackUp(int count)  {
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GOOGLE_LOG(FATAL) << "Tests never call this.";
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual bool Skip(int count) {
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      GOOGLE_LOG(FATAL) << "Tests never call this.";
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return false;
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    virtual int64 ByteCount() const { return 0; }
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int count_;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } in;
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream input(&in);
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  input.ReadTag();
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(input.ConsumedEntireMessage());
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) {
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Leave one byte at the beginning of the buffer so we can read it
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // to force the first buffer to be loaded.
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  buffer_[0] = '\0';
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_ + 1, kVarintCases_case.bytes, kVarintCases_case.size);
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_));
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Read one byte to force coded_input.Refill() to be called.  Otherwise,
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ExpectTag() will return a false negative.
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint8 dummy;
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    coded_input.ReadRaw(&dummy, 1);
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ((uint)'\0', (uint)dummy);
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // ExpectTag() produces false negatives for large values.
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (kVarintCases_case.size <= 2) {
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(coded_input.ExpectTag(expected_value + 1));
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_TRUE(coded_input.ExpectTag(expected_value));
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_FALSE(coded_input.ExpectTag(expected_value));
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (kVarintCases_case.size <= 2) {
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kVarintCases_case.size + 1, input.ByteCount());
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(1, input.ByteCount());
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_1D(CodedStreamTest, ExpectTagFromArray, kVarintCases) {
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the expectation succeeds, it should return a pointer past the tag.
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (kVarintCases_case.size <= 2) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(NULL ==
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CodedInputStream::ExpectTagFromArray(buffer_,
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                     expected_value + 1));
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(buffer_ + kVarintCases_case.size ==
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CodedInputStream::ExpectTagFromArray(buffer_, expected_value));
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(NULL ==
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                CodedInputStream::ExpectTagFromArray(buffer_, expected_value));
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_2D(CodedStreamTest, ReadVarint64, kVarintCases, kBlockSizes) {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint64 value;
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadVarint64(&value));
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kVarintCases_case.value, value);
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_2D(CodedStreamTest, WriteVarint32, kVarintCases, kBlockSizes) {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (kVarintCases_case.value > ULL(0x00000000FFFFFFFF)) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Skip this test for the 64-bit values.
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedOutputStream coded_output(&output);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    coded_output.WriteVarint32(static_cast<uint32>(kVarintCases_case.value));
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(coded_output.HadError());
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount());
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kVarintCases_case.size, output.ByteCount());
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0,
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size));
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_2D(CodedStreamTest, WriteVarint64, kVarintCases, kBlockSizes) {
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedOutputStream coded_output(&output);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    coded_output.WriteVarint64(kVarintCases_case.value);
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(coded_output.HadError());
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount());
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kVarintCases_case.size, output.ByteCount());
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0,
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size));
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This test causes gcc 3.3.5 (and earlier?) to give the cryptic error:
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)//   "sorry, unimplemented: `method_call_expr' not supported by dump_expr"
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int32 kSignExtendedVarintCases[] = {
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0, 1, -1, 1237894, -37895138
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_2D(CodedStreamTest, WriteVarint32SignExtended,
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        kSignExtendedVarintCases, kBlockSizes) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedOutputStream coded_output(&output);
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    coded_output.WriteVarint32SignExtended(kSignExtendedVarintCases_case);
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(coded_output.HadError());
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (kSignExtendedVarintCases_case < 0) {
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_EQ(10, coded_output.ByteCount());
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    } else {
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      EXPECT_LE(coded_output.ByteCount(), 5);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (kSignExtendedVarintCases_case < 0) {
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(10, output.ByteCount());
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_LE(output.ByteCount(), 5);
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read value back in as a varint64 and insure it matches.
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_));
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint64 value;
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadVarint64(&value));
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kSignExtendedVarintCases_case, static_cast<int64>(value));
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(output.ByteCount(), input.ByteCount());
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------------------------------------------------------------------
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Varint failure test.
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct VarintErrorCase {
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8 bytes[12];
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size;
4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool can_parse;
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline std::ostream& operator<<(std::ostream& os, const VarintErrorCase& c) {
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return os << "size " << c.size;
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const VarintErrorCase kVarintErrorCases[] = {
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Control case.  (Insures that there isn't something else wrong that
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // makes parsing always fail.)
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0x00}, 1, true},
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // No input data.
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{}, 0, false},
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Input ends unexpectedly.
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0xf0, 0xab}, 2, false},
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Input ends unexpectedly after 32 bits.
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0xf0, 0xab, 0xc9, 0x9a, 0xf8, 0xb2}, 6, false},
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Longer than 10 bytes.
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01},
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)   11, false},
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_2D(CodedStreamTest, ReadVarint32Error, kVarintErrorCases, kBlockSizes) {
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         kBlockSizes_case);
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream coded_input(&input);
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 value;
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint32(&value));
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_2D(CodedStreamTest, ReadVarint64Error, kVarintErrorCases, kBlockSizes) {
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         kBlockSizes_case);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream coded_input(&input);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 value;
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint64(&value));
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------------------------------------------------------------------
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// VarintSize
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct VarintSizeCase {
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 value;
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size;
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline std::ostream& operator<<(std::ostream& os, const VarintSizeCase& c) {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return os << c.value;
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)VarintSizeCase kVarintSizeCases[] = {
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {0u, 1},
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {1u, 1},
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {127u, 1},
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {128u, 2},
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {758923u, 3},
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {4000000000u, 5},
4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {ULL(41256202580718336), 8},
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {ULL(11964378330978735131), 10},
4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_1D(CodedStreamTest, VarintSize32, kVarintSizeCases) {
4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (kVarintSizeCases_case.value > 0xffffffffu) {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Skip 64-bit values.
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kVarintSizeCases_case.size,
4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedOutputStream::VarintSize32(
4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      static_cast<uint32>(kVarintSizeCases_case.value)));
4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_1D(CodedStreamTest, VarintSize64, kVarintSizeCases) {
4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kVarintSizeCases_case.size,
4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedOutputStream::VarintSize64(kVarintSizeCases_case.value));
4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------------------------------------------------------------------
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Fixed-size int tests
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Fixed32Case {
4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8 bytes[sizeof(uint32)];          // Encoded bytes.
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 value;                         // Parsed value.
4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct Fixed64Case {
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8 bytes[sizeof(uint64)];          // Encoded bytes.
5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 value;                         // Parsed value.
5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline std::ostream& operator<<(std::ostream& os, const Fixed32Case& c) {
5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return os << "0x" << hex << c.value << dec;
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)inline std::ostream& operator<<(std::ostream& os, const Fixed64Case& c) {
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return os << "0x" << hex << c.value << dec;
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Fixed32Case kFixed32Cases[] = {
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0xef, 0xcd, 0xab, 0x90}, 0x90abcdefu},
5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0x12, 0x34, 0x56, 0x78}, 0x78563412u},
5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Fixed64Case kFixed64Cases[] = {
5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0xef, 0xcd, 0xab, 0x90, 0x12, 0x34, 0x56, 0x78}, ULL(0x7856341290abcdef)},
5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, ULL(0x8877665544332211)},
5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_2D(CodedStreamTest, ReadLittleEndian32, kFixed32Cases, kBlockSizes) {
5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes));
5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 value;
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kFixed32Cases_case.value, value);
5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(sizeof(uint32), input.ByteCount());
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_2D(CodedStreamTest, ReadLittleEndian64, kFixed64Cases, kBlockSizes) {
5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes));
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint64 value;
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadLittleEndian64(&value));
5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kFixed64Cases_case.value, value);
5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(sizeof(uint64), input.ByteCount());
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_2D(CodedStreamTest, WriteLittleEndian32, kFixed32Cases, kBlockSizes) {
5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedOutputStream coded_output(&output);
5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    coded_output.WriteLittleEndian32(kFixed32Cases_case.value);
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(coded_output.HadError());
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(sizeof(uint32), coded_output.ByteCount());
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(sizeof(uint32), output.ByteCount());
5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, memcmp(buffer_, kFixed32Cases_case.bytes, sizeof(uint32)));
5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_2D(CodedStreamTest, WriteLittleEndian64, kFixed64Cases, kBlockSizes) {
5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedOutputStream coded_output(&output);
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    coded_output.WriteLittleEndian64(kFixed64Cases_case.value);
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(coded_output.HadError());
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(sizeof(uint64), coded_output.ByteCount());
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(sizeof(uint64), output.ByteCount());
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, memcmp(buffer_, kFixed64Cases_case.bytes, sizeof(uint64)));
5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests using the static methods to read fixed-size values from raw arrays.
5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_1D(CodedStreamTest, ReadLittleEndian32FromArray, kFixed32Cases) {
5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes));
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 value;
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint8* end = CodedInputStream::ReadLittleEndian32FromArray(
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buffer_, &value);
5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kFixed32Cases_case.value, value);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(end == buffer_ + sizeof(value));
5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_1D(CodedStreamTest, ReadLittleEndian64FromArray, kFixed64Cases) {
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes));
5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint64 value;
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const uint8* end = CodedInputStream::ReadLittleEndian64FromArray(
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      buffer_, &value);
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(kFixed64Cases_case.value, value);
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(end == buffer_ + sizeof(value));
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------------------------------------------------------------------
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Raw reads and writes
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kRawBytes[] = "Some bytes which will be written and read raw.";
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_1D(CodedStreamTest, ReadRaw, kBlockSizes) {
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char read_buffer[sizeof(kRawBytes)];
6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadRaw(read_buffer, sizeof(kRawBytes)));
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, memcmp(kRawBytes, read_buffer, sizeof(kRawBytes)));
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(sizeof(kRawBytes), input.ByteCount());
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_1D(CodedStreamTest, WriteRaw, kBlockSizes) {
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedOutputStream coded_output(&output);
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    coded_output.WriteRaw(kRawBytes, sizeof(kRawBytes));
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(coded_output.HadError());
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(sizeof(kRawBytes), coded_output.ByteCount());
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(sizeof(kRawBytes), output.ByteCount());
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, memcmp(buffer_, kRawBytes, sizeof(kRawBytes)));
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_1D(CodedStreamTest, ReadString, kBlockSizes) {
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string str;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(kRawBytes, str);
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check to make sure ReadString doesn't crash on impossibly large strings.
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_1D(CodedStreamTest, ReadStringImpossiblyLarge, kBlockSizes) {
6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string str;
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Try to read a gigabyte.
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnStack) {
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Same test as above, except directly use a buffer. This used to cause
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // crashes while the above did not.
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint8 buffer[8];
6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream coded_input(buffer, 8);
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string str;
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnHeap) {
6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_array<uint8> buffer(new uint8[8]);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream coded_input(buffer.get(), 8);
6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string str;
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------------------------------------------------------------------
6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Skip
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSkipTestBytes[] =
6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "<Before skipping><To be skipped><After skipping>";
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSkipOutputTestBytes[] =
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  "-----------------<To be skipped>----------------";
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_1D(CodedStreamTest, SkipInput, kBlockSizes) {
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  memcpy(buffer_, kSkipTestBytes, sizeof(kSkipTestBytes));
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string str;
7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadString(&str, strlen("<Before skipping>")));
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("<Before skipping>", str);
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.Skip(strlen("<To be skipped>")));
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadString(&str, strlen("<After skipping>")));
7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ("<After skipping>", str);
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(strlen(kSkipTestBytes), input.ByteCount());
7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------------------------------------------------------------------
7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// GetDirectBufferPointer
7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CodedStreamTest, GetDirectBufferPointerInput) {
7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_), 8);
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream coded_input(&input);
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* ptr;
7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size;
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(buffer_, ptr);
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8, size);
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Peeking again should return the same pointer.
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(buffer_, ptr);
7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8, size);
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Skip forward in the same buffer then peek again.
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.Skip(3));
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(buffer_ + 3, ptr);
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, size);
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Skip to end of buffer and peek -- should get next buffer.
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.Skip(5));
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(buffer_ + 8, ptr);
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8, size);
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CodedStreamTest, GetDirectBufferPointerInlineInput) {
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_), 8);
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream coded_input(&input);
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const void* ptr;
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size;
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.GetDirectBufferPointerInline(&ptr, &size);
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(buffer_, ptr);
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8, size);
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Peeking again should return the same pointer.
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.GetDirectBufferPointerInline(&ptr, &size);
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(buffer_, ptr);
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8, size);
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Skip forward in the same buffer then peek again.
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.Skip(3));
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.GetDirectBufferPointerInline(&ptr, &size);
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(buffer_ + 3, ptr);
7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, size);
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Skip to end of buffer and peek -- should return false and provide an empty
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // buffer. It does not try to Refresh().
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.Skip(5));
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.GetDirectBufferPointerInline(&ptr, &size);
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(buffer_ + 8, ptr);
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, size);
7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CodedStreamTest, GetDirectBufferPointerOutput) {
7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayOutputStream output(buffer_, sizeof(buffer_), 8);
7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedOutputStream coded_output(&output);
7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void* ptr;
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int size;
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(buffer_, ptr);
7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8, size);
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Peeking again should return the same pointer.
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(buffer_, ptr);
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8, size);
7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Skip forward in the same buffer then peek again.
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_output.Skip(3));
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(buffer_ + 3, ptr);
7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(5, size);
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Skip to end of buffer and peek -- should get next buffer.
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_output.Skip(5));
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(buffer_ + 8, ptr);
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8, size);
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Skip over multiple buffers.
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_output.Skip(22));
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(buffer_ + 30, ptr);
8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(2, size);
8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// -------------------------------------------------------------------
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Limits
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_1D(CodedStreamTest, BasicLimit, kBlockSizes) {
8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream::Limit limit = coded_input.PushLimit(8);
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Read until we hit the limit.
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 value;
8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(8, coded_input.BytesUntilLimit());
8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(4, coded_input.BytesUntilLimit());
8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, coded_input.BytesUntilLimit());
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, coded_input.BytesUntilLimit());
8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    coded_input.PopLimit(limit);
8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(12, input.ByteCount());
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test what happens when we push two limits where the second (top) one is
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// shorter.
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_1D(CodedStreamTest, SmallLimitOnTopOfBigLimit, kBlockSizes) {
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream::Limit limit1 = coded_input.PushLimit(8);
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(8, coded_input.BytesUntilLimit());
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream::Limit limit2 = coded_input.PushLimit(4);
8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 value;
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Read until we hit limit2, the top and shortest limit.
8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(4, coded_input.BytesUntilLimit());
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, coded_input.BytesUntilLimit());
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, coded_input.BytesUntilLimit());
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    coded_input.PopLimit(limit2);
8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Read until we hit limit1.
8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(4, coded_input.BytesUntilLimit());
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, coded_input.BytesUntilLimit());
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, coded_input.BytesUntilLimit());
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    coded_input.PopLimit(limit1);
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No more limits.
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(12, input.ByteCount());
8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test what happens when we push two limits where the second (top) one is
8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// longer.  In this case, the top limit is shortened to match the previous
8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// limit.
8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_1D(CodedStreamTest, BigLimitOnTopOfSmallLimit, kBlockSizes) {
8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream::Limit limit1 = coded_input.PushLimit(4);
8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(4, coded_input.BytesUntilLimit());
8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream::Limit limit2 = coded_input.PushLimit(8);
8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    uint32 value;
8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Read until we hit limit2.  Except, wait!  limit1 is shorter, so
8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // we end up hitting that first, despite having 4 bytes to go on
8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // limit2.
9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(4, coded_input.BytesUntilLimit());
9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, coded_input.BytesUntilLimit());
9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, coded_input.BytesUntilLimit());
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    coded_input.PopLimit(limit2);
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // OK, popped limit2, now limit1 is on top, which we've already hit.
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, coded_input.BytesUntilLimit());
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, coded_input.BytesUntilLimit());
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    coded_input.PopLimit(limit1);
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // No more limits.
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(-1, coded_input.BytesUntilLimit());
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(8, input.ByteCount());
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CodedStreamTest, ExpectAtEnd) {
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Test ExpectAtEnd(), which is based on limits.
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_));
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream coded_input(&input);
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(coded_input.ExpectAtEnd());
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream::Limit limit = coded_input.PushLimit(4);
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  uint32 value;
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.ExpectAtEnd());
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.PopLimit(limit);
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(coded_input.ExpectAtEnd());
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CodedStreamTest, NegativeLimit) {
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check what happens when we push a negative limit.
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_));
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream coded_input(&input);
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream::Limit limit = coded_input.PushLimit(-1234);
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BytesUntilLimit() returns -1 to mean "no limit", which actually means
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "the limit is INT_MAX relative to the beginning of the stream".
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, coded_input.BytesUntilLimit());
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.PopLimit(limit);
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CodedStreamTest, NegativeLimitAfterReading) {
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check what happens when we push a negative limit.
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_));
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream coded_input(&input);
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(coded_input.Skip(128));
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream::Limit limit = coded_input.PushLimit(-64);
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BytesUntilLimit() returns -1 to mean "no limit", which actually means
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "the limit is INT_MAX relative to the beginning of the stream".
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, coded_input.BytesUntilLimit());
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.PopLimit(limit);
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CodedStreamTest, OverflowLimit) {
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check what happens when we push a limit large enough that its absolute
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // position is more than 2GB into the stream.
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_));
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream coded_input(&input);
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(coded_input.Skip(128));
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream::Limit limit = coded_input.PushLimit(INT_MAX);
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // BytesUntilLimit() returns -1 to mean "no limit", which actually means
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // "the limit is INT_MAX relative to the beginning of the stream".
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(-1, coded_input.BytesUntilLimit());
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.PopLimit(limit);
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CodedStreamTest, TotalBytesLimit) {
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_));
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream coded_input(&input);
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.SetTotalBytesLimit(16, -1);
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string str;
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.ReadString(&str, 16));
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<string> errors;
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedMemoryLog error_log;
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_FALSE(coded_input.ReadString(&str, 1));
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors = error_log.GetMessages(ERROR);
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_EQ(1, errors.size());
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_PRED_FORMAT2(testing::IsSubstring,
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "A protocol message was rejected because it was too big", errors[0]);
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.SetTotalBytesLimit(32, -1);
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.ReadString(&str, 16));
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CodedStreamTest, TotalBytesLimitNotValidMessageEnd) {
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // total_bytes_limit_ is not a valid place for a message to end.
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_));
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream coded_input(&input);
10085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set both total_bytes_limit and a regular limit at 16 bytes.
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.SetTotalBytesLimit(16, -1);
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream::Limit limit = coded_input.PushLimit(16);
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read 16 bytes.
10145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  string str;
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.ReadString(&str, 16));
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read a tag.  Should fail, but report being a valid endpoint since it's
10185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a regular limit.
10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, coded_input.ReadTag());
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.ConsumedEntireMessage());
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Pop the limit.
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.PopLimit(limit);
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Read a tag.  Should fail, and report *not* being a valid endpoint, since
10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // this time we're hitting the total bytes limit.
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, coded_input.ReadTag());
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(coded_input.ConsumedEntireMessage());
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1031ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// This method is used by the tests below.
1032ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// It constructs a CodedInputStream with the given limits and tries to read 2KiB
1033ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// of data from it. Then it returns the logged errors and warnings in the given
1034ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch// vectors.
1035ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdochvoid CodedStreamTest::SetupTotalBytesLimitWarningTest(
1036ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    int total_bytes_limit, int warning_threshold,
1037ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    vector<string>* out_errors, vector<string>* out_warnings) {
1038ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ArrayInputStream raw_input(buffer_, sizeof(buffer_), 128);
1039ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1040ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ScopedMemoryLog scoped_log;
1041ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  {
1042ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    CodedInputStream input(&raw_input);
1043ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    input.SetTotalBytesLimit(total_bytes_limit, warning_threshold);
1044ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    string str;
1045ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    EXPECT_TRUE(input.ReadString(&str, 2048));
1046ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  }
1047ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1048ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  *out_errors = scoped_log.GetMessages(ERROR);
1049ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  *out_warnings = scoped_log.GetMessages(WARNING);
1050ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
1051ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1052ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(CodedStreamTest, TotalBytesLimitWarning) {
1053ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  vector<string> errors;
1054ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  vector<string> warnings;
1055ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SetupTotalBytesLimitWarningTest(10240, 1024, &errors, &warnings);
1056ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1057ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(0, errors.size());
1058ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1059ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  ASSERT_EQ(2, warnings.size());
1060ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_PRED_FORMAT2(testing::IsSubstring,
1061ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "Reading dangerously large protocol message.  If the message turns out to "
1062ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "be larger than 10240 bytes, parsing will be halted for security reasons.",
1063ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    warnings[0]);
1064ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_PRED_FORMAT2(testing::IsSubstring,
1065ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    "The total number of bytes read was 2048",
1066ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch    warnings[1]);
1067ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
1068ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1069ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben MurdochTEST_F(CodedStreamTest, TotalBytesLimitWarningDisabled) {
1070ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  vector<string> errors;
1071ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  vector<string> warnings;
1072ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1073ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Test with -1
1074ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SetupTotalBytesLimitWarningTest(10240, -1, &errors, &warnings);
1075ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(0, errors.size());
1076ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(0, warnings.size());
1077ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
1078ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  // Test again with -2, expecting the same result
1079ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  SetupTotalBytesLimitWarningTest(10240, -2, &errors, &warnings);
1080ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(0, errors.size());
1081ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch  EXPECT_EQ(0, warnings.size());
1082ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch}
1083ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CodedStreamTest, RecursionLimit) {
10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ArrayInputStream input(buffer_, sizeof(buffer_));
10875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CodedInputStream coded_input(&input);
10885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.SetRecursionLimit(4);
10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // This is way too much testing for a counter.
10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 1
10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 2
10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 3
10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 4
10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 5
10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 6
10975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.DecrementRecursionDepth();                   // 5
10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 6
10995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.DecrementRecursionDepth();                   // 5
11005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.DecrementRecursionDepth();                   // 4
11015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.DecrementRecursionDepth();                   // 3
11025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 4
11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 5
11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.DecrementRecursionDepth();                   // 4
11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.DecrementRecursionDepth();                   // 3
11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.DecrementRecursionDepth();                   // 2
11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.DecrementRecursionDepth();                   // 1
11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.DecrementRecursionDepth();                   // 0
11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.DecrementRecursionDepth();                   // 0
11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.DecrementRecursionDepth();                   // 0
11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 1
11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 2
11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 3
11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 4
11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 5
11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  coded_input.SetRecursionLimit(6);
11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 6
11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 7
11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1122ba5b9a6411cb1792fd21f0a078d7a25cd1ceec16Ben Murdoch
11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class ReallyBigInputStream : public ZeroCopyInputStream {
11245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
11255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReallyBigInputStream() : backup_amount_(0), buffer_count_(0) {}
11265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ~ReallyBigInputStream() {}
11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // implements ZeroCopyInputStream ----------------------------------
11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Next(const void** data, int* size) {
11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We only expect BackUp() to be called at the end.
11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, backup_amount_);
11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    switch (buffer_count_++) {
11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 0:
11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *data = buffer_;
11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *size = sizeof(buffer_);
11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      case 1:
11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // Return an enormously large buffer that, when combined with the 1k
11405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // returned already, should overflow the total_bytes_read_ counter in
11415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // CodedInputStream.  Note that we'll only read the first 1024 bytes
11425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        // of this buffer so it's OK that we have it point at buffer_.
11435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *data = buffer_;
11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        *size = INT_MAX;
11455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return true;
11465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      default:
11475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return false;
11485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
11495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void BackUp(int count) {
11525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    backup_amount_ = count;
11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool Skip(int count)    { GOOGLE_LOG(FATAL) << "Not implemented."; return false; }
11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 ByteCount() const { GOOGLE_LOG(FATAL) << "Not implemented."; return 0; }
11575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int backup_amount_;
11595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  char buffer_[1024];
11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 buffer_count_;
11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
11645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CodedStreamTest, InputOver2G) {
11665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CodedInputStream should gracefully handle input over 2G and call
11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // input.BackUp() with the correct number of bytes on destruction.
11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ReallyBigInputStream input;
11695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  vector<string> errors;
11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  {
11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ScopedMemoryLog error_log;
11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    CodedInputStream coded_input(&input);
11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    string str;
11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadString(&str, 512));
11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(coded_input.ReadString(&str, 1024));
11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    errors = error_log.GetMessages(ERROR);
11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(INT_MAX - 512, input.backup_amount_);
11825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(0, errors.size());
11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ===================================================================
11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
11885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
11895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace io
11905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace protobuf
11915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google
1192