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