分享

UC头条:c 好用的json解析类源码分享及简单使用

 cnzrp 2023-06-22 发布于山西

json数据解析,这是很常见的功能需求。c语言里有有名的cJSON库可用,当然c++里也可以直接用或者做个封装。但是可用不代表着就好用。有些情况下我们拿c++做开发而不是选择c,不就是为了开发上高效,维护上方便,可以做一些大项目么。

这里分享下封装的c++的好用的json解析库,不是原创。从OpenHarmony源码里摘出来的,所以可以放心用。直接学习优秀的开源项目代码好处多多,有时候是看书本学不来的。

摘自开源鸿蒙系统源码的JSUI框架代码。开源鸿蒙应用使用js开发,运行效率不用担心是因为框架使用的还是c++。

c++自从c++11标准之后真是焕然一新,使用变得简单且更好用了。从这个json解析源码里就能看出来一些:如使用了auto,lambda,智能指针等,智能指针的使用使得不用担心什么时候new的忘了释放掉这个心智负担,后续想new的地方要优先考虑使用智能指针。

条款21里有一条:尽量使用std::make_unique和std::make_shared而不直接使用new(《EffectiveModernC++》一书)。

c++需要注意的地方之一就是对内存的管理,动态内存的使用经常会出现内存泄漏,或者产生引用非法内存的指针。

新的标准库提供了两种智能指针类型来管理动态对象:

(1)shared_ptr允许多个指针指向同一个对象

(2)unique_ptr独占所指向的对象

定义在memory头文件中,他们的作用在于会自动释放所指向的对象。

unique_ptr是C++11提供的用于防止内存泄漏的智能指针中的一种实现,独享被管理对象指针所有权的智能指针。unique_ptr对象包装一个原始指针,并负责其生命周期。当该对象被销毁时,会在其析构函数中删除关联的原始指针。

unique_ptr具有->和*运算符重载符,因此它可以像普通指针一样使用。

unique_ptr不能直接复制,必须使用std::move转移其管理的指针,转移后原unique_ptr为空。

unique_ptr支持的操作(C++PrimerFifthEdition中文版一书):

这个json解析类的源码里,至少用到了c++14及以上的特性(从std::make_unique这个智能指针可看出),若你的工具链版本低可能不行。

gcc工具链从4.7.0之后开始支持c++11标准。GCC4.8.1完全支持c++11核心部分,对应的glibc为2.17,gcc4.9支持c++11正则表达式。gcc从哪个版本之后开始支持c++14?好像是GCCv6.1之后。

源码文件路径:code-v3.0-LTS\OpenHarmony\foundation\ace\ace_engine\frameworks\base\json

json_util.cpp和json_util.h

其实还是对cJSON库的封装:

