Remove incorrect cache_purge() calls in *_rmdir() (OLD API). These could
[dragonfly.git] / contrib / libstdc++3 / src / fstream.cc
1 // File based streams -*- C++ -*-
2
3 // Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003
4 // Free Software Foundation, Inc.
5 //
6 // This file is part of the GNU ISO C++ Library.  This library is free
7 // software; you can redistribute it and/or modify it under the
8 // terms of the GNU General Public License as published by the
9 // Free Software Foundation; either version 2, or (at your option)
10 // any later version.
11
12 // This library is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16
17 // You should have received a copy of the GNU General Public License along
18 // with this library; see the file COPYING.  If not, write to the Free
19 // Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
20 // USA.
21
22 // As a special exception, you may use this file as part of a free software
23 // library without restriction.  Specifically, if other files instantiate
24 // templates or use macros or inline functions from this file, or you compile
25 // this file and link it with other files to produce an executable, this
26 // file does not by itself cause the resulting executable to be covered by
27 // the GNU General Public License.  This exception does not however
28 // invalidate any other reasons why the executable file might be covered by
29 // the GNU General Public License.
30
31 //
32 // ISO C++ 14882: 27.8  File-based streams
33 //
34
35 #include <fstream>
36
37 namespace std 
38 {
39   template<> 
40     basic_filebuf<char>::int_type 
41     basic_filebuf<char>::_M_underflow_common(bool __bump)
42     {
43       int_type __ret = traits_type::eof();
44       bool __testin = _M_mode & ios_base::in;
45       bool __testout = _M_mode & ios_base::out;
46
47       if (__testin)
48         {
49           // Check for pback madness, and if so swich back to the
50           // normal buffers and jet outta here before expensive
51           // fileops happen...
52           if (_M_pback_init)
53             _M_pback_destroy();
54
55           if (_M_in_cur && _M_in_cur < _M_in_end)
56             {
57               __ret = traits_type::to_int_type(*_M_in_cur);
58               if (__bump)
59                 _M_in_cur_move(1);
60               return __ret;
61             }
62
63           // Sync internal and external buffers.
64           // NB: __testget -> __testput as _M_buf_unified here.
65           bool __testget = _M_in_cur && _M_in_beg < _M_in_cur;
66           bool __testinit = _M_is_indeterminate();
67           if (__testget)
68             {
69               if (__testout)
70                 _M_really_overflow();
71               else if (_M_in_cur != _M_filepos)
72                 _M_file.seekoff(_M_in_cur - _M_filepos,
73                                 ios_base::cur, ios_base::in);
74             }
75
76           if (__testinit || __testget)
77             {
78               streamsize __elen = 0;
79               streamsize __ilen = 0;
80               __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg), 
81                                       _M_buf_size);
82               __ilen = __elen;
83
84               if (0 < __ilen)
85                 {
86                   _M_set_determinate(__ilen);
87                   if (__testout)
88                     _M_out_cur = _M_in_cur;
89                   __ret = traits_type::to_int_type(*_M_in_cur);
90                   if (__bump)
91                     _M_in_cur_move(1);
92                   else if (_M_buf_size == 1)
93                     {
94                       // If we are synced with stdio, we have to unget the
95                       // character we just read so that the file pointer
96                       // doesn't move.
97                       _M_file.sys_ungetc(traits_type::to_int_type(*_M_in_cur));
98                       _M_set_indeterminate();
99                     }
100                 }          
101             }
102         }
103       _M_last_overflowed = false;       
104       return __ret;
105     }
106
107 #ifdef _GLIBCPP_USE_WCHAR_T
108   template<> 
109     basic_filebuf<wchar_t>::int_type 
110     basic_filebuf<wchar_t>::_M_underflow_common(bool __bump)
111     {
112       int_type __ret = traits_type::eof();
113       bool __testin = _M_mode & ios_base::in;
114       bool __testout = _M_mode & ios_base::out;
115
116       if (__testin)
117         {
118           // Check for pback madness, and if so swich back to the
119           // normal buffers and jet outta here before expensive
120           // fileops happen...
121           if (_M_pback_init)
122             _M_pback_destroy();
123
124           if (_M_in_cur && _M_in_cur < _M_in_end)
125             {
126               __ret = traits_type::to_int_type(*_M_in_cur);
127               if (__bump)
128                 _M_in_cur_move(1);
129               return __ret;
130             }
131
132           // Sync internal and external buffers.
133           // NB: __testget -> __testput as _M_buf_unified here.
134           bool __testget = _M_in_cur && _M_in_beg < _M_in_cur;
135           bool __testinit = _M_is_indeterminate();
136           if (__testget)
137             {
138               if (__testout)
139                 _M_really_overflow();
140               else if (_M_in_cur != _M_filepos)
141                 _M_file.seekoff(_M_in_cur - _M_filepos,
142                                 ios_base::cur, ios_base::in);
143             }
144
145           if (__testinit || __testget)
146             {
147               const locale __loc = this->getloc();
148               const __codecvt_type& __cvt = use_facet<__codecvt_type>(__loc); 
149
150               streamsize __elen = 0;
151               streamsize __ilen = 0;
152               if (__cvt.always_noconv())
153                 {
154                   __elen = _M_file.xsgetn(reinterpret_cast<char*>(_M_in_beg), 
155                                           _M_buf_size);
156                   __ilen = __elen;
157                 }
158               else
159                 {
160                   char* __buf = static_cast<char*>(__builtin_alloca(_M_buf_size));
161                   __elen = _M_file.xsgetn(__buf, _M_buf_size);
162
163                   const char* __eend;
164                   char_type* __iend;
165                   codecvt_base::result __r;
166                   __r = __cvt.in(_M_state_cur, __buf, 
167                                  __buf + __elen, __eend, _M_in_beg, 
168                                  _M_in_beg + _M_buf_size, __iend);
169                   if (__r == codecvt_base::ok)
170                     __ilen = __iend - _M_in_beg;
171                   else 
172                     {
173                       // Unwind.
174                       __ilen = 0;
175                       _M_file.seekoff(-__elen, ios_base::cur, ios_base::in);
176                     }
177                 }
178
179               if (0 < __ilen)
180                 {
181                   _M_set_determinate(__ilen);
182                   if (__testout)
183                     _M_out_cur = _M_in_cur;
184                   __ret = traits_type::to_int_type(*_M_in_cur);
185                   if (__bump)
186                     _M_in_cur_move(1);
187                   else if (_M_buf_size == 1)
188                     {
189                       // If we are synced with stdio, we have to unget the
190                       // character we just read so that the file pointer
191                       // doesn't move.
192                       _M_file.sys_ungetc(traits_type::to_int_type(*_M_in_cur));
193                       _M_set_indeterminate();
194                     }
195                 }          
196             }
197         }
198       _M_last_overflowed = false;       
199       return __ret;
200     }
201 #endif
202 } // namespace std