]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
formatter: add the ability to dump attrs in xml entities
authorYehuda Sadeh <yehuda@inktank.com>
Fri, 22 Feb 2013 23:02:02 +0000 (15:02 -0800)
committerYehuda Sadeh <yehuda@inktank.com>
Fri, 8 Mar 2013 17:03:10 +0000 (09:03 -0800)
xml entities may have attrs assigned to them. Add the ability
to set them. A usage example:

formatter->open_array_section_with_attrs("container",
     FormatterAttrs("name", "foo", NULL));

This will generate the following xml entity:
<container name="foo">

Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
Reviewed-by: Greg Farnum <greg@inktank.com>
(cherry picked from commit 7cb6ee28073824591d8132a87ea09a11c44efd66)

Conflicts:
src/common/Formatter.cc

src/common/Formatter.cc
src/common/Formatter.h

index 305aa3bc466e7e1b354a86b16c769485a6295acb..4fbccecc2d9d7c5eaafd782d5709b47a6309b9af 100644 (file)
 // -----------------------
 namespace ceph {
 
+/*
+ * FormatterAttrs(const char *attr, ...)
+ *
+ * Requires a list of of attrs followed by NULL. The attrs should be char *
+ * pairs, first one is the name, second one is the value. E.g.,
+ *
+ * FormatterAttrs("name1", "value1", "name2", "value2", NULL);
+ */
+FormatterAttrs::FormatterAttrs(const char *attr, ...)
+{
+  const char *s = attr;
+  va_list ap;
+  va_start(ap, attr);
+  do {
+    const char *val = va_arg(ap, char *);
+    if (!val)
+      break;
+
+    attrs.push_back(make_pair(std::string(s), std::string(val)));
+    s = va_arg(ap, char *);
+  } while (s);
+  va_end(ap);
+}
+
 Formatter::Formatter()
 {
 }
@@ -251,22 +275,32 @@ void XMLFormatter::reset()
 
 void XMLFormatter::open_object_section(const char *name)
 {
-  open_section_in_ns(name, NULL);
+  open_section_in_ns(name, NULL, NULL);
+}
+
+void XMLFormatter::open_object_section_with_attrs(const char *name, const FormatterAttrs& attrs)
+{
+  open_section_in_ns(name, NULL, &attrs);
 }
 
 void XMLFormatter::open_object_section_in_ns(const char *name, const char *ns)
 {
-  open_section_in_ns(name, ns);
+  open_section_in_ns(name, ns, NULL);
 }
 
 void XMLFormatter::open_array_section(const char *name)
 {
-  open_section_in_ns(name, NULL);
+  open_section_in_ns(name, NULL, NULL);
+}
+
+void XMLFormatter::open_array_section_with_attrs(const char *name, const FormatterAttrs& attrs)
+{
+  open_section_in_ns(name, NULL, &attrs);
 }
 
 void XMLFormatter::open_array_section_in_ns(const char *name, const char *ns)
 {
-  open_section_in_ns(name, ns);
+  open_section_in_ns(name, ns, NULL);
 }
 
 void XMLFormatter::close_section()
@@ -315,6 +349,17 @@ void XMLFormatter::dump_string(const char *name, std::string s)
     m_ss << "\n";
 }
 
+void XMLFormatter::dump_string_with_attrs(const char *name, std::string s, const FormatterAttrs& attrs)
+{
+  std::string e(name);
+  std::string attrs_str;
+  get_attrs_str(&attrs, attrs_str);
+  print_spaces(true);
+  m_ss << "<" << e << attrs_str << ">" << escape_xml_str(s.c_str()) << "</" << e << ">";
+  if (m_pretty)
+    m_ss << "\n";
+}
+
 std::ostream& XMLFormatter::dump_stream(const char *name)
 {
   assert(m_pending_string_name.empty());
@@ -348,14 +393,33 @@ void XMLFormatter::write_raw_data(const char *data)
   m_ss << data;
 }
 
-void XMLFormatter::open_section_in_ns(const char *name, const char *ns)
+void XMLFormatter::get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str)
+{
+  std::stringstream attrs_ss;
+
+  for (std::list<std::pair<std::string, std::string> >::const_iterator iter = attrs->attrs.begin();
+       iter != attrs->attrs.end(); ++iter) {
+    std::pair<std::string, std::string> p = *iter;
+    attrs_ss << " " << p.first << "=" << "\"" << p.second << "\"";
+  }
+
+  attrs_str = attrs_ss.str();
+}
+
+void XMLFormatter::open_section_in_ns(const char *name, const char *ns, const FormatterAttrs *attrs)
 {
   print_spaces(false);
+  std::string attrs_str;
+
+  if (attrs) {
+    get_attrs_str(attrs, attrs_str);
+  }
+
   if (ns) {
-    m_ss << "<" << name << " xmlns=\"" << ns << "\">";
+    m_ss << "<" << name << attrs_str << " xmlns=\"" << ns << "\">";
   }
   else {
-    m_ss << "<" << name << ">";
+    m_ss << "<" << name << attrs_str << ">";
   }
   m_sections.push_back(name);
 }
index 5c6bb573d23d4a1dfedce3161889052367a457a8..74c5efa2c82c6fd7de6fae493be004b41745144b 100644 (file)
@@ -9,9 +9,17 @@
 #include <sstream>
 #include <stdarg.h>
 #include <string>
+#include <list>
 
 namespace ceph {
 
+
+struct FormatterAttrs {
+  std::list< std::pair<std::string, std::string> > attrs;
+
+  FormatterAttrs(const char *attr, ...);
+};
+
 class Formatter {
  public:
   Formatter();
@@ -33,6 +41,17 @@ class Formatter {
   virtual void dump_format(const char *name, const char *fmt, ...) = 0;
   virtual int get_len() const = 0;
   virtual void write_raw_data(const char *data) = 0;
+
+  /* with attrs */
+  virtual void open_array_section_with_attrs(const char *name, const FormatterAttrs& attrs) {
+    open_array_section(name);
+  }
+  virtual void open_object_section_with_attrs(const char *name, const FormatterAttrs& attrs) {
+    open_object_section(name);
+  }
+  virtual void dump_string_with_attrs(const char *name, std::string s, const FormatterAttrs& attrs) {
+    dump_string(name, s);
+  }
 };
 
 
@@ -42,7 +61,7 @@ class JSONFormatter : public Formatter {
 
   void flush(std::ostream& os);
   void reset();
-  void open_array_section(const char *name);
+  virtual void open_array_section(const char *name);
   void open_array_section_in_ns(const char *name, const char *ns);
   void open_object_section(const char *name);
   void open_object_section_in_ns(const char *name, const char *ns);
@@ -96,11 +115,16 @@ class XMLFormatter : public Formatter {
   int get_len() const;
   void write_raw_data(const char *data);
 
+  /* with attrs */
+  void open_array_section_with_attrs(const char *name, const FormatterAttrs& attrs);
+  void open_object_section_with_attrs(const char *name, const FormatterAttrs& attrs);
+  void dump_string_with_attrs(const char *name, std::string s, const FormatterAttrs& attrs);
  private:
-  void open_section_in_ns(const char *name, const char *ns);
+  void open_section_in_ns(const char *name, const char *ns, const FormatterAttrs *attrs);
   void finish_pending_string();
   void print_spaces(bool extra_space);
   static std::string escape_xml_str(const char *str);
+  void get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str);
 
   std::stringstream m_ss, m_pending_string;
   std::deque<std::string> m_sections;