Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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     static Formatter *create(const std::string& type,
27                              const std::string& default_type,
28                              const std::string& fallback);
29     static Formatter *create(const std::string& type,
30                              const std::string& default_type) {
31       return create(type, default_type, "");
32     }
33     static Formatter *create(const std::string& type) {
34       return create(type, "json-pretty", "");
35     }
36
37     Formatter();
38     virtual ~Formatter();
39
40     virtual void enable_line_break() = 0;
41     virtual void flush(std::ostream& os) = 0;
42     void flush(bufferlist &bl);
43     virtual void reset() = 0;
44
45     virtual void set_status(int status, const char* status_name) = 0;
46     virtual void output_header() = 0;
47     virtual void output_footer() = 0;
48
49     virtual void open_array_section(const char *name) = 0;
50     virtual void open_array_section_in_ns(const char *name, const char *ns) = 0;
51     virtual void open_object_section(const char *name) = 0;
52     virtual void open_object_section_in_ns(const char *name, const char *ns) = 0;
53     virtual void close_section() = 0;
54     virtual void dump_unsigned(const char *name, uint64_t u) = 0;
55     virtual void dump_int(const char *name, int64_t s) = 0;
56     virtual void dump_float(const char *name, double d) = 0;
57     virtual void dump_string(const char *name, const std::string& s) = 0;
58     virtual void dump_bool(const char *name, bool b)
59     {
60       dump_format_unquoted(name, "%s", (b ? "true" : "false"));
61     }
62     template<typename T>
63     void dump_object(const char *name, const T& foo) {
64       open_object_section(name);
65       foo.dump(this);
66       close_section();
67     }
68     virtual std::ostream& dump_stream(const char *name) = 0;
69     virtual void dump_format_va(const char *name, const char *ns, bool quoted, const char *fmt, va_list ap) = 0;
70     virtual void dump_format(const char *name, const char *fmt, ...);
71     virtual void dump_format_ns(const char *name, const char *ns, const char *fmt, ...);
72     virtual void dump_format_unquoted(const char *name, const char *fmt, ...);
73     virtual int get_len() const = 0;
74     virtual void write_raw_data(const char *data) = 0;
75     /* with attrs */
76     virtual void open_array_section_with_attrs(const char *name, const FormatterAttrs& attrs)
77     {
78       open_array_section(name);
79     }
80     virtual void open_object_section_with_attrs(const char *name, const FormatterAttrs& attrs)
81     {
82       open_object_section(name);
83     }
84     virtual void dump_string_with_attrs(const char *name, const std::string& s, const FormatterAttrs& attrs)
85     {
86       dump_string(name, s);
87     }
88   };
89
90   class JSONFormatter : public Formatter {
91   public:
92     explicit JSONFormatter(bool p = false);
93
94     void set_status(int status, const char* status_name) override {};
95     void output_header() override {};
96     void output_footer() override {};
97     void enable_line_break() override { m_line_break_enabled = true; }
98     void flush(std::ostream& os) override;
99     using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
100     void reset() override;
101     void open_array_section(const char *name) override;
102     void open_array_section_in_ns(const char *name, const char *ns) override;
103     void open_object_section(const char *name) override;
104     void open_object_section_in_ns(const char *name, const char *ns) override;
105     void close_section() override;
106     void dump_unsigned(const char *name, uint64_t u) override;
107     void dump_int(const char *name, int64_t u) override;
108     void dump_float(const char *name, double d) override;
109     void dump_string(const char *name, const std::string& s) override;
110     std::ostream& dump_stream(const char *name) override;
111     void dump_format_va(const char *name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
112     int get_len() const override;
113     void write_raw_data(const char *data) override;
114
115   private:
116
117     struct json_formatter_stack_entry_d {
118       int size;
119       bool is_array;
120       json_formatter_stack_entry_d() : size(0), is_array(false) { }
121     };
122
123     bool m_pretty;
124     void open_section(const char *name, bool is_array);
125     void print_quoted_string(const std::string& s);
126     void print_name(const char *name);
127     void print_comma(json_formatter_stack_entry_d& entry);
128     void finish_pending_string();
129
130     std::stringstream m_ss, m_pending_string;
131     std::list<json_formatter_stack_entry_d> m_stack;
132     bool m_is_pending_string;
133     bool m_line_break_enabled = false;
134   };
135
136   class XMLFormatter : public Formatter {
137   public:
138     static const char *XML_1_DTD;
139     XMLFormatter(bool pretty = false, bool lowercased = false, bool underscored = true);
140
141     void set_status(int status, const char* status_name) override {}
142     void output_header() override;
143     void output_footer() override;
144
145     void enable_line_break() override { m_line_break_enabled = true; }
146     void flush(std::ostream& os) override;
147     using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
148     void reset() override;
149     void open_array_section(const char *name) override;
150     void open_array_section_in_ns(const char *name, const char *ns) override;
151     void open_object_section(const char *name) override;
152     void open_object_section_in_ns(const char *name, const char *ns) override;
153     void close_section() override;
154     void dump_unsigned(const char *name, uint64_t u) override;
155     void dump_int(const char *name, int64_t u) override;
156     void dump_float(const char *name, double d) override;
157     void dump_string(const char *name, const std::string& s) override;
158     std::ostream& dump_stream(const char *name) override;
159     void dump_format_va(const char *name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
160     int get_len() const override;
161     void write_raw_data(const char *data) override;
162
163     /* with attrs */
164     void open_array_section_with_attrs(const char *name, const FormatterAttrs& attrs) override;
165     void open_object_section_with_attrs(const char *name, const FormatterAttrs& attrs) override;
166     void dump_string_with_attrs(const char *name, const std::string& s, const FormatterAttrs& attrs) override;
167
168   protected:
169     void open_section_in_ns(const char *name, const char *ns, const FormatterAttrs *attrs);
170     void finish_pending_string();
171     void print_spaces();
172     static std::string escape_xml_str(const char *str);
173     void get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str);
174     char to_lower_underscore(char c) const;
175
176     std::stringstream m_ss, m_pending_string;
177     std::deque<std::string> m_sections;
178     const bool m_pretty;
179     const bool m_lowercased;
180     const bool m_underscored;
181     std::string m_pending_string_name;
182     bool m_header_done;
183     bool m_line_break_enabled = false;
184   };
185
186   class TableFormatter : public Formatter {
187   public:
188     explicit TableFormatter(bool keyval = false);
189
190     void set_status(int status, const char* status_name) override {};
191     void output_header() override {};
192     void output_footer() override {};
193     void enable_line_break() override {};
194     void flush(std::ostream& os) override;
195     using Formatter::flush; // don't hide Formatter::flush(bufferlist &bl)
196     void reset() override;
197     void open_array_section(const char *name) override;
198     void open_array_section_in_ns(const char *name, const char *ns) override;
199     void open_object_section(const char *name) override;
200     void open_object_section_in_ns(const char *name, const char *ns) override;
201
202     void open_array_section_with_attrs(const char *name, const FormatterAttrs& attrs) override;
203     void open_object_section_with_attrs(const char *name, const FormatterAttrs& attrs) override;
204
205     void close_section() override;
206     void dump_unsigned(const char *name, uint64_t u) override;
207     void dump_int(const char *name, int64_t u) override;
208     void dump_float(const char *name, double d) override;
209     void dump_string(const char *name, const std::string& s) override;
210     void dump_format_va(const char *name, const char *ns, bool quoted, const char *fmt, va_list ap) override;
211     void dump_string_with_attrs(const char *name, const std::string& s, const FormatterAttrs& attrs) override;
212     std::ostream& dump_stream(const char *name) override;
213
214     int get_len() const override;
215     void write_raw_data(const char *data) override;
216     void get_attrs_str(const FormatterAttrs *attrs, std::string& attrs_str);
217
218   private:
219     void open_section_in_ns(const char *name, const char *ns, const FormatterAttrs *attrs);
220     std::vector< std::vector<std::pair<std::string, std::string> > > m_vec;
221     std::stringstream m_ss;
222     size_t m_vec_index(const char* name);
223     std::string get_section_name(const char* name);
224     void finish_pending_string();
225     std::string m_pending_name;
226     bool m_keyval;
227
228     int m_section_open;
229     std::vector< std::string > m_section;
230     std::map<std::string, int> m_section_cnt;
231     std::vector<size_t> m_column_size;
232     std::vector< std::string > m_column_name;
233   };
234
235
236 }
237 #endif