#include'base/json/json_util.h'#include'cJSON.h'namespaceOHOS::Ace{JsonValue::JsonValue(JsonObject*object):object_(object){}JsonValue::JsonValue(JsonObject*object,boolisRoot):object_(object),isRoot_(isRoot){}JsonValue::~JsonValue{if(object_!=nullptr&&isRoot_){cJSON_Delete(object_);}object_=nullptr;}boolJsonValue::IsBoolconst{returncJSON_IsBool(object_);}boolJsonValue::IsNumberconst{returncJSON_IsNumber(object_);}boolJsonValue::IsStringconst{returncJSON_IsString(object_);}boolJsonValue::IsArrayconst{returncJSON_IsArray(object_);}boolJsonValue::IsObjectconst{returncJSON_IsObject(object_);}boolJsonValue::IsValidconst{return(object_!=nullptr)&&!cJSON_IsInvalid(object_);}boolJsonValue::IsNullconst{return(object_==nullptr)||cJSON_IsNull(object_);}boolJsonValue::Contains(conststd::string&key)const{returncJSON_HasObjectItem(object_,key.c_str);}boolJsonValue::GetBoolconst{returncJSON_IsTrue(object_)!=0;}boolJsonValue::GetBool(conststd::string&key,booldefaultValue)const{if(Contains(key)&&GetValue(key)->IsBool){returnGetValue(key)->GetBool;}returndefaultValue;}int32_tJsonValue::GetIntconst{returnstatic_cast((object_==nullptr)?0:object_->valuedouble);}uint32_tJsonValue::GetUIntconst{returnstatic_cast((object_==nullptr)?0:object_->valuedouble);}doubleJsonValue::GetDoubleconst{return(object_==nullptr)?0.0:object_->valuedouble;}doubleJsonValue::GetDouble(conststd::string&key,doubledefaultVal)const{autovalue=GetValue(key);if(value&&value->IsNumber){returnvalue->GetDouble;}returndefaultVal;}std::stringJsonValue::GetStringconst{return((object_==nullptr)||(object_->valuestring==nullptr))?'':std::string(object_->valuestring);}std::unique_ptrJsonValue::GetNextconst{if(object_==nullptr){returnstd::make_unique(nullptr);}returnstd::make_unique(object_->next);}std::unique_ptrJsonValue::GetChildconst{if(object_==nullptr){returnstd::make_unique(nullptr);}returnstd::make_unique(object_->child);}std::stringJsonValue::GetKeyconst{return((object_==nullptr)||(object_->string==nullptr))?'':std::string(object_->string);}std::unique_ptrJsonValue::GetValue(conststd::string&key)const{returnstd::make_unique(cJSON_GetObjectItem(object_,key.c_str));}std::unique_ptrJsonValue::GetObject(conststd::string&key)const{if(Contains(key)&&GetValue(key)->IsObject){returnGetValue(key);}returnstd::make_unique;}int32_tJsonValue::GetArraySizeconst{returncJSON_GetArraySize(object_);}std::unique_ptrJsonValue::GetArrayItem(int32_tindex)const{returnstd::make_unique(cJSON_GetArrayItem(object_,index));}boolJsonValue::Put(constchar*key,constchar*value){if(!value||!key){returnfalse;}cJSON*child=cJSON_CreateString(value);if(child==nullptr){returnfalse;}cJSON_AddItemToObject(object_,key,child);returntrue;}constJsonObject*JsonValue::GetJsonObjectconst{returnobject_;}boolJsonValue::Put(constchar*key,conststd::unique_ptr&value){if(!value||!key){returnfalse;}cJSON*jsonObject=cJSON_Duplicate(value->GetJsonObject,true);if(jsonObject==nullptr){returnfalse;}cJSON_AddItemToObject(object_,key,jsonObject);returntrue;}//additemtoarrayboolJsonValue::Put(conststd::unique_ptr&value){if(!value){returnfalse;}cJSON*jsonObject=cJSON_Duplicate(value->GetJsonObject,true);if(jsonObject==nullptr){returnfalse;}cJSON_AddItemToArray(object_,jsonObject);returntrue;}boolJsonValue::Put(constchar*key,size_tvalue){if(key==nullptr){returnfalse;}cJSON*child=cJSON_CreateNumber(static_cast(value));if(child==nullptr){returnfalse;}cJSON_AddItemToObject(object_,key,child);returntrue;}boolJsonValue::Put(constchar*key,int32_tvalue){if(key==nullptr){returnfalse;}cJSON*child=cJSON_CreateNumber(static_cast(value));if(child==nullptr){returnfalse;}cJSON_AddItemToObject(object_,key,child);returntrue;}boolJsonValue::Put(constchar*key,doublevalue){if(key==nullptr){returnfalse;}cJSON*child=cJSON_CreateNumber(value);if(child==nullptr){returnfalse;}cJSON_AddItemToObject(object_,key,child);returntrue;}boolJsonValue::Put(constchar*key,boolvalue){if(key==nullptr){returnfalse;}cJSON*child=cJSON_CreateBool(value);if(child==nullptr){returnfalse;}cJSON_AddItemToObject(object_,key,child);returntrue;}boolJsonValue::Replace(constchar*key,constchar*value){if((value==nullptr)||(key==nullptr)){returnfalse;}cJSON*child=cJSON_CreateString(value);if(child==nullptr){returnfalse;}if(!cJSON_ReplaceItemInObject(object_,key,child)){cJSON_Delete(child);returnfalse;}returntrue;}boolJsonValue::Replace(constchar*key,int32_tvalue){if(key==nullptr){returnfalse;}cJSON*child=cJSON_CreateNumber(static_cast(value));if(child==nullptr){returnfalse;}if(!cJSON_ReplaceItemInObject(object_,key,child)){cJSON_Delete(child);returnfalse;}returntrue;}boolJsonValue::Replace(constchar*key,conststd::unique_ptr&value){if((value==nullptr)||(key==nullptr)){returnfalse;}cJSON*jsonObject=cJSON_Duplicate(value->GetJsonObject,true);if(jsonObject==nullptr){returnfalse;}if(!cJSON_ReplaceItemInObject(object_,key,jsonObject)){cJSON_Delete(jsonObject);returnfalse;}returntrue;}boolJsonValue::Delete(constchar*key){if(key==nullptr){returnfalse;}cJSON_DeleteItemFromObject(object_,key);returntrue;}std::stringJsonValue::ToString{std::stringresult;if(!object_){returnresult;}//Itisnull-terminated.char*unformatted=cJSON_PrintUnformatted(object_);if(unformatted!=nullptr){result=unformatted;cJSON_free(unformatted);}returnresult;}std::stringJsonValue::GetString(conststd::string&key,conststd::string&defaultVal)const{autovalue=GetValue(key);if(value&&value->IsString){returnvalue->GetString;}returndefaultVal;}int32_tJsonValue::GetInt(conststd::string&key,int32_tdefaultVal)const{autovalue=GetValue(key);if(value&&value->IsNumber){returnvalue->GetInt;}returndefaultVal;}uint32_tJsonValue::GetUInt(conststd::string&key,uint32_tdefaultVal)const{autovalue=GetValue(key);if(value&&value->IsNumber){returnvalue->GetUInt;}returndefaultVal;}std::unique_ptrJsonUtil::ParseJsonData(constchar*data,constchar**parseEnd){returnstd::make_unique(cJSON_ParseWithOpts(data,parseEnd,true),true);}std::unique_ptrJsonUtil::ParseJsonString(conststd::string&content,constchar**parseEnd){returnParseJsonData(content.c_str,parseEnd);}std::unique_ptrJsonUtil::Create(boolisRoot){returnstd::make_unique(cJSON_CreateObject,isRoot);}std::unique_ptrJsonUtil::CreateArray(boolisRoot){returnstd::make_unique(cJSON_CreateArray,isRoot);}}//namespaceOHOS::Ace

