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