|
1 /* |
|
2 * © Portions copyright (c) 2006-2007 Nokia Corporation. All rights reserved. |
|
3 * |
|
4 * Copyright (c) 1999 |
|
5 * Silicon Graphics Computer Systems, Inc. |
|
6 * |
|
7 * Copyright (c) 1999 |
|
8 * Boris Fomitchev |
|
9 * |
|
10 * This material is provided "as is", with absolutely no warranty expressed |
|
11 * or implied. Any use is at your own risk. |
|
12 * |
|
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. |
|
18 * |
|
19 */ |
|
20 # include "stlport_prefix.h" |
|
21 #include <stdio_streambuf> |
|
22 |
|
23 #ifdef _STLP_UNIX |
|
24 #include <sys/types.h> |
|
25 #include <sys/stat.h> |
|
26 #endif /* __unix */ |
|
27 |
|
28 #include <stl/_fstream.h> |
|
29 #include "fstream_impl.h" |
|
30 |
|
31 # if defined (_STLP_USE_WIN32_IO) && !defined(_STLP_WINCE) |
|
32 # if defined (__BORLANDC__) |
|
33 // # include <cio.h> |
|
34 # include <cfcntl.h> |
|
35 # else |
|
36 # include <io.h> |
|
37 # include <fcntl.h> |
|
38 # endif |
|
39 |
|
40 # include <sys/stat.h> |
|
41 # endif |
|
42 |
|
43 __SGI_BEGIN_NAMESPACE |
|
44 //---------------------------------------------------------------------- |
|
45 // Class stdio_streambuf_base |
|
46 |
|
47 stdio_streambuf_base::stdio_streambuf_base(FILE* file) |
|
48 : _STLP_STD::basic_streambuf<char, _STLP_STD::char_traits<char> >(file, 0), |
|
49 _M_file(file) |
|
50 {} |
|
51 |
|
52 stdio_streambuf_base::~stdio_streambuf_base() |
|
53 { |
|
54 _STLP_VENDOR_CSTD::fflush(_M_file); |
|
55 } |
|
56 |
|
57 _STLP_STD::streambuf* stdio_streambuf_base::setbuf(char* s, streamsize n) |
|
58 { |
|
59 _STLP_VENDOR_CSTD::setvbuf(_M_file, s, (s == 0 && n == 0) ? _IONBF : _IOFBF, n); |
|
60 return this; |
|
61 } |
|
62 |
|
63 stdio_streambuf_base::pos_type |
|
64 stdio_streambuf_base::seekoff(off_type off, ios_base::seekdir dir, |
|
65 ios_base::openmode /* mode */) |
|
66 { |
|
67 int whence; |
|
68 switch(dir) { |
|
69 case ios_base::beg: |
|
70 whence = SEEK_SET; |
|
71 break; |
|
72 case ios_base::cur: |
|
73 whence = SEEK_CUR; |
|
74 break; |
|
75 case ios_base::end: |
|
76 whence = SEEK_END; |
|
77 break; |
|
78 default: |
|
79 return pos_type(-1); |
|
80 } |
|
81 |
|
82 if (_STLP_VENDOR_CSTD::fseek(_M_file, off, whence) == 0) { |
|
83 fpos_t pos; |
|
84 _STLP_VENDOR_CSTD::fgetpos(_M_file, &pos); |
|
85 // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead |
|
86 // of a primitive type |
|
87 #if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) ) |
|
88 return pos_type((streamoff)pos.__pos); |
|
89 #elif defined(__ISCPP__) || defined(__MVS__) || (__OS400__) |
|
90 return pos_type(pos.__fpos_elem[ 0 ]); |
|
91 #elif defined (__EMX__) |
|
92 return pos_type((streamoff)pos._pos); |
|
93 #else |
|
94 return pos_type(pos); |
|
95 #endif |
|
96 } |
|
97 else |
|
98 return pos_type(-1); |
|
99 } |
|
100 |
|
101 |
|
102 stdio_streambuf_base::pos_type |
|
103 stdio_streambuf_base::seekpos(pos_type pos, ios_base::openmode /* mode */) // dwa 4/27/00 - suppress unused parameter warning |
|
104 { |
|
105 |
|
106 // added 21 june 00 mdb,rjf,wjs: glibc 2.2 changed fpos_t to be a struct instead |
|
107 // of a primitive type |
|
108 #if (defined(__GLIBC__) && ( (__GLIBC__ > 2) || ( (__GLIBC__ == 2) && (__GLIBC_MINOR__ >= 2) ) ) ) |
|
109 fpos_t p; |
|
110 p.__pos = pos; |
|
111 memset( &(p.__state), 0, sizeof(p.__state) ); |
|
112 #elif defined(__MVS__) || (__OS400__) |
|
113 fpos_t p; |
|
114 p.__fpos_elem[0] = pos; |
|
115 #elif defined(__EMX__) |
|
116 fpos_t p; |
|
117 p._pos = pos; |
|
118 memset( &(p._mbstate), 0, sizeof(p._mbstate) ); |
|
119 #else |
|
120 fpos_t p(pos); |
|
121 #endif |
|
122 |
|
123 if (_STLP_VENDOR_CSTD::fsetpos(_M_file, &p) == 0) |
|
124 return pos; |
|
125 else |
|
126 return pos_type(-1); |
|
127 } |
|
128 |
|
129 int stdio_streambuf_base::sync() |
|
130 { |
|
131 return _STLP_VENDOR_CSTD::fflush(_M_file) == 0 ? 0 : -1; |
|
132 } |
|
133 |
|
134 //---------------------------------------------------------------------- |
|
135 // Class stdio_istreambuf |
|
136 |
|
137 stdio_istreambuf::~stdio_istreambuf() {} |
|
138 |
|
139 _STLP_EXP_DECLSPEC streamsize stdio_istreambuf::showmanyc() |
|
140 { |
|
141 if (feof(_M_file)) |
|
142 return -1; |
|
143 else { |
|
144 int fd = _FILE_fd(_M_file); |
|
145 # ifdef _STLP_USE_WIN32_IO |
|
146 // in this case, __file_size works with Win32 fh , not libc one |
|
147 streamoff size; |
|
148 struct stat buf; |
|
149 # ifdef __BORLANDC__ |
|
150 if(fstat(fd, &buf) == 0 && S_ISREG( buf.st_mode ) ) |
|
151 # else |
|
152 if(fstat(fd, &buf) == 0 && ( _S_IFREG & buf.st_mode ) ) |
|
153 # endif |
|
154 size = ( buf.st_size > 0 ? buf.st_size : 0); |
|
155 else |
|
156 size = 0; |
|
157 # else |
|
158 streamoff size = _SgI::__file_size(fd); |
|
159 # endif |
|
160 // fbp : we can use ftell as this flavour always use stdio. |
|
161 long pos = _STLP_VENDOR_CSTD::ftell(_M_file); |
|
162 return pos >= 0 && size > pos ? size - pos : 0; |
|
163 } |
|
164 } |
|
165 |
|
166 stdio_istreambuf::int_type stdio_istreambuf::underflow() |
|
167 { |
|
168 int c = getc(_M_file); |
|
169 if (c != EOF) { |
|
170 _STLP_VENDOR_CSTD::ungetc(c, _M_file); |
|
171 return c; |
|
172 } |
|
173 else |
|
174 return traits_type::eof(); |
|
175 } |
|
176 |
|
177 stdio_istreambuf::int_type stdio_istreambuf::uflow() |
|
178 { |
|
179 #ifdef __SYMBIAN32__ |
|
180 const int_type eof = traits_type::eof(); |
|
181 return this->underflow() == eof |
|
182 ? eof |
|
183 : traits_type::to_int_type(_FILE_I_postincr(_M_file)); |
|
184 #else |
|
185 int c = getc(_M_file); |
|
186 return c != EOF ? c : traits_type::eof(); |
|
187 #endif |
|
188 } |
|
189 |
|
190 stdio_istreambuf::int_type stdio_istreambuf::pbackfail(int_type c) |
|
191 { |
|
192 if (c != traits_type::eof()) { |
|
193 int result = _STLP_VENDOR_CSTD::ungetc(c, _M_file); |
|
194 return result != EOF ? result : traits_type::eof(); |
|
195 } |
|
196 else{ |
|
197 if (this->eback() < this->gptr()) { |
|
198 this->gbump(-1); |
|
199 return traits_type::not_eof(c); |
|
200 } |
|
201 else |
|
202 return traits_type::eof(); |
|
203 } |
|
204 } |
|
205 |
|
206 //---------------------------------------------------------------------- |
|
207 // Class stdio_ostreambuf |
|
208 |
|
209 stdio_ostreambuf::~stdio_ostreambuf() {} |
|
210 |
|
211 _STLP_EXP_DECLSPEC streamsize stdio_ostreambuf::showmanyc() |
|
212 { |
|
213 return -1; |
|
214 } |
|
215 |
|
216 stdio_ostreambuf::int_type stdio_ostreambuf::overflow(int_type c) |
|
217 { |
|
218 // Write the existing buffer, without writing any additional character. |
|
219 if (c == traits_type::eof()) { |
|
220 // Do we have a buffer to write? |
|
221 ptrdiff_t unwritten = this->pptr() - this->pbase(); |
|
222 if (unwritten != 0) { |
|
223 _STLP_VENDOR_CSTD::fflush(_M_file); |
|
224 // Test if the write succeeded. |
|
225 if (this->pptr() - this->pbase() < unwritten) |
|
226 return traits_type::not_eof(c); |
|
227 else |
|
228 return traits_type::eof(); |
|
229 } |
|
230 |
|
231 // We always succeed if we don't have to do anything. |
|
232 else |
|
233 return traits_type::not_eof(c); |
|
234 } |
|
235 |
|
236 // Write the character c, and whatever else might be in the buffer. |
|
237 else { |
|
238 int result = putc(c, _M_file); |
|
239 return result != EOF ? result : traits_type::eof(); |
|
240 } |
|
241 } |
|
242 |
|
243 __SGI_END_NAMESPACE |
|
244 |
|
245 // Local Variables: |
|
246 // mode:C++ |
|
247 // End: |
|
248 |