Commit 8e8b5e75 authored by Tudor Bosman's avatar Tudor Bosman Committed by Sara Golemon

Add Formatter::writeTo(FILE*)

Summary: Because I needed it.

Test Plan: test added

Reviewed By: delong.j@fb.com

FB internal diff: D1032179
parent 46600f3e
......@@ -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<containerMode, Args...>::operator()(Output& out) const {
}
}
template <bool containerMode, class... Args>
void writeTo(FILE* fp, const Formatter<containerMode, Args...>& 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 <class FormatCallback>
......
......@@ -18,6 +18,7 @@
#define FOLLY_FORMAT_H_
#include <array>
#include <cstdio>
#include <tuple>
#include <type_traits>
#include <vector>
......@@ -154,11 +155,18 @@ std::ostream& operator<<(std::ostream& out,
return out;
}
/**
* Formatter objects can be written to stdio FILEs.
*/
template<bool containerMode, class... Args>
void writeTo(FILE* fp, const Formatter<containerMode, Args...>& formatter);
/**
* Create a formatter object.
*
* std::string formatted = format("{} {}", 23, 42).str();
* LOG(INFO) << format("{} {}", 23, 42);
* writeTo(stdout, format("{} {}", 23, 42));
*/
template <class... Args>
Formatter<false, Args...> format(StringPiece fmt, Args&&... args) {
......
......@@ -21,6 +21,7 @@
#include <gtest/gtest.h>
#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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment