]> git.proxmox.com Git - ceph.git/blob - ceph/src/common/ceph_json.h
update sources to v12.1.0
[ceph.git] / ceph / src / common / ceph_json.h
1 #ifndef CEPH_JSON_H
2 #define CEPH_JSON_H
3
4 #include <include/types.h>
5
6 #ifdef _ASSERT_H
7 #define NEED_ASSERT_H
8 #pragma push_macro("_ASSERT_H")
9 #endif
10
11 #include "json_spirit/json_spirit.h"
12 #undef _ASSERT_H
13
14 #ifdef NEED_ASSERT_H
15 #pragma pop_macro("_ASSERT_H")
16 #endif
17
18 #include "Formatter.h"
19
20 using namespace json_spirit;
21
22
23 class JSONObj;
24
25 class JSONObjIter {
26 typedef map<string, JSONObj *>::iterator map_iter_t;
27 map_iter_t cur;
28 map_iter_t last;
29
30 public:
31 JSONObjIter();
32 ~JSONObjIter();
33 void set(const JSONObjIter::map_iter_t &_cur, const JSONObjIter::map_iter_t &_end);
34
35 void operator++();
36 JSONObj *operator*();
37
38 bool end() const {
39 return (cur == last);
40 }
41 };
42
43 class JSONObj
44 {
45 JSONObj *parent;
46 protected:
47 string name; // corresponds to obj_type in XMLObj
48 Value data;
49 string data_string;
50 multimap<string, JSONObj *> children;
51 map<string, string> attr_map;
52 void handle_value(Value v);
53
54 public:
55
56 JSONObj() : parent(NULL){}
57
58 virtual ~JSONObj();
59
60 void init(JSONObj *p, Value v, string n);
61
62 string& get_name() { return name; }
63 string& get_data() { return data_string; }
64 bool get_data(const string& key, string *dest);
65 JSONObj *get_parent();
66 void add_child(string el, JSONObj *child);
67 bool get_attr(string name, string& attr);
68 JSONObjIter find(const string& name);
69 JSONObjIter find_first();
70 JSONObjIter find_first(const string& name);
71 JSONObj *find_obj(const string& name);
72
73 friend ostream& operator<<(ostream &out,
74 const JSONObj &obj); // does not work, FIXME
75
76 bool is_array();
77 bool is_object();
78 vector<string> get_array_elements();
79 };
80
81 class JSONParser : public JSONObj
82 {
83 int buf_len;
84 string json_buffer;
85 bool success;
86 public:
87 JSONParser();
88 ~JSONParser() override;
89 void handle_data(const char *s, int len);
90
91 bool parse(const char *buf_, int len);
92 bool parse(int len);
93 bool parse();
94 bool parse(const char *file_name);
95
96 const char *get_json() { return json_buffer.c_str(); }
97 void set_failure() { success = false; }
98 };
99
100
101 class JSONDecoder {
102 public:
103 struct err {
104 string message;
105
106 err(const string& m) : message(m) {}
107 };
108
109 JSONParser parser;
110
111 JSONDecoder(bufferlist& bl) {
112 if (!parser.parse(bl.c_str(), bl.length())) {
113 cout << "JSONDecoder::err()" << std::endl;
114 throw JSONDecoder::err("failed to parse JSON input");
115 }
116 }
117
118 template<class T>
119 static bool decode_json(const char *name, T& val, JSONObj *obj, bool mandatory = false);
120
121 template<class C>
122 static bool decode_json(const char *name, C& container, void (*cb)(C&, JSONObj *obj), JSONObj *obj, bool mandatory = false);
123
124 template<class T>
125 static void decode_json(const char *name, T& val, T& default_val, JSONObj *obj);
126 };
127
128 template<class T>
129 void decode_json_obj(T& val, JSONObj *obj)
130 {
131 val.decode_json(obj);
132 }
133
134 static inline void decode_json_obj(string& val, JSONObj *obj)
135 {
136 val = obj->get_data();
137 }
138
139 void decode_json_obj(unsigned long long& val, JSONObj *obj);
140 void decode_json_obj(long long& val, JSONObj *obj);
141 void decode_json_obj(unsigned long& val, JSONObj *obj);
142 void decode_json_obj(long& val, JSONObj *obj);
143 void decode_json_obj(unsigned& val, JSONObj *obj);
144 void decode_json_obj(int& val, JSONObj *obj);
145 void decode_json_obj(bool& val, JSONObj *obj);
146 void decode_json_obj(bufferlist& val, JSONObj *obj);
147 class utime_t;
148 void decode_json_obj(utime_t& val, JSONObj *obj);
149
150 template<class T>
151 void decode_json_obj(list<T>& l, JSONObj *obj)
152 {
153 l.clear();
154
155 JSONObjIter iter = obj->find_first();
156
157 for (; !iter.end(); ++iter) {
158 T val;
159 JSONObj *o = *iter;
160 decode_json_obj(val, o);
161 l.push_back(val);
162 }
163 }
164
165 template<class T>
166 void decode_json_obj(deque<T>& l, JSONObj *obj)
167 {
168 l.clear();
169
170 JSONObjIter iter = obj->find_first();
171
172 for (; !iter.end(); ++iter) {
173 T val;
174 JSONObj *o = *iter;
175 decode_json_obj(val, o);
176 l.push_back(val);
177 }
178 }
179
180 template<class T>
181 void decode_json_obj(set<T>& l, JSONObj *obj)
182 {
183 l.clear();
184
185 JSONObjIter iter = obj->find_first();
186
187 for (; !iter.end(); ++iter) {
188 T val;
189 JSONObj *o = *iter;
190 decode_json_obj(val, o);
191 l.insert(val);
192 }
193 }
194
195 template<class T>
196 void decode_json_obj(vector<T>& l, JSONObj *obj)
197 {
198 l.clear();
199
200 JSONObjIter iter = obj->find_first();
201
202 for (; !iter.end(); ++iter) {
203 T val;
204 JSONObj *o = *iter;
205 decode_json_obj(val, o);
206 l.push_back(val);
207 }
208 }
209
210 template<class K, class V, class C = std::less<K> >
211 void decode_json_obj(map<K, V, C>& m, JSONObj *obj)
212 {
213 m.clear();
214
215 JSONObjIter iter = obj->find_first();
216
217 for (; !iter.end(); ++iter) {
218 K key;
219 V val;
220 JSONObj *o = *iter;
221 JSONDecoder::decode_json("key", key, o);
222 JSONDecoder::decode_json("val", val, o);
223 m[key] = val;
224 }
225 }
226
227 template<class K, class V>
228 void decode_json_obj(multimap<K, V>& m, JSONObj *obj)
229 {
230 m.clear();
231
232 JSONObjIter iter = obj->find_first();
233
234 for (; !iter.end(); ++iter) {
235 K key;
236 V val;
237 JSONObj *o = *iter;
238 JSONDecoder::decode_json("key", key, o);
239 JSONDecoder::decode_json("val", val, o);
240 m.insert(make_pair(key, val));
241 }
242 }
243
244 template<class C>
245 void decode_json_obj(C& container, void (*cb)(C&, JSONObj *obj), JSONObj *obj)
246 {
247 container.clear();
248
249 JSONObjIter iter = obj->find_first();
250
251 for (; !iter.end(); ++iter) {
252 JSONObj *o = *iter;
253 cb(container, o);
254 }
255 }
256
257 template<class T>
258 bool JSONDecoder::decode_json(const char *name, T& val, JSONObj *obj, bool mandatory)
259 {
260 JSONObjIter iter = obj->find_first(name);
261 if (iter.end()) {
262 if (mandatory) {
263 string s = "missing mandatory field " + string(name);
264 throw err(s);
265 }
266 val = T();
267 return false;
268 }
269
270 try {
271 decode_json_obj(val, *iter);
272 } catch (err& e) {
273 string s = string(name) + ": ";
274 s.append(e.message);
275 throw err(s);
276 }
277
278 return true;
279 }
280
281 template<class C>
282 bool JSONDecoder::decode_json(const char *name, C& container, void (*cb)(C&, JSONObj *), JSONObj *obj, bool mandatory)
283 {
284 container.clear();
285
286 JSONObjIter iter = obj->find_first(name);
287 if (iter.end()) {
288 if (mandatory) {
289 string s = "missing mandatory field " + string(name);
290 throw err(s);
291 }
292 return false;
293 }
294
295 try {
296 decode_json_obj(container, cb, *iter);
297 } catch (err& e) {
298 string s = string(name) + ": ";
299 s.append(e.message);
300 throw err(s);
301 }
302
303 return true;
304 }
305
306 template<class T>
307 void JSONDecoder::decode_json(const char *name, T& val, T& default_val, JSONObj *obj)
308 {
309 JSONObjIter iter = obj->find_first(name);
310 if (iter.end()) {
311 val = default_val;
312 return;
313 }
314
315 try {
316 decode_json_obj(val, *iter);
317 } catch (err& e) {
318 val = default_val;
319 string s = string(name) + ": ";
320 s.append(e.message);
321 throw err(s);
322 }
323 }
324
325 template<class T>
326 static void encode_json(const char *name, const T& val, ceph::Formatter *f)
327 {
328 f->open_object_section(name);
329 val.dump(f);
330 f->close_section();
331 }
332
333 class utime_t;
334
335 void encode_json(const char *name, const string& val, ceph::Formatter *f);
336 void encode_json(const char *name, const char *val, ceph::Formatter *f);
337 void encode_json(const char *name, bool val, ceph::Formatter *f);
338 void encode_json(const char *name, int val, ceph::Formatter *f);
339 void encode_json(const char *name, unsigned val, ceph::Formatter *f);
340 void encode_json(const char *name, long val, ceph::Formatter *f);
341 void encode_json(const char *name, unsigned long val, ceph::Formatter *f);
342 void encode_json(const char *name, long long val, ceph::Formatter *f);
343 void encode_json(const char *name, const utime_t& val, ceph::Formatter *f);
344 void encode_json(const char *name, const bufferlist& bl, ceph::Formatter *f);
345 void encode_json(const char *name, long long unsigned val, ceph::Formatter *f);
346
347 template<class T>
348 static void encode_json(const char *name, const std::list<T>& l, ceph::Formatter *f)
349 {
350 f->open_array_section(name);
351 for (typename std::list<T>::const_iterator iter = l.begin(); iter != l.end(); ++iter) {
352 encode_json("obj", *iter, f);
353 }
354 f->close_section();
355 }
356 template<class T>
357 static void encode_json(const char *name, const std::deque<T>& l, ceph::Formatter *f)
358 {
359 f->open_array_section(name);
360 for (typename std::deque<T>::const_iterator iter = l.begin(); iter != l.end(); ++iter) {
361 encode_json("obj", *iter, f);
362 }
363 f->close_section();
364 }template<class T>
365 static void encode_json(const char *name, const std::set<T>& l, ceph::Formatter *f)
366 {
367 f->open_array_section(name);
368 for (typename std::set<T>::const_iterator iter = l.begin(); iter != l.end(); ++iter) {
369 encode_json("obj", *iter, f);
370 }
371 f->close_section();
372 }
373
374 template<class T>
375 static void encode_json(const char *name, const std::vector<T>& l, ceph::Formatter *f)
376 {
377 f->open_array_section(name);
378 for (typename std::vector<T>::const_iterator iter = l.begin(); iter != l.end(); ++iter) {
379 encode_json("obj", *iter, f);
380 }
381 f->close_section();
382 }
383
384 template<class K, class V, class C = std::less<K> >
385 static void encode_json(const char *name, const std::map<K, V, C>& m, ceph::Formatter *f)
386 {
387 f->open_array_section(name);
388 for (typename std::map<K, V, C>::const_iterator i = m.begin(); i != m.end(); ++i) {
389 f->open_object_section("entry");
390 encode_json("key", i->first, f);
391 encode_json("val", i->second, f);
392 f->close_section();
393 }
394 f->close_section();
395 }
396
397 template<class K, class V>
398 static void encode_json(const char *name, const std::multimap<K, V>& m, ceph::Formatter *f)
399 {
400 f->open_array_section(name);
401 for (typename std::multimap<K, V>::const_iterator i = m.begin(); i != m.end(); ++i) {
402 f->open_object_section("entry");
403 encode_json("key", i->first, f);
404 encode_json("val", i->second, f);
405 f->close_section();
406 }
407 f->close_section();
408 }
409 template<class K, class V>
410 void encode_json_map(const char *name, const map<K, V>& m, ceph::Formatter *f)
411 {
412 f->open_array_section(name);
413 typename map<K,V>::const_iterator iter;
414 for (iter = m.begin(); iter != m.end(); ++iter) {
415 encode_json("obj", iter->second, f);
416 }
417 f->close_section();
418 }
419
420
421 template<class K, class V>
422 void encode_json_map(const char *name, const char *index_name,
423 const char *object_name, const char *value_name,
424 void (*cb)(const char *, const V&, ceph::Formatter *, void *), void *parent,
425 const map<K, V>& m, ceph::Formatter *f)
426 {
427 f->open_array_section(name);
428 typename map<K,V>::const_iterator iter;
429 for (iter = m.begin(); iter != m.end(); ++iter) {
430 if (index_name) {
431 f->open_object_section("key_value");
432 f->dump_string(index_name, iter->first);
433 }
434
435 if (object_name) {
436 f->open_object_section(object_name);
437 }
438
439 if (cb) {
440 cb(value_name, iter->second, f, parent);
441 } else {
442 encode_json(value_name, iter->second, f);
443 }
444
445 if (object_name) {
446 f->close_section();
447 }
448 if (index_name) {
449 f->close_section();
450 }
451 }
452 f->close_section();
453 }
454
455 template<class K, class V>
456 void encode_json_map(const char *name, const char *index_name,
457 const char *object_name, const char *value_name,
458 const map<K, V>& m, ceph::Formatter *f)
459 {
460 encode_json_map<K, V>(name, index_name, object_name, value_name, NULL, NULL, m, f);
461 }
462
463 template<class K, class V>
464 void encode_json_map(const char *name, const char *index_name, const char *value_name,
465 const map<K, V>& m, ceph::Formatter *f)
466 {
467 encode_json_map<K, V>(name, index_name, NULL, value_name, NULL, NULL, m, f);
468 }
469
470 #endif