/*
* This file is part of the libCEC(R) library.
*
- * libCEC(R) is Copyright (C) 2011 Pulse-Eight Limited. All rights reserved.
+ * libCEC(R) is Copyright (C) 2011-2012 Pulse-Eight Limited. All rights reserved.
* libCEC(R) is an original work, containing original code.
*
* libCEC(R) is a trademark of Pulse-Eight Limited.
namespace PLATFORM
{
- class CSocket : public PreventCopy
+ class ISocket : public PreventCopy
{
- public:
- CSocket(void) :
- m_socket(INVALID_SOCKET) {};
- virtual ~CSocket(void)
- {
- Close();
- }
+ public:
+ ISocket(void) {};
+ virtual ~ISocket(void) {}
- virtual bool IsOpen(void)
- {
- CLockObject lock(m_mutex);
- return m_socket != INVALID_SOCKET &&
- m_socket != SOCKET_ERROR;
- }
+ virtual bool Open(uint64_t iTimeoutMs = 0) = 0;
+ virtual void Close(void) = 0;
+ virtual void Shutdown(void) = 0;
+ virtual bool IsOpen(void) = 0;
+ virtual ssize_t Write(void* data, size_t len) = 0;
+ virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0) = 0;
+ virtual CStdString GetError(void) = 0;
+ virtual int GetErrorNumber(void) = 0;
+ virtual CStdString GetName(void) = 0;
+ };
- virtual void Close(void)
- {
- CLockObject lock(m_mutex);
- SocketClose(m_socket);
- m_socket = INVALID_SOCKET;
- m_strError = "";
- }
+ template <typename _SType>
+ class CCommonSocket : public ISocket
+ {
+ public:
+ CCommonSocket(_SType initialSocketValue, const CStdString &strName) :
+ m_socket(initialSocketValue),
+ m_strName(strName),
+ m_iError(0) {}
+
+ virtual ~CCommonSocket(void) {}
+
+ virtual CStdString GetError(void)
+ {
+ CStdString strError;
+ strError = m_strError.IsEmpty() && m_iError != 0 ? strerror(m_iError) : m_strError;
+ return strError;
+ }
+
+ virtual int GetErrorNumber(void)
+ {
+ return m_iError;
+ }
+
+ virtual CStdString GetName(void)
+ {
+ CStdString strName;
+ strName = m_strName;
+ return strName;
+ }
+
+ protected:
+ _SType m_socket;
+ CStdString m_strError;
+ CStdString m_strName;
+ int m_iError;
+ CMutex m_mutex;
+ };
+
+ template <typename _Socket>
+ class CProtectedSocket : public ISocket
+ {
+ public:
+ CProtectedSocket(_Socket *socket) :
+ m_socket(socket),
+ m_bIsIdle(true) {}
- int64_t Write(uint8_t* data, uint32_t len)
+ virtual ~CProtectedSocket(void)
+ {
+ Close();
+ delete m_socket;
+ }
+
+ virtual bool Open(uint64_t iTimeoutMs = 0)
+ {
+ bool bReturn(false);
+ if (m_socket && WaitReady())
{
- CLockObject lock(m_mutex);
- int iError(0);
- int64_t iReturn = SocketWrite(m_socket, &iError, data, len);
- m_strError = strerror(iError);
- return iReturn;
+ bReturn = m_socket->Open(iTimeoutMs);
+ MarkReady();
}
+ return bReturn;
+ }
- int32_t Read(uint8_t* data, uint32_t len, uint64_t iTimeoutMs = 0)
+ virtual void Close(void)
+ {
+ if (m_socket && WaitReady())
{
- CLockObject lock(m_mutex);
- int iError(0);
- int32_t iReturn = SocketRead(m_socket, &iError, data, len, iTimeoutMs);
- m_strError = strerror(iError);
- return iReturn;
+ m_socket->Close();
+ MarkReady();
}
+ }
- virtual CStdString GetError(void) const
+ virtual void Shutdown(void)
+ {
+ if (m_socket && WaitReady())
{
- CStdString strReturn;
- strReturn = m_strError;
- return strReturn;
+ m_socket->Shutdown();
+ MarkReady();
}
+ }
+
+ virtual bool IsOpen(void)
+ {
+ CLockObject lock(m_mutex);
+ return m_socket && m_socket->IsOpen();
+ }
+
+ virtual bool IsBusy(void)
+ {
+ CLockObject lock(m_mutex);
+ return m_socket && !m_bIsIdle;
+ }
+
+ virtual bool IsIdle(void)
+ {
+ CLockObject lock(m_mutex);
+ return m_socket && m_bIsIdle;
+ }
+
+ virtual ssize_t Write(void* data, size_t len)
+ {
+ if (!m_socket || !WaitReady())
+ return -EINVAL;
+
+ ssize_t iReturn = m_socket->Write(data, len);
+ MarkReady();
+
+ return iReturn;
+ }
+
+ virtual ssize_t Read(void* data, size_t len, uint64_t iTimeoutMs = 0)
+ {
+ if (!m_socket || !WaitReady())
+ return -EINVAL;
+
+ ssize_t iReturn = m_socket->Read(data, len, iTimeoutMs);
+ MarkReady();
+
+ return iReturn;
+ }
+
+ virtual CStdString GetError(void)
+ {
+ CStdString strError;
+ CLockObject lock(m_mutex);
+ strError = m_socket ? m_socket->GetError() : "";
+ return strError;
+ }
+
+ virtual int GetErrorNumber(void)
+ {
+ CLockObject lock(m_mutex);
+ return m_socket ? m_socket->GetErrorNumber() : -EINVAL;
+ }
+
+ virtual CStdString GetName(void)
+ {
+ CStdString strName;
+ CLockObject lock(m_mutex);
+ strName = m_socket ? m_socket->GetName() : "";
+ return strName;
+ }
+
+ private:
+ bool WaitReady(void)
+ {
+ CLockObject lock(m_mutex);
+ m_condition.Wait(m_mutex, m_bIsIdle);
+ m_bIsIdle = false;
+ return true;
+ }
+
+ void MarkReady(void)
+ {
+ CLockObject lock(m_mutex);
+ m_bIsIdle = true;
+ m_condition.Signal();
+ }
- protected:
- socket_t m_socket;
- CStdString m_strError;
- CMutex m_mutex;
+ _Socket * m_socket;
+ CMutex m_mutex;
+ CCondition<bool &> m_condition;
+ bool m_bIsIdle;
};
};