From: Tudor Bosman Date: Tue, 29 Oct 2013 19:00:50 +0000 (-0700) Subject: Add Formatter::writeTo(FILE*) X-Git-Tag: v0.22.0~803 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8e8b5e75d573305b7a9c34f4a405be5df0f17738;p=folly.git Add Formatter::writeTo(FILE*) Summary: Because I needed it. Test Plan: test added Reviewed By: delong.j@fb.com FB internal diff: D1032179 --- diff --git a/folly/Format-inl.h b/folly/Format-inl.h index 620557a6..b8eb0a16 100644 --- a/folly/Format-inl.h +++ b/folly/Format-inl.h @@ -18,6 +18,7 @@ #error This file may only be included from Format.h. #endif +#include "folly/Exception.h" #include "folly/Traits.h" namespace folly { @@ -233,6 +234,17 @@ void Formatter::operator()(Output& out) const { } } +template +void writeTo(FILE* fp, const Formatter& formatter) { + auto writer = [fp] (StringPiece sp) { + ssize_t n = fwrite(sp.data(), 1, sp.size(), fp); + if (n < sp.size()) { + throwSystemError("Formatter writeTo", "fwrite failed"); + } + }; + formatter(writer); +} + namespace format_value { template diff --git a/folly/Format.h b/folly/Format.h index c4e18f75..dae9ae4b 100644 --- a/folly/Format.h +++ b/folly/Format.h @@ -18,6 +18,7 @@ #define FOLLY_FORMAT_H_ #include +#include #include #include #include @@ -154,11 +155,18 @@ std::ostream& operator<<(std::ostream& out, return out; } +/** + * Formatter objects can be written to stdio FILEs. + */ +template +void writeTo(FILE* fp, const Formatter& formatter); + /** * Create a formatter object. * * std::string formatted = format("{} {}", 23, 42).str(); * LOG(INFO) << format("{} {}", 23, 42); + * writeTo(stdout, format("{} {}", 23, 42)); */ template Formatter format(StringPiece fmt, Args&&... args) { diff --git a/folly/test/FormatTest.cpp b/folly/test/FormatTest.cpp index 0c41d7ae..e81266ea 100644 --- a/folly/test/FormatTest.cpp +++ b/folly/test/FormatTest.cpp @@ -21,6 +21,7 @@ #include #include "folly/FBVector.h" +#include "folly/FileUtil.h" #include "folly/dynamic.h" #include "folly/json.h" @@ -184,6 +185,26 @@ TEST(Format, Simple) { format(&s, "{} {}", 42, 23); format(&s, " hello {:X<7}", "world"); EXPECT_EQ("42 23 hello worldXX", s); + + // Test writing to FILE. I'd use open_memstream but that's not available + // outside of Linux (even though it's in POSIX.1-2008). + { + int fds[2]; + CHECK_ERR(pipe(fds)); + SCOPE_EXIT { closeNoInt(fds[1]); }; + { + FILE* fp = fdopen(fds[1], "wb"); + PCHECK(fp); + SCOPE_EXIT { fclose(fp); }; + writeTo(fp, format("{} {}", 42, 23)); // <= 512 bytes (PIPE_BUF) + } + + char buf[512]; + ssize_t n = readFull(fds[0], buf, sizeof(buf)); + CHECK_GE(n, 0); + + EXPECT_EQ("42 23", std::string(buf, n)); + } } TEST(Format, Float) {