• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
22 #ifdef _STLP_UNIX
23 #  include <sys/types.h>
24 #  include <sys/stat.h>
25 #endif
26 
27 #include <fstream>
28 #include <limits>
29 
30 _STLP_BEGIN_NAMESPACE
31 _STLP_MOVE_TO_PRIV_NAMESPACE
32 
33 // Compare with streamoff definition in stl/char_traits.h!
34 
35 #if defined (_STLP_USE_DEFAULT_FILE_OFFSET) || \
36     (!defined(_LARGEFILE_SOURCE) && !defined(_LARGEFILE64_SOURCE))
37 #  if !defined (_STLP_MSVC) || (_STLP_MSVC < 1400) || defined(_STLP_WCE)
38 #    define FSEEK fseek
39 #  else
40 #    define FSEEK _fseeki64
41 #  endif
42 #  define FSETPOS  fsetpos
43 #  define FGETPOS  fgetpos
44 #  define FPOS_T   fpos_t
45 #else
46 #  define FSEEK fseeko64
47 #  define FSETPOS  fsetpos64
48 #  define FGETPOS  fgetpos64
49 #  define FPOS_T   fpos64_t
50 #endif
51 
52 //----------------------------------------------------------------------
53 // Class stdio_streambuf_base
54 
stdio_streambuf_base(FILE * file)55 stdio_streambuf_base::stdio_streambuf_base(FILE* file)
56     : /* _STLP_STD::FILE_basic_streambuf(file, 0), */
57     _M_file(file)
58 {}
59 
~stdio_streambuf_base()60 stdio_streambuf_base::~stdio_streambuf_base() {
61   _STLP_VENDOR_CSTD::fflush(_M_file);
62 }
63 
setbuf(char * s,streamsize n)64 _STLP_STD::streambuf* stdio_streambuf_base::setbuf(char* s, streamsize n) {
65 #ifdef _STLP_WCE
66   // no buffering in windows ce .NET
67 #else
68   size_t __n_size_t = (sizeof(streamsize) > sizeof(size_t)) ? __STATIC_CAST(size_t, (min)(__STATIC_CAST(streamsize, (numeric_limits<size_t>::max)()), n))
69                                                             : __STATIC_CAST(size_t, n);
70   _STLP_VENDOR_CSTD::setvbuf(_M_file, s, (s == 0 && n == 0) ? _IONBF : _IOFBF, __n_size_t);
71 #endif
72   return this;
73 }
74 
75 stdio_streambuf_base::pos_type
seekoff(off_type off,ios_base::seekdir dir,ios_base::openmode)76 stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir,
77                               ios_base::openmode /* mode */) {
78   int whence;
79   switch (dir) {
80   case ios_base::beg:
81     whence = SEEK_SET;
82     break;
83   case ios_base::cur:
84     whence = SEEK_CUR;
85     break;
86   case ios_base::end:
87     whence = SEEK_END;
88     break;
89   default:
90     return pos_type(-1);
91   }
92 
93   if (off <= numeric_limits<off_type>::max() && FSEEK(_M_file, off, whence) == 0) {
94     FPOS_T pos;
95     FGETPOS(_M_file, &pos);
96     // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
97     // of a primitive type
98 #if (defined (__GLIBC__) && ((__GLIBC__ > 2) || ((__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2))))
99     return pos_type((streamoff)pos.__pos);
100 #elif defined (__ISCPP__) || defined (__MVS__) || defined (__OS400__)
101     return pos_type(pos.__fpos_elem[ 0 ]);
102 #elif defined (__EMX__)
103     return pos_type((streamoff)pos._pos);
104 #else
105     return pos_type(pos);
106 #endif
107   }
108   else
109     return pos_type(-1);
110 }
111 
112 
113 stdio_streambuf_base::pos_type
seekpos(pos_type pos,ios_base::openmode)114 stdio_streambuf_base::seekpos(pos_type pos, ios_base::openmode /* mode */) {
115   // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead
116   // of a primitive type
117 #if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) )
118   FPOS_T p;
119   p.__pos = pos;
120 #  ifdef _STLP_USE_UCLIBC
121 #    ifdef __STDIO_MBSTATE
122   memset( &(p.__mbstate), 0, sizeof(p.__mbstate) );
123 #    endif
124 #    ifdef __STDIO_WIDE
125   p.mblen_pending = 0;
126 #    endif
127 #  else
128   memset( &(p.__state), 0, sizeof(p.__state) );
129 #  endif
130 #elif defined (__MVS__) || defined (__OS400__)
131   FPOS_T p;
132   p.__fpos_elem[0] = pos;
133 #elif defined (__EMX__)
134   FPOS_T p;
135   p._pos = pos;
136   memset( &(p._mbstate), 0, sizeof(p._mbstate) );
137 #else
138   FPOS_T p(pos);
139 #endif
140 
141   return FSETPOS(_M_file, &p) == 0 ? pos : pos_type(-1);
142 }
143 
sync()144 int stdio_streambuf_base::sync() {
145   return _STLP_VENDOR_CSTD::fflush(_M_file) == 0 ? 0 : -1;
146 }
147 
148 //----------------------------------------------------------------------
149 // Class stdio_istreambuf
150 
~stdio_istreambuf()151 stdio_istreambuf::~stdio_istreambuf() {}
152 
showmanyc()153 streamsize stdio_istreambuf::showmanyc()
154 { return 0; }
155 
underflow()156 stdio_istreambuf::int_type stdio_istreambuf::underflow()
157 {
158 #ifdef _STLP_WCE
159   int c = fgetc(_M_file);
160 #else
161   int c = getc(_M_file);
162 #endif
163   if (c != EOF) {
164     _STLP_VENDOR_CSTD::ungetc(c, _M_file);
165     return c;
166   }
167   else
168     return traits_type::eof();
169 }
170 
uflow()171 stdio_istreambuf::int_type stdio_istreambuf::uflow() {
172 #ifdef _STLP_WCE
173   int c = fgetc(_M_file);
174 #else
175   int c = getc(_M_file);
176 #endif
177   return c != EOF ? c : traits_type::eof();
178 }
179 
pbackfail(int_type c)180 stdio_istreambuf::int_type stdio_istreambuf::pbackfail(int_type c) {
181   if (c != traits_type::eof()) {
182     int result = _STLP_VENDOR_CSTD::ungetc(c, _M_file);
183     return result != EOF ? result : traits_type::eof();
184   }
185   else{
186     if (this->eback() < this->gptr()) {
187       this->gbump(-1);
188       return traits_type::not_eof(c);
189     }
190     else
191       return traits_type::eof();
192   }
193 }
194 
195 //----------------------------------------------------------------------
196 // Class stdio_ostreambuf
197 
~stdio_ostreambuf()198 stdio_ostreambuf::~stdio_ostreambuf() {}
199 
showmanyc()200 streamsize stdio_ostreambuf::showmanyc()
201 { return -1; }
202 
overflow(int_type c)203 stdio_ostreambuf::int_type stdio_ostreambuf::overflow(int_type c) {
204   // Write the existing buffer, without writing any additional character.
205   if (c == traits_type::eof()) {
206     // Do we have a buffer to write?
207     ptrdiff_t unwritten = this->pptr() - this->pbase();
208     if (unwritten != 0) {
209       _STLP_VENDOR_CSTD::fflush(_M_file);
210       // Test if the write succeeded.
211       if (this->pptr() - this->pbase() < unwritten)
212         return traits_type::not_eof(c);
213       else
214         return traits_type::eof();
215     }
216 
217     // We always succeed if we don't have to do anything.
218     else
219       return traits_type::not_eof(c);
220   }
221 
222   // Write the character c, and whatever else might be in the buffer.
223   else {
224 #ifdef _STLP_WCE
225     int result = fputc(c, _M_file);
226 #else
227     int result = putc(c, _M_file);
228 #endif
229     return result != EOF ? result : traits_type::eof();
230   }
231 }
232 
233 _STLP_MOVE_TO_STD_NAMESPACE
234 _STLP_END_NAMESPACE
235 
236 // Local Variables:
237 // mode:C++
238 // End:
239 
240