]> git.saurik.com Git - wxWidgets.git/blobdiff - src/common/socket.cpp
* Changed behaviour of wxTextStreams::operator(wxUint8/wxInt8). Now it writes
[wxWidgets.git] / src / common / socket.cpp
index 2372865175a5af539076b86c05773be378eb93e7..052078b3b48ae5951831dce65d57556e85c69eec 100644 (file)
@@ -35,6 +35,11 @@ typedef int socklen_t ;
 #include <wx/timer.h>
 #include <wx/utils.h>
 
 #include <wx/timer.h>
 #include <wx/utils.h>
 
+// IRIX requires bstring.h be included to use select()
+#ifdef sgi
+    #include <bstring.h>
+#endif // IRIX
+
 // Not enough OS behaviour defined for wxStubs
 #ifndef __WXSTUBS__
 
 // Not enough OS behaviour defined for wxStubs
 #ifndef __WXSTUBS__
 
@@ -260,6 +265,65 @@ wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
   return *this;
 }
 
   return *this;
 }
 
+wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes)
+{
+  unsigned long len, len2, sig;
+  struct {
+    char sig[4];
+    char len[4];
+  } msg;
+
+  // sig should be an explicit 32-bit unsigned integer; I've seen
+  // compilers in which size_t was actually a 16-bit unsigned integer
+
+  Read((char *)&msg, sizeof(msg));
+  if (m_lcount != sizeof(msg))
+    return *this;
+
+  sig = msg.sig[0] & 0xff;
+  sig |= (size_t)(msg.sig[1] & 0xff) << 8;
+  sig |= (size_t)(msg.sig[2] & 0xff) << 16;
+  sig |= (size_t)(msg.sig[3] & 0xff) << 24;
+
+  if (sig != 0xfeeddead)
+    return *this;
+  len = msg.len[0] & 0xff;
+  len |= (size_t)(msg.len[1] & 0xff) << 8;
+  len |= (size_t)(msg.len[2] & 0xff) << 16;
+  len |= (size_t)(msg.len[3] & 0xff) << 24;
+
+  // len2 is incorrectly computed in the original; this sequence is
+  // the fix
+  if (len > nbytes) {
+    len2 = len - nbytes;
+    len = nbytes;
+  }
+  else
+    len2 = 0;
+
+  // the "len &&" in the following statement is necessary so that
+  // we don't attempt to read (and possibly hang the system)
+  // if the message was zero bytes long
+  if (len && Read(buffer, len).LastCount() != len)
+    return *this;
+  if (len2 && (Read(NULL, len2).LastCount() != len2))
+    return *this;
+  if (Read((char *)&msg, sizeof(msg)).LastCount() != sizeof(msg))
+    return *this;
+
+  sig = msg.sig[0] & 0xff;
+  sig |= (size_t)(msg.sig[1] & 0xff) << 8;
+  sig |= (size_t)(msg.sig[2] & 0xff) << 16;
+  sig |= (size_t)(msg.sig[3] & 0xff) << 24;
+// ERROR
+// we return *this either way, so a smart optimizer will
+// optimize the following sequence out; I'm leaving it in anyway
+  if (sig != 0xdeadfeed)
+    return *this;
+
+  return *this;
+}
+
 wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
 {
   m_lcount = GetPushback(buffer, nbytes, TRUE);
 wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
 {
   m_lcount = GetPushback(buffer, nbytes, TRUE);
@@ -282,9 +346,54 @@ wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes)
   return *this;
 }
 
   return *this;
 }
 
+wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes)
+{
+  struct {
+    char sig[4];
+    char len[4];
+  } msg;
+
+  // warning about 'cast truncates constant value'
+#ifdef __VISUALC__
+    #pragma warning(disable: 4310)
+#endif // __VISUALC__
+
+  msg.sig[0] = (char) 0xad;
+  msg.sig[1] = (char) 0xde;
+  msg.sig[2] = (char) 0xed;
+  msg.sig[3] = (char) 0xfe;
+
+    msg.len[0] = (char) nbytes & 0xff;
+  msg.len[1] = (char) (nbytes >> 8) & 0xff;
+  msg.len[2] = (char) (nbytes >> 16) & 0xff;
+  msg.len[3] = (char) (nbytes >> 24) & 0xff;
+
+  if (Write((char *)&msg, sizeof(msg)).LastCount() < sizeof(msg))
+    return *this;
+  if (Write(buffer, nbytes).LastCount() < nbytes)
+    return *this;
+
+  msg.sig[0] = (char) 0xed;
+  msg.sig[1] = (char) 0xfe;
+  msg.sig[2] = (char) 0xad;
+  msg.sig[3] = (char) 0xde;
+  msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
+  Write((char *)&msg, sizeof(msg));
+
+  return *this;
+
+#ifdef __VISUALC__
+    #pragma warning(default: 4310)
+#endif // __VISUALC__
+}
+
 wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes)
 {
 wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes)
 {
-  CreatePushbackAfter(buffer, nbytes);
+  m_lcount = 0;
+  if (nbytes != 0) {
+    CreatePushbackAfter(buffer, nbytes);
+    m_lcount = nbytes;
+  }
   return *this;
 }
 
   return *this;
 }
 
