Git Product home page Git Product logo

iguana's People

Contributors

alqaz avatar asing325 avatar bbbgan avatar bot-man-jl avatar buffer8848 avatar dengxbin avatar duancw123 avatar dust-ii avatar fananchong avatar helintongh avatar jacyking avatar kcwl avatar kidsunbo avatar kingwl avatar mymartin avatar poor-circle avatar qicosmos avatar saberlion avatar sandyhsia avatar thorneliu avatar willduancw avatar yangxingpping avatar zacklocx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

iguana's Issues

我为example.cpp增加了示例和注释

#include <iostream>
#include "json.hpp"
#include "xml.hpp"

struct person
{
	std::string  name;
	int          age;
};
REFLECTION(person, name, age)
/* REFLECTION(person, name, age)展开后的代码如下
constexpr std::array<const char*, 2> arr_person = { "name" , "age" };
template<>
struct Members<person> {
	constexpr decltype(auto) static apply() { 
		return std::make_tuple(&person::name, &person::age); 
	} 
	using type = void; 
	constexpr static const char *name = "person"; 
	constexpr static const size_t value = 2; 
	constexpr static const std::array<const char*, value>& arr = arr_person;
};
*/

struct one_t
{
	int id;
};
REFLECTION(one_t, id);

struct third_t
{
	std::string name;
	one_t one;
	int age;
};
REFLECTION(third, name, one, age);

struct composit_t
{
	int a;
	std::vector<std::string> b;
	int c;
	std::map<int, int> d;
	std::unordered_map<int, int> e;
	double f;
	std::list<one_t> g;
};
REFLECTION(composit_t, a, b, c, d, e, f, g);

void test_json()
{
	person p;
	const char * json = "{ \"name\" : \"tom\", \"age\" : 28}";
	iguana::json::from_json(p, json);

	iguana::string_stream ss;
	iguana::json::to_json(ss, p);
	std::cout << ss.str() << std::endl;

	one_t one = { 2 };
	composit_t composit = { 1,{ "tom", "jack" }, 3,{ { 2,3 } },{ { 5,6 } }, 5.3,{ one } };
	iguana::string_stream sst;
	iguana::json::to_json(sst, composit);
	std::cout << sst.str() << std::endl;

	const char* str_comp = R"({"a":1, "b":["tom", "jack"], "c":3, "d":{"2":3,"5":6},"e":{"3":4},"f":5.3,"g":[{"id":1},{"id":2}])";
	composit_t comp;
	iguana::json::from_json(comp, str_comp);
}

//void performance()
//{
//	person obj;
//	char * json = "{ \"Name\" : \"Boo\", \"Age\" : 28}";
//	ajson::load_from_buff(obj, json);
//
//	const size_t LEN = 1000000;
//
//	//反序列化
//	std::cout << "ajson deserialize: ";
//	boost::timer t;
//	for (size_t i = 0; i < LEN; i++)
//	{
//		ajson::load_from_buff(obj, json);
//	}
//	std::cout << t.elapsed() << std::endl;
//
//	std::cout << "reflib deserialize: ";
//	t.restart();
//	for (size_t i = 0; i < LEN; i++)
//	{
//		iguana::json::from_json(obj, json);
//	}
//	std::cout << t.elapsed() << std::endl;
//
//	//序列化
//	std::cout << "ajson serialize: ";
//	t.restart();
//	ajson::string_stream ss1;
//
//	for (size_t i = 0; i < LEN; i++)
//	{
//		ss1.clear();
//		ajson::save_to(ss1, obj);
//	}
//	std::cout << t.elapsed() << std::endl;
//
//	std::cout << "reflib serialize: ";
//	t.restart();
//
//	iguana::json::string_stream ss;
//	for (size_t i = 0; i < LEN; i++)
//	{
//		ss.clear();
//		iguana::json::to_json(ss, obj);
//	}
//	std::cout << t.elapsed() << std::endl;
//}

void test_xml()
{
	person p = {"admin", 20};
	iguana::string_stream ss;
	iguana::xml::to_xml(ss, p);
	std::cout << ss.str() << std::endl;

	ss.clear();
	two t = { "test", {2}, 4 };
	iguana::xml::to_xml(ss, t);
	auto result = ss.str();
	std::cout << result << std::endl;

	std::string xml = "			<?xml version=\"1.0\" encoding=\"UTF-8\">  <name>buke</name> <one><id>1</id></one>  <age>2</age>";
	two t1;
	iguana::xml::from_xml(t1, xml.data(), xml.length());
}

