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