Connection.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473
  1. #ifndef __CONNECTION_H__
  2. #define __CONNECTION_H__
  3. #include "../global.h"
  4. #include <string>
  5. #include <vector>
  6. #include <set>
  7. #include <boost/type_traits/is_fundamental.hpp>
  8. #include <boost/type_traits/is_enum.hpp>
  9. #include <boost/type_traits/is_pointer.hpp>
  10. #include <boost/type_traits/is_class.hpp>
  11. #include <boost/type_traits/remove_pointer.hpp>
  12. #include <boost/mpl/eval_if.hpp>
  13. #include <boost/mpl/equal_to.hpp>
  14. #include <boost/mpl/int.hpp>
  15. #include <boost/mpl/identity.hpp>
  16. #include <boost/type_traits/is_array.hpp>
  17. const int version = 63;
  18. class CConnection;
  19. namespace mpl = boost::mpl;
  20. template<typename T, size_t N> char (&_ArrayCountObj(const T (&)[N]))[N];
  21. #define ARRAY_COUNT(arr) (sizeof(_ArrayCountObj(arr)))
  22. namespace boost
  23. {
  24. namespace asio
  25. {
  26. namespace ip
  27. {
  28. class tcp;
  29. }
  30. class io_service;
  31. template <typename Protocol> class stream_socket_service;
  32. template <typename Protocol,typename StreamSocketService>
  33. class basic_stream_socket;
  34. template <typename Protocol> class socket_acceptor_service;
  35. template <typename Protocol,typename SocketAcceptorService>
  36. class basic_socket_acceptor;
  37. }
  38. class mutex;
  39. };
  40. enum SerializationLvl
  41. {
  42. Wrong=0,
  43. Primitive,
  44. Array,
  45. Pointer,
  46. Serializable
  47. };
  48. template<typename Ser,typename T>
  49. struct SavePrimitive
  50. {
  51. static void invoke(Ser &s, const T &data)
  52. {
  53. s.savePrimitive(data);
  54. }
  55. };
  56. template<typename Ser,typename T>
  57. struct SaveSerializable
  58. {
  59. static void invoke(Ser &s, const T &data)
  60. {
  61. s.saveSerializable(data);
  62. }
  63. };
  64. template<typename Ser,typename T>
  65. struct LoadPrimitive
  66. {
  67. static void invoke(Ser &s, T &data)
  68. {
  69. s.loadPrimitive(data);
  70. }
  71. };
  72. template<typename Ser,typename T>
  73. struct SavePointer
  74. {
  75. static void invoke(Ser &s, const T &data)
  76. {
  77. s.savePointer(data);
  78. }
  79. };
  80. template<typename Ser,typename T>
  81. struct LoadPointer
  82. {
  83. static void invoke(Ser &s, T &data)
  84. {
  85. s.loadPointer(data);
  86. }
  87. };
  88. template<typename Ser,typename T>
  89. struct SaveArray
  90. {
  91. static void invoke(Ser &s, const T &data)
  92. {
  93. s.saveArray(data);
  94. }
  95. };
  96. template<typename Ser,typename T>
  97. struct LoadArray
  98. {
  99. static void invoke(Ser &s, T &data)
  100. {
  101. s.loadArray(data);
  102. }
  103. };
  104. template<typename Ser,typename T>
  105. struct LoadSerializable
  106. {
  107. static void invoke(Ser &s, T &data)
  108. {
  109. s.loadSerializable(data);
  110. }
  111. };
  112. template<typename Ser,typename T>
  113. struct SaveWrong
  114. {
  115. static void invoke(Ser &s, const T &data)
  116. {
  117. throw std::string("Wrong save serialization call!");
  118. }
  119. };
  120. template<typename Ser,typename T>
  121. struct LoadWrong
  122. {
  123. static void invoke(Ser &s, const T &data)
  124. {
  125. throw std::string("Wrong load serialization call!");
  126. }
  127. };
  128. template<typename T>
  129. struct SerializationLevel
  130. {
  131. typedef mpl::integral_c_tag tag;
  132. typedef
  133. typename mpl::eval_if<
  134. boost::is_fundamental<T>,
  135. mpl::int_<Primitive>,
  136. //else
  137. typename mpl::eval_if<
  138. boost::is_class<T>,
  139. mpl::int_<Serializable>,
  140. //else
  141. typename mpl::eval_if<
  142. boost::is_array<T>,
  143. mpl::int_<Array>,
  144. //else
  145. typename mpl::eval_if<
  146. boost::is_pointer<T>,
  147. mpl::int_<Pointer>,
  148. //else
  149. typename mpl::eval_if<
  150. boost::is_enum<T>,
  151. mpl::int_<Primitive>,
  152. //else
  153. mpl::int_<Wrong>
  154. >
  155. >
  156. >
  157. >
  158. >::type type;
  159. static const int value = SerializationLevel::type::value;
  160. };
  161. template <typename Serializer> class DLL_EXPORT COSer
  162. {
  163. public:
  164. bool saving;
  165. COSer(){saving=true;};
  166. Serializer * This()
  167. {
  168. return static_cast<Serializer*>(this);
  169. }
  170. template<class T>
  171. Serializer & operator<<(const T &t)
  172. {
  173. this->This()->save(t);
  174. return * this->This();
  175. }
  176. template<class T>
  177. COSer & operator&(T & t)
  178. {
  179. return * this->This() << t;
  180. }
  181. int write(const void * data, unsigned size);
  182. template <typename T>
  183. void savePrimitive(const T &data)
  184. {
  185. this->This()->write(&data,sizeof(data));
  186. }
  187. template <typename T>
  188. void savePointer(const T &data)
  189. {
  190. ui8 hlp = (data!=NULL);
  191. *this << hlp;
  192. if(hlp)
  193. *this << *data;
  194. }
  195. template <typename T>
  196. void saveArray(const T &data)
  197. {
  198. ui32 size = ARRAY_COUNT(data);
  199. for(ui32 i=0; i < size; i++)
  200. *this << data[i];
  201. }
  202. template <typename T>
  203. void save(const T &data)
  204. {
  205. typedef
  206. //if
  207. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
  208. mpl::identity<SavePrimitive<Serializer,T> >,
  209. //else if
  210. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
  211. mpl::identity<SavePointer<Serializer,T> >,
  212. //else if
  213. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Array> >,
  214. mpl::identity<SaveArray<Serializer,T> >,
  215. //else if
  216. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
  217. mpl::identity<SaveSerializable<Serializer,T> >,
  218. //else
  219. mpl::identity<SaveWrong<Serializer,T> >
  220. >
  221. >
  222. >
  223. >::type typex;
  224. typex::invoke(* this->This(), data);
  225. }
  226. template <typename T>
  227. void saveSerializable(const T &data)
  228. {
  229. const_cast<T&>(data).serialize(*this,version);
  230. }
  231. template <typename T>
  232. void saveSerializable(const std::vector<T> &data)
  233. {
  234. boost::uint32_t length = data.size();
  235. *this << length;
  236. for(ui32 i=0;i<length;i++)
  237. *this << data[i];
  238. }
  239. template <typename T>
  240. void saveSerializable(const std::set<T> &data)
  241. {
  242. std::set<T> &d = const_cast<std::set<T> &>(data);
  243. boost::uint32_t length = d.size();
  244. *this << length;
  245. for(typename std::set<T>::iterator i=d.begin();i!=d.end();i++)
  246. *this << *i;
  247. }
  248. void saveSerializable(const std::string &data)
  249. {
  250. *this << ui32(data.length());
  251. this->This()->write(data.c_str(),data.size());
  252. }
  253. template <typename T1, typename T2>
  254. void saveSerializable(const std::pair<T1,T2> &data)
  255. {
  256. *this << data.first << data.second;
  257. }
  258. template <typename T1, typename T2>
  259. void saveSerializable(const std::map<T1,T2> &data)
  260. {
  261. *this << ui32(data.size());
  262. for(typename std::map<T1,T2>::const_iterator i=data.begin();i!=data.end();i++)
  263. *this << i->first << i->second;
  264. }
  265. };
  266. template <typename Serializer> class DLL_EXPORT CISer
  267. {
  268. public:
  269. bool saving;
  270. CISer(){saving = false;};
  271. Serializer * This()
  272. {
  273. return static_cast<Serializer*>(this);
  274. }
  275. template<class T>
  276. Serializer & operator>>(T &t)
  277. {
  278. this->This()->load(t);
  279. return * this->This();
  280. }
  281. template<class T>
  282. CISer & operator&(T & t)
  283. {
  284. return * this->This() >> t;
  285. }
  286. int write(const void * data, unsigned size);
  287. template <typename T>
  288. void load(T &data)
  289. {
  290. typedef
  291. //if
  292. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
  293. mpl::identity<LoadPrimitive<Serializer,T> >,
  294. //else if
  295. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
  296. mpl::identity<LoadPointer<Serializer,T> >,
  297. //else if
  298. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Array> >,
  299. mpl::identity<LoadArray<Serializer,T> >,
  300. //else if
  301. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
  302. mpl::identity<LoadSerializable<Serializer,T> >,
  303. //else
  304. mpl::identity<LoadWrong<Serializer,T> >
  305. >
  306. >
  307. >
  308. >::type typex;
  309. typex::invoke(* this->This(), data);
  310. }
  311. template <typename T>
  312. void loadPrimitive(T &data)
  313. {
  314. this->This()->read(&data,sizeof(data));
  315. }
  316. template <typename T>
  317. void loadSerializable(T &data)
  318. {
  319. data.serialize(*this,version);
  320. }
  321. template <typename T>
  322. void loadArray(T &data)
  323. {
  324. ui32 size = ARRAY_COUNT(data);
  325. for(ui32 i=0; i < size; i++)
  326. *this >> data[i];
  327. }
  328. template <typename T>
  329. void loadPointer(T &data)
  330. {
  331. ui8 hlp;
  332. *this >> hlp;
  333. if(!hlp)
  334. {
  335. data = NULL;
  336. return;
  337. }
  338. tlog5<<"Allocating memory for pointer!"<<std::endl;
  339. typedef typename boost::remove_pointer<T>::type npT;
  340. data = new npT;
  341. *this >> *data;
  342. }
  343. template <typename T>
  344. void loadSerializable(std::vector<T> &data)
  345. {
  346. boost::uint32_t length;
  347. *this >> length;
  348. data.resize(length);
  349. for(ui32 i=0;i<length;i++)
  350. *this >> data[i];
  351. }
  352. template <typename T>
  353. void loadSerializable(std::set<T> &data)
  354. {
  355. boost::uint32_t length;
  356. *this >> length;
  357. T ins;
  358. for(ui32 i=0;i<length;i++)
  359. {
  360. *this >> ins;
  361. data.insert(ins);
  362. }
  363. }
  364. template <typename T1, typename T2>
  365. void loadSerializable(std::pair<T1,T2> &data)
  366. {
  367. *this >> data.first >> data.second;
  368. }
  369. template <typename T1, typename T2>
  370. void loadSerializable(std::map<T1,T2> &data)
  371. {
  372. ui32 length;
  373. *this >> length;
  374. T1 t;
  375. for(int i=0;i<length;i++)
  376. {
  377. *this >> t;
  378. *this >> data[t];
  379. }
  380. }
  381. void loadSerializable(std::string &data)
  382. {
  383. ui32 length;
  384. *this >> length;
  385. data.resize(length);
  386. this->This()->read((void*)data.c_str(),length);
  387. }
  388. };
  389. class DLL_EXPORT CSaveFile
  390. : public COSer<CSaveFile>
  391. {
  392. void dummyMagicFunction()
  393. {
  394. *this << std::string("This function makes stuff working.");
  395. }
  396. public:
  397. std::ofstream *sfile;
  398. CSaveFile(const std::string &fname);
  399. ~CSaveFile();
  400. int write(const void * data, unsigned size);
  401. };
  402. class DLL_EXPORT CLoadFile
  403. : public CISer<CLoadFile>
  404. {
  405. void dummyMagicFunction()
  406. {
  407. std::string dummy = "This function makes stuff working.";
  408. *this >> dummy;
  409. }
  410. public:
  411. std::ifstream *sfile;
  412. CLoadFile(const std::string &fname);
  413. ~CLoadFile();
  414. int read(const void * data, unsigned size);
  415. };
  416. class DLL_EXPORT CConnection
  417. :public CISer<CConnection>, public COSer<CConnection>
  418. {
  419. CConnection(void);
  420. void init();
  421. public:
  422. boost::mutex *rmx, *wmx; // read/write mutexes
  423. boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > * socket;
  424. bool logging;
  425. bool connected;
  426. bool myEndianess, contactEndianess; //true if little endian, if ednianess is different we'll have to revert recieved multi-byte vars
  427. boost::asio::io_service *io_service;
  428. std::string name; //who uses this connection
  429. CConnection
  430. (std::string host, std::string port, std::string Name);
  431. CConnection
  432. (boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> > * acceptor,
  433. boost::asio::io_service *Io_service, std::string Name);
  434. CConnection
  435. (boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > * Socket,
  436. std::string Name); //use immediately after accepting connection into socket
  437. int write(const void * data, unsigned size);
  438. int read(void * data, unsigned size);
  439. int readLine(void * data, unsigned maxSize);
  440. void close();
  441. ~CConnection(void);
  442. };
  443. #endif // __CONNECTION_H__