template<typename T, typename = std::enable_if_t<is_reflection<T>::value>>
void test_nest_read(T &&t, int indent = 0) {
	using namespace std;
	for_each(std::forward<T>(t),	[=](auto &v, size_t I, bool is_last) {
		for (size_t i = 0; i < indent; i++) 	cout << "  ";
		cout << I << " : " << get_name<T>(I) << " = " << v << endl;
	},
		[=](auto &o, size_t I, bool is_last) {
		for (size_t i = 0; i < indent; i++)		cout << "  ";
		cout << I << " : 下面是嵌入的成员" << typeid(o).name() << endl;
		test_nest_read(o, indent + 1);
	});
}

void test_reflection()
{
	person p = { "admin", 20 };
	
	constexpr auto fieldname = get_name<person, 0>();	//"name", const char* const. get_name直接返回Members<person>::arr[0]
	auto val = get<0>(p);								//"admin",std::basic_string. person.*(&person::name)

	//person只含有非反射类型成员
	for_each(p, [](const auto& item, size_t index, bool is_last) {
		std::cout << index <<" "<< item << std::endl;
	});
	
	std::cout << std::endl;
	
	two_t two = { "test",{ 2 }, 4 };
	//two只嵌套了(一层)一个映射类型成员
	for_each(two, [](const auto& item, size_t index, bool is_last) { //处理非反射类型成员
		std::cout << index << " " << item << std::endl;
	}, [](const auto& o, size_t index, bool is_last) {				//处理反射类型成员
		std::cout << index << " "<<typeid(o).name()<< std::endl;
	});

	std::cout << std::endl;
	//test_nest_read可以处理无限映射类型嵌套,但是不能处理容器如vector、map,详细可以参考test_json()
	third_t third = { "test",{ 2 }, 4 };
	test_nest_read(third);
}

int main()
{
	test_reflection();
//	test_json();
//	test_xml();
}

反序列化会陷入死循环的问题?

struct A { int a; std::string b; }; struct B { A a; std::string c; };
REFLECTION(A, a,b);
REFLECTION(B, a,c);

序列化:{"a":{"a":1,"b":"123"},"c":"123"} json没问题。
但是序列化:{"a":{"a":1},"c":"123"} 会陷入死循环

json字符串解析时有个问题不清楚,想请问下作者

struct string_ref {
                char const *str;
                size_t len;

                int length() const {
                    auto size = len;
                    for (size_t i = 0; i < len; ++i) {
                        if (str[i] == 92 || str[i] == 116 || str[i] == 50) // 92: ‘\’, 116: ‘t’, 50: ‘2’
                            size -= 1;
                    }

                    return static_cast(size);
                }

                bool operator!=(const char *data) const {
                    auto const str_length = strlen(data);
                    if (len != str_length) {
                        if (length() != str_length)
                            return true;
                    }

                    for (size_t i = 0; i < str_length; ++i) {
                        if (str[i] != data[i]) {
                            return true;
                        }
                    }
                    return false;
                }
            };
        } 

不知道上面的length() 函数中为何当str[i]=92,116,50的时候size要-1?

结构体中的第一个序位的float的值,被修改为大的正值。

struct ca{

std::string c_id;
std::string ca_id;
std::string c_name;
float pan; // =0.0;
float tilt;
float zoom;
}
REFLECTION(ca, c_id,ca_id, c_name, pan, tilt , zoom)

执行完上面的定义后,在一个执行函数中定义这个ca类
ca tb_ca;
发现成员变量的值 tb_ca.pan 不为接近于0的一个数,而为一个正的有意义的值。

请问是内存溢出的错误嘛,该如何修改。

由于VS2015不支持C++17,使用的0.09版本(C++14),但对示例中的json,自定义类型(user)如果为null,会报错。

struct TaskQuery_User
{
int id;
string email;
string nickName;
string avatar;
};
REFLECTION(TaskQuery_User, id, email, nickName, avatar);

struct TaskQuery_List
{
TaskQuery_User user;
};
REFLECTION(TaskQuery_List,user);

struct TaskQuery_data
{
vector<TaskQuery_List> list;
};
REFLECTION(TaskQuery_data, list);

struct TaskQuery_Json
{
TaskQuery_data data;
long long timestamp;
};
REFLECTION(TaskQuery_Json, data, timestamp);

int main(void)
{
string strTaskQueryJsonResult = "{"data":{"list":[{"user":null}]},"timestamp":1533134762747}";
TaskQuery_Json taskQueryJson;
iguana::json::from_json(taskQueryJson,strTaskQueryJsonResult.c_str(), strTaskQueryJsonResult.length());

return 0;

}

