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