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
6 #include "include/int_types.h"
7 #include "include/buffer_fwd.h"
18 struct FormatterAttrs
{
19 std::list
< std::pair
<std::string
, std::string
> > attrs
;
21 FormatterAttrs(const char *attr
, ...);
30 ObjectSection(Formatter
& f
, const char *name
) : formatter(f
) {
31 formatter
.open_object_section(name
);
33 ObjectSection(Formatter
& f
, const char *name
, const char *ns
) : formatter(f
) {
34 formatter
.open_object_section_in_ns(name
, ns
);
37 formatter
.close_section();
44 ArraySection(Formatter
& f
, const char *name
) : formatter(f
) {
45 formatter
.open_array_section(name
);
47 ArraySection(Formatter
& f
, const char *name
, const char *ns
) : formatter(f
) {
48 formatter
.open_array_section_in_ns(name
, ns
);
51 formatter
.close_section();
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
, "");
62 static Formatter
*create(std::string_view type
) {
63 return create(type
, "json-pretty", "");
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;
74 virtual void set_status(int status
, const char* status_name
) = 0;
75 virtual void output_header() = 0;
76 virtual void output_footer() = 0;
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
)
89 dump_format_unquoted(name
, "%s", (b
? "true" : "false"));
92 void dump_object(const char *name
, const T
& foo
) {
93 open_object_section(name
);
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;
105 virtual void open_array_section_with_attrs(const char *name
, const FormatterAttrs
& attrs
)
107 open_array_section(name
);
109 virtual void open_object_section_with_attrs(const char *name
, const FormatterAttrs
& attrs
)
111 open_object_section(name
);
113 virtual void dump_string_with_attrs(const char *name
, std::string_view s
, const FormatterAttrs
& attrs
)
115 dump_string(name
, s
);
119 class copyable_sstream
: public std::stringstream
{
121 copyable_sstream() {}
122 copyable_sstream(const copyable_sstream
& rhs
) {
125 copyable_sstream
& operator=(const copyable_sstream
& rhs
) {
131 class JSONFormatter
: public Formatter
{
133 explicit JSONFormatter(bool p
= false);
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
;
157 virtual bool handle_value(const char *name
, std::string_view s
, bool quoted
) {
158 return false; /* is handling done? */
161 virtual bool handle_open_section(const char *name
, const char *ns
, bool is_array
) {
162 return false; /* is handling done? */
165 virtual bool handle_close_section() {
166 return false; /* is handling done? */
171 struct json_formatter_stack_entry_d
{
174 json_formatter_stack_entry_d() : size(0), is_array(false) { }
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();
185 void add_value(const char *name
, T val
);
186 void add_value(const char *name
, std::string_view val
, bool quoted
);
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;
197 void add_value(const char *name
, T val
);
199 class XMLFormatter
: public Formatter
{
201 static const char *XML_1_DTD
;
202 XMLFormatter(bool pretty
= false, bool lowercased
= false, bool underscored
= true);
204 void set_status(int status
, const char* status_name
) override
{}
205 void output_header() override
;
206 void output_footer() override
;
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
;
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
;
232 void open_section_in_ns(const char *name
, const char *ns
, const FormatterAttrs
*attrs
);
233 void finish_pending_string();
235 void get_attrs_str(const FormatterAttrs
*attrs
, std::string
& attrs_str
);
236 char to_lower_underscore(char c
) const;
238 std::stringstream m_ss
, m_pending_string
;
239 std::deque
<std::string
> m_sections
;
241 const bool m_lowercased
;
242 const bool m_underscored
;
243 std::string m_pending_string_name
;
245 bool m_line_break_enabled
= false;
248 void add_value(const char *name
, T val
);
251 class TableFormatter
: public Formatter
{
253 explicit TableFormatter(bool keyval
= false);
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
;
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
;
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
;
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
);
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
;
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
;
302 std::string
fixed_to_string(int64_t num
, int scale
);
303 std::string
fixed_u_to_string(uint64_t num
, int scale
);