]>
git.proxmox.com Git - ceph.git/blob - ceph/src/common/ceph_json.h
6 #include <include/types.h>
7 #include <boost/container/flat_map.hpp>
9 #include "json_spirit/json_spirit.h"
11 #include "Formatter.h"
13 using namespace json_spirit
;
19 typedef std::map
<std::string
, JSONObj
*>::iterator map_iter_t
;
26 void set(const JSONObjIter::map_iter_t
&_cur
, const JSONObjIter::map_iter_t
&_end
);
44 void set(std::string_view s
, bool q
) {
50 std::string name
; // corresponds to obj_type in XMLObj
51 json_spirit::Value data
;
53 bool data_quoted
{false};
54 std::multimap
<std::string
, JSONObj
*> children
;
55 std::map
<std::string
, data_val
> attr_map
;
56 void handle_value(json_spirit::Value v
);
60 JSONObj() : parent(NULL
){}
64 void init(JSONObj
*p
, json_spirit::Value v
, std::string n
);
66 std::string
& get_name() { return name
; }
67 data_val
& get_data_val() { return val
; }
68 const std::string
& get_data() { return val
.str
; }
69 bool get_data(const std::string
& key
, data_val
*dest
);
70 JSONObj
*get_parent();
71 void add_child(std::string el
, JSONObj
*child
);
72 bool get_attr(std::string name
, data_val
& attr
);
73 JSONObjIter
find(const std::string
& name
);
74 JSONObjIter
find_first();
75 JSONObjIter
find_first(const std::string
& name
);
76 JSONObj
*find_obj(const std::string
& name
);
78 friend std::ostream
& operator<<(std::ostream
&out
,
79 const JSONObj
&obj
); // does not work, FIXME
83 std::vector
<std::string
> get_array_elements();
86 inline std::ostream
& operator<<(std::ostream
&out
, const JSONObj::data_val
& dv
) {
87 const char *q
= (dv
.quoted
? "\"" : "");
88 out
<< q
<< dv
.str
<< q
;
92 class JSONParser
: public JSONObj
95 std::string json_buffer
;
99 ~JSONParser() override
;
100 void handle_data(const char *s
, int len
);
102 bool parse(const char *buf_
, int len
);
105 bool parse(const char *file_name
);
107 const char *get_json() { return json_buffer
.c_str(); }
108 void set_failure() { success
= false; }
111 void encode_json(const char *name
, const JSONObj::data_val
& v
, ceph::Formatter
*f
);
115 struct err
: std::runtime_error
{
116 using runtime_error::runtime_error
;
121 JSONDecoder(ceph::buffer::list
& bl
) {
122 if (!parser
.parse(bl
.c_str(), bl
.length())) {
123 std::cout
<< "JSONDecoder::err()" << std::endl
;
124 throw JSONDecoder::err("failed to parse JSON input");
129 static bool decode_json(const char *name
, T
& val
, JSONObj
*obj
, bool mandatory
= false);
132 static bool decode_json(const char *name
, C
& container
, void (*cb
)(C
&, JSONObj
*obj
), JSONObj
*obj
, bool mandatory
= false);
135 static void decode_json(const char *name
, T
& val
, const T
& default_val
, JSONObj
*obj
);
138 static bool decode_json(const char *name
, boost::optional
<T
>& val
, JSONObj
*obj
, bool mandatory
= false);
141 static bool decode_json(const char *name
, std::optional
<T
>& val
, JSONObj
*obj
, bool mandatory
= false);
146 void decode_json_obj(T
& val
, JSONObj
*obj
)
148 val
.decode_json(obj
);
151 inline void decode_json_obj(std::string
& val
, JSONObj
*obj
)
153 val
= obj
->get_data();
156 static inline void decode_json_obj(JSONObj::data_val
& val
, JSONObj
*obj
)
158 val
= obj
->get_data_val();
161 void decode_json_obj(unsigned long long& val
, JSONObj
*obj
);
162 void decode_json_obj(long long& val
, JSONObj
*obj
);
163 void decode_json_obj(unsigned long& val
, JSONObj
*obj
);
164 void decode_json_obj(long& val
, JSONObj
*obj
);
165 void decode_json_obj(unsigned& val
, JSONObj
*obj
);
166 void decode_json_obj(int& val
, JSONObj
*obj
);
167 void decode_json_obj(bool& val
, JSONObj
*obj
);
168 void decode_json_obj(ceph::buffer::list
& val
, JSONObj
*obj
);
170 void decode_json_obj(utime_t
& val
, JSONObj
*obj
);
173 void decode_json_obj(std::list
<T
>& l
, JSONObj
*obj
)
177 JSONObjIter iter
= obj
->find_first();
179 for (; !iter
.end(); ++iter
) {
182 decode_json_obj(val
, o
);
188 void decode_json_obj(std::deque
<T
>& l
, JSONObj
*obj
)
192 JSONObjIter iter
= obj
->find_first();
194 for (; !iter
.end(); ++iter
) {
197 decode_json_obj(val
, o
);
203 void decode_json_obj(std::set
<T
>& l
, JSONObj
*obj
)
207 JSONObjIter iter
= obj
->find_first();
209 for (; !iter
.end(); ++iter
) {
212 decode_json_obj(val
, o
);
218 void decode_json_obj(std::vector
<T
>& l
, JSONObj
*obj
)
222 JSONObjIter iter
= obj
->find_first();
224 for (; !iter
.end(); ++iter
) {
227 decode_json_obj(val
, o
);
232 template<class K
, class V
, class C
= std::less
<K
> >
233 void decode_json_obj(std::map
<K
, V
, C
>& m
, JSONObj
*obj
)
237 JSONObjIter iter
= obj
->find_first();
239 for (; !iter
.end(); ++iter
) {
243 JSONDecoder::decode_json("key", key
, o
);
244 JSONDecoder::decode_json("val", val
, o
);
249 template<class K
, class V
>
250 void decode_json_obj(std::multimap
<K
, V
>& m
, JSONObj
*obj
)
254 JSONObjIter iter
= obj
->find_first();
256 for (; !iter
.end(); ++iter
) {
260 JSONDecoder::decode_json("key", key
, o
);
261 JSONDecoder::decode_json("val", val
, o
);
262 m
.insert(make_pair(key
, val
));
266 template<class K
, class V
>
267 void decode_json_obj(boost::container::flat_map
<K
, V
>& m
, JSONObj
*obj
)
271 JSONObjIter iter
= obj
->find_first();
273 for (; !iter
.end(); ++iter
) {
277 JSONDecoder::decode_json("key", key
, o
);
278 JSONDecoder::decode_json("val", val
, o
);
283 void decode_json_obj(C
& container
, void (*cb
)(C
&, JSONObj
*obj
), JSONObj
*obj
)
287 JSONObjIter iter
= obj
->find_first();
289 for (; !iter
.end(); ++iter
) {
296 bool JSONDecoder::decode_json(const char *name
, T
& val
, JSONObj
*obj
, bool mandatory
)
298 JSONObjIter iter
= obj
->find_first(name
);
301 std::string s
= "missing mandatory field " + std::string(name
);
309 decode_json_obj(val
, *iter
);
310 } catch (const err
& e
) {
311 std::string s
= std::string(name
) + ": ";
320 bool JSONDecoder::decode_json(const char *name
, C
& container
, void (*cb
)(C
&, JSONObj
*), JSONObj
*obj
, bool mandatory
)
324 JSONObjIter iter
= obj
->find_first(name
);
327 std::string s
= "missing mandatory field " + std::string(name
);
334 decode_json_obj(container
, cb
, *iter
);
335 } catch (const err
& e
) {
336 std::string s
= std::string(name
) + ": ";
345 void JSONDecoder::decode_json(const char *name
, T
& val
, const T
& default_val
, JSONObj
*obj
)
347 JSONObjIter iter
= obj
->find_first(name
);
354 decode_json_obj(val
, *iter
);
355 } catch (const err
& e
) {
357 std::string s
= std::string(name
) + ": ";
364 bool JSONDecoder::decode_json(const char *name
, boost::optional
<T
>& val
, JSONObj
*obj
, bool mandatory
)
366 JSONObjIter iter
= obj
->find_first(name
);
369 std::string s
= "missing mandatory field " + std::string(name
);
378 decode_json_obj(val
.get(), *iter
);
379 } catch (const err
& e
) {
381 std::string s
= std::string(name
) + ": ";
390 bool JSONDecoder::decode_json(const char *name
, std::optional
<T
>& val
, JSONObj
*obj
, bool mandatory
)
392 JSONObjIter iter
= obj
->find_first(name
);
395 std::string s
= "missing mandatory field " + std::string(name
);
404 decode_json_obj(*val
, *iter
);
405 } catch (const err
& e
) {
407 std::string s
= std::string(name
) + ": ";
415 class JSONEncodeFilter
420 virtual ~HandlerBase() {}
422 virtual std::type_index
get_type() = 0;
423 virtual void encode_json(const char *name
, const void *pval
, ceph::Formatter
*) const = 0;
427 class Handler
: public HandlerBase
{
429 virtual ~Handler() {}
431 std::type_index
get_type() override
{
432 return std::type_index(typeid(const T
&));
437 std::map
<std::type_index
, HandlerBase
*> handlers
;
440 void register_type(HandlerBase
*h
) {
441 handlers
[h
->get_type()] = h
;
445 bool encode_json(const char *name
, const T
& val
, ceph::Formatter
*f
) {
446 auto iter
= handlers
.find(std::type_index(typeid(val
)));
447 if (iter
== handlers
.end()) {
451 iter
->second
->encode_json(name
, (const void *)&val
, f
);
457 static void encode_json_impl(const char *name
, const T
& val
, ceph::Formatter
*f
)
459 f
->open_object_section(name
);
465 static void encode_json(const char *name
, const T
& val
, ceph::Formatter
*f
)
467 JSONEncodeFilter
*filter
= static_cast<JSONEncodeFilter
*>(f
->get_external_feature_handler("JSONEncodeFilter"));
470 !filter
->encode_json(name
, val
, f
)) {
471 encode_json_impl(name
, val
, f
);
477 void encode_json(const char *name
, const std::string
& val
, ceph::Formatter
*f
);
478 void encode_json(const char *name
, const char *val
, ceph::Formatter
*f
);
479 void encode_json(const char *name
, bool val
, ceph::Formatter
*f
);
480 void encode_json(const char *name
, int val
, ceph::Formatter
*f
);
481 void encode_json(const char *name
, unsigned val
, ceph::Formatter
*f
);
482 void encode_json(const char *name
, long val
, ceph::Formatter
*f
);
483 void encode_json(const char *name
, unsigned long val
, ceph::Formatter
*f
);
484 void encode_json(const char *name
, long long val
, ceph::Formatter
*f
);
485 void encode_json(const char *name
, const utime_t
& val
, ceph::Formatter
*f
);
486 void encode_json(const char *name
, const ceph::buffer::list
& bl
, ceph::Formatter
*f
);
487 void encode_json(const char *name
, long long unsigned val
, ceph::Formatter
*f
);
490 static void encode_json(const char *name
, const std::list
<T
>& l
, ceph::Formatter
*f
)
492 f
->open_array_section(name
);
493 for (auto iter
= l
.cbegin(); iter
!= l
.cend(); ++iter
) {
494 encode_json("obj", *iter
, f
);
500 static void encode_json(const char *name
, const std::deque
<T
>& l
, ceph::Formatter
*f
)
502 f
->open_array_section(name
);
503 for (auto iter
= l
.cbegin(); iter
!= l
.cend(); ++iter
) {
504 encode_json("obj", *iter
, f
);
509 template<class T
, class Compare
= std::less
<T
> >
510 static void encode_json(const char *name
, const std::set
<T
, Compare
>& l
, ceph::Formatter
*f
)
512 f
->open_array_section(name
);
513 for (auto iter
= l
.cbegin(); iter
!= l
.cend(); ++iter
) {
514 encode_json("obj", *iter
, f
);
520 static void encode_json(const char *name
, const std::vector
<T
>& l
, ceph::Formatter
*f
)
522 f
->open_array_section(name
);
523 for (auto iter
= l
.cbegin(); iter
!= l
.cend(); ++iter
) {
524 encode_json("obj", *iter
, f
);
529 template<class K
, class V
, class C
= std::less
<K
>>
530 static void encode_json(const char *name
, const std::map
<K
, V
, C
>& m
, ceph::Formatter
*f
)
532 f
->open_array_section(name
);
533 for (auto i
= m
.cbegin(); i
!= m
.cend(); ++i
) {
534 f
->open_object_section("entry");
535 encode_json("key", i
->first
, f
);
536 encode_json("val", i
->second
, f
);
542 template<class K
, class V
>
543 static void encode_json(const char *name
, const std::multimap
<K
, V
>& m
, ceph::Formatter
*f
)
545 f
->open_array_section(name
);
546 for (auto i
= m
.begin(); i
!= m
.end(); ++i
) {
547 f
->open_object_section("entry");
548 encode_json("key", i
->first
, f
);
549 encode_json("val", i
->second
, f
);
555 template<class K
, class V
>
556 static void encode_json(const char *name
, const boost::container::flat_map
<K
, V
>& m
, ceph::Formatter
*f
)
558 f
->open_array_section(name
);
559 for (auto i
= m
.begin(); i
!= m
.end(); ++i
) {
560 f
->open_object_section("entry");
561 encode_json("key", i
->first
, f
);
562 encode_json("val", i
->second
, f
);
568 template<class K
, class V
>
569 void encode_json_map(const char *name
, const std::map
<K
, V
>& m
, ceph::Formatter
*f
)
571 f
->open_array_section(name
);
572 for (auto iter
= m
.cbegin(); iter
!= m
.cend(); ++iter
) {
573 encode_json("obj", iter
->second
, f
);
579 template<class K
, class V
>
580 void encode_json_map(const char *name
, const char *index_name
,
581 const char *object_name
, const char *value_name
,
582 void (*cb
)(const char *, const V
&, ceph::Formatter
*, void *), void *parent
,
583 const std::map
<K
, V
>& m
, ceph::Formatter
*f
)
585 f
->open_array_section(name
);
586 for (auto iter
= m
.cbegin(); iter
!= m
.cend(); ++iter
) {
588 f
->open_object_section("key_value");
589 f
->dump_string(index_name
, iter
->first
);
593 f
->open_object_section(object_name
);
597 cb(value_name
, iter
->second
, f
, parent
);
599 encode_json(value_name
, iter
->second
, f
);
612 template<class K
, class V
>
613 void encode_json_map(const char *name
, const char *index_name
,
614 const char *object_name
, const char *value_name
,
615 const std::map
<K
, V
>& m
, ceph::Formatter
*f
)
617 encode_json_map
<K
, V
>(name
, index_name
, object_name
, value_name
, NULL
, NULL
, m
, f
);
620 template<class K
, class V
>
621 void encode_json_map(const char *name
, const char *index_name
, const char *value_name
,
622 const std::map
<K
, V
>& m
, ceph::Formatter
*f
)
624 encode_json_map
<K
, V
>(name
, index_name
, NULL
, value_name
, NULL
, NULL
, m
, f
);
628 static void encode_json(const char *name
, const std::optional
<T
>& o
, ceph::Formatter
*f
)
633 encode_json(name
, *o
, f
);
637 class JSONFormattable
: public ceph::JSONFormatter
{
638 JSONObj::data_val value
;
639 std::vector
<JSONFormattable
> arr
;
640 std::map
<std::string
, JSONFormattable
> obj
;
642 std::vector
<JSONFormattable
*> enc_stack
;
643 JSONFormattable
*cur_enc
;
646 bool handle_value(std::string_view name
, std::string_view s
, bool quoted
) override
;
647 bool handle_open_section(std::string_view name
, const char *ns
, bool section_is_array
) override
;
648 bool handle_close_section() override
;
651 JSONFormattable(bool p
= false) : JSONFormatter(p
) {
653 enc_stack
.push_back(cur_enc
);
663 void set_type(Type t
) {
667 void decode_json(JSONObj
*jo
) {
668 if (jo
->is_array()) {
669 set_type(JSONFormattable::FMT_ARRAY
);
670 decode_json_obj(arr
, jo
);
671 } else if (jo
->is_object()) {
672 set_type(JSONFormattable::FMT_OBJ
);
673 auto iter
= jo
->find_first();
674 for (;!iter
.end(); ++iter
) {
675 JSONObj
*field
= *iter
;
676 decode_json_obj(obj
[field
->get_name()], field
);
679 set_type(JSONFormattable::FMT_VALUE
);
680 decode_json_obj(value
, jo
);
684 void encode(ceph::buffer::list
& bl
) const {
685 ENCODE_START(2, 1, bl
);
686 encode((uint8_t)type
, bl
);
687 encode(value
.str
, bl
);
690 encode(value
.quoted
, bl
);
694 void decode(ceph::buffer::list::const_iterator
& bl
) {
699 decode(value
.str
, bl
);
703 decode(value
.quoted
, bl
);
710 const std::string
& val() const {
715 long val_long() const;
716 long long val_long_long() const;
717 bool val_bool() const;
719 const std::map
<std::string
, JSONFormattable
> object() const {
723 const std::vector
<JSONFormattable
>& array() const {
727 const JSONFormattable
& operator[](const std::string
& name
) const;
728 const JSONFormattable
& operator[](size_t index
) const;
730 JSONFormattable
& operator[](const std::string
& name
);
731 JSONFormattable
& operator[](size_t index
);
733 operator std::string() const {
737 explicit operator int() const {
741 explicit operator long() const {
745 explicit operator long long() const {
746 return val_long_long();
749 explicit operator bool() const {
754 T
operator[](const std::string
& name
) const {
755 return this->operator[](name
)(T());
759 T
operator[](const std::string
& name
) {
760 return this->operator[](name
)(T());
763 std::string
operator ()(const char *def_val
) const {
764 return def(std::string(def_val
));
767 int operator()(int def_val
) const {
771 bool operator()(bool def_val
) const {
775 bool exists(const std::string
& name
) const;
776 bool exists(size_t index
) const;
778 std::string
def(const std::string
& def_val
) const;
779 int def(int def_val
) const;
780 bool def(bool def_val
) const;
782 bool find(const std::string
& name
, std::string
*val
) const;
784 std::string
get(const std::string
& name
, const std::string
& def_val
) const;
786 int get_int(const std::string
& name
, int def_val
) const;
787 bool get_bool(const std::string
& name
, bool def_val
) const;
789 int set(const std::string
& name
, const std::string
& val
);
790 int erase(const std::string
& name
);
792 void derive_from(const JSONFormattable
& jf
);
794 void encode_json(const char *name
, ceph::Formatter
*f
) const;
796 bool is_array() const {
797 return (type
== FMT_ARRAY
);
800 WRITE_CLASS_ENCODER(JSONFormattable
)
802 void encode_json(const char *name
, const JSONFormattable
& v
, ceph::Formatter
*f
);