解析集合数据的时候,from_json会产生重复的记录
asing325 opened this issue · 16 comments
#include <assert.h>
void test_v()
{
client::person p1 = { "tom", 20 };
client::person p2 = { "jack", 19 };
client::person p3 = { "mike", 21 };
std::vector<client::person> v{ p1, p2, p3 };
iguana::string_stream ss;
iguana::json::to_json(ss, v);
auto json_str = ss.str();
std::cout << json_str << std::endl;
std::vector<client::person> v1;
iguana::json::from_json(v1, json_str.data(), json_str.length());
assert(v == v1);
// 测试嵌套的数据
client::person allPerson;
allPerson.age = 20 + 19 + 21;
allPerson.name = json_str; // vector<>转换过来的json字符串
ss.clear();
iguana::json::to_json(ss, allPerson);
json_str = ss.str();
std::cout << json_str << std::endl;
client::person allPerson2;
iguana::json::from_json(allPerson2, json_str.data(), json_str.length());
assert(allPerson2 == allPerson);
// bug: 有重复的记录
iguana::json::from_json(v1, allPerson2.name.data(), allPerson2.name.length());
assert(v == v1);
}
namespace client
{
struct person
{
std::string name;
int64_t age;
bool operator == (const person& p) const
{
return name == p.name && age == p.age;
}
};
REFLECTION(person, name, age);
}
修改了测试代码,增加了注释,提交了请查阅。
vs平台上,pvs-studio静态代码分析工具不错,可以考虑试试看。
另外,很佩服你一个文件搞定json,不过维护起来有点麻烦,要不要考虑用第三方的jsoncpp做解析呢?
问题的原因在这里:
iguana::json::from_json(v1, allPerson2.name.data(), allPerson2.name.length());
iguana现在没有对这个v1做清空处理,内部是直接push_back的,这个v1之前是有3个元素的,导致再push进去了3个元素。你可以用一个新的vector验证。
不过这里iguana内部应该要做一下清空先。
@asing325
我项目中的问题还在,增加了测试用例文件,请查阅 example/test_json_channel.cpp
之前测试用例,重复数据的问题好了。
我项目中的用法复杂一点,嵌套几层后还原json报错,请查阅新提交的测试文件
error at line :0 col :177 msg:unknown escape char!
error at line :0 col :347 msg:unknown escape char!
error at line :0 col :517 msg:unknown escape char!
请查阅 \example\test_json_channel.cpp
。。。
UserMsg msg;
msg.id = 0;
msg.msg = jsonStr;
auto str = ToJsonString(msg);
UserMsg msg2;
bOK = ToUserData(msg2, str);
// bug: 这里还原不出来了,打印了错误提示
assert(bOK);
assert(msg.id == msg2.id);
assert(msg.msg == msg2.msg);
datas2.clear();
// bug: 这里死循环了
bOK = ToUserData(datas2, msg2.msg);
assert(bOK);
assert(datas2.size() == datas.size());
assert(datas[0].seats.size() == datas2[0].seats.size());
死循环解决了,数据不正确
建议你不要把json串多次序列化,目前只支持序列化一次json字符串。
你如果希望支持多层嵌套就用嵌套结构体。
另外,为了效率,from_json会修改原来的json串,所以from_json之后原来的字符串就无效了,不能再用了。
1、“你如果希望支持多层嵌套就用嵌套结构体”,,,好的,可以去掉特殊用法。
2、“为了效率,from_json会修改原来的json串,”,,,可以接受,后面也没有用那个字符串了。
另外一个问题,g_has_error这个全局变量能不能去掉啊,不然转换数据的时候还得全局加锁,不然 from_json 函数的返回值可能不正确,影响代码流程
需要向外面返回解析结果是否正确,不加这个就只能抛异常了,这样感觉也不太好。
你可以把g_has_error改成一个原子变量,这样可以保证这个变量是线程安全的。