]> git.proxmox.com Git - ceph.git/blame - ceph/src/common/ceph_json.cc
update sources to v12.1.0
[ceph.git] / ceph / src / common / ceph_json.cc
CommitLineData
7c673cae
FG
1#include "common/ceph_json.h"
2#include "include/utime.h"
3
4// for testing DELETE ME
5#include <fstream>
31f18b77 6#include <include/types.h>
7c673cae
FG
7
8using namespace std;
9using namespace json_spirit;
10
11#define dout_subsys ceph_subsys_rgw
12
13JSONObjIter::JSONObjIter()
14{
15}
16
17JSONObjIter::~JSONObjIter()
18{
19}
20
21void JSONObjIter::set(const JSONObjIter::map_iter_t &_cur, const JSONObjIter::map_iter_t &_last)
22{
23 cur = _cur;
24 last = _last;
25}
26
27void JSONObjIter::operator++()
28{
29 if (cur != last)
30 ++cur;
31}
32
33JSONObj *JSONObjIter::operator*()
34{
35 return cur->second;
36}
37
38// does not work, FIXME
39ostream& operator<<(ostream &out, const JSONObj &obj) {
40 out << obj.name << ": " << obj.data_string;
41 return out;
42}
43
44JSONObj::~JSONObj()
45{
46 multimap<string, JSONObj *>::iterator iter;
47 for (iter = children.begin(); iter != children.end(); ++iter) {
48 JSONObj *obj = iter->second;
49 delete obj;
50 }
51}
52
53
54void JSONObj::add_child(string el, JSONObj *obj)
55{
56 children.insert(pair<string, JSONObj *>(el, obj));
57}
58
59bool JSONObj::get_attr(string name, string& attr)
60{
61 map<string, string>::iterator iter = attr_map.find(name);
62 if (iter == attr_map.end())
63 return false;
64 attr = iter->second;
65 return true;
66}
67
68JSONObjIter JSONObj::find(const string& name)
69{
70 JSONObjIter iter;
71 map<string, JSONObj *>::iterator first;
72 map<string, JSONObj *>::iterator last;
73 first = children.find(name);
74 if (first != children.end()) {
75 last = children.upper_bound(name);
76 iter.set(first, last);
77 }
78 return iter;
79}
80
81JSONObjIter JSONObj::find_first()
82{
83 JSONObjIter iter;
84 iter.set(children.begin(), children.end());
85 return iter;
86}
87
88JSONObjIter JSONObj::find_first(const string& name)
89{
90 JSONObjIter iter;
91 map<string, JSONObj *>::iterator first;
92 first = children.find(name);
93 iter.set(first, children.end());
94 return iter;
95}
96
97JSONObj *JSONObj::find_obj(const string& name)
98{
99 JSONObjIter iter = find(name);
100 if (iter.end())
101 return NULL;
102
103 return *iter;
104}
105
106bool JSONObj::get_data(const string& key, string *dest)
107{
108 JSONObj *obj = find_obj(key);
109 if (!obj)
110 return false;
111
112 *dest = obj->get_data();
113
114 return true;
115}
116
117/* accepts a JSON Array or JSON Object contained in
118 * a JSON Spirit Value, v, and creates a JSONObj for each
119 * child contained in v
120 */
121void JSONObj::handle_value(Value v)
122{
123 if (v.type() == obj_type) {
124 Object temp_obj = v.get_obj();
125 for (Object::size_type i = 0; i < temp_obj.size(); i++) {
126 Pair temp_pair = temp_obj[i];
127 string temp_name = temp_pair.name_;
128 Value temp_value = temp_pair.value_;
129 JSONObj *child = new JSONObj;
130 child->init(this, temp_value, temp_name);
131 add_child(temp_name, child);
132 }
133 } else if (v.type() == array_type) {
134 Array temp_array = v.get_array();
135 Value value;
136
137 for (unsigned j = 0; j < temp_array.size(); j++) {
138 Value cur = temp_array[j];
139 string temp_name;
140
141 JSONObj *child = new JSONObj;
142 child->init(this, cur, temp_name);
143 add_child(child->get_name(), child);
144 }
145 }
146}
147
148void JSONObj::init(JSONObj *p, Value v, string n)
149{
150 name = n;
151 parent = p;
152 data = v;
153
154 handle_value(v);
155 if (v.type() == str_type)
156 data_string = v.get_str();
157 else
158 data_string = write(v, raw_utf8);
159 attr_map.insert(pair<string,string>(name, data_string));
160}
161
162JSONObj *JSONObj::get_parent()
163{
164 return parent;
165}
166
167bool JSONObj::is_object()
168{
169 return (data.type() == obj_type);
170}
171
172bool JSONObj::is_array()
173{
174 return (data.type() == array_type);
175}
176
177vector<string> JSONObj::get_array_elements()
178{
179 vector<string> elements;
180 Array temp_array;
181
182 if (data.type() == array_type)
183 temp_array = data.get_array();
184
185 int array_size = temp_array.size();
186 if (array_size > 0)
187 for (int i = 0; i < array_size; i++) {
188 Value temp_value = temp_array[i];
189 string temp_string;
190 temp_string = write(temp_value, raw_utf8);
191 elements.push_back(temp_string);
192 }
193
194 return elements;
195}
196
197JSONParser::JSONParser() : buf_len(0), success(true)
198{
199}
200
201JSONParser::~JSONParser()
202{
203}
204
205
206
207void JSONParser::handle_data(const char *s, int len)
208{
209 json_buffer.append(s, len); // check for problems with null termination FIXME
210 buf_len += len;
211}
212
213// parse a supplied JSON fragment
214bool JSONParser::parse(const char *buf_, int len)
215{
216 if (!buf_) {
217 set_failure();
218 return false;
219 }
220
221 string json_string(buf_, len);
222 success = read(json_string, data);
223 if (success)
224 handle_value(data);
225 else
226 set_failure();
227
228 return success;
229}
230
231// parse the internal json_buffer up to len
232bool JSONParser::parse(int len)
233{
234 string json_string = json_buffer.substr(0, len);
235 success = read(json_string, data);
236 if (success)
237 handle_value(data);
238 else
239 set_failure();
240
241 return success;
242}
243
244// parse the complete internal json_buffer
245bool JSONParser::parse()
246{
247 success = read(json_buffer, data);
248 if (success)
249 handle_value(data);
250 else
251 set_failure();
252
253 return success;
254}
255
256// parse a supplied ifstream, for testing. DELETE ME
257bool JSONParser::parse(const char *file_name)
258{
259 ifstream is(file_name);
260 success = read(is, data);
261 if (success)
262 handle_value(data);
263 else
264 set_failure();
265
266 return success;
267}
268
269
270void decode_json_obj(long& val, JSONObj *obj)
271{
272 string s = obj->get_data();
273 const char *start = s.c_str();
274 char *p;
275
276 errno = 0;
277 val = strtol(start, &p, 10);
278
279 /* Check for various possible errors */
280
281 if ((errno == ERANGE && (val == LONG_MAX || val == LONG_MIN)) ||
282 (errno != 0 && val == 0)) {
283 throw JSONDecoder::err("failed to parse number");
284 }
285
286 if (p == start) {
287 throw JSONDecoder::err("failed to parse number");
288 }
289
290 while (*p != '\0') {
291 if (!isspace(*p)) {
292 throw JSONDecoder::err("failed to parse number");
293 }
294 p++;
295 }
296}
297
298void decode_json_obj(unsigned long& val, JSONObj *obj)
299{
300 string s = obj->get_data();
301 const char *start = s.c_str();
302 char *p;
303
304 errno = 0;
305 val = strtoul(start, &p, 10);
306
307 /* Check for various possible errors */
308
309 if ((errno == ERANGE && val == ULONG_MAX) ||
310 (errno != 0 && val == 0)) {
311 throw JSONDecoder::err("failed to number");
312 }
313
314 if (p == start) {
315 throw JSONDecoder::err("failed to parse number");
316 }
317
318 while (*p != '\0') {
319 if (!isspace(*p)) {
320 throw JSONDecoder::err("failed to parse number");
321 }
322 p++;
323 }
324}
325
326void decode_json_obj(long long& val, JSONObj *obj)
327{
328 string s = obj->get_data();
329 const char *start = s.c_str();
330 char *p;
331
332 errno = 0;
333 val = strtoll(start, &p, 10);
334
335 /* Check for various possible errors */
336
337 if ((errno == ERANGE && (val == LLONG_MAX || val == LLONG_MIN)) ||
338 (errno != 0 && val == 0)) {
339 throw JSONDecoder::err("failed to parse number");
340 }
341
342 if (p == start) {
343 throw JSONDecoder::err("failed to parse number");
344 }
345
346 while (*p != '\0') {
347 if (!isspace(*p)) {
348 throw JSONDecoder::err("failed to parse number");
349 }
350 p++;
351 }
352}
353
354void decode_json_obj(unsigned long long& val, JSONObj *obj)
355{
356 string s = obj->get_data();
357 const char *start = s.c_str();
358 char *p;
359
360 errno = 0;
361 val = strtoull(start, &p, 10);
362
363 /* Check for various possible errors */
364
365 if ((errno == ERANGE && val == ULLONG_MAX) ||
366 (errno != 0 && val == 0)) {
367 throw JSONDecoder::err("failed to number");
368 }
369
370 if (p == start) {
371 throw JSONDecoder::err("failed to parse number");
372 }
373
374 while (*p != '\0') {
375 if (!isspace(*p)) {
376 throw JSONDecoder::err("failed to parse number");
377 }
378 p++;
379 }
380}
381
382void decode_json_obj(int& val, JSONObj *obj)
383{
384 long l;
385 decode_json_obj(l, obj);
386#if LONG_MAX > INT_MAX
387 if (l > INT_MAX || l < INT_MIN) {
388 throw JSONDecoder::err("integer out of range");
389 }
390#endif
391
392 val = (int)l;
393}
394
395void decode_json_obj(unsigned& val, JSONObj *obj)
396{
397 unsigned long l;
398 decode_json_obj(l, obj);
399#if ULONG_MAX > UINT_MAX
400 if (l > UINT_MAX) {
401 throw JSONDecoder::err("unsigned integer out of range");
402 }
403#endif
404
405 val = (unsigned)l;
406}
407
408void decode_json_obj(bool& val, JSONObj *obj)
409{
410 string s = obj->get_data();
411 if (strcasecmp(s.c_str(), "true") == 0) {
412 val = true;
413 return;
414 }
415 if (strcasecmp(s.c_str(), "false") == 0) {
416 val = false;
417 return;
418 }
419 int i;
420 decode_json_obj(i, obj);
421 val = (bool)i;
422}
423
424void decode_json_obj(bufferlist& val, JSONObj *obj)
425{
426 string s = obj->get_data();
427
428 bufferlist bl;
429 bl.append(s.c_str(), s.size());
430 try {
431 val.decode_base64(bl);
432 } catch (buffer::error& err) {
433 throw JSONDecoder::err("failed to decode base64");
434 }
435}
436
437void decode_json_obj(utime_t& val, JSONObj *obj)
438{
439 string s = obj->get_data();
440 uint64_t epoch;
441 uint64_t nsec;
442 int r = utime_t::parse_date(s, &epoch, &nsec);
443 if (r == 0) {
444 val = utime_t(epoch, nsec);
445 } else {
446 throw JSONDecoder::err("failed to decode utime_t");
447 }
448}
449
450void encode_json(const char *name, const string& val, Formatter *f)
451{
452 f->dump_string(name, val);
453}
454
455void encode_json(const char *name, const char *val, Formatter *f)
456{
457 f->dump_string(name, val);
458}
459
460void encode_json(const char *name, bool val, Formatter *f)
461{
462 string s;
463 if (val)
464 s = "true";
465 else
466 s = "false";
467
468 f->dump_string(name, s);
469}
470
471void encode_json(const char *name, int val, Formatter *f)
472{
473 f->dump_int(name, val);
474}
475
476void encode_json(const char *name, long val, Formatter *f)
477{
478 f->dump_int(name, val);
479}
480
481void encode_json(const char *name, unsigned val, Formatter *f)
482{
483 f->dump_unsigned(name, val);
484}
485
486void encode_json(const char *name, unsigned long val, Formatter *f)
487{
488 f->dump_unsigned(name, val);
489}
490
491void encode_json(const char *name, unsigned long long val, Formatter *f)
492{
493 f->dump_unsigned(name, val);
494}
495
496void encode_json(const char *name, long long val, Formatter *f)
497{
498 f->dump_int(name, val);
499}
500
501void encode_json(const char *name, const utime_t& val, Formatter *f)
502{
503 val.gmtime(f->dump_stream(name));
504}
505
506void encode_json(const char *name, const bufferlist& bl, Formatter *f)
507{
508 /* need to copy data from bl, as it is const bufferlist */
509 bufferlist src = bl;
510
511 bufferlist b64;
512 src.encode_base64(b64);
513
514 string s(b64.c_str(), b64.length());
515
516 encode_json(name, s, f);
517}
518