Add Formatter::writeTo(FILE*)
authorTudor Bosman <tudorb@fb.com>
Tue, 29 Oct 2013 19:00:50 +0000 (12:00 -0700)
committerSara Golemon <sgolemon@fb.com>
Wed, 6 Nov 2013 01:35:18 +0000 (17:35 -0800)
Summary: Because I needed it.

Test Plan: test added

Reviewed By: delong.j@fb.com

FB internal diff: D1032179

folly/Format-inl.h
folly/Format.h
folly/test/FormatTest.cpp

index 620557a6b435a80b139b241975952f9545d8dafb..b8eb0a164c8fb9acb176acf7dc90f0a601abd049 100644 (file)
@@ -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>
index c4e18f75f0de030fa07f35510191418307aee107..dae9ae4b51d47b96fe2ead03d36d9d8a792c732d 100644 (file)
@@ -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) {
index 0c41d7ae8d9a36e1946d2fc08d9665242197c112..e81266ea7ccd244dd777bac8e63620c18a4e1709 100644 (file)
@@ -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) {