Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4680 right-hear 1
// File based streams -*- C++ -*-
2
 
3
// Copyright (C) 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
4
//
5
// This file is part of the GNU ISO C++ Library.  This library is free
6
// software; you can redistribute it and/or modify it under the
7
// terms of the GNU General Public License as published by the
8
// Free Software Foundation; either version 2, or (at your option)
9
// any later version.
10
 
11
// This library is distributed in the hope that it will be useful,
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
// GNU General Public License for more details.
15
 
16
// You should have received a copy of the GNU General Public License along
17
// with this library; see the file COPYING.  If not, write to the Free
18
// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19
// USA.
20
 
21
// As a special exception, you may use this file as part of a free software
22
// library without restriction.  Specifically, if other files instantiate
23
// templates or use macros or inline functions from this file, or you compile
24
// this file and link it with other files to produce an executable, this
25
// file does not by itself cause the resulting executable to be covered by
26
// the GNU General Public License.  This exception does not however
27
// invalidate any other reasons why the executable file might be covered by
28
// the GNU General Public License.
29
 
30
//
31
// ISO C++ 14882: 27.8  File-based streams
32
//
33
 
34
#ifndef _CPP_FSTREAM
35
#define _CPP_FSTREAM	1
36
 
37
#pragma GCC system_header
38
 
39
#include 
40
#include 
41
#include 
42
#include 	// For codecvt
43
#include 
44
 
