]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
common/Formatter: move {JSON,Table,XML}Formatter to separate files
authorMax Kellermann <max.kellermann@ionos.com>
Wed, 16 Oct 2024 15:34:06 +0000 (17:34 +0200)
committerMax Kellermann <max.kellermann@ionos.com>
Fri, 19 Sep 2025 19:52:50 +0000 (21:52 +0200)
Most sources only need the Formatter interface and don't need the
other implementations (and their header dependencies).

Signed-off-by: Max Kellermann <max.kellermann@ionos.com>
84 files changed:
src/ceph_mon.cc
src/common/AsyncReserver.h
src/common/CMakeLists.txt
src/common/Formatter.cc
src/common/Formatter.h
src/common/HTMLFormatter.cc
src/common/HTMLFormatter.h
src/common/JSONFormatter.cc [new file with mode: 0644]
src/common/JSONFormatter.h [new file with mode: 0644]
src/common/JSONFormatterFile.h [new file with mode: 0644]
src/common/TableFormatter.cc [new file with mode: 0644]
src/common/TableFormatter.h [new file with mode: 0644]
src/common/XMLFormatter.cc [new file with mode: 0644]
src/common/XMLFormatter.h [new file with mode: 0644]
src/common/admin_socket.cc
src/common/ceph_json.h
src/crimson/CMakeLists.txt
src/crimson/os/cyanstore/cyan_store.cc
src/crimson/os/seastore/seastore.cc
src/crimson/tools/store_bench/store-bench.cc
src/global/signal_handler.cc
src/libcephsqlite.cc
src/mds/MDSRank.cc
src/mds/ScrubStack.cc
src/mgr/BaseMgrModule.cc
src/mgr/ClusterState.cc
src/mgr/DaemonServer.cc
src/mgr/PyFormatter.h
src/mgr/PyModule.cc
src/mon/ConfigMap.cc
src/mon/ConfigMonitor.cc
src/mon/ElectionLogic.cc
src/mon/Elector.cc
src/mon/LogMonitor.cc
src/mon/MonitorDBStore.h
src/mon/OSDMonitor.cc
src/mon/Paxos.h
src/os/bluestore/BlueFS.cc
src/os/bluestore/BlueStore.cc
src/os/bluestore/bluestore_tool.cc
src/os/kstore/KStore.cc
src/os/memstore/MemStore.cc
src/osd/osd_types.cc
src/rbd_replay/Replayer.cc
src/rbd_replay/actions.hpp
src/rgw/driver/rados/rgw_bucket.cc
src/rgw/driver/rados/rgw_lc_tier.cc
src/rgw/driver/rados/rgw_pubsub_push.cc
src/rgw/driver/rados/rgw_sync_module_aws.cc
src/rgw/driver/rados/rgw_sync_trace.cc
src/rgw/radosgw-admin/radosgw-admin.cc
src/rgw/rgw_cors_s3.cc
src/rgw/rgw_cors_s3.h
src/rgw/rgw_formats.cc
src/rgw/rgw_op.cc
src/rgw/rgw_rest.cc
src/test/admin_socket.cc
src/test/common/test_json_formatter.cc
src/test/common/test_tableformatter.cc
src/test/common/test_xmlformatter.cc
src/test/crush/crush.cc
src/test/formatter.cc
src/test/libcephfs/snapdiff.cc
src/test/librados/service.cc
src/test/librados/test_common.cc
src/test/mon/test_mon_workloadgen.cc
src/test/objectstore/store_test.cc
src/test/rgw/test_rgw_xml.cc
src/test/test_mempool.cc
src/tools/ceph-client-debug.cc
src/tools/ceph-dencoder/ceph_dencoder.cc
src/tools/ceph_monstore_tool.cc
src/tools/cephfs/EventOutput.cc
src/tools/cephfs/JournalTool.cc
src/tools/cephfs/TableTool.cc
src/tools/cephfs_mirror/ServiceDaemon.cc
src/tools/osdmaptool.cc
src/tools/rados/rados.cc
src/tools/rbd/ArgumentTypes.cc
src/tools/rbd/action/Journal.cc
src/tools/rbd_ggate/main.cc
src/tools/rbd_mirror/ServiceDaemon.cc
src/tools/rbd_nbd/rbd-nbd.cc
src/tools/rbd_wnbd/rbd_wnbd.cc

index 28c4acff4352cb531de63438f285508a88944176..3c50aecb3d4f93ff8e1c989b1cf9d7b756888616 100644 (file)
@@ -35,6 +35,7 @@
 
 #include "common/ceph_argparse.h"
 #include "common/pick_address.h"
+#include "common/JSONFormatter.h"
 #include "common/Throttle.h"
 #include "common/Timer.h"
 #include "common/errno.h"
index b98e54ef767ceb59fff5c418d9c36692d6f30ddb..df880844d2ecf94a9372afa39865f25b94d40213 100644 (file)
@@ -15,7 +15,7 @@
 #ifndef ASYNC_RESERVER_H
 #define ASYNC_RESERVER_H
 
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "common/ceph_context.h"
 #include "common/ceph_mutex.h"
 #include "include/Context.h"
