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