mirror of
https://github.com/fmtlib/fmt.git
synced 2025-01-28 18:32:46 +00:00
Make buffer size configurable
This commit is contained in:
parent
f0b84da5ff
commit
7c4c5c79d2
@ -18,6 +18,7 @@
|
|||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib> // for strtod_l
|
#include <cstdlib> // for strtod_l
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#if defined __APPLE__ || defined(__FreeBSD__)
|
#if defined __APPLE__ || defined(__FreeBSD__)
|
||||||
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
|
# include <xlocale.h> // for LC_NUMERIC_MASK on OS X
|
||||||
@ -29,7 +30,7 @@
|
|||||||
#if FMT_HAS_INCLUDE("winapifamily.h")
|
#if FMT_HAS_INCLUDE("winapifamily.h")
|
||||||
# include <winapifamily.h>
|
# include <winapifamily.h>
|
||||||
#endif
|
#endif
|
||||||
#if FMT_HAS_INCLUDE("fcntl.h") && \
|
#if (FMT_HAS_INCLUDE(<fcntl.h>) || defined(__APPLE__)) && \
|
||||||
(!defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
|
(!defined(WINAPI_FAMILY) || (WINAPI_FAMILY == WINAPI_FAMILY_DESKTOP_APP))
|
||||||
# include <fcntl.h> // for O_RDONLY
|
# include <fcntl.h> // for O_RDONLY
|
||||||
# define FMT_USE_FCNTL 1
|
# define FMT_USE_FCNTL 1
|
||||||
@ -343,32 +344,78 @@ class file {
|
|||||||
// Returns the memory page size.
|
// Returns the memory page size.
|
||||||
long getpagesize();
|
long getpagesize();
|
||||||
|
|
||||||
|
namespace detail {
|
||||||
|
|
||||||
|
struct buffer_size {
|
||||||
|
size_t value = 0;
|
||||||
|
buffer_size operator=(size_t val) const {
|
||||||
|
auto bs = buffer_size();
|
||||||
|
bs.value = val;
|
||||||
|
return bs;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ostream_params {
|
||||||
|
int oflag = file::WRONLY | file::CREATE;
|
||||||
|
size_t buffer_size = BUFSIZ;
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void get_params(ostream_params&) {}
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
inline void get_params(ostream_params& op, int oflag, T... params) {
|
||||||
|
op.oflag = oflag;
|
||||||
|
get_params(op, params...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... T>
|
||||||
|
inline void get_params(ostream_params& op, buffer_size bs, T... params) {
|
||||||
|
op.buffer_size = bs.value;
|
||||||
|
get_params(op, params...);
|
||||||
|
}
|
||||||
|
} // namespace detail
|
||||||
|
|
||||||
|
static constexpr detail::buffer_size buffer_size;
|
||||||
|
|
||||||
// A fast output stream which is not thread-safe.
|
// A fast output stream which is not thread-safe.
|
||||||
class ostream : private detail::buffer<char> {
|
class ostream : private detail::buffer<char> {
|
||||||
private:
|
private:
|
||||||
file file_;
|
file file_;
|
||||||
char buffer_[BUFSIZ];
|
size_t buffer_size_;
|
||||||
|
std::unique_ptr<char[]> buffer_;
|
||||||
|
|
||||||
|
char* move_buffer(ostream&& other) {
|
||||||
|
buffer_ = std::move(other.buffer_);
|
||||||
|
buffer_size_ = other.buffer_size_;
|
||||||
|
return buffer_.get();
|
||||||
|
}
|
||||||
|
|
||||||
void flush() {
|
void flush() {
|
||||||
if (size() == 0) return;
|
if (size() == 0) return;
|
||||||
file_.write(buffer_, size());
|
file_.write(buffer_.get(), size());
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void grow(size_t) final;
|
void grow(size_t) final;
|
||||||
|
|
||||||
ostream(cstring_view path, int oflag)
|
ostream(cstring_view path, const detail::ostream_params& params)
|
||||||
: buffer<char>(buffer_, 0, BUFSIZ), file_(path, oflag) {}
|
: file_(path, params.oflag),
|
||||||
|
buffer_size_(params.buffer_size),
|
||||||
|
buffer_(new char[params.buffer_size]) {
|
||||||
|
set(buffer_.get(), params.buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ostream(ostream&& other)
|
ostream(ostream&& other)
|
||||||
: buffer<char>(buffer_, 0, BUFSIZ), file_(std::move(other.file_)) {
|
: file_(std::move(other.file_)),
|
||||||
append(other.begin(), other.end());
|
buffer_size_(other.buffer_size_),
|
||||||
|
buffer_(std::move(other.buffer_)) {
|
||||||
other.clear();
|
other.clear();
|
||||||
}
|
}
|
||||||
~ostream() { flush(); }
|
~ostream() { flush(); }
|
||||||
|
|
||||||
friend ostream output_file(cstring_view path, int oflag);
|
template <typename... T>
|
||||||
|
friend ostream output_file(cstring_view path, T... params);
|
||||||
|
|
||||||
void close() {
|
void close() {
|
||||||
flush();
|
flush();
|
||||||
@ -381,9 +428,16 @@ class ostream : private detail::buffer<char> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
inline ostream output_file(cstring_view path,
|
/**
|
||||||
int oflag = file::WRONLY | file::CREATE) {
|
Opens a file for writing. Supported parameters passed in `params`:
|
||||||
return {path, oflag};
|
* ``<integer>``: Output flags (``file::WRONLY | file::CREATE`` by default)
|
||||||
|
* ``buffer_size=<integer>``: Output buffer size (``BUFSIZ`` by default)
|
||||||
|
*/
|
||||||
|
template <typename... T>
|
||||||
|
inline ostream output_file(cstring_view path, T... params) {
|
||||||
|
auto op = detail::ostream_params();
|
||||||
|
get_params(op, params...);
|
||||||
|
return {path, op};
|
||||||
}
|
}
|
||||||
#endif // FMT_USE_FCNTL
|
#endif // FMT_USE_FCNTL
|
||||||
|
|
||||||
|
@ -315,7 +315,7 @@ long getpagesize() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void ostream::grow(size_t) {
|
void ostream::grow(size_t) {
|
||||||
if (this->size() == BUFSIZ) flush();
|
if (this->size() == buffer_size_) flush();
|
||||||
}
|
}
|
||||||
#endif // FMT_USE_FCNTL
|
#endif // FMT_USE_FCNTL
|
||||||
FMT_END_NAMESPACE
|
FMT_END_NAMESPACE
|
||||||
|
@ -305,6 +305,14 @@ TEST(OStreamTest, BufferBoundary) {
|
|||||||
EXPECT_READ(in, str + str);
|
EXPECT_READ(in, str + str);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(OStreamTest, BufferSize) {
|
||||||
|
fmt::ostream out = fmt::output_file("test-file", fmt::buffer_size=1);
|
||||||
|
out.print("{}", "foo");
|
||||||
|
out.close();
|
||||||
|
file in("test-file", file::RDONLY);
|
||||||
|
EXPECT_READ(in, "foo");
|
||||||
|
}
|
||||||
|
|
||||||
TEST(FileTest, DefaultCtor) {
|
TEST(FileTest, DefaultCtor) {
|
||||||
file f;
|
file f;
|
||||||
EXPECT_EQ(-1, f.descriptor());
|
EXPECT_EQ(-1, f.descriptor());
|
||||||
|
Loading…
x
Reference in New Issue
Block a user