#pragma once #include #include #include struct cJSON; class gb_json { volatile int32_t ref_; std::mutex ref_mutex_; enum val_type { VAL_TYPE_NULL = 0, VAL_TYPE_BOOL, VAL_TYPE_INT, VAL_TYPE_FLOAT, VAL_TYPE_STRING, VAL_TYPE_OBJECT, VAL_TYPE_ARRAY, }; val_type type_; std::string key_; union { bool bval; int nval; double dval; }simple_val_; std::string strval_; std::vector arr_val_; size_t cur_child_; static std::string object_key(gb_json* jsn); static std::string array_key(gb_json* jsn); void from_cjson(cJSON* cj); gb_json* find_child(const char* key, bool remove = false); public: gb_json(char* json_txt = 0); gb_json(const char* key, bool val); gb_json(const char* key, int val); gb_json(const char* key, double val); gb_json(const char* key, const char* val); gb_json(const char* key, const std::string& val); protected: ~gb_json(); public: int32_t add_ref(); int32_t release(); public: // parse/un-parse ... bool attach_text(char* json_txt); void clear(bool as_array = false); std::string to_string(void); // attributes ... std::string& key(void); bool is_array(void); bool is_leaf_node(void); // whether this object is a leaf node contains final value // value access ... bool get_value(const char* key, bool& val); bool get_value(const char* key, int& val); bool get_value(const char* key, double& val); bool get_value(const char* key, std::string& val); bool get_value(const char* key, gb_json*& val); // enumeration ... size_t children(void); // return children count if was object or array, or else -1 returned gb_json* child(size_t ind); gb_json* first_child(void); gb_json* next_child(void); // change the item matching 'key', otherwise add a new item bool set_value(const char* key, bool val); bool set_value(const char* key, int val); bool set_value(const char* key, double val); bool set_value(const char* key, const char* val); bool set_value(const char* key, gb_json* val); // operator+= only for array gb_json& operator+=(bool val); gb_json& operator+=(int val); gb_json& operator+=(double val); gb_json& operator+=(const char* val); gb_json& operator+=(gb_json* val); // remove item gb_json& operator-=(int ind); bool remove(const char* key); bool remove(gb_json* child); bool remove(int ind); // position management, return index int index(gb_json* child); int index_move_to(gb_json* child, int ind); int insert(int ind, const char* key, gb_json* child); // leaf node value ... bool value(bool& val); bool value(int& val); bool value(double& val); bool value(std::string& val); gb_json& operator=(bool val); gb_json& operator=(int val); gb_json& operator=(double val); gb_json& operator=(const char* val); bool operator==(const gb_json& r); bool operator!=(const gb_json& r); // [2024-01-13] double value maybe consider as integer if the number just an integer, this method is to set numbre to right type // dbval - true: make integer to double and simple_val_.dval = simple_val_.nval; // false: make double to integer and simple_val_.nval = simple_val_.dval bool revise_number_type(bool dbval); }; #ifdef DUMP_JSON_OBJECT_LIFE void set_gbjson_life_callback(void(*life)(gb_json*, bool, void*), void* param); #endif