数组感觉有点问题

#include "stdafx.h"
#include "iguana\json.hpp"
#include <iostream>

struct struct_A
{
	int aa[2];
};

REFLECTION(struct_A, aa)

int main()
{
	struct_A A = { {1,2} };

	iguana::string_stream ss;
	iguana::json::to_json(ss, A);

	auto json_s = ss.str();

	std::cout << json_s << std::endl;

	struct_A A_;
	iguana::json::from_json(A_, json_s.c_str());

	return 0;
}

数组在from_json过不去,vector可以

support dom parse

  • 1. api和from_json对齐
  • 2. 抛异常的接口;
  • 3. 错误码的接口;
  • 4. 带默认值的接口?
  • 5. [] 访问object和array的接口
  • 6. 增加corner case的测试
  • 7. json文件测试(10个文件)
  • 8. json文件benchmark

几个问题

对于自定义的类,序列化代码已经很少了,不错

1)流能支持 std::stringstream吗?

2)类外定义,可以放到类内定义,这样也许可以少些一个类名。
struct one_t
{
int id;
};
REFLECTION(one_t, id);

能不能够改为:
struct one_t
{
int id;
REFLECTIONINNER( id);
};
3)private/protect可以支持吗?
4)编译性能的benchmark。

是否支持enum

enum COLOR {
RED,
GREEN,
BLUE
};

struct S{
int a;
COLOR c;
};
S data;
data.a = 1;
data.c = GREEN;
iguana::json::to_json(ss, data);
cout << ss.str() << endl;

输出{"a":1,"c":2}

期望输出 ("a":1,"c":GREEN)

不能正常解析字段

namespace Model {
    struct BookData {
        std::string name;
        std::string pubs;
        int pages;
        std::string types;
    };
    REFLECTION(BookData, name, pages, pubs, types);
}
const char * bookJson = "{\"name\":\"my book\",\"types\":\"aaa\",\"pages\":11,\"pubs\":\"bbb\"}";
Model::BookData book;
iguana::json::from_json(book, bookJson);
cout << book.name << endl;//正常输出
cout << book.types << endl;//没有输出

Could not represent null fields...

#include <iostream>
#include "iguana/json.hpp"

struct Model {
    std::string str;
    int num;
};
REFLECTION (Model, str, num);

void parseJson (const char *json)
{
    Model model;
    model.str = "";
    model.num = 0;
    iguana::json::from_json (model, json);
    std::cout << "str: '" << model.str << "', "
        << "num: " << model.num << std::endl;
}

//$ clang++ json_test.cpp -std=c++14 -o json_test && ./json_test
int main (int argc, char *argv[])
{
    parseJson (R"({ "str": "string", "num": 6, "dummy": 0 })");  // str: 'string', num: 6
    parseJson (R"({ "str": "string", "num": 6 })");              // str: 'string', num: 6
    parseJson (R"({ "str": "string" })");                        // str: 'string', num: 0
    parseJson (R"({ "dummy": 0 })");                             // str: '', num: 0
    parseJson (R"({ "dummy": 0, "num": 6 })");                   // str: '', num: 0
    parseJson (R"({ "dummy": 0, "num": 6, "str": "string" })");  // str: '', num: 0
    return 0;
}
  • Unable to tell if a field presents or not..
  • Failed to parse json with some dummy field...

char array problem

hi:
In some cases, I want to use char array in struct, not use std::string, I found it deal char array as c_array, is there any suggestion to make it like string

Some problems in using iguana

  1. In the process of using, Value of stucted Json strings can't be treated as string. so while we need to solve it later, the only thing we can do is base64 encoding it, and decoding later, the use another class by some values we have already got in the upper.
  2. Json's key-value pairs can't be treated will by iguana while they are disordered, and we shouldn't missing or abandon on pair expect it is in the tail of the Json string, and iguana can only arrange JSON based on the order of reflected macros, although it can be avoided by some methods, but it does not conform to the design of Json, I think so.
  3. Iguana cannot support the replacement of key, and if some special naming is used, the same name is required for the key in the JSON, which is very inconvenient on the co-work in the multilingual C/S.

hope to be replied.

to_json 不支持int64_t uint64_t 等

#include "json.hpp"
#include "reflection.hpp"
struct ita
{
	int64_t b;
};
REFLECTION(ita,  b)
int main()
{
     ita f{1 };
     iguana::string_stream ss;
     iguana::json::to_json(ss, f);
     auto json_str = ss.str();
     std::cout << json_str << std::endl;
     return 0;
}

