source: trunk/gcc/libstdc++-v3/src/fstream.cc

Last change on this file was 1392, checked in by bird, 21 years ago

This commit was generated by cvs2svn to compensate for changes in r1391,
which included commits to RCS files with non-trunk default branches.

  • Property cvs2svn:cvs-rev set to 1.1.1.2
  • Property svn:eol-style set to native
  • Property svn:executable set to *
File size: 5.8 KB
Line 
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
37namespace 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
Note: See TracBrowser for help on using the repository browser.