Home | History | Annotate | Download | only in io
      1 // Protocol Buffers - Google's data interchange format
      2 // Copyright 2008 Google Inc.  All rights reserved.
      3 // http://code.google.com/p/protobuf/
      4 //
      5 // Redistribution and use in source and binary forms, with or without
      6 // modification, are permitted provided that the following conditions are
      7 // met:
      8 //
      9 //     * Redistributions of source code must retain the above copyright
     10 // notice, this list of conditions and the following disclaimer.
     11 //     * Redistributions in binary form must reproduce the above
     12 // copyright notice, this list of conditions and the following disclaimer
     13 // in the documentation and/or other materials provided with the
     14 // distribution.
     15 //     * Neither the name of Google Inc. nor the names of its
     16 // contributors may be used to endorse or promote products derived from
     17 // this software without specific prior written permission.
     18 //
     19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     20 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     21 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     22 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     23 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     24 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     25 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     26 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     28 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     29 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     30 
     31 // Author: kenton (at) google.com (Kenton Varda)
     32 //  Based on original Protocol Buffers design by
     33 //  Sanjay Ghemawat, Jeff Dean, and others.
     34 //
     35 // This file contains tests and benchmarks.
     36 
     37 #include <vector>
     38 
     39 #include <google/protobuf/io/coded_stream.h>
     40 
     41 #include <limits.h>
     42 
     43 #include <google/protobuf/stubs/common.h>
     44 #include <google/protobuf/testing/googletest.h>
     45 #include <gtest/gtest.h>
     46 #include <google/protobuf/io/zero_copy_stream_impl.h>
     47 #include <google/protobuf/stubs/strutil.h>
     48 
     49 
     50 // This declares an unsigned long long integer literal in a portable way.
     51 // (The original macro is way too big and ruins my formatting.)
     52 #undef ULL
     53 #define ULL(x) GOOGLE_ULONGLONG(x)
     54 
     55 namespace google {
     56 namespace protobuf {
     57 namespace io {
     58 namespace {
     59 
     60 // ===================================================================
     61 // Data-Driven Test Infrastructure
     62 
     63 // TEST_1D and TEST_2D are macros I'd eventually like to see added to
     64 // gTest.  These macros can be used to declare tests which should be
     65 // run multiple times, once for each item in some input array.  TEST_1D
     66 // tests all cases in a single input array.  TEST_2D tests all
     67 // combinations of cases from two arrays.  The arrays must be statically
     68 // defined such that the GOOGLE_ARRAYSIZE() macro works on them.  Example:
     69 //
     70 // int kCases[] = {1, 2, 3, 4}
     71 // TEST_1D(MyFixture, MyTest, kCases) {
     72 //   EXPECT_GT(kCases_case, 0);
     73 // }
     74 //
     75 // This test iterates through the numbers 1, 2, 3, and 4 and tests that
     76 // they are all grater than zero.  In case of failure, the exact case
     77 // which failed will be printed.  The case type must be printable using
     78 // ostream::operator<<.
     79 
     80 // TODO(kenton):  gTest now supports "parameterized tests" which would be
     81 //   a better way to accomplish this.  Rewrite when time permits.
     82 
     83 #define TEST_1D(FIXTURE, NAME, CASES)                                      \
     84   class FIXTURE##_##NAME##_DD : public FIXTURE {                           \
     85    protected:                                                              \
     86     template <typename CaseType>                                           \
     87     void DoSingleCase(const CaseType& CASES##_case);                       \
     88   };                                                                       \
     89                                                                            \
     90   TEST_F(FIXTURE##_##NAME##_DD, NAME) {                                    \
     91     for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES); i++) {                           \
     92       SCOPED_TRACE(testing::Message()                                      \
     93         << #CASES " case #" << i << ": " << CASES[i]);                     \
     94       DoSingleCase(CASES[i]);                                              \
     95     }                                                                      \
     96   }                                                                        \
     97                                                                            \
     98   template <typename CaseType>                                             \
     99   void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType& CASES##_case)
    100 
    101 #define TEST_2D(FIXTURE, NAME, CASES1, CASES2)                             \
    102   class FIXTURE##_##NAME##_DD : public FIXTURE {                           \
    103    protected:                                                              \
    104     template <typename CaseType1, typename CaseType2>                      \
    105     void DoSingleCase(const CaseType1& CASES1##_case,                      \
    106                       const CaseType2& CASES2##_case);                     \
    107   };                                                                       \
    108                                                                            \
    109   TEST_F(FIXTURE##_##NAME##_DD, NAME) {                                    \
    110     for (int i = 0; i < GOOGLE_ARRAYSIZE(CASES1); i++) {                          \
    111       for (int j = 0; j < GOOGLE_ARRAYSIZE(CASES2); j++) {                        \
    112         SCOPED_TRACE(testing::Message()                                    \
    113           << #CASES1 " case #" << i << ": " << CASES1[i] << ", "           \
    114           << #CASES2 " case #" << j << ": " << CASES2[j]);                 \
    115         DoSingleCase(CASES1[i], CASES2[j]);                                \
    116       }                                                                    \
    117     }                                                                      \
    118   }                                                                        \
    119                                                                            \
    120   template <typename CaseType1, typename CaseType2>                        \
    121   void FIXTURE##_##NAME##_DD::DoSingleCase(const CaseType1& CASES1##_case, \
    122                                            const CaseType2& CASES2##_case)
    123 
    124 // ===================================================================
    125 
    126 class CodedStreamTest : public testing::Test {
    127  protected:
    128   static const int kBufferSize = 1024 * 64;
    129   static uint8 buffer_[kBufferSize];
    130 };
    131 
    132 uint8 CodedStreamTest::buffer_[CodedStreamTest::kBufferSize];
    133 
    134 // We test each operation over a variety of block sizes to insure that
    135 // we test cases where reads or writes cross buffer boundaries, cases
    136 // where they don't, and cases where there is so much buffer left that
    137 // we can use special optimized paths that don't worry about bounds
    138 // checks.
    139 const int kBlockSizes[] = {1, 2, 3, 5, 7, 13, 32, 1024};
    140 
    141 // -------------------------------------------------------------------
    142 // Varint tests.
    143 
    144 struct VarintCase {
    145   uint8 bytes[10];          // Encoded bytes.
    146   int size;                 // Encoded size, in bytes.
    147   uint64 value;             // Parsed value.
    148 };
    149 
    150 inline std::ostream& operator<<(std::ostream& os, const VarintCase& c) {
    151   return os << c.value;
    152 }
    153 
    154 VarintCase kVarintCases[] = {
    155   // 32-bit values
    156   {{0x00}      , 1, 0},
    157   {{0x01}      , 1, 1},
    158   {{0x7f}      , 1, 127},
    159   {{0xa2, 0x74}, 2, (0x22 << 0) | (0x74 << 7)},          // 14882
    160   {{0xbe, 0xf7, 0x92, 0x84, 0x0b}, 5,                    // 2961488830
    161     (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
    162     (ULL(0x0b) << 28)},
    163 
    164   // 64-bit
    165   {{0xbe, 0xf7, 0x92, 0x84, 0x1b}, 5,                    // 7256456126
    166     (0x3e << 0) | (0x77 << 7) | (0x12 << 14) | (0x04 << 21) |
    167     (ULL(0x1b) << 28)},
    168   {{0x80, 0xe6, 0xeb, 0x9c, 0xc3, 0xc9, 0xa4, 0x49}, 8,  // 41256202580718336
    169     (0x00 << 0) | (0x66 << 7) | (0x6b << 14) | (0x1c << 21) |
    170     (ULL(0x43) << 28) | (ULL(0x49) << 35) | (ULL(0x24) << 42) |
    171     (ULL(0x49) << 49)},
    172   // 11964378330978735131
    173   {{0x9b, 0xa8, 0xf9, 0xc2, 0xbb, 0xd6, 0x80, 0x85, 0xa6, 0x01}, 10,
    174     (0x1b << 0) | (0x28 << 7) | (0x79 << 14) | (0x42 << 21) |
    175     (ULL(0x3b) << 28) | (ULL(0x56) << 35) | (ULL(0x00) << 42) |
    176     (ULL(0x05) << 49) | (ULL(0x26) << 56) | (ULL(0x01) << 63)},
    177 };
    178 
    179 TEST_2D(CodedStreamTest, ReadVarint32, kVarintCases, kBlockSizes) {
    180   memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
    181   ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
    182 
    183   {
    184     CodedInputStream coded_input(&input);
    185 
    186     uint32 value;
    187     EXPECT_TRUE(coded_input.ReadVarint32(&value));
    188     EXPECT_EQ(static_cast<uint32>(kVarintCases_case.value), value);
    189   }
    190 
    191   EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
    192 }
    193 
    194 TEST_2D(CodedStreamTest, ReadTag, kVarintCases, kBlockSizes) {
    195   memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
    196   ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
    197 
    198   {
    199     CodedInputStream coded_input(&input);
    200 
    201     uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
    202     EXPECT_EQ(expected_value, coded_input.ReadTag());
    203 
    204     EXPECT_TRUE(coded_input.LastTagWas(expected_value));
    205     EXPECT_FALSE(coded_input.LastTagWas(expected_value + 1));
    206   }
    207 
    208   EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
    209 }
    210 
    211 TEST_1D(CodedStreamTest, ExpectTag, kVarintCases) {
    212   // Leave one byte at the beginning of the buffer so we can read it
    213   // to force the first buffer to be loaded.
    214   buffer_[0] = '\0';
    215   memcpy(buffer_ + 1, kVarintCases_case.bytes, kVarintCases_case.size);
    216   ArrayInputStream input(buffer_, sizeof(buffer_));
    217 
    218   {
    219     CodedInputStream coded_input(&input);
    220 
    221     // Read one byte to force coded_input.Refill() to be called.  Otherwise,
    222     // ExpectTag() will return a false negative.
    223     uint8 dummy;
    224     coded_input.ReadRaw(&dummy, 1);
    225     EXPECT_EQ((uint)'\0', (uint)dummy);
    226 
    227     uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
    228 
    229     // ExpectTag() produces false negatives for large values.
    230     if (kVarintCases_case.size <= 2) {
    231       EXPECT_FALSE(coded_input.ExpectTag(expected_value + 1));
    232       EXPECT_TRUE(coded_input.ExpectTag(expected_value));
    233     } else {
    234       EXPECT_FALSE(coded_input.ExpectTag(expected_value));
    235     }
    236   }
    237 
    238   if (kVarintCases_case.size <= 2) {
    239     EXPECT_EQ(kVarintCases_case.size + 1, input.ByteCount());
    240   } else {
    241     EXPECT_EQ(1, input.ByteCount());
    242   }
    243 }
    244 
    245 TEST_1D(CodedStreamTest, ExpectTagFromArray, kVarintCases) {
    246   memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
    247 
    248   const uint32 expected_value = static_cast<uint32>(kVarintCases_case.value);
    249 
    250   // If the expectation succeeds, it should return a pointer past the tag.
    251   if (kVarintCases_case.size <= 2) {
    252     EXPECT_TRUE(NULL ==
    253                 CodedInputStream::ExpectTagFromArray(buffer_,
    254                                                      expected_value + 1));
    255     EXPECT_TRUE(buffer_ + kVarintCases_case.size ==
    256                 CodedInputStream::ExpectTagFromArray(buffer_, expected_value));
    257   } else {
    258     EXPECT_TRUE(NULL ==
    259                 CodedInputStream::ExpectTagFromArray(buffer_, expected_value));
    260   }
    261 }
    262 
    263 TEST_2D(CodedStreamTest, ReadVarint64, kVarintCases, kBlockSizes) {
    264   memcpy(buffer_, kVarintCases_case.bytes, kVarintCases_case.size);
    265   ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
    266 
    267   {
    268     CodedInputStream coded_input(&input);
    269 
    270     uint64 value;
    271     EXPECT_TRUE(coded_input.ReadVarint64(&value));
    272     EXPECT_EQ(kVarintCases_case.value, value);
    273   }
    274 
    275   EXPECT_EQ(kVarintCases_case.size, input.ByteCount());
    276 }
    277 
    278 TEST_2D(CodedStreamTest, WriteVarint32, kVarintCases, kBlockSizes) {
    279   if (kVarintCases_case.value > ULL(0x00000000FFFFFFFF)) {
    280     // Skip this test for the 64-bit values.
    281     return;
    282   }
    283 
    284   ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
    285 
    286   {
    287     CodedOutputStream coded_output(&output);
    288 
    289     coded_output.WriteVarint32(static_cast<uint32>(kVarintCases_case.value));
    290     EXPECT_FALSE(coded_output.HadError());
    291 
    292     EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount());
    293   }
    294 
    295   EXPECT_EQ(kVarintCases_case.size, output.ByteCount());
    296   EXPECT_EQ(0,
    297     memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size));
    298 }
    299 
    300 TEST_2D(CodedStreamTest, WriteVarint64, kVarintCases, kBlockSizes) {
    301   ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
    302 
    303   {
    304     CodedOutputStream coded_output(&output);
    305 
    306     coded_output.WriteVarint64(kVarintCases_case.value);
    307     EXPECT_FALSE(coded_output.HadError());
    308 
    309     EXPECT_EQ(kVarintCases_case.size, coded_output.ByteCount());
    310   }
    311 
    312   EXPECT_EQ(kVarintCases_case.size, output.ByteCount());
    313   EXPECT_EQ(0,
    314     memcmp(buffer_, kVarintCases_case.bytes, kVarintCases_case.size));
    315 }
    316 
    317 // This test causes gcc 3.3.5 (and earlier?) to give the cryptic error:
    318 //   "sorry, unimplemented: `method_call_expr' not supported by dump_expr"
    319 #if !defined(__GNUC__) || __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)
    320 
    321 int32 kSignExtendedVarintCases[] = {
    322   0, 1, -1, 1237894, -37895138
    323 };
    324 
    325 TEST_2D(CodedStreamTest, WriteVarint32SignExtended,
    326         kSignExtendedVarintCases, kBlockSizes) {
    327   ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
    328 
    329   {
    330     CodedOutputStream coded_output(&output);
    331 
    332     coded_output.WriteVarint32SignExtended(kSignExtendedVarintCases_case);
    333     EXPECT_FALSE(coded_output.HadError());
    334 
    335     if (kSignExtendedVarintCases_case < 0) {
    336       EXPECT_EQ(10, coded_output.ByteCount());
    337     } else {
    338       EXPECT_LE(coded_output.ByteCount(), 5);
    339     }
    340   }
    341 
    342   if (kSignExtendedVarintCases_case < 0) {
    343     EXPECT_EQ(10, output.ByteCount());
    344   } else {
    345     EXPECT_LE(output.ByteCount(), 5);
    346   }
    347 
    348   // Read value back in as a varint64 and insure it matches.
    349   ArrayInputStream input(buffer_, sizeof(buffer_));
    350 
    351   {
    352     CodedInputStream coded_input(&input);
    353 
    354     uint64 value;
    355     EXPECT_TRUE(coded_input.ReadVarint64(&value));
    356 
    357     EXPECT_EQ(kSignExtendedVarintCases_case, static_cast<int64>(value));
    358   }
    359 
    360   EXPECT_EQ(output.ByteCount(), input.ByteCount());
    361 }
    362 
    363 #endif
    364 
    365 
    366 // -------------------------------------------------------------------
    367 // Varint failure test.
    368 
    369 struct VarintErrorCase {
    370   uint8 bytes[12];
    371   int size;
    372   bool can_parse;
    373 };
    374 
    375 inline std::ostream& operator<<(std::ostream& os, const VarintErrorCase& c) {
    376   return os << "size " << c.size;
    377 }
    378 
    379 const VarintErrorCase kVarintErrorCases[] = {
    380   // Control case.  (Insures that there isn't something else wrong that
    381   // makes parsing always fail.)
    382   {{0x00}, 1, true},
    383 
    384   // No input data.
    385   {{}, 0, false},
    386 
    387   // Input ends unexpectedly.
    388   {{0xf0, 0xab}, 2, false},
    389 
    390   // Input ends unexpectedly after 32 bits.
    391   {{0xf0, 0xab, 0xc9, 0x9a, 0xf8, 0xb2}, 6, false},
    392 
    393   // Longer than 10 bytes.
    394   {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01},
    395    11, false},
    396 };
    397 
    398 TEST_2D(CodedStreamTest, ReadVarint32Error, kVarintErrorCases, kBlockSizes) {
    399   memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
    400   ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
    401                          kBlockSizes_case);
    402   CodedInputStream coded_input(&input);
    403 
    404   uint32 value;
    405   EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint32(&value));
    406 }
    407 
    408 TEST_2D(CodedStreamTest, ReadVarint64Error, kVarintErrorCases, kBlockSizes) {
    409   memcpy(buffer_, kVarintErrorCases_case.bytes, kVarintErrorCases_case.size);
    410   ArrayInputStream input(buffer_, kVarintErrorCases_case.size,
    411                          kBlockSizes_case);
    412   CodedInputStream coded_input(&input);
    413 
    414   uint64 value;
    415   EXPECT_EQ(kVarintErrorCases_case.can_parse, coded_input.ReadVarint64(&value));
    416 }
    417 
    418 // -------------------------------------------------------------------
    419 // VarintSize
    420 
    421 struct VarintSizeCase {
    422   uint64 value;
    423   int size;
    424 };
    425 
    426 inline std::ostream& operator<<(std::ostream& os, const VarintSizeCase& c) {
    427   return os << c.value;
    428 }
    429 
    430 VarintSizeCase kVarintSizeCases[] = {
    431   {0u, 1},
    432   {1u, 1},
    433   {127u, 1},
    434   {128u, 2},
    435   {758923u, 3},
    436   {4000000000u, 5},
    437   {ULL(41256202580718336), 8},
    438   {ULL(11964378330978735131), 10},
    439 };
    440 
    441 TEST_1D(CodedStreamTest, VarintSize32, kVarintSizeCases) {
    442   if (kVarintSizeCases_case.value > 0xffffffffu) {
    443     // Skip 64-bit values.
    444     return;
    445   }
    446 
    447   EXPECT_EQ(kVarintSizeCases_case.size,
    448     CodedOutputStream::VarintSize32(
    449       static_cast<uint32>(kVarintSizeCases_case.value)));
    450 }
    451 
    452 TEST_1D(CodedStreamTest, VarintSize64, kVarintSizeCases) {
    453   EXPECT_EQ(kVarintSizeCases_case.size,
    454     CodedOutputStream::VarintSize64(kVarintSizeCases_case.value));
    455 }
    456 
    457 // -------------------------------------------------------------------
    458 // Fixed-size int tests
    459 
    460 struct Fixed32Case {
    461   uint8 bytes[sizeof(uint32)];          // Encoded bytes.
    462   uint32 value;                         // Parsed value.
    463 };
    464 
    465 struct Fixed64Case {
    466   uint8 bytes[sizeof(uint64)];          // Encoded bytes.
    467   uint64 value;                         // Parsed value.
    468 };
    469 
    470 inline std::ostream& operator<<(std::ostream& os, const Fixed32Case& c) {
    471   return os << "0x" << hex << c.value << dec;
    472 }
    473 
    474 inline std::ostream& operator<<(std::ostream& os, const Fixed64Case& c) {
    475   return os << "0x" << hex << c.value << dec;
    476 }
    477 
    478 Fixed32Case kFixed32Cases[] = {
    479   {{0xef, 0xcd, 0xab, 0x90}, 0x90abcdefu},
    480   {{0x12, 0x34, 0x56, 0x78}, 0x78563412u},
    481 };
    482 
    483 Fixed64Case kFixed64Cases[] = {
    484   {{0xef, 0xcd, 0xab, 0x90, 0x12, 0x34, 0x56, 0x78}, ULL(0x7856341290abcdef)},
    485   {{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88}, ULL(0x8877665544332211)},
    486 };
    487 
    488 TEST_2D(CodedStreamTest, ReadLittleEndian32, kFixed32Cases, kBlockSizes) {
    489   memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes));
    490   ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
    491 
    492   {
    493     CodedInputStream coded_input(&input);
    494 
    495     uint32 value;
    496     EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
    497     EXPECT_EQ(kFixed32Cases_case.value, value);
    498   }
    499 
    500   EXPECT_EQ(sizeof(uint32), input.ByteCount());
    501 }
    502 
    503 TEST_2D(CodedStreamTest, ReadLittleEndian64, kFixed64Cases, kBlockSizes) {
    504   memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes));
    505   ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
    506 
    507   {
    508     CodedInputStream coded_input(&input);
    509 
    510     uint64 value;
    511     EXPECT_TRUE(coded_input.ReadLittleEndian64(&value));
    512     EXPECT_EQ(kFixed64Cases_case.value, value);
    513   }
    514 
    515   EXPECT_EQ(sizeof(uint64), input.ByteCount());
    516 }
    517 
    518 TEST_2D(CodedStreamTest, WriteLittleEndian32, kFixed32Cases, kBlockSizes) {
    519   ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
    520 
    521   {
    522     CodedOutputStream coded_output(&output);
    523 
    524     coded_output.WriteLittleEndian32(kFixed32Cases_case.value);
    525     EXPECT_FALSE(coded_output.HadError());
    526 
    527     EXPECT_EQ(sizeof(uint32), coded_output.ByteCount());
    528   }
    529 
    530   EXPECT_EQ(sizeof(uint32), output.ByteCount());
    531   EXPECT_EQ(0, memcmp(buffer_, kFixed32Cases_case.bytes, sizeof(uint32)));
    532 }
    533 
    534 TEST_2D(CodedStreamTest, WriteLittleEndian64, kFixed64Cases, kBlockSizes) {
    535   ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
    536 
    537   {
    538     CodedOutputStream coded_output(&output);
    539 
    540     coded_output.WriteLittleEndian64(kFixed64Cases_case.value);
    541     EXPECT_FALSE(coded_output.HadError());
    542 
    543     EXPECT_EQ(sizeof(uint64), coded_output.ByteCount());
    544   }
    545 
    546   EXPECT_EQ(sizeof(uint64), output.ByteCount());
    547   EXPECT_EQ(0, memcmp(buffer_, kFixed64Cases_case.bytes, sizeof(uint64)));
    548 }
    549 
    550 // Tests using the static methods to read fixed-size values from raw arrays.
    551 
    552 TEST_1D(CodedStreamTest, ReadLittleEndian32FromArray, kFixed32Cases) {
    553   memcpy(buffer_, kFixed32Cases_case.bytes, sizeof(kFixed32Cases_case.bytes));
    554 
    555   uint32 value;
    556   const uint8* end = CodedInputStream::ReadLittleEndian32FromArray(
    557       buffer_, &value);
    558   EXPECT_EQ(kFixed32Cases_case.value, value);
    559   EXPECT_TRUE(end == buffer_ + sizeof(value));
    560 }
    561 
    562 TEST_1D(CodedStreamTest, ReadLittleEndian64FromArray, kFixed64Cases) {
    563   memcpy(buffer_, kFixed64Cases_case.bytes, sizeof(kFixed64Cases_case.bytes));
    564 
    565   uint64 value;
    566   const uint8* end = CodedInputStream::ReadLittleEndian64FromArray(
    567       buffer_, &value);
    568   EXPECT_EQ(kFixed64Cases_case.value, value);
    569   EXPECT_TRUE(end == buffer_ + sizeof(value));
    570 }
    571 
    572 // -------------------------------------------------------------------
    573 // Raw reads and writes
    574 
    575 const char kRawBytes[] = "Some bytes which will be written and read raw.";
    576 
    577 TEST_1D(CodedStreamTest, ReadRaw, kBlockSizes) {
    578   memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
    579   ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
    580   char read_buffer[sizeof(kRawBytes)];
    581 
    582   {
    583     CodedInputStream coded_input(&input);
    584 
    585     EXPECT_TRUE(coded_input.ReadRaw(read_buffer, sizeof(kRawBytes)));
    586     EXPECT_EQ(0, memcmp(kRawBytes, read_buffer, sizeof(kRawBytes)));
    587   }
    588 
    589   EXPECT_EQ(sizeof(kRawBytes), input.ByteCount());
    590 }
    591 
    592 TEST_1D(CodedStreamTest, WriteRaw, kBlockSizes) {
    593   ArrayOutputStream output(buffer_, sizeof(buffer_), kBlockSizes_case);
    594 
    595   {
    596     CodedOutputStream coded_output(&output);
    597 
    598     coded_output.WriteRaw(kRawBytes, sizeof(kRawBytes));
    599     EXPECT_FALSE(coded_output.HadError());
    600 
    601     EXPECT_EQ(sizeof(kRawBytes), coded_output.ByteCount());
    602   }
    603 
    604   EXPECT_EQ(sizeof(kRawBytes), output.ByteCount());
    605   EXPECT_EQ(0, memcmp(buffer_, kRawBytes, sizeof(kRawBytes)));
    606 }
    607 
    608 TEST_1D(CodedStreamTest, ReadString, kBlockSizes) {
    609   memcpy(buffer_, kRawBytes, sizeof(kRawBytes));
    610   ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
    611 
    612   {
    613     CodedInputStream coded_input(&input);
    614 
    615     string str;
    616     EXPECT_TRUE(coded_input.ReadString(&str, strlen(kRawBytes)));
    617     EXPECT_EQ(kRawBytes, str);
    618   }
    619 
    620   EXPECT_EQ(strlen(kRawBytes), input.ByteCount());
    621 }
    622 
    623 // Check to make sure ReadString doesn't crash on impossibly large strings.
    624 TEST_1D(CodedStreamTest, ReadStringImpossiblyLarge, kBlockSizes) {
    625   ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
    626 
    627   {
    628     CodedInputStream coded_input(&input);
    629 
    630     string str;
    631     // Try to read a gigabyte.
    632     EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
    633   }
    634 }
    635 
    636 TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnStack) {
    637   // Same test as above, except directly use a buffer. This used to cause
    638   // crashes while the above did not.
    639   uint8 buffer[8];
    640   CodedInputStream coded_input(buffer, 8);
    641   string str;
    642   EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
    643 }
    644 
    645 TEST_F(CodedStreamTest, ReadStringImpossiblyLargeFromStringOnHeap) {
    646   scoped_array<uint8> buffer(new uint8[8]);
    647   CodedInputStream coded_input(buffer.get(), 8);
    648   string str;
    649   EXPECT_FALSE(coded_input.ReadString(&str, 1 << 30));
    650 }
    651 
    652 
    653 // -------------------------------------------------------------------
    654 // Skip
    655 
    656 const char kSkipTestBytes[] =
    657   "<Before skipping><To be skipped><After skipping>";
    658 const char kSkipOutputTestBytes[] =
    659   "-----------------<To be skipped>----------------";
    660 
    661 TEST_1D(CodedStreamTest, SkipInput, kBlockSizes) {
    662   memcpy(buffer_, kSkipTestBytes, sizeof(kSkipTestBytes));
    663   ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
    664 
    665   {
    666     CodedInputStream coded_input(&input);
    667 
    668     string str;
    669     EXPECT_TRUE(coded_input.ReadString(&str, strlen("<Before skipping>")));
    670     EXPECT_EQ("<Before skipping>", str);
    671     EXPECT_TRUE(coded_input.Skip(strlen("<To be skipped>")));
    672     EXPECT_TRUE(coded_input.ReadString(&str, strlen("<After skipping>")));
    673     EXPECT_EQ("<After skipping>", str);
    674   }
    675 
    676   EXPECT_EQ(strlen(kSkipTestBytes), input.ByteCount());
    677 }
    678 
    679 // -------------------------------------------------------------------
    680 // GetDirectBufferPointer
    681 
    682 TEST_F(CodedStreamTest, GetDirectBufferPointerInput) {
    683   ArrayInputStream input(buffer_, sizeof(buffer_), 8);
    684   CodedInputStream coded_input(&input);
    685 
    686   const void* ptr;
    687   int size;
    688 
    689   EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
    690   EXPECT_EQ(buffer_, ptr);
    691   EXPECT_EQ(8, size);
    692 
    693   // Peeking again should return the same pointer.
    694   EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
    695   EXPECT_EQ(buffer_, ptr);
    696   EXPECT_EQ(8, size);
    697 
    698   // Skip forward in the same buffer then peek again.
    699   EXPECT_TRUE(coded_input.Skip(3));
    700   EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
    701   EXPECT_EQ(buffer_ + 3, ptr);
    702   EXPECT_EQ(5, size);
    703 
    704   // Skip to end of buffer and peek -- should get next buffer.
    705   EXPECT_TRUE(coded_input.Skip(5));
    706   EXPECT_TRUE(coded_input.GetDirectBufferPointer(&ptr, &size));
    707   EXPECT_EQ(buffer_ + 8, ptr);
    708   EXPECT_EQ(8, size);
    709 }
    710 
    711 TEST_F(CodedStreamTest, GetDirectBufferPointerInlineInput) {
    712   ArrayInputStream input(buffer_, sizeof(buffer_), 8);
    713   CodedInputStream coded_input(&input);
    714 
    715   const void* ptr;
    716   int size;
    717 
    718   coded_input.GetDirectBufferPointerInline(&ptr, &size);
    719   EXPECT_EQ(buffer_, ptr);
    720   EXPECT_EQ(8, size);
    721 
    722   // Peeking again should return the same pointer.
    723   coded_input.GetDirectBufferPointerInline(&ptr, &size);
    724   EXPECT_EQ(buffer_, ptr);
    725   EXPECT_EQ(8, size);
    726 
    727   // Skip forward in the same buffer then peek again.
    728   EXPECT_TRUE(coded_input.Skip(3));
    729   coded_input.GetDirectBufferPointerInline(&ptr, &size);
    730   EXPECT_EQ(buffer_ + 3, ptr);
    731   EXPECT_EQ(5, size);
    732 
    733   // Skip to end of buffer and peek -- should return false and provide an empty
    734   // buffer. It does not try to Refresh().
    735   EXPECT_TRUE(coded_input.Skip(5));
    736   coded_input.GetDirectBufferPointerInline(&ptr, &size);
    737   EXPECT_EQ(buffer_ + 8, ptr);
    738   EXPECT_EQ(0, size);
    739 }
    740 
    741 TEST_F(CodedStreamTest, GetDirectBufferPointerOutput) {
    742   ArrayOutputStream output(buffer_, sizeof(buffer_), 8);
    743   CodedOutputStream coded_output(&output);
    744 
    745   void* ptr;
    746   int size;
    747 
    748   EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
    749   EXPECT_EQ(buffer_, ptr);
    750   EXPECT_EQ(8, size);
    751 
    752   // Peeking again should return the same pointer.
    753   EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
    754   EXPECT_EQ(buffer_, ptr);
    755   EXPECT_EQ(8, size);
    756 
    757   // Skip forward in the same buffer then peek again.
    758   EXPECT_TRUE(coded_output.Skip(3));
    759   EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
    760   EXPECT_EQ(buffer_ + 3, ptr);
    761   EXPECT_EQ(5, size);
    762 
    763   // Skip to end of buffer and peek -- should get next buffer.
    764   EXPECT_TRUE(coded_output.Skip(5));
    765   EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
    766   EXPECT_EQ(buffer_ + 8, ptr);
    767   EXPECT_EQ(8, size);
    768 
    769   // Skip over multiple buffers.
    770   EXPECT_TRUE(coded_output.Skip(22));
    771   EXPECT_TRUE(coded_output.GetDirectBufferPointer(&ptr, &size));
    772   EXPECT_EQ(buffer_ + 30, ptr);
    773   EXPECT_EQ(2, size);
    774 }
    775 
    776 // -------------------------------------------------------------------
    777 // Limits
    778 
    779 TEST_1D(CodedStreamTest, BasicLimit, kBlockSizes) {
    780   ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
    781 
    782   {
    783     CodedInputStream coded_input(&input);
    784 
    785     EXPECT_EQ(-1, coded_input.BytesUntilLimit());
    786     CodedInputStream::Limit limit = coded_input.PushLimit(8);
    787 
    788     // Read until we hit the limit.
    789     uint32 value;
    790     EXPECT_EQ(8, coded_input.BytesUntilLimit());
    791     EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
    792     EXPECT_EQ(4, coded_input.BytesUntilLimit());
    793     EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
    794     EXPECT_EQ(0, coded_input.BytesUntilLimit());
    795     EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
    796     EXPECT_EQ(0, coded_input.BytesUntilLimit());
    797 
    798     coded_input.PopLimit(limit);
    799 
    800     EXPECT_EQ(-1, coded_input.BytesUntilLimit());
    801     EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
    802   }
    803 
    804   EXPECT_EQ(12, input.ByteCount());
    805 }
    806 
    807 // Test what happens when we push two limits where the second (top) one is
    808 // shorter.
    809 TEST_1D(CodedStreamTest, SmallLimitOnTopOfBigLimit, kBlockSizes) {
    810   ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
    811 
    812   {
    813     CodedInputStream coded_input(&input);
    814 
    815     EXPECT_EQ(-1, coded_input.BytesUntilLimit());
    816     CodedInputStream::Limit limit1 = coded_input.PushLimit(8);
    817     EXPECT_EQ(8, coded_input.BytesUntilLimit());
    818     CodedInputStream::Limit limit2 = coded_input.PushLimit(4);
    819 
    820     uint32 value;
    821 
    822     // Read until we hit limit2, the top and shortest limit.
    823     EXPECT_EQ(4, coded_input.BytesUntilLimit());
    824     EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
    825     EXPECT_EQ(0, coded_input.BytesUntilLimit());
    826     EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
    827     EXPECT_EQ(0, coded_input.BytesUntilLimit());
    828 
    829     coded_input.PopLimit(limit2);
    830 
    831     // Read until we hit limit1.
    832     EXPECT_EQ(4, coded_input.BytesUntilLimit());
    833     EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
    834     EXPECT_EQ(0, coded_input.BytesUntilLimit());
    835     EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
    836     EXPECT_EQ(0, coded_input.BytesUntilLimit());
    837 
    838     coded_input.PopLimit(limit1);
    839 
    840     // No more limits.
    841     EXPECT_EQ(-1, coded_input.BytesUntilLimit());
    842     EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
    843   }
    844 
    845   EXPECT_EQ(12, input.ByteCount());
    846 }
    847 
    848 // Test what happens when we push two limits where the second (top) one is
    849 // longer.  In this case, the top limit is shortened to match the previous
    850 // limit.
    851 TEST_1D(CodedStreamTest, BigLimitOnTopOfSmallLimit, kBlockSizes) {
    852   ArrayInputStream input(buffer_, sizeof(buffer_), kBlockSizes_case);
    853 
    854   {
    855     CodedInputStream coded_input(&input);
    856 
    857     EXPECT_EQ(-1, coded_input.BytesUntilLimit());
    858     CodedInputStream::Limit limit1 = coded_input.PushLimit(4);
    859     EXPECT_EQ(4, coded_input.BytesUntilLimit());
    860     CodedInputStream::Limit limit2 = coded_input.PushLimit(8);
    861 
    862     uint32 value;
    863 
    864     // Read until we hit limit2.  Except, wait!  limit1 is shorter, so
    865     // we end up hitting that first, despite having 4 bytes to go on
    866     // limit2.
    867     EXPECT_EQ(4, coded_input.BytesUntilLimit());
    868     EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
    869     EXPECT_EQ(0, coded_input.BytesUntilLimit());
    870     EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
    871     EXPECT_EQ(0, coded_input.BytesUntilLimit());
    872 
    873     coded_input.PopLimit(limit2);
    874 
    875     // OK, popped limit2, now limit1 is on top, which we've already hit.
    876     EXPECT_EQ(0, coded_input.BytesUntilLimit());
    877     EXPECT_FALSE(coded_input.ReadLittleEndian32(&value));
    878     EXPECT_EQ(0, coded_input.BytesUntilLimit());
    879 
    880     coded_input.PopLimit(limit1);
    881 
    882     // No more limits.
    883     EXPECT_EQ(-1, coded_input.BytesUntilLimit());
    884     EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
    885   }
    886 
    887   EXPECT_EQ(8, input.ByteCount());
    888 }
    889 
    890 TEST_F(CodedStreamTest, ExpectAtEnd) {
    891   // Test ExpectAtEnd(), which is based on limits.
    892   ArrayInputStream input(buffer_, sizeof(buffer_));
    893   CodedInputStream coded_input(&input);
    894 
    895   EXPECT_FALSE(coded_input.ExpectAtEnd());
    896 
    897   CodedInputStream::Limit limit = coded_input.PushLimit(4);
    898 
    899   uint32 value;
    900   EXPECT_TRUE(coded_input.ReadLittleEndian32(&value));
    901   EXPECT_TRUE(coded_input.ExpectAtEnd());
    902 
    903   coded_input.PopLimit(limit);
    904   EXPECT_FALSE(coded_input.ExpectAtEnd());
    905 }
    906 
    907 TEST_F(CodedStreamTest, NegativeLimit) {
    908   // Check what happens when we push a negative limit.
    909   ArrayInputStream input(buffer_, sizeof(buffer_));
    910   CodedInputStream coded_input(&input);
    911 
    912   CodedInputStream::Limit limit = coded_input.PushLimit(-1234);
    913   // BytesUntilLimit() returns -1 to mean "no limit", which actually means
    914   // "the limit is INT_MAX relative to the beginning of the stream".
    915   EXPECT_EQ(-1, coded_input.BytesUntilLimit());
    916   coded_input.PopLimit(limit);
    917 }
    918 
    919 TEST_F(CodedStreamTest, NegativeLimitAfterReading) {
    920   // Check what happens when we push a negative limit.
    921   ArrayInputStream input(buffer_, sizeof(buffer_));
    922   CodedInputStream coded_input(&input);
    923   ASSERT_TRUE(coded_input.Skip(128));
    924 
    925   CodedInputStream::Limit limit = coded_input.PushLimit(-64);
    926   // BytesUntilLimit() returns -1 to mean "no limit", which actually means
    927   // "the limit is INT_MAX relative to the beginning of the stream".
    928   EXPECT_EQ(-1, coded_input.BytesUntilLimit());
    929   coded_input.PopLimit(limit);
    930 }
    931 
    932 TEST_F(CodedStreamTest, OverflowLimit) {
    933   // Check what happens when we push a limit large enough that its absolute
    934   // position is more than 2GB into the stream.
    935   ArrayInputStream input(buffer_, sizeof(buffer_));
    936   CodedInputStream coded_input(&input);
    937   ASSERT_TRUE(coded_input.Skip(128));
    938 
    939   CodedInputStream::Limit limit = coded_input.PushLimit(INT_MAX);
    940   // BytesUntilLimit() returns -1 to mean "no limit", which actually means
    941   // "the limit is INT_MAX relative to the beginning of the stream".
    942   EXPECT_EQ(-1, coded_input.BytesUntilLimit());
    943   coded_input.PopLimit(limit);
    944 }
    945 
    946 TEST_F(CodedStreamTest, TotalBytesLimit) {
    947   ArrayInputStream input(buffer_, sizeof(buffer_));
    948   CodedInputStream coded_input(&input);
    949   coded_input.SetTotalBytesLimit(16, -1);
    950 
    951   string str;
    952   EXPECT_TRUE(coded_input.ReadString(&str, 16));
    953 
    954   vector<string> errors;
    955 
    956   {
    957     ScopedMemoryLog error_log;
    958     EXPECT_FALSE(coded_input.ReadString(&str, 1));
    959     errors = error_log.GetMessages(ERROR);
    960   }
    961 
    962   ASSERT_EQ(1, errors.size());
    963   EXPECT_PRED_FORMAT2(testing::IsSubstring,
    964     "A protocol message was rejected because it was too big", errors[0]);
    965 
    966   coded_input.SetTotalBytesLimit(32, -1);
    967   EXPECT_TRUE(coded_input.ReadString(&str, 16));
    968 }
    969 
    970 TEST_F(CodedStreamTest, TotalBytesLimitNotValidMessageEnd) {
    971   // total_bytes_limit_ is not a valid place for a message to end.
    972 
    973   ArrayInputStream input(buffer_, sizeof(buffer_));
    974   CodedInputStream coded_input(&input);
    975 
    976   // Set both total_bytes_limit and a regular limit at 16 bytes.
    977   coded_input.SetTotalBytesLimit(16, -1);
    978   CodedInputStream::Limit limit = coded_input.PushLimit(16);
    979 
    980   // Read 16 bytes.
    981   string str;
    982   EXPECT_TRUE(coded_input.ReadString(&str, 16));
    983 
    984   // Read a tag.  Should fail, but report being a valid endpoint since it's
    985   // a regular limit.
    986   EXPECT_EQ(0, coded_input.ReadTag());
    987   EXPECT_TRUE(coded_input.ConsumedEntireMessage());
    988 
    989   // Pop the limit.
    990   coded_input.PopLimit(limit);
    991 
    992   // Read a tag.  Should fail, and report *not* being a valid endpoint, since
    993   // this time we're hitting the total bytes limit.
    994   EXPECT_EQ(0, coded_input.ReadTag());
    995   EXPECT_FALSE(coded_input.ConsumedEntireMessage());
    996 }
    997 
    998 TEST_F(CodedStreamTest, RecursionLimit) {
    999   ArrayInputStream input(buffer_, sizeof(buffer_));
   1000   CodedInputStream coded_input(&input);
   1001   coded_input.SetRecursionLimit(4);
   1002 
   1003   // This is way too much testing for a counter.
   1004   EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 1
   1005   EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 2
   1006   EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 3
   1007   EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 4
   1008   EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 5
   1009   EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 6
   1010   coded_input.DecrementRecursionDepth();                   // 5
   1011   EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 6
   1012   coded_input.DecrementRecursionDepth();                   // 5
   1013   coded_input.DecrementRecursionDepth();                   // 4
   1014   coded_input.DecrementRecursionDepth();                   // 3
   1015   EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 4
   1016   EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 5
   1017   coded_input.DecrementRecursionDepth();                   // 4
   1018   coded_input.DecrementRecursionDepth();                   // 3
   1019   coded_input.DecrementRecursionDepth();                   // 2
   1020   coded_input.DecrementRecursionDepth();                   // 1
   1021   coded_input.DecrementRecursionDepth();                   // 0
   1022   coded_input.DecrementRecursionDepth();                   // 0
   1023   coded_input.DecrementRecursionDepth();                   // 0
   1024   EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 1
   1025   EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 2
   1026   EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 3
   1027   EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 4
   1028   EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 5
   1029 
   1030   coded_input.SetRecursionLimit(6);
   1031   EXPECT_TRUE(coded_input.IncrementRecursionDepth());      // 6
   1032   EXPECT_FALSE(coded_input.IncrementRecursionDepth());     // 7
   1033 }
   1034 
   1035 class ReallyBigInputStream : public ZeroCopyInputStream {
   1036  public:
   1037   ReallyBigInputStream() : backup_amount_(0), buffer_count_(0) {}
   1038   ~ReallyBigInputStream() {}
   1039 
   1040   // implements ZeroCopyInputStream ----------------------------------
   1041   bool Next(const void** data, int* size) {
   1042     // We only expect BackUp() to be called at the end.
   1043     EXPECT_EQ(0, backup_amount_);
   1044 
   1045     switch (buffer_count_++) {
   1046       case 0:
   1047         *data = buffer_;
   1048         *size = sizeof(buffer_);
   1049         return true;
   1050       case 1:
   1051         // Return an enormously large buffer that, when combined with the 1k
   1052         // returned already, should overflow the total_bytes_read_ counter in
   1053         // CodedInputStream.  Note that we'll only read the first 1024 bytes
   1054         // of this buffer so it's OK that we have it point at buffer_.
   1055         *data = buffer_;
   1056         *size = INT_MAX;
   1057         return true;
   1058       default:
   1059         return false;
   1060     }
   1061   }
   1062 
   1063   void BackUp(int count) {
   1064     backup_amount_ = count;
   1065   }
   1066 
   1067   bool Skip(int count)    { GOOGLE_LOG(FATAL) << "Not implemented."; return false; }
   1068   int64 ByteCount() const { GOOGLE_LOG(FATAL) << "Not implemented."; return 0; }
   1069 
   1070   int backup_amount_;
   1071 
   1072  private:
   1073   char buffer_[1024];
   1074   int64 buffer_count_;
   1075 };
   1076 
   1077 TEST_F(CodedStreamTest, InputOver2G) {
   1078   // CodedInputStream should gracefully handle input over 2G and call
   1079   // input.BackUp() with the correct number of bytes on destruction.
   1080   ReallyBigInputStream input;
   1081 
   1082   vector<string> errors;
   1083 
   1084   {
   1085     ScopedMemoryLog error_log;
   1086     CodedInputStream coded_input(&input);
   1087     string str;
   1088     EXPECT_TRUE(coded_input.ReadString(&str, 512));
   1089     EXPECT_TRUE(coded_input.ReadString(&str, 1024));
   1090     errors = error_log.GetMessages(ERROR);
   1091   }
   1092 
   1093   EXPECT_EQ(INT_MAX - 512, input.backup_amount_);
   1094   EXPECT_EQ(0, errors.size());
   1095 }
   1096 
   1097 // ===================================================================
   1098 
   1099 
   1100 }  // namespace
   1101 }  // namespace io
   1102 }  // namespace protobuf
   1103 }  // namespace google
   1104