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