index 97fb1fe7440143dfa832f15f6b6722e040868336..1f21ad4c0c5838397468bd762458281dc8598516 100644 (file)
@@ -29,6 +29,7 @@ set(common_srcs
   FixedCDC.cc
   Formatter.cc
   Graylog.cc
+  JSONFormatter.cc
   HTMLFormatter.cc
   HeartbeatMap.cc
   LogClient.cc
@@ -39,12 +40,14 @@ set(common_srcs
   Readahead.cc
   RefCountedObj.cc
   SloppyCRCMap.cc
+  TableFormatter.cc
   Thread.cc
   Throttle.cc
   Timer.cc
   TracepointProvider.cc
   TrackedOp.cc
   WorkQueue.cc
+  XMLFormatter.cc
   admin_socket.cc
   admin_socket_client.cc
   assert.cc
index 58046e1ff0e2f354b434e91f2cfb5b3377f3fc64..3a47addd2b6cc5501e1e95309dd5de8eb0821b73 100644 (file)
 
 #define LARGE_SIZE 1024
 
+#include "Formatter.h"
+#include "JSONFormatter.h"
 #include "HTMLFormatter.h"
+#include "TableFormatter.h"
+#include "XMLFormatter.h"
 #include "common/escape.h"
 #include "common/StackStringStream.h"
 #include "include/buffer.h"
@@ -23,8 +27,6 @@
 #include <algorithm>
 #include <set>
 #include <limits>
-#include <utility>
-#include <boost/container/small_vector.hpp>
 
 // -----------------------
 namespace ceph {
@@ -157,864 +159,4 @@ void Formatter::dump_format_unquoted(std::string_view name, const char *fmt, ...
   va_end(ap);
 }
 
-// -----------------------
-
-void JSONFormatter::flush(std::ostream& os)
-{
-  finish_pending_string();
-  os << m_ss.str();
-  if (m_line_break_enabled)
-    os << "\n";
-  m_ss.clear();
-  m_ss.str("");
-}
-
-void JSONFormatter::reset()
-{
-  m_stack.clear();
-  m_ss.clear();
-  m_ss.str("");
-  m_pending_string.clear();
-  m_pending_string.str("");
-}
-
-void JSONFormatter::print_comma(json_formatter_stack_entry_d& entry)
-{
-  auto& ss = get_ss();
-  if (entry.size) {
-    if (m_pretty) {
-      ss << ",\n";
-      for (unsigned i = 1; i < m_stack.size(); i++)
-        ss << "    ";
-    } else {
-      ss << ",";
-    }
-  } else if (m_pretty) {
-    ss << "\n";
-    for (unsigned i = 1; i < m_stack.size(); i++)
-      ss << "    ";
-  }
-  if (m_pretty && entry.is_array)
-    ss << "    ";
-}
-
-void JSONFormatter::print_quoted_string(std::string_view s)
-{
-  auto& ss = get_ss();
-  ss << '\"' << json_stream_escaper(s) << '\"';
-}
-
-void JSONFormatter::print_name(std::string_view name)
-{
-  auto& ss = get_ss();
-  finish_pending_string();
-  if (m_stack.empty())
-    return;
-  struct json_formatter_stack_entry_d& entry = m_stack.back();
-  print_comma(entry);
-  if (!entry.is_array) {
-    if (m_pretty) {
-      ss << "    ";
-    }
-    ss << "\"" << name << "\"";
-    if (m_pretty)
-      ss << ": ";
-    else
-      ss << ':';
-  }
-  ++entry.size;
-}
-
-void JSONFormatter::open_section(std::string_view name, const char *ns, bool is_array)
-{
-  auto& ss = get_ss();
-  if (handle_open_section(name, ns, is_array)) {
-    return;
-  }
-  if (ns) {
-    std::ostringstream oss;
-    oss << name << " " << ns;
-    print_name(oss.str().c_str());
-  } else {
-    print_name(name);
-  }
-  if (is_array)
-    ss << '[';
-  else
-    ss << '{';
-
-  json_formatter_stack_entry_d n;
-  n.is_array = is_array;
-  m_stack.push_back(n);
-}
-
-void JSONFormatter::open_array_section(std::string_view name)
-{
-  open_section(name, nullptr, true);
-}
-
-void JSONFormatter::open_array_section_in_ns(std::string_view name, const char *ns)
-{
-  open_section(name, ns, true);
-}
-
-void JSONFormatter::open_object_section(std::string_view name)
-{
-  open_section(name, nullptr, false);
-}
-
-void JSONFormatter::open_object_section_in_ns(std::string_view name, const char *ns)
-{
-  open_section(name, ns, false);
-}
-
-void JSONFormatter::close_section()
-{
-  auto& ss = get_ss();
-  if (handle_close_section()) {
-    return;
-  }
-  ceph_assert(!m_stack.empty());
-  finish_pending_string();
-
-  struct json_formatter_stack_entry_d& entry = m_stack.back();
-  if (m_pretty && entry.size) {
-    ss << "\n";
-    for (unsigned i = 1; i < m_stack.size(); i++)
-      ss << "    ";
-  }
-  ss << (entry.is_array ? ']' : '}');
-  m_stack.pop_back();
-  if (m_pretty && m_stack.empty())
-    ss << "\n";
-}
-
-void JSONFormatter::finish_pending_string()
-{
-  if (m_is_pending_string) {
-    m_is_pending_string = false;
-    add_value(m_pending_name.c_str(), m_pending_string.str(), true);
-    m_pending_string.str("");
-  }
-}
-
-void JSONFormatter::add_value(std::string_view name, double val) {
-  CachedStackStringStream css;
-  if (!std::isfinite(val) || std::isnan(val)) {
-    *css << "null";
-  } else {
-    css->precision(std::numeric_limits<double>::max_digits10);
-    *css << val;
-  }
-  add_value(name, css->strv(), false);
-}
-
-template <class T>
-void JSONFormatter::add_value(std::string_view name, T val)
-{
-  CachedStackStringStream css;
-  css->precision(std::numeric_limits<T>::max_digits10);
-  *css << val;
-  add_value(name, css->strv(), false);
-}
-
-void JSONFormatter::add_value(std::string_view name, std::string_view val, bool quoted)
-{
-  auto& ss = get_ss();
-  if (handle_value(name, val, quoted)) {
-    return;
-  }
-  print_name(name);
-  if (!quoted) {
-    ss << val;
-  } else {
-    print_quoted_string(val);
-  }
-}
-
-void JSONFormatter::dump_null(std::string_view name)
-{
-  add_value(name, "null");
-}
-
-void JSONFormatter::dump_unsigned(std::string_view name, uint64_t u)
-{
-  add_value(name, u);
-}
-
-void JSONFormatter::dump_int(std::string_view name, int64_t s)
-{
-  add_value(name, s);
-}
-
-void JSONFormatter::dump_float(std::string_view name, double d)
-{
-  add_value(name, d);
-}
-
-void JSONFormatter::dump_string(std::string_view name, std::string_view s)
-{
-  add_value(name, s, true);
-}
-
-std::ostream& JSONFormatter::dump_stream(std::string_view name)
-{
-  finish_pending_string();
-  m_pending_name = name;
-  m_is_pending_string = true;
-  return m_pending_string;
-}
-
-void JSONFormatter::dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap)
-{
-  auto buf = boost::container::small_vector<char, LARGE_SIZE>{
-      LARGE_SIZE, boost::container::default_init};
-
-  va_list ap_copy;
-  va_copy(ap_copy, ap);
-  int len = vsnprintf(buf.data(), buf.size(), fmt, ap_copy);
-  va_end(ap_copy);
-
-  if (std::cmp_greater_equal(len, buf.size())) {
-    // output was truncated, allocate a buffer large enough
-    buf.resize(len + 1, boost::container::default_init);
-    vsnprintf(buf.data(), buf.size(), fmt, ap);
-  }
-
-  add_value(name, buf.data(), quoted);
-}
-
-int JSONFormatter::get_len() const
-{
-  return m_ss.tellp();
-}
-
-void JSONFormatter::write_raw_data(const char *data)
-{
-  get_ss() << data;
-}
-
-const char *XMLFormatter::XML_1_DTD =
-  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
-
-XMLFormatter::XMLFormatter(bool pretty, bool lowercased, bool underscored)
-: m_pretty(pretty),
-  m_lowercased(lowercased),
-  m_underscored(underscored)
-{
-  reset();
-}
-
-void XMLFormatter::flush(std::ostream& os)
-{
-  finish_pending_string();
-  std::string m_ss_str = m_ss.str();
-  os << m_ss_str;
-  /* There is a small catch here. If the rest of the formatter had NO output,
-   * we should NOT output a newline. This primarily triggers on HTTP redirects */
-  if (m_pretty && !m_ss_str.empty())
-    os << "\n";
-  else if (m_line_break_enabled)
-    os << "\n";
-  m_ss.clear();
-  m_ss.str("");
-}
-
-void XMLFormatter::reset()
-{
-  m_ss.clear();
-  m_ss.str("");
-  m_pending_string.clear();
-  m_pending_string.str("");
-  m_sections.clear();
-  m_pending_string_name.clear();
-  m_header_done = false;
-}
-
-void XMLFormatter::output_header()
-{
-  if(!m_header_done) {
-    m_header_done = true;
-    write_raw_data(XMLFormatter::XML_1_DTD);
-    if (m_pretty)
-      m_ss << "\n";
-  }
-}
-
-void XMLFormatter::output_footer()
-{
-  while(!m_sections.empty()) {
-    close_section();
-  }
-}
-
-void XMLFormatter::open_object_section(std::string_view name)
-{
-  open_section_in_ns(name, NULL, NULL);
-}
-
-void XMLFormatter::open_object_section_with_attrs(std::string_view name, const FormatterAttrs& attrs)
-{
-  open_section_in_ns(name, NULL, &attrs);
-}
-
-void XMLFormatter::open_object_section_in_ns(std::string_view name, const char *ns)
-{
-  open_section_in_ns(name, ns, NULL);
-}
-
-void XMLFormatter::open_array_section(std::string_view name)
-{
-  open_section_in_ns(name, NULL, NULL);
-}
-
-void XMLFormatter::open_array_section_with_attrs(std::string_view name, const FormatterAttrs& attrs)
-{
-  open_section_in_ns(name, NULL, &attrs);
-}
-
-void XMLFormatter::open_array_section_in_ns(std::string_view name, const char *ns)
-{
-  open_section_in_ns(name, ns, NULL);
-}
-
-std::string XMLFormatter::get_xml_name(std::string_view name) const
-{
-  std::string e(name);
-  std::transform(e.begin(), e.end(), e.begin(),
-      [this](char c) { return this->to_lower_underscore(c); });
-  return e;
-}
-
-void XMLFormatter::close_section()
-{
-  ceph_assert(!m_sections.empty());
-  finish_pending_string();
-
-  auto section = get_xml_name(m_sections.back());
-  m_sections.pop_back();
-  print_spaces();
-  m_ss << "</" << section << ">";
-  if (m_pretty)
-    m_ss << "\n";
-}
-
-template <class T>
-void XMLFormatter::add_value(std::string_view name, T val)
-{
-  auto e = get_xml_name(name);
-  print_spaces();
-  m_ss.precision(std::numeric_limits<T>::max_digits10);
-  m_ss << "<" << e << ">" << val << "</" << e << ">";
-  if (m_pretty)
-    m_ss << "\n";
-}
-
-void XMLFormatter::dump_null(std::string_view name)
-{
-  print_spaces();
-  m_ss << "<" << get_xml_name(name) << " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\" />";
-  if (m_pretty)
-    m_ss << "\n";
-}
-
-void XMLFormatter::dump_unsigned(std::string_view name, uint64_t u)
-{
-  add_value(name, u);
-}
-
-void XMLFormatter::dump_int(std::string_view name, int64_t s)
-{
-  add_value(name, s);
-}
-
-void XMLFormatter::dump_float(std::string_view name, double d)
-{
-  add_value(name, d);
-}
-
-void XMLFormatter::dump_string(std::string_view name, std::string_view s)
-{
-  auto e = get_xml_name(name);
-  print_spaces();
-  m_ss << "<" << e << ">" << xml_stream_escaper(s) << "</" << e << ">";
-  if (m_pretty)
-    m_ss << "\n";
-}
-
-void XMLFormatter::dump_string_with_attrs(std::string_view name, std::string_view s, const FormatterAttrs& attrs)
-{
-  auto e = get_xml_name(name);
-  std::string attrs_str;
-  get_attrs_str(&attrs, attrs_str);
-  print_spaces();
-  m_ss << "<" << e << attrs_str << ">" << xml_stream_escaper(s) << "</" << e << ">";
-  if (m_pretty)
-    m_ss << "\n";
-}
-
-std::ostream& XMLFormatter::dump_stream(std::string_view name)
-{
-  print_spaces();
-  m_pending_string_name = name;
-  m_ss << "<" << m_pending_string_name << ">";
-  return m_pending_string;
-}
-
-void XMLFormatter::dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap)
-{
-  auto buf = boost::container::small_vector<char, LARGE_SIZE>{
-      LARGE_SIZE, boost::container::default_init};
-
-  va_list ap_copy;
-  va_copy(ap_copy, ap);
-  int len = vsnprintf(buf.data(), buf.size(), fmt, ap_copy);
-  va_end(ap_copy);
-
-  if (std::cmp_greater_equal(len, buf.size())) {
-    // output was truncated, allocate a buffer large enough
-    buf.resize(len + 1, boost::container::default_init);
-    vsnprintf(buf.data(), buf.size(), fmt, ap);
-  }
-
-  auto e = get_xml_name(name);
-
-  print_spaces();
-  if (ns) {
-    m_ss << "<" << e << " xmlns=\"" << ns << "\">" << xml_stream_escaper(std::string_view(buf.data(), len)) << "</" << e << ">";
-  } else {
-    m_ss << "<" << e << ">" << xml_stream_escaper(std::string_view(buf.data(), len)) << "</" << e << ">";
-  }
-
-  if (m_pretty)
-    m_ss << "\n";
-}
-
-int XMLFormatter::get_len() const
-{
-  return m_ss.str().size();
-}
-
-void XMLFormatter::write_raw_data(const char *data)
-{
-  m_ss << data;
-}
-
-void XMLFormatter::write_bin_data(const char* buff, int buf_len)
-{
-  std::stringbuf *pbuf = m_ss.rdbuf();
-  pbuf->sputn(buff, buf_len);
-  m_ss.seekg(buf_len);
-}
-
-void XMLFormatter::get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str) const
-{
-  CachedStackStringStream css;
-
-  for (const auto &p : attrs->attrs) {
-    *css << " " << p.first << "=" << "\"" << p.second << "\"";
-  }
-
-  attrs_str = css->strv();
-}
-
-void XMLFormatter::open_section_in_ns(std::string_view name, const char *ns, const FormatterAttrs *attrs)
-{
-  print_spaces();
-  std::string attrs_str;
-
-  if (attrs) {
-    get_attrs_str(attrs, attrs_str);
-  }
-
-  auto e = get_xml_name(name);
-
-  if (ns) {
-    m_ss << "<" << e << attrs_str << " xmlns=\"" << ns << "\">";
-  } else {
-    m_ss << "<" << e << attrs_str << ">";
-  }
-  if (m_pretty)
-    m_ss << "\n";
-  m_sections.push_back(std::string(name));
-}
-
-void XMLFormatter::finish_pending_string()
-{
-  if (!m_pending_string_name.empty()) {
-    m_ss << xml_stream_escaper(m_pending_string.str())
-      << "</" << m_pending_string_name << ">";
-    m_pending_string_name.clear();
-    m_pending_string.str(std::string());
-    if (m_pretty) {
-      m_ss << "\n";
-    }
-  }
-}
-
-void XMLFormatter::print_spaces()
-{
-  finish_pending_string();
-  if (m_pretty) {
-    std::string spaces(m_sections.size(), ' ');
-    m_ss << spaces;
-  }
-}
-
-char XMLFormatter::to_lower_underscore(char c) const
-{
-  if (m_underscored && c == ' ') {
-      return '_';
-  } else if (m_lowercased) {
-    return std::tolower(c);
-  }
-  return c;
-}
-
-TableFormatter::TableFormatter(bool keyval) : m_keyval(keyval)
-{
-  reset();
-}
-
-void TableFormatter::flush(std::ostream& os)
-{
-  finish_pending_string();
-  std::vector<size_t> column_size = m_column_size;
-  std::vector<std::string> column_name = m_column_name;
-
-  std::set<int> need_header_set;
-
-  // auto-sizing columns
-  for (size_t i = 0; i < m_vec.size(); i++) {
-    for (size_t j = 0; j < m_vec[i].size(); j++) {
-      column_size.resize(m_vec[i].size());
-      column_name.resize(m_vec[i].size());
-      if (i > 0) {
-        if (m_vec[i - 1][j] != m_vec[i][j]) {
-          // changing row labels require to show the header
-          need_header_set.insert(i);
-          column_name[i] = m_vec[i][j].first;
-        }
-      } else {
-        column_name[i] = m_vec[i][j].first;
-      }
-
-      if (m_vec[i][j].second.length() > column_size[j])
-        column_size[j] = m_vec[i][j].second.length();
-      if (m_vec[i][j].first.length() > column_size[j])
-        column_size[j] = m_vec[i][j].first.length();
-    }
-  }
-
-  bool need_header = false;
-  if ((column_size.size() == m_column_size.size())) {
-    for (size_t i = 0; i < column_size.size(); i++) {
-      if (column_size[i] != m_column_size[i]) {
-        need_header = true;
-        break;
-      }
-    }
-  } else {
-    need_header = true;
-  }
-
-  if (need_header) {
-    // first row always needs a header if there wasn't one before
-    need_header_set.insert(0);
-  }
-
-  m_column_size = column_size;
-  for (size_t i = 0; i < m_vec.size(); i++) {
-    if (i == 0) {
-      if (need_header_set.count(i)) {
-        // print the header
-        if (!m_keyval) {
-          os << "+";
-          for (size_t j = 0; j < m_vec[i].size(); j++) {
-            for (size_t v = 0; v < m_column_size[j] + 3; v++)
-              os << "-";
-            os << "+";
-          }
-          os << "\n";
-          os << "|";
-
-          for (size_t j = 0; j < m_vec[i].size(); j++) {
-            os << fmt::format(" {:<{}}|",
-                              m_vec[i][j].first, m_column_size[j] + 2);
-          }
-          os << "\n";
-          os << "+";
-          for (size_t j = 0; j < m_vec[i].size(); j++) {
-            for (size_t v = 0; v < m_column_size[j] + 3; v++)
-              os << "-";
-            os << "+";
-          }
-          os << "\n";
-        }
-      }
-    }
-    // print body
-    if (!m_keyval)
-      os << "|";
-    for (size_t j = 0; j < m_vec[i].size(); j++) {
-      if (!m_keyval)
-        os << " ";
-      if (m_keyval) {
-        os << "key::";
-        os << m_vec[i][j].first;
-        os << "=";
-        os << "\"";
-        os << m_vec[i][j].second;
-        os << "\" ";
-      } else {
-        os << fmt::format("{:<{}}|", m_vec[i][j].second, m_column_size[j] + 2);
-      }
-    }
-
-    os << "\n";
-    if (!m_keyval) {
-      if (i == (m_vec.size() - 1)) {
-        // print trailer
-        os << "+";
-        for (size_t j = 0; j < m_vec[i].size(); j++) {
-          for (size_t v = 0; v < m_column_size[j] + 3; v++)
-            os << "-";
-          os << "+";
-        }
-        os << "\n";
-      }
-    }
-    m_vec[i].clear();
-  }
-  m_vec.clear();
-}
-
-void TableFormatter::reset()
-{
-  m_ss.clear();
-  m_ss.str("");
-  m_section_cnt.clear();
-  m_column_size.clear();
-  m_section_open = 0;
-}
-
-void TableFormatter::open_object_section(std::string_view name)
-{
-  open_section_in_ns(name, NULL, NULL);
-}
-
-void TableFormatter::open_object_section_with_attrs(std::string_view name, const FormatterAttrs& attrs)
-{
-  open_section_in_ns(name, NULL, NULL);
-}
-
-void TableFormatter::open_object_section_in_ns(std::string_view name, const char *ns)
-{
-  open_section_in_ns(name, NULL, NULL);
-}
-
-void TableFormatter::open_array_section(std::string_view name)
-{
-  open_section_in_ns(name, NULL, NULL);
-}
-
-void TableFormatter::open_array_section_with_attrs(std::string_view name, const FormatterAttrs& attrs)
-{
-  open_section_in_ns(name, NULL, NULL);
-}
-
-void TableFormatter::open_array_section_in_ns(std::string_view name, const char *ns)
-{
-  open_section_in_ns(name, NULL, NULL);
-}
-
-void TableFormatter::open_section_in_ns(std::string_view name, const char *ns, const FormatterAttrs *attrs)
-{
-  m_section.push_back(std::string(name));
-  m_section_open++;
-}
-
-void TableFormatter::close_section()
-{
-  //
-  m_section_open--;
-  if (m_section.size()) {
-    m_section_cnt[m_section.back()] = 0;
-    m_section.pop_back();
-  }
-}
-
-size_t TableFormatter::m_vec_index(std::string_view name)
-{
-  std::string key(name);
-
-  size_t i = m_vec.size();
-  if (i)
-    i--;
-
-  // make sure there are vectors to push back key/val pairs
-  if (!m_vec.size())
-    m_vec.resize(1);
-
-  if (m_vec.size()) {
-    if (m_vec[i].size()) {
-      if (m_vec[i][0].first == key) {
-        // start a new column if a key is repeated
-        m_vec.resize(m_vec.size() + 1);
-        i++;
-      }
-    }
-  }
-
-  return i;
-}
-
-std::string TableFormatter::get_section_name(std::string_view name)
-{
-  std::string t_name{name};
-  for (const auto &i : m_section) {
-    t_name.insert(0, ":");
-    t_name.insert(0, i);
-  }
-  if (m_section_open) {
-    std::stringstream lss;
-    lss << t_name;
-    lss << "[";
-    lss << m_section_cnt[t_name]++;
-    lss << "]";
-    return lss.str();
-  } else {
-    return t_name;
-  }
-}
-
-template <class T>
-void TableFormatter::add_value(std::string_view name, T val) {
-  finish_pending_string();
-  size_t i = m_vec_index(name);
-  m_ss.precision(std::numeric_limits<double>::max_digits10);
-  m_ss << val;
-
-  m_vec[i].push_back(std::make_pair(get_section_name(name), m_ss.str()));
-  m_ss.clear();
-  m_ss.str("");
-}
-
-void TableFormatter::dump_null(std::string_view name)
-{
-  add_value(name, "null");
-}
-
-void TableFormatter::dump_unsigned(std::string_view name, uint64_t u)
-{
-  add_value(name, u);
-}
-
-void TableFormatter::dump_int(std::string_view name, int64_t s)
-{
-  add_value(name, s);
-}
-
-void TableFormatter::dump_float(std::string_view name, double d)
-{
-  add_value(name, d);
 }
