00001
00002
00003
00004
00005
00006
00007
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
00030
00031
00032
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
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
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
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
00245
00246
00247
00248
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;
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);
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
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
00356
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
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
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
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
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();
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 }