OSDN Git Service

original
[gb-231r1-is01/Gingerbread_2.3.3_r1_IS01.git] / ndk / tests / device / test-stlport / unit / fstream_test.cpp
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