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"
19 struct FormatterAttrs
{
20 std::list
< std::pair
<std::string
, std::string
> > attrs
;
22 FormatterAttrs(const char *attr
, ...);
31 ObjectSection(Formatter
& f
, std::string_view name
) : formatter(f
) {
32 formatter
.open_object_section(name
);
34 ObjectSection(Formatter
& f
, std::string_view name
, const char *ns
) : formatter(f
) {
35 formatter
.open_object_section_in_ns(name
, ns
);
38 formatter
.close_section();
45 ArraySection(Formatter
& f
, std::string_view name
) : formatter(f
) {
46 formatter
.open_array_section(name
);
48 ArraySection(Formatter
& f
, std::string_view name
, const char *ns
) : formatter(f
) {
49 formatter
.open_array_section_in_ns(name
, ns
);
52 formatter
.close_section();
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
, "");
63 static Formatter
*create(std::string_view type
) {
64 return create(type
, "json-pretty", "");
66 template <typename
... Params
>
67 static std::unique_ptr
<Formatter
> create_unique(Params
&&...params
)
69 return std::unique_ptr
<Formatter
>(
70 Formatter::create(std::forward
<Params
>(params
)...));
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;
81 virtual void set_status(int status
, const char* status_name
) = 0;
82 virtual void output_header() = 0;
83 virtual void output_footer() = 0;
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
)
96 dump_format_unquoted(name
, "%s", (b
? "true" : "false"));
99 void dump_object(std::string_view name
, const T
& foo
) {
100 open_object_section(name
);
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;
112 virtual void open_array_section_with_attrs(std::string_view name
, const FormatterAttrs
& attrs
)
114 open_array_section(name
);
116 virtual void open_object_section_with_attrs(std::string_view name
, const FormatterAttrs
& attrs
)
118 open_object_section(name
);
120 virtual void dump_string_with_attrs(std::string_view name
, std::string_view s
, const FormatterAttrs
& attrs
)
122 dump_string(name
, s
);
125 virtual void *get_external_feature_handler(const std::string
& feature
) {
128 virtual void write_bin_data(const char* buff
, int buf_len
);
131 class copyable_sstream
: public std::stringstream
{
133 copyable_sstream() {}
134 copyable_sstream(const copyable_sstream
& rhs
) {
137 copyable_sstream
& operator=(const copyable_sstream
& rhs
) {
143 class JSONFormatter
: public Formatter
{
145 explicit JSONFormatter(bool p
= false);
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
;
169 virtual bool handle_value(std::string_view name
, std::string_view s
, bool quoted
) {
170 return false; /* is handling done? */
173 virtual bool handle_open_section(std::string_view name
, const char *ns
, bool is_array
) {
174 return false; /* is handling done? */
177 virtual bool handle_close_section() {
178 return false; /* is handling done? */
181 int stack_size() { return m_stack
.size(); }
185 struct json_formatter_stack_entry_d
{
188 json_formatter_stack_entry_d() : size(0), is_array(false) { }
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();
199 void add_value(std::string_view name
, T val
);
200 void add_value(std::string_view name
, std::string_view val
, bool quoted
);
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;
211 void add_value(std::string_view name
, T val
);
213 class XMLFormatter
: public Formatter
{
215 static const char *XML_1_DTD
;
216 XMLFormatter(bool pretty
= false, bool lowercased
= false, bool underscored
= true);
218 void set_status(int status
, const char* status_name
) override
{}
219 void output_header() override
;
220 void output_footer() override
;
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
;
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
;
247 void open_section_in_ns(std::string_view name
, const char *ns
, const FormatterAttrs
*attrs
);
248 void finish_pending_string();
250 void get_attrs_str(const FormatterAttrs
*attrs
, std::string
& attrs_str
);
251 char to_lower_underscore(char c
) const;
253 std::stringstream m_ss
, m_pending_string
;
254 std::deque
<std::string
> m_sections
;
256 const bool m_lowercased
;
257 const bool m_underscored
;
258 std::string m_pending_string_name
;
260 bool m_line_break_enabled
= false;
263 void add_value(std::string_view name
, T val
);
266 class TableFormatter
: public Formatter
{
268 explicit TableFormatter(bool keyval
= false);
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
;
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
;
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
;
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
);
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
;
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
;
317 std::string
fixed_to_string(int64_t num
, int scale
);
318 std::string
fixed_u_to_string(uint64_t num
, int scale
);