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