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