00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
#ifndef _CPP_BITS_FSTREAM_TCC
00036
#define _CPP_BITS_FSTREAM_TCC 1
00037
00038
#pragma GCC system_header
00039
00040
namespace std
00041 {
00042
template<
typename _CharT,
typename _Traits>
00043
void
00044 basic_filebuf<_CharT, _Traits>::
00045 _M_allocate_internal_buffer()
00046 {
00047
if (!_M_buf && _M_buf_size_opt)
00048 {
00049 _M_buf_size = _M_buf_size_opt;
00050
00051
00052 _M_buf =
new char_type[_M_buf_size];
00053 _M_buf_allocated =
true;
00054 }
00055 }
00056
00057
00058
template<
typename _CharT,
typename _Traits>
00059
void
00060 basic_filebuf<_CharT, _Traits>::
00061 _M_destroy_internal_buffer()
00062 {
00063
if (_M_buf_allocated)
00064 {
00065
delete [] _M_buf;
00066 _M_buf = NULL;
00067 _M_buf_allocated =
false;
00068 this->setg(NULL, NULL, NULL);
00069 this->setp(NULL, NULL);
00070 }
00071 }
00072
00073
template<
typename _CharT,
typename _Traits>
00074 basic_filebuf<_CharT, _Traits>::
00075 basic_filebuf() : __streambuf_type(), _M_file(&_M_lock),
00076 _M_state_cur(__state_type()), _M_state_beg(__state_type()),
00077 _M_buf_allocated(false), _M_last_overflowed(false)
00078 { _M_buf_unified =
true; }
00079
00080
template<
typename _CharT,
typename _Traits>
00081
typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
00082 basic_filebuf<_CharT, _Traits>::
00083 open(
const char* __s, ios_base::openmode __mode)
00084 {
00085 __filebuf_type *__ret = NULL;
00086
if (!this->
is_open())
00087 {
00088 _M_file.open(__s, __mode);
00089
if (this->
is_open())
00090 {
00091 _M_allocate_internal_buffer();
00092 _M_mode = __mode;
00093 _M_set_indeterminate();
00094
00095
if ((__mode & ios_base::ate)
00096 && this->seekoff(0, ios_base::end, __mode) < 0)
00097 {
00098
00099 this->
close();
00100
return __ret;
00101 }
00102
00103 __ret =
this;
00104 }
00105 }
00106
return __ret;
00107 }
00108
00109
template<
typename _CharT,
typename _Traits>
00110
typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
00111 basic_filebuf<_CharT, _Traits>::
00112 close()
00113 {
00114 __filebuf_type *__ret = NULL;
00115
if (this->
is_open())
00116 {
00117
const int_type __eof = traits_type::eof();
00118
bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00119
if (__testput
00120 && traits_type::eq_int_type(_M_really_overflow(__eof), __eof))
00121
return __ret;
00122
00123
00124 _M_mode = ios_base::openmode(0);
00125 _M_destroy_internal_buffer();
00126 _M_pback_destroy();
00127
00128
#if 0
00129
00130
if (_M_last_overflowed)
00131 {
00132 _M_output_unshift();
00133 _M_really_overflow(__eof);
00134 }
00135
#endif
00136
00137
if (_M_file.close())
00138 __ret =
this;
00139 }
00140
00141 _M_last_overflowed =
false;
00142
return __ret;
00143 }
00144
00145
template<
typename _CharT,
typename _Traits>
00146 streamsize
00147 basic_filebuf<_CharT, _Traits>::
00148 showmanyc()
00149 {
00150 streamsize __ret = -1;
00151
bool __testin = _M_mode & ios_base::in;
00152
00153
if (__testin && this->
is_open())
00154 __ret = _M_in_end - _M_in_cur;
00155 _M_last_overflowed =
false;
00156
return __ret;
00157 }
00158
00159
template<
typename _CharT,
typename _Traits>
00160
typename basic_filebuf<_CharT, _Traits>::int_type
00161 basic_filebuf<_CharT, _Traits>::
00162 pbackfail(int_type __i)
00163 {
00164 int_type __ret = traits_type::eof();
00165
bool __testin = _M_mode & ios_base::in;
00166
00167
if (__testin)
00168 {
00169
bool __testpb = _M_in_beg < _M_in_cur;
00170 char_type __c = traits_type::to_char_type(__i);
00171
bool __testeof = traits_type::eq_int_type(__i, __ret);
00172
00173
if (__testpb)
00174 {
00175
bool __testout = _M_mode & ios_base::out;
00176
bool __testeq = traits_type::eq(__c, this->gptr()[-1]);
00177
00178
00179
00180
if (!__testeof && __testeq)
00181 {
00182 --_M_in_cur;
00183
if (__testout)
00184 --_M_out_cur;
00185 __ret = __i;
00186 }
00187
else if (__testeof)
00188 {
00189 --_M_in_cur;
00190
if (__testout)
00191 --_M_out_cur;
00192 __ret = traits_type::not_eof(__i);
00193 }
00194
else if (!__testeof)
00195 {
00196 --_M_in_cur;
00197
if (__testout)
00198 --_M_out_cur;
00199 _M_pback_create();
00200 *_M_in_cur = __c;
00201 __ret = __i;
00202 }
00203 }
00204
else
00205 {
00206
00207
00208 this->seekoff(-1, ios_base::cur);
00209 this->underflow();
00210
if (!__testeof)
00211 {
00212
if (!traits_type::eq(__c, *_M_in_cur))
00213 {
00214 _M_pback_create();
00215 *_M_in_cur = __c;
00216 }
00217 __ret = __i;
00218 }
00219
else
00220 __ret = traits_type::not_eof(__i);
00221 }
00222 }
00223 _M_last_overflowed =
false;
00224
return __ret;
00225 }
00226
00227
template<
typename _CharT,
typename _Traits>
00228
typename basic_filebuf<_CharT, _Traits>::int_type
00229 basic_filebuf<_CharT, _Traits>::
00230 overflow(int_type __c)
00231 {
00232 int_type __ret = traits_type::eof();
00233
bool __testput = _M_out_cur && _M_out_cur < _M_buf + _M_buf_size;
00234
bool __testout = _M_mode & ios_base::out;
00235
00236
if (__testout)
00237 {
00238
if (__testput)
00239 {
00240 *_M_out_cur = traits_type::to_char_type(__c);
00241 _M_out_cur_move(1);
00242 __ret = traits_type::not_eof(__c);
00243 }
00244
else
00245 __ret = this->_M_really_overflow(__c);
00246 }
00247
00248 _M_last_overflowed =
false;
00249
return __ret;
00250 }
00251
00252
template<
typename _CharT,
typename _Traits>
00253
void
00254 basic_filebuf<_CharT, _Traits>::
00255 _M_convert_to_external(_CharT* __ibuf, streamsize __ilen,
00256 streamsize& __elen, streamsize& __plen)
00257 {
00258
const locale __loc = this->getloc();
00259
const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
00260
00261
if (__cvt.always_noconv() && __ilen)
00262 {
00263 __elen += _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
00264 __plen += __ilen;
00265 }
00266
else
00267 {
00268
00269
int __ext_multiplier = __cvt.encoding();
00270
if (__ext_multiplier == -1 || __ext_multiplier == 0)
00271 __ext_multiplier =
sizeof(char_type);
00272 streamsize __blen = __ilen * __ext_multiplier;
00273
char* __buf = static_cast<char*>(__builtin_alloca(__blen));
00274
char* __bend;
00275
const char_type* __iend;
00276 __res_type __r = __cvt.out(_M_state_cur, __ibuf, __ibuf + __ilen,
00277 __iend, __buf, __buf + __blen, __bend);
00278
00279
if (__r == codecvt_base::ok || __r == codecvt_base::partial)
00280 __blen = __bend - __buf;
00281
00282
else if (__r == codecvt_base::noconv)
00283 {
00284 __buf = reinterpret_cast<char*>(__ibuf);
00285 __blen = __ilen;
00286 }
00287
00288
else
00289 __blen = 0;
00290
00291
if (__blen)
00292 {
00293 __elen += _M_file.xsputn(__buf, __blen);
00294 __plen += __blen;
00295 }
00296
00297
00298
if (__r == codecvt_base::partial)
00299 {
00300
const char_type* __iresume = __iend;
00301 streamsize __rlen = _M_out_end - __iend;
00302 __r = __cvt.out(_M_state_cur, __iresume, __iresume + __rlen,
00303 __iend, __buf, __buf + __blen, __bend);
00304
if (__r != codecvt_base::error)
00305 __rlen = __bend - __buf;
00306
else
00307 __rlen = 0;
00308
if (__rlen)
00309 {
00310 __elen += _M_file.xsputn(__buf, __rlen);
00311 __plen += __rlen;
00312 }
00313 }
00314 }
00315 }
00316
00317
template<
typename _CharT,
typename _Traits>
00318
typename basic_filebuf<_CharT, _Traits>::int_type
00319 basic_filebuf<_CharT, _Traits>::
00320 _M_really_overflow(int_type __c)
00321 {
00322 int_type __ret = traits_type::eof();
00323
bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00324
bool __testunbuffered = _M_file.is_open() && !_M_buf_size_opt;
00325
00326
if (__testput || __testunbuffered)
00327 {
00328
00329 streamsize __elen = 0;
00330 streamsize __plen = 0;
00331
00332
00333
00334
00335
if (_M_filepos && _M_filepos != _M_out_beg)
00336 {
00337 off_type __off = _M_out_beg - _M_filepos;
00338 _M_file.seekoff(__off, ios_base::cur);
00339 }
00340
00341
00342
00343
if (!__testunbuffered)
00344 _M_convert_to_external(_M_out_beg, _M_out_end - _M_out_beg,
00345 __elen, __plen);
00346
00347
00348
00349
if (!traits_type::eq_int_type(__c, traits_type::eof()))
00350 {
00351 char_type __pending = traits_type::to_char_type(__c);
00352 _M_convert_to_external(&__pending, 1, __elen, __plen);
00353
00354
00355
if (__elen == __plen)
00356 {
00357 _M_set_indeterminate();
00358 __ret = traits_type::not_eof(__c);
00359 }
00360 }
00361
else if (!_M_file.sync())
00362 {
00363 _M_set_indeterminate();
00364 __ret = traits_type::not_eof(__c);
00365 }
00366 }
00367 _M_last_overflowed =
true;
00368
return __ret;
00369 }
00370
00371
template<
typename _CharT,
typename _Traits>
00372
typename basic_filebuf<_CharT, _Traits>::__streambuf_type*
00373 basic_filebuf<_CharT, _Traits>::
00374 setbuf(char_type* __s, streamsize __n)
00375 {
00376
if (!this->
is_open() && __s == 0 && __n == 0)
00377 _M_buf_size_opt = 0;
00378
else if (__s && __n)
00379 {
00380
00381
00382
00383
00384
00385 _M_destroy_internal_buffer();
00386
00387
00388 _M_buf = __s;
00389 _M_buf_size_opt = _M_buf_size = __n;
00390 _M_set_indeterminate();
00391 }
00392 _M_last_overflowed =
false;
00393
return this;
00394 }
00395
00396
template<
typename _CharT,
typename _Traits>
00397
typename basic_filebuf<_CharT, _Traits>::pos_type
00398 basic_filebuf<_CharT, _Traits>::
00399 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
00400 {
00401 pos_type __ret = pos_type(off_type(-1));
00402
bool __testin = (ios_base::in & _M_mode & __mode) != 0;
00403
bool __testout = (ios_base::out & _M_mode & __mode) != 0;
00404
00405
00406
int __width = use_facet<__codecvt_type>(_M_buf_locale).encoding();
00407
if (__width < 0)
00408 __width = 0;
00409
bool __testfail = __off != 0 && __width <= 0;
00410
00411
if (this->
is_open() && !__testfail && (__testin || __testout))
00412 {
00413
00414 _M_pback_destroy();
00415
00416
if (__way != ios_base::cur || __off != 0)
00417 {
00418 off_type __computed_off = __width * __off;
00419
00420
bool __testget = _M_in_cur && _M_in_beg < _M_in_end;
00421
bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00422
00423
00424
if (__testput || _M_last_overflowed)
00425 {
00426
00427 this->sync();
00428
00429 _M_output_unshift();
00430 }
00431
00432
else if (__testget && __way == ios_base::cur)
00433 __computed_off += _M_in_cur - _M_filepos;
00434
00435 __ret = _M_file.seekoff(__computed_off, __way, __mode);
00436 _M_set_indeterminate();
00437 }
00438
00439
00440
else
00441 {
00442 __ret = _M_file.seekoff(__off, ios_base::cur, __mode);
00443 __ret +=
max(_M_out_cur, _M_in_cur) - _M_filepos;
00444 }
00445 }
00446 _M_last_overflowed =
false;
00447
return __ret;
00448 }
00449
00450
template<
typename _CharT,
typename _Traits>
00451
typename basic_filebuf<_CharT, _Traits>::pos_type
00452 basic_filebuf<_CharT, _Traits>::
00453 seekpos(pos_type __pos, ios_base::openmode __mode)
00454 {
00455
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
00456
00457
return this->seekoff(off_type(__pos), ios_base::beg, __mode);
00458
#endif
00459
}
00460
00461
template<
typename _CharT,
typename _Traits>
00462
void
00463 basic_filebuf<_CharT, _Traits>::
00464 _M_output_unshift()
00465 { }
00466
00467
template<
typename _CharT,
typename _Traits>
00468
void
00469 basic_filebuf<_CharT, _Traits>::
00470 imbue(
const locale& __loc)
00471 {
00472
bool __testbeg = gptr() == eback() && pptr() == pbase();
00473
00474
if (__testbeg && _M_buf_locale != __loc)
00475 _M_buf_locale = __loc;
00476
00477
00478
00479
00480
00481 _M_last_overflowed =
false;
00482 }
00483
00484
00485
00486
00487
extern template class basic_filebuf<char>;
00488
extern template class basic_ifstream<char>;
00489
extern template class basic_ofstream<char>;
00490
extern template class basic_fstream<char>;
00491
00492
#ifdef _GLIBCPP_USE_WCHAR_T
00493
extern template class basic_filebuf<wchar_t>;
00494
extern template class basic_ifstream<wchar_t>;
00495
extern template class basic_ofstream<wchar_t>;
00496
extern template class basic_fstream<wchar_t>;
00497
#endif
00498
}
00499
00500
#endif