-
-void TableFormatter::dump_string(std::string_view name, std::string_view s)
-{
-  finish_pending_string();
-  size_t i = m_vec_index(name);
-  m_ss << s;
-
-  m_vec[i].push_back(std::make_pair(get_section_name(name), m_ss.str()));
-  m_ss.clear();
-  m_ss.str("");
-}
-
-void TableFormatter::dump_string_with_attrs(std::string_view name, std::string_view s, const FormatterAttrs& attrs)
-{
-  finish_pending_string();
-  size_t i = m_vec_index(name);
-
-  std::string attrs_str;
-  get_attrs_str(&attrs, attrs_str);
-  m_ss << attrs_str << s;
-
-  m_vec[i].push_back(std::make_pair(get_section_name(name), m_ss.str()));
-  m_ss.clear();
-  m_ss.str("");
-}
-
-void TableFormatter::dump_format_va(std::string_view name,
-                                   const char *ns, bool quoted,
-                                   const char *fmt, va_list ap)
-{
-  finish_pending_string();
-  auto buf = boost::container::small_vector<char, LARGE_SIZE>{
-      LARGE_SIZE, boost::container::default_init};
-
-  va_list ap_copy;
-  va_copy(ap_copy, ap);
-  int len = vsnprintf(buf.data(), buf.size(), fmt, ap_copy);
-  va_end(ap_copy);
-
-  if (std::cmp_greater_equal(len, buf.size())) {
-    // output was truncated, allocate a buffer large enough
-    buf.resize(len + 1, boost::container::default_init);
-    vsnprintf(buf.data(), buf.size(), fmt, ap); 
-  }
-
-  size_t i = m_vec_index(name);
-  if (ns) {
-    m_ss << ns << "." << buf.data();
-  } else {
-    m_ss << buf.data();
-  }
-
-  m_vec[i].push_back(std::make_pair(get_section_name(name), m_ss.str()));
-  m_ss.clear();
-  m_ss.str("");
-}
-
-std::ostream& TableFormatter::dump_stream(std::string_view name)
-{
-  finish_pending_string();
-  // we don't support this
-  m_pending_name = name;
-  return m_ss;
-}
-
-int TableFormatter::get_len() const
-{
-  // we don't know the size until flush is called
-  return 0;
-}
-
-void TableFormatter::write_raw_data(const char *data) {
-  // not supported
-}
-
-void TableFormatter::get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str) const
-{
-  CachedStackStringStream css;
-
-  for (const auto &p : attrs->attrs) {
-    *css << " " << p.first << "=" << "\"" << p.second << "\"";
-  }
-
-  attrs_str = css->strv();
-}
-
-void TableFormatter::finish_pending_string()
-{
-  if (m_pending_name.length()) {
-    std::string ss = m_ss.str();
-    m_ss.clear();
-    m_ss.str("");
-    std::string pending_name = m_pending_name;
-    m_pending_name = "";
-    dump_string(pending_name.c_str(), ss);
-  }
-}
-}
-
index 05814ec66c3bffcc2d2f9173ad69857ffbe76c83..0c20b61f06f97cac636e873ed4a95dee25bf4a4e 100644 (file)
@@ -5,16 +5,12 @@
 
 #include "include/buffer_fwd.h"
 
-#include <deque>
-#include <fstream>
 #include <functional>
 #include <list>
 #include <memory>
-#include <vector>
+#include <string>
+
 #include <stdarg.h>
-#include <sstream>
-#include <map>
-#include <vector>
 
 namespace ceph {
 
@@ -247,272 +243,6 @@ namespace ceph {
     virtual void write_bin_data(const char* buff, int buf_len);
   };
 
-  class JSONFormatter : public Formatter {
-  public:
-    explicit JSONFormatter(bool p = false) : m_pretty(p) {}
-    JSONFormatter(const JSONFormatter& f) :
-      m_pretty(f.m_pretty),
-      m_pending_name(f.m_pending_name),
-      m_stack(f.m_stack),
-      m_is_pending_string(f.m_is_pending_string),
-      m_line_break_enabled(f.m_line_break_enabled)
-    {
-      m_ss.str(f.m_ss.str());
-      m_pending_string.str(f.m_pending_string.str());
-    }
-    JSONFormatter(JSONFormatter&& f) :
-      m_pretty(f.m_pretty),
-      m_ss(std::move(f.m_ss)),
-      m_pending_string(std::move(f.m_pending_string)),
-      m_pending_name(f.m_pending_name),
-      m_stack(std::move(f.m_stack)),
-      m_is_pending_string(f.m_is_pending_string),
-      m_line_break_enabled(f.m_line_break_enabled)
-    {
-    }
-    JSONFormatter& operator=(const JSONFormatter& f)
-    {
-      m_pretty = f.m_pretty;
-      m_ss.str(f.m_ss.str());
-      m_pending_string.str(f.m_pending_string.str());
-      m_pending_name = f.m_pending_name;
-      m_stack = f.m_stack;
-      m_is_pending_string = f.m_is_pending_string;
-      m_line_break_enabled = f.m_line_break_enabled;
-      return *this;
-    }
-
-    JSONFormatter& operator=(JSONFormatter&& f)
-    {
-      m_pretty = f.m_pretty;
-      m_ss = std::move(f.m_ss);
-      m_pending_string = std::move(f.m_pending_string);
-      m_pending_name = f.m_pending_name;
-      m_stack = std::move(f.m_stack);
-      m_is_pending_string = f.m_is_pending_string;
-      m_line_break_enabled = f.m_line_break_enabled;
-      return *this;
-    }
-
-    void set_status(int status, const char* status_name) override {};
-    void output_header() override {};
-    void output_footer() override {};
-    void enable_line_break() override { m_line_break_enabled = true; }
-    void flush(std::ostream& os) override;
-    using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
-    void reset() override;
-    void open_array_section(std::string_view name) override;
-    void open_array_section_in_ns(std::string_view name, const char *ns) override;
-    void open_object_section(std::string_view name) override;
-    void open_object_section_in_ns(std::string_view name, const char *ns) override;
-    void close_section() override;
-    void dump_null(std::string_view name) override;
-    void dump_unsigned(std::string_view name, uint64_t u) override;
-    void dump_int(std::string_view name, int64_t s) override;
-    void dump_float(std::string_view name, double d) override;
-    void dump_string(std::string_view name, std::string_view s) override;
-    std::ostream& dump_stream(std::string_view name) override;
-    void dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
-    int get_len() const override;
-    void write_raw_data(const char *data) override;
-
-protected:
-    virtual bool handle_value(std::string_view name, std::string_view s, bool quoted) {
-      return false; /* is handling done? */
-    }
-
-    virtual bool handle_open_section(std::string_view name, const char *ns, bool is_array) {
-      return false; /* is handling done? */
-    }
-
-    virtual bool handle_close_section() {
-      return false; /* is handling done? */
-    }
-
-    int stack_size() { return m_stack.size(); }
-
-    virtual std::ostream& get_ss() {
-      return m_ss;
-    }
-
-    void finish_pending_string();
-
-private:
-    struct json_formatter_stack_entry_d {
-      int size = 0;
-      bool is_array = false;
-    };
-
-    bool m_pretty = false;
-    void open_section(std::string_view name, const char *ns, bool is_array);
-    void print_quoted_string(std::string_view s);
-    void print_name(std::string_view name);
-    void print_comma(json_formatter_stack_entry_d& entry);
-    void add_value(std::string_view name, double val);
-
-    template <class T>
-    void add_value(std::string_view name, T val);
-    void add_value(std::string_view name, std::string_view val, bool quoted);
-
-    mutable std::stringstream m_ss; // mutable for get_len
-    std::stringstream m_pending_string;
-    std::string m_pending_name;
-    std::vector<json_formatter_stack_entry_d> m_stack;
-    bool m_is_pending_string = false;
-    bool m_line_break_enabled = false;
-  };
-
-  class JSONFormatterFile : public JSONFormatter {
-public:
-    JSONFormatterFile(const std::string& path, bool pretty=false) :
-      JSONFormatter(pretty),
-      path(path),
-      file(path, std::ios::out | std::ios::trunc)
-    {
-    }
-    ~JSONFormatterFile() {
-      flush();
-    }
-
-    void flush(std::ostream& os) override {
-      flush();
-    }
-    void flush() {
-      JSONFormatter::finish_pending_string();
-      file.flush();
-    }
-
-    void reset() override {
-      JSONFormatter::reset();
-      file = std::ofstream(path, std::ios::out | std::ios::trunc);
-    }
-    int get_len() const override {
-      return file.tellp();
-    }
-    std::ofstream const& get_ofstream() const {
-      return file;
-    }
-
-protected:
-    std::ostream& get_ss() override {
-      return file;
-    }
-
-private:
-    std::string path;
-    mutable std::ofstream file; // mutable for get_len
-  };
-
-  template <class T>
-  void add_value(std::string_view name, T val);
-
-  class XMLFormatter : public Formatter {
-  public:
-    static const char *XML_1_DTD;
-    XMLFormatter(bool pretty = false, bool lowercased = false, bool underscored = true);
-
-    void set_status(int status, const char* status_name) override {}
-    void output_header() override;
-    void output_footer() override;
-
-    void enable_line_break() override { m_line_break_enabled = true; }
-    void flush(std::ostream& os) override;
-    using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
-    void reset() override;
-    void open_array_section(std::string_view name) override;
-    void open_array_section_in_ns(std::string_view name, const char *ns) override;
-    void open_object_section(std::string_view name) override;
-    void open_object_section_in_ns(std::string_view name, const char *ns) override;
-    void close_section() override;
-    void dump_null(std::string_view name) override;
-    void dump_unsigned(std::string_view name, uint64_t u) override;
-    void dump_int(std::string_view name, int64_t s) override;
-    void dump_float(std::string_view name, double d) override;
-    void dump_string(std::string_view name, std::string_view s) override;
-    std::ostream& dump_stream(std::string_view name) override;
-    void dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
-    int get_len() const override;
-    void write_raw_data(const char *data) override;
-    void write_bin_data(const char* buff, int len) override;
-
-    /* with attrs */
-    void open_array_section_with_attrs(std::string_view name, const FormatterAttrs& attrs) override;
-    void open_object_section_with_attrs(std::string_view name, const FormatterAttrs& attrs) override;
-    void dump_string_with_attrs(std::string_view name, std::string_view s, const FormatterAttrs& attrs) override;
-
-  protected:
-    void open_section_in_ns(std::string_view name, const char *ns, const FormatterAttrs *attrs);
-    void finish_pending_string();
-    void print_spaces();
-    void get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str) const;
-    char to_lower_underscore(char c) const;
-    std::string get_xml_name(std::string_view name) const;
-
-    std::stringstream m_ss, m_pending_string;
-    std::deque<std::string> m_sections;
-    const bool m_pretty;
-    const bool m_lowercased;
-    const bool m_underscored;
-    std::string m_pending_string_name;
-    bool m_header_done;
-    bool m_line_break_enabled = false;
-  private:
-    template <class T>
-    void add_value(std::string_view name, T val);
-  };
-
-  class TableFormatter : public Formatter {
-  public:
-    explicit TableFormatter(bool keyval = false);
-
-    void set_status(int status, const char* status_name) override {};
-    void output_header() override {};
-    void output_footer() override {};
-    void enable_line_break() override {};
-    void flush(std::ostream& os) override;
-    using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
-    void reset() override;
-    void open_array_section(std::string_view name) override;
-    void open_array_section_in_ns(std::string_view name, const char *ns) override;
-    void open_object_section(std::string_view name) override;
-    void open_object_section_in_ns(std::string_view name, const char *ns) override;
-
-    void open_array_section_with_attrs(std::string_view name, const FormatterAttrs& attrs) override;
-    void open_object_section_with_attrs(std::string_view name, const FormatterAttrs& attrs) override;
-
-    void close_section() override;
-    void dump_null(std::string_view name) override;
-    void dump_unsigned(std::string_view name, uint64_t u) override;
-    void dump_int(std::string_view name, int64_t s) override;
-    void dump_float(std::string_view name, double d) override;
-    void dump_string(std::string_view name, std::string_view s) override;
-    void dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
-    void dump_string_with_attrs(std::string_view name, std::string_view s, const FormatterAttrs& attrs) override;
-    std::ostream& dump_stream(std::string_view name) override;
-
-    int get_len() const override;
-    void write_raw_data(const char *data) override;
-    void get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str) const;
-
-  private:
-    template <class T>
-    void add_value(std::string_view name, T val);
-    void open_section_in_ns(std::string_view name, const char *ns, const FormatterAttrs *attrs);
-    std::vector< std::vector<std::pair<std::string, std::string> > > m_vec;
-    std::stringstream m_ss;
-    size_t m_vec_index(std::string_view name);
-    std::string get_section_name(std::string_view name);
-    void finish_pending_string();
-    std::string m_pending_name;
-    bool m_keyval;
-
-    int m_section_open;
-    std::vector< std::string > m_section;
-    std::map<std::string, int> m_section_cnt;
-    std::vector<size_t> m_column_size;
-    std::vector< std::string > m_column_name;
-  };
-
   std::string fixed_to_string(int64_t num, int scale);
   std::string fixed_u_to_string(uint64_t num, int scale);
 }
