sl@0
|
1 |
/*
|
sl@0
|
2 |
* Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
|
sl@0
|
3 |
*
|
sl@0
|
4 |
* Copyright (c) 1999
|
sl@0
|
5 |
* Silicon Graphics Computer Systems, Inc.
|
sl@0
|
6 |
*
|
sl@0
|
7 |
* Copyright (c) 1999
|
sl@0
|
8 |
* Boris Fomitchev
|
sl@0
|
9 |
*
|
sl@0
|
10 |
* This material is provided "as is", with absolutely no warranty expressed
|
sl@0
|
11 |
* or implied. Any use is at your own risk.
|
sl@0
|
12 |
*
|
sl@0
|
13 |
* Permission to use or copy this software for any purpose is hereby granted
|
sl@0
|
14 |
* without fee, provided the above notices are retained on all copies.
|
sl@0
|
15 |
* Permission to modify the code and to distribute modified code is granted,
|
sl@0
|
16 |
* provided the above notices are retained, and a notice that the code was
|
sl@0
|
17 |
* modified is included with the above copyright notice.
|
sl@0
|
18 |
*
|
sl@0
|
19 |
*/
|
sl@0
|
20 |
|
sl@0
|
21 |
#include "stlport_prefix.h"
|
sl@0
|
22 |
#include "stdio_streambuf.h"
|
sl@0
|
23 |
// #include "file_streambuf.h"
|
sl@0
|
24 |
|
sl@0
|
25 |
#ifdef _STLP_UNIX
|
sl@0
|
26 |
# include <sys/types.h>
|
sl@0
|
27 |
# include <sys/stat.h>
|
sl@0
|
28 |
#endif /* __unix */
|
sl@0
|
29 |
|
sl@0
|
30 |
#include <fstream>
|
sl@0
|
31 |
#include <limits>
|
sl@0
|
32 |
#include "fstream_impl.h"
|
sl@0
|
33 |
|
sl@0
|
34 |
#if defined (_STLP_USE_WIN32_IO) && !defined(_STLP_WCE)
|
sl@0
|
35 |
# if defined (__BORLANDC__)
|
sl@0
|
36 |
// # include <cio.h>
|
sl@0
|
37 |
# include <cfcntl.h>
|
sl@0
|
38 |
# else
|
sl@0
|
39 |
# include <io.h>
|
sl@0
|
40 |
# include <fcntl.h>
|
sl@0
|
41 |
# endif
|
sl@0
|
42 |
# include <sys/stat.h>
|
sl@0
|
43 |
#endif
|
sl@0
|
44 |
|
sl@0
|
45 |
_STLP_BEGIN_NAMESPACE
|
sl@0
|
46 |
_STLP_MOVE_TO_PRIV_NAMESPACE
|
sl@0
|
47 |
|
sl@0
|
48 |
// Compare with streamoff definition in stl/char_traits.h!
|
sl@0
|
49 |
|
sl@0
|
50 |
#ifdef _STLP_USE_DEFAULT_FILE_OFFSET
|
sl@0
|
51 |
# define FSEEK fseek
|
sl@0
|
52 |
# define FTELL ftell
|
sl@0
|
53 |
# define FSTAT fstat
|
sl@0
|
54 |
# define STAT stat
|
sl@0
|
55 |
# define FSETPOS fsetpos
|
sl@0
|
56 |
# define FGETPOS fgetpos
|
sl@0
|
57 |
# define FPOS_T fpos_t
|
sl@0
|
58 |
#elif defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) /* || defined(__USE_FILE_OFFSET64) */ \
|
sl@0
|
59 |
/* || (defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)) */ /* || defined(__sgi) */
|
sl@0
|
60 |
# define FSEEK fseeko64
|
sl@0
|
61 |
# define FTELL ftello64
|
sl@0
|
62 |
# define FSTAT fstat64
|
sl@0
|
63 |
# define STAT stat64
|
sl@0
|
64 |
# define FSETPOS fsetpos64
|
sl@0
|
65 |
# define FGETPOS fgetpos64
|
sl@0
|
66 |
# define FPOS_T fpos64_t
|
sl@0
|
67 |
#else
|
sl@0
|
68 |
# define FSEEK fseek
|
sl@0
|
69 |
# define FTELL ftell
|
sl@0
|
70 |
# define FSTAT fstat
|
sl@0
|
71 |
# define STAT stat
|
sl@0
|
72 |
# define FSETPOS fsetpos
|
sl@0
|
73 |
# define FGETPOS fgetpos
|
sl@0
|
74 |
# define FPOS_T fpos_t
|
sl@0
|
75 |
#endif
|
sl@0
|
76 |
|
sl@0
|
77 |
//----------------------------------------------------------------------
|
sl@0
|
78 |
// Class stdio_streambuf_base
|
sl@0
|
79 |
|
sl@0
|
80 |
stdio_streambuf_base::stdio_streambuf_base(FILE* file)
|
sl@0
|
81 |
: /* _STLP_STD::FILE_basic_streambuf(file, 0), */
|
sl@0
|
82 |
_M_file(file)
|
sl@0
|
83 |
{}
|
sl@0
|
84 |
|
sl@0
|
85 |
stdio_streambuf_base::~stdio_streambuf_base() {
|
sl@0
|
86 |
_STLP_VENDOR_CSTD::fflush(_M_file);
|
sl@0
|
87 |
}
|
sl@0
|
88 |
|
sl@0
|
89 |
_STLP_STD::streambuf* stdio_streambuf_base::setbuf(char* s, streamsize n) {
|
sl@0
|
90 |
#ifdef _STLP_WCE
|
sl@0
|
91 |
// no buffering in windows ce .NET
|
sl@0
|
92 |
#else
|
sl@0
|
93 |
size_t __n_size_t = (sizeof(streamsize) > sizeof(size_t)) ? __STATIC_CAST(size_t, (min)(__STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()), n))
|
sl@0
|
94 |
: __STATIC_CAST(size_t, n);
|
sl@0
|
95 |
_STLP_VENDOR_CSTD::setvbuf(_M_file, s, (s == 0 && n == 0) ? _IONBF : _IOFBF, __n_size_t);
|
sl@0
|
96 |
#endif
|
sl@0
|
97 |
return this;
|
sl@0
|
98 |
}
|
sl@0
|
99 |
|
sl@0
|
100 |
stdio_streambuf_base::pos_type
|
sl@0
|
101 |
stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir,
|
sl@0
|
102 |
ios_base::openmode /* mode */) {
|
sl@0
|
103 |
int whence;
|
sl@0
|
104 |
switch (dir) {
|
sl@0
|
105 |
case ios_base::beg:
|
sl@0
|
106 |
whence = SEEK_SET;
|
sl@0
|
107 |
break;
|
sl@0
|
108 |
case ios_base::cur:
|
sl@0
|
109 |
whence = SEEK_CUR;
|
sl@0
|
110 |
break;
|
sl@0
|
111 |
case ios_base::end:
|
sl@0
|
112 |
whence = SEEK_END;
|
sl@0
|
113 |
break;
|
sl@0
|
114 |
default:
|
sl@0
|
115 |
return pos_type(-1);
|
sl@0
|
116 |
}
|
sl@0
|
117 |
|
sl@0
|
118 |
if (off <= numeric_limits<off_type>::max() && FSEEK(_M_file, off, whence) == 0) {
|
sl@0
|
119 |
FPOS_T pos;
|
sl@0
|
120 |
FGETPOS(_M_file, &pos);
|
sl@0
|
121 |
// added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
|
sl@0
|
122 |
// of a primitive type
|
sl@0
|
123 |
#if (defined (__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2))))
|
sl@0
|
124 |
return pos_type((streamoff)pos.__pos);
|
sl@0
|
125 |
#elif defined (__ISCPP__) || defined (__MVS__) || defined (__OS400__)
|
sl@0
|
126 |
return pos_type(pos.__fpos_elem[ 0 ]);
|
sl@0
|
127 |
#elif defined (__EMX__)
|
sl@0
|
128 |
return pos_type((streamoff)pos._pos);
|
sl@0
|
129 |
#else
|
sl@0
|
130 |
return pos_type(pos);
|
sl@0
|
131 |
#endif
|
sl@0
|
132 |
}
|
sl@0
|
133 |
else
|
sl@0
|
134 |
return pos_type(-1);
|
sl@0
|
135 |
}
|
sl@0
|
136 |
|
sl@0
|
137 |
|
sl@0
|
138 |
stdio_streambuf_base::pos_type
|
sl@0
|
139 |
stdio_streambuf_base::seekpos(pos_type pos, ios_base::openmode /* mode */) {
|
sl@0
|
140 |
// added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
|
sl@0
|
141 |
// of a primitive type
|
sl@0
|
142 |
#if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) )
|
sl@0
|
143 |
FPOS_T p;
|
sl@0
|
144 |
p.__pos = pos;
|
sl@0
|
145 |
# ifdef _STLP_USE_UCLIBC
|
sl@0
|
146 |
# ifdef __STDIO_MBSTATE
|
sl@0
|
147 |
memset( &(p.__mbstate), 0, sizeof(p.__mbstate) );
|
sl@0
|
148 |
# endif
|
sl@0
|
149 |
# ifdef __STDIO_WIDE
|
sl@0
|
150 |
p.mblen_pending = 0;
|
sl@0
|
151 |
# endif
|
sl@0
|
152 |
# else
|
sl@0
|
153 |
memset( &(p.__state), 0, sizeof(p.__state) );
|
sl@0
|
154 |
# endif
|
sl@0
|
155 |
#elif defined (__MVS__) || defined (__OS400__)
|
sl@0
|
156 |
FPOS_T p;
|
sl@0
|
157 |
p.__fpos_elem[0] = pos;
|
sl@0
|
158 |
#elif defined(__EMX__)
|
sl@0
|
159 |
FPOS_T p;
|
sl@0
|
160 |
p._pos = pos;
|
sl@0
|
161 |
memset( &(p._mbstate), 0, sizeof(p._mbstate) );
|
sl@0
|
162 |
#else
|
sl@0
|
163 |
FPOS_T p(pos);
|
sl@0
|
164 |
#endif
|
sl@0
|
165 |
|
sl@0
|
166 |
return FSETPOS(_M_file, &p) == 0 ? pos : pos_type(-1);
|
sl@0
|
167 |
}
|
sl@0
|
168 |
|
sl@0
|
169 |
int stdio_streambuf_base::sync() {
|
sl@0
|
170 |
return _STLP_VENDOR_CSTD::fflush(_M_file) == 0 ? 0 : -1;
|
sl@0
|
171 |
}
|
sl@0
|
172 |
|
sl@0
|
173 |
//----------------------------------------------------------------------
|
sl@0
|
174 |
// Class stdio_istreambuf
|
sl@0
|
175 |
|
sl@0
|
176 |
stdio_istreambuf::~stdio_istreambuf() {}
|
sl@0
|
177 |
|
sl@0
|
178 |
streamsize stdio_istreambuf::showmanyc() {
|
sl@0
|
179 |
if (feof(_M_file))
|
sl@0
|
180 |
return -1;
|
sl@0
|
181 |
else {
|
sl@0
|
182 |
#ifdef __SYMBIAN32__
|
sl@0
|
183 |
int fd = fileno(_M_file);
|
sl@0
|
184 |
#else
|
sl@0
|
185 |
int fd = _FILE_fd(_M_file);
|
sl@0
|
186 |
#endif
|
sl@0
|
187 |
#ifdef _STLP_WCE
|
sl@0
|
188 |
(fd); // prevent warning about unused variable
|
sl@0
|
189 |
// not sure if i can mix win32 io mode with ftell but time will show
|
sl@0
|
190 |
// cannot use WIN32_IO implementation since missing stat
|
sl@0
|
191 |
streamsize tmp = FTELL(_M_file);
|
sl@0
|
192 |
FSEEK(_M_file, 0, SEEK_END);
|
sl@0
|
193 |
streamoff size= FTELL(_M_file)-tmp;
|
sl@0
|
194 |
FSEEK(_M_file, tmp, SEEK_SET);
|
sl@0
|
195 |
#elif defined (_STLP_USE_WIN32_IO)
|
sl@0
|
196 |
// in this case, __file_size works with Win32 fh , not libc one
|
sl@0
|
197 |
streamoff size;
|
sl@0
|
198 |
struct stat buf;
|
sl@0
|
199 |
if(FSTAT(fd, &buf) == 0 && ( _S_IFREG & buf.st_mode ) )
|
sl@0
|
200 |
size = ( buf.st_size > 0 ? buf.st_size : 0);
|
sl@0
|
201 |
else
|
sl@0
|
202 |
size = 0;
|
sl@0
|
203 |
#else
|
sl@0
|
204 |
streamoff size = __file_size(fd);
|
sl@0
|
205 |
#endif
|
sl@0
|
206 |
// fbp : we can use ftell as this flavour always use stdio.
|
sl@0
|
207 |
streamsize pos = FTELL(_M_file);
|
sl@0
|
208 |
return pos >= 0 && size > pos ? size - pos : 0;
|
sl@0
|
209 |
}
|
sl@0
|
210 |
}
|
sl@0
|
211 |
|
sl@0
|
212 |
stdio_istreambuf::int_type stdio_istreambuf::underflow()
|
sl@0
|
213 |
{
|
sl@0
|
214 |
#ifdef _STLP_WCE
|
sl@0
|
215 |
int c = fgetc(_M_file);
|
sl@0
|
216 |
#else
|
sl@0
|
217 |
int c = getc(_M_file);
|
sl@0
|
218 |
#endif
|
sl@0
|
219 |
if (c != EOF) {
|
sl@0
|
220 |
_STLP_VENDOR_CSTD::ungetc(c, _M_file);
|
sl@0
|
221 |
return c;
|
sl@0
|
222 |
}
|
sl@0
|
223 |
else
|
sl@0
|
224 |
return traits_type::eof();
|
sl@0
|
225 |
}
|
sl@0
|
226 |
|
sl@0
|
227 |
stdio_istreambuf::int_type stdio_istreambuf::uflow() {
|
sl@0
|
228 |
#ifdef _STLP_WCE
|
sl@0
|
229 |
int c = fgetc(_M_file);
|
sl@0
|
230 |
#else
|
sl@0
|
231 |
int c = getc(_M_file);
|
sl@0
|
232 |
#endif
|
sl@0
|
233 |
return c != EOF ? c : traits_type::eof();
|
sl@0
|
234 |
}
|
sl@0
|
235 |
|
sl@0
|
236 |
stdio_istreambuf::int_type stdio_istreambuf::pbackfail(int_type c) {
|
sl@0
|
237 |
if (c != traits_type::eof()) {
|
sl@0
|
238 |
int result = _STLP_VENDOR_CSTD::ungetc(c, _M_file);
|
sl@0
|
239 |
return result != EOF ? result : traits_type::eof();
|
sl@0
|
240 |
}
|
sl@0
|
241 |
else{
|
sl@0
|
242 |
if (this->eback() < this->gptr()) {
|
sl@0
|
243 |
this->gbump(-1);
|
sl@0
|
244 |
return traits_type::not_eof(c);
|
sl@0
|
245 |
}
|
sl@0
|
246 |
else
|
sl@0
|
247 |
return traits_type::eof();
|
sl@0
|
248 |
}
|
sl@0
|
249 |
}
|
sl@0
|
250 |
|
sl@0
|
251 |
//----------------------------------------------------------------------
|
sl@0
|
252 |
// Class stdio_ostreambuf
|
sl@0
|
253 |
|
sl@0
|
254 |
stdio_ostreambuf::~stdio_ostreambuf() {}
|
sl@0
|
255 |
|
sl@0
|
256 |
streamsize stdio_ostreambuf::showmanyc() {
|
sl@0
|
257 |
return -1;
|
sl@0
|
258 |
}
|
sl@0
|
259 |
|
sl@0
|
260 |
stdio_ostreambuf::int_type stdio_ostreambuf::overflow(int_type c) {
|
sl@0
|
261 |
// Write the existing buffer, without writing any additional character.
|
sl@0
|
262 |
if (c == traits_type::eof()) {
|
sl@0
|
263 |
// Do we have a buffer to write?
|
sl@0
|
264 |
ptrdiff_t unwritten = this->pptr() - this->pbase();
|
sl@0
|
265 |
if (unwritten != 0) {
|
sl@0
|
266 |
_STLP_VENDOR_CSTD::fflush(_M_file);
|
sl@0
|
267 |
// Test if the write succeeded.
|
sl@0
|
268 |
if (this->pptr() - this->pbase() < unwritten)
|
sl@0
|
269 |
return traits_type::not_eof(c);
|
sl@0
|
270 |
else
|
sl@0
|
271 |
return traits_type::eof();
|
sl@0
|
272 |
}
|
sl@0
|
273 |
|
sl@0
|
274 |
// We always succeed if we don't have to do anything.
|
sl@0
|
275 |
else
|
sl@0
|
276 |
return traits_type::not_eof(c);
|
sl@0
|
277 |
}
|
sl@0
|
278 |
|
sl@0
|
279 |
// Write the character c, and whatever else might be in the buffer.
|
sl@0
|
280 |
else {
|
sl@0
|
281 |
#ifdef _STLP_WCE
|
sl@0
|
282 |
int result = fputc(c, _M_file);
|
sl@0
|
283 |
#else
|
sl@0
|
284 |
int result = putc(c, _M_file);
|
sl@0
|
285 |
#endif
|
sl@0
|
286 |
return result != EOF ? result : traits_type::eof();
|
sl@0
|
287 |
}
|
sl@0
|
288 |
}
|
sl@0
|
289 |
|
sl@0
|
290 |
_STLP_MOVE_TO_STD_NAMESPACE
|
sl@0
|
291 |
_STLP_END_NAMESPACE
|
sl@0
|
292 |
|
sl@0
|
293 |
// Local Variables:
|
sl@0
|
294 |
// mode:C++
|
sl@0
|
295 |
// End:
|
sl@0
|
296 |
|