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_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
)
97 dump_format_unquoted(name
, "%s", (b
? "true" : "false"));
100 void dump_object(std::string_view name
, const T
& foo
) {
101 open_object_section(name
);
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;
113 virtual void open_array_section_with_attrs(std::string_view name
, const FormatterAttrs
& attrs
)
115 open_array_section(name
);
117 virtual void open_object_section_with_attrs(std::string_view name
, const FormatterAttrs
& attrs
)
119 open_object_section(name
);
121 virtual void dump_string_with_attrs(std::string_view name
, std::string_view s
, const FormatterAttrs
& attrs
)
123 dump_string(name
, s
);
126 virtual void *get_external_feature_handler(const std::string
& feature
) {
129 virtual void write_bin_data(const char* buff
, int buf_len
);
132 class copyable_sstream
: public std::stringstream
{
134 copyable_sstream() {}
135 copyable_sstream(const copyable_sstream
& rhs
) {
138 copyable_sstream
& operator=(const copyable_sstream
& rhs
) {
144 class JSONFormatter
: public Formatter
{
146 explicit JSONFormatter(bool p
= false);
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
;
171 virtual bool handle_value(std::string_view name
, std::string_view s
, bool quoted
) {
172 return false; /* is handling done? */
175 virtual bool handle_open_section(std::string_view name
, const char *ns
, bool is_array
) {
176 return false; /* is handling done? */
179 virtual bool handle_close_section() {
180 return false; /* is handling done? */
183 int stack_size() { return m_stack
.size(); }
187 struct json_formatter_stack_entry_d
{
190 json_formatter_stack_entry_d() : size(0), is_array(false) { }
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();
201 void add_value(std::string_view name
, T val
);
202 void add_value(std::string_view name
, std::string_view val
, bool quoted
);
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;
213 void add_value(std::string_view name
, T val
);
215 class XMLFormatter
: public Formatter
{
217 static const char *XML_1_DTD
;
218 XMLFormatter(bool pretty
= false, bool lowercased
= false, bool underscored
= true);
220 void set_status(int status
, const char* status_name
) override
{}
221 void output_header() override
;
222 void output_footer() override
;
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
;
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
;
250 void open_section_in_ns(std::string_view name
, const char *ns
, const FormatterAttrs
*attrs
);
251 void finish_pending_string();
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;
257 std::stringstream m_ss
, m_pending_string
;
258 std::deque
<std::string
> m_sections
;
260 const bool m_lowercased
;
261 const bool m_underscored
;
262 std::string m_pending_string_name
;
264 bool m_line_break_enabled
= false;
267 void add_value(std::string_view name
, T val
);
270 class TableFormatter
: public Formatter
{
272 explicit TableFormatter(bool keyval
= false);
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
;
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
;
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
;
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
);
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
;
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
;
322 std::string
fixed_to_string(int64_t num
, int scale
);
323 std::string
fixed_u_to_string(uint64_t num
, int scale
);