summaryrefslogtreecommitdiff
path: root/src/common/Formatter.h
blob: 5c6bb573d23d4a1dfedce3161889052367a457a8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#ifndef CEPH_FORMATTER_H
#define CEPH_FORMATTER_H

#include <deque>
#include <inttypes.h>
#include <iostream>
#include <list>
#include <ostream>
#include <sstream>
#include <stdarg.h>
#include <string>

namespace ceph {

class Formatter {
 public:
  Formatter();
  virtual ~Formatter();

  virtual void flush(std::ostream& os) = 0;
  virtual void reset() = 0;

  virtual void open_array_section(const char *name) = 0;
  virtual void open_array_section_in_ns(const char *name, const char *ns) = 0;
  virtual void open_object_section(const char *name) = 0;
  virtual void open_object_section_in_ns(const char *name, const char *ns) = 0;
  virtual void close_section() = 0;
  virtual void dump_unsigned(const char *name, uint64_t u) = 0;
  virtual void dump_int(const char *name, int64_t s) = 0;
  virtual void dump_float(const char *name, double d) = 0;
  virtual void dump_string(const char *name, std::string s) = 0;
  virtual std::ostream& dump_stream(const char *name) = 0;
  virtual void dump_format(const char *name, const char *fmt, ...) = 0;
  virtual int get_len() const = 0;
  virtual void write_raw_data(const char *data) = 0;
};


class JSONFormatter : public Formatter {
 public:
  JSONFormatter(bool p=false);

  void flush(std::ostream& os);
  void reset();
  void open_array_section(const char *name);
  void open_array_section_in_ns(const char *name, const char *ns);
  void open_object_section(const char *name);
  void open_object_section_in_ns(const char *name, const char *ns);
  void close_section();
  void dump_unsigned(const char *name, uint64_t u);
  void dump_int(const char *name, int64_t u);
  void dump_float(const char *name, double d);
  void dump_string(const char *name, std::string s);
  std::ostream& dump_stream(const char *name);
  void dump_format(const char *name, const char *fmt, ...);
  int get_len() const;
  void write_raw_data(const char *data);

 private:
  struct json_formatter_stack_entry_d {
    int size;
    bool is_array;
    json_formatter_stack_entry_d() : size(0), is_array(false) {}
  };
  
  bool m_pretty;
  void open_section(const char *name, bool is_array);
  void print_quoted_string(const char *s);
  void print_name(const char *name);
  void print_comma(json_formatter_stack_entry_d& entry);
  void finish_pending_string();

  std::stringstream m_ss, m_pending_string;
  std::list<json_formatter_stack_entry_d> m_stack;
  bool m_is_pending_string;
};

class XMLFormatter : public Formatter {
 public:
  static const char *XML_1_DTD;
  XMLFormatter(bool pretty = false);

  void flush(std::ostream& os);
  void reset();
  void open_array_section(const char *name);
  void open_array_section_in_ns(const char *name, const char *ns);
  void open_object_section(const char *name);
  void open_object_section_in_ns(const char *name, const char *ns);
  void close_section();
  void dump_unsigned(const char *name, uint64_t u);
  void dump_int(const char *name, int64_t u);
  void dump_float(const char *name, double d);
  void dump_string(const char *name, std::string s);
  std::ostream& dump_stream(const char *name);
  void dump_format(const char *name, const char *fmt, ...);
  int get_len() const;
  void write_raw_data(const char *data);

 private:
  void open_section_in_ns(const char *name, const char *ns);
  void finish_pending_string();
  void print_spaces(bool extra_space);
  static std::string escape_xml_str(const char *str);

  std::stringstream m_ss, m_pending_string;
  std::deque<std::string> m_sections;
  bool m_pretty;
  std::string m_pending_string_name;
};

}
#endif