15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Protocol Buffers - Google's data interchange format 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2008 Google Inc. All rights reserved. 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://code.google.com/p/protobuf/ 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Redistribution and use in source and binary forms, with or without 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modification, are permitted provided that the following conditions are 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// met: 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions of source code must retain the above copyright 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// notice, this list of conditions and the following disclaimer. 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Redistributions in binary form must reproduce the above 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// copyright notice, this list of conditions and the following disclaimer 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// in the documentation and/or other materials provided with the 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// distribution. 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// * Neither the name of Google Inc. nor the names of its 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// contributors may be used to endorse or promote products derived from 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this software without specific prior written permission. 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author: kenton@google.com (Kenton Varda) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Based on original Protocol Buffers design by 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Sanjay Ghemawat, Jeff Dean, and others. 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Testing strategy: For each type of I/O (array, string, file, etc.) we 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// create an output stream and write some data to it, then create a 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// corresponding input stream to read the same data back and expect it to 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// match. When the data is written, it is written in several small chunks 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of varying sizes, with a BackUp() after each chunk. It is read back 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// similarly, but with chunks separated at different points. The whole 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// process is run with a variety of block sizes for both the input and 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the output. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(kenton): Rewrite this test to bring it up to the standards of all 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the other proto2 tests. May want to wait for gTest to implement 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// "parametized tests" so that one set of tests can be used on all the 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// implementations. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "config.h" 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _MSC_VER 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <io.h> 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <stdlib.h> 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/types.h> 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/stat.h> 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <fcntl.h> 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sstream> 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/zero_copy_stream_impl.h> 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/coded_stream.h> 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if HAVE_ZLIB 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/io/gzip_stream.h> 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/stubs/common.h> 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/testing/googletest.h> 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <google/protobuf/testing/file.h> 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <gtest/gtest.h> 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace protobuf { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace io { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _WIN32 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define pipe(fds) _pipe(fds, 4096, O_BINARY) 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef O_BINARY 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifdef _O_BINARY 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define O_BINARY _O_BINARY 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define O_BINARY 0 // If this isn't defined, the platform doesn't need it. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IoTest : public testing::Test { 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test helpers. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper to write an array of data to an output stream. 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WriteToOutput(ZeroCopyOutputStream* output, const void* data, int size); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Helper to read a fixed-length array of data from an input stream. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int ReadFromInput(ZeroCopyInputStream* input, void* data, int size); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Write a string to the output stream. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void WriteString(ZeroCopyOutputStream* output, const string& str); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Read a number of bytes equal to the size of the given string and checks 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that it matches the string. 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReadString(ZeroCopyInputStream* input, const string& str); 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Writes some text to the output stream in a particular order. Returns 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the number of bytes written, incase the caller needs that to set up an 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // input stream. 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int WriteStuff(ZeroCopyOutputStream* output); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads text from an input stream and expects it to match what 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // WriteStuff() writes. 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReadStuff(ZeroCopyInputStream* input); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Similar to WriteStuff, but performs more sophisticated testing. 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int WriteStuffLarge(ZeroCopyOutputStream* output); 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reads and tests a stream that should have been written to 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // via WriteStuffLarge(). 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReadStuffLarge(ZeroCopyInputStream* input); 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if HAVE_ZLIB 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string Compress(const string& data, const GzipOutputStream::Options& options); 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string Uncompress(const string& data); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kBlockSizes[]; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kBlockSizeCount; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int IoTest::kBlockSizes[] = {-1, 1, 2, 5, 7, 10, 23, 64}; 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int IoTest::kBlockSizeCount = GOOGLE_ARRAYSIZE(IoTest::kBlockSizes); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool IoTest::WriteToOutput(ZeroCopyOutputStream* output, 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* data, int size) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const uint8* in = reinterpret_cast<const uint8*>(data); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int in_size = size; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* out; 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int out_size; 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!output->Next(&out, &out_size)) { 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(out_size, 0); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (in_size <= out_size) { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(out, in, in_size); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output->BackUp(out_size - in_size); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(out, in, out_size); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in += out_size; 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) in_size -= out_size; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAX_REPEATED_ZEROS 100 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int IoTest::ReadFromInput(ZeroCopyInputStream* input, void* data, int size) { 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* out = reinterpret_cast<uint8*>(data); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int out_size = size; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* in; 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int in_size = 0; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int repeated_zeros = 0; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (true) { 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!input->Next(&in, &in_size)) { 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size - out_size; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(in_size, -1); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (in_size == 0) { 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) repeated_zeros++; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) repeated_zeros = 0; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(repeated_zeros, MAX_REPEATED_ZEROS); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (out_size <= in_size) { 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(out, in, out_size); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (in_size > out_size) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input->BackUp(in_size - out_size); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return size; // Copied all of it. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memcpy(out, in, in_size); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out += in_size; 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) out_size -= in_size; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IoTest::WriteString(ZeroCopyOutputStream* output, const string& str) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(WriteToOutput(output, str.c_str(), str.size())); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IoTest::ReadString(ZeroCopyInputStream* input, const string& str) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_array<char> buffer(new char[str.size() + 1]); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer[str.size()] = '\0'; 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ReadFromInput(input, buffer.get(), str.size()), str.size()); 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_STREQ(str.c_str(), buffer.get()); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int IoTest::WriteStuff(ZeroCopyOutputStream* output) { 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteString(output, "Hello world!\n"); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteString(output, "Some te"); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteString(output, "xt. Blah blah."); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteString(output, "abcdefg"); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteString(output, "01234567890123456789"); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteString(output, "foobar"); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output->ByteCount(), 68); 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = output->ByteCount(); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Reads text from an input stream and expects it to match what WriteStuff() 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// writes. 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IoTest::ReadStuff(ZeroCopyInputStream* input) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadString(input, "Hello world!\n"); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadString(input, "Some text. "); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadString(input, "Blah "); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadString(input, "blah."); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadString(input, "abcdefg"); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(input->Skip(20)); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadString(input, "foo"); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadString(input, "bar"); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(input->ByteCount(), 68); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 byte; 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ReadFromInput(input, &byte, 1), 0); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int IoTest::WriteStuffLarge(ZeroCopyOutputStream* output) { 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteString(output, "Hello world!\n"); 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteString(output, "Some te"); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteString(output, "xt. Blah blah."); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteString(output, string(100000, 'x')); // A very long string 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteString(output, string(100000, 'y')); // A very long string 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteString(output, "01234567890123456789"); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(output->ByteCount(), 200055); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result = output->ByteCount(); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Reads text from an input stream and expects it to match what WriteStuff() 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// writes. 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void IoTest::ReadStuffLarge(ZeroCopyInputStream* input) { 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadString(input, "Hello world!\nSome text. "); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(input->Skip(5)); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadString(input, "blah."); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(input->Skip(100000 - 10)); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadString(input, string(10, 'x') + string(100000 - 20000, 'y')); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(input->Skip(20000 - 10)); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadString(input, "yyyyyyyyyy01234567890123456789"); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(input->ByteCount(), 200055); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 byte; 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(ReadFromInput(input, &byte, 1), 0); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// =================================================================== 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, ArrayIo) { 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kBufferSize = 256; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 buffer[kBufferSize]; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kBlockSizeCount; i++) { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < kBlockSizeCount; j++) { 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = WriteStuff(&output); 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input(buffer, size, kBlockSizes[j]); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadStuff(&input); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, TwoSessionWrite) { 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that two concatenated write sessions read correctly 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* strA = "0123456789"; 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* strB = "WhirledPeas"; 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kBufferSize = 2*1024; 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* buffer = new uint8[kBufferSize]; 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* temp_buffer = new char[40]; 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kBlockSizeCount; i++) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < kBlockSizeCount; j++) { 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputStream* output = 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodedOutputStream* coded_output = new CodedOutputStream(output); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_output->WriteVarint32(strlen(strA)); 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_output->WriteRaw(strA, strlen(strA)); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete coded_output; // flush 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 pos = output->ByteCount(); 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete output; 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output = new ArrayOutputStream( 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer + pos, kBufferSize - pos, kBlockSizes[i]); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_output = new CodedOutputStream(output); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_output->WriteVarint32(strlen(strB)); 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_output->WriteRaw(strB, strlen(strB)); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete coded_output; // flush 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 size = pos + output->ByteCount(); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete output; 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream* input = 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ArrayInputStream(buffer, size, kBlockSizes[j]); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodedInputStream* coded_input = new CodedInputStream(input); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 insize; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(coded_input->ReadVarint32(&insize)); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(strlen(strA), insize); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize)); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, memcmp(temp_buffer, strA, insize)); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(coded_input->ReadVarint32(&insize)); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(strlen(strB), insize); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize)); 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, memcmp(temp_buffer, strB, insize)); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete coded_input; 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete input; 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete [] temp_buffer; 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete [] buffer; 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if HAVE_ZLIB 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, GzipIo) { 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kBufferSize = 2*1024; 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* buffer = new uint8[kBufferSize]; 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kBlockSizeCount; i++) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < kBlockSizeCount; j++) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int z = 0; z < kBlockSizeCount; z++) { 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int gzip_buffer_size = kBlockSizes[z]; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipOutputStream::Options options; 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.format = GzipOutputStream::GZIP; 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gzip_buffer_size != -1) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.buffer_size = gzip_buffer_size; 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipOutputStream gzout(&output, options); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStuff(&gzout); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gzout.Close(); 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = output.ByteCount(); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input(buffer, size, kBlockSizes[j]); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipInputStream gzin( 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &input, GzipInputStream::GZIP, gzip_buffer_size); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadStuff(&gzin); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete [] buffer; 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3733d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben MurdochTEST_F(IoTest, GzipIoWithFlush) { 3743d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch const int kBufferSize = 2*1024; 3753d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch uint8* buffer = new uint8[kBufferSize]; 3763d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch // We start with i = 4 as we want a block size > 6. With block size <= 6 3773d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch // Flush() fills up the entire 2K buffer with flush markers and the test 3783d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch // fails. See documentation for Flush() for more detail. 3793d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch for (int i = 4; i < kBlockSizeCount; i++) { 3803d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch for (int j = 0; j < kBlockSizeCount; j++) { 3813d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch for (int z = 0; z < kBlockSizeCount; z++) { 3823d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch int gzip_buffer_size = kBlockSizes[z]; 3833d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch int size; 3843d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch { 3853d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); 3863d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch GzipOutputStream::Options options; 3873d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch options.format = GzipOutputStream::GZIP; 3883d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch if (gzip_buffer_size != -1) { 3893d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch options.buffer_size = gzip_buffer_size; 3903d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch } 3913d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch GzipOutputStream gzout(&output, options); 3923d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch WriteStuff(&gzout); 3933d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch EXPECT_TRUE(gzout.Flush()); 3943d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch gzout.Close(); 3953d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch size = output.ByteCount(); 3963d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch } 3973d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch { 3983d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch ArrayInputStream input(buffer, size, kBlockSizes[j]); 3993d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch GzipInputStream gzin( 4003d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch &input, GzipInputStream::GZIP, gzip_buffer_size); 4013d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch ReadStuff(&gzin); 4023d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch } 4033d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch } 4043d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch } 4053d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch } 4063d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch delete [] buffer; 4073d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch} 4083d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 4093d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben MurdochTEST_F(IoTest, GzipIoContiguousFlushes) { 4103d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch const int kBufferSize = 2*1024; 4113d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch uint8* buffer = new uint8[kBufferSize]; 4123d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 4133d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch int block_size = kBlockSizes[4]; 4143d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch int gzip_buffer_size = block_size; 4153d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch int size; 4163d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 4173d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch ArrayOutputStream output(buffer, kBufferSize, block_size); 4183d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch GzipOutputStream::Options options; 4193d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch options.format = GzipOutputStream::GZIP; 4203d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch if (gzip_buffer_size != -1) { 4213d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch options.buffer_size = gzip_buffer_size; 4223d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch } 4233d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch GzipOutputStream gzout(&output, options); 4243d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch WriteStuff(&gzout); 4253d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch EXPECT_TRUE(gzout.Flush()); 4263d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch EXPECT_TRUE(gzout.Flush()); 4273d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch gzout.Close(); 4283d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch size = output.ByteCount(); 4293d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 4303d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch ArrayInputStream input(buffer, size, block_size); 4313d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch GzipInputStream gzin( 4323d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch &input, GzipInputStream::GZIP, gzip_buffer_size); 4333d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch ReadStuff(&gzin); 4343d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 4353d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch delete [] buffer; 4363d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch} 4373d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 4383d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben MurdochTEST_F(IoTest, GzipIoReadAfterFlush) { 4393d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch const int kBufferSize = 2*1024; 4403d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch uint8* buffer = new uint8[kBufferSize]; 4413d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 4423d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch int block_size = kBlockSizes[4]; 4433d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch int gzip_buffer_size = block_size; 4443d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch int size; 4453d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch ArrayOutputStream output(buffer, kBufferSize, block_size); 4463d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch GzipOutputStream::Options options; 4473d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch options.format = GzipOutputStream::GZIP; 4483d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch if (gzip_buffer_size != -1) { 4493d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch options.buffer_size = gzip_buffer_size; 4503d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch } 4513d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 4523d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch GzipOutputStream gzout(&output, options); 4533d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch WriteStuff(&gzout); 4543d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch EXPECT_TRUE(gzout.Flush()); 4553d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch size = output.ByteCount(); 4563d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 4573d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch ArrayInputStream input(buffer, size, block_size); 4583d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch GzipInputStream gzin( 4593d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch &input, GzipInputStream::GZIP, gzip_buffer_size); 4603d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch ReadStuff(&gzin); 4613d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 4623d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch gzout.Close(); 4633d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 4643d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch delete [] buffer; 4653d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch} 4663d4dfb6f11fb4e934d658743a8efc26d5490fdb0Ben Murdoch 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, ZlibIo) { 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kBufferSize = 2*1024; 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* buffer = new uint8[kBufferSize]; 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kBlockSizeCount; i++) { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < kBlockSizeCount; j++) { 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int z = 0; z < kBlockSizeCount; z++) { 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int gzip_buffer_size = kBlockSizes[z]; 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputStream output(buffer, kBufferSize, kBlockSizes[i]); 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipOutputStream::Options options; 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.format = GzipOutputStream::ZLIB; 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (gzip_buffer_size != -1) { 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.buffer_size = gzip_buffer_size; 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipOutputStream gzout(&output, options); 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStuff(&gzout); 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gzout.Close(); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = output.ByteCount(); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input(buffer, size, kBlockSizes[j]); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipInputStream gzin( 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &input, GzipInputStream::ZLIB, gzip_buffer_size); 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadStuff(&gzin); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete [] buffer; 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, ZlibIoInputAutodetect) { 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kBufferSize = 2*1024; 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* buffer = new uint8[kBufferSize]; 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputStream output(buffer, kBufferSize); 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipOutputStream::Options options; 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.format = GzipOutputStream::ZLIB; 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipOutputStream gzout(&output, options); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStuff(&gzout); 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gzout.Close(); 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = output.ByteCount(); 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input(buffer, size); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipInputStream gzin(&input, GzipInputStream::AUTO); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadStuff(&gzin); 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputStream output(buffer, kBufferSize); 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipOutputStream::Options options; 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.format = GzipOutputStream::GZIP; 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipOutputStream gzout(&output, options); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStuff(&gzout); 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gzout.Close(); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size = output.ByteCount(); 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input(buffer, size); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipInputStream gzin(&input, GzipInputStream::AUTO); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadStuff(&gzin); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete [] buffer; 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string IoTest::Compress(const string& data, 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GzipOutputStream::Options& options) { 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string result; 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringOutputStream output(&result); 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipOutputStream gzout(&output, options); 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteToOutput(&gzout, data.data(), data.size()); 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)string IoTest::Uncompress(const string& data) { 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string result; 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input(data.data(), data.size()); 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipInputStream gzin(&input); 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* buffer; 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (gzin.Next(&buffer, &size)) { 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result.append(reinterpret_cast<const char*>(buffer), size); 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, CompressionOptions) { 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Some ad-hoc testing of compression options. 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string golden; 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) File::ReadFileToStringOrDie( 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestSourceDir() + "/google/protobuf/testdata/golden_message", 5655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &golden); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipOutputStream::Options options; 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string gzip_compressed = Compress(golden, options); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.compression_level = 0; 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string not_compressed = Compress(golden, options); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try zlib compression for fun. 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options = GzipOutputStream::Options(); 5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) options.format = GzipOutputStream::ZLIB; 5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string zlib_compressed = Compress(golden, options); 5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Uncompressed should be bigger than the original since it should have some 5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // sort of header. 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_GT(not_compressed.size(), golden.size()); 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Higher compression levels should result in smaller sizes. 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_LT(zlib_compressed.size(), not_compressed.size()); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // ZLIB format should differ from GZIP format. 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(zlib_compressed != gzip_compressed); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Everything should decompress correctly. 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(Uncompress(not_compressed) == golden); 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(Uncompress(gzip_compressed) == golden); 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(Uncompress(zlib_compressed) == golden); 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, TwoSessionWriteGzip) { 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test that two concatenated gzip streams can be read correctly 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* strA = "0123456789"; 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const char* strB = "QuickBrownFox"; 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kBufferSize = 2*1024; 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* buffer = new uint8[kBufferSize]; 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* temp_buffer = new char[40]; 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kBlockSizeCount; i++) { 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < kBlockSizeCount; j++) { 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputStream* output = 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ArrayOutputStream(buffer, kBufferSize, kBlockSizes[i]); 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipOutputStream* gzout = new GzipOutputStream(output); 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodedOutputStream* coded_output = new CodedOutputStream(gzout); 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int32 outlen = strlen(strA) + 1; 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_output->WriteVarint32(outlen); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_output->WriteRaw(strA, outlen); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete coded_output; // flush 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete gzout; // flush 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 pos = output->ByteCount(); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete output; 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output = new ArrayOutputStream( 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer + pos, kBufferSize - pos, kBlockSizes[i]); 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gzout = new GzipOutputStream(output); 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_output = new CodedOutputStream(gzout); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) outlen = strlen(strB) + 1; 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_output->WriteVarint32(outlen); 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) coded_output->WriteRaw(strB, outlen); 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete coded_output; // flush 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete gzout; // flush 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 size = pos + output->ByteCount(); 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete output; 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream* input = 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new ArrayInputStream(buffer, size, kBlockSizes[j]); 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipInputStream* gzin = new GzipInputStream(input); 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CodedInputStream* coded_input = new CodedInputStream(gzin); 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 insize; 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(coded_input->ReadVarint32(&insize)); 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(strlen(strA) + 1, insize); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize)); 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, memcmp(temp_buffer, strA, insize)) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "strA=" << strA << " in=" << temp_buffer; 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(coded_input->ReadVarint32(&insize)); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(strlen(strB) + 1, insize); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize)); 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, memcmp(temp_buffer, strB, insize)) 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " out_block_size=" << kBlockSizes[i] 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " in_block_size=" << kBlockSizes[j] 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " pos=" << pos 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " size=" << size 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " strB=" << strB << " in=" << temp_buffer; 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete coded_input; 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete gzin; 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete input; 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete [] temp_buffer; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delete [] buffer; 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There is no string input, only string output. Also, it doesn't support 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// explicit block sizes. So, we'll only run one test and we'll use 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ArrayInput to read back the results. 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, StringIo) { 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string str; 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StringOutputStream output(&str); 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStuff(&output); 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input(str.data(), str.size()); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadStuff(&input); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// To test files, we create a temporary file, write, read, truncate, repeat. 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, FileIo) { 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string filename = TestTempDir() + "/zero_copy_stream_test_file"; 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kBlockSizeCount; i++) { 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < kBlockSizeCount; j++) { 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a temporary file. 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int file = 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0777); 6855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GE(file, 0); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileOutputStream output(file, kBlockSizes[i]); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStuff(&output); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, output.GetErrno()); 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Rewind. 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileInputStream input(file, kBlockSizes[j]); 6985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadStuff(&input); 6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, input.GetErrno()); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(file); 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if HAVE_ZLIB 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, GzipFileIo) { 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) string filename = TestTempDir() + "/zero_copy_stream_test_file"; 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kBlockSizeCount; i++) { 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < kBlockSizeCount; j++) { 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make a temporary file. 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int file = 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, 0777); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_GE(file, 0); 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileOutputStream output(file, kBlockSizes[i]); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipOutputStream gzout(&output); 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStuffLarge(&gzout); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gzout.Close(); 7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output.Flush(); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, output.GetErrno()); 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Rewind. 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1); 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileInputStream input(file, kBlockSizes[j]); 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) GzipInputStream gzin(&input); 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadStuffLarge(&gzin); 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, input.GetErrno()); 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(file); 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MSVC raises various debugging exceptions if we try to use a file 7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// descriptor of -1, defeating our tests below. This class will disable 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// these debug assertions while in scope. 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class MsvcDebugDisabler { 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(_MSC_VER) && _MSC_VER >= 1400 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MsvcDebugDisabler() { 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_handler_ = _set_invalid_parameter_handler(MyHandler); 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_mode_ = _CrtSetReportMode(_CRT_ASSERT, 0); 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~MsvcDebugDisabler() { 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_handler_ = _set_invalid_parameter_handler(old_handler_); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) old_mode_ = _CrtSetReportMode(_CRT_ASSERT, old_mode_); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void MyHandler(const wchar_t *expr, 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t *func, 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t *file, 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned int line, 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uintptr_t pReserved) { 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // do nothing 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) _invalid_parameter_handler old_handler_; 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int old_mode_; 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Dummy constructor and destructor to ensure that GCC doesn't complain 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that debug_disabler is an unused variable. 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MsvcDebugDisabler() {} 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~MsvcDebugDisabler() {} 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that FileInputStreams report errors correctly. 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, FileReadError) { 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MsvcDebugDisabler debug_disabler; 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // -1 = invalid file descriptor. 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileInputStream input(-1); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* buffer; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(input.Next(&buffer, &size)); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EBADF, input.GetErrno()); 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test that FileOutputStreams report errors correctly. 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, FileWriteError) { 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MsvcDebugDisabler debug_disabler; 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // -1 = invalid file descriptor. 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileOutputStream input(-1); 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* buffer; 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The first call to Next() succeeds because it doesn't have anything to 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // write yet. 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(input.Next(&buffer, &size)); 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Second call fails. 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(input.Next(&buffer, &size)); 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(EBADF, input.GetErrno()); 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Pipes are not seekable, so File{Input,Output}Stream ends up doing some 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// different things to handle them. We'll test by writing to a pipe and 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// reading back from it. 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, PipeIo) { 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int files[2]; 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kBlockSizeCount; i++) { 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < kBlockSizeCount; j++) { 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Need to create a new pipe each time because ReadStuff() expects 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to see EOF at the end. 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(pipe(files), 0); 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileOutputStream output(files[1], kBlockSizes[i]); 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStuff(&output); 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, output.GetErrno()); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(files[1]); // Send EOF. 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FileInputStream input(files[0], kBlockSizes[j]); 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadStuff(&input); 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, input.GetErrno()); 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) close(files[0]); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test using C++ iostreams. 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, IostreamIo) { 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kBlockSizeCount; i++) { 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < kBlockSizeCount; j++) { 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringstream stream; 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OstreamOutputStream output(&stream, kBlockSizes[i]); 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStuff(&output); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(stream.fail()); 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IstreamInputStream input(&stream, kBlockSizes[j]); 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadStuff(&input); 8535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(stream.eof()); 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) stringstream stream; 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OstreamOutputStream output(&stream, kBlockSizes[i]); 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStuffLarge(&output); 8635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(stream.fail()); 8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IstreamInputStream input(&stream, kBlockSizes[j]); 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadStuffLarge(&input); 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(stream.eof()); 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// To test ConcatenatingInputStream, we create several ArrayInputStreams 8775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// covering a buffer and then concatenate them. 8785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, ConcatenatingInputStream) { 8795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kBufferSize = 256; 8805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 buffer[kBufferSize]; 8815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fill the buffer. 8835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputStream output(buffer, kBufferSize); 8845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStuff(&output); 8855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now split it up into multiple streams of varying sizes. 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(68, output.ByteCount()); // Test depends on this. 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input1(buffer , 12); 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input2(buffer + 12, 7); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input3(buffer + 19, 6); 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input4(buffer + 25, 15); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input5(buffer + 40, 0); 8935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Note: We want to make sure we have a stream boundary somewhere between 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // bytes 42 and 62, which is the range that it Skip()ed by ReadStuff(). This 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // tests that a bug that existed in the original code for Skip() is fixed. 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input6(buffer + 40, 10); 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input7(buffer + 50, 18); // Total = 68 bytes. 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ZeroCopyInputStream* streams[] = 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) {&input1, &input2, &input3, &input4, &input5, &input6, &input7}; 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create the concatenating stream and read. 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConcatenatingInputStream input(streams, GOOGLE_ARRAYSIZE(streams)); 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadStuff(&input); 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// To test LimitingInputStream, we write our golden text to a buffer, then 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// create an ArrayInputStream that contains the whole buffer (not just the 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bytes written), then use a LimitingInputStream to limit it just to the 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// bytes written. 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(IoTest, LimitingInputStream) { 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const int kBufferSize = 256; 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8 buffer[kBufferSize]; 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fill the buffer. 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputStream output(buffer, kBufferSize); 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) WriteStuff(&output); 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set up input. 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream array_input(buffer, kBufferSize); 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LimitingInputStream input(&array_input, output.ByteCount()); 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReadStuff(&input); 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Check that a zero-size array doesn't confuse the code. 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ZeroSizeArray, Input) { 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayInputStream input(NULL, 0); 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* data; 9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(input.Next(&data, &size)); 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST(ZeroSizeArray, Output) { 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ArrayOutputStream output(NULL, 0); 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void* data; 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int size; 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_FALSE(output.Next(&data, &size)); 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace io 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace protobuf 9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace google 945