+ if (len2)
+ {
+ char *discard_buffer = new char[MAX_DISCARD_SIZE];
+ long discard_len;
+
+ // NOTE: discarded bytes don't add to m_lcount.
+ do
+ {
+ discard_len = ((len2 > MAX_DISCARD_SIZE)? MAX_DISCARD_SIZE : len2);
+ discard_len = DoRead(discard_buffer, (wxUint32)discard_len);
+ len2 -= (wxUint32)discard_len;
+ }
+ while ((discard_len > 0) && len2);
+
+ delete [] discard_buffer;
+
+ if (len2 != 0)
+ goto exit;
+ }
+ if (DoRead(&msg, sizeof(msg)) != sizeof(msg))
+ goto exit;
+
+ sig = (wxUint32)msg.sig[0];
+ sig |= (wxUint32)(msg.sig[1] << 8);
+ sig |= (wxUint32)(msg.sig[2] << 16);
+ sig |= (wxUint32)(msg.sig[3] << 24);
+
+ if (sig != 0xdeadfeed)
+ {
+ wxLogWarning(_("wxSocket: invalid signature in ReadMsg."));
+ goto exit;
+ }
+
+ // everything was OK
+ error = false;
+
+exit:
+ m_error = error;
+ m_lcount = total;
+ m_reading = false;
+ SetFlags(old_flags);
+
+ return *this;
+}
+
+wxSocketBase& wxSocketBase::Peek(void* buffer, wxUint32 nbytes)
+{
+ // Mask read events
+ m_reading = true;
+
+ m_lcount = DoRead(buffer, nbytes);
+ Pushback(buffer, m_lcount);
+
+ // If in wxSOCKET_WAITALL mode, all bytes should have been read.
+ if (m_flags & wxSOCKET_WAITALL)
+ m_error = (m_lcount != nbytes);
+ else
+ m_error = (m_lcount == 0);
+
+ // Allow read events again
+ m_reading = false;
+
+ return *this;
+}
+
+wxSocketBase& wxSocketBase::Write(const void *buffer, wxUint32 nbytes)
+{
+ // Mask write events
+ m_writing = true;
+
+ m_lcount = DoWrite(buffer, nbytes);
+
+ // If in wxSOCKET_WAITALL mode, all bytes should have been written.
+ if (m_flags & wxSOCKET_WAITALL)
+ m_error = (m_lcount != nbytes);
+ else
+ m_error = (m_lcount == 0);
+
+ // Allow write events again
+ m_writing = false;
+
+ return *this;
+}
+
+// This function is a mirror image of DoRead() except that it doesn't use the
+// push back buffer, please see comments there
+wxUint32 wxSocketBase::DoWrite(const void *buffer_, wxUint32 nbytes)
+{
+ const char *buffer = static_cast<const char *>(buffer_);
+
+ // Return if there is nothing to read or the socket is (already?) closed.
+ if ( !m_impl || !nbytes )
+ return 0;
+
+ wxCHECK_MSG( buffer, 0, "NULL buffer" );
+
+ wxUint32 total = 0;
+ if ( m_flags & wxSOCKET_NOWAIT )
+ {
+ wxSocketUnblocker unblock(m_impl);
+ const int ret = m_impl->Write(buffer, nbytes);
+ if ( ret > 0 )
+ total += ret;
+ }
+ else // blocking socket
+ {
+ for ( ;; )
+ {
+ if ( !(m_flags & wxSOCKET_BLOCK) && !WaitForWrite() )
+ break;
+
+ const int ret = m_impl->Write(buffer, nbytes);
+ if ( ret == 0 )
+ {
+ m_closed = true;
+ break;
+ }
+
+ if ( ret < 0 )
+ return 0;
+
+ total += ret;
+ if ( !(m_flags & wxSOCKET_WAITALL) )
+ break;
+
+ nbytes -= ret;
+ if ( !nbytes )
+ break;
+
+ buffer += ret;
+ }
+ }
+
+ return total;