1//
2// MemoryStreamTest.cpp
3//
4// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
5// and Contributors.
6//
7// SPDX-License-Identifier: BSL-1.0
8//
9
10
11#include "MemoryStreamTest.h"
12#include "Poco/CppUnit/TestCaller.h"
13#include "Poco/CppUnit/TestSuite.h"
14#include "Poco/Buffer.h"
15#include "Poco/MemoryStream.h"
16#include <sstream>
17
18
19using Poco::MemoryInputStream;
20using Poco::MemoryOutputStream;
21
22
23MemoryStreamTest::MemoryStreamTest(const std::string& rName): CppUnit::TestCase(rName)
24{
25}
26
27
28MemoryStreamTest::~MemoryStreamTest()
29{
30}
31
32
33void MemoryStreamTest::testInput()
34{
35 const char* data = "This is a test";
36 MemoryInputStream istr1(data, 14);
37
38 int c = istr1.get();
39 assertTrue (c == 'T');
40 c = istr1.get();
41 assertTrue (c == 'h');
42
43 std::string str;
44 istr1 >> str;
45 assertTrue (str == "is");
46
47 char buffer[32];
48 istr1.read(buffer, sizeof(buffer));
49 assertTrue (istr1.gcount() == 10);
50 buffer[istr1.gcount()] = 0;
51 assertTrue (std::string(" is a test") == buffer);
52
53 const char* data2 = "123";
54 MemoryInputStream istr2(data2, 3);
55 c = istr2.get();
56 assertTrue (c == '1');
57 assertTrue (istr2.good());
58 c = istr2.get();
59 assertTrue (c == '2');
60 istr2.unget();
61 c = istr2.get();
62 assertTrue (c == '2');
63 assertTrue (istr2.good());
64 c = istr2.get();
65 assertTrue (c == '3');
66 assertTrue (istr2.good());
67 c = istr2.get();
68 assertTrue (c == -1);
69 assertTrue (istr2.eof());
70}
71
72
73void MemoryStreamTest::testOutput()
74{
75 char output[64];
76 MemoryOutputStream ostr1(output, 64);
77 ostr1 << "This is a test " << 42 << std::ends;
78 assertTrue (ostr1.charsWritten() == 18);
79 assertTrue (std::string("This is a test 42") == output);
80
81 char output2[4];
82 MemoryOutputStream ostr2(output2, 4);
83 ostr2 << "test";
84 assertTrue (ostr2.good());
85 ostr2 << 'x';
86 assertTrue (ostr2.fail());
87}
88
89void MemoryStreamTest::testTell()
90{
91 Poco::Buffer<char> buffer(1024);
92 Poco::MemoryOutputStream ostr(buffer.begin(), buffer.size());
93 ostr << 'H' << 'e' << 'l' << 'l' << 'o' << '\0';
94 std::streamoff np = ostr.tellp();
95 assertTrue (np == 6);
96
97 Poco::MemoryInputStream istr(buffer.begin(), buffer.size());
98
99 char c;
100 istr >> c;
101 assertTrue (c == 'H');
102
103 istr >> c;
104 assertTrue (c == 'e');
105
106 istr >> c;
107 assertTrue (c == 'l');
108
109 std::streamoff ng = istr.tellg();
110 assertTrue (ng == 3);
111}
112
113
114void MemoryStreamTest::testInputSeek()
115{
116 Poco::Buffer<char> buffer(9);
117 Poco::MemoryOutputStream ostr(buffer.begin(), buffer.size());
118 ostr << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9';
119
120 Poco::MemoryInputStream istr(buffer.begin(), buffer.size());
121 char c;
122
123 istr >> c;
124 assertTrue (c == '1');
125
126 istr.seekg(3, std::ios_base::beg); // 3 from beginning
127 istr >> c; // now that makes 4
128 assertTrue (4 == istr.tellg());
129 assertTrue (c == '4');
130
131 istr.seekg(2, std::ios_base::cur); // now that makes 6
132 istr >> c; // now that makes 7
133 assertTrue (7 == istr.tellg());
134 assertTrue (c == '7');
135
136 istr.seekg(-7, std::ios_base::end); // so that puts us at 9-7=2
137 istr >> c; // now 3
138 assertTrue (3 == istr.tellg());
139 assertTrue (c == '3');
140
141
142 istr.seekg(9, std::ios_base::beg);
143 assertTrue (istr.good());
144 assertTrue (9 == istr.tellg());
145
146 {
147 Poco::MemoryInputStream istr2(buffer.begin(), buffer.size());
148 istr2.seekg(10, std::ios_base::beg);
149#ifdef __APPLE__
150 // workaround for clang libstdc++, which does not
151 // set failbit if seek returns -1
152 assertTrue (istr2.fail() || istr2.tellg() == std::streampos(0));
153#else
154 assertTrue (istr2.fail());
155#endif
156 }
157
158
159 istr.seekg(-9, std::ios_base::end);
160 assertTrue (istr.good());
161 assertTrue (0 == istr.tellg());
162
163 {
164 Poco::MemoryInputStream istr2(buffer.begin(), buffer.size());
165 istr2.seekg(-10, std::ios_base::end);
166#ifdef __APPLE__
167 // workaround for clang libstdc++, which does not
168 // set failbit if seek returns -1
169 assertTrue (istr2.fail() || istr2.tellg() == std::streampos(0));
170#else
171 assertTrue (istr2.fail());
172#endif
173 }
174
175
176 istr.seekg(0, std::ios_base::beg);
177 assertTrue (istr.good());
178 assertTrue (0 == istr.tellg());
179
180 {
181 Poco::MemoryInputStream istr2(buffer.begin(), buffer.size());
182 istr2.seekg(-1, std::ios_base::beg);
183#ifdef __APPLE__
184 // workaround for clang libstdc++, which does not
185 // set failbit if seek returns -1
186 assertTrue (istr2.fail() || istr2.tellg() == std::streampos(0));
187#else
188 assertTrue (istr2.fail());
189#endif
190 }
191
192
193 istr.seekg(0, std::ios_base::end);
194 assertTrue (istr.good());
195 assertTrue (9 == istr.tellg());
196
197 {
198 Poco::MemoryInputStream istr2(buffer.begin(), buffer.size());
199 istr2.seekg(1, std::ios_base::end);
200#ifdef __APPLE__
201 // workaround for clang libstdc++, which does not
202 // set failbit if seek returns -1
203 assertTrue (istr2.fail() || istr2.tellg() == std::streampos(0));
204#else
205 assertTrue (istr2.fail());
206#endif
207 }
208
209
210 istr.seekg(3, std::ios_base::beg);
211 assertTrue (istr.good());
212 assertTrue (3 == istr.tellg());
213 istr.seekg(6, std::ios_base::cur);
214 assertTrue (istr.good());
215 assertTrue (9 == istr.tellg());
216
217 {
218 Poco::MemoryInputStream istr2(buffer.begin(), buffer.size());
219 istr2.seekg(4, std::ios_base::beg);
220 istr2.seekg(6, std::ios_base::cur);
221#ifdef __APPLE__
222 // workaround for clang libstdc++, which does not
223 // set failbit if seek returns -1
224 assertTrue (istr2.fail() || istr2.tellg() == std::streampos(4));
225#else
226 assertTrue (istr2.fail());
227#endif
228 }
229
230
231 istr.seekg(-4, std::ios_base::end);
232 assertTrue (istr.good());
233 assertTrue (5 == istr.tellg());
234 istr.seekg(4, std::ios_base::cur);
235 assertTrue (istr.good());
236 assertTrue (9 == istr.tellg());
237
238 {
239 Poco::MemoryInputStream istr2(buffer.begin(), buffer.size());
240 istr2.seekg(-4, std::ios_base::end);
241 istr2.seekg(5, std::ios_base::cur);
242#ifdef __APPLE__
243 // workaround for clang libstdc++, which does not
244 // set failbit if seek returns -1
245 assertTrue (istr2.fail() || istr2.tellg() == std::streampos(5));
246#else
247 assertTrue (istr2.fail());
248#endif
249 }
250
251
252 istr.seekg(4, std::ios_base::beg);
253 assertTrue (istr.good());
254 assertTrue (4 == istr.tellg());
255 istr.seekg(-4, std::ios_base::cur);
256 assertTrue (istr.good());
257 assertTrue (0 == istr.tellg());
258
259 {
260 Poco::MemoryInputStream istr2(buffer.begin(), buffer.size());
261 istr2.seekg(4, std::ios_base::beg);
262 istr2.seekg(-5, std::ios_base::cur);
263#ifdef __APPLE__
264 // workaround for clang libstdc++, which does not
265 // set failbit if seek returns -1
266 assertTrue (istr2.fail() || istr2.tellg() == std::streampos(4));
267#else
268 assertTrue (istr2.fail());
269#endif
270 }
271}
272
273
274void MemoryStreamTest::testInputSeekVsStringStream()
275{
276 Poco::Buffer<char> buffer(9);
277 Poco::MemoryOutputStream ostr(buffer.begin(), buffer.size());
278 ostr << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9';
279
280 std::stringstream sss;
281 sss << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9';
282
283 Poco::MemoryInputStream mis(buffer.begin(), buffer.size());
284
285 char x, y;
286
287 sss >> x;
288 mis >> y;
289 assertTrue (x == y);
290
291 sss.seekg(3, std::ios_base::beg);
292 mis.seekg(3, std::ios_base::beg);
293 sss >> x;
294 mis >> y;
295 assertTrue (x == y);
296 assertTrue (sss.tellg() == mis.tellg());
297
298 sss.seekg(2, std::ios_base::cur);
299 mis.seekg(2, std::ios_base::cur);
300 sss >> x;
301 mis >> y;
302 assertTrue (x == y);
303 assertTrue (sss.tellg() == mis.tellg());
304
305 sss.seekg(-7, std::ios_base::end);
306 mis.seekg(-7, std::ios_base::end);
307 sss >> x;
308 mis >> y;
309 assertTrue (x == y);
310 assertTrue (sss.tellg() == mis.tellg());
311}
312
313
314void MemoryStreamTest::testOutputSeek()
315{
316 Poco::Buffer<char> buffer(9);
317 Poco::MemoryOutputStream ostr(buffer.begin(), buffer.size());
318 ostr << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9';
319
320 ostr.seekp(4, std::ios_base::beg); // 4 from beginning
321 ostr << 'a'; // and that makes 5 (zero index 4)
322 assertTrue (5 == ostr.tellp());
323 assertTrue (buffer[4] == 'a');
324
325 ostr.seekp(2, std::ios_base::cur); // and this makes 7
326 ostr << 'b'; // and this makes 8 (zero index 7)
327 assertTrue (8 == ostr.tellp());
328 assertTrue (buffer[7] == 'b');
329
330 ostr.seekp(-3, std::ios_base::end); // 9-3=6 from the beginning
331 ostr << 'c'; // and this makes 7 (zero index 6)
332 assertTrue (7 == ostr.tellp());
333 assertTrue (buffer[6] == 'c');
334
335
336 ostr.seekp(9, std::ios_base::beg);
337 assertTrue (ostr.good());
338 assertTrue (9 == ostr.tellp());
339
340 {
341 Poco::MemoryOutputStream ostr2(buffer.begin(), buffer.size());
342 ostr2.seekp(10, std::ios_base::beg);
343 assertTrue (ostr2.fail());
344 }
345
346
347 ostr.seekp(-9, std::ios_base::end);
348 assertTrue (ostr.good());
349 assertTrue (0 == ostr.tellp());
350
351 {
352 Poco::MemoryOutputStream ostr2(buffer.begin(), buffer.size());
353 ostr2.seekp(-10, std::ios_base::end);
354 assertTrue (ostr2.fail());
355 }
356
357
358 ostr.seekp(0, std::ios_base::beg);
359 assertTrue (ostr.good());
360 assertTrue (0 == ostr.tellp());
361
362 {
363 Poco::MemoryOutputStream ostr2(buffer.begin(), buffer.size());
364 ostr2.seekp(-1, std::ios_base::beg);
365 assertTrue (ostr2.fail());
366 }
367
368
369 ostr.seekp(0, std::ios_base::end);
370 assertTrue (ostr.good());
371 assertTrue (9 == ostr.tellp());
372
373 {
374 Poco::MemoryOutputStream ostr2(buffer.begin(), buffer.size());
375 ostr2.seekp(1, std::ios_base::end);
376 assertTrue (ostr2.fail());
377 }
378
379
380 ostr.seekp(3, std::ios_base::beg);
381 assertTrue (ostr.good());
382 assertTrue (3 == ostr.tellp());
383 ostr.seekp(6, std::ios_base::cur);
384 assertTrue (ostr.good());
385 assertTrue (9 == ostr.tellp());
386
387 {
388 Poco::MemoryOutputStream ostr2(buffer.begin(), buffer.size());
389 ostr2.seekp(4, std::ios_base::beg);
390 ostr2.seekp(6, std::ios_base::cur);
391 assertTrue (ostr2.fail());
392 }
393
394
395 ostr.seekp(-4, std::ios_base::end);
396 assertTrue (ostr.good());
397 assertTrue (5 == ostr.tellp());
398 ostr.seekp(4, std::ios_base::cur);
399 assertTrue (ostr.good());
400 assertTrue (9 == ostr.tellp());
401
402 {
403 Poco::MemoryOutputStream ostr2(buffer.begin(), buffer.size());
404 ostr2.seekp(-4, std::ios_base::end);
405 ostr2.seekp(5, std::ios_base::cur);
406 assertTrue (ostr2.fail());
407 }
408
409
410 ostr.seekp(4, std::ios_base::beg);
411 assertTrue (ostr.good());
412 assertTrue (4 == ostr.tellp());
413 ostr.seekp(-4, std::ios_base::cur);
414 assertTrue (ostr.good());
415 assertTrue (0 == ostr.tellp());
416
417 {
418 Poco::MemoryOutputStream ostr2(buffer.begin(), buffer.size());
419 ostr2.seekp(4, std::ios_base::beg);
420 ostr2.seekp(-5, std::ios_base::cur);
421 assertTrue (ostr2.fail());
422 }
423}
424
425
426void MemoryStreamTest::testOutputSeekVsStringStream()
427{
428 Poco::Buffer<char> buffer(9);
429 Poco::MemoryOutputStream mos(buffer.begin(), buffer.size());
430 mos << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9';
431
432 std::ostringstream oss;
433 oss << '1' << '2' << '3' << '4' << '5' << '6' << '7' << '8' << '9';
434
435 mos.seekp(4, std::ios_base::beg);
436 oss.seekp(4, std::ios_base::beg);
437 mos << 'a';
438 oss << 'a';
439 assertTrue (oss.str()[4] == 'a');
440 assertTrue (buffer[4] == oss.str()[4]);
441 assertTrue (oss.tellp() == mos.tellp());
442
443 mos.seekp(2, std::ios_base::cur);
444 oss.seekp(2, std::ios_base::cur);
445 mos << 'b';
446 oss << 'b';
447 assertTrue (oss.str()[7] == 'b');
448 assertTrue (buffer[7] == oss.str()[7]);
449 assertTrue (oss.tellp() == mos.tellp());
450
451 mos.seekp(-3, std::ios_base::end);
452 oss.seekp(-3, std::ios_base::end);
453 mos << 'c';
454 oss << 'c';
455 assertTrue (oss.str()[6] == 'c');
456 assertTrue (buffer[6] == oss.str()[6]);
457 assertTrue (oss.tellp() == mos.tellp());
458
459 mos.seekp(-2, std::ios_base::cur);
460 oss.seekp(-2, std::ios_base::cur);
461 mos << 'd';
462 oss << 'd';
463 assertTrue (oss.str()[5] == 'd');
464 assertTrue (buffer[5] == oss.str()[5]);
465 assertTrue (oss.tellp() == mos.tellp());
466}
467
468
469void MemoryStreamTest::setUp()
470{
471}
472
473
474void MemoryStreamTest::tearDown()
475{
476}
477
478
479CppUnit::Test* MemoryStreamTest::suite()
480{
481 CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("MemoryStreamTest");
482
483 CppUnit_addTest(pSuite, MemoryStreamTest, testInput);
484 CppUnit_addTest(pSuite, MemoryStreamTest, testOutput);
485 CppUnit_addTest(pSuite, MemoryStreamTest, testTell);
486 CppUnit_addTest(pSuite, MemoryStreamTest, testInputSeek);
487 CppUnit_addTest(pSuite, MemoryStreamTest, testInputSeekVsStringStream);
488 CppUnit_addTest(pSuite, MemoryStreamTest, testOutputSeek);
489 CppUnit_addTest(pSuite, MemoryStreamTest, testOutputSeekVsStringStream);
490
491 return pSuite;
492}
493