编译报错(vs2017)

refactor to c++ 20

refactor: improve json parsing performance; fix some bugs; use c++20;

  • functional implementation(support std::array, vector like, map like containers, nested objects)
  • ifstream interface
  • unit test for json_reader(function test; special character test(\t, \n, \...)
  • unicode character test)
  • json validation check test(test with many json files)
  • performance test
  • documents
  • 提供python 等其它语言的接口

序列化时容器为空时有小问题

容器为空时,序列化时 未做判断

	template<typename InputIt, typename T, typename F>
	T join(InputIt first, InputIt last, const T &delim, const F &f) {
		if (first == last) return T();
		T t = f(*first++);
		while (first != last) {
			t += delim;
			t += f(*first++);
		}
		return t;
	}

	template<typename Stream, typename InputIt, typename T, typename F>
	void join(Stream& ss, InputIt first, InputIt last, const T &delim, const F &f) {
		if (first == last) return;
		f(*first++);
		while (first != last) {
			ss.put(delim);
			f(*first++);
		}
	}

some bug for parse_item

  • I didn't get the right answer when i take someone test

     std::list<char> str; 
     str.push_back('\"');
     str.push_back('a');
     str.push_back('\\');
     str.push_back('\"');
     std::string test{};
     iguana::parse_item(test, str.begin(), str.end());
     CHECK(test == "a");
    

    the result of test is a\", not a

  • The string to be deserialized has fewer words,maybe lesser than 7, it will crash at json_util@line 132

Qt可以使用吗?

Qt版本5.12.0,定义的结构体,里面使用了QString / qreal / QMap 等Qt自定义的类型。可以使用该库序列化吗

msgpack.hpp 不支持char[]

json.hpp支持char[],但是换成msgpack就编译失败了,
请看看能不能支持一下啊,第三方接口里面有char[],没有办法回避~


#include <iguana/msgpack.hpp>

namespace client
{
struct game
{
char ip[32]; // add for test
std::string name;
double price;
};
REFLECTION(game,ip, name, price);
}


编译错误

1>------ 已启动生成: 项目: msgpack_example, 配置: Debug Win32 ------
1>msgpack_example.cpp
\iguana\iguana\reflection.hpp(388): error C2672: “std::make_tuple”: 未找到匹配的重载函数

build error in CentOS7 env

