• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include <string>
2 #include "math_aux.h"
3 
4 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
5 #  include <sstream>
6 #  include <memory>
7 
8 #  include "full_streambuf.h"
9 
10 #  include "cppunit/cppunit_proxy.h"
11 
12 #  if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
13 using namespace std;
14 #  endif
15 
16 //
17 // TestCase class
18 //
19 class SstreamTest : public CPPUNIT_NS::TestCase
20 {
21   CPPUNIT_TEST_SUITE(SstreamTest);
22   CPPUNIT_TEST(output);
23   CPPUNIT_TEST(input);
24   CPPUNIT_TEST(input_char);
25   CPPUNIT_TEST(io);
26   CPPUNIT_TEST(err);
27   CPPUNIT_TEST(err_long);
28   CPPUNIT_TEST(maxint);
29   CPPUNIT_TEST(init_in);
30   CPPUNIT_TEST(init_out);
31   CPPUNIT_TEST(buf);
32   CPPUNIT_TEST(rdbuf);
33   CPPUNIT_TEST(streambuf_output);
34   CPPUNIT_TEST(seek);
35   CPPUNIT_TEST(seekp);
36   CPPUNIT_TEST(seek_gp);
37   CPPUNIT_TEST(tellp);
38   CPPUNIT_TEST(negative);
39   CPPUNIT_TEST_SUITE_END();
40 
41   protected:
42     void output();
43     void input();
44     void input_char();
45     void io();
46     void err();
47     void err_long();
48     void maxint();
49     void init_in();
50     void init_out();
51     void buf();
52     void rdbuf();
53     void streambuf_output();
54     void seek();
55     void seekp();
56     void seek_gp();
57     void tellp();
58     void negative();
59 };
60 
61 CPPUNIT_TEST_SUITE_REGISTRATION(SstreamTest);
62 
63 //
64 // tests implementation
65 //
output()66 void SstreamTest::output()
67 {
68   {
69     ostringstream s;
70 
71     s << 1 << '\n' << 2.0 << '\n' << "abcd\n" << "ghk lm\n" << "abcd ef";
72     CPPUNIT_ASSERT( s.good() );
73     CPPUNIT_ASSERT( s.str() == "1\n2\nabcd\nghk lm\nabcd ef" );
74   }
75 
76   //Following tests are mostly used to reveal problem with the MSVC /Wp64 option
77   //used to track 64 bits portability issue:
78   {
79     ostringstream s;
80     size_t i = 0;
81     s << i;
82     CPPUNIT_ASSERT( s.good() );
83     CPPUNIT_ASSERT( s.str() == "0" );
84   }
85   {
86     ostringstream s;
87     ptrdiff_t i = 0;
88     s << i;
89     CPPUNIT_ASSERT( s.good() );
90     CPPUNIT_ASSERT( s.str() == "0" );
91   }
92 }
93 
input()94 void SstreamTest::input()
95 {
96   {
97     istringstream s( "1\n2\nabcd\nghk lm\nabcd ef" );
98     int i = 0;
99     s >> i;
100     CPPUNIT_ASSERT( s.good() );
101     CPPUNIT_ASSERT( i == 1 );
102     double d = 0.0;
103     s >> d;
104     CPPUNIT_ASSERT( s.good() );
105     CPPUNIT_ASSERT( d == 2.0 );
106     string str;
107     s >> str;
108     CPPUNIT_ASSERT( s.good() );
109     CPPUNIT_ASSERT( str == "abcd" );
110     char c;
111     s.get(c); // extract newline, that not extracted by operator >>
112     CPPUNIT_ASSERT( s.good() );
113     CPPUNIT_ASSERT( c == '\n' );
114     getline( s, str );
115     CPPUNIT_ASSERT( s.good() );
116     CPPUNIT_ASSERT( str == "ghk lm" );
117     getline( s, str );
118     CPPUNIT_ASSERT( s.eof() );
119     CPPUNIT_ASSERT( str == "abcd ef" );
120   }
121   {
122     istringstream s("0");
123     size_t i = 1;
124     s >> i;
125     CPPUNIT_ASSERT( !s.fail() );
126     CPPUNIT_ASSERT( s.eof() );
127     CPPUNIT_ASSERT( i == 0 );
128   }
129 }
130 
input_char()131 void SstreamTest::input_char()
132 {
133   char buf[16] = { 0, '1', '2', '3' };
134   istringstream s( "0" );
135   s >> buf;
136 
137   CPPUNIT_ASSERT( buf[0] == '0' );
138   CPPUNIT_ASSERT( buf[1] == 0 );
139   CPPUNIT_ASSERT( buf[2] == '2' );
140 }
141 
142 
io()143 void SstreamTest::io()
144 {
145   stringstream s;
146   s << 1 << '\n' << 2.0 << '\n' << "abcd\n" << "ghk lm\n" << "abcd ef";
147   CPPUNIT_ASSERT( s.good() );
148 
149   int i = 0;
150   s >> i;
151   CPPUNIT_ASSERT( i == 1 );
152   CPPUNIT_ASSERT( s.good() );
153   double d = 0.0;
154   s >> d;
155   CPPUNIT_ASSERT( d == 2.0 );
156   CPPUNIT_ASSERT( s.good() );
157   string str;
158   s >> str;
159   CPPUNIT_ASSERT( str == "abcd" );
160   CPPUNIT_ASSERT( s.good() );
161   char c;
162   s.get(c); // extract newline, that not extracted by operator >>
163   CPPUNIT_ASSERT( s.good() );
164   CPPUNIT_ASSERT( c == '\n' );
165   getline( s, str );
166   CPPUNIT_ASSERT( s.good() );
167   CPPUNIT_ASSERT( str == "ghk lm" );
168   getline( s, str );
169   CPPUNIT_ASSERT( str == "abcd ef" );
170   CPPUNIT_ASSERT( s.eof() );
171 }
172 
err()173 void SstreamTest::err()
174 {
175   stringstream s( "9" );
176 
177   int i = 0;
178   s >> i;
179   CPPUNIT_ASSERT( !s.fail() );
180   CPPUNIT_ASSERT( i == 9 );
181   s >> i;
182   CPPUNIT_ASSERT( s.fail() );
183   CPPUNIT_ASSERT( s.eof() );
184   CPPUNIT_ASSERT( i == 9 );
185 }
186 
err_long()187 void SstreamTest::err_long()
188 {
189   stringstream s( "9" );
190 
191   long i = 0;
192   s >> i;
193   CPPUNIT_ASSERT( !s.fail() );
194   CPPUNIT_ASSERT( i == 9 );
195   s >> i;
196   CPPUNIT_ASSERT( s.fail() );
197   CPPUNIT_ASSERT( s.eof() );
198   CPPUNIT_ASSERT( i == 9 );
199 }
200 
maxint()201 void SstreamTest::maxint()
202 {
203   stringstream s;
204 
205   s << INT_MAX << " " << UINT_MAX << " " << LONG_MAX << " " << ULONG_MAX << " "
206     << INT_MIN << " " << LONG_MIN;
207   CPPUNIT_ASSERT( s.good() );
208 
209   int i = 0;
210   unsigned int u = 0;
211   long l = 0;
212   unsigned long ul = 0;
213 
214   s >> i >> u >> l >> ul;
215   CPPUNIT_ASSERT( s.good() );
216   CPPUNIT_ASSERT( i == INT_MAX );
217   CPPUNIT_ASSERT( u == UINT_MAX );
218   CPPUNIT_ASSERT( l == LONG_MAX );
219   CPPUNIT_ASSERT( ul == ULONG_MAX );
220 
221   s >> i >> l;
222   CPPUNIT_ASSERT( !s.fail() );
223   CPPUNIT_ASSERT( i == INT_MIN );
224   CPPUNIT_ASSERT( l == LONG_MIN );
225 }
226 
init_in()227 void SstreamTest::init_in()
228 {
229   istringstream is( "12345" );
230   int n;
231 
232   is >> n;
233   CPPUNIT_ASSERT( !is.fail() );
234   CPPUNIT_ASSERT( n == 12345 );
235 
236   istringstream dis( "1.2345" );
237   double d;
238 
239   dis >> d;
240   CPPUNIT_ASSERT( !dis.fail() );
241   CPPUNIT_ASSERT( are_equals(d, 1.2345) );
242 
243   istringstream fis( "1.2345" );
244   float f;
245 
246   fis >> f;
247   CPPUNIT_ASSERT( !fis.fail() );
248   CPPUNIT_ASSERT( are_equals(f, 1.2345f) );
249 }
250 
init_out()251 void SstreamTest::init_out()
252 {
253   ostringstream os( "12345" );
254   CPPUNIT_ASSERT( os.str() == "12345" );
255 
256   os << 67;
257   CPPUNIT_ASSERT( os.good() );
258 
259   // This satisfy to the Standard:
260   // CPPUNIT_ASSERT( os.str() == "67345" );
261   // But we don't know the reason, why standard state that.
262 
263   /*
264    * 27.7.1.1: ... then copies the content of str into the basic_sringbuf
265    * underlying character sequence and initializes the input and output
266    * sequences according to which. If which & ios_base::out is true, initializes
267    * the output sequence with underlying sequence. ...
268    *
269    * I can treat this as 'like output was performed', and then I should bump
270    * put pointer... Looks like more useful then my previous treatment.
271    *
272    *          - ptr
273    */
274 
275   CPPUNIT_ASSERT( os.str() == "1234567" );
276 
277 
278   os.str( "89ab" );
279   CPPUNIT_ASSERT( os.str() == "89ab" );
280 
281   os << 10;
282   CPPUNIT_ASSERT( os.good() );
283   // CPPUNIT_ASSERT( os.str() == "10ab" );
284   CPPUNIT_ASSERT( os.str() == "89ab10" );
285 }
286 
buf()287 void SstreamTest::buf()
288 {
289   stringstream ss;
290 
291   ss << "1234567\n89\n";
292   char buf[10];
293   buf[7] = 'x';
294   ss.get( buf, 10 );
295   CPPUNIT_ASSERT( !ss.fail() );
296   CPPUNIT_ASSERT( buf[0] == '1' );
297   CPPUNIT_ASSERT( buf[1] == '2' );
298   CPPUNIT_ASSERT( buf[2] == '3' );
299   CPPUNIT_ASSERT( buf[3] == '4' );
300   CPPUNIT_ASSERT( buf[4] == '5' );
301   CPPUNIT_ASSERT( buf[5] == '6' );
302   CPPUNIT_ASSERT( buf[6] == '7' ); // 27.6.1.3 paragraph 10, paragraph 7
303   CPPUNIT_ASSERT( buf[7] == 0 ); // 27.6.1.3 paragraph 8
304   char c;
305   ss.get(c);
306   CPPUNIT_ASSERT( !ss.fail() );
307   CPPUNIT_ASSERT( c == '\n' ); // 27.6.1.3 paragraph 10, paragraph 7
308   ss.get(c);
309   CPPUNIT_ASSERT( !ss.fail() );
310   CPPUNIT_ASSERT( c == '8' );
311 }
312 
rdbuf()313 void SstreamTest::rdbuf()
314 {
315   stringstream ss;
316 
317   ss << "1234567\n89\n";
318 
319   ostringstream os;
320   ss.get( *os.rdbuf(), '\n' );
321   CPPUNIT_ASSERT( !ss.fail() );
322   char c;
323   ss.get(c);
324   CPPUNIT_ASSERT( !ss.fail() );
325   CPPUNIT_ASSERT( c == '\n' ); // 27.6.1.3 paragraph 12
326   CPPUNIT_ASSERT( os.str() == "1234567" );
327 }
328 
streambuf_output()329 void SstreamTest::streambuf_output()
330 {
331   {
332     istringstream in("01234567890123456789");
333     CPPUNIT_ASSERT( in );
334 
335     full_streambuf full_buf(10);
336     ostream out(&full_buf);
337     CPPUNIT_ASSERT( out );
338 
339     out << in.rdbuf();
340     CPPUNIT_ASSERT( out );
341     CPPUNIT_ASSERT( in );
342     //out is good we can check what has been extracted:
343     CPPUNIT_ASSERT( full_buf.str() == "0123456789" );
344 
345     out << in.rdbuf();
346     CPPUNIT_ASSERT( out.fail() );
347     CPPUNIT_ASSERT( in );
348 
349     ostringstream ostr;
350     ostr << in.rdbuf();
351     CPPUNIT_ASSERT( ostr );
352     CPPUNIT_ASSERT( in );
353     CPPUNIT_ASSERT( ostr.str() == "0123456789" );
354   }
355 
356 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
357   {
358     //If the output stream buffer throws:
359     istringstream in("01234567890123456789");
360     CPPUNIT_ASSERT( in );
361 
362     full_streambuf full_buf(10, true);
363     ostream out(&full_buf);
364     CPPUNIT_ASSERT( out );
365 
366     out << in.rdbuf();
367     CPPUNIT_ASSERT( out.bad() );
368     CPPUNIT_ASSERT( in );
369     //out is bad we have no guaranty on what has been extracted:
370     //CPPUNIT_ASSERT( full_buf.str() == "0123456789" );
371 
372     out.clear();
373     out << in.rdbuf();
374     CPPUNIT_ASSERT( out.fail() && out.bad() );
375     CPPUNIT_ASSERT( in );
376 
377     ostringstream ostr;
378     ostr << in.rdbuf();
379     CPPUNIT_ASSERT( ostr );
380     CPPUNIT_ASSERT( in );
381     CPPUNIT_ASSERT( ostr.str() == "01234567890123456789" );
382   }
383 #  endif
384 }
385 
seek()386 void SstreamTest::seek()
387 {
388   stringstream s( "0123456789" );
389 
390   CPPUNIT_ASSERT( s.tellg() == stringstream::pos_type(0) );
391   s.seekg( 6, ios::beg );
392   CPPUNIT_ASSERT( s.tellg() == stringstream::pos_type(6) );
393   s.seekg( -3, ios::cur );
394   CPPUNIT_ASSERT( s.tellg() == stringstream::pos_type(3) );
395 
396   istringstream is( "0123456789" );
397   CPPUNIT_ASSERT( is.tellg() == stringstream::pos_type(0) );
398   is.seekg( 6, ios::beg );
399   CPPUNIT_ASSERT( is.tellg() == stringstream::pos_type(6) );
400   is.seekg( -3, ios::cur );
401   CPPUNIT_ASSERT( is.tellg() == stringstream::pos_type(3) );
402 }
403 
seekp()404 void SstreamTest::seekp()
405 {
406   ostringstream s;
407 
408   s << "1234567";
409   CPPUNIT_CHECK( s.tellp() == stringstream::pos_type(7) );
410   CPPUNIT_CHECK( s.str() == "1234567" );
411   s.seekp( 0 );
412   s << "X";
413   CPPUNIT_CHECK( s.str() == "X234567" );
414   s.seekp( 0, ios::beg );
415   s << "Y";
416   CPPUNIT_CHECK( s.str() == "Y234567" );
417 }
418 
seek_gp()419 void SstreamTest::seek_gp()
420 {
421   stringstream ss( "1" );
422 
423   /* ISO/IEC 14882 2003 (and 1998 too) assume change as get as put positions
424      with seekg and seekp (27.6.1.3, par 38; 27.6.2.4 par 2),
425      but this contradict to common practice and proposed draft N2588
426      (27.6.1.3, par 41; 27.6.2.5, par 4)
427 
428      Now STLport implement (i.e. change behaviour ) the draft's point of view.
429    */
430 
431   ss.seekg( 0, ios::beg );
432   ss.seekp( 0, ios::end );
433 
434   ss << "2";
435 
436   string str;
437 
438   ss >> str;
439 
440   /*  CPPUNIT_CHECK( str == "2" ); --- according ISO/IEC 14882 2003 */
441   CPPUNIT_CHECK( str == "12" );
442 }
443 
tellp()444 void SstreamTest::tellp()
445 {
446   {
447     ostringstream o( "1" );
448 
449     o << "23456";
450 
451     CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == stringstream::pos_type(6) );
452     CPPUNIT_CHECK( o.tellp() == stringstream::pos_type(6) );
453   }
454   {
455     ostringstream o;
456 
457     o << "123456";
458 
459     CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == stringstream::pos_type(6) );
460     CPPUNIT_CHECK( o.tellp() == stringstream::pos_type(6) );
461   }
462   {
463     ostringstream o( "1" );
464 
465     o << "23456789";
466 
467     CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == stringstream::pos_type(9) );
468     CPPUNIT_CHECK( o.tellp() == stringstream::pos_type(9) );
469   }
470 }
471 
472 
473 template < class T >
to_string(const T & v)474 string to_string( const T& v )
475 {
476   ostringstream oss;
477   oss << v;
478   return oss.str();
479 }
480 
negative()481 void SstreamTest::negative()
482 {
483   CPPUNIT_CHECK( to_string<int>(-1) == "-1" );
484   CPPUNIT_CHECK( to_string<long>(-1) == "-1" );
485 }
486 
487 #endif
488