Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenfstream_test.cpp
Go to the documentation of this file.
00001 #include <string> 00002 #if !defined (STLPORT) || !defined (_STLP_USE_NO_IOSTREAMS) 00003 # include <fstream> 00004 # include <iostream> 00005 # include <iomanip> 00006 # include <sstream> 00007 # include <vector> 00008 # include <stdexcept> 00009 00010 #include <stdio.h> 00011 00012 # include "full_streambuf.h" 00013 # include "cppunit/cppunit_proxy.h" 00014 00015 # if !defined (STLPORT) || defined(_STLP_USE_NAMESPACES) 00016 using namespace std; 00017 # endif 00018 00019 //The macro value gives approximately the generated file 00020 //size in Go 00021 //#define CHECK_BIG_FILE 4 00022 00023 # if (!defined(STLPORT) && (defined (__GNUC__) && (__GNUC__ > 3))) || \ 00024 (defined (STLPORT) && !defined (_STLP_NO_CUSTOM_IO) && !defined (_STLP_NO_MEMBER_TEMPLATES) && \ 00025 !((defined (_STLP_MSVC) && (_STLP_MSVC < 1300)) || \ 00026 (defined (__GNUC__) && (__GNUC__ < 3)) || \ 00027 (defined (__SUNPRO_CC)) || \ 00028 (defined (__DMC__) && defined (_DLL)))) 00029 # define DO_CUSTOM_FACET_TEST 00030 # endif 00031 00032 // 00033 // TestCase class 00034 // 00035 class FstreamTest : public CPPUNIT_NS::TestCase 00036 { 00037 CPPUNIT_TEST_SUITE(FstreamTest); 00038 CPPUNIT_TEST(output); 00039 CPPUNIT_TEST(input); 00040 CPPUNIT_TEST(input_char); 00041 CPPUNIT_TEST(io); 00042 CPPUNIT_TEST(err); 00043 CPPUNIT_TEST(tellg); 00044 CPPUNIT_TEST(tellp); 00045 CPPUNIT_TEST(seek); 00046 CPPUNIT_TEST(buf); 00047 CPPUNIT_TEST(rdbuf); 00048 CPPUNIT_TEST(streambuf_output); 00049 CPPUNIT_TEST(win32_file_format); 00050 CPPUNIT_TEST(null_stream); 00051 # if defined (STLPORT) && (defined (_STLP_NO_WCHAR_T) || !defined (_STLP_USE_EXCEPTIONS)) 00052 CPPUNIT_IGNORE; 00053 # endif 00054 CPPUNIT_TEST(null_buf); 00055 # if !defined (STLPORT) || !defined (_STLP_WIN32) 00056 CPPUNIT_TEST(offset); 00057 # endif 00058 # if defined (CHECK_BIG_FILE) 00059 CPPUNIT_TEST(big_file); 00060 # endif 00061 # if !defined (DO_CUSTOM_FACET_TEST) 00062 CPPUNIT_IGNORE; 00063 # endif 00064 CPPUNIT_TEST(custom_facet); 00065 CPPUNIT_TEST_SUITE_END(); 00066 00067 protected: 00068 void output(); 00069 void input(); 00070 void input_char(); 00071 void io(); 00072 void err(); 00073 void tellg(); 00074 void tellp(); 00075 void seek(); 00076 void buf(); 00077 void rdbuf(); 00078 void streambuf_output(); 00079 void win32_file_format(); 00080 void null_stream(); 00081 void null_buf(); 00082 # if !defined (STLPORT) || !defined (_STLP_WIN32) 00083 void offset(); 00084 # endif 00085 void custom_facet(); 00086 # if defined (CHECK_BIG_FILE) 00087 void big_file(); 00088 # endif 00089 }; 00090 00091 CPPUNIT_TEST_SUITE_REGISTRATION(FstreamTest); 00092 00093 // 00094 // tests implementation 00095 // 00096 void FstreamTest::output() 00097 { 00098 ofstream f( "test_file.txt" ); 00099 00100 f << 1 << '\n' << 2.0 << '\n' << "abcd\n" << "ghk lm\n" << "abcd ef"; 00101 CPPUNIT_ASSERT (f.good()); 00102 // CPPUNIT_ASSERT( s.str() == "1\n2\nabcd\nghk lm\nabcd ef" ); 00103 } 00104 00105 void FstreamTest::input() 00106 { 00107 { 00108 ifstream f( "test_file.txt" ); 00109 int i = 0; 00110 f >> i; 00111 CPPUNIT_ASSERT( f.good() ); 00112 CPPUNIT_ASSERT( i == 1 ); 00113 double d = 0.0; 00114 f >> d; 00115 CPPUNIT_ASSERT( f.good() ); 00116 CPPUNIT_ASSERT( d == 2.0 ); 00117 string str; 00118 f >> str; 00119 CPPUNIT_ASSERT( f.good() ); 00120 CPPUNIT_ASSERT( str == "abcd" ); 00121 char c; 00122 f.get(c); // extract newline, that not extracted by operator >> 00123 CPPUNIT_ASSERT( f.good() ); 00124 CPPUNIT_ASSERT( c == '\n' ); 00125 getline( f, str ); 00126 CPPUNIT_ASSERT( f.good() ); 00127 CPPUNIT_ASSERT( str == "ghk lm" ); 00128 getline( f, str ); 00129 CPPUNIT_ASSERT( f.eof() ); 00130 CPPUNIT_ASSERT( str == "abcd ef" ); 00131 } 00132 #if defined (STLPORT) && !defined (_STLP_USE_WIN32_IO) 00133 { 00134 ifstream in("/tmp"); 00135 if (in.good()) { 00136 string s; 00137 getline(in, s); 00138 CPPUNIT_ASSERT( in.fail() ); 00139 } 00140 } 00141 #endif 00142 } 00143 00144 void FstreamTest::input_char() 00145 { 00146 char buf[16] = { 0, '1', '2', '3' }; 00147 ifstream s( "test_file.txt" ); 00148 s >> buf; 00149 00150 CPPUNIT_ASSERT( buf[0] == '1' ); 00151 CPPUNIT_ASSERT( buf[1] == 0 ); 00152 CPPUNIT_ASSERT( buf[2] == '2' ); 00153 } 00154 00155 void FstreamTest::io() 00156 { 00157 basic_fstream<char,char_traits<char> > f( "test_file.txt", ios_base::in | ios_base::out | ios_base::trunc ); 00158 00159 CPPUNIT_ASSERT( f.is_open() ); 00160 00161 f << 1 << '\n' << 2.0 << '\n' << "abcd\n" << "ghk lm\n" << "abcd ef"; 00162 00163 // f.flush(); 00164 f.seekg( 0, ios_base::beg ); 00165 00166 int i = 0; 00167 f >> i; 00168 CPPUNIT_ASSERT( f.good() ); 00169 CPPUNIT_ASSERT( i == 1 ); 00170 double d = 0.0; 00171 f >> d; 00172 CPPUNIT_ASSERT( d == 2.0 ); 00173 string s; 00174 f >> s; 00175 CPPUNIT_ASSERT( f.good() ); 00176 CPPUNIT_ASSERT( s == "abcd" ); 00177 char c; 00178 f.get(c); // extract newline, that not extracted by operator >> 00179 CPPUNIT_ASSERT( f.good() ); 00180 CPPUNIT_ASSERT( c == '\n' ); 00181 getline( f, s ); 00182 CPPUNIT_ASSERT( f.good() ); 00183 CPPUNIT_ASSERT( s == "ghk lm" ); 00184 getline( f, s ); 00185 CPPUNIT_ASSERT( !f.fail() ); 00186 CPPUNIT_ASSERT( s == "abcd ef" ); 00187 CPPUNIT_ASSERT( f.eof() ); 00188 } 00189 00190 void FstreamTest::err() 00191 { 00192 basic_fstream<char,char_traits<char> > f( "test_file.txt", ios_base::in | ios_base::out | ios_base::trunc ); 00193 00194 CPPUNIT_ASSERT( f.is_open() ); 00195 00196 int i = 9; 00197 f << i; 00198 CPPUNIT_ASSERT( f.good() ); 00199 i = 0; 00200 f.seekg( 0, ios_base::beg ); 00201 f >> i; 00202 CPPUNIT_ASSERT( !f.fail() ); 00203 CPPUNIT_ASSERT( i == 9 ); 00204 f >> i; 00205 CPPUNIT_ASSERT( f.fail() ); 00206 CPPUNIT_ASSERT( f.eof() ); 00207 CPPUNIT_ASSERT( i == 9 ); 00208 } 00209 00210 void FstreamTest::tellg() 00211 { 00212 { 00213 // bogus ios_base::binary is for Wins 00214 ofstream of("test_file.txt", ios_base::out | ios_base::binary | ios_base::trunc); 00215 CPPUNIT_ASSERT( of.is_open() ); 00216 00217 for (int i = 0; i < 50; ++i) { 00218 of << "line " << setiosflags(ios_base::right) << setfill('0') << setw(2) << i << "\n"; 00219 CPPUNIT_ASSERT( !of.fail() ); 00220 } 00221 of.close(); 00222 } 00223 00224 { 00225 // bogus ios_base::binary is for Wins 00226 ifstream is("test_file.txt", ios_base::in | ios_base::binary); 00227 CPPUNIT_ASSERT( is.is_open() ); 00228 char buf[64]; 00229 00230 // CPPUNIT_ASSERT( is.tellg() == 0 ); 00231 streampos p = 0; 00232 for (int i = 0; i < 50; ++i) { 00233 is.read(buf, 0); 00234 CPPUNIT_ASSERT( is.gcount() == 0 ); 00235 CPPUNIT_ASSERT( is.tellg() == p ); 00236 is.read( buf, 8 ); 00237 CPPUNIT_ASSERT( !is.fail() ); 00238 CPPUNIT_ASSERT( is.gcount() == 8 ); 00239 p += 8; 00240 } 00241 } 00242 00243 { 00244 // bogus ios_base::binary is for Wins 00245 ifstream is("test_file.txt", ios_base::in | ios_base::binary); 00246 CPPUNIT_ASSERT( is.is_open() ); 00247 00248 streampos p = 0; 00249 for (int i = 0; i < 50; ++i) { 00250 CPPUNIT_ASSERT( !is.fail() ); 00251 is.tellg(); 00252 CPPUNIT_ASSERT( is.tellg() == p ); 00253 p += 8; 00254 is.seekg( p, ios_base::beg ); 00255 CPPUNIT_ASSERT( !is.fail() ); 00256 } 00257 } 00258 00259 { 00260 // bogus ios_base::binary is for Wins 00261 ifstream is("test_file.txt", ios_base::in | ios_base::binary); 00262 CPPUNIT_ASSERT( is.is_open() ); 00263 00264 streampos p = 0; 00265 for (int i = 0; i < 50; ++i) { 00266 CPPUNIT_ASSERT( is.tellg() == p ); 00267 p += 8; 00268 is.seekg( 8, ios_base::cur ); 00269 CPPUNIT_ASSERT( !is.fail() ); 00270 } 00271 } 00272 } 00273 00274 void FstreamTest::tellp() 00275 { 00276 { 00277 ofstream o( "test_file.txt" ); 00278 00279 o << "123456"; 00280 00281 CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == ofstream::pos_type(6) ); 00282 CPPUNIT_CHECK( o.tellp() == ofstream::pos_type(6) ); 00283 } 00284 { 00285 ofstream o( "test_file.txt" ); 00286 00287 o << "123456789"; 00288 00289 CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == ofstream::pos_type(9) ); 00290 CPPUNIT_CHECK( o.tellp() == ofstream::pos_type(9) ); 00291 } 00292 /* According to the standard 00293 ofstream o( "test_file.txt", ios_base::app | ios_base::out ) 00294 should give the same effect as fopen( "test_file.txt", "a" ). 00295 Problem is fopen( "test_file.txt", "a" ) has a bit different behaviour 00296 on different platforms, and this difference is not covered by specification. 00297 After fopen( "test_file.txt", "a" ) in this context ftell( f ) == 9 for 00298 Linux and Mac OS X (I expect the same for others POSIX-like platforms too); 00299 on Windows (independently from version?) ftell( f ) == 0, i.e. write pointer not 00300 shifted to EOF (but shifted to EOF just before write, as described in the specs). 00301 00302 It isn't specifications violation, neither for Linux and Mac OS X nor for Windows. 00303 00304 The code below is intended to demonstrate ambiguity (dependance from fopen implementation). 00305 */ 00306 { 00307 #ifdef WIN32 00308 //In Windows, stlport and fopen use kernel32.CreateFile for open. 00309 //File position is at BOF after open, unless we open with ios_base::ate 00310 long expected_pos = 0; 00311 #else 00312 //On UNIX flavours, stlport and fopen use unix's open 00313 //File position is at EOF after open 00314 // 00315 //3rd possible scenario, "other platforms" - _STLP_USE_STDIO_IO 00316 //stlport uses fopen here. This case may fail this test, since the file position after 00317 //fopen is implementation-dependent 00318 long expected_pos = 9; 00319 #endif 00320 ofstream o( "test_file.txt", ios_base::app | ios_base::out ); 00321 CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == ofstream::pos_type(expected_pos) ); 00322 CPPUNIT_CHECK( o.tellp() == ofstream::pos_type(expected_pos) ); 00323 } 00324 { // for reference, to test fopen/ftell behaviour in append mode: 00325 #ifdef WIN32 00326 long expected_pos = 0; 00327 #else 00328 long expected_pos = 9; 00329 #endif 00330 FILE* f = fopen( "test_file.txt", "a" ); 00331 CPPUNIT_CHECK( ftell( f ) == expected_pos ); 00332 fclose( f ); 00333 } 00334 { 00335 //In append mode, file is positioned at EOF just before a write. 00336 // After a write, file is at EOF. This is implementation-independent. 00337 ofstream o( "test_file.txt", ios_base::app | ios_base::out ); 00338 o << "X"; 00339 CPPUNIT_CHECK( o.rdbuf()->pubseekoff( 0, ios_base::cur, ios_base::out ) == ofstream::pos_type(10) ); 00340 CPPUNIT_CHECK( o.tellp() == ofstream::pos_type(10) ); 00341 } 00342 } 00343 00344 void FstreamTest::buf() 00345 { 00346 fstream ss( "test_file.txt", ios_base::in | ios_base::out | ios_base::binary | ios_base::trunc ); 00347 00348 ss << "1234567\n89\n"; 00349 ss.seekg( 0, ios_base::beg ); 00350 char buf[10]; 00351 buf[7] = 'x'; 00352 ss.get( buf, 10 ); 00353 CPPUNIT_ASSERT( !ss.fail() ); 00354 CPPUNIT_ASSERT( buf[0] == '1' ); 00355 CPPUNIT_ASSERT( buf[1] == '2' ); 00356 CPPUNIT_ASSERT( buf[2] == '3' ); 00357 CPPUNIT_ASSERT( buf[3] == '4' ); 00358 CPPUNIT_ASSERT( buf[4] == '5' ); 00359 CPPUNIT_ASSERT( buf[5] == '6' ); 00360 CPPUNIT_ASSERT( buf[6] == '7' ); // 27.6.1.3 paragraph 10, paragraph 7 00361 CPPUNIT_ASSERT( buf[7] == 0 ); // 27.6.1.3 paragraph 8 00362 char c; 00363 ss.get(c); 00364 CPPUNIT_ASSERT( !ss.fail() ); 00365 CPPUNIT_ASSERT( c == '\n' ); // 27.6.1.3 paragraph 10, paragraph 7 00366 ss.get(c); 00367 CPPUNIT_ASSERT( !ss.fail() ); 00368 CPPUNIT_ASSERT( c == '8' ); 00369 } 00370 00371 void FstreamTest::seek() 00372 { 00373 { 00374 // Test in binary mode: 00375 { 00376 fstream s( "test_file.txt", ios_base::in | ios_base::out | ios_base::binary | ios_base::trunc ); 00377 CPPUNIT_ASSERT( s ); 00378 00379 s << "1234567890\n"; 00380 CPPUNIT_ASSERT( s ); 00381 } 00382 00383 char b1[] = { 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x' }; 00384 fstream s( "test_file.txt", ios_base::in | ios_base::out | ios_base::binary ); 00385 CPPUNIT_ASSERT( s ); 00386 00387 int chars_read = (int)s.rdbuf()->sgetn( b1, sizeof(b1) ); 00388 CPPUNIT_CHECK( chars_read == 11 ); 00389 CPPUNIT_CHECK( b1[9] == '0' ); 00390 CPPUNIT_ASSERT( s.rdbuf()->pubseekoff( 0, ios_base::cur ) == fstream::pos_type(chars_read) ); 00391 CPPUNIT_ASSERT( s.rdbuf()->pubseekoff( -chars_read, ios_base::cur ) == fstream::pos_type(0) ); 00392 00393 char b2[10] = { 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y' }; 00394 00395 CPPUNIT_ASSERT( s.rdbuf()->sgetn( b2, 10 ) == 10 ); 00396 CPPUNIT_CHECK( b2[9] == '0' ); 00397 } 00398 00399 { 00400 // Test in text mode: 00401 { 00402 fstream s( "test_file.txt", ios_base::in | ios_base::out | ios_base::trunc ); 00403 CPPUNIT_ASSERT( s ); 00404 00405 s << "1234567890\n"; 00406 CPPUNIT_ASSERT( s ); 00407 } 00408 00409 char b1[] = { 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x', 'x' }; 00410 fstream s( "test_file.txt", ios_base::in | ios_base::out ); 00411 CPPUNIT_ASSERT( s ); 00412 00413 int chars_read = (int)s.rdbuf()->sgetn( b1, sizeof(b1) ); 00414 CPPUNIT_CHECK( chars_read == 11 ); 00415 CPPUNIT_CHECK( b1[9] == '0' ); 00416 00417 fstream::pos_type pos = s.rdbuf()->pubseekoff(0, ios_base::cur); 00418 // Depending on how '\n' is written in file, file position can be greater or equal to the number of chars_read read. 00419 streamoff offset = pos; 00420 CPPUNIT_ASSERT( offset >= chars_read ); 00421 offset = s.rdbuf()->pubseekoff( -offset, ios_base::cur ); 00422 CPPUNIT_ASSERT( offset == 0 ); 00423 00424 char b2[10] = { 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y', 'y' }; 00425 00426 CPPUNIT_ASSERT( s.rdbuf()->sgetn( b2, 5 ) == 5 ); 00427 CPPUNIT_CHECK( b2[4] == '5' ); 00428 00429 pos = s.rdbuf()->pubseekoff(0, ios_base::cur); 00430 CPPUNIT_ASSERT( pos == fstream::pos_type(5) ); 00431 CPPUNIT_ASSERT( s.rdbuf()->pubseekoff(-5, ios_base::cur) == fstream::pos_type(0) ); 00432 } 00433 00434 #if !defined (STLPORT) || \ 00435 (!defined (_STLP_NO_WCHAR_T) && defined (_STLP_USE_EXCEPTIONS)) 00436 { 00437 // Test with a wariable encoding: 00438 locale loc; 00439 try 00440 { 00441 locale tmp(locale::classic(), new codecvt_byname<wchar_t, char, mbstate_t>(".UTF8")); 00442 loc = tmp; 00443 } 00444 catch (const runtime_error&) 00445 { 00446 // Localization no supported so no test: 00447 return; 00448 } 00449 00450 { 00451 wfstream s( "test_file.txt", ios_base::in | ios_base::out | ios_base::trunc ); 00452 CPPUNIT_ASSERT( s ); 00453 s.imbue(loc); 00454 CPPUNIT_ASSERT( s ); 00455 00456 s << L"1234567890\n"; 00457 CPPUNIT_ASSERT( s ); 00458 } 00459 00460 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' }; 00461 wfstream s( "test_file.txt", ios_base::in | ios_base::out ); 00462 CPPUNIT_ASSERT( s ); 00463 s.imbue(loc); 00464 CPPUNIT_ASSERT( s ); 00465 00466 int chars_read = (int)s.rdbuf()->sgetn( b1, sizeof(b1) / sizeof(wchar_t) ); 00467 CPPUNIT_CHECK( chars_read == 11 ); 00468 CPPUNIT_CHECK( b1[9] == L'0' ); 00469 00470 fstream::pos_type pos = s.rdbuf()->pubseekoff(0, ios_base::cur); 00471 // Depending on how '\n' is written in file, file position can be greater or equal to the number of chars_read read. 00472 streamoff off = pos; 00473 CPPUNIT_ASSERT( off >= chars_read ); 00474 off = s.rdbuf()->pubseekoff(-off, ios_base::cur); 00475 CPPUNIT_ASSERT( off == -1 ); 00476 off = s.rdbuf()->pubseekoff(0, ios_base::beg); 00477 CPPUNIT_ASSERT( off == 0 ); 00478 00479 wchar_t b2[10] = { L'y', L'y', L'y', L'y', L'y', L'y', L'y', L'y', L'y', L'y' }; 00480 00481 CPPUNIT_ASSERT( s.rdbuf()->sgetn( b2, 5 ) == 5 ); 00482 CPPUNIT_CHECK( b2[4] == L'5' ); 00483 00484 pos = s.rdbuf()->pubseekoff(0, ios_base::cur); 00485 CPPUNIT_ASSERT( pos == fstream::pos_type(5) ); 00486 //CPPUNIT_ASSERT( s.rdbuf()->pubseekoff(-5, ios_base::cur) == fstream::pos_type(0) ); 00487 } 00488 #endif 00489 } 00490 00491 void FstreamTest::rdbuf() 00492 { 00493 fstream ss( "test_file.txt", ios_base::in | ios_base::out | ios_base::binary | ios_base::trunc ); 00494 00495 ss << "1234567\n89\n"; 00496 ss.seekg( 0, ios_base::beg ); 00497 00498 ostringstream os; 00499 ss.get( *os.rdbuf(), '\n' ); 00500 CPPUNIT_ASSERT( !ss.fail() ); 00501 char c; 00502 ss.get(c); 00503 CPPUNIT_ASSERT( !ss.fail() ); 00504 CPPUNIT_ASSERT( c == '\n' ); // 27.6.1.3 paragraph 12 00505 CPPUNIT_ASSERT( os.str() == "1234567" ); 00506 } 00507 00508 void FstreamTest::streambuf_output() 00509 { 00510 { 00511 ofstream ofstr("test_file.txt", ios_base::binary); 00512 if (!ofstr) 00513 //No test if we cannot create the file 00514 return; 00515 ofstr << "01234567890123456789"; 00516 CPPUNIT_ASSERT( ofstr ); 00517 } 00518 00519 { 00520 ifstream in("test_file.txt", ios_base::binary); 00521 CPPUNIT_ASSERT( in ); 00522 00523 full_streambuf full_buf(10); 00524 ostream out(&full_buf); 00525 CPPUNIT_ASSERT( out ); 00526 00527 out << in.rdbuf(); 00528 CPPUNIT_ASSERT( out ); 00529 CPPUNIT_ASSERT( in ); 00530 CPPUNIT_ASSERT( full_buf.str() == "0123456789" ); 00531 00532 out << in.rdbuf(); 00533 CPPUNIT_ASSERT( out.fail() ); 00534 CPPUNIT_ASSERT( in ); 00535 00536 ostringstream ostr; 00537 ostr << in.rdbuf(); 00538 CPPUNIT_ASSERT( ostr ); 00539 CPPUNIT_ASSERT( in ); 00540 CPPUNIT_ASSERT( ostr.str() == "0123456789" ); 00541 } 00542 00543 # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 00544 { 00545 //If the output stream buffer throws: 00546 ifstream in("test_file.txt", ios_base::binary); 00547 CPPUNIT_ASSERT( in ); 00548 00549 full_streambuf full_buf(10, true); 00550 ostream out(&full_buf); 00551 CPPUNIT_ASSERT( out ); 00552 00553 out << in.rdbuf(); 00554 CPPUNIT_ASSERT( out.bad() ); 00555 CPPUNIT_ASSERT( in ); 00556 //out is bad we have no guaranty on what has been extracted: 00557 //CPPUNIT_ASSERT( full_buf.str() == "0123456789" ); 00558 00559 out.clear(); 00560 out << in.rdbuf(); 00561 CPPUNIT_ASSERT( out.fail() && out.bad() ); 00562 CPPUNIT_ASSERT( in ); 00563 00564 ostringstream ostr; 00565 ostr << in.rdbuf(); 00566 CPPUNIT_ASSERT( ostr ); 00567 CPPUNIT_ASSERT( in ); 00568 CPPUNIT_ASSERT( ostr.str() == "0123456789" ); 00569 } 00570 # endif 00571 } 00572 00573 void FstreamTest::win32_file_format() 00574 { 00575 const char* file_name = "win32_file_format.tmp"; 00576 const size_t nb_lines = 2049; 00577 { 00578 ofstream out(file_name); 00579 CPPUNIT_ASSERT( out.good() ); 00580 out << 'a'; 00581 for (size_t i = 0; i < nb_lines - 1; ++i) { 00582 out << '\n'; 00583 } 00584 out << '\r'; 00585 CPPUNIT_ASSERT( out.good() ); 00586 } 00587 { 00588 ifstream in(file_name); 00589 CPPUNIT_ASSERT( in.good() ); 00590 string line, last_line; 00591 size_t nb_read_lines = 0; 00592 while (getline(in, line)) { 00593 ++nb_read_lines; 00594 last_line = line; 00595 } 00596 CPPUNIT_ASSERT( in.eof() ); 00597 CPPUNIT_ASSERT( nb_read_lines == nb_lines ); 00598 CPPUNIT_ASSERT( !last_line.empty() && (last_line[0] == '\r') ); 00599 } 00600 } 00601 00602 #if defined (DO_CUSTOM_FACET_TEST) 00603 struct my_state { 00604 char dummy; 00605 }; 00606 00607 struct my_traits : public char_traits<char> { 00608 typedef my_state state_type; 00609 typedef fpos<state_type> pos_type; 00610 }; 00611 00612 #if !defined (STLPORT) 00613 //STLport grant a default implementation, other Standard libs implementation 00614 //do not necessarily do the same: 00615 namespace std { 00616 template <> 00617 class codecvt<char, char, my_state> 00618 : public locale::facet, public codecvt_base { 00619 public: 00620 typedef char intern_type; 00621 typedef char extern_type; 00622 typedef my_state state_type; 00623 00624 explicit codecvt(size_t __refs = 0) : locale::facet(__refs) {} 00625 result out(state_type&, 00626 const intern_type* __from, 00627 const intern_type*, 00628 const intern_type*& __from_next, 00629 extern_type* __to, 00630 extern_type*, 00631 extern_type*& __to_next) const 00632 { __from_next = __from; __to_next = __to; return noconv; } 00633 00634 result in (state_type&, 00635 const extern_type* __from, 00636 const extern_type*, 00637 const extern_type*& __from_next, 00638 intern_type* __to, 00639 intern_type*, 00640 intern_type*& __to_next) const 00641 { __from_next = __from; __to_next = __to; return noconv; } 00642 00643 result unshift(state_type&, 00644 extern_type* __to, 00645 extern_type*, 00646 extern_type*& __to_next) const 00647 { __to_next = __to; return noconv; } 00648 00649 int encoding() const throw() 00650 { return 1; } 00651 00652 bool always_noconv() const throw() 00653 { return true; } 00654 00655 int length(const state_type&, 00656 const extern_type* __from, 00657 const extern_type* __end, 00658 size_t __max) const 00659 { return (int)min(static_cast<size_t>(__end - __from), __max); } 00660 00661 int max_length() const throw() 00662 { return 1; } 00663 00664 static locale::id id; 00665 }; 00666 00667 locale::id codecvt<char, char, my_state>::id; 00668 } 00669 # else 00670 # if defined (__BORLANDC__) && (__BORLANDC__ < 0x590) 00671 template <> 00672 locale::id codecvt<char, char, my_state>::id; 00673 # endif 00674 # endif 00675 #endif 00676 00677 void FstreamTest::custom_facet() 00678 { 00679 #if defined (DO_CUSTOM_FACET_TEST) 00680 const char* fileName = "test_file.txt"; 00681 //File preparation: 00682 { 00683 ofstream ofstr(fileName, ios_base::binary); 00684 ofstr << "0123456789"; 00685 CPPUNIT_ASSERT( ofstr ); 00686 } 00687 00688 { 00689 typedef basic_ifstream<char, my_traits> my_ifstream; 00690 typedef basic_string<char, my_traits> my_string; 00691 00692 my_ifstream ifstr(fileName); 00693 CPPUNIT_ASSERT( ifstr ); 00694 00695 # if !defined (STLPORT) || defined (_STLP_USE_EXCEPTIONS) 00696 ifstr.imbue(locale::classic()); 00697 CPPUNIT_ASSERT( ifstr.fail() && !ifstr.bad() ); 00698 ifstr.clear(); 00699 # endif 00700 typedef codecvt<char, char, my_state> my_codecvt; 00701 locale my_loc(locale::classic(), new my_codecvt()); 00702 // Check that my_codecvt has not replace default codecvt: 00703 CPPUNIT_ASSERT( (has_facet<my_codecvt>(my_loc)) ); 00704 CPPUNIT_ASSERT( (has_facet<codecvt<char, char, mbstate_t> >(my_loc)) ); 00705 # if !defined (STLPORT) || !defined (_STLP_NO_WCHAR_T) 00706 CPPUNIT_ASSERT( (has_facet<codecvt<wchar_t, char, mbstate_t> >(my_loc)) ); 00707 # endif 00708 ifstr.imbue(my_loc); 00709 CPPUNIT_ASSERT( ifstr.good() ); 00710 /* 00711 my_string res; 00712 ifstr >> res; 00713 CPPUNIT_ASSERT( !ifstr.fail() ); 00714 CPPUNIT_ASSERT( !ifstr.bad() ); 00715 CPPUNIT_ASSERT( ifstr.eof() ); 00716 CPPUNIT_ASSERT( res == "0123456789" ); 00717 */ 00718 } 00719 #endif 00720 } 00721 00722 # if defined (CHECK_BIG_FILE) 00723 void FstreamTest::big_file() 00724 { 00725 vector<pair<streamsize, streamoff> > file_pos; 00726 00727 //Big file creation: 00728 { 00729 ofstream out("big_file.txt"); 00730 CPPUNIT_ASSERT( out ); 00731 00732 //We are going to generate a file with the following schema for the content: 00733 //0(1019 times)0000 //1023 characters + 1 charater for \n (for some platforms it will be a 1 ko line) 00734 //0(1019 times)0001 00735 //... 00736 //0(1019 times)1234 00737 //... 00738 00739 //Generation of the number of loop: 00740 streamoff nb = 1; 00741 for (int i = 0; i < 20; ++i) { 00742 //This assertion check that the streamoff can at least represent the necessary integers values 00743 //for this test: 00744 CPPUNIT_ASSERT( (nb << 1) > nb ); 00745 nb <<= 1; 00746 } 00747 CPPUNIT_ASSERT( nb * CHECK_BIG_FILE >= nb ); 00748 nb *= CHECK_BIG_FILE; 00749 00750 //Preparation of the ouput stream state: 00751 out << setiosflags(ios_base::right) << setfill('*'); 00752 for (streamoff index = 0; index < nb; ++index) { 00753 if (index % 1024 == 0) { 00754 file_pos.push_back(make_pair(out.tellp(), index)); 00755 CPPUNIT_ASSERT( file_pos.back().first != streamsize(-1) ); 00756 if (file_pos.size() > 1) { 00757 CPPUNIT_ASSERT( file_pos[file_pos.size() - 1].first > file_pos[file_pos.size() - 2].first ); 00758 } 00759 } 00760 out << setw(1023) << index << '\n'; 00761 } 00762 } 00763 00764 { 00765 ifstream in("big_file.txt"); 00766 CPPUNIT_ASSERT( in ); 00767 00768 string line; 00769 vector<pair<streamsize, streamsize> >::const_iterator pit(file_pos.begin()), 00770 pitEnd(file_pos.end()); 00771 for (; pit != pitEnd; ++pit) { 00772 in.seekg((*pit).first); 00773 CPPUNIT_ASSERT( in ); 00774 in >> line; 00775 size_t lastStarPos = line.rfind('*'); 00776 CPPUNIT_ASSERT( atoi(line.substr(lastStarPos + 1).c_str()) == (*pit).second ); 00777 } 00778 } 00779 00780 /* 00781 The following test has been used to check that STLport do not generate 00782 an infinite loop when the file size is larger than the streamsize and 00783 streamoff representation (32 bits or 64 bits). 00784 { 00785 ifstream in("big_file.txt"); 00786 CPPUNIT_ASSERT( in ); 00787 char tmp[4096]; 00788 streamsize nb_reads = 0; 00789 while ((!in.eof()) && in.good()){ 00790 in.read(tmp, 4096); 00791 nb_reads += in.gcount(); 00792 } 00793 } 00794 */ 00795 } 00796 # endif 00797 00798 void FstreamTest::null_stream() 00799 { 00800 # if (defined (STLPORT) && defined (_STLP_USE_WIN32_IO)) || \ 00801 (!defined (STLPORT) && (defined (WIN32) || defined (_WIN32))) 00802 const char* nullStreamName = "NUL"; 00803 # else 00804 const char* nullStreamName = "/dev/null"; 00805 # endif 00806 { 00807 ofstream nullStream(nullStreamName); 00808 CPPUNIT_CHECK( nullStream ); 00809 } 00810 00811 { 00812 ofstream nullStream(nullStreamName, ios_base::ate); 00813 CPPUNIT_CHECK( nullStream ); 00814 } 00815 00816 { 00817 ofstream nullStream(nullStreamName, ios_base::trunc); 00818 CPPUNIT_CHECK( nullStream ); 00819 } 00820 00821 { 00822 ofstream nullStream(nullStreamName, ios_base::app); 00823 CPPUNIT_CHECK( nullStream ); 00824 } 00825 00826 { 00827 ifstream nullStream(nullStreamName); 00828 CPPUNIT_CHECK( nullStream ); 00829 } 00830 00831 { 00832 ifstream nullStream(nullStreamName, ios_base::ate); 00833 CPPUNIT_CHECK( nullStream ); 00834 } 00835 00836 { 00837 fstream nullStream(nullStreamName); 00838 CPPUNIT_CHECK( nullStream ); 00839 } 00840 00841 { 00842 fstream nullStream(nullStreamName, ios_base::in | ios_base::out | ios_base::ate); 00843 CPPUNIT_CHECK( nullStream ); 00844 } 00845 00846 { 00847 fstream nullStream(nullStreamName, ios_base::in | ios_base::out | ios_base::trunc); 00848 CPPUNIT_CHECK( nullStream ); 00849 } 00850 } 00851 00852 void FstreamTest::null_buf() 00853 { 00854 /* ********************************************************************************** 00855 00856 testcase for bug #1830513: 00857 in _istream.c 00858 00859 template < class _CharT, class _Traits, class _Is_Delim> 00860 streamsize _STLP_CALL __read_unbuffered(basic_istream<_CharT, _Traits>* __that, 00861 basic_streambuf<_CharT, _Traits>* __buf, 00862 streamsize _Num, _CharT* __s, 00863 _Is_Delim __is_delim, 00864 bool __extract_delim, bool __append_null, 00865 bool __is_getline) 00866 00867 can't accept _Num == 0; this is legal case, and may happen from 00868 00869 template <class _CharT, class _Traits> 00870 basic_istream<_CharT, _Traits>& 00871 basic_istream<_CharT, _Traits>::getline(_CharT* __s, streamsize __n, _CharT __delim) 00872 00873 *********************************************************************************** */ 00874 00875 fstream f( "test.txt", ios_base::in | ios_base::out | ios_base::trunc ); 00876 // string line; 00877 00878 for ( int i = 0; i < 0x200; ++i ) { 00879 f.put( ' ' ); 00880 } 00881 00882 // const streambuf *b = f.rdbuf(); 00883 00884 // string s; 00885 char buf[1024]; 00886 buf[0] = 'a'; 00887 buf[1] = 'b'; 00888 buf[2] = 'c'; 00889 00890 // getline( f, s ); 00891 // cerr << f.good() << endl; 00892 f.seekg( 0, ios_base::beg ); 00893 // f.seekg( 0, ios_base::end ); 00894 // buf[0] = f.get(); 00895 00896 // cerr << (void *)(b->_M_gptr()) << " " << (void *)(b->_M_egptr()) << endl; 00897 // cerr << f.good() << endl; 00898 // getline( f, s ); 00899 f.getline( buf, 1 ); // <-- key line 00900 CPPUNIT_CHECK( buf[0] == 0 ); 00901 CPPUNIT_CHECK( f.fail() ); // due to delimiter not found while buffer was exhausted 00902 } 00903 00904 # if !defined (STLPORT) || !defined (_STLP_WIN32) 00905 void FstreamTest::offset() 00906 { 00907 # if (defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE)) && !defined(_STLP_USE_DEFAULT_FILE_OFFSET) 00908 CPPUNIT_CHECK( sizeof(streamoff) == 8 ); 00909 # else 00910 CPPUNIT_CHECK( sizeof(streamoff) == sizeof(off_t) ); 00911 # endif 00912 } 00913 # endif 00914 00915 #endif Generated on Sun May 27 2012 04:35:24 for ReactOS by
1.7.6.1
|