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