index 1bc8d864cb6ba369373e715dc783e2cab6916eed..1f452710f600ff9173b71eaf7aa310c1a9a316a6 100644 (file)
@@ -17,7 +17,6 @@
 #include "HTMLFormatter.h"
 #include "Formatter.h"
 
-#include <sstream>
 #include <stdarg.h>
 #include <stdio.h>
 #include <stdlib.h>
index cc891824b03ad41b73689e18c6f973e0636126d9..d01d2d8b60336a93c4e2951bda2890a78d0600e6 100644 (file)
@@ -3,7 +3,7 @@
 #ifndef CEPH_HTML_FORMATTER_H
 #define CEPH_HTML_FORMATTER_H
 
-#include "Formatter.h"
+#include "XMLFormatter.h"
 
 namespace ceph {
   class HTMLFormatter : public XMLFormatter {
diff --git a/src/common/JSONFormatter.cc b/src/common/JSONFormatter.cc
new file mode 100644 (file)
index 0000000..7308f44
--- /dev/null
@@ -0,0 +1,265 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+#include "JSONFormatter.h"
+#include "common/escape.h"
+#include "common/StackStringStream.h"
+#include "include/ceph_assert.h"
+
+#include <boost/container/small_vector.hpp>
+
+#include <cmath> // for std::isfinite(), std::isnan()
+#include <limits>
+#include <utility>
+
+#define LARGE_SIZE 1024
+
+namespace ceph {
+
+void JSONFormatter::flush(std::ostream& os)
+{
+  finish_pending_string();
+  os << m_ss.str();
+  if (m_line_break_enabled)
+    os << "\n";
+  m_ss.clear();
+  m_ss.str("");
+}
+
+void JSONFormatter::reset()
+{
+  m_stack.clear();
+  m_ss.clear();
+  m_ss.str("");
+  m_pending_string.clear();
+  m_pending_string.str("");
+}
+
+void JSONFormatter::print_comma(json_formatter_stack_entry_d& entry)
+{
+  auto& ss = get_ss();
+  if (entry.size) {
+    if (m_pretty) {
+      ss << ",\n";
+      for (unsigned i = 1; i < m_stack.size(); i++)
+        ss << "    ";
+    } else {
+      ss << ",";
+    }
+  } else if (m_pretty) {
+    ss << "\n";
+    for (unsigned i = 1; i < m_stack.size(); i++)
+      ss << "    ";
+  }
+  if (m_pretty && entry.is_array)
+    ss << "    ";
+}
+
+void JSONFormatter::print_quoted_string(std::string_view s)
+{
+  auto& ss = get_ss();
+  ss << '\"' << json_stream_escaper(s) << '\"';
+}
+
+void JSONFormatter::print_name(std::string_view name)
+{
+  auto& ss = get_ss();
+  finish_pending_string();
+  if (m_stack.empty())
+    return;
+  struct json_formatter_stack_entry_d& entry = m_stack.back();
+  print_comma(entry);
+  if (!entry.is_array) {
+    if (m_pretty) {
+      ss << "    ";
+    }
+    ss << "\"" << name << "\"";
+    if (m_pretty)
+      ss << ": ";
+    else
+      ss << ':';
+  }
+  ++entry.size;
+}
+
+void JSONFormatter::open_section(std::string_view name, const char *ns, bool is_array)
+{
+  auto& ss = get_ss();
+  if (handle_open_section(name, ns, is_array)) {
+    return;
+  }
+  if (ns) {
+    std::ostringstream oss;
+    oss << name << " " << ns;
+    print_name(oss.str().c_str());
+  } else {
+    print_name(name);
+  }
+  if (is_array)
+    ss << '[';
+  else
+    ss << '{';
+
+  json_formatter_stack_entry_d n;
+  n.is_array = is_array;
+  m_stack.push_back(n);
+}
+
+void JSONFormatter::open_array_section(std::string_view name)
+{
+  open_section(name, nullptr, true);
+}
+
+void JSONFormatter::open_array_section_in_ns(std::string_view name, const char *ns)
+{
+  open_section(name, ns, true);
+}
+
+void JSONFormatter::open_object_section(std::string_view name)
+{
+  open_section(name, nullptr, false);
+}
+
+void JSONFormatter::open_object_section_in_ns(std::string_view name, const char *ns)
+{
+  open_section(name, ns, false);
+}
+
+void JSONFormatter::close_section()
+{
+  auto& ss = get_ss();
+  if (handle_close_section()) {
+    return;
+  }
+  ceph_assert(!m_stack.empty());
+  finish_pending_string();
+
+  struct json_formatter_stack_entry_d& entry = m_stack.back();
+  if (m_pretty && entry.size) {
+    ss << "\n";
+    for (unsigned i = 1; i < m_stack.size(); i++)
+      ss << "    ";
+  }
+  ss << (entry.is_array ? ']' : '}');
+  m_stack.pop_back();
+  if (m_pretty && m_stack.empty())
+    ss << "\n";
+}
+
+void JSONFormatter::finish_pending_string()
+{
+  if (m_is_pending_string) {
+    m_is_pending_string = false;
+    add_value(m_pending_name.c_str(), m_pending_string.str(), true);
+    m_pending_string.str("");
+  }
+}
+
+void JSONFormatter::add_value(std::string_view name, double val) {
+  CachedStackStringStream css;
+  if (!std::isfinite(val) || std::isnan(val)) {
+    *css << "null";
+  } else {
+    css->precision(std::numeric_limits<double>::max_digits10);
+    *css << val;
+  }
+  add_value(name, css->strv(), false);
+}
+
+template <class T>
+void JSONFormatter::add_value(std::string_view name, T val)
+{
+  CachedStackStringStream css;
+  css->precision(std::numeric_limits<T>::max_digits10);
+  *css << val;
+  add_value(name, css->strv(), false);
+}
+
+void JSONFormatter::add_value(std::string_view name, std::string_view val, bool quoted)
+{
+  auto& ss = get_ss();
+  if (handle_value(name, val, quoted)) {
+    return;
+  }
+  print_name(name);
+  if (!quoted) {
+    ss << val;
+  } else {
+    print_quoted_string(val);
+  }
+}
+
+void JSONFormatter::dump_null(std::string_view name)
+{
+  add_value(name, "null");
+}
+
+void JSONFormatter::dump_unsigned(std::string_view name, uint64_t u)
+{
+  add_value(name, u);
+}
+
+void JSONFormatter::dump_int(std::string_view name, int64_t s)
+{
+  add_value(name, s);
+}
+
+void JSONFormatter::dump_float(std::string_view name, double d)
+{
+  add_value(name, d);
+}
+
+void JSONFormatter::dump_string(std::string_view name, std::string_view s)
+{
+  add_value(name, s, true);
+}
+
+std::ostream& JSONFormatter::dump_stream(std::string_view name)
+{
+  finish_pending_string();
+  m_pending_name = name;
+  m_is_pending_string = true;
+  return m_pending_string;
+}
+
+void JSONFormatter::dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap)
+{
+  auto buf = boost::container::small_vector<char, LARGE_SIZE>{
+      LARGE_SIZE, boost::container::default_init};
+
+  va_list ap_copy;
+  va_copy(ap_copy, ap);
+  int len = vsnprintf(buf.data(), buf.size(), fmt, ap_copy);
+  va_end(ap_copy);
+
+  if (std::cmp_greater_equal(len, buf.size())) {
+    // output was truncated, allocate a buffer large enough
+    buf.resize(len + 1, boost::container::default_init);
+    vsnprintf(buf.data(), buf.size(), fmt, ap);
+  }
+
+  add_value(name, buf.data(), quoted);
+}
+
+int JSONFormatter::get_len() const
+{
+  return m_ss.tellp();
+}
+
+void JSONFormatter::write_raw_data(const char *data)
+{
+  get_ss() << data;
+}
+
+}
diff --git a/src/common/JSONFormatter.h b/src/common/JSONFormatter.h
new file mode 100644 (file)
index 0000000..4cc711d
--- /dev/null
@@ -0,0 +1,128 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "common/Formatter.h"
+
+#include <sstream>
+#include <vector>
+
+namespace ceph {
+
+  class JSONFormatter : public Formatter {
+  public:
+    explicit JSONFormatter(bool p = false) : m_pretty(p) {}
+    JSONFormatter(const JSONFormatter& f) :
+      m_pretty(f.m_pretty),
+      m_pending_name(f.m_pending_name),
+      m_stack(f.m_stack),
+      m_is_pending_string(f.m_is_pending_string),
+      m_line_break_enabled(f.m_line_break_enabled)
+    {
+      m_ss.str(f.m_ss.str());
+      m_pending_string.str(f.m_pending_string.str());
+    }
+    JSONFormatter(JSONFormatter&& f) :
+      m_pretty(f.m_pretty),
+      m_ss(std::move(f.m_ss)),
+      m_pending_string(std::move(f.m_pending_string)),
+      m_pending_name(f.m_pending_name),
+      m_stack(std::move(f.m_stack)),
+      m_is_pending_string(f.m_is_pending_string),
+      m_line_break_enabled(f.m_line_break_enabled)
+    {
+    }
+    JSONFormatter& operator=(const JSONFormatter& f)
+    {
+      m_pretty = f.m_pretty;
+      m_ss.str(f.m_ss.str());
+      m_pending_string.str(f.m_pending_string.str());
+      m_pending_name = f.m_pending_name;
+      m_stack = f.m_stack;
+      m_is_pending_string = f.m_is_pending_string;
+      m_line_break_enabled = f.m_line_break_enabled;
+      return *this;
+    }
+
+    JSONFormatter& operator=(JSONFormatter&& f)
+    {
+      m_pretty = f.m_pretty;
+      m_ss = std::move(f.m_ss);
+      m_pending_string = std::move(f.m_pending_string);
+      m_pending_name = f.m_pending_name;
+      m_stack = std::move(f.m_stack);
+      m_is_pending_string = f.m_is_pending_string;
+      m_line_break_enabled = f.m_line_break_enabled;
+      return *this;
+    }
+
+    void set_status(int status, const char* status_name) override {};
+    void output_header() override {};
+    void output_footer() override {};
+    void enable_line_break() override { m_line_break_enabled = true; }
+    void flush(std::ostream& os) override;
+    using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
+    void reset() override;
+    void open_array_section(std::string_view name) override;
+    void open_array_section_in_ns(std::string_view name, const char *ns) override;
+    void open_object_section(std::string_view name) override;
+    void open_object_section_in_ns(std::string_view name, const char *ns) override;
+    void close_section() override;
+    void dump_null(std::string_view name) override;
+    void dump_unsigned(std::string_view name, uint64_t u) override;
+    void dump_int(std::string_view name, int64_t s) override;
+    void dump_float(std::string_view name, double d) override;
+    void dump_string(std::string_view name, std::string_view s) override;
+    std::ostream& dump_stream(std::string_view name) override;
+    void dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
+    int get_len() const override;
+    void write_raw_data(const char *data) override;
+
+protected:
+    virtual bool handle_value(std::string_view name, std::string_view s, bool quoted) {
+      return false; /* is handling done? */
+    }
+
+    virtual bool handle_open_section(std::string_view name, const char *ns, bool is_array) {
+      return false; /* is handling done? */
+    }
+
+    virtual bool handle_close_section() {
+      return false; /* is handling done? */
+    }
+
+    int stack_size() { return m_stack.size(); }
+
+    virtual std::ostream& get_ss() {
+      return m_ss;
+    }
+
+    void finish_pending_string();
+
+private:
+    struct json_formatter_stack_entry_d {
+      int size = 0;
+      bool is_array = false;
+    };
+
+    bool m_pretty = false;
+    void open_section(std::string_view name, const char *ns, bool is_array);
+    void print_quoted_string(std::string_view s);
+    void print_name(std::string_view name);
+    void print_comma(json_formatter_stack_entry_d& entry);
+    void add_value(std::string_view name, double val);
+
+    template <class T>
+    void add_value(std::string_view name, T val);
+    void add_value(std::string_view name, std::string_view val, bool quoted);
+
+    mutable std::stringstream m_ss; // mutable for get_len
+    std::stringstream m_pending_string;
+    std::string m_pending_name;
+    std::vector<json_formatter_stack_entry_d> m_stack;
+    bool m_is_pending_string = false;
+    bool m_line_break_enabled = false;
+  };
+
+}
diff --git a/src/common/JSONFormatterFile.h b/src/common/JSONFormatterFile.h
new file mode 100644 (file)
index 0000000..91a6873
--- /dev/null
@@ -0,0 +1,54 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "JSONFormatter.h"
+
+#include <fstream>
+
+namespace ceph {
+
+  class JSONFormatterFile : public JSONFormatter {
+public:
+    JSONFormatterFile(const std::string& path, bool pretty=false) :
+      JSONFormatter(pretty),
+      path(path),
+      file(path, std::ios::out | std::ios::trunc)
+    {
+    }
+    ~JSONFormatterFile() {
+      flush();
+    }
+
+    void flush(std::ostream& os) override {
+      flush();
+    }
+    void flush() {
+      JSONFormatter::finish_pending_string();
+      file.flush();
+    }
+
+    void reset() override {
+      JSONFormatter::reset();
+      file = std::ofstream(path, std::ios::out | std::ios::trunc);
+    }
+    int get_len() const override {
+      return file.tellp();
+    }
+    std::ofstream const& get_ofstream() const {
+      return file;
+    }
+
+protected:
+    std::ostream& get_ss() override {
+      return file;
+    }
+
+private:
+    std::string path;
+    mutable std::ofstream file; // mutable for get_len
+  };
+
+}
+
diff --git a/src/common/TableFormatter.cc b/src/common/TableFormatter.cc
new file mode 100644 (file)
index 0000000..8995d6c
--- /dev/null
@@ -0,0 +1,378 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+#include "TableFormatter.h"
+#include "common/escape.h"
+#include "common/StackStringStream.h"
+#include "include/buffer.h"
+
+#include <boost/container/small_vector.hpp>
+#include <fmt/format.h>
+
+#include <algorithm>
+#include <set>
+#include <limits>
+#include <utility>
+
+#define LARGE_SIZE 1024
+
+namespace ceph {
+
+TableFormatter::TableFormatter(bool keyval) : m_keyval(keyval)
+{
+  reset();
+}
+
+void TableFormatter::flush(std::ostream& os)
+{
+  finish_pending_string();
+  std::vector<size_t> column_size = m_column_size;
+  std::vector<std::string> column_name = m_column_name;
+
+  std::set<int> need_header_set;
+
+  // auto-sizing columns
+  for (size_t i = 0; i < m_vec.size(); i++) {
+    for (size_t j = 0; j < m_vec[i].size(); j++) {
+      column_size.resize(m_vec[i].size());
+      column_name.resize(m_vec[i].size());
+      if (i > 0) {
+        if (m_vec[i - 1][j] != m_vec[i][j]) {
+          // changing row labels require to show the header
+          need_header_set.insert(i);
+          column_name[i] = m_vec[i][j].first;
+        }
+      } else {
+        column_name[i] = m_vec[i][j].first;
+      }
+
+      if (m_vec[i][j].second.length() > column_size[j])
+        column_size[j] = m_vec[i][j].second.length();
+      if (m_vec[i][j].first.length() > column_size[j])
+        column_size[j] = m_vec[i][j].first.length();
+    }
+  }
+
+  bool need_header = false;
+  if ((column_size.size() == m_column_size.size())) {
+    for (size_t i = 0; i < column_size.size(); i++) {
+      if (column_size[i] != m_column_size[i]) {
+        need_header = true;
+        break;
+      }
+    }
+  } else {
+    need_header = true;
+  }
+
+  if (need_header) {
+    // first row always needs a header if there wasn't one before
+    need_header_set.insert(0);
+  }
+
+  m_column_size = column_size;
+  for (size_t i = 0; i < m_vec.size(); i++) {
+    if (i == 0) {
+      if (need_header_set.count(i)) {
+        // print the header
+        if (!m_keyval) {
+          os << "+";
+          for (size_t j = 0; j < m_vec[i].size(); j++) {
+            for (size_t v = 0; v < m_column_size[j] + 3; v++)
+              os << "-";
+            os << "+";
+          }
+          os << "\n";
+          os << "|";
+
+          for (size_t j = 0; j < m_vec[i].size(); j++) {
+            os << fmt::format(" {:<{}}|",
+                              m_vec[i][j].first, m_column_size[j] + 2);
+          }
+          os << "\n";
+          os << "+";
+          for (size_t j = 0; j < m_vec[i].size(); j++) {
+            for (size_t v = 0; v < m_column_size[j] + 3; v++)
+              os << "-";
+            os << "+";
+          }
+          os << "\n";
+        }
+      }
+    }
+    // print body
+    if (!m_keyval)
+      os << "|";
+    for (size_t j = 0; j < m_vec[i].size(); j++) {
+      if (!m_keyval)
+        os << " ";
+      if (m_keyval) {
+        os << "key::";
+        os << m_vec[i][j].first;
+        os << "=";
+        os << "\"";
+        os << m_vec[i][j].second;
+        os << "\" ";
+      } else {
+        os << fmt::format("{:<{}}|", m_vec[i][j].second, m_column_size[j] + 2);
+      }
+    }
+
+    os << "\n";
+    if (!m_keyval) {
+      if (i == (m_vec.size() - 1)) {
+        // print trailer
+        os << "+";
+        for (size_t j = 0; j < m_vec[i].size(); j++) {
+          for (size_t v = 0; v < m_column_size[j] + 3; v++)
+            os << "-";
+          os << "+";
+        }
+        os << "\n";
+      }
+    }
+    m_vec[i].clear();
+  }
+  m_vec.clear();
+}
+
+void TableFormatter::reset()
+{
+  m_ss.clear();
+  m_ss.str("");
+  m_section_cnt.clear();
+  m_column_size.clear();
+  m_section_open = 0;
+}
+
+void TableFormatter::open_object_section(std::string_view name)
+{
+  open_section_in_ns(name, NULL, NULL);
+}
+
+void TableFormatter::open_object_section_with_attrs(std::string_view name, const FormatterAttrs& attrs)
+{
+  open_section_in_ns(name, NULL, NULL);
+}
+
+void TableFormatter::open_object_section_in_ns(std::string_view name, const char *ns)
+{
+  open_section_in_ns(name, NULL, NULL);
+}
+
+void TableFormatter::open_array_section(std::string_view name)
+{
+  open_section_in_ns(name, NULL, NULL);
+}
+
+void TableFormatter::open_array_section_with_attrs(std::string_view name, const FormatterAttrs& attrs)
+{
+  open_section_in_ns(name, NULL, NULL);
+}
+
+void TableFormatter::open_array_section_in_ns(std::string_view name, const char *ns)
+{
+  open_section_in_ns(name, NULL, NULL);
+}
+
+void TableFormatter::open_section_in_ns(std::string_view name, const char *ns, const FormatterAttrs *attrs)
+{
+  m_section.push_back(std::string(name));
+  m_section_open++;
+}
+
+void TableFormatter::close_section()
+{
+  //
+  m_section_open--;
+  if (m_section.size()) {
+    m_section_cnt[m_section.back()] = 0;
+    m_section.pop_back();
+  }
+}
+
+size_t TableFormatter::m_vec_index(std::string_view name)
+{
+  std::string key(name);
+
+  size_t i = m_vec.size();
+  if (i)
+    i--;
+
+  // make sure there are vectors to push back key/val pairs
+  if (!m_vec.size())
+    m_vec.resize(1);
+
+  if (m_vec.size()) {
+    if (m_vec[i].size()) {
+      if (m_vec[i][0].first == key) {
+        // start a new column if a key is repeated
+        m_vec.resize(m_vec.size() + 1);
+        i++;
+      }
+    }
+  }
+
+  return i;
+}
+
+std::string TableFormatter::get_section_name(std::string_view name)
+{
+  std::string t_name{name};
+  for (const auto &i : m_section) {
+    t_name.insert(0, ":");
+    t_name.insert(0, i);
+  }
+  if (m_section_open) {
+    std::stringstream lss;
+    lss << t_name;
+    lss << "[";
+    lss << m_section_cnt[t_name]++;
+    lss << "]";
+    return lss.str();
+  } else {
+    return t_name;
+  }
+}
+
+template <class T>
+void TableFormatter::add_value(std::string_view name, T val) {
+  finish_pending_string();
+  size_t i = m_vec_index(name);
+  m_ss.precision(std::numeric_limits<double>::max_digits10);
+  m_ss << val;
+
+  m_vec[i].push_back(std::make_pair(get_section_name(name), m_ss.str()));
+  m_ss.clear();
+  m_ss.str("");
+}
+
+void TableFormatter::dump_null(std::string_view name)
+{
+  add_value(name, "null");
+}
+
+void TableFormatter::dump_unsigned(std::string_view name, uint64_t u)
+{
+  add_value(name, u);
+}
+
+void TableFormatter::dump_int(std::string_view name, int64_t s)
+{
+  add_value(name, s);
+}
+
+void TableFormatter::dump_float(std::string_view name, double d)
+{
+  add_value(name, d);
+}
+
+void TableFormatter::dump_string(std::string_view name, std::string_view s)
+{
+  finish_pending_string();
+  size_t i = m_vec_index(name);
+  m_ss << s;
+
+  m_vec[i].push_back(std::make_pair(get_section_name(name), m_ss.str()));
+  m_ss.clear();
+  m_ss.str("");
+}
+
+void TableFormatter::dump_string_with_attrs(std::string_view name, std::string_view s, const FormatterAttrs& attrs)
+{
+  finish_pending_string();
+  size_t i = m_vec_index(name);
+
+  std::string attrs_str;
+  get_attrs_str(&attrs, attrs_str);
+  m_ss << attrs_str << s;
+
+  m_vec[i].push_back(std::make_pair(get_section_name(name), m_ss.str()));
+  m_ss.clear();
+  m_ss.str("");
+}
+
+void TableFormatter::dump_format_va(std::string_view name,
+                                   const char *ns, bool quoted,
+                                   const char *fmt, va_list ap)
+{
+  finish_pending_string();
+  auto buf = boost::container::small_vector<char, LARGE_SIZE>{
+      LARGE_SIZE, boost::container::default_init};
+
+  va_list ap_copy;
+  va_copy(ap_copy, ap);
+  int len = vsnprintf(buf.data(), buf.size(), fmt, ap_copy);
+  va_end(ap_copy);
+
+  if (std::cmp_greater_equal(len, buf.size())) {
+    // output was truncated, allocate a buffer large enough
+    buf.resize(len + 1, boost::container::default_init);
+    vsnprintf(buf.data(), buf.size(), fmt, ap); 
+  }
+
+  size_t i = m_vec_index(name);
+  if (ns) {
+    m_ss << ns << "." << buf.data();
+  } else {
+    m_ss << buf.data();
+  }
+
+  m_vec[i].push_back(std::make_pair(get_section_name(name), m_ss.str()));
+  m_ss.clear();
+  m_ss.str("");
+}
+
+std::ostream& TableFormatter::dump_stream(std::string_view name)
+{
+  finish_pending_string();
+  // we don't support this
+  m_pending_name = name;
+  return m_ss;
+}
+
+int TableFormatter::get_len() const
+{
+  // we don't know the size until flush is called
+  return 0;
+}
+
+void TableFormatter::write_raw_data(const char *data) {
+  // not supported
+}
+
+void TableFormatter::get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str) const
+{
+  CachedStackStringStream css;
+
+  for (const auto &p : attrs->attrs) {
+    *css << " " << p.first << "=" << "\"" << p.second << "\"";
+  }
+
+  attrs_str = css->strv();
+}
+
+void TableFormatter::finish_pending_string()
+{
+  if (m_pending_name.length()) {
+    std::string ss = m_ss.str();
+    m_ss.clear();
+    m_ss.str("");
+    std::string pending_name = m_pending_name;
+    m_pending_name = "";
+    dump_string(pending_name.c_str(), ss);
+  }
+}
+
+}
diff --git a/src/common/TableFormatter.h b/src/common/TableFormatter.h
new file mode 100644 (file)
index 0000000..31bfaa2
--- /dev/null
@@ -0,0 +1,67 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "common/Formatter.h"
+
+#include <memory>
+#include <vector>
+#include <sstream>
+#include <map>
+
+namespace ceph {
+
+  class TableFormatter : public Formatter {
+  public:
+    explicit TableFormatter(bool keyval = false);
+
+    void set_status(int status, const char* status_name) override {};
+    void output_header() override {};
+    void output_footer() override {};
+    void enable_line_break() override {};
+    void flush(std::ostream& os) override;
+    using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
+    void reset() override;
+    void open_array_section(std::string_view name) override;
+    void open_array_section_in_ns(std::string_view name, const char *ns) override;
+    void open_object_section(std::string_view name) override;
+    void open_object_section_in_ns(std::string_view name, const char *ns) override;
+
+    void open_array_section_with_attrs(std::string_view name, const FormatterAttrs& attrs) override;
+    void open_object_section_with_attrs(std::string_view name, const FormatterAttrs& attrs) override;
+
+    void close_section() override;
+    void dump_null(std::string_view name) override;
+    void dump_unsigned(std::string_view name, uint64_t u) override;
+    void dump_int(std::string_view name, int64_t s) override;
+    void dump_float(std::string_view name, double d) override;
+    void dump_string(std::string_view name, std::string_view s) override;
+    void dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
+    void dump_string_with_attrs(std::string_view name, std::string_view s, const FormatterAttrs& attrs) override;
+    std::ostream& dump_stream(std::string_view name) override;
+
+    int get_len() const override;
+    void write_raw_data(const char *data) override;
+    void get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str) const;
+
+  private:
+    template <class T>
+    void add_value(std::string_view name, T val);
+    void open_section_in_ns(std::string_view name, const char *ns, const FormatterAttrs *attrs);
+    std::vector< std::vector<std::pair<std::string, std::string> > > m_vec;
+    std::stringstream m_ss;
+    size_t m_vec_index(std::string_view name);
+    std::string get_section_name(std::string_view name);
+    void finish_pending_string();
+    std::string m_pending_name;
+    bool m_keyval;
+
+    int m_section_open;
+    std::vector< std::string > m_section;
+    std::map<std::string, int> m_section_cnt;
+    std::vector<size_t> m_column_size;
+    std::vector< std::string > m_column_name;
+  };
+
+}
diff --git a/src/common/XMLFormatter.cc b/src/common/XMLFormatter.cc
new file mode 100644 (file)
index 0000000..e1baaf0
--- /dev/null
@@ -0,0 +1,307 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2011 New Dream Network
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software
+ * Foundation.  See file COPYING.
+ *
+ */
+
+#include "XMLFormatter.h"
+#include "common/escape.h"
+#include "common/StackStringStream.h"
+#include "include/ceph_assert.h"
+
+#include <boost/container/small_vector.hpp>
+
+#include <algorithm>
+#include <limits>
+#include <utility>
+
+#define LARGE_SIZE 1024
+
+namespace ceph {
+
+const char *XMLFormatter::XML_1_DTD =
+  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+
+XMLFormatter::XMLFormatter(bool pretty, bool lowercased, bool underscored)
+: m_pretty(pretty),
+  m_lowercased(lowercased),
+  m_underscored(underscored)
+{
+  reset();
+}
+
+void XMLFormatter::flush(std::ostream& os)
+{
+  finish_pending_string();
+  std::string m_ss_str = m_ss.str();
+  os << m_ss_str;
+  /* There is a small catch here. If the rest of the formatter had NO output,
+   * we should NOT output a newline. This primarily triggers on HTTP redirects */
+  if (m_pretty && !m_ss_str.empty())
+    os << "\n";
+  else if (m_line_break_enabled)
+    os << "\n";
+  m_ss.clear();
+  m_ss.str("");
+}
+
+void XMLFormatter::reset()
+{
+  m_ss.clear();
+  m_ss.str("");
+  m_pending_string.clear();
+  m_pending_string.str("");
+  m_sections.clear();
+  m_pending_string_name.clear();
+  m_header_done = false;
+}
+
+void XMLFormatter::output_header()
+{
+  if(!m_header_done) {
+    m_header_done = true;
+    write_raw_data(XMLFormatter::XML_1_DTD);
+    if (m_pretty)
+      m_ss << "\n";
+  }
+}
+
+void XMLFormatter::output_footer()
+{
+  while(!m_sections.empty()) {
+    close_section();
+  }
+}
+
+void XMLFormatter::open_object_section(std::string_view name)
+{
+  open_section_in_ns(name, NULL, NULL);
+}
+
+void XMLFormatter::open_object_section_with_attrs(std::string_view name, const FormatterAttrs& attrs)
+{
+  open_section_in_ns(name, NULL, &attrs);
+}
+
+void XMLFormatter::open_object_section_in_ns(std::string_view name, const char *ns)
+{
+  open_section_in_ns(name, ns, NULL);
+}
+
+void XMLFormatter::open_array_section(std::string_view name)
+{
+  open_section_in_ns(name, NULL, NULL);
+}
+
+void XMLFormatter::open_array_section_with_attrs(std::string_view name, const FormatterAttrs& attrs)
+{
+  open_section_in_ns(name, NULL, &attrs);
+}
+
+void XMLFormatter::open_array_section_in_ns(std::string_view name, const char *ns)
+{
+  open_section_in_ns(name, ns, NULL);
+}
+
+std::string XMLFormatter::get_xml_name(std::string_view name) const
+{
+  std::string e(name);
+  std::transform(e.begin(), e.end(), e.begin(),
+      [this](char c) { return this->to_lower_underscore(c); });
+  return e;
+}
+
+void XMLFormatter::close_section()
+{
+  ceph_assert(!m_sections.empty());
+  finish_pending_string();
+
+  auto section = get_xml_name(m_sections.back());
+  m_sections.pop_back();
+  print_spaces();
+  m_ss << "</" << section << ">";
+  if (m_pretty)
+    m_ss << "\n";
+}
+
+template <class T>
+void XMLFormatter::add_value(std::string_view name, T val)
+{
+  auto e = get_xml_name(name);
+  print_spaces();
+  m_ss.precision(std::numeric_limits<T>::max_digits10);
+  m_ss << "<" << e << ">" << val << "</" << e << ">";
+  if (m_pretty)
+    m_ss << "\n";
+}
+
+void XMLFormatter::dump_null(std::string_view name)
+{
+  print_spaces();
+  m_ss << "<" << get_xml_name(name) << " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:nil=\"true\" />";
+  if (m_pretty)
+    m_ss << "\n";
+}
+
+void XMLFormatter::dump_unsigned(std::string_view name, uint64_t u)
+{
+  add_value(name, u);
+}
+
+void XMLFormatter::dump_int(std::string_view name, int64_t s)
+{
+  add_value(name, s);
+}
+
+void XMLFormatter::dump_float(std::string_view name, double d)
+{
+  add_value(name, d);
+}
+
+void XMLFormatter::dump_string(std::string_view name, std::string_view s)
+{
+  auto e = get_xml_name(name);
+  print_spaces();
+  m_ss << "<" << e << ">" << xml_stream_escaper(s) << "</" << e << ">";
+  if (m_pretty)
+    m_ss << "\n";
+}
+
+void XMLFormatter::dump_string_with_attrs(std::string_view name, std::string_view s, const FormatterAttrs& attrs)
+{
+  auto e = get_xml_name(name);
+  std::string attrs_str;
+  get_attrs_str(&attrs, attrs_str);
+  print_spaces();
+  m_ss << "<" << e << attrs_str << ">" << xml_stream_escaper(s) << "</" << e << ">";
+  if (m_pretty)
+    m_ss << "\n";
+}
+
+std::ostream& XMLFormatter::dump_stream(std::string_view name)
+{
+  print_spaces();
+  m_pending_string_name = name;
+  m_ss << "<" << m_pending_string_name << ">";
+  return m_pending_string;
+}
+
+void XMLFormatter::dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap)
+{
+  auto buf = boost::container::small_vector<char, LARGE_SIZE>{
+      LARGE_SIZE, boost::container::default_init};
+
+  va_list ap_copy;
+  va_copy(ap_copy, ap);
+  int len = vsnprintf(buf.data(), buf.size(), fmt, ap_copy);
+  va_end(ap_copy);
+
+  if (std::cmp_greater_equal(len, buf.size())) {
+    // output was truncated, allocate a buffer large enough
+    buf.resize(len + 1, boost::container::default_init);
+    vsnprintf(buf.data(), buf.size(), fmt, ap);
+  }
+
+  auto e = get_xml_name(name);
+
+  print_spaces();
+  if (ns) {
+    m_ss << "<" << e << " xmlns=\"" << ns << "\">" << xml_stream_escaper(std::string_view(buf.data(), len)) << "</" << e << ">";
+  } else {
+    m_ss << "<" << e << ">" << xml_stream_escaper(std::string_view(buf.data(), len)) << "</" << e << ">";
+  }
+
+  if (m_pretty)
+    m_ss << "\n";
+}
+
+int XMLFormatter::get_len() const
+{
+  return m_ss.str().size();
+}
+
+void XMLFormatter::write_raw_data(const char *data)
+{
+  m_ss << data;
+}
+
+void XMLFormatter::write_bin_data(const char* buff, int buf_len)
+{
+  std::stringbuf *pbuf = m_ss.rdbuf();
+  pbuf->sputn(buff, buf_len);
+  m_ss.seekg(buf_len);
+}
+
+void XMLFormatter::get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str) const
+{
+  CachedStackStringStream css;
+
+  for (const auto &p : attrs->attrs) {
+    *css << " " << p.first << "=" << "\"" << p.second << "\"";
+  }
+
+  attrs_str = css->strv();
+}
+
+void XMLFormatter::open_section_in_ns(std::string_view name, const char *ns, const FormatterAttrs *attrs)
+{
+  print_spaces();
+  std::string attrs_str;
+
+  if (attrs) {
+    get_attrs_str(attrs, attrs_str);
+  }
+
+  auto e = get_xml_name(name);
+
+  if (ns) {
+    m_ss << "<" << e << attrs_str << " xmlns=\"" << ns << "\">";
+  } else {
+    m_ss << "<" << e << attrs_str << ">";
+  }
+  if (m_pretty)
+    m_ss << "\n";
+  m_sections.push_back(std::string(name));
+}
+
+void XMLFormatter::finish_pending_string()
+{
+  if (!m_pending_string_name.empty()) {
+    m_ss << xml_stream_escaper(m_pending_string.str())
+      << "</" << m_pending_string_name << ">";
+    m_pending_string_name.clear();
+    m_pending_string.str(std::string());
+    if (m_pretty) {
+      m_ss << "\n";
+    }
+  }
+}
+
+void XMLFormatter::print_spaces()
+{
+  finish_pending_string();
+  if (m_pretty) {
+    std::string spaces(m_sections.size(), ' ');
+    m_ss << spaces;
+  }
+}
+
+char XMLFormatter::to_lower_underscore(char c) const
+{
+  if (m_underscored && c == ' ') {
+      return '_';
+  } else if (m_lowercased) {
+    return std::tolower(c);
+  }
+  return c;
+}
+
+}
diff --git a/src/common/XMLFormatter.h b/src/common/XMLFormatter.h
new file mode 100644 (file)
index 0000000..7beb5c1
--- /dev/null
@@ -0,0 +1,68 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#pragma once
+
+#include "common/Formatter.h"
+
+#include <deque>
+#include <sstream>
+
+namespace ceph {
+
+  class XMLFormatter : public Formatter {
+  public:
+    static const char *XML_1_DTD;
+    XMLFormatter(bool pretty = false, bool lowercased = false, bool underscored = true);
+
+    void set_status(int status, const char* status_name) override {}
+    void output_header() override;
+    void output_footer() override;
+
+    void enable_line_break() override { m_line_break_enabled = true; }
+    void flush(std::ostream& os) override;
+    using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
+    void reset() override;
+    void open_array_section(std::string_view name) override;
+    void open_array_section_in_ns(std::string_view name, const char *ns) override;
+    void open_object_section(std::string_view name) override;
+    void open_object_section_in_ns(std::string_view name, const char *ns) override;
+    void close_section() override;
+    void dump_null(std::string_view name) override;
+    void dump_unsigned(std::string_view name, uint64_t u) override;
+    void dump_int(std::string_view name, int64_t s) override;
+    void dump_float(std::string_view name, double d) override;
+    void dump_string(std::string_view name, std::string_view s) override;
+    std::ostream& dump_stream(std::string_view name) override;
+    void dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
+    int get_len() const override;
+    void write_raw_data(const char *data) override;
+    void write_bin_data(const char* buff, int len) override;
+
+    /* with attrs */
+    void open_array_section_with_attrs(std::string_view name, const FormatterAttrs& attrs) override;
+    void open_object_section_with_attrs(std::string_view name, const FormatterAttrs& attrs) override;
+    void dump_string_with_attrs(std::string_view name, std::string_view s, const FormatterAttrs& attrs) override;
+
+  protected:
+    void open_section_in_ns(std::string_view name, const char *ns, const FormatterAttrs *attrs);
+    void finish_pending_string();
+    void print_spaces();
+    void get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str) const;
+    char to_lower_underscore(char c) const;
+    std::string get_xml_name(std::string_view name) const;
+
+    std::stringstream m_ss, m_pending_string;
+    std::deque<std::string> m_sections;
+    const bool m_pretty;
+    const bool m_lowercased;
+    const bool m_underscored;
+    std::string m_pending_string_name;
+    bool m_header_done;
+    bool m_line_break_enabled = false;
+  private:
+    template <class T>
+    void add_value(std::string_view name, T val);
+  };
+
+}
index 957f92ad4d3b626d3e9bd17a5e35ae0fe8db277e..3b5152d4edb721799daaf135a889adc96e14ca06 100644 (file)
@@ -30,6 +30,7 @@
 #include "common/admin_socket_client.h"
 #include "common/dout.h"
 #include "common/errno.h"
