/** * 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////////////////////////// // TEMPLATE CLASS _Is_number template struct _Is_number : std::false_type { }; template<> struct _Is_number : std::true_type { }; template<> struct _Is_number : std::true_type { }; template<> struct _Is_number : std::true_type { }; template<> struct _Is_number : std::true_type { }; template<> struct _Is_number : std::true_type { }; template<> struct _Is_number : std::true_type { }; template<> struct _Is_number : std::true_type { }; template<> struct _Is_number : std::true_type { }; template struct is_number : _Is_number::type>::type> { }; //string template struct _Is_string : std::false_type { }; template<> struct _Is_string : std::true_type { }; template<> struct _Is_string : std::true_type { }; template struct is_string : _Is_string::type>::type> { }; //double template struct _Is_double : std::false_type { }; template<> struct _Is_double : std::true_type { }; template<> struct _Is_double : std::true_type { }; template<> struct _Is_double : std::true_type { }; template struct is_double : _Is_double::type>::type> { }; //char ptr. c string in cpp template struct _Is_char_ptr : std::false_type { }; template<> struct _Is_char_ptr : std::true_type { }; template struct is_char_ptr :_Is_char_ptr::type> { }; template struct _Is_bool : std::false_type { }; template<> struct _Is_bool : std::true_type { }; template struct is_bool : _Is_bool::type>::type> { }; template struct _Is_object :std::false_type { }; template<> struct _Is_object : std::true_type { }; template struct is_object : _Is_object ::value && !std::is_floating_point::type>::type>::value && !is_number::value && !is_bool::value && !is_char_ptr::value> { }; // template typename std::enable_if::value, bool>::type static inline check_nullptr(T&) { return false; } template typename std::enable_if::value, bool>::type static inline check_nullptr(T *t) { if (t == nullptr) return true; return false; } //acl::string ,std::string template typename std::enable_if::value && !std::is_pointer::value, const char *>::type static inline get_value(const T &value) { return value.c_str(); } template typename std::enable_if::value && std::is_pointer::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 std::enable_if::value && !std::is_pointer::value, T>::type static inline get_value(const T t) { return t; } // number pointor -> number // eg: int * -> int . template typename std::enable_if::value && std::is_pointer::value, typename std::remove_pointer::type>::type static inline get_value(const T &t) { return *t; } template typename std::enable_if::value, T>::type static inline get_value(const T &t) { return t; } template typename std::enable_if::value , T>::type static inline get_value(const T *t) { return *t; } // obj template typename std::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)); } template typename std::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 add_item(json, node, *obj); } // number template typename std::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 std::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 std::enable_if::type>::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 std::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 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 std::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 std::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 std::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 std::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 std::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 std::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 std::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 std::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 std::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) { 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 std::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 std::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 = new T; **obj = static_cast(*node.get_double()); return std::make_pair(true, ""); } //intergral template typename std::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 std::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 = new T; **obj = static_cast(*node.get_int64()); return std::make_pair(true, ""); } //string template typename std::enable_if::value, std::pair>::type static inline gson(acl::json_node &node, T **obj) { if (node.is_string() == false) return std::make_pair(false, "get char * string failed"); int len = strlen(node.get_string()); *obj = new T[len + 1]; memcpy(*obj, node.get_string(), len); (*obj)[len] = 0; return std::make_pair(true, ""); } template typename std::enable_if::value && !std::is_pointer::value, std::pair>::type static inline gson(acl::json_node &node, T *obj) { if (node.is_string() == false) return std::make_pair(false, "get string failed"); obj->append(node.get_string()); return std::make_pair(true, ""); } template typename std::enable_if::value, std::pair>::type static inline gson(acl::json_node &node, std::string **obj) { 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 std::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 std::enable_if ::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) objs->insert(std::make_pair(K(itr->tag_name()), obj)); else break; itr = node.next_child(); } if (result.first == false) { for (typename std::map::iterator it = objs->begin(); it != objs->end(); ++it) { del(&it->second); } objs->clear(); return result; } return std::make_pair(true, ""); } template typename std::enable_if ::type>::value && !is_string::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) objs->insert(std::make_pair(K(itr->tag_name()), obj)); else break; itr = node.next_child(); } if (result.first == false) { for (typename std::map::iterator itr2 = objs->begin(); itr2 != objs->end(); ++itr2) { del(&itr2->second); } objs->clear(); return result; } return std::make_pair(true, ""); } //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