|
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 |
|
55 stdio_streambuf_base::stdio_streambuf_base(FILE* file) |
|
56 : /* _STLP_STD::FILE_basic_streambuf(file, 0), */ |
|
57 _M_file(file) |
|
58 {} |
|
59 |
|
60 stdio_streambuf_base::~stdio_streambuf_base() { |
|
61 _STLP_VENDOR_CSTD::fflush(_M_file); |
|
62 } |
|
63 |
|
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 |
|
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 |
|
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 |
|
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 |
|
151 stdio_istreambuf::~stdio_istreambuf() {} |
|
152 |
|
153 streamsize stdio_istreambuf::showmanyc() |
|
154 { return 0; } |
|
155 |
|
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 |
|
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 |
|
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 |
|
198 stdio_ostreambuf::~stdio_ostreambuf() {} |
|
199 |
|
200 streamsize stdio_ostreambuf::showmanyc() |
|
201 { return -1; } |
|
202 |
|
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 |