57 #include <sys/types.h>
83 #define pipe(fds) _pipe(fds, 4096, O_BINARY)
87 using google::protobuf::io::win32::close;
88 using google::protobuf::io::win32::mkdir;
89 using google::protobuf::io::win32::open;
94 #define O_BINARY _O_BINARY
96 #define O_BINARY 0 // If this isn't defined, the platform doesn't need it.
105 bool WriteToOutput(ZeroCopyOutputStream*
output,
const void*
data,
int size);
107 int ReadFromInput(ZeroCopyInputStream*
input,
void*
data,
int size);
116 int WriteStuff(ZeroCopyOutputStream*
output);
119 void ReadStuff(ZeroCopyInputStream*
input);
122 int WriteStuffLarge(ZeroCopyOutputStream*
output);
125 void ReadStuffLarge(ZeroCopyInputStream*
input);
129 const GzipOutputStream::Options&
options);
140 bool IoTest::WriteToOutput(ZeroCopyOutputStream*
output,
const void*
data,
149 if (!
output->Next(&out, &out_size)) {
154 if (in_size <= out_size) {
155 memcpy(out, in, in_size);
156 output->BackUp(out_size - in_size);
160 memcpy(out, in, out_size);
166 #define MAX_REPEATED_ZEROS 100
168 int IoTest::ReadFromInput(ZeroCopyInputStream*
input,
void*
data,
int size) {
175 int repeated_zeros = 0;
178 if (!
input->Next(&in, &in_size)) {
179 return size - out_size;
189 if (out_size <= in_size) {
190 memcpy(out, in, out_size);
191 if (in_size > out_size) {
192 input->BackUp(in_size - out_size);
197 memcpy(out, in, in_size);
208 std::unique_ptr<char[]>
buffer(
new char[
str.size() + 1]);
214 int IoTest::WriteStuff(ZeroCopyOutputStream*
output) {
215 WriteString(
output,
"Hello world!\n");
216 WriteString(
output,
"Some te");
217 WriteString(
output,
"xt. Blah blah.");
218 WriteString(
output,
"abcdefg");
219 WriteString(
output,
"01234567890123456789");
220 WriteString(
output,
"foobar");
224 int result =
output->ByteCount();
230 void IoTest::ReadStuff(ZeroCopyInputStream*
input) {
231 ReadString(
input,
"Hello world!\n");
232 ReadString(
input,
"Some text. ");
233 ReadString(
input,
"Blah ");
234 ReadString(
input,
"blah.");
235 ReadString(
input,
"abcdefg");
237 ReadString(
input,
"foo");
238 ReadString(
input,
"bar");
246 int IoTest::WriteStuffLarge(ZeroCopyOutputStream*
output) {
247 WriteString(
output,
"Hello world!\n");
248 WriteString(
output,
"Some te");
249 WriteString(
output,
"xt. Blah blah.");
252 WriteString(
output,
"01234567890123456789");
256 int result =
output->ByteCount();
262 void IoTest::ReadStuffLarge(ZeroCopyInputStream*
input) {
263 ReadString(
input,
"Hello world!\nSome text. ");
265 ReadString(
input,
"blah.");
269 ReadString(
input,
"yyyyyyyyyy01234567890123456789");
298 TEST_F(IoTest, TwoSessionWrite) {
301 static const char* strA =
"0123456789";
302 static const char* strB =
"WhirledPeas";
305 char* temp_buffer =
new char[40];
309 ArrayOutputStream*
output =
311 CodedOutputStream* coded_output =
new CodedOutputStream(
output);
312 coded_output->WriteVarint32(strlen(strA));
313 coded_output->WriteRaw(strA, strlen(strA));
319 coded_output =
new CodedOutputStream(
output);
320 coded_output->WriteVarint32(strlen(strB));
321 coded_output->WriteRaw(strB, strlen(strB));
326 ArrayInputStream*
input =
328 CodedInputStream* coded_input =
new CodedInputStream(
input);
332 EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
333 EXPECT_EQ(0, memcmp(temp_buffer, strA, insize));
337 EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
338 EXPECT_EQ(0, memcmp(temp_buffer, strB, insize));
345 delete[] temp_buffer;
360 GzipOutputStream::Options
options;
362 if (gzip_buffer_size != -1) {
363 options.buffer_size = gzip_buffer_size;
381 TEST_F(IoTest, GzipIoWithFlush) {
394 GzipOutputStream::Options
options;
396 if (gzip_buffer_size != -1) {
397 options.buffer_size = gzip_buffer_size;
416 TEST_F(IoTest, GzipIoContiguousFlushes) {
421 int gzip_buffer_size = block_size;
425 GzipOutputStream::Options
options;
427 if (gzip_buffer_size != -1) {
428 options.buffer_size = gzip_buffer_size;
444 TEST_F(IoTest, GzipIoReadAfterFlush) {
449 int gzip_buffer_size = block_size;
452 GzipOutputStream::Options
options;
454 if (gzip_buffer_size != -1) {
455 options.buffer_size = gzip_buffer_size;
482 GzipOutputStream::Options
options;
484 if (gzip_buffer_size != -1) {
485 options.buffer_size = gzip_buffer_size;
503 TEST_F(IoTest, ZlibIoInputAutodetect) {
509 GzipOutputStream::Options
options;
523 GzipOutputStream::Options
options;
539 const GzipOutputStream::Options&
options) {
542 StringOutputStream
output(&result);
544 WriteToOutput(&gzout,
data.data(),
data.size());
553 GzipInputStream gzin(&
input);
557 result.append(
reinterpret_cast<const char*
>(
buffer),
size);
563 TEST_F(IoTest, CompressionOptions) {
571 GzipOutputStream::Options
options;
578 options = GzipOutputStream::Options();
584 EXPECT_GT(not_compressed.size(), golden.size());
587 EXPECT_LT(zlib_compressed.size(), not_compressed.size());
594 EXPECT_TRUE(Uncompress(gzip_compressed) == golden);
595 EXPECT_TRUE(Uncompress(zlib_compressed) == golden);
598 TEST_F(IoTest, TwoSessionWriteGzip) {
601 static const char* strA =
"0123456789";
602 static const char* strB =
"QuickBrownFox";
605 char* temp_buffer =
new char[40];
609 ArrayOutputStream*
output =
611 GzipOutputStream* gzout =
new GzipOutputStream(
output);
612 CodedOutputStream* coded_output =
new CodedOutputStream(gzout);
613 int32 outlen = strlen(strA) + 1;
614 coded_output->WriteVarint32(outlen);
615 coded_output->WriteRaw(strA, outlen);
622 gzout =
new GzipOutputStream(
output);
623 coded_output =
new CodedOutputStream(gzout);
624 outlen = strlen(strB) + 1;
625 coded_output->WriteVarint32(outlen);
626 coded_output->WriteRaw(strB, outlen);
632 ArrayInputStream*
input =
634 GzipInputStream* gzin =
new GzipInputStream(
input);
635 CodedInputStream* coded_input =
new CodedInputStream(gzin);
639 EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
640 EXPECT_EQ(0, memcmp(temp_buffer, strA, insize))
641 <<
"strA=" << strA <<
" in=" << temp_buffer;
645 EXPECT_TRUE(coded_input->ReadRaw(temp_buffer, insize));
646 EXPECT_EQ(0, memcmp(temp_buffer, strB, insize))
648 <<
" in_block_size=" <<
kBlockSizes[j] <<
" pos=" << pos
649 <<
" size=" <<
size <<
" strB=" << strB <<
" in=" << temp_buffer;
657 delete[] temp_buffer;
661 TEST_F(IoTest, GzipInputByteCountAfterClosed) {
663 std::string compressed = Compress(golden, GzipOutputStream::Options());
666 ArrayInputStream arr_input(compressed.data(), compressed.size(),
668 GzipInputStream gz_input(&arr_input);
672 EXPECT_LE(gz_input.ByteCount(), golden.size());
674 EXPECT_EQ(golden.size(), gz_input.ByteCount());
678 TEST_F(IoTest, GzipInputByteCountAfterClosedConcatenatedStreams) {
679 std::string golden1 =
"abcdefghijklmnopqrstuvwxyz";
680 std::string golden2 =
"the quick brown fox jumps over the lazy dog";
681 const size_t total_size = golden1.size() + golden2.size();
682 std::string compressed = Compress(golden1, GzipOutputStream::Options()) +
683 Compress(golden2, GzipOutputStream::Options());
686 ArrayInputStream arr_input(compressed.data(), compressed.size(),
688 GzipInputStream gz_input(&arr_input);
692 EXPECT_LE(gz_input.ByteCount(), total_size);
694 EXPECT_EQ(total_size, gz_input.ByteCount());
702 TEST_F(IoTest, StringIo) {
723 open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC |
O_BINARY, 0777);
733 ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1);
747 TEST_F(IoTest, GzipFileIo) {
754 open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC |
O_BINARY, 0777);
758 GzipOutputStream gzout(&
output);
759 WriteStuffLarge(&gzout);
766 ASSERT_NE(lseek(file, 0, SEEK_SET), (off_t)-1);
770 GzipInputStream gzin(&
input);
771 ReadStuffLarge(&gzin);
784 class MsvcDebugDisabler {
786 #if defined(_MSC_VER) && _MSC_VER >= 1400
787 MsvcDebugDisabler() {
788 old_handler_ = _set_invalid_parameter_handler(MyHandler);
789 old_mode_ = _CrtSetReportMode(_CRT_ASSERT, 0);
791 ~MsvcDebugDisabler() {
792 old_handler_ = _set_invalid_parameter_handler(old_handler_);
793 old_mode_ = _CrtSetReportMode(_CRT_ASSERT, old_mode_);
796 static void MyHandler(
const wchar_t* expr,
const wchar_t*
func,
797 const wchar_t* file,
unsigned int line,
798 uintptr_t pReserved) {
802 _invalid_parameter_handler old_handler_;
807 MsvcDebugDisabler() {}
808 ~MsvcDebugDisabler() {}
813 TEST_F(IoTest, FileReadError) {
814 MsvcDebugDisabler debug_disabler;
817 FileInputStream
input(-1);
826 TEST_F(IoTest, FileWriteError) {
827 MsvcDebugDisabler debug_disabler;
830 FileOutputStream
input(-1);
875 TEST_F(IoTest, IostreamIo) {
905 ReadStuffLarge(&
input);
915 TEST_F(IoTest, ConcatenatingInputStream) {
925 ArrayInputStream input1(
buffer, 12);
926 ArrayInputStream input2(
buffer + 12, 7);
927 ArrayInputStream input3(
buffer + 19, 6);
928 ArrayInputStream input4(
buffer + 25, 15);
929 ArrayInputStream input5(
buffer + 40, 0);
933 ArrayInputStream input6(
buffer + 40, 10);
934 ArrayInputStream input7(
buffer + 50, 18);
936 ZeroCopyInputStream* streams[] = {&input1, &input2, &input3, &input4,
937 &input5, &input6, &input7};
948 TEST_F(IoTest, LimitingInputStream) {
958 LimitingInputStream
input(&array_input,
output.ByteCount());
965 TEST_F(IoTest, LimitingInputStreamByteCount) {
966 const int kHalfBufferSize = 128;
975 EXPECT_EQ(kHalfBufferSize, array_input.ByteCount());
977 LimitingInputStream
input(&array_input, kHalfBufferSize - 1);
984 TEST(ZeroSizeArray, Input) {
991 TEST(ZeroSizeArray, Output) {