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 #ifndef _CPP_BITS_FSTREAM_TCC
00035 #define _CPP_BITS_FSTREAM_TCC 1
00036
00037 namespace std
00038 {
00039 template<typename _CharT, typename _Traits>
00040 void
00041 basic_filebuf<_CharT, _Traits>::
00042 _M_allocate_file()
00043 {
00044 if (!_M_file)
00045 {
00046 _M_buf_unified = true;
00047 try
00048 { _M_file = new __file_type(&_M_lock); }
00049 catch(...)
00050 {
00051 delete _M_file;
00052 __throw_exception_again;
00053 }
00054 }
00055 }
00056
00057 template<typename _CharT, typename _Traits>
00058 void
00059 basic_filebuf<_CharT, _Traits>::
00060 _M_allocate_internal_buffer()
00061 {
00062 if (!_M_buf && _M_buf_size_opt)
00063 {
00064 _M_buf_size = _M_buf_size_opt;
00065
00066
00067 try { _M_buf = new char_type[_M_buf_size]; }
00068 catch(...)
00069 {
00070 delete [] _M_buf;
00071 __throw_exception_again;
00072 }
00073 _M_buf_allocated = true;
00074 }
00075 }
00076
00077
00078 template<typename _CharT, typename _Traits>
00079 void
00080 basic_filebuf<_CharT, _Traits>::
00081 _M_destroy_internal_buffer()
00082 {
00083 if (_M_buf_allocated)
00084 {
00085 delete [] _M_buf;
00086 _M_buf = NULL;
00087 _M_buf_allocated = false;
00088 this->setg(NULL, NULL, NULL);
00089 this->setp(NULL, NULL);
00090 }
00091 }
00092
00093 template<typename _CharT, typename _Traits>
00094 void
00095 basic_filebuf<_CharT, _Traits>::
00096 _M_allocate_pback_buffer()
00097 {
00098 if (!_M_pback && _M_pback_size)
00099 {
00100
00101 try
00102 { _M_pback = new char_type[_M_pback_size]; }
00103 catch(...)
00104 {
00105 delete [] _M_pback;
00106 __throw_exception_again;
00107 }
00108 }
00109 }
00110
00111 template<typename _CharT, typename _Traits>
00112 basic_filebuf<_CharT, _Traits>::
00113 basic_filebuf()
00114 : __streambuf_type(), _M_file(NULL), _M_state_cur(__state_type()),
00115 _M_state_beg(__state_type()), _M_buf_allocated(false),
00116 _M_last_overflowed(false)
00117 { }
00118
00119 template<typename _CharT, typename _Traits>
00120 basic_filebuf<_CharT, _Traits>::
00121 basic_filebuf(__c_file_type* __f, ios_base::openmode __mode, int_type __s)
00122 : __streambuf_type(), _M_file(NULL), _M_state_cur(__state_type()),
00123 _M_state_beg(__state_type()), _M_buf_allocated(false),
00124 _M_last_overflowed(false)
00125 {
00126 _M_allocate_file();
00127 _M_file->sys_open(__f, __mode);
00128 if (this->is_open())
00129 {
00130 _M_mode = __mode;
00131 if (__s)
00132 {
00133 _M_buf_size_opt = __s;
00134 _M_allocate_internal_buffer();
00135 _M_set_indeterminate();
00136 }
00137 _M_allocate_pback_buffer();
00138 }
00139 }
00140
00141 template<typename _CharT, typename _Traits>
00142 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
00143 basic_filebuf<_CharT, _Traits>::
00144 open(const char* __s, ios_base::openmode __mode)
00145 {
00146 __filebuf_type *__ret = NULL;
00147 if (!this->is_open())
00148 {
00149 _M_allocate_file();
00150 _M_file->open(__s, __mode);
00151 if (this->is_open())
00152 {
00153 _M_allocate_internal_buffer();
00154 _M_allocate_pback_buffer();
00155 _M_mode = __mode;
00156
00157
00158 _M_set_indeterminate();
00159 if (__mode & ios_base::ate
00160 && this->seekoff(0, ios_base::end, __mode) < 0)
00161 this->close();
00162 __ret = this;
00163 }
00164 }
00165 return __ret;
00166 }
00167
00168 template<typename _CharT, typename _Traits>
00169 typename basic_filebuf<_CharT, _Traits>::__filebuf_type*
00170 basic_filebuf<_CharT, _Traits>::
00171 close()
00172 {
00173 __filebuf_type *__ret = NULL;
00174 if (this->is_open())
00175 {
00176 bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00177 if (__testput)
00178 _M_really_overflow(traits_type::eof());
00179
00180
00181 _M_pback_destroy();
00182
00183 #if 0
00184
00185 if (_M_last_overflowed)
00186 {
00187 _M_output_unshift();
00188 _M_really_overflow(traits_type::eof());
00189 }
00190 #endif
00191
00192 _M_mode = ios_base::openmode(0);
00193 _M_destroy_internal_buffer();
00194
00195 if (_M_pback)
00196 {
00197 delete [] _M_pback;
00198 _M_pback = NULL;
00199 }
00200 __ret = this;
00201 }
00202
00203
00204
00205 if (_M_file)
00206 {
00207 delete _M_file;
00208 _M_file = NULL;
00209 }
00210 _M_last_overflowed = false;
00211 return __ret;
00212 }
00213
00214 template<typename _CharT, typename _Traits>
00215 streamsize
00216 basic_filebuf<_CharT, _Traits>::
00217 showmanyc()
00218 {
00219 streamsize __ret = -1;
00220 bool __testin = _M_mode & ios_base::in;
00221
00222 if (__testin)
00223 {
00224 bool __testeof = false;
00225 if (_M_in_cur >= _M_in_end)
00226 __testeof = this->underflow() == traits_type::eof();
00227 if (!__testeof)
00228 __ret = _M_in_end - _M_in_cur;
00229 }
00230 _M_last_overflowed = false;
00231 return __ret;
00232 }
00233
00234 template<typename _CharT, typename _Traits>
00235 typename basic_filebuf<_CharT, _Traits>::int_type
00236 basic_filebuf<_CharT, _Traits>::
00237 underflow()
00238 {
00239 int_type __ret = traits_type::eof();
00240 bool __testin = _M_mode & ios_base::in;
00241 bool __testout = _M_mode & ios_base::out;
00242
00243
00244 if (__testin)
00245 {
00246
00247
00248
00249 if (_M_pback_init)
00250 {
00251 _M_pback_destroy();
00252 if (_M_in_cur < _M_in_end)
00253 return traits_type::to_int_type(*_M_in_cur);
00254 }
00255
00256 bool __testget = _M_in_cur && _M_in_beg < _M_in_cur;
00257 bool __testinit = _M_is_indeterminate();
00258
00259
00260 if (__testget)
00261 {
00262 if (__testout)
00263 _M_really_overflow();
00264 #if _GLIBCPP_AVOID_FSEEK
00265 else if ((_M_in_cur - _M_in_beg) == 1)
00266 _M_file->sys_getc();
00267 #endif
00268 else
00269 _M_file->seekoff(_M_in_cur - _M_in_beg,
00270 ios_base::cur, ios_base::in);
00271 }
00272
00273 if (__testinit || __testget)
00274 {
00275
00276 streamsize __size = _M_file->xsgetn(_M_in_beg, _M_buf_size);
00277 if (0 < __size)
00278 {
00279 _M_set_determinate(__size);
00280 if (__testout)
00281 _M_out_cur = _M_in_cur;
00282 __ret = traits_type::to_int_type(*_M_in_cur);
00283 #if _GLIBCPP_AVOID_FSEEK
00284 if (__size == 1)
00285 _M_file->sys_ungetc(*_M_in_cur);
00286 else
00287 {
00288 #endif
00289 streamoff __p = _M_file->seekoff(0 - __size, ios_base::cur,
00290 ios_base::in);
00291 if (__p == -1)
00292 {
00293
00294 }
00295 #if _GLIBCPP_AVOID_FSEEK
00296 }
00297 #endif
00298 }
00299 }
00300 }
00301 _M_last_overflowed = false;
00302 return __ret;
00303 }
00304
00305 template<typename _CharT, typename _Traits>
00306 typename basic_filebuf<_CharT, _Traits>::int_type
00307 basic_filebuf<_CharT, _Traits>::
00308 pbackfail(int_type __i)
00309 {
00310 int_type __ret = traits_type::eof();
00311 bool __testin = _M_mode & ios_base::in;
00312
00313 if (__testin)
00314 {
00315 bool __testpb = _M_in_beg < _M_in_cur;
00316 char_type __c = traits_type::to_char_type(__i);
00317 bool __testeof = traits_type::eq_int_type(__i, __ret);
00318
00319 if (__testpb)
00320 {
00321 bool __testout = _M_mode & ios_base::out;
00322 bool __testeq = traits_type::eq(__c, this->gptr()[-1]);
00323
00324
00325
00326 if (!__testeof && __testeq)
00327 {
00328 --_M_in_cur;
00329 if (__testout)
00330 --_M_out_cur;
00331 __ret = __i;
00332 }
00333 else if (__testeof)
00334 {
00335 --_M_in_cur;
00336 if (__testout)
00337 --_M_out_cur;
00338 __ret = traits_type::not_eof(__i);
00339 }
00340 else if (!__testeof)
00341 {
00342 --_M_in_cur;
00343 if (__testout)
00344 --_M_out_cur;
00345 _M_pback_create();
00346 *_M_in_cur = __c;
00347 __ret = __i;
00348 }
00349 }
00350 else
00351 {
00352
00353
00354 this->seekoff(-1, ios_base::cur);
00355 this->underflow();
00356 if (!__testeof)
00357 {
00358 if (!traits_type::eq(__c, *_M_in_cur))
00359 {
00360 _M_pback_create();
00361 *_M_in_cur = __c;
00362 }
00363 __ret = __i;
00364 }
00365 else
00366 __ret = traits_type::not_eof(__i);
00367 }
00368 }
00369 _M_last_overflowed = false;
00370 return __ret;
00371 }
00372
00373 template<typename _CharT, typename _Traits>
00374 typename basic_filebuf<_CharT, _Traits>::int_type
00375 basic_filebuf<_CharT, _Traits>::
00376 overflow(int_type __c)
00377 {
00378 int_type __ret = traits_type::eof();
00379 bool __testput = _M_out_cur && _M_out_cur < _M_buf + _M_buf_size;
00380 bool __testout = _M_mode & ios_base::out;
00381
00382 if (__testout)
00383 {
00384 if (__testput)
00385 {
00386 *_M_out_cur = traits_type::to_char_type(__c);
00387 _M_out_cur_move(1);
00388 __ret = traits_type::not_eof(__c);
00389 }
00390 else
00391 __ret = this->_M_really_overflow(__c);
00392 }
00393
00394 _M_last_overflowed = false;
00395 return __ret;
00396 }
00397
00398 template<typename _CharT, typename _Traits>
00399 typename basic_filebuf<_CharT, _Traits>::int_type
00400 basic_filebuf<_CharT, _Traits>::
00401 _M_really_overflow(int_type __c)
00402 {
00403 int_type __ret = traits_type::eof();
00404 bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00405 bool __testunbuffered = _M_file && !_M_buf_size;
00406
00407 if (__testput || __testunbuffered)
00408 {
00409 #if 1
00410 int __plen = _M_out_end - _M_out_beg;
00411 streamsize __len = 0;
00412
00413 if (__plen)
00414 __len = _M_file->xsputn(_M_out_beg, __plen);
00415
00416 if (__c !=traits_type::eof())
00417 {
00418 char_type __pending = traits_type::to_char_type(__c);
00419 __len += _M_file->xsputn(&__pending, 1);
00420 ++__plen;
00421 }
00422
00423
00424
00425 _M_file->sync();
00426 if (__len == __plen)
00427 {
00428 _M_set_indeterminate();
00429 __ret = traits_type::not_eof(__c);
00430 }
00431 #else
00432
00433
00434
00435 int __plen = _M_out_end - _M_out_beg;
00436 char_type* __pbuf = static_cast<char_type*>(__builtin_alloca(sizeof(char_type) * __plen + 1));
00437 traits_type::copy(__pbuf, this->pbase(), __plen);
00438 if (!__testeof)
00439 {
00440 __pbuf[__plen] = traits_type::to_char_type(__c);
00441 ++__plen;
00442 }
00443
00444 char_type* __pend;
00445 char* __conv_buf = static_cast<char*>(__builtin_alloca(__plen));
00446 char* __conv_end;
00447 _M_state_beg = _M_state_cur;
00448
00449 __res_type __r = _M_fcvt->out(_M_state_cur,
00450 __pbuf, __pbuf + __plen,
00451 const_cast<const char_type*&>(__pend),
00452 __conv_buf, __conv_buf + __plen,
00453 __conv_end);
00454
00455
00456
00457
00458
00459 if (__r != codecvt_base::error)
00460 {
00461 streamsize __len = _M_file->xsputn(__conv_buf, __plen);
00462
00463
00464 _M_file->sync();
00465 if (__len == __plen)
00466 {
00467 _M_set_indeterminate();
00468 __ret = traits_type::not_eof(__c);
00469 }
00470 }
00471 #endif
00472 }
00473 _M_last_overflowed = true;
00474 return __ret;
00475 }
00476
00477 template<typename _CharT, typename _Traits>
00478 typename basic_filebuf<_CharT, _Traits>::__streambuf_type*
00479 basic_filebuf<_CharT, _Traits>::
00480 setbuf(char_type* __s, streamsize __n)
00481 {
00482 if (!this->is_open() && __s == 0 && __n == 0)
00483 _M_buf_size_opt = 0;
00484 else if (__s && __n)
00485 {
00486
00487
00488
00489
00490
00491 _M_destroy_internal_buffer();
00492
00493
00494 _M_buf = __s;
00495 _M_buf_size_opt = _M_buf_size = __n;
00496 _M_set_indeterminate();
00497
00498
00499 _M_allocate_pback_buffer();
00500 }
00501 _M_last_overflowed = false;
00502 return this;
00503 }
00504
00505 template<typename _CharT, typename _Traits>
00506 typename basic_filebuf<_CharT, _Traits>::pos_type
00507 basic_filebuf<_CharT, _Traits>::
00508 seekoff(off_type __off, ios_base::seekdir __way, ios_base::openmode __mode)
00509 {
00510 pos_type __ret = pos_type(off_type(-1));
00511 bool __testopen = this->is_open();
00512 bool __testin = __mode & ios_base::in && _M_mode & ios_base::in;
00513 bool __testout = __mode & ios_base::out && _M_mode & ios_base::out;
00514
00515
00516 int __width = use_facet<__codecvt_type>(_M_buf_locale).encoding();
00517 if (__width < 0)
00518 __width = 0;
00519 bool __testfail = __off != 0 && __width <= 0;
00520
00521 if (__testopen && !__testfail && (__testin || __testout))
00522 {
00523
00524 _M_pback_destroy();
00525
00526 if (__way != ios_base::cur || __off != 0)
00527 {
00528 off_type __computed_off = __width * __off;
00529
00530 bool __testget = _M_in_cur && _M_in_beg < _M_in_end;
00531 bool __testput = _M_out_cur && _M_out_beg < _M_out_end;
00532
00533
00534 if (__testput || _M_last_overflowed)
00535 {
00536
00537 this->sync();
00538
00539 _M_output_unshift();
00540 }
00541
00542
00543 else if (__testget && __way == ios_base::cur)
00544 __computed_off += _M_in_cur - _M_in_beg;
00545
00546 __ret = _M_file->seekoff(__computed_off, __way, __mode);
00547 _M_set_indeterminate();
00548 }
00549
00550
00551 else
00552 {
00553 __ret = _M_file->seekoff(__off, ios_base::cur, __mode);
00554 __ret += max(_M_out_cur, _M_in_cur) - _M_buf;
00555 }
00556 }
00557 _M_last_overflowed = false;
00558 return __ret;
00559 }
00560
00561 template<typename _CharT, typename _Traits>
00562 typename basic_filebuf<_CharT, _Traits>::pos_type
00563 basic_filebuf<_CharT, _Traits>::
00564 seekpos(pos_type __pos, ios_base::openmode __mode)
00565 {
00566 pos_type __ret;
00567 off_type __off = __pos;
00568
00569 __ret = this->seekoff(__off, ios_base::beg, __mode);
00570
00571 _M_last_overflowed = false;
00572 return __ret;
00573 }
00574
00575 template<typename _CharT, typename _Traits>
00576 void
00577 basic_filebuf<_CharT, _Traits>::
00578 _M_output_unshift()
00579 { }
00580
00581 template<typename _CharT, typename _Traits>
00582 void
00583 basic_filebuf<_CharT, _Traits>::
00584 imbue(const locale& __loc)
00585 {
00586 bool __testbeg = gptr() == eback() && pptr() == pbase();
00587
00588 if (__testbeg && _M_buf_locale != __loc)
00589 {
00590 _M_buf_locale = __loc;
00591 _M_buf_locale_init = true;
00592 }
00593
00594
00595
00596
00597
00598 _M_last_overflowed = false;
00599 }
00600
00601 }
00602
00603 #endif // _CPP_BITS_FSTREAM_TCC
00604
00605