Home | History | Annotate | Download | only in unit
      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 //
     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 
     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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 >
    474 string to_string( const T& v )
    475 {
    476   ostringstream oss;
    477   oss << v;
    478   return oss.str();
    479 }
    480 
    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