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