]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/ceph_json.cc
1 #include "common/ceph_json.h"
2 #include "include/utime.h"
4 // for testing DELETE ME
6 #include <include/types.h>
9 using namespace json_spirit
;
11 #define dout_subsys ceph_subsys_rgw
13 JSONObjIter::JSONObjIter()
17 JSONObjIter::~JSONObjIter()
21 void JSONObjIter::set(const JSONObjIter::map_iter_t
&_cur
, const JSONObjIter::map_iter_t
&_last
)
27 void JSONObjIter::operator++()
33 JSONObj
*JSONObjIter::operator*()
38 // does not work, FIXME
39 ostream
& operator<<(ostream
&out
, const JSONObj
&obj
) {
40 out
<< obj
.name
<< ": " << obj
.data_string
;
46 multimap
<string
, JSONObj
*>::iterator iter
;
47 for (iter
= children
.begin(); iter
!= children
.end(); ++iter
) {
48 JSONObj
*obj
= iter
->second
;
54 void JSONObj::add_child(string el
, JSONObj
*obj
)
56 children
.insert(pair
<string
, JSONObj
*>(el
, obj
));
59 bool JSONObj::get_attr(string name
, string
& attr
)
61 map
<string
, string
>::iterator iter
= attr_map
.find(name
);
62 if (iter
== attr_map
.end())
68 JSONObjIter
JSONObj::find(const string
& name
)
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
);
81 JSONObjIter
JSONObj::find_first()
84 iter
.set(children
.begin(), children
.end());
88 JSONObjIter
JSONObj::find_first(const string
& name
)
91 map
<string
, JSONObj
*>::iterator first
;
92 first
= children
.find(name
);
93 iter
.set(first
, children
.end());
97 JSONObj
*JSONObj::find_obj(const string
& name
)
99 JSONObjIter iter
= find(name
);
106 bool JSONObj::get_data(const string
& key
, string
*dest
)
108 JSONObj
*obj
= find_obj(key
);
112 *dest
= obj
->get_data();
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
121 void JSONObj::handle_value(Value v
)
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
);
133 } else if (v
.type() == array_type
) {
134 Array temp_array
= v
.get_array();
137 for (unsigned j
= 0; j
< temp_array
.size(); j
++) {
138 Value cur
= temp_array
[j
];
141 JSONObj
*child
= new JSONObj
;
142 child
->init(this, cur
, temp_name
);
143 add_child(child
->get_name(), child
);
148 void JSONObj::init(JSONObj
*p
, Value v
, string n
)
155 if (v
.type() == str_type
)
156 data_string
= v
.get_str();
158 data_string
= write(v
, raw_utf8
);
159 attr_map
.insert(pair
<string
,string
>(name
, data_string
));
162 JSONObj
*JSONObj::get_parent()
167 bool JSONObj::is_object()
169 return (data
.type() == obj_type
);
172 bool JSONObj::is_array()
174 return (data
.type() == array_type
);
177 vector
<string
> JSONObj::get_array_elements()
179 vector
<string
> elements
;
182 if (data
.type() == array_type
)
183 temp_array
= data
.get_array();
185 int array_size
= temp_array
.size();
187 for (int i
= 0; i
< array_size
; i
++) {
188 Value temp_value
= temp_array
[i
];
190 temp_string
= write(temp_value
, raw_utf8
);
191 elements
.push_back(temp_string
);
197 JSONParser::JSONParser() : buf_len(0), success(true)
201 JSONParser::~JSONParser()
207 void JSONParser::handle_data(const char *s
, int len
)
209 json_buffer
.append(s
, len
); // check for problems with null termination FIXME
213 // parse a supplied JSON fragment
214 bool JSONParser::parse(const char *buf_
, int len
)
221 string
json_string(buf_
, len
);
222 success
= read(json_string
, data
);
231 // parse the internal json_buffer up to len
232 bool JSONParser::parse(int len
)
234 string json_string
= json_buffer
.substr(0, len
);
235 success
= read(json_string
, data
);
244 // parse the complete internal json_buffer
245 bool JSONParser::parse()
247 success
= read(json_buffer
, data
);
256 // parse a supplied ifstream, for testing. DELETE ME
257 bool JSONParser::parse(const char *file_name
)
259 ifstream
is(file_name
);
260 success
= read(is
, data
);
270 void decode_json_obj(long& val
, JSONObj
*obj
)
272 string s
= obj
->get_data();
273 const char *start
= s
.c_str();
277 val
= strtol(start
, &p
, 10);
279 /* Check for various possible errors */
281 if ((errno
== ERANGE
&& (val
== LONG_MAX
|| val
== LONG_MIN
)) ||
282 (errno
!= 0 && val
== 0)) {
283 throw JSONDecoder::err("failed to parse number");
287 throw JSONDecoder::err("failed to parse number");
292 throw JSONDecoder::err("failed to parse number");
298 void decode_json_obj(unsigned long& val
, JSONObj
*obj
)
300 string s
= obj
->get_data();
301 const char *start
= s
.c_str();
305 val
= strtoul(start
, &p
, 10);
307 /* Check for various possible errors */
309 if ((errno
== ERANGE
&& val
== ULONG_MAX
) ||
310 (errno
!= 0 && val
== 0)) {
311 throw JSONDecoder::err("failed to number");
315 throw JSONDecoder::err("failed to parse number");
320 throw JSONDecoder::err("failed to parse number");
326 void decode_json_obj(long long& val
, JSONObj
*obj
)
328 string s
= obj
->get_data();
329 const char *start
= s
.c_str();
333 val
= strtoll(start
, &p
, 10);
335 /* Check for various possible errors */
337 if ((errno
== ERANGE
&& (val
== LLONG_MAX
|| val
== LLONG_MIN
)) ||
338 (errno
!= 0 && val
== 0)) {
339 throw JSONDecoder::err("failed to parse number");
343 throw JSONDecoder::err("failed to parse number");
348 throw JSONDecoder::err("failed to parse number");
354 void decode_json_obj(unsigned long long& val
, JSONObj
*obj
)
356 string s
= obj
->get_data();
357 const char *start
= s
.c_str();
361 val
= strtoull(start
, &p
, 10);
363 /* Check for various possible errors */
365 if ((errno
== ERANGE
&& val
== ULLONG_MAX
) ||
366 (errno
!= 0 && val
== 0)) {
367 throw JSONDecoder::err("failed to number");
371 throw JSONDecoder::err("failed to parse number");
376 throw JSONDecoder::err("failed to parse number");
382 void decode_json_obj(int& val
, JSONObj
*obj
)
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");
395 void decode_json_obj(unsigned& val
, JSONObj
*obj
)
398 decode_json_obj(l
, obj
);
399 #if ULONG_MAX > UINT_MAX
401 throw JSONDecoder::err("unsigned integer out of range");
408 void decode_json_obj(bool& val
, JSONObj
*obj
)
410 string s
= obj
->get_data();
411 if (strcasecmp(s
.c_str(), "true") == 0) {
415 if (strcasecmp(s
.c_str(), "false") == 0) {
420 decode_json_obj(i
, obj
);
424 void decode_json_obj(bufferlist
& val
, JSONObj
*obj
)
426 string s
= obj
->get_data();
429 bl
.append(s
.c_str(), s
.size());
431 val
.decode_base64(bl
);
432 } catch (buffer::error
& err
) {
433 throw JSONDecoder::err("failed to decode base64");
437 void decode_json_obj(utime_t
& val
, JSONObj
*obj
)
439 string s
= obj
->get_data();
442 int r
= utime_t::parse_date(s
, &epoch
, &nsec
);
444 val
= utime_t(epoch
, nsec
);
446 throw JSONDecoder::err("failed to decode utime_t");
450 void encode_json(const char *name
, const string
& val
, Formatter
*f
)
452 f
->dump_string(name
, val
);
455 void encode_json(const char *name
, const char *val
, Formatter
*f
)
457 f
->dump_string(name
, val
);
460 void encode_json(const char *name
, bool val
, Formatter
*f
)
468 f
->dump_string(name
, s
);
471 void encode_json(const char *name
, int val
, Formatter
*f
)
473 f
->dump_int(name
, val
);
476 void encode_json(const char *name
, long val
, Formatter
*f
)
478 f
->dump_int(name
, val
);
481 void encode_json(const char *name
, unsigned val
, Formatter
*f
)
483 f
->dump_unsigned(name
, val
);
486 void encode_json(const char *name
, unsigned long val
, Formatter
*f
)
488 f
->dump_unsigned(name
, val
);
491 void encode_json(const char *name
, unsigned long long val
, Formatter
*f
)
493 f
->dump_unsigned(name
, val
);
496 void encode_json(const char *name
, long long val
, Formatter
*f
)
498 f
->dump_int(name
, val
);
501 void encode_json(const char *name
, const utime_t
& val
, Formatter
*f
)
503 val
.gmtime(f
->dump_stream(name
));
506 void encode_json(const char *name
, const bufferlist
& bl
, Formatter
*f
)
508 /* need to copy data from bl, as it is const bufferlist */
512 src
.encode_base64(b64
);
514 string
s(b64
.c_str(), b64
.length());
516 encode_json(name
, s
, f
);