cec: clean up lib/platform
[deb_libcec.git] / src / lib / platform / sockets / socket.h
index 2e8acdbdca4de00fb7b76822b0ed36214c870d9f..388bb2d8a0d2fd13e2500207f13481ce31dfbbf9 100644 (file)
 
 namespace PLATFORM
 {
-  class CSocket : public PreventCopy
+  class ISocket : public PreventCopy
   {
-    public:
-      CSocket(void) :
-        m_socket(INVALID_SOCKET),
-        m_iError(0) {};
+  public:
+    ISocket(void) {};
+    virtual ~ISocket(void) {}
 
-      virtual ~CSocket(void)
-      {
-        Close();
-      }
+    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 bool IsOpen(void)
-      {
-        CLockObject lock(m_mutex);
-        return m_socket != INVALID_SOCKET &&
-            m_socket != SOCKET_ERROR;
-      }
+  template <typename _SType>
+  class CCommonSocket : public ISocket
+  {
+  public:
+    CCommonSocket(_SType initialSocketValue, const CStdString &strName) :
+      m_socket(initialSocketValue),
+      m_strName(strName),
+      m_iError(0) {}
 
-      virtual void Close(void)
-      {
-        CLockObject lock(m_mutex);
-        SocketClose(m_socket);
-        m_socket = INVALID_SOCKET;
-        m_strError = "";
-      }
+    virtual ~CCommonSocket(void) {}
 
-      virtual int64_t Write(uint8_t* data, uint32_t len)
-      {
-        CLockObject lock(m_mutex);
-        int64_t iReturn = SocketWrite(m_socket, &m_iError, data, len);
-        m_strError = strerror(m_iError);
-        return iReturn;
-      }
+    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_iUseCount(0) {}
+
+    virtual ~CProtectedSocket(void)
+    {
+      Close();
+      delete m_socket;
+    }
 
-      virtual int32_t Read(uint8_t* data, uint32_t len, uint64_t iTimeoutMs = 0)
+    virtual bool Open(uint64_t iTimeoutMs = 0)
+    {
+      bool bReturn(false);
+      if (m_socket && WaitReady())
       {
-        CLockObject lock(m_mutex);
-        int32_t iReturn = SocketRead(m_socket, &m_iError, data, len, iTimeoutMs);
-        m_strError = strerror(m_iError);
-        return iReturn;
+        bReturn = m_socket->Open(iTimeoutMs);
+        MarkReady();
       }
+      return bReturn;
+    }
 
-      virtual CStdString GetError(void) const
+    virtual void Close(void)
+    {
+      if (m_socket && WaitReady())
       {
-        CStdString strReturn;
-        strReturn = m_strError;
-        return strReturn;
+        m_socket->Close();
+        MarkReady();
       }
+    }
 
-      virtual int GetErrorNumber(void) const
+    virtual void Shutdown(void)
+    {
+      if (m_socket && WaitReady())
       {
-        return m_iError;
+        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_iUseCount > 0;
+    }
+
+    virtual int GetUseCount(void)
+    {
+      CLockObject lock(m_mutex);
+      return m_iUseCount;
+    }
+
+    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);
+      if (m_iUseCount > 0)
+        m_condition.Wait(m_mutex);
+
+      if (m_iUseCount > 0)
+        return false;
+
+      ++m_iUseCount;
+      return true;
+    }
+
+    void MarkReady(void)
+    {
+      CLockObject lock(m_mutex);
+      if (m_iUseCount > 0)
+        --m_iUseCount;
+      m_condition.Broadcast();
+    }
 
-    protected:
-      socket_t   m_socket;
-      CStdString m_strError;
-      int        m_iError;
-      CMutex     m_mutex;
+    _Socket   *m_socket;
+    CMutex     m_mutex;
+    CCondition m_condition;
+    int        m_iUseCount;
   };
 };