@@ -304,7 +413,7 @@ bool wxSocketBase::IsData() const
   tv.tv_usec = 0;
   FD_ZERO(&sock_set);
   FD_SET(m_fd, &sock_set);
   tv.tv_usec = 0;
   FD_ZERO(&sock_set);
   FD_SET(m_fd, &sock_set);
-  select(FD_SETSIZE, &sock_set, NULL, NULL, &tv);
+  select(m_fd+1, &sock_set, NULL, NULL, &tv);
 
   m_internal->ReleaseFD();
 
 
   m_internal->ReleaseFD();
 
@@ -424,7 +533,9 @@ void wxSocketBase::RestoreState()
   state = (SocketState *)node->Data();
 
   SetFlags(state->socket_flags);
   state = (SocketState *)node->Data();
 
   SetFlags(state->socket_flags);
+  m_internal->AcquireData();
   m_neededreq = state->evt_notify_state;
   m_neededreq = state->evt_notify_state;
+  m_internal->ReleaseData();
   m_cbk       = state->c_callback;
   m_cdata     = state->c_callback_data;
   Notify(state->notify_state);
   m_cbk       = state->c_callback;
   m_cdata     = state->c_callback_data;
   Notify(state->notify_state);
@@ -543,7 +654,9 @@ void wxSocketBase::SetNotify(wxRequestNotify flags)
   if (m_type != SOCK_SERVER)
     flags &= ~REQ_ACCEPT;
 
   if (m_type != SOCK_SERVER)
     flags &= ~REQ_ACCEPT;
 
+  m_internal->AcquireData();
   m_neededreq = flags;
   m_neededreq = flags;
+  m_internal->ReleaseData();
   if (m_neededreq == 0)
     m_internal->StopWaiter();
   else
   if (m_neededreq == 0)
     m_internal->StopWaiter();
   else
@@ -680,7 +793,6 @@ void wxSocketBase::WantBuffer(char *buffer, size_t nbytes,
   SockRequest *buf = new SockRequest;
 
   SaveState();
   SockRequest *buf = new SockRequest;
 
   SaveState();
-  m_internal->StopWaiter(); 
   buf->buffer = buffer;
   buf->size = nbytes;
   buf->done = FALSE;
   buf->buffer = buffer;
   buf->size = nbytes;
   buf->done = FALSE;
@@ -691,10 +803,10 @@ void wxSocketBase::WantBuffer(char *buffer, size_t nbytes,
   buf->timeout = 1000;
   buf_timed_out = FALSE;
 
   buf->timeout = 1000;
   buf_timed_out = FALSE;
 
-  if (m_flags & SPEED
+  if ((m_flags & SPEED) != 0
     m_internal->QueueRequest(buf, FALSE);
   else
     m_internal->QueueRequest(buf, FALSE);
   else
-    if (m_flags & NOWAIT
+    if ((m_flags & NOWAIT) != 0
       m_internal->QueueRequest(buf, TRUE);
     else 
       m_internal->QueueRequest(buf, TRUE);
       m_internal->QueueRequest(buf, TRUE);
     else 
       m_internal->QueueRequest(buf, TRUE);
@@ -736,6 +848,8 @@ wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
     return;
   }
 
     return;
   }
 
+  m_internal->SetFD(m_fd);
+
   Notify(TRUE);
 }
 
   Notify(TRUE);
 }
 
@@ -767,6 +881,8 @@ bool wxSocketServer::AcceptWith(wxSocketBase& sock)
   sock.m_fd = fd2;
   sock.m_connected = TRUE;
 
   sock.m_fd = fd2;
   sock.m_connected = TRUE;
 
+  sock.m_internal->SetFD(fd2);
+
   sock.m_internal->ResumeWaiter();
 
   return TRUE;
   sock.m_internal->ResumeWaiter();
 
   return TRUE;
@@ -849,6 +965,8 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) )
   if (connect(m_fd, remote, len) != 0)
     return FALSE;
 
   if (connect(m_fd, remote, len) != 0)
     return FALSE;
 
+  m_internal->SetFD(m_fd);
+
   // Enables bg events.
   // ------------------
   Notify(TRUE);
   // Enables bg events.
   // ------------------
   Notify(TRUE);