- if ((m_flags & WAITALL) != 0) {
- while (ret > 0 && nbytes > 0) {
- ret = GSocket_Read(m_socket, buffer, nbytes);
- m_lcount += ret;
- buffer += ret;
- nbytes -= ret;
+wxUint32 wxSocketBase::_Read(void* buffer_, wxUint32 nbytes)
+{
+ char *buffer = (char *)buffer_;
+
+ int total;
+
+ // Try the pushback buffer first
+ total = GetPushback(buffer, nbytes, false);
+ nbytes -= total;
+ buffer = (char *)buffer + total;
+
+ // Return now in one of the following cases:
+ // - the socket is invalid,
+ // - we got all the data
+ if ( !m_socket ||
+ !nbytes )
+ return total;
+
+ // Possible combinations (they are checked in this order)
+ // wxSOCKET_NOWAIT
+ // wxSOCKET_WAITALL (with or without wxSOCKET_BLOCK)
+ // wxSOCKET_BLOCK
+ // wxSOCKET_NONE
+ //
+ int ret;
+ if (m_flags & wxSOCKET_NOWAIT)
+ {
+ m_socket->SetNonBlocking(1);
+ ret = m_socket->Read(buffer, nbytes);
+ m_socket->SetNonBlocking(0);
+
+ if ( ret < 0 )
+ return 0;
+
+ total += ret;
+ }
+ else // blocking socket
+ {
+ for ( ;; )
+ {
+ // dispatch events unless disabled
+ if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForRead() )
+ break;
+
+ 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;