Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / common / ceph_json.cc
1 #include "common/ceph_json.h"
2 #include "include/utime.h"
3
4 // for testing DELETE ME
5 #include <fstream>
6 #include <include/types.h>
7
8 using namespace std;
9 using namespace json_spirit;
10
11 #define dout_subsys ceph_subsys_rgw
12
13 JSONObjIter::JSONObjIter()
14 {
15 }
16
17 JSONObjIter::~JSONObjIter()
18 {
19 }
20
21 void JSONObjIter::set(const JSONObjIter::map_iter_t &_cur, const JSONObjIter::map_iter_t &_last)
22 {
23   cur = _cur;
24   last = _last;
25 }
26
27 void JSONObjIter::operator++()
28 {
29   if (cur != last)
30     ++cur;
31 }
32
33 JSONObj *JSONObjIter::operator*()
34 {
35   return cur->second;
36 }
37
38 // does not work, FIXME
39 ostream& operator<<(ostream &out, const JSONObj &obj) {
40    out << obj.name << ": " << obj.data_string;
41    return out;
42 }
43
44 JSONObj::~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
54 void JSONObj::add_child(string el, JSONObj *obj)
55 {
56   children.insert(pair<string, JSONObj *>(el, obj));
57 }
58
59 bool 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
68 JSONObjIter 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
81 JSONObjIter JSONObj::find_first()
82 {
83   JSONObjIter iter;
84   iter.set(children.begin(), children.end());
85   return iter;
86 }
87
88 JSONObjIter 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
97 JSONObj *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
106 bool 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  */
121 void 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
148 void 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
162 JSONObj *JSONObj::get_parent()
163 {
164   return parent;
165 }
166
167 bool JSONObj::is_object()
168 {
169   return (data.type() == obj_type);
170 }
171
172 bool JSONObj::is_array()
173 {
174   return (data.type() == array_type);
175 }
176
177 vector<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
197 JSONParser::JSONParser() : buf_len(0), success(true)
198 {
199 }
200
201 JSONParser::~JSONParser()
202 {
203 }
204
205
206
207 void 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
214 bool 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
232 bool 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
245 bool 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
257 bool 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
270 void 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
298 void 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
326 void 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
354 void 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
382 void 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
395 void 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
408 void 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
424 void 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
437 void 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
450 void encode_json(const char *name, const string& val, Formatter *f)
451 {
452   f->dump_string(name, val);
453 }
454
455 void encode_json(const char *name, const char *val, Formatter *f)
456 {
457   f->dump_string(name, val);
458 }
459
460 void 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
471 void encode_json(const char *name, int val, Formatter *f)
472 {
473   f->dump_int(name, val);
474 }
475
476 void encode_json(const char *name, long val, Formatter *f)
477 {
478   f->dump_int(name, val);
479 }
480
481 void encode_json(const char *name, unsigned val, Formatter *f)
482 {
483   f->dump_unsigned(name, val);
484 }
485
486 void encode_json(const char *name, unsigned long val, Formatter *f)
487 {
488   f->dump_unsigned(name, val);
489 }
490
491 void encode_json(const char *name, unsigned long long val, Formatter *f)
492 {
493   f->dump_unsigned(name, val);
494 }
495
496 void encode_json(const char *name, long long val, Formatter *f)
497 {
498   f->dump_int(name, val);
499 }
500
501 void encode_json(const char *name, const utime_t& val, Formatter *f)
502 {
503   val.gmtime(f->dump_stream(name));
504 }
505
506 void 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