diff options
author | Yehuda Sadeh <yehuda@inktank.com> | 2013-02-22 15:02:02 -0800 |
---|---|---|
committer | Yehuda Sadeh <yehuda@inktank.com> | 2013-03-08 08:31:37 -0800 |
commit | 7cb6ee28073824591d8132a87ea09a11c44efd66 (patch) | |
tree | b62c978f159c2ecf9eaf1a9c4510ed95c810c837 | |
parent | 6669e73fa50e3908ec825ee030c31a6dbede6ac0 (diff) | |
download | ceph-7cb6ee28073824591d8132a87ea09a11c44efd66.tar.gz |
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:
<container name="foo">
Signed-off-by: Yehuda Sadeh <yehuda@inktank.com>
Reviewed-by: Greg Farnum <greg@inktank.com>
-rw-r--r-- | src/common/Formatter.cc | 78 | ||||
-rw-r--r-- | src/common/Formatter.h | 28 |
2 files changed, 97 insertions, 9 deletions
diff --git a/src/common/Formatter.cc b/src/common/Formatter.cc index d08cd3e5dcb..3efca59214d 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() @@ -318,6 +352,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(); + 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()); @@ -352,14 +397,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(); + 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 << ">"; } if (m_pretty) m_ss << "\n"; diff --git a/src/common/Formatter.h b/src/common/Formatter.h index fccb26a226b..0f9a94a86ad 100644 --- a/src/common/Formatter.h +++ b/src/common/Formatter.h @@ -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(); 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; |