34 #include <gtest/gtest.h>
49 using std::stringstream;
60 static string test_word =
"QuotesFromOscarWilde";
61 static string test_line =
"It is always a silly thing to give advice, but to give good advice is fatal.";
62 static string test_long =
63 "One can survive everything, nowadays, except death, and live down everything except a good reputation.\n"
64 "One should always play fairly when one has the winning cards.\n"
65 "Patriotism is the virtue of the vicious.\n"
66 "Selfishness is not living as one wishes to live, it is asking others to live as one wishes to live.";
68 TEST(iostream_test, example_decorator_stack)
74 std::stringstream sstr;
78 rws << test_line << endl;
79 rws << test_long << endl;
80 sstr << test_line << endl;
81 sstr << test_long << endl;
83 ASSERT_EQ(rwbuf.
str(), sstr.str());
85 ASSERT_EQ(rwcount.write_count(), sstr.str().size());
86 ASSERT_EQ(rwcount.read_count(), 0);
93 ASSERT_TRUE(rws >> tests);
94 ASSERT_EQ(reads, tests);
97 ASSERT_FALSE(rws >> tests);
99 ASSERT_EQ(rwcount.read_count(), sstr.str().size());
101 ASSERT_EQ(rwbuf.
str().size(), 0);
104 struct iostreamTest :
public testing::Test
106 std::vector<string> all;
109 all.push_back(test_word);
110 all.push_back(test_line);
111 all.push_back(test_long);
113 virtual ~iostreamTest() {}
115 void readwords_test(
const string s,
int recvbuf_size=10)
117 stringstream sstr(s);
120 ins.recvbuf_size(recvbuf_size);
122 ASSERT_EQ(ins.recvbuf_size(), recvbuf_size);
124 cout <<
"readwords_test: " << s.substr(0,10) <<
"... size=" << s.size() <<
" recvbuf_size= " << ins.recvbuf_size() << endl;
127 while (sstr >> reads)
129 ASSERT_TRUE(ins >> tests);
130 ASSERT_EQ(reads, tests);
133 void readlines_test(
const string s,
int recvbuf_size=10)
135 stringstream sstr(s);
138 ins.recvbuf_size(recvbuf_size);
140 ASSERT_EQ(ins.recvbuf_size(), recvbuf_size);
142 cout <<
"readlines_test: " << s.substr(0,10) <<
"... size=" << s.size() <<
" recvbuf_size= " << ins.recvbuf_size() << endl;
145 while (std::getline(sstr, reads))
147 ASSERT_TRUE(std::getline(ins, tests));
148 ASSERT_EQ(reads, tests);
151 void writewords_test(
const string s,
int sendbuf_size=10)
153 stringstream sstr(s);
156 ous.sendbuf_size(sendbuf_size);
158 ASSERT_EQ(ous.sendbuf_size(), sendbuf_size);
160 cout <<
"writewords_test: " << s.substr(0,10) <<
"... size=" << s.size() <<
" sendbuf_size= " << ous.sendbuf_size() << endl;
163 stringstream writess;
164 while (sstr >> reads)
167 ASSERT_TRUE(ous << reads);
171 ASSERT_EQ(writess.str(), rw.
str());
173 void writelines_test(
const string s,
int sendbuf_size=10)
175 stringstream sstr(s);
178 ous.sendbuf_size(sendbuf_size);
180 ASSERT_EQ(ous.sendbuf_size(), sendbuf_size);
182 cout <<
"writelines_test: " << s.substr(0,10) <<
"... size=" << s.size() <<
" sendbuf_size= " << ous.sendbuf_size() << endl;
185 stringstream writess;
186 while (std::getline(sstr, reads))
188 writess << reads << endl;
189 ASSERT_TRUE(ous << reads << endl);
193 ASSERT_EQ(writess.str(), rw.
str());
195 void readchunks_test(
const string s,
int rbuf1=10,
int rsz1=1024,
int rbuf2=10)
200 ins.recvbuf_size(rbuf1);
201 ASSERT_EQ(ins.recvbuf_size(), rbuf1);
203 int toread = s.size();
204 cout <<
"readchunks_test1: " << s.substr(0,10) <<
"... read=" << rsz1 <<
" toread=" << toread
205 <<
" recvbuf_size= " << ins.recvbuf_size() << endl;
207 ins.read(bin1, rsz1);
208 auto lastread = ins.gcount();
209 ASSERT_EQ(lastread, std::min(rsz1, toread));
210 ASSERT_EQ(memcmp(s.data(), bin1, lastread), 0);
214 ASSERT_EQ((ins.rdstate()&std::ios_base::eofbit), std::ios_base::eofbit);
219 ins.recvbuf_size(rbuf2);
220 ASSERT_EQ(ins.recvbuf_size(), rbuf2);
222 cout <<
"readchunks_test2: " << s.substr(0,10) <<
"... read=" << toread <<
" toread=" << toread
223 <<
" recvbuf_size= " << ins.recvbuf_size() << endl;
225 ins.read(bin2, toread);
226 auto lastread2 = ins.gcount();
227 ASSERT_EQ(lastread2, toread);
228 ASSERT_EQ(memcmp(s.data()+lastread, bin2, lastread2), 0);
229 ASSERT_NE((ins.rdstate()&std::ios_base::eofbit), std::ios_base::eofbit);
232 void writechunks_test(
const string s,
int wbuf1=10,
int wsz1=1024,
int wbuf2=10)
237 ous.sendbuf_size(wbuf1);
238 ASSERT_EQ(ous.sendbuf_size(), wbuf1);
240 int towrite = s.size();
241 wsz1 = std::min(wsz1, towrite);
242 cout <<
"writechunks_test1: " << s.substr(0,10) <<
"... write=" << wsz1 <<
" towrite=" << towrite
243 <<
" sendbuf_size= " << ous.sendbuf_size() << endl;
244 ASSERT_TRUE(ous.write(s.data(), wsz1));
250 ous.sendbuf_size(wbuf2);
251 ASSERT_EQ(ous.sendbuf_size(), wbuf2);
253 cout <<
"writechunks_test2: " << s.substr(0,10) <<
"... write=" << towrite <<
" towrite=" << towrite
254 <<
" sendbuf_size= " << ous.sendbuf_size() << endl;
256 ASSERT_TRUE(ous.write(s.data()+wsz1, towrite));
259 ASSERT_EQ(s, rw.
str());
263 TEST_F(iostreamTest, read)
275 TEST_F(iostreamTest, write)
287 TEST_F(iostreamTest, readchunks)
292 readchunks_test(s, 10, 5, 20);
293 readchunks_test(s, 10, 8, 5);
297 TEST_F(iostreamTest, writechunks)
302 writechunks_test(s, 10, 5, 20);
303 writechunks_test(s, 10, 8, 5);
307 TEST(iostream_test, write_read)
309 string val(
"this\nis\na\ntest\n");
313 ASSERT_TRUE(ios.write(val.data(), val.size()));
315 char buf[
sizeof(val)];
316 ASSERT_TRUE(ios.read(buf, val.size()));
317 ASSERT_EQ(ios.gcount(), val.size());
318 ASSERT_EQ(memcmp(buf, val.data(), val.size()), 0);
319 ASSERT_FALSE(ios.read(buf, val.size()));
322 TEST(iostream_test, stream_write_read)
324 string val(
"this\nis\na\ntest\n");
328 ASSERT_TRUE(ios << val);
331 ASSERT_TRUE(ios >> s);
332 ASSERT_EQ(s,
"this");
333 ASSERT_TRUE(ios >> s);
335 ASSERT_TRUE(ios >> s);
337 ASSERT_TRUE(ios >> s);
338 ASSERT_EQ(s,
"test");
340 string printstate(
int state)
344 if (state == 0) st <<
"good ";
345 if ((state&std::ios_base::badbit)==std::ios_base::badbit) st <<
"bad ";
346 if ((state&std::ios_base::failbit)==std::ios_base::failbit) st <<
"fail ";
347 if ((state&std::ios_base::eofbit)==std::ios_base::eofbit) st <<
"eof ";
351 TEST(iostream_test, write_buffer_states_test)
356 string s1 =
"This is a test", s2 =
" of the stream bit stuff.";
358 cout <<
"***OutStream test" << endl;
359 cout <<
"Before " << printstate(st.rdstate()) << endl;
360 ASSERT_EQ(st.rdstate(), 0);
362 cout <<
"write '"<<s1<<
"' string: '" << rw.
str() <<
"' " << printstate(st.rdstate()) << endl;
363 ASSERT_EQ(st.rdstate(), 0);
364 ASSERT_EQ(rw.
str(), s1.substr(0, 10));
365 st.setstate(std::ios_base::eofbit);
366 cout <<
"seteof string: '" << rw.
str() <<
"' " << printstate(st.rdstate()) << endl;
367 ASSERT_TRUE(st.eof());
369 cout <<
"write '"<<s2<<
"' string: '" << rw.
str() <<
"' " << printstate(st.rdstate()) << endl;
370 ASSERT_TRUE(st.eof());
371 ASSERT_EQ(rw.
str(), s1.substr(0, 10));
373 cout <<
"clear string: '" << rw.
str() <<
"' " << printstate(st.rdstate()) << endl;
375 cout <<
"write '"<<s2<<
"' string: '" << rw.
str() <<
"' " << printstate(st.rdstate()) << endl;
377 cout <<
"flush string: '" << rw.
str() <<
"' " << printstate(st.rdstate()) << endl;
378 ASSERT_EQ(st.rdstate(), 0);
379 ASSERT_EQ(rw.
str(), s1+s2);
382 TEST(iostream_test, move_assign)
391 cout <<
"got: " << s << endl;
392 ASSERT_EQ(s,
"test");
395 TEST(iostream_test, move_moveconstruct)
404 cout <<
"got: " << s << endl;
405 ASSERT_EQ(s,
"test");
408 TEST(instream_test, move_assign)
415 cout <<
"got: " << s << endl;
416 ASSERT_EQ(s,
"test");
419 TEST(instream_test, move_construct)
426 cout <<
"got: " << s << endl;
427 ASSERT_EQ(s,
"test");
430 TEST(outstream_test, move_assign)
437 cout <<
"got: " << rw.
str() << endl;
438 ASSERT_EQ(rw.
str(),
"test");
441 TEST(outstream_test, move_construct)
448 cout <<
"got: " << rw.
str() << endl;
449 ASSERT_EQ(rw.
str(),
"test");
452 TEST(fail_test, outstream_except)
456 struct ExReader :
public Reader
459 ExReader() : fail(true) {}
460 size_t read(
void* loc,
size_t len)
462 if (fail)
throw std::runtime_error(
"test");
466 struct ExWriter :
public Writer
469 ExWriter() : fail(true) {}
470 size_t write(
const void*,
size_t len)
472 if (fail)
throw std::runtime_error(
"test");
483 is.read((
char*)line.data(), 4);
485 ASSERT_TRUE(is.fail());
486 ASSERT_EQ(is.rdstate() & ios::badbit, ios::badbit);
487 ASSERT_EQ(is.recv_fail(),
"test");
490 ASSERT_EQ(is.recv_fail(),
"");
492 is.read((
char*)line.data(), 4);
494 ASSERT_FALSE(is.fail());
495 ASSERT_EQ(is.recv_fail(),
"");
500 ASSERT_TRUE(os.fail());
501 ASSERT_EQ(os.rdstate() & ios::badbit, ios::badbit);
502 ASSERT_EQ(os.send_fail(),
"test");
505 ASSERT_EQ(os.send_fail(),
"");
510 ASSERT_FALSE(os.fail());
511 ASSERT_EQ(os.send_fail(),
"");
517 io.read((
char*)line.data(), 4);
522 ASSERT_TRUE(io.fail());
523 ASSERT_EQ(io.rdstate() & ios::badbit, ios::badbit);
524 ASSERT_EQ(io.send_fail(),
"");
525 ASSERT_EQ(io.recv_fail(),
"test");
532 io.read((
char*)line.data(), 4);
534 ASSERT_TRUE(io.fail());
535 ASSERT_EQ(io.send_fail(),
"test");
536 ASSERT_EQ(io.recv_fail(),
"");
545 io.read((
char*)line.data(), 4);
547 ASSERT_FALSE(io.fail());
548 ASSERT_EQ(io.send_fail(),
"");
549 ASSERT_EQ(io.recv_fail(),
"");
552 TEST(shared_ptr_test, shared_io)
557 for (
char ch : test_long) io.put(ch);
560 ASSERT_EQ(test_long, buf->str());
563 for (
char ch; io.get(ch);) got.push_back(ch);
565 ASSERT_EQ(test_long, got);
567 cout <<
"io buf references: " << buf.use_count() << endl;
568 ASSERT_EQ(buf.use_count(), 3);
571 TEST(shared_ptr_test, shared_in)
576 buf->set(test_long.data(), test_long.size());
579 for (
char ch; io.get(ch);) got.push_back(ch);
581 ASSERT_EQ(test_long, got);
583 cout <<
"in buf references: " << buf.use_count() << endl;
584 ASSERT_EQ(buf.use_count(), 2);
587 TEST(shared_ptr_test, shared_out)
592 for (
char ch : test_long) io.put(ch);
595 ASSERT_EQ(test_long, buf->str());
597 cout <<
"out buf references: " << buf.use_count() << endl;
598 ASSERT_EQ(buf.use_count(), 2);
601 TEST(basic_stream_test, sync_n_flush)
607 for (
unsigned i = 0; i < 7; i++) io.put(test_long[i]);
609 cout <<
"partial put buf size: " << buf.size() << endl;
610 cout <<
"partial put idx: " << buf.idx() << endl;
617 cout <<
"partial write buf size: " << buf.size() << endl;
618 cout <<
"partial write idx: " << buf.idx() << endl;
623 for (
unsigned i = 7; i < test_long.size(); i++) io.put(test_long[i]);
625 cout <<
"full write buf size: " << buf.size() << endl;
626 cout <<
"full write idx: " << buf.idx() << endl;
633 for (
unsigned i = 0; i < 7 && io.get(ch); i++) got.push_back(ch);
634 cout <<
"partial read got: " << got << endl;
635 cout <<
"partial read buf size: " << buf.size() << endl;
636 cout <<
"partial read idx: " << buf.idx() << endl;
640 for (
unsigned i = 0; i < 2 && io.get(ch); i++) got.push_back(ch);
642 cout <<
"sync & read 2 more got: " << got << endl;
643 cout <<
"sync & read 2 more buf size: " << buf.size() << endl;
644 cout <<
"sync & read 2 more idx: " << buf.idx() << endl;
646 while (io.get(ch)) got.push_back(ch);
648 cout <<
"full read got: " << got << endl;
649 cout <<
"full read buf size: " << buf.size() << endl;
650 cout <<
"full read idx: " << buf.idx() << endl;
Input stream wrapper for reader.
Input/output stream wrapper for reader/writer.
Output stream wrapper for writer.
Adds byte count to a read/write stream.
Loopback read/write stream buffer.
std::string str()
Read as a string.
Base input/output stream classes.
Loopback read/write buffer.
Interface class for objects which can be read.
virtual size_t read(void *, size_t)=0
Read interface.
Interface class for objects which can be written.
virtual size_t write(const void *, size_t)=0
Write interface.
TEST(inet_example, client_server_stream_test)
[Inet client server]