00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
#ifndef _STDIO_SYNC_FILEBUF_H
00035
#define _STDIO_SYNC_FILEBUF_H 1
00036
00037
#pragma GCC system_header
00038
00039
#include <streambuf>
00040
#include <unistd.h>
00041
#include <cstdio>
00042
00043
#ifdef _GLIBCXX_USE_WCHAR_T
00044
#include <cwchar>
00045
#endif
00046
00047
namespace __gnu_cxx
00048 {
00049
template<
typename _CharT,
typename _Traits = std::
char_traits<_CharT> >
00050
class stdio_sync_filebuf :
public std::basic_streambuf<_CharT, _Traits>
00051 {
00052
public:
00053
00054
typedef _CharT char_type;
00055
typedef _Traits traits_type;
00056
typedef typename traits_type::int_type int_type;
00057
typedef typename traits_type::pos_type pos_type;
00058
typedef typename traits_type::off_type off_type;
00059
00060
private:
00061
00062 std::__c_file*
const _M_file;
00063
00064
00065
00066 int_type _M_unget_buf;
00067
00068
public:
00069
explicit
00070 stdio_sync_filebuf(std::__c_file* __f)
00071 : _M_file(__f), _M_unget_buf(traits_type::eof())
00072 { }
00073
00074
00075
00076
00077
00078
00079
00080
00081 std::__c_file*
const
00082 file() {
return this->_M_file; }
00083
00084
protected:
00085 int_type
00086 syncgetc();
00087
00088 int_type
00089 syncungetc(int_type __c);
00090
00091 int_type
00092 syncputc(int_type __c);
00093
00094
virtual int_type
00095 underflow()
00096 {
00097 int_type __c = this->syncgetc();
00098
return this->syncungetc(__c);
00099 }
00100
00101
virtual int_type
00102 uflow()
00103 {
00104
00105 _M_unget_buf = this->syncgetc();
00106
return _M_unget_buf;
00107 }
00108
00109
virtual int_type
00110 pbackfail(int_type __c = traits_type::eof())
00111 {
00112 int_type __ret;
00113
const int_type __eof = traits_type::eof();
00114
00115
00116
if (traits_type::eq_int_type(__c, __eof))
00117 {
00118
if (!traits_type::eq_int_type(_M_unget_buf, __eof))
00119 __ret = this->syncungetc(_M_unget_buf);
00120
else
00121 __ret = __eof;
00122 }
00123
else
00124 __ret = this->syncungetc(__c);
00125
00126
00127 _M_unget_buf = __eof;
00128
return __ret;
00129 }
00130
00131
virtual std::streamsize
00132 xsgetn(char_type* __s, std::streamsize __n);
00133
00134
virtual int_type
00135 overflow(int_type __c = traits_type::eof())
00136 {
00137 int_type __ret;
00138
if (traits_type::eq_int_type(__c, traits_type::eof()))
00139 {
00140
if (std::fflush(_M_file))
00141 __ret = traits_type::eof();
00142
else
00143 __ret = traits_type::not_eof(__c);
00144 }
00145
else
00146 __ret = this->syncputc(__c);
00147
return __ret;
00148 }
00149
00150
virtual std::streamsize
00151 xsputn(
const char_type* __s, std::streamsize __n);
00152
00153
virtual int
00154 sync()
00155 {
return std::fflush(_M_file); }
00156
00157
virtual std::streampos
00158
seekoff(
std::streamoff __off,
std::ios_base::seekdir __dir,
00159
std::ios_base::openmode = std::ios_base::in | std::ios_base::out)
00160 {
00161
std::streampos __ret(std::streamoff(-1));
00162
int __whence;
00163
if (__dir ==
std::ios_base::beg)
00164 __whence = SEEK_SET;
00165
else if (__dir ==
std::ios_base::cur)
00166 __whence = SEEK_CUR;
00167
else
00168 __whence = SEEK_END;
00169
#ifdef _GLIBCXX_USE_LFS
00170
if (!fseeko64(_M_file, __off, __whence))
00171 __ret =
std::streampos(ftello64(_M_file));
00172
#else
00173
if (!fseek(_M_file, __off, __whence))
00174 __ret =
std::streampos(std::ftell(_M_file));
00175
#endif
00176
return __ret;
00177 }
00178
00179
virtual std::streampos
00180
seekpos(std::streampos __pos,
00181 std::ios_base::openmode __mode =
00182 std::ios_base::in | std::ios_base::out)
00183 {
return seekoff(std::streamoff(__pos), std::ios_base::beg, __mode); }
00184 };
00185
00186
template<>
00187
inline stdio_sync_filebuf<char>::int_type
00188 stdio_sync_filebuf<char>::syncgetc()
00189 {
return std::getc(_M_file); }
00190
00191
template<>
00192
inline stdio_sync_filebuf<char>::int_type
00193 stdio_sync_filebuf<char>::syncungetc(int_type __c)
00194 {
return std::ungetc(__c, _M_file); }
00195
00196
template<>
00197
inline stdio_sync_filebuf<char>::int_type
00198 stdio_sync_filebuf<char>::syncputc(int_type __c)
00199 {
return std::putc(__c, _M_file); }
00200
00201
template<>
00202
inline std::streamsize
00203 stdio_sync_filebuf<char>::xsgetn(
char* __s, std::streamsize __n)
00204 {
00205 std::streamsize __ret = std::fread(__s, 1, __n, _M_file);
00206
if (__ret > 0)
00207 _M_unget_buf = traits_type::to_int_type(__s[__ret - 1]);
00208
else
00209 _M_unget_buf = traits_type::eof();
00210
return __ret;
00211 }
00212
00213
template<>
00214
inline std::streamsize
00215 stdio_sync_filebuf<char>::xsputn(
const char* __s, std::streamsize __n)
00216 {
return std::fwrite(__s, 1, __n, _M_file); }
00217
00218
#ifdef _GLIBCXX_USE_WCHAR_T
00219
template<>
00220
inline stdio_sync_filebuf<wchar_t>::int_type
00221 stdio_sync_filebuf<wchar_t>::syncgetc()
00222 {
return std::getwc(_M_file); }
00223
00224
template<>
00225
inline stdio_sync_filebuf<wchar_t>::int_type
00226 stdio_sync_filebuf<wchar_t>::syncungetc(int_type __c)
00227 {
return std::ungetwc(__c, _M_file); }
00228
00229
template<>
00230
inline stdio_sync_filebuf<wchar_t>::int_type
00231 stdio_sync_filebuf<wchar_t>::syncputc(int_type __c)
00232 {
return std::putwc(__c, _M_file); }
00233
00234
template<>
00235
inline std::streamsize
00236 stdio_sync_filebuf<wchar_t>::xsgetn(
wchar_t* __s, std::streamsize __n)
00237 {
00238 std::streamsize __ret = 0;
00239
const int_type __eof = traits_type::eof();
00240
while (__n--)
00241 {
00242
int_type __c = this->syncgetc();
00243
if (traits_type::eq_int_type(__c, __eof))
00244
break;
00245 __s[__ret] = traits_type::to_char_type(__c);
00246 ++__ret;
00247 }
00248
00249
if (__ret > 0)
00250 _M_unget_buf = traits_type::to_int_type(__s[__ret - 1]);
00251
else
00252 _M_unget_buf = traits_type::eof();
00253
return __ret;
00254 }
00255
00256
template<>
00257
inline std::streamsize
00258 stdio_sync_filebuf<wchar_t>::xsputn(
const wchar_t* __s,
00259 std::streamsize __n)
00260 {
00261 std::streamsize __ret = 0;
00262
const int_type __eof = traits_type::eof();
00263
while (__n--)
00264 {
00265
if (traits_type::eq_int_type(this->syncputc(*__s++), __eof))
00266
break;
00267 ++__ret;
00268 }
00269
return __ret;
00270 }
00271
#endif
00272
00273
#if _GLIBCXX_EXTERN_TEMPLATE
00274
extern template class stdio_sync_filebuf<char>;
00275
#ifdef _GLIBCXX_USE_WCHAR_T
00276
extern template class stdio_sync_filebuf<wchar_t>;
00277
#endif
00278
#endif
00279
}
00280
00281
#endif