#include <wx/string.h>
#include <wx/timer.h>
#include <wx/utils.h>
+#include <wx/module.h>
#include <wx/log.h>
#include <stdlib.h>
/////////////////////////////////////////////////////////////////////////////
// wxSocket headers
/////////////////////////////////////////////////////////////////////////////
-#include <wx/module.h>
#include <wx/sckaddr.h>
#include <wx/socket.h>
class wxSocketState : public wxObject {
public:
- bool notify_state;
+ bool notify_state;
GSocketEventFlags evt_notify_state;
wxSocketBase::wxSockFlags socket_flags;
wxSocketBase::wxSockCbk c_callback;
wxEvtHandler(),
m_socket(NULL), m_flags(_flags), m_type(_type),
m_neededreq(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG),
- m_lcount(0), m_timeout(3600),
+ m_lcount(0), m_timeout(600),
m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
m_cbk(NULL), m_cdata(NULL),
m_connected(FALSE), m_notify_state(FALSE), m_id(-1),
wxSocketBase::wxSocketBase() :
wxEvtHandler(),
- m_socket(NULL), m_flags((wxSockFlags)SPEED | WAITALL), m_type(SOCK_UNINIT),
+ m_socket(NULL), m_flags(SPEED | WAITALL), m_type(SOCK_UNINIT),
m_neededreq(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG),
- m_lcount(0), m_timeout(3600),
+ m_lcount(0), m_timeout(600),
m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
m_cbk(NULL), m_cdata(NULL),
m_connected(FALSE), m_notify_state(FALSE), m_id(-1),
bool wxSocketBase::Close()
{
- if (m_socket)
+ if (m_socket)
{
if (m_notify_state == TRUE)
Notify(FALSE);
// --------------------------------------------------------------
// wxSocketBase base IO function
// --------------------------------------------------------------
+class _wxSocketInternalTimer: public wxTimer {
+ public:
+ int *m_state;
+ unsigned long m_new_val;
-int wxSocketBase::DeferRead(char *buffer, size_t nbytes)
+ void Notify()
+ {
+ *m_state = m_new_val; // Change the value
+ }
+};
+
+int wxSocketBase::DeferRead(char *buffer, wxUint32 nbytes)
{
- GSocketEventFlags old_event_flags;
+ wxSocketEventFlags old_event_flags;
bool old_notify_state;
+ // Timer for timeout
+ _wxSocketInternalTimer timer;
wxASSERT(m_defering == NO_DEFER);
+ // Set the defering mode to READ.
m_defering = DEFER_READ;
+ // Save the old state.
old_event_flags = NeededReq();
old_notify_state = m_notify_state;
-
+
+ // Set the new async flag.
SetNotify(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
Notify(TRUE);
+ // Set the current buffer.
m_defer_buffer = buffer;
m_defer_nbytes = nbytes;
+ m_defer_timer = &timer;
+
+ timer.m_state = (int *)&m_defer_buffer;
+ timer.m_new_val = 0;
+
+ timer.Start(m_timeout * 1000, FALSE);
+
+ // Wait for buffer completion.
while (m_defer_buffer != NULL)
wxYield();
+ timer.Stop();
+
+ // Restore the old state.
Notify(old_notify_state);
SetNotify(old_event_flags);
+ // Disable defering mode.
m_defering = NO_DEFER;
+ m_defer_timer = NULL;
+ // Return the number of bytes read from the socket.
return nbytes-m_defer_nbytes;
}
-wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
+wxSocketBase& wxSocketBase::Read(char* buffer, wxUint32 nbytes)
{
int ret = 1;
return *this;
}
-wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes)
+wxSocketBase& wxSocketBase::ReadMsg(char* buffer, wxUint32 nbytes)
{
unsigned long len, len2, sig;
struct {
} 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
+ // compilers in which wxUint32 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;
+ sig |= (wxUint32)(msg.sig[1] & 0xff) << 8;
+ sig |= (wxUint32)(msg.sig[2] & 0xff) << 16;
+ sig |= (wxUint32)(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;
+ len |= (wxUint32)(msg.len[1] & 0xff) << 8;
+ len |= (wxUint32)(msg.len[2] & 0xff) << 16;
+ len |= (wxUint32)(msg.len[3] & 0xff) << 24;
// len2 is incorrectly computed in the original; this sequence is
// the fix
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;
+ sig |= (wxUint32)(msg.sig[1] & 0xff) << 8;
+ sig |= (wxUint32)(msg.sig[2] & 0xff) << 16;
+ sig |= (wxUint32)(msg.sig[3] & 0xff) << 24;
// ERROR
if (sig != 0xdeadfeed)
return *this;
}
-wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
+wxSocketBase& wxSocketBase::Peek(char* buffer, wxUint32 nbytes)
{
Read(buffer, nbytes);
CreatePushbackAfter(buffer, nbytes);
return *this;
}
-int wxSocketBase::DeferWrite(const char *buffer, size_t nbytes)
+int wxSocketBase::DeferWrite(const char *buffer, wxUint32 nbytes)
{
- GSocketEventFlags old_event_flags;
+ wxSocketEventFlags old_event_flags;
bool old_notify_state;
+ // Timer for timeout
+ _wxSocketInternalTimer timer;
wxASSERT(m_defering == NO_DEFER);
m_defering = DEFER_WRITE;
+ // Save the old state
old_event_flags = NeededReq();
old_notify_state = m_notify_state;
SetNotify(GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG);
Notify(TRUE);
+ // Set the current buffer
m_defer_buffer = (char *)buffer;
m_defer_nbytes = nbytes;
+
+ // Start timer
+ timer.m_state = (int *)&m_defer_buffer;
+ timer.m_new_val = 0;
+
+ m_defer_timer = &timer;
+ timer.Start(m_timeout * 1000, FALSE);
+
while (m_defer_buffer != NULL)
wxYield();
+ // Stop timer
+ m_defer_timer = NULL;
+ timer.Stop();
+
+ // Restore the old state
Notify(old_notify_state);
SetNotify(old_event_flags);
return nbytes-m_defer_nbytes;
}
-wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes)
+wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 nbytes)
{
int ret;
return *this;
}
-wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes)
+wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, wxUint32 nbytes)
{
struct {
char sig[4];
msg.sig[2] = (char) 0xed;
msg.sig[3] = (char) 0xfe;
- msg.len[0] = (char) nbytes & 0xff;
+ 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;
#endif // __VISUALC__
}
-wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes)
+wxSocketBase& wxSocketBase::Unread(const char *buffer, wxUint32 nbytes)
{
m_lcount = 0;
if (nbytes != 0) {
return (GSocket_DataAvailable(m_socket));
}
-void wxSocketBase::DoDefer(GSocketEvent req_evt)
+void wxSocketBase::DoDefer(wxSocketNotify req_evt)
{
int ret;
- if (req_evt == GSOCK_LOST) {
+ if (req_evt == wxSOCKET_LOST) {
Close();
m_defer_buffer = NULL;
return;
if (ret < 0)
m_defer_nbytes++;
+ // If we are waiting for all bytes to be acquired, keep the defering modei
+ // enabled.
if ((m_flags & WAITALL) == 0 || m_defer_nbytes == 0 || ret < 0) {
m_defer_buffer = NULL;
Notify(FALSE);
- } else
+ } else {
m_defer_buffer += ret;
+ m_defer_timer->Start(m_timeout * 1000, FALSE);
+ }
}
// ---------------------------------------------------------------------
{
#define MAX_BUFSIZE (10*1024)
char *my_data = new char[MAX_BUFSIZE];
- size_t recv_size = MAX_BUFSIZE;
+ wxUint32 recv_size = MAX_BUFSIZE;
SaveState();
- SetFlags((wxSockFlags)(NOWAIT | SPEED));
+ SetFlags(NOWAIT | SPEED);
- while (recv_size == MAX_BUFSIZE)
+ while (recv_size == MAX_BUFSIZE)
{
recv_size = Read(my_data, MAX_BUFSIZE).LastCount();
}
// --------- wxSocketBase wait functions ------------------------
// --------------------------------------------------------------
-class _wxSocketInternalTimer: public wxTimer {
- public:
- int *m_state;
-
- void Notify()
- {
- *m_state = GSOCK_MAX_EVENT; // Just to say it's a timeout.
- }
-};
-
static void wx_socket_wait(GSocket *socket, GSocketEvent event, char *cdata)
{
int *state = (int *)cdata;
bool wxSocketBase::_Wait(long seconds, long milliseconds, int type)
{
bool old_notify_state = m_notify_state;
- int state = 0;
+ int state = -1;
_wxSocketInternalTimer timer;
if (!m_connected || !m_socket)
return FALSE;
+ // Set the variable to change
timer.m_state = &state;
+ timer.m_new_val = GSOCK_MAX_EVENT;
+ // Disable the previous handler
Notify(FALSE);
+ // Set the timeout
timer.Start(seconds * 1000 + milliseconds, TRUE);
- GSocket_SetFallback(m_socket, type, wx_socket_wait, (char *)&state);
+ GSocket_SetCallback(m_socket, type, wx_socket_wait, (char *)&state);
- while (state == 0)
+ while (state == -1)
wxYield();
- GSocket_UnsetFallback(m_socket, type);
+ GSocket_UnsetCallback(m_socket, type);
timer.Stop();
+ // Notify will restore automatically the old GSocket flags
Notify(old_notify_state);
return (state != GSOCK_MAX_EVENT);
// --------- wxSocketBase callback management -------------------
// --------------------------------------------------------------
-GSocketEventFlags wxSocketBase::EventToNotify(GSocketEvent evt)
+wxSocketEventFlags wxSocketBase::EventToNotify(wxSocketNotify evt)
{
- switch (evt)
+ switch (evt)
{
case GSOCK_INPUT:
return GSOCK_INPUT_FLAG;
return GSOCK_OUTPUT_FLAG;
case GSOCK_CONNECTION:
return GSOCK_CONNECTION_FLAG;
- case GSOCK_LOST_FLAG:
+ case GSOCK_LOST:
return GSOCK_LOST_FLAG;
default:
return 0;
return m_flags;
}
-void wxSocketBase::SetNotify(GSocketEventFlags flags)
+void wxSocketBase::SetNotify(wxSocketEventFlags flags)
{
/* Check if server */
if (m_type != SOCK_SERVER)
{
wxSocketBase *sckobj = (wxSocketBase *)cdata;
- sckobj->OnRequest(event);
+ sckobj->OnRequest((wxSocketNotify)event);
}
void wxSocketBase::Notify(bool notify)
if (!m_socket)
return;
- GSocket_UnsetFallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
+ GSocket_UnsetCallback(m_socket, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
GSOCK_LOST_FLAG | GSOCK_CONNECTION_FLAG);
if (!notify)
return;
- GSocket_SetFallback(m_socket, m_neededreq, wx_socket_fallback, (char *)this);
+ GSocket_SetCallback(m_socket, m_neededreq, wx_socket_fallback, (char *)this);
}
-void wxSocketBase::OnRequest(GSocketEvent req_evt)
+void wxSocketBase::OnRequest(wxSocketNotify req_evt)
{
wxSocketEvent event(m_id);
- GSocketEventFlags notify = EventToNotify(req_evt);
+ wxSocketEventFlags notify = EventToNotify(req_evt);
if (m_defering != NO_DEFER) {
DoDefer(req_evt);
if ((m_neededreq & notify) == notify) {
event.m_socket = this;
- event.m_skevt = req_evt;
+ event.m_skevt = req_evt;
ProcessEvent(event);
OldOnNotify(req_evt);
}
- if (req_evt == GSOCK_LOST)
+ if (req_evt == wxSOCKET_LOST)
Close();
}
-void wxSocketBase::OldOnNotify(GSocketEvent evt)
+void wxSocketBase::OldOnNotify(wxSocketNotify evt)
{
}
// --------- wxSocketBase pushback library ----------------------
// --------------------------------------------------------------
-void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size)
+void wxSocketBase::CreatePushbackAfter(const char *buffer, wxUint32 size)
{
char *curr_pos;
m_unrd_size += size;
}
-void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size)
+void wxSocketBase::CreatePushbackBefore(const char *buffer, wxUint32 size)
{
if (m_unread == NULL)
m_unread = (char *)malloc(size);
m_unread = tmp;
}
-
+
m_unrd_size += size;
memcpy(m_unread, buffer, size);
}
-size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek)
+wxUint32 wxSocketBase::GetPushback(char *buffer, wxUint32 size, bool peek)
{
if (!m_unrd_size)
return 0;
// --------------------------------------------------------------
// --------- wxSocketClient Connect functions -------------------
// --------------------------------------------------------------
-bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) )
+bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait)
{
+ GSocketError err;
+
if (IsConnected())
Close();
m_connected = FALSE;
+ // GRG: If wait == FALSE, then set the socket to
+ // nonblocking. I will set it back to blocking later,
+ // but I am not sure if this is really a good idea.
+ // IMO, all GSockets objects used in wxSocket should
+ // be non-blocking.
+ // --------------------------------
+ if (!wait)
+ GSocket_SetNonBlocking(m_socket, TRUE);
+
// Update the flags of m_socket.
SetFlags(m_flags);
+
+ // Try to connect
GSocket_SetPeer(m_socket, addr_man.GetAddress());
- if (GSocket_Connect(m_socket, GSOCK_STREAMED) != GSOCK_NOERROR) {
+ err = GSocket_Connect(m_socket, GSOCK_STREAMED);
+
+ if (!wait)
+ GSocket_SetNonBlocking(m_socket, FALSE);
+
+ if (err != GSOCK_NOERROR)
return FALSE;
- }
// Enables bg events.
// ------------------
return m_connected;
}
-void wxSocketClient::OnRequest(GSocketEvent evt)
+void wxSocketClient::OnRequest(wxSocketNotify evt)
{
- if (evt == GSOCK_CONNECTION)
+ if ((GSocketEvent)evt == GSOCK_CONNECTION)
{
- if (m_connected)
+ if (m_connected)
{
m_neededreq &= ~GSOCK_CONNECTION_FLAG;
return;
event->m_socket = m_socket;
}
+// --------------------------------------------------------------------------
+// wxSocketModule
+// --------------------------------------------------------------------------
+class WXDLLEXPORT wxSocketModule: public wxModule {
+ DECLARE_DYNAMIC_CLASS(wxSocketModule)
+ public:
+ bool OnInit() {
+ return GSocket_Init();
+ }
+ void OnExit() {
+ GSocket_Cleanup();
+ }
+};
+
+IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
+
#endif
// wxUSE_SOCKETS