diff --git a/include/fmt/format-inl.h b/include/fmt/format-inl.h index 2aa1fb6f..9fc87ecf 100644 --- a/include/fmt/format-inl.h +++ b/include/fmt/format-inl.h @@ -1467,6 +1467,8 @@ template class file_base { if (ungetc(c, file_) == EOF) FMT_THROW(system_error(errno, FMT_STRING("ungetc failed"))); } + + void flush() { fflush(this->file_); } }; // A FILE wrapper for glibc. @@ -1477,10 +1479,6 @@ template class glibc_file : public file_base { unbuffered = 2 // _IO_UNBUFFERED }; - auto available_space() const -> ptrdiff_t { - return this->file_->_IO_buf_end - this->file_->_IO_write_ptr; - } - public: using file_base::file_base; @@ -1495,16 +1493,16 @@ template class glibc_file : public file_base { --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 { - return {this->file_->_IO_read_ptr, - to_unsigned(this->file_->_IO_read_end - this->file_->_IO_read_ptr)}; + auto ptr = 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 { - if (available_space() == 0) fflush_unlocked(this->file_); - FMT_ASSERT(available_space() > 0, ""); - return {this->file_->_IO_write_ptr, static_cast(available_space())}; + auto ptr = this->file_->_IO_write_ptr; + return {ptr, to_unsigned(this->file_->_IO_buf_end - ptr)}; } void advance_write_buffer(size_t size) { this->file_->_IO_write_ptr += size; } @@ -1514,6 +1512,8 @@ template class glibc_file : public file_base { char* end = this->file_->_IO_write_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. @@ -1524,10 +1524,6 @@ template class apple_file : public file_base { unbuffered = 2 // __SLBF }; - auto available_space() const -> ptrdiff_t { - return this->file_->_bf._base + this->file_->_bf._size - this->file_->_p; - } - public: using file_base::file_base; @@ -1549,10 +1545,9 @@ template class apple_file : public file_base { } auto get_write_buffer() const -> span { - if (available_space() == 0) fflush(this->file_); - FMT_ASSERT(available_space() > 0, ""); return {reinterpret_cast(this->file_->_p), - static_cast(available_space())}; + to_unsigned(this->file_->_bf._base + this->file_->_bf._size - + this->file_->_p)}; } void advance_write_buffer(size_t size) { @@ -1586,6 +1581,8 @@ template class fallback_file : public file_base { auto get_write_buffer() const -> span { return {nullptr, 0}; } + void advance_write_buffer(size_t) {} + auto get() -> int { has_next_ = false; return file_base::get(); @@ -1596,8 +1593,6 @@ template class fallback_file : public file_base { next_ = c; has_next_ = true; } - - void advance_write_buffer(size_t) {} }; template @@ -1616,15 +1611,13 @@ class file_print_buffer : public buffer { private: file_ref file_; - void set_buffer() { - auto buf = file_.get_write_buffer(); - this->set(buf.data, buf.size); - } - - static void grow(buffer& buf, size_t) { - auto& self = static_cast(buf); + static void grow(buffer& base, size_t) { + auto& self = static_cast(base); 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(); } @@ -1632,7 +1625,8 @@ class file_print_buffer : public buffer { explicit file_print_buffer(FILE* f) : buffer(grow, size_t()), file_(f) { flockfile(f); file_.init_buffer(); - set_buffer(); + auto buf = file_.get_write_buffer(); + set(buf.data, buf.size); } ~file_print_buffer() { file_.advance_write_buffer(size());