]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/socket.cpp
get rid of base arrays in wxUSE_STL build, we don't need them there and deriving...
[wxWidgets.git] / src / common / socket.cpp
index 52aba80f2d4c2bc014da5b1d17f30e22e670a06e..a4f8583376c5a679db752e9ae5c353c03cb63d90 100644 (file)
@@ -203,7 +203,8 @@ void wxSocketBase::Init()
   m_establishing =
   m_reading      =
   m_writing      =
-  m_error        = false;
+  m_error        =
+  m_closed       = false;
   m_lcount       = 0;
   m_timeout      = 600;
   m_beingDeleted = false;
@@ -339,8 +340,10 @@ wxSocketBase& wxSocketBase::Read(void* buffer, wxUint32 nbytes)
   return *this;
 }
 
-wxUint32 wxSocketBase::_Read(void* buffer, wxUint32 nbytes)
+wxUint32 wxSocketBase::_Read(void* buffer_, wxUint32 nbytes)
 {
+  char *buffer = (char *)buffer_;
+
   int total;
 
   // Try the pushback buffer first
@@ -365,35 +368,53 @@ wxUint32 wxSocketBase::_Read(void* buffer, wxUint32 nbytes)
   if (m_flags & wxSOCKET_NOWAIT)
   {
     m_socket->SetNonBlocking(1);
-    ret = m_socket->Read((char *)buffer, nbytes);
+    ret = m_socket->Read(buffer, nbytes);
     m_socket->SetNonBlocking(0);
 
-    if (ret > 0)
-      total += ret;
+    if ( ret < 0 )
+        return 0;
+
+    total += ret;
   }
-  else
+  else // blocking socket
   {
-    bool more = true;
-
-    while (more)
+    for ( ;; )
     {
+      // dispatch events unless disabled
       if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForRead() )
         break;
 
-      ret = m_socket->Read((char *)buffer, nbytes);
+      ret = m_socket->Read(buffer, nbytes);
+      if ( ret == 0 )
+      {
+          // for connection-oriented (e.g. TCP) sockets we can only read 0
+          // bytes if the other end has been closed, and for connectionless
+          // ones (UDP) this flag doesn't make sense anyhow so we can set it to
+          // true too without doing any harm
+          m_closed = true;
+          break;
+      }
 
-      if (ret > 0)
+      if ( ret < 0 )
       {
-        total  += ret;
-        nbytes -= ret;
-        buffer  = (char *)buffer + ret;
+          // this will be always interpreted as error by Read()
+          return 0;
       }
 
-      // If we got here and wxSOCKET_WAITALL is not set, we can leave
-      // now. Otherwise, wait until we recv all the data or until there
-      // is an error.
-      //
-      more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL));
+      total += ret;
+
+      // if wxSOCKET_WAITALL is not set, we can leave now as we did read
+      // something
+      if ( !(m_flags & wxSOCKET_WAITALL) )
+          break;
+
+      // otherwise check if read the maximal requested amount of data
+      nbytes -= ret;
+      if ( !nbytes )
+          break;
+
+      // we didn't, so continue reading
+      buffer  = (char *)buffer + ret;
     }
   }
 
@@ -538,8 +559,10 @@ wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
   return *this;
 }
 
-wxUint32 wxSocketBase::_Write(const void *buffer, wxUint32 nbytes)
+wxUint32 wxSocketBase::_Write(const void *buffer_, wxUint32 nbytes)
 {
+  const char *buffer = (const char *)buffer_;
+
   wxUint32 total = 0;
 
   // If the socket is invalid or parameters are ill, return immediately
@@ -556,35 +579,42 @@ wxUint32 wxSocketBase::_Write(const void *buffer, wxUint32 nbytes)
   if (m_flags & wxSOCKET_NOWAIT)
   {
     m_socket->SetNonBlocking(1);
-    ret = m_socket->Write((const char *)buffer, nbytes);
+    ret = m_socket->Write(buffer, nbytes);
     m_socket->SetNonBlocking(0);
 
     if (ret > 0)
       total = ret;
   }
-  else
+  else // blocking socket
   {
-    bool more = true;
-
-    while (more)
+    for ( ;; )
     {
       if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForWrite() )
         break;
 
-      ret = m_socket->Write((const char *)buffer, nbytes);
+      ret = m_socket->Write(buffer, nbytes);
 
-      if (ret > 0)
+      // see comments for similar logic for ret handling in _Read()
+      if ( ret == 0 )
       {
-        total  += ret;
-        nbytes -= ret;
-        buffer  = (const char *)buffer + ret;
+          m_closed = true;
+          break;
       }
 
-      // If we got here and wxSOCKET_WAITALL is not set, we can leave
-      // now. Otherwise, wait until we send all the data or until there
-      // is an error.
-      //
-      more = (ret > 0 && nbytes > 0 && (m_flags & wxSOCKET_WAITALL));
+      if ( ret < 0 )
+      {
+          return 0;
+      }
+
+      total += ret;
+      if ( !(m_flags & wxSOCKET_WAITALL) )
+          break;
+
+      nbytes -= ret;
+      if ( !nbytes )
+          break;
+
+      buffer = (const char *)buffer + ret;
     }
   }
 
@@ -1234,7 +1264,7 @@ bool wxSocketBase::SetOption(int level, int optname, const void *optval,
     return true;
 }
 
-bool wxSocketBase::SetLocal(wxIPV4address& local)
+bool wxSocketBase::SetLocal(const wxIPV4address& local)
 {
   GAddress* la = local.GetAddress();
 
@@ -1260,6 +1290,8 @@ bool wxSocketBase::SetLocal(wxIPV4address& local)
 wxSocketClient::wxSocketClient(wxSocketFlags flags)
               : wxSocketBase(flags, wxSOCKET_CLIENT)
 {
+    m_initialRecvBufferSize =
+    m_initialSendBufferSize = -1;
 }
 
 wxSocketClient::~wxSocketClient()
@@ -1270,7 +1302,9 @@ wxSocketClient::~wxSocketClient()
 // Connect
 // --------------------------------------------------------------------------
 
-bool wxSocketClient::DoConnect(wxSockAddress& addr_man, wxSockAddress* local, bool wait)
+bool wxSocketClient::DoConnect(const wxSockAddress& addr_man,
+                               const wxSockAddress* local,
+                               bool wait)
 {
   GSocketError err;
 
@@ -1354,14 +1388,16 @@ bool wxSocketClient::DoConnect(wxSockAddress& addr_man, wxSockAddress* local, bo
   return true;
 }
 
-bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait)
+bool wxSocketClient::Connect(const wxSockAddress& addr_man, bool wait)
 {
-    return (DoConnect(addr_man, NULL, wait));
+    return DoConnect(addr_man, NULL, wait);
 }
 
-bool wxSocketClient::Connect(wxSockAddress& addr_man, wxSockAddress& local, bool wait)
+bool wxSocketClient::Connect(const wxSockAddress& addr_man,
+                             const wxSockAddress& local,
+                             bool wait)
 {
-    return (DoConnect(addr_man, &local, wait));
+    return DoConnect(addr_man, &local, wait);
 }
 
 bool wxSocketClient::WaitOnConnect(long seconds, long milliseconds)