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