]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | #ifndef CEPH_FORMATTER_H | |
4 | #define CEPH_FORMATTER_H | |
5 | ||
6 | #include "include/int_types.h" | |
31f18b77 | 7 | #include "include/buffer_fwd.h" |
7c673cae FG |
8 | |
9 | #include <deque> | |
7c673cae FG |
10 | #include <list> |
11 | #include <vector> | |
12 | #include <stdarg.h> | |
7c673cae | 13 | #include <sstream> |
7c673cae FG |
14 | #include <map> |
15 | ||
7c673cae FG |
16 | namespace ceph { |
17 | ||
18 | struct FormatterAttrs { | |
19 | std::list< std::pair<std::string, std::string> > attrs; | |
20 | ||
21 | FormatterAttrs(const char *attr, ...); | |
22 | }; | |
23 | ||
24 | class Formatter { | |
25 | public: | |
26 | static Formatter *create(const std::string& type, | |
27 | const std::string& default_type, | |
28 | const std::string& fallback); | |
29 | static Formatter *create(const std::string& type, | |
30 | const std::string& default_type) { | |
31 | return create(type, default_type, ""); | |
32 | } | |
33 | static Formatter *create(const std::string& type) { | |
34 | return create(type, "json-pretty", ""); | |
35 | } | |
36 | ||
37 | Formatter(); | |
38 | virtual ~Formatter(); | |
39 | ||
40 | virtual void flush(std::ostream& os) = 0; | |
41 | void flush(bufferlist &bl); | |
42 | virtual void reset() = 0; | |
43 | ||
44 | virtual void set_status(int status, const char* status_name) = 0; | |
45 | virtual void output_header() = 0; | |
46 | virtual void output_footer() = 0; | |
47 | ||
48 | virtual void open_array_section(const char *name) = 0; | |
49 | virtual void open_array_section_in_ns(const char *name, const char *ns) = 0; | |
50 | virtual void open_object_section(const char *name) = 0; | |
51 | virtual void open_object_section_in_ns(const char *name, const char *ns) = 0; | |
52 | virtual void close_section() = 0; | |
53 | virtual void dump_unsigned(const char *name, uint64_t u) = 0; | |
54 | virtual void dump_int(const char *name, int64_t s) = 0; | |
55 | virtual void dump_float(const char *name, double d) = 0; | |
56 | virtual void dump_string(const char *name, const std::string& s) = 0; | |
57 | virtual void dump_bool(const char *name, bool b) | |
58 | { | |
59 | dump_format_unquoted(name, "%s", (b ? "true" : "false")); | |
60 | } | |
61 | template<typename T> | |
62 | void dump_object(const char *name, const T& foo) { | |
63 | open_object_section(name); | |
64 | foo.dump(this); | |
65 | close_section(); | |
66 | } | |
67 | virtual std::ostream& dump_stream(const char *name) = 0; | |
68 | virtual void dump_format_va(const char *name, const char *ns, bool quoted, const char *fmt, va_list ap) = 0; | |
69 | virtual void dump_format(const char *name, const char *fmt, ...); | |
70 | virtual void dump_format_ns(const char *name, const char *ns, const char *fmt, ...); | |
71 | virtual void dump_format_unquoted(const char *name, const char *fmt, ...); | |
72 | virtual int get_len() const = 0; | |
73 | virtual void write_raw_data(const char *data) = 0; | |
74 | /* with attrs */ | |
75 | virtual void open_array_section_with_attrs(const char *name, const FormatterAttrs& attrs) | |
76 | { | |
77 | open_array_section(name); | |
78 | } | |
79 | virtual void open_object_section_with_attrs(const char *name, const FormatterAttrs& attrs) | |
80 | { | |
81 | open_object_section(name); | |
82 | } | |
83 | virtual void dump_string_with_attrs(const char *name, const std::string& s, const FormatterAttrs& attrs) | |
84 | { | |
85 | dump_string(name, s); | |
86 | } | |
87 | }; | |
88 | ||
89 | class JSONFormatter : public Formatter { | |
90 | public: | |
91 | explicit JSONFormatter(bool p = false); | |
92 | ||
93 | void set_status(int status, const char* status_name) override {}; | |
94 | void output_header() override {}; | |
95 | void output_footer() override {}; | |
96 | void flush(std::ostream& os) override; | |
97 | using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl) | |
98 | void reset() override; | |
99 | void open_array_section(const char *name) override; | |
100 | void open_array_section_in_ns(const char *name, const char *ns) override; | |
101 | void open_object_section(const char *name) override; | |
102 | void open_object_section_in_ns(const char *name, const char *ns) override; | |
103 | void close_section() override; | |
104 | void dump_unsigned(const char *name, uint64_t u) override; | |
105 | void dump_int(const char *name, int64_t u) override; | |
106 | void dump_float(const char *name, double d) override; | |
107 | void dump_string(const char *name, const std::string& s) override; | |
108 | std::ostream& dump_stream(const char *name) override; | |
109 | void dump_format_va(const char *name, const char *ns, bool quoted, const char *fmt, va_list ap) override; | |
110 | int get_len() const override; | |
111 | void write_raw_data(const char *data) override; | |
112 | ||
113 | private: | |
114 | ||
115 | struct json_formatter_stack_entry_d { | |
116 | int size; | |
117 | bool is_array; | |
118 | json_formatter_stack_entry_d() : size(0), is_array(false) { } | |
119 | }; | |
120 | ||
121 | bool m_pretty; | |
122 | void open_section(const char *name, bool is_array); | |
123 | void print_quoted_string(const std::string& s); | |
124 | void print_name(const char *name); | |
125 | void print_comma(json_formatter_stack_entry_d& entry); | |
126 | void finish_pending_string(); | |
127 | ||
128 | std::stringstream m_ss, m_pending_string; | |
129 | std::list<json_formatter_stack_entry_d> m_stack; | |
130 | bool m_is_pending_string; | |
131 | }; | |
132 | ||
133 | class XMLFormatter : public Formatter { | |
134 | public: | |
135 | static const char *XML_1_DTD; | |
136 | XMLFormatter(bool pretty = false, bool lowercased = false, bool underscored = true); | |
137 | ||
138 | void set_status(int status, const char* status_name) override {} | |
139 | void output_header() override; | |
140 | void output_footer() override; | |
141 | ||
142 | void flush(std::ostream& os) override; | |
143 | using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl) | |
144 | void reset() override; | |
145 | void open_array_section(const char *name) override; | |
146 | void open_array_section_in_ns(const char *name, const char *ns) override; | |
147 | void open_object_section(const char *name) override; | |
148 | void open_object_section_in_ns(const char *name, const char *ns) override; | |
149 | void close_section() override; | |
150 | void dump_unsigned(const char *name, uint64_t u) override; | |
151 | void dump_int(const char *name, int64_t u) override; | |
152 | void dump_float(const char *name, double d) override; | |
153 | void dump_string(const char *name, const std::string& s) override; | |
154 | std::ostream& dump_stream(const char *name) override; | |
155 | void dump_format_va(const char *name, const char *ns, bool quoted, const char *fmt, va_list ap) override; | |
156 | int get_len() const override; | |
157 | void write_raw_data(const char *data) override; | |
158 | ||
159 | /* with attrs */ | |
160 | void open_array_section_with_attrs(const char *name, const FormatterAttrs& attrs) override; | |
161 | void open_object_section_with_attrs(const char *name, const FormatterAttrs& attrs) override; | |
162 | void dump_string_with_attrs(const char *name, const std::string& s, const FormatterAttrs& attrs) override; | |
163 | ||
164 | protected: | |
165 | void open_section_in_ns(const char *name, const char *ns, const FormatterAttrs *attrs); | |
166 | void finish_pending_string(); | |
167 | void print_spaces(); | |
168 | static std::string escape_xml_str(const char *str); | |
169 | void get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str); | |
170 | char to_lower_underscore(char c) const; | |
171 | ||
172 | std::stringstream m_ss, m_pending_string; | |
173 | std::deque<std::string> m_sections; | |
174 | const bool m_pretty; | |
175 | const bool m_lowercased; | |
176 | const bool m_underscored; | |
177 | std::string m_pending_string_name; | |
178 | bool m_header_done; | |
179 | }; | |
180 | ||
181 | class TableFormatter : public Formatter { | |
182 | public: | |
183 | explicit TableFormatter(bool keyval = false); | |
184 | ||
185 | void set_status(int status, const char* status_name) override {}; | |
186 | void output_header() override {}; | |
187 | void output_footer() override {}; | |
188 | void flush(std::ostream& os) override; | |
189 | using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl) | |
190 | void reset() override; | |
191 | void open_array_section(const char *name) override; | |
192 | void open_array_section_in_ns(const char *name, const char *ns) override; | |
193 | void open_object_section(const char *name) override; | |
194 | void open_object_section_in_ns(const char *name, const char *ns) override; | |
195 | ||
196 | void open_array_section_with_attrs(const char *name, const FormatterAttrs& attrs) override; | |
197 | void open_object_section_with_attrs(const char *name, const FormatterAttrs& attrs) override; | |
198 | ||
199 | void close_section() override; | |
200 | void dump_unsigned(const char *name, uint64_t u) override; | |
201 | void dump_int(const char *name, int64_t u) override; | |
202 | void dump_float(const char *name, double d) override; | |
203 | void dump_string(const char *name, const std::string& s) override; | |
204 | void dump_format_va(const char *name, const char *ns, bool quoted, const char *fmt, va_list ap) override; | |
205 | void dump_string_with_attrs(const char *name, const std::string& s, const FormatterAttrs& attrs) override; | |
206 | std::ostream& dump_stream(const char *name) override; | |
207 | ||
208 | int get_len() const override; | |
209 | void write_raw_data(const char *data) override; | |
210 | void get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str); | |
211 | ||
212 | private: | |
213 | void open_section_in_ns(const char *name, const char *ns, const FormatterAttrs *attrs); | |
214 | std::vector< std::vector<std::pair<std::string, std::string> > > m_vec; | |
215 | std::stringstream m_ss; | |
216 | size_t m_vec_index(const char* name); | |
217 | std::string get_section_name(const char* name); | |
218 | void finish_pending_string(); | |
219 | std::string m_pending_name; | |
220 | bool m_keyval; | |
221 | ||
222 | int m_section_open; | |
223 | std::vector< std::string > m_section; | |
224 | std::map<std::string, int> m_section_cnt; | |
225 | std::vector<size_t> m_column_size; | |
226 | std::vector< std::string > m_column_name; | |
227 | }; | |
228 | ||
229 | ||
230 | } | |
231 | #endif |