Home | History | Annotate | Download | only in unit
      1 #include <string>
      2 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS)
      3 #  include <fstream>
      4 #  include <iostream>
      5 #  include <iomanip>
      6 #  include <sstream>
      7 #  include <vector>
      8 #  include <stdexcept>
      9 
     10 #include <stdio.h>
     11 
     12 #  include "full_streambuf.h"
     13 #  include "cppunit/cppunit_proxy.h"
     14 
     15 #  if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES)
     16 using namespace std;
     17 #  endif
     18 
     19 //The macro value gives approximately the generated file
     20 //size in Go
     21 //#define CHECK_BIG_FILE 4
     22 
     23 #  if (!defined(STLPORT) && (defined (__GNUC__) && (__GNUC__ > 3))) || \
     24       (defined (STLPORT) && !defined (_STLP_NO_CUSTOM_IO) && !defined (_STLP_NO_MEMBER_TEMPLATES) && \
     25                             !((defined (_STLP_MSVC) && (_STLP_MSVC < 1300)) || \
     26                               (defined (__GNUC__) && (__GNUC__ < 3)) || \
     27                               (defined (__SUNPRO_CC)) || \
     28                               (defined (__DMC__) && defined (_DLL))))
     29 #    define DO_CUSTOM_FACET_TEST
     30 #  endif
     31 
     32 //
     33 // TestCase class
     34 //
     35 class FstreamTest : public CPPUNIT_NS::TestCase
     36 {
     37   CPPUNIT_TEST_SUITE(FstreamTest);
     38   CPPUNIT_TEST(output);
     39   CPPUNIT_TEST(input);
     40   CPPUNIT_TEST(input_char);
     41   CPPUNIT_TEST(io);
     42   CPPUNIT_TEST(err);
     43   CPPUNIT_TEST(tellg);
     44   CPPUNIT_TEST(tellp);
     45   CPPUNIT_TEST(seek);
     46   CPPUNIT_TEST(buf);
     47   CPPUNIT_TEST(rdbuf);
     48   CPPUNIT_TEST(streambuf_output);
     49   CPPUNIT_TEST(win32_file_format);
     50   CPPUNIT_TEST(null_stream);
     51 #  if defined (STLPORT) && (defined (_STLP_NO_WCHAR_T) || !defined (_STLP_USE_EXCEPTIONS))
     52   CPPUNIT_IGNORE;
     53 #  endif
     54   CPPUNIT_TEST(null_buf);
     55 #  if !defined (STLPORT) || !defined (_STLP_WIN32)
     56   CPPUNIT_TEST(offset);
     57 #  endif
     58 #  if defined (CHECK_BIG_FILE)
     59   CPPUNIT_TEST(big_file);
     60 #  endif
     61 #  if !defined (DO_CUSTOM_FACET_TEST)
     62   CPPUNIT_IGNORE;
     63 #  endif
     64   CPPUNIT_TEST(custom_facet);
     65   CPPUNIT_TEST_SUITE_END();
     66 
     67   protected:
     68     void output();
     69     void input();
     70     void input_char();
     71     void io();
     72     void err();
     73     void tellg();
     74     void tellp();
     75     void seek();
     76     void buf();
     77     void rdbuf();
     78     void streambuf_output();
     79     void win32_file_format();
     80     void null_stream();
     81     void null_buf();
     82 #  if !defined (STLPORT) || !defined (_STLP_WIN32)
     83     void offset();
     84 #  endif
     85     void custom_facet();
     86 #  if defined (CHECK_BIG_FILE)
     87     void big_file();
     88 #  endif
     89 };
     90 
     91 CPPUNIT_TEST_SUITE_REGISTRATION(FstreamTest);
     92 
     93 //
     94 // tests implementation
     95 //
     96 void FstreamTest::output()
     97 {
     98   ofstream f( "test_file.txt" );
     99 
    100   f << 1 << '\n' << 2.0 << '\n' << "abcd\n" << "ghk lm\n" << "abcd ef";
    101   CPPUNIT_ASSERT (f.good());
    102   // CPPUNIT_ASSERT( s.str() == "1\n2\nabcd\nghk lm\nabcd ef" );
    103 }
    104 
    105 void FstreamTest::input()
    106 {
    107   {
    108     ifstream f( "test_file.txt" );
    109     int i = 0;
    110     f >> i;
    111     CPPUNIT_ASSERT( f.good() );
    112     CPPUNIT_ASSERT( i == 1 );
    113     double d = 0.0;
    114     f >> d;
    115     CPPUNIT_ASSERT( f.good() );
    116     CPPUNIT_ASSERT( d == 2.0 );
    117     string str;
    118     f >> str;
    119     CPPUNIT_ASSERT( f.good() );
    120     CPPUNIT_ASSERT( str == "abcd" );
    121     char c;
    122     f.get(c); // extract newline, that not extracted by operator >>
    123     CPPUNIT_ASSERT( f.good() );
    124     CPPUNIT_ASSERT( c == '\n' );
    125     getline( f, str );
    126     CPPUNIT_ASSERT( f.good() );
    127     CPPUNIT_ASSERT( str == "ghk lm" );
    128     getline( f, str );
    129     CPPUNIT_ASSERT( f.eof() );
    130     CPPUNIT_ASSERT( str == "abcd ef" );
    131   }
    132 #if defined (STLPORT) && !defined (_STLP_USE_WIN32_IO)
    133   {
    134     ifstream in("/tmp");
    135     if (in.good()) {
    136       string s;
    137       getline(in, s);
    138       CPPUNIT_ASSERT( in.fail() );
    139     }
    140   }
    141 #endif
    142 }
    143 
    144 void FstreamTest::input_char()
    145 {
    146   char buf[16] = { 0, '1', '2', '3' };
    147   ifstream s( "test_file.txt" );
    148   s >> buf;
    149 
    150   CPPUNIT_ASSERT( buf[0] == '1' );
    151   CPPUNIT_ASSERT( buf[1] == 0 );
    152   CPPUNIT_ASSERT( buf[2] == '2' );
    153 }
    154 
    155 void FstreamTest::io()
    156 {
    157   basic_fstream<char,char_traits<char> > f( "test_file.txt", ios_base::in | ios_base::out | ios_base::trunc );
    158 
    159   CPPUNIT_ASSERT( f.is_open() );
    160 
    161   f << 1 << '\n' << 2.0 << '\n' << "abcd\n" << "ghk lm\n" << "abcd ef";
    162 
    163   // f.flush();
    164   f.seekg( 0, ios_base::beg );
    165 
    166   int i = 0;
    167   f >> i;
    168   CPPUNIT_ASSERT( f.good() );
    169   CPPUNIT_ASSERT( i == 1 );
    170   double d = 0.0;
    171   f >> d;
    172   CPPUNIT_ASSERT( d == 2.0 );
    173   string s;
    174   f >> s;
    175   CPPUNIT_ASSERT( f.good() );
    176   CPPUNIT_ASSERT( s == "abcd" );
    177   char c;
    178   f.get(c); // extract newline, that not extracted by operator >>
    179   CPPUNIT_ASSERT( f.good() );
    180   CPPUNIT_ASSERT( c == '\n' );
    181   getline( f, s );
    182   CPPUNIT_ASSERT( f.good() );
    183   CPPUNIT_ASSERT( s == "ghk lm" );
    184   getline( f, s );
    185   CPPUNIT_ASSERT( !f.fail() );
    186   CPPUNIT_ASSERT( s == "abcd ef" );
    187   CPPUNIT_ASSERT( f.eof() );
    188 }
    189 
    190 void FstreamTest::err()
    191 {
    192   basic_fstream<char,char_traits<char> > f( "test_file.txt", ios_base::in | ios_base::out | ios_base::trunc );
    193 
    194   CPPUNIT_ASSERT( f.is_open() );
    195 
    196   int i = 9;
    197   f << i;
    198   CPPUNIT_ASSERT( f.good() );
    199   i = 0;
    200   f.seekg( 0, ios_base::beg );
    201   f >> i;
    202   CPPUNIT_ASSERT( !f.fail() );
    203   CPPUNIT_ASSERT( i == 9 );
    204   f >> i;
    205   CPPUNIT_ASSERT( f.fail() );
    206   CPPUNIT_ASSERT( f.eof() );
    207   CPPUNIT_ASSERT( i == 9 );
    208 }
    209 
    210 void FstreamTest::tellg()
    211 {
    212   {
    213     // bogus ios_base::binary is for Wins
    214     ofstream of("test_file.txt", ios_base::out | ios_base::binary | ios_base::trunc);
    215     CPPUNIT_ASSERT( of.is_open() );
    216 
    217     for (int i = 0; i < 50; ++i) {
    218       of << "line " << setiosflags(ios_base::right) << setfill('0') << setw(2) << i << "\n";
    219       CPPUNIT_ASSERT( !of.fail() );
    220     }
    221     of.close();
    222   }
    223 
    224   {
    225     // bogus ios_base::binary is for Wins
    226     ifstream is("test_file.txt", ios_base::in | ios_base::binary);
    227     CPPUNIT_ASSERT( is.is_open() );
    228     char buf[64];
    229 
    230     // CPPUNIT_ASSERT( is.tellg() == 0 );
    231     streampos p = 0;
    232     for (int i = 0; i < 50; ++i) {
    233       is.read(buf, 0);
    234       CPPUNIT_ASSERT( is.gcount() == 0 );
    235       CPPUNIT_ASSERT( is.tellg() == p );
    236       is.read( buf, 8 );
    237       CPPUNIT_ASSERT( !is.fail() );
    238       CPPUNIT_ASSERT( is.gcount() == 8 );
    239       p += 8;
    240     }
    241   }
    242 
    243   {
    244     // bogus ios_base::binary is for Wins
    245     ifstream is("test_file.txt", ios_base::in | ios_base::binary);
    246     CPPUNIT_ASSERT( is.is_open() );
    247 
    248     streampos p = 0;
    249     for (int i = 0; i < 50; ++i) {
    250       CPPUNIT_ASSERT( !is.fail() );
    251       is.tellg();
    252       CPPUNIT_ASSERT( is.tellg() == p );
    253       p += 8;
    254       is.seekg( p, ios_base::beg  );
    255       CPPUNIT_ASSERT( !is.fail() );
    256     }
    257   }
    258 
    259   {
    260     // bogus ios_base::binary is for Wins
    261     ifstream is("test_file.txt", ios_base::in | ios_base::binary);
    262     CPPUNIT_ASSERT( is.is_open() );
    263 
    264     streampos p = 0;
    265     for (int i = 0; i < 50; ++i) {
    266       CPPUNIT_ASSERT( is.tellg() == p );
    267       p += 8;
    268       is.seekg( 8, ios_base::cur );
    269       CPPUNIT_ASSERT( !is.fail() );
    270     }
    271   }
    272 }
    273 
    274 void FstreamTest::tellp()
    275 {
    276   {
    277     ofstream o( "test_file.txt" );
    278 
    279     o << "123456";
    280 
    281     CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == ofstream::pos_type(6) );
    282     CPPUNIT_CHECK( o.tellp() == ofstream::pos_type(6) );
    283   }
    284   {
    285     ofstream o( "test_file.txt" );
    286 
    287     o << "123456789";
    288 
    289     CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == ofstream::pos_type(9) );
    290     CPPUNIT_CHECK( o.tellp() == ofstream::pos_type(9) );
    291   }
    292   /* According to the standard
    293      ofstream o( "test_file.txt", ios_base::app | ios_base::out )
    294      should give the same effect as fopen( "test_file.txt", "a" ).
    295      Problem is fopen( "test_file.txt", "a" ) has a bit different behaviour
    296      on different platforms, and this difference is not covered by specification.
    297      After fopen( "test_file.txt", "a" ) in this context ftell( f ) == 9 for
    298      Linux and Mac OS X (I expect the same for others POSIX-like platforms too);
    299      on Windows (independently from version?) ftell( f ) == 0, i.e. write pointer not
    300      shifted to EOF (but shifted to EOF just before write, as described in the specs).
    301 
    302      It isn't specifications violation, neither for Linux and Mac OS X nor for Windows.
    303 
    304      The code below is intended to demonstrate ambiguity (dependance from fopen implementation).
    305    */
    306   {
    307     #ifdef WIN32
    308     //In Windows, stlport and fopen use kernel32.CreateFile for open.
    309     //File position is at BOF after open, unless we open with ios_base::ate
    310     long expected_pos = 0;
    311     #else
    312     //On UNIX flavours, stlport and fopen use unix's open
    313     //File position is at EOF after open
    314     //
    315     //3rd possible scenario, "other platforms" - _STLP_USE_STDIO_IO
    316     //stlport uses fopen here. This case may fail this test, since the file position after
    317     //fopen is implementation-dependent
    318     long expected_pos = 9;
    319     #endif
    320     ofstream o( "test_file.txt", ios_base::app | ios_base::out );
    321     CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == ofstream::pos_type(expected_pos) );
    322     CPPUNIT_CHECK( o.tellp() == ofstream::pos_type(expected_pos) );
    323   }
    324   { // for reference, to test fopen/ftell behaviour in append mode:
    325     #ifdef WIN32
    326     long expected_pos = 0;
    327     #else
    328     long expected_pos = 9;
    329     #endif
    330     FILE* f = fopen( "test_file.txt", "a" );
    331     CPPUNIT_CHECK( ftell( f ) == expected_pos );
    332     fclose( f );
    333   }
    334   {
    335     //In append mode, file is positioned at EOF just before a write.
    336     // After a write, file is at EOF. This is implementation-independent.
    337     ofstream o( "test_file.txt", ios_base::app | ios_base::out );
    338     o << "X";
    339     CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == ofstream::pos_type(10) );
    340     CPPUNIT_CHECK( o.tellp() == ofstream::pos_type(10) );
    341   }
    342 }
    343 
    344 void FstreamTest::buf()
    345 {
    346   fstream ss( "test_file.txt", ios_base::in | ios_base::out | ios_base::binary | ios_base::trunc );
    347 
    348   ss << "1234567\n89\n";
    349   ss.seekg( 0, ios_base::beg );
    350   char buf[10];
    351   buf[7] = 'x';
    352   ss.get( buf, 10 );
    353   CPPUNIT_ASSERT( !ss.fail() );
    354   CPPUNIT_ASSERT( buf[0] == '1' );
    355   CPPUNIT_ASSERT( buf[1] == '2' );
    356   CPPUNIT_ASSERT( buf[2] == '3' );
    357   CPPUNIT_ASSERT( buf[3] == '4' );
    358   CPPUNIT_ASSERT( buf[4] == '5' );
    359   CPPUNIT_ASSERT( buf[5] == '6' );
    360   CPPUNIT_ASSERT( buf[6] == '7' ); // 27.6.1.3 paragraph 10, paragraph 7
    361   CPPUNIT_ASSERT( buf[7] == 0 ); // 27.6.1.3 paragraph 8
    362   char c;
    363   ss.get(c);
    364   CPPUNIT_ASSERT( !ss.fail() );
    365   CPPUNIT_ASSERT( c == '\n' ); // 27.6.1.3 paragraph 10, paragraph 7
    366   ss.get(c);
    367   CPPUNIT_ASSERT( !ss.fail() );
    368   CPPUNIT_ASSERT( c == '8' );
    369 }
    370 
    371 void FstreamTest::seek()
    372 {
    373   {
    374     // Test in binary mode:
    375     {
    376       fstream s( "test_file.txt", ios_base::in | ios_base::out | ios_base::binary | ios_base::trunc );
    377       CPPUNIT_ASSERT( s );
    378 
    379       s << "1234567890\n";
    380       CPPUNIT_ASSERT( s );
    381     }
    382 
    383     char b1[] = { 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x' };
    384     fstream s( "test_file.txt", ios_base::in | ios_base::out | ios_base::binary );
    385     CPPUNIT_ASSERT( s );
    386 
    387     int chars_read = (int)s.rdbuf()->sgetn( b1, sizeof(b1) );
    388     CPPUNIT_CHECK( chars_read == 11 );
    389     CPPUNIT_CHECK( b1[9] == '0' );
    390     CPPUNIT_ASSERT( s.rdbuf()->pubseekoff( 0, ios_base::cur ) == fstream::pos_type(chars_read) );
    391     CPPUNIT_ASSERT( s.rdbuf()->pubseekoff( -chars_read, ios_base::cur ) == fstream::pos_type(0) );
    392 
    393     char b2[10] = { 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y' };
    394 
    395     CPPUNIT_ASSERT( s.rdbuf()->sgetn( b2, 10 ) == 10 );
    396     CPPUNIT_CHECK( b2[9] == '0' );
    397   }
    398 
    399   {
    400     // Test in text mode:
    401     {
    402       fstream s( "test_file.txt", ios_base::in | ios_base::out | ios_base::trunc );
    403       CPPUNIT_ASSERT( s );
    404 
    405       s << "1234567890\n";
    406       CPPUNIT_ASSERT( s );
    407     }
    408 
    409     char b1[] = { 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x' };
    410     fstream s( "test_file.txt", ios_base::in | ios_base::out );
    411     CPPUNIT_ASSERT( s );
    412 
    413     int chars_read = (int)s.rdbuf()->sgetn( b1, sizeof(b1) );
    414     CPPUNIT_CHECK( chars_read == 11 );
    415     CPPUNIT_CHECK( b1[9] == '0' );
    416 
    417     fstream::pos_type pos = s.rdbuf()->pubseekoff(0, ios_base::cur);
    418     // Depending on how '\n' is written in file, file position can be greater or equal to the number of chars_read read.
    419     streamoff offset = pos;
    420     CPPUNIT_ASSERT( offset >= chars_read );
    421     offset = s.rdbuf()->pubseekoff( -offset, ios_base::cur );
    422     CPPUNIT_ASSERT( offset == 0 );
    423 
    424     char b2[10] = { 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y' };
    425 
    426     CPPUNIT_ASSERT( s.rdbuf()->sgetn( b2, 5 ) == 5 );
    427     CPPUNIT_CHECK( b2[4] == '5' );
    428 
    429     pos = s.rdbuf()->pubseekoff(0, ios_base::cur);
    430     CPPUNIT_ASSERT( pos == fstream::pos_type(5) );
    431     CPPUNIT_ASSERT( s.rdbuf()->pubseekoff(-5, ios_base::cur) == fstream::pos_type(0) );
    432   }
    433 
    434 #if !defined (STLPORT) || \
    435     (!defined (_STLP_NO_WCHAR_T) && defined (_STLP_USE_EXCEPTIONS))
    436   {
    437     // Test with a wariable encoding:
    438     locale loc;
    439     try
    440     {
    441       locale tmp(locale::classic(), new codecvt_byname<wchar_t, char, mbstate_t>(".UTF8"));
    442       loc = tmp;
    443     }
    444     catch (const runtime_error&)
    445     {
    446       // Localization no supported so no test:
    447       return;
    448     }
    449 
    450     {
    451       wfstream s( "test_file.txt", ios_base::in | ios_base::out | ios_base::trunc );
    452       CPPUNIT_ASSERT( s );
    453       s.imbue(loc);
    454       CPPUNIT_ASSERT( s );
    455 
    456       s << L"1234567890\n";
    457       CPPUNIT_ASSERT( s );
    458     }
    459 
    460     wchar_t b1[] = { L'x', L'x', L'x', L'x', L'x', L'x', L'x', L'x', L'x', L'x', L'x', L'x', L'x', L'x', L'x', L'x', L'x', L'x', L'x', L'x' };
    461     wfstream s( "test_file.txt", ios_base::in | ios_base::out );
    462     CPPUNIT_ASSERT( s );
    463     s.imbue(loc);
    464     CPPUNIT_ASSERT( s );
    465 
    466     int chars_read = (int)s.rdbuf()->sgetn( b1, sizeof(b1) / sizeof(wchar_t) );
    467     CPPUNIT_CHECK( chars_read == 11 );
    468     CPPUNIT_CHECK( b1[9] == L'0' );
    469 
    470     fstream::pos_type pos = s.rdbuf()->pubseekoff(0, ios_base::cur);
    471     // Depending on how '\n' is written in file, file position can be greater or equal to the number of chars_read read.
    472     streamoff off = pos;
    473     CPPUNIT_ASSERT( off >= chars_read );
    474     off = s.rdbuf()->pubseekoff(-off, ios_base::cur);
    475     CPPUNIT_ASSERT( off == -1 );
    476     off = s.rdbuf()->pubseekoff(0, ios_base::beg);
    477     CPPUNIT_ASSERT( off == 0 );
    478 
    479     wchar_t b2[10] = { L'y', L'y', L'y', L'y', L'y', L'y', L'y', L'y', L'y', L'y' };
    480 
    481     CPPUNIT_ASSERT( s.rdbuf()->sgetn( b2, 5 ) == 5 );
    482     CPPUNIT_CHECK( b2[4] == L'5' );
    483 
    484     pos = s.rdbuf()->pubseekoff(0, ios_base::cur);
    485     CPPUNIT_ASSERT( pos == fstream::pos_type(5) );
    486     //CPPUNIT_ASSERT( s.rdbuf()->pubseekoff(-5, ios_base::cur) == fstream::pos_type(0) );
    487   }
    488 #endif
    489 }
    490 
    491 void FstreamTest::rdbuf()
    492 {
    493   fstream ss( "test_file.txt", ios_base::in | ios_base::out | ios_base::binary | ios_base::trunc );
    494 
    495   ss << "1234567\n89\n";
    496   ss.seekg( 0, ios_base::beg );
    497 
    498   ostringstream os;
    499   ss.get( *os.rdbuf(), '\n' );
    500   CPPUNIT_ASSERT( !ss.fail() );
    501   char c;
    502   ss.get(c);
    503   CPPUNIT_ASSERT( !ss.fail() );
    504   CPPUNIT_ASSERT( c == '\n' ); // 27.6.1.3 paragraph 12
    505   CPPUNIT_ASSERT( os.str() == "1234567" );
    506 }
    507 
    508 void FstreamTest::streambuf_output()
    509 {
    510   {
    511     ofstream ofstr("test_file.txt", ios_base::binary);
    512     if (!ofstr)
    513       //No test if we cannot create the file
    514       return;
    515     ofstr << "01234567890123456789";
    516     CPPUNIT_ASSERT( ofstr );
    517   }
    518 
    519   {
    520     ifstream in("test_file.txt", ios_base::binary);
    521     CPPUNIT_ASSERT( in );
    522 
    523     full_streambuf full_buf(10);
    524     ostream out(&full_buf);
    525     CPPUNIT_ASSERT( out );
    526 
    527     out << in.rdbuf();
    528     CPPUNIT_ASSERT( out );
    529     CPPUNIT_ASSERT( in );
    530     CPPUNIT_ASSERT( full_buf.str() == "0123456789" );
    531 
    532     out << in.rdbuf();
    533     CPPUNIT_ASSERT( out.fail() );
    534     CPPUNIT_ASSERT( in );
    535 
    536     ostringstream ostr;
    537     ostr << in.rdbuf();
    538     CPPUNIT_ASSERT( ostr );
    539     CPPUNIT_ASSERT( in );
    540     CPPUNIT_ASSERT( ostr.str() == "0123456789" );
    541   }
    542 
    543 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
    544   {
    545     //If the output stream buffer throws:
    546     ifstream in("test_file.txt", ios_base::binary);
    547     CPPUNIT_ASSERT( in );
    548 
    549     full_streambuf full_buf(10, true);
    550     ostream out(&full_buf);
    551     CPPUNIT_ASSERT( out );
    552 
    553     out << in.rdbuf();
    554     CPPUNIT_ASSERT( out.bad() );
    555     CPPUNIT_ASSERT( in );
    556     //out is bad we have no guaranty on what has been extracted:
    557     //CPPUNIT_ASSERT( full_buf.str() == "0123456789" );
    558 
    559     out.clear();
    560     out << in.rdbuf();
    561     CPPUNIT_ASSERT( out.fail() && out.bad() );
    562     CPPUNIT_ASSERT( in );
    563 
    564     ostringstream ostr;
    565     ostr << in.rdbuf();
    566     CPPUNIT_ASSERT( ostr );
    567     CPPUNIT_ASSERT( in );
    568     CPPUNIT_ASSERT( ostr.str() == "0123456789" );
    569   }
    570 #  endif
    571 }
    572 
    573 void FstreamTest::win32_file_format()
    574 {
    575   const char* file_name = "win32_file_format.tmp";
    576   const size_t nb_lines = 2049;
    577   {
    578     ofstream out(file_name);
    579     CPPUNIT_ASSERT( out.good() );
    580     out << 'a';
    581     for (size_t i = 0; i < nb_lines - 1; ++i) {
    582       out << '\n';
    583     }
    584     out << '\r';
    585     CPPUNIT_ASSERT( out.good() );
    586   }
    587   {
    588     ifstream in(file_name);
    589     CPPUNIT_ASSERT( in.good() );
    590     string line, last_line;
    591     size_t nb_read_lines = 0;
    592     while (getline(in, line)) {
    593       ++nb_read_lines;
    594       last_line = line;
    595     }
    596     CPPUNIT_ASSERT( in.eof() );
    597     CPPUNIT_ASSERT( nb_read_lines == nb_lines );
    598     CPPUNIT_ASSERT( !last_line.empty() && (last_line[0] == '\r') );
    599   }
    600 }
    601 
    602 #if defined (DO_CUSTOM_FACET_TEST)
    603 struct my_state {
    604   char dummy;
    605 };
    606 
    607 struct my_traits : public char_traits<char> {
    608   typedef my_state state_type;
    609   typedef fpos<state_type> pos_type;
    610 };
    611 
    612 #if !defined (STLPORT)
    613 //STLport grant a default implementation, other Standard libs implementation
    614 //do not necessarily do the same:
    615 namespace std {
    616   template <>
    617   class codecvt<char, char, my_state>
    618     : public locale::facet, public codecvt_base {
    619   public:
    620     typedef char intern_type;
    621     typedef char extern_type;
    622     typedef my_state state_type;
    623 
    624     explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {}
    625     result out(state_type&,
    626                const intern_type*  __from,
    627                const intern_type*,
    628                const intern_type*& __from_next,
    629                extern_type*        __to,
    630                extern_type*,
    631                extern_type*&       __to_next) const
    632     { __from_next = __from; __to_next   = __to; return noconv; }
    633 
    634     result in (state_type&,
    635                const extern_type*  __from,
    636                const extern_type*,
    637                const extern_type*& __from_next,
    638                intern_type*        __to,
    639                intern_type*,
    640                intern_type*&       __to_next) const
    641     { __from_next = __from; __to_next = __to; return noconv; }
    642 
    643     result unshift(state_type&,
    644                    extern_type* __to,
    645                    extern_type*,
    646                    extern_type*& __to_next) const
    647     { __to_next = __to; return noconv; }
    648 
    649     int encoding() const throw()
    650     { return 1; }
    651 
    652     bool always_noconv() const throw()
    653     { return true; }
    654 
    655     int length(const state_type&,
    656                const extern_type* __from,
    657                const extern_type* __end,
    658                size_t __max) const
    659     { return (int)min(static_cast<size_t>(__end - __from), __max); }
    660 
    661     int max_length() const throw()
    662     { return 1; }
    663 
    664     static locale::id id;
    665   };
    666 
    667   locale::id codecvt<char, char, my_state>::id;
    668 }
    669 #  else
    670 #    if defined (__BORLANDC__) && (__BORLANDC__ < 0x590)
    671 template <>
    672 locale::id codecvt<char, char, my_state>::id;
    673 #    endif
    674 #  endif
    675 #endif
    676 
    677 void FstreamTest::custom_facet()
    678 {
    679 #if defined (DO_CUSTOM_FACET_TEST)
    680   const char* fileName = "test_file.txt";
    681   //File preparation:
    682   {
    683     ofstream ofstr(fileName, ios_base::binary);
    684     ofstr << "0123456789";
    685     CPPUNIT_ASSERT( ofstr );
    686   }
    687 
    688   {
    689     typedef basic_ifstream<char, my_traits> my_ifstream;
    690     typedef basic_string<char, my_traits> my_string;
    691 
    692     my_ifstream ifstr(fileName);
    693     CPPUNIT_ASSERT( ifstr );
    694 
    695 #  if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS)
    696     ifstr.imbue(locale::classic());
    697     CPPUNIT_ASSERT( ifstr.fail() && !ifstr.bad() );
    698     ifstr.clear();
    699 #  endif
    700     typedef codecvt<char, char, my_state> my_codecvt;
    701     locale my_loc(locale::classic(), new my_codecvt());
    702     // Check that my_codecvt has not replace default codecvt:
    703     CPPUNIT_ASSERT( (has_facet<my_codecvt>(my_loc)) );
    704     CPPUNIT_ASSERT( (has_facet<codecvt<char, char, mbstate_t> >(my_loc)) );
    705 #  if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T)
    706     CPPUNIT_ASSERT( (has_facet<codecvt<wchar_t, char, mbstate_t> >(my_loc)) );
    707 #  endif
    708     ifstr.imbue(my_loc);
    709     CPPUNIT_ASSERT( ifstr.good() );
    710     /*
    711     my_string res;
    712     ifstr >> res;
    713     CPPUNIT_ASSERT( !ifstr.fail() );
    714     CPPUNIT_ASSERT( !ifstr.bad() );
    715     CPPUNIT_ASSERT( ifstr.eof() );
    716     CPPUNIT_ASSERT( res == "0123456789" );
    717     */
    718   }
    719 #endif
    720 }
    721 
    722 #  if defined (CHECK_BIG_FILE)
    723 void FstreamTest::big_file()
    724 {
    725   vector<pair<streamsize, streamoff> > file_pos;
    726 
    727   //Big file creation:
    728   {
    729     ofstream out("big_file.txt");
    730     CPPUNIT_ASSERT( out );
    731 
    732     //We are going to generate a file with the following schema for the content:
    733     //0(1019 times)0000  //1023 characters + 1 charater for \n (for some platforms it will be a 1 ko line)
    734     //0(1019 times)0001
    735     //...
    736     //0(1019 times)1234
    737     //...
    738 
    739     //Generation of the number of loop:
    740     streamoff nb = 1;
    741     for (int i = 0; i < 20; ++i) {
    742       //This assertion check that the streamoff can at least represent the necessary integers values
    743       //for this test:
    744       CPPUNIT_ASSERT( (nb << 1) > nb );
    745       nb <<= 1;
    746     }
    747     CPPUNIT_ASSERT( nb * CHECK_BIG_FILE >= nb );
    748     nb *= CHECK_BIG_FILE;
    749 
    750     //Preparation of the ouput stream state:
    751     out << setiosflags(ios_base::right) << setfill('*');
    752     for (streamoff index = 0; index < nb; ++index) {
    753       if (index % 1024 == 0) {
    754         file_pos.push_back(make_pair(out.tellp(), index));
    755         CPPUNIT_ASSERT( file_pos.back().first != streamsize(-1) );
    756         if (file_pos.size() > 1) {
    757           CPPUNIT_ASSERT( file_pos[file_pos.size() - 1].first > file_pos[file_pos.size() - 2].first );
    758         }
    759       }
    760       out << setw(1023) << index << '\n';
    761     }
    762   }
    763 
    764   {
    765     ifstream in("big_file.txt");
    766     CPPUNIT_ASSERT( in );
    767 
    768     string line;
    769     vector<pair<streamsize, streamsize> >::const_iterator pit(file_pos.begin()),
    770                                                           pitEnd(file_pos.end());
    771     for (; pit != pitEnd; ++pit) {
    772       in.seekg((*pit).first);
    773       CPPUNIT_ASSERT( in );
    774       in >> line;
    775       size_t lastStarPos = line.rfind('*');
    776       CPPUNIT_ASSERT( atoi(line.substr(lastStarPos + 1).c_str()) == (*pit).second );
    777     }
    778   }
    779 
    780   /*
    781   The following test has been used to check that STLport do not generate
    782   an infinite loop when the file size is larger than the streamsize and
    783   streamoff representation (32 bits or 64 bits).
    784   {
    785     ifstream in("big_file.txt");
    786     CPPUNIT_ASSERT( in );
    787     char tmp[4096];
    788     streamsize nb_reads = 0;
    789     while ((!in.eof()) && in.good()){
    790       in.read(tmp, 4096);
    791       nb_reads += in.gcount();
    792     }
    793   }
    794   */
    795 }
    796 #  endif
    797 
    798 void FstreamTest::null_stream()
    799 {
    800 #  if (defined (STLPORT) && defined (_STLP_USE_WIN32_IO)) || \
    801       (!defined (STLPORT) && (defined (WIN32) || defined (_WIN32)))
    802   const char* nullStreamName = "NUL";
    803 #  else
    804   const char* nullStreamName = "/dev/null";
    805 #  endif
    806   {
    807     ofstream nullStream(nullStreamName);
    808     CPPUNIT_CHECK( nullStream );
    809   }
    810 
    811   {
    812     ofstream nullStream(nullStreamName, ios_base::ate);
    813     CPPUNIT_CHECK( nullStream );
    814   }
    815 
    816   {
    817     ofstream nullStream(nullStreamName, ios_base::trunc);
    818     CPPUNIT_CHECK( nullStream );
    819   }
    820 
    821   {
    822     ofstream nullStream(nullStreamName, ios_base::app);
    823     CPPUNIT_CHECK( nullStream );
    824   }
    825 
    826   {
    827     ifstream nullStream(nullStreamName);
    828     CPPUNIT_CHECK( nullStream );
    829   }
    830 
    831   {
    832     ifstream nullStream(nullStreamName, ios_base::ate);
    833     CPPUNIT_CHECK( nullStream );
    834   }
    835 
    836   {
    837     fstream nullStream(nullStreamName);
    838     CPPUNIT_CHECK( nullStream );
    839   }
    840 
    841   {
    842     fstream nullStream(nullStreamName, ios_base::in | ios_base::out | ios_base::ate);
    843     CPPUNIT_CHECK( nullStream );
    844   }
    845 
    846   {
    847     fstream nullStream(nullStreamName, ios_base::in | ios_base::out | ios_base::trunc);
    848     CPPUNIT_CHECK( nullStream );
    849   }
    850 }
    851 
    852 void FstreamTest::null_buf()
    853 {
    854   /* **********************************************************************************
    855 
    856   testcase for bug #1830513:
    857   in _istream.c
    858 
    859   template < class _CharT, class _Traits, class _Is_Delim>
    860   streamsize _STLP_CALL __read_unbuffered(basic_istream<_CharT, _Traits>* __that,
    861                                           basic_streambuf<_CharT, _Traits>* __buf,
    862                                           streamsize _Num, _CharT* __s,
    863                                           _Is_Delim __is_delim,
    864                                           bool __extract_delim, bool __append_null,
    865                                           bool __is_getline)
    866 
    867   can't accept _Num == 0; this is legal case, and may happen from
    868 
    869   template <class _CharT, class _Traits>
    870   basic_istream<_CharT, _Traits>&
    871   basic_istream<_CharT, _Traits>::getline(_CharT* __s, streamsize __n, _CharT __delim)
    872 
    873   *********************************************************************************** */
    874 
    875   fstream f( "test.txt", ios_base::in | ios_base::out | ios_base::trunc );
    876   // string line;
    877 
    878   for ( int i = 0; i < 0x200; ++i ) {
    879     f.put( ' ' );
    880   }
    881 
    882   // const streambuf *b = f.rdbuf();
    883 
    884   // string s;
    885   char buf[1024];
    886   buf[0] = 'a';
    887   buf[1] = 'b';
    888   buf[2] = 'c';
    889 
    890   // getline( f, s );
    891   // cerr << f.good() << endl;
    892   f.seekg( 0, ios_base::beg );
    893   // f.seekg( 0, ios_base::end );
    894   // buf[0] = f.get();
    895 
    896   // cerr << (void *)(b->_M_gptr()) << " " << (void *)(b->_M_egptr()) << endl;
    897   // cerr << f.good() << endl;
    898   // getline( f, s );
    899   f.getline( buf, 1 ); // <-- key line
    900   CPPUNIT_CHECK( buf[0] == 0 );
    901   CPPUNIT_CHECK( f.fail() ); // due to delimiter not found while buffer was exhausted
    902 }
    903 
    904 #  if !defined (STLPORT) || !defined (_STLP_WIN32)
    905 void FstreamTest::offset()
    906 {
    907 #    if (defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE)) && !defined(_STLP_USE_DEFAULT_FILE_OFFSET)
    908   CPPUNIT_CHECK( sizeof(streamoff) == 8 );
    909 #    else
    910   CPPUNIT_CHECK( sizeof(streamoff) == sizeof(off_t) );
    911 #    endif
    912 }
    913 #  endif
    914 
    915 #endif
    916