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