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