Connection.h 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. #pragma once
  2. #include "../global.h"
  3. #include <string>
  4. #include <vector>
  5. #include <set>
  6. #include <boost/type_traits/is_fundamental.hpp>
  7. #include <boost/type_traits/is_enum.hpp>
  8. #include <boost/type_traits/is_pointer.hpp>
  9. #include <boost/type_traits/remove_pointer.hpp>
  10. #include <boost/mpl/eval_if.hpp>
  11. #include <boost/mpl/equal_to.hpp>
  12. #include <boost/mpl/int.hpp>
  13. #include <boost/mpl/identity.hpp>
  14. const int version = 63;
  15. class CConnection;
  16. namespace mpl = boost::mpl;
  17. namespace boost
  18. {
  19. namespace asio
  20. {
  21. namespace ip
  22. {
  23. class tcp;
  24. }
  25. class io_service;
  26. template <typename Protocol> class stream_socket_service;
  27. template <typename Protocol,typename StreamSocketService>
  28. class basic_stream_socket;
  29. template <typename Protocol> class socket_acceptor_service;
  30. template <typename Protocol,typename SocketAcceptorService>
  31. class basic_socket_acceptor;
  32. }
  33. class mutex;
  34. };
  35. enum SerializationLvl
  36. {
  37. Wrong=0,
  38. Primitive,
  39. Pointer,
  40. Serializable
  41. };
  42. template<typename T>
  43. struct SerializationLevel
  44. {
  45. typedef mpl::integral_c_tag tag;
  46. typedef
  47. typename mpl::eval_if<
  48. boost::is_fundamental<T>,
  49. mpl::int_<Primitive>,
  50. //else
  51. typename mpl::eval_if<
  52. boost::is_class<T>,
  53. mpl::int_<Serializable>,
  54. //else
  55. typename mpl::eval_if<
  56. boost::is_array<T>,
  57. mpl::int_<Primitive>,
  58. //else
  59. typename mpl::eval_if<
  60. boost::is_pointer<T>,
  61. mpl::int_<Pointer>,
  62. //else
  63. typename mpl::eval_if<
  64. boost::is_enum<T>,
  65. mpl::int_<Primitive>,
  66. //else
  67. mpl::int_<Wrong>
  68. >
  69. >
  70. >
  71. >
  72. >::type type;
  73. static const int value = SerializationLevel::type::value;
  74. };
  75. template <typename Serializer> class DLL_EXPORT COSer
  76. {
  77. public:
  78. bool saving;
  79. COSer(){saving=true;};
  80. Serializer * This()
  81. {
  82. return static_cast<Serializer*>(this);
  83. }
  84. template<class T>
  85. Serializer & operator<<(const T &t)
  86. {
  87. this->This()->save(t);
  88. return * this->This();
  89. }
  90. template<class T>
  91. COSer & operator&(T & t){
  92. return * this->This() << t;
  93. }
  94. };
  95. template <typename Serializer> class DLL_EXPORT CISer
  96. {
  97. public:
  98. bool saving;
  99. CISer(){saving = false;};
  100. Serializer * This()
  101. {
  102. return static_cast<Serializer*>(this);
  103. }
  104. template<class T>
  105. Serializer & operator>>(T &t)
  106. {
  107. this->This()->load(t);
  108. return * this->This();
  109. }
  110. template<class T>
  111. CISer & operator&(T & t){
  112. return * this->This() >> t;
  113. }
  114. };
  115. template<typename Ser,typename T>
  116. struct SavePrimitive
  117. {
  118. static void invoke(Ser &s, const T &data)
  119. {
  120. s.savePrimitive(data);
  121. }
  122. };
  123. template<typename Ser,typename T>
  124. struct SaveSerializable
  125. {
  126. static void invoke(Ser &s, const T &data)
  127. {
  128. s.saveSerializable(data);
  129. }
  130. };
  131. template<typename Ser,typename T>
  132. struct LoadPrimitive
  133. {
  134. static void invoke(Ser &s, T &data)
  135. {
  136. s.loadPrimitive(data);
  137. }
  138. };
  139. template<typename Ser,typename T>
  140. struct SavePointer
  141. {
  142. static void invoke(Ser &s, const T &data)
  143. {
  144. s.savePointer(data);
  145. }
  146. };
  147. template<typename Ser,typename T>
  148. struct LoadPointer
  149. {
  150. static void invoke(Ser &s, T &data)
  151. {
  152. s.loadPointer(data);
  153. }
  154. };
  155. template<typename Ser,typename T>
  156. struct LoadSerializable
  157. {
  158. static void invoke(Ser &s, T &data)
  159. {
  160. s.loadSerializable(data);
  161. }
  162. };
  163. template<typename Ser,typename T>
  164. struct SaveWrong
  165. {
  166. static void invoke(Ser &s, const T &data)
  167. {
  168. throw std::exception("Wrong save serialization call!");
  169. }
  170. };
  171. template<typename Ser,typename T>
  172. struct LoadWrong
  173. {
  174. static void invoke(Ser &s, const T &data)
  175. {
  176. throw std::exception("Wrong load serialization call!");
  177. }
  178. };
  179. class DLL_EXPORT CConnection
  180. :public CISer<CConnection>, public COSer<CConnection>
  181. {
  182. std::ostream &out;
  183. CConnection(void);
  184. void init();
  185. public:
  186. boost::mutex *rmx, *wmx; // read/write mutexes
  187. template <typename T>
  188. void savePrimitive(const T &data)
  189. {
  190. write(&data,sizeof(data));
  191. }
  192. template <typename T>
  193. void loadPrimitive(T &data)
  194. {
  195. read(&data,sizeof(data));
  196. }
  197. template <typename T>
  198. void saveSerializable(const T &data)
  199. {
  200. const_cast<T&>(data).serialize(*static_cast<COSer<CConnection>*>(this),version);
  201. }
  202. template <typename T>
  203. void loadSerializable(T &data)
  204. {
  205. data.serialize(*static_cast<CISer<CConnection>*>(this),version);
  206. }
  207. template <typename T>
  208. void savePointer(const T &data)
  209. {
  210. *this << *data;
  211. }
  212. template <typename T>
  213. void loadPointer(T &data)
  214. {
  215. std::cout<<"Allocating memory for pointer!"<<std::endl;
  216. typedef boost::remove_pointer<T>::type npT;
  217. data = new npT;
  218. *this >> *data;
  219. }
  220. template <typename T>
  221. void saveSerializable(const std::vector<T> &data)
  222. {
  223. boost::uint32_t length = data.size();
  224. *this << length;
  225. for(ui32 i=0;i<length;i++)
  226. *this << data[i];
  227. }
  228. template <typename T>
  229. void loadSerializable(std::vector<T> &data)
  230. {
  231. boost::uint32_t length;
  232. *this >> length;
  233. data.resize(length);
  234. for(ui32 i=0;i<length;i++)
  235. *this >> data[i];
  236. }
  237. template <typename T>
  238. void saveSerializable(const std::set<T> &data)
  239. {
  240. std::set<T> &d = const_cast<std::set<T> &>(data);
  241. boost::uint32_t length = d.size();
  242. *this << length;
  243. for(typename std::set<T>::iterator i=d.begin();i!=d.end();i++)
  244. *this << *i;
  245. }
  246. template <typename T>
  247. void loadSerializable(std::set<T> &data)
  248. {
  249. boost::uint32_t length;
  250. *this >> length;
  251. T ins;
  252. for(ui32 i=0;i<length;i++)
  253. {
  254. *this >> ins;
  255. data.insert(ins);
  256. }
  257. }
  258. template <typename T1, typename T2>
  259. void saveSerializable(const std::pair<T1,T2> &data)
  260. {
  261. *this << data.first << data.second;
  262. }
  263. template <typename T1, typename T2>
  264. void loadSerializable(std::pair<T1,T2> &data)
  265. {
  266. *this >> data.first >> data.second;
  267. }
  268. template <typename T1, typename T2>
  269. void saveSerializable(const std::map<T1,T2> &data)
  270. {
  271. *this << ui32(data.size());
  272. for(typename std::map<T1,T2>::const_iterator i=data.begin();i!=data.end();i++)
  273. *this << i->first << i->second;
  274. }
  275. template <typename T1, typename T2>
  276. void loadSerializable(std::map<T1,T2> &data)
  277. {
  278. ui32 length;
  279. *this >> length;
  280. T1 t;
  281. for(int i=0;i<length;i++)
  282. {
  283. *this >> t;
  284. *this >> data[t];
  285. }
  286. }
  287. template <typename T>
  288. void save(const T &data)
  289. {
  290. typedef
  291. //if
  292. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
  293. mpl::identity<SavePrimitive<CConnection,T> >,
  294. //else if
  295. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
  296. mpl::identity<SavePointer<CConnection,T> >,
  297. //else if
  298. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
  299. mpl::identity<SaveSerializable<CConnection,T> >,
  300. //else
  301. mpl::identity<SaveWrong<CConnection,T> >
  302. >
  303. >
  304. >::type typex;
  305. typex::invoke(*this, data);
  306. }
  307. template <typename T>
  308. void load(T &data)
  309. {
  310. typedef
  311. //if
  312. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
  313. mpl::identity<LoadPrimitive<CConnection,T> >,
  314. //else if
  315. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
  316. mpl::identity<LoadPointer<CConnection,T> >,
  317. //else if
  318. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
  319. mpl::identity<LoadSerializable<CConnection,T> >,
  320. //else
  321. mpl::identity<LoadWrong<CConnection,T> >
  322. >
  323. >
  324. >::type typex;
  325. typex::invoke(*this, data);
  326. }
  327. boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > * socket;
  328. bool logging;
  329. bool connected;
  330. bool myEndianess, contactEndianess; //true if little endian, if ednianess is different we'll have to revert recieved multi-byte vars
  331. boost::asio::io_service *io_service;
  332. std::string name; //who uses this connection
  333. CConnection
  334. (std::string host, std::string port, std::string Name, std::ostream & Out);
  335. CConnection
  336. (boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> > * acceptor,
  337. boost::asio::io_service *Io_service, std::string Name, std::ostream & Out);
  338. CConnection
  339. (boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > * Socket,
  340. std::string Name, std::ostream & Out); //use immediately after accepting connection into socket
  341. int write(const void * data, unsigned size);
  342. int read(void * data, unsigned size);
  343. int readLine(void * data, unsigned maxSize);
  344. ~CConnection(void);
  345. };
  346. template<> DLL_EXPORT
  347. void CConnection::saveSerializable<std::string>(const std::string &data);
  348. template <>DLL_EXPORT
  349. void CConnection::loadSerializable<std::string>(std::string &data);