#ifndefFOUNDATION_ACE_FRAMEWORKS_BASE_JSON_JSON_UTIL_H#defineFOUNDATION_ACE_FRAMEWORKS_BASE_JSON_JSON_UTIL_H#include#include#include'base/utils/macros.h'structcJSON;namespaceOHOS::Ace{usingJsonObject=cJSON;classACE_FORCE_EXPORTJsonValuefinal{public:JsonValue=default;explicitJsonValue(JsonObject*object);JsonValue(JsonObject*object,boolisRoot);~JsonValue;//checkfunctionsboolIsBoolconst;boolIsNumberconst;boolIsStringconst;boolIsArrayconst;boolIsObjectconst;boolIsValidconst;boolIsNullconst;boolContains(conststd::string&key)const;//getfunctionsboolGetBoolconst;boolGetBool(conststd::string&key,booldefaultValue=false)const;int32_tGetIntconst;int32_tGetInt(conststd::string&key,int32_tdefaultVal=0)const;uint32_tGetUIntconst;uint32_tGetUInt(conststd::string&key,uint32_tdefaultVal=0)const;doubleGetDoubleconst;doubleGetDouble(conststd::string&key,doubledefaultVal=0.0)const;std::stringGetStringconst;std::stringGetString(conststd::string&key,conststd::string&defaultVal='')const;std::unique_ptrGetNextconst;std::unique_ptrGetChildconst;std::stringGetKeyconst;std::unique_ptrGetValue(conststd::string&key)const;std::unique_ptrGetObject(conststd::string&key)const;int32_tGetArraySizeconst;std::unique_ptrGetArrayItem(int32_tindex)const;constJsonObject*GetJsonObjectconst;//putfunctionsboolPut(constchar*key,constchar*value);boolPut(constchar*key,size_tvalue);boolPut(constchar*key,int32_tvalue);boolPut(constchar*key,doublevalue);boolPut(constchar*key,boolvalue);boolPut(constchar*key,conststd::unique_ptr&value);boolPut(conststd::unique_ptr&value);//replacefunctionsboolReplace(constchar*key,constchar*value);boolReplace(constchar*key,int32_tvalue);boolReplace(constchar*key,conststd::unique_ptr&value);//deletefunctionsboolDelete(constchar*key);//serializestd::stringToString;private:JsonObject*object_=nullptr;boolisRoot_=false;};classACE_EXPORTJsonUtilfinal{public:JsonUtil=delete;~JsonUtil=delete;staticstd::unique_ptrParseJsonData(constchar*data,constchar**parseEnd=nullptr);staticstd::unique_ptrParseJsonString(conststd::string&content,constchar**parseEnd=nullptr);staticstd::unique_ptrCreate(boolisRoot);staticstd::unique_ptrCreateArray(boolisRoot);};}//namespaceOHOS::Ace#endif//FOUNDATION_ACE_FRAMEWORKS_BASE_JSON_JSON_UTIL_H

使用方法,如以下代码片段,定义了一个右值引用actionEventHandler,使用了lambda表达式写法,c++新语法用着就是美:

//actioneventhadnlerauto&&actionEventHandler=[this](conststd::string&action){LOGI('onActioncalledtoeventhandler');autoeventAction=JsonUtil::ParseJsonString(action);autobundleName=eventAction->GetValue('bundleName');autoabilityName=eventAction->GetValue('abilityName');autoparams=eventAction->GetValue('params');autobundle=bundleName->GetString;autoability=abilityName->GetString;LOGI('bundle:%{public}sability:%{public}s,params:%{public}s',bundle.c_str,ability.c_str,params->GetString.c_str);if(bundle.empty||ability.empty){LOGE('actionabilityorbundleisempty');return;}AAFwk::Wantwant;want.SetElementName(bundle,ability);this->StartAbility(want);};

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多