updated copyright messages for 2013
[deb_libcec.git] / src / lib / platform / sockets / socket.h
index aa3625a275891ac777c92e4a8312ddd3d6398ec7..d36dbb0ea420be625066f1c9b84d2141eca7ae17 100644 (file)
@@ -2,7 +2,7 @@
 /*
  * 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-2013 Pulse-Eight Limited.  All rights reserved.
  * libCEC(R) is an original work, containing original code.
  *
  * libCEC(R) is a trademark of Pulse-Eight Limited.
  *     http://www.pulse-eight.net/
  */
 
-#include "../threads/mutex.h"
-#include "../util/StdString.h"
+#include "lib/platform/threads/mutex.h"
 
 #if defined(__WINDOWS__)
-#include "../windows/os-socket.h"
+#include "lib/platform/windows/os-socket.h"
 #else
-#include "../posix/os-socket.h"
+#include "lib/platform/posix/os-socket.h"
 #endif
 
+#include <string>
+
 // Common socket operations
 
 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 std::string GetError(void) = 0;
+    virtual int GetErrorNumber(void) = 0;
+    virtual std::string 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 std::string &strName) :
+      m_socket(initialSocketValue),
+      m_strName(strName),
+      m_iError(0) {}
+
+    virtual ~CCommonSocket(void) {}
+
+    virtual std::string GetError(void)
+    {
+      std::string strError;
+      strError = m_strError.empty() && m_iError != 0 ? strerror(m_iError) : m_strError;
+      return strError;
+    }
+
+    virtual int GetErrorNumber(void)
+    {
+      return m_iError;
+    }
+
+    virtual std::string GetName(void)
+    {
+      std::string strName;
+      strName = m_strName;
+      return strName;
+    }
+
+  protected:
+    _SType     m_socket;
+    std::string m_strError;
+    std::string 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) {}
+
+    virtual ~CProtectedSocket(void)
+    {
+      Close();
+      delete m_socket;
+    }
 
-      int64_t Write(uint8_t* data, uint32_t len)
+    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 std::string GetError(void)
+    {
+      std::string 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 std::string GetName(void)
+    {
+      std::string 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;
   };
 };