From: Yehuda Sadeh Date: Fri, 22 Feb 2013 23:02:02 +0000 (-0800) Subject: formatter: add the ability to dump attrs in xml entities X-Git-Tag: v0.56.4~48 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=e39660c901756d5e722308e72a9d8ee4893f70f7;p=ceph.git formatter: add the ability to dump attrs in xml entities 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: Signed-off-by: Yehuda Sadeh Reviewed-by: Greg Farnum (cherry picked from commit 7cb6ee28073824591d8132a87ea09a11c44efd66) Conflicts: src/common/Formatter.cc --- diff --git a/src/common/Formatter.cc b/src/common/Formatter.cc index 305aa3bc466e7..4fbccecc2d9d7 100644 --- a/src/common/Formatter.cc +++ b/src/common/Formatter.cc @@ -29,6 +29,30 @@ // ----------------------- 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()) << ""; + 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 >::const_iterator iter = attrs->attrs.begin(); + iter != attrs->attrs.end(); ++iter) { + std::pair 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); } diff --git a/src/common/Formatter.h b/src/common/Formatter.h index 5c6bb573d23d4..74c5efa2c82c6 100644 --- a/src/common/Formatter.h +++ b/src/common/Formatter.h @@ -9,9 +9,17 @@ #include #include #include +#include namespace ceph { + +struct FormatterAttrs { + std::list< std::pair > 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 m_sections;