+#include "common/JSONFormatterFile.h"
 #include "common/safe_io.h"
 #include "common/Thread.h"
 #include "common/version.h"
index 485c91b149d9f02dc6b21bd3dc8416a7d5914db1..a2e4fba5d7cec322f91496514f42be92945d714c 100644 (file)
@@ -17,7 +17,7 @@
 
 #include "json_spirit/json_spirit.h"
 
-#include "Formatter.h"
+#include "JSONFormatter.h"
 
 
 
index 4133494039c58ce731828d905606f0e533ec8c4c..aeca72c5cde3d3cc7e768d5d7938aa17f96fb5f5 100644 (file)
@@ -79,6 +79,9 @@ add_library(crimson-common STATIC
   ${PROJECT_SOURCE_DIR}/src/common/DecayCounter.cc
   ${PROJECT_SOURCE_DIR}/src/common/HTMLFormatter.cc
   ${PROJECT_SOURCE_DIR}/src/common/Formatter.cc
+  ${PROJECT_SOURCE_DIR}/src/common/JSONFormatter.cc
+  ${PROJECT_SOURCE_DIR}/src/common/TableFormatter.cc
+  ${PROJECT_SOURCE_DIR}/src/common/XMLFormatter.cc
   ${PROJECT_SOURCE_DIR}/src/common/Graylog.cc
   ${PROJECT_SOURCE_DIR}/src/common/Journald.cc
   ${PROJECT_SOURCE_DIR}/src/common/ostream_temp.cc
index 9c3f5d6551cd606618b5a17c972bc3d38f7306b5..b7dba884c4e0e51380a33ffb939b235f89d3d8ce 100644 (file)
@@ -7,6 +7,7 @@
 #include <fmt/format.h>
 #include <fmt/ostream.h>
 
+#include "common/JSONFormatter.h"
 #include "common/safe_io.h"
 #include "os/Transaction.h"
 
index 17926425cf1ed6832d755003334cd2b8f3c26204..d4ad567448b9a3accfb031681b1a15683254ab38 100644 (file)
@@ -14,6 +14,7 @@
 #include <seastar/core/metrics.hh>
 #include <seastar/core/shared_mutex.hh>
 
+#include "common/JSONFormatter.h"
 #include "common/safe_io.h"
 #include "include/stringify.h"
 #include "os/Transaction.h"
index 1312cbcb453a62b67e3c987a48b163e66f46b56f..d00f95e7a34c9c61157916794a49c66148d3b1c1 100644 (file)
@@ -41,6 +41,7 @@
 #include <seastar/core/thread.hh>
 #include <seastar/util/defer.hh>
 
+#include "common/JSONFormatter.h"
 #include "crimson/common/config_proxy.h"
 #include "crimson/common/coroutine.h"
 #include "crimson/common/log.h"
index 1a9f43ce55f02af5de175b894096cfdeba9dc60b..b0974efdd1a574dd513593bc8bb2931c09abd83c 100644 (file)
@@ -23,7 +23,7 @@
 #include "common/Clock.h" // for ceph_clock_now()
 #include "common/BackTrace.h"
 #include "common/debug.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "common/safe_io.h"
 #include "common/version.h"
 
index fa3164d893b6faa96016a7b5f978a28ba1e613fa..6f12c4fa185b0a91c824717ae9edffab0a7090f8 100644 (file)
@@ -38,7 +38,7 @@ SQLITE_EXTENSION_INIT1
 #include "include/rados/librados.hpp"
 
 #include "common/Clock.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "common/ceph_argparse.h"
 #include "common/ceph_mutex.h"
 #include "common/common_init.h"
index c1f3960f49d498cecf9284ee84127ae1004385cb..c50874e3a025f3d2a162656450ad232e219dc8cf 100644 (file)
@@ -20,6 +20,7 @@
 #include "common/debug.h"
 #include "common/errno.h"
 #include "common/fair_mutex.h"
+#include "common/JSONFormatterFile.h"
 #include "common/likely.h"
 #include "common/Timer.h"
 #include "common/async/blocked_completion.h"
index 9c401f14aab72b327df6c61e44565cf4d6bc1a6b..98d5c8a8f517744d6e692c3afd846cafad599d9b 100644 (file)
@@ -17,7 +17,7 @@
 #include "RetryMessage.h"
 #include "SnapRealm.h"
 #include "common/debug.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "mds/MDLog.h"
 #include "mds/MDSRank.h"
 #include "mds/MDCache.h"
index 8ac3ef021048b394bdada17181861c484b08a760..b0ad9fb94326b6e05ea0c284002f7d284d796181 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "mon/MonClient.h"
 #include "common/errno.h"
+#include "common/JSONFormatter.h"
 #include "common/version.h"
 #include "mgr/Types.h"
 
index b1f9ff654d4be1b939c27f7ab5a15de5f0f0b766..a18c7fd6f4963c175c7a9615d985e7ca994d57dd 100644 (file)
@@ -12,6 +12,7 @@
  */
 
 #include "mgr/ClusterState.h"
+#include "common/JSONFormatter.h"
 #include "messages/MMgrDigest.h"
 #include "messages/MMonMgrReport.h"
 #include "messages/MPGStats.h"
index a967658e2f41034c4c59ff34aa6ae210dc795c12..85be92ea3b81cf2aa42396595ea1527da41542b1 100644 (file)
@@ -44,6 +44,7 @@
 #include "messages/MOSDScrub2.h"
 #include "messages/MOSDForceRecovery.h"
 #include "common/errno.h"
+#include "common/JSONFormatter.h"
 #include "common/pick_address.h"
 #include "common/TextTable.h"
 #include "crush/CrushWrapper.h"
index b45fbf162e0b02cd5881ddb3905b7857e84703e9..5608707c1dc28b70b931d6f5b8df5e3594b3d023 100644 (file)
@@ -27,7 +27,7 @@
 #include <memory>
 #include <list>
 
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "include/ceph_assert.h"
 
 class PyFormatter : public ceph::Formatter
index fe33555280e149d82b8194b6127f5081a856a2d2..8b0629bb9ea45976d34c44e24669dceb86d4be2a 100644 (file)
@@ -21,6 +21,7 @@
 
 #include "include/stringify.h"
 #include "common/BackTrace.h"
+#include "common/JSONFormatter.h"
 #include "global/signal_handler.h"
 
 #include "common/debug.h"
index a1f3f5051e8c951371965b194d650bb4cb05d0be..ce5938ffb56f10f8b28f4b91e115833c19e488b1 100644 (file)
@@ -37,7 +37,6 @@ using ceph::bufferlist;
 using ceph::decode;
 using ceph::encode;
 using ceph::Formatter;
-using ceph::JSONFormatter;
 using ceph::mono_clock;
 using ceph::mono_time;
 using ceph::timespan_str;
index 3a1526b4ed4edcb10b9e3eac308825f2410b6f3a..f124ce1c24adfdba3586269a9c6963b6c511c587 100644 (file)
@@ -9,7 +9,7 @@
 #include "messages/MConfig.h"
 #include "messages/MGetConfig.h"
 #include "messages/MMonCommand.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "common/TextTable.h"
 #include "common/cmdparse.h"
 #include "include/stringify.h"
index be0c35d06ac523ab67f3bd292e256d2ada374df4..0110256eca6052dc8538690751f93d6508eae52d 100644 (file)
@@ -47,7 +47,6 @@ using ceph::bufferlist;
 using ceph::decode;
 using ceph::encode;
 using ceph::Formatter;
-using ceph::JSONFormatter;
 using ceph::mono_clock;
 using ceph::mono_time;
 using ceph::timespan_str;
index 3e71a69426ee590ee6705805ff7885133be68c92..bfc854d6bdcf7e13a78ea2eae52abfa22829b5a0 100644 (file)
@@ -48,8 +48,6 @@ using std::unique_ptr;
 using ceph::bufferlist;
 using ceph::decode;
 using ceph::encode;
-using ceph::Formatter;
-using ceph::JSONFormatter;
 using ceph::mono_clock;
 using ceph::mono_time;
 using ceph::timespan_str;
index 82ddf9a899a695328eeeb9d08703e5105c2a25d7..80747195751749569344640d39fcfd6a29f8f7a8 100644 (file)
@@ -92,7 +92,6 @@ using ceph::bufferlist;
 using ceph::decode;
 using ceph::encode;
 using ceph::Formatter;
-using ceph::JSONFormatter;
 using ceph::make_message;
 using ceph::mono_clock;
 using ceph::mono_time;
index f4c66de1812884d9c57d879cfac8708d45ef980e..6f1ae0543c3550be2b4c21e5ddf9cc29a652a676 100644 (file)
@@ -24,7 +24,7 @@
 #include "kv/KeyValueDB.h"
 
 #include "include/ceph_assert.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "common/Finisher.h"
 #include "common/errno.h"
 #include "common/debug.h"
index 97c632cd7e971ff29cf648153512e26513673250..a33464f95620a6f03e6344fd1f8e6507c850e63c 100644 (file)
@@ -57,6 +57,7 @@
 #include "messages/MMonGetPurgedSnaps.h"
 #include "messages/MMonGetPurgedSnapsReply.h"
 
+#include "common/JSONFormatter.h"
 #include "common/TextTable.h"
 #include "common/Timer.h"
 #include "common/ceph_argparse.h"
index d9b6fd228d8b9687f1c7c592db27113ac00d785e..a705069db86841241ebb848227b7fcf655a5ce59 100644 (file)
@@ -114,6 +114,7 @@ e 12v
 #include "include/buffer.h"
 #include "msg/msg_types.h"
 #include "include/Context.h"
+#include "common/JSONFormatter.h"
 #include "common/perf_counters.h"
 #include <errno.h>
 
index de08397128739103f13e5273ee1ee480e5922b4d..6247f372627bf0643696d7c942183105d0e8c3ff 100644 (file)
@@ -10,6 +10,7 @@
 #include "common/Clock.h" // for ceph_clock_now()
 #include "common/debug.h"
 #include "common/errno.h"
+#include "common/JSONFormatter.h"
 #include "common/perf_counters.h"
 #include "Allocator.h"
 #include "include/buffer_fwd.h"
index 8533d6761190454e9c353bed030211938eb2dd72..4d4b2acc635c1c199c27ce4af8c3d7e5288d6b6e 100644 (file)
@@ -42,6 +42,7 @@
 #include "include/util.h"
 #include "common/debug.h"
 #include "common/errno.h"
+#include "common/JSONFormatter.h"
 #include "common/safe_io.h"
 #include "common/PriorityCache.h"
 #include "common/url_escape.h"
index ad1f8d30841df94b6df152c3570829f09da47e7a..14f94494cce1b457d3b39cb01fe8dedfc008043e 100644 (file)
@@ -16,6 +16,7 @@
 #include "common/ceph_argparse.h"
 #include "include/stringify.h"
 #include "common/errno.h"
+#include "common/JSONFormatter.h"
 #include "common/safe_io.h"
 
 #include "os/bluestore/BlueFS.h"
index 12cf6f6aef5f33d4100916396239a9eb7436712a..2fd1c0b19a1cdceb7dcefcc4004ec6b906128e4f 100644 (file)
@@ -31,7 +31,7 @@
 #include "common/debug.h"
 #include "common/errno.h"
 #include "common/safe_io.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "common/pretty_binary.h"
 
 #include <shared_mutex> // for std::shared_lock
index f1278a0f025b0058eee1cd57b1b94e3a8cb34802..bdcde2cf348acc387c50351376f13fbeeef143ed 100644 (file)
@@ -25,6 +25,7 @@
 #include "include/stringify.h"
 #include "common/debug.h"
 #include "common/errno.h"
+#include "common/JSONFormatter.h"
 #include "MemStore.h"
 #include "include/compat.h"
 
index fc380d6ba8903cfdc1839ccd2c03f2bf35224a81..143f007ab9c591553970704382b6fec72f3e01a3 100644 (file)
@@ -42,7 +42,7 @@ extern "C" {
 }
 
 #include "common/ceph_context.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "common/StackStringStream.h"
 #include "include/utime_fmt.h"
 #include "OSDMap.h"
index 8e7bd0c1917e9a900c1e06e7fbfafea0e8173047..a0f83a6c7b7628343e20965f43783337b88a55e7 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "Replayer.hpp"
 #include "common/errno.h"
+#include "common/JSONFormatter.h"
 #include "include/scope_guard.h"
 #include "rbd_replay/ActionTypes.h"
 #include "rbd_replay/BufferReader.h"
index 89e48315863838540ac29cda9043c369defdf600..3b5dd8bd789056f180e55710445a04254352f6ad 100644 (file)
@@ -17,7 +17,7 @@
 
 #include <boost/shared_ptr.hpp>
 #include "include/rbd/librbd.hpp"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "rbd_replay/ActionTypes.h"
 #include "rbd_loc.hpp"
 #include <iostream>
index 2fd6535827ba65b4340f3692d498e170785b4b95..209be5d0803f8a819fdc17b873ba4fbd3e33813b 100644 (file)
@@ -2,6 +2,7 @@
 // vim: ts=8 sw=2 smarttab ft=cpp
 
 #include "common/Clock.h" // for ceph_clock_now()
+#include "common/JSONFormatter.h"
 #include "include/function2.hpp"
 #include "rgw_acl_s3.h"
 #include "rgw_tag_s3.h"
index 440ecf3d21dfe812008f9be2d9caebef3fde4f12..4c3eb7c1fc719887f04e1e4106cbc2e703572c14 100644 (file)
@@ -5,7 +5,7 @@
 #include <iostream>
 #include <map>
 
-#include "common/Formatter.h"
+#include "common/XMLFormatter.h"
 #include <common/errno.h>
 #include "rgw_lc.h"
 #include "rgw_lc_tier.h"
index 159e2b876df55ec6eb544bfed8a9dfa84f514b1c..91526f8d76f356a939f8aa561c8530171075947f 100644 (file)
@@ -9,6 +9,7 @@
 #include <curl/curl.h>
 #include "common/Formatter.h"
 #include "common/iso_8601.h"
+#include "common/JSONFormatter.h"
 #include "common/async/completion.h"
 #include "common/async/yield_waiter.h"
 #include "common/async/waiter.h"
index fa14d056f16821e67839739af73769d0b4d70e1e..a565a2fced7629c03bb92fd075a56b677a82965d 100644 (file)
@@ -2,6 +2,8 @@
 // vim: ts=8 sw=2 smarttab ft=cpp
 
 #include "common/errno.h"
+#include "common/JSONFormatter.h"
+#include "common/XMLFormatter.h"
 
 #include "rgw_common.h"
 #include "rgw_coroutine.h"
index b346835938d6f0ae3fa09bf2e0a10411a04e8424..343c4a689100f39969468e8ce3766cbc34c0faa3 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "common/debug.h"
 #include "common/ceph_json.h"
+#include "common/JSONFormatter.h"
 
 #include "rgw_sync_trace.h"
 #include "rgw_rados.h"
index 4f4bb112063e3be6a3dd9e70c193e2b1a70f4435..7306c60edd82c6068598e2da6c175399c3e66c8d 100644 (file)
@@ -29,7 +29,8 @@ extern "C" {
 #include "common/ceph_json.h"
 #include "common/config.h"
 #include "common/ceph_argparse.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
+#include "common/XMLFormatter.h"
 #include "common/errno.h"
 #include "common/safe_io.h"
 #include "common/fault_injector.h"
index ba68487e2758311ee260558a8a317b2a4577f671..f85a225e1c7ddf2c0243fa415bc09deb916599e4 100644 (file)
@@ -19,6 +19,7 @@
 #include <iostream>
 #include <map>
 
+#include "common/XMLFormatter.h"
 #include "include/types.h"
 
 #include "rgw_cors_s3.h"
index 8d92a3c5fd34bc0466963a50bfc45276d1fcef27..8cbad45303977b2e8733bc98127acf733fa78074 100644 (file)
@@ -20,7 +20,7 @@
 #include <iosfwd>
 
 #include <include/types.h>
-#include <common/Formatter.h>
+#include <common/XMLFormatter.h>
 #include <common/dout.h>
 #include "rgw_xml.h"
 #include "rgw_cors.h"
index a252ef7375696dc4064173a962b87238734aa4ec..a49ad3f330ba024ee66d7a886ee3c91615518d38 100644 (file)
@@ -16,7 +16,7 @@
 #include <boost/format.hpp>
 
 #include "common/escape.h"
-#include "common/Formatter.h"
+#include "common/XMLFormatter.h"
 #include "rgw/rgw_common.h"
 #include "rgw/rgw_formats.h"
 #include "rgw/rgw_rest.h"
index 75f83ea95afdb7210dfcabb054f6474e5e41c97e..815e7e35541b3828cae1c1909458b4e94dc116c5 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "common/dout.h"
 #include "include/scope_guard.h"
+#include "common/XMLFormatter.h"
 #include "common/Clock.h"
 #include "common/armor.h"
 #include "common/async/spawn_throttle.h"
index 4a6a2e6c576657f14a17d1ac8bdc64e7892d1c26..d03e4a3a9422fc106e25d604a0422ba7494b1d0c 100644 (file)
@@ -8,8 +8,8 @@
 #include <boost/algorithm/string.hpp>
 #include <boost/tokenizer.hpp>
 #include "ceph_ver.h"
-#include "common/Formatter.h"
 #include "common/HTMLFormatter.h"
+#include "common/XMLFormatter.h"
 #include "common/utf8.h"
 #include "include/str_list.h"
 #include "rgw_common.h"
index dea29f96f1136f22f18748b91d893e0fdfcb3df6..db23e245ea81d575d8e32aead7b2e9c12d5fcacc 100644 (file)
@@ -17,6 +17,7 @@
 #include "common/admin_socket.h"
 #include "common/admin_socket_client.h"
 #include "common/ceph_argparse.h"
+#include "common/JSONFormatter.h"
 #include "json_spirit/json_spirit.h"
 #include "gtest/gtest.h"
 #include "fmt/format.h"
index d0ddd262c0a1ab655cfb18bc335ae0b140097341..e67f829065986f2bb6439b44f0be6a1bd61c436f 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "common/ceph_json.h"
 #include "common/Clock.h"
+#include "common/JSONFormatter.h"
 #include "common/StackStringStream.h"
 
 #include <sstream>
index 90de133d315550e00d2c2bf1fbe6934f99df11db..2ab1a930bb4b5f58c72f3d5050278d42d4640a04 100644 (file)
@@ -1,6 +1,6 @@
 #include "gtest/gtest.h"
 
-#include "common/Formatter.h"
+#include "common/TableFormatter.h"
 #include <iostream>
 #include <sstream>
 #include <string>
index abbe9e4e25e94be3173c05f8f95639e153b4b963..fbe87966e8d9f8005aab529afd21f94054e16329 100644 (file)
@@ -1,6 +1,6 @@
 #include "gtest/gtest.h"
 
-#include "common/Formatter.h"
+#include "common/XMLFormatter.h"
 #include <sstream>
 #include <string>
 
index 85806a1799de3a16c3441f92eaa10b07f65b0230..02512d0ba239ba3a69e20d960809eed033f0957b 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "common/ceph_argparse.h"
 #include "common/common_init.h"
+#include "common/JSONFormatter.h"
 #include "include/stringify.h"
 
 #include "crush/CrushWrapper.h"
index 1e78a18a006cbb19b72b2aeca515207fd90a2531..cb9b1a3f8b4144c12b70b3b72b2d0b41dc1d50ea 100644 (file)
@@ -13,8 +13,9 @@
  */
 
 #include "gtest/gtest.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "common/HTMLFormatter.h"
+#include "common/XMLFormatter.h"
 
 #include <sstream>
 #include <string>
index e337716a0173557c9bc6b20070a66b9b6db5c798..a22d35cd90adc3ec62370205cebb9ebd36f4d872 100644 (file)
@@ -20,6 +20,7 @@
 #include "include/stringify.h"
 #include "common/ceph_context.h"
 #include "common/config_proxy.h"
+#include "common/JSONFormatter.h"
 #include "json_spirit/json_spirit.h"
 #include "boost/format/alt_sstream.hpp"
 #include <errno.h>
index 6d88f0da9afd4b1f40af1c010dbccc50ab4d06f4..da66955251c1245f7d8511d35aef171e89455326 100644 (file)
@@ -2,6 +2,7 @@
 #include "include/rados/librados.hpp"
 #include "include/stringify.h"
 #include "common/config_proxy.h"
+#include "common/JSONFormatter.h"
 #include "test/librados/test.h"
 #include "test/librados/TestCase.h"
 #ifndef _WIN32
index e6e6c21bdf1dd2b48df11daae62d2292cfa21d37..4c34a9fa65762ccd668c91a180efe6a43bcf5d03 100644 (file)
@@ -1,7 +1,7 @@
 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
 // vim: ts=8 sw=2 smarttab
 
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "include/ceph_assert.h"
 #include "include/stringify.h"
 #include "json_spirit/json_spirit.h"
index a8c01cda8f2340b47ea86e775b2b831351a17443..22e1845b06c527cb61c5da003f54da76dcede732 100644 (file)
@@ -48,6 +48,7 @@
 #include "common/debug.h"
 #include "common/errno.h"
 #include "common/ceph_mutex.h"
+#include "common/JSONFormatter.h"
 #include "common/strtol.h"
 #include "common/LogEntry.h"
 #include "auth/KeyRing.h"
index eb101fd803745c7b48747516ed185cadf614f168..9248c14862d620a284b0f1e0dac7031bb3d535b6 100644 (file)
@@ -41,6 +41,7 @@
 #include "common/Cond.h"
 #include "common/debug.h"
 #include "common/errno.h"
+#include "common/JSONFormatter.h"
 #include "common/options.h" // for the size literals
 #include "common/pretty_binary.h"
 #include "include/stringify.h"
index a31be59a3c8850abe9c458e637a530e2a22d55e2..e7bb3c0328a63d9fa26b96c6b3827c5962672d79 100644 (file)
@@ -2,6 +2,8 @@
 // vim: ts=8 sw=2 smarttab
 
 #include "rgw_xml.h"
+#include "common/XMLFormatter.h"
+
 #include <gtest/gtest.h>
 #include <list>
 #include <stdexcept>
index cde8d293fdf4717eac2b09dd16d35127a43f4200..71a874270825f9377571360def52b8814feb076c 100644 (file)
@@ -20,6 +20,7 @@
 
 #include "global/global_init.h"
 #include "common/ceph_argparse.h"
+#include "common/TableFormatter.h"
 #include "global/global_context.h"
 #include "gtest/gtest.h"
 #include "include/btree_map.h"
index 229162e3bf37c44ab307e1d5efb90b3c6aab9204..87d8be497f3b5eb87dc2f51de635e158c4267fb8 100644 (file)
@@ -15,7 +15,7 @@
 
 #include "common/ceph_argparse.h"
 #include "global/global_init.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "common/debug.h"
 #include "common/errno.h"
 #include "client/Inode.h"
index a7273622a29e501e9acc3be9ccfb62a708f5c173..1cd16b0238c91ad419ac7f8f94aae0d74ca7a126 100644 (file)
@@ -20,7 +20,7 @@
 
 #include "ceph_ver.h"
 #include "include/types.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "common/ceph_argparse.h"
 #include "common/errno.h"
 #include "denc_plugin.h"
index 8c6c9c7233b24f64b5a926e43eaee36d4746671f..5bb0ece595ecc8d947156f7d047fa35659289999 100644 (file)
@@ -23,6 +23,7 @@
 #include "auth/KeyRing.h"
 #include "auth/cephx/CephxKeyServer.h"
 #include "global/global_init.h"
+#include "common/JSONFormatter.h"
 #include "include/scope_guard.h"
 #include "include/stringify.h"
 #include "mgr/mgr_commands.h"
index 8cb235a82f987a94238a4cd0d58ea5903f95d7a4..bce2f524111c93db1a5c1a0d71fe892457d028dc 100644 (file)
@@ -16,6 +16,7 @@
 #include <fstream>
 
 #include "common/errno.h"
+#include "common/JSONFormatter.h"
 #include "mds/mdstypes.h"
 #include "mds/events/EUpdate.h"
 #include "mds/LogEvent.h"
index 0c970bd7bae2abdbab10024ce2ef30c56f767f80..d93f74b68cd25b95c717bb16caf9eb263be52745 100644 (file)
@@ -17,6 +17,7 @@
 #include "common/ceph_argparse.h"
 #include "common/debug.h"
 #include "common/errno.h"
+#include "common/JSONFormatter.h"
 #include "osdc/Journaler.h"
 #include "mds/mdstypes.h"
 #include "mds/LogEvent.h"
index c07828f364e9d939d8364c21478e97ab0407b997..70f7e24296b552f88a485a9deb27fd0579c4cac2 100644 (file)
@@ -15,6 +15,7 @@
 #include "common/ceph_argparse.h"
 #include "common/debug.h"
 #include "common/errno.h"
+#include "common/JSONFormatter.h"
 
 #include "mds/SessionMap.h"
 #include "mds/InoTable.h"
index 7d8227f88457823960705ef286fdd25a5266a7fe..e3489cdba53ed4fcbb755f1cb68ba661b8395eb3 100644 (file)
@@ -4,6 +4,7 @@
 #include "ServiceDaemon.h"
 #include "common/debug.h"
 #include "common/errno.h"
+#include "common/JSONFormatter.h"
 #include "common/Timer.h"
 #include "include/Context.h"
 #include "include/stringify.h"
index be75a326c825b812386ed1de84735f0639f7346e..f3ae27e868350ae189eac1371a6a200e23ffdf7f 100644 (file)
@@ -17,6 +17,7 @@
 
 #include "common/ceph_argparse.h"
 #include "common/errno.h"
+#include "common/JSONFormatter.h"
 #include "common/safe_io.h"
 #include "common/strtol.h" // for strict_strtoll()
 #include "crush/CrushWrapper.h"
index 849b958152c17bdb7a31ad8146d9cd6f6f68169a..647a740e3b6d1361c2d90b77a5c972ea932f68bb 100644 (file)
@@ -31,7 +31,7 @@
 #include "common/Cond.h"
 #include "common/debug.h"
 #include "common/errno.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "common/obj_bencher.h"
 #include "common/strtol.h" // for strict_strtoll()
 #include "common/TextTable.h"
index 7d60a95ca4be49e44ad383304801bd3adfab3756..d7be40342e52cbd1531fa42f5010cd6aedaca879 100644 (file)
@@ -7,7 +7,8 @@
 #include "include/rbd/features.h"
 #include "common/config_proxy.h"
 #include "common/strtol.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
+#include "common/XMLFormatter.h"
 #include "global/global_context.h"
 #include <iostream>
 #include <boost/tokenizer.hpp>
index a7069ab668736d61087fda7a85fde8f118768f5a..44843e7600ad6f2a4d1f29955fb31b0cfe0a8cd9 100644 (file)
@@ -5,7 +5,7 @@
 #include "tools/rbd/Shell.h"
 #include "tools/rbd/Utils.h"
 #include "common/Cond.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "common/ceph_json.h"
 #include "common/errno.h"
 #include "common/safe_io.h"
index 0942f5689eaae2218cf074f53ccf54c4cbbefb4b..705cb152f436a6a9be7f0f9ab772881bd90306ef 100644 (file)
@@ -17,7 +17,8 @@
 #include <boost/algorithm/string/predicate.hpp>
 #include <regex>
 
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
+#include "common/XMLFormatter.h"
 #include "common/Preforker.h"
 #include "common/TextTable.h"
 #include "common/ceph_argparse.h"
index 203be5f613412d91ac5fa0395b427638f654022b..bdfb576eb56d62b462b37c49912a369c6b226884 100644 (file)
@@ -8,7 +8,7 @@
 #include "common/config.h"
 #include "common/debug.h"
 #include "common/errno.h"
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
 #include "common/Timer.h"
 #include "tools/rbd_mirror/Threads.h"
 #include <sstream>
index 68c6f5455917ad1ec0dfe7972fc50f58fa006d70..e3ae6cce55fb6973a2d496ed5e805aa47e8f81e8 100644 (file)
@@ -52,7 +52,8 @@
 #include <boost/algorithm/string/predicate.hpp>
 #include <boost/lexical_cast.hpp>
 
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
+#include "common/XMLFormatter.h"
 #include "common/Preforker.h"
 #include "common/SubProcess.h"
 #include "common/TextTable.h"
index 2ebf2c04b24e8a556bd75e95faee4dcdbdce3454..a0802895aa3270e3eb3245341191214f755c4927 100644 (file)
@@ -35,7 +35,8 @@
 #include <memory>
 #include <regex>
 
-#include "common/Formatter.h"
+#include "common/JSONFormatter.h"
+#include "common/XMLFormatter.h"
 #include "common/TextTable.h"
 #include "common/ceph_argparse.h"
 #include "common/config.h"