/** * Copyright (C) 2015-2018 * All rights reserved. * * AUTHOR(S) * E-mail: niukey@qq.com * * VERSION * Sat 08 Oct 2016 09:07:14 PM CST */ #pragma once #include "acl_cpp/acl_cpp_define.hpp" #include "acl_cpp/stdlib/string.hpp" #include "acl_cpp/stdlib/json.hpp" #include "acl_cpp/stdlib/string.hpp" namespace acl { ///////////////////////////////////type_traits//////////////////////// struct true_type { static const bool value = true; }; struct false_type { static const bool value = false; }; template struct remove_const { typedef T type; }; template struct remove_const { typedef T type; }; template struct remove_volatile { typedef T type; }; template struct remove_volatile { typedef T type; }; template struct remove_cv { typedef typename remove_const ::type>::type type; }; //remove_pointer template struct remove_pointer { typedef T type; }; template struct remove_pointer { typedef T type; }; template struct remove_pointer { typedef T type; }; template struct remove_pointer { typedef T type; }; template struct remove_pointer { typedef T type; }; template struct enable_if { }; template struct enable_if { typedef T type; }; //_Is_number template struct _Is_number : false_type { }; template<> struct _Is_number : true_type { }; template<> struct _Is_number : true_type { }; template<> struct _Is_number : true_type { }; template<> struct _Is_number : true_type { }; template<> struct _Is_number : true_type { }; template<> struct _Is_number : true_type { }; template<> struct _Is_number : true_type { }; template<> struct _Is_number : true_type { }; template struct is_number : _Is_number::type> { }; //string template struct _Is_string : false_type { }; template<> struct _Is_string : true_type { }; template<> struct _Is_string : true_type { }; template struct is_string : _Is_string::type> { }; //double template struct _Is_double : false_type { }; template<> struct _Is_double : true_type { }; template<> struct _Is_double : true_type { }; template<> struct _Is_double : true_type { }; template struct is_double : _Is_double::type> { }; //char ptr. c string in cpp template struct _Is_char_ptr : false_type { }; template<> struct _Is_char_ptr : true_type { }; template struct is_char_ptr :_Is_char_ptr::type> { }; template struct _Is_bool : false_type { }; template<> struct _Is_bool : true_type { }; template struct is_bool : _Is_bool::type> { }; template struct _Is_object :false_type { }; template<> struct _Is_object : true_type { }; template struct is_object : _Is_object< !is_string::value && !is_double::value && !is_number::value && !is_bool::value && !is_char_ptr::value> { }; template static inline bool check_nullptr(T&) { return false; } template static inline bool check_nullptr(T *t) { if (t == NULL) return true; return false; } //acl::string ,std::string template typename enable_if::value, const char *>::type static inline get_value(const T &value) { return value.c_str(); } template typename enable_if::value, const char *>::type static inline get_value(const T *value) { return value->c_str(); } //char *,const char * static inline const char *get_value(const char *value) { return value; } //bool static inline bool get_value(const bool value) { return value; } static inline bool get_value(const bool* value) { return *value; } //number template typename enable_if::value, T>::type static inline get_value(const T t) { return t; } // number pointor -> number // eg: int * -> int . template typename enable_if::value, T>::type static inline get_value(const T *t) { return *t; } template typename enable_if::value, T>::type static inline get_value(const T &t) { return t; } template typename enable_if::value, T>::type static inline get_value(const T *t) { return *t; } // obj template typename enable_if::value, void>::type static inline add_item(acl::json &json, acl::json_node &node, const T &obj) { if(check_nullptr(obj)) node.add_array_null(); else node.add_child(gson(json, obj)); } // number template typename enable_if::value, void>::type static inline add_item(acl::json &, acl::json_node &node, T value) { node.add_array_number(get_value(value)); } template typename enable_if::value, void>::type static inline add_item(acl::json &, acl::json_node &node, T *value) { if (check_nullptr(value)) node.add_array_null(); else node.add_array_number(get_value(value)); } template typename enable_if::value, void>::type static inline add_item(acl::json &, acl::json_node &node, T value) { node.add_array_double(get_value(value)); } template typename enable_if::value, void>::type static inline add_item(acl::json &, acl::json_node &node, T* value) { if(check_nullptr(value)) node.add_array_null(); else node.add_array_double(get_value(value)); } //bool template typename enable_if::value, void>::type static inline add_item(acl::json &, acl::json_node &node, T *value) { if (check_nullptr(value)) node.add_array_null(); else node.add_array_bool(get_value(value)); } template typename enable_if::value, void>::type static inline add_item(acl::json &, acl::json_node &node, T value) { node.add_array_bool(get_value(value)); } template typename enable_if::value, void>::type static inline add_item(acl::json &, acl::json_node &node, T value) { node.add_array_text(get_value(value)); } template typename enable_if::value, void>::type static inline add_item(acl::json &, acl::json_node &node, T *value) { if(check_nullptr(value)) node.add_array_null(); else node.add_array_text(get_value(value)); } static inline void add_item(acl::json &, acl::json_node &node, char *value) { if(check_nullptr(value)) node.add_array_null(); else node.add_array_text(value); } template static inline acl::json_node &gson(acl::json &json, const std::list &objects) { acl::json_node &node = json.create_array(); for (typename std::list::const_iterator itr = objects.begin(); itr != objects.end(); ++itr) { add_item(json, node, *itr); } return node; } template static inline acl::json_node &gson(acl::json &json, const std::list *objects) { acl::json_node &node = json.create_array(); for (typename std::list::const_iterator itr = objects->begin(); itr != objects->end(); ++itr) { add_item(json, node, *itr); } return node; } template static inline acl::json_node &gson(acl::json &json, const std::vector &objects) { acl::json_node &node = json.create_array(); for (typename std::vector::const_iterator itr = objects.begin(); itr != objects.end(); ++itr) { add_item(json, node, *itr); } return node; } template static inline acl::json_node &gson(acl::json &json, const std::vector *objects) { return gson(json, *objects); } //define number map template typename enable_if::value, acl::json_node &>::type static inline gson(acl::json &json, const std::map &objects) { acl::json_node &node = json.create_array(); for (typename std::map::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 { acl::json_node &item = gson(json, itr->second); node.add_child(json.create_node().add_child(tag, item)); } } return node; } //define number map template typename enable_if< is_number::value, acl::json_node &>::type static inline gson(acl::json &json, const std::map *objects) { acl::json_node &node = json.create_array(); for (typename std::map::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 { acl::json_node &item = gson(json, itr->second); node.add_child(json.create_node().add_child(tag, item)); } } return node; } //define floating map template typename enable_if::value, acl::json_node &>::type static inline gson(acl::json &json, const std::map &objects) { acl::json_node &node = json.create_array(); for (typename std::map::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 { acl::json_node &item = gson(json, itr->second); node.add_child(json.create_node().add_child(tag, item)); } } return node; } template typename enable_if::value, acl::json_node &>::type static inline gson(acl::json &json, const std::map *objects) { acl::json_node &node = json.create_array(); for (typename std::map::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 { acl::json_node &item = gson(json, itr->second); node.add_child(json.create_node().add_child(tag, item)); } } return node; } //define bool map template typename enable_if::value, acl::json_node &>::type static inline gson(acl::json &json, const std::map &objects) { acl::json_node &node = json.create_array(); for (typename std::map::const_iterator itr = objects; 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 { acl::json_node &item = gson(json, itr->second); node.add_child(json.create_node().add_child(tag, item)); } } return node; } template typename enable_if::value || is_char_ptr::value, acl::json_node &>::type static inline gson(acl::json &json, const std::map & objects) { acl::json_node &node = json.create_array(); for (typename std::map::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 { acl::json_node &item = gson(json, itr->second); node.add_child(json.create_node().add_child(tag, item)); } } return node; } template typename enable_if::value, acl::json_node &>::type static inline gson(acl::json &json, const std::map &objects) { acl::json_node &node = json.create_array(); for (typename std::map::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 { acl::json_node &item = gson(json, itr->second); node.add_child(json.create_node().add_child(tag, item)); } } return node; } template typename enable_if::value, acl::json_node &>::type static inline gson(acl::json &json, const std::map *objects) { acl::json_node &node = json.create_array(); for (typename std::map::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 { acl::json_node &item = gson(json, itr->second); node.add_child(json.create_node().add_child(tag, item)); } } return node; } ////////////////////////////////////////////////////////////////////////////// template typename enable_if::value, std::pair >::type static inline gson(acl::json_node &node, T **obj); template static inline void del(T **obj) { delete *obj; *obj = NULL; } template static inline void del(T *obj) { (void) obj; } //bool static inline std::pair gson(acl::json_node &node, bool *obj) { if (node.is_bool() == false) return std::make_pair(false, "get bool failed"); *obj = *node.get_bool(); return std::make_pair(true, ""); } static inline std::pair gson(acl::json_node &node, bool **obj) { *obj = NULL; if (node.is_bool() == false) return std::make_pair(false, "get bool failed"); *obj = new bool; **obj = *node.get_bool(); return std::make_pair(true, ""); } //double template typename enable_if::value, std::pair >::type static inline gson(acl::json_node &node, T *obj) { if (node.is_double() == false) return std::make_pair(false, "get double failed"); *obj = static_cast(*node.get_double()); return std::make_pair(true, ""); } template typename enable_if::value, std::pair >::type static inline gson(acl::json_node &node, T **obj) { *obj = NULL; if (node.is_double() == false) return std::make_pair(false, "get double failed");; *obj = new T; **obj = static_cast(*node.get_double()); return std::make_pair(true, ""); } //intergral template typename enable_if::value, std::pair >::type static inline gson(acl::json_node &node, T *obj) { if (node.is_number() == false) return std::make_pair(false, "get number failed"); *obj = static_cast(*node.get_int64()); return std::make_pair(true, ""); } template typename enable_if::value, std::pair >::type static inline gson(acl::json_node &node, T **obj) { *obj = NULL; if (node.is_number() == false) return std::make_pair(false, "get number failed");; *obj = new T; **obj = static_cast(*node.get_int64()); return std::make_pair(true, ""); } //string static inline std::pair gson(acl::json_node &node, char **obj) { *obj = NULL; if (node.is_string() == false) return std::make_pair(false, "get char * string failed"); int len = strlen(node.get_string()); *obj = new char[len + 1]; memcpy(*obj, node.get_string(), len); (*obj)[len] = 0; return std::make_pair(true, ""); } static inline std::pair gson(acl::json_node &node, acl::string *obj) { if (node.is_string() == false) return std::make_pair(false, "get string failed"); obj->append(node.get_string()); return std::make_pair(true, ""); } static inline std::pair gson(acl::json_node &node, acl::string **obj) { *obj = NULL; if (node.is_string() == false) return std::make_pair(false, "get string failed"); *obj = new acl::string; (*obj)->append(node.get_string()); return std::make_pair(true, ""); } static inline std::pair gson(acl::json_node &node, std::string *obj) { if (node.is_string() == false) return std::make_pair(false, "get string failed"); obj->append(node.get_string()); return std::make_pair(true, ""); } static inline std::pair gson(acl::json_node &node, std::string **obj) { *obj = NULL; if (node.is_string() == false) return std::make_pair(false, "get string failed"); *obj = new std::string; (*obj)->append(node.get_string()); return std::make_pair(true, ""); } template static inline std::pair gson(acl::json_node &node, std::list *objs) { std::pair result; std::string error_string; acl::json_node *itr = node.first_child(); while (itr) { T obj; result = gson(*itr, &obj); if (result.first) objs->push_back(obj); else error_string.append(result.second); itr = node.next_child(); } return std::make_pair(!!!objs->empty(), error_string); } //vector template std::pair static inline gson(acl::json_node &node, std::vector *objs) { std::pair result; acl::json_node *itr = node.first_child(); std::string error_string; while (itr) { T obj; result = gson(*itr, &obj); if (result.first) objs->push_back(obj); else error_string.append(result.second); itr = node.next_child(); //todo delete obj when failed } return std::make_pair(!!!objs->empty(), error_string); } template typename enable_if::value, std::pair >::type static inline gson(acl::json_node &node, T **obj) { *obj = new T(); std::pair result = gson(node, *obj); if (result.first == false) { delete *obj; *obj = NULL; } return result; } ///////////////////////////////////////////map//////////////////////////////// //int map template typename enable_if< is_string::value|| is_bool::value|| is_number::value|| is_double::value|| is_char_ptr::value, std::pair >::type static inline expand(acl::json_node &node, std::map *objs) { std::pair result; acl::json_node *itr = node.first_child(); while (itr) { T obj; 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::iterator it = objs->begin(); it != objs->end(); ++it) { del(&it->second); } objs->clear(); return result; } template typename enable_if ::value , std::pair > ::type static inline expand(acl::json_node &node, std::map *objs) { std::pair result; acl::json_node *itr = node.first_child(); while (itr && itr->get_obj()) { T obj; 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::iterator itr2 = objs->begin(); itr2 != objs->end(); ++itr2) { del(&itr2->second); } objs->clear(); return result; } //map template std::pair static inline gson(acl::json_node &node, std::map *objs) { std::pair 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