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