PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 0ms

/include/SFML/Network/Packet.hpp

http://github.com/LaurentGomila/SFML
C++ Header | 545 lines | 72 code | 61 blank | 412 comment | 0 complexity | 413804833041001ca20b589e868217bd MD5 | raw file
  1. ////////////////////////////////////////////////////////////
  2. //
  3. // SFML - Simple and Fast Multimedia Library
  4. // Copyright (C) 2007-2019 Laurent Gomila (laurent@sfml-dev.org)
  5. //
  6. // This software is provided 'as-is', without any express or implied warranty.
  7. // In no event will the authors be held liable for any damages arising from the use of this software.
  8. //
  9. // Permission is granted to anyone to use this software for any purpose,
  10. // including commercial applications, and to alter it and redistribute it freely,
  11. // subject to the following restrictions:
  12. //
  13. // 1. The origin of this software must not be misrepresented;
  14. // you must not claim that you wrote the original software.
  15. // If you use this software in a product, an acknowledgment
  16. // in the product documentation would be appreciated but is not required.
  17. //
  18. // 2. Altered source versions must be plainly marked as such,
  19. // and must not be misrepresented as being the original software.
  20. //
  21. // 3. This notice may not be removed or altered from any source distribution.
  22. //
  23. ////////////////////////////////////////////////////////////
  24. #ifndef SFML_PACKET_HPP
  25. #define SFML_PACKET_HPP
  26. ////////////////////////////////////////////////////////////
  27. // Headers
  28. ////////////////////////////////////////////////////////////
  29. #include <SFML/Network/Export.hpp>
  30. #include <string>
  31. #include <vector>
  32. namespace sf
  33. {
  34. class String;
  35. class TcpSocket;
  36. class UdpSocket;
  37. ////////////////////////////////////////////////////////////
  38. /// \brief Utility class to build blocks of data to transfer
  39. /// over the network
  40. ///
  41. ////////////////////////////////////////////////////////////
  42. class SFML_NETWORK_API Packet
  43. {
  44. // A bool-like type that cannot be converted to integer or pointer types
  45. typedef bool (Packet::*BoolType)(std::size_t);
  46. public:
  47. ////////////////////////////////////////////////////////////
  48. /// \brief Default constructor
  49. ///
  50. /// Creates an empty packet.
  51. ///
  52. ////////////////////////////////////////////////////////////
  53. Packet();
  54. ////////////////////////////////////////////////////////////
  55. /// \brief Virtual destructor
  56. ///
  57. ////////////////////////////////////////////////////////////
  58. virtual ~Packet();
  59. ////////////////////////////////////////////////////////////
  60. /// \brief Append data to the end of the packet
  61. ///
  62. /// \param data Pointer to the sequence of bytes to append
  63. /// \param sizeInBytes Number of bytes to append
  64. ///
  65. /// \see clear
  66. /// \see getReadPosition
  67. ///
  68. ////////////////////////////////////////////////////////////
  69. void append(const void* data, std::size_t sizeInBytes);
  70. ////////////////////////////////////////////////////////////
  71. /// \brief Get the current reading position in the packet
  72. ///
  73. /// The next read operation will read data from this position
  74. ///
  75. /// \return The byte offset of the current read position
  76. ///
  77. /// \see append
  78. ///
  79. ////////////////////////////////////////////////////////////
  80. std::size_t getReadPosition() const;
  81. ////////////////////////////////////////////////////////////
  82. /// \brief Clear the packet
  83. ///
  84. /// After calling Clear, the packet is empty.
  85. ///
  86. /// \see append
  87. ///
  88. ////////////////////////////////////////////////////////////
  89. void clear();
  90. ////////////////////////////////////////////////////////////
  91. /// \brief Get a pointer to the data contained in the packet
  92. ///
  93. /// Warning: the returned pointer may become invalid after
  94. /// you append data to the packet, therefore it should never
  95. /// be stored.
  96. /// The return pointer is NULL if the packet is empty.
  97. ///
  98. /// \return Pointer to the data
  99. ///
  100. /// \see getDataSize
  101. ///
  102. ////////////////////////////////////////////////////////////
  103. const void* getData() const;
  104. ////////////////////////////////////////////////////////////
  105. /// \brief Get the size of the data contained in the packet
  106. ///
  107. /// This function returns the number of bytes pointed to by
  108. /// what getData returns.
  109. ///
  110. /// \return Data size, in bytes
  111. ///
  112. /// \see getData
  113. ///
  114. ////////////////////////////////////////////////////////////
  115. std::size_t getDataSize() const;
  116. ////////////////////////////////////////////////////////////
  117. /// \brief Tell if the reading position has reached the
  118. /// end of the packet
  119. ///
  120. /// This function is useful to know if there is some data
  121. /// left to be read, without actually reading it.
  122. ///
  123. /// \return True if all data was read, false otherwise
  124. ///
  125. /// \see operator bool
  126. ///
  127. ////////////////////////////////////////////////////////////
  128. bool endOfPacket() const;
  129. public:
  130. ////////////////////////////////////////////////////////////
  131. /// \brief Test the validity of the packet, for reading
  132. ///
  133. /// This operator allows to test the packet as a boolean
  134. /// variable, to check if a reading operation was successful.
  135. ///
  136. /// A packet will be in an invalid state if it has no more
  137. /// data to read.
  138. ///
  139. /// This behavior is the same as standard C++ streams.
  140. ///
  141. /// Usage example:
  142. /// \code
  143. /// float x;
  144. /// packet >> x;
  145. /// if (packet)
  146. /// {
  147. /// // ok, x was extracted successfully
  148. /// }
  149. ///
  150. /// // -- or --
  151. ///
  152. /// float x;
  153. /// if (packet >> x)
  154. /// {
  155. /// // ok, x was extracted successfully
  156. /// }
  157. /// \endcode
  158. ///
  159. /// Don't focus on the return type, it's equivalent to bool but
  160. /// it disallows unwanted implicit conversions to integer or
  161. /// pointer types.
  162. ///
  163. /// \return True if last data extraction from packet was successful
  164. ///
  165. /// \see endOfPacket
  166. ///
  167. ////////////////////////////////////////////////////////////
  168. operator BoolType() const;
  169. ////////////////////////////////////////////////////////////
  170. /// Overload of operator >> to read data from the packet
  171. ///
  172. ////////////////////////////////////////////////////////////
  173. Packet& operator >>(bool& data);
  174. ////////////////////////////////////////////////////////////
  175. /// \overload
  176. ////////////////////////////////////////////////////////////
  177. Packet& operator >>(Int8& data);
  178. ////////////////////////////////////////////////////////////
  179. /// \overload
  180. ////////////////////////////////////////////////////////////
  181. Packet& operator >>(Uint8& data);
  182. ////////////////////////////////////////////////////////////
  183. /// \overload
  184. ////////////////////////////////////////////////////////////
  185. Packet& operator >>(Int16& data);
  186. ////////////////////////////////////////////////////////////
  187. /// \overload
  188. ////////////////////////////////////////////////////////////
  189. Packet& operator >>(Uint16& data);
  190. ////////////////////////////////////////////////////////////
  191. /// \overload
  192. ////////////////////////////////////////////////////////////
  193. Packet& operator >>(Int32& data);
  194. ////////////////////////////////////////////////////////////
  195. /// \overload
  196. ////////////////////////////////////////////////////////////
  197. Packet& operator >>(Uint32& data);
  198. ////////////////////////////////////////////////////////////
  199. /// \overload
  200. ////////////////////////////////////////////////////////////
  201. Packet& operator >>(Int64& data);
  202. ////////////////////////////////////////////////////////////
  203. /// \overload
  204. ////////////////////////////////////////////////////////////
  205. Packet& operator >>(Uint64& data);
  206. ////////////////////////////////////////////////////////////
  207. /// \overload
  208. ////////////////////////////////////////////////////////////
  209. Packet& operator >>(float& data);
  210. ////////////////////////////////////////////////////////////
  211. /// \overload
  212. ////////////////////////////////////////////////////////////
  213. Packet& operator >>(double& data);
  214. ////////////////////////////////////////////////////////////
  215. /// \overload
  216. ////////////////////////////////////////////////////////////
  217. Packet& operator >>(char* data);
  218. ////////////////////////////////////////////////////////////
  219. /// \overload
  220. ////////////////////////////////////////////////////////////
  221. Packet& operator >>(std::string& data);
  222. ////////////////////////////////////////////////////////////
  223. /// \overload
  224. ////////////////////////////////////////////////////////////
  225. Packet& operator >>(wchar_t* data);
  226. ////////////////////////////////////////////////////////////
  227. /// \overload
  228. ////////////////////////////////////////////////////////////
  229. Packet& operator >>(std::wstring& data);
  230. ////////////////////////////////////////////////////////////
  231. /// \overload
  232. ////////////////////////////////////////////////////////////
  233. Packet& operator >>(String& data);
  234. ////////////////////////////////////////////////////////////
  235. /// Overload of operator << to write data into the packet
  236. ///
  237. ////////////////////////////////////////////////////////////
  238. Packet& operator <<(bool data);
  239. ////////////////////////////////////////////////////////////
  240. /// \overload
  241. ////////////////////////////////////////////////////////////
  242. Packet& operator <<(Int8 data);
  243. ////////////////////////////////////////////////////////////
  244. /// \overload
  245. ////////////////////////////////////////////////////////////
  246. Packet& operator <<(Uint8 data);
  247. ////////////////////////////////////////////////////////////
  248. /// \overload
  249. ////////////////////////////////////////////////////////////
  250. Packet& operator <<(Int16 data);
  251. ////////////////////////////////////////////////////////////
  252. /// \overload
  253. ////////////////////////////////////////////////////////////
  254. Packet& operator <<(Uint16 data);
  255. ////////////////////////////////////////////////////////////
  256. /// \overload
  257. ////////////////////////////////////////////////////////////
  258. Packet& operator <<(Int32 data);
  259. ////////////////////////////////////////////////////////////
  260. /// \overload
  261. ////////////////////////////////////////////////////////////
  262. Packet& operator <<(Uint32 data);
  263. ////////////////////////////////////////////////////////////
  264. /// \overload
  265. ////////////////////////////////////////////////////////////
  266. Packet& operator <<(Int64 data);
  267. ////////////////////////////////////////////////////////////
  268. /// \overload
  269. ////////////////////////////////////////////////////////////
  270. Packet& operator <<(Uint64 data);
  271. ////////////////////////////////////////////////////////////
  272. /// \overload
  273. ////////////////////////////////////////////////////////////
  274. Packet& operator <<(float data);
  275. ////////////////////////////////////////////////////////////
  276. /// \overload
  277. ////////////////////////////////////////////////////////////
  278. Packet& operator <<(double data);
  279. ////////////////////////////////////////////////////////////
  280. /// \overload
  281. ////////////////////////////////////////////////////////////
  282. Packet& operator <<(const char* data);
  283. ////////////////////////////////////////////////////////////
  284. /// \overload
  285. ////////////////////////////////////////////////////////////
  286. Packet& operator <<(const std::string& data);
  287. ////////////////////////////////////////////////////////////
  288. /// \overload
  289. ////////////////////////////////////////////////////////////
  290. Packet& operator <<(const wchar_t* data);
  291. ////////////////////////////////////////////////////////////
  292. /// \overload
  293. ////////////////////////////////////////////////////////////
  294. Packet& operator <<(const std::wstring& data);
  295. ////////////////////////////////////////////////////////////
  296. /// \overload
  297. ////////////////////////////////////////////////////////////
  298. Packet& operator <<(const String& data);
  299. protected:
  300. friend class TcpSocket;
  301. friend class UdpSocket;
  302. ////////////////////////////////////////////////////////////
  303. /// \brief Called before the packet is sent over the network
  304. ///
  305. /// This function can be defined by derived classes to
  306. /// transform the data before it is sent; this can be
  307. /// used for compression, encryption, etc.
  308. /// The function must return a pointer to the modified data,
  309. /// as well as the number of bytes pointed.
  310. /// The default implementation provides the packet's data
  311. /// without transforming it.
  312. ///
  313. /// \param size Variable to fill with the size of data to send
  314. ///
  315. /// \return Pointer to the array of bytes to send
  316. ///
  317. /// \see onReceive
  318. ///
  319. ////////////////////////////////////////////////////////////
  320. virtual const void* onSend(std::size_t& size);
  321. ////////////////////////////////////////////////////////////
  322. /// \brief Called after the packet is received over the network
  323. ///
  324. /// This function can be defined by derived classes to
  325. /// transform the data after it is received; this can be
  326. /// used for decompression, decryption, etc.
  327. /// The function receives a pointer to the received data,
  328. /// and must fill the packet with the transformed bytes.
  329. /// The default implementation fills the packet directly
  330. /// without transforming the data.
  331. ///
  332. /// \param data Pointer to the received bytes
  333. /// \param size Number of bytes
  334. ///
  335. /// \see onSend
  336. ///
  337. ////////////////////////////////////////////////////////////
  338. virtual void onReceive(const void* data, std::size_t size);
  339. private:
  340. ////////////////////////////////////////////////////////////
  341. /// Disallow comparisons between packets
  342. ///
  343. ////////////////////////////////////////////////////////////
  344. bool operator ==(const Packet& right) const;
  345. bool operator !=(const Packet& right) const;
  346. ////////////////////////////////////////////////////////////
  347. /// \brief Check if the packet can extract a given number of bytes
  348. ///
  349. /// This function updates accordingly the state of the packet.
  350. ///
  351. /// \param size Size to check
  352. ///
  353. /// \return True if \a size bytes can be read from the packet
  354. ///
  355. ////////////////////////////////////////////////////////////
  356. bool checkSize(std::size_t size);
  357. ////////////////////////////////////////////////////////////
  358. // Member data
  359. ////////////////////////////////////////////////////////////
  360. std::vector<char> m_data; //!< Data stored in the packet
  361. std::size_t m_readPos; //!< Current reading position in the packet
  362. std::size_t m_sendPos; //!< Current send position in the packet (for handling partial sends)
  363. bool m_isValid; //!< Reading state of the packet
  364. };
  365. } // namespace sf
  366. #endif // SFML_PACKET_HPP
  367. ////////////////////////////////////////////////////////////
  368. /// \class sf::Packet
  369. /// \ingroup network
  370. ///
  371. /// Packets provide a safe and easy way to serialize data,
  372. /// in order to send it over the network using sockets
  373. /// (sf::TcpSocket, sf::UdpSocket).
  374. ///
  375. /// Packets solve 2 fundamental problems that arise when
  376. /// transferring data over the network:
  377. /// \li data is interpreted correctly according to the endianness
  378. /// \li the bounds of the packet are preserved (one send == one receive)
  379. ///
  380. /// The sf::Packet class provides both input and output modes.
  381. /// It is designed to follow the behavior of standard C++ streams,
  382. /// using operators >> and << to extract and insert data.
  383. ///
  384. /// It is recommended to use only fixed-size types (like sf::Int32, etc.),
  385. /// to avoid possible differences between the sender and the receiver.
  386. /// Indeed, the native C++ types may have different sizes on two platforms
  387. /// and your data may be corrupted if that happens.
  388. ///
  389. /// Usage example:
  390. /// \code
  391. /// sf::Uint32 x = 24;
  392. /// std::string s = "hello";
  393. /// double d = 5.89;
  394. ///
  395. /// // Group the variables to send into a packet
  396. /// sf::Packet packet;
  397. /// packet << x << s << d;
  398. ///
  399. /// // Send it over the network (socket is a valid sf::TcpSocket)
  400. /// socket.send(packet);
  401. ///
  402. /// -----------------------------------------------------------------
  403. ///
  404. /// // Receive the packet at the other end
  405. /// sf::Packet packet;
  406. /// socket.receive(packet);
  407. ///
  408. /// // Extract the variables contained in the packet
  409. /// sf::Uint32 x;
  410. /// std::string s;
  411. /// double d;
  412. /// if (packet >> x >> s >> d)
  413. /// {
  414. /// // Data extracted successfully...
  415. /// }
  416. /// \endcode
  417. ///
  418. /// Packets have built-in operator >> and << overloads for
  419. /// standard types:
  420. /// \li bool
  421. /// \li fixed-size integer types (sf::Int8/16/32, sf::Uint8/16/32)
  422. /// \li floating point numbers (float, double)
  423. /// \li string types (char*, wchar_t*, std::string, std::wstring, sf::String)
  424. ///
  425. /// Like standard streams, it is also possible to define your own
  426. /// overloads of operators >> and << in order to handle your
  427. /// custom types.
  428. ///
  429. /// \code
  430. /// struct MyStruct
  431. /// {
  432. /// float number;
  433. /// sf::Int8 integer;
  434. /// std::string str;
  435. /// };
  436. ///
  437. /// sf::Packet& operator <<(sf::Packet& packet, const MyStruct& m)
  438. /// {
  439. /// return packet << m.number << m.integer << m.str;
  440. /// }
  441. ///
  442. /// sf::Packet& operator >>(sf::Packet& packet, MyStruct& m)
  443. /// {
  444. /// return packet >> m.number >> m.integer >> m.str;
  445. /// }
  446. /// \endcode
  447. ///
  448. /// Packets also provide an extra feature that allows to apply
  449. /// custom transformations to the data before it is sent,
  450. /// and after it is received. This is typically used to
  451. /// handle automatic compression or encryption of the data.
  452. /// This is achieved by inheriting from sf::Packet, and overriding
  453. /// the onSend and onReceive functions.
  454. ///
  455. /// Here is an example:
  456. /// \code
  457. /// class ZipPacket : public sf::Packet
  458. /// {
  459. /// virtual const void* onSend(std::size_t& size)
  460. /// {
  461. /// const void* srcData = getData();
  462. /// std::size_t srcSize = getDataSize();
  463. ///
  464. /// return MySuperZipFunction(srcData, srcSize, &size);
  465. /// }
  466. ///
  467. /// virtual void onReceive(const void* data, std::size_t size)
  468. /// {
  469. /// std::size_t dstSize;
  470. /// const void* dstData = MySuperUnzipFunction(data, size, &dstSize);
  471. ///
  472. /// append(dstData, dstSize);
  473. /// }
  474. /// };
  475. ///
  476. /// // Use like regular packets:
  477. /// ZipPacket packet;
  478. /// packet << x << s << d;
  479. /// ...
  480. /// \endcode
  481. ///
  482. /// \see sf::TcpSocket, sf::UdpSocket
  483. ///
  484. ////////////////////////////////////////////////////////////