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