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