1fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Protocol Buffers - Google's data interchange format 2fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Copyright 2008 Google Inc. All rights reserved. 3fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// http://code.google.com/p/protobuf/ 4fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 5fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Redistribution and use in source and binary forms, with or without 6fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// modification, are permitted provided that the following conditions are 7fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// met: 8fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 9fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions of source code must retain the above copyright 10fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// notice, this list of conditions and the following disclaimer. 11fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Redistributions in binary form must reproduce the above 12fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// copyright notice, this list of conditions and the following disclaimer 13fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// in the documentation and/or other materials provided with the 14fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// distribution. 15fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// * Neither the name of Google Inc. nor the names of its 16fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// contributors may be used to endorse or promote products derived from 17fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// this software without specific prior written permission. 18fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 19fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 21fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 22fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 23fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 24fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 25fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 26fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 27fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 28fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 31fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Author: kenton@google.com (Kenton Varda) 32fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Based on original Protocol Buffers design by 33fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Sanjay Ghemawat, Jeff Dean, and others. 34fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 35fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Testing strategy: For each type of I/O (array, string, file, etc.) we 36fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// create an output stream and write some data to it, then create a 37fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// corresponding input stream to read the same data back and expect it to 38fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// match. When the data is written, it is written in several small chunks 39fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// of varying sizes, with a BackUp() after each chunk. It is read back 40fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// similarly, but with chunks separated at different points. The whole 41fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// process is run with a variety of block sizes for both the input and 42fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the output. 43fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// 44fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// TODO(kenton): Rewrite this test to bring it up to the standards of all 45fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// the other proto2 tests. May want to wait for gTest to implement 46fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// "parametized tests" so that one set of tests can be used on all the 47fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// implementations. 48fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 49fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include "config.h" 50fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 51fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifdef _MSC_VER 52fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <io.h> 53fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#else 54fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <unistd.h> 55fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 56fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <stdlib.h> 57fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <sys/types.h> 58fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <sys/stat.h> 59fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <fcntl.h> 60fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <errno.h> 61fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <sstream> 62fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 63fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/zero_copy_stream_impl.h> 64fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 65fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#if HAVE_ZLIB 66fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/io/gzip_stream.h> 67fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 68fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 69fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/stubs/common.h> 70fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/testing/googletest.h> 71fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <google/protobuf/testing/file.h> 72fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#include <gtest/gtest.h> 73fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 74fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace google { 75fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace protobuf { 76fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace io { 77fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillenamespace { 78fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 79fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifdef _WIN32 80fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define pipe(fds) _pipe(fds, 4096, O_BINARY) 81fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 82fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 83fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifndef O_BINARY 84fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#ifdef _O_BINARY 85fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define O_BINARY _O_BINARY 86fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#else 87fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. 88fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 89fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 90fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 91fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass IoTest : public testing::Test { 92fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville protected: 93fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Test helpers. 94fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 95fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Helper to write an array of data to an output stream. 96fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville bool WriteToOutput(ZeroCopyOutputStream* output, const void* data, int size); 97fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Helper to read a fixed-length array of data from an input stream. 98fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int ReadFromInput(ZeroCopyInputStream* input, void* data, int size); 99fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Write a string to the output stream. 100fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void WriteString(ZeroCopyOutputStream* output, const string& str); 101fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Read a number of bytes equal to the size of the given string and checks 102fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // that it matches the string. 103fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ReadString(ZeroCopyInputStream* input, const string& str); 104fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Writes some text to the output stream in a particular order. Returns 105fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // the number of bytes written, incase the caller needs that to set up an 106fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // input stream. 107fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int WriteStuff(ZeroCopyOutputStream* output); 108fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Reads text from an input stream and expects it to match what 109fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // WriteStuff() writes. 110fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ReadStuff(ZeroCopyInputStream* input); 111fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 112fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Similar to WriteStuff, but performs more sophisticated testing. 113fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int WriteStuffLarge(ZeroCopyOutputStream* output); 114fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Reads and tests a stream that should have been written to 115fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // via WriteStuffLarge(). 116fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void ReadStuffLarge(ZeroCopyInputStream* input); 117fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 118fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#if HAVE_ZLIB 119fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string Compress(const string& data, const GzipOutputStream::Options& options); 120fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string Uncompress(const string& data); 121fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 122fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 123fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static const int kBlockSizes[]; 124fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static const int kBlockSizeCount; 125fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 126fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 127fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst int IoTest::kBlockSizes[] = {-1, 1, 2, 5, 7, 10, 23, 64}; 128fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleconst int IoTest::kBlockSizeCount = GOOGLE_ARRAYSIZE(IoTest::kBlockSizes); 129fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 130fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillebool IoTest::WriteToOutput(ZeroCopyOutputStream* output, 131fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* data, int size) { 132fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const uint8* in = reinterpret_cast<const uint8*>(data); 133fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int in_size = size; 134fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 135fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void* out; 136fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int out_size; 137fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 138fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (true) { 139fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!output->Next(&out, &out_size)) { 140fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return false; 141fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 142fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_GT(out_size, 0); 143fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 144fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (in_size <= out_size) { 145fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memcpy(out, in, in_size); 146fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output->BackUp(out_size - in_size); 147fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return true; 148fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 149fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 150fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memcpy(out, in, out_size); 151fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville in += out_size; 152fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville in_size -= out_size; 153fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 154fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 155fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 156fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#define MAX_REPEATED_ZEROS 100 157fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 158fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint IoTest::ReadFromInput(ZeroCopyInputStream* input, void* data, int size) { 159fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8* out = reinterpret_cast<uint8*>(data); 160fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int out_size = size; 161fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 162fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* in; 163fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int in_size = 0; 164fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 165fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int repeated_zeros = 0; 166fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 167fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (true) { 168fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (!input->Next(&in, &in_size)) { 169fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return size - out_size; 170fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 171fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_GT(in_size, -1); 172fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (in_size == 0) { 173fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville repeated_zeros++; 174fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } else { 175fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville repeated_zeros = 0; 176fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 177fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_LT(repeated_zeros, MAX_REPEATED_ZEROS); 178fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 179fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (out_size <= in_size) { 180fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memcpy(out, in, out_size); 181fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville if (in_size > out_size) { 182fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville input->BackUp(in_size - out_size); 183fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 184fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return size; // Copied all of it. 185fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 186fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 187fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville memcpy(out, in, in_size); 188fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville out += in_size; 189fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville out_size -= in_size; 190fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 191fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 192fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 193fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid IoTest::WriteString(ZeroCopyOutputStream* output, const string& str) { 194fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(WriteToOutput(output, str.c_str(), str.size())); 195fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 196fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 197fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid IoTest::ReadString(ZeroCopyInputStream* input, const string& str) { 198fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville scoped_array<char> buffer(new char[str.size() + 1]); 199fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville buffer[str.size()] = '\0'; 200fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(ReadFromInput(input, buffer.get(), str.size()), str.size()); 201fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_STREQ(str.c_str(), buffer.get()); 202fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 203fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 204fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint IoTest::WriteStuff(ZeroCopyOutputStream* output) { 205fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteString(output, "Hello world!\n"); 206fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteString(output, "Some te"); 207fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteString(output, "xt. Blah blah."); 208fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteString(output, "abcdefg"); 209fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteString(output, "01234567890123456789"); 210fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteString(output, "foobar"); 211fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 212fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(output->ByteCount(), 68); 213fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 214fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int result = output->ByteCount(); 215fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 216fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 217fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 218fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Reads text from an input stream and expects it to match what WriteStuff() 219fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// writes. 220fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid IoTest::ReadStuff(ZeroCopyInputStream* input) { 221fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadString(input, "Hello world!\n"); 222fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadString(input, "Some text. "); 223fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadString(input, "Blah "); 224fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadString(input, "blah."); 225fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadString(input, "abcdefg"); 226fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(input->Skip(20)); 227fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadString(input, "foo"); 228fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadString(input, "bar"); 229fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 230fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(input->ByteCount(), 68); 231fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 232fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8 byte; 233fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(ReadFromInput(input, &byte, 1), 0); 234fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 235fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 236fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleint IoTest::WriteStuffLarge(ZeroCopyOutputStream* output) { 237fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteString(output, "Hello world!\n"); 238fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteString(output, "Some te"); 239fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteString(output, "xt. Blah blah."); 240fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteString(output, string(100000, 'x')); // A very long string 241fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteString(output, string(100000, 'y')); // A very long string 242fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteString(output, "01234567890123456789"); 243fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 244fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(output->ByteCount(), 200055); 245fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 246fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int result = output->ByteCount(); 247fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 248fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 249fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 250fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Reads text from an input stream and expects it to match what WriteStuff() 251fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// writes. 252fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillevoid IoTest::ReadStuffLarge(ZeroCopyInputStream* input) { 253fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadString(input, "Hello world!\nSome text. "); 254fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(input->Skip(5)); 255fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadString(input, "blah."); 256fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(input->Skip(100000 - 10)); 257fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadString(input, string(10, 'x') + string(100000 - 20000, 'y')); 258fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(input->Skip(20000 - 10)); 259fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadString(input, "yyyyyyyyyy01234567890123456789"); 260fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 261fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(input->ByteCount(), 200055); 262fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 263fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8 byte; 264fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(ReadFromInput(input, &byte, 1), 0); 265fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 266fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 267fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// =================================================================== 268fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 269fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(IoTest, ArrayIo) { 270fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const int kBufferSize = 256; 271fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8 buffer[kBufferSize]; 272fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 273fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < kBlockSizeCount; i++) { 274fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int j = 0; j < kBlockSizeCount; j++) { 275fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size; 276fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 277fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); 278fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = WriteStuff(&output); 279fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 280fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 281fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input(buffer, size, kBlockSizes[j]); 282fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadStuff(&input); 283fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 284fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 285fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 286fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 287fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 288fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#if HAVE_ZLIB 289fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(IoTest, GzipIo) { 290fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const int kBufferSize = 2*1024; 291fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8* buffer = new uint8[kBufferSize]; 292fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < kBlockSizeCount; i++) { 293fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int j = 0; j < kBlockSizeCount; j++) { 294fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int z = 0; z < kBlockSizeCount; z++) { 295fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int gzip_buffer_size = kBlockSizes[z]; 296fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size; 297fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 298fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); 299fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GzipOutputStream gzout( 300fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville &output, GzipOutputStream::GZIP, gzip_buffer_size); 301fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteStuff(&gzout); 302fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville gzout.Close(); 303fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = output.ByteCount(); 304fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 305fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 306fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input(buffer, size, kBlockSizes[j]); 307fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GzipInputStream gzin( 308fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville &input, GzipInputStream::GZIP, gzip_buffer_size); 309fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadStuff(&gzin); 310fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 311fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 312fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 313fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 314fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville delete [] buffer; 315fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 316fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 317fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(IoTest, ZlibIo) { 318fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const int kBufferSize = 2*1024; 319fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8* buffer = new uint8[kBufferSize]; 320fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < kBlockSizeCount; i++) { 321fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int j = 0; j < kBlockSizeCount; j++) { 322fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int z = 0; z < kBlockSizeCount; z++) { 323fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int gzip_buffer_size = kBlockSizes[z]; 324fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size; 325fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 326fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); 327fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GzipOutputStream gzout( 328fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville &output, GzipOutputStream::ZLIB, gzip_buffer_size); 329fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteStuff(&gzout); 330fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville gzout.Close(); 331fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = output.ByteCount(); 332fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 333fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 334fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input(buffer, size, kBlockSizes[j]); 335fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GzipInputStream gzin( 336fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville &input, GzipInputStream::ZLIB, gzip_buffer_size); 337fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadStuff(&gzin); 338fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 339fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 340fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 341fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 342fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville delete [] buffer; 343fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 344fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 345fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(IoTest, ZlibIoInputAutodetect) { 346fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const int kBufferSize = 2*1024; 347fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8* buffer = new uint8[kBufferSize]; 348fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size; 349fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 350fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayOutputStream output(buffer, kBufferSize); 351fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GzipOutputStream gzout(&output, GzipOutputStream::ZLIB); 352fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteStuff(&gzout); 353fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville gzout.Close(); 354fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = output.ByteCount(); 355fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 356fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 357fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input(buffer, size); 358fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GzipInputStream gzin(&input, GzipInputStream::AUTO); 359fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadStuff(&gzin); 360fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 361fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 362fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayOutputStream output(buffer, kBufferSize); 363fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GzipOutputStream gzout(&output, GzipOutputStream::GZIP); 364fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteStuff(&gzout); 365fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville gzout.Close(); 366fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville size = output.ByteCount(); 367fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 368fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 369fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input(buffer, size); 370fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GzipInputStream gzin(&input, GzipInputStream::AUTO); 371fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadStuff(&gzin); 372fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 373fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville delete [] buffer; 374fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 375fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 376fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring IoTest::Compress(const string& data, 377fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const GzipOutputStream::Options& options) { 378fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string result; 379fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 380fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville StringOutputStream output(&result); 381fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GzipOutputStream gzout(&output, options); 382fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteToOutput(&gzout, data.data(), data.size()); 383fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 384fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 385fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 386fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 387fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savillestring IoTest::Uncompress(const string& data) { 388fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string result; 389fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 390fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input(data.data(), data.size()); 391fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GzipInputStream gzin(&input); 392fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* buffer; 393fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size; 394fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville while (gzin.Next(&buffer, &size)) { 395fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville result.append(reinterpret_cast<const char*>(buffer), size); 396fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 397fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 398fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville return result; 399fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 400fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 401fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(IoTest, CompressionOptions) { 402fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Some ad-hoc testing of compression options. 403fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 404fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string golden; 405fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville File::ReadFileToStringOrDie( 406d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville TestSourceDir() + "/google/protobuf/testdata/golden_message", 407d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville &golden); 408fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 409fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GzipOutputStream::Options options; 410fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string gzip_compressed = Compress(golden, options); 411fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 412fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options.compression_level = 0; 413fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string not_compressed = Compress(golden, options); 414fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 415fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Try zlib compression for fun. 416fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options = GzipOutputStream::Options(); 417fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville options.format = GzipOutputStream::ZLIB; 418fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string zlib_compressed = Compress(golden, options); 419fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 420fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Uncompressed should be bigger than the original since it should have some 421fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // sort of header. 422fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_GT(not_compressed.size(), golden.size()); 423fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 424fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Higher compression levels should result in smaller sizes. 425fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_LT(zlib_compressed.size(), not_compressed.size()); 426fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 427fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // ZLIB format should differ from GZIP format. 428fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(zlib_compressed != gzip_compressed); 429fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 430fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Everything should decompress correctly. 431fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(Uncompress(not_compressed) == golden); 432fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(Uncompress(gzip_compressed) == golden); 433fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(Uncompress(zlib_compressed) == golden); 434fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 435fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 436fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 437fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// There is no string input, only string output. Also, it doesn't support 438fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// explicit block sizes. So, we'll only run one test and we'll use 439fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// ArrayInput to read back the results. 440fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(IoTest, StringIo) { 441fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string str; 442fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 443fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville StringOutputStream output(&str); 444fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteStuff(&output); 445fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 446fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 447fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input(str.data(), str.size()); 448fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadStuff(&input); 449fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 450fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 451fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 452fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 453fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// To test files, we create a temporary file, write, read, truncate, repeat. 454fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(IoTest, FileIo) { 455fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string filename = TestTempDir() + "/zero_copy_stream_test_file"; 456fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 457fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < kBlockSizeCount; i++) { 458fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int j = 0; j < kBlockSizeCount; j++) { 459fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Make a temporary file. 460fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int file = 461fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0777); 462fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_GE(file, 0); 463fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 464fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 465fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileOutputStream output(file, kBlockSizes[i]); 466fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteStuff(&output); 467fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(0, output.GetErrno()); 468fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 469fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 470fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Rewind. 471fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1); 472fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 473fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 474fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileInputStream input(file, kBlockSizes[j]); 475fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadStuff(&input); 476fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(0, input.GetErrno()); 477fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 478fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 479fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville close(file); 480fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 481fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 482fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 483fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 484fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#if HAVE_ZLIB 485fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(IoTest, GzipFileIo) { 486fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville string filename = TestTempDir() + "/zero_copy_stream_test_file"; 487fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 488fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < kBlockSizeCount; i++) { 489fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int j = 0; j < kBlockSizeCount; j++) { 490fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Make a temporary file. 491fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int file = 492fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0777); 493fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_GE(file, 0); 494fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 495fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileOutputStream output(file, kBlockSizes[i]); 496fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GzipOutputStream gzout(&output); 497fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteStuffLarge(&gzout); 498fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville gzout.Close(); 499fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville output.Flush(); 500fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(0, output.GetErrno()); 501fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 502fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 503fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Rewind. 504fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1); 505fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 506fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 507fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileInputStream input(file, kBlockSizes[j]); 508fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville GzipInputStream gzin(&input); 509fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadStuffLarge(&gzin); 510fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(0, input.GetErrno()); 511fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 512fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 513fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville close(file); 514fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 515fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 516fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 517fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 518fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 519fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// MSVC raises various debugging exceptions if we try to use a file 520fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// descriptor of -1, defeating our tests below. This class will disable 521fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// these debug assertions while in scope. 522fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Savilleclass MsvcDebugDisabler { 523fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville public: 524d0332953cda33fb4f8e24ebff9c49159b69c43d6Wink Saville#if defined(_MSC_VER) && _MSC_VER >= 1400 525fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MsvcDebugDisabler() { 526fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville old_handler_ = _set_invalid_parameter_handler(MyHandler); 527fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville old_mode_ = _CrtSetReportMode(_CRT_ASSERT, 0); 528fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 529fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ~MsvcDebugDisabler() { 530fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville old_handler_ = _set_invalid_parameter_handler(old_handler_); 531fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville old_mode_ = _CrtSetReportMode(_CRT_ASSERT, old_mode_); 532fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 533fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 534fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville static void MyHandler(const wchar_t *expr, 535fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const wchar_t *func, 536fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const wchar_t *file, 537fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville unsigned int line, 538fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uintptr_t pReserved) { 539fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // do nothing 540fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 541fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 542fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville _invalid_parameter_handler old_handler_; 543fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int old_mode_; 544fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#else 545fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Dummy constructor and destructor to ensure that GCC doesn't complain 546fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // that debug_disabler is an unused variable. 547fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MsvcDebugDisabler() {} 548fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ~MsvcDebugDisabler() {} 549fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville#endif 550fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville}; 551fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 552fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Test that FileInputStreams report errors correctly. 553fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(IoTest, FileReadError) { 554fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MsvcDebugDisabler debug_disabler; 555fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 556fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // -1 = invalid file descriptor. 557fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileInputStream input(-1); 558fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 559fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* buffer; 560fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size; 561fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_FALSE(input.Next(&buffer, &size)); 562fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(EBADF, input.GetErrno()); 563fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 564fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 565fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Test that FileOutputStreams report errors correctly. 566fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(IoTest, FileWriteError) { 567fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville MsvcDebugDisabler debug_disabler; 568fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 569fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // -1 = invalid file descriptor. 570fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileOutputStream input(-1); 571fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 572fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void* buffer; 573fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size; 574fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 575fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // The first call to Next() succeeds because it doesn't have anything to 576fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // write yet. 577fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(input.Next(&buffer, &size)); 578fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 579fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Second call fails. 580fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_FALSE(input.Next(&buffer, &size)); 581fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 582fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(EBADF, input.GetErrno()); 583fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 584fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 585fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Pipes are not seekable, so File{Input,Output}Stream ends up doing some 586fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// different things to handle them. We'll test by writing to a pipe and 587fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// reading back from it. 588fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(IoTest, PipeIo) { 589fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int files[2]; 590fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 591fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < kBlockSizeCount; i++) { 592fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int j = 0; j < kBlockSizeCount; j++) { 593fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Need to create a new pipe each time because ReadStuff() expects 594fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // to see EOF at the end. 595fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_EQ(pipe(files), 0); 596fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 597fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 598fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileOutputStream output(files[1], kBlockSizes[i]); 599fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteStuff(&output); 600fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(0, output.GetErrno()); 601fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 602fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville close(files[1]); // Send EOF. 603fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 604fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 605fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville FileInputStream input(files[0], kBlockSizes[j]); 606fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadStuff(&input); 607fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_EQ(0, input.GetErrno()); 608fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 609fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville close(files[0]); 610fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 611fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 612fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 613fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 614fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Test using C++ iostreams. 615fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(IoTest, IostreamIo) { 616fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int i = 0; i < kBlockSizeCount; i++) { 617fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville for (int j = 0; j < kBlockSizeCount; j++) { 618fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 619fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville stringstream stream; 620fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 621fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 622fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OstreamOutputStream output(&stream, kBlockSizes[i]); 623fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteStuff(&output); 624fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_FALSE(stream.fail()); 625fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 626fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 627fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 628fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville IstreamInputStream input(&stream, kBlockSizes[j]); 629fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadStuff(&input); 630fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(stream.eof()); 631fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 632fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 633fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 634fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 635fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville stringstream stream; 636fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 637fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 638fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville OstreamOutputStream output(&stream, kBlockSizes[i]); 639fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteStuffLarge(&output); 640fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_FALSE(stream.fail()); 641fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 642fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 643fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville { 644fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville IstreamInputStream input(&stream, kBlockSizes[j]); 645fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadStuffLarge(&input); 646fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_TRUE(stream.eof()); 647fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 648fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 649fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 650fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville } 651fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 652fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 653fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// To test ConcatenatingInputStream, we create several ArrayInputStreams 654fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// covering a buffer and then concatenate them. 655fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(IoTest, ConcatenatingInputStream) { 656fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const int kBufferSize = 256; 657fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8 buffer[kBufferSize]; 658fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 659fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Fill the buffer. 660fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayOutputStream output(buffer, kBufferSize); 661fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteStuff(&output); 662fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 663fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Now split it up into multiple streams of varying sizes. 664fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ASSERT_EQ(68, output.ByteCount()); // Test depends on this. 665fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input1(buffer , 12); 666fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input2(buffer + 12, 7); 667fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input3(buffer + 19, 6); 668fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input4(buffer + 25, 15); 669fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input5(buffer + 40, 0); 670fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Note: We want to make sure we have a stream boundary somewhere between 671fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // bytes 42 and 62, which is the range that it Skip()ed by ReadStuff(). This 672fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // tests that a bug that existed in the original code for Skip() is fixed. 673fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input6(buffer + 40, 10); 674fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input7(buffer + 50, 18); // Total = 68 bytes. 675fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 676fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ZeroCopyInputStream* streams[] = 677fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville {&input1, &input2, &input3, &input4, &input5, &input6, &input7}; 678fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 679fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Create the concatenating stream and read. 680fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ConcatenatingInputStream input(streams, GOOGLE_ARRAYSIZE(streams)); 681fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadStuff(&input); 682fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 683fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 684fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// To test LimitingInputStream, we write our golden text to a buffer, then 685fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// create an ArrayInputStream that contains the whole buffer (not just the 686fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// bytes written), then use a LimitingInputStream to limit it just to the 687fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// bytes written. 688fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST_F(IoTest, LimitingInputStream) { 689fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const int kBufferSize = 256; 690fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville uint8 buffer[kBufferSize]; 691fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 692fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Fill the buffer. 693fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayOutputStream output(buffer, kBufferSize); 694fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville WriteStuff(&output); 695fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 696fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville // Set up input. 697fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream array_input(buffer, kBufferSize); 698fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville LimitingInputStream input(&array_input, output.ByteCount()); 699fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 700fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ReadStuff(&input); 701fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 702fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 703fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville// Check that a zero-size array doesn't confuse the code. 704fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST(ZeroSizeArray, Input) { 705fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayInputStream input(NULL, 0); 706fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville const void* data; 707fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size; 708fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_FALSE(input.Next(&data, &size)); 709fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 710fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 711fbaaef999ba563838ebd00874ed8a1c01fbf286dWink SavilleTEST(ZeroSizeArray, Output) { 712fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville ArrayOutputStream output(NULL, 0); 713fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville void* data; 714fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville int size; 715fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville EXPECT_FALSE(output.Next(&data, &size)); 716fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} 717fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville 718fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace 719fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace io 720fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace protobuf 721fbaaef999ba563838ebd00874ed8a1c01fbf286dWink Saville} // namespace google 722