[Issue #53] Removed ext/stdio_sync_filebuf.h
This commit is contained in:
parent
473d91ea18
commit
350eb235b1
1 changed files with 130 additions and 26 deletions
|
@ -31,18 +31,6 @@
|
|||
# include <cstdio>
|
||||
# include <memory>
|
||||
# include <fstream>
|
||||
|
||||
# ifdef __GNUC__
|
||||
# if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
# define off_t _off_t
|
||||
# define off64_t _off64_t
|
||||
# endif
|
||||
# include <ext/stdio_sync_filebuf.h>
|
||||
# if defined(__MINGW32__) || defined(__MINGW64__)
|
||||
# undef off_t
|
||||
# undef off64_t
|
||||
# endif
|
||||
# endif
|
||||
# else
|
||||
# include <stdio.h>
|
||||
# endif
|
||||
|
@ -143,37 +131,155 @@ CR_END_C_API
|
|||
# ifdef __cplusplus
|
||||
namespace criterion {
|
||||
|
||||
template <typename CharT, typename Traits = std::char_traits<CharT>>
|
||||
class stdio_sync_filebuf : public std::basic_streambuf<CharT, Traits> {
|
||||
public:
|
||||
typedef Traits traits;
|
||||
typedef std::basic_filebuf<CharT, Traits> 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<char>::int_type
|
||||
stdio_sync_filebuf<char>::syncgetc() {
|
||||
return std::getc(file);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline stdio_sync_filebuf<char>::int_type
|
||||
stdio_sync_filebuf<char>::syncungetc(stdio_sync_filebuf<char>::int_type c) {
|
||||
return std::ungetc(c, file);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline stdio_sync_filebuf<char>::int_type
|
||||
stdio_sync_filebuf<char>::syncputc(stdio_sync_filebuf<char>::int_type c) {
|
||||
return std::putc(c, file);
|
||||
}
|
||||
|
||||
template <>
|
||||
inline std::streamsize
|
||||
stdio_sync_filebuf<char>::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<char>::xsputn(const char *s, std::streamsize n) {
|
||||
return std::fwrite(s, 1, n, file);
|
||||
}
|
||||
|
||||
template <typename CharT, typename Super>
|
||||
class stream_mixin : public Super {
|
||||
public:
|
||||
stream_mixin(FILE* f)
|
||||
# ifdef __GNUC__
|
||||
: Super()
|
||||
, fbuf(new ::__gnu_cxx::stdio_sync_filebuf<CharT>(f))
|
||||
# else
|
||||
: Super(f)
|
||||
# endif
|
||||
, fbuf(new stdio_sync_filebuf<CharT>(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<CharT>> fbuf;
|
||||
# endif
|
||||
std::shared_ptr<stdio_sync_filebuf<CharT>> fbuf;
|
||||
std::FILE* file;
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue