diff --git a/bin/unit_tests/assets/html/eepp-ui-reddit-old-thread.webp b/bin/unit_tests/assets/html/eepp-ui-reddit-old-thread.webp
index 8affeff14..31db9e495 100644
Binary files a/bin/unit_tests/assets/html/eepp-ui-reddit-old-thread.webp and b/bin/unit_tests/assets/html/eepp-ui-reddit-old-thread.webp differ
diff --git a/include/eepp/graphics/base.hpp b/include/eepp/graphics/base.hpp
index 8f28dd945..fa55652da 100644
--- a/include/eepp/graphics/base.hpp
+++ b/include/eepp/graphics/base.hpp
@@ -1,7 +1,7 @@
#ifndef EE_GRAPHICS_BASE
#define EE_GRAPHICS_BASE
-#include
+#include
#include
#include
diff --git a/include/eepp/graphics/drawableresource.hpp b/include/eepp/graphics/drawableresource.hpp
index 9a2754284..0141912a5 100644
--- a/include/eepp/graphics/drawableresource.hpp
+++ b/include/eepp/graphics/drawableresource.hpp
@@ -1,9 +1,11 @@
#ifndef EE_GRAPHICS_DRAWABLERESOURCE_HPP
#define EE_GRAPHICS_DRAWABLERESOURCE_HPP
-#include
+#include
#include
+#include
#include
+#include
#include
namespace EE { namespace Graphics {
diff --git a/include/eepp/graphics/image.hpp b/include/eepp/graphics/image.hpp
index 97afec088..bceaf6e60 100644
--- a/include/eepp/graphics/image.hpp
+++ b/include/eepp/graphics/image.hpp
@@ -1,7 +1,8 @@
#ifndef EE_GRAPHICSCIMAGE_HPP
#define EE_GRAPHICSCIMAGE_HPP
-#include
+#include
+#include
#include
#include
@@ -315,11 +316,11 @@ class EE_API Image {
/** Overload the assignment operator to ensure the image copy */
Image& operator=( const Image& right );
- /** @brief Move constructor */
- Image( Image&& other ) noexcept;
+ /** @brief Move constructor */
+ Image( Image&& other ) noexcept;
- /** @brief Move assignment operator */
- Image& operator=( Image&& other ) noexcept;
+ /** @brief Move assignment operator */
+ Image& operator=( Image&& other ) noexcept;
virtual ~Image();
diff --git a/include/eepp/graphics/ninepatch.hpp b/include/eepp/graphics/ninepatch.hpp
index 6c7102b1d..7adec70fd 100644
--- a/include/eepp/graphics/ninepatch.hpp
+++ b/include/eepp/graphics/ninepatch.hpp
@@ -1,7 +1,7 @@
#ifndef EE_GRAPHICS_NINEPATCH_HPP
#define EE_GRAPHICS_NINEPATCH_HPP
-#include
+#include
#include
#include
diff --git a/include/eepp/graphics/resource.hpp b/include/eepp/graphics/resource.hpp
index ac603e37e..407bf1354 100644
--- a/include/eepp/graphics/resource.hpp
+++ b/include/eepp/graphics/resource.hpp
@@ -7,7 +7,9 @@
#include
#include
-#include
+#include
+#include
+#include
namespace EE { namespace Graphics {
diff --git a/include/eepp/graphics/shaderprogram.hpp b/include/eepp/graphics/shaderprogram.hpp
index 901c48408..46c277e17 100644
--- a/include/eepp/graphics/shaderprogram.hpp
+++ b/include/eepp/graphics/shaderprogram.hpp
@@ -1,6 +1,7 @@
#ifndef EE_GRAPHICSCSHADERPROGRAM_H
#define EE_GRAPHICSCSHADERPROGRAM_H
+#include
#include
#include
diff --git a/include/eepp/graphics/systemfontresolver.hpp b/include/eepp/graphics/systemfontresolver.hpp
index 358f1e9d1..bfd7bf551 100644
--- a/include/eepp/graphics/systemfontresolver.hpp
+++ b/include/eepp/graphics/systemfontresolver.hpp
@@ -2,6 +2,8 @@
#define EE_GRAPHICS_SYSTEMFONTRESOLVER_HPP
#include
+#include
+#include
#include
#include
#include
diff --git a/include/eepp/graphics/texture.hpp b/include/eepp/graphics/texture.hpp
index e3395ee79..b1dc5ea6c 100644
--- a/include/eepp/graphics/texture.hpp
+++ b/include/eepp/graphics/texture.hpp
@@ -1,8 +1,9 @@
#ifndef EE_GRAPHICSCTEXTURE_H
#define EE_GRAPHICSCTEXTURE_H
-#include
+#include
#include
+#include
#include
#include
#include
diff --git a/include/eepp/network/ftp.hpp b/include/eepp/network/ftp.hpp
index 7582fc6d9..773ad285a 100644
--- a/include/eepp/network/ftp.hpp
+++ b/include/eepp/network/ftp.hpp
@@ -1,402 +1,402 @@
-#ifndef EE_NETWORKCFTP_HPP
-#define EE_NETWORKCFTP_HPP
-
-#include
-#include
-#include
-#include
-#include
-#include
-
-using namespace EE::System;
-
-namespace EE { namespace Network {
-
-class IpAddress;
-
-/** @brief A FTP client */
-class EE_API Ftp : NonCopyable {
- public:
- /** @brief Enumeration of transfer modes */
- enum TransferMode {
- Binary, ///< Binary mode (file is transferred as a sequence of bytes)
- Ascii, ///< Text mode using ASCII encoding
- Ebcdic ///< Text mode using EBCDIC encoding
- };
-
- /** @brief Define a FTP response */
- class EE_API Response {
- public:
- /** @brief Status codes possibly returned by a FTP response */
- enum Status {
- // 1xx: the requested action is being initiated,
- // expect another reply before proceeding with a new command
- RestartMarkerReply = 110, ///< Restart marker reply
- ServiceReadySoon = 120, ///< Service ready in N minutes
- DataConnectionAlreadyOpened =
- 125, ///< Data connection already opened, transfer starting
- OpeningDataConnection = 150, ///< File status ok, about to open data connection
-
- // 2xx: the requested action has been successfully completed
- Ok = 200, ///< Command ok
- PointlessCommand = 202, ///< Command not implemented
- SystemStatus = 211, ///< System status, or system help reply
- DirectoryStatus = 212, ///< Directory status
- FileStatus = 213, ///< File status
- HelpMessage = 214, ///< Help message
- SystemType = 215, ///< NAME system type, where NAME is an official system name from the
- ///< list in the Assigned Numbers document
- ServiceReady = 220, ///< Service ready for new user
- ClosingConnection = 221, ///< Service closing control connection
- DataConnectionOpened = 225, ///< Data connection open, no transfer in progress
- ClosingDataConnection =
- 226, ///< Closing data connection, requested file action successful
- EnteringPassiveMode = 227, ///< Entering passive mode
- LoggedIn = 230, ///< User logged in, proceed. Logged out if appropriate
- FileActionOk = 250, ///< Requested file action ok
- DirectoryOk = 257, ///< PATHNAME created
-
- // 3xx: the command has been accepted, but the requested action
- // is dormant, pending receipt of further information
- NeedPassword = 331, ///< User name ok, need password
- NeedAccountToLogIn = 332, ///< Need account for login
- NeedInformation = 350, ///< Requested file action pending further information
-
- // 4xx: the command was not accepted and the requested action did not take place,
- // but the error condition is temporary and the action may be requested again
- ServiceUnavailable = 421, ///< Service not available, closing control connection
- DataConnectionUnavailable = 425, ///< Can't open data connection
- TransferAborted = 426, ///< Connection closed, transfer aborted
- FileActionAborted = 450, ///< Requested file action not taken
- LocalError = 451, ///< Requested action aborted, local error in processing
- InsufficientStorageSpace = 452, ///< Requested action not taken; insufficient storage
- ///< space in system, file unavailable
-
- // 5xx: the command was not accepted and
- // the requested action did not take place
- CommandUnknown = 500, ///< Syntax error, command unrecognized
- ParametersUnknown = 501, ///< Syntax error in parameters or arguments
- CommandNotImplemented = 502, ///< Command not implemented
- BadCommandSequence = 503, ///< Bad sequence of commands
- ParameterNotImplemented = 504, ///< Command not implemented for that parameter
- NotLoggedIn = 530, ///< Not logged in
- NeedAccountToStore = 532, ///< Need account for storing files
- FileUnavailable = 550, ///< Requested action not taken, file unavailable
- PageTypeUnknown = 551, ///< Requested action aborted, page type unknown
- NotEnoughMemory = 552, ///< Requested file action aborted, exceeded storage allocation
- FilenameNotAllowed = 553, ///< Requested action not taken, file name not allowed
-
- // 10xx: Custom codes
- InvalidResponse = 1000, ///< Response is not a valid FTP one
- ConnectionFailed = 1001, ///< Connection with server failed
- ConnectionClosed = 1002, ///< Connection with server closed
- InvalidFile = 1003 ///< Invalid file to upload / download
- };
-
- /** @brief Default constructor
- **
- ** This constructor is used by the FTP client to build
- ** the response.
- **
- ** @param code Response status code
- ** @param message Response message */
- explicit Response( Status code = InvalidResponse, const std::string& message = "" );
-
- /** @brief Check if the status code means a success
- **
- ** This function is defined for convenience, it is
- ** equivalent to testing if the status code is < 400.
- **
- ** @return True if the status is a success, false if it is a failure */
- bool isOk() const;
-
- /** @brief Get the status code of the response
- **
- ** @return Status code */
- Status getStatus() const;
-
- /** @brief Get the full message contained in the response
- ** @return The response message */
- const std::string& getMessage() const;
-
- private:
- // Member data
- Status mStatus; ///< Status code returned from the server
- std::string mMessage; ///< Last message received from the server
- };
-
- /** @brief Specialization of FTP response returning a directory */
- class EE_API DirectoryResponse : public Response {
- public:
- /** @brief Default constructor
- ** @param response Source response */
- DirectoryResponse( const Response& response );
-
- /** @brief Get the directory returned in the response
- ** @return Directory name */
- const std::string& getDirectory() const;
-
- private:
- // Member data
- std::string mDirectory; ///< Directory extracted from the response message
- };
-
- /** @brief Specialization of FTP response returning a filename listing */
- class EE_API ListingResponse : public Response {
- public:
- /** @brief Default constructor
- **
- ** @param response Source response
- ** @param data Data containing the raw listing */
- ListingResponse( const Response& response, const std::string& data );
-
- /** @brief Return the array of directory/file names
- **
- ** @return Array containing the requested listing */
- const std::vector& getListing() const;
-
- private:
- // Member data
- std::vector mListing; ///< Directory/file names extracted from the data
- };
-
- Ftp();
-
- /** @brief Destructor
- ** Automatically closes the connection with the server if
- ** it is still opened. */
- ~Ftp();
-
- /** @brief Connect to the specified FTP server
- ** The port has a default value of 21, which is the standard
- ** port used by the FTP protocol. You shouldn't use a different
- ** value, unless you really know what you do.
- ** This function tries to connect to the server so it may take
- ** a while to complete, especially if the server is not
- ** reachable. To avoid blocking your application for too long,
- ** you can use a timeout. The default value, Time::Zero, means that the
- ** system timeout will be used (which is usually pretty long).
- ** @param server Hostname or address of the FTP server to connect to
- ** @param port Port used for the connection
- ** @param useTLS force TLS connection for FTPS.
- ** @param validateCertificate Enables certificate validation for https request
- ** @param validateHostname Enables hostname validation for https request
- ** @param timeout Maximum time to wait
- ** @return Server response to the request
- ** @see disconnect */
- Response connect( const std::string& server, unsigned short port = 21, bool useTLS = false,
- bool validateCertificate = true, bool validateHostname = true,
- const Time& timeout = Time::Zero );
-
- /** @brief Close the connection with the server
- ** @return Server response to the request
- ** @see connect */
- Response disconnect();
-
- /** @brief Log in using an anonymous account
- ** Logging in is mandatory after connecting to the server.
- ** Users that are not logged in cannot perform any operation.
- ** @return Server response to the request */
- Response login();
-
- /** @brief Log in using a username and a password
- ** Logging in is mandatory after connecting to the server.
- ** Users that are not logged in cannot perform any operation.
- ** @param name User name
- ** @param password Password
- ** @return Server response to the request */
- Response login( const std::string& name, const std::string& password );
-
- /** @brief Send a null command to keep the connection alive
- ** This command is useful because the server may close the
- ** connection automatically if no command is sent.
- ** @return Server response to the request */
- Response keepAlive();
-
- /** @brief Get the current working directory
- ** The working directory is the root path for subsequent
- ** operations involving directories and/or filenames.
- ** @return Server response to the request
- ** @see getDirectoryListing, changeDirectory, parentDirectory */
- DirectoryResponse getWorkingDirectory();
-
- /** @brief Get the contents of the given directory
- ** This function retrieves the sub-directories and files
- ** contained in the given directory. It is not recursive.
- ** The @a directory parameter is relative to the current
- ** working directory.
- ** @param directory Directory to list
- ** @return Server response to the request
- ** @see getWorkingDirectory, changeDirectory, parentDirectory */
- ListingResponse getDirectoryListing( const std::string& directory = "" );
-
- /** @brief Change the current working directory
- ** The new directory must be relative to the current one.
- ** @param directory New working directory
- ** @return Server response to the request
- ** @see getWorkingDirectory, getDirectoryListing, parentDirectory */
- Response changeDirectory( const std::string& directory );
-
- /** @brief Go to the parent directory of the current one
- ** @return Server response to the request
- ** @see getWorkingDirectory, getDirectoryListing, changeDirectory */
- Response parentDirectory();
-
- /** @brief Create a new directory
- ** The new directory is created as a child of the current
- ** working directory.
- ** @param name Name of the directory to create
- ** @return Server response to the request
- ** @see deleteDirectory */
- Response createDirectory( const std::string& name );
-
- /** @brief Remove an existing directory
- ** The directory to remove must be relative to the
- ** current working directory.
- ** Use this function with caution, the directory will
- ** be removed permanently!
- ** @param name Name of the directory to remove
- ** @return Server response to the request
- ** @see createDirectory */
- Response deleteDirectory( const std::string& name );
-
- /** @brief Rename an existing file
- ** The filenames must be relative to the current working
- ** directory.
- ** @param file File to rename
- ** @param newName New name of the file
- ** @return Server response to the request
- ** @see deleteFile */
- Response renameFile( const std::string& file, const std::string& newName );
-
- /** @brief Remove an existing file
- ** The file name must be relative to the current working
- ** directory.
- ** Use this function with caution, the file will be
- ** removed permanently!
- ** @param name File to remove
- ** @return Server response to the request
- ** @see RenameFile */
- Response deleteFile( const std::string& name );
-
- /** @brief Download a file from the server
- ** The filename of the distant file is relative to the
- ** current working directory of the server, and the local
- ** destination path is relative to the current directory
- ** of your application.
- ** If a file with the same filename as the distant file
- ** already exists in the local destination path, it will
- ** be overwritten.
- ** @param remoteFile Filename of the distant file to download
- ** @param localPath Where to put to file on the local computer
- ** @param mode Transfer mode
- ** @return Server response to the request
- ** @see upload */
- Response download( const std::string& remoteFile, const std::string& localPath,
- TransferMode mode = Binary );
-
- /** @brief Upload a file to the server
- ** The name of the local file is relative to the current
- ** working directory of your application, and the
- ** remote path is relative to the current directory of the
- ** FTP server.
- ** @param localFile Path of the local file to upload
- ** @param remotePath Where to put to file on the server
- ** @param mode Transfer mode
- ** @param append Pass true to append to or false to overwrite the remote file if it already
- *exists
- ** @return Server response to the request
- ** @see download */
- Response upload( const std::string& localFile, const std::string& remotePath,
- TransferMode mode = Binary, bool append = false );
-
- /** @return The server hostname (available only after connect). */
- const std::string& getHostname() const;
-
- /** @return True if connection is using TLS (available only after connect). */
- const bool& isTLS() const;
-
- private:
- /** @brief Send a command to the FTP server
- ** @param command Command to send
- ** @param parameter Command parameter
- ** @return Server response to the request */
- Response sendCommand( const std::string& command, const std::string& parameter = "" );
-
- /** @brief Receive a response from the server
- ** This function must be called after each call to
- ** SendCommand that expects a response.
- ** @return Server response to the request */
- Response getResponse();
-
- /** @brief Utility class for exchanging data with the server on the data channel */
- class DataChannel;
- friend class DataChannel;
-
- // Member data
- TcpSocket* mCommandSocket; ///< Socket holding the control connection with the server
- std::string mReceiveBuffer; ///< Received command data that is yet to be processed
- std::string mHostName;
- bool mConnected;
- bool mIsTLS;
-};
-
-}} // namespace EE::Network
-
-#endif // EE_NETWORKCFTP_HPP
-
-/**
-@class EE::Network::Ftp
-
-Ftp is a very simple FTP client that allows you
-to communicate with a FTP server. The FTP protocol allows
-you to manipulate a remote file system (list files,
-upload, download, create, remove, ...).
-Using the FTP client consists of 4 parts:
-@li Connecting to the FTP server
-@li Logging in (either as a registered user or anonymously)
-@li Sending commands to the server
-@li Disconnecting (this part can be done implicitly by the destructor)
-Every command returns a FTP response, which contains the
-status code as well as a message from the server. Some
-commands such as getWorkingDirectory and getDirectoryListing
-return additional data, and use a class derived from
-Ftp::Response to provide this data.
-All commands, especially upload and download, may take some
-time to complete. This is important to know if you don't want
-to block your application while the server is completing
-the task.
-Usage example:
-@code
-// Create a new FTP client
-Ftp ftp;
-
-// Connect to the server
-Ftp::Response response = ftp.connect("ftp://ftp.myserver.com");
-if (response.isOk())
- std::cout << "Connected" << std::endl;
-
-// Log in
-response = ftp.login("laurent", "dF6Zm89D");
-if (response.isOk())
- std::cout << "Logged in" << std::endl;
-
-// Print the working directory
-Ftp::DirectoryResponse directory = ftp.getWorkingDirectory();
-if (directory.isOk())
- std::cout << "Working directory: " << directory.getDirectory() << std::endl;
-
-// Create a new directory
-response = ftp.createDirectory("files");
-if (response.isOk())
- std::cout << "Created new directory" << std::endl;
-
-// Upload a file to this new directory
-response = ftp.upload("local-path/file.txt", "files", Ftp::Ascii);
-if (response.isOk())
- std::cout << "File uploaded" << std::endl;
-
-// Disconnect from the server (optional)
-ftp.disconnect();
-@endcode
-*/
+#ifndef EE_NETWORKCFTP_HPP
+#define EE_NETWORKCFTP_HPP
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+using namespace EE::System;
+
+namespace EE { namespace Network {
+
+class IpAddress;
+
+/** @brief A FTP client */
+class EE_API Ftp : NonCopyable {
+ public:
+ /** @brief Enumeration of transfer modes */
+ enum TransferMode {
+ Binary, ///< Binary mode (file is transferred as a sequence of bytes)
+ Ascii, ///< Text mode using ASCII encoding
+ Ebcdic ///< Text mode using EBCDIC encoding
+ };
+
+ /** @brief Define a FTP response */
+ class EE_API Response {
+ public:
+ /** @brief Status codes possibly returned by a FTP response */
+ enum Status {
+ // 1xx: the requested action is being initiated,
+ // expect another reply before proceeding with a new command
+ RestartMarkerReply = 110, ///< Restart marker reply
+ ServiceReadySoon = 120, ///< Service ready in N minutes
+ DataConnectionAlreadyOpened =
+ 125, ///< Data connection already opened, transfer starting
+ OpeningDataConnection = 150, ///< File status ok, about to open data connection
+
+ // 2xx: the requested action has been successfully completed
+ Ok = 200, ///< Command ok
+ PointlessCommand = 202, ///< Command not implemented
+ SystemStatus = 211, ///< System status, or system help reply
+ DirectoryStatus = 212, ///< Directory status
+ FileStatus = 213, ///< File status
+ HelpMessage = 214, ///< Help message
+ SystemType = 215, ///< NAME system type, where NAME is an official system name from the
+ ///< list in the Assigned Numbers document
+ ServiceReady = 220, ///< Service ready for new user
+ ClosingConnection = 221, ///< Service closing control connection
+ DataConnectionOpened = 225, ///< Data connection open, no transfer in progress
+ ClosingDataConnection =
+ 226, ///< Closing data connection, requested file action successful
+ EnteringPassiveMode = 227, ///< Entering passive mode
+ LoggedIn = 230, ///< User logged in, proceed. Logged out if appropriate
+ FileActionOk = 250, ///< Requested file action ok
+ DirectoryOk = 257, ///< PATHNAME created
+
+ // 3xx: the command has been accepted, but the requested action
+ // is dormant, pending receipt of further information
+ NeedPassword = 331, ///< User name ok, need password
+ NeedAccountToLogIn = 332, ///< Need account for login
+ NeedInformation = 350, ///< Requested file action pending further information
+
+ // 4xx: the command was not accepted and the requested action did not take place,
+ // but the error condition is temporary and the action may be requested again
+ ServiceUnavailable = 421, ///< Service not available, closing control connection
+ DataConnectionUnavailable = 425, ///< Can't open data connection
+ TransferAborted = 426, ///< Connection closed, transfer aborted
+ FileActionAborted = 450, ///< Requested file action not taken
+ LocalError = 451, ///< Requested action aborted, local error in processing
+ InsufficientStorageSpace = 452, ///< Requested action not taken; insufficient storage
+ ///< space in system, file unavailable
+
+ // 5xx: the command was not accepted and
+ // the requested action did not take place
+ CommandUnknown = 500, ///< Syntax error, command unrecognized
+ ParametersUnknown = 501, ///< Syntax error in parameters or arguments
+ CommandNotImplemented = 502, ///< Command not implemented
+ BadCommandSequence = 503, ///< Bad sequence of commands
+ ParameterNotImplemented = 504, ///< Command not implemented for that parameter
+ NotLoggedIn = 530, ///< Not logged in
+ NeedAccountToStore = 532, ///< Need account for storing files
+ FileUnavailable = 550, ///< Requested action not taken, file unavailable
+ PageTypeUnknown = 551, ///< Requested action aborted, page type unknown
+ NotEnoughMemory = 552, ///< Requested file action aborted, exceeded storage allocation
+ FilenameNotAllowed = 553, ///< Requested action not taken, file name not allowed
+
+ // 10xx: Custom codes
+ InvalidResponse = 1000, ///< Response is not a valid FTP one
+ ConnectionFailed = 1001, ///< Connection with server failed
+ ConnectionClosed = 1002, ///< Connection with server closed
+ InvalidFile = 1003 ///< Invalid file to upload / download
+ };
+
+ /** @brief Default constructor
+ **
+ ** This constructor is used by the FTP client to build
+ ** the response.
+ **
+ ** @param code Response status code
+ ** @param message Response message */
+ explicit Response( Status code = InvalidResponse, const std::string& message = "" );
+
+ /** @brief Check if the status code means a success
+ **
+ ** This function is defined for convenience, it is
+ ** equivalent to testing if the status code is < 400.
+ **
+ ** @return True if the status is a success, false if it is a failure */
+ bool isOk() const;
+
+ /** @brief Get the status code of the response
+ **
+ ** @return Status code */
+ Status getStatus() const;
+
+ /** @brief Get the full message contained in the response
+ ** @return The response message */
+ const std::string& getMessage() const;
+
+ private:
+ // Member data
+ Status mStatus; ///< Status code returned from the server
+ std::string mMessage; ///< Last message received from the server
+ };
+
+ /** @brief Specialization of FTP response returning a directory */
+ class EE_API DirectoryResponse : public Response {
+ public:
+ /** @brief Default constructor
+ ** @param response Source response */
+ DirectoryResponse( const Response& response );
+
+ /** @brief Get the directory returned in the response
+ ** @return Directory name */
+ const std::string& getDirectory() const;
+
+ private:
+ // Member data
+ std::string mDirectory; ///< Directory extracted from the response message
+ };
+
+ /** @brief Specialization of FTP response returning a filename listing */
+ class EE_API ListingResponse : public Response {
+ public:
+ /** @brief Default constructor
+ **
+ ** @param response Source response
+ ** @param data Data containing the raw listing */
+ ListingResponse( const Response& response, const std::string& data );
+
+ /** @brief Return the array of directory/file names
+ **
+ ** @return Array containing the requested listing */
+ const std::vector& getListing() const;
+
+ private:
+ // Member data
+ std::vector mListing; ///< Directory/file names extracted from the data
+ };
+
+ Ftp();
+
+ /** @brief Destructor
+ ** Automatically closes the connection with the server if
+ ** it is still opened. */
+ ~Ftp();
+
+ /** @brief Connect to the specified FTP server
+ ** The port has a default value of 21, which is the standard
+ ** port used by the FTP protocol. You shouldn't use a different
+ ** value, unless you really know what you do.
+ ** This function tries to connect to the server so it may take
+ ** a while to complete, especially if the server is not
+ ** reachable. To avoid blocking your application for too long,
+ ** you can use a timeout. The default value, Time::Zero, means that the
+ ** system timeout will be used (which is usually pretty long).
+ ** @param server Hostname or address of the FTP server to connect to
+ ** @param port Port used for the connection
+ ** @param useTLS force TLS connection for FTPS.
+ ** @param validateCertificate Enables certificate validation for https request
+ ** @param validateHostname Enables hostname validation for https request
+ ** @param timeout Maximum time to wait
+ ** @return Server response to the request
+ ** @see disconnect */
+ Response connect( const std::string& server, unsigned short port = 21, bool useTLS = false,
+ bool validateCertificate = true, bool validateHostname = true,
+ const Time& timeout = Time::Zero );
+
+ /** @brief Close the connection with the server
+ ** @return Server response to the request
+ ** @see connect */
+ Response disconnect();
+
+ /** @brief Log in using an anonymous account
+ ** Logging in is mandatory after connecting to the server.
+ ** Users that are not logged in cannot perform any operation.
+ ** @return Server response to the request */
+ Response login();
+
+ /** @brief Log in using a username and a password
+ ** Logging in is mandatory after connecting to the server.
+ ** Users that are not logged in cannot perform any operation.
+ ** @param name User name
+ ** @param password Password
+ ** @return Server response to the request */
+ Response login( const std::string& name, const std::string& password );
+
+ /** @brief Send a null command to keep the connection alive
+ ** This command is useful because the server may close the
+ ** connection automatically if no command is sent.
+ ** @return Server response to the request */
+ Response keepAlive();
+
+ /** @brief Get the current working directory
+ ** The working directory is the root path for subsequent
+ ** operations involving directories and/or filenames.
+ ** @return Server response to the request
+ ** @see getDirectoryListing, changeDirectory, parentDirectory */
+ DirectoryResponse getWorkingDirectory();
+
+ /** @brief Get the contents of the given directory
+ ** This function retrieves the sub-directories and files
+ ** contained in the given directory. It is not recursive.
+ ** The @a directory parameter is relative to the current
+ ** working directory.
+ ** @param directory Directory to list
+ ** @return Server response to the request
+ ** @see getWorkingDirectory, changeDirectory, parentDirectory */
+ ListingResponse getDirectoryListing( const std::string& directory = "" );
+
+ /** @brief Change the current working directory
+ ** The new directory must be relative to the current one.
+ ** @param directory New working directory
+ ** @return Server response to the request
+ ** @see getWorkingDirectory, getDirectoryListing, parentDirectory */
+ Response changeDirectory( const std::string& directory );
+
+ /** @brief Go to the parent directory of the current one
+ ** @return Server response to the request
+ ** @see getWorkingDirectory, getDirectoryListing, changeDirectory */
+ Response parentDirectory();
+
+ /** @brief Create a new directory
+ ** The new directory is created as a child of the current
+ ** working directory.
+ ** @param name Name of the directory to create
+ ** @return Server response to the request
+ ** @see deleteDirectory */
+ Response createDirectory( const std::string& name );
+
+ /** @brief Remove an existing directory
+ ** The directory to remove must be relative to the
+ ** current working directory.
+ ** Use this function with caution, the directory will
+ ** be removed permanently!
+ ** @param name Name of the directory to remove
+ ** @return Server response to the request
+ ** @see createDirectory */
+ Response deleteDirectory( const std::string& name );
+
+ /** @brief Rename an existing file
+ ** The filenames must be relative to the current working
+ ** directory.
+ ** @param file File to rename
+ ** @param newName New name of the file
+ ** @return Server response to the request
+ ** @see deleteFile */
+ Response renameFile( const std::string& file, const std::string& newName );
+
+ /** @brief Remove an existing file
+ ** The file name must be relative to the current working
+ ** directory.
+ ** Use this function with caution, the file will be
+ ** removed permanently!
+ ** @param name File to remove
+ ** @return Server response to the request
+ ** @see RenameFile */
+ Response deleteFile( const std::string& name );
+
+ /** @brief Download a file from the server
+ ** The filename of the distant file is relative to the
+ ** current working directory of the server, and the local
+ ** destination path is relative to the current directory
+ ** of your application.
+ ** If a file with the same filename as the distant file
+ ** already exists in the local destination path, it will
+ ** be overwritten.
+ ** @param remoteFile Filename of the distant file to download
+ ** @param localPath Where to put to file on the local computer
+ ** @param mode Transfer mode
+ ** @return Server response to the request
+ ** @see upload */
+ Response download( const std::string& remoteFile, const std::string& localPath,
+ TransferMode mode = Binary );
+
+ /** @brief Upload a file to the server
+ ** The name of the local file is relative to the current
+ ** working directory of your application, and the
+ ** remote path is relative to the current directory of the
+ ** FTP server.
+ ** @param localFile Path of the local file to upload
+ ** @param remotePath Where to put to file on the server
+ ** @param mode Transfer mode
+ ** @param append Pass true to append to or false to overwrite the remote file if it already
+ *exists
+ ** @return Server response to the request
+ ** @see download */
+ Response upload( const std::string& localFile, const std::string& remotePath,
+ TransferMode mode = Binary, bool append = false );
+
+ /** @return The server hostname (available only after connect). */
+ const std::string& getHostname() const;
+
+ /** @return True if connection is using TLS (available only after connect). */
+ const bool& isTLS() const;
+
+ private:
+ /** @brief Send a command to the FTP server
+ ** @param command Command to send
+ ** @param parameter Command parameter
+ ** @return Server response to the request */
+ Response sendCommand( const std::string& command, const std::string& parameter = "" );
+
+ /** @brief Receive a response from the server
+ ** This function must be called after each call to
+ ** SendCommand that expects a response.
+ ** @return Server response to the request */
+ Response getResponse();
+
+ /** @brief Utility class for exchanging data with the server on the data channel */
+ class DataChannel;
+ friend class DataChannel;
+
+ // Member data
+ TcpSocket* mCommandSocket; ///< Socket holding the control connection with the server
+ std::string mReceiveBuffer; ///< Received command data that is yet to be processed
+ std::string mHostName;
+ bool mConnected;
+ bool mIsTLS;
+};
+
+}} // namespace EE::Network
+
+#endif // EE_NETWORKCFTP_HPP
+
+/**
+@class EE::Network::Ftp
+
+Ftp is a very simple FTP client that allows you
+to communicate with a FTP server. The FTP protocol allows
+you to manipulate a remote file system (list files,
+upload, download, create, remove, ...).
+Using the FTP client consists of 4 parts:
+@li Connecting to the FTP server
+@li Logging in (either as a registered user or anonymously)
+@li Sending commands to the server
+@li Disconnecting (this part can be done implicitly by the destructor)
+Every command returns a FTP response, which contains the
+status code as well as a message from the server. Some
+commands such as getWorkingDirectory and getDirectoryListing
+return additional data, and use a class derived from
+Ftp::Response to provide this data.
+All commands, especially upload and download, may take some
+time to complete. This is important to know if you don't want
+to block your application while the server is completing
+the task.
+Usage example:
+@code
+// Create a new FTP client
+Ftp ftp;
+
+// Connect to the server
+Ftp::Response response = ftp.connect("ftp://ftp.myserver.com");
+if (response.isOk())
+ std::cout << "Connected" << std::endl;
+
+// Log in
+response = ftp.login("laurent", "dF6Zm89D");
+if (response.isOk())
+ std::cout << "Logged in" << std::endl;
+
+// Print the working directory
+Ftp::DirectoryResponse directory = ftp.getWorkingDirectory();
+if (directory.isOk())
+ std::cout << "Working directory: " << directory.getDirectory() << std::endl;
+
+// Create a new directory
+response = ftp.createDirectory("files");
+if (response.isOk())
+ std::cout << "Created new directory" << std::endl;
+
+// Upload a file to this new directory
+response = ftp.upload("local-path/file.txt", "files", Ftp::Ascii);
+if (response.isOk())
+ std::cout << "File uploaded" << std::endl;
+
+// Disconnect from the server (optional)
+ftp.disconnect();
+@endcode
+*/
diff --git a/include/eepp/network/http.hpp b/include/eepp/network/http.hpp
index b3d313a24..7082cd53c 100644
--- a/include/eepp/network/http.hpp
+++ b/include/eepp/network/http.hpp
@@ -2,8 +2,10 @@
#define EE_NETWORKCHTTP_HPP
#include
-#include
+#include
+#include
#include
+#include
#include
#include
#include
@@ -186,7 +188,7 @@ class EE_API Http : NonCopyable, public std::enable_shared_from_this {
///< target resource.
Patch, ///< The PATCH method is used to apply partial modifications to a resource.
Connect ///< The CONNECT method starts two-way communications with the requested
- ///< resource. It can be used to open a tunnel.
+ ///< resource. It can be used to open a tunnel.
};
/** @brief Enumerate the available states for a request */
diff --git a/include/eepp/network/ipaddress.hpp b/include/eepp/network/ipaddress.hpp
index 7ae0db374..c901c1680 100644
--- a/include/eepp/network/ipaddress.hpp
+++ b/include/eepp/network/ipaddress.hpp
@@ -1,194 +1,194 @@
-#ifndef EE_NETWORKCIPADDRESS_HPP
-#define EE_NETWORKCIPADDRESS_HPP
-
-#include
-#include
-using namespace EE::System;
-
-#include
-#include
-#include
-
-namespace EE { namespace Network {
-
-/** @brief Encapsulate an IPv4 network address */
-class EE_API IpAddress {
- public:
- /** @brief Default constructor
- ** This constructor creates an empty (invalid) address */
- IpAddress();
-
- /** @brief Construct the address from a string
- ** Here @a address can be either a decimal address
- ** (ex: "192.168.1.56") or a network name (ex: "localhost").
- ** @param address IP address or network name */
- IpAddress( const std::string& address );
-
- /** @brief Construct the address from a string
- ** Here @a address can be either a decimal address
- ** (ex: "192.168.1.56") or a network name (ex: "localhost").
- ** This is equivalent to the constructor taking a std::string
- ** parameter, it is defined for convenience so that the
- ** implicit conversions from literal strings to IpAddress work.
- ** @param address IP address or network name */
- IpAddress( const char* address );
-
- /** @brief Construct the address from 4 bytes
- ** Calling IpAddress(a, b, c, d) is equivalent to calling
- ** IpAddress("a.b.c.d"), but safer as it doesn't have to
- ** parse a string to get the address components.
- ** @param byte0 First byte of the address
- ** @param byte1 Second byte of the address
- ** @param byte2 Third byte of the address
- ** @param byte3 Fourth byte of the address */
- IpAddress( Uint8 byte0, Uint8 byte1, Uint8 byte2, Uint8 byte3 );
-
- /** @brief Construct the address from a 32-bits integer
- ** This constructor uses the internal representation of
- ** the address directly. It should be used for optimization
- ** purposes, and only if you got that representation from
- ** IpAddress::toInteger().
- ** @param address 4 bytes of the address packed into a 32-bits integer
- ** @see ToInteger */
- explicit IpAddress( Uint32 address );
-
- /** @brief Get a string representation of the address
- ** The returned string is the decimal representation of the
- ** IP address (like "192.168.1.56"), even if it was constructed
- ** from a host name.
- ** @return String representation of the address
- ** @see ToInteger */
- std::string toString() const;
-
- /** @brief Get an integer representation of the address
- ** The returned number is the internal representation of the
- ** address, and should be used for optimization purposes only
- ** (like sending the address through a socket).
- ** The integer produced by this function can then be converted
- ** back to a IpAddress with the proper constructor.
- ** @return 32-bits unsigned integer representation of the address
- ** @see ToString */
- Uint32 toInteger() const;
-
- /** @brief Get the computer's local address
- ** The local address is the address of the computer from the
- ** LAN point of view, i.e. something like 192.168.1.56. It is
- ** meaningful only for communications over the local network.
- ** Unlike GetPublicAddress, this function is fast and may be
- ** used safely anywhere.
- ** @return Local IP address of the computer
- ** @see GetPublicAddress */
- static IpAddress getLocalAddress();
-
- /** @brief Get the computer's public address
- ** The public address is the address of the computer from the
- ** internet point of view, i.e. something like 89.54.1.169.
- ** It is necessary for communications over the world wide web.
- ** The only way to get a public address is to ask it to a
- ** distant website; as a consequence, this function depends on
- ** both your network connection and the server, and may be
- ** very slow. You should use it as few as possible. Because
- ** this function depends on the network connection and on a distant
- ** server, you may use a time limit if you don't want your program
- ** to be possibly stuck waiting in case there is a problem; this
- ** limit is deactivated by default.
- ** @param timeout Maximum time to wait
- ** @return Public IP address of the computer
- ** @see GetLocalAddress */
- static IpAddress getPublicAddress( Time timeout = Time::Zero );
-
- // Static member data
- static const IpAddress None; ///< Value representing an empty/invalid address
- static const IpAddress Any; ///< Value representing any address (0.0.0.0)
- static const IpAddress
- LocalHost; ///< The "localhost" address (for connecting a computer to itself locally)
- static const IpAddress Broadcast; ///< The "broadcast" address (for sending UDP messages to
- ///< everyone on a local network)
- private:
- friend EE_API bool operator<( const IpAddress& left, const IpAddress& right );
-
- /** @brief Resolve the given address string
- ** @param address Address string */
- void resolve( const std::string& address );
-
- // Member data
- Uint32 mAddress; ///< Address stored as an unsigned 32 bits integer
- bool mValid; ///< Is the address valid?
-};
-
-/** @brief Overload of == operator to compare two IP addresses
-** @param left Left operand (a IP address)
-** @param right Right operand (a IP address)
-** @return True if both addresses are equal */
-EE_API bool operator==( const IpAddress& left, const IpAddress& right );
-
-/** @brief Overload of != operator to compare two IP addresses
-** @param left Left operand (a IP address)
-** @param right Right operand (a IP address)
-** @return True if both addresses are different */
-EE_API bool operator!=( const IpAddress& left, const IpAddress& right );
-
-/** @brief Overload of < operator to compare two IP addresses
-** @param left Left operand (a IP address)
-** @param right Right operand (a IP address)
-** @return True if @a left is lesser than @a right */
-EE_API bool operator<( const IpAddress& left, const IpAddress& right );
-
-/** @brief Overload of > operator to compare two IP addresses
-** @param left Left operand (a IP address)
-** @param right Right operand (a IP address)
-** @return True if @a left is greater than @a right */
-EE_API bool operator>( const IpAddress& left, const IpAddress& right );
-
-/** @brief Overload of <= operator to compare two IP addresses
-** @param left Left operand (a IP address)
-** @param right Right operand (a IP address)
-** @return True if @a left is lesser or equal than @a right */
-EE_API bool operator<=( const IpAddress& left, const IpAddress& right );
-
-/** @brief Overload of >= operator to compare two IP addresses
-** @param left Left operand (a IP address)
-** @param right Right operand (a IP address)
-** @return True if @a left is greater or equal than @a right */
-EE_API bool operator>=( const IpAddress& left, const IpAddress& right );
-
-/** @brief Overload of >> operator to extract an IP address from an input stream
-** @param stream Input stream
-** @param address IP address to extract
-** @return Reference to the input stream */
-EE_API std::istream& operator>>( std::istream& stream, IpAddress& address );
-
-/** @brief Overload of << operator to print an IP address to an output stream
-** @param stream Output stream
-** @param address IP address to print
-** @return Reference to the output stream */
-EE_API std::ostream& operator<<( std::ostream& stream, const IpAddress& address );
-
-}} // namespace EE::Network
-
-#endif // EE_NETWORKCIPADDRESS_HPP
-
-/**
-@class EE::Network::IpAddress
-
-IpAddress is a utility class for manipulating network
-addresses. It provides a set a implicit constructors and
-conversion functions to easily build or transform an IP
-address from/to various representations.
-
-Usage example:
-@code
-IpAddress a0; // an invalid address
-IpAddress a1 = IpAddress::None; // an invalid address (same as a0)
-IpAddress a2("127.0.0.1"); // the local host address
-IpAddress a3 = IpAddress::Broadcast; // the broadcast address
-IpAddress a4(192, 168, 1, 56); // a local address
-IpAddress a5("my_computer"); // a local address created from a network name
-IpAddress a6("89.54.1.169"); // a distant address
-IpAddress a7("www.google.com"); // a distant address created from a network name
-IpAddress a8 = IpAddress::getLocalAddress(); // my address on the local network
-IpAddress a9 = IpAddress::getPublicAddress(); // my address on the internet
-@endcode
-Note that IpAddress currently doesn't support IPv6
-nor other types of network addresses.
-*/
+#ifndef EE_NETWORKCIPADDRESS_HPP
+#define EE_NETWORKCIPADDRESS_HPP
+
+#include
+#include
+using namespace EE::System;
+
+#include
+#include
+#include
+
+namespace EE { namespace Network {
+
+/** @brief Encapsulate an IPv4 network address */
+class EE_API IpAddress {
+ public:
+ /** @brief Default constructor
+ ** This constructor creates an empty (invalid) address */
+ IpAddress();
+
+ /** @brief Construct the address from a string
+ ** Here @a address can be either a decimal address
+ ** (ex: "192.168.1.56") or a network name (ex: "localhost").
+ ** @param address IP address or network name */
+ IpAddress( const std::string& address );
+
+ /** @brief Construct the address from a string
+ ** Here @a address can be either a decimal address
+ ** (ex: "192.168.1.56") or a network name (ex: "localhost").
+ ** This is equivalent to the constructor taking a std::string
+ ** parameter, it is defined for convenience so that the
+ ** implicit conversions from literal strings to IpAddress work.
+ ** @param address IP address or network name */
+ IpAddress( const char* address );
+
+ /** @brief Construct the address from 4 bytes
+ ** Calling IpAddress(a, b, c, d) is equivalent to calling
+ ** IpAddress("a.b.c.d"), but safer as it doesn't have to
+ ** parse a string to get the address components.
+ ** @param byte0 First byte of the address
+ ** @param byte1 Second byte of the address
+ ** @param byte2 Third byte of the address
+ ** @param byte3 Fourth byte of the address */
+ IpAddress( Uint8 byte0, Uint8 byte1, Uint8 byte2, Uint8 byte3 );
+
+ /** @brief Construct the address from a 32-bits integer
+ ** This constructor uses the internal representation of
+ ** the address directly. It should be used for optimization
+ ** purposes, and only if you got that representation from
+ ** IpAddress::toInteger().
+ ** @param address 4 bytes of the address packed into a 32-bits integer
+ ** @see ToInteger */
+ explicit IpAddress( Uint32 address );
+
+ /** @brief Get a string representation of the address
+ ** The returned string is the decimal representation of the
+ ** IP address (like "192.168.1.56"), even if it was constructed
+ ** from a host name.
+ ** @return String representation of the address
+ ** @see ToInteger */
+ std::string toString() const;
+
+ /** @brief Get an integer representation of the address
+ ** The returned number is the internal representation of the
+ ** address, and should be used for optimization purposes only
+ ** (like sending the address through a socket).
+ ** The integer produced by this function can then be converted
+ ** back to a IpAddress with the proper constructor.
+ ** @return 32-bits unsigned integer representation of the address
+ ** @see ToString */
+ Uint32 toInteger() const;
+
+ /** @brief Get the computer's local address
+ ** The local address is the address of the computer from the
+ ** LAN point of view, i.e. something like 192.168.1.56. It is
+ ** meaningful only for communications over the local network.
+ ** Unlike GetPublicAddress, this function is fast and may be
+ ** used safely anywhere.
+ ** @return Local IP address of the computer
+ ** @see GetPublicAddress */
+ static IpAddress getLocalAddress();
+
+ /** @brief Get the computer's public address
+ ** The public address is the address of the computer from the
+ ** internet point of view, i.e. something like 89.54.1.169.
+ ** It is necessary for communications over the world wide web.
+ ** The only way to get a public address is to ask it to a
+ ** distant website; as a consequence, this function depends on
+ ** both your network connection and the server, and may be
+ ** very slow. You should use it as few as possible. Because
+ ** this function depends on the network connection and on a distant
+ ** server, you may use a time limit if you don't want your program
+ ** to be possibly stuck waiting in case there is a problem; this
+ ** limit is deactivated by default.
+ ** @param timeout Maximum time to wait
+ ** @return Public IP address of the computer
+ ** @see GetLocalAddress */
+ static IpAddress getPublicAddress( Time timeout = Time::Zero );
+
+ // Static member data
+ static const IpAddress None; ///< Value representing an empty/invalid address
+ static const IpAddress Any; ///< Value representing any address (0.0.0.0)
+ static const IpAddress
+ LocalHost; ///< The "localhost" address (for connecting a computer to itself locally)
+ static const IpAddress Broadcast; ///< The "broadcast" address (for sending UDP messages to
+ ///< everyone on a local network)
+ private:
+ friend EE_API bool operator<( const IpAddress& left, const IpAddress& right );
+
+ /** @brief Resolve the given address string
+ ** @param address Address string */
+ void resolve( const std::string& address );
+
+ // Member data
+ Uint32 mAddress; ///< Address stored as an unsigned 32 bits integer
+ bool mValid; ///< Is the address valid?
+};
+
+/** @brief Overload of == operator to compare two IP addresses
+** @param left Left operand (a IP address)
+** @param right Right operand (a IP address)
+** @return True if both addresses are equal */
+EE_API bool operator==( const IpAddress& left, const IpAddress& right );
+
+/** @brief Overload of != operator to compare two IP addresses
+** @param left Left operand (a IP address)
+** @param right Right operand (a IP address)
+** @return True if both addresses are different */
+EE_API bool operator!=( const IpAddress& left, const IpAddress& right );
+
+/** @brief Overload of < operator to compare two IP addresses
+** @param left Left operand (a IP address)
+** @param right Right operand (a IP address)
+** @return True if @a left is lesser than @a right */
+EE_API bool operator<( const IpAddress& left, const IpAddress& right );
+
+/** @brief Overload of > operator to compare two IP addresses
+** @param left Left operand (a IP address)
+** @param right Right operand (a IP address)
+** @return True if @a left is greater than @a right */
+EE_API bool operator>( const IpAddress& left, const IpAddress& right );
+
+/** @brief Overload of <= operator to compare two IP addresses
+** @param left Left operand (a IP address)
+** @param right Right operand (a IP address)
+** @return True if @a left is lesser or equal than @a right */
+EE_API bool operator<=( const IpAddress& left, const IpAddress& right );
+
+/** @brief Overload of >= operator to compare two IP addresses
+** @param left Left operand (a IP address)
+** @param right Right operand (a IP address)
+** @return True if @a left is greater or equal than @a right */
+EE_API bool operator>=( const IpAddress& left, const IpAddress& right );
+
+/** @brief Overload of >> operator to extract an IP address from an input stream
+** @param stream Input stream
+** @param address IP address to extract
+** @return Reference to the input stream */
+EE_API std::istream& operator>>( std::istream& stream, IpAddress& address );
+
+/** @brief Overload of << operator to print an IP address to an output stream
+** @param stream Output stream
+** @param address IP address to print
+** @return Reference to the output stream */
+EE_API std::ostream& operator<<( std::ostream& stream, const IpAddress& address );
+
+}} // namespace EE::Network
+
+#endif // EE_NETWORKCIPADDRESS_HPP
+
+/**
+@class EE::Network::IpAddress
+
+IpAddress is a utility class for manipulating network
+addresses. It provides a set a implicit constructors and
+conversion functions to easily build or transform an IP
+address from/to various representations.
+
+Usage example:
+@code
+IpAddress a0; // an invalid address
+IpAddress a1 = IpAddress::None; // an invalid address (same as a0)
+IpAddress a2("127.0.0.1"); // the local host address
+IpAddress a3 = IpAddress::Broadcast; // the broadcast address
+IpAddress a4(192, 168, 1, 56); // a local address
+IpAddress a5("my_computer"); // a local address created from a network name
+IpAddress a6("89.54.1.169"); // a distant address
+IpAddress a7("www.google.com"); // a distant address created from a network name
+IpAddress a8 = IpAddress::getLocalAddress(); // my address on the local network
+IpAddress a9 = IpAddress::getPublicAddress(); // my address on the internet
+@endcode
+Note that IpAddress currently doesn't support IPv6
+nor other types of network addresses.
+*/
diff --git a/include/eepp/network/socket.hpp b/include/eepp/network/socket.hpp
index a7603a5ad..89691e655 100644
--- a/include/eepp/network/socket.hpp
+++ b/include/eepp/network/socket.hpp
@@ -1,125 +1,125 @@
-#ifndef EE_NETWORKCSOCKET_HPP
-#define EE_NETWORKCSOCKET_HPP
-
-#include
-#include
-#include
-
-namespace EE { namespace Network {
-class SocketSelector;
-
-/** @brief Base class for all the socket types */
-class EE_API Socket : NonCopyable {
- public:
- /** @brief Status codes that may be returned by socket functions */
- enum Status {
- Done, ///< The socket has sent / received the data
- NotReady, ///< The socket is not ready to send / receive data yet
- Partial, ///< The socket sent a part of the data
- Disconnected, ///< The TCP socket has been disconnected
- Error ///< An unexpected error happened
- };
-
- /** @brief Some special values used by sockets */
- enum {
- AnyPort = 0 ///< Special value that tells the system to pick any available port
- };
-
- /** @brief Destructor */
- virtual ~Socket();
-
- /** @brief Set the blocking state of the socket
- ** In blocking mode, calls will not return until they have
- ** completed their task. For example, a call to Receive in
- ** blocking mode won't return until some data was actually
- ** received.
- ** In non-blocking mode, calls will always return immediately,
- ** using the return code to signal whether there was data
- ** available or not.
- ** By default, all sockets are blocking.
- ** @param blocking True to set the socket as blocking, false for non-blocking
- ** @see IsBlocking */
- void setBlocking( bool blocking );
-
- /** @brief Tell whether the socket is in blocking or non-blocking mode
- ** @return True if the socket is blocking, false otherwise
- ** @see SetBlocking */
- bool isBlocking() const;
-
- protected:
- /** @brief Types of protocols that the socket can use */
- enum Type {
- Tcp, ///< TCP protocol
- Udp ///< UDP protocol
- };
-
- /** @brief Default constructor
- ** This constructor can only be accessed by derived classes.
- ** @param type Type of the socket (TCP or UDP) */
- Socket( Type type );
-
- /** @brief Return the internal handle of the socket
- ** The returned handle may be invalid if the socket
- ** was not created yet (or already destroyed).
- ** This function can only be accessed by derived classes.
- ** @return The internal (OS-specific) handle of the socket */
- SocketHandle getHandle() const;
-
+#ifndef EE_NETWORKCSOCKET_HPP
+#define EE_NETWORKCSOCKET_HPP
+
+#include
+#include
+#include
+
+namespace EE { namespace Network {
+class SocketSelector;
+
+/** @brief Base class for all the socket types */
+class EE_API Socket : NonCopyable {
+ public:
+ /** @brief Status codes that may be returned by socket functions */
+ enum Status {
+ Done, ///< The socket has sent / received the data
+ NotReady, ///< The socket is not ready to send / receive data yet
+ Partial, ///< The socket sent a part of the data
+ Disconnected, ///< The TCP socket has been disconnected
+ Error ///< An unexpected error happened
+ };
+
+ /** @brief Some special values used by sockets */
+ enum {
+ AnyPort = 0 ///< Special value that tells the system to pick any available port
+ };
+
+ /** @brief Destructor */
+ virtual ~Socket();
+
+ /** @brief Set the blocking state of the socket
+ ** In blocking mode, calls will not return until they have
+ ** completed their task. For example, a call to Receive in
+ ** blocking mode won't return until some data was actually
+ ** received.
+ ** In non-blocking mode, calls will always return immediately,
+ ** using the return code to signal whether there was data
+ ** available or not.
+ ** By default, all sockets are blocking.
+ ** @param blocking True to set the socket as blocking, false for non-blocking
+ ** @see IsBlocking */
+ void setBlocking( bool blocking );
+
+ /** @brief Tell whether the socket is in blocking or non-blocking mode
+ ** @return True if the socket is blocking, false otherwise
+ ** @see SetBlocking */
+ bool isBlocking() const;
+
+ protected:
+ /** @brief Types of protocols that the socket can use */
+ enum Type {
+ Tcp, ///< TCP protocol
+ Udp ///< UDP protocol
+ };
+
+ /** @brief Default constructor
+ ** This constructor can only be accessed by derived classes.
+ ** @param type Type of the socket (TCP or UDP) */
+ Socket( Type type );
+
+ /** @brief Return the internal handle of the socket
+ ** The returned handle may be invalid if the socket
+ ** was not created yet (or already destroyed).
+ ** This function can only be accessed by derived classes.
+ ** @return The internal (OS-specific) handle of the socket */
+ SocketHandle getHandle() const;
+
/** @brief Create the internal representation of the socket
///
** This function can only be accessed by derived classes.
** @return True when a valid socket exists, false when socket creation failed. */
bool create();
-
- /** @brief Create the internal representation of the socket from a socket handle
- ** This function can only be accessed by derived classes.
- ** @param handle OS-specific handle of the socket to wrap */
- void create( SocketHandle handle );
-
- /** @brief Close the socket gracefully
- ** This function can only be accessed by derived classes. */
- void close();
-
- protected:
- friend class SocketSelector;
- // Member data
- Type mType; ///< Type of the socket (TCP or UDP)
- SocketHandle mSocket; ///< Socket descriptor
- bool mIsBlocking; ///< Current blocking mode of the socket
-};
-
-}} // namespace EE::Network
-
-#endif // EE_NETWORKCSOCKET_HPP
-
-/**
-@class EE::Network::Socket
-
-This class mainly defines internal stuff to be used by
-derived classes.
-
-The only public features that it defines, and which
-is therefore common to all the socket classes, is the
-blocking state. All sockets can be set as blocking or
-non-blocking.
-
-In blocking mode, socket functions will hang until
-the operation completes, which means that the entire
-program (well, in fact the current thread if you use
-multiple ones) will be stuck waiting for your socket
-operation to complete.
-
-In non-blocking mode, all the socket functions will
-return immediately. If the socket is not ready to complete
-the requested operation, the function simply returns
-the proper status code (Socket::NotReady).
-The default mode, which is blocking, is the one that is
-generally used, in combination with threads or selectors.
-
-The non-blocking mode is rather used in real-time
-applications that run an endless loop that can poll
-the socket often enough, and cannot afford blocking
-this loop.
-
-@see EE::Network::TcpListener, EE::Network::TcpSocket, EE::Network::UdpSocket
-*/
+
+ /** @brief Create the internal representation of the socket from a socket handle
+ ** This function can only be accessed by derived classes.
+ ** @param handle OS-specific handle of the socket to wrap */
+ void create( SocketHandle handle );
+
+ /** @brief Close the socket gracefully
+ ** This function can only be accessed by derived classes. */
+ void close();
+
+ protected:
+ friend class SocketSelector;
+ // Member data
+ Type mType; ///< Type of the socket (TCP or UDP)
+ SocketHandle mSocket; ///< Socket descriptor
+ bool mIsBlocking; ///< Current blocking mode of the socket
+};
+
+}} // namespace EE::Network
+
+#endif // EE_NETWORKCSOCKET_HPP
+
+/**
+@class EE::Network::Socket
+
+This class mainly defines internal stuff to be used by
+derived classes.
+
+The only public features that it defines, and which
+is therefore common to all the socket classes, is the
+blocking state. All sockets can be set as blocking or
+non-blocking.
+
+In blocking mode, socket functions will hang until
+the operation completes, which means that the entire
+program (well, in fact the current thread if you use
+multiple ones) will be stuck waiting for your socket
+operation to complete.
+
+In non-blocking mode, all the socket functions will
+return immediately. If the socket is not ready to complete
+the requested operation, the function simply returns
+the proper status code (Socket::NotReady).
+The default mode, which is blocking, is the one that is
+generally used, in combination with threads or selectors.
+
+The non-blocking mode is rather used in real-time
+applications that run an endless loop that can poll
+the socket often enough, and cannot afford blocking
+this loop.
+
+@see EE::Network::TcpListener, EE::Network::TcpSocket, EE::Network::UdpSocket
+*/
diff --git a/include/eepp/network/socketselector.hpp b/include/eepp/network/socketselector.hpp
index 71981acc6..b21e707cf 100644
--- a/include/eepp/network/socketselector.hpp
+++ b/include/eepp/network/socketselector.hpp
@@ -1,168 +1,168 @@
-#ifndef EE_NETWORKCSOCKETSELECTOR_HPP
-#define EE_NETWORKCSOCKETSELECTOR_HPP
-
-#include
-#include
-using namespace EE::System;
-
-namespace EE { namespace Network {
-
-class Socket;
-
-/** Multiplexer that allows to read from multiple sockets */
-class EE_API SocketSelector {
- public:
- /** @brief Default constructor */
- SocketSelector();
-
- /** @brief Copy constructor
- ** @param copy Instance to copy */
- SocketSelector( const SocketSelector& copy );
-
- /** @brief Destructor */
- ~SocketSelector();
-
- /** @brief Add a new socket to the selector
- ** This function keeps a weak reference to the socket,
- ** so you have to make sure that the socket is not destroyed
- ** while it is stored in the selector.
- ** This function does nothing if the socket is not valid.
- ** @param socket Reference to the socket to add
- ** @see Remove, Clear */
- void add( Socket& socket );
-
- /** @brief Remove a socket from the selector
- ** This function doesn't destroy the socket, it simply
- ** removes the reference that the selector has to it.
- ** @param socket Reference to the socket to remove
- ** @see Add, Clear */
- void remove( Socket& socket );
-
- /** @brief Remove all the sockets stored in the selector
- ** This function doesn't destroy any instance, it simply
- ** removes all the references that the selector has to
- ** external sockets.
- ** @see Add, Remove */
- void clear();
-
- /** @brief Wait until one or more sockets are ready to receive
- ** This function returns as soon as at least one socket has
- ** some data available to be received. To know which sockets are
- ** ready, use the isReady function.
- ** If you use a timeout and no socket is ready before the timeout
- ** is over, the function returns false.
- ** @param timeout Maximum time to wait, (use Time::Zero for infinity)
- ** @return True if there are sockets ready, false otherwise
- ** @see IsReady */
- bool wait( Time timeout = Time::Zero );
-
- /** @brief Test a socket to know if it is ready to receive data
- ** This function must be used after a call to Wait, to know
- ** which sockets are ready to receive data. If a socket is
- ** ready, a call to receive will never block because we know
- ** that there is data available to read.
- ** Note that if this function returns true for a TcpListener,
- ** this means that it is ready to accept a new connection.
- ** @param socket Socket to test
- ** @return True if the socket is ready to read, false otherwise
- ** @see IsReady */
- bool isReady( Socket& socket ) const;
-
- /** @brief Overload of assignment operator
- ** @param right Instance to assign
- ** @return Reference to self */
- SocketSelector& operator=( const SocketSelector& right );
-
- private:
- struct SocketSelectorImpl;
-
- // Member data
- SocketSelectorImpl*
- mImpl; ///< Opaque pointer to the implementation (which requires OS-specific types)
-};
-
-}} // namespace EE::Network
-
-#endif // EE_NETWORKCSOCKETSELECTOR_HPP
-
-/**
-@class EE::Network::SocketSelector
-
-Socket selectors provide a way to wait until some data is
-available on a set of sockets, instead of just one. This
-is convenient when you have multiple sockets that may
-possibly receive data, but you don't know which one will
-be ready first. In particular, it avoids to use a thread
-for each socket; with selectors, a single thread can handle
-all the sockets.
-
-All types of sockets can be used in a selector:
-@li EE::NetworkTcpListener
-@li EE::NetworkTcpSocket
-@li EE::NetworkUdpSocket
-
-A selector doesn't store its own copies of the sockets
-(socket classes are not copyable anyway), it simply keeps
-a reference to the original sockets that you pass to the
-"add" function. Therefore, you can't use the selector as a
-socket container, you must store them outside and make sure
-that they are alive as long as they are used in the selector.
-
-Using a selector is simple:
-@li populate the selector with all the sockets that you want to observe
-@li make it wait until there is data available on any of the sockets
-@li test each socket to find out which ones are ready
-
-Usage example:
-@code
-// Create a socket to listen to new connections
-TcpListener listener;
-listener.listen(55001);
-
-// Create a list to store the future clients
-std::vector clients;
-
-// Create a selector
-SocketSelector selector;
-
-// Add the listener to the selector
-selector.add(listener);
-
-// Endless loop that waits for new connections
-while (running) {
- // Make the selector wait for data on any socket
- if (selector.wait()) {
- // Test the listener
- if (selector.isReady(listener)) {
- // The listener is ready: there is a pending connection
- TcpSocket* client = new TcpSocket;
- if (listener.accept(*client) == Socket::Done) {
- // Add the new client to the clients list
- clients.push_back(client);
-
- // Add the new client to the selector so that we will
- // be notified when he sends something
- selector.add(*client);
- } else {
- // Error, we won't get a new connection, delete the socket
- delete client;
- }
- } else {
- // The listener socket is not ready, test all other sockets (the clients)
- for (std::vector::iterator it = clients.begin(); it != clients.end(); ++it) {
- TcpSocket& client = **it;
- if (selector.isReady(client)) {
- // The client has sent some data, we can receive it
- Packet packet;
- if (client.Receive(packet) == Socket::Done) {
- ...
- }
- }
- }
- }
- }
-}
-@endcode
-
-@see EE::Network::Socket
-*/
+#ifndef EE_NETWORKCSOCKETSELECTOR_HPP
+#define EE_NETWORKCSOCKETSELECTOR_HPP
+
+#include
+#include
+#include
+using namespace EE::System;
+
+namespace EE { namespace Network {
+
+class Socket;
+
+/** Multiplexer that allows to read from multiple sockets */
+class EE_API SocketSelector {
+ public:
+ /** @brief Default constructor */
+ SocketSelector();
+
+ /** @brief Copy constructor
+ ** @param copy Instance to copy */
+ SocketSelector( const SocketSelector& copy );
+
+ /** @brief Destructor */
+ ~SocketSelector();
+
+ /** @brief Add a new socket to the selector
+ ** This function keeps a weak reference to the socket,
+ ** so you have to make sure that the socket is not destroyed
+ ** while it is stored in the selector.
+ ** This function does nothing if the socket is not valid.
+ ** @param socket Reference to the socket to add
+ ** @see Remove, Clear */
+ void add( Socket& socket );
+
+ /** @brief Remove a socket from the selector
+ ** This function doesn't destroy the socket, it simply
+ ** removes the reference that the selector has to it.
+ ** @param socket Reference to the socket to remove
+ ** @see Add, Clear */
+ void remove( Socket& socket );
+
+ /** @brief Remove all the sockets stored in the selector
+ ** This function doesn't destroy any instance, it simply
+ ** removes all the references that the selector has to
+ ** external sockets.
+ ** @see Add, Remove */
+ void clear();
+
+ /** @brief Wait until one or more sockets are ready to receive
+ ** This function returns as soon as at least one socket has
+ ** some data available to be received. To know which sockets are
+ ** ready, use the isReady function.
+ ** If you use a timeout and no socket is ready before the timeout
+ ** is over, the function returns false.
+ ** @param timeout Maximum time to wait, (use Time::Zero for infinity)
+ ** @return True if there are sockets ready, false otherwise
+ ** @see IsReady */
+ bool wait( Time timeout = Time::Zero );
+
+ /** @brief Test a socket to know if it is ready to receive data
+ ** This function must be used after a call to Wait, to know
+ ** which sockets are ready to receive data. If a socket is
+ ** ready, a call to receive will never block because we know
+ ** that there is data available to read.
+ ** Note that if this function returns true for a TcpListener,
+ ** this means that it is ready to accept a new connection.
+ ** @param socket Socket to test
+ ** @return True if the socket is ready to read, false otherwise
+ ** @see IsReady */
+ bool isReady( Socket& socket ) const;
+
+ /** @brief Overload of assignment operator
+ ** @param right Instance to assign
+ ** @return Reference to self */
+ SocketSelector& operator=( const SocketSelector& right );
+
+ private:
+ struct SocketSelectorImpl;
+
+ // Member data
+ SocketSelectorImpl*
+ mImpl; ///< Opaque pointer to the implementation (which requires OS-specific types)
+};
+
+}} // namespace EE::Network
+
+#endif // EE_NETWORKCSOCKETSELECTOR_HPP
+
+/**
+@class EE::Network::SocketSelector
+
+Socket selectors provide a way to wait until some data is
+available on a set of sockets, instead of just one. This
+is convenient when you have multiple sockets that may
+possibly receive data, but you don't know which one will
+be ready first. In particular, it avoids to use a thread
+for each socket; with selectors, a single thread can handle
+all the sockets.
+
+All types of sockets can be used in a selector:
+@li EE::NetworkTcpListener
+@li EE::NetworkTcpSocket
+@li EE::NetworkUdpSocket
+
+A selector doesn't store its own copies of the sockets
+(socket classes are not copyable anyway), it simply keeps
+a reference to the original sockets that you pass to the
+"add" function. Therefore, you can't use the selector as a
+socket container, you must store them outside and make sure
+that they are alive as long as they are used in the selector.
+
+Using a selector is simple:
+@li populate the selector with all the sockets that you want to observe
+@li make it wait until there is data available on any of the sockets
+@li test each socket to find out which ones are ready
+
+Usage example:
+@code
+// Create a socket to listen to new connections
+TcpListener listener;
+listener.listen(55001);
+
+// Create a list to store the future clients
+std::vector clients;
+
+// Create a selector
+SocketSelector selector;
+
+// Add the listener to the selector
+selector.add(listener);
+
+// Endless loop that waits for new connections
+while (running) {
+ // Make the selector wait for data on any socket
+ if (selector.wait()) {
+ // Test the listener
+ if (selector.isReady(listener)) {
+ // The listener is ready: there is a pending connection
+ TcpSocket* client = new TcpSocket;
+ if (listener.accept(*client) == Socket::Done) {
+ // Add the new client to the clients list
+ clients.push_back(client);
+
+ // Add the new client to the selector so that we will
+ // be notified when he sends something
+ selector.add(*client);
+ } else {
+ // Error, we won't get a new connection, delete the socket
+ delete client;
+ }
+ } else {
+ // The listener socket is not ready, test all other sockets (the clients)
+ for (std::vector::iterator it = clients.begin(); it != clients.end(); ++it)
+{ TcpSocket& client = **it; if (selector.isReady(client)) {
+ // The client has sent some data, we can receive it
+ Packet packet;
+ if (client.Receive(packet) == Socket::Done) {
+ ...
+ }
+ }
+ }
+ }
+ }
+}
+@endcode
+
+@see EE::Network::Socket
+*/
diff --git a/include/eepp/network/tcpsocket.hpp b/include/eepp/network/tcpsocket.hpp
index 3e90d6a70..2375d461c 100644
--- a/include/eepp/network/tcpsocket.hpp
+++ b/include/eepp/network/tcpsocket.hpp
@@ -1,227 +1,229 @@
-#ifndef EE_NETWORKCTCPSOCKET_HPP
-#define EE_NETWORKCTCPSOCKET_HPP
-
-#include
-#include
-#include
-using namespace EE::System;
-
-namespace EE { namespace Network {
-
-class TcpListener;
-class IpAddress;
-class Packet;
-
-/** @brief Specialized socket using the TCP protocol */
-class EE_API TcpSocket : public Socket {
- public:
- static TcpSocket* New();
-
- /** @brief Default constructor */
- TcpSocket();
-
- virtual ~TcpSocket();
-
- /** @brief Get the port to which the socket is bound locally
- ** If the socket is not connected, this function returns 0.
- ** @return Port to which the socket is bound
- ** @see Connect, GetRemotePort */
- unsigned short getLocalPort() const;
-
- /** @brief Get the address of the connected peer
- ** It the socket is not connected, this function returns
- ** IpAddress::None.
- ** @return Address of the remote peer
- ** @see GetRemotePort */
- IpAddress getRemoteAddress() const;
-
- /** @brief Get the port of the connected peer to which
- the socket is connected
- ** If the socket is not connected, this function returns 0.
- ** @return Remote port to which the socket is connected
- ** @see GetRemoteAddress */
- unsigned short getRemotePort() const;
-
- /** @brief Connect the socket to a remote peer
- ** In blocking mode, this function may take a while, especially
- ** if the remote peer is not reachable. The last parameter allows
- ** you to stop trying to connect after a given timeout.
- ** If the socket was previously connected, it is first disconnected.
- ** @param remoteAddress Address of the remote peer
- ** @param remotePort Port of the remote peer
- ** @param timeout Optional maximum time to wait
- ** @return Status code
- ** @see Disconnect */
- virtual Status connect( const IpAddress& remoteAddress, unsigned short remotePort,
- Time timeout = Time::Zero );
-
- /** @brief Disconnect the socket from its remote peer
- ** This function gracefully closes the connection. If the
- ** socket is not connected, this function has no effect.
- ** @see Connect */
- virtual void disconnect();
-
- /** @brief Send raw data to the remote peer
- ** To be able to handle partial sends over non-blocking
- ** sockets, use the send(const void*, std::size_t, std::size_t&)
- ** overload instead.
- **
- ** This function will fail if the socket is not connected.
- **
- ** @param data Pointer to the sequence of bytes to send
- ** @param size Number of bytes to send
- ** @return Status code
- ** @see Receive */
- virtual Status send( const void* data, std::size_t size );
-
- /** @brief Send raw data to the remote peer
- ** This function will fail if the socket is not connected.
- ** @param data Pointer to the sequence of bytes to send
- ** @param size Number of bytes to send
- ** @param sent The number of bytes sent will be written here
- ** @return Status code
- ** @see receive */
- virtual Status send( const void* data, std::size_t size, std::size_t& sent );
-
- /** @brief Receive raw data from the remote peer
- ** In blocking mode, this function will wait until some
- ** bytes are actually received.
- ** This function will fail if the socket is not connected.
- ** @param data Pointer to the array to fill with the received bytes
- ** @param size Maximum number of bytes that can be received
- ** @param received This variable is filled with the actual number of bytes received
- ** @return Status code
- ** @see Send */
- virtual Status receive( void* data, std::size_t size, std::size_t& received );
-
- /** @brief Send a formatted packet of data to the remote peer
- *
- ** In non-blocking mode, if this function returns sf::Socket::Partial,
- ** you \em must retry sending the same unmodified packet before sending
- ** anything else in order to guarantee the packet arrives at the remote
- ** peer uncorrupted.
- **
- ** This function will fail if the socket is not connected.
- ** @param packet Packet to send
- ** @return Status code
- ** @see Receive */
- virtual Status send( Packet& packet );
-
- /** @brief Receive a formatted packet of data from the remote peer
- ** In blocking mode, this function will wait until the whole packet
- ** has been received.
- ** This function will fail if the socket is not connected.
- ** @param packet Packet to fill with the received data
- ** @return Status code
- ** @see Send */
- virtual Status receive( Packet& packet );
-
- /** Set the send timeout. Only callable after connect ( after the socket
- ** has been initialized ). */
- void setSendTimeout( const Time& timeout );
-
- /** Set the receive timeout Only callable after connect ( after the socket
- ** has been initialized ). */
- void setReceiveTimeout( const Time& timeout );
-
- typedef std::function ReadFn;
-
- /** @brief Starts a new thread to receive all stdout and stderr data */
- void startAsyncRead( ReadFn readFn = nullptr );
-
- private:
- friend class TcpListener;
-
- /** @brief Structure holding the data of a pending packet */
- struct PendingPacket {
- PendingPacket();
-
- Uint32 Size; ///< Data of packet size
- std::size_t SizeReceived; ///< Number of size bytes received so far
- std::vector Data; ///< Data of the packet
- };
-
- // Member data
- PendingPacket mPendingPacket; ///< Temporary data of the packet currently being received
- std::thread mReadThread;
-};
-
-}} // namespace EE::Network
-
-#endif // EE_NETWORKCTCPSOCKET_HPP
-
-/**
-@class EE::Network::TcpSocket
-
-TCP is a connected protocol, which means that a TCP
-socket can only communicate with the host it is connected
-to. It can't send or receive anything if it is not connected.
-
-The TCP protocol is reliable but adds a slight overhead.
-It ensures that your data will always be received in order
-and without errors (no data corrupted, lost or duplicated).
-
-When a socket is connected to a remote host, you can
-retrieve information about this host with the
-GetRemoteAddress and GetRemotePort functions. You can
-also get the local port to which the socket is bound
-(which is automatically chosen when the socket is connected),
-with the GetLocalPort function.
-
-Sending and receiving data can use either the low-level
-or the high-level functions. The low-level functions
-process a raw sequence of bytes, and cannot ensure that
-one call to Send will exactly match one call to Receive
-at the other end of the socket.
-
-The high-level interface uses packets (see Packet),
-which are easier to use and provide more safety regarding
-the data that is exchanged. You can look at the Packet
-class to get more details about how they work.
-
-The socket is automatically disconnected when it is destroyed,
-but if you want to explicitly close the connection while
-the socket instance is still alive, you can call disconnect.
-
-Usage example:
-@code
-// ----- The client -----
-
-// Create a socket and connect it to 192.168.1.50 on port 55001
-TcpSocket socket;
-socket.connect("192.168.1.50", 55001);
-
-// Send a message to the connected host
-std::string message = "Hi, I am a client";
-socket.send(message.c_str(), message.size() + 1);
-
-// Receive an answer from the server
-char buffer[1024];
-std::size_t received = 0;
-socket.receive(buffer, sizeof(buffer), received);
-std::cout << "The server said: " << buffer << std::endl;
-
-// ----- The server -----
-
-// Create a listener to wait for incoming connections on port 55001
-TcpListener listener;
-listener.listen(55001);
-
-// Wait for a connection
-TcpSocket socket;
-listener.accept(socket);
-std::cout << "New client connected: " << socket.getRemoteAddress() << std::endl;
-
-// Receive a message from the client
-char buffer[1024];
-std::size_t received = 0;
-socket.receive(buffer, sizeof(buffer), received);
-std::cout << "The client said: " << buffer << std::endl;
-
-// Send an answer
-std::string message = "Welcome, client";
-socket.send(message.c_str(), message.size() + 1);
-@endcode
-
-@see EE::Network::Socket, EE::Network::UdpSocket, EE::Network::Packet
-*/
+#ifndef EE_NETWORKCTCPSOCKET_HPP
+#define EE_NETWORKCTCPSOCKET_HPP
+
+#include
+#include
+#include
+#include
+#include
+using namespace EE::System;
+
+namespace EE { namespace Network {
+
+class TcpListener;
+class IpAddress;
+class Packet;
+
+/** @brief Specialized socket using the TCP protocol */
+class EE_API TcpSocket : public Socket {
+ public:
+ static TcpSocket* New();
+
+ /** @brief Default constructor */
+ TcpSocket();
+
+ virtual ~TcpSocket();
+
+ /** @brief Get the port to which the socket is bound locally
+ ** If the socket is not connected, this function returns 0.
+ ** @return Port to which the socket is bound
+ ** @see Connect, GetRemotePort */
+ unsigned short getLocalPort() const;
+
+ /** @brief Get the address of the connected peer
+ ** It the socket is not connected, this function returns
+ ** IpAddress::None.
+ ** @return Address of the remote peer
+ ** @see GetRemotePort */
+ IpAddress getRemoteAddress() const;
+
+ /** @brief Get the port of the connected peer to which
+ the socket is connected
+ ** If the socket is not connected, this function returns 0.
+ ** @return Remote port to which the socket is connected
+ ** @see GetRemoteAddress */
+ unsigned short getRemotePort() const;
+
+ /** @brief Connect the socket to a remote peer
+ ** In blocking mode, this function may take a while, especially
+ ** if the remote peer is not reachable. The last parameter allows
+ ** you to stop trying to connect after a given timeout.
+ ** If the socket was previously connected, it is first disconnected.
+ ** @param remoteAddress Address of the remote peer
+ ** @param remotePort Port of the remote peer
+ ** @param timeout Optional maximum time to wait
+ ** @return Status code
+ ** @see Disconnect */
+ virtual Status connect( const IpAddress& remoteAddress, unsigned short remotePort,
+ Time timeout = Time::Zero );
+
+ /** @brief Disconnect the socket from its remote peer
+ ** This function gracefully closes the connection. If the
+ ** socket is not connected, this function has no effect.
+ ** @see Connect */
+ virtual void disconnect();
+
+ /** @brief Send raw data to the remote peer
+ ** To be able to handle partial sends over non-blocking
+ ** sockets, use the send(const void*, std::size_t, std::size_t&)
+ ** overload instead.
+ **
+ ** This function will fail if the socket is not connected.
+ **
+ ** @param data Pointer to the sequence of bytes to send
+ ** @param size Number of bytes to send
+ ** @return Status code
+ ** @see Receive */
+ virtual Status send( const void* data, std::size_t size );
+
+ /** @brief Send raw data to the remote peer
+ ** This function will fail if the socket is not connected.
+ ** @param data Pointer to the sequence of bytes to send
+ ** @param size Number of bytes to send
+ ** @param sent The number of bytes sent will be written here
+ ** @return Status code
+ ** @see receive */
+ virtual Status send( const void* data, std::size_t size, std::size_t& sent );
+
+ /** @brief Receive raw data from the remote peer
+ ** In blocking mode, this function will wait until some
+ ** bytes are actually received.
+ ** This function will fail if the socket is not connected.
+ ** @param data Pointer to the array to fill with the received bytes
+ ** @param size Maximum number of bytes that can be received
+ ** @param received This variable is filled with the actual number of bytes received
+ ** @return Status code
+ ** @see Send */
+ virtual Status receive( void* data, std::size_t size, std::size_t& received );
+
+ /** @brief Send a formatted packet of data to the remote peer
+ *
+ ** In non-blocking mode, if this function returns sf::Socket::Partial,
+ ** you \em must retry sending the same unmodified packet before sending
+ ** anything else in order to guarantee the packet arrives at the remote
+ ** peer uncorrupted.
+ **
+ ** This function will fail if the socket is not connected.
+ ** @param packet Packet to send
+ ** @return Status code
+ ** @see Receive */
+ virtual Status send( Packet& packet );
+
+ /** @brief Receive a formatted packet of data from the remote peer
+ ** In blocking mode, this function will wait until the whole packet
+ ** has been received.
+ ** This function will fail if the socket is not connected.
+ ** @param packet Packet to fill with the received data
+ ** @return Status code
+ ** @see Send */
+ virtual Status receive( Packet& packet );
+
+ /** Set the send timeout. Only callable after connect ( after the socket
+ ** has been initialized ). */
+ void setSendTimeout( const Time& timeout );
+
+ /** Set the receive timeout Only callable after connect ( after the socket
+ ** has been initialized ). */
+ void setReceiveTimeout( const Time& timeout );
+
+ typedef std::function ReadFn;
+
+ /** @brief Starts a new thread to receive all stdout and stderr data */
+ void startAsyncRead( ReadFn readFn = nullptr );
+
+ private:
+ friend class TcpListener;
+
+ /** @brief Structure holding the data of a pending packet */
+ struct PendingPacket {
+ PendingPacket();
+
+ Uint32 Size; ///< Data of packet size
+ std::size_t SizeReceived; ///< Number of size bytes received so far
+ std::vector Data; ///< Data of the packet
+ };
+
+ // Member data
+ PendingPacket mPendingPacket; ///< Temporary data of the packet currently being received
+ std::thread mReadThread;
+};
+
+}} // namespace EE::Network
+
+#endif // EE_NETWORKCTCPSOCKET_HPP
+
+/**
+@class EE::Network::TcpSocket
+
+TCP is a connected protocol, which means that a TCP
+socket can only communicate with the host it is connected
+to. It can't send or receive anything if it is not connected.
+
+The TCP protocol is reliable but adds a slight overhead.
+It ensures that your data will always be received in order
+and without errors (no data corrupted, lost or duplicated).
+
+When a socket is connected to a remote host, you can
+retrieve information about this host with the
+GetRemoteAddress and GetRemotePort functions. You can
+also get the local port to which the socket is bound
+(which is automatically chosen when the socket is connected),
+with the GetLocalPort function.
+
+Sending and receiving data can use either the low-level
+or the high-level functions. The low-level functions
+process a raw sequence of bytes, and cannot ensure that
+one call to Send will exactly match one call to Receive
+at the other end of the socket.
+
+The high-level interface uses packets (see Packet),
+which are easier to use and provide more safety regarding
+the data that is exchanged. You can look at the Packet
+class to get more details about how they work.
+
+The socket is automatically disconnected when it is destroyed,
+but if you want to explicitly close the connection while
+the socket instance is still alive, you can call disconnect.
+
+Usage example:
+@code
+// ----- The client -----
+
+// Create a socket and connect it to 192.168.1.50 on port 55001
+TcpSocket socket;
+socket.connect("192.168.1.50", 55001);
+
+// Send a message to the connected host
+std::string message = "Hi, I am a client";
+socket.send(message.c_str(), message.size() + 1);
+
+// Receive an answer from the server
+char buffer[1024];
+std::size_t received = 0;
+socket.receive(buffer, sizeof(buffer), received);
+std::cout << "The server said: " << buffer << std::endl;
+
+// ----- The server -----
+
+// Create a listener to wait for incoming connections on port 55001
+TcpListener listener;
+listener.listen(55001);
+
+// Wait for a connection
+TcpSocket socket;
+listener.accept(socket);
+std::cout << "New client connected: " << socket.getRemoteAddress() << std::endl;
+
+// Receive a message from the client
+char buffer[1024];
+std::size_t received = 0;
+socket.receive(buffer, sizeof(buffer), received);
+std::cout << "The client said: " << buffer << std::endl;
+
+// Send an answer
+std::string message = "Welcome, client";
+socket.send(message.c_str(), message.size() + 1);
+@endcode
+
+@see EE::Network::Socket, EE::Network::UdpSocket, EE::Network::Packet
+*/
diff --git a/include/eepp/network/uri.hpp b/include/eepp/network/uri.hpp
index ef8bce336..66c248d9d 100644
--- a/include/eepp/network/uri.hpp
+++ b/include/eepp/network/uri.hpp
@@ -1,7 +1,11 @@
#ifndef EE_NETWORK_URI_HPP
#define EE_NETWORK_URI_HPP
-#include
+#include
+#include
+#include
+#include
+#include
#include
namespace EE { namespace Network {
diff --git a/include/eepp/system/condition.hpp b/include/eepp/system/condition.hpp
index 85e8e26de..fa8612f55 100644
--- a/include/eepp/system/condition.hpp
+++ b/include/eepp/system/condition.hpp
@@ -1,7 +1,7 @@
#ifndef EE_SYSTEMCCONDITION_HPP
#define EE_SYSTEMCCONDITION_HPP
-#include
+#include
#include
namespace EE { namespace System {
diff --git a/include/eepp/system/filesystem.hpp b/include/eepp/system/filesystem.hpp
index e4a1c5e46..18c31a5e5 100644
--- a/include/eepp/system/filesystem.hpp
+++ b/include/eepp/system/filesystem.hpp
@@ -1,9 +1,11 @@
#ifndef EE_SYSTEM_FILESYSTEM_HPP
#define EE_SYSTEM_FILESYSTEM_HPP
-#include
+#include
+#include
#include
#include
+#include
#include
#include
diff --git a/include/eepp/system/log.hpp b/include/eepp/system/log.hpp
index 324774f1c..213442b3e 100644
--- a/include/eepp/system/log.hpp
+++ b/include/eepp/system/log.hpp
@@ -1,6 +1,7 @@
#ifndef EE_SYSTEM_LOG_H
#define EE_SYSTEM_LOG_H
+#include
#include
#include
#include
@@ -87,8 +88,7 @@ class EE_API Log : protected Mutex {
}
/** @brief Writes a formatted string to the log */
- template
- void writef( std::string_view format, Args&&... args ) {
+ template void writef( std::string_view format, Args&&... args ) {
auto result = String::format(
format, FormatArg>::get( std::forward( args ) )... );
write( result );
diff --git a/include/eepp/system/md5.hpp b/include/eepp/system/md5.hpp
index dc3daa171..c325bc3f6 100644
--- a/include/eepp/system/md5.hpp
+++ b/include/eepp/system/md5.hpp
@@ -1,9 +1,10 @@
#ifndef EE_SYSTEM_MD5_HPP
#define EE_SYSTEM_MD5_HPP
-#include
-#include
#include
+#include
+#include
+#include
namespace EE { namespace System {
diff --git a/include/eepp/system/mutex.hpp b/include/eepp/system/mutex.hpp
index 851eaa3a1..37247b45d 100644
--- a/include/eepp/system/mutex.hpp
+++ b/include/eepp/system/mutex.hpp
@@ -1,7 +1,7 @@
#ifndef EE_SYSTEMCMUTEX_H
#define EE_SYSTEMCMUTEX_H
-#include
+#include
#include
#include
diff --git a/include/eepp/system/pack.hpp b/include/eepp/system/pack.hpp
index 552d27405..261157e7a 100644
--- a/include/eepp/system/pack.hpp
+++ b/include/eepp/system/pack.hpp
@@ -5,6 +5,7 @@
#include
#include
#include