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() throw()
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
00094
00095 _M_set_indeterminate();
00096
00097
if ((__mode & ios_base::ate)
00098 && this->
seekoff(0, ios_base::end, __mode) < 0)
00099 {
00100
00101 this->
close();
00102
return __ret;
00103 }
00104
00105 __ret =
this;
00106 }
00107 }
00108
return __ret;
00109 }
00110
00111
template<
typename _CharT,
typename _Traits>
00112
typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
00113
basic_filebuf<_CharT, _Traits>::
00114 close() throw()
00115 {
00116
__filebuf_type* __ret = NULL;
00117
if (this->
is_open())
00118 {
00119
bool __testfail =
false;
00120
try
00121 {
00122
const int_type __eof = traits_type::eof();
00123
bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00124
if (__testput
00125 && traits_type::eq_int_type(_M_really_overflow(__eof),
00126 __eof))
00127 __testfail =
true;
00128
00129
#if 0
00130
00131
if (_M_last_overflowed)
00132 {
00133 _M_output_unshift();
00134 _M_really_overflow(__eof);
00135 }
00136
#endif
00137
}
00138
catch(...)
00139 { __testfail =
true; }
00140
00141
00142 this->_M_mode =
ios_base::openmode(0);
00143 _M_destroy_internal_buffer();
00144 _M_pback_destroy();
00145
00146
if (!_M_file.close())
00147 __testfail =
true;
00148
00149
if (!__testfail)
00150 __ret =
this;
00151 }
00152 _M_last_overflowed =
false;
00153
return __ret;
00154 }
00155
00156
template<
typename _CharT,
typename _Traits>
00157 streamsize
00158
basic_filebuf<_CharT, _Traits>::
00159 showmanyc()
00160 {
00161 streamsize __ret = -1;
00162
bool __testin = _M_mode & ios_base::in;
00163
const locale __loc = this->
getloc();
00164
const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
00165
00166
if (__testin && this->
is_open())
00167 {
00168 __ret = _M_in_end - _M_in_cur;
00169
if (__cvt.always_noconv())
00170 __ret += _M_file.showmanyc_helper();
00171 }
00172
00173 _M_last_overflowed =
false;
00174
return __ret;
00175 }
00176
00177
template<
typename _CharT,
typename _Traits>
00178
typename basic_filebuf<_CharT, _Traits>::int_type
00179
basic_filebuf<_CharT, _Traits>::
00180 pbackfail(
int_type __i)
00181 {
00182
int_type __ret = traits_type::eof();
00183
bool __testin = _M_mode & ios_base::in;
00184
00185
if (__testin)
00186 {
00187
bool __testpb = _M_in_beg < _M_in_cur;
00188
char_type __c = traits_type::to_char_type(__i);
00189
bool __testeof = traits_type::eq_int_type(__i, __ret);
00190
00191
if (__testpb)
00192 {
00193
bool __testout = _M_mode & ios_base::out;
00194
bool __testeq = traits_type::eq(__c, this->gptr()[-1]);
00195
00196
00197
00198
if (!__testeof && __testeq)
00199 {
00200 --_M_in_cur;
00201
if (__testout)
00202 --_M_out_cur;
00203 __ret = __i;
00204 }
00205
else if (__testeof)
00206 {
00207 --_M_in_cur;
00208
if (__testout)
00209 --_M_out_cur;
00210 __ret = traits_type::not_eof(__i);
00211 }
00212
else if (!__testeof)
00213 {
00214 --_M_in_cur;
00215
if (__testout)
00216 --_M_out_cur;
00217 _M_pback_create();
00218 *_M_in_cur = __c;
00219 __ret = __i;
00220 }
00221 }
00222
else
00223 {
00224
00225
00226
00227
00228
00229
if (this->
seekoff(-1, ios_base::cur) >= 0)
00230 {
00231 this->
underflow();
00232
if (!__testeof)
00233 {
00234
if (!traits_type::eq(__c, *_M_in_cur))
00235 {
00236 _M_pback_create();
00237 *_M_in_cur = __c;
00238 }
00239 __ret = __i;
00240 }
00241
else
00242 __ret = traits_type::not_eof(__i);
00243 }
00244 }
00245 }
00246 _M_last_overflowed =
false;
00247
return __ret;
00248 }
00249
00250
template<
typename _CharT,
typename _Traits>
00251
typename basic_filebuf<_CharT, _Traits>::int_type
00252
basic_filebuf<_CharT, _Traits>::
00253 overflow(
int_type __c)
00254 {
00255
int_type __ret = traits_type::eof();
00256
bool __testput = _M_out_cur && _M_out_cur < _M_buf + _M_buf_size;
00257
bool __testout = _M_mode & ios_base::out;
00258
00259
if (__testout)
00260 {
00261
if (traits_type::eq_int_type(__c, traits_type::eof()))
00262 __ret = traits_type::not_eof(__c);
00263
else if (__testput)
00264 {
00265 *_M_out_cur = traits_type::to_char_type(__c);
00266 _M_out_cur_move(1);
00267 __ret = traits_type::not_eof(__c);
00268 }
00269
else
00270 __ret = this->_M_really_overflow(__c);
00271 }
00272
00273 _M_last_overflowed =
false;
00274
return __ret;
00275 }
00276
00277
template<
typename _CharT,
typename _Traits>
00278
void
00279
basic_filebuf<_CharT, _Traits>::
00280
_M_convert_to_external(_CharT* __ibuf, streamsize __ilen,
00281 streamsize& __elen, streamsize& __plen)
00282 {
00283
const locale __loc = this->
getloc();
00284
const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc);
00285
00286
if (__cvt.always_noconv() && __ilen)
00287 {
00288 __elen += _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
00289 __plen += __ilen;
00290 }
00291
else
00292 {
00293
00294
int __ext_multiplier = __cvt.encoding();
00295
if (__ext_multiplier == -1 || __ext_multiplier == 0)
00296 __ext_multiplier =
sizeof(char_type);
00297 streamsize __blen = __ilen * __ext_multiplier;
00298
char* __buf = static_cast<char*>(__builtin_alloca(__blen));
00299
char* __bend;
00300
const char_type* __iend;
00301 codecvt_base::result __r;
00302 __r = __cvt.out(_M_state_cur, __ibuf, __ibuf + __ilen,
00303 __iend, __buf, __buf + __blen, __bend);
00304
00305
if (__r == codecvt_base::ok || __r == codecvt_base::partial)
00306 __blen = __bend - __buf;
00307
else if (__r == codecvt_base::noconv)
00308 {
00309
00310 __buf = reinterpret_cast<char*>(__ibuf);
00311 __blen = __ilen;
00312 }
00313
else
00314 {
00315
00316 __blen = 0;
00317 }
00318
00319
if (__blen)
00320 {
00321 __elen += _M_file.xsputn(__buf, __blen);
00322 __plen += __blen;
00323 }
00324
00325
00326
if (__r == codecvt_base::partial)
00327 {
00328
const char_type* __iresume = __iend;
00329 streamsize __rlen = _M_out_end - __iend;
00330 __r = __cvt.out(_M_state_cur, __iresume, __iresume + __rlen,
00331 __iend, __buf, __buf + __blen, __bend);
00332
if (__r != codecvt_base::error)
00333 {
00334 __rlen = __bend - __buf;
00335 __elen += _M_file.xsputn(__buf, __rlen);
00336 __plen += __rlen;
00337 }
00338 }
00339 }
00340 }
00341
00342
template<
typename _CharT,
typename _Traits>
00343
typename basic_filebuf<_CharT, _Traits>::int_type
00344 basic_filebuf<_CharT, _Traits>::
00345 _M_really_overflow(int_type __c)
00346 {
00347
int_type __ret = traits_type::eof();
00348
bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00349
bool __testunbuffered = _M_file.is_open() && !_M_buf_size;
00350
00351
if (__testput || __testunbuffered)
00352 {
00353
00354 streamsize __elen = 0;
00355 streamsize __plen = 0;
00356
00357
00358
00359
00360
if (_M_filepos && _M_filepos != _M_out_beg)
00361 {
00362
off_type __off = _M_out_beg - _M_filepos;
00363 _M_file.seekoff(__off, ios_base::cur);
00364 }
00365
00366
00367
00368
if (!__testunbuffered)
00369 _M_convert_to_external(_M_out_beg, _M_out_end - _M_out_beg,
00370 __elen, __plen);
00371
00372
00373
00374
if (__testunbuffered || (__elen && __elen == __plen))
00375 {
00376
00377
00378
if (!traits_type::eq_int_type(__c, traits_type::eof()))
00379 {
00380
char_type __pending = traits_type::to_char_type(__c);
00381 _M_convert_to_external(&__pending, 1, __elen, __plen);
00382
00383
00384
00385
if (__elen == __plen && __elen)
00386 {
00387 _M_set_indeterminate();
00388 __ret = traits_type::not_eof(__c);
00389 }
00390 }
00391
else if (!_M_file.sync())
00392 {
00393 _M_set_indeterminate();
00394 __ret = traits_type::not_eof(__c);
00395 }
00396 }
00397 }
00398 _M_last_overflowed =
true;
00399
return __ret;
00400 }
00401
00402
template<
typename _CharT,
typename _Traits>
00403
typename basic_filebuf<_CharT, _Traits>::__streambuf_type*
00404 basic_filebuf<_CharT, _Traits>::
00405 setbuf(
char_type* __s, streamsize __n)
00406 {
00407
if (!this->
is_open() && __s == 0 && __n == 0)
00408 _M_buf_size_opt = 0;
00409
else if (__s && __n)
00410 {
00411
00412
00413
00414
00415
00416 _M_destroy_internal_buffer();
00417
00418
00419 _M_buf = __s;
00420 _M_buf_size_opt = _M_buf_size = __n;
00421 _M_set_indeterminate();
00422 }
00423 _M_last_overflowed =
false;
00424
return this;
00425 }
00426
00427
template<
typename _CharT,
typename _Traits>
00428
typename basic_filebuf<_CharT, _Traits>::pos_type
00429
basic_filebuf<_CharT, _Traits>::
00430 seekoff(
off_type __off,
ios_base::seekdir __way,
ios_base::openmode __mode)
00431 {
00432
pos_type __ret =
pos_type(
off_type(-1));
00433
bool __testin = (ios_base::in & _M_mode & __mode) != 0;
00434
bool __testout = (ios_base::out & _M_mode & __mode) != 0;
00435
00436
int __width = 0;
00437
if (has_facet<__codecvt_type>(this->_M_buf_locale))
00438 __width = use_facet<__codecvt_type>(this->_M_buf_locale).encoding();
00439
if (__width < 0)
00440 __width = 0;
00441
00442
bool __testfail = __off != 0 && __width <= 0;
00443
if (this->
is_open() && !__testfail && (__testin || __testout))
00444 {
00445
00446 _M_pback_destroy();
00447
00448
if (__way != ios_base::cur || __off != 0)
00449 {
00450
off_type __computed_off = __width * __off;
00451
00452
bool __testget = _M_in_cur && _M_in_beg < _M_in_end;
00453
bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00454
00455
00456
if (__testput || _M_last_overflowed)
00457 {
00458
00459 this->
sync();
00460
00461 _M_output_unshift();
00462 }
00463
00464
else if (__testget && __way == ios_base::cur)
00465 __computed_off += _M_in_cur - _M_filepos;
00466
00467
00468 __ret = _M_file.seekoff(__computed_off, __way, __mode);
00469 _M_set_indeterminate();
00470 }
00471
00472
00473
else
00474 {
00475 pos_type __tmp =
00476 _M_file.seekoff(__off, ios_base::cur, __mode);
00477
if (__tmp >= 0)
00478 {
00479
00480 __ret = __tmp;
00481 __ret +=
max(_M_out_cur, _M_in_cur) - _M_filepos;
00482 }
00483 }
00484 }
00485 _M_last_overflowed =
false;
00486
return __ret;
00487 }
00488
00489
template<
typename _CharT,
typename _Traits>
00490
typename basic_filebuf<_CharT, _Traits>::pos_type
00491
basic_filebuf<_CharT, _Traits>::
00492 seekpos(
pos_type __pos,
ios_base::openmode __mode)
00493 {
00494
#ifdef _GLIBCPP_RESOLVE_LIB_DEFECTS
00495
00496
return this->
seekoff(
off_type(__pos), ios_base::beg, __mode);
00497
#endif
00498
}
00499
00500
template<
typename _CharT,
typename _Traits>
00501
void
00502
basic_filebuf<_CharT, _Traits>::
00503
_M_output_unshift()
00504 { }
00505
00506
template<
typename _CharT,
typename _Traits>
00507
void
00508 basic_filebuf<_CharT, _Traits>::
00509 imbue(
const locale&)
00510 { _M_last_overflowed =
false; }
00511
00512
00513
00514
00515
#if _GLIBCPP_EXTERN_TEMPLATE
00516
extern template class basic_filebuf<char>;
00517
extern template class basic_ifstream<char>;
00518
extern template class basic_ofstream<char>;
00519
extern template class basic_fstream<char>;
00520
00521
#ifdef _GLIBCPP_USE_WCHAR_T
00522
extern template class basic_filebuf<wchar_t>;
00523
extern template class basic_ifstream<wchar_t>;
00524
extern template class basic_ofstream<wchar_t>;
00525
extern template class basic_fstream<wchar_t>;
00526
#endif
00527
#endif
00528
}
00529
00530
#endif