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