I met build error in my env. Do we have tutorial about how to build this project in Linux env?
my gcc version is 5.30
Build log:
[mcong@localhost build]$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/local/gcc/libexec/gcc/x86_64-unknown-linux-gnu/5.3.0/lto-wrapper
Target: x86_64-unknown-linux-gnu
Configured with: ./configure --prefix=/usr/local/gcc --enable-threads=posix --disable-checking --enable-languages=c,c++ --disable-multilib --with-gmp=/usr/local/lib --with-mpfr=/usr/local/lib --with-mpc=/usr/local/lib
Thread model: posix
gcc version 5.3.0 (GCC)
[mcong@localhost build]$ vi /home/mcong/study/github/iguana/reflection.hpp
[mcong@localhost build]$ make
Scanning dependencies of target json_example
[ 33%] Building CXX object CMakeFiles/json_example.dir/example/json_example.cpp.o
In file included from /home/mcong/study/github/iguana/json.hpp:8:0,
from /home/mcong/study/github/example/json_example.cpp:1:
/home/mcong/study/github/iguana/reflection.hpp:326:55: error: global qualification of class name is invalid before ‘{’ token
template<>struct ::iguana_reflect_members<STRUCT_NAME>{
^
/home/mcong/study/github/iguana/reflection.hpp:338:5: note: in expansion of macro ‘MAKE_META_DATA_IMPL’
MAKE_META_DATA_IMPL(STRUCT_NAME, MAKE_ARG_LIST(N, &STRUCT_NAME::OBJECT, VA_ARGS))
^
/home/mcong/study/github/iguana/reflection.hpp:343:1: note: in expansion of macro ‘MAKE_META_DATA’
MAKE_META_DATA(STRUCT_NAME, GET_ARG_COUNT(VA_ARGS), VA_ARGS)
^
/home/mcong/study/github/example/json_example.cpp:11:2: note: in expansion of macro ‘REFLECTION’
REFLECTION(person, name, age);
^
/home/mcong/study/github/example/json_example.cpp: In function ‘int main()’:
/home/mcong/study/github/example/json_example.cpp:19:29: error: no matching function for call to ‘to_json(iguana::string_stream&, client::person&)’
iguana::json::to_json(ss, p);
^
In file included from /home/mcong/study/github/example/json_example.cpp:1:0:
/home/mcong/study/github/iguana/json.hpp:138:7: note: candidate: template<class Stream, class T> std::enable_if_t<iguana::is_reflection::value> iguana::json::to_json(Stream&, T&&)
auto to_json(Stream& s, T &&t) -> std::enable_if_t<is_reflection::value>
^
/home/mcong/study/github/iguana/json.hpp:138:7: note: template argument deduction/substitution failed:
/home/mcong/study/github/iguana/json.hpp:161:7: note: candidate: template<class Stream, class T> void iguana::json::to_json(Stream&, const std::vector&)
void to_json(Stream& s, const std::vector &v) {
^
/home/mcong/study/github/iguana/json.hpp:161:7: note: template argument deduction/substitution failed:
/home/mcong/study/github/example/json_example.cpp:19:29: note: ‘client::person’ is not derived from ‘const std::vector’
iguana::json::to_json(ss, p);
^
In file included from /home/mcong/study/github/example/json_example.cpp:1:0:
/home/mcong/study/github/iguana/json.hpp:166:7: note: candidate: template<class Stream, class ... Args> void iguana::json::to_json(Stream&, std::tuple<_Elements ...>)
void to_json(Stream& s, std::tuple<Args...> tp) {
^
/home/mcong/study/github/iguana/json.hpp:166:7: note: template argument deduction/substitution failed:
/home/mcong/study/github/example/json_example.cpp:19:29: note: ‘client::person’ is not derived from ‘std::tuple<_Elements ...>’
iguana::json::to_json(ss, p);
^
/home/mcong/study/github/example/json_example.cpp:25:64: error: no matching function for call to ‘from_json(client::person&, const char*, std::__cxx11::basic_string::size_type)’
iguana::json::from_json(p2, json_str.data(), json_str.length());
^
In file included from /home/mcong/study/github/example/json_example.cpp:1:0:
/home/mcong/study/github/iguana/json.hpp:1030:7: note: candidate: template<class T, class> void iguana::json::from_json(T&&, const char*, size_t)
void from_json(T &&t, const char *buf, size_t len = -1) {
^
/home/mcong/study/github/iguana/json.hpp:1030:7: note: template argument deduction/substitution failed:
make[2]: *** [CMakeFiles/json_example.dir/example/json_example.cpp.o] Error 1
make[1]: *** [CMakeFiles/json_example.dir/all] Error 2
make: *** [all] Error 2

结构体包含由子结构体转换成的json字符串,无法反解回结构体

以“六年级-三班-某学生”为例,学生由结构体转换为json字符,作为班级的成员; 班级由结构体转换为json字符,作为年级的成员; 由年级json字符无法解析出classParm成员变量,解析出的结构只有"{"

#include "mainwindow.h"
#include <QApplication>
#include <iostream>
#include "../iguana/iguana/json.hpp"
// 六年级-三班-某学生
struct Person
{
    std::string  name;
    int          age;
};
REFLECTION(Person, name, age);

struct Class   
{
    int classID;
    std::string personParm;
};
REFLECTION(Class, classID, personParm)

struct Grade   
{
    int gradeID;
    std::string classParm;  
};
REFLECTION(Grade, gradeID, classParm)

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
//    MainWindow w;
//    w.show();
    Person p;
    p.age = 10;
    p.name = "suli";
    iguana::string_stream pp;
    iguana::json::to_json(pp, p);
    std::cout << pp.str() << std::endl;
    Person res_p;
    iguana::json::from_json(res_p, pp.str().c_str());

    Class c;
    c.classID = 3;
    c.personParm = pp.str();
    iguana::string_stream cc;
    iguana::json::to_json(cc, c);
    std::cout << cc.str() << std::endl;
    //const char* dd= "{\"classID\":3,\"personParm\":\"{\\\"name\\\":\\\"suli\\\",\\\"age\\\":10}\"}";
    Class res_c;
    iguana::json::from_json(res_c, cc.str().c_str());

    Grade g;
    g.gradeID = 6;
    g.classParm = cc.str();
    iguana::string_stream gg;
    iguana::json::to_json(gg, g);
    std::cout << gg.str().c_str() << std::endl;
    Grade res_g;
    iguana::json::from_json(res_g, gg.str().c_str());

    Grade res;
    iguana::json::from_json(res, gg.str().c_str());
    return a.exec();
}

struct_container_t build faild

compiling environment:ubuntu16.04,gcc 12.1.0

code is as following:

struct struct_test_t {
int32_t value;
};
REFLECTION(struct_test_t, value);

struct struct_container_t {
std::vector<struct_test_t> values;
};
REFLECTION(struct_container_t, values);

std::string json_str = "123";
struct_container_t struct_container_obj;
iguana::from_json(struct_container_obj, std::begin(json_str), std::end(json_str)); //编译失败
iguana::string_stream ss;
iguana::json::to_json(ss, struct_container_obj); //可以编译通过

build log is:
[build] /home/zeeuser/workspace/project/github/iguana/iguana/json_reader.hpp:253:15: error: no matching function for call to ‘parse_item(__gnu_cxx::__alloc_traits<std::allocator<struct_test_t>, struct_test_t>::value_type&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&)’
[build] 253 | parse_item(value.emplace_back(), it, end);
[build] | ~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[build] /home/zeeuser/workspace/project/github/iguana/iguana/json_reader.hpp:144:20: note: candidate: ‘template<class U, class It, class auto:65> requires num_t void iguana::parse_item(U&, It&&, auto:65&&)’
[build] 144 | IGUANA_INLINE void parse_item(U &value, It &&it, auto &&end) {
[build] | ^~~~~~~~~~
[build] /home/zeeuser/workspace/project/github/iguana/iguana/json_reader.hpp:144:20: note: template argument deduction/substitution failed:
[build] /home/zeeuser/workspace/project/github/iguana/iguana/json_reader.hpp:144:20: note: constraints not satisfied
[build] /home/zeeuser/workspace/project/github/iguana/iguana/json_reader.hpp: In substitution of ‘template<class U, class It, class auto:65> requires num_t void iguana::parse_item(U&, It&&, auto:65&&) [with U = struct_test_t; It = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&; auto:65 = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&]’:
[build] /home/zeeuser/workspace/project/github/iguana/iguana/json_reader.hpp:253:15: required from ‘void iguana::parse_item(U&, It&&, auto:68&&) [with U = std::vector<struct_test_t>; It = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&; auto:68 = __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&]’
[build] /home/zeeuser/workspace/project/github/iguana/iguana/json_reader.hpp:441:27: required from ‘iguana::from_json<struct_container_t, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string > >(struct_container_t&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&)::<lambda(auto:77&&)> [with auto:77 = std::vector<struct_test_t> struct_container_t::* const&]’
[build] /usr/local/gcc-12.1/include/c++/12.1.0/type_traits:2565:26: required by substitution of ‘template<class _Fn, class ... _Args> static std::__result_of_success<decltype (declval<_Fn>()((declval<_Args>)()...)), std::__invoke_other> std::__result_of_other_impl::_S_test(int) [with _Fn = iguana::from_json<struct_container_t, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string > >(struct_container_t&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&)::<lambda(auto:77&&)>; _Args = {std::vector<struct_test_t, std::allocator<struct_test_t> > struct_container_t::* const&}]’
[build] /usr/local/gcc-12.1/include/c++/12.1.0/type_traits:2576:55: required from ‘struct std::__result_of_impl<false, false, iguana::from_json<struct_container_t, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string > >(struct_container_t&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&)::<lambda(auto:77&&)>, std::vector<struct_test_t, std::allocator<struct_test_t> > struct_container_t::* const&>’
[build] /usr/local/gcc-12.1/include/c++/12.1.0/type_traits:2581:12: required from ‘struct std::__invoke_result<iguana::from_json<struct_container_t, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string > >(struct_container_t&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&)::<lambda(auto:77&&)>, std::vector<struct_test_t, std::allocator<struct_test_t> > struct_container_t::* const&>’
[build] /usr/local/gcc-12.1/include/c++/12.1.0/type_traits:3022:12: required from ‘struct std::invoke_result<iguana::from_json<struct_container_t, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string > >(struct_container_t&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&)::<lambda(auto:77&&)>, std::vector<struct_test_t, std::allocator<struct_test_t> > struct_container_t::* const&>’
[build] /usr/local/gcc-12.1/include/c++/12.1.0/type_traits:3034:11: required by substitution of ‘template<class _Fn, class ... _Args> using invoke_result_t = typename std::invoke_result::type [with _Fn = iguana::from_json<struct_container_t, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string > >(struct_container_t&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&)::<lambda(auto:77&&)>; _Args = {std::vector<struct_test_t, std::allocator<struct_test_t> > struct_container_t::* const&}]’
[build] /usr/local/gcc-12.1/include/c++/12.1.0/variant:1093:11: required by substitution of ‘template<class _Visitor, class ... _Variants> using __visit_result_t = std::invoke_result_t<_Visitor, std::__detail::__variant::__get_t<0, _Variants, decltype (std::__detail::__variant::__as(declval<_Variants>())), typename std::variant_alternative<0, typename std::remove_reference<decltype (std::__detail::__variant::__as(declval<_Variants>()))>::type>::type>...> [with _Visitor = iguana::from_json<struct_container_t, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string > >(struct_container_t&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&)::<lambda(auto:77&&)>; _Variants = {const std::variant<std::vector<struct_test_t, std::allocator<struct_test_t> > struct_container_t::>&}]’
[build] /usr/local/gcc-12.1/include/c++/12.1.0/variant:1819:5: required by substitution of ‘template<class _Visitor, class ... _Variants> constexpr std::__detail::__variant::__visit_result_t<_Visitor, _Variants ...> std::visit(_Visitor&&, _Variants&& ...) [with _Visitor = iguana::from_json<struct_container_t, __gnu_cxx::__normal_iterator<char
, std::__cxx11::basic_string > >(struct_container_t&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&, __gnu_cxx::__normal_iterator<char*, std::__cxx11::basic_string >&&)::<lambda(auto:77&&)>; _Variants = {const std::variant<std::vector<struct_test_t, std::allocator<struct_test_t> > struct_container_t::>&}]’
[build] /home/zeeuser/workspace/project/github/iguana/iguana/json_reader.hpp:437:19: required from ‘void iguana::from_json(T&, It&&, It&&) [with T = struct_container_t; It = __gnu_cxx::__normal_iterator<char
, std::__cxx11::basic_string >]’
[build] /home/zeeuser/workspace/project/github/iguana/test/json_file_test.cpp:32:20: required from here

解析时没有安全检查

我在尝试使用这个库时遇到一些问题,对于json字符串的解析,没有安全检查,比如某个字段类型不正确,不存在,iguana::json::from_json0()会仍然返回true,并且在对象中使用不正确的值.
举个例子:
struct test
{
std::string username;
std::string password;
long long id;
bool error;
};
REFLECTION(test, username, password, id, error);

int main(void)
{
test test1;
std::string str1 = "{"username1":"test","password":"test","id": 10.1, "error": false}";
auto ret = iguana::json::from_json0(test1, str1.c_str(), str1.length());
std::cout << test1.username << std::endl;
std::cout << test1.password << std::endl;
std::cout << test1.id << std::endl;
std::cout << std::boolalpha << test1.error << std::endl;
std::cout << std::boolalpha << ret << std::endl;
return 0;
}
以上代码,json字符串不存在username这个key,并且id的类型也不正确,但是解析仍然返回true. 我认为该库无法用于生产环境,因为解析的正确性不应该由使用库的用户来检查.

结构体中成员名与JSON中key的名字不一致时,出现内存溢出或者其他错误

``struct student
{
int code;
std::string write;
std::string Read;
std::string Descript;
};
REFLECTION(student, code, write, Read, Descript);
struct person
{
std::string name;
int64_t age;
std::list list;
std::list ss;
std::map<std::string, student> dic;
};

REFLECTION(person, name, age, list, ss, dic);

person p;
const char * json = "{ \"name\" : \"tom\", \"age\" : 20,\"list\":[1,2,3],\"ss\":[{\"Code\":1,\"Write\":\"add\",\"Read\":\"cut\",\"Descript\":\"这是描述\"}],\"dic\":{\"a\":{\"Code\":1,\"Write\":\"add\",\"Read\":\"cut\",\"Descript\":\"这是描述\"}}}";
auto r = iguana::json::from_json0(p, json);

以上代码:
1、定义两个结构体--person和student
2、使用iguama把json字符串填充结构体类型的变量

clang++6.0 failed

/root/source/vcpkg/installed/x64-linux/include/iguana/json.hpp:1213:13: error: variable of non-literal type 'iguana::json::reader_t' cannot be
defined in a constexpr function
reader_t rd(buf, len);

解析集合数据的时候,from_json会产生重复的记录

#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);

}

json解析bug

qq 20190227165256

struct SampleInfo
{
std::string features;
std::string modpath;
int filetype;
std::string ip;
__int64 time;
SampleInfo()
{
filetype = SFT_DLL;
time = 0;
}
}
std::string buf = R"({"status":{"msg":"","code":0},"result":[{"features":"9a/AFjFJnblBG7e6YrLm4R0SCGNZPgZJankK0hA=","modpath":"F:\xxx\榫嶄箣瀵嗕紶瀹屾暣瀹㈡埛12.01\InterceptAttacks.dll","filetype":1,"ip":"","time":1551259301}]})";
在解析上面这个json是会出问题 ,一直分配内存直到分配失败,出问题是乱码那个+路径, 路径是2个斜杠的编辑怎么变成一个了

How to package as a dynamic library(如何封装成库)

Hi bro, after reading your project, thank you very much for sharing such good things

I have a question:

Because the project is written in xxx.hpp and c++ template

I want to make package to dll and .h ,but it's too hard.

So I want to ask how to do this

Thanks !

嗨,兄弟,看完你的项目,非常感谢你分享这么好的东西

我有一个问题:

因为项目是用xxx.hpp和c++模板编写的

我想让它封装为dll和。h,但它太难了。

我想问一下如何做到这一点

谢谢!

是否可以加一个set_field_value的方法,便于通过某个字符串名称来设置对象相应成员的值

`template<typename T, typename V>
void set_field_value(T& to_obj, std::string_view to_field_name, const V& from_v)
{
using M = decltype(iguana_reflect_members(to_obj));
auto tp = M::apply_impl();
constexpr auto Size = M::value();
auto index = iguana::get_index(to_field_name);
tuple_switch(index, tp, [&](auto& v) {
using type_v = decltype(std::declval().*std::declval<decltype(v)>());
to_obj.*v = (type_v)from_v;
}, std::make_index_sequence{});
}
///////////////////////////////////////////////
struct person
{
std::string name;
int age = 0;
};

REFLECTION(person, age, name);

int main()
{
person p;
iguana::set_field_value(p, "name", "Tom");
iguana::set_field_value(p, "age", 20);
return getchar();
}`

反序列化时的问题?

    template<typename T>
    void check_result(T val, char const *str){
        if(val == 0 && strcmp(str,"0") != 0){
            g_has_error = true;
        }
    }

在源代码里面看到有这行代码,序列化std::map<int,自定义结构>时,如果key是0,在某些时候from_json(对象,JSON字符串)会返回false,,但是检查对象时,发现数据都已经反序列化成功。

写了num_t、fixed_array、str_t部分的一些测试代码,以下部分不符合预期.

#define DOCTEST_CONFIG_IMPLEMENT
#include "doctest.h"
#include "iguana/json_reader.hpp"
#include "test_headers.h"
#include <iguana/json.hpp>
#include <iguana/json_util.hpp>
#include

TEST_CASE("test parse item num_t") {
{
std::string str{"3e6"};
int p{};
iguana::parse_item(p, str.begin(), str.end());
//throw here because parsed p = 3 and said not correct.
//CHECK(p == 3e6);
}
{
std::string str;
str.append(300, '1');
int p{};
CHECK_THROWS_WITH(iguana::parse_item(p, str.begin(), str.end()),
"Failed to parse number"); // expect to have exception: Number is too long.
}
}

TEST_CASE("test parse item array_t") {
{
std::string str{"[1, -222,"};
std::array<int, 2> test;

///should throw "unexpected end"? but pass..
//CHECK_THROWS_WITH(iguana::parse_item(test, str.begin(), str.end()),
//                  "Unexpected end");

}
{
std::string str{"[ ] "};
std::array<int, 2> test;

///should throw at this case? but not..
//CHECK_THROWS_WITH(iguana::parse_item(test, str.begin(), str.end()),
//                  "Unexpected end");

}
{
std::string str{"[ 1.2345] "};
std::array<int, 2> test;
///should throw unexpected end? but throw "expected]"..
//CHECK_THROWS_WITH(iguana::parse_item(test, str.begin(), str.end()),
// "Unexpected end");
}
}

TEST_CASE("test parse item str_t") {
{
// this case throw at json_util@line 132
std::string str{""aaa1""};
std::string test{};
//iguana::parse_item(test, str.begin(), str.end());
//CHECK(test == str);
}
}

// doctest comments
// 'function' : must be 'attribute' - see issue #182
DOCTEST_MSVC_SUPPRESS_WARNING_WITH_PUSH(4007) int main(int argc, char **argv) {
return doctest::Context(argc, argv).run();
}
DOCTEST_MSVC_SUPPRESS_WARNING_POP

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.