diff --git a/platform/platform.pro b/platform/platform.pro index d05cc1f1e4..c6fb2fd10e 100644 --- a/platform/platform.pro +++ b/platform/platform.pro @@ -105,3 +105,4 @@ SOURCES += \ preferred_languages.cpp \ servers_list.cpp \ settings.cpp \ + socket.cpp \ diff --git a/platform/socket.cpp b/platform/socket.cpp new file mode 100644 index 0000000000..7e9129d9d6 --- /dev/null +++ b/platform/socket.cpp @@ -0,0 +1,91 @@ +#include "socket.hpp" + +#include "base/assert.hpp" + +#include "std/algorithm.hpp" + +namespace platform { + +TestSocket::TestSocket() + : m_isConnected(false) +{ +} + +TestSocket::~TestSocket() +{ + m_isConnected = false; +} + +bool TestSocket::Open(string const & host, uint16_t port) +{ + m_isConnected = true; + return true; +} + +void TestSocket::Close() +{ + m_isConnected = false; +} + +bool TestSocket::Read(uint8_t * data, uint32_t count) +{ + if (!m_isConnected) + return false; + + lock_guard lg(m_inputMutex); + + if (m_input.size() < count) + return false; + + copy( m_input.data(), m_input.data()+count, data ); + m_input.erase( m_input.begin(), m_input.begin() + count ); + return true; +} + +bool TestSocket::Write(uint8_t const * data, uint32_t count) +{ + if (!m_isConnected) + return false; + + lock_guard lg(m_outputMutex); + m_output.insert(m_output.end(), data, data + count); + return true; +} + +void TestSocket::SetTimeout(uint32_t milliseconds) +{ +} + +bool TestSocket::HasInput() const +{ + lock_guard lg(m_inputMutex); + return !m_input.empty(); +} + +bool TestSocket::HasOutput() const +{ + lock_guard lg(m_outputMutex); + return !m_output.empty(); +} + +void TestSocket::AddInput(uint8_t const * data, uint32_t count) +{ + ASSERT(m_isConnected, ()); + + lock_guard lg(m_inputMutex); + m_input.insert(m_input.end(), data, data + count); +} + +size_t TestSocket::FetchOutput(vector & destination) +{ + lock_guard lg(m_outputMutex); + + size_t const outputSize = m_output.size(); + if (outputSize == 0) + return 0; + + destination.insert(destination.end(), m_output.begin(), m_output.end()); + m_output.clear(); + return outputSize; +} +} // namespace platform diff --git a/platform/socket.hpp b/platform/socket.hpp index 92a7b74d07..3d2e0d2b05 100644 --- a/platform/socket.hpp +++ b/platform/socket.hpp @@ -1,31 +1,78 @@ #pragma once +#include "std/mutex.hpp" #include "std/string.hpp" #include "std/target_os.hpp" - -#if defined(OMIM_OS_IPHONE) || defined(OMIM_OS_MAC) -@class SocketImpl; -#else -class SocketImpl; -#endif +#include "std/vector.hpp" namespace platform { class Socket { public: - Socket(); - ~Socket(); + virtual ~Socket() {} - bool Open(string const & host, uint16_t port); - void Close(); + virtual bool Open(string const & host, uint16_t port) = 0; + virtual void Close() = 0; - bool Read(uint8_t * data, uint32_t count); - bool Write(uint8_t const * data, uint32_t count); + virtual bool Read(uint8_t * data, uint32_t count) = 0; + virtual bool Write(uint8_t const * data, uint32_t count) = 0; - void SetTimeout(uint32_t milliseconds); + virtual void SetTimeout(uint32_t milliseconds) = 0; +}; + +class PlatformSocket final : public Socket +{ + PlatformSocket(); + virtual ~PlatformSocket(); + virtual bool Open(string const & host, uint16_t port) override; + virtual void Close() override; + virtual bool Read(uint8_t * data, uint32_t count) override; + virtual bool Write(uint8_t const * data, uint32_t count) override; + virtual void SetTimeout(uint32_t milliseconds) override; +}; + +class MockSocket final : public Socket +{ +public: + virtual bool Open(string const & host, uint16_t port) override { return false; } + virtual void Close() override {} + + virtual bool Read(uint8_t * data, uint32_t count) override { return false; } + virtual bool Write(uint8_t const * data, uint32_t count) override { return false; } + + virtual void SetTimeout(uint32_t milliseconds) override {} +}; + +class TestSocket final : public Socket +{ +public: + TestSocket(); + virtual ~TestSocket(); + virtual bool Open(string const & host, uint16_t port) override; + virtual void Close() override; + virtual bool Read(uint8_t * data, uint32_t count) override; + virtual bool Write(uint8_t const * data, uint32_t count) override; + virtual void SetTimeout(uint32_t milliseconds) override; + + bool HasInput() const; + bool HasOutput() const; + + // Simulate server writing + void AddInput(uint8_t const * data, uint32_t count); + + // Simulate server reading + // returns size of read data + size_t FetchOutput(vector & destination); private: - SocketImpl * m_socketImpl = nullptr; + bool m_isConnected; + + vector m_input; + mutable mutex m_inputMutex; + + vector m_output; + mutable mutex m_outputMutex; }; + } // namespace platform diff --git a/platform/socket_apple.mm b/platform/socket_apple.mm index 57dd0ebc18..d7abb737f3 100644 --- a/platform/socket_apple.mm +++ b/platform/socket_apple.mm @@ -22,22 +22,24 @@ namespace platform { -Socket::Socket() { m_socketImpl = [[SocketImpl alloc] init]; } -Socket::~Socket() +PlatformSocket::PlatformSocket() {} +PlatformSocket::~PlatformSocket() { Close(); - m_socketImpl = nil; } -bool Socket::Open(string const & host, uint16_t port) +bool PlatformSocket::Open(string const & host, uint16_t port) { - return [m_socketImpl open:@(host.c_str()) port:port]; + return false; } -void Socket::Close() { [m_socketImpl close]; } -bool Socket::Read(uint8_t * data, uint32_t count) { return [m_socketImpl read:data count:count]; } -bool Socket::Write(uint8_t const * data, uint32_t count) +void PlatformSocket::Close() {} +bool PlatformSocket::Read(uint8_t * data, uint32_t count) { return false; } +bool PlatformSocket::Write(uint8_t const * data, uint32_t count) +{ + return false; +} +void PlatformSocket::SetTimeout(uint32_t milliseconds) { - return [m_socketImpl write:data count:count]; } } // namespace platform