Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-06-02 08:58:14

0001 ////////////////////////////////////////////////////////////
0002 //
0003 // SFML - Simple and Fast Multimedia Library
0004 // Copyright (C) 2007-2023 Laurent Gomila (laurent@sfml-dev.org)
0005 //
0006 // This software is provided 'as-is', without any express or implied warranty.
0007 // In no event will the authors be held liable for any damages arising from the use of this software.
0008 //
0009 // Permission is granted to anyone to use this software for any purpose,
0010 // including commercial applications, and to alter it and redistribute it freely,
0011 // subject to the following restrictions:
0012 //
0013 // 1. The origin of this software must not be misrepresented;
0014 //    you must not claim that you wrote the original software.
0015 //    If you use this software in a product, an acknowledgment
0016 //    in the product documentation would be appreciated but is not required.
0017 //
0018 // 2. Altered source versions must be plainly marked as such,
0019 //    and must not be misrepresented as being the original software.
0020 //
0021 // 3. This notice may not be removed or altered from any source distribution.
0022 //
0023 ////////////////////////////////////////////////////////////
0024 
0025 #ifndef SFML_PACKET_HPP
0026 #define SFML_PACKET_HPP
0027 
0028 ////////////////////////////////////////////////////////////
0029 // Headers
0030 ////////////////////////////////////////////////////////////
0031 #include <SFML/Network/Export.hpp>
0032 #include <string>
0033 #include <vector>
0034 
0035 
0036 namespace sf
0037 {
0038 class String;
0039 class TcpSocket;
0040 class UdpSocket;
0041 
0042 ////////////////////////////////////////////////////////////
0043 /// \brief Utility class to build blocks of data to transfer
0044 ///        over the network
0045 ///
0046 ////////////////////////////////////////////////////////////
0047 class SFML_NETWORK_API Packet
0048 {
0049     // A bool-like type that cannot be converted to integer or pointer types
0050     typedef bool (Packet::*BoolType)(std::size_t);
0051 
0052 public:
0053 
0054     ////////////////////////////////////////////////////////////
0055     /// \brief Default constructor
0056     ///
0057     /// Creates an empty packet.
0058     ///
0059     ////////////////////////////////////////////////////////////
0060     Packet();
0061 
0062     ////////////////////////////////////////////////////////////
0063     /// \brief Virtual destructor
0064     ///
0065     ////////////////////////////////////////////////////////////
0066     virtual ~Packet();
0067 
0068     ////////////////////////////////////////////////////////////
0069     /// \brief Append data to the end of the packet
0070     ///
0071     /// \param data        Pointer to the sequence of bytes to append
0072     /// \param sizeInBytes Number of bytes to append
0073     ///
0074     /// \see clear
0075     /// \see getReadPosition
0076     ///
0077     ////////////////////////////////////////////////////////////
0078     void append(const void* data, std::size_t sizeInBytes);
0079 
0080     ////////////////////////////////////////////////////////////
0081     /// \brief Get the current reading position in the packet
0082     ///
0083     /// The next read operation will read data from this position
0084     ///
0085     /// \return The byte offset of the current read position
0086     ///
0087     /// \see append
0088     ///
0089     ////////////////////////////////////////////////////////////
0090     std::size_t getReadPosition() const;
0091 
0092     ////////////////////////////////////////////////////////////
0093     /// \brief Clear the packet
0094     ///
0095     /// After calling Clear, the packet is empty.
0096     ///
0097     /// \see append
0098     ///
0099     ////////////////////////////////////////////////////////////
0100     void clear();
0101 
0102     ////////////////////////////////////////////////////////////
0103     /// \brief Get a pointer to the data contained in the packet
0104     ///
0105     /// Warning: the returned pointer may become invalid after
0106     /// you append data to the packet, therefore it should never
0107     /// be stored.
0108     /// The return pointer is NULL if the packet is empty.
0109     ///
0110     /// \return Pointer to the data
0111     ///
0112     /// \see getDataSize
0113     ///
0114     ////////////////////////////////////////////////////////////
0115     const void* getData() const;
0116 
0117     ////////////////////////////////////////////////////////////
0118     /// \brief Get the size of the data contained in the packet
0119     ///
0120     /// This function returns the number of bytes pointed to by
0121     /// what getData returns.
0122     ///
0123     /// \return Data size, in bytes
0124     ///
0125     /// \see getData
0126     ///
0127     ////////////////////////////////////////////////////////////
0128     std::size_t getDataSize() const;
0129 
0130     ////////////////////////////////////////////////////////////
0131     /// \brief Tell if the reading position has reached the
0132     ///        end of the packet
0133     ///
0134     /// This function is useful to know if there is some data
0135     /// left to be read, without actually reading it.
0136     ///
0137     /// \return True if all data was read, false otherwise
0138     ///
0139     /// \see operator bool
0140     ///
0141     ////////////////////////////////////////////////////////////
0142     bool endOfPacket() const;
0143 
0144 public:
0145 
0146     ////////////////////////////////////////////////////////////
0147     /// \brief Test the validity of the packet, for reading
0148     ///
0149     /// This operator allows to test the packet as a boolean
0150     /// variable, to check if a reading operation was successful.
0151     ///
0152     /// A packet will be in an invalid state if it has no more
0153     /// data to read.
0154     ///
0155     /// This behavior is the same as standard C++ streams.
0156     ///
0157     /// Usage example:
0158     /// \code
0159     /// float x;
0160     /// packet >> x;
0161     /// if (packet)
0162     /// {
0163     ///    // ok, x was extracted successfully
0164     /// }
0165     ///
0166     /// // -- or --
0167     ///
0168     /// float x;
0169     /// if (packet >> x)
0170     /// {
0171     ///    // ok, x was extracted successfully
0172     /// }
0173     /// \endcode
0174     ///
0175     /// Don't focus on the return type, it's equivalent to bool but
0176     /// it disallows unwanted implicit conversions to integer or
0177     /// pointer types.
0178     ///
0179     /// \return True if last data extraction from packet was successful
0180     ///
0181     /// \see endOfPacket
0182     ///
0183     ////////////////////////////////////////////////////////////
0184     operator BoolType() const;
0185 
0186     ////////////////////////////////////////////////////////////
0187     /// Overload of operator >> to read data from the packet
0188     ///
0189     ////////////////////////////////////////////////////////////
0190     Packet& operator >>(bool&         data);
0191 
0192     ////////////////////////////////////////////////////////////
0193     /// \overload
0194     ////////////////////////////////////////////////////////////
0195     Packet& operator >>(Int8&         data);
0196 
0197     ////////////////////////////////////////////////////////////
0198     /// \overload
0199     ////////////////////////////////////////////////////////////
0200     Packet& operator >>(Uint8&        data);
0201 
0202     ////////////////////////////////////////////////////////////
0203     /// \overload
0204     ////////////////////////////////////////////////////////////
0205     Packet& operator >>(Int16&        data);
0206 
0207     ////////////////////////////////////////////////////////////
0208     /// \overload
0209     ////////////////////////////////////////////////////////////
0210     Packet& operator >>(Uint16&       data);
0211 
0212     ////////////////////////////////////////////////////////////
0213     /// \overload
0214     ////////////////////////////////////////////////////////////
0215     Packet& operator >>(Int32&        data);
0216 
0217     ////////////////////////////////////////////////////////////
0218     /// \overload
0219     ////////////////////////////////////////////////////////////
0220     Packet& operator >>(Uint32&       data);
0221 
0222     ////////////////////////////////////////////////////////////
0223     /// \overload
0224     ////////////////////////////////////////////////////////////
0225     Packet& operator >>(Int64&        data);
0226 
0227     ////////////////////////////////////////////////////////////
0228     /// \overload
0229     ////////////////////////////////////////////////////////////
0230     Packet& operator >>(Uint64&       data);
0231 
0232     ////////////////////////////////////////////////////////////
0233     /// \overload
0234     ////////////////////////////////////////////////////////////
0235     Packet& operator >>(float&        data);
0236 
0237     ////////////////////////////////////////////////////////////
0238     /// \overload
0239     ////////////////////////////////////////////////////////////
0240     Packet& operator >>(double&       data);
0241 
0242     ////////////////////////////////////////////////////////////
0243     /// \overload
0244     ////////////////////////////////////////////////////////////
0245     Packet& operator >>(char*         data);
0246 
0247     ////////////////////////////////////////////////////////////
0248     /// \overload
0249     ////////////////////////////////////////////////////////////
0250     Packet& operator >>(std::string&  data);
0251 
0252     ////////////////////////////////////////////////////////////
0253     /// \overload
0254     ////////////////////////////////////////////////////////////
0255     Packet& operator >>(wchar_t*      data);
0256 
0257     ////////////////////////////////////////////////////////////
0258     /// \overload
0259     ////////////////////////////////////////////////////////////
0260     Packet& operator >>(std::wstring& data);
0261 
0262     ////////////////////////////////////////////////////////////
0263     /// \overload
0264     ////////////////////////////////////////////////////////////
0265     Packet& operator >>(String&       data);
0266 
0267     ////////////////////////////////////////////////////////////
0268     /// Overload of operator << to write data into the packet
0269     ///
0270     ////////////////////////////////////////////////////////////
0271     Packet& operator <<(bool                data);
0272 
0273     ////////////////////////////////////////////////////////////
0274     /// \overload
0275     ////////////////////////////////////////////////////////////
0276     Packet& operator <<(Int8                data);
0277 
0278     ////////////////////////////////////////////////////////////
0279     /// \overload
0280     ////////////////////////////////////////////////////////////
0281     Packet& operator <<(Uint8               data);
0282 
0283     ////////////////////////////////////////////////////////////
0284     /// \overload
0285     ////////////////////////////////////////////////////////////
0286     Packet& operator <<(Int16               data);
0287 
0288     ////////////////////////////////////////////////////////////
0289     /// \overload
0290     ////////////////////////////////////////////////////////////
0291     Packet& operator <<(Uint16              data);
0292 
0293     ////////////////////////////////////////////////////////////
0294     /// \overload
0295     ////////////////////////////////////////////////////////////
0296     Packet& operator <<(Int32               data);
0297 
0298     ////////////////////////////////////////////////////////////
0299     /// \overload
0300     ////////////////////////////////////////////////////////////
0301     Packet& operator <<(Uint32              data);
0302 
0303     ////////////////////////////////////////////////////////////
0304     /// \overload
0305     ////////////////////////////////////////////////////////////
0306     Packet& operator <<(Int64               data);
0307 
0308     ////////////////////////////////////////////////////////////
0309     /// \overload
0310     ////////////////////////////////////////////////////////////
0311     Packet& operator <<(Uint64              data);
0312 
0313     ////////////////////////////////////////////////////////////
0314     /// \overload
0315     ////////////////////////////////////////////////////////////
0316     Packet& operator <<(float               data);
0317 
0318     ////////////////////////////////////////////////////////////
0319     /// \overload
0320     ////////////////////////////////////////////////////////////
0321     Packet& operator <<(double              data);
0322 
0323     ////////////////////////////////////////////////////////////
0324     /// \overload
0325     ////////////////////////////////////////////////////////////
0326     Packet& operator <<(const char*         data);
0327 
0328     ////////////////////////////////////////////////////////////
0329     /// \overload
0330     ////////////////////////////////////////////////////////////
0331     Packet& operator <<(const std::string&  data);
0332 
0333     ////////////////////////////////////////////////////////////
0334     /// \overload
0335     ////////////////////////////////////////////////////////////
0336     Packet& operator <<(const wchar_t*      data);
0337 
0338     ////////////////////////////////////////////////////////////
0339     /// \overload
0340     ////////////////////////////////////////////////////////////
0341     Packet& operator <<(const std::wstring& data);
0342 
0343     ////////////////////////////////////////////////////////////
0344     /// \overload
0345     ////////////////////////////////////////////////////////////
0346     Packet& operator <<(const String&       data);
0347 
0348 protected:
0349 
0350     friend class TcpSocket;
0351     friend class UdpSocket;
0352 
0353     ////////////////////////////////////////////////////////////
0354     /// \brief Called before the packet is sent over the network
0355     ///
0356     /// This function can be defined by derived classes to
0357     /// transform the data before it is sent; this can be
0358     /// used for compression, encryption, etc.
0359     /// The function must return a pointer to the modified data,
0360     /// as well as the number of bytes pointed.
0361     /// The default implementation provides the packet's data
0362     /// without transforming it.
0363     ///
0364     /// \param size Variable to fill with the size of data to send
0365     ///
0366     /// \return Pointer to the array of bytes to send
0367     ///
0368     /// \see onReceive
0369     ///
0370     ////////////////////////////////////////////////////////////
0371     virtual const void* onSend(std::size_t& size);
0372 
0373     ////////////////////////////////////////////////////////////
0374     /// \brief Called after the packet is received over the network
0375     ///
0376     /// This function can be defined by derived classes to
0377     /// transform the data after it is received; this can be
0378     /// used for decompression, decryption, etc.
0379     /// The function receives a pointer to the received data,
0380     /// and must fill the packet with the transformed bytes.
0381     /// The default implementation fills the packet directly
0382     /// without transforming the data.
0383     ///
0384     /// \param data Pointer to the received bytes
0385     /// \param size Number of bytes
0386     ///
0387     /// \see onSend
0388     ///
0389     ////////////////////////////////////////////////////////////
0390     virtual void onReceive(const void* data, std::size_t size);
0391 
0392 private:
0393 
0394     ////////////////////////////////////////////////////////////
0395     /// Disallow comparisons between packets
0396     ///
0397     ////////////////////////////////////////////////////////////
0398     bool operator ==(const Packet& right) const;
0399     bool operator !=(const Packet& right) const;
0400 
0401     ////////////////////////////////////////////////////////////
0402     /// \brief Check if the packet can extract a given number of bytes
0403     ///
0404     /// This function updates accordingly the state of the packet.
0405     ///
0406     /// \param size Size to check
0407     ///
0408     /// \return True if \a size bytes can be read from the packet
0409     ///
0410     ////////////////////////////////////////////////////////////
0411     bool checkSize(std::size_t size);
0412 
0413     ////////////////////////////////////////////////////////////
0414     // Member data
0415     ////////////////////////////////////////////////////////////
0416     std::vector<char> m_data;    //!< Data stored in the packet
0417     std::size_t       m_readPos; //!< Current reading position in the packet
0418     std::size_t       m_sendPos; //!< Current send position in the packet (for handling partial sends)
0419     bool              m_isValid; //!< Reading state of the packet
0420 };
0421 
0422 } // namespace sf
0423 
0424 
0425 #endif // SFML_PACKET_HPP
0426 
0427 
0428 ////////////////////////////////////////////////////////////
0429 /// \class sf::Packet
0430 /// \ingroup network
0431 ///
0432 /// Packets provide a safe and easy way to serialize data,
0433 /// in order to send it over the network using sockets
0434 /// (sf::TcpSocket, sf::UdpSocket).
0435 ///
0436 /// Packets solve 2 fundamental problems that arise when
0437 /// transferring data over the network:
0438 /// \li data is interpreted correctly according to the endianness
0439 /// \li the bounds of the packet are preserved (one send == one receive)
0440 ///
0441 /// The sf::Packet class provides both input and output modes.
0442 /// It is designed to follow the behavior of standard C++ streams,
0443 /// using operators >> and << to extract and insert data.
0444 ///
0445 /// It is recommended to use only fixed-size types (like sf::Int32, etc.),
0446 /// to avoid possible differences between the sender and the receiver.
0447 /// Indeed, the native C++ types may have different sizes on two platforms
0448 /// and your data may be corrupted if that happens.
0449 ///
0450 /// Usage example:
0451 /// \code
0452 /// sf::Uint32 x = 24;
0453 /// std::string s = "hello";
0454 /// double d = 5.89;
0455 ///
0456 /// // Group the variables to send into a packet
0457 /// sf::Packet packet;
0458 /// packet << x << s << d;
0459 ///
0460 /// // Send it over the network (socket is a valid sf::TcpSocket)
0461 /// socket.send(packet);
0462 ///
0463 /// -----------------------------------------------------------------
0464 ///
0465 /// // Receive the packet at the other end
0466 /// sf::Packet packet;
0467 /// socket.receive(packet);
0468 ///
0469 /// // Extract the variables contained in the packet
0470 /// sf::Uint32 x;
0471 /// std::string s;
0472 /// double d;
0473 /// if (packet >> x >> s >> d)
0474 /// {
0475 ///     // Data extracted successfully...
0476 /// }
0477 /// \endcode
0478 ///
0479 /// Packets have built-in operator >> and << overloads for
0480 /// standard types:
0481 /// \li bool
0482 /// \li fixed-size integer types (sf::Int8/16/32, sf::Uint8/16/32)
0483 /// \li floating point numbers (float, double)
0484 /// \li string types (char*, wchar_t*, std::string, std::wstring, sf::String)
0485 ///
0486 /// Like standard streams, it is also possible to define your own
0487 /// overloads of operators >> and << in order to handle your
0488 /// custom types.
0489 ///
0490 /// \code
0491 /// struct MyStruct
0492 /// {
0493 ///     float       number;
0494 ///     sf::Int8    integer;
0495 ///     std::string str;
0496 /// };
0497 ///
0498 /// sf::Packet& operator <<(sf::Packet& packet, const MyStruct& m)
0499 /// {
0500 ///     return packet << m.number << m.integer << m.str;
0501 /// }
0502 ///
0503 /// sf::Packet& operator >>(sf::Packet& packet, MyStruct& m)
0504 /// {
0505 ///     return packet >> m.number >> m.integer >> m.str;
0506 /// }
0507 /// \endcode
0508 ///
0509 /// Packets also provide an extra feature that allows to apply
0510 /// custom transformations to the data before it is sent,
0511 /// and after it is received. This is typically used to
0512 /// handle automatic compression or encryption of the data.
0513 /// This is achieved by inheriting from sf::Packet, and overriding
0514 /// the onSend and onReceive functions.
0515 ///
0516 /// Here is an example:
0517 /// \code
0518 /// class ZipPacket : public sf::Packet
0519 /// {
0520 ///     virtual const void* onSend(std::size_t& size)
0521 ///     {
0522 ///         const void* srcData = getData();
0523 ///         std::size_t srcSize = getDataSize();
0524 ///
0525 ///         return MySuperZipFunction(srcData, srcSize, &size);
0526 ///     }
0527 ///
0528 ///     virtual void onReceive(const void* data, std::size_t size)
0529 ///     {
0530 ///         std::size_t dstSize;
0531 ///         const void* dstData = MySuperUnzipFunction(data, size, &dstSize);
0532 ///
0533 ///         append(dstData, dstSize);
0534 ///     }
0535 /// };
0536 ///
0537 /// // Use like regular packets:
0538 /// ZipPacket packet;
0539 /// packet << x << s << d;
0540 /// ...
0541 /// \endcode
0542 ///
0543 /// \see sf::TcpSocket, sf::UdpSocket
0544 ///
0545 ////////////////////////////////////////////////////////////