mirror of
https://github.com/fmtlib/fmt.git
synced 2025-02-03 20:54:08 +00:00
Improve buffering
This commit is contained in:
parent
af44c29744
commit
28afff363c
@ -1467,6 +1467,8 @@ template <typename F> class file_base {
|
|||||||
if (ungetc(c, file_) == EOF)
|
if (ungetc(c, file_) == EOF)
|
||||||
FMT_THROW(system_error(errno, FMT_STRING("ungetc failed")));
|
FMT_THROW(system_error(errno, FMT_STRING("ungetc failed")));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void flush() { fflush(this->file_); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// A FILE wrapper for glibc.
|
// A FILE wrapper for glibc.
|
||||||
@ -1477,10 +1479,6 @@ template <typename F> class glibc_file : public file_base<F> {
|
|||||||
unbuffered = 2 // _IO_UNBUFFERED
|
unbuffered = 2 // _IO_UNBUFFERED
|
||||||
};
|
};
|
||||||
|
|
||||||
auto available_space() const -> ptrdiff_t {
|
|
||||||
return this->file_->_IO_buf_end - this->file_->_IO_write_ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using file_base<F>::file_base;
|
using file_base<F>::file_base;
|
||||||
|
|
||||||
@ -1495,16 +1493,16 @@ template <typename F> class glibc_file : public file_base<F> {
|
|||||||
--this->file_->_IO_write_ptr;
|
--this->file_->_IO_write_ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the file's read buffer as a string_view.
|
// Returns the file's read buffer.
|
||||||
auto get_read_buffer() const -> span<const char> {
|
auto get_read_buffer() const -> span<const char> {
|
||||||
return {this->file_->_IO_read_ptr,
|
auto ptr = this->file_->_IO_read_ptr;
|
||||||
to_unsigned(this->file_->_IO_read_end - this->file_->_IO_read_ptr)};
|
return {ptr, to_unsigned(this->file_->_IO_read_end - ptr)};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the file's write buffer.
|
||||||
auto get_write_buffer() const -> span<char> {
|
auto get_write_buffer() const -> span<char> {
|
||||||
if (available_space() == 0) fflush_unlocked(this->file_);
|
auto ptr = this->file_->_IO_write_ptr;
|
||||||
FMT_ASSERT(available_space() > 0, "");
|
return {ptr, to_unsigned(this->file_->_IO_buf_end - ptr)};
|
||||||
return {this->file_->_IO_write_ptr, static_cast<size_t>(available_space())};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void advance_write_buffer(size_t size) { this->file_->_IO_write_ptr += size; }
|
void advance_write_buffer(size_t size) { this->file_->_IO_write_ptr += size; }
|
||||||
@ -1514,6 +1512,8 @@ template <typename F> class glibc_file : public file_base<F> {
|
|||||||
char* end = this->file_->_IO_write_end;
|
char* end = this->file_->_IO_write_end;
|
||||||
return memchr(end, '\n', to_unsigned(this->file_->_IO_write_ptr - end));
|
return memchr(end, '\n', to_unsigned(this->file_->_IO_write_ptr - end));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void flush() { fflush_unlocked(this->file_); }
|
||||||
};
|
};
|
||||||
|
|
||||||
// A FILE wrapper for Apple's libc.
|
// A FILE wrapper for Apple's libc.
|
||||||
@ -1524,10 +1524,6 @@ template <typename F> class apple_file : public file_base<F> {
|
|||||||
unbuffered = 2 // __SLBF
|
unbuffered = 2 // __SLBF
|
||||||
};
|
};
|
||||||
|
|
||||||
auto available_space() const -> ptrdiff_t {
|
|
||||||
return this->file_->_bf._base + this->file_->_bf._size - this->file_->_p;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using file_base<F>::file_base;
|
using file_base<F>::file_base;
|
||||||
|
|
||||||
@ -1549,10 +1545,9 @@ template <typename F> class apple_file : public file_base<F> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
auto get_write_buffer() const -> span<char> {
|
auto get_write_buffer() const -> span<char> {
|
||||||
if (available_space() == 0) fflush(this->file_);
|
|
||||||
FMT_ASSERT(available_space() > 0, "");
|
|
||||||
return {reinterpret_cast<char*>(this->file_->_p),
|
return {reinterpret_cast<char*>(this->file_->_p),
|
||||||
static_cast<size_t>(available_space())};
|
to_unsigned(this->file_->_bf._base + this->file_->_bf._size -
|
||||||
|
this->file_->_p)};
|
||||||
}
|
}
|
||||||
|
|
||||||
void advance_write_buffer(size_t size) {
|
void advance_write_buffer(size_t size) {
|
||||||
@ -1586,6 +1581,8 @@ template <typename F> class fallback_file : public file_base<F> {
|
|||||||
|
|
||||||
auto get_write_buffer() const -> span<char> { return {nullptr, 0}; }
|
auto get_write_buffer() const -> span<char> { return {nullptr, 0}; }
|
||||||
|
|
||||||
|
void advance_write_buffer(size_t) {}
|
||||||
|
|
||||||
auto get() -> int {
|
auto get() -> int {
|
||||||
has_next_ = false;
|
has_next_ = false;
|
||||||
return file_base<F>::get();
|
return file_base<F>::get();
|
||||||
@ -1596,8 +1593,6 @@ template <typename F> class fallback_file : public file_base<F> {
|
|||||||
next_ = c;
|
next_ = c;
|
||||||
has_next_ = true;
|
has_next_ = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void advance_write_buffer(size_t) {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename F, FMT_ENABLE_IF(sizeof(F::_p) != 0)>
|
template <typename F, FMT_ENABLE_IF(sizeof(F::_p) != 0)>
|
||||||
@ -1616,15 +1611,13 @@ class file_print_buffer : public buffer<char> {
|
|||||||
private:
|
private:
|
||||||
file_ref file_;
|
file_ref file_;
|
||||||
|
|
||||||
void set_buffer() {
|
static void grow(buffer<char>& base, size_t) {
|
||||||
auto buf = file_.get_write_buffer();
|
auto& self = static_cast<file_print_buffer&>(base);
|
||||||
this->set(buf.data, buf.size);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void grow(buffer<char>& buf, size_t) {
|
|
||||||
auto& self = static_cast<file_print_buffer&>(buf);
|
|
||||||
self.file_.advance_write_buffer(self.size());
|
self.file_.advance_write_buffer(self.size());
|
||||||
self.set_buffer();
|
if (self.file_.get_write_buffer().size == 0) self.file_.flush();
|
||||||
|
auto buf = self.file_.get_write_buffer();
|
||||||
|
FMT_ASSERT(buf.size > 0, "");
|
||||||
|
self.set(buf.data, buf.size);
|
||||||
self.clear();
|
self.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1632,7 +1625,8 @@ class file_print_buffer : public buffer<char> {
|
|||||||
explicit file_print_buffer(FILE* f) : buffer(grow, size_t()), file_(f) {
|
explicit file_print_buffer(FILE* f) : buffer(grow, size_t()), file_(f) {
|
||||||
flockfile(f);
|
flockfile(f);
|
||||||
file_.init_buffer();
|
file_.init_buffer();
|
||||||
set_buffer();
|
auto buf = file_.get_write_buffer();
|
||||||
|
set(buf.data, buf.size);
|
||||||
}
|
}
|
||||||
~file_print_buffer() {
|
~file_print_buffer() {
|
||||||
file_.advance_write_buffer(size());
|
file_.advance_write_buffer(size());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user