8 Star 29 Fork 21

10km / common_source_cpp

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
克隆/下载
json_utilits.hpp 8.03 KB
一键复制 编辑 原始数据 按行查看 历史
/*
* json_utilits.hpp
*
* Created on: 2021年10月15日
* Author: guyadong
*/
#ifndef COMMON_SOURCE_CPP_JSON_UTILITS_HPP_
#define COMMON_SOURCE_CPP_JSON_UTILITS_HPP_
#include <regex>
#include <mutex>
#include "base64.hpp"
#include "nlohmann/json.hpp"
#ifndef _BASIC_JSON_TPL_PARAMS_
#define _BASIC_JSON_TPL_PARAMS_ \
ObjectType, ArrayType, StringType, BooleanType, \
NumberIntegerType, NumberUnsignedType, NumberFloatType, \
AllocatorType, JSONSerializer, BinaryType
#endif // !_BASIC_JSON_TPL_PARAMS_
#ifndef _BASIC_JSON_TPL_PARAM_DECL_
#define _BASIC_JSON_TPL_PARAM_DECL_ \
template<typename U, typename V, typename... Args> class ObjectType = std::map, \
template<typename U, typename... Args> class ArrayType = std::vector, \
class StringType = std::string, class BooleanType = bool, \
class NumberIntegerType = std::int64_t, \
class NumberUnsignedType = std::uint64_t, \
class NumberFloatType = double, \
template<typename U> class AllocatorType = std::allocator, \
template<typename T, typename SFINAE = void> class JSONSerializer = nlohmann::adl_serializer, \
class BinaryType = std::vector<std::uint8_t>
#endif // !_BASIC_JSON_TPL_PARAM_DECL_
#ifndef _BASIC_JSON_TPL_DECLARATION_
#define _BASIC_JSON_TPL_DECLARATION_ template<_BASIC_JSON_TPL_PARAM_DECL_>
#endif // !_BASIC_JSON_TPL_DECLARATION_
#ifndef _BASIC_JSON_TPL_
#define _BASIC_JSON_TPL_ \
nlohmann::basic_json<ObjectType, ArrayType, StringType, BooleanType, \
NumberIntegerType, NumberUnsignedType, NumberFloatType, \
AllocatorType, JSONSerializer, BinaryType>
#endif // ! _BASIC_JSON_TPL_
namespace json_utilits{
template<typename VTYPE, _BASIC_JSON_TPL_PARAM_DECL_>
VTYPE get_value(const _BASIC_JSON_TPL_ & params, const std::string& name, const VTYPE & defaultValue)
{
if (params.contains(name))
{
return params[name].template get<VTYPE>();
}
return defaultValue;
}
_BASIC_JSON_TPL_DECLARATION_
_BASIC_JSON_TPL_ get_value(const _BASIC_JSON_TPL_ & params, const std::string& name, const _BASIC_JSON_TPL_ & defaultValue)
{
if (params.contains(name))
{
return params[name];
}
return defaultValue;
}
/**
* 如果value不为空保存到params中 name 指定字段
*/
_BASIC_JSON_TPL_DECLARATION_
void set_value_noempty(_BASIC_JSON_TPL_ & params, const std::string& name, const std::string & value)
{
if (!value.empty())
{
params[name] = value;
}
}
/**
* 如果value大于0保存到params中 name 指定字段
*/
template<typename VTYPE, _BASIC_JSON_TPL_PARAM_DECL_>
typename std::enable_if<std::is_arithmetic<VTYPE>::value,void>::type
set_value_gt0(_BASIC_JSON_TPL_ & params, const std::string& name, VTYPE value)
{
if (value > 0)
{
params[name] = value;
}
}
/**
* 如果value不为0保存到params中 name 指定字段
*/
template<typename VTYPE, _BASIC_JSON_TPL_PARAM_DECL_>
typename std::enable_if<std::is_arithmetic<VTYPE>::value, void>::type
set_value_ne0(_BASIC_JSON_TPL_ & params, const std::string& name, VTYPE value)
{
if (value != 0)
{
params[name] = value;
}
}
template<typename VTYPE,_BASIC_JSON_TPL_PARAM_DECL_>
void fill_field(VTYPE& output, const _BASIC_JSON_TPL_ & j, const std::string &field)
{
if (j.contains(field))output = j[field].template get<VTYPE>();
}
_BASIC_JSON_TPL_DECLARATION_
void fill_field(_BASIC_JSON_TPL_& output, const _BASIC_JSON_TPL_ & j, const std::string &field)
{
if (j.contains(field))output = j[field];
}
/**
* 返回枚举类型变量的名字字符串
* 枚举类型 ETYPE 必须支持 nlohmann::json 的名字序列化和返序列
*/
template<typename ETYPE, _BASIC_JSON_TPL_PARAM_DECL_>
static const std::string& name_of(ETYPE e, const _BASIC_JSON_TPL_ & ununsed = nlohmann::json())
{
static std::map<ETYPE, std::string> names;
static std::mutex name_mutex;
if (!names.count(e))
{
// double check
std::lock_guard<std::mutex> guard(name_mutex);
if (!names.count(e))
{
_BASIC_JSON_TPL_ j;
to_json(j, e);
names[e] = std::regex_replace(j.dump(), std::regex("^\"(.*)\"$"), "$1");
}
}
return names[e];
}
/** 将类型为string的BASE64编译的字符串转为解码的string json 对象 */
_BASIC_JSON_TPL_DECLARATION_
void from_base64(_BASIC_JSON_TPL_ & j)
{
if (j.is_string())
{
/** 保存BASE64字符串解码后的二进制数据 */
j = gdface::base64_decode(j.template get<std::string>());
}
}
/** 将类型为string的json对象中的二进制数据转为BASE64编码的 json 对象 */
_BASIC_JSON_TPL_DECLARATION_
_BASIC_JSON_TPL_ to_base64(const _BASIC_JSON_TPL_&j)
{
_BASIC_JSON_TPL_ out;
if (j.is_string())
{
auto v = j.template get<std::string>();
out = gdface::base64_encode(v);
}
return out;
}
//************************************
// (递归)返回 path 指定的 json 元素
// @param const json & j
// @param const std::string & path 节点路径描述
// 如果 j 中包含名为 path 的子节点则直接返回
// 如果 path 包含'/'且不以'/'开始和结尾,则视为'/'分割的节点名组成的路径描述
// 会递归从左到右递归搜索指定的节点,找到所有的节点则返回最后的节点
// 否则返回 null json
// 例如: person/sex 指定返回名为 person 的 object 节点下的 sex 字段
// @param bool try_parse_string 是否尝试解析string类型为json继续搜索
// 为true时,如果 j 为string类型,尝试将其解析为json,在其中查找子节点
// @return nlohmann::basic_json
//************************************
_BASIC_JSON_TPL_DECLARATION_
_BASIC_JSON_TPL_ get_json_by_path(const _BASIC_JSON_TPL_& j, const std::string &path, bool try_parse_string = false)
{
if (!j.is_null() && !path.empty()) {
if (j.contains(path)) {
/** 如果 j 中包含名为 path 的子节点则直接返回 */
return j[path];
}
auto idx = path.find_first_of('/');
if (idx > 0 && idx < path.size() - 1)
{
/************************************************************************/
/* idx > 0 即要求字符串包含'/',但不以'/'开始 */
/* idx < path.size() - 1,即要求'/'不是结尾 */
/************************************************************************/
/** 因为后面的逻辑有可能会修改_j,所以这里_j要用指针类型,而不能是引用 */
const _BASIC_JSON_TPL_* _j = &j;
_BASIC_JSON_TPL_ parsed;
if (j.is_string())
{
if (!try_parse_string)
{
return _BASIC_JSON_TPL_();
}
/************************************************************************/
/* 尝试将string解析为json继续查找子节点 */
/* 解析失败返回 null json */
/************************************************************************/
try
{
parsed = _BASIC_JSON_TPL_::parse(j.template get<std::string>());
_j = &parsed;
}
catch (const std::exception&)
{
return _BASIC_JSON_TPL_();
}
}
/** 左侧第一个节点名 */
auto first = std::string(path.begin(), path.begin() + idx);
/** 剩余节点名 */
auto remaining = std::string(path.begin() + idx + 1, path.end());
if (_j->contains(first))
{
/** 递归查找下一级节点 */
return get_json_by_path((*_j)[first], remaining, try_parse_string);
}
}
}
// null json
return _BASIC_JSON_TPL_();
}
} /** namespace json_utilits */
#endif /* COMMON_SOURCE_CPP_JSON_UTILITS_HPP_ */
C++
1
https://gitee.com/l0km/common_source_cpp.git
git@gitee.com:l0km/common_source_cpp.git
l0km
common_source_cpp
common_source_cpp
master

搜索帮助