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