Github repo: github.com/h46incon/ijst
ijst (iJsonStruct) 一个是 C++ Json 序列化/反序列化库:
include/ijst
文件夹复制进工程。可通过以下命令安装依赖并执行单元测试:
cd IJST
git submodule update --init
mkdir CMakeBuild && cd CMakeBuild
cmake ..
make
./unit_test/unit_test
#include <ijst/ijst.h>
#include <ijst/types_std.h>
#include <ijst/types_container.h>
using namespace ijst;
//*** 需要反序列化的 JSON 字符串
const std::string jsonStr = R"(
{
"int_val": 42,
"vec_val": ["str1", "str2"],
"map_val": {"k1": 1, "k2": 2}
})";
//*** 定义一个 ijst 结构体:
IJST_DEFINE_STRUCT(
// 结构体名字
JsonStruct
// 定义字段
, (T_int, iVal, "int_val", 0)
, (IJST_TVEC(T_string), vecVal, "vec_val", 0)
, (IJST_TMAP(T_uint64), mapVal, "map_val", 0)
);
//*** 默认情况下会生成这样的类:
/*
class JsonStruct {
public:
ijst::Accessor _; // 通过这个对象进行序列化等操作
int iVal;
std::vector<std::string> vecVal;
std::map<std::string, uint64_t> mapVal;
private:
//... Some private methods
};
*/
//*** 定义一个 JsonStruct 对象
JsonStruct jStruct;
//*** 反序列化
int ret = jStruct._.Deserialize(jsonStr);
assert(ret == 0);
//*** 访问字段
assert(jStruct.iVal == 42);
assert(jStruct.vecVal[0] == "str1");
assert(jStruct.mapVal["k2"] == 2);
//*** 序列化
std::string strOut;
ret = jStruct._.Serialize(strOut);
assert (ret == 0);
如果所需访问的字段的路径比较深的时候,为避免累赘的判断,可使用 get_*
方法,比如:
//*** 和 IJST_DEFINE_STRUCT 类似
IJST_DEFINE_STRUCT_WITH_GETTER(
StIn
, (T_int, iData, "i", ijst::FDesc::Optional)
, (IJST_TVEC(T_int), vecData, "vec", ijst::FDesc::Optional)
, (IJST_TMAP(T_int), mapData, "map", ijst::FDesc::Optional)
)
//*** 默认情况下会生成这样的结构体:
/*
class JsonStruct {
public:
//... 普通的字段,同 IJST_DEFINE_STRUCT
// Getters
ijst::Optional<int> get_iData();
ijst::Optional<std::vector<int> > get_vecData();
ijst::Optional<std::map<std::string, int> > get_mapData();
private:
};
*/
IJST_DEFINE_STRUCT_WITH_GETTER(
StOut
, (IJST_TST(StOut), stIn, "inner", ijst::FDesc::Optional)
)
StOut st;
//*** 可以通过连串的 get_* 尝试直接访问字段,而不用关注路径的中间节点是否存在
// 下行语句可访问 "/stIn/vecData/2"
// int* pData = st.get_stIn()->get_vecData()[2].Ptr();
// 即:
int* pData = st // StOut 对象
.get_stIn() // 访问 stIn 字段
->get_vecData() // 访问 vecData 字段,注意需使用 -> 操作符
[2] // 访问数组中第2个元素
.Ptr(); // 获取最后结果的地址
assert (pData == NULL);
// 如果路径中的每个字段都是 kValid 的,且 vector 的下标存在,则最终得到的指针会指向该字段:
// int* pData = st.get_stIn()->get_vecData()[2].Ptr() == &st.stIn.vecData[2];
ijst 底层使用的是 RapidJSON,其本身具有优秀的性能。
ijst 因有额外的工作,会带来一些性能上的开销,但也比常用的 JsonCpp 快上不少:
Library | 序列化 | 反序列化 |
---|---|---|
RapidJSON | 14 | 10 |
ijst | 16 | 23 |
JsonCpp | 128 | 109 |
测试环境:Corei7-4790_3.60GHz_vc2017_win7x64,测试代码: nativejson-benchmark。
注:不同环境测得的性能会有差异,一般而言,ijst 的序列化性能和 RapidJSON 相似,反序列化性能为其 1/4 ~ 1/2。
详请请移步 Github : github.com/h46incon/ijst
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。