fixed bugs in gson_helper.ipp for object's pointer copy

This commit is contained in:
zhengshuxin 2017-05-14 00:16:42 +08:00
parent 1a6af8a6be
commit 8b0c600fac
12 changed files with 317 additions and 85 deletions

View File

@ -1,11 +1,13 @@
all:
@(cd benchmark; make)
@(cd test; make)
@(cd test0; make)
@(cd test1; make)
@(cd test2; make)
@(cd test3; make)
@(../gson -d benchmark; cd benchmark; make; ./test1)
@(../gson -d test; cd test; make; ./test)
@(../gson -d test0; cd test0; make; ./test)
@(../gson -d test1; cd test1; make; ./test)
@(../gson -d test2; cd test2; make; ./test)
@(../gson -d test3; cd test3; make; ./test)
@(../gson -d test4; cd test4; make; ./test)
@(../gson -d test5; cd test5; make; ./test)
clean:
@(cd benchmark; make clean)
@(cd test; make clean)
@ -13,3 +15,5 @@ clean:
@(cd test1; make clean)
@(cd test2; make clean)
@(cd test3; make clean)
@(cd test4; make clean)
@(cd test5; make clean)

View File

@ -54,5 +54,6 @@ int main(void)
{
serialize();
deserialize();
printf("Enter any key to continue ..."); fflush(stdout); getchar();
return 0;
}

View File

@ -181,5 +181,6 @@ int main(int argc, char* argv[])
}
test1();
printf("Enter any key to continue ..."); fflush(stdout); getchar();
return 0;
}

View File

@ -168,5 +168,6 @@ int main(int argc, char* argv[])
}
test1();
printf("Enter any key to continue ..."); fflush(stdout); getchar();
return 0;
}

View File

@ -107,5 +107,6 @@ int main(int argc, char* argv[])
}
test();
printf("Enter any key to continue ..."); fflush(stdout); getchar();
return 0;
}

View File

@ -136,5 +136,6 @@ int main(void)
printf("------------------------test2--------------------------\r\n");
test2();
printf("Enter any key to continue ..."); fflush(stdout); getchar();
return 0;
}

View File

@ -89,5 +89,6 @@ int main(void)
{
serialize();
deserialize();
printf("Enter any key to continue ..."); fflush(stdout); getchar();
return 0;
}

View File

@ -9,4 +9,11 @@ struct user
bool male;
std::map<std::string, std::vector<std::string> > names;
std::map<std::string, std::vector<std::string*> > names2;
std::map<std::string, std::string> names3;
std::list<acl::string*> values1;
std::list<acl::string> values2;
std::list<std::string*> values3;
std::list<std::string> values4;
std::map<std::string, std::string*> names4;
};

View File

@ -125,5 +125,6 @@ int main(int argc, char* argv[])
}
test();
printf("Enter any key to continue ..."); fflush(stdout); getchar();
return 0;
}

View File

@ -1,6 +1,11 @@
修改历史列表:
-----------------------------------------------------------------------
475) 2017.5.13
475.1) bugfix: gson_helper.ipp 中 gson 模板函数中当第二个参数为 std::list 或
std::vector 时,如果容器中元素中的成员为对象指针时会因浅拷贝的原因导致指针对象
被二次释放的问题 -- "lindawei" <672496008@qq.com>
474) 2017.5.5
474.1) feature: db_pgsql.cpp 支持以 UNIX 域套接口方式连接 postgresql 数据库

View File

