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