From aa6d970619f8dd5aa0d157953ad431acfde89963 Mon Sep 17 00:00:00 2001 From: Guilhem Lavaux Date: Sun, 5 Sep 1999 10:23:22 +0000 Subject: [PATCH] Updated wxSocket documentation Renamed GSOCK_TIMEOUT to GSOCK_TIMEDOUT Added wxURL::ConvertFromURI Use wxUSE_LIBGIF in imaggif.cpp and samples/html/test/test.cpp Full implementation of "timeout"s in gsocket.c Non-blocking WaitConnection()/Connect() are supported now. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3566 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/sckaddr.tex | 19 ---- docs/latex/wx/socket.tex | 171 ++++++++++++++++++++++++++---- include/wx/gsocket.h | 2 +- include/wx/image.h | 4 + include/wx/motif/setup0.h | 4 + include/wx/msw/setup0.h | 2 + include/wx/sckaddr.h | 3 - include/wx/socket.h | 48 ++++----- include/wx/stubs/setup.h | 4 + include/wx/url.h | 1 + samples/html/test/test.cpp | 3 + src/common/ftp.cpp | 2 +- src/common/http.cpp | 2 +- src/common/imaggif.cpp | 2 +- src/common/socket.cpp | 44 ++++---- src/common/url.cpp | 30 ++++++ src/unix/gsocket.c | 209 ++++++++++++++++++++++--------------- src/unix/gsockunx.h | 1 + 18 files changed, 374 insertions(+), 177 deletions(-) diff --git a/docs/latex/wx/sckaddr.tex b/docs/latex/wx/sckaddr.tex index f356aecb76..e39bf6598f 100644 --- a/docs/latex/wx/sckaddr.tex +++ b/docs/latex/wx/sckaddr.tex @@ -50,25 +50,6 @@ Default destructor. Delete all informations about the address. -% -% Build -% -\membersection{wxSockAddress::Build} - -\func{void}{Build}{\param{struct sockaddr *\&}{ addr}, \param{size\_t\&}{ len}} - -Build a coded socket address. - -% -% Disassemble -% -\membersection{wxSockAddress::Disassemble} - -\func{void}{Disassemble}{\param{struct sockaddr *}{addr}, \param{size\_t}{ len}} - -Decode a socket address. {\bf Actually, you don't have to use this -function: only wxSocketBase use it.} - % % SockAddrLen % diff --git a/docs/latex/wx/socket.tex b/docs/latex/wx/socket.tex index d224507f85..682df90cd9 100644 --- a/docs/latex/wx/socket.tex +++ b/docs/latex/wx/socket.tex @@ -8,9 +8,31 @@ -\wxheading{See also} +\wxheading{wxSocket errors}{wxsocketerrs} + +\twocolwidtha{7cm} +\begin{twocollist}\itemsep=0pt +\twocolitem{{\bf wxSOCKET\_NOERROR}}{No error happened.} +\twocolitem{{\bf wxSOCKET\_INVOP}}{Invalid operation.} +\twocolitem{{\bf wxSOCKET\_IOERR}}{Input/Output error.} +\twocolitem{{\bf wxSOCKET\_INVADDR}}{Invalid address passed to wxSocket.} +\twocolitem{{\bf wxSOCKET\_INVSOCK}}{Invalid socket (uninitialized).} +\twocolitem{{\bf wxSOCKET\_NOHOST}}{No corresponding host.} +\twocolitem{{\bf wxSOCKET\_INVPORT}}{Invalid port.} +\twocolitem{{\bf wxSOCKET\_TRYAGAIN}}{The IO call has a timeout or is in non-blocking mode.} +\twocolitem{{\bf wxSOCKET\_MEMERR}}{Memory exhausted.} +\end{twocollist}% + +\wxheading{wxSocket events}{wxsocketevents} -GSocket for wxWindows +\twocolwidtha{7cm} +\begin{twocollist}\itemsep=0pt +\twocolitem{{\bf wxSOCKET\_INPUT}}{Some data are ready to be got.} +\twocolitem{{\bf wxSOCKET\_OUTPUT}}{The socket is ready to be written to.} +\twocolitem{{\bf wxSOCKET\_CONNECTION}}{Someone want to connect our server.} +\twocolitem{{\bf wxSOCKET\_LOST}}{The connection has been broken.} +\twocolitem{{\bf wxSOCKET\_MAX\_EVENT}}{This should never happen but the compiler may complain about it.} +\end{twocollist}% % --------------------------------------------------------------------------- % Event handling @@ -78,10 +100,35 @@ Destroys the wxSocketBase object. % \membersection{wxSocketBase::SetNotify}\label{wxsocketbasesetnotify} -\func{void}{SetNotify}{\param{GSocketEventFlags}{ event_flags}} +\func{void}{SetNotify}{\param{wxSocketEventFlags}{ event_flags}} SetNotify setups which socket events are to be sent to the event handler. -For more information on socket events see GSocket events. +You specify in parameters a mask of wxSocket events. The flags is: + +\twocolwidtha{7cm} +\begin{twocollist}\itemsep=0pt +\twocolitem{{\bf wxSOCKET\_INPUT\_FLAG}}{to receive wxSOCKET_INPUT} +\twocolitem{{\bf wxSOCKET\_OUTPUT\_FLAG}}{to receive wxSOCKET_OUTPUT} +\twocolitem{{\bf wxSOCKET\_CONNECTION\_FLAG}}{to receive wxSOCKET_CONNECTION} +\twocolitem{{\bf wxSOCKET\_LOST\_FLAG}}{to receive wxSOCKET_LOST} +\end{twocollist}% + +For example: +\begin{verbatim} + sock.SetNotify(wxSOCKET\_INPUT\_FLAG | wxSOCKET\_LOST\_FLAG); +\end{verbatim} +In this example, the user will be notified about incoming socket datas and +a broken connection. + +For more information on socket events see \helpref{wxSocket events}{wxsocketevents}. + +% +% SetTimeout +% +\membersection{wxSocketBase::SetTimeout}{wxsocketbasesettimeout} +\func{void}{SetTimeout}{\param{int }{seconds}} + +This function sets the socket timeout in seconds. % % Notify @@ -136,15 +183,15 @@ Returns TRUE if the socket mustn't wait. \membersection{wxSocketBase::LastCount}\label{wxsocketbaselastcount} -\constfunc{size\_t}{LastCount}{\void} +\constfunc{wxUint32}{LastCount}{\void} Returns the number of bytes read or written by the last IO call. \membersection{wxSocketBase::LastError}\label{wxsocketbaselasterror} -\constfunc{GSocketError}{LastError}{\void} +\constfunc{wxSocketError}{LastError}{\void} -Returns an error in the GSocket format. See GSocket errors. +Returns the last occured wxSocket error. See \helpref{wxSocket errors}{wxsocketerrs}. % --------------------------------------------------------------------------- % IO calls @@ -154,7 +201,7 @@ Returns an error in the GSocket format. See GSocket errors. % \membersection{wxSocketBase::Peek}\label{wxsocketbasepeek} -\func{wxSocketBase\&}{Peek}{\param{char *}{ buffer}, \param{size\_t}{ nbytes}} +\func{wxSocketBase\&}{Peek}{\param{char *}{ buffer}, \param{wxUint32}{ nbytes}} This function peeks a buffer of {\it nbytes} bytes from the socket. Peeking a buffer doesn't delete it from the system socket in-queue. @@ -180,7 +227,7 @@ Returns a reference to the current object. % \membersection{wxSocketBase::Read}\label{wxsocketbaseread} -\func{wxSocketBase\&}{Read}{\param{char *}{ buffer}, \param{size\_t}{ nbytes}} +\func{wxSocketBase\&}{Read}{\param{char *}{ buffer}, \param{wxUint32}{ nbytes}} This function reads a buffer of {\it nbytes} bytes from the socket. @@ -219,7 +266,7 @@ This remark is also valid for all IO call. % \membersection{wxSocketBase::Write}\label{wxsocketbasewrite} -\func{wxSocketBase\&}{Write}{\param{const char *}{ buffer}, \param{size\_t}{ nbytes}} +\func{wxSocketBase\&}{Write}{\param{const char *}{ buffer}, \param{wxUint32}{ nbytes}} This function writes a buffer of {\it nbytes} bytes from the socket. @@ -256,7 +303,7 @@ Returns a reference to the current object. % \membersection{wxSocketBase::WriteMsg}\label{wxsocketbasewritemsg} -\func{wxSocketBase\&}{WriteMsg}{\param{const char *}{ buffer}, \param{size\_t}{ nbytes}} +\func{wxSocketBase\&}{WriteMsg}{\param{const char *}{ buffer}, \param{wxUint32}{ nbytes}} This function writes a buffer of {\it nbytes} bytes from the socket. But it writes a short header before so that ReadMsg can alloc the right size for @@ -284,7 +331,7 @@ Returns a reference to the current object. % \membersection{wxSocketBase::ReadMsg}\label{wxsocketbasereadmsg} -\func{wxSocketBase\&}{ReadMsg}{\param{char *}{ buffer}, \param{size\_t}{ nbytes}} +\func{wxSocketBase\&}{ReadMsg}{\param{char *}{ buffer}, \param{wxUint32}{ nbytes}} This function reads a buffer sent by WriteMsg on a socket. If the buffer passed to the function isn't big enough, the function filled it and then discard the @@ -312,7 +359,7 @@ Returns a reference to the current object. % \membersection{wxSocketBase::Unread}\label{wxsocketbaseunread} -\func{wxSocketBase\&}{Unread}{\param{const char *}{ buffer}, \param{size\_t}{ nbytes}} +\func{wxSocketBase\&}{Unread}{\param{const char *}{ buffer}, \param{wxUint32}{ nbytes}} This function unreads a buffer. It means that the buffer is put in the top of the incoming queue. But, it is put also at the end of all unread buffers. @@ -349,7 +396,7 @@ doesn't wait. % --------------------------------------------------------------------------- \membersection{wxSocketBase::Wait}\label{wxsocketbasewait} -\func{bool}{Wait}{\param{long}{ seconds = -1}, \param{long}{ microsecond = 0}} +\func{bool}{Wait}{\param{long}{ seconds = -1}, \param{long}{ millisecond = 0}} This function waits for an event: it could be an incoming byte, the possibility for the client to write, a lost connection, an incoming connection, an @@ -359,7 +406,7 @@ established connection. \docparam{seconds}{Number of seconds to wait. By default, it waits infinitely.} -\docparam{microsecond}{Number of microseconds to wait.} +\docparam{millisecond}{Number of milliseconds to wait.} \wxheading{Return value} @@ -376,7 +423,7 @@ Returns TRUE if an event occured, FALSE if the timeout was reached. % \membersection{wxSocketBase::WaitForRead}\label{wxsocketbasewaitforread} -\func{bool}{WaitForRead}{\param{long}{ seconds = -1}, \param{long}{ microsecond = 0}} +\func{bool}{WaitForRead}{\param{long}{ seconds = -1}, \param{long}{ millisecond = 0}} This function waits for a read event. @@ -384,7 +431,7 @@ This function waits for a read event. \docparam{seconds}{Number of seconds to wait. By default, it waits infinitely.} -\docparam{microsecond}{Number of microseconds to wait.} +\docparam{millisecond}{Number of milliseconds to wait.} \wxheading{Return value} @@ -401,7 +448,7 @@ Returns TRUE if a byte arrived, FALSE if the timeout was reached. % \membersection{wxSocketBase::WaitForWrite}\label{wxsocketbasewaitforwrite} -\func{bool}{WaitForWrite}{\param{long}{ seconds = -1}, \param{long}{ microsecond = 0}} +\func{bool}{WaitForWrite}{\param{long}{ seconds = -1}, \param{long}{ millisecond = 0}} This function waits for a write event. @@ -409,7 +456,7 @@ This function waits for a write event. \docparam{seconds}{Number of seconds to wait. By default, it waits infinitely.} -\docparam{microsecond}{Number of microseconds to wait.} +\docparam{millisecond}{Number of milliseconds to wait.} \wxheading{Return value} @@ -426,7 +473,7 @@ Returns TRUE if a write event occured, FALSE if the timeout was reached. % \membersection{wxSocketBase::WaitForLost}\label{wxsocketbasewaitforlost} -\func{bool}{Wait}{\param{long}{ seconds = -1}, \param{long}{ microsecond = 0}} +\func{bool}{Wait}{\param{long}{ seconds = -1}, \param{long}{ millisecond = 0}} This function waits for a "lost" event. For instance, the peer may have closed the connection, or the connection may have been broken. @@ -435,7 +482,7 @@ the connection, or the connection may have been broken. \docparam{seconds}{Number of seconds to wait. By default, it waits infinitely.} -\docparam{microsecond}{Number of microseconds to wait.} +\docparam{millisecond}{Number of milliseconds to wait.} \wxheading{Return value} @@ -475,7 +522,49 @@ actually it saves all flags and the state of the asynchronous callbacks. \wxheading{See also} +% +% SaveState +% + \helpref{wxSocketBase::RestoreState}{wxsocketbaserestorestate} +\membersection{wxSocketBase::RestoreState}\label{wxsocketbaserestorestate} + +\func{void}{RestoreState}{\void} + +This function restores the previous state of the socket (include flags, +notify flags, notify state, C callback function and data). + +\wxheading{See also} + +\helpref{wxSocketBase::SaveState}{wxsocketbasesavestate} + +% +% GetLocal +% +\membersection{wxSocketBase::GetLocal}{wxsocketbasegetlocal} +\constfunc{bool}{GetLocal}{\param{wxSockAddress\& }{addr_man}} + +This function returns the local address field of the socket. The local +address field contains the complete local address of the socket (local +address, local port, ...). + +\wxheading{Return value} + +It returns TRUE if no errors happened, FALSE otherwise. + +% +% GetPeer +% +\membersection{wxSocketBase::GetPeer}{wxsocketbasegetlocal} +\constfunc{bool}{GetPeer}{\param{wxSockAddress\& }{addr_man}} + +This function returns the peer address field of the socket. The peer +address field contains the complete peer host address of the socket +(address, port, ...). + +\wxheading{Return value} + +It returns TRUE if no errors happened, FALSE otherwise. % --------------------------------------------------------------------------- % Socket callbacks @@ -494,7 +583,43 @@ Sets an event handler to be called when a socket event occured. \wxheading{See also} +\helpref{wxSocketBase::SetNotify}{wxsocketbasesetnotify} +\helpref{wxSocketBase::Notify}{wxsocketbasenotify} \helpref{wxSocketEvent}{wxsocketevent} +\helpref{wxEvtHandler}{wxevthandler} + +\membersection{wxSocketBase::Callback}\label{wxsocketbasecallback} + +\func{wxSocketBase::wxSockCbk}{Callback}{\param{wxSocketBase::wxSockCbk}{ callback}} + +wxSocket event handler can call C callback. This function allows you to set it. +The format of the callback is as followed: +\begin{verbatim} +void SocketCallback(wxSocketBase& sock,wxSocketNotify evt,char *cdata); +\end{verbatim} + +The first parameter reminds you of the caller socket. The second parameter +informs you about the current event (See \helpref{wxSocket events}{wxsocketevents}). +The third parameters is the client data you specified using \helpref{CallbackData}{wxsocketcallbackdata}. + +\wxheading{Return value} + +It returns the previous callback. + +\wxheading{See also} + +\helpref{wxSocketBase::SetNotify}{wxsocketbasesetnotify} +\helpref{wxSocketBase::Notify}{wxsocketbasenotify} + +\membersection{wxSocketBase::CallbackData}\label{wxsocketcallbackdata} + +\func{char *}{CallbackData}{\param{char *}{cdata}} + +This function sets the the client data which will be passed to a \helpref{C callback}{wxsocketcallback}. + +\wxheading{Return value} + +This function returns the old value of the client data pointer. % --------------------------------------------------------------------------- % CLASS wxSocketClient @@ -563,7 +688,7 @@ Returns TRUE if the connection is established and no error occurs. % \membersection{wxSocketClient::WaitOnConnect}\label{wxsocketclientwaitonconnect} -\func{bool}{WaitOnConnect}{\param{long}{ seconds = -1}, \param{long}{ microseconds = 0}} +\func{bool}{WaitOnConnect}{\param{long}{ seconds = -1}, \param{long}{ milliseconds = 0}} Wait for a "connect" event. @@ -612,7 +737,7 @@ Constructor. \membersection{wxSocketEvent::SocketEvent}\label{wxsocketeventsocketevent} -\constfunc{GSocketEvent}{SocketEvent}{\void} +\constfunc{wxSocketNotify}{SocketEvent}{\void} Returns the socket event type. diff --git a/include/wx/gsocket.h b/include/wx/gsocket.h index 938b6f0b77..1c66aa4584 100644 --- a/include/wx/gsocket.h +++ b/include/wx/gsocket.h @@ -51,7 +51,7 @@ typedef enum { GSOCK_NOHOST, GSOCK_INVPORT, GSOCK_WOULDBLOCK, - GSOCK_TIMEOUT, + GSOCK_TIMEDOUT, GSOCK_MEMERR } GSocketError; diff --git a/include/wx/image.h b/include/wx/image.h index fb0ebb3bfe..a02183e100 100644 --- a/include/wx/image.h +++ b/include/wx/image.h @@ -159,6 +159,8 @@ public: // wxGIFHandler //----------------------------------------------------------------------------- +#if wxUSE_LIBGIF + class WXDLLEXPORT wxGIFHandler : public wxImageHandler { DECLARE_DYNAMIC_CLASS(wxGIFHandler) @@ -180,6 +182,8 @@ public: #endif }; +#endif + //----------------------------------------------------------------------------- // wxPNMHandler //----------------------------------------------------------------------------- diff --git a/include/wx/motif/setup0.h b/include/wx/motif/setup0.h index 8fe235aafe..307855bc98 100644 --- a/include/wx/motif/setup0.h +++ b/include/wx/motif/setup0.h @@ -61,6 +61,10 @@ * Use libjpeg */ #define wxUSE_LIBJPEG 0 +/* + * Use gif + */ +#define wxUSE_LIBGIF 0 /* * Use iODBC */ diff --git a/include/wx/msw/setup0.h b/include/wx/msw/setup0.h index a6a024817a..d3471be263 100644 --- a/include/wx/msw/setup0.h +++ b/include/wx/msw/setup0.h @@ -190,6 +190,8 @@ // Use PNG bitmap code #define wxUSE_LIBJPEG 0 // Use JPEG bitmap code +#define wxUSE_LIBGIF 0 + // Use GIF bitmap code #define wxUSE_SERIAL 0 // Use serialization (requires utils/serialize) #define wxUSE_DYNLIB_CLASS 0 diff --git a/include/wx/sckaddr.h b/include/wx/sckaddr.h index 74f0c57a35..b0bef4a497 100644 --- a/include/wx/sckaddr.h +++ b/include/wx/sckaddr.h @@ -60,9 +60,6 @@ public: wxString Hostname(); unsigned short Service(); - void Build(struct sockaddr*& addr, size_t& len); - void Disassemble(struct sockaddr *addr, size_t len); - inline int Type() { return wxSockAddress::IPV4; } }; diff --git a/include/wx/socket.h b/include/wx/socket.h index ba17e64804..77a04e2f24 100644 --- a/include/wx/socket.h +++ b/include/wx/socket.h @@ -62,7 +62,7 @@ typedef enum { wxSOCKET_NOHOST = GSOCK_NOHOST, wxSOCKET_INVPORT = GSOCK_INVPORT, wxSOCKET_WOULDBLOCK = GSOCK_WOULDBLOCK, - wxSOCKET_TIMEOUT = GSOCK_TIMEOUT, + wxSOCKET_TIMEDOUT = GSOCK_TIMEDOUT, wxSOCKET_MEMERR = GSOCK_MEMERR } wxSocketError; @@ -89,12 +89,12 @@ protected: wxSockFlags m_flags; // wxSocket flags wxSockType m_type; // wxSocket type wxSocketEventFlags m_neededreq; // Specify which requet signals we need - size_t m_lcount; // Last IO request size + wxUint32 m_lcount; // Last IO request size unsigned long m_timeout; // IO timeout value char *m_unread; // Pushback buffer - size_t m_unrd_size; // Pushback buffer size - size_t m_unrd_cur; // Pushback pointer + wxUint32 m_unrd_size; // Pushback buffer size + wxUint32 m_unrd_cur; // Pushback pointer wxSockCbk m_cbk; // C callback char *m_cdata; // C callback data @@ -108,7 +108,7 @@ protected: DEFER_READ, DEFER_WRITE, NO_DEFER } m_defering; // Defering state char *m_defer_buffer; // Defering target buffer - size_t m_defer_nbytes; // Defering buffer size + wxUint32 m_defer_nbytes; // Defering buffer size wxTimer *m_defer_timer; // Timer for defering mode wxList m_states; // Stack of states @@ -119,17 +119,17 @@ public: virtual bool Close(); // Base IO - wxSocketBase& Peek(char* buffer, size_t nbytes); - wxSocketBase& Read(char* buffer, size_t nbytes); - wxSocketBase& Write(const char *buffer, size_t nbytes); - wxSocketBase& Unread(const char *buffer, size_t nbytes); - wxSocketBase& ReadMsg(char *buffer, size_t nbytes); - wxSocketBase& WriteMsg(const char *buffer, size_t nbytes); + wxSocketBase& Peek(char* buffer, wxUint32 nbytes); + wxSocketBase& Read(char* buffer, wxUint32 nbytes); + wxSocketBase& Write(const char *buffer, wxUint32 nbytes); + wxSocketBase& Unread(const char *buffer, wxUint32 nbytes); + wxSocketBase& ReadMsg(char *buffer, wxUint32 nbytes); + wxSocketBase& WriteMsg(const char *buffer, wxUint32 nbytes); void Discard(); // Try not to use this two methods (they sould be protected) - void CreatePushbackAfter(const char *buffer, size_t size); - void CreatePushbackBefore(const char *buffer, size_t size); + void CreatePushbackAfter(const char *buffer, wxUint32 size); + void CreatePushbackBefore(const char *buffer, wxUint32 size); // Status inline bool Ok() const { return (m_socket != NULL); }; @@ -139,21 +139,21 @@ public: inline bool IsDisconnected() const { return !IsConnected(); }; inline bool IsNoWait() const { return ((m_flags & NOWAIT) != 0); }; bool IsData() const; - inline size_t LastCount() const { return m_lcount; } + inline wxUint32 LastCount() const { return m_lcount; } inline wxSocketError LastError() const { return (wxSocketError)GSocket_GetError(m_socket); } inline wxSockType GetType() const { return m_type; } void SetFlags(wxSockFlags _flags); wxSockFlags GetFlags() const; - inline void SetTimeout(unsigned long sec) { m_timeout = sec; } + void SetTimeout(unsigned long sec); // seconds = -1 means infinite wait // seconds = 0 means no wait // seconds > 0 means specified wait - bool Wait(long seconds = -1, long microseconds = 0); - bool WaitForRead(long seconds = -1, long microseconds = 0); - bool WaitForWrite(long seconds = -1, long microseconds = 0); - bool WaitForLost(long seconds = -1, long microseconds = 0); + bool Wait(long seconds = -1, long milliseconds = 0); + bool WaitForRead(long seconds = -1, long milliseconds = 0); + bool WaitForWrite(long seconds = -1, long milliseconds = 0); + bool WaitForLost(long seconds = -1, long milliseconds = 0); // Save the current state of Socket void SaveState(); @@ -200,14 +200,14 @@ public: protected: #endif - bool _Wait(long seconds, long microseconds, int type); + bool _Wait(long seconds, long milliseconds, int type); - int DeferRead(char *buffer, size_t nbytes); - int DeferWrite(const char *buffer, size_t nbytes); + int DeferRead(char *buffer, wxUint32 nbytes); + int DeferWrite(const char *buffer, wxUint32 nbytes); void DoDefer(wxSocketNotify evt); // Pushback library - size_t GetPushback(char *buffer, size_t size, bool peek); + wxUint32 GetPushback(char *buffer, wxUint32 size, bool peek); }; //////////////////////////////////////////////////////////////////////// @@ -237,7 +237,7 @@ public: virtual bool Connect(wxSockAddress& addr_man, bool wait = TRUE); - bool WaitOnConnect(long seconds = -1, long microseconds = 0); + bool WaitOnConnect(long seconds = -1, long milliseconds = 0); virtual void OnRequest(wxSocketNotify flags); }; diff --git a/include/wx/stubs/setup.h b/include/wx/stubs/setup.h index 68f1572249..c11c00ae61 100644 --- a/include/wx/stubs/setup.h +++ b/include/wx/stubs/setup.h @@ -120,6 +120,10 @@ // Use zlib for compression in streams and PNG code #define wxUSE_LIBPNG 1 // Use PNG bitmap code +#define wxUSE_LIBPNG 0 + // Use JPEG bitmap code +#define wxUSE_LIBGIF 0 + // Use GIF bitmap code #define wxUSE_STD_IOSTREAM 1 // Use standard C++ streams if 1. If 0, use wxWin // streams implementation. diff --git a/include/wx/url.h b/include/wx/url.h index 0b145297ef..40ff50c370 100644 --- a/include/wx/url.h +++ b/include/wx/url.h @@ -82,6 +82,7 @@ public: #endif static wxString ConvertToValidURI(const wxString& uri); + static wxString ConvertFromURI(const wxString& uri); }; #endif diff --git a/samples/html/test/test.cpp b/samples/html/test/test.cpp index fa61e56489..d167408c47 100644 --- a/samples/html/test/test.cpp +++ b/samples/html/test/test.cpp @@ -114,6 +114,9 @@ #if wxUSE_LIBJPEG wxImage::AddHandler(new wxJPEGHandler); #endif + #if wxUSE_LIBGIF + wxImage::AddHandler(new wxGIFHandler); + #endif // Create the main application window MyFrame *frame = new MyFrame("wxHtmlWindow testing application", wxPoint(50, 50), wxSize(640, 480)); diff --git a/src/common/ftp.cpp b/src/common/ftp.cpp index b789852c92..094fdad98b 100644 --- a/src/common/ftp.cpp +++ b/src/common/ftp.cpp @@ -340,7 +340,7 @@ wxInputStream *wxFTP::GetInputStream(const wxString& path) return NULL; } - tmp_str = _T("RETR ") + path; + tmp_str = _T("RETR ") + wxURL::ConvertFromURI(path); if (!SendCommand(tmp_str, '1')) return NULL; diff --git a/src/common/http.cpp b/src/common/http.cpp index f9c7722269..00b711b2ad 100644 --- a/src/common/http.cpp +++ b/src/common/http.cpp @@ -289,7 +289,7 @@ size_t wxHTTPStream::OnSysRead(void *buffer, size_t bufsize) bool wxHTTP::Abort(void) { - bool ret, connected; + bool ret; ret = wxSocketClient::Close(); diff --git a/src/common/imaggif.cpp b/src/common/imaggif.cpp index c4e42ff7f9..55348602d1 100644 --- a/src/common/imaggif.cpp +++ b/src/common/imaggif.cpp @@ -23,7 +23,7 @@ # include "wx/defs.h" #endif -#if 1 // change this to #if wxUSE_GIF +#if wxUSE_LIBGIF #include "wx/image.h" #include "wx/gifdecod.h" diff --git a/src/common/socket.cpp b/src/common/socket.cpp index 6201f0de4d..7c13039777 100644 --- a/src/common/socket.cpp +++ b/src/common/socket.cpp @@ -139,7 +139,7 @@ class _wxSocketInternalTimer: public wxTimer { } }; -int wxSocketBase::DeferRead(char *buffer, size_t nbytes) +int wxSocketBase::DeferRead(char *buffer, wxUint32 nbytes) { wxSocketEventFlags old_event_flags; bool old_notify_state; @@ -187,7 +187,7 @@ int wxSocketBase::DeferRead(char *buffer, size_t nbytes) return nbytes-m_defer_nbytes; } -wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes) +wxSocketBase& wxSocketBase::Read(char* buffer, wxUint32 nbytes) { int ret = 1; @@ -232,7 +232,7 @@ wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes) return *this; } -wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes) +wxSocketBase& wxSocketBase::ReadMsg(char* buffer, wxUint32 nbytes) { unsigned long len, len2, sig; struct { @@ -241,23 +241,23 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes) } 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 @@ -279,9 +279,9 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes) 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) @@ -290,7 +290,7 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes) return *this; } -wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes) +wxSocketBase& wxSocketBase::Peek(char* buffer, wxUint32 nbytes) { Read(buffer, nbytes); CreatePushbackAfter(buffer, nbytes); @@ -298,7 +298,7 @@ wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes) return *this; } -int wxSocketBase::DeferWrite(const char *buffer, size_t nbytes) +int wxSocketBase::DeferWrite(const char *buffer, wxUint32 nbytes) { wxSocketEventFlags old_event_flags; bool old_notify_state; @@ -343,7 +343,7 @@ int wxSocketBase::DeferWrite(const char *buffer, size_t nbytes) return nbytes-m_defer_nbytes; } -wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes) +wxSocketBase& wxSocketBase::Write(const char *buffer, wxUint32 nbytes) { int ret; @@ -358,7 +358,7 @@ wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes) return *this; } -wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes) +wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, wxUint32 nbytes) { struct { char sig[4]; @@ -399,7 +399,7 @@ wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes) #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) { @@ -461,7 +461,7 @@ void wxSocketBase::Discard() { #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(NOWAIT | SPEED); @@ -742,7 +742,7 @@ void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id) // --------- wxSocketBase pushback library ---------------------- // -------------------------------------------------------------- -void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size) +void wxSocketBase::CreatePushbackAfter(const char *buffer, wxUint32 size) { char *curr_pos; @@ -757,7 +757,7 @@ void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size) 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); @@ -776,7 +776,7 @@ void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t 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; diff --git a/src/common/url.cpp b/src/common/url.cpp index a51ee7b273..6c735d5599 100644 --- a/src/common/url.cpp +++ b/src/common/url.cpp @@ -385,3 +385,33 @@ wxString wxURL::ConvertToValidURI(const wxString& uri) return out_str; } +wxString wxURL::ConvertFromURI(const wxString& uri) +{ + int code; + int i; + wxString new_uri; + + new_uri.Empty(); + + i = 0; + while (i= _T('A') && uri[i] <= _T('F')) + code = (uri[i] - _T('A') + 10) * 16; + else + code = (uri[i] - _T('0')) * 16; + i++; + if (uri[i] >= _T('A') && uri[i] <= _T('F')) + code += (uri[i] - _T('A')) + 10; + else + code += (uri[i] - _T('0')); + i++; + new_uri += (wxChar)code; + continue; + } + new_uri += uri[i]; + i++; + } + return new_uri; +} diff --git a/src/unix/gsocket.c b/src/unix/gsocket.c index 2ffafc86b6..de516f4506 100644 --- a/src/unix/gsocket.c +++ b/src/unix/gsocket.c @@ -57,13 +57,34 @@ #endif -#if !defined(__LINUX__) && !defined(__FREEBSD__) -# define CAN_USE_TIMEOUT -#elif defined(__GLIBC__) && defined(__GLIBC_MINOR__) -# if (__GLIBC__ == 2) && (__GLIBC_MINOR__ == 1) -# define CAN_USE_TIMEOUT -# endif -#endif +#define MASK_SIGNAL() \ +{ \ + void (*old_handler)(int); \ +\ + old_handler = signal(SIGPIPE, SIG_IGN); + +#define UNMASK_SIGNAL() \ + signal(SIGPIPE, old_handler); \ +} + +#define ENABLE_TIMEOUT(socket) \ +{ \ + struct itimerval old_ival, new_ival; \ + void (*old_timer_sig)(int); \ +\ + old_timer_sig = signal(SIGALRM, SIG_DFL); \ + siginterrupt(SIGALRM, 1); \ + new_ival.it_value.tv_sec = socket->m_timeout / 1000; \ + new_ival.it_value.tv_usec = (socket->m_timeout % 1000) * 1000; \ + new_ival.it_interval.tv_sec = 0; \ + new_ival.it_interval.tv_usec = 0; \ + setitimer(ITIMER_REAL, &new_ival, &old_ival); + +#define DISABLE_TIMEOUT(socket) \ + signal(SIGALRM, old_timer_sig); \ + siginterrupt(SIGALRM, 0); \ + setitimer(ITIMER_REAL, &old_ival, NULL); \ +} /* Global initialisers */ @@ -102,6 +123,7 @@ GSocket *GSocket_new() socket->m_non_blocking = FALSE; socket->m_timeout = 10*60*1000; /* 10 minutes * 60 sec * 1000 millisec */ + socket->m_establishing = FALSE; /* We initialize the GUI specific entries here */ _GSocket_GUI_Init(socket); @@ -197,6 +219,7 @@ GAddress *GSocket_GetLocal(GSocket *socket) GAddress *address; struct sockaddr addr; SOCKLEN_T size; + GSocketError err; assert(socket != NULL); @@ -220,7 +243,8 @@ GAddress *GSocket_GetLocal(GSocket *socket) socket->m_error = GSOCK_MEMERR; return NULL; } - if (_GAddress_translate_from(address, &addr, size) != GSOCK_NOERROR) { + socket->m_error = _GAddress_translate_from(address, &addr, size); + if (socket->m_error != GSOCK_NOERROR) { GAddress_destroy(address); return NULL; } @@ -317,12 +341,29 @@ GSocket *GSocket_WaitConnection(GSocket *socket) /* Create a GSocket object for the new connection */ connection = GSocket_new(); + if (!connection) { + connection->m_error = GSOCK_MEMERR; + return NULL; + } /* Accept the incoming connection */ + ENABLE_TIMEOUT(connection); connection->m_fd = accept(socket->m_fd, NULL, NULL); + DISABLE_TIMEOUT(connection); if (connection->m_fd == -1) { GSocket_destroy(connection); - socket->m_error = GSOCK_IOERR; + switch(errno) { + case EINTR: + case ETIMEDOUT: + connection->m_error = GSOCK_TIMEDOUT; + break; + case EWOULDBLOCK: + connection->m_error = GSOCK_WOULDBLOCK; + break; + default: + connection->m_error = GSOCK_IOERR; + break; + } return NULL; } @@ -357,6 +398,11 @@ GSocketError GSocket_SetNonOriented(GSocket *sck) /* Create the socket */ sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0); + if (sck->m_fd < 0) { + sck->m_error = GSOCK_IOERR; + return GSOCK_IOERR; + } + /* Bind it to the LOCAL address */ if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) { close(sck->m_fd); @@ -380,7 +426,7 @@ GSocketError GSocket_SetNonOriented(GSocket *sck) */ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream) { - int type; + int type, err; assert(sck != NULL); @@ -411,22 +457,34 @@ GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream) return GSOCK_IOERR; } + GSocket_SetNonBlocking(sck, sck->m_non_blocking); + GSocket_SetTimeout(sck, sck->m_timeout); + /* Connect it to the PEER address */ - if (connect(sck->m_fd, sck->m_peer->m_addr, - sck->m_peer->m_len) != 0) { + ENABLE_TIMEOUT(sck); + err = connect(sck->m_fd, sck->m_peer->m_addr, sck->m_peer->m_len); + DISABLE_TIMEOUT(sck); + + if (err != 0 && errno != EINPROGRESS) { close(sck->m_fd); sck->m_fd = -1; - sck->m_error = GSOCK_IOERR; + switch (errno) { + case EINTR: + case ETIMEDOUT: + sck->m_error = GSOCK_TIMEDOUT; + break; + default: + sck->m_error = GSOCK_IOERR; + break; + } return GSOCK_IOERR; } /* It is not a server */ - sck->m_server = FALSE; - - GSocket_SetNonBlocking(sck, sck->m_non_blocking); - GSocket_SetTimeout(sck, sck->m_timeout); + sck->m_server = FALSE; + sck->m_establishing = (errno == EINPROGRESS); - return GSOCK_NOERROR; + return (sck->m_establishing) ? GSOCK_WOULDBLOCK : GSOCK_NOERROR; } /* Generic IO */ @@ -516,25 +574,6 @@ void GSocket_SetTimeout(GSocket *socket, unsigned long millisec) assert(socket != NULL); socket->m_timeout = millisec; - /* Neither GLIBC 2.0 nor the kernel 2.0.36 define SO_SNDTIMEO or - SO_RCVTIMEO. The man pages, that these flags should exist but - are read only. RR. */ - /* OK, restrict this to GLIBC 2.1. GL. */ - /* Anyway, they seem to pose problems: I need to know the socket level and - it varies (may be SOL_TCP, SOL_UDP, ...). I disables this and use the - other solution. GL. */ -#if 0 -#ifdef CAN_USE_TIMEOUT - if (socket->m_fd != -1) { - struct timeval tval; - - tval.tv_sec = millisec / 1000; - tval.tv_usec = (millisec % 1000) * 1000; - setsockopt(socket->m_fd, SOL_SOCKET, SO_SNDTIMEO, &tval, sizeof(tval)); - setsockopt(socket->m_fd, SOL_SOCKET, SO_RCVTIMEO, &tval, sizeof(tval)); - } -#endif -#endif } /* @@ -605,7 +644,7 @@ void GSocket_UnsetCallback(GSocket *socket, GSocketEventFlags event) } } -#define CALL_FALLBACK(socket, event) \ +#define CALL_CALLBACK(socket, event) \ if (socket->m_iocalls[event] && \ socket->m_cbacks[event]) {\ _GSocket_Disable(socket, event); \ @@ -613,35 +652,6 @@ if (socket->m_iocalls[event] && \ socket->m_data[event]); \ } -#define MASK_SIGNAL() \ -{ \ - void (*old_handler)(int); \ -\ - old_handler = signal(SIGPIPE, SIG_IGN); - -#define UNMASK_SIGNAL() \ - signal(SIGPIPE, old_handler); \ -} - -#define ENABLE_TIMEOUT(socket) \ -{ \ - struct itimerval old_ival, new_ival; \ - void (*old_timer_sig)(int); \ -\ - old_timer_sig = signal(SIGALRM, SIG_DFL); \ - siginterrupt(SIGALRM, 1); \ - new_ival.it_value.tv_sec = socket->m_timeout / 1000; \ - new_ival.it_value.tv_usec = (socket->m_timeout % 1000) * 1000; \ - new_ival.it_interval.tv_sec = 0; \ - new_ival.it_interval.tv_usec = 0; \ - setitimer(ITIMER_REAL, &new_ival, &old_ival); - -#define DISABLE_TIMEOUT(socket) \ - signal(SIGALRM, old_timer_sig); \ - siginterrupt(SIGALRM, 0); \ - setitimer(ITIMER_REAL, &old_ival, NULL); \ -} - void _GSocket_Enable(GSocket *socket, GSocketEvent event) { socket->m_iocalls[event] = TRUE; @@ -666,14 +676,19 @@ int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size) DISABLE_TIMEOUT(socket); UNMASK_SIGNAL(); - if (ret == -1 && errno != EWOULDBLOCK) { - socket->m_error = GSOCK_IOERR; - return -1; + if (ret == -1 && + errno != ETIMEDOUT && errno != EWOULDBLOCK && errno != EINTR) { + socket->m_error = GSOCK_IOERR; + return -1; } if (errno == EWOULDBLOCK) { socket->m_error = GSOCK_WOULDBLOCK; return -1; } + if (errno == ETIMEDOUT || errno == EINTR) { + socket->m_error = GSOCK_TIMEDOUT; + return -1; + } return ret; } @@ -682,6 +697,7 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size) struct sockaddr from; SOCKLEN_T fromlen; int ret; + GSocketError err; fromlen = sizeof(from); @@ -690,7 +706,7 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size) ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen); DISABLE_TIMEOUT(socket); UNMASK_SIGNAL(); - if (ret == -1 && errno != EWOULDBLOCK) { + if (ret == -1 && errno != EWOULDBLOCK && errno != EINTR && errno != ETIMEDOUT) { socket->m_error = GSOCK_IOERR; return -1; } @@ -698,6 +714,10 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size) socket->m_error = GSOCK_WOULDBLOCK; return -1; } + if (errno == ETIMEDOUT || errno == EINTR) { + socket->m_error = GSOCK_TIMEDOUT; + return -1; + } /* Translate a system address into a GSocket address */ if (!socket->m_peer) { @@ -707,8 +727,13 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size) return -1; } } - if (_GAddress_translate_from(socket->m_peer, &from, fromlen) != GSOCK_NOERROR) + err = _GAddress_translate_from(socket->m_peer, &from, fromlen); + if (err != GSOCK_NOERROR) { + GAddress_destroy(socket->m_peer); + socket->m_peer = NULL; + socket->m_error = err; return -1; + } return ret; } @@ -716,13 +741,14 @@ int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size) int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size) { int ret; + GSocketError err; MASK_SIGNAL(); ENABLE_TIMEOUT(socket); ret = send(socket->m_fd, buffer, size, 0); DISABLE_TIMEOUT(socket); UNMASK_SIGNAL(); - if (ret == -1 && errno != EWOULDBLOCK) { + if (ret == -1 && errno != EWOULDBLOCK && errno != ETIMEDOUT && errno != EINTR) { socket->m_error = GSOCK_IOERR; return -1; } @@ -730,6 +756,10 @@ int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size) socket->m_error = GSOCK_WOULDBLOCK; return -1; } + if (errno == ETIMEDOUT || errno == EINTR) { + socket->m_error = GSOCK_TIMEDOUT; + return -1; + } return ret; } @@ -737,13 +767,16 @@ int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size) { struct sockaddr *addr; int len, ret; + GSocketError err; if (!socket->m_peer) { socket->m_error = GSOCK_INVADDR; return -1; } - if (_GAddress_translate_to(socket->m_peer, &addr, &len) != GSOCK_NOERROR) { + err = _GAddress_translate_to(socket->m_peer, &addr, &len); + if (err != GSOCK_NOERROR) { + socket->m_error = err; return -1; } @@ -777,26 +810,38 @@ void _GSocket_Detected_Read(GSocket *socket) ret = recv(socket->m_fd, &c, 1, MSG_PEEK); if (ret < 0 && socket->m_server) { - CALL_FALLBACK(socket, GSOCK_CONNECTION); + CALL_CALLBACK(socket, GSOCK_CONNECTION); return; } if (ret > 0) { - CALL_FALLBACK(socket, GSOCK_INPUT); + CALL_CALLBACK(socket, GSOCK_INPUT); } else { - CALL_FALLBACK(socket, GSOCK_LOST); + CALL_CALLBACK(socket, GSOCK_LOST); } } } void _GSocket_Detected_Write(GSocket *socket) { - CALL_FALLBACK(socket, GSOCK_OUTPUT); -} + if (socket->m_establishing) { + int error, len; + + len = sizeof(error); -#undef CALL_FALLBACK -#undef MASK_SIGNAL -#undef UNMASK_SIGNAL + socket->m_establishing = FALSE; + getsockopt(socket->m_fd, SOL_SOCKET, SO_ERROR, &error, &len); + + if (error) { + socket->m_error = GSOCK_IOERR; + GSocket_Shutdown(socket); + } else + socket->m_error = GSOCK_NOERROR; + + CALL_CALLBACK(socket, GSOCK_CONNECTION); + } else + CALL_CALLBACK(socket, GSOCK_OUTPUT); +} /* * ------------------------------------------------------------------------- diff --git a/src/unix/gsockunx.h b/src/unix/gsockunx.h index 79321a2374..2981d1293f 100644 --- a/src/unix/gsockunx.h +++ b/src/unix/gsockunx.h @@ -26,6 +26,7 @@ struct _GSocket { GSocketError m_error; bool m_non_blocking, m_server, m_stream, m_oriented; + bool m_establishing; unsigned long m_timeout; /* Callbacks */ -- 2.45.2