diff options
| author | Shawn Hoffman <godisgovernment@gmail.com> | 2009-05-08 17:04:11 +0000 |
|---|---|---|
| committer | Shawn Hoffman <godisgovernment@gmail.com> | 2009-05-08 17:04:11 +0000 |
| commit | 56398758b0628f9fcdd3e43b01cccea76cc3cfc8 (patch) | |
| tree | c34bd4d77692f204cf15ab2b92fb160a8082a061 | |
| parent | 79aa90b87615eec3a0fb95a0630493dc0697fbda (diff) | |
Add sfml network library. Hopefully this will make net-related coding a breeze :)
Note that as it is not used by anything yet, it has not yet been added as a dependency for any projects
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@3184 8ced0084-cf51-0410-be5f-012b33b47a6e
28 files changed, 6097 insertions, 0 deletions
diff --git a/Externals/SFML/build/vc2008/sfml-network.vcproj b/Externals/SFML/build/vc2008/sfml-network.vcproj new file mode 100644 index 0000000000..0562381715 --- /dev/null +++ b/Externals/SFML/build/vc2008/sfml-network.vcproj @@ -0,0 +1,395 @@ +<?xml version="1.0" encoding="Windows-1252"?>
+<VisualStudioProject
+ ProjectType="Visual C++"
+ Version="9.00"
+ Name="SFML_Network"
+ ProjectGUID="{823DDC98-42D5-4A38-88CF-9DC06C788AE4}"
+ RootNamespace="sfml-network"
+ Keyword="Win32Proj"
+ TargetFrameworkVersion="131072"
+ >
+ <Platforms>
+ <Platform
+ Name="Win32"
+ />
+ <Platform
+ Name="x64"
+ />
+ </Platforms>
+ <ToolFiles>
+ </ToolFiles>
+ <Configurations>
+ <Configuration
+ Name="Debug|Win32"
+ OutputDirectory="$(SolutionDir)..\..\Temp\vc2008\$(ProjectName)\$(ConfigurationName)"
+ IntermediateDirectory="$(SolutionDir)..\..\Temp\vc2008\$(ProjectName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ Description=""
+ CommandLine=""
+ Outputs=""
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""$(ProjectDir)..\..\src";"$(ProjectDir)..\..\include""
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;SFML_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="4"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalDependencies="ws2_32.lib"
+ OutputFile="$(SolutionDir)..\..\lib\vc2008\$(ProjectName)-s-d.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Debug|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ Description=""
+ CommandLine=""
+ Outputs=""
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="0"
+ AdditionalIncludeDirectories=""$(ProjectDir)..\..\src";"$(ProjectDir)..\..\include""
+ PreprocessorDefinitions="WIN32;_DEBUG;_LIB;SFML_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
+ MinimalRebuild="true"
+ BasicRuntimeChecks="3"
+ RuntimeLibrary="3"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="3"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalDependencies="ws2_32.lib"
+ OutputFile="$(SolutionDir)..\..\lib\vc2008\$(ProjectName)-s-d.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ CommandLine=""
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|Win32"
+ OutputDirectory="$(SolutionDir)..\..\Temp\vc2008\$(ProjectName)\$(ConfigurationName)"
+ IntermediateDirectory="$(SolutionDir)..\..\Temp\vc2008\$(ProjectName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ Description=""
+ CommandLine=""
+ Outputs=""
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ WholeProgramOptimization="false"
+ AdditionalIncludeDirectories=""$(ProjectDir)..\..\src";"$(ProjectDir)..\..\include""
+ PreprocessorDefinitions="NDEBUG;WIN32;_LIB;SFML_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalDependencies="ws2_32.lib"
+ OutputFile="$(SolutionDir)..\..\lib\vc2008\$(ProjectName)-s.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ <Configuration
+ Name="Release|x64"
+ OutputDirectory="$(SolutionDir)$(PlatformName)\$(ConfigurationName)"
+ IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
+ ConfigurationType="4"
+ CharacterSet="2"
+ WholeProgramOptimization="0"
+ >
+ <Tool
+ Name="VCPreBuildEventTool"
+ />
+ <Tool
+ Name="VCCustomBuildTool"
+ Description=""
+ CommandLine=""
+ Outputs=""
+ />
+ <Tool
+ Name="VCXMLDataGeneratorTool"
+ />
+ <Tool
+ Name="VCWebServiceProxyGeneratorTool"
+ />
+ <Tool
+ Name="VCMIDLTool"
+ TargetEnvironment="3"
+ />
+ <Tool
+ Name="VCCLCompilerTool"
+ Optimization="3"
+ InlineFunctionExpansion="2"
+ EnableIntrinsicFunctions="true"
+ FavorSizeOrSpeed="1"
+ WholeProgramOptimization="false"
+ AdditionalIncludeDirectories=""$(ProjectDir)..\..\src";"$(ProjectDir)..\..\include""
+ PreprocessorDefinitions="NDEBUG;WIN32;_LIB;SFML_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
+ StringPooling="true"
+ RuntimeLibrary="2"
+ BufferSecurityCheck="false"
+ EnableEnhancedInstructionSet="0"
+ FloatingPointModel="2"
+ UsePrecompiledHeader="0"
+ WarningLevel="4"
+ DebugInformationFormat="0"
+ />
+ <Tool
+ Name="VCManagedResourceCompilerTool"
+ />
+ <Tool
+ Name="VCResourceCompilerTool"
+ />
+ <Tool
+ Name="VCPreLinkEventTool"
+ />
+ <Tool
+ Name="VCLibrarianTool"
+ AdditionalDependencies="ws2_32.lib"
+ OutputFile="$(SolutionDir)..\..\lib\vc2008\$(ProjectName)-s.lib"
+ />
+ <Tool
+ Name="VCALinkTool"
+ />
+ <Tool
+ Name="VCXDCMakeTool"
+ />
+ <Tool
+ Name="VCBscMakeTool"
+ />
+ <Tool
+ Name="VCFxCopTool"
+ />
+ <Tool
+ Name="VCPostBuildEventTool"
+ />
+ </Configuration>
+ </Configurations>
+ <References>
+ </References>
+ <Files>
+ <Filter
+ Name="Win32"
+ >
+ <File
+ RelativePath="..\..\src\SFML\Network\Win32\SocketHelper.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\Win32\SocketHelper.hpp"
+ >
+ </File>
+ </Filter>
+ <File
+ RelativePath="..\..\src\SFML\Network\Ftp.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\SFML\Network\Ftp.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\Http.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\SFML\Network\Http.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\IPAddress.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\IPAddress.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\Packet.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\Packet.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\Selector.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\Selector.inl"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\SelectorBase.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\include\SFML\Network\SelectorBase.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\SocketHelper.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\SocketTCP.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\SocketTCP.hpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\SocketUDP.cpp"
+ >
+ </File>
+ <File
+ RelativePath="..\..\src\SFML\Network\SocketUDP.hpp"
+ >
+ </File>
+ </Files>
+ <Globals>
+ </Globals>
+</VisualStudioProject>
diff --git a/Externals/SFML/include/SFML/Config.hpp b/Externals/SFML/include/SFML/Config.hpp new file mode 100644 index 0000000000..86800e42aa --- /dev/null +++ b/Externals/SFML/include/SFML/Config.hpp @@ -0,0 +1,160 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_CONFIG_HPP
+#define SFML_CONFIG_HPP
+
+////////////////////////////////////////////////////////////
+// Identify the operating system
+////////////////////////////////////////////////////////////
+#if defined(_WIN32) || defined(__WIN32__)
+
+ // Windows
+ #define SFML_SYSTEM_WINDOWS
+ #ifndef WIN32_LEAN_AND_MEAN
+ #define WIN32_LEAN_AND_MEAN
+ #endif
+ #ifndef NOMINMAX
+ #define NOMINMAX
+ #endif
+
+#elif defined(linux) || defined(__linux)
+
+ // Linux
+ #define SFML_SYSTEM_LINUX
+
+#elif defined(__APPLE__) || defined(MACOSX) || defined(macintosh) || defined(Macintosh)
+
+ // MacOS
+ #define SFML_SYSTEM_MACOS
+
+#else
+
+ // Unsupported system
+ #error This operating system is not supported by SFML library
+
+#endif
+
+
+////////////////////////////////////////////////////////////
+// Define a portable debug macro
+////////////////////////////////////////////////////////////
+#if !defined(NDEBUG)
+
+ #define SFML_DEBUG
+
+#endif
+
+
+////////////////////////////////////////////////////////////
+// Define portable import / export macros
+////////////////////////////////////////////////////////////
+#if defined(SFML_SYSTEM_WINDOWS)
+
+ #ifdef SFML_DYNAMIC
+
+ // Windows platforms
+ #ifdef SFML_EXPORTS
+
+ // From DLL side, we must export
+ #define SFML_API __declspec(dllexport)
+
+ #else
+
+ // From client application side, we must import
+ #define SFML_API __declspec(dllimport)
+
+ #endif
+
+ // For Visual C++ compilers, we also need to turn off this annoying C4251 warning.
+ // You can read lots ot different things about it, but the point is the code will
+ // just work fine, and so the simplest way to get rid of this warning is to disable it
+ #ifdef _MSC_VER
+
+ #pragma warning(disable : 4251)
+
+ #endif
+
+ #else
+
+ // No specific directive needed for static build
+ #define SFML_API
+
+ #endif
+
+#else
+
+ // Other platforms don't need to define anything
+ #define SFML_API
+
+#endif
+
+
+////////////////////////////////////////////////////////////
+// Define portable fixed-size types
+////////////////////////////////////////////////////////////
+#include <climits>
+
+namespace sf
+{
+ // 8 bits integer types
+ #if UCHAR_MAX == 0xFF
+ typedef signed char Int8;
+ typedef unsigned char Uint8;
+ #else
+ #error No 8 bits integer type for this platform
+ #endif
+
+ // 16 bits integer types
+ #if USHRT_MAX == 0xFFFF
+ typedef signed short Int16;
+ typedef unsigned short Uint16;
+ #elif UINT_MAX == 0xFFFF
+ typedef signed int Int16;
+ typedef unsigned int Uint16;
+ #elif ULONG_MAX == 0xFFFF
+ typedef signed long Int16;
+ typedef unsigned long Uint16;
+ #else
+ #error No 16 bits integer type for this platform
+ #endif
+
+ // 32 bits integer types
+ #if USHRT_MAX == 0xFFFFFFFF
+ typedef signed short Int32;
+ typedef unsigned short Uint32;
+ #elif UINT_MAX == 0xFFFFFFFF
+ typedef signed int Int32;
+ typedef unsigned int Uint32;
+ #elif ULONG_MAX == 0xFFFFFFFF
+ typedef signed long Int32;
+ typedef unsigned long Uint32;
+ #else
+ #error No 32 bits integer type for this platform
+ #endif
+
+} // namespace sf
+
+
+#endif // SFML_CONFIG_HPP
diff --git a/Externals/SFML/include/SFML/Network.hpp b/Externals/SFML/include/SFML/Network.hpp new file mode 100644 index 0000000000..fe1730ad62 --- /dev/null +++ b/Externals/SFML/include/SFML/Network.hpp @@ -0,0 +1,42 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_NETWORK_HPP
+#define SFML_NETWORK_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+
+#include <SFML/System.hpp>
+#include <SFML/Network/Ftp.hpp>
+#include <SFML/Network/Http.hpp>
+#include <SFML/Network/IPAddress.hpp>
+#include <SFML/Network/Packet.hpp>
+#include <SFML/Network/Selector.hpp>
+#include <SFML/Network/SocketTCP.hpp>
+#include <SFML/Network/SocketUDP.hpp>
+
+
+#endif // SFML_NETWORK_HPP
diff --git a/Externals/SFML/include/SFML/Network/Ftp.hpp b/Externals/SFML/include/SFML/Network/Ftp.hpp new file mode 100644 index 0000000000..673b9048c9 --- /dev/null +++ b/Externals/SFML/include/SFML/Network/Ftp.hpp @@ -0,0 +1,448 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_FTP_HPP
+#define SFML_FTP_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/System/NonCopyable.hpp>
+#include <SFML/Network/SocketTCP.hpp>
+#include <string>
+#include <vector>
+
+
+namespace sf
+{
+class IPAddress;
+
+////////////////////////////////////////////////////////////
+/// This class provides methods for manipulating the FTP
+/// protocol (described in RFC 959).
+/// It provides easy access and transfers to remote
+/// directories and files on a FTP server
+////////////////////////////////////////////////////////////
+class SFML_API Ftp : NonCopyable
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Enumeration of transfer modes
+ ////////////////////////////////////////////////////////////
+ enum TransferMode
+ {
+ Binary, ///< Binary mode (file is transfered as a sequence of bytes)
+ Ascii, ///< Text mode using ASCII encoding
+ Ebcdic ///< Text mode using EBCDIC encoding
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// This class wraps a FTP response, which is basically :
+ /// - a status code
+ /// - a message
+ ////////////////////////////////////////////////////////////
+ class SFML_API Response
+ {
+ public :
+
+ ////////////////////////////////////////////////////////////
+ /// Enumerate all the valid status codes returned in
+ /// 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: SFML 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
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ /// \param Code : Response status code (InvalidResponse by default)
+ /// \param Message : Response message (empty by default)
+ ///
+ ////////////////////////////////////////////////////////////
+ Response(Status Code = InvalidResponse, const std::string& Message = "");
+
+ ////////////////////////////////////////////////////////////
+ /// Convenience function to check if the response status code
+ /// means a success
+ ///
+ /// \return True if status is success (code < 400)
+ ///
+ ////////////////////////////////////////////////////////////
+ bool IsOk() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the response status code
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Status GetStatus() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the full message contained in the response
+ ///
+ /// \return The response message
+ ///
+ ////////////////////////////////////////////////////////////
+ const std::string& GetMessage() const;
+
+ private :
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ Status myStatus; ///< Status code returned from the server
+ std::string myMessage; ///< Last message received from the server
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// Specialization of FTP response returning a directory
+ ////////////////////////////////////////////////////////////
+ class SFML_API DirectoryResponse : public Response
+ {
+ public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ /// \param Resp : Source response
+ ///
+ ////////////////////////////////////////////////////////////
+ DirectoryResponse(Response Resp);
+
+ ////////////////////////////////////////////////////////////
+ /// Get the directory returned in the response
+ ///
+ /// \return Directory name
+ ///
+ ////////////////////////////////////////////////////////////
+ const std::string& GetDirectory() const;
+
+ private :
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ std::string myDirectory; ///< Directory extracted from the response message
+ };
+
+
+ ////////////////////////////////////////////////////////////
+ /// Specialization of FTP response returning a filename lisiting
+ ////////////////////////////////////////////////////////////
+ class SFML_API ListingResponse : public Response
+ {
+ public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ /// \param Resp : Source response
+ /// \param Data : Data containing the raw listing
+ ///
+ ////////////////////////////////////////////////////////////
+ ListingResponse(Response Resp, const std::vector<char>& Data);
+
+ ////////////////////////////////////////////////////////////
+ /// Get the number of filenames in the listing
+ ///
+ /// \return Total number of filenames
+ ///
+ ////////////////////////////////////////////////////////////
+ std::size_t GetCount() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the Index-th filename in the directory
+ ///
+ /// \param Index : Index of the filename to get
+ ///
+ /// \return Index-th filename
+ ///
+ ////////////////////////////////////////////////////////////
+ const std::string& GetFilename(std::size_t Index) const;
+
+ private :
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ std::vector<std::string> myFilenames; ///< Filenames extracted from the data
+ };
+
+
+ ////////////////////////////////////////////////////////////
+ /// Destructor -- close the connection with the server
+ ///
+ ////////////////////////////////////////////////////////////
+ ~Ftp();
+
+ ////////////////////////////////////////////////////////////
+ /// Connect to the specified FTP server
+ ///
+ /// \param Server : FTP server to connect to
+ /// \param Port : Port used for connection (21 by default, standard FTP port)
+ /// \param Timeout : Maximum time to wait, in seconds (0 by default, means no timeout)
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response Connect(const IPAddress& Server, unsigned short Port = 21, float Timeout = 0.f);
+
+ ////////////////////////////////////////////////////////////
+ /// Log in using anonymous account
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response Login();
+
+ ////////////////////////////////////////////////////////////
+ /// Log in using a username and a password
+ ///
+ /// \param UserName : User name
+ /// \param Password : Password
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response Login(const std::string& UserName, const std::string& Password);
+
+ ////////////////////////////////////////////////////////////
+ /// Close the connection with FTP server
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response Disconnect();
+
+ ////////////////////////////////////////////////////////////
+ /// Send a null command just to prevent from being disconnected
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response KeepAlive();
+
+ ////////////////////////////////////////////////////////////
+ /// Get the current working directory
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ DirectoryResponse GetWorkingDirectory();
+
+ ////////////////////////////////////////////////////////////
+ /// Get the contents of the given directory
+ /// (subdirectories and files)
+ ///
+ /// \param Directory : Directory to list ("" by default, the current one)
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ ListingResponse GetDirectoryListing(const std::string& Directory = "");
+
+ ////////////////////////////////////////////////////////////
+ /// Change the current working directory
+ ///
+ /// \param Directory : New directory, relative to the current one
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response ChangeDirectory(const std::string& Directory);
+
+ ////////////////////////////////////////////////////////////
+ /// Go to the parent directory of the current one
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response ParentDirectory();
+
+ ////////////////////////////////////////////////////////////
+ /// Create a new directory
+ ///
+ /// \param Name : Name of the directory to create
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response MakeDirectory(const std::string& Name);
+
+ ////////////////////////////////////////////////////////////
+ /// Remove an existing directory
+ ///
+ /// \param Name : Name of the directory to remove
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response DeleteDirectory(const std::string& Name);
+
+ ////////////////////////////////////////////////////////////
+ /// Rename a file
+ ///
+ /// \param File : File to rename
+ /// \param NewName : New name
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response RenameFile(const std::string& File, const std::string& NewName);
+
+ ////////////////////////////////////////////////////////////
+ /// Remove an existing file
+ ///
+ /// \param Name : File to remove
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response DeleteFile(const std::string& Name);
+
+ ////////////////////////////////////////////////////////////
+ /// Download a file from the server
+ ///
+ /// \param DistantFile : Path of the distant file to download
+ /// \param DestPath : Where to put to file on the local computer
+ /// \param Mode : Transfer mode (binary by default)
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response Download(const std::string& DistantFile, const std::string& DestPath, TransferMode Mode = Binary);
+
+ ////////////////////////////////////////////////////////////
+ /// Upload a file to the server
+ ///
+ /// \param LocalFile : Path of the local file to upload
+ /// \param DestPath : Where to put to file on the server
+ /// \param Mode : Transfer mode (binary by default)
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response Upload(const std::string& LocalFile, const std::string& DestPath, TransferMode Mode = Binary);
+
+private :
+
+ ////////////////////////////////////////////////////////////
+ /// Send a command to the FTP server
+ ///
+ /// \param Command : Command to send
+ /// \param Parameter : Command parameter ("" by default)
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response SendCommand(const std::string& Command, const std::string& Parameter = "");
+
+ ////////////////////////////////////////////////////////////
+ /// Receive a response from the server
+ /// (usually after a command has been sent)
+ ///
+ /// \return Server response to the request
+ ///
+ ////////////////////////////////////////////////////////////
+ Response GetResponse();
+
+ ////////////////////////////////////////////////////////////
+ /// Utility class for exchanging datas with the server
+ /// on the data channel
+ ////////////////////////////////////////////////////////////
+ class DataChannel;
+
+ friend class DataChannel;
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ SocketTCP myCommandSocket; ///< Socket holding the control connection with the server
+};
+
+} // namespace sf
+
+
+#endif // SFML_FTP_HPP
diff --git a/Externals/SFML/include/SFML/Network/Http.hpp b/Externals/SFML/include/SFML/Network/Http.hpp new file mode 100644 index 0000000000..3e02531fb8 --- /dev/null +++ b/Externals/SFML/include/SFML/Network/Http.hpp @@ -0,0 +1,339 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_HTTP_HPP
+#define SFML_HTTP_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/System/NonCopyable.hpp>
+#include <SFML/Network/IPAddress.hpp>
+#include <SFML/Network/SocketTCP.hpp>
+#include <map>
+#include <string>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// This class provides methods for manipulating the HTTP
+/// protocol (described in RFC 1945).
+/// It can connect to a website, get its files, send requests, etc.
+////////////////////////////////////////////////////////////
+class SFML_API Http : NonCopyable
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// This class wraps an HTTP request, which is basically :
+ /// - a header with a method, a target URI, and a set of field/value pairs
+ /// - an optional body (for POST requests)
+ ////////////////////////////////////////////////////////////
+ class SFML_API Request
+ {
+ public :
+
+ ////////////////////////////////////////////////////////////
+ /// Enumerate the available HTTP methods for a request
+ ////////////////////////////////////////////////////////////
+ enum Method
+ {
+ Get, ///< Request in get mode, standard method to retrieve a page
+ Post, ///< Request in post mode, usually to send data to a page
+ Head ///< Request a page's header only
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ /// \param RequestMethod : Method to use for the request (Get by default)
+ /// \param URI : Target URI ("/" by default -- index page)
+ /// \param Body : Content of the request's body (empty by default)
+ ///
+ ////////////////////////////////////////////////////////////
+ Request(Method RequestMethod = Get, const std::string& URI = "/", const std::string& Body = "");
+
+ ////////////////////////////////////////////////////////////
+ /// Set the value of a field; the field is added if it doesn't exist
+ ///
+ /// \param Field : Name of the field to set (case-insensitive)
+ /// \param Value : Value of the field
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetField(const std::string& Field, const std::string& Value);
+
+ ////////////////////////////////////////////////////////////
+ /// Set the request method.
+ /// This parameter is Http::Request::Get by default
+ ///
+ /// \param RequestMethod : Method to use for the request
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetMethod(Method RequestMethod);
+
+ ////////////////////////////////////////////////////////////
+ /// Set the target URI of the request.
+ /// This parameter is "/" by default
+ ///
+ /// \param URI : URI to request, local to the host
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetURI(const std::string& URI);
+
+ ////////////////////////////////////////////////////////////
+ /// Set the HTTP version of the request.
+ /// This parameter is 1.0 by default
+ ///
+ /// \param Major : Major version number
+ /// \param Minor : Minor version number
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetHttpVersion(unsigned int Major, unsigned int Minor);
+
+ ////////////////////////////////////////////////////////////
+ /// Set the body of the request. This parameter is optional and
+ /// makes sense only for POST requests.
+ /// This parameter is empty by default
+ ///
+ /// \param Body : Content of the request body
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetBody(const std::string& Body);
+
+ private :
+
+ friend class Http;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the string representation of the request header
+ ///
+ /// \return String containing the request
+ ///
+ ////////////////////////////////////////////////////////////
+ std::string ToString() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Check if the given field has been defined
+ ///
+ /// \param Field : Name of the field to check (case-insensitive)
+ ///
+ /// \return True if the field exists
+ ///
+ ////////////////////////////////////////////////////////////
+ bool HasField(const std::string& Field) const;
+
+ ////////////////////////////////////////////////////////////
+ // Types
+ ////////////////////////////////////////////////////////////
+ typedef std::map<std::string, std::string> FieldTable;
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ FieldTable myFields; ///< Fields of the header
+ Method myMethod; ///< Method to use for the request
+ std::string myURI; ///< Target URI of the request
+ unsigned int myMajorVersion; ///< Major HTTP version
+ unsigned int myMinorVersion; ///< Minor HTTP version
+ std::string myBody; ///< Body of the request
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// This class wraps an HTTP response, which is basically :
+ /// - a header with a status code and a set of field/value pairs
+ /// - a body (the content of the requested resource)
+ ////////////////////////////////////////////////////////////
+ class SFML_API Response
+ {
+ public :
+
+ ////////////////////////////////////////////////////////////
+ /// Enumerate all the valid status codes returned in
+ /// a HTTP response
+ ////////////////////////////////////////////////////////////
+ enum Status
+ {
+ // 2xx: success
+ Ok = 200, ///< Most common code returned when operation was successful
+ Created = 201, ///< The resource has successfully been created
+ Accepted = 202, ///< The request has been accepted, but will be processed later by the server
+ NoContent = 204, ///< Sent when the server didn't send any data in return
+
+ // 3xx: redirection
+ MultipleChoices = 300, ///< The requested page can be accessed from several locations
+ MovedPermanently = 301, ///< The requested page has permanently moved to a new location
+ MovedTemporarily = 302, ///< The requested page has temporarily moved to a new location
+ NotModified = 304, ///< For conditionnal requests, means the requested page hasn't changed and doesn't need to be refreshed
+
+ // 4xx: client error
+ BadRequest = 400, ///< The server couldn't understand the request (syntax error)
+ Unauthorized = 401, ///< The requested page needs an authentification to be accessed
+ Forbidden = 403, ///< The requested page cannot be accessed at all, even with authentification
+ NotFound = 404, ///< The requested page doesn't exist
+
+ // 5xx: server error
+ InternalServerError = 500, ///< The server encountered an unexpected error
+ NotImplemented = 501, ///< The server doesn't implement a requested feature
+ BadGateway = 502, ///< The gateway server has received an error from the source server
+ ServiceNotAvailable = 503, ///< The server is temporarily unavailable (overloaded, in maintenance, ...)
+
+ // 10xx: SFML custom codes
+ InvalidResponse = 1000, ///< Response is not a valid HTTP one
+ ConnectionFailed = 1001 ///< Connection with server failed
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ ////////////////////////////////////////////////////////////
+ Response();
+
+ ////////////////////////////////////////////////////////////
+ /// Get the value of a field
+ ///
+ /// \param Field : Name of the field to get (case-insensitive)
+ ///
+ /// \return Value of the field, or empty string if not found
+ ///
+ ////////////////////////////////////////////////////////////
+ const std::string& GetField(const std::string& Field) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the header's status code
+ ///
+ /// \return Header's status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Status GetStatus() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the major HTTP version number of the response
+ ///
+ /// \return Major version number
+ ///
+ ////////////////////////////////////////////////////////////
+ unsigned int GetMajorHttpVersion() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the major HTTP version number of the response
+ ///
+ /// \return Major version number
+ ///
+ ////////////////////////////////////////////////////////////
+ unsigned int GetMinorHttpVersion() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the body of the response. The body can contain :
+ /// - the requested page (for GET requests)
+ /// - a response from the server (for POST requests)
+ /// - nothing (for HEAD requests)
+ /// - an error message (in case of an error)
+ ///
+ /// \return The response body
+ ///
+ ////////////////////////////////////////////////////////////
+ const std::string& GetBody() const;
+
+ private :
+
+ friend class Http;
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the header from a response string
+ ///
+ /// \param Data : Content of the response's header to parse
+ ///
+ ////////////////////////////////////////////////////////////
+ void FromString(const std::string& Data);
+
+ ////////////////////////////////////////////////////////////
+ // Types
+ ////////////////////////////////////////////////////////////
+ typedef std::map<std::string, std::string> FieldTable;
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ FieldTable myFields; ///< Fields of the header
+ Status myStatus; ///< Status code
+ unsigned int myMajorVersion; ///< Major HTTP version
+ unsigned int myMinorVersion; ///< Minor HTTP version
+ std::string myBody; ///< Body of the response
+ };
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ ////////////////////////////////////////////////////////////
+ Http();
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the Http instance with the target host
+ ///
+ /// \param Host : Web server to connect to
+ /// \param Port : Port to use for connection (0 by default -- use the standard port of the protocol used)
+ ///
+ ////////////////////////////////////////////////////////////
+ Http(const std::string& Host, unsigned short Port = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// Set the target host
+ ///
+ /// \param Host : Web server to connect to
+ /// \param Port : Port to use for connection (0 by default -- use the standard port of the protocol used)
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetHost(const std::string& Host, unsigned short Port = 0);
+
+ ////////////////////////////////////////////////////////////
+ /// Send a HTTP request and return the server's response.
+ /// You must be connected to a host before sending requests.
+ /// Any missing mandatory header field will be added with an appropriate value.
+ /// Warning : this function waits for the server's response and may
+ /// not return instantly; use a thread if you don't want to block your
+ /// application.
+ ///
+ /// \param Req : Request to send
+ ///
+ /// \return Server's response
+ ///
+ ////////////////////////////////////////////////////////////
+ Response SendRequest(const Request& Req);
+
+private :
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ SocketTCP myConnection; ///< Connection to the host
+ IPAddress myHost; ///< Web host address
+ std::string myHostName; ///< Web host name
+ unsigned short myPort; ///< Port used for connection with host
+};
+
+} // namespace sf
+
+
+#endif // SFML_HTTP_HPP
diff --git a/Externals/SFML/include/SFML/Network/IPAddress.hpp b/Externals/SFML/include/SFML/Network/IPAddress.hpp new file mode 100644 index 0000000000..8373315228 --- /dev/null +++ b/Externals/SFML/include/SFML/Network/IPAddress.hpp @@ -0,0 +1,229 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_IPADDRESS_HPP
+#define SFML_IPADDRESS_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+#include <istream>
+#include <ostream>
+#include <string>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// IPAddress provides easy manipulation of IP v4 addresses
+////////////////////////////////////////////////////////////
+class SFML_API IPAddress
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor -- constructs an invalid address
+ ///
+ ////////////////////////////////////////////////////////////
+ IPAddress();
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the address from a string
+ ///
+ /// \param Address : IP address ("xxx.xxx.xxx.xxx") or network name
+ ///
+ ////////////////////////////////////////////////////////////
+ IPAddress(const std::string& Address);
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the address from a C-style string ;
+ /// Needed for implicit conversions from literal strings to IPAddress to work
+ ///
+ /// \param Address : IP address ("xxx.xxx.xxx.xxx") or network name
+ ///
+ ////////////////////////////////////////////////////////////
+ IPAddress(const char* Address);
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the address from 4 bytes
+ ///
+ /// \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);
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the address from a 32-bits integer
+ ///
+ /// \param Address : 4 bytes of the address packed into a 32-bits integer
+ ///
+ ////////////////////////////////////////////////////////////
+ IPAddress(Uint32 Address);
+
+ ////////////////////////////////////////////////////////////
+ /// Tell if the address is a valid one
+ ///
+ /// \return True if address has a valid syntax
+ ///
+ ////////////////////////////////////////////////////////////
+ bool IsValid() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get a string representation of the address
+ ///
+ /// \return String representation of the IP address ("xxx.xxx.xxx.xxx")
+ ///
+ ////////////////////////////////////////////////////////////
+ std::string ToString() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get an integer representation of the address
+ ///
+ /// \return 32-bits integer containing the 4 bytes of the address, in system endianness
+ ///
+ ////////////////////////////////////////////////////////////
+ Uint32 ToInteger() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the computer's local IP address (from the LAN point of view)
+ ///
+ /// \return Local IP address
+ ///
+ ////////////////////////////////////////////////////////////
+ static IPAddress GetLocalAddress();
+
+ ////////////////////////////////////////////////////////////
+ /// Get the computer's public IP address (from the web point of view).
+ /// The only way to get a public address is to ask it to a
+ /// distant website ; as a consequence, this function may be
+ /// very slow -- use it as few as possible !
+ ///
+ /// \return Public IP address
+ ///
+ ////////////////////////////////////////////////////////////
+ static IPAddress GetPublicAddress();
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator ==
+ ///
+ /// \param Other : Address to compare
+ ///
+ /// \return True if *this == Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator ==(const IPAddress& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator !=
+ ///
+ /// \param Other : Address to compare
+ ///
+ /// \return True if *this != Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator !=(const IPAddress& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator <
+ ///
+ /// \param Other : Address to compare
+ ///
+ /// \return True if *this < Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator <(const IPAddress& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator >
+ ///
+ /// \param Other : Address to compare
+ ///
+ /// \return True if *this > Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator >(const IPAddress& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator <=
+ ///
+ /// \param Other : Address to compare
+ ///
+ /// \return True if *this <= Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator <=(const IPAddress& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator >=
+ ///
+ /// \param Other : Address to compare
+ ///
+ /// \return True if *this >= Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator >=(const IPAddress& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ // Static member data
+ ////////////////////////////////////////////////////////////
+ static const IPAddress LocalHost; ///< Local host address (to connect to the same computer)
+
+private :
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ Uint32 myAddress; ///< Address stored as an unsigned 32 bits integer
+};
+
+////////////////////////////////////////////////////////////
+/// Operator >> overload to extract an address from an input stream
+///
+/// \param Stream : Input stream
+/// \param Address : Address to extract
+///
+/// \return Reference to the input stream
+///
+////////////////////////////////////////////////////////////
+SFML_API std::istream& operator >>(std::istream& Stream, IPAddress& Address);
+
+////////////////////////////////////////////////////////////
+/// Operator << overload to print an address to an output stream
+///
+/// \param Stream : Output stream
+/// \param Address : Address to print
+///
+/// \return Reference to the output stream
+///
+////////////////////////////////////////////////////////////
+SFML_API std::ostream& operator <<(std::ostream& Stream, const IPAddress& Address);
+
+} // namespace sf
+
+
+#endif // SFML_IPADDRESS_HPP
diff --git a/Externals/SFML/include/SFML/Network/Packet.hpp b/Externals/SFML/include/SFML/Network/Packet.hpp new file mode 100644 index 0000000000..3add17ffcc --- /dev/null +++ b/Externals/SFML/include/SFML/Network/Packet.hpp @@ -0,0 +1,187 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_PACKET_HPP
+#define SFML_PACKET_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+#include <string>
+#include <vector>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Packet wraps data to send / to receive through the network
+////////////////////////////////////////////////////////////
+class SFML_API Packet
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ ////////////////////////////////////////////////////////////
+ Packet();
+
+ ////////////////////////////////////////////////////////////
+ /// Virtual destructor
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual ~Packet();
+
+ ////////////////////////////////////////////////////////////
+ /// Append data to the end of the packet
+ ///
+ /// \param Data : Pointer to the bytes to append
+ /// \param SizeInBytes : Number of bytes to append
+ ///
+ ////////////////////////////////////////////////////////////
+ void Append(const void* Data, std::size_t SizeInBytes);
+
+ ////////////////////////////////////////////////////////////
+ /// Clear the packet data
+ ///
+ ////////////////////////////////////////////////////////////
+ void Clear();
+
+ ////////////////////////////////////////////////////////////
+ /// Get a pointer to the data contained in the packet
+ /// Warning : the returned pointer may be invalid after you
+ /// append data to the packet
+ ///
+ /// \return Pointer to the data
+ ///
+ ////////////////////////////////////////////////////////////
+ const char* GetData() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the size of the data contained in the packet
+ ///
+ /// \return Data size, in bytes
+ ///
+ ////////////////////////////////////////////////////////////
+ std::size_t GetDataSize() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Tell if the reading position has reached the end of the packet
+ ///
+ /// \return True if all data have been read into the packet
+ ///
+ ////////////////////////////////////////////////////////////
+ bool EndOfPacket() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Return the validity of packet
+ ///
+ /// \return True if last data extraction from packet was successful
+ ///
+ ////////////////////////////////////////////////////////////
+ operator bool() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Operator >> overloads to extract data from the packet
+ ///
+ ////////////////////////////////////////////////////////////
+ Packet& operator >>(bool& Data);
+ Packet& operator >>(Int8& Data);
+ Packet& operator >>(Uint8& Data);
+ Packet& operator >>(Int16& Data);
+ Packet& operator >>(Uint16& Data);
+ Packet& operator >>(Int32& Data);
+ Packet& operator >>(Uint32& Data);
+ Packet& operator >>(float& Data);
+ Packet& operator >>(double& Data);
+ Packet& operator >>(char* Data);
+ Packet& operator >>(std::string& Data);
+ Packet& operator >>(wchar_t* Data);
+ Packet& operator >>(std::wstring& Data);
+
+ ////////////////////////////////////////////////////////////
+ /// Operator << overloads to put data into the packet
+ ///
+ ////////////////////////////////////////////////////////////
+ Packet& operator <<(bool Data);
+ Packet& operator <<(Int8 Data);
+ Packet& operator <<(Uint8 Data);
+ Packet& operator <<(Int16 Data);
+ Packet& operator <<(Uint16 Data);
+ Packet& operator <<(Int32 Data);
+ Packet& operator <<(Uint32 Data);
+ Packet& operator <<(float Data);
+ Packet& operator <<(double Data);
+ Packet& operator <<(const char* Data);
+ Packet& operator <<(const std::string& Data);
+ Packet& operator <<(const wchar_t* Data);
+ Packet& operator <<(const std::wstring& Data);
+
+private :
+
+ friend class SocketTCP;
+ friend class SocketUDP;
+
+ ////////////////////////////////////////////////////////////
+ /// Check if the packet can extract a given size of bytes
+ ///
+ /// \param Size : Size to check
+ ///
+ /// \return True if Size bytes can be read from the packet's data
+ ///
+ ////////////////////////////////////////////////////////////
+ bool CheckSize(std::size_t Size);
+
+ ////////////////////////////////////////////////////////////
+ /// Called before the packet is sent to the network
+ ///
+ /// \param DataSize : Variable to fill with the size of data to send
+ ///
+ /// \return Pointer to the array of bytes to send
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual const char* OnSend(std::size_t& DataSize);
+
+ ////////////////////////////////////////////////////////////
+ /// Called after the packet has been received from the network
+ ///
+ /// \param Data : Pointer to the array of received bytes
+ /// \param DataSize : Size of the array of bytes
+ ///
+ ////////////////////////////////////////////////////////////
+ virtual void OnReceive(const char* Data, std::size_t DataSize);
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ std::vector<char> myData; ///< Data stored in the packet
+ std::size_t myReadPos; ///< Current reading position in the packet
+ bool myIsValid; ///< Reading state of the packet
+};
+
+} // namespace sf
+
+
+#endif // SFML_PACKET_HPP
diff --git a/Externals/SFML/include/SFML/Network/Selector.hpp b/Externals/SFML/include/SFML/Network/Selector.hpp new file mode 100644 index 0000000000..3ab7dfaa70 --- /dev/null +++ b/Externals/SFML/include/SFML/Network/Selector.hpp @@ -0,0 +1,116 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SELECTOR_HPP
+#define SFML_SELECTOR_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/SocketUDP.hpp>
+#include <SFML/Network/SocketTCP.hpp>
+#include <SFML/Network/SelectorBase.hpp>
+#include <map>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Selector allow reading from multiple sockets
+/// without blocking. It's a kind of multiplexer
+////////////////////////////////////////////////////////////
+template <typename Type>
+class Selector : private SelectorBase
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Add a socket to watch
+ ///
+ /// \param Socket : Socket to add
+ ///
+ ////////////////////////////////////////////////////////////
+ void Add(Type Socket);
+
+ ////////////////////////////////////////////////////////////
+ /// Remove a socket
+ ///
+ /// \param Socket : Socket to remove
+ ///
+ ////////////////////////////////////////////////////////////
+ void Remove(Type Socket);
+
+ ////////////////////////////////////////////////////////////
+ /// Remove all sockets
+ ///
+ ////////////////////////////////////////////////////////////
+ void Clear();
+
+ ////////////////////////////////////////////////////////////
+ /// Wait and collect sockets which are ready for reading.
+ /// This functions will return either when at least one socket
+ /// is ready, or when the given time is out
+ ///
+ /// \param Timeout : Timeout, in seconds (0 by default : no timeout)
+ ///
+ /// \return Number of sockets ready to be read
+ ///
+ ////////////////////////////////////////////////////////////
+ unsigned int Wait(float Timeout = 0.f);
+
+ ////////////////////////////////////////////////////////////
+ /// After a call to Wait(), get the Index-th socket which is
+ /// ready for reading. The total number of sockets ready
+ /// is the integer returned by the previous call to Wait()
+ ///
+ /// \param Index : Index of the socket to get
+ ///
+ /// \return The Index-th socket
+ ///
+ ////////////////////////////////////////////////////////////
+ Type GetSocketReady(unsigned int Index);
+
+private :
+
+ ////////////////////////////////////////////////////////////
+ // Types
+ ////////////////////////////////////////////////////////////
+ typedef std::map<SocketHelper::SocketType, Type> SocketTable;
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ SocketTable mySockets; ///< Table matching the SFML socket instances with their low-level handles
+};
+
+#include <SFML/Network/Selector.inl>
+
+// Let's define the two only valid types of Selector
+typedef Selector<SocketUDP> SelectorUDP;
+typedef Selector<SocketTCP> SelectorTCP;
+
+} // namespace sf
+
+
+#endif // SFML_SELECTOR_HPP
diff --git a/Externals/SFML/include/SFML/Network/Selector.inl b/Externals/SFML/include/SFML/Network/Selector.inl new file mode 100644 index 0000000000..326c994602 --- /dev/null +++ b/Externals/SFML/include/SFML/Network/Selector.inl @@ -0,0 +1,97 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////
+/// Add a socket to watch
+////////////////////////////////////////////////////////////
+template <typename Type>
+void Selector<Type>::Add(Type Socket)
+{
+ if (Socket.IsValid())
+ {
+ SelectorBase::Add(Socket.mySocket);
+ mySockets[Socket.mySocket] = Socket;
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Remove a socket
+////////////////////////////////////////////////////////////
+template <typename Type>
+void Selector<Type>::Remove(Type Socket)
+{
+ typename SocketTable::iterator It = mySockets.find(Socket.mySocket);
+ if (It != mySockets.end())
+ {
+ SelectorBase::Remove(Socket.mySocket);
+ mySockets.erase(It);
+ }
+}
+
+
+////////////////////////////////////////////////////////////
+/// Remove all sockets
+////////////////////////////////////////////////////////////
+template <typename Type>
+void Selector<Type>::Clear()
+{
+ SelectorBase::Clear();
+ mySockets.clear();
+}
+
+
+////////////////////////////////////////////////////////////
+/// Wait and collect sockets which are ready for reading.
+/// This functions will return either when at least one socket
+/// is ready, or when the given time is out
+////////////////////////////////////////////////////////////
+template <typename Type>
+unsigned int Selector<Type>::Wait(float Timeout)
+{
+ // No socket in the selector : return 0
+ if (mySockets.empty())
+ return 0;
+
+ return SelectorBase::Wait(Timeout);
+}
+
+
+////////////////////////////////////////////////////////////
+/// After a call to Wait(), get the Index-th socket which is
+/// ready for reading. The total number of sockets ready
+/// is the integer returned by the previous call to Wait()
+////////////////////////////////////////////////////////////
+template <typename Type>
+Type Selector<Type>::GetSocketReady(unsigned int Index)
+{
+ SocketHelper::SocketType Socket = SelectorBase::GetSocketReady(Index);
+
+ typename SocketTable::const_iterator It = mySockets.find(Socket);
+ if (It != mySockets.end())
+ return It->second;
+ else
+ return Type(Socket);
+}
diff --git a/Externals/SFML/include/SFML/Network/SelectorBase.hpp b/Externals/SFML/include/SFML/Network/SelectorBase.hpp new file mode 100644 index 0000000000..433e7893c4 --- /dev/null +++ b/Externals/SFML/include/SFML/Network/SelectorBase.hpp @@ -0,0 +1,112 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SELECTORBASE_HPP
+#define SFML_SELECTORBASE_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+#include <SFML/Network/SocketHelper.hpp>
+#include <map>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Private base class for selectors.
+/// As Selector is a template class, this base is needed so that
+/// every system call get compiled in SFML (not inlined)
+////////////////////////////////////////////////////////////
+class SFML_API SelectorBase
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ ////////////////////////////////////////////////////////////
+ SelectorBase();
+
+ ////////////////////////////////////////////////////////////
+ /// Add a socket to watch
+ ///
+ /// \param Socket : Socket to add
+ ///
+ ////////////////////////////////////////////////////////////
+ void Add(SocketHelper::SocketType Socket);
+
+ ////////////////////////////////////////////////////////////
+ /// Remove a socket
+ ///
+ /// \param Socket : Socket to remove
+ ///
+ ////////////////////////////////////////////////////////////
+ void Remove(SocketHelper::SocketType Socket);
+
+ ////////////////////////////////////////////////////////////
+ /// Remove all sockets
+ ///
+ ////////////////////////////////////////////////////////////
+ void Clear();
+
+ ////////////////////////////////////////////////////////////
+ /// Wait and collect sockets which are ready for reading.
+ /// This functions will return either when at least one socket
+ /// is ready, or when the given time is out
+ ///
+ /// \param Timeout : Timeout, in seconds (0 by default : no timeout)
+ ///
+ /// \return Number of sockets ready to be read
+ ///
+ ////////////////////////////////////////////////////////////
+ unsigned int Wait(float Timeout = 0.f);
+
+ ////////////////////////////////////////////////////////////
+ /// After a call to Wait(), get the Index-th socket which is
+ /// ready for reading. The total number of sockets ready
+ /// is the integer returned by the previous call to Wait()
+ ///
+ /// \param Index : Index of the socket to get
+ ///
+ /// \return The Index-th socket
+ ///
+ ////////////////////////////////////////////////////////////
+ SocketHelper::SocketType GetSocketReady(unsigned int Index);
+
+private :
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ fd_set mySet; ///< Set of socket to watch
+ fd_set mySetReady; ///< Set of socket which are ready for reading
+ int myMaxSocket; ///< Maximum socket index
+};
+
+} // namespace sf
+
+
+#endif // SFML_SELECTORBASE_HPP
diff --git a/Externals/SFML/include/SFML/Network/SocketHelper.hpp b/Externals/SFML/include/SFML/Network/SocketHelper.hpp new file mode 100644 index 0000000000..36126dbb8a --- /dev/null +++ b/Externals/SFML/include/SFML/Network/SocketHelper.hpp @@ -0,0 +1,64 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOCKETHELPER_HPP
+#define SFML_SOCKETHELPER_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+namespace sf
+{
+namespace Socket
+{
+ ////////////////////////////////////////////////////////////
+ /// Enumeration of status 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
+ Disconnected, ///< The TCP socket has been disconnected
+ Error ///< An unexpected error happened
+ };
+}
+
+} // namespace sf
+
+
+#ifdef SFML_SYSTEM_WINDOWS
+
+ #include <SFML/Network/Win32/SocketHelper.hpp>
+
+#else
+
+ #include <SFML/Network/Unix/SocketHelper.hpp>
+
+#endif
+
+
+#endif // SFML_SOCKETHELPER_HPP
diff --git a/Externals/SFML/include/SFML/Network/SocketTCP.hpp b/Externals/SFML/include/SFML/Network/SocketTCP.hpp new file mode 100644 index 0000000000..452b3045cd --- /dev/null +++ b/Externals/SFML/include/SFML/Network/SocketTCP.hpp @@ -0,0 +1,225 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOCKETTCP_HPP
+#define SFML_SOCKETTCP_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/SocketHelper.hpp>
+#include <vector>
+
+
+namespace sf
+{
+class Packet;
+class IPAddress;
+template <typename> class Selector;
+
+////////////////////////////////////////////////////////////
+/// SocketTCP wraps a socket using TCP protocol to
+/// send data safely (but a bit slower)
+////////////////////////////////////////////////////////////
+class SFML_API SocketTCP
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ ////////////////////////////////////////////////////////////
+ SocketTCP();
+
+ ////////////////////////////////////////////////////////////
+ /// Change the blocking state of the socket.
+ /// The default behaviour of a socket is blocking
+ ///
+ /// \param Blocking : Pass true to set the socket as blocking, or false for non-blocking
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetBlocking(bool Blocking);
+
+ ////////////////////////////////////////////////////////////
+ /// Connect to another computer on a specified port
+ ///
+ /// \param Port : Port to use for transfers (warning : ports < 1024 are reserved)
+ /// \param HostAddress : IP Address of the host to connect to
+ /// \param Timeout : Maximum time to wait, in seconds (0 by default : no timeout) (this parameter is ignored for non-blocking sockets)
+ ///
+ /// \return True if operation has been successful
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Connect(unsigned short Port, const IPAddress& HostAddress, float Timeout = 0.f);
+
+ ////////////////////////////////////////////////////////////
+ /// Listen to a specified port for incoming data or connections
+ ///
+ /// \param Port : Port to listen to
+ ///
+ /// \return True if operation has been successful
+ ///
+ ////////////////////////////////////////////////////////////
+ bool Listen(unsigned short Port);
+
+ ////////////////////////////////////////////////////////////
+ /// Wait for a connection (must be listening to a port).
+ /// This function will block if the socket is blocking
+ ///
+ /// \param Connected : Socket containing the connection with the connected client
+ /// \param Address : Pointer to an address to fill with client infos (NULL by default)
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Accept(SocketTCP& Connected, IPAddress* Address = NULL);
+
+ ////////////////////////////////////////////////////////////
+ /// Send an array of bytes to the host (must be connected first)
+ ///
+ /// \param Data : Pointer to the bytes to send
+ /// \param Size : Number of bytes to send
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Send(const char* Data, std::size_t Size);
+
+ ////////////////////////////////////////////////////////////
+ /// Receive an array of bytes from the host (must be connected first).
+ /// This function will block if the socket is blocking
+ ///
+ /// \param Data : Pointer to a byte array to fill (make sure it is big enough)
+ /// \param MaxSize : Maximum number of bytes to read
+ /// \param SizeReceived : Number of bytes received
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Receive(char* Data, std::size_t MaxSize, std::size_t& SizeReceived);
+
+ ////////////////////////////////////////////////////////////
+ /// Send a packet of data to the host (must be connected first)
+ ///
+ /// \param PacketToSend : Packet to send
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Send(Packet& PacketToSend);
+
+ ////////////////////////////////////////////////////////////
+ /// Receive a packet from the host (must be connected first).
+ /// This function will block if the socket is blocking
+ ///
+ /// \param PacketToReceive : Packet to fill with received data
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Receive(Packet& PacketToReceive);
+
+ ////////////////////////////////////////////////////////////
+ /// Close the socket
+ ///
+ /// \return True if operation has been successful
+ ///
+ ////////////////////////////////////////////////////////////
+ bool Close();
+
+ ////////////////////////////////////////////////////////////
+ /// Check if the socket is in a valid state ; this function
+ /// can be called any time to check if the socket is OK
+ ///
+ /// \return True if the socket is valid
+ ///
+ ////////////////////////////////////////////////////////////
+ bool IsValid() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator ==
+ ///
+ /// \param Other : Socket to compare
+ ///
+ /// \return True if *this == Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator ==(const SocketTCP& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator !=
+ ///
+ /// \param Other : Socket to compare
+ ///
+ /// \return True if *this != Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator !=(const SocketTCP& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator <.
+ /// Provided for compatibility with standard containers, as
+ /// comparing two sockets doesn't make much sense...
+ ///
+ /// \param Other : Socket to compare
+ ///
+ /// \return True if *this < Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator <(const SocketTCP& Other) const;
+
+private :
+
+ friend class Selector<SocketTCP>;
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the socket from a socket descriptor
+ /// (for internal use only)
+ ///
+ /// \param Descriptor : Socket descriptor
+ ///
+ ////////////////////////////////////////////////////////////
+ SocketTCP(SocketHelper::SocketType Descriptor);
+
+ ////////////////////////////////////////////////////////////
+ /// Create the socket
+ ///
+ /// \param Descriptor : System socket descriptor to use (0 by default -- create a new socket)
+ ///
+ ////////////////////////////////////////////////////////////
+ void Create(SocketHelper::SocketType Descriptor = 0);
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ SocketHelper::SocketType mySocket; ///< Socket descriptor
+ std::vector<char> myPendingPacket; ///< Data of the current pending packet, if any (in non-blocking mode)
+ Int32 myPendingPacketSize; ///< Size of the current pending packet, if any (in non-blocking mode)
+ bool myIsBlocking; ///< Is the socket blocking or non-blocking ?
+};
+
+} // namespace sf
+
+
+#endif // SFML_SOCKETTCP_HPP
diff --git a/Externals/SFML/include/SFML/Network/SocketUDP.hpp b/Externals/SFML/include/SFML/Network/SocketUDP.hpp new file mode 100644 index 0000000000..ba43762de5 --- /dev/null +++ b/Externals/SFML/include/SFML/Network/SocketUDP.hpp @@ -0,0 +1,224 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOCKETUDP_HPP
+#define SFML_SOCKETUDP_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Network/SocketHelper.hpp>
+#include <vector>
+
+
+namespace sf
+{
+class Packet;
+class IPAddress;
+template <typename> class Selector;
+
+////////////////////////////////////////////////////////////
+/// SocketUDP wraps a socket using UDP protocol to
+/// send data fastly (but with less safety)
+////////////////////////////////////////////////////////////
+class SFML_API SocketUDP
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ /// Default constructor
+ ///
+ ////////////////////////////////////////////////////////////
+ SocketUDP();
+
+ ////////////////////////////////////////////////////////////
+ /// Change the blocking state of the socket.
+ /// The default behaviour of a socket is blocking
+ ///
+ /// \param Blocking : Pass true to set the socket as blocking, or false for non-blocking
+ ///
+ ////////////////////////////////////////////////////////////
+ void SetBlocking(bool Blocking);
+
+ ////////////////////////////////////////////////////////////
+ /// Bind the socket to a specific port
+ ///
+ /// \param Port : Port to bind the socket to
+ ///
+ /// \return True if operation has been successful
+ ///
+ ////////////////////////////////////////////////////////////
+ bool Bind(unsigned short Port);
+
+ ////////////////////////////////////////////////////////////
+ /// Unbind the socket from its previous port, if any
+ ///
+ /// \return True if operation has been successful
+ ///
+ ////////////////////////////////////////////////////////////
+ bool Unbind();
+
+ ////////////////////////////////////////////////////////////
+ /// Send an array of bytes
+ ///
+ /// \param Data : Pointer to the bytes to send
+ /// \param Size : Number of bytes to send
+ /// \param Address : Address of the computer to send the packet to
+ /// \param Port : Port to send the data to
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Send(const char* Data, std::size_t Size, const IPAddress& Address, unsigned short Port);
+
+ ////////////////////////////////////////////////////////////
+ /// Receive an array of bytes.
+ /// This function will block if the socket is blocking
+ ///
+ /// \param Data : Pointer to a byte array to fill (make sure it is big enough)
+ /// \param MaxSize : Maximum number of bytes to read
+ /// \param SizeReceived : Number of bytes received
+ /// \param Address : Address of the computer which sent the data
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Receive(char* Data, std::size_t MaxSize, std::size_t& SizeReceived, IPAddress& Address);
+
+ ////////////////////////////////////////////////////////////
+ /// Send a packet of data
+ ///
+ /// \param PacketToSend : Packet to send
+ /// \param Address : Address of the computer to send the packet to
+ /// \param Port : Port to send the data to
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Send(Packet& PacketToSend, const IPAddress& Address, unsigned short Port);
+
+ ////////////////////////////////////////////////////////////
+ /// Receive a packet.
+ /// This function will block if the socket is blocking
+ ///
+ /// \param PacketToReceive : Packet to fill with received data
+ /// \param Address : Address of the computer which sent the packet
+ ///
+ /// \return Status code
+ ///
+ ////////////////////////////////////////////////////////////
+ Socket::Status Receive(Packet& PacketToReceive, IPAddress& Address);
+
+ ////////////////////////////////////////////////////////////
+ /// Close the socket
+ ///
+ /// \return True if operation has been successful
+ ///
+ ////////////////////////////////////////////////////////////
+ bool Close();
+
+ ////////////////////////////////////////////////////////////
+ /// Check if the socket is in a valid state ; this function
+ /// can be called any time to check if the socket is OK
+ ///
+ /// \return True if the socket is valid
+ ///
+ ////////////////////////////////////////////////////////////
+ bool IsValid() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Get the port the socket is currently bound to
+ ///
+ /// \return Current port (0 means the socket is not bound)
+ ///
+ ////////////////////////////////////////////////////////////
+ unsigned short GetPort() const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator ==
+ ///
+ /// \param Other : Socket to compare
+ ///
+ /// \return True if *this == Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator ==(const SocketUDP& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator !=
+ ///
+ /// \param Other : Socket to compare
+ ///
+ /// \return True if *this != Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator !=(const SocketUDP& Other) const;
+
+ ////////////////////////////////////////////////////////////
+ /// Comparison operator <.
+ /// Provided for compatibility with standard containers, as
+ /// comparing two sockets doesn't make much sense...
+ ///
+ /// \param Other : Socket to compare
+ ///
+ /// \return True if *this < Other
+ ///
+ ////////////////////////////////////////////////////////////
+ bool operator <(const SocketUDP& Other) const;
+
+private :
+
+ friend class Selector<SocketUDP>;
+
+ ////////////////////////////////////////////////////////////
+ /// Construct the socket from a socket descriptor
+ /// (for internal use only)
+ ///
+ /// \param Descriptor : Socket descriptor
+ ///
+ ////////////////////////////////////////////////////////////
+ SocketUDP(SocketHelper::SocketType Descriptor);
+
+ ////////////////////////////////////////////////////////////
+ /// Create the socket
+ ///
+ /// \param Descriptor : System socket descriptor to use (0 by default -- create a new socket)
+ ///
+ ////////////////////////////////////////////////////////////
+ void Create(SocketHelper::SocketType Descriptor = 0);
+
+ ////////////////////////////////////////////////////////////
+ // Member data
+ ////////////////////////////////////////////////////////////
+ SocketHelper::SocketType mySocket; ///< Socket identifier
+ unsigned short myPort; ///< Port to which the socket is bound
+ std::vector<char> myPendingPacket; ///< Data of the current pending packet, if any (in non-blocking mode)
+ Int32 myPendingPacketSize; ///< Size of the current pending packet, if any (in non-blocking mode)
+ bool myIsBlocking; ///< Is the socket blocking or non-blocking ?
+};
+
+} // namespace sf
+
+
+#endif // SFML_SOCKETUDP_HPP
diff --git a/Externals/SFML/include/SFML/Network/Sockets.hpp b/Externals/SFML/include/SFML/Network/Sockets.hpp new file mode 100644 index 0000000000..b611e852b8 --- /dev/null +++ b/Externals/SFML/include/SFML/Network/Sockets.hpp @@ -0,0 +1,45 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOCKETS_HPP
+#define SFML_SOCKETS_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+#ifdef SFML_SYSTEM_WINDOWS
+
+ #include <SFML/Network/Win32/Sockets.hpp>
+
+#else
+
+ #include <SFML/Network/Unix/Sockets.hpp>
+
+#endif
+
+
+#endif // SFML_SOCKETS_HPP
diff --git a/Externals/SFML/include/SFML/Network/Unix/SocketHelper.hpp b/Externals/SFML/include/SFML/Network/Unix/SocketHelper.hpp new file mode 100644 index 0000000000..1068cd8536 --- /dev/null +++ b/Externals/SFML/include/SFML/Network/Unix/SocketHelper.hpp @@ -0,0 +1,96 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOCKETHELPERUNIX_HPP
+#define SFML_SOCKETHELPERUNIX_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netinet/tcp.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// This class defines helper functions to do all the
+/// non-portable socket stuff. This class is meant for internal
+/// use only
+////////////////////////////////////////////////////////////
+class SFML_API SocketHelper
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ // Define some socket types
+ ////////////////////////////////////////////////////////////
+ typedef int SocketType;
+ typedef socklen_t LengthType;
+
+ ////////////////////////////////////////////////////////////
+ /// Return the value of the invalid socket
+ ///
+ /// \return Unique value of the invalid socket
+ ///
+ ////////////////////////////////////////////////////////////
+ static SocketType InvalidSocket();
+
+ ////////////////////////////////////////////////////////////
+ /// Close / destroy a socket
+ ///
+ /// \param Socket : Socket to close
+ ///
+ /// \return True on success
+ ///
+ ////////////////////////////////////////////////////////////
+ static bool Close(SocketType Socket);
+
+ ////////////////////////////////////////////////////////////
+ /// Set a socket as blocking or non-blocking
+ ///
+ /// \param Socket : Socket to modify
+ /// \param Block : New blocking state of the socket
+ ///
+ ////////////////////////////////////////////////////////////
+ static void SetBlocking(SocketType Socket, bool Block);
+
+ ////////////////////////////////////////////////////////////
+ /// Get the last socket error status
+ ///
+ /// \return Status corresponding to the last socket error
+ ///
+ ////////////////////////////////////////////////////////////
+ static Socket::Status GetErrorStatus();
+};
+
+} // namespace sf
+
+
+#endif // SFML_SOCKETHELPERUNIX_HPP
diff --git a/Externals/SFML/include/SFML/Network/Win32/SocketHelper.hpp b/Externals/SFML/include/SFML/Network/Win32/SocketHelper.hpp new file mode 100644 index 0000000000..d7851b4645 --- /dev/null +++ b/Externals/SFML/include/SFML/Network/Win32/SocketHelper.hpp @@ -0,0 +1,90 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SOCKETHELPERWIN32_HPP
+#define SFML_SOCKETHELPERWIN32_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <winsock2.h>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// This class defines helper functions to do all the
+/// non-portable socket stuff. This class is meant for internal
+/// use only
+////////////////////////////////////////////////////////////
+class SFML_API SocketHelper
+{
+public :
+
+ ////////////////////////////////////////////////////////////
+ // Define some socket types
+ ////////////////////////////////////////////////////////////
+ typedef SOCKET SocketType;
+ typedef int LengthType;
+
+ ////////////////////////////////////////////////////////////
+ /// Return the value of the invalid socket
+ ///
+ /// \return Unique value of the invalid socket
+ ///
+ ////////////////////////////////////////////////////////////
+ static SocketType InvalidSocket();
+
+ ////////////////////////////////////////////////////////////
+ /// Close / destroy a socket
+ ///
+ /// \param Socket : Socket to close
+ ///
+ /// \return True on success
+ ///
+ ////////////////////////////////////////////////////////////
+ static bool Close(SocketType Socket);
+
+ ////////////////////////////////////////////////////////////
+ /// Set a socket as blocking or non-blocking
+ ///
+ /// \param Socket : Socket to modify
+ /// \param Block : New blocking state of the socket
+ ///
+ ////////////////////////////////////////////////////////////
+ static void SetBlocking(SocketType Socket, bool Block);
+
+ ////////////////////////////////////////////////////////////
+ /// Get the last socket error status
+ ///
+ /// \return Status corresponding to the last socket error
+ ///
+ ////////////////////////////////////////////////////////////
+ static Socket::Status GetErrorStatus();
+};
+
+} // namespace sf
+
+
+#endif // SFML_SOCKETHELPERWIN32_HPP
diff --git a/Externals/SFML/include/SFML/System.hpp b/Externals/SFML/include/SFML/System.hpp new file mode 100644 index 0000000000..0fd60564be --- /dev/null +++ b/Externals/SFML/include/SFML/System.hpp @@ -0,0 +1,43 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_SYSTEM_HPP
+#define SFML_SYSTEM_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+
+#include <SFML/Config.hpp>
+//#include <SFML/System/Clock.hpp>
+//#include <SFML/System/Lock.hpp>
+//#include <SFML/System/Mutex.hpp>
+//#include <SFML/System/Randomizer.hpp>
+//#include <SFML/System/Sleep.hpp>
+//#include <SFML/System/Thread.hpp>
+//#include <SFML/System/Unicode.hpp>
+//#include <SFML/System/Vector2.hpp>
+//#include <SFML/System/Vector3.hpp>
+
+#endif // SFML_SYSTEM_HPP
diff --git a/Externals/SFML/include/SFML/System/NonCopyable.hpp b/Externals/SFML/include/SFML/System/NonCopyable.hpp new file mode 100644 index 0000000000..338653db6d --- /dev/null +++ b/Externals/SFML/include/SFML/System/NonCopyable.hpp @@ -0,0 +1,70 @@ +////////////////////////////////////////////////////////////
+//
+// SFML - Simple and Fast Multimedia Library
+// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com)
+//
+// This software is provided 'as-is', without any express or implied warranty.
+// In no event will the authors be held liable for any damages arising from the use of this software.
+//
+// Permission is granted to anyone to use this software for any purpose,
+// including commercial applications, and to alter it and redistribute it freely,
+// subject to the following restrictions:
+//
+// 1. The origin of this software must not be misrepresented;
+// you must not claim that you wrote the original software.
+// If you use this software in a product, an acknowledgment
+// in the product documentation would be appreciated but is not required.
+//
+// 2. Altered source versions must be plainly marked as such,
+// and must not be misrepresented as being the original software.
+//
+// 3. This notice may not be removed or altered from any source distribution.
+//
+////////////////////////////////////////////////////////////
+
+#ifndef SFML_NONCOPYABLE_HPP
+#define SFML_NONCOPYABLE_HPP
+
+////////////////////////////////////////////////////////////
+// Headers
+////////////////////////////////////////////////////////////
+#include <SFML/Config.hpp>
+
+
+namespace sf
+{
+////////////////////////////////////////////////////////////
+/// Utility base class to easily declare non-copyable classes.
+/// Just inherit from NonCopyable to get a non-copyable class
+////////////////////////////////////////////////////////////
+struct SFML_API NonCopyable
+{
+protected :
+
+ ////////////////////////////////////////////////////////////
+ /// The default constructor won't be generated, so provide it
+ ///
+ ////////////////////////////////////////////////////////////
+ NonCopyable() {}
+
+private :
+
+ ////////////////////////////////////////////////////////////
+ /// Copy constructor : declare it private and don't implement
+ /// it to prevent from calling it
+ ///
+ ////////////////////////////////////////////////////////////
+ NonCopyable(const NonCopyable&);
+
+ ////////////////////////////////////////////////////////////
+ /// Assignment operator : declare it private and don't implement
+ /// it to prevent from calling it
+ ///
+ ////////////////////////////////////////////////////////////
+ NonCopyable& operator =(const NonCopyable&);
+};
+
+} // namespace sf
+
+
+#endif // SFML_NONCOPYABLE_HPP
diff --git a/Externals/SFML/src/SFML/Network/Ftp.cpp b/Externals/SFML/src/SFML/Network/Ftp.cpp new file mode 100644 index 0000000000..090e6af803 --- /dev/null +++ b/Externals/SFML/src/SFML/Network/Ftp.cpp @@ -0,0 +1,709 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Network/Ftp.hpp> +#include <SFML/Network/IPAddress.hpp> +#include <algorithm> +#include <fstream> +#include <iterator> +#include <sstream> + + +namespace sf +{ +//////////////////////////////////////////////////////////// +// Utility class for exchanging stuff with the server +// on the data channel +//////////////////////////////////////////////////////////// +class Ftp::DataChannel : NonCopyable +{ +public : + + //////////////////////////////////////////////////////////// + // Constructor + //////////////////////////////////////////////////////////// + DataChannel(Ftp& Owner); + + //////////////////////////////////////////////////////////// + // Destructor + //////////////////////////////////////////////////////////// + ~DataChannel(); + + //////////////////////////////////////////////////////////// + // Open the data channel using the specified mode and port + //////////////////////////////////////////////////////////// + Ftp::Response Open(Ftp::TransferMode Mode); + + //////////////////////////////////////////////////////////// + // Send data on the data channel + //////////////////////////////////////////////////////////// + void Send(const std::vector<char>& Data); + + //////////////////////////////////////////////////////////// + // Receive data on the data channel until it is closed + //////////////////////////////////////////////////////////// + void Receive(std::vector<char>& Data); + +private : + + //////////////////////////////////////////////////////////// + // Member data + //////////////////////////////////////////////////////////// + Ftp& myFtp; ///< Reference to the owner Ftp instance + SocketTCP myDataSocket; ///< Socket used for data transfers +}; + + +//////////////////////////////////////////////////////////// +/// Default constructor +//////////////////////////////////////////////////////////// +Ftp::Response::Response(Status Code, const std::string& Message) : +myStatus (Code), +myMessage(Message) +{ + +} + + +//////////////////////////////////////////////////////////// +/// Convenience function to check if the response status code +/// means a success +//////////////////////////////////////////////////////////// +bool Ftp::Response::IsOk() const +{ + return myStatus < 400; +} + + +//////////////////////////////////////////////////////////// +/// Get the response status code +//////////////////////////////////////////////////////////// +Ftp::Response::Status Ftp::Response::GetStatus() const +{ + return myStatus; +} + + +//////////////////////////////////////////////////////////// +/// Get the full message contained in the response +//////////////////////////////////////////////////////////// +const std::string& Ftp::Response::GetMessage() const +{ + return myMessage; +} + + +//////////////////////////////////////////////////////////// +/// Default constructor +//////////////////////////////////////////////////////////// +Ftp::DirectoryResponse::DirectoryResponse(Ftp::Response Resp) : +Ftp::Response(Resp) +{ + if (IsOk()) + { + // Extract the directory from the server response + std::string::size_type Begin = Resp.GetMessage().find('"', 0); + std::string::size_type End = Resp.GetMessage().find('"', Begin + 1); + myDirectory = Resp.GetMessage().substr(Begin + 1, End - Begin - 1); + } +} + + +//////////////////////////////////////////////////////////// +/// Get the directory returned in the response +//////////////////////////////////////////////////////////// +const std::string& Ftp::DirectoryResponse::GetDirectory() const +{ + return myDirectory; +} + + +//////////////////////////////////////////////////////////// +/// Default constructor +//////////////////////////////////////////////////////////// +Ftp::ListingResponse::ListingResponse(Ftp::Response Resp, const std::vector<char>& Data) : +Ftp::Response(Resp) +{ + if (IsOk()) + { + // Fill the array of strings + std::string Paths(Data.begin(), Data.end()); + std::string::size_type LastPos = 0; + for (std::string::size_type Pos = Paths.find("\r\n"); Pos != std::string::npos; Pos = Paths.find("\r\n", LastPos)) + { + myFilenames.push_back(Paths.substr(LastPos, Pos - LastPos)); + LastPos = Pos + 2; + } + } +} + + +//////////////////////////////////////////////////////////// +/// Get the number of filenames in the listing +//////////////////////////////////////////////////////////// +std::size_t Ftp::ListingResponse::GetCount() const +{ + return myFilenames.size(); +} + + +//////////////////////////////////////////////////////////// +/// Get the Index-th filename in the directory +//////////////////////////////////////////////////////////// +const std::string& Ftp::ListingResponse::GetFilename(std::size_t Index) const +{ + return myFilenames[Index]; +} + + +//////////////////////////////////////////////////////////// +/// Destructor -- close the connection with the server +//////////////////////////////////////////////////////////// +Ftp::~Ftp() +{ + Disconnect(); +} + + +//////////////////////////////////////////////////////////// +/// Connect to the specified FTP server +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::Connect(const IPAddress& Server, unsigned short Port, float Timeout) +{ + // Connect to the server + if (myCommandSocket.Connect(Port, Server, Timeout) != Socket::Done) + return Response(Response::ConnectionFailed); + + // Get the response to the connection + return GetResponse(); +} + + +//////////////////////////////////////////////////////////// +/// Log in using anonymous account +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::Login() +{ + return Login("anonymous", "user@sfml-dev.org"); +} + + +//////////////////////////////////////////////////////////// +/// Log in using a username and a password +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::Login(const std::string& UserName, const std::string& Password) +{ + Response Resp = SendCommand("USER", UserName); + if (Resp.IsOk()) + Resp = SendCommand("PASS", Password); + + return Resp; +} + + +//////////////////////////////////////////////////////////// +/// Close the connection with FTP server +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::Disconnect() +{ + // Send the exit command + Response Resp = SendCommand("QUIT"); + if (Resp.IsOk()) + myCommandSocket.Close(); + + return Resp; +} + + +//////////////////////////////////////////////////////////// +/// Send a null command just to prevent from being disconnected +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::KeepAlive() +{ + return SendCommand("NOOP"); +} + + +//////////////////////////////////////////////////////////// +/// Get the current working directory +//////////////////////////////////////////////////////////// +Ftp::DirectoryResponse Ftp::GetWorkingDirectory() +{ + return DirectoryResponse(SendCommand("PWD")); +} + + +//////////////////////////////////////////////////////////// +/// Get the contents of the given directory +/// (subdirectories and files) +//////////////////////////////////////////////////////////// +Ftp::ListingResponse Ftp::GetDirectoryListing(const std::string& Directory) +{ + // Open a data channel on default port (20) using ASCII transfer mode + std::vector<char> DirData; + DataChannel Data(*this); + Response Resp = Data.Open(Ascii); + if (Resp.IsOk()) + { + // Tell the server to send us the listing + Resp = SendCommand("NLST", Directory); + if (Resp.IsOk()) + { + // Receive the listing + Data.Receive(DirData); + + // Get the response from the server + Resp = GetResponse(); + } + } + + return ListingResponse(Resp, DirData); +} + + +//////////////////////////////////////////////////////////// +/// Change the current working directory +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::ChangeDirectory(const std::string& Directory) +{ + return SendCommand("CWD", Directory); +} + + +//////////////////////////////////////////////////////////// +/// Go to the parent directory of the current one +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::ParentDirectory() +{ + return SendCommand("CDUP"); +} + + +//////////////////////////////////////////////////////////// +/// Create a new directory +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::MakeDirectory(const std::string& Name) +{ + return SendCommand("MKD", Name); +} + + +//////////////////////////////////////////////////////////// +/// Remove an existing directory +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::DeleteDirectory(const std::string& Name) +{ + return SendCommand("RMD", Name); +} + + +//////////////////////////////////////////////////////////// +/// Rename a file +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::RenameFile(const std::string& File, const std::string& NewName) +{ + Response Resp = SendCommand("RNFR", File); + if (Resp.IsOk()) + Resp = SendCommand("RNTO", NewName); + + return Resp; +} + + +//////////////////////////////////////////////////////////// +/// Remove an existing file +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::DeleteFile(const std::string& Name) +{ + return SendCommand("DELE", Name); +} + + +//////////////////////////////////////////////////////////// +/// Download a file from the server +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::Download(const std::string& DistantFile, const std::string& DestPath, TransferMode Mode) +{ + // Open a data channel using the given transfer mode + DataChannel Data(*this); + Response Resp = Data.Open(Mode); + if (Resp.IsOk()) + { + // Tell the server to start the transfer + Resp = SendCommand("RETR", DistantFile); + if (Resp.IsOk()) + { + // Receive the file data + std::vector<char> FileData; + Data.Receive(FileData); + + // Get the response from the server + Resp = GetResponse(); + if (Resp.IsOk()) + { + // Extract the filename from the file path + std::string Filename = DistantFile; + std::string::size_type Pos = Filename.find_last_of("/\\"); + if (Pos != std::string::npos) + Filename = Filename.substr(Pos + 1); + + // Make sure the destination path ends with a slash + std::string Path = DestPath; + if (!Path.empty() && (Path[Path.size() - 1] != '\\') && (Path[Path.size() - 1] != '/')) + Path += "/"; + + // Create the file and copy the received data into it + std::ofstream File((Path + Filename).c_str(), std::ios_base::binary); + if (!File) + return Response(Response::InvalidFile); + File.write(&FileData[0], static_cast<std::streamsize>(FileData.size())); + } + } + } + + return Resp; +} + + +//////////////////////////////////////////////////////////// +/// Upload a file to the server +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::Upload(const std::string& LocalFile, const std::string& DestPath, TransferMode Mode) +{ + // Get the contents of the file to send + std::ifstream File(LocalFile.c_str(), std::ios_base::binary); + if (!File) + return Response(Response::InvalidFile); + File.seekg(0, std::ios::end); + std::size_t Length = File.tellg(); + File.seekg(0, std::ios::beg); + std::vector<char> FileData(Length); + File.read(&FileData[0], static_cast<std::streamsize>(Length)); + + // Extract the filename from the file path + std::string Filename = LocalFile; + std::string::size_type Pos = Filename.find_last_of("/\\"); + if (Pos != std::string::npos) + Filename = Filename.substr(Pos + 1); + + // Make sure the destination path ends with a slash + std::string Path = DestPath; + if (!Path.empty() && (Path[Path.size() - 1] != '\\') && (Path[Path.size() - 1] != '/')) + Path += "/"; + + // Open a data channel using the given transfer mode + DataChannel Data(*this); + Response Resp = Data.Open(Mode); + if (Resp.IsOk()) + { + // Tell the server to start the transfer + Resp = SendCommand("STOR", Path + Filename); + if (Resp.IsOk()) + { + // Send the file data + Data.Send(FileData); + + // Get the response from the server + Resp = GetResponse(); + } + } + + return Resp; +} + + +//////////////////////////////////////////////////////////// +/// Send a command to the FTP server +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::SendCommand(const std::string& Command, const std::string& Parameter) +{ + // Build the command string + std::string CommandStr; + if (Parameter != "") + CommandStr = Command + " " + Parameter + "\r\n"; + else + CommandStr = Command + "\r\n"; + + // Send it to the server + if (myCommandSocket.Send(CommandStr.c_str(), CommandStr.length()) != sf::Socket::Done) + return Response(Response::ConnectionClosed); + + // Get the response + return GetResponse(); +} + + +//////////////////////////////////////////////////////////// +/// Receive a response from the server +/// (usually after a command has been sent) +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::GetResponse() +{ + // We'll use a variable to keep track of the last valid code. + // It is useful in case of multi-lines responses, because the end of such a response + // will start by the same code + unsigned int LastCode = 0; + bool IsInsideMultiline = false; + std::string Message; + + for (;;) + { + // Receive the response from the server + char Buffer[1024]; + std::size_t Length; + if (myCommandSocket.Receive(Buffer, sizeof(Buffer), Length) != sf::Socket::Done) + return Response(Response::ConnectionClosed); + + // There can be several lines inside the received buffer, extract them all + std::istringstream In(std::string(Buffer, Length), std::ios_base::binary); + while (In) + { + // Try to extract the code + unsigned int Code; + if (In >> Code) + { + // Extract the separator + char Sep; + In.get(Sep); + + // The '-' character means a multiline response + if ((Sep == '-') && !IsInsideMultiline) + { + // Set the multiline flag + IsInsideMultiline = true; + + // Keep track of the code + if (LastCode == 0) + LastCode = Code; + + // Extract the line + std::getline(In, Message); + + // Remove the ending '\r' (all lines are terminated by "\r\n") + Message.erase(Message.length() - 1); + Message = Sep + Message + "\n"; + } + else + { + // We must make sure that the code is the same, otherwise it means + // we haven't reached the end of the multiline response + if ((Sep != '-') && ((Code == LastCode) || (LastCode == 0))) + { + // Clear the multiline flag + IsInsideMultiline = false; + + // Extract the line + std::string Line; + std::getline(In, Line); + + // Remove the ending '\r' (all lines are terminated by "\r\n") + Line.erase(Line.length() - 1); + + // Append it to the message + if (Code == LastCode) + { + std::ostringstream Out; + Out << Code << Sep << Line; + Message += Out.str(); + } + else + { + Message = Sep + Line; + } + + // Return the response code and message + return Response(static_cast<Response::Status>(Code), Message); + } + else + { + // The line we just read was actually not a response, + // only a new part of the current multiline response + + // Extract the line + std::string Line; + std::getline(In, Line); + + if (!Line.empty()) + { + // Remove the ending '\r' (all lines are terminated by "\r\n") + Line.erase(Line.length() - 1); + + // Append it to the current message + std::ostringstream Out; + Out << Code << Sep << Line << "\n"; + Message += Out.str(); + } + } + } + } + else if (LastCode != 0) + { + // It seems we are in the middle of a multiline response + + // Clear the error bits of the stream + In.clear(); + + // Extract the line + std::string Line; + std::getline(In, Line); + + if (!Line.empty()) + { + // Remove the ending '\r' (all lines are terminated by "\r\n") + Line.erase(Line.length() - 1); + + // Append it to the current message + Message += Line + "\n"; + } + } + else + { + // Error : cannot extract the code, and we are not in a multiline response + return Response(Response::InvalidResponse); + } + } + } + + // We never reach there +} + + +//////////////////////////////////////////////////////////// +/// Constructor +//////////////////////////////////////////////////////////// +Ftp::DataChannel::DataChannel(Ftp& Owner) : +myFtp(Owner) +{ + +} + + +//////////////////////////////////////////////////////////// +/// Destructor +//////////////////////////////////////////////////////////// +Ftp::DataChannel::~DataChannel() +{ + // Close the data socket + myDataSocket.Close(); +} + + +//////////////////////////////////////////////////////////// +/// Open the data channel using the specified mode and port +//////////////////////////////////////////////////////////// +Ftp::Response Ftp::DataChannel::Open(Ftp::TransferMode Mode) +{ + // Open a data connection in active mode (we connect to the server) + Ftp::Response Resp = myFtp.SendCommand("PASV"); + if (Resp.IsOk()) + { + // Extract the connection address and port from the response + std::string::size_type begin = Resp.GetMessage().find_first_of("0123456789"); + if (begin != std::string::npos) + { + sf::Uint8 Data[6] = {0, 0, 0, 0, 0, 0}; + std::string Str = Resp.GetMessage().substr(begin); + std::size_t Index = 0; + for (int i = 0; i < 6; ++i) + { + // Extract the current number + while (isdigit(Str[Index])) + { + Data[i] = Data[i] * 10 + (Str[Index] - '0'); + Index++; + } + + // Skip separator + Index++; + } + + // Reconstruct connection port and address + unsigned short Port = Data[4] * 256 + Data[5]; + sf::IPAddress Address(static_cast<sf::Uint8>(Data[0]), + static_cast<sf::Uint8>(Data[1]), + static_cast<sf::Uint8>(Data[2]), + static_cast<sf::Uint8>(Data[3])); + + // Connect the data channel to the server + if (myDataSocket.Connect(Port, Address) == Socket::Done) + { + // Translate the transfer mode to the corresponding FTP parameter + std::string ModeStr; + switch (Mode) + { + case Ftp::Binary : ModeStr = "I"; break; + case Ftp::Ascii : ModeStr = "A"; break; + case Ftp::Ebcdic : ModeStr = "E"; break; + } + + // Set the transfer mode + Resp = myFtp.SendCommand("TYPE", ModeStr); + } + else + { + // Failed to connect to the server + Resp = Ftp::Response(Ftp::Response::ConnectionFailed); + } + } + } + + return Resp; +} + + +//////////////////////////////////////////////////////////// +/// Receive data on the data channel until it is closed +//////////////////////////////////////////////////////////// +void Ftp::DataChannel::Receive(std::vector<char>& Data) +{ + // Receive data + Data.clear(); + char Buffer[1024]; + std::size_t Received; + while (myDataSocket.Receive(Buffer, sizeof(Buffer), Received) == sf::Socket::Done) + { + std::copy(Buffer, Buffer + Received, std::back_inserter(Data)); + } + + // Close the data socket + myDataSocket.Close(); +} + + +//////////////////////////////////////////////////////////// +/// Send data on the data channel +//////////////////////////////////////////////////////////// +void Ftp::DataChannel::Send(const std::vector<char>& Data) +{ + // Send data + myDataSocket.Send(&Data[0], Data.size()); + + // Close the data socket + myDataSocket.Close(); +} + +} // namespace sf diff --git a/Externals/SFML/src/SFML/Network/Http.cpp b/Externals/SFML/src/SFML/Network/Http.cpp new file mode 100644 index 0000000000..4794aff131 --- /dev/null +++ b/Externals/SFML/src/SFML/Network/Http.cpp @@ -0,0 +1,425 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Network/Http.hpp> +#include <ctype.h> +#include <sstream> + + +namespace +{ + //////////////////////////////////////////////////////////// + // Convenience function to convert a string to lower case + //////////////////////////////////////////////////////////// + std::string ToLower(const std::string& Str) + { + std::string Ret = Str; + for (std::string::iterator i = Ret.begin(); i != Ret.end(); ++i) + *i = static_cast<char>(tolower(*i)); + + return Ret; + } +} + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// Default constructor +//////////////////////////////////////////////////////////// +Http::Request::Request(Method RequestMethod, const std::string& URI, const std::string& Body) : +myMethod (RequestMethod), +myURI (URI), +myMajorVersion(1), +myMinorVersion(0), +myBody (Body) +{ + +} + + +//////////////////////////////////////////////////////////// +/// Set the value of a field; the field is added if it doesn't exist +//////////////////////////////////////////////////////////// +void Http::Request::SetField(const std::string& Field, const std::string& Value) +{ + myFields[ToLower(Field)] = Value; +} + + +//////////////////////////////////////////////////////////// +/// Set the request method. +/// This parameter is Get by default +//////////////////////////////////////////////////////////// +void Http::Request::SetMethod(Http::Request::Method RequestMethod) +{ + myMethod = RequestMethod; +} + + +//////////////////////////////////////////////////////////// +/// Set the target URI of the request. +/// This parameter is "/" by default +//////////////////////////////////////////////////////////// +void Http::Request::SetURI(const std::string& URI) +{ + myURI = URI; + + // Make sure it starts with a '/' + if (myURI.empty() || (myURI[0] != '/')) + myURI.insert(0, "/"); +} + + +//////////////////////////////////////////////////////////// +/// Set the HTTP version of the request. +/// This parameter is 1.0 by default +//////////////////////////////////////////////////////////// +void Http::Request::SetHttpVersion(unsigned int Major, unsigned int Minor) +{ + myMajorVersion = Major; + myMinorVersion = Minor; +} + + +//////////////////////////////////////////////////////////// +/// Set the body of the request. This parameter is optional and +/// makes sense only for POST requests. +/// This parameter is empty by default +//////////////////////////////////////////////////////////// +void Http::Request::SetBody(const std::string& Body) +{ + myBody = Body; +} + + +//////////////////////////////////////////////////////////// +/// Get the string representation of a request header +//////////////////////////////////////////////////////////// +std::string Http::Request::ToString() const +{ + std::ostringstream Out; + + // Convert the method to its string representation + std::string RequestMethod; + switch (myMethod) + { + default : + case Get : RequestMethod = "GET"; break; + case Post : RequestMethod = "POST"; break; + case Head : RequestMethod = "HEAD"; break; + } + + // Write the first line containing the request type + Out << RequestMethod << " " << myURI << " "; + Out << "HTTP/" << myMajorVersion << "." << myMinorVersion << "\r\n"; + + // Write fields + for (FieldTable::const_iterator i = myFields.begin(); i != myFields.end(); ++i) + { + Out << i->first << ": " << i->second << "\r\n"; + } + + // Use an extra \r\n to separate the header from the body + Out << "\r\n"; + + // Add the body + Out << myBody; + + return Out.str(); +} + + +//////////////////////////////////////////////////////////// +/// Check if the given field has been defined +//////////////////////////////////////////////////////////// +bool Http::Request::HasField(const std::string& Field) const +{ + return myFields.find(Field) != myFields.end(); +} + + +//////////////////////////////////////////////////////////// +/// Default constructor +//////////////////////////////////////////////////////////// +Http::Response::Response() : +myStatus (ConnectionFailed), +myMajorVersion(0), +myMinorVersion(0) +{ + +} + + +//////////////////////////////////////////////////////////// +/// Get the value of a field +//////////////////////////////////////////////////////////// +const std::string& Http::Response::GetField(const std::string& Field) const +{ + FieldTable::const_iterator It = myFields.find(Field); + if (It != myFields.end()) + { + return It->second; + } + else + { + static const std::string Empty = ""; + return Empty; + } +} + + +//////////////////////////////////////////////////////////// +/// Get the header's status code +//////////////////////////////////////////////////////////// +Http::Response::Status Http::Response::GetStatus() const +{ + return myStatus; +} + + +//////////////////////////////////////////////////////////// +/// Get the major HTTP version number of the response +//////////////////////////////////////////////////////////// +unsigned int Http::Response::GetMajorHttpVersion() const +{ + return myMajorVersion; +} + + +//////////////////////////////////////////////////////////// +/// Get the major HTTP version number of the response +//////////////////////////////////////////////////////////// +unsigned int Http::Response::GetMinorHttpVersion() const +{ + return myMinorVersion; +} + + +//////////////////////////////////////////////////////////// +/// Get the body of the response. The body can contain : +/// - the requested page (for GET requests) +/// - a response from the server (for POST requests) +/// - nothing (for HEAD requests) +/// - an error message (in case of an error) +//////////////////////////////////////////////////////////// +const std::string& Http::Response::GetBody() const +{ + return myBody; +} + + +//////////////////////////////////////////////////////////// +/// Construct the header from a response string +//////////////////////////////////////////////////////////// +void Http::Response::FromString(const std::string& Data) +{ + std::istringstream In(Data); + + // Extract the HTTP version from the first line + std::string Version; + if (In >> Version) + { + if ((Version.size() >= 8) && (Version[6] == '.') && + (ToLower(Version.substr(0, 5)) == "http/") && + isdigit(Version[5]) && isdigit(Version[7])) + { + myMajorVersion = Version[5] - '0'; + myMinorVersion = Version[7] - '0'; + } + else + { + // Invalid HTTP version + myStatus = InvalidResponse; + return; + } + } + + // Extract the status code from the first line + int StatusCode; + if (In >> StatusCode) + { + myStatus = static_cast<Status>(StatusCode); + } + else + { + // Invalid status code + myStatus = InvalidResponse; + return; + } + + // Ignore the end of the first line + In.ignore(10000, '\n'); + + // Parse the other lines, which contain fields, one by one + std::string Line; + while (std::getline(In, Line) && (Line.size() > 2)) + { + std::string::size_type Pos = Line.find(": "); + if (Pos != std::string::npos) + { + // Extract the field name and its value + std::string Field = Line.substr(0, Pos); + std::string Value = Line.substr(Pos + 2); + + // Remove any trailing \r + if (!Value.empty() && (*Value.rbegin() == '\r')) + Value.erase(Value.size() - 1); + + // Add the field + myFields[ToLower(Field)] = Value; + } + } + + // Finally extract the body + myBody.clear(); + while (std::getline(In, Line)) + myBody += Line + "\n"; +} + + +//////////////////////////////////////////////////////////// +/// Default constructor +//////////////////////////////////////////////////////////// +Http::Http() : +myHost(), +myPort(0) +{ + +} + + +//////////////////////////////////////////////////////////// +/// Construct the Http instance with the target host +//////////////////////////////////////////////////////////// +Http::Http(const std::string& Host, unsigned short Port) +{ + SetHost(Host, Port); +} + + +//////////////////////////////////////////////////////////// +/// Set the target host +//////////////////////////////////////////////////////////// +void Http::SetHost(const std::string& Host, unsigned short Port) +{ + // Detect the protocol used + std::string Protocol = ToLower(Host.substr(0, 8)); + if (Protocol.substr(0, 7) == "http://") + { + // HTTP protocol + myHostName = Host.substr(7); + myPort = (Port != 0 ? Port : 80); + } + else if (Protocol == "https://") + { + // HTTPS protocol + myHostName = Host.substr(8); + myPort = (Port != 0 ? Port : 443); + } + else + { + // Undefined protocol - use HTTP + myHostName = Host; + myPort = (Port != 0 ? Port : 80); + } + + // Remove any trailing '/' from the host name + if (!myHostName.empty() && (*myHostName.rbegin() == '/')) + myHostName.erase(myHostName.size() - 1); + + myHost = sf::IPAddress(myHostName); +} + + +//////////////////////////////////////////////////////////// +/// Send a HTTP request and return the server's response. +/// You must be connected to a host before sending requests. +/// Any missing mandatory header field will be added with an appropriate value. +/// Warning : this function waits for the server's response and may +/// not return instantly; use a thread if you don't want to block your +/// application. +//////////////////////////////////////////////////////////// +Http::Response Http::SendRequest(const Http::Request& Req) +{ + // First make sure the request is valid -- add missing mandatory fields + Request ToSend(Req); + if (!ToSend.HasField("From")) + { + ToSend.SetField("From", "user@sfml-dev.org"); + } + if (!ToSend.HasField("User-Agent")) + { + ToSend.SetField("User-Agent", "libsfml-network/1.x"); + } + if (!ToSend.HasField("Host")) + { + ToSend.SetField("Host", myHostName); + } + if (!ToSend.HasField("Content-Length")) + { + std::ostringstream Out; + Out << ToSend.myBody.size(); + ToSend.SetField("Content-Length", Out.str()); + } + + // Prepare the response + Response Received; + + // Connect the socket to the host + if (myConnection.Connect(myPort, myHost) == Socket::Done) + { + // Convert the request to string and send it through the connected socket + std::string RequestStr = ToSend.ToString(); + + if (!RequestStr.empty()) + { + // Send it through the socket + if (myConnection.Send(RequestStr.c_str(), RequestStr.size()) == sf::Socket::Done) + { + // Wait for the server's response + std::string ReceivedStr; + std::size_t Size = 0; + char Buffer[1024]; + while (myConnection.Receive(Buffer, sizeof(Buffer), Size) == sf::Socket::Done) + { + ReceivedStr.append(Buffer, Buffer + Size); + } + + // Build the Response object from the received data + Received.FromString(ReceivedStr); + } + } + + // Close the connection + myConnection.Close(); + } + + return Received; +} + +} // namespace sf diff --git a/Externals/SFML/src/SFML/Network/IPAddress.cpp b/Externals/SFML/src/SFML/Network/IPAddress.cpp new file mode 100644 index 0000000000..985ef41c75 --- /dev/null +++ b/Externals/SFML/src/SFML/Network/IPAddress.cpp @@ -0,0 +1,303 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Network/IPAddress.hpp> +#include <SFML/Network/Http.hpp> +#include <SFML/Network/SocketHelper.hpp> +#include <string.h> + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// Static member data +//////////////////////////////////////////////////////////// +const IPAddress IPAddress::LocalHost("127.0.0.1"); + + +//////////////////////////////////////////////////////////// +/// Default constructor +//////////////////////////////////////////////////////////// +IPAddress::IPAddress() : +myAddress(INADDR_NONE) +{ + +} + + +//////////////////////////////////////////////////////////// +/// Construct the address from a string +//////////////////////////////////////////////////////////// +IPAddress::IPAddress(const std::string& Address) +{ + // First try to convert it as a byte representation ("xxx.xxx.xxx.xxx") + myAddress = inet_addr(Address.c_str()); + + // If not successful, try to convert it as a host name + if (!IsValid()) + { + hostent* Host = gethostbyname(Address.c_str()); + if (Host) + { + // Host found, extract its IP address + myAddress = reinterpret_cast<in_addr*>(Host->h_addr)->s_addr; + } + else + { + // Host name not found on the network + myAddress = INADDR_NONE; + } + } +} + + +//////////////////////////////////////////////////////////// +/// Construct the address from a C-style string ; +/// Needed for implicit conversions from literal strings to IPAddress to work +//////////////////////////////////////////////////////////// +IPAddress::IPAddress(const char* Address) +{ + // First try to convert it as a byte representation ("xxx.xxx.xxx.xxx") + myAddress = inet_addr(Address); + + // If not successful, try to convert it as a host name + if (!IsValid()) + { + hostent* Host = gethostbyname(Address); + if (Host) + { + // Host found, extract its IP address + myAddress = reinterpret_cast<in_addr*>(Host->h_addr)->s_addr; + } + else + { + // Host name not found on the network + myAddress = INADDR_NONE; + } + } +} + + +//////////////////////////////////////////////////////////// +/// Construct the address from 4 bytes +//////////////////////////////////////////////////////////// +IPAddress::IPAddress(Uint8 Byte0, Uint8 Byte1, Uint8 Byte2, Uint8 Byte3) +{ + myAddress = htonl((Byte0 << 24) | (Byte1 << 16) | (Byte2 << 8) | Byte3); +} + + +//////////////////////////////////////////////////////////// +/// Construct the address from a 32-bits integer +//////////////////////////////////////////////////////////// +IPAddress::IPAddress(Uint32 Address) +{ + myAddress = htonl(Address); +} + + +//////////////////////////////////////////////////////////// +/// Tell if the address is a valid one +//////////////////////////////////////////////////////////// +bool IPAddress::IsValid() const +{ + return myAddress != INADDR_NONE; +} + + +//////////////////////////////////////////////////////////// +/// Get a string representation of the address +//////////////////////////////////////////////////////////// +std::string IPAddress::ToString() const +{ + in_addr InAddr; + InAddr.s_addr = myAddress; + + return inet_ntoa(InAddr); +} + + +//////////////////////////////////////////////////////////// +/// Get an integer representation of the address +//////////////////////////////////////////////////////////// +Uint32 IPAddress::ToInteger() const +{ + return ntohl(myAddress); +} + + +//////////////////////////////////////////////////////////// +/// Get the computer's local IP address (from the LAN point of view) +//////////////////////////////////////////////////////////// +IPAddress IPAddress::GetLocalAddress() +{ + // The method here is to connect a UDP socket to anyone (here to localhost), + // and get the local socket address with the getsockname function. + // UDP connection will not send anything to the network, so this function won't cause any overhead + + IPAddress LocalAddress; + + // Create the socket + SocketHelper::SocketType Socket = socket(PF_INET, SOCK_DGRAM, 0); + if (Socket == SocketHelper::InvalidSocket()) + return LocalAddress; + + // Build the host address (use a random port) + sockaddr_in SockAddr; + memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero)); + SockAddr.sin_addr.s_addr = INADDR_LOOPBACK; + SockAddr.sin_family = AF_INET; + SockAddr.sin_port = htons(4567); + + // Connect the socket + if (connect(Socket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1) + { + SocketHelper::Close(Socket); + return LocalAddress; + } + + // Get the local address of the socket connection + SocketHelper::LengthType Size = sizeof(SockAddr); + if (getsockname(Socket, reinterpret_cast<sockaddr*>(&SockAddr), &Size) == -1) + { + SocketHelper::Close(Socket); + return LocalAddress; + } + + // Close the socket + SocketHelper::Close(Socket); + + // Finally build the IP address + LocalAddress.myAddress = SockAddr.sin_addr.s_addr; + + return LocalAddress; +} + + +//////////////////////////////////////////////////////////// +/// Get the computer's public IP address (from the web point of view) +//////////////////////////////////////////////////////////// +IPAddress IPAddress::GetPublicAddress() +{ + // The trick here is more complicated, because the only way + // to get our public IP address is to get it from a distant computer. + // Here we get the web page from http://www.whatismyip.org + // and parse the result to extract our IP address + // (not very hard : the web page contains only our IP address) + + IPAddress PublicAddress; + + // Connect to the web server and get its index page + Http Server("www.whatismyip.org"); + Http::Request Request(Http::Request::Get, "/"); + Http::Response Page = Server.SendRequest(Request); + + // If the request was successful, we can extract + // the address from the body of the web page + if (Page.GetStatus() == Http::Response::Ok) + PublicAddress = Page.GetBody(); + + return PublicAddress; +} + + +//////////////////////////////////////////////////////////// +/// Comparison operator == +//////////////////////////////////////////////////////////// +bool IPAddress::operator ==(const IPAddress& Other) const +{ + return myAddress == Other.myAddress; +} + + +//////////////////////////////////////////////////////////// +/// Comparison operator != +//////////////////////////////////////////////////////////// +bool IPAddress::operator !=(const IPAddress& Other) const +{ + return myAddress != Other.myAddress; +} + + +//////////////////////////////////////////////////////////// +/// Comparison operator < +//////////////////////////////////////////////////////////// +bool IPAddress::operator <(const IPAddress& Other) const +{ + return myAddress < Other.myAddress; +} + + +//////////////////////////////////////////////////////////// +/// Comparison operator > +//////////////////////////////////////////////////////////// +bool IPAddress::operator >(const IPAddress& Other) const +{ + return myAddress > Other.myAddress; +} + + +//////////////////////////////////////////////////////////// +/// Comparison operator <= +//////////////////////////////////////////////////////////// +bool IPAddress::operator <=(const IPAddress& Other) const +{ + return myAddress <= Other.myAddress; +} + + +//////////////////////////////////////////////////////////// +/// Comparison operator >= +//////////////////////////////////////////////////////////// +bool IPAddress::operator >=(const IPAddress& Other) const +{ + return myAddress >= Other.myAddress; +} + + +//////////////////////////////////////////////////////////// +/// Operator >> overload to extract an address from an input stream +//////////////////////////////////////////////////////////// +std::istream& operator >>(std::istream& Stream, IPAddress& Address) +{ + std::string Str; + Stream >> Str; + Address = IPAddress(Str); + + return Stream; +} + + +//////////////////////////////////////////////////////////// +/// Operator << overload to print an address to an output stream +//////////////////////////////////////////////////////////// +std::ostream& operator <<(std::ostream& Stream, const IPAddress& Address) +{ + return Stream << Address.ToString(); +} + +} // namespace sf diff --git a/Externals/SFML/src/SFML/Network/Packet.cpp b/Externals/SFML/src/SFML/Network/Packet.cpp new file mode 100644 index 0000000000..9bc37ddaff --- /dev/null +++ b/Externals/SFML/src/SFML/Network/Packet.cpp @@ -0,0 +1,426 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Network/Packet.hpp> +#include <SFML/Network/SocketHelper.hpp> +#include <string.h> + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// Default constructor +//////////////////////////////////////////////////////////// +Packet::Packet() : +myReadPos(0), +myIsValid(true) +{ + +} + + +//////////////////////////////////////////////////////////// +/// Virtual destructor +//////////////////////////////////////////////////////////// +Packet::~Packet() +{ + +} + + +//////////////////////////////////////////////////////////// +/// Append data to the end of the packet +//////////////////////////////////////////////////////////// +void Packet::Append(const void* Data, std::size_t SizeInBytes) +{ + if (Data && (SizeInBytes > 0)) + { + std::size_t Start = myData.size(); + myData.resize(Start + SizeInBytes); + memcpy(&myData[Start], Data, SizeInBytes); + } +} + + +//////////////////////////////////////////////////////////// +/// Clear the packet data +//////////////////////////////////////////////////////////// +void Packet::Clear() +{ + myData.clear(); + myReadPos = 0; + myIsValid = true; +} + + +//////////////////////////////////////////////////////////// +/// Get a pointer to the data contained in the packet +/// Warning : the returned pointer may be invalid after you +/// append data to the packet +//////////////////////////////////////////////////////////// +const char* Packet::GetData() const +{ + return !myData.empty() ? &myData[0] : NULL; +} + + +//////////////////////////////////////////////////////////// +/// Get the size of the data contained in the packet +//////////////////////////////////////////////////////////// +std::size_t Packet::GetDataSize() const +{ + return myData.size(); +} + + +//////////////////////////////////////////////////////////// +/// Tell if the reading position has reached the end of the packet +//////////////////////////////////////////////////////////// +bool Packet::EndOfPacket() const +{ + return myReadPos >= myData.size(); +} + + +//////////////////////////////////////////////////////////// +/// Tell if the packet is valid for reading +//////////////////////////////////////////////////////////// +Packet::operator bool() const +{ + return myIsValid; +} + + +//////////////////////////////////////////////////////////// +/// Operator >> overloads to extract data from the packet +//////////////////////////////////////////////////////////// +Packet& Packet::operator >>(bool& Data) +{ + Uint8 Value; + if (*this >> Value) + Data = (Value != 0); + + return *this; +} +Packet& Packet::operator >>(Int8& Data) +{ + if (CheckSize(sizeof(Data))) + { + Data = *reinterpret_cast<const Int8*>(GetData() + myReadPos); + myReadPos += sizeof(Data); + } + + return *this; +} +Packet& Packet::operator >>(Uint8& Data) +{ + if (CheckSize(sizeof(Data))) + { + Data = *reinterpret_cast<const Uint8*>(GetData() + myReadPos); + myReadPos += sizeof(Data); + } + + return *this; +} +Packet& Packet::operator >>(Int16& Data) +{ + if (CheckSize(sizeof(Data))) + { + Data = ntohs(*reinterpret_cast<const Int16*>(GetData() + myReadPos)); + myReadPos += sizeof(Data); + } + + return *this; +} +Packet& Packet::operator >>(Uint16& Data) +{ + if (CheckSize(sizeof(Data))) + { + Data = ntohs(*reinterpret_cast<const Uint16*>(GetData() + myReadPos)); + myReadPos += sizeof(Data); + } + + return *this; +} +Packet& Packet::operator >>(Int32& Data) +{ + if (CheckSize(sizeof(Data))) + { + Data = ntohl(*reinterpret_cast<const Int32*>(GetData() + myReadPos)); + myReadPos += sizeof(Data); + } + + return *this; +} +Packet& Packet::operator >>(Uint32& Data) +{ + if (CheckSize(sizeof(Data))) + { + Data = ntohl(*reinterpret_cast<const Uint32*>(GetData() + myReadPos)); + myReadPos += sizeof(Data); + } + + return *this; +} +Packet& Packet::operator >>(float& Data) +{ + if (CheckSize(sizeof(Data))) + { + Data = *reinterpret_cast<const float*>(GetData() + myReadPos); + myReadPos += sizeof(Data); + } + + return *this; +} +Packet& Packet::operator >>(double& Data) +{ + if (CheckSize(sizeof(Data))) + { + Data = *reinterpret_cast<const double*>(GetData() + myReadPos); + myReadPos += sizeof(Data); + } + + return *this; +} +Packet& Packet::operator >>(char* Data) +{ + // First extract string length + Uint32 Length; + *this >> Length; + + if ((Length > 0) && CheckSize(Length)) + { + // Then extract characters + memcpy(Data, GetData() + myReadPos, Length); + Data[Length] = '\0'; + + // Update reading position + myReadPos += Length; + } + + return *this; +} +Packet& Packet::operator >>(std::string& Data) +{ + // First extract string length + Uint32 Length; + *this >> Length; + + Data.clear(); + if ((Length > 0) && CheckSize(Length)) + { + // Then extract characters + Data.assign(GetData() + myReadPos, Length); + + // Update reading position + myReadPos += Length; + } + + return *this; +} +Packet& Packet::operator >>(wchar_t* Data) +{ + // First extract string length + Uint32 Length; + *this >> Length; + + if ((Length > 0) && CheckSize(Length * sizeof(Int32))) + { + // Then extract characters + for (Uint32 i = 0; i < Length; ++i) + { + Uint32 c; + *this >> c; + Data[i] = static_cast<wchar_t>(c); + } + Data[Length] = L'\0'; + } + + return *this; +} +Packet& Packet::operator >>(std::wstring& Data) +{ + // First extract string length + Uint32 Length; + *this >> Length; + + Data.clear(); + if ((Length > 0) && CheckSize(Length * sizeof(Int32))) + { + // Then extract characters + for (Uint32 i = 0; i < Length; ++i) + { + Uint32 c; + *this >> c; + Data += static_cast<wchar_t>(c); + } + } + + return *this; +} + + +//////////////////////////////////////////////////////////// +/// Operator << overloads to put data into the packet +//////////////////////////////////////////////////////////// +Packet& Packet::operator <<(bool Data) +{ + *this << static_cast<Uint8>(Data); + return *this; +} +Packet& Packet::operator <<(Int8 Data) +{ + Append(&Data, sizeof(Data)); + return *this; +} +Packet& Packet::operator <<(Uint8 Data) +{ + Append(&Data, sizeof(Data)); + return *this; +} +Packet& Packet::operator <<(Int16 Data) +{ + Int16 ToWrite = htons(Data); + Append(&ToWrite, sizeof(ToWrite)); + return *this; +} +Packet& Packet::operator <<(Uint16 Data) +{ + Uint16 ToWrite = htons(Data); + Append(&ToWrite, sizeof(ToWrite)); + return *this; +} +Packet& Packet::operator <<(Int32 Data) +{ + Int32 ToWrite = htonl(Data); + Append(&ToWrite, sizeof(ToWrite)); + return *this; +} +Packet& Packet::operator <<(Uint32 Data) +{ + Uint32 ToWrite = htonl(Data); + Append(&ToWrite, sizeof(ToWrite)); + return *this; +} +Packet& Packet::operator <<(float Data) +{ + Append(&Data, sizeof(Data)); + return *this; +} +Packet& Packet::operator <<(double Data) +{ + Append(&Data, sizeof(Data)); + return *this; +} +Packet& Packet::operator <<(const char* Data) +{ + // First insert string length + Uint32 Length = 0; + for (const char* c = Data; *c != '\0'; ++c) + ++Length; + *this << Length; + + // Then insert characters + Append(Data, Length * sizeof(char)); + + return *this; +} +Packet& Packet::operator <<(const std::string& Data) +{ + // First insert string length + Uint32 Length = static_cast<Uint32>(Data.size()); + *this << Length; + + // Then insert characters + if (Length > 0) + { + Append(Data.c_str(), Length * sizeof(std::string::value_type)); + } + + return *this; +} +Packet& Packet::operator <<(const wchar_t* Data) +{ + // First insert string length + Uint32 Length = 0; + for (const wchar_t* c = Data; *c != L'\0'; ++c) + ++Length; + *this << Length; + + // Then insert characters + for (const wchar_t* c = Data; *c != L'\0'; ++c) + *this << static_cast<Int32>(*c); + + return *this; +} +Packet& Packet::operator <<(const std::wstring& Data) +{ + // First insert string length + Uint32 Length = static_cast<Uint32>(Data.size()); + *this << Length; + + // Then insert characters + if (Length > 0) + { + for (std::wstring::const_iterator c = Data.begin(); c != Data.end(); ++c) + *this << static_cast<Int32>(*c); + } + + return *this; +} + + +//////////////////////////////////////////////////////////// +/// Check if the packet can extract a given size of bytes +//////////////////////////////////////////////////////////// +bool Packet::CheckSize(std::size_t Size) +{ + myIsValid = myIsValid && (myReadPos + Size <= myData.size()); + + return myIsValid; +} + + +//////////////////////////////////////////////////////////// +/// Called before the packet is sent to the network +//////////////////////////////////////////////////////////// +const char* Packet::OnSend(std::size_t& DataSize) +{ + DataSize = GetDataSize(); + return GetData(); +} + + +//////////////////////////////////////////////////////////// +/// Called after the packet has been received from the network +//////////////////////////////////////////////////////////// +void Packet::OnReceive(const char* Data, std::size_t DataSize) +{ + Append(Data, DataSize); +} + +} // namespace sf diff --git a/Externals/SFML/src/SFML/Network/SelectorBase.cpp b/Externals/SFML/src/SFML/Network/SelectorBase.cpp new file mode 100644 index 0000000000..ebe31a7be7 --- /dev/null +++ b/Externals/SFML/src/SFML/Network/SelectorBase.cpp @@ -0,0 +1,132 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +#ifdef _MSC_VER + #pragma warning(disable : 4127) // "conditional expression is constant" generated by the FD_SET macro +#endif + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Network/SelectorBase.hpp> + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// Default constructor +//////////////////////////////////////////////////////////// +SelectorBase::SelectorBase() : +myMaxSocket(0) +{ + Clear(); +} + + +//////////////////////////////////////////////////////////// +/// Add a socket to watch +//////////////////////////////////////////////////////////// +void SelectorBase::Add(SocketHelper::SocketType Socket) +{ + FD_SET(Socket, &mySet); + + int Size = static_cast<int>(Socket); + if (Size > myMaxSocket) + myMaxSocket = Size; +} + + +//////////////////////////////////////////////////////////// +/// Remove a socket +//////////////////////////////////////////////////////////// +void SelectorBase::Remove(SocketHelper::SocketType Socket) +{ + FD_CLR(Socket, &mySet); +} + + +//////////////////////////////////////////////////////////// +/// Remove all sockets +//////////////////////////////////////////////////////////// +void SelectorBase::Clear() +{ + FD_ZERO(&mySet); + FD_ZERO(&mySetReady); + + myMaxSocket = 0; +} + + +//////////////////////////////////////////////////////////// +/// Wait and collect sockets which are ready for reading. +/// This functions will return either when at least one socket +/// is ready, or when the given time is out +//////////////////////////////////////////////////////////// +unsigned int SelectorBase::Wait(float Timeout) +{ + // Setup the timeout structure + timeval Time; + Time.tv_sec = static_cast<long>(Timeout); + Time.tv_usec = (static_cast<long>(Timeout * 1000) % 1000) * 1000; + + // Prepare the set of sockets to return + mySetReady = mySet; + + // Wait until one of the sockets is ready for reading, or timeout is reached + int NbSockets = select(myMaxSocket + 1, &mySetReady, NULL, NULL, Timeout > 0 ? &Time : NULL); + + return NbSockets >= 0 ? static_cast<unsigned int>(NbSockets) : 0; +} + + +//////////////////////////////////////////////////////////// +/// After a call to Wait(), get the Index-th socket which is +/// ready for reading. The total number of sockets ready +/// is the integer returned by the previous call to Wait() +//////////////////////////////////////////////////////////// +SocketHelper::SocketType SelectorBase::GetSocketReady(unsigned int Index) +{ + // The standard FD_xxx interface doesn't define a direct access, + // so we must go through the whole set to find the socket we're looking for + for (int i = 0; i < myMaxSocket + 1; ++i) + { + if (FD_ISSET(i, &mySetReady)) + { + // Current socket is ready, but is it the Index-th one ? + if (Index > 0) + { + Index--; + } + else + { + return static_cast<SocketHelper::SocketType>(i); + } + } + } + + // Invalid index : return an invalid socket + return SocketHelper::InvalidSocket(); +} + +} // namespace sf diff --git a/Externals/SFML/src/SFML/Network/SocketTCP.cpp b/Externals/SFML/src/SFML/Network/SocketTCP.cpp new file mode 100644 index 0000000000..f7f9ec1498 --- /dev/null +++ b/Externals/SFML/src/SFML/Network/SocketTCP.cpp @@ -0,0 +1,490 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Network/SocketTCP.hpp> +#include <SFML/Network/IPAddress.hpp> +#include <SFML/Network/Packet.hpp> +#include <SFML/Network/SocketHelper.hpp> +#include <algorithm> +#include <iostream> +#include <string.h> + + +#ifdef _MSC_VER + #pragma warning(disable : 4127) // "conditional expression is constant" generated by the FD_SET macro +#endif + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// Default constructor +//////////////////////////////////////////////////////////// +SocketTCP::SocketTCP() +{ + Create(SocketHelper::InvalidSocket()); +} + + +//////////////////////////////////////////////////////////// +/// Change the blocking state of the socket +//////////////////////////////////////////////////////////// +void SocketTCP::SetBlocking(bool Blocking) +{ + // Make sure our socket is valid + if (!IsValid()) + Create(); + + SocketHelper::SetBlocking(mySocket, Blocking); + myIsBlocking = Blocking; +} + + +//////////////////////////////////////////////////////////// +/// Connect to another computer on a specified port +//////////////////////////////////////////////////////////// +Socket::Status SocketTCP::Connect(unsigned short Port, const IPAddress& HostAddress, float Timeout) +{ + // Make sure our socket is valid + if (!IsValid()) + Create(); + + // Build the host address + sockaddr_in SockAddr; + memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero)); + SockAddr.sin_addr.s_addr = inet_addr(HostAddress.ToString().c_str()); + SockAddr.sin_family = AF_INET; + SockAddr.sin_port = htons(Port); + + if (Timeout <= 0) + { + // ----- We're not using a timeout : just try to connect ----- + + if (connect(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1) + { + // Failed to connect + return SocketHelper::GetErrorStatus(); + } + + // Connection succeeded + return Socket::Done; + } + else + { + // ----- We're using a timeout : we'll need a few tricks to make it work ----- + + // Save the previous blocking state + bool IsBlocking = myIsBlocking; + + // Switch to non-blocking to enable our connection timeout + if (IsBlocking) + SetBlocking(false); + + // Try to connect to host + if (connect(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) >= 0) + { + // We got instantly connected! (it may no happen a lot...) + return Socket::Done; + } + + // Get the error status + Socket::Status Status = SocketHelper::GetErrorStatus(); + + // If we were in non-blocking mode, return immediatly + if (!IsBlocking) + return Status; + + // Otherwise, wait until something happens to our socket (success, timeout or error) + if (Status == Socket::NotReady) + { + // Setup the selector + fd_set Selector; + FD_ZERO(&Selector); + FD_SET(mySocket, &Selector); + + // Setup the timeout + timeval Time; + Time.tv_sec = static_cast<long>(Timeout); + Time.tv_usec = (static_cast<long>(Timeout * 1000) % 1000) * 1000; + + // Wait for something to write on our socket (would mean the connection has been accepted) + if (select(static_cast<int>(mySocket + 1), NULL, &Selector, NULL, &Time) > 0) + { + // Connection succeeded + Status = Socket::Done; + } + else + { + // Failed to connect before timeout is over + Status = SocketHelper::GetErrorStatus(); + } + } + + // Switch back to blocking mode + SetBlocking(true); + + return Status; + } +} + + +//////////////////////////////////////////////////////////// +/// Listen to a specified port for incoming data or connections +//////////////////////////////////////////////////////////// +bool SocketTCP::Listen(unsigned short Port) +{ + // Make sure our socket is valid + if (!IsValid()) + Create(); + + // Build the address + sockaddr_in SockAddr; + memset(SockAddr.sin_zero, 0, sizeof(SockAddr.sin_zero)); + SockAddr.sin_addr.s_addr = htonl(INADDR_ANY); + SockAddr.sin_family = AF_INET; + SockAddr.sin_port = htons(Port); + + // Bind the socket to the specified port + if (bind(mySocket, reinterpret_cast<sockaddr*>(&SockAddr), sizeof(SockAddr)) == -1) + { + // Not likely to happen, but... + std::cerr << "Failed to bind socket to port " << Port << std::endl; + return false; + } + + // Listen to the bound port + if (listen(mySocket, 0) == -1) + { + // Oops, socket is deaf + std::cerr << "Failed to listen to port " << Port << std::endl; + return false; + } + + return true; +} + + +//////////////////////////////////////////////////////////// +/// Wait for a connection (must be listening to a port). +/// This function will block if the socket is blocking +//////////////////////////////////////////////////////////// +Socket::Status SocketTCP::Accept(SocketTCP& Connected, IPAddress* Address) +{ + // Address that will be filled with client informations + sockaddr_in ClientAddress; + SocketHelper::LengthType Length = sizeof(ClientAddress); + + // Accept a new connection + Connected = accept(mySocket, reinterpret_cast<sockaddr*>(&ClientAddress), &Length); + + // Check errors + if (!Connected.IsValid()) + { + if (Address) + *Address = IPAddress(); + + return SocketHelper::GetErrorStatus(); + } + + // Fill address if requested + if (Address) + *Address = IPAddress(inet_ntoa(ClientAddress.sin_addr)); + + return Socket::Done; +} + + +//////////////////////////////////////////////////////////// +/// Send an array of bytes to the host (must be connected first) +//////////////////////////////////////////////////////////// +Socket::Status SocketTCP::Send(const char* Data, std::size_t Size) +{ + // First check that socket is valid + if (!IsValid()) + return Socket::Error; + + // Check parameters + if (Data && Size) + { + // Loop until every byte has been sent + int Sent = 0; + int SizeToSend = static_cast<int>(Size); + for (int Length = 0; Length < SizeToSend; Length += Sent) + { + // Send a chunk of data + Sent = send(mySocket, Data + Length, SizeToSend - Length, 0); + + // Check if an error occured + if (Sent <= 0) + return SocketHelper::GetErrorStatus(); + } + + return Socket::Done; + } + else + { + // Error... + std::cerr << "Cannot send data over the network (invalid parameters)" << std::endl; + return Socket::Error; + } +} + + +//////////////////////////////////////////////////////////// +/// Receive an array of bytes from the host (must be connected first). +/// This function will block if the socket is blocking +//////////////////////////////////////////////////////////// +Socket::Status SocketTCP::Receive(char* Data, std::size_t MaxSize, std::size_t& SizeReceived) +{ + // First clear the size received + SizeReceived = 0; + + // Check that socket is valid + if (!IsValid()) + return Socket::Error; + + // Check parameters + if (Data && MaxSize) + { + // Receive a chunk of bytes + int Received = recv(mySocket, Data, static_cast<int>(MaxSize), 0); + + // Check the number of bytes received + if (Received > 0) + { + SizeReceived = static_cast<std::size_t>(Received); + return Socket::Done; + } + else if (Received == 0) + { + return Socket::Disconnected; + } + else + { + return SocketHelper::GetErrorStatus(); + } + } + else + { + // Error... + std::cerr << "Cannot receive data from the network (invalid parameters)" << std::endl; + return Socket::Error; + } +} + + +//////////////////////////////////////////////////////////// +/// Send a packet of data to the host (must be connected first) +//////////////////////////////////////////////////////////// +Socket::Status SocketTCP::Send(Packet& PacketToSend) +{ + // Get the data to send from the packet + std::size_t DataSize = 0; + const char* Data = PacketToSend.OnSend(DataSize); + + // Send the packet size + Uint32 PacketSize = htonl(static_cast<unsigned long>(DataSize)); + Send(reinterpret_cast<const char*>(&PacketSize), sizeof(PacketSize)); + + // Send the packet data + if (PacketSize > 0) + { + return Send(Data, DataSize); + } + else + { + return Socket::Done; + } +} + + +//////////////////////////////////////////////////////////// +/// Receive a packet from the host (must be connected first). +/// This function will block if the socket is blocking +//////////////////////////////////////////////////////////// +Socket::Status SocketTCP::Receive(Packet& PacketToReceive) +{ + // We start by getting the size of the incoming packet + Uint32 PacketSize = 0; + std::size_t Received = 0; + if (myPendingPacketSize < 0) + { + Socket::Status Status = Receive(reinterpret_cast<char*>(&PacketSize), sizeof(PacketSize), Received); + if (Status != Socket::Done) + return Status; + + PacketSize = ntohl(PacketSize); + } + else + { + // There is a pending packet : we already know its size + PacketSize = myPendingPacketSize; + } + + // Then loop until we receive all the packet data + char Buffer[1024]; + while (myPendingPacket.size() < PacketSize) + { + // Receive a chunk of data + std::size_t SizeToGet = std::min(static_cast<std::size_t>(PacketSize - myPendingPacket.size()), sizeof(Buffer)); + Socket::Status Status = Receive(Buffer, SizeToGet, Received); + if (Status != Socket::Done) + { + // We must save the size of the pending packet until we can receive its content + if (Status == Socket::NotReady) + myPendingPacketSize = PacketSize; + return Status; + } + + // Append it into the packet + if (Received > 0) + { + myPendingPacket.resize(myPendingPacket.size() + Received); + char* Begin = &myPendingPacket[0] + myPendingPacket.size() - Received; + memcpy(Begin, Buffer, Received); + } + } + + // We have received all the datas : we can copy it to the user packet, and clear our internal packet + PacketToReceive.Clear(); + if (!myPendingPacket.empty()) + PacketToReceive.OnReceive(&myPendingPacket[0], myPendingPacket.size()); + myPendingPacket.clear(); + myPendingPacketSize = -1; + + return Socket::Done; +} + + +//////////////////////////////////////////////////////////// +/// Close the socket +//////////////////////////////////////////////////////////// +bool SocketTCP::Close() +{ + if (IsValid()) + { + if (!SocketHelper::Close(mySocket)) + { + std::cerr << "Failed to close socket" << std::endl; + return false; + } + + mySocket = SocketHelper::InvalidSocket(); + } + + myIsBlocking = true; + + return true; +} + + +//////////////////////////////////////////////////////////// +/// Check if the socket is in a valid state ; this function +/// can be called any time to check if the socket is OK +//////////////////////////////////////////////////////////// +bool SocketTCP::IsValid() const +{ + return mySocket != SocketHelper::InvalidSocket(); +} + + +//////////////////////////////////////////////////////////// +/// Comparison operator == +//////////////////////////////////////////////////////////// +bool SocketTCP::operator ==(const SocketTCP& Other) const +{ + return mySocket == Other.mySocket; +} + + +//////////////////////////////////////////////////////////// +/// Comparison operator != +//////////////////////////////////////////////////////////// +bool SocketTCP::operator !=(const SocketTCP& Other) const +{ + return mySocket != Other.mySocket; +} + + +//////////////////////////////////////////////////////////// +/// Comparison operator <. +/// Provided for compatibility with standard containers, as +/// comparing two sockets doesn't make much sense... +//////////////////////////////////////////////////////////// +bool SocketTCP::operator <(const SocketTCP& Other) const +{ + return mySocket < Other.mySocket; +} + + +//////////////////////////////////////////////////////////// +/// Construct the socket from a socket descriptor +/// (for internal use only) +//////////////////////////////////////////////////////////// +SocketTCP::SocketTCP(SocketHelper::SocketType Descriptor) +{ + Create(Descriptor); +} + + +//////////////////////////////////////////////////////////// +/// Create the socket +//////////////////////////////////////////////////////////// +void SocketTCP::Create(SocketHelper::SocketType Descriptor) +{ + // Use the given socket descriptor, or get a new one + mySocket = Descriptor ? Descriptor : socket(PF_INET, SOCK_STREAM, 0); + myIsBlocking = true; + + // Reset the pending packet + myPendingPacket.clear(); + myPendingPacketSize = -1; + + // Setup default options + if (IsValid()) + { + // To avoid the "Address already in use" error message when trying to bind to the same port + int Yes = 1; + if (setsockopt(mySocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1) + { + std::cerr << "Failed to set socket option \"SO_REUSEADDR\" ; " + << "binding to a same port may fail if too fast" << std::endl; + } + + // Disable the Nagle algorithm (ie. removes buffering of TCP packets) + if (setsockopt(mySocket, IPPROTO_TCP, TCP_NODELAY, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1) + { + std::cerr << "Failed to set socket option \"TCP_NODELAY\" ; " + << "all your TCP packets will be buffered" << std::endl; + } + + // Set blocking by default (should always be the case anyway) + SetBlocking(true); + } +} + +} // namespace sf diff --git a/Externals/SFML/src/SFML/Network/SocketUDP.cpp b/Externals/SFML/src/SFML/Network/SocketUDP.cpp new file mode 100644 index 0000000000..2cd42274ab --- /dev/null +++ b/Externals/SFML/src/SFML/Network/SocketUDP.cpp @@ -0,0 +1,431 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Network/SocketUDP.hpp> +#include <SFML/Network/IPAddress.hpp> +#include <SFML/Network/Packet.hpp> +#include <algorithm> +#include <iostream> +#include <string.h> + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// Default constructor +//////////////////////////////////////////////////////////// +SocketUDP::SocketUDP() +{ + Create(); +} + + +//////////////////////////////////////////////////////////// +/// Change the blocking state of the socket +//////////////////////////////////////////////////////////// +void SocketUDP::SetBlocking(bool Blocking) +{ + // Make sure our socket is valid + if (!IsValid()) + Create(); + + SocketHelper::SetBlocking(mySocket, Blocking); + myIsBlocking = Blocking; +} + + +//////////////////////////////////////////////////////////// +/// Bind the socket to a specific port +//////////////////////////////////////////////////////////// +bool SocketUDP::Bind(unsigned short Port) +{ + // Check if the socket is already bound to the specified port + if (myPort != Port) + { + // If the socket was previously bound to another port, we need to recreate it + if (myPort != 0) + { + Close(); + Create(); + } + + if (Port != 0) + { + // Build an address with the specified port + sockaddr_in Addr; + Addr.sin_family = AF_INET; + Addr.sin_port = htons(Port); + Addr.sin_addr.s_addr = INADDR_ANY; + memset(Addr.sin_zero, 0, sizeof(Addr.sin_zero)); + + // Bind the socket to the port + if (bind(mySocket, reinterpret_cast<sockaddr*>(&Addr), sizeof(Addr)) == -1) + { + std::cerr << "Failed to bind the socket to port " << Port << std::endl; + myPort = 0; + return false; + } + } + + // Save the new port + myPort = Port; + } + + return true; +} + + +//////////////////////////////////////////////////////////// +/// Unbind the socket to its previous port +//////////////////////////////////////////////////////////// +bool SocketUDP::Unbind() +{ + // To unbind the socket, we just recreate it + if (myPort != 0) + { + Close(); + Create(); + myPort = 0; + } + + return true; +} + + +//////////////////////////////////////////////////////////// +/// Send an array of bytes +//////////////////////////////////////////////////////////// +Socket::Status SocketUDP::Send(const char* Data, std::size_t Size, const IPAddress& Address, unsigned short Port) +{ + // Make sure the socket is valid + if (!IsValid()) + Create(); + + // Check parameters + if (Data && Size) + { + // Build the target address + sockaddr_in Target; + Target.sin_family = AF_INET; + Target.sin_port = htons(Port); + Target.sin_addr.s_addr = inet_addr(Address.ToString().c_str()); + memset(Target.sin_zero, 0, sizeof(Target.sin_zero)); + + // Loop until every byte has been sent + int Sent = 0; + int SizeToSend = static_cast<int>(Size); + for (int Length = 0; Length < SizeToSend; Length += Sent) + { + // Send a chunk of data + Sent = sendto(mySocket, Data + Length, SizeToSend - Length, 0, reinterpret_cast<sockaddr*>(&Target), sizeof(Target)); + + // Check errors + if (Sent <= 0) + return SocketHelper::GetErrorStatus(); + } + + return Socket::Done; + } + else + { + // Error... + std::cerr << "Cannot send data over the network (invalid parameters)" << std::endl; + return Socket::Error; + } +} + + +//////////////////////////////////////////////////////////// +/// Receive an array of bytes. +/// This function will block if the socket is blocking +//////////////////////////////////////////////////////////// +Socket::Status SocketUDP::Receive(char* Data, std::size_t MaxSize, std::size_t& SizeReceived, IPAddress& Address) +{ + // First clear the size received + SizeReceived = 0; + + // Make sure the socket is bound to a port + if (myPort == 0) + { + std::cerr << "Failed to receive data ; the UDP socket first needs to be bound to a port" << std::endl; + return Socket::Error; + } + + // Make sure the socket is valid + if (!IsValid()) + Create(); + + // Check parameters + if (Data && MaxSize) + { + // Data that will be filled with the other computer's address + sockaddr_in Sender; + Sender.sin_family = AF_INET; + Sender.sin_port = htons(myPort); + Sender.sin_addr.s_addr = INADDR_ANY; + memset(Sender.sin_zero, 0, sizeof(Sender.sin_zero)); + SocketHelper::LengthType SenderSize = sizeof(Sender); + + // Receive a chunk of bytes + int Received = recvfrom(mySocket, Data, static_cast<int>(MaxSize), 0, reinterpret_cast<sockaddr*>(&Sender), &SenderSize); + + // Check the number of bytes received + if (Received > 0) + { + Address = IPAddress(inet_ntoa(Sender.sin_addr)); + SizeReceived = static_cast<std::size_t>(Received); + return Socket::Done; + } + else + { + Address = IPAddress(); + return Received == 0 ? Socket::Disconnected : SocketHelper::GetErrorStatus(); + } + } + else + { + // Error... + std::cerr << "Cannot receive data from the network (invalid parameters)" << std::endl; + return Socket::Error; + } +} + + +//////////////////////////////////////////////////////////// +/// Send a packet of data +//////////////////////////////////////////////////////////// +Socket::Status SocketUDP::Send(Packet& PacketToSend, const IPAddress& Address, unsigned short Port) +{ + // Get the data to send from the packet + std::size_t DataSize = 0; + const char* Data = PacketToSend.OnSend(DataSize); + + // Send the packet size + Uint32 PacketSize = htonl(static_cast<unsigned long>(DataSize)); + Send(reinterpret_cast<const char*>(&PacketSize), sizeof(PacketSize), Address, Port); + + // Send the packet data + if (PacketSize > 0) + { + return Send(Data, DataSize, Address, Port); + } + else + { + return Socket::Done; + } +} + + +//////////////////////////////////////////////////////////// +/// Receive a packet. +/// This function will block if the socket is blocking +//////////////////////////////////////////////////////////// +Socket::Status SocketUDP::Receive(Packet& PacketToReceive, IPAddress& Address) +{ + // This is not safe at all, as data can be lost, duplicated, or arrive in a different order. + // So if a packet is split into more than one chunk, nobody knows what could happen... + // Conclusion : we shouldn't use packets with UDP, unless we build a more complex protocol on top of it. + + // We start by getting the size of the incoming packet + Uint32 PacketSize = 0; + std::size_t Received = 0; + if (myPendingPacketSize < 0) + { + Socket::Status Status = Receive(reinterpret_cast<char*>(&PacketSize), sizeof(PacketSize), Received, Address); + if (Status != Socket::Done) + return Status; + + PacketSize = ntohl(PacketSize); + } + else + { + // There is a pending packet : we already know its size + PacketSize = myPendingPacketSize; + } + + // Clear the user packet + PacketToReceive.Clear(); + + // Use another address instance for receiving the packet data ; + // chunks of data coming from a different sender will be discarded (and lost...) + IPAddress Sender; + + // Then loop until we receive all the packet data + char Buffer[1024]; + while (myPendingPacket.size() < PacketSize) + { + // Receive a chunk of data + std::size_t SizeToGet = std::min(static_cast<std::size_t>(PacketSize - myPendingPacket.size()), sizeof(Buffer)); + Socket::Status Status = Receive(Buffer, SizeToGet, Received, Sender); + if (Status != Socket::Done) + { + // We must save the size of the pending packet until we can receive its content + if (Status == Socket::NotReady) + myPendingPacketSize = PacketSize; + return Status; + } + + // Append it into the packet + if ((Sender == Address) && (Received > 0)) + { + myPendingPacket.resize(myPendingPacket.size() + Received); + char* Begin = &myPendingPacket[0] + myPendingPacket.size() - Received; + memcpy(Begin, Buffer, Received); + } + } + + // We have received all the datas : we can copy it to the user packet, and clear our internal packet + PacketToReceive.Clear(); + if (!myPendingPacket.empty()) + PacketToReceive.OnReceive(&myPendingPacket[0], myPendingPacket.size()); + myPendingPacket.clear(); + myPendingPacketSize = -1; + + return Socket::Done; +} + + +//////////////////////////////////////////////////////////// +/// Close the socket +//////////////////////////////////////////////////////////// +bool SocketUDP::Close() +{ + if (IsValid()) + { + if (!SocketHelper::Close(mySocket)) + { + std::cerr << "Failed to close socket" << std::endl; + return false; + } + + mySocket = SocketHelper::InvalidSocket(); + } + + myPort = 0; + myIsBlocking = true; + + return true; +} + + +//////////////////////////////////////////////////////////// +/// Check if the socket is in a valid state ; this function +/// can be called any time to check if the socket is OK +//////////////////////////////////////////////////////////// +bool SocketUDP::IsValid() const +{ + return mySocket != SocketHelper::InvalidSocket(); +} + + +//////////////////////////////////////////////////////////// +/// Get the port the socket is currently bound to +//////////////////////////////////////////////////////////// +unsigned short SocketUDP::GetPort() const +{ + return myPort; +} + + +//////////////////////////////////////////////////////////// +/// Comparison operator == +//////////////////////////////////////////////////////////// +bool SocketUDP::operator ==(const SocketUDP& Other) const +{ + return mySocket == Other.mySocket; +} + + +//////////////////////////////////////////////////////////// +/// Comparison operator != +//////////////////////////////////////////////////////////// +bool SocketUDP::operator !=(const SocketUDP& Other) const +{ + return mySocket != Other.mySocket; +} + + +//////////////////////////////////////////////////////////// +/// Comparison operator <. +/// Provided for compatibility with standard containers, as +/// comparing two sockets doesn't make much sense... +//////////////////////////////////////////////////////////// +bool SocketUDP::operator <(const SocketUDP& Other) const +{ + return mySocket < Other.mySocket; +} + + +//////////////////////////////////////////////////////////// +/// Construct the socket from a socket descriptor +/// (for internal use only) +//////////////////////////////////////////////////////////// +SocketUDP::SocketUDP(SocketHelper::SocketType Descriptor) +{ + Create(Descriptor); +} + + +//////////////////////////////////////////////////////////// +/// Create the socket +//////////////////////////////////////////////////////////// +void SocketUDP::Create(SocketHelper::SocketType Descriptor) +{ + // Use the given socket descriptor, or get a new one + mySocket = Descriptor ? Descriptor : socket(PF_INET, SOCK_DGRAM, 0); + myIsBlocking = true; + + // Clear the last port used + myPort = 0; + + // Reset the pending packet + myPendingPacket.clear(); + myPendingPacketSize = -1; + + // Setup default options + if (IsValid()) + { + // To avoid the "Address already in use" error message when trying to bind to the same port + int Yes = 1; + if (setsockopt(mySocket, SOL_SOCKET, SO_REUSEADDR, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1) + { + std::cerr << "Failed to set socket option \"reuse address\" ; " + << "binding to a same port may fail if too fast" << std::endl; + } + + // Enable broadcast by default + if (setsockopt(mySocket, SOL_SOCKET, SO_BROADCAST, reinterpret_cast<char*>(&Yes), sizeof(Yes)) == -1) + { + std::cerr << "Failed to enable broadcast on UDP socket" << std::endl; + } + + // Set blocking by default (should always be the case anyway) + SetBlocking(true); + } +} + +} // namespace sf diff --git a/Externals/SFML/src/SFML/Network/Unix/SocketHelper.cpp b/Externals/SFML/src/SFML/Network/Unix/SocketHelper.cpp new file mode 100644 index 0000000000..2a2e6b2cfc --- /dev/null +++ b/Externals/SFML/src/SFML/Network/Unix/SocketHelper.cpp @@ -0,0 +1,83 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Network/SocketHelper.hpp> +#include <errno.h> +#include <fcntl.h> + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// Return the value of the invalid socket +//////////////////////////////////////////////////////////// +SocketHelper::SocketType SocketHelper::InvalidSocket() +{ + return -1; +} + + +//////////////////////////////////////////////////////////// +/// Close / destroy a socket +//////////////////////////////////////////////////////////// +bool SocketHelper::Close(SocketHelper::SocketType Socket) +{ + return close(Socket) != -1; +} + + +//////////////////////////////////////////////////////////// +/// Set a socket as blocking or non-blocking +//////////////////////////////////////////////////////////// +void SocketHelper::SetBlocking(SocketHelper::SocketType Socket, bool Block) +{ + int Status = fcntl(Socket, F_GETFL); + if (Block) + fcntl(Socket, F_SETFL, Status & ~O_NONBLOCK); + else + fcntl(Socket, F_SETFL, Status | O_NONBLOCK); +} + + +//////////////////////////////////////////////////////////// +/// Get the last socket error status +//////////////////////////////////////////////////////////// +Socket::Status SocketHelper::GetErrorStatus() +{ + switch (errno) + { + case EWOULDBLOCK : return Socket::NotReady; + case ECONNABORTED : return Socket::Disconnected; + case ECONNRESET : return Socket::Disconnected; + case ETIMEDOUT : return Socket::Disconnected; + case ENETRESET : return Socket::Disconnected; + case ENOTCONN : return Socket::Disconnected; + default : return Socket::Error; + } +} + +} // namespace sf diff --git a/Externals/SFML/src/SFML/Network/Win32/SocketHelper.cpp b/Externals/SFML/src/SFML/Network/Win32/SocketHelper.cpp new file mode 100644 index 0000000000..f3ddb0855e --- /dev/null +++ b/Externals/SFML/src/SFML/Network/Win32/SocketHelper.cpp @@ -0,0 +1,100 @@ +//////////////////////////////////////////////////////////// +// +// SFML - Simple and Fast Multimedia Library +// Copyright (C) 2007-2008 Laurent Gomila (laurent.gom@gmail.com) +// +// This software is provided 'as-is', without any express or implied warranty. +// In no event will the authors be held liable for any damages arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it freely, +// subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; +// you must not claim that you wrote the original software. +// If you use this software in a product, an acknowledgment +// in the product documentation would be appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, +// and must not be misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// +//////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////// +// Headers +//////////////////////////////////////////////////////////// +#include <SFML/Network/SocketHelper.hpp> + + +namespace sf +{ +//////////////////////////////////////////////////////////// +/// Return the value of the invalid socket +//////////////////////////////////////////////////////////// +SocketHelper::SocketType SocketHelper::InvalidSocket() +{ + return INVALID_SOCKET; +} + + +//////////////////////////////////////////////////////////// +/// Close / destroy a socket +//////////////////////////////////////////////////////////// +bool SocketHelper::Close(SocketHelper::SocketType Socket) +{ + return closesocket(Socket) != -1; +} + + +//////////////////////////////////////////////////////////// +/// Set a socket as blocking or non-blocking +//////////////////////////////////////////////////////////// +void SocketHelper::SetBlocking(SocketHelper::SocketType Socket, bool Block) +{ + unsigned long Blocking = Block ? 0 : 1; + ioctlsocket(Socket, FIONBIO, &Blocking); +} + + +//////////////////////////////////////////////////////////// +/// Get the last socket error status +//////////////////////////////////////////////////////////// +Socket::Status SocketHelper::GetErrorStatus() +{ + switch (WSAGetLastError()) + { + case WSAEWOULDBLOCK : return Socket::NotReady; + case WSAECONNABORTED : return Socket::Disconnected; + case WSAECONNRESET : return Socket::Disconnected; + case WSAETIMEDOUT : return Socket::Disconnected; + case WSAENETRESET : return Socket::Disconnected; + case WSAENOTCONN : return Socket::Disconnected; + default : return Socket::Error; + } +} + + +//////////////////////////////////////////////////////////// +// Windows needs some initialization and cleanup to get +// sockets working properly... so let's create a class that will +// do it automatically +//////////////////////////////////////////////////////////// +struct SocketInitializer +{ + SocketInitializer() + { + WSADATA InitData; + WSAStartup(MAKEWORD(2,2), &InitData); + } + + ~SocketInitializer() + { + WSACleanup(); + } +}; + +SocketInitializer GlobalInitializer; + +} // namespace sf diff --git a/Source/Dolphin.sln b/Source/Dolphin.sln index d8b3cc9072..2a4606a6b0 100644 --- a/Source/Dolphin.sln +++ b/Source/Dolphin.sln @@ -182,6 +182,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DSPSpy", "DSPSpy\DSPSpy.vcp EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SOIL", "..\Externals\SOIL\SOIL.vcproj", "{C0B84DA9-FF15-4FAB-9590-17132F3C6DE4}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SFML_Network", "..\Externals\SFML\build\vc2008\sfml-network.vcproj", "{823DDC98-42D5-4A38-88CF-9DC06C788AE4}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Win32 = Debug|Win32
@@ -604,6 +606,20 @@ Global {C0B84DA9-FF15-4FAB-9590-17132F3C6DE4}.Release|Win32.Build.0 = Release|Win32
{C0B84DA9-FF15-4FAB-9590-17132F3C6DE4}.Release|x64.ActiveCfg = Release|x64
{C0B84DA9-FF15-4FAB-9590-17132F3C6DE4}.Release|x64.Build.0 = Release|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Debug|Win32.ActiveCfg = Debug|Win32
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Debug|Win32.Build.0 = Debug|Win32
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Debug|x64.ActiveCfg = Debug|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Debug|x64.Build.0 = Debug|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.DebugFast|Win32.ActiveCfg = Debug|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.DebugFast|x64.ActiveCfg = Debug|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.DebugFast|x64.Build.0 = Debug|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release_JITIL|Win32.ActiveCfg = Release|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release_JITIL|x64.ActiveCfg = Release|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release_JITIL|x64.Build.0 = Release|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release|Win32.ActiveCfg = Release|Win32
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release|Win32.Build.0 = Release|Win32
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release|x64.ActiveCfg = Release|x64
+ {823DDC98-42D5-4A38-88CF-9DC06C788AE4}.Release|x64.Build.0 = Release|x64
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
|
