aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/google/protobuf/io/zero_copy_stream_impl.cc5
-rw-r--r--src/google/protobuf/io/zero_copy_stream_unittest.cc92
2 files changed, 77 insertions, 20 deletions
diff --git a/src/google/protobuf/io/zero_copy_stream_impl.cc b/src/google/protobuf/io/zero_copy_stream_impl.cc
index b3e6bf2f..10071054 100644
--- a/src/google/protobuf/io/zero_copy_stream_impl.cc
+++ b/src/google/protobuf/io/zero_copy_stream_impl.cc
@@ -218,7 +218,8 @@ int CopyingInputStream::Skip(int count) {
char junk[4096];
int skipped = 0;
while (skipped < count) {
- int bytes = Read(junk, min(count, implicit_cast<int>(sizeof(junk))));
+ int bytes = Read(junk, min(count - skipped,
+ implicit_cast<int>(sizeof(junk))));
if (bytes <= 0) {
// EOF or read error.
return skipped;
@@ -757,7 +758,7 @@ LimitingInputStream::~LimitingInputStream() {
}
bool LimitingInputStream::Next(const void** data, int* size) {
- if (limit_ < 0) return false;
+ if (limit_ <= 0) return false;
if (!input_->Next(data, size)) return false;
limit_ -= *size;
diff --git a/src/google/protobuf/io/zero_copy_stream_unittest.cc b/src/google/protobuf/io/zero_copy_stream_unittest.cc
index 8c115500..ec92127d 100644
--- a/src/google/protobuf/io/zero_copy_stream_unittest.cc
+++ b/src/google/protobuf/io/zero_copy_stream_unittest.cc
@@ -90,10 +90,10 @@ class IoTest : public testing::Test {
// Helper to read a fixed-length array of data from an input stream.
int ReadFromInput(ZeroCopyInputStream* input, void* data, int size);
// Write a string to the output stream.
- void WriteString(ZeroCopyOutputStream* output, const char* str);
+ void WriteString(ZeroCopyOutputStream* output, const string& str);
// Read a number of bytes equal to the size of the given string and checks
// that it matches the string.
- void ReadString(ZeroCopyInputStream* input, const char* str);
+ void ReadString(ZeroCopyInputStream* input, const string& str);
// Writes some text to the output stream in a particular order. Returns
// the number of bytes written, incase the caller needs that to set up an
// input stream.
@@ -102,6 +102,12 @@ class IoTest : public testing::Test {
// WriteStuff() writes.
void ReadStuff(ZeroCopyInputStream* input);
+ // Similar to WriteStuff, but performs more sophisticated testing.
+ int WriteStuffLarge(ZeroCopyOutputStream* output);
+ // Reads and tests a stream that should have been written to
+ // via WriteStuffLarge().
+ void ReadStuffLarge(ZeroCopyInputStream* input);
+
static const int kBlockSizes[];
static const int kBlockSizeCount;
};
@@ -121,6 +127,7 @@ bool IoTest::WriteToOutput(ZeroCopyOutputStream* output,
if (!output->Next(&out, &out_size)) {
return false;
}
+ EXPECT_GT(out_size, 0);
if (in_size <= out_size) {
memcpy(out, in, in_size);
@@ -145,6 +152,7 @@ int IoTest::ReadFromInput(ZeroCopyInputStream* input, void* data, int size) {
if (!input->Next(&in, &in_size)) {
return size - out_size;
}
+ EXPECT_GT(in_size, 0);
if (out_size <= in_size) {
memcpy(out, in, out_size);
@@ -158,16 +166,15 @@ int IoTest::ReadFromInput(ZeroCopyInputStream* input, void* data, int size) {
}
}
-void IoTest::WriteString(ZeroCopyOutputStream* output, const char* str) {
- EXPECT_TRUE(WriteToOutput(output, str, strlen(str)));
+void IoTest::WriteString(ZeroCopyOutputStream* output, const string& str) {
+ EXPECT_TRUE(WriteToOutput(output, str.c_str(), str.size()));
}
-void IoTest::ReadString(ZeroCopyInputStream* input, const char* str) {
- int length = strlen(str);
- scoped_array<char> buffer(new char[length + 1]);
- buffer[length] = '\0';
- EXPECT_EQ(ReadFromInput(input, buffer.get(), length), length);
- EXPECT_STREQ(str, buffer.get());
+void IoTest::ReadString(ZeroCopyInputStream* input, const string& str) {
+ scoped_array<char> buffer(new char[str.size() + 1]);
+ buffer[str.size()] = '\0';
+ EXPECT_EQ(ReadFromInput(input, buffer.get(), str.size()), str.size());
+ EXPECT_STREQ(str.c_str(), buffer.get());
}
int IoTest::WriteStuff(ZeroCopyOutputStream* output) {
@@ -202,6 +209,37 @@ void IoTest::ReadStuff(ZeroCopyInputStream* input) {
EXPECT_EQ(ReadFromInput(input, &byte, 1), 0);
}
+int IoTest::WriteStuffLarge(ZeroCopyOutputStream* output) {
+ WriteString(output, "Hello world!\n");
+ WriteString(output, "Some te");
+ WriteString(output, "xt. Blah blah.");
+ WriteString(output, string(100000, 'x')); // A very long string
+ WriteString(output, string(100000, 'y')); // A very long string
+ WriteString(output, "01234567890123456789");
+
+ EXPECT_EQ(output->ByteCount(), 200055);
+
+ int result = output->ByteCount();
+ return result;
+}
+
+// Reads text from an input stream and expects it to match what WriteStuff()
+// writes.
+void IoTest::ReadStuffLarge(ZeroCopyInputStream* input) {
+ ReadString(input, "Hello world!\nSome text. ");
+ EXPECT_TRUE(input->Skip(5));
+ ReadString(input, "blah.");
+ EXPECT_TRUE(input->Skip(100000 - 10));
+ ReadString(input, string(10, 'x') + string(100000 - 20000, 'y'));
+ EXPECT_TRUE(input->Skip(20000 - 10));
+ ReadString(input, "yyyyyyyyyy01234567890123456789");
+
+ EXPECT_EQ(input->ByteCount(), 200055);
+
+ uint8 byte;
+ EXPECT_EQ(ReadFromInput(input, &byte, 1), 0);
+}
+
// ===================================================================
TEST_F(IoTest, ArrayIo) {
@@ -369,18 +407,36 @@ TEST_F(IoTest, PipeIo) {
TEST_F(IoTest, IostreamIo) {
for (int i = 0; i < kBlockSizeCount; i++) {
for (int j = 0; j < kBlockSizeCount; j++) {
- stringstream stream;
-
{
- OstreamOutputStream output(&stream, kBlockSizes[i]);
- WriteStuff(&output);
- EXPECT_FALSE(stream.fail());
+ stringstream stream;
+
+ {
+ OstreamOutputStream output(&stream, kBlockSizes[i]);
+ WriteStuff(&output);
+ EXPECT_FALSE(stream.fail());
+ }
+
+ {
+ IstreamInputStream input(&stream, kBlockSizes[j]);
+ ReadStuff(&input);
+ EXPECT_TRUE(stream.eof());
+ }
}
{
- IstreamInputStream input(&stream, kBlockSizes[j]);
- ReadStuff(&input);
- EXPECT_TRUE(stream.eof());
+ stringstream stream;
+
+ {
+ OstreamOutputStream output(&stream, kBlockSizes[i]);
+ WriteStuffLarge(&output);
+ EXPECT_FALSE(stream.fail());
+ }
+
+ {
+ IstreamInputStream input(&stream, kBlockSizes[j]);
+ ReadStuffLarge(&input);
+ EXPECT_TRUE(stream.eof());
+ }
}
}
}