@ -7,63 +7,63 @@ class ACL_CPP_API pgsql_conf
{
public:
/**
*
* @param dbaddr {const char*} ip:port
* unix_domain_path unix unix
* postgresql unix
* /tmp/.s.PGSQL.5432 dbaddr /tmp
* unix mysql mysql
*
* @param dbname {const char*}
*
* @param dbaddr {const char*} ip:port
* unix_domain_path unix unix
* postgresql unix
* /tmp/.s.PGSQL.5432 dbaddr /tmp
* unix mysql mysql
*
* @param dbname {const char*}
*/
pgsql_conf(const char* dbaddr, const char* dbname);
/**
*
* @param conf {const pgsql_conf&}
*
*
* @param conf {const pgsql_conf&}
*
*/
pgsql_conf(const pgsql_conf& conf);
~pgsql_conf(void);
/**
*
* @param dbuser {const char*}
*
* @param dbuser {const char*}
* @return {pgsql_conf&}
*/
pgsql_conf& set_dbuser(const char* dbuser);
/**
*
* @param dbpass {const char*}
*
* @param dbpass {const char*}
* @return {pgsql_conf&}
*/
pgsql_conf& set_dbpass(const char* dbpass);
/**
*
* @param dblimit {size_t} 0
*
* @param dblimit {size_t} 0
* @return {pgsql_conf&}
*/
pgsql_conf& set_dblimit(size_t dblimit);
/**
*
*
* @param timeout {int}
* @return {pgsql_conf&}
*/
pgsql_conf& set_conn_timeout(int timeout);
/**
*
*
* @param int {timeout}
* @return {pgsql_conf&}
*/
pgsql_conf& set_rw_timeout(int timeout);
/**
*
*
* @param charset {const char*}
* @return {pgsql_conf&}
*/

View File

@ -3,7 +3,8 @@
* All rights reserved.
*
* AUTHOR(S)
* E-mail: niukey@qq.com
* E-mail: "fuwangqini" niukey@qq.com
* 2017.5.13 fixed one bug by "lindawei" <672496008@qq.com>
*
* VERSION
* Sat 08 Oct 2016 09:07:14 PM CST
@ -18,7 +19,7 @@
namespace acl
{
///////////////////////////////////type_traits////////////////////////
///////////////////////////////////type_traits////////////////////////////////
struct true_type
{
@ -417,7 +418,7 @@ template<class T>
typename enable_if<is_string<T>::value, void>::type
static inline add_item(acl::json &, acl::json_node &node, T *value)
{
if(check_nullptr(value))
if (check_nullptr(value))
node.add_array_null();
else
node.add_array_text(get_value(value));
@ -425,17 +426,18 @@ static inline add_item(acl::json &, acl::json_node &node, T *value)
static inline void add_item(acl::json &, acl::json_node &node, char *value)
{
if(check_nullptr(value))
if (check_nullptr(value))
node.add_array_null();
else
node.add_array_text(value);
}
template<class V>
static inline acl::json_node &gson(acl::json &json, const std::list<V> &objects)
template<class T>
static inline acl::json_node &gson(acl::json &json,
const std::list<T> &objects)
{
acl::json_node &node = json.create_array();
for (typename std::list<V>::const_iterator
for (typename std::list<T>::const_iterator
itr = objects.begin(); itr != objects.end(); ++itr)
{
add_item(json, node, *itr);
@ -445,16 +447,10 @@ static inline acl::json_node &gson(acl::json &json, const std::list<V> &objects)
}
template<class T>
static inline acl::json_node &gson(acl::json &json, const std::list<T> *objects)
static inline acl::json_node &gson(acl::json &json,
const std::list<T> *objects)
{
acl::json_node &node = json.create_array();
for (typename std::list<T>::const_iterator
itr = objects->begin(); itr != objects->end(); ++itr)
{
add_item(json, node, *itr);
}
return node;
return gson(json, *objects);
}
template<class T>
@ -491,9 +487,8 @@ static inline gson(acl::json &json, const std::map<K, V> &objects)
if (check_nullptr(itr->second))
node.add_child(json.create_node().add_null(tag));
else
{
node.add_child(json.create_node().add_number(tag, get_value(itr->second)));
}
node.add_child(json.create_node()
.add_number(tag, get_value(itr->second)));
}
return node;
@ -512,9 +507,8 @@ static inline gson(acl::json &json, const std::map<K, V> *objects)
if (check_nullptr(itr->second))
node.add_child(json.create_node().add_null(tag));
else
{
node.add_child(json.create_node().add_number(tag, get_value(itr->second)));
}
node.add_child(json.create_node()
.add_number(tag, get_value(itr->second)));
}
return node;
@ -533,9 +527,8 @@ static inline gson(acl::json &json, const std::map<K, V> &objects)
if (check_nullptr(itr->second))
node.add_child(json.create_node().add_null(tag));
else
{
node.add_child(json.create_node().add_double(tag, get_value(itr->second)));
}
node.add_child(json.create_node()
.add_double(tag, get_value(itr->second)));
}
return node;
@ -553,9 +546,8 @@ static inline gson(acl::json &json, const std::map<K, V> *objects)
if (check_nullptr(itr->second))
node.add_child(json.create_node().add_null(tag));
else
{
node.add_child(json.create_node().add_double(tag, get_value(itr->second)));
}
node.add_child(json.create_node()
.add_double(tag, get_value(itr->second)));
}
return node;
@ -574,9 +566,8 @@ static inline gson(acl::json &json, const std::map<K, V> &objects)
if (check_nullptr(itr->second))
node.add_child(json.create_node().add_null(tag));
else
{
node.add_child(json.create_node().add_bool(tag, itr->second));
}
node.add_child(json.create_node()
.add_bool(tag, itr->second));
}
return node;
@ -595,9 +586,28 @@ static inline gson(acl::json &json, const std::map<K, V> & objects)
if (check_nullptr(itr->second))
node.add_child(json.create_node().add_null(tag));
else
{
node.add_child(json.create_node().add_text(tag, get_value(itr->second)));
}
node.add_child(json.create_node()
.add_text(tag, get_value(itr->second)));
}
return node;
}
template<class K, class V>
typename enable_if<is_string<V>::value
|| is_char_ptr<V>::value, acl::json_node &>::type
static inline gson(acl::json &json, const std::map<K, V*> & objects)
{
acl::json_node &node = json.create_array();
for (typename std::map<K, V*>::const_iterator
itr = objects.begin(); itr != objects.end(); ++itr)
{
const char *tag = get_value(itr->first);
if (check_nullptr(itr->second))
node.add_child(json.create_node().add_null(tag));
else
node.add_child(json.create_node()
.add_text(tag, get_value(itr->second)));
}
return node;
@ -617,7 +627,8 @@ static inline gson(acl::json &json, const std::map<T, V> &objects)
else
{
acl::json_node &item = gson(json, itr->second);
node.add_child(json.create_node().add_child(tag, item));
node.add_child(json.create_node()
.add_child(tag, item));
}
}
@ -627,10 +638,17 @@ static inline gson(acl::json &json, const std::map<T, V> &objects)
template<class T, class V>
typename enable_if<is_object<V>::value, acl::json_node &>::type
static inline gson(acl::json &json, const std::map<T, V> *objects)
{
return gson(json, *objects);
}
template<class T, class V>
typename enable_if<is_object<V>::value, acl::json_node &>::type
static inline gson(acl::json &json, const std::map<T, V*> &objects)
{
acl::json_node &node = json.create_array();
for (typename std::map<T, V>::const_iterator
itr = objects->begin(); itr != objects->end(); ++itr)
for (typename std::map<T, V*>::const_iterator
itr = objects.begin(); itr != objects.end(); ++itr)
{
const char *tag = get_value(itr->first);
if (check_nullptr(itr->second))
@ -638,13 +656,21 @@ static inline gson(acl::json &json, const std::map<T, V> *objects)
else
{
acl::json_node &item = gson(json, itr->second);
node.add_child(json.create_node().add_child(tag, item));
node.add_child(json.create_node()
.add_child(tag, item));
}
}
return node;
}
template<class T, class V>
typename enable_if<is_object<V>::value, acl::json_node &>::type
static inline gson(acl::json &json, const std::map<T, V*> *objects)
{
return gson(json, *objects);
}
//////////////////////////////////////////////////////////////////////////////
template <class T>
@ -666,7 +692,8 @@ static inline void del(T *obj)
}
//bool
static inline std::pair<bool, std::string> gson(acl::json_node &node, bool *obj)
static inline std::pair<bool, std::string>
gson(acl::json_node &node, bool *obj)
{
if (node.is_bool() == false)
return std::make_pair(false, "get bool failed");
@ -675,7 +702,8 @@ static inline std::pair<bool, std::string> gson(acl::json_node &node, bool *obj)
return std::make_pair(true, "");
}
static inline std::pair<bool, std::string> gson(acl::json_node &node, bool **obj)
static inline std::pair<bool, std::string>
gson(acl::json_node &node, bool **obj)
{
*obj = NULL;
if (node.is_bool() == false)
@ -744,7 +772,8 @@ static inline gson(acl::json_node &node, T **obj)
}
//string
static inline std::pair<bool, std::string> gson(acl::json_node &node, char **obj)
static inline std::pair<bool, std::string>
gson(acl::json_node &node, char **obj)
{
*obj = NULL;
if (node.is_string() == false)
@ -758,8 +787,19 @@ static inline std::pair<bool, std::string> gson(acl::json_node &node, char **obj
return std::make_pair(true, "");
}
static inline std::pair<bool, std::string>
gson(acl::json_node &node, acl::string &obj)
{
if (node.is_string() == false)
return std::make_pair(false, "get string failed");
obj.clear();
obj.append(node.get_string());
return std::make_pair(true, "");
}
static inline std::pair<bool, std::string>
gson(acl::json_node &node, acl::string *obj)
gson(acl::json_node &node, acl::string *obj)
{
if (node.is_string() == false)
return std::make_pair(false, "get string failed");
@ -769,7 +809,7 @@ static inline std::pair<bool, std::string>
}
static inline std::pair<bool, std::string>
gson(acl::json_node &node, acl::string **obj)
gson(acl::json_node &node, acl::string **obj)
{
*obj = NULL;
if (node.is_string() == false)
@ -782,7 +822,17 @@ static inline std::pair<bool, std::string>
}
static inline std::pair<bool, std::string>
gson(acl::json_node &node, std::string *obj)
gson(acl::json_node &node, std::string &obj)
{
if (node.is_string() == false)
return std::make_pair(false, "get string failed");
obj.clear();
obj.append(node.get_string());
return std::make_pair(true, "");
}
static inline std::pair<bool, std::string>
gson(acl::json_node &node, std::string *obj)
{
if (node.is_string() == false)
return std::make_pair(false, "get string failed");
@ -792,7 +842,7 @@ static inline std::pair<bool, std::string>
}
static inline std::pair<bool, std::string>
gson(acl::json_node &node, std::string **obj)
gson(acl::json_node &node, std::string **obj)
{
*obj = NULL;
if (node.is_string() == false)
@ -804,9 +854,10 @@ static inline std::pair<bool, std::string>
return std::make_pair(true, "");
}
// list
template<class T>
static inline std::pair<bool, std::string>
gson(acl::json_node &node, std::list<T> *objs)
gson(acl::json_node &node, std::list<T> *objs)
{
std::pair<bool, std::string> result;
std::string error_string;
@ -814,19 +865,57 @@ static inline std::pair<bool, std::string>
while (itr)
{
// for avoiding object's member pointor copy, the obj can be
// put in list first, when error happened just only erase it.
// ---lindawei
T obj;
result = gson(*itr, &obj);
if (result.first)
objs->push_back(obj);
else
objs->push_back(obj);
typename std::list<T>::iterator it = objs->end();
--it;
result = gson(*itr, *it);
if (!result.first)
{
error_string.append(result.second);
objs->erase(it);
}
itr = node.next_child();
}
return std::make_pair(!!!objs->empty(), error_string);
}
//vector
// list
template<class T>
static inline std::pair<bool, std::string>
gson(acl::json_node &node, std::list<T*> *objs)
{
std::pair<bool, std::string> result;
std::string error_string;
acl::json_node *itr = node.first_child();
while (itr)
{
// for avoiding object's member pointor copy
// ---lindawei
T* obj = new T;
objs->push_back(obj);
typename std::list<T*>::iterator it = objs->end();
--it;
result = gson(*itr, *it);
if (!result.first)
{
error_string.append(result.second);
objs->erase(it);
}
itr = node.next_child();
}
return std::make_pair(!!!objs->empty(), error_string);
}
// vector
template<class T>
std::pair<bool, std::string>
static inline gson(acl::json_node &node, std::vector<T> *objs)
@ -837,14 +926,47 @@ static inline gson(acl::json_node &node, std::vector<T> *objs)
while (itr)
{
// for avoiding object's member pointor copy
// ---lindawei
T obj;
result = gson(*itr, &obj);
if (result.first)
objs->push_back(obj);
else
objs->push_back(obj);
typename std::vector<T>::iterator it = objs->end();
--it;
result = gson(*itr, *it);
if (!result.first)
{
error_string.append(result.second);
objs->erase(it);
}
itr = node.next_child();
}
return std::make_pair(!!!objs->empty(), error_string);
}
// vector
template<class T>
std::pair<bool, std::string>
static inline gson(acl::json_node &node, std::vector<T*> *objs)
{
std::pair<bool, std::string> result;
acl::json_node *itr = node.first_child();
std::string error_string;
while (itr)
{
T* obj = new T;
objs->push_back(obj);
typename std::vector<T*>::iterator it = objs->end();
--it;
result = gson(*itr, *it);
if (!result.first)
{
error_string.append(result.second);
objs->erase(it);
}
itr = node.next_child();
//todo delete obj when failed
}
return std::make_pair(!!!objs->empty(), error_string);
@ -868,8 +990,7 @@ static inline gson(acl::json_node &node, T **obj)
///////////////////////////////////////////map////////////////////////////////
//int map
// int map
template<class K, class T>
typename enable_if<
is_string<T>::value||
@ -938,7 +1059,7 @@ static inline expand(acl::json_node &node, std::map<K, T> *objs)
return result;
}
//map
// map
template<class K, class V>
std::pair<bool, std::string>
static inline gson(acl::json_node &node, std::map<K, V> *objs)
@ -958,4 +1079,92 @@ static inline gson(acl::json_node &node, std::map<K, V> *objs)
return std::make_pair(!!!objs->empty(), error_string);
}
template<class K, class T>
typename enable_if<
is_string<T>::value||
is_bool<T>::value||
is_number<T>::value||
is_double<T>::value||
is_char_ptr<T>::value,
std::pair<bool, std::string> >::type
static inline expand(acl::json_node &node, std::map<K, T*> *objs)
{
std::pair<bool, std::string> result;
acl::json_node *itr = node.first_child();
while (itr)
{
T* obj = new T;
result = gson(*itr, obj);
if (!result.first)
break;
objs->insert(std::make_pair(K(itr->tag_name()), obj));
itr = node.next_child();
}
if (result.first)
return std::make_pair(true, "");
for (typename std::map<K, T*>::iterator it = objs->begin();
it != objs->end(); ++it)
{
del(it->second);
}
objs->clear();
return result;
}
template<class K, class T>
typename enable_if <is_object<T>::value ,
std::pair<bool, std::string > > ::type
static inline expand(acl::json_node &node, std::map<K, T*> *objs)
{
std::pair<bool, std::string> result;
acl::json_node *itr = node.first_child();
while (itr && itr->get_obj())
{
T* obj = new T;
result = gson(*(itr->get_obj()), obj);
if (!result.first)
break;
objs->insert(std::make_pair(K(itr->tag_name()), obj));
itr = node.next_child();
}
if (result.first)
return std::make_pair(true, "");
for (typename std::map<K, T*>::iterator itr2 = objs->begin();
itr2 != objs->end(); ++itr2)
{
del(itr2->second);
}
objs->clear();
return result;
}
// map
template<class K, class V>
std::pair<bool, std::string>
static inline gson(acl::json_node &node, std::map<K, V*> *objs)
{
std::pair<bool, std::string> result;
acl::json_node *itr = node.first_child();
std::string error_string;
while (itr)
{
result = expand(*itr, objs);
if (result.first == false)
error_string.append(result.second);
itr = node.next_child();
}
return std::make_pair(!!!objs->empty(), error_string);
}
} // namespace acl