35 class OFILE_streambuf :
public std::streambuf {
46 OFILE_streambuf(FILE *fp,
size_t buf_size = 1024) :
48 buf_(
new char[buf_size]),
52 throw std::ios_base::failure(
"Underlying stream pointer is null");
54 if (buf_.get() ==
nullptr) {
55 throw std::bad_alloc();
61 setp(&b[0], &b[buf_size_]);
74 int_type overflow(int_type ch = traits_type::eof())
override {
77 if (pptr() == epptr()) {
80 if (traits_type::eq_int_type(ch, traits_type::eof()) ==
true) {
81 return traits_type::eof();
86 if (pptr() != epptr()) {
91 return traits_type::eof();
99 size_t chars_to_write = pptr() - pbase();
100 size_t chars_written = fwrite(pbase(), 1, chars_to_write, fp_);
101 if (chars_written == chars_to_write) {
102 char *b = buf_.get();
103 setp(&b[0], &b[buf_size_]);
106 pbump(chars_written);
117 std::streamsize xsputn(
const char_type *s, std::streamsize count)
override {
124 return fwrite(s, 1, count, fp_);
128 std::unique_ptr<char[]> buf_;
129 const size_t buf_size_;
140 stream_(&streambuf_) { }
154 OFILE_streambuf streambuf_;
155 std::ostream stream_;
188 class IFILE_streambuf :
public std::streambuf {
199 IFILE_streambuf(FILE *fp,
size_t buf_size = 1024) :
201 buf_(
new char[buf_size]),
204 if (fp_ ==
nullptr) {
205 throw std::ios_base::failure(
"Underlying stream pointer is null");
207 if (buf_.get() ==
nullptr) {
208 throw std::bad_alloc();
211 char *b = buf_.get();
214 setg(&b[0], &b[buf_size_], &b[buf_size_]);
227 int_type underflow()
override {
228 if (gptr() == egptr()) {
229 char *b = buf_.get();
230 auto byte_cnt = xsgetn(b, buf_size_);
235 return traits_type::eof();
237 }
else if (
static_cast<size_t>(byte_cnt) < buf_size_) {
241 setg(&b[0], &b[0], &b[byte_cnt]);
246 setg(&b[0], &b[0], &b[buf_size_]);
259 std::streamsize xsgetn(
char *s, std::streamsize count)
override {
261 size_t intermediate_chars = egptr() - gptr();
262 size_t intermediate_copy = std::min(intermediate_chars,
static_cast<size_t>(count));
263 memcpy(s, gptr(), intermediate_copy);
264 gbump(intermediate_copy);
265 s += intermediate_copy;
266 count -= intermediate_copy;
267 size_t retval = intermediate_copy;
270 retval += fread(s, 1, count, fp_);
275 std::unique_ptr<char[]> buf_;
276 const size_t buf_size_;
287 stream_(&streambuf_) { }
301 IFILE_streambuf streambuf_;
302 std::istream stream_;