X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Fcommon%2Fceph_json.h;fp=src%2Fceph%2Fsrc%2Fcommon%2Fceph_json.h;h=cd868a88f4ed134fec87f58e11d2c4117f682938;hb=812ff6ca9fcd3e629e49d4328905f33eee8ca3f5;hp=0000000000000000000000000000000000000000;hpb=15280273faafb77777eab341909a3f495cf248d9;p=stor4nfv.git diff --git a/src/ceph/src/common/ceph_json.h b/src/ceph/src/common/ceph_json.h new file mode 100644 index 0000000..cd868a8 --- /dev/null +++ b/src/ceph/src/common/ceph_json.h @@ -0,0 +1,470 @@ +#ifndef CEPH_JSON_H +#define CEPH_JSON_H + +#include + +#ifdef _ASSERT_H +#define NEED_ASSERT_H +#pragma push_macro("_ASSERT_H") +#endif + +#include "json_spirit/json_spirit.h" +#undef _ASSERT_H + +#ifdef NEED_ASSERT_H +#pragma pop_macro("_ASSERT_H") +#endif + +#include "Formatter.h" + +using namespace json_spirit; + + +class JSONObj; + +class JSONObjIter { + typedef map::iterator map_iter_t; + map_iter_t cur; + map_iter_t last; + +public: + JSONObjIter(); + ~JSONObjIter(); + void set(const JSONObjIter::map_iter_t &_cur, const JSONObjIter::map_iter_t &_end); + + void operator++(); + JSONObj *operator*(); + + bool end() const { + return (cur == last); + } +}; + +class JSONObj +{ + JSONObj *parent; +protected: + string name; // corresponds to obj_type in XMLObj + Value data; + string data_string; + multimap children; + map attr_map; + void handle_value(Value v); + +public: + + JSONObj() : parent(NULL){} + + virtual ~JSONObj(); + + void init(JSONObj *p, Value v, string n); + + string& get_name() { return name; } + string& get_data() { return data_string; } + bool get_data(const string& key, string *dest); + JSONObj *get_parent(); + void add_child(string el, JSONObj *child); + bool get_attr(string name, string& attr); + JSONObjIter find(const string& name); + JSONObjIter find_first(); + JSONObjIter find_first(const string& name); + JSONObj *find_obj(const string& name); + + friend ostream& operator<<(ostream &out, + const JSONObj &obj); // does not work, FIXME + + bool is_array(); + bool is_object(); + vector get_array_elements(); +}; + +class JSONParser : public JSONObj +{ + int buf_len; + string json_buffer; + bool success; +public: + JSONParser(); + ~JSONParser() override; + void handle_data(const char *s, int len); + + bool parse(const char *buf_, int len); + bool parse(int len); + bool parse(); + bool parse(const char *file_name); + + const char *get_json() { return json_buffer.c_str(); } + void set_failure() { success = false; } +}; + + +class JSONDecoder { +public: + struct err { + string message; + + err(const string& m) : message(m) {} + }; + + JSONParser parser; + + JSONDecoder(bufferlist& bl) { + if (!parser.parse(bl.c_str(), bl.length())) { + cout << "JSONDecoder::err()" << std::endl; + throw JSONDecoder::err("failed to parse JSON input"); + } + } + + template + static bool decode_json(const char *name, T& val, JSONObj *obj, bool mandatory = false); + + template + static bool decode_json(const char *name, C& container, void (*cb)(C&, JSONObj *obj), JSONObj *obj, bool mandatory = false); + + template + static void decode_json(const char *name, T& val, T& default_val, JSONObj *obj); +}; + +template +void decode_json_obj(T& val, JSONObj *obj) +{ + val.decode_json(obj); +} + +static inline void decode_json_obj(string& val, JSONObj *obj) +{ + val = obj->get_data(); +} + +void decode_json_obj(unsigned long long& val, JSONObj *obj); +void decode_json_obj(long long& val, JSONObj *obj); +void decode_json_obj(unsigned long& val, JSONObj *obj); +void decode_json_obj(long& val, JSONObj *obj); +void decode_json_obj(unsigned& val, JSONObj *obj); +void decode_json_obj(int& val, JSONObj *obj); +void decode_json_obj(bool& val, JSONObj *obj); +void decode_json_obj(bufferlist& val, JSONObj *obj); +class utime_t; +void decode_json_obj(utime_t& val, JSONObj *obj); + +template +void decode_json_obj(list& l, JSONObj *obj) +{ + l.clear(); + + JSONObjIter iter = obj->find_first(); + + for (; !iter.end(); ++iter) { + T val; + JSONObj *o = *iter; + decode_json_obj(val, o); + l.push_back(val); + } +} + +template +void decode_json_obj(deque& l, JSONObj *obj) +{ + l.clear(); + + JSONObjIter iter = obj->find_first(); + + for (; !iter.end(); ++iter) { + T val; + JSONObj *o = *iter; + decode_json_obj(val, o); + l.push_back(val); + } +} + +template +void decode_json_obj(set& l, JSONObj *obj) +{ + l.clear(); + + JSONObjIter iter = obj->find_first(); + + for (; !iter.end(); ++iter) { + T val; + JSONObj *o = *iter; + decode_json_obj(val, o); + l.insert(val); + } +} + +template +void decode_json_obj(vector& l, JSONObj *obj) +{ + l.clear(); + + JSONObjIter iter = obj->find_first(); + + for (; !iter.end(); ++iter) { + T val; + JSONObj *o = *iter; + decode_json_obj(val, o); + l.push_back(val); + } +} + +template > +void decode_json_obj(map& m, JSONObj *obj) +{ + m.clear(); + + JSONObjIter iter = obj->find_first(); + + for (; !iter.end(); ++iter) { + K key; + V val; + JSONObj *o = *iter; + JSONDecoder::decode_json("key", key, o); + JSONDecoder::decode_json("val", val, o); + m[key] = val; + } +} + +template +void decode_json_obj(multimap& m, JSONObj *obj) +{ + m.clear(); + + JSONObjIter iter = obj->find_first(); + + for (; !iter.end(); ++iter) { + K key; + V val; + JSONObj *o = *iter; + JSONDecoder::decode_json("key", key, o); + JSONDecoder::decode_json("val", val, o); + m.insert(make_pair(key, val)); + } +} + +template +void decode_json_obj(C& container, void (*cb)(C&, JSONObj *obj), JSONObj *obj) +{ + container.clear(); + + JSONObjIter iter = obj->find_first(); + + for (; !iter.end(); ++iter) { + JSONObj *o = *iter; + cb(container, o); + } +} + +template +bool JSONDecoder::decode_json(const char *name, T& val, JSONObj *obj, bool mandatory) +{ + JSONObjIter iter = obj->find_first(name); + if (iter.end()) { + if (mandatory) { + string s = "missing mandatory field " + string(name); + throw err(s); + } + val = T(); + return false; + } + + try { + decode_json_obj(val, *iter); + } catch (err& e) { + string s = string(name) + ": "; + s.append(e.message); + throw err(s); + } + + return true; +} + +template +bool JSONDecoder::decode_json(const char *name, C& container, void (*cb)(C&, JSONObj *), JSONObj *obj, bool mandatory) +{ + container.clear(); + + JSONObjIter iter = obj->find_first(name); + if (iter.end()) { + if (mandatory) { + string s = "missing mandatory field " + string(name); + throw err(s); + } + return false; + } + + try { + decode_json_obj(container, cb, *iter); + } catch (err& e) { + string s = string(name) + ": "; + s.append(e.message); + throw err(s); + } + + return true; +} + +template +void JSONDecoder::decode_json(const char *name, T& val, T& default_val, JSONObj *obj) +{ + JSONObjIter iter = obj->find_first(name); + if (iter.end()) { + val = default_val; + return; + } + + try { + decode_json_obj(val, *iter); + } catch (err& e) { + val = default_val; + string s = string(name) + ": "; + s.append(e.message); + throw err(s); + } +} + +template +static void encode_json(const char *name, const T& val, ceph::Formatter *f) +{ + f->open_object_section(name); + val.dump(f); + f->close_section(); +} + +class utime_t; + +void encode_json(const char *name, const string& val, ceph::Formatter *f); +void encode_json(const char *name, const char *val, ceph::Formatter *f); +void encode_json(const char *name, bool val, ceph::Formatter *f); +void encode_json(const char *name, int val, ceph::Formatter *f); +void encode_json(const char *name, unsigned val, ceph::Formatter *f); +void encode_json(const char *name, long val, ceph::Formatter *f); +void encode_json(const char *name, unsigned long val, ceph::Formatter *f); +void encode_json(const char *name, long long val, ceph::Formatter *f); +void encode_json(const char *name, const utime_t& val, ceph::Formatter *f); +void encode_json(const char *name, const bufferlist& bl, ceph::Formatter *f); +void encode_json(const char *name, long long unsigned val, ceph::Formatter *f); + +template +static void encode_json(const char *name, const std::list& l, ceph::Formatter *f) +{ + f->open_array_section(name); + for (typename std::list::const_iterator iter = l.begin(); iter != l.end(); ++iter) { + encode_json("obj", *iter, f); + } + f->close_section(); +} +template +static void encode_json(const char *name, const std::deque& l, ceph::Formatter *f) +{ + f->open_array_section(name); + for (typename std::deque::const_iterator iter = l.begin(); iter != l.end(); ++iter) { + encode_json("obj", *iter, f); + } + f->close_section(); +}template +static void encode_json(const char *name, const std::set& l, ceph::Formatter *f) +{ + f->open_array_section(name); + for (typename std::set::const_iterator iter = l.begin(); iter != l.end(); ++iter) { + encode_json("obj", *iter, f); + } + f->close_section(); +} + +template +static void encode_json(const char *name, const std::vector& l, ceph::Formatter *f) +{ + f->open_array_section(name); + for (typename std::vector::const_iterator iter = l.begin(); iter != l.end(); ++iter) { + encode_json("obj", *iter, f); + } + f->close_section(); +} + +template > +static void encode_json(const char *name, const std::map& m, ceph::Formatter *f) +{ + f->open_array_section(name); + for (typename std::map::const_iterator i = m.begin(); i != m.end(); ++i) { + f->open_object_section("entry"); + encode_json("key", i->first, f); + encode_json("val", i->second, f); + f->close_section(); + } + f->close_section(); +} + +template +static void encode_json(const char *name, const std::multimap& m, ceph::Formatter *f) +{ + f->open_array_section(name); + for (typename std::multimap::const_iterator i = m.begin(); i != m.end(); ++i) { + f->open_object_section("entry"); + encode_json("key", i->first, f); + encode_json("val", i->second, f); + f->close_section(); + } + f->close_section(); +} +template +void encode_json_map(const char *name, const map& m, ceph::Formatter *f) +{ + f->open_array_section(name); + typename map::const_iterator iter; + for (iter = m.begin(); iter != m.end(); ++iter) { + encode_json("obj", iter->second, f); + } + f->close_section(); +} + + +template +void encode_json_map(const char *name, const char *index_name, + const char *object_name, const char *value_name, + void (*cb)(const char *, const V&, ceph::Formatter *, void *), void *parent, + const map& m, ceph::Formatter *f) +{ + f->open_array_section(name); + typename map::const_iterator iter; + for (iter = m.begin(); iter != m.end(); ++iter) { + if (index_name) { + f->open_object_section("key_value"); + f->dump_string(index_name, iter->first); + } + + if (object_name) { + f->open_object_section(object_name); + } + + if (cb) { + cb(value_name, iter->second, f, parent); + } else { + encode_json(value_name, iter->second, f); + } + + if (object_name) { + f->close_section(); + } + if (index_name) { + f->close_section(); + } + } + f->close_section(); +} + +template +void encode_json_map(const char *name, const char *index_name, + const char *object_name, const char *value_name, + const map& m, ceph::Formatter *f) +{ + encode_json_map(name, index_name, object_name, value_name, NULL, NULL, m, f); +} + +template +void encode_json_map(const char *name, const char *index_name, const char *value_name, + const map& m, ceph::Formatter *f) +{ + encode_json_map(name, index_name, NULL, value_name, NULL, NULL, m, f); +} + +#endif