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