+wxUint32 wxSocketBase::DeferWrite(const char *buffer, wxUint32 nbytes)
+{
+ // Timer for timeout
+ _wxSocketInternalTimer timer;
+
+ wxASSERT(m_defering == NO_DEFER);
+ //wxLogMessage("Entrando a DeferWrite");
+
+ m_defering = DEFER_WRITE;
+
+ // Set the current buffer
+ m_defer_buffer = (char *)buffer;
+ m_defer_nbytes = nbytes;
+ m_defer_timer = &timer;
+
+ // Start timer
+ timer.m_state = (int *)&m_defer_buffer;
+ timer.m_new_val = 0;
+
+ timer.Start(m_timeout * 1000, FALSE);
+
+ // If the socket is writable, call DoDefer for the first time
+ if (GSocket_Select(m_socket, GSOCK_OUTPUT_FLAG))
+ {
+ //wxLogMessage("Llamando al primer DoDefer");
+ DoDefer();
+ }
+
+ // Wait for buffer completion.
+ while (m_defer_buffer != NULL)
+ PROCESS_EVENTS();
+
+ timer.Stop();
+
+ // Disable defering mode
+ m_defer_timer = NULL;
+ m_defering = NO_DEFER;
+
+ wxString s;
+ s.Printf("Saliendo de DeferWrite: total %d bytes", nbytes-m_defer_nbytes);
+ //wxLogMessage(s);
+
+ return nbytes-m_defer_nbytes;
+}
+
+wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 nbytes)
+{
+ // Mask write events
+ m_writing = TRUE;
+
+ m_lcount = _Write(buffer, nbytes);
+
+ // If in WAITALL mode, all bytes should have been written.
+ if (m_flags & WAITALL)
+ m_error = (m_lcount != nbytes);
+ else
+ m_error = (m_lcount == 0);
+
+ // Trigger another write event if the socket is still writable
+ m_writing = FALSE;
+
+ // TODO: TriggerWrite
+ return *this;
+}
+
+wxUint32 wxSocketBase::_Write(const char *buffer, wxUint32 nbytes)
+{
+ wxUint32 total = 0;
+ int ret = 1;
+
+ if (!m_connected || !m_socket)
+ return 0;
+
+ // Possible combinations (they are checked in this order)
+ // NOWAIT
+ // SPEED | WAITALL
+ // SPEED
+ // WAITALL
+ // NONE
+ //
+ if (m_flags & NOWAIT) // NOWAIT
+ {
+ GSocket_SetNonBlocking(m_socket, TRUE);
+ ret = GSocket_Write(m_socket, buffer, nbytes);
+ GSocket_SetNonBlocking(m_socket, FALSE);
+
+ if (ret > 0)
+ total = ret;
+ }
+ else if ((m_flags & SPEED) && (m_flags & WAITALL)) // SPEED, WAITALL
+ {
+ while (ret > 0 && nbytes > 0)
+ {
+ ret = GSocket_Write(m_socket, buffer, nbytes);
+ total += ret;
+ buffer += ret;
+ nbytes -= ret;
+ }
+ // In case the last call was an error ...
+ if (ret < 0)
+ total ++;
+ }
+ else if (m_flags & SPEED) // SPEED, !WAITALL
+ {
+ ret = GSocket_Write(m_socket, buffer, nbytes);
+
+ if (ret > 0)
+ total = ret;
+ }
+ else // NONE or WAITALL
+ {
+ ret = DeferWrite(buffer, nbytes);
+
+ if (ret > 0)
+ total = ret;
+ }
+
+ return total;
+}
+
+wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, wxUint32 nbytes)
+{
+ wxUint32 total;
+ bool error;
+ int old_flags;
+ struct {
+ unsigned char sig[4];
+ unsigned char len[4];
+ } msg;
+
+ // Mask write events
+ m_writing = TRUE;
+
+ error = TRUE;
+ total = 0;
+ old_flags = m_flags;
+ SetFlags((m_flags & SPEED) | WAITALL);
+
+ // warning about 'cast truncates constant value'
+#ifdef __VISUALC__
+# pragma warning(disable: 4310)
+#endif // __VISUALC__
+
+ msg.sig[0] = (unsigned char) 0xad;
+ msg.sig[1] = (unsigned char) 0xde;
+ msg.sig[2] = (unsigned char) 0xed;
+ msg.sig[3] = (unsigned char) 0xfe;
+
+ msg.len[0] = (unsigned char) nbytes & 0xff;
+ msg.len[1] = (unsigned char) (nbytes >> 8) & 0xff;
+ msg.len[2] = (unsigned char) (nbytes >> 16) & 0xff;
+ msg.len[3] = (unsigned char) (nbytes >> 24) & 0xff;
+
+ //wxLogMessage("Writemsg: %d %d %d %d -> %d",
+ // nbytes & 0xff,
+ // (nbytes >> 8) & 0xff,
+ // (nbytes >> 16) & 0xff,
+ // (nbytes >> 24) & 0xff,
+ // nbytes
+ // );
+
+ if (_Write((char *)&msg, sizeof(msg)) < sizeof(msg))
+ goto exit;
+
+ total = _Write(buffer, nbytes);
+
+ if (total < nbytes)
+ goto exit;
+
+ msg.sig[0] = (unsigned char) 0xed;
+ msg.sig[1] = (unsigned char) 0xfe;
+ msg.sig[2] = (unsigned char) 0xad;
+ msg.sig[3] = (unsigned char) 0xde;
+ msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = (char) 0;
+
+ if ((_Write((char *)&msg, sizeof(msg))) < sizeof(msg))
+ goto exit;
+
+ // everything was OK
+ error = FALSE;
+
+exit:
+ m_error = error;
+ m_lcount = total;
+ m_writing = FALSE;
+
+ // TODO: TriggerWrite