bzr branch
http://bzr.ed.am/elec/propeller-clock
57
by edam
added ulibc |
1 |
/* Copyright (C) 2004 Garrett A. Kajmowicz |
2 |
||
3 |
This file is part of the uClibc++ Library. |
|
4 |
This library is free software; you can redistribute it and/or |
|
5 |
modify it under the terms of the GNU Lesser General Public |
|
6 |
License as published by the Free Software Foundation; either |
|
7 |
version 2.1 of the License, or (at your option) any later version. |
|
8 |
||
9 |
This library is distributed in the hope that it will be useful, |
|
10 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
11 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
12 |
Lesser General Public License for more details. |
|
13 |
||
14 |
You should have received a copy of the GNU Lesser General Public |
|
15 |
License along with this library; if not, write to the Free Software |
|
16 |
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
17 |
*/ |
|
18 |
||
19 |
#ifndef __STD_HEADER_FSTREAM |
|
20 |
#define __STD_HEADER_FSTREAM 1 |
|
21 |
||
22 |
||
23 |
#include<basic_definitions> |
|
24 |
||
25 |
#include <cstdio> |
|
26 |
#include <cstdlib> |
|
27 |
#include <streambuf> |
|
28 |
#include <istream> |
|
29 |
#include <ostream> |
|
30 |
#include <char_traits> |
|
31 |
||
32 |
#include <unistd.h> |
|
33 |
#include <fcntl.h> |
|
34 |
#include <errno.h> |
|
35 |
||
36 |
#ifdef __UCLIBCXX_HAS_WCHAR__ |
|
37 |
#include <cwchar> |
|
38 |
#include <cwctype> |
|
39 |
#endif //__UCLIBCXX_HAS_WCHAR__ |
|
40 |
||
41 |
#pragma GCC visibility push(default) |
|
42 |
||
43 |
namespace std{ |
|
44 |
||
45 |
template <class C, class T> class basic_filebuf; |
|
46 |
||
47 |
typedef basic_filebuf<char> filebuf; |
|
48 |
#ifdef __UCLIBCXX_HAS_WCHAR__ |
|
49 |
typedef basic_filebuf<wchar_t> wfilebuf; |
|
50 |
#endif |
|
51 |
||
52 |
||
53 |
template <class charT, class traits> class _UCXXEXPORT basic_filebuf |
|
54 |
: public basic_streambuf<charT,traits> |
|
55 |
{ |
|
56 |
#ifdef __UCLIBCXX_SUPPORT_CDIR__ |
|
57 |
friend ios_base::Init::Init(); //Needed for cout/cin stuff |
|
58 |
#endif |
|
59 |
public: |
|
60 |
// Types (inherited from basic_streambuf: |
|
61 |
typedef typename basic_streambuf<charT, traits>::char_type char_type; |
|
62 |
typedef typename basic_streambuf<charT, traits>::int_type int_type; |
|
63 |
typedef typename basic_streambuf<charT, traits>::pos_type pos_type; |
|
64 |
typedef typename basic_streambuf<charT, traits>::off_type off_type; |
|
65 |
typedef traits traits_type; |
|
66 |
||
67 |
//Constructors/destructor: |
|
68 |
||
69 |
_UCXXEXPORT basic_filebuf() : basic_streambuf<charT, traits>(), fp(0), pbuffer(0), gbuffer(0) |
|
70 |
{ |
|
71 |
append=false; |
|
72 |
pbuffer = new char_type[__UCLIBCXX_IOSTREAM_BUFSIZE__]; |
|
73 |
gbuffer = new char_type[__UCLIBCXX_IOSTREAM_BUFSIZE__]; |
|
74 |
||
75 |
setp(pbuffer, pbuffer + __UCLIBCXX_IOSTREAM_BUFSIZE__); |
|
76 |
//Position get buffer so that there is no data available |
|
77 |
setg(gbuffer, gbuffer + __UCLIBCXX_IOSTREAM_BUFSIZE__, |
|
78 |
gbuffer + __UCLIBCXX_IOSTREAM_BUFSIZE__); |
|
79 |
} |
|
80 |
||
81 |
||
82 |
_UCXXEXPORT virtual ~basic_filebuf(){ |
|
83 |
sync(); |
|
84 |
close(); |
|
85 |
delete [] pbuffer; |
|
86 |
delete [] gbuffer; |
|
87 |
pbuffer = 0; |
|
88 |
gbuffer = 0; |
|
89 |
} |
|
90 |
||
91 |
||
92 |
//Members: |
|
93 |
||
94 |
_UCXXEXPORT bool is_open() const{ |
|
95 |
if(fp == 0){ |
|
96 |
return false; |
|
97 |
} |
|
98 |
return true; |
|
99 |
} |
|
100 |
||
101 |
_UCXXEXPORT basic_filebuf<charT,traits>* open(const char* s, ios_base::openmode mode){ |
|
102 |
bool move_end = (mode & ios_base::ate) != 0; |
|
103 |
if(is_open() !=false){ //Must call close() first |
|
104 |
return 0; |
|
105 |
} |
|
106 |
basic_streambuf<charT,traits>::openedFor = mode; |
|
107 |
mode = mode & ~ios_base::ate; |
|
108 |
||
109 |
if(mode == ios_base::out || mode == (ios_base::out | ios_base::trunc)){ |
|
110 |
fp = fopen(s, "w" ); |
|
111 |
}else if((mode & ios_base::app) && ! (mode & ios_base::trunc)){ |
|
112 |
if(mode & ios_base::binary){ |
|
113 |
if(mode & ios_base::in){ |
|
114 |
fp = fopen(s, "a+b"); |
|
115 |
}else{ |
|
116 |
fp = fopen(s, "ab"); |
|
117 |
} |
|
118 |
}else{ |
|
119 |
if(mode & ios_base::in){ |
|
120 |
fp = fopen(s, "a+"); |
|
121 |
}else{ |
|
122 |
fp = fopen(s, "a"); |
|
123 |
} |
|
124 |
} |
|
125 |
}else if(mode == ios_base::in){ |
|
126 |
fp = fopen(s, "r"); |
|
127 |
}else if(mode == (ios_base::in | ios_base::out)){ |
|
128 |
fp = fopen(s, "r+"); |
|
129 |
}else if(mode == (ios_base::in | ios_base::out | ios_base::trunc)){ |
|
130 |
fp = fopen(s, "w+"); |
|
131 |
}else if(mode == (ios_base::binary | ios_base::out)){ |
|
132 |
fp = fopen(s, "wb"); |
|
133 |
}else if(mode == (ios_base::in | ios_base::binary)){ |
|
134 |
fp = fopen(s, "rb"); |
|
135 |
}else if(mode == (ios_base::in | ios_base::binary | ios_base::out)){ |
|
136 |
fp = fopen(s, "r+b"); |
|
137 |
}else if(mode==(ios_base::binary | ios_base::out | ios_base::trunc)){ |
|
138 |
fp = fopen(s, "w+b"); |
|
139 |
}else if(mode == (ios_base::in | ios_base::binary | ios_base::out | ios_base::trunc)){ |
|
140 |
fp = fopen(s, "w+b"); |
|
141 |
} |
|
142 |
||
143 |
if(fp == 0){ |
|
144 |
return 0; |
|
145 |
} |
|
146 |
if(ferror(fp)){ |
|
147 |
fclose(fp); |
|
148 |
fp=0; |
|
149 |
return 0; |
|
150 |
} |
|
151 |
int retval = 0; |
|
152 |
||
153 |
//Check to make sure the stream is good |
|
154 |
if(move_end == true){ |
|
155 |
retval = fseek(fp, 0, SEEK_END); |
|
156 |
}else{ |
|
157 |
retval = fseek(fp, 0, SEEK_SET); |
|
158 |
} |
|
159 |
if(retval!=0){ //Seek error |
|
160 |
fclose(fp); |
|
161 |
fp=0; |
|
162 |
return 0; |
|
163 |
} |
|
164 |
||
165 |
basic_streambuf<charT,traits>::mgnext = basic_streambuf<charT,traits>::mgend; |
|
166 |
||
167 |
return this; |
|
168 |
} |
|
169 |
_UCXXEXPORT basic_filebuf<charT,traits>* close(){ |
|
170 |
if(fp != 0 && fp != stdin && fp != stdout && fp !=stderr ){ |
|
171 |
overflow(); |
|
172 |
sync(); |
|
173 |
int retval = fclose(fp); |
|
174 |
if(retval !=0){ //Error of some sort |
|
175 |
return 0; |
|
176 |
} |
|
177 |
fp=0; |
|
178 |
} |
|
179 |
return this; |
|
180 |
} |
|
181 |
protected: |
|
182 |
_UCXXEXPORT basic_filebuf(const basic_filebuf<charT,traits> &){ } |
|
183 |
_UCXXEXPORT basic_filebuf<charT,traits> & operator=(const basic_filebuf<charT,traits> &){ return *this; } |
|
184 |
||
185 |
//Overridden virtual functions: |
|
186 |
||
187 |
virtual _UCXXEXPORT int showmanyc(){ |
|
188 |
return basic_streambuf<charT,traits>::egptr() - basic_streambuf<charT,traits>::gptr(); |
|
189 |
} |
|
190 |
virtual _UCXXEXPORT int_type underflow(){ |
|
191 |
/* Some variables used internally: |
|
192 |
Buffer pointers: |
|
193 |
charT * mgbeg; |
|
194 |
charT * mgnext; |
|
195 |
charT * mgend; |
|
196 |
||
197 |
eback() returns mgbeg |
|
198 |
gptr() returns mgnext |
|
199 |
egptr() returns mgend |
|
200 |
||
201 |
gbump(int n) mgnext+=n |
|
202 |
||
203 |
*/ |
|
204 |
||
205 |
if(!is_open()){ |
|
206 |
return traits::eof(); |
|
207 |
} |
|
208 |
||
209 |
if(basic_streambuf<charT,traits>::eback() == 0){ |
|
210 |
//No buffer, so... |
|
211 |
charT c; |
|
212 |
int retval; |
|
213 |
retval = fread(&c, sizeof(charT), 1, fp); |
|
214 |
||
215 |
if(retval == 0 || feof(fp) || ferror(fp) ){ |
|
216 |
return traits::eof(); |
|
217 |
} |
|
218 |
return traits::to_int_type(c); |
|
219 |
} |
|
220 |
||
221 |
if(basic_streambuf<charT,traits>::eback() == basic_streambuf<charT,traits>::gptr()){ //Buffer is full |
|
222 |
return traits::to_int_type(*basic_streambuf<charT,traits>::gptr()); |
|
223 |
} |
|
224 |
//Shift entire buffer back to the begining |
|
225 |
size_t offset = basic_streambuf<charT,traits>::gptr() - basic_streambuf<charT,traits>::eback(); |
|
226 |
size_t amountData = basic_streambuf<charT,traits>::egptr() - basic_streambuf<charT,traits>::gptr(); |
|
227 |
||
228 |
for(charT * i = basic_streambuf<charT,traits>::gptr(); i < basic_streambuf<charT,traits>::egptr(); ++i){ |
|
229 |
*(i-offset) = *i; |
|
230 |
} |
|
231 |
||
232 |
size_t retval = 0; |
|
233 |
//Save operating flags from file descriptor |
|
234 |
int fcntl_flags = fcntl(fileno(fp), F_GETFL); |
|
235 |
retval = 0; |
|
236 |
||
237 |
//Set to non_blocking mode |
|
238 |
fcntl(fileno(fp), F_SETFL, fcntl_flags | O_NONBLOCK); |
|
239 |
||
240 |
//Fill rest of buffer |
|
241 |
retval = fread(basic_streambuf<charT,traits>::egptr() - |
|
242 |
basic_streambuf<charT,traits>::gptr() + basic_streambuf<charT,traits>::eback(), |
|
243 |
sizeof(charT), |
|
244 |
offset, |
|
245 |
fp |
|
246 |
); |
|
247 |
||
248 |
//Clear problems where we didn't read in enough characters |
|
249 |
if(EAGAIN == errno){ |
|
250 |
clearerr(fp); |
|
251 |
} |
|
252 |
||
253 |
//Restore file descriptor clase |
|
254 |
fcntl(fileno(fp), F_SETFL, fcntl_flags); |
|
255 |
||
256 |
//Now we are going to make sure that we read in at least one character. The hard way. |
|
257 |
if(retval == 0){ |
|
258 |
fcntl_flags = fcntl(fileno(fp), F_GETFL); |
|
259 |
//Set to blocking mode |
|
260 |
fcntl(fileno(fp), F_SETFL, fcntl_flags & ~O_NONBLOCK); |
|
261 |
||
262 |
retval = fread(basic_streambuf<charT,traits>::egptr() - |
|
263 |
basic_streambuf<charT,traits>::gptr() + basic_streambuf<charT,traits>::eback(), |
|
264 |
sizeof(charT), |
|
265 |
1, |
|
266 |
fp |
|
267 |
); |
|
268 |
||
269 |
//Restore file descriptor clase |
|
270 |
fcntl(fileno(fp), F_SETFL, fcntl_flags); |
|
271 |
||
272 |
} |
|
273 |
||
274 |
if(retval !=offset){ //Slide buffer forward again |
|
275 |
for(size_t i = 0; i < amountData + retval; ++i){ |
|
276 |
*(basic_streambuf<charT,traits>::egptr() - i - 1) = |
|
277 |
*(basic_streambuf<charT,traits>::eback() + amountData + retval - i - 1); |
|
278 |
} |
|
279 |
} |
|
280 |
||
281 |
basic_streambuf<charT,traits>::mgnext -= retval; |
|
282 |
||
283 |
if( (retval <= 0 && feof(fp)) || ferror(fp) ){ |
|
284 |
return traits::eof(); |
|
285 |
} |
|
286 |
||
287 |
return traits::to_int_type(*basic_streambuf<charT,traits>::gptr()); |
|
288 |
} |
|
289 |
virtual _UCXXEXPORT int_type uflow(){ |
|
290 |
bool dobump = (basic_streambuf<charT,traits>::gptr() != 0); |
|
291 |
int_type retval = underflow(); |
|
292 |
if(dobump){ |
|
293 |
basic_streambuf<charT,traits>::gbump(1); |
|
294 |
} |
|
295 |
return retval; |
|
296 |
} |
|
297 |
virtual _UCXXEXPORT int_type pbackfail(int_type c = traits::eof()){ |
|
298 |
if(is_open() == false || |
|
299 |
basic_streambuf<charT,traits>::gptr() == basic_streambuf<charT,traits>::eback()) |
|
300 |
{ |
|
301 |
return traits::eof(); |
|
302 |
} |
|
303 |
if(traits::eq_int_type(c,traits::eof()) == false){ |
|
304 |
if(traits::eq(traits::to_char_type(c), basic_streambuf<charT,traits>::gptr()[-1]) == true){ |
|
305 |
basic_streambuf<charT,traits>::gbump(-1); |
|
306 |
}else{ |
|
307 |
basic_streambuf<charT,traits>::gbump(-1); |
|
308 |
basic_streambuf<charT,traits>::gptr()[0] = c; |
|
309 |
} |
|
310 |
return c; |
|
311 |
}else{ |
|
312 |
basic_streambuf<charT,traits>::gbump(-1); |
|
313 |
return traits::not_eof(c); |
|
314 |
} |
|
315 |
} |
|
316 |
||
317 |
virtual _UCXXEXPORT int_type overflow(int_type c = traits::eof()){ |
|
318 |
if(is_open() == false){ |
|
319 |
//Can't do much |
|
320 |
return traits::eof(); |
|
321 |
} |
|
322 |
if(basic_streambuf<charT,traits>::pbase() == 0){ //Unbuffered - elliminate dupe code below |
|
323 |
if(fputc(c, fp) == EOF){ |
|
324 |
return traits::eof(); |
|
325 |
} |
|
326 |
return c; |
|
327 |
} |
|
328 |
if(basic_streambuf<charT,traits>::pbase() == 0 && traits::eq_int_type(c,traits::eof()) ){ |
|
329 |
//Nothing to flush |
|
330 |
return traits::not_eof(c); |
|
331 |
} |
|
332 |
size_t r = basic_streambuf<charT,traits>::pptr() - basic_streambuf<charT,traits>::pbase(); |
|
333 |
||
334 |
if( r == 0 && traits::eq_int_type(c,traits::eof()) ){ |
|
335 |
return traits::not_eof(c); |
|
336 |
}else if (r == 0 ){ |
|
337 |
if(fputc(c, fp) == EOF){ |
|
338 |
return traits::eof(); |
|
339 |
} |
|
340 |
return c; |
|
341 |
} |
|
342 |
||
343 |
size_t totalChars = r; |
|
344 |
||
345 |
char_type *buffer = 0; |
|
346 |
if(traits::eq_int_type(c,traits::eof())){ |
|
347 |
buffer = new char_type[r]; |
|
348 |
}else{ |
|
349 |
buffer = new char_type[r+1]; |
|
350 |
buffer[r] = c; |
|
351 |
totalChars++; |
|
352 |
} |
|
353 |
||
354 |
traits::copy(buffer, basic_streambuf<charT,traits>::pbase(), r); |
|
355 |
// memcpy(buffer, basic_streambuf<charT,traits>::pbase(), r); |
|
356 |
||
357 |
size_t retval = fwrite(buffer, sizeof(charT), totalChars, fp); |
|
358 |
if(retval !=totalChars){ |
|
359 |
if(retval == 0){ |
|
360 |
delete [] buffer; |
|
361 |
return traits::eof(); |
|
362 |
} |
|
363 |
basic_streambuf<charT,traits>::pbump(-retval); |
|
364 |
fprintf(stderr, "***** Did not write the full buffer out. Should be: %d, actually: %d\n", |
|
365 |
totalChars, retval); |
|
366 |
}else{ |
|
367 |
basic_streambuf<charT,traits>::pbump(-r); |
|
368 |
} |
|
369 |
||
370 |
delete [] buffer; |
|
371 |
return traits::not_eof(c); |
|
372 |
} |
|
373 |
||
374 |
virtual _UCXXEXPORT basic_streambuf<charT,traits>* setbuf(char_type* s, streamsize n){ |
|
375 |
if(s == 0 && n == 0){ //Unbuffered |
|
376 |
if(pbuffer !=0){ |
|
377 |
delete [] pbuffer; |
|
378 |
} |
|
379 |
if(gbuffer !=0){ |
|
380 |
delete [] gbuffer; |
|
381 |
} |
|
382 |
pbuffer = 0; |
|
383 |
gbuffer = 0; |
|
384 |
}else if(basic_streambuf<charT,traits>::gptr() !=0 && |
|
385 |
basic_streambuf<charT,traits>::gptr()==basic_streambuf<charT,traits>::egptr()) |
|
386 |
{ |
|
387 |
delete [] pbuffer; |
|
388 |
pbuffer = s; |
|
389 |
} |
|
390 |
return this; |
|
391 |
} |
|
392 |
virtual _UCXXEXPORT pos_type seekoff(off_type off, ios_base::seekdir way, |
|
393 |
ios_base::openmode = ios_base::in | ios_base::out) |
|
394 |
{ |
|
395 |
if(is_open() == false){ |
|
396 |
return -1; |
|
397 |
} |
|
398 |
int whence = SEEK_SET; // if(way == basic_ios<charT>::beg) |
|
399 |
off_type position = off; |
|
400 |
||
401 |
if(way == basic_ios<charT>::cur){ |
|
402 |
whence = SEEK_CUR; |
|
403 |
position -= (basic_streambuf<charT,traits>::egptr() - basic_streambuf<charT,traits>::gptr()); |
|
404 |
}else if(way == basic_ios<charT>::end){ |
|
405 |
whence = SEEK_END; |
|
406 |
} |
|
407 |
||
408 |
sync(); |
|
409 |
||
410 |
int retval = fseek( |
|
411 |
fp, |
|
412 |
sizeof(charT)*(position), |
|
413 |
whence |
|
414 |
); |
|
415 |
||
416 |
//Invalidate read buffer |
|
417 |
basic_streambuf<charT,traits>::gbump( |
|
418 |
basic_streambuf<charT,traits>::egptr() - basic_streambuf<charT,traits>::gptr() |
|
419 |
); |
|
420 |
||
421 |
if(-1 != retval){ |
|
422 |
retval = ftell(fp); |
|
423 |
} |
|
424 |
||
425 |
return retval; |
|
426 |
} |
|
427 |
virtual _UCXXEXPORT pos_type seekpos(pos_type sp, ios_base::openmode = ios_base::in | ios_base::out){ |
|
428 |
if(is_open() == false){ |
|
429 |
return -1; |
|
430 |
} |
|
431 |
sync(); |
|
432 |
||
433 |
int retval = fseek(fp,sizeof(charT)* sp, SEEK_SET); |
|
434 |
||
435 |
//Invalidate read buffer |
|
436 |
basic_streambuf<charT,traits>::gbump(basic_streambuf<charT,traits>::egptr() - basic_streambuf<charT,traits>::gptr()); |
|
437 |
if(retval > -1){ |
|
438 |
return sp; |
|
439 |
} |
|
440 |
return -1; |
|
441 |
} |
|
442 |
virtual _UCXXEXPORT int sync(){ |
|
443 |
if(pbuffer !=0){ |
|
444 |
if(overflow() == traits::eof()){ |
|
445 |
return -1; |
|
446 |
} |
|
447 |
} |
|
448 |
if(0 != fp && 0 != fflush(fp)){ |
|
449 |
return -1; |
|
450 |
} |
|
451 |
return 0; |
|
452 |
} |
|
453 |
virtual _UCXXEXPORT void imbue(const locale&){ |
|
454 |
return; |
|
455 |
} |
|
456 |
||
457 |
||
458 |
virtual _UCXXEXPORT streamsize xsputn(const char_type* s, streamsize n){ |
|
459 |
if(is_open() == false){ |
|
460 |
return 0; |
|
461 |
} |
|
462 |
//Check to see if buffered |
|
463 |
||
464 |
//Check to see if we can buffer the data |
|
465 |
streamsize buffer_avail = basic_streambuf<charT,traits>::epptr() - basic_streambuf<charT,traits>::pptr(); |
|
466 |
||
467 |
if(n > buffer_avail){ //Flush buffer and write directly |
|
468 |
overflow(); //Flush the buffer |
|
469 |
return fwrite(s, sizeof(charT), n, fp); |
|
470 |
} |
|
471 |
||
472 |
//Add to buffer to be written later |
|
473 |
||
474 |
traits::copy(basic_streambuf<charT,traits>::pptr(), s, n); |
|
475 |
basic_streambuf<charT,traits>::pbump(n); |
|
476 |
||
477 |
return n; |
|
478 |
} |
|
479 |
||
480 |
FILE * fp; |
|
481 |
char_type * pbuffer; |
|
482 |
char_type * gbuffer; |
|
483 |
bool append; |
|
484 |
}; |
|
485 |
||
486 |
||
487 |
#ifdef __UCLIBCXX_HAS_WCHAR__ |
|
488 |
||
489 |
template <> _UCXXEXPORT basic_filebuf<wchar_t, char_traits<wchar_t> >::int_type |
|
490 |
basic_filebuf<wchar_t, char_traits<wchar_t> >::overflow(int_type c); |
|
491 |
||
492 |
template <> _UCXXEXPORT basic_filebuf<wchar_t, char_traits<wchar_t> >::int_type |
|
493 |
basic_filebuf<wchar_t, char_traits<wchar_t> >::underflow(); |
|
494 |
||
495 |
#endif //__UCLIBCXX_HAS_WCHAR__ |
|
496 |
||
497 |
||
498 |
||
499 |
#ifdef __UCLIBCXX_EXPAND_FSTREAM_CHAR__ |
|
500 |
#ifndef __UCLIBCXX_COMPILE_FSTREAM__ |
|
501 |
||
502 |
#ifdef __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__ |
|
503 |
||
504 |
template <> _UCXXEXPORT filebuf::basic_filebuf(); |
|
505 |
template <> _UCXXEXPORT filebuf::~basic_filebuf(); |
|
506 |
||
507 |
#endif // __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__ |
|
508 |
||
509 |
template <> _UCXXEXPORT filebuf::int_type filebuf::pbackfail(filebuf::int_type c); |
|
510 |
template <> _UCXXEXPORT filebuf * filebuf::open(const char* s, ios_base::openmode mode); |
|
511 |
template <> _UCXXEXPORT filebuf * filebuf::close(); |
|
512 |
template <> _UCXXEXPORT filebuf::int_type filebuf::overflow(filebuf::int_type c); |
|
513 |
template <> _UCXXEXPORT filebuf::int_type filebuf::underflow (); |
|
514 |
||
515 |
template <> _UCXXEXPORT basic_streambuf<char, char_traits<char> > * filebuf::setbuf(char * s, streamsize n); |
|
516 |
template <> _UCXXEXPORT streamsize filebuf::xsputn(const char* s, streamsize n); |
|
517 |
||
518 |
#endif |
|
519 |
#endif |
|
520 |
||
521 |
||
522 |
template <class charT, class traits> class _UCXXEXPORT basic_ifstream |
|
523 |
: public basic_istream<charT,traits> |
|
524 |
{ |
|
525 |
public: |
|
526 |
typedef charT char_type; |
|
527 |
typedef typename traits::int_type int_type; |
|
528 |
typedef typename traits::pos_type pos_type; |
|
529 |
typedef typename traits::off_type off_type; |
|
530 |
||
531 |
_UCXXEXPORT basic_ifstream(): basic_ios<charT, traits>(&sb), basic_istream<charT,traits>(&sb){ |
|
532 |
//Passing the address of sb |
|
533 |
} |
|
534 |
explicit _UCXXEXPORT basic_ifstream(const char* s, ios_base::openmode mode = ios_base::in) |
|
535 |
: basic_ios<charT, traits>(&sb), basic_istream<charT,traits>(&sb) |
|
536 |
{ |
|
537 |
if(sb.open(s, mode) == 0){ |
|
538 |
basic_ios<charT,traits>::setstate(ios_base::failbit); |
|
539 |
} |
|
540 |
} |
|
541 |
||
542 |
virtual _UCXXEXPORT ~basic_ifstream(){ |
|
543 |
||
544 |
} |
|
545 |
||
546 |
_UCXXEXPORT basic_filebuf<charT,traits>* rdbuf() const{ |
|
547 |
return (basic_filebuf<charT,traits>*)&sb; |
|
548 |
} |
|
549 |
_UCXXEXPORT bool is_open() const{ |
|
550 |
return sb.is_open(); |
|
551 |
} |
|
552 |
_UCXXEXPORT void open(const char* s, ios_base::openmode mode = ios_base::in){ |
|
553 |
if(sb.open(s, mode) == 0){ |
|
554 |
basic_ios<charT,traits>::setstate(ios_base::failbit); |
|
555 |
} |
|
556 |
} |
|
557 |
_UCXXEXPORT void close(){ |
|
558 |
sb.close(); |
|
559 |
} |
|
560 |
private: |
|
561 |
basic_filebuf<charT,traits> sb; |
|
562 |
}; |
|
563 |
||
564 |
||
565 |
template <class charT, class traits> class _UCXXEXPORT basic_ofstream |
|
566 |
: public basic_ostream<charT,traits> |
|
567 |
{ |
|
568 |
public: |
|
569 |
typedef charT char_type; |
|
570 |
typedef typename traits::int_type int_type; |
|
571 |
typedef typename traits::pos_type pos_type; |
|
572 |
typedef typename traits::off_type off_type; |
|
573 |
||
574 |
_UCXXEXPORT basic_ofstream() : basic_ios<charT, traits>(&sb), basic_ostream<charT,traits>(&sb){ |
|
575 |
||
576 |
} |
|
577 |
||
578 |
virtual _UCXXEXPORT ~basic_ofstream(); |
|
579 |
||
580 |
explicit _UCXXEXPORT basic_ofstream(const char* s, ios_base::openmode mode = ios_base::out | ios_base::trunc) : |
|
581 |
basic_ios<charT, traits>(&sb), basic_ostream<charT,traits>(&sb) |
|
582 |
{ |
|
583 |
if(sb.open(s, mode | ios_base::out ) == 0){ |
|
584 |
basic_ios<charT,traits>::setstate(ios_base::failbit); |
|
585 |
} |
|
586 |
} |
|
587 |
||
588 |
_UCXXEXPORT basic_filebuf<charT,traits>* rdbuf() const{ |
|
589 |
return (basic_filebuf<charT,traits>*)&sb; |
|
590 |
} |
|
591 |
||
592 |
_UCXXEXPORT bool is_open() const{ |
|
593 |
return sb.is_open(); |
|
594 |
} |
|
595 |
_UCXXEXPORT void open(const char* s, ios_base::openmode mode = ios_base::out | ios_base::trunc){ |
|
596 |
if(sb.open(s, mode) == 0){ |
|
597 |
basic_ios<charT,traits>::setstate(ios_base::failbit); |
|
598 |
} |
|
599 |
} |
|
600 |
_UCXXEXPORT void close(){ |
|
601 |
sb.close(); |
|
602 |
} |
|
603 |
private: |
|
604 |
basic_filebuf<charT,traits> sb; |
|
605 |
}; |
|
606 |
||
607 |
template <class charT, class traits> _UCXXEXPORT basic_ofstream<charT, traits>::~basic_ofstream(){ |
|
608 |
basic_ostream<charT, traits>::flush(); |
|
609 |
} |
|
610 |
||
611 |
||
612 |
template <class charT, class traits> class _UCXXEXPORT basic_fstream |
|
613 |
: public basic_iostream<charT,traits> |
|
614 |
{ |
|
615 |
public: |
|
616 |
typedef charT char_type; |
|
617 |
typedef typename traits::int_type ins_type; |
|
618 |
typedef typename traits::pos_type pos_type; |
|
619 |
typedef typename traits::off_type off_type; |
|
620 |
||
621 |
_UCXXEXPORT basic_fstream(): basic_ios<charT, traits>(&sb), basic_iostream<charT,traits>(&sb){ } |
|
622 |
||
623 |
explicit _UCXXEXPORT basic_fstream(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out): |
|
624 |
basic_ios<charT, traits>(&sb), basic_iostream<charT,traits>(&sb) |
|
625 |
{ |
|
626 |
if(sb.open(s, mode) == 0){ |
|
627 |
basic_ios<charT,traits>::setstate(ios_base::failbit); |
|
628 |
} |
|
629 |
} |
|
630 |
||
631 |
_UCXXEXPORT basic_filebuf<charT,traits>* rdbuf() const{ |
|
632 |
return (basic_filebuf<charT,traits>*)&sb; |
|
633 |
} |
|
634 |
_UCXXEXPORT bool is_open() const{ |
|
635 |
return sb.is_open(); |
|
636 |
} |
|
637 |
_UCXXEXPORT void open(const char* s, ios_base::openmode mode = ios_base::in|ios_base::out){ |
|
638 |
if(sb.open(s, mode) == 0){ |
|
639 |
basic_ios<charT,traits>::setstate(ios_base::failbit); |
|
640 |
} |
|
641 |
} |
|
642 |
_UCXXEXPORT void close(){ |
|
643 |
sb.close(); |
|
644 |
} |
|
645 |
private: |
|
646 |
basic_filebuf<charT,traits> sb; |
|
647 |
}; |
|
648 |
||
649 |
||
650 |
#if 0 |
|
651 |
#ifdef __UCLIBCXX_EXPAND_FSTREAM_CHAR__ |
|
652 |
#ifndef __UCLIBCXX_COMPILE_FSTREAM__ |
|
653 |
||
654 |
#ifdef __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__ |
|
655 |
||
656 |
template <> _UCXXEXPORT basic_ofstream<char, char_traits<char> >::basic_ofstream(); |
|
657 |
template <> _UCXXEXPORT basic_ofstream<char, char_traits<char> >::basic_ofstream(const char* s, ios_base::openmode mode); |
|
658 |
template <> _UCXXEXPORT basic_ofstream<char, char_traits<char> >::~basic_ofstream(); |
|
659 |
||
660 |
template <> _UCXXEXPORT basic_ifstream<char, char_traits<char> >::basic_ifstream(); |
|
661 |
template <> _UCXXEXPORT basic_ifstream<char, char_traits<char> >::basic_ifstream(const char* s, ios_base::openmode mode); |
|
662 |
template <> _UCXXEXPORT basic_ifstream<char, char_traits<char> >::~basic_ifstream(); |
|
663 |
||
664 |
#endif // __UCLIBCXX_EXPAND_CONSTRUCTORS_DESTRUCTORS__ |
|
665 |
||
666 |
#endif |
|
667 |
||
668 |
#endif |
|
669 |
#endif |
|
670 |
||
671 |
||
672 |
||
673 |
} |
|
674 |
||
675 |
#pragma GCC visibility pop |
|
676 |
||
677 |
#endif |
|
678 |