]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/Formatter.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / common / Formatter.h
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 #include "include/buffer_fwd.h"
8
9 #include <deque>
10 #include <list>
11 #include <vector>
12 #include <stdarg.h>
13 #include <sstream>
14 #include <map>
15
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 class ObjectSection {
27 Formatter& formatter;
28
29 public:
30 ObjectSection(Formatter& f, std::string_view name) : formatter(f) {
31 formatter.open_object_section(name);
32 }
33 ObjectSection(Formatter& f, std::string_view name, const char *ns) : formatter(f) {
34 formatter.open_object_section_in_ns(name, ns);
35 }
36 ~ObjectSection() {
37 formatter.close_section();
38 }
39 };
40 class ArraySection {
41 Formatter& formatter;
42
43 public:
44 ArraySection(Formatter& f, std::string_view name) : formatter(f) {
45 formatter.open_array_section(name);
46 }
47 ArraySection(Formatter& f, std::string_view name, const char *ns) : formatter(f) {
48 formatter.open_array_section_in_ns(name, ns);
49 }
50 ~ArraySection() {
51 formatter.close_section();
52 }
53 };
54
55 static Formatter *create(std::string_view type,
56 std::string_view default_type,
57 std::string_view fallback);
58 static Formatter *create(std::string_view type,
59 std::string_view default_type) {
60 return create(type, default_type, "");
61 }
62 static Formatter *create(std::string_view type) {
63 return create(type, "json-pretty", "");
64 }
65
66 Formatter();
67 virtual ~Formatter();
68
69 virtual void enable_line_break() = 0;
70 virtual void flush(std::ostream& os) = 0;
71 void flush(bufferlist &bl);
72 virtual void reset() = 0;
73
74 virtual void set_status(int status, const char* status_name) = 0;
75 virtual void output_header() = 0;
76 virtual void output_footer() = 0;
77
78 virtual void open_array_section(std::string_view name) = 0;
79 virtual void open_array_section_in_ns(std::string_view name, const char *ns) = 0;
80 virtual void open_object_section(std::string_view name) = 0;
81 virtual void open_object_section_in_ns(std::string_view name, const char *ns) = 0;
82 virtual void close_section() = 0;
83 virtual void dump_unsigned(std::string_view name, uint64_t u) = 0;
84 virtual void dump_int(std::string_view name, int64_t s) = 0;
85 virtual void dump_float(std::string_view name, double d) = 0;
86 virtual void dump_string(std::string_view name, std::string_view s) = 0;
87 virtual void dump_bool(std::string_view name, bool b)
88 {
89 dump_format_unquoted(name, "%s", (b ? "true" : "false"));
90 }
91 template<typename T>
92 void dump_object(std::string_view name, const T& foo) {
93 open_object_section(name);
94 foo.dump(this);
95 close_section();
96 }
97 virtual std::ostream& dump_stream(std::string_view name) = 0;
98 virtual void dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) = 0;
99 virtual void dump_format(std::string_view name, const char *fmt, ...);
100 virtual void dump_format_ns(std::string_view name, const char *ns, const char *fmt, ...);
101 virtual void dump_format_unquoted(std::string_view name, const char *fmt, ...);
102 virtual int get_len() const = 0;
103 virtual void write_raw_data(const char *data) = 0;
104 /* with attrs */
105 virtual void open_array_section_with_attrs(std::string_view name, const FormatterAttrs& attrs)
106 {
107 open_array_section(name);
108 }
109 virtual void open_object_section_with_attrs(std::string_view name, const FormatterAttrs& attrs)
110 {
111 open_object_section(name);
112 }
113 virtual void dump_string_with_attrs(std::string_view name, std::string_view s, const FormatterAttrs& attrs)
114 {
115 dump_string(name, s);
116 }
117
118 virtual void *get_external_feature_handler(const std::string& feature) {
119 return nullptr;
120 }
121 virtual void write_bin_data(const char* buff, int buf_len);
122 };
123
124 class copyable_sstream : public std::stringstream {
125 public:
126 copyable_sstream() {}
127 copyable_sstream(const copyable_sstream& rhs) {
128 str(rhs.str());
129 }
130 copyable_sstream& operator=(const copyable_sstream& rhs) {
131 str(rhs.str());
132 return *this;
133 }
134 };
135
136 class JSONFormatter : public Formatter {
137 public:
138 explicit JSONFormatter(bool p = false);
139
140 void set_status(int status, const char* status_name) override {};
141 void output_header() override {};
142 void output_footer() override {};
143 void enable_line_break() override { m_line_break_enabled = true; }
144 void flush(std::ostream& os) override;
145 using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
146 void reset() override;
147 void open_array_section(std::string_view name) override;
148 void open_array_section_in_ns(std::string_view name, const char *ns) override;
149 void open_object_section(std::string_view name) override;
150 void open_object_section_in_ns(std::string_view name, const char *ns) override;
151 void close_section() override;
152 void dump_unsigned(std::string_view name, uint64_t u) override;
153 void dump_int(std::string_view name, int64_t s) override;
154 void dump_float(std::string_view name, double d) override;
155 void dump_string(std::string_view name, std::string_view s) override;
156 std::ostream& dump_stream(std::string_view name) override;
157 void dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
158 int get_len() const override;
159 void write_raw_data(const char *data) override;
160
161 protected:
162 virtual bool handle_value(std::string_view name, std::string_view s, bool quoted) {
163 return false; /* is handling done? */
164 }
165
166 virtual bool handle_open_section(std::string_view name, const char *ns, bool is_array) {
167 return false; /* is handling done? */
168 }
169
170 virtual bool handle_close_section() {
171 return false; /* is handling done? */
172 }
173
174 int stack_size() { return m_stack.size(); }
175
176 private:
177
178 struct json_formatter_stack_entry_d {
179 int size;
180 bool is_array;
181 json_formatter_stack_entry_d() : size(0), is_array(false) { }
182 };
183
184 bool m_pretty;
185 void open_section(std::string_view name, const char *ns, bool is_array);
186 void print_quoted_string(std::string_view s);
187 void print_name(std::string_view name);
188 void print_comma(json_formatter_stack_entry_d& entry);
189 void finish_pending_string();
190
191 template <class T>
192 void add_value(std::string_view name, T val);
193 void add_value(std::string_view name, std::string_view val, bool quoted);
194
195 copyable_sstream m_ss;
196 copyable_sstream m_pending_string;
197 std::string m_pending_name;
198 std::list<json_formatter_stack_entry_d> m_stack;
199 bool m_is_pending_string;
200 bool m_line_break_enabled = false;
201 };
202
203 template <class T>
204 void add_value(std::string_view name, T val);
205
206 class XMLFormatter : public Formatter {
207 public:
208 static const char *XML_1_DTD;
209 XMLFormatter(bool pretty = false, bool lowercased = false, bool underscored = true);
210
211 void set_status(int status, const char* status_name) override {}
212 void output_header() override;
213 void output_footer() override;
214
215 void enable_line_break() override { m_line_break_enabled = true; }
216 void flush(std::ostream& os) override;
217 using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
218 void reset() override;
219 void open_array_section(std::string_view name) override;
220 void open_array_section_in_ns(std::string_view name, const char *ns) override;
221 void open_object_section(std::string_view name) override;
222 void open_object_section_in_ns(std::string_view name, const char *ns) override;
223 void close_section() override;
224 void dump_unsigned(std::string_view name, uint64_t u) override;
225 void dump_int(std::string_view name, int64_t s) override;
226 void dump_float(std::string_view name, double d) override;
227 void dump_string(std::string_view name, std::string_view s) override;
228 std::ostream& dump_stream(std::string_view name) override;
229 void dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
230 int get_len() const override;
231 void write_raw_data(const char *data) override;
232 void write_bin_data(const char* buff, int len) override;
233
234 /* with attrs */
235 void open_array_section_with_attrs(std::string_view name, const FormatterAttrs& attrs) override;
236 void open_object_section_with_attrs(std::string_view name, const FormatterAttrs& attrs) override;
237 void dump_string_with_attrs(std::string_view name, std::string_view s, const FormatterAttrs& attrs) override;
238
239 protected:
240 void open_section_in_ns(std::string_view name, const char *ns, const FormatterAttrs *attrs);
241 void finish_pending_string();
242 void print_spaces();
243 void get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str);
244 char to_lower_underscore(char c) const;
245
246 std::stringstream m_ss, m_pending_string;
247 std::deque<std::string> m_sections;
248 const bool m_pretty;
249 const bool m_lowercased;
250 const bool m_underscored;
251 std::string m_pending_string_name;
252 bool m_header_done;
253 bool m_line_break_enabled = false;
254 private:
255 template <class T>
256 void add_value(std::string_view name, T val);
257 };
258
259 class TableFormatter : public Formatter {
260 public:
261 explicit TableFormatter(bool keyval = false);
262
263 void set_status(int status, const char* status_name) override {};
264 void output_header() override {};
265 void output_footer() override {};
266 void enable_line_break() override {};
267 void flush(std::ostream& os) override;
268 using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
269 void reset() override;
270 void open_array_section(std::string_view name) override;
271 void open_array_section_in_ns(std::string_view name, const char *ns) override;
272 void open_object_section(std::string_view name) override;
273 void open_object_section_in_ns(std::string_view name, const char *ns) override;
274
275 void open_array_section_with_attrs(std::string_view name, const FormatterAttrs& attrs) override;
276 void open_object_section_with_attrs(std::string_view name, const FormatterAttrs& attrs) override;
277
278 void close_section() override;
279 void dump_unsigned(std::string_view name, uint64_t u) override;
280 void dump_int(std::string_view name, int64_t s) override;
281 void dump_float(std::string_view name, double d) override;
282 void dump_string(std::string_view name, std::string_view s) override;
283 void dump_format_va(std::string_view name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
284 void dump_string_with_attrs(std::string_view name, std::string_view s, const FormatterAttrs& attrs) override;
285 std::ostream& dump_stream(std::string_view name) override;
286
287 int get_len() const override;
288 void write_raw_data(const char *data) override;
289 void get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str);
290
291 private:
292 template <class T>
293 void add_value(std::string_view name, T val);
294 void open_section_in_ns(std::string_view name, const char *ns, const FormatterAttrs *attrs);
295 std::vector< std::vector<std::pair<std::string, std::string> > > m_vec;
296 std::stringstream m_ss;
297 size_t m_vec_index(std::string_view name);
298 std::string get_section_name(std::string_view name);
299 void finish_pending_string();
300 std::string m_pending_name;
301 bool m_keyval;
302
303 int m_section_open;
304 std::vector< std::string > m_section;
305 std::map<std::string, int> m_section_cnt;
306 std::vector<size_t> m_column_size;
307 std::vector< std::string > m_column_name;
308 };
309
310 std::string fixed_to_string(int64_t num, int scale);
311 std::string fixed_u_to_string(uint64_t num, int scale);
312 }
313 #endif
314