wxlsock.cpp

Go to the documentation of this file.
00001 /////////////////////////////////////////////////////////////////////////////
00002 // Name:        wxlsock.cpp
00003 // Purpose:     Socket class for wxLua.
00004 // Author:      J. Winwood, John Labenski, Ray Gilbert
00005 // Created:     February 2002
00006 // Copyright:   (c) 2002 Lomtick Software. All rights reserved.
00007 // Licence:     wxWidgets licence
00008 /////////////////////////////////////////////////////////////////////////////
00009 
00010 #include "wx/wxprec.h"
00011 
00012 #ifdef __BORLANDC__
00013     #pragma hdrstop
00014 #endif
00015 
00016 #ifndef WX_PRECOMP
00017     #include "wx/wx.h"
00018 #endif
00019 
00020 #include "wxluasocket/include/wxlsock.h"
00021 #include "wxluasocket/include/wxldserv.h"
00022 #include "wxlua/include/wxlstate.h"
00023 #include "wxluadebug/include/wxldebug.h"
00024 
00025 #ifdef _MSC_VER
00026     #pragma warning(push, 4)
00027 #endif
00028 
00029 // A simple way to debug the sockets to see if things are right
00030 // prints to the console for unix and to a file (see below) for MSW the socket
00031 // cmd/event and the socket read/write
00032 //#define DEBUG_WXLUASOCKET
00033 #ifdef DEBUG_WXLUASOCKET
00034 
00035     char* s_wxlsocket_event[] = {
00036         "wxLUASOCKET_DEBUGGEE_EVENT_NONE",
00037         "wxLUASOCKET_DEBUGGEE_EVENT_BREAK",
00038         "wxLUASOCKET_DEBUGGEE_EVENT_PRINT",
00039         "wxLUASOCKET_DEBUGGEE_EVENT_ERROR",
00040         "wxLUASOCKET_DEBUGGEE_EVENT_EXIT",
00041         "wxLUASOCKET_DEBUGGEE_EVENT_STACK_ENUM",
00042         "wxLUASOCKET_DEBUGGEE_EVENT_STACK_ENTRY_ENUM",
00043         "wxLUASOCKET_DEBUGGEE_EVENT_TABLE_ENUM",
00044         "wxLUASOCKET_DEBUGGEE_EVENT_EVALUATE_EXPR",
00045     };
00046 
00047     char* s_wxlsocket_cmd[] = {
00048         "wxLUASOCKET_DEBUGGER_CMD_NONE",
00049         "wxLUASOCKET_DEBUGGER_CMD_ADD_BREAKPOINT",
00050         "wxLUASOCKET_DEBUGGER_CMD_REMOVE_BREAKPOINT",
00051         "wxLUASOCKET_DEBUGGER_CMD_DISABLE_BREAKPOINT",
00052         "wxLUASOCKET_DEBUGGER_CMD_ENABLE_BREAKPOINT",
00053         "wxLUASOCKET_DEBUGGER_CMD_CLEAR_ALL_BREAKPOINTS",
00054         "wxLUASOCKET_DEBUGGER_CMD_RUN_BUFFER",
00055         "wxLUASOCKET_DEBUGGER_CMD_DEBUG_STEP",
00056         "wxLUASOCKET_DEBUGGER_CMD_DEBUG_STEPOVER",
00057         "wxLUASOCKET_DEBUGGER_CMD_DEBUG_STEPOUT",
00058         "wxLUASOCKET_DEBUGGER_CMD_DEBUG_CONTINUE",
00059         "wxLUASOCKET_DEBUGGER_CMD_DEBUG_BREAK",
00060         "wxLUASOCKET_DEBUGGER_CMD_RESET",
00061         "wxLUASOCKET_DEBUGGER_CMD_ENUMERATE_STACK",
00062         "wxLUASOCKET_DEBUGGER_CMD_ENUMERATE_STACK_ENTRY",
00063         "wxLUASOCKET_DEBUGGER_CMD_ENUMERATE_TABLE_REF",
00064         "wxLUASOCKET_DEBUGGER_CMD_CLEAR_DEBUG_REFERENCES",
00065         "wxLUASOCKET_DEBUGGER_CMD_EVALUATE_EXPR",
00066     };
00067 
00068     wxString wxLuaSocketCmdEventMsg(int val)
00069     {
00070         if (val <= 0) return wxString::Format(wxT("INVALID SOCKET CMD/EVENT (%d), SOCKET ERROR?"), val);
00071 
00072         if ((val >= wxLUASOCKET_DEBUGGEE_EVENT_BREAK) && (val <= wxLUASOCKET_DEBUGGEE_EVENT__COUNT))
00073             return lua2wx(s_wxlsocket_event[val]);
00074 
00075         if ((val >= wxLUASOCKET_DEBUGGER_CMD_ADD_BREAKPOINT) && (val <= wxLUASOCKET_DEBUGGER_CMD_ENABLE_BREAKPOINT))
00076             return lua2wx(s_wxlsocket_cmd[val - wxLUASOCKET_DEBUGGER_CMD_ADD_BREAKPOINT + 1]);
00077 
00078         return wxString::Format(wxT("INVALID SOCKET CMD/EVENT (%d), SOCKET ERROR?"), val);
00079     }
00080 
00081 
00082     void wxLuaSocketDebugMsg(const wxString& title, const wxString& msg)
00083     {
00084 #ifdef __WXMSW__ // no console in MSW
00085         wxLuaCharBuffer buf(title+ wxString::Format(wxT(" PID %ld TIME %s "), (long)wxGetProcessId(), wxT(__TIME__)) + msg + wxT("\n"));
00086         FILE* h = fopen("wxLua_socketdebug.log", "a");
00087         fprintf(h, buf.GetData());
00088         fclose(h);
00089 #else  // !__WXMSW__
00090         wxSafeShowMessage(title, wxString::Format(wxT("PID %ld TIME %s\n\t"), (long)wxGetProcessId(), wxT(__TIME__)) + msg);
00091 #endif // __WXMSW__
00092     }
00093 
00094 #else // !DEBUG_WXLUASOCKET
00095 
00096     #define wxLuaSocketDebugMsg(title, msg) // do nothing
00097 
00098 #endif //DEBUG_WXLUASOCKET
00099 
00100 // ----------------------------------------------------------------------------
00101 // wxLuaSocketBase
00102 // ----------------------------------------------------------------------------
00103 IMPLEMENT_ABSTRACT_CLASS(wxLuaSocketBase, wxObject);
00104 
00105 bool wxLuaSocketBase::ReadCmd(unsigned char& value_)
00106 {
00107     unsigned char value = 0;
00108     bool ok = Read((char *) &value, sizeof(unsigned char)) == sizeof(unsigned char);
00109     wxLuaSocketDebugMsg(m_name + wxT(" wxLuaSocketBase::ReadCmd"), wxString::Format(wxT("ok %d val %d "), (int)ok, (int)value) + wxLuaSocketCmdEventMsg(value));
00110     if (ok) value_ = value;
00111     return ok;
00112 }
00113 bool wxLuaSocketBase::ReadInt32(wxInt32& value_)
00114 {
00115     wxInt32 value = 0;
00116     bool ok = Read((char *) &value, sizeof(wxInt32)) == sizeof(wxInt32);
00117     wxLuaSocketDebugMsg(m_name + wxT(" wxLuaSocketBase::ReadInt32"), wxString::Format(wxT("ok %d val %d"), (int)ok, value));
00118     if (ok) value_ = value;
00119     return ok;
00120 }
00121 bool wxLuaSocketBase::ReadLong(long& value_)
00122 {
00123     long value = 0;
00124     // make sure that long really works for 32 and 64 bit platforms, use a string
00125     char buf[65] = { 0 }; memset(buf, 0, 65);
00126     bool ok = Read(buf, 64) == 64;
00127     if (ok) ok = lua2wx(buf).ToLong(&value);
00128     wxLuaSocketDebugMsg(m_name + wxT(" wxLuaSocketBase::ReadLong"), wxString::Format(wxT("ok %d val %ld '%s'"), (int)ok, value, lua2wx(buf).c_str()));
00129     if (ok) value_ = value;
00130     return ok;
00131 }
00132 bool wxLuaSocketBase::ReadString(wxString& value_)
00133 {
00134     wxString value;
00135     wxUint32 length = 0;
00136     bool ok = Read((char *) &length, sizeof(wxUint32)) == sizeof(wxUint32);
00137 
00138     if (ok && (length > 0))
00139     {
00140         char *buffer = new char[length + 1];
00141         memset(buffer, 0, length+1);
00142         ok = Read(buffer, length) == (int)length;
00143         buffer[length] = 0;
00144         if (ok) value = lua2wx(buffer);
00145         delete[] buffer;
00146     }
00147 
00148     wxLuaSocketDebugMsg(m_name + wxT(" wxLuaSocketBase::ReadString"), wxString::Format(wxT("ok %d len %u val '%s'"), (int)ok, length, value.c_str()));
00149 
00150     if (ok) value_ = value;
00151     return ok;
00152 }
00153 bool wxLuaSocketBase::ReadDebugData(wxLuaDebugData& value)
00154 {
00155     wxLuaDebugData debugData(true);
00156 
00157     wxInt32 idx, idxMax = 0;
00158     bool ok = ReadInt32(idxMax);
00159 
00160     wxLuaSocketDebugMsg(m_name + wxT(" wxLuaSocketBase::ReadDebugData"), wxString::Format(wxT("items %d"), idxMax));
00161 
00162     for (idx = 0; ok && (idx < idxMax); ++idx)
00163     {
00164         wxInt32 bufferLength = 0;
00165         ok = Read((char*)&bufferLength, sizeof(wxInt32)) == sizeof(wxInt32);
00166 
00167         if (ok && (bufferLength > 0))
00168         {
00169             char *pBuffer = new char[bufferLength];
00170             char *pMemory = pBuffer;
00171             ok = Read(pMemory, bufferLength) == bufferLength;
00172             if (!ok) break;
00173 
00174             wxInt32 nReference = *(wxInt32 *) pMemory;
00175             pMemory += sizeof(wxInt32);
00176 
00177             wxInt32 nIndex = *(wxInt32 *) pMemory;
00178             pMemory += sizeof(wxInt32);
00179 
00180             wxInt32 flag = *(wxInt32 *) pMemory;
00181             pMemory += sizeof(wxInt32);
00182 
00183             wxInt32 keyType = *(wxInt32 *) pMemory;
00184             pMemory += sizeof(wxInt32);
00185 
00186             wxInt32 valueType = *(wxInt32 *) pMemory;
00187             pMemory += sizeof(wxInt32);
00188 
00189             const char *pKeyPtr = pMemory;
00190             pMemory += strlen(pKeyPtr) + 1;
00191             const char *pValuePtr = pMemory;
00192             pMemory += strlen(pValuePtr) + 1;
00193             const char *pSourcePtr = pMemory;
00194 
00195             wxLuaDebugItem *pItem = new wxLuaDebugItem(lua2wx(pKeyPtr), keyType,
00196                                                        lua2wx(pValuePtr), valueType,
00197                                                        lua2wx(pSourcePtr),
00198                                                        nReference,
00199                                                        nIndex,
00200                                                        flag);
00201             debugData.Add(pItem);
00202 
00203             delete[] pBuffer;
00204         }
00205     }
00206 
00207     if (ok) value = debugData;
00208     return ok;
00209 }
00210 
00211 bool wxLuaSocketBase::WriteCmd(char value)
00212 {
00213     wxLuaSocketDebugMsg(m_name + wxT(" wxLuaSocketBase::WriteCmd"), wxString::Format(wxT("val %d "), (int)value) + wxLuaSocketCmdEventMsg(value));
00214     return Write((const char*)&value, sizeof(char)) == sizeof(char);
00215 }
00216 bool wxLuaSocketBase::WriteInt32(wxInt32 value)
00217 {
00218     wxLuaSocketDebugMsg(m_name + wxT(" wxLuaSocketBase::WriteInt32"), wxString::Format(wxT("val %d"), value));
00219     return Write((const char*)&value, sizeof(wxInt32)) == sizeof(wxInt32);
00220 }
00221 bool wxLuaSocketBase::WriteLong(long value)
00222 {
00223     wxLuaSocketDebugMsg(m_name + wxT(" wxLuaSocketBase::WriteLong"), wxString::Format(wxT("val %ld"), value));
00224     // make sure that long really works for 32 and 64 bit platforms, use a string
00225     char buf[65] = { 0 }; memset(buf, 0, 65);
00226     sprintf(buf, "%ld", value);
00227     return Write(buf, 64) == 64;
00228 }
00229 bool wxLuaSocketBase::WriteString(const wxString &value)
00230 {
00231     wxLuaCharBuffer buf(value);
00232     wxUint32 buflen = (wxUint32)buf.Length();
00233 
00234     wxLuaSocketDebugMsg(m_name + wxT(" wxLuaSocketBase::WriteString"), wxString::Format(wxT("len %u val '%s'"), buflen, value.c_str()));
00235 
00236     bool ok = Write((const char*)&buflen, sizeof(wxUint32)) == sizeof(wxUint32);
00237     if (ok && (buflen > 0))
00238         ok = Write(buf.GetData(), buflen) == (int)buflen;
00239 
00240     return ok;
00241 }
00242 bool wxLuaSocketBase::WriteDebugData(const wxLuaDebugData& debugData)
00243 {
00244     // Debug data is written as
00245     // [wxInt32 debug data item count] then for each item
00246     //   [wxInt32 item data length]
00247     //   [{wxInt32 GetReference}{wxInt32 GetIndex}{wxInt32 GetFlag}
00248     //    {char GetName \0}{char GetType \0}{char GetValue \0}{char GetSource \0}]
00249 
00250     wxInt32 idx, idxMax = debugData.GetCount();
00251 
00252     wxLuaSocketDebugMsg(m_name + wxT(" wxLuaSocketBase::WriteDebugData"), wxString::Format(wxT("items %d"), idxMax));
00253 
00254     bool ok = Write((const char*)&idxMax, sizeof(wxInt32)) == sizeof(wxInt32);
00255 
00256     for (idx = 0; ok && (idx < idxMax); ++idx)
00257     {
00258         const wxLuaDebugItem *item = debugData.Item(idx);
00259 
00260         wxLuaCharBuffer keyBuffer(item->GetKey());
00261         wxLuaCharBuffer valueBuffer(item->GetValue());
00262         wxLuaCharBuffer sourceBuffer(item->GetSource());
00263 
00264         int keyLength    = keyBuffer.Length() + 1; // add 1 for terminating \0
00265         int valueLength  = valueBuffer.Length() + 1;
00266         int sourceLength = sourceBuffer.Length() + 1;
00267 
00268         wxInt32 bufferLength = (5 * sizeof(wxInt32)) +
00269                                 keyLength + valueLength + sourceLength;
00270 
00271         unsigned char *pBuffer = new unsigned char[bufferLength];
00272         unsigned char *pMemory = pBuffer;
00273 
00274         ok = Write((const char*)&bufferLength, sizeof(wxInt32)) == sizeof(wxInt32);
00275         if (!ok) break;
00276 
00277         *(wxInt32 *) pMemory = (wxInt32)item->GetRef();
00278         pMemory += sizeof(wxInt32);
00279 
00280         *(wxInt32 *) pMemory = (wxInt32)item->GetIndex();
00281         pMemory += sizeof(wxInt32);
00282 
00283         *(wxInt32 *) pMemory = (wxInt32)item->GetFlag();
00284         pMemory += sizeof(wxInt32);
00285 
00286         *(wxInt32 *) pMemory = (wxInt32)item->GetKeyType();
00287         pMemory += sizeof(wxInt32);
00288 
00289         *(wxInt32 *) pMemory = (wxInt32)item->GetValueType();
00290         pMemory += sizeof(wxInt32);
00291 
00292         memcpy(pMemory, keyBuffer.GetData(), keyLength);
00293         pMemory += keyLength;
00294 
00295         memcpy(pMemory, valueBuffer.GetData(), valueLength);
00296         pMemory += valueLength;
00297 
00298         memcpy(pMemory, sourceBuffer.GetData(), sourceLength);
00299 
00300         ok = Write((const char *) pBuffer, bufferLength) == bufferLength;
00301 
00302         delete[] pBuffer;
00303     }
00304 
00305     return ok;
00306 }
00307 
00308 wxString wxLuaSocketBase::GetErrorMsg(bool clear_msg)
00309 {
00310     wxString s(m_errorMsg);
00311     if (clear_msg)
00312         m_errorMsg.Clear();
00313 
00314     return s;
00315 }
00316 
00317 void wxLuaSocketBase::AddErrorMessage(const wxString& msg)
00318 {
00319     wxString s(msg); // wxT(__TIME__)
00320 
00321     if (m_address.Length() != 0)
00322         s += wxString::Format(wxT(" Address '%s'."), m_address.c_str());
00323     if (m_port_number > 0)
00324         s += wxString::Format(wxT(" Port %d."), m_port_number);
00325 
00326     wxString lastErrorMsg = GetLastErrorMsg();
00327     if (lastErrorMsg.Length() > 0)
00328         s += wxT("\n") + s;
00329 
00330     if (m_errorMsg.Length() > 0)
00331         m_errorMsg += wxT("\n\n");
00332 
00333     m_errorMsg += s;
00334 }
00335 
00336 // ----------------------------------------------------------------------------
00337 // wxLuaCSocket
00338 // ----------------------------------------------------------------------------
00339 IMPLEMENT_ABSTRACT_CLASS(wxLuaCSocket, wxLuaSocketBase);
00340 
00341 wxLuaCSocket::wxLuaCSocket() : m_sock(0), m_sockstate(SOCKET_CLOSED)
00342 {
00343     memset(&m_sockaddress, 0, sizeof(m_sockaddress));
00344 }
00345 
00346 wxLuaCSocket::wxLuaCSocket(socket_type socket, sockaddr_in address)
00347              :m_sock(socket), m_sockaddress(address), m_sockstate(SOCKET_ACCEPTED)
00348 {
00349     m_address = lua2wx(inet_ntoa(m_sockaddress.sin_addr));
00350     m_port_number = ntohs(m_sockaddress.sin_port);
00351 }
00352 
00353 wxLuaCSocket::~wxLuaCSocket()
00354 {
00355     // close the socket if not already closed, don't bother with errors
00356     //  since we should have shut down nicely unless the program is terminating
00357     if (m_sockstate != SOCKET_CLOSED)
00358     {
00359 #ifdef WIN32
00360         ::closesocket(m_sock);
00361 #else
00362         ::close(m_sock);
00363 #endif //WIN32
00364     }
00365 }
00366 
00367 bool wxLuaCSocket::Listen(u_short port_number, int backLog)
00368 {
00369     m_port_number = port_number;
00370 
00371     if (m_sockstate != SOCKET_CLOSED)
00372     {
00373         AddErrorMessage(wxT("Failed to create a listening socket, socket already open."));
00374         return false;
00375     }
00376 
00377     m_sock = ::socket(AF_INET, SOCK_STREAM, 0);
00378 
00379     if (m_sock == INVALID_SOCKET)
00380     {
00381         AddErrorMessage(wxT("Unable to create a listening socket."));
00382         return false;
00383     }
00384 
00385     sockaddr_in localAddr = { 0 };
00386 
00387     localAddr.sin_family      = AF_INET;
00388     localAddr.sin_port        = htons(port_number);
00389     localAddr.sin_addr.s_addr = htonl(INADDR_ANY);
00390 
00391     if (::bind(m_sock, (sockaddr *) &localAddr, sizeof(localAddr)) == SOCKET_ERROR)
00392     {
00393         AddErrorMessage(wxT("Unable to bind to socket to listen for clients."));
00394         return false;
00395     }
00396 
00397     if (::listen(m_sock, backLog) == SOCKET_ERROR)
00398     {
00399         AddErrorMessage(wxT("Unable to listen to bound socket."));
00400         return false;
00401     }
00402 
00403     memset(&m_sockaddress, 0, sizeof(m_sockaddress));
00404     m_sockstate = SOCKET_LISTENING;
00405 
00406     return true;
00407 }
00408 
00409 wxLuaCSocket* wxLuaCSocket::Accept()
00410 {
00411     if (m_sockstate != SOCKET_LISTENING)
00412     {
00413         AddErrorMessage(wxT("Unable to accept from a socket that's not listening."));
00414         return NULL;
00415     }
00416 
00417     sockaddr_in fromAddr = { 0 };
00418     socklen_t length = sizeof(fromAddr);
00419 
00420     socket_type acceptedSocket = ::accept(m_sock, (sockaddr *)&fromAddr, &length);
00421     if (acceptedSocket == INVALID_SOCKET)
00422     {
00423         AddErrorMessage(wxT("Unable to accept socket connection."));
00424         return NULL;
00425     }
00426 
00427     return new wxLuaCSocket(acceptedSocket, fromAddr);
00428 }
00429 
00430 bool wxLuaCSocket::Connect(const wxString &addr, u_short port_number)
00431 {
00432     m_port_number = port_number;
00433     hostent *pHost = NULL;
00434 
00435     if (m_sockstate != SOCKET_CLOSED)
00436     {
00437         AddErrorMessage(wxString::Format(wxT("Unable to connect to addr '%s' socket already open."), addr.c_str()));
00438         return false;
00439     }
00440 
00441     m_sock = ::socket(AF_INET, SOCK_STREAM, 0);
00442     if (m_sock == INVALID_SOCKET)
00443     {
00444         AddErrorMessage(wxString::Format(wxT("Unable to create client socket for addr '%s'."), addr.c_str()));
00445         return false;
00446     }
00447 
00448     unsigned long  address = ::inet_addr(wx2lua(addr));
00449     if (address != INADDR_NONE)
00450         pHost = ::gethostbyaddr((const char*) &address, 4, AF_INET);
00451     else
00452         pHost = ::gethostbyname(wx2lua(addr));
00453 
00454     if (pHost == NULL)
00455     {
00456         AddErrorMessage(wxString::Format(wxT("Unable to get hostbyaddr or gethostbyname for addr '%s'."), addr.c_str()));
00457         return false;
00458     }
00459 
00460     if (pHost->h_addrtype != AF_INET)
00461     {
00462         AddErrorMessage(wxString::Format(wxT("Socket for addr '%s' is wrong type, isn't AF_INET."), addr.c_str()));
00463         return false;
00464     }
00465 
00466     memset(&m_sockaddress, 0, sizeof(m_sockaddress));
00467     memcpy(&(m_sockaddress.sin_addr), pHost->h_addr_list[0], pHost->h_length);
00468 
00469     m_sockaddress.sin_family = AF_INET;
00470     m_sockaddress.sin_port   = htons(port_number);
00471 
00472     m_address = lua2wx(inet_ntoa(m_sockaddress.sin_addr));
00473     m_port_number = ntohs(m_sockaddress.sin_port);
00474 
00475     if (::connect(m_sock, (sockaddr *) &m_sockaddress, sizeof(m_sockaddress)) == SOCKET_ERROR)
00476     {
00477         AddErrorMessage(wxString::Format(wxT("Unable to connect socket to addr '%s'."), addr.c_str()));
00478         return false;
00479     }
00480 
00481     m_sockstate = SOCKET_CONNECTED;
00482     return true;
00483 }
00484 
00485 // Write data to an open socket, repeat until all data has been sent.
00486 int wxLuaCSocket::Write(const char *buffer_, wxUint32 length_)
00487 {
00488     if ((m_sockstate != SOCKET_CONNECTED) && (m_sockstate != SOCKET_ACCEPTED))
00489     {
00490         AddErrorMessage(wxT("Unable to write to unconnected or unaccepted socket. "));
00491         return 0;
00492     }
00493 
00494     int length = length_;
00495     const char *buffer = buffer_;
00496     int num_written = 0;
00497 
00498     while (num_written < length)
00499     {
00500         int s = ::send(m_sock, buffer, length - num_written, 0);
00501         if (s == SOCKET_ERROR)
00502         {
00503             AddErrorMessage(wxT("Got a socket error trying to write to socket."));
00504             return num_written;
00505         }
00506 
00507         num_written += s;
00508         buffer += s;
00509     }
00510 
00511     return num_written;
00512 }
00513 
00514 // Read data from an open socket, repeat reading until all data has been read
00515 int wxLuaCSocket::Read(char *buffer_, wxUint32 length_)
00516 {
00517     if ((m_sockstate != SOCKET_CONNECTED) && (m_sockstate != SOCKET_ACCEPTED))
00518     {
00519         AddErrorMessage(wxT("Unable to read from an unconnected or unaccepted socket. "));
00520         return 0;
00521     }
00522 
00523     int length = length_;
00524     char *buffer = buffer_;
00525     int num_read = 0;
00526 
00527     while (num_read < length)
00528     {
00529         int r = ::recv(m_sock, buffer, length - num_read, 0);
00530         if (r == 0)
00531             return num_read;
00532 
00533         if (r == SOCKET_ERROR)
00534         {
00535             AddErrorMessage(wxT("Got a socket error trying to read."));
00536             return num_read;
00537         }
00538 
00539         num_read += r;
00540         buffer += r;
00541     }
00542 
00543     return num_read;
00544 }
00545 
00546 bool wxLuaCSocket::Shutdown(int how)
00547 {
00548     if (m_sockstate != SOCKET_CLOSED)
00549     {
00550         return ::shutdown(m_sock, how) == 0;
00551     }
00552 
00553     return false;
00554 }
00555 
00556 bool wxLuaCSocket::Close()
00557 {
00558     if (m_sockstate != SOCKET_CLOSED)
00559     {
00560 #ifdef WIN32
00561         if (::closesocket(m_sock) == SOCKET_ERROR)
00562         {
00563             AddErrorMessage(wxT("Unable to close socket."));
00564             return false;
00565         }
00566 #else
00567         if (::close(m_sock))
00568         {
00569             AddErrorMessage(wxT("Unable to close socket."));
00570             return false;
00571         }
00572 #endif // WIN32
00573         else
00574         {
00575             m_sockstate = SOCKET_CLOSED;
00576             return true;
00577         }
00578     }
00579 
00580     return false;
00581 }
00582 
00583 wxString wxLuaCSocket::GetLastErrorMsg() const
00584 {
00585     wxString str;
00586     int errnum = 0;
00587 
00588 #ifdef WIN32
00589     errnum = ::WSAGetLastError();
00590     switch(errnum)
00591     {
00592         case WSANOTINITIALISED:
00593             str = _("A successful WSAStartup must occur before using this function.");
00594             break;
00595         case WSAENETDOWN:
00596             str = _("The network subsystem or the associated service provider has failed.");
00597             break;
00598         case WSAEAFNOSUPPORT:
00599             str = _("The specified address family is not supported.");
00600             break;
00601         case WSAEINPROGRESS:
00602             str = _("A blocking Windows Sockets 1.1 call is in progress, or the service provider is still processing a callback function.");
00603             break;
00604         case WSAEMFILE:
00605             str = _("No more socket descriptors are available.");
00606             break;
00607         case WSAENOBUFS:
00608             str = _("No buffer space is available. The socket cannot be created.");
00609             break;
00610         case WSAEPROTONOSUPPORT:
00611             str = _("The specified protocol is not supported.");
00612             break;
00613         case WSAEPROTOTYPE:
00614             str = _("The specified protocol is the wrong type for this socket.");
00615             break;
00616         case WSAESOCKTNOSUPPORT:
00617             str = _("The specified socket type is not supported in this address family.");
00618             break;
00619     }
00620 
00621 #else // a unix type system
00622 
00623     str = lua2wx(strerror(errno));
00624     errnum = errno;
00625     //wxPrintf(wxT("ERRNO %d '%s' code: %d msg: '%s'\n"), errno, m_description.c_str(), code, m_msg.c_str());
00626 
00627 #endif //WIN32
00628 
00629     if (str.IsEmpty())
00630         str = _("Unknown Socket Error.");
00631 
00632     str = wxString::Format(wxT("Socket Error %d : '%s'"), errnum, str.c_str());
00633 
00634     return str;
00635 }
00636 
00637 // ----------------------------------------------------------------------------
00638 // wxLuawxSocket - Handles Debugger/Debuggee IO
00639 // ----------------------------------------------------------------------------
00640 
00641 bool wxLuawxSocket::Destroy()
00642 {
00643     if (m_socket)
00644     {
00645         wxSocketBase* sock = m_socket;
00646         m_socket = NULL;
00647         return sock->Destroy(); // this deletes the socket
00648     }
00649 
00650     return true;
00651 }
00652 
00653 int wxLuawxSocket::Read(char *buffer, wxUint32 length)
00654 {
00655     wxCHECK_MSG(m_socket, 0, wxT("Invalid wxLuawxSocket"));
00656 
00657     if (!IsConnected())
00658     {
00659         AddErrorMessage(wxT("Unable to read from an unconnected or unaccepted socket. "));
00660         return 0;
00661     }
00662 
00663     long num_read = 0;
00664 
00665     if (m_socket->WaitForRead(20, 0))
00666         num_read = (long)m_socket->Read(buffer, length).LastCount();
00667 
00668     if ((num_read < (long)length) || m_socket->Error())
00669     {
00670         wxString s(wxT("Got a socket error trying to read. "));
00671         if (m_socket->Error())
00672             s += GetLastErrorMsg();
00673 
00674         AddErrorMessage(s);
00675     }
00676 
00677     return num_read;
00678 }
00679 
00680 int wxLuawxSocket::Write(const char *buffer, wxUint32 length)
00681 {
00682     wxCHECK_MSG(m_socket, 0, wxT("Invalid wxLuawxSocket"));
00683 
00684     if (!IsConnected())
00685     {
00686         AddErrorMessage(wxT("Unable to write to an unconnected or unaccepted socket. "));
00687         return 0;
00688     }
00689 
00690     long num_written = 0;
00691 
00692     if (m_socket->WaitForWrite(20, 0))
00693         num_written = m_socket->Write(buffer, length).LastCount();
00694 
00695     if ((num_written < (long)length) || m_socket->Error())
00696     {
00697         wxString s(wxT("Got a socket error trying to read. "));
00698         if (m_socket->Error())
00699             s += GetLastErrorMsg();
00700 
00701         AddErrorMessage(s);
00702     }
00703 
00704     return num_written;
00705 }
00706 
00707 wxString wxLuawxSocket::GetLastErrorMsg() const
00708 {
00709     wxString s;
00710     if ((m_socket == NULL) || !m_socket->Error())
00711         return s;
00712 
00713     switch (m_socket->LastError())
00714     {
00715         case wxSOCKET_NOERROR    : s = wxT("No error happened."); break;
00716         case wxSOCKET_INVOP      : s = wxT("Invalid operation."); break;
00717         case wxSOCKET_IOERR      : s = wxT("Input/Output error."); break;
00718         case wxSOCKET_INVADDR    : s = wxT("Invalid address passed to wxSocket."); break;
00719         case wxSOCKET_INVSOCK    : s = wxT("Invalid socket (uninitialized)."); break;
00720         case wxSOCKET_NOHOST     : s = wxT("No corresponding host."); break;
00721         case wxSOCKET_INVPORT    : s = wxT("Invalid port."); break;
00722         case wxSOCKET_WOULDBLOCK : s = wxT("The socket is non-blocking and the operation would block."); break;
00723         case wxSOCKET_TIMEDOUT   : s = wxT("The timeout for this operation expired."); break;
00724         case wxSOCKET_MEMERR     : s = wxT("Memory exhausted."); break;
00725         default                  : break;
00726     }
00727 
00728     return s;
00729 }
Generated on Tue Jul 13 10:30:39 2010 for wxLua by  doxygen 1.6.3