#include "json.h" #include #include #if defined(WIN32) || defined(_WIN64) #define bzero(b, s) memset(b, 0, s) #endif json::json(char* json_txt) : obj_(0), cur_child_(0) { attach_text(json_txt); } json::~json() { clear(); } std::string json::to_string(cJSON* root) { char* txt = cJSON_Print(root); std::string ret(txt ? txt : ""); if (txt) free(txt); return ret; } std::string json::get_value_as_string(cJSON* root, bool integer) { std::string ret(""); switch (root->type) { case cJSON_False: ret = "false"; break; case cJSON_True: ret = "true"; break; case cJSON_NULL: ret = "null"; break; case cJSON_Number: { char buf[40]; if (integer) sprintf(buf, "%d", root->valueint); else sprintf(buf, "%f", root->valuedouble); ret = buf; } break; case cJSON_String: if (root->valuestring) ret = root->valuestring; break; default: ret = json::to_string(root); break; } return ret; } cJSON* json::find_child(cJSON *parent, const char* child_name) { if (!parent) return 0; cJSON *child = parent->child; while (child) { if (child->string && strcmp(child->string, child_name) == 0) break; child = child->next; } return child; } cJSON* json::find(const char* path) { cJSON *found = obj_; if (path && *path) { std::string all(path); char *cur = strtok(&all[0], "/"); while (cur) { found = find_child(found, cur); if (!found) break; cur = strtok(0, "/"); } } return found; } bool json::attach_text(char* json_txt) { clear(); obj_ = cJSON_Parse(json_txt); return obj_ != 0; } bool json::attach_cjson(cJSON* cjson) { clear(); if (cjson) { std::string txt(json::to_string(cjson)); if (txt.length()) obj_ = cJSON_Parse(txt.c_str()); } return obj_ != 0; } void json::clear(void) { if (obj_) { cJSON_Delete(obj_); obj_ = 0; } } std::string json::to_string(void) { if (obj_) return json::to_string(obj_); else return ""; } bool json::get_value(const char* key, bool& val) { cJSON* obj = find(key); if (!obj) return false; if (obj->type == cJSON_True) val = true; else if (obj->type == cJSON_False) val = false; else return false; return true; } bool json::get_value(const char* key, int& val) { cJSON* obj = find(key); if (!obj) return false; if (obj->type != cJSON_Number) return false; val = obj->valueint; return true; } bool json::get_value(const char* key, double& val) { cJSON *obj = find(key); if (!obj) return false; if (obj->type != cJSON_Number) return false; val = obj->valuedouble; return true; } bool json::get_value(const char* key, std::string& val) { cJSON *obj = find(key); if (!obj) return false; if (obj->type != cJSON_String) return false; val = obj->valuestring ? obj->valuestring : ""; return true; } bool json::get_value(const char* key, json*& val) { cJSON *obj = find(key); if (!obj) return false; val = new json(); if (!val->attach_cjson(obj)) { delete val; return false; } return true; } bool json::get_value_as_string(const char* key, std::string& val, bool integer) { cJSON* obj = find(key); if (!obj) return false; val = json::get_value_as_string(obj, integer); return true; } bool json::get_as_array(const char* key, std::vector& val) { cJSON *obj = find(key); val.clear(); if (obj && obj->type == cJSON_Array) { cJSON *child = obj->child; while (child) { if (child->type == cJSON_Number) { char buf[40]; sprintf(buf, "%d", child->valueint); val.push_back(buf); } else if (child->type == cJSON_String) val.push_back(child->valuestring ? child->valuestring : ""); else { char *text = cJSON_Print(child); val.push_back(text); free(text); } child = child->next; } return true; } return false; } bool json::first_child(std::string& val) { cur_child_ = obj_->child; val = ""; if (cur_child_) { val = json::get_value_as_string(cur_child_); return true; } else { return false; } } bool json::next_child(std::string& val) { if (cur_child_) cur_child_ = cur_child_->next; val = ""; if (cur_child_) { val = json::get_value_as_string(cur_child_); return true; } else { return false; } } bool json::set_value(const char* key, bool val) { cJSON* ele = this->find(key); if (!ele) return false; if (ele->type == cJSON_String) free(ele->valuestring); if (val) ele->type = cJSON_True; else ele->type = cJSON_False; return true; } bool json::set_value(const char* key, int val) { cJSON* ele = this->find(key); if (!ele) return false; if (ele->type == cJSON_String) free(ele->valuestring); ele->type = cJSON_Number; ele->valuedouble = ele->valueint = val; return true; } bool json::set_value(const char* key, double val) { cJSON* ele = this->find(key); if (!ele) return false; if (ele->type == cJSON_String) free(ele->valuestring); ele->type = cJSON_Number; ele->valuedouble = val; return true; } bool json::set_value(const char* key, std::string val) { cJSON* ele = this->find(key); if (!ele) return false; if (ele->type == cJSON_String) free(ele->valuestring); ele->type = cJSON_String; ele->valuestring = (char*)malloc(val.length() + 4); bzero(ele->valuestring, val.length() + 4); strcpy(ele->valuestring, val.c_str()); return true; }