Update contrib.
2 * Portions Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
5 * Silicon Graphics Computer Systems, Inc.
10 * This material is provided "as is", with absolutely no warranty expressed
11 * or implied. Any use is at your own risk.
13 * Permission to use or copy this software for any purpose is hereby granted
14 * without fee, provided the above notices are retained on all copies.
15 * Permission to modify the code and to distribute modified code is granted,
16 * provided the above notices are retained, and a notice that the code was
17 * modified is included with the above copyright notice.
21 #include "stlport_prefix.h"
22 #include "stdio_streambuf.h"
23 // #include "file_streambuf.h"
26 # include <sys/types.h>
27 # include <sys/stat.h>
32 #include "fstream_impl.h"
34 #if defined (_STLP_USE_WIN32_IO) && !defined(_STLP_WCE)
35 # if defined (__BORLANDC__)
42 # include <sys/stat.h>
46 _STLP_MOVE_TO_PRIV_NAMESPACE
48 // Compare with streamoff definition in stl/char_traits.h!
50 #ifdef _STLP_USE_DEFAULT_FILE_OFFSET
55 # define FSETPOS fsetpos
56 # define FGETPOS fgetpos
57 # define FPOS_T fpos_t
58 #elif defined(_LARGEFILE_SOURCE) || defined(_LARGEFILE64_SOURCE) /* || defined(__USE_FILE_OFFSET64) */ \
59 /* || (defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)) */ /* || defined(__sgi) */
60 # define FSEEK fseeko64
61 # define FTELL ftello64
62 # define FSTAT fstat64
64 # define FSETPOS fsetpos64
65 # define FGETPOS fgetpos64
66 # define FPOS_T fpos64_t
72 # define FSETPOS fsetpos
73 # define FGETPOS fgetpos
74 # define FPOS_T fpos_t
77 //----------------------------------------------------------------------
78 // Class stdio_streambuf_base
80 stdio_streambuf_base::stdio_streambuf_base(FILE* file)
81 : /* _STLP_STD::FILE_basic_streambuf(file, 0), */
85 stdio_streambuf_base::~stdio_streambuf_base() {
86 _STLP_VENDOR_CSTD::fflush(_M_file);
89 _STLP_STD::streambuf* stdio_streambuf_base::setbuf(char* s, streamsize n) {
91 // no buffering in windows ce .NET
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))
94 : __STATIC_CAST(size_t, n);
95 _STLP_VENDOR_CSTD::setvbuf(_M_file, s, (s == 0 && n == 0) ? _IONBF : _IOFBF, __n_size_t);
100 stdio_streambuf_base::pos_type
101 stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir,
102 ios_base::openmode /* mode */) {
118 if (off <= numeric_limits<off_type>::max() && FSEEK(_M_file, off, whence) == 0) {
120 FGETPOS(_M_file, &pos);
121 // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
122 // of a primitive type
123 #if (defined (__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2))))
124 return pos_type((streamoff)pos.__pos);
125 #elif defined (__ISCPP__) || defined (__MVS__) || defined (__OS400__)
126 return pos_type(pos.__fpos_elem[ 0 ]);
127 #elif defined (__EMX__)
128 return pos_type((streamoff)pos._pos);
130 return pos_type(pos);
138 stdio_streambuf_base::pos_type
139 stdio_streambuf_base::seekpos(pos_type pos, ios_base::openmode /* mode */) {
140 // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
141 // of a primitive type
142 #if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) )
145 # ifdef _STLP_USE_UCLIBC
146 # ifdef __STDIO_MBSTATE
147 memset( &(p.__mbstate), 0, sizeof(p.__mbstate) );
153 memset( &(p.__state), 0, sizeof(p.__state) );
155 #elif defined (__MVS__) || defined (__OS400__)
157 p.__fpos_elem[0] = pos;
158 #elif defined(__EMX__)
161 memset( &(p._mbstate), 0, sizeof(p._mbstate) );
166 return FSETPOS(_M_file, &p) == 0 ? pos : pos_type(-1);
169 int stdio_streambuf_base::sync() {
170 return _STLP_VENDOR_CSTD::fflush(_M_file) == 0 ? 0 : -1;
173 //----------------------------------------------------------------------
174 // Class stdio_istreambuf
176 stdio_istreambuf::~stdio_istreambuf() {}
178 streamsize stdio_istreambuf::showmanyc() {
183 int fd = fileno(_M_file);
185 int fd = _FILE_fd(_M_file);
188 (fd); // prevent warning about unused variable
189 // not sure if i can mix win32 io mode with ftell but time will show
190 // cannot use WIN32_IO implementation since missing stat
191 streamsize tmp = FTELL(_M_file);
192 FSEEK(_M_file, 0, SEEK_END);
193 streamoff size= FTELL(_M_file)-tmp;
194 FSEEK(_M_file, tmp, SEEK_SET);
195 #elif defined (_STLP_USE_WIN32_IO)
196 // in this case, __file_size works with Win32 fh , not libc one
199 if(FSTAT(fd, &buf) == 0 && ( _S_IFREG & buf.st_mode ) )
200 size = ( buf.st_size > 0 ? buf.st_size : 0);
204 streamoff size = __file_size(fd);
206 // fbp : we can use ftell as this flavour always use stdio.
207 streamsize pos = FTELL(_M_file);
208 return pos >= 0 && size > pos ? size - pos : 0;
212 stdio_istreambuf::int_type stdio_istreambuf::underflow()
215 int c = fgetc(_M_file);
217 int c = getc(_M_file);
220 _STLP_VENDOR_CSTD::ungetc(c, _M_file);
224 return traits_type::eof();
227 stdio_istreambuf::int_type stdio_istreambuf::uflow() {
229 int c = fgetc(_M_file);
231 int c = getc(_M_file);
233 return c != EOF ? c : traits_type::eof();
236 stdio_istreambuf::int_type stdio_istreambuf::pbackfail(int_type c) {
237 if (c != traits_type::eof()) {
238 int result = _STLP_VENDOR_CSTD::ungetc(c, _M_file);
239 return result != EOF ? result : traits_type::eof();
242 if (this->eback() < this->gptr()) {
244 return traits_type::not_eof(c);
247 return traits_type::eof();
251 //----------------------------------------------------------------------
252 // Class stdio_ostreambuf
254 stdio_ostreambuf::~stdio_ostreambuf() {}
256 streamsize stdio_ostreambuf::showmanyc() {
260 stdio_ostreambuf::int_type stdio_ostreambuf::overflow(int_type c) {
261 // Write the existing buffer, without writing any additional character.
262 if (c == traits_type::eof()) {
263 // Do we have a buffer to write?
264 ptrdiff_t unwritten = this->pptr() - this->pbase();
265 if (unwritten != 0) {
266 _STLP_VENDOR_CSTD::fflush(_M_file);
267 // Test if the write succeeded.
268 if (this->pptr() - this->pbase() < unwritten)
269 return traits_type::not_eof(c);
271 return traits_type::eof();
274 // We always succeed if we don't have to do anything.
276 return traits_type::not_eof(c);
279 // Write the character c, and whatever else might be in the buffer.
282 int result = fputc(c, _M_file);
284 int result = putc(c, _M_file);
286 return result != EOF ? result : traits_type::eof();
290 _STLP_MOVE_TO_STD_NAMESPACE