Connection.h 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. #ifndef __CONNECTION_H__
  2. #define __CONNECTION_H__
  3. #include "../global.h"
  4. #include <string>
  5. #include <vector>
  6. #include <set>
  7. #include <list>
  8. #include <typeinfo>
  9. #include <boost/type_traits/is_fundamental.hpp>
  10. #include <boost/type_traits/is_enum.hpp>
  11. #include <boost/type_traits/is_pointer.hpp>
  12. #include <boost/type_traits/is_class.hpp>
  13. #include <boost/type_traits/remove_pointer.hpp>
  14. #include <boost/mpl/eval_if.hpp>
  15. #include <boost/mpl/equal_to.hpp>
  16. #include <boost/mpl/int.hpp>
  17. #include <boost/mpl/identity.hpp>
  18. #include <boost/type_traits/is_array.hpp>
  19. const ui32 version = 703;
  20. class CConnection;
  21. namespace mpl = boost::mpl;
  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 Serializer> DLL_EXPORT void registerTypes(Serializer &s); //defined in .cpp and explicitly instantiated for used serializers
  49. class DLL_EXPORT CTypeList
  50. {
  51. std::map<const type_info *,ui16> types;
  52. public:
  53. CTypeList();
  54. ui16 registerType(const type_info *type);
  55. template <typename T> ui16 registerType(const T * t)
  56. {
  57. return registerType(&typeid(*t));
  58. }
  59. ui16 getTypeID(const type_info *type);
  60. template <typename T> ui16 getTypeID(const T * t)
  61. {
  62. return getTypeID(&typeid(*t));
  63. }
  64. };
  65. extern DLL_EXPORT CTypeList typeList;
  66. template<typename Ser,typename T>
  67. struct SavePrimitive
  68. {
  69. static void invoke(Ser &s, const T &data)
  70. {
  71. s.savePrimitive(data);
  72. }
  73. };
  74. template<typename Ser,typename T>
  75. struct SaveSerializable
  76. {
  77. static void invoke(Ser &s, const T &data)
  78. {
  79. s.saveSerializable(data);
  80. }
  81. };
  82. template<typename Ser,typename T>
  83. struct LoadPrimitive
  84. {
  85. static void invoke(Ser &s, T &data)
  86. {
  87. s.loadPrimitive(data);
  88. }
  89. };
  90. template<typename Ser,typename T>
  91. struct SavePointer
  92. {
  93. static void invoke(Ser &s, const T &data)
  94. {
  95. s.savePointer(data);
  96. }
  97. };
  98. template<typename Ser,typename T>
  99. struct LoadPointer
  100. {
  101. static void invoke(Ser &s, T &data)
  102. {
  103. s.loadPointer(data);
  104. }
  105. };
  106. template<typename Ser,typename T>
  107. struct SaveArray
  108. {
  109. static void invoke(Ser &s, const T &data)
  110. {
  111. s.saveArray(data);
  112. }
  113. };
  114. template<typename Ser,typename T>
  115. struct LoadArray
  116. {
  117. static void invoke(Ser &s, T &data)
  118. {
  119. s.loadArray(data);
  120. }
  121. };
  122. template<typename Ser,typename T>
  123. struct LoadSerializable
  124. {
  125. static void invoke(Ser &s, T &data)
  126. {
  127. s.loadSerializable(data);
  128. }
  129. };
  130. template<typename Ser,typename T>
  131. struct SaveWrong
  132. {
  133. static void invoke(Ser &s, const T &data)
  134. {
  135. throw std::string("Wrong save serialization call!");
  136. }
  137. };
  138. template<typename Ser,typename T>
  139. struct LoadWrong
  140. {
  141. static void invoke(Ser &s, const T &data)
  142. {
  143. throw std::string("Wrong load serialization call!");
  144. }
  145. };
  146. template<typename T>
  147. struct SerializationLevel
  148. {
  149. typedef mpl::integral_c_tag tag;
  150. typedef
  151. typename mpl::eval_if<
  152. boost::is_fundamental<T>,
  153. mpl::int_<Primitive>,
  154. //else
  155. typename mpl::eval_if<
  156. boost::is_class<T>,
  157. mpl::int_<Serializable>,
  158. //else
  159. typename mpl::eval_if<
  160. boost::is_array<T>,
  161. mpl::int_<Array>,
  162. //else
  163. typename mpl::eval_if<
  164. boost::is_pointer<T>,
  165. mpl::int_<Pointer>,
  166. //else
  167. typename mpl::eval_if<
  168. boost::is_enum<T>,
  169. mpl::int_<Primitive>,
  170. //else
  171. mpl::int_<Wrong>
  172. >
  173. >
  174. >
  175. >
  176. >::type type;
  177. static const int value = SerializationLevel::type::value;
  178. };
  179. class DLL_EXPORT CSerializerBase
  180. {
  181. public:
  182. bool saving;
  183. };
  184. class DLL_EXPORT CSaverBase : public virtual CSerializerBase
  185. {
  186. };
  187. class CBasicPointerSaver
  188. {
  189. public:
  190. virtual void savePtr(CSaverBase &ar, const void *data) const =0;
  191. };
  192. template <typename Serializer, typename T> class CPointerSaver : public CBasicPointerSaver
  193. {
  194. public:
  195. void savePtr(CSaverBase &ar, const void *data) const
  196. {
  197. Serializer &s = static_cast<Serializer&>(ar);
  198. const T *ptr = static_cast<const T*>(data);
  199. //T is most derived known type, it's time to call actual serialize
  200. const_cast<T&>(*ptr).serialize(s,version);
  201. }
  202. };
  203. template <typename Serializer> class DLL_EXPORT COSer : public CSaverBase
  204. {
  205. public:
  206. std::map<ui16,CBasicPointerSaver*> savers; // typeID => CPointerSaver<serializer,type>
  207. COSer()
  208. {
  209. saving=true;
  210. }
  211. template<typename T> void registerType(const T * t=NULL)
  212. {
  213. ui16 ID = typeList.registerType(&typeid(T));
  214. savers[ID] = new CPointerSaver<Serializer,T>;
  215. }
  216. Serializer * This()
  217. {
  218. return static_cast<Serializer*>(this);
  219. }
  220. template<class T>
  221. Serializer & operator<<(const T &t)
  222. {
  223. this->This()->save(t);
  224. return * this->This();
  225. }
  226. template<class T>
  227. COSer & operator&(const T & t)
  228. {
  229. return * this->This() << t;
  230. }
  231. int write(const void * data, unsigned size);
  232. template <typename T>
  233. void savePrimitive(const T &data)
  234. {
  235. this->This()->write(&data,sizeof(data));
  236. }
  237. template <typename T>
  238. void savePointer(const T &data)
  239. {
  240. //write if pointer is not NULL
  241. ui8 hlp = (data!=NULL);
  242. *this << hlp;
  243. //if pointer is NULL then we don't need anything more...
  244. if(!hlp)
  245. return;
  246. //write type identifier
  247. ui16 tid = typeList.getTypeID(data);
  248. *this << tid;
  249. if(!tid)
  250. *this << *data; //if type is unregistered simply write all data in a standard way
  251. else
  252. savers[tid]->savePtr(*this,data); //call serializer specific for our real type
  253. }
  254. template <typename T>
  255. void saveArray(const T &data)
  256. {
  257. ui32 size = ARRAY_COUNT(data);
  258. for(ui32 i=0; i < size; i++)
  259. *this << data[i];
  260. }
  261. template <typename T>
  262. void save(const T &data)
  263. {
  264. typedef
  265. //if
  266. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
  267. mpl::identity<SavePrimitive<Serializer,T> >,
  268. //else if
  269. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
  270. mpl::identity<SavePointer<Serializer,T> >,
  271. //else if
  272. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Array> >,
  273. mpl::identity<SaveArray<Serializer,T> >,
  274. //else if
  275. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
  276. mpl::identity<SaveSerializable<Serializer,T> >,
  277. //else
  278. mpl::identity<SaveWrong<Serializer,T> >
  279. >
  280. >
  281. >
  282. >::type typex;
  283. typex::invoke(* this->This(), data);
  284. }
  285. template <typename T>
  286. void saveSerializable(const T &data)
  287. {
  288. const_cast<T&>(data).serialize(*this,version);
  289. }
  290. template <typename T>
  291. void saveSerializable(const std::vector<T> &data)
  292. {
  293. boost::uint32_t length = data.size();
  294. *this << length;
  295. for(ui32 i=0;i<length;i++)
  296. *this << data[i];
  297. }
  298. template <typename T>
  299. void saveSerializable(const std::set<T> &data)
  300. {
  301. std::set<T> &d = const_cast<std::set<T> &>(data);
  302. boost::uint32_t length = d.size();
  303. *this << length;
  304. for(typename std::set<T>::iterator i=d.begin();i!=d.end();i++)
  305. *this << *i;
  306. }
  307. template <typename T>
  308. void saveSerializable(const std::list<T> &data)
  309. {
  310. std::list<T> &d = const_cast<std::list<T> &>(data);
  311. boost::uint32_t length = d.size();
  312. *this << length;
  313. for(typename std::list<T>::iterator i=d.begin();i!=d.end();i++)
  314. *this << *i;
  315. }
  316. void saveSerializable(const std::string &data)
  317. {
  318. *this << ui32(data.length());
  319. this->This()->write(data.c_str(),data.size());
  320. }
  321. template <typename T1, typename T2>
  322. void saveSerializable(const std::pair<T1,T2> &data)
  323. {
  324. *this << data.first << data.second;
  325. }
  326. template <typename T1, typename T2>
  327. void saveSerializable(const std::map<T1,T2> &data)
  328. {
  329. *this << ui32(data.size());
  330. for(typename std::map<T1,T2>::const_iterator i=data.begin();i!=data.end();i++)
  331. *this << i->first << i->second;
  332. }
  333. };
  334. class DLL_EXPORT CLoaderBase : public virtual CSerializerBase
  335. {};
  336. class CBasicPointerLoader
  337. {
  338. public:
  339. virtual void loadPtr(CLoaderBase &ar, void *data) const =0; //data is pointer to the ACTUAL POINTER
  340. };
  341. template <typename Serializer, typename T> class CPointerLoader : public CBasicPointerLoader
  342. {
  343. public:
  344. void loadPtr(CLoaderBase &ar, void *data) const //data is pointer to the ACTUAL POINTER
  345. {
  346. Serializer &s = static_cast<Serializer&>(ar);
  347. T *&ptr = *static_cast<T**>(data);
  348. //create new object under pointer
  349. typedef typename boost::remove_pointer<T>::type npT;
  350. ptr = new npT;
  351. //T is most derived known type, it's time to call actual serialize
  352. ptr->serialize(s,version);
  353. }
  354. };
  355. template <typename Serializer> class DLL_EXPORT CISer : public CLoaderBase
  356. {
  357. public:
  358. std::map<ui16,CBasicPointerLoader*> loaders; // typeID => CPointerSaver<serializer,type>
  359. CISer()
  360. {
  361. saving = false;
  362. }
  363. template<typename T> void registerType(const T * t=NULL)
  364. {
  365. ui16 ID = typeList.registerType(&typeid(T));
  366. loaders[ID] = new CPointerLoader<Serializer,T>;
  367. }
  368. Serializer * This()
  369. {
  370. return static_cast<Serializer*>(this);
  371. }
  372. template<class T>
  373. Serializer & operator>>(T &t)
  374. {
  375. this->This()->load(t);
  376. return * this->This();
  377. }
  378. template<class T>
  379. CISer & operator&(T & t)
  380. {
  381. return * this->This() >> t;
  382. }
  383. int write(const void * data, unsigned size);
  384. template <typename T>
  385. void load(T &data)
  386. {
  387. typedef
  388. //if
  389. typename mpl::eval_if< mpl::equal_to<SerializationLevel<T>,mpl::int_<Primitive> >,
  390. mpl::identity<LoadPrimitive<Serializer,T> >,
  391. //else if
  392. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Pointer> >,
  393. mpl::identity<LoadPointer<Serializer,T> >,
  394. //else if
  395. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Array> >,
  396. mpl::identity<LoadArray<Serializer,T> >,
  397. //else if
  398. typename mpl::eval_if<mpl::equal_to<SerializationLevel<T>,mpl::int_<Serializable> >,
  399. mpl::identity<LoadSerializable<Serializer,T> >,
  400. //else
  401. mpl::identity<LoadWrong<Serializer,T> >
  402. >
  403. >
  404. >
  405. >::type typex;
  406. typex::invoke(* this->This(), data);
  407. }
  408. template <typename T>
  409. void loadPrimitive(T &data)
  410. {
  411. this->This()->read(&data,sizeof(data));
  412. }
  413. template <typename T>
  414. void loadSerializable(T &data)
  415. {
  416. data.serialize(*this,version);
  417. }
  418. template <typename T>
  419. void loadArray(T &data)
  420. {
  421. ui32 size = ARRAY_COUNT(data);
  422. for(ui32 i=0; i < size; i++)
  423. *this >> data[i];
  424. }
  425. template <typename T>
  426. void loadPointer(T &data)
  427. {
  428. ui8 hlp;
  429. *this >> hlp;
  430. if(!hlp)
  431. {
  432. data = NULL;
  433. return;
  434. }
  435. //get type id
  436. ui16 tid;
  437. *this >> tid;
  438. if(!tid)
  439. {
  440. typedef typename boost::remove_pointer<T>::type npT;
  441. data = new npT;
  442. *this >> *data;
  443. }
  444. else
  445. {
  446. loaders[tid]->loadPtr(*this,&data);
  447. }
  448. }
  449. template <typename T>
  450. void loadSerializable(std::vector<T> &data)
  451. {
  452. boost::uint32_t length;
  453. *this >> length;
  454. data.resize(length);
  455. for(ui32 i=0;i<length;i++)
  456. *this >> data[i];
  457. }
  458. template <typename T>
  459. void loadSerializable(std::set<T> &data)
  460. {
  461. boost::uint32_t length;
  462. *this >> length;
  463. T ins;
  464. for(ui32 i=0;i<length;i++)
  465. {
  466. *this >> ins;
  467. data.insert(ins);
  468. }
  469. }
  470. template <typename T>
  471. void loadSerializable(std::list<T> &data)
  472. {
  473. boost::uint32_t length;
  474. *this >> length;
  475. T ins;
  476. for(ui32 i=0;i<length;i++)
  477. {
  478. *this >> ins;
  479. data.push_back(ins);
  480. }
  481. }
  482. template <typename T1, typename T2>
  483. void loadSerializable(std::pair<T1,T2> &data)
  484. {
  485. *this >> data.first >> data.second;
  486. }
  487. template <typename T1, typename T2>
  488. void loadSerializable(std::map<T1,T2> &data)
  489. {
  490. ui32 length;
  491. *this >> length;
  492. T1 t;
  493. for(int i=0;i<length;i++)
  494. {
  495. *this >> t;
  496. *this >> data[t];
  497. }
  498. }
  499. void loadSerializable(std::string &data)
  500. {
  501. ui32 length;
  502. *this >> length;
  503. data.resize(length);
  504. this->This()->read((void*)data.c_str(),length);
  505. }
  506. };
  507. class DLL_EXPORT CSaveFile
  508. : public COSer<CSaveFile>
  509. {
  510. void dummyMagicFunction()
  511. {
  512. *this << std::string("This function makes stuff working.");
  513. }
  514. public:
  515. std::ofstream *sfile;
  516. CSaveFile(const std::string &fname);
  517. ~CSaveFile();
  518. int write(const void * data, unsigned size);
  519. };
  520. class DLL_EXPORT CLoadFile
  521. : public CISer<CLoadFile>
  522. {
  523. void dummyMagicFunction()
  524. {
  525. std::string dummy = "This function makes stuff working.";
  526. *this >> dummy;
  527. }
  528. public:
  529. std::ifstream *sfile;
  530. CLoadFile(const std::string &fname);
  531. ~CLoadFile();
  532. int read(const void * data, unsigned size);
  533. };
  534. class DLL_EXPORT CConnection
  535. :public CISer<CConnection>, public COSer<CConnection>
  536. {
  537. CConnection(void);
  538. void init();
  539. public:
  540. boost::mutex *rmx, *wmx; // read/write mutexes
  541. boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > * socket;
  542. bool logging;
  543. bool connected;
  544. bool myEndianess, contactEndianess; //true if little endian, if ednianess is different we'll have to revert recieved multi-byte vars
  545. boost::asio::io_service *io_service;
  546. std::string name; //who uses this connection
  547. CConnection
  548. (std::string host, std::string port, std::string Name);
  549. CConnection
  550. (boost::asio::basic_socket_acceptor<boost::asio::ip::tcp, boost::asio::socket_acceptor_service<boost::asio::ip::tcp> > * acceptor,
  551. boost::asio::io_service *Io_service, std::string Name);
  552. CConnection
  553. (boost::asio::basic_stream_socket < boost::asio::ip::tcp , boost::asio::stream_socket_service<boost::asio::ip::tcp> > * Socket,
  554. std::string Name); //use immediately after accepting connection into socket
  555. int write(const void * data, unsigned size);
  556. int read(void * data, unsigned size);
  557. int readLine(void * data, unsigned maxSize);
  558. void close();
  559. ~CConnection(void);
  560. };
  561. #endif // __CONNECTION_H__