Skip to content

Commit

Permalink
Network/TcpClient: Make TcpClient a Stream
Browse files Browse the repository at this point in the history
  • Loading branch information
SirLynix committed Nov 23, 2015
1 parent eb2bf06 commit 1acf41e
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 10 deletions.
2 changes: 1 addition & 1 deletion include/Nazara/Core/Stream.hpp
Expand Up @@ -55,7 +55,7 @@ namespace Nz
Stream& operator=(Stream&&) = default;

protected:
inline Stream(UInt32 openMode);
inline Stream(UInt32 streamOptions = StreamOption_None, UInt32 openMode = OpenMode_NotOpen);

virtual void FlushStream() = 0;
virtual std::size_t ReadBlock(void* buffer, std::size_t size) = 0;
Expand Down
4 changes: 2 additions & 2 deletions include/Nazara/Core/Stream.inl
Expand Up @@ -7,9 +7,9 @@

namespace Nz
{
inline Stream::Stream(UInt32 openMode) :
inline Stream::Stream(UInt32 streamOptions, UInt32 openMode) :
m_openMode(openMode),
m_streamOptions(0)
m_streamOptions(streamOptions)
{
}

Expand Down
13 changes: 12 additions & 1 deletion include/Nazara/Network/TcpClient.hpp
Expand Up @@ -9,12 +9,13 @@

#include <Nazara/Prerequesites.hpp>
#include <Nazara/Core/Signal.hpp>
#include <Nazara/Core/Stream.hpp>
#include <Nazara/Network/AbstractSocket.hpp>
#include <Nazara/Network/IpAddress.hpp>

namespace Nz
{
class NAZARA_NETWORK_API TcpClient : public AbstractSocket
class NAZARA_NETWORK_API TcpClient : public AbstractSocket, public Stream
{
friend class TcpServer;

Expand All @@ -30,9 +31,13 @@ namespace Nz
void EnableLowDelay(bool lowDelay);
void EnableKeepAlive(bool keepAlive, UInt64 msTime = 10000, UInt64 msInterval = 1000);

bool EndOfStream() const override;

UInt64 GetCursorPos() const override;
inline UInt64 GetKeepAliveInterval() const;
inline UInt64 GetKeepAliveTime() const;
inline IpAddress GetRemoteAddress() const;
UInt64 GetSize() const override;

inline bool IsLowDelayEnabled() const;
inline bool IsKeepAliveEnabled() const;
Expand All @@ -41,13 +46,19 @@ namespace Nz

bool Send(const void* buffer, std::size_t size, std::size_t* sent);

bool SetCursorPos(UInt64 offset) override;

bool WaitForConnected(UInt64 msTimeout = 3000);

private:
void FlushStream() override;

void OnClose() override;
void OnOpened() override;

std::size_t ReadBlock(void* buffer, std::size_t size) override;
void Reset(SocketHandle handle, const IpAddress& peerAddress);
std::size_t WriteBlock(const void* buffer, std::size_t size) override;

IpAddress m_peerAddress;
UInt64 m_keepAliveInterval;
Expand Down
2 changes: 2 additions & 0 deletions include/Nazara/Network/TcpClient.inl
Expand Up @@ -9,6 +9,7 @@ namespace Nz
{
inline TcpClient::TcpClient() :
AbstractSocket(SocketType_TCP),
Stream(StreamOption_Sequential),
m_keepAliveInterval(1000), //TODO: Query OS default value
m_keepAliveTime(7'200'000), //TODO: Query OS default value
m_isKeepAliveEnabled(false), //TODO: Query OS default value
Expand All @@ -18,6 +19,7 @@ namespace Nz

inline TcpClient::TcpClient(TcpClient&& tcpClient) :
AbstractSocket(std::move(tcpClient)),
Stream(std::move(tcpClient)),
m_peerAddress(std::move(tcpClient.m_peerAddress)),
m_keepAliveInterval(tcpClient.m_keepAliveInterval),
m_keepAliveTime(tcpClient.m_keepAliveTime),
Expand Down
11 changes: 5 additions & 6 deletions src/Nazara/Core/File.cpp
Expand Up @@ -31,7 +31,6 @@
namespace Nz
{
File::File() :
Stream(OpenMode_NotOpen),
m_impl(nullptr)
{
}
Expand Down Expand Up @@ -75,6 +74,8 @@ namespace Nz
m_impl->Close();
delete m_impl;
m_impl = nullptr;

m_openMode = OpenMode_NotOpen;
}
}

Expand Down Expand Up @@ -208,20 +209,18 @@ namespace Nz
if (m_filePath.IsEmpty())
return false;

if (openMode != 0)
m_openMode = openMode;

if (m_openMode == 0)
if (openMode == OpenMode_NotOpen)
return false;

std::unique_ptr<FileImpl> impl(new FileImpl(this));
if (!impl->Open(m_filePath, m_openMode))
if (!impl->Open(m_filePath, openMode))
{
ErrorFlags flags(ErrorFlag_Silent); // Silencieux par défaut
NazaraError("Failed to open \"" + m_filePath + "\": " + Error::GetLastSystemError());
return false;
}

m_openMode = openMode;
m_impl = impl.release();

if (m_openMode & OpenMode_Text)
Expand Down
71 changes: 71 additions & 0 deletions src/Nazara/Network/TcpClient.cpp
Expand Up @@ -94,6 +94,22 @@ namespace Nz
}
}

bool TcpClient::EndOfStream() const
{
return QueryAvailableBytes() == 0;
}

UInt64 TcpClient::GetCursorPos() const
{
NazaraError("GetCursorPos() cannot be used on sequential streams");
return 0;
}

UInt64 TcpClient::GetSize() const
{
return QueryAvailableBytes();
}

bool TcpClient::Receive(void* buffer, std::size_t size, std::size_t* received)
{
NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle");
Expand Down Expand Up @@ -165,6 +181,12 @@ namespace Nz
return true;
}

bool TcpClient::SetCursorPos(UInt64 offset)
{
NazaraError("SetCursorPos() cannot be used on sequential streams");
return false;
}

bool TcpClient::WaitForConnected(UInt64 msTimeout)
{
switch (m_state)
Expand Down Expand Up @@ -209,10 +231,15 @@ namespace Nz
return false;
}

void TcpClient::FlushStream()
{
}

void TcpClient::OnClose()
{
AbstractSocket::OnClose();

m_openMode = OpenMode_NotOpen;
m_peerAddress = IpAddress::Invalid;
}

Expand All @@ -229,12 +256,56 @@ namespace Nz
NazaraWarning("Failed to set socket keep alive mode (0x" + String::Number(errorCode, 16) + ')');

m_peerAddress = IpAddress::Invalid;
m_openMode = OpenMode_ReadWrite;
}

std::size_t TcpClient::ReadBlock(void* buffer, std::size_t size)
{
NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle");

CallOnExit restoreBlocking;
if (!m_isBlockingEnabled)
{
SocketImpl::SetBlocking(m_handle, true);
restoreBlocking.Reset([this] ()
{
SocketImpl::SetBlocking(m_handle, false);
});
}

std::size_t received;
if (!Receive(buffer, size, &received))
received = 0;

return received;
}

void TcpClient::Reset(SocketHandle handle, const IpAddress& peerAddress)
{
Open(handle);
m_peerAddress = peerAddress;
m_openMode = OpenMode_ReadWrite;
UpdateState(SocketState_Connected);
}

std::size_t TcpClient::WriteBlock(const void* buffer, std::size_t size)
{
NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Invalid handle");

CallOnExit restoreBlocking;
if (!m_isBlockingEnabled)
{
SocketImpl::SetBlocking(m_handle, true);
restoreBlocking.Reset([this] ()
{
SocketImpl::SetBlocking(m_handle, false);
});
}

std::size_t sent;
if (!Send(buffer, size, &sent))
sent = 0;

return sent;
}
}

0 comments on commit 1acf41e

Please sign in to comment.