From 350eb235b1ebb6f85d03e86345f1f227354b097e Mon Sep 17 00:00:00 2001 From: Snaipe Date: Wed, 23 Sep 2015 14:11:33 +0200 Subject: [PATCH] [Issue #53] Removed ext/stdio_sync_filebuf.h --- include/criterion/redirect.h | 156 +++++++++++++++++++++++++++++------ 1 file changed, 130 insertions(+), 26 deletions(-) diff --git a/include/criterion/redirect.h b/include/criterion/redirect.h index 4851b3d..effb909 100644 --- a/include/criterion/redirect.h +++ b/include/criterion/redirect.h @@ -31,18 +31,6 @@ # include # include # include - -# ifdef __GNUC__ -# if defined(__MINGW32__) || defined(__MINGW64__) -# define off_t _off_t -# define off64_t _off64_t -# endif -# include -# if defined(__MINGW32__) || defined(__MINGW64__) -# undef off_t -# undef off64_t -# endif -# endif # else # include # endif @@ -143,37 +131,155 @@ CR_END_C_API # ifdef __cplusplus namespace criterion { + template > + class stdio_sync_filebuf : public std::basic_streambuf { + public: + typedef Traits traits; + typedef std::basic_filebuf super; + typedef typename Traits::int_type int_type; + typedef typename Traits::pos_type pos_type; + typedef typename Traits::off_type off_type; + + stdio_sync_filebuf(std::FILE *file) + : file(file) + , lastchar(Traits::eof()) + {} + + stdio_sync_filebuf(stdio_sync_filebuf&& other) = default; + stdio_sync_filebuf& operator=(stdio_sync_filebuf&& other) = default; + + void swap(stdio_sync_filebuf& other) { + super::swap(other); + std::swap(file, other.file); + std::swap(lastchar, other.lastchar); + } + + protected: + int_type syncgetc(); + int_type syncungetc(int_type); + int_type syncputc(int_type); + + virtual std::streampos seekoff(std::streamoff off, + std::ios_base::seekdir dir, + std::ios_base::openmode = std::ios_base::in | std::ios_base::out) { + + int whence; + if (dir == std::ios_base::beg) + whence = SEEK_SET; + else if (dir == std::ios_base::cur) + whence = SEEK_CUR; + else + whence = SEEK_END; + + if (!fseek(file, off, whence)) + return std::streampos(std::ftell(file)); + return std::streamoff(-1); + } + + virtual std::streampos seekpos(std::streampos pos, + std::ios_base::openmode mode = std::ios_base::in | std::ios_base::out) { + return seekoff(std::streamoff(pos), std::ios_base::beg, mode); + } + + virtual std::streamsize xsgetn(CharT* s, std::streamsize n); + virtual std::streamsize xsputn(const CharT* s, std::streamsize n); + + virtual int sync() { + return std::fflush(file); + } + + virtual int_type underflow() { + int_type c = syncgetc(); + return syncungetc(c); + } + + virtual int_type uflow() { + return lastchar = syncgetc(); + } + + static inline bool is_eof(int_type c) { + static const int_type eof = Traits::eof(); + return Traits::eq_int_type(c, eof); + } + + virtual int_type overflow(int_type c = Traits::eof()) { + int_type ret; + if (is_eof(c)) { + if (std::fflush(file)) + ret = Traits::eof(); + else + ret = Traits::not_eof(c); + } else { + ret = syncputc(c); + } + return ret; + } + + virtual int_type pbackfail(int_type c = Traits::eof()) { + int_type ret = syncungetc(is_eof(c) && !is_eof(lastchar) ? lastchar : c); + lastchar = Traits::eof(); + return ret; + } + + private: + std::FILE *file; + bool file_open; + int_type lastchar; + }; + + template <> + inline stdio_sync_filebuf::int_type + stdio_sync_filebuf::syncgetc() { + return std::getc(file); + } + + template <> + inline stdio_sync_filebuf::int_type + stdio_sync_filebuf::syncungetc(stdio_sync_filebuf::int_type c) { + return std::ungetc(c, file); + } + + template <> + inline stdio_sync_filebuf::int_type + stdio_sync_filebuf::syncputc(stdio_sync_filebuf::int_type c) { + return std::putc(c, file); + } + + template <> + inline std::streamsize + stdio_sync_filebuf::xsgetn(char *s, std::streamsize n) { + std::streamsize res = std::fread(s, 1, n, file); + lastchar = res > 0 ? traits::to_int_type(s[res - 1]) : traits::eof(); + return res; + } + + template <> + inline std::streamsize + stdio_sync_filebuf::xsputn(const char *s, std::streamsize n) { + return std::fwrite(s, 1, n, file); + } + template class stream_mixin : public Super { public: stream_mixin(FILE* f) -# ifdef __GNUC__ : Super() - , fbuf(new ::__gnu_cxx::stdio_sync_filebuf(f)) -# else - : Super(f) -# endif + , fbuf(new stdio_sync_filebuf(f)) , file(f) { -# ifdef __GNUC__ std::ios::rdbuf(&*fbuf); -# endif } stream_mixin(const stream_mixin& other) = delete; stream_mixin& operator=(const stream_mixin& other) = delete; stream_mixin(stream_mixin&& other) : -# ifdef __GNUC__ fbuf(std::move(other.fbuf)), -# endif file(std::move(other.file)) {} stream_mixin& operator=(stream_mixin&& other) { -# ifdef __GNUC__ fbuf = std::move(other.fbuf); -# endif file = std::move(other.file); } @@ -184,9 +290,7 @@ public: } private: -# ifdef __GNUC__ - std::shared_ptr<::__gnu_cxx::stdio_sync_filebuf> fbuf; -# endif + std::shared_ptr> fbuf; std::FILE* file; };