CernVM-FS  2.13.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
json_document_write.h
Go to the documentation of this file.
1 
5 #ifndef CVMFS_JSON_DOCUMENT_WRITE_H_
6 #define CVMFS_JSON_DOCUMENT_WRITE_H_
7 
8 #include <cstdio>
9 #include <string>
10 #include <vector>
11 
12 #include "util/exception.h"
13 #include "util/string.h"
14 
15 #ifdef CVMFS_NAMESPACE_GUARD
16 namespace CVMFS_NAMESPACE_GUARD {
17 #endif
18 
30  enum JsonVariant {
34  kJsonObject
35  };
36 
37  struct JsonEntry {
39  std::string key_escaped;
40  std::string str_val_escaped;
41  int64_t int_val;
42  float float_val;
43 
44  JsonEntry(const std::string &key_escaped, const std::string &val)
45  : variant(kString)
46  , key_escaped(key_escaped)
47  , str_val_escaped(val)
48  , int_val(0)
49  , float_val(0.0) { }
50 
51  JsonEntry(const std::string &key_escaped, const std::string &val,
52  const JsonVariant variant)
53  : variant(variant)
54  , key_escaped(key_escaped)
55  , str_val_escaped(val)
56  , int_val(0)
57  , float_val(0.0) { }
58 
59  JsonEntry(const std::string &key_escaped, const int val)
60  : variant(kInteger)
61  , key_escaped(key_escaped)
62  , str_val_escaped()
63  , int_val(val)
64  , float_val(0.0) { }
65 
66  JsonEntry(const std::string &key_escaped, const float val)
67  : variant(kFloat)
68  , key_escaped(key_escaped)
69  , str_val_escaped()
70  , int_val(0)
71  , float_val(val) { }
72 
73  JsonEntry(const std::string &key_escaped, const int64_t val)
74  : variant(kInteger)
75  , key_escaped(key_escaped)
76  , str_val_escaped()
77  , int_val(val)
78  , float_val(0.0) { }
79 
80  std::string Format() const {
81  switch (variant) {
82  case kString:
83  return "\"" + key_escaped + "\":\"" + str_val_escaped + "\"";
84  case kInteger:
85  return "\"" + key_escaped + "\":" + StringifyInt(int_val);
86  case kFloat:
87  return "\"" + key_escaped + "\":" + StringifyDouble(float_val);
88  case kJsonObject:
89  return "\"" + key_escaped + "\":" + str_val_escaped;
90  default:
91  PANIC(kLogStdout | kLogStderr, "JSON creation failed");
92  }
93  }
94  };
95 
96  public:
97  void Add(const std::string &key, const std::string &val) {
98  const JsonEntry entry(Escape(key), Escape(val));
99  entries.push_back(entry);
100  }
101 
102  void Add(const std::string &key, const int val) {
103  const JsonEntry entry(Escape(key), val);
104  entries.push_back(entry);
105  }
106 
107  void Add(const std::string &key, const float val) {
108  const JsonEntry entry(Escape(key), val);
109  entries.push_back(entry);
110  }
111 
112  void Add(const std::string &key, const int64_t val) {
113  const JsonEntry entry(Escape(key), val);
114  entries.push_back(entry);
115  }
116 
117  void AddJsonObject(const std::string &key, const std::string &json) {
118  // we **do not escape** the value here
119  const JsonEntry entry(Escape(key), json, kJsonObject);
120  entries.push_back(entry);
121  }
122 
123  std::string GenerateString() const {
124  std::string output;
125 
126  output += "{";
127  for (size_t i = 0u; i < this->entries.size(); ++i) {
128  output += this->entries[i].Format();
129  if (i < this->entries.size() - 1) {
130  output += ',';
131  }
132  }
133  output += std::string("}");
134  return output;
135  }
136 
137  void Clear() { entries.clear(); }
138 
139  private:
140  // this escape procedure is not as complete as it should be.
141  // we should manage ALL control chars from '\x00' to '\x1f'
142  // however this are the one that we can expect to happen
143  // More info: https://stackoverflow.com/a/33799784/869271
144  const std::string Escape(const std::string &input) const {
145  std::string result;
146  result.reserve(input.size());
147  for (size_t i = 0; i < input.size(); i++) {
148  switch (input[i]) {
149  case '"':
150  result.append("\\\"");
151  break;
152  case '\\':
153  result.append("\\\\");
154  break;
155  case '\b':
156  result.append("\\b");
157  break;
158  case '\f':
159  result.append("\\f");
160  break;
161  case '\n':
162  result.append("\\n");
163  break;
164  case '\r':
165  result.append("\\r");
166  break;
167  case '\t':
168  result.append("\\t");
169  break;
170  default:
171  result.push_back(input[i]);
172  break;
173  }
174  }
175  return result;
176  }
177 
178  std::vector<JsonEntry> entries;
179 };
180 
181 #ifdef CVMFS_NAMESPACE_GUARD
182 } // namespace CVMFS_NAMESPACE_GUARD
183 #endif
184 
185 #endif // CVMFS_JSON_DOCUMENT_WRITE_H_
void Add(const std::string &key, const float val)
void Add(const std::string &key, const std::string &val)
JsonEntry(const std::string &key_escaped, const int val)
#define PANIC(...)
Definition: exception.h:29
const std::string Escape(const std::string &input) const
string StringifyDouble(const double value)
Definition: string.cc:95
std::vector< JsonEntry > entries
JsonVariant variant
int64_t int_val
std::string str_val_escaped
float float_val
JsonEntry(const std::string &key_escaped, const float val)
string StringifyInt(const int64_t value)
Definition: string.cc:77
std::string Format() const
void Add(const std::string &key, const int val)
JsonEntry(const std::string &key_escaped, const int64_t val)
void Add(const std::string &key, const int64_t val)
std::string key_escaped
JsonEntry(const std::string &key_escaped, const std::string &val)
std::string GenerateString() const
void AddJsonObject(const std::string &key, const std::string &json)
JsonEntry(const std::string &key_escaped, const std::string &val, const JsonVariant variant)