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