45
namespace std
46
{
47
  template
48
    class basic_filebuf : public basic_streambuf<_CharT, _Traits>
49
    {
50
    public:
51
      // Types:
52
      typedef _CharT                     	        char_type;
53
      typedef _Traits                    	        traits_type;
54
      typedef typename traits_type::int_type 		int_type;
55
      typedef typename traits_type::pos_type 		pos_type;
56
      typedef typename traits_type::off_type 		off_type;
57
 
58
      // Non-standard Types:
59
      typedef basic_streambuf  	__streambuf_type;
60
      typedef basic_filebuf     __filebuf_type;
61
      typedef __basic_file		        __file_type;
62
      typedef typename traits_type::state_type          __state_type;
63
      typedef codecvt    __codecvt_type;
64
      typedef typename __codecvt_type::result 	        __res_type;
65
      typedef ctype                          __ctype_type;
66
 
67
      friend class ios_base; // For sync_with_stdio.
68
 
69
    private:
70
      // Data Members:
71
      // External buffer.
72
      __file_type* 		_M_file;
73
 
74
      // Current and beginning state type for codecvt.
75
      __state_type		_M_state_cur;
76
      __state_type 		_M_state_beg;
77
 
78
      // MT lock inherited from libio or other low-level io library.
79
      __c_lock          	_M_lock;
80
 
81
      // Set iff _M_buf is allocated memory from _M_allocate_internal_buffer..
82
      bool			_M_buf_allocated;
83
 
84
      // XXX Needed?
85
      bool			_M_last_overflowed;
86
 
87
    public:
88
      // Constructors/destructor:
89
      basic_filebuf();
90
 
91
      // Non-standard ctor:
92
      basic_filebuf(__c_file_type* __f, ios_base::openmode __mode,
93
		    int_type __s = static_cast(BUFSIZ));
94
 
95
      virtual
96
      ~basic_filebuf()
97
      {
98
	this->close();
99
	_M_last_overflowed = false;
100
      }
101
 
102
      // Members:
103
      bool
104
      is_open(void) const { return _M_file ? _M_file->is_open() : false; }
105
 
106
      __filebuf_type*
107
      open(const char* __s, ios_base::openmode __mode);
108
 
109
      __filebuf_type*
110
      close(void);
111
 
112
    protected:
113
      void
114
      _M_allocate_internal_buffer();
115
 
116
      void
117
      _M_destroy_internal_buffer();
118
 
119
      void
120
      _M_allocate_pback_buffer();
121
 
122
      // Create __file_type object and initialize it properly.
123
      void
124
      _M_allocate_file();
125
 
126
      // Overridden virtual functions:
127
      virtual streamsize
128
      showmanyc(void);
129
 
130
      // Stroustrup, 1998, p. 628
131
      // underflow() and uflow() functions are called to get the next
132
      // charater from the real input source when the buffer is empty.
133
      // Buffered input uses underflow()
134
      virtual int_type
135
      underflow(void);
136
 
137
      virtual int_type
138
      pbackfail(int_type __c = _Traits::eof());
139
 
140
      // NB: For what the standard expects of the overflow function,
141
      // see _M_really_overflow(), below. Because basic_streambuf's
142
      // sputc/sputn call overflow directly, and the complications of
143
      // this implementation's setting of the initial pointers all
144
      // equal to _M_buf when initializing, it seems essential to have
145
      // this in actuality be a helper function that checks for the
146
      // eccentricities of this implementation, and then call
147
      // overflow() if indeed the buffer is full.
148
      virtual int_type
149
      overflow(int_type __c = _Traits::eof());
150
 
151
      // Stroustrup, 1998, p 648
152
      // The overflow() function is called to transfer characters to the
153
      // real output destination when the buffer is full. A call to
154
      // overflow(c) outputs the contents of the buffer plus the
155
      // character c.
156
      // 27.5.2.4.5
157
      // Consume some sequence of the characters in the pending sequence.
158
      int_type
159
      _M_really_overflow(int_type __c = _Traits::eof());
160
 
161
      virtual __streambuf_type*
162
      setbuf(char_type* __s, streamsize __n);
163
 
164
      virtual pos_type
165
      seekoff(off_type __off, ios_base::seekdir __way,
166
	      ios_base::openmode __mode = ios_base::in | ios_base::out);
167
 
168
      virtual pos_type
169
      seekpos(pos_type __pos,
170
	      ios_base::openmode __mode = ios_base::in | ios_base::out);
171
 
172
      virtual int
173
      sync(void)
174
      {
175
	bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
176
	if (__testput)
177
	  {
178
            // Make sure that libio resyncs its idea of the file position
179
            // with the external file.
180
            _M_file->sync();
181
 
182
	    // Need to restore current position. This interpreted as
183
	    // the position of the external byte sequence (_M_file)
184
	    // plus the offset in the current internal buffer
185
	    // (_M_out_beg - _M_out_cur)
186
	    streamoff __cur = _M_file->seekoff(0, ios_base::cur);
187
	    off_type __off = _M_out_cur - _M_out_beg;
188
	    _M_really_overflow();
189
	    _M_file->seekpos(__cur + __off);
190
	  }
191
	_M_last_overflowed = false;
192
	return 0;
193
      }
194
 
195
      virtual void
196
      imbue(const locale& __loc);
197
 
198
      virtual streamsize
199
      xsgetn(char_type* __s, streamsize __n)
200
      {
201
	streamsize __ret = 0;
202
	// Clear out pback buffer before going on to the real deal...
203
	if (_M_pback_init)
204
	  {
205
	    while (__ret < __n && _M_in_cur < _M_in_end)
206
	      {
207
		*__s = *_M_in_cur;
208
		++__ret;
209
		++__s;
210
		++_M_in_cur;
211
	      }
212
	    _M_pback_destroy();
213
	  }
214
	if (__ret < __n)
215
	  __ret += __streambuf_type::xsgetn(__s, __n - __ret);
216
	return __ret;
217
      }
218
 
219
      virtual streamsize
220
      xsputn(const char_type* __s, streamsize __n)
221
      {
222
	_M_pback_destroy();
223
	return __streambuf_type::xsputn(__s, __n);
224
      }
225
 
226
      void
227
      _M_output_unshift();
228
    };
229
 
230
 
231
  // 27.8.1.5  Template class basic_ifstream
232
  template
233
    class basic_ifstream : public basic_istream<_CharT, _Traits>
234
    {
235
    public:
236
      // Types:
237
      typedef _CharT 					char_type;
238
      typedef _Traits 					traits_type;
239
      typedef typename traits_type::int_type 		int_type;
240
      typedef typename traits_type::pos_type 		pos_type;
241
      typedef typename traits_type::off_type 		off_type;
242
 
243
      // Non-standard types:
244
      typedef basic_filebuf 	__filebuf_type;
245
      typedef basic_istream	__istream_type;
246
 
247
    private:
248
      __filebuf_type	_M_filebuf;
249
 
250
    public:
251
     // Constructors/Destructors:
252
      basic_ifstream()
253
      : __istream_type(NULL), _M_filebuf()
254
      { this->init(&_M_filebuf); }
255
 
256
      explicit
257
      basic_ifstream(const char* __s, ios_base::openmode __mode = ios_base::in)
258
      : __istream_type(NULL), _M_filebuf()
259
      {
260
	this->init(&_M_filebuf);
261
	this->open(__s, __mode);
262
      }
263
 
264
      ~basic_ifstream()
265
      { }
266
 
267
      // Members:
268
      __filebuf_type*
269
      rdbuf() const
270
      { return const_cast<__filebuf_type*>(&_M_filebuf); }
271
 
272
      bool
273
      is_open(void) { return _M_filebuf.is_open(); }
274
 
275
      void
276
      open(const char* __s, ios_base::openmode __mode = ios_base::in)
277
      {
278
	if (_M_filebuf.open(__s, __mode | ios_base::in) == NULL)
279
	  this->setstate(ios_base::failbit);
280
      }
281
 
282
      void
283
      close(void)
284
      {
285
	if (!_M_filebuf.close())
286
	  this->setstate(ios_base::failbit);
287
      }
288
    };
289
 
290
 
291
  // 27.8.1.8  Template class basic_ofstream
292
  template
293
    class basic_ofstream : public basic_ostream<_CharT,_Traits>
294
    {
295
    public:
296
      // Types:
297
      typedef _CharT 					char_type;
298
      typedef _Traits 					traits_type;
299
      typedef typename traits_type::int_type 		int_type;
300
      typedef typename traits_type::pos_type 		pos_type;
301
      typedef typename traits_type::off_type 		off_type;
302
 
303
      // Non-standard types:
304
      typedef basic_filebuf 	__filebuf_type;
305
      typedef basic_ostream	__ostream_type;
306
 
307
    private:
308
      __filebuf_type	_M_filebuf;
309
 
310
    public:
311
      // Constructors:
312
      basic_ofstream()
313
      : __ostream_type(NULL), _M_filebuf()
314
      { this->init(&_M_filebuf); }
315
 
316
      explicit
317
      basic_ofstream(const char* __s,
318
		     ios_base::openmode __mode = ios_base::out|ios_base::trunc)
319
      : __ostream_type(NULL), _M_filebuf()
320
      {
321
	this->init(&_M_filebuf);
322
	this->open(__s, __mode);
323
      }
324
 
325
      ~basic_ofstream()
326
      { }
327
 
328
      // Members:
329
      __filebuf_type*
330
      rdbuf(void) const
331
      { return const_cast<__filebuf_type*>(&_M_filebuf); }
332
 
333
      bool
334
      is_open(void) { return _M_filebuf.is_open(); }
335
 
336
      void
337
      open(const char* __s,
338
	   ios_base::openmode __mode = ios_base::out | ios_base::trunc)
339
      {
340
	if (!_M_filebuf.open(__s, __mode | ios_base::out))
341
	  this->setstate(ios_base::failbit);
342
      }
343
 
344
      void
345
      close(void)
346
      {
347
	if (!_M_filebuf.close())
348
	  setstate(ios_base::failbit);
349
      }
350
    };
351
 
352
 
353
  // 27.8.1.11  Template class basic_fstream
354
  template
355
    class basic_fstream : public basic_iostream<_CharT, _Traits>
356
    {
357
    public:
358
      // Types:
359
      typedef _CharT 					char_type;
360
      typedef _Traits 					traits_type;
361
      typedef typename traits_type::int_type 		int_type;
362
      typedef typename traits_type::pos_type 		pos_type;
363
      typedef typename traits_type::off_type 		off_type;
364
 
365
      // Non-standard types:
366
      typedef basic_filebuf 	__filebuf_type;
367
      typedef basic_ios		__ios_type;
368
      typedef basic_iostream	__iostream_type;
369
 
370
    private:
371
      __filebuf_type	_M_filebuf;
372
 
373
    public:
374
      // Constructors/destructor:
375
      basic_fstream()
376
      : __iostream_type(NULL), _M_filebuf()
377
      { this->init(&_M_filebuf); }
378
 
379
      explicit
380
      basic_fstream(const char* __s,
381
		    ios_base::openmode __mode = ios_base::in | ios_base::out)
382
      : __iostream_type(NULL), _M_filebuf()
383
      {
384
	this->init(&_M_filebuf);
385
	this->open(__s, __mode);
386
      }
387
 
388
      ~basic_fstream()
389
      { }
390
 
391
      // Members:
392
      __filebuf_type*
393
      rdbuf(void) const
394
      { return const_cast<__filebuf_type*>(&_M_filebuf); }
395
 
396
      bool
397
      is_open(void) { return _M_filebuf.is_open(); }
398
 
399
      void
400
      open(const char* __s,
401
	   ios_base::openmode __mode = ios_base::in | ios_base::out)
402
      {
403
	if (!_M_filebuf.open(__s, __mode))
404
	  setstate(ios_base::failbit);
405
      }
406
 
407
      void
408
      close(void)
409
      {
410
	if (!_M_filebuf.close())
411
	  setstate(ios_base::failbit);
412
      }
413
    };
414
} // namespace std
415
 
416
 
417
#ifdef _GLIBCPP_NO_TEMPLATE_EXPORT
418
# define export
419
#ifdef  _GLIBCPP_FULLY_COMPLIANT_HEADERS
420
# include 
421
#endif
422
#endif
423
 
424
#endif
425