]> git.saurik.com Git - wxWidgets.git/commitdiff
Added GSocket for Unix (only GTK for the moment)
authorGuilhem Lavaux <lavaux@easynet.fr>
Thu, 22 Jul 1999 17:51:54 +0000 (17:51 +0000)
committerGuilhem Lavaux <lavaux@easynet.fr>
Thu, 22 Jul 1999 17:51:54 +0000 (17:51 +0000)
Updated wxSocket to use GSocket API
Added a progress bar to client.cpp
Added CopyTo to wxMemoryOutputStream to copy the internal buffer to a specified buffer.
Various changes/fixes to the high-level protocols FTP/HTTP
Various Unicode fixes
Removed sckint.*

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@3085 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775

30 files changed:
include/wx/gsocket.h [new file with mode: 0644]
include/wx/mstream.h
include/wx/sckaddr.h
include/wx/sckint.h [deleted file]
include/wx/sckipc.h
include/wx/sckstrm.h
include/wx/socket.h
include/wx/textctrl.h
samples/wxsocket/client.cpp
samples/wxsocket/server.cpp
src/common/ffile.cpp
src/common/ftp.cpp
src/common/http.cpp
src/common/log.cpp
src/common/mstream.cpp
src/common/sckaddr.cpp
src/common/sckint.cpp [deleted file]
src/common/sckipc.cpp
src/common/sckstrm.cpp
src/common/socket.cpp
src/common/stream.cpp
src/common/textcmn.cpp
src/common/url.cpp
src/common/wfstream.cpp
src/gtk/Makefile.am
src/gtk/gsockgtk.c [new file with mode: 0644]
src/gtk1/Makefile.am
src/gtk1/gsockgtk.c [new file with mode: 0644]
src/unix/gsocket.c [new file with mode: 0644]
src/unix/gsockunx.h [new file with mode: 0644]

diff --git a/include/wx/gsocket.h b/include/wx/gsocket.h
new file mode 100644 (file)
index 0000000..096cff1
--- /dev/null
@@ -0,0 +1,233 @@
+/* -------------------------------------------------------------------------
+ * Project: GSocket (Generic Socket)
+ * Name:    gsocket.h
+ * Purpose: GSocket include file (system independent)
+ * CVSID:   $Id$
+ * Log:     $Log$
+ * Log:     Revision 1.1  1999/07/22 17:51:47  GL
+ * Log:     Added GSocket for Unix (only GTK for the moment)
+ * Log:     Updated wxSocket to use GSocket API
+ * Log:     Added a progress bar to client.cpp
+ * Log:     Added CopyTo to wxMemoryOutputStream to copy the internal buffer to a specified buffer.
+ * Log:     Various changes/fixes to the high-level protocols FTP/HTTP
+ * Log:     Various Unicode fixes
+ * Log:     Removed sckint.*
+ * Log:
+ * Log:     Revision 1.2  1999/07/18 15:54:28  guilhem
+ * Log:     Copyright, etc.
+ * Log:
+ * -------------------------------------------------------------------------
+ */
+#ifndef __GSOCKET_H
+#define __GSOCKET_H
+
+#include <sys/types.h>
+
+#if !defined(__cplusplus)
+
+typedef int bool;
+
+#endif
+
+#ifndef TRUE
+#define TRUE 1
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+typedef struct _GSocket GSocket;
+typedef struct _GAddress GAddress;
+
+typedef enum {
+  GSOCK_NOFAMILY = 0,
+  GSOCK_INET,
+  GSOCK_INET6,
+  GSOCK_UNIX
+} GAddressType;
+
+typedef enum {
+  GSOCK_STREAMED,
+  GSOCK_UNSTREAMED
+} GSocketStream;
+
+typedef enum {
+  GSOCK_NOERROR = 0,
+  GSOCK_INVOP,
+  GSOCK_IOERR,
+  GSOCK_INVADDR,
+  GSOCK_INVSOCK,
+  GSOCK_NOHOST,
+  GSOCK_INVPORT
+} GSocketError;
+
+typedef enum {
+  GSOCK_INPUT  = 0,
+  GSOCK_OUTPUT = 1,
+  GSOCK_CONNECTION = 2,
+  GSOCK_LOST = 3,
+  GSOCK_MAX_EVENT = 4
+} GSocketEvent;
+
+enum {
+  GSOCK_INPUT_FLAG = 1 << GSOCK_INPUT,
+  GSOCK_OUTPUT_FLAG = 1 << GSOCK_OUTPUT,
+  GSOCK_CONNECTION_FLAG = 1 << GSOCK_CONNECTION,
+  GSOCK_LOST_FLAG = 1 << GSOCK_LOST,
+};
+
+typedef int GSocketEventFlags;
+
+typedef void (*GSocketFallback)(GSocket *socket, GSocketEvent event,
+                               char *cdata);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Constructors / Destructors */
+
+GSocket *GSocket_new();
+void GSocket_destroy(GSocket *socket);
+
+/* This will disable all IO calls to this socket but errors are still available */
+void GSocket_Shutdown(GSocket *socket);
+
+/* Address handling */
+
+GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address);
+GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address);
+GAddress *GSocket_GetLocal(GSocket *socket);
+GAddress *GSocket_GetPeer(GSocket *socket);
+
+/* Non-oriented connections handlers */
+
+GSocketError GSocket_SetNonOriented(GSocket *socket);
+
+/* Server specific parts */
+
+/*
+  GSocket_SetServer() setup the socket as a server. It uses the "Local" field
+  of GSocket. "Local" must be set by GSocket_SetLocal() before
+  GSocket_SetServer() is called. In the other case, it returns GSOCK_INVADDR.
+*/
+GSocketError GSocket_SetServer(GSocket *socket);
+
+/*
+  GSocket_WaitConnection() waits for an incoming client connection.
+*/
+GSocket *GSocket_WaitConnection(GSocket *socket);
+
+/* Client specific parts */
+
+/*
+  GSocket_Connect() establishes a client connection to a server using the "Peer"
+  field of GSocket. "Peer" must be set by GSocket_SetPeer() before
+  GSocket_Connect() is called. In the other case, it returns GSOCK_INVADDR.
+*/
+GSocketError GSocket_Connect(GSocket *socket, GSocketStream stream);
+
+/* Generic IO */
+
+/* Like recv(), send(), ... */
+/* 
+   NOTE: In case we read from a non-oriented connection, the incoming (outgoing)
+   connection address is stored in the "Local" ("Peer") field. 
+*/
+int GSocket_Read(GSocket *socket, char *buffer, int size);
+int GSocket_Write(GSocket *socket, const char *buffer,
+                 int size);
+bool GSocket_DataAvailable(GSocket *socket);
+
+/* Flags */
+
+/*
+  GSocket_SetBlocking() puts the socket in non-blocking mode. This is useful
+  if we don't want to wait.
+*/
+void GSocket_SetBlocking(GSocket *socket, bool block);
+
+/*
+  GSocket_GetError() returns the last error occured on the socket stream.
+*/
+
+GSocketError GSocket_GetError(GSocket *socket);
+
+/* Callbacks */
+
+/* 
+   Only one fallback is possible for each event (INPUT, OUTPUT, CONNECTION, LOST)
+   INPUT: The function is called when there is at least a byte in the 
+          input buffer
+   OUTPUT: The function is called when the system is sure the next write call
+           will not block
+   CONNECTION: Two cases is possible:
+             Client socket -> the connection is established
+            Server socket -> a client request a connection
+   LOST: the connection is lost
+
+   SetFallback accepts a combination of these flags so a same callback can
+   receive different events.
+
+   An event is generated only once and its state is reseted when the relative
+   IO call is requested.
+   For example: INPUT -> GSocket_Read()
+                CONNECTION -> GSocket_Accept()
+*/
+void GSocket_SetFallback(GSocket *socket, GSocketEventFlags event,
+                        GSocketFallback fallback, char *cdata);
+
+/*
+  UnsetFallback will disables all fallbacks specified by "event".
+  NOTE: event may be a combination of flags
+*/
+void GSocket_UnsetFallback(GSocket *socket, GSocketEventFlags event);
+
+/* GAddress */
+
+GAddress *GAddress_new();
+GAddress *GAddress_copy(GAddress *address);
+void GAddress_destroy(GAddress *address);
+
+void GAddress_SetFamily(GAddress *address, GAddressType type);
+GAddressType GAddress_GetFamily(GAddress *address);
+
+/* 
+   The use of any of the next functions will set the address family to the adapted
+   one. For example if you use GAddress_INET_SetHostName, address family will be AF_INET
+   implicitely
+*/
+
+GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname);
+GSocketError GAddress_INET_SetHostAddress(GAddress *address,
+                                          unsigned long hostaddr);
+GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port);
+GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port);
+
+GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname,
+                                       size_t sbuf);
+unsigned long GAddress_INET_GetHostAddress(GAddress *address);
+unsigned short GAddress_INET_GetPort(GAddress *address);
+
+/* TODO: Define specific parts (INET6, UNIX) */
+
+GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path);
+GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf);
+
+/*
+ * System specific functions
+ */
+
+/* On systems needing an event id */
+void GSocket_SetEventID(GSocket *socket, unsigned long evt_id);
+
+/* On systems which don't have background refresh */
+void GSocket_DoEvent(unsigned long evt_id);
+
+#ifdef __cplusplus
+};
+#endif
+
+#endif
+ /* __GSOCKET_H */
index 65e67aa24fbc4a758d471d865c6b7390732d1a68..c16cfea2ed3334736a93913d2c073f65570a860e 100644 (file)
@@ -45,6 +45,8 @@ class wxMemoryOutputStream:  public wxOutputStream {
 
   wxStreamBuffer *OutputStreamBuffer() const { return m_o_streambuf; }
 
 
   wxStreamBuffer *OutputStreamBuffer() const { return m_o_streambuf; }
 
+  size_t CopyTo(char *buffer, size_t len) const;
+
  protected:
   wxStreamBuffer *m_o_streambuf;
 
  protected:
   wxStreamBuffer *m_o_streambuf;
 
index b182548948986108844187eeea2fde85ab44e84e..1ea7a599dd91e3b2838718a475cd9302c5e7f521 100644 (file)
 
 #if wxUSE_SOCKETS
 
 
 #if wxUSE_SOCKETS
 
-#if defined(__WINDOWS__) && defined(WXSOCK_INTERNAL)
-#include <winsock.h>
-
-#elif defined(__UNIX__) && defined(WXSOCK_INTERNAL)
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#endif
-
 #include "wx/string.h"
 #include "wx/string.h"
+#include "gsocket.h"
+
 
 class WXDLLEXPORT wxSockAddress : public wxObject {
   DECLARE_ABSTRACT_CLASS(wxSockAddress)
 public:
   typedef enum { IPV4=1, IPV6=2, UNIX=3 } Addr;
 
 
 class WXDLLEXPORT wxSockAddress : public wxObject {
   DECLARE_ABSTRACT_CLASS(wxSockAddress)
 public:
   typedef enum { IPV4=1, IPV6=2, UNIX=3 } Addr;
 
-  wxSockAddress() {};
-  virtual ~wxSockAddress() {};
+  wxSockAddress();
+  virtual ~wxSockAddress();
+
+  virtual void Clear();
+  virtual int Type() = 0;
 
 
-  virtual void Clear() = 0;
+  GAddress *GetAddress() const { return m_address; }
+  void SetAddress(GAddress *address);
+  const wxSockAddress& operator =(const wxSockAddress& addr);
 
 
-  virtual void Build(struct sockaddr*& addr, size_t& len) = 0;
-  virtual void Disassemble(struct sockaddr *addr, size_t len) = 0;
-  virtual int SockAddrLen() = 0;
+  void CopyObject(wxObject& dest) const;
 
 
-  virtual int GetFamily() = 0;
-  virtual int Type() = 0;
+protected:
+  GAddress *m_address;
 };
 
 class WXDLLEXPORT wxIPV4address : public wxSockAddress {
   DECLARE_DYNAMIC_CLASS(wxIPV4address)
 };
 
 class WXDLLEXPORT wxIPV4address : public wxSockAddress {
   DECLARE_DYNAMIC_CLASS(wxIPV4address)
-private:
-  struct sockaddr_in *m_addr;
 public:
   wxIPV4address();
   virtual ~wxIPV4address();
 
 public:
   wxIPV4address();
   virtual ~wxIPV4address();
 
-  virtual void Clear();
-//  const wxSockAddress& operator =(const wxSockAddress& addr);
-
-  virtual bool Hostname(const wxString& name);
-  virtual bool Hostname(unsigned long addr);
-  virtual bool Service(const wxString& name);
-  virtual bool Service(unsigned short port);
-  virtual bool LocalHost();
+  bool Hostname(const wxString& name);
+  bool Hostname(unsigned long addr);
+  bool Service(const wxString& name);
+  bool Service(unsigned short port);
+  bool LocalHost();
 
   wxString Hostname();
   unsigned short Service();
 
   wxString Hostname();
   unsigned short Service();
@@ -73,8 +63,6 @@ public:
   void Build(struct sockaddr*& addr, size_t& len);
   void Disassemble(struct sockaddr *addr, size_t len);
 
   void Build(struct sockaddr*& addr, size_t& len);
   void Disassemble(struct sockaddr *addr, size_t len);
 
-  inline int SockAddrLen();
-  inline int GetFamily();
   inline int Type() { return wxSockAddress::IPV4; }
 };
 
   inline int Type() { return wxSockAddress::IPV4; }
 };
 
@@ -87,9 +75,6 @@ public:
   wxIPV6address();
   ~wxIPV6address();
 
   wxIPV6address();
   ~wxIPV6address();
 
-  void Clear();
-//  const wxSockAddress& operator =(const wxSockAddress& addr);
-
   bool Hostname(const wxString& name);
   bool Hostname(unsigned char addr[16]);
   bool Service(const wxString& name);
   bool Hostname(const wxString& name);
   bool Hostname(unsigned char addr[16]);
   bool Service(const wxString& name);
@@ -99,11 +84,6 @@ public:
   wxString Hostname() const;
   unsigned short Service() const;
 
   wxString Hostname() const;
   unsigned short Service() const;
 
-  void Build(struct sockaddr*& addr, size_t& len);
-  void Disassemble(struct sockaddr *addr, size_t len);
-
-  inline int SockAddrLen();
-  inline int GetFamily();
   inline int Type() { return wxSockAddress::IPV6; }
 };
 #endif
   inline int Type() { return wxSockAddress::IPV6; }
 };
 #endif
@@ -119,17 +99,9 @@ public:
   wxUNIXaddress();
   ~wxUNIXaddress();
 
   wxUNIXaddress();
   ~wxUNIXaddress();
 
-  void Clear();
-//  const wxSockAddress& operator =(const wxSockAddress& addr);
-
   void Filename(const wxString& name);
   wxString Filename();
 
   void Filename(const wxString& name);
   wxString Filename();
 
-  void Build(struct sockaddr*& addr, size_t& len);
-  void Disassemble(struct sockaddr *addr, size_t len);
-
-  inline int SockAddrLen();
-  inline int GetFamily();
   inline int Type() { return wxSockAddress::UNIX; }
 };
 #endif
   inline int Type() { return wxSockAddress::UNIX; }
 };
 #endif
diff --git a/include/wx/sckint.h b/include/wx/sckint.h
deleted file mode 100644 (file)
index 103595f..0000000
+++ /dev/null
@@ -1,158 +0,0 @@
-/////////////////////////////////////////////////////////////////////////////
-// Name:        sckint.h
-// Purpose:     Socket internal classes
-// Author:      Guilhem Lavaux
-// Modified by:
-// Created:     April 1999
-// RCS-ID:      $Id$
-// Copyright:   (c) Guilhem Lavaux
-// Licence:     wxWindows licence
-/////////////////////////////////////////////////////////////////////////////
-#ifndef _WX_NETWORK_SOCKET_INT_H
-#define _WX_NETWORK_SOCKET_INT_H
-
-#ifdef __GNUG__
-#pragma interface
-#endif
-
-#include "wx/defs.h"
-
-#if wxUSE_SOCKETS
-
-#include "wx/object.h"
-#include "wx/list.h"
-#include "wx/socket.h"
-#include "wx/thread.h"
-
-// Socket state
-class SocketState
-{
- public:
-  // TRUE if the background notifyier is on.
-  bool notify_state;
-  // Specifies which events we want to be notified.
-  wxSocketBase::wxRequestNotify evt_notify_state;
-  // Socket flags.
-  wxSocketBase::wxSockFlags socket_flags;
-  // Pointer to the C callback function. 
-  wxSocketBase::wxSockCbk c_callback;
-  char *c_callback_data;
-};
-
-// Socket request
-class SockRequest 
-{
- public:
-  // Buffer where to get/put data.
-  char *buffer;
-  // Size of the buffer.
-  size_t size;
-  // Number of bytes really read/written.
-  size_t io_nbytes;
-  // Error.
-  unsigned int error;
-  // Type of the request.
-  wxSocketBase::wxRequestNotify type;
-  // Timeout (in milliseconds).
-  unsigned int timeout;
-  // TRUE if the buffer has been processed.
-  bool done;
-  // TRUE if we must wait for the request completion, in the other case an
-  // event will be sent to the main thread when the request is finished.
-  bool wait;
-};
-
-class wxSocketInternal;
-
-#if wxUSE_THREADS
-class SocketWaiter: public wxThread {
- public:
-  SocketWaiter(wxSocketBase *socket, wxSocketInternal *internal);
-  ~SocketWaiter();
-
-  // Thread Entry point
-  // ---
-  virtual void *Entry();
-
- protected:
-  void ProcessReadEvent();
-  void ProcessWriteEvent();
-
- public:
-  wxSocketBase *m_socket;
-  wxSocketInternal *m_internal;
-  int m_fd;
-};
-#endif
-
-class SocketRequester
-#if wxUSE_THREADS
-  : public wxThread 
-#endif
-         {
- public:
-  SocketRequester(wxSocketBase *socket, wxSocketInternal *internal);
-  ~SocketRequester();
-
-  void ProcessWaitEvent(SockRequest *req);
-  void ProcessReadEvent(SockRequest *req);
-  void ProcessWriteEvent(SockRequest *req);
-
-  bool WaitFor(wxSocketBase::wxRequestNotify req, int millisec);
-
-#if wxUSE_THREADS
-  // Thread Entry point
-  // ---
-  virtual void *Entry();
-#endif
-
- public:
-  wxSocketBase *m_socket;
-  wxSocketInternal *m_internal;
-  int m_fd;
-};
-
-class wxSocketInternal {
- public:
-  wxSocketInternal(wxSocketBase *socket);
-  ~wxSocketInternal();
-
-  // wxSocket thread manager
-  // -----------------------
-  void AcquireData();
-  void ReleaseData();
-  void AcquireFD();
-  void ReleaseFD();
-
-  int GetFD() { return m_fd; }
-  void SetFD(int fd) { m_fd = fd; }
-  
-  void ResumeWaiter();
-  void StopWaiter();
-  void ResumeRequester();
-  void StopRequester();
-
-  void QueueRequest(SockRequest *request, bool async);
-  void WaitForEnd(SockRequest *request);
-
-  // Used by SocketRequester
-  SockRequest *WaitForReq();
-  void EndRequest(SockRequest *req);
- public:
-  wxSocketBase *m_socket;
-#if wxUSE_THREADS
-  wxMutex m_socket_locker, m_fd_locker, m_request_locker, m_end_requester;
-  wxCondition m_socket_cond;
-  SocketWaiter *m_thread_waiter;
-#endif
-  SocketRequester *m_thread_requester;
-  wxList m_requests;
-  int m_fd;
-  bool m_invalid_requester;
-};
-
-#endif
-  // wxUSE_SOCKETS
-
-#endif
-  // _WX_NETWORK_SOCKET_INT_H
index ef78d5f86646ee3b31aafddd94798e06e75f2525..18e1a1908fc92d626a8d0f2ed65e61e8a8a7edf5 100644 (file)
@@ -63,9 +63,9 @@ protected:
   friend class wxTCPServer;
   friend class wxTCPClient;
   friend void Client_OnRequest(wxSocketBase&,
   friend class wxTCPServer;
   friend class wxTCPClient;
   friend void Client_OnRequest(wxSocketBase&,
-                              wxSocketBase::wxRequestEvent, char *);
+                              GSocketEvent, char *);
   friend void Server_OnRequest(wxSocketServer&,
   friend void Server_OnRequest(wxSocketServer&,
-                              wxSocketBase::wxRequestEvent, char *);
+                              GSocketEvent, char *);
 public:
 
   wxTCPConnection(char *buffer, int size);
 public:
 
   wxTCPConnection(char *buffer, int size);
index e22c65baf42af7df838e4a4be8ded4b7ae81305f..a330bb173fc8069a0a14f7b00740bac547639aa9 100644 (file)
@@ -27,7 +27,6 @@ class WXDLLEXPORT wxSocketOutputStream : public wxOutputStream
   wxSocketOutputStream(wxSocketBase& s);
   ~wxSocketOutputStream();
 
   wxSocketOutputStream(wxSocketBase& s);
   ~wxSocketOutputStream();
 
-  wxOutputStream& Write(const void *buffer, size_t size);
   off_t SeekO( off_t WXUNUSED(pos), wxSeekMode WXUNUSED(mode) ) 
     { return -1; }
   off_t TellO() 
   off_t SeekO( off_t WXUNUSED(pos), wxSeekMode WXUNUSED(mode) ) 
     { return -1; }
   off_t TellO() 
@@ -45,7 +44,6 @@ class WXDLLEXPORT wxSocketInputStream : public wxInputStream
   wxSocketInputStream(wxSocketBase& s);
   ~wxSocketInputStream();
 
   wxSocketInputStream(wxSocketBase& s);
   ~wxSocketInputStream();
 
-  wxInputStream& Read(void *buffer, size_t size);
   off_t SeekI( off_t WXUNUSED(pos), wxSeekMode WXUNUSED(mode) ) 
     { return -1; }
   off_t TellI() 
   off_t SeekI( off_t WXUNUSED(pos), wxSeekMode WXUNUSED(mode) ) 
     { return -1; }
   off_t TellI() 
@@ -69,4 +67,4 @@ class WXDLLEXPORT wxSocketStream : public wxSocketInputStream,
   // wxUSE_SOCKETS && wxUSE_STREAMS
 
 #endif
   // wxUSE_SOCKETS && wxUSE_STREAMS
 
 #endif
-  // __SCK_STREAM_H__
\ No newline at end of file
+  // __SCK_STREAM_H__
index 36a0934e45e35bfbc7a1590b22d1826da64f6f8b..b2dcf6056a64022c2df2034255e18dd066d00b65 100644 (file)
 
 #if wxUSE_SOCKETS
 
 
 #if wxUSE_SOCKETS
 
-// ---------------------------------------------------------------------------
-// Windows(tm) specific
-// ---------------------------------------------------------------------------
-#if defined(__WINDOWS__) && defined(WXSOCK_INTERNAL)
-#include <winsock.h>
-#include <wx/msw/private.h>
-#endif // defined(__WINDOWS__) && defined(WXSOCK_INTERNAL)
-
-// ---------------------------------------------------------------------------
-// Unix specific
-// ---------------------------------------------------------------------------
-#if defined(__UNIX__) && defined(WXSOCK_INTERNAL)
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#endif // defined(__UNIX__) && defined(WXSOCK_INTERNAL)
-
 // ---------------------------------------------------------------------------
 // wxSocket headers (generic)
 // ---------------------------------------------------------------------------
 // ---------------------------------------------------------------------------
 // wxSocket headers (generic)
 // ---------------------------------------------------------------------------
 #endif
 
 #include "wx/sckaddr.h"
 #endif
 
 #include "wx/sckaddr.h"
+#include "gsocket.h"
 
 class WXDLLEXPORT wxSocketEvent;
 
 class WXDLLEXPORT wxSocketEvent;
-class WXDLLEXPORT wxSocketHandler;
-class wxSocketInternal;
 class WXDLLEXPORT wxSocketBase : public wxEvtHandler
 {
   DECLARE_CLASS(wxSocketBase)
 class WXDLLEXPORT wxSocketBase : public wxEvtHandler
 {
   DECLARE_CLASS(wxSocketBase)
-#ifdef __WXMAC__
-  friend void wxMacSocketOnRequestProc(void *refcon , short event) ;
-#endif
 public:
 
   enum wxSockFlags { NONE=0, NOWAIT=1, WAITALL=2, SPEED=4 };
   // Type of request
 public:
 
   enum wxSockFlags { NONE=0, NOWAIT=1, WAITALL=2, SPEED=4 };
   // Type of request
-  enum { REQ_READ=0x1, REQ_PEEK=0x2, REQ_WRITE=0x4, REQ_LOST=0x8,
-         REQ_ACCEPT=0x10, REQ_CONNECT=0x20, REQ_WAIT=0x40};
-  enum { EVT_READ=0, EVT_PEEK=1, EVT_WRITE=2, EVT_LOST=3, EVT_ACCEPT=4,
-         EVT_CONNECT=5 };
 
 
-  typedef int wxRequestNotify;
-  typedef int wxRequestEvent;
   enum wxSockType { SOCK_CLIENT, SOCK_SERVER, SOCK_INTERNAL, SOCK_UNINIT }; 
   enum wxSockType { SOCK_CLIENT, SOCK_SERVER, SOCK_INTERNAL, SOCK_UNINIT }; 
-  typedef void (*wxSockCbk)(wxSocketBase& sock,wxRequestEvent evt,char *cdata);
+  typedef void (*wxSockCbk)(wxSocketBase& sock,GSocketEvent evt,char *cdata);
 
 protected:
 
 protected:
-  wxSockFlags m_flags;
+  GSocket *m_socket;                   // wxSocket socket
+  wxSockFlags m_flags;                 // wxSocket flags
   wxSockType m_type;                   // wxSocket type
   wxSockType m_type;                   // wxSocket type
-  bool m_connected, m_connecting;      // State of the socket
-  int m_fd;                            // Socket file descriptors
-  wxList m_states;                     // States list
-  int m_id;                            // Socket id (for event handler)
-  wxSocketHandler *m_handler;          // the current socket handler
-  wxRequestNotify m_neededreq;         // Specify which requet signals we need
-  unsigned long m_timeout;
+  GSocketEventFlags m_neededreq;       // Specify which requet signals we need
   size_t m_lcount;                     // Last IO request size
   size_t m_lcount;                     // Last IO request size
-  int m_error;                         // Last IO error
-  wxSocketInternal *m_internal;
+  unsigned long m_timeout;             // IO timeout value
+
   char *m_unread;                      // Pushback buffer
   size_t m_unrd_size;                  // Pushback buffer size
   char *m_unread;                      // Pushback buffer
   size_t m_unrd_size;                  // Pushback buffer size
-  wxSockCbk m_cbk;
-  char *m_cdata;
-  bool m_notify_state;
+  size_t m_unrd_cur;                   // Pushback pointer
+
+  wxSockCbk m_cbk;                     // C callback
+  char *m_cdata;                       // C callback data
+
+  bool m_connected;                    // Connected ?
+  bool m_notify_state;                 // Notify state
+  int m_id;                            // Socket id (for event handler)
+
+  enum {
+    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
+
+  wxList m_states;                     // Stack of states
   
 public:
   wxSocketBase();
   
 public:
   wxSocketBase();
@@ -110,14 +91,15 @@ public:
   void CreatePushbackBefore(const char *buffer, size_t size);
 
   // Status
   void CreatePushbackBefore(const char *buffer, size_t size);
 
   // Status
-  inline bool Ok() const { return (m_fd < 0 ? 0 : 1); };
-  inline bool Error() const { return (m_error != 0); };
+  inline bool Ok() const { return (m_socket != NULL); };
+  inline bool Error() const
+           { return (GSocket_GetError(m_socket) != GSOCK_NOERROR); };
   inline bool IsConnected() const { return m_connected; };
   inline bool IsDisconnected() const { return !IsConnected(); };
   inline bool IsConnected() const { return m_connected; };
   inline bool IsDisconnected() const { return !IsConnected(); };
-  inline bool IsNoWait() const { return m_flags & NOWAIT; };
+  inline bool IsNoWait() const { return ((m_flags & NOWAIT) != 0); };
   bool IsData() const;
   inline size_t LastCount() const { return m_lcount; }
   bool IsData() const;
   inline size_t LastCount() const { return m_lcount; }
-  inline int LastError() const { return m_error; }
+  inline GSocketError LastError() const { return GSocket_GetError(m_socket); }
   inline wxSockType GetType() const { return m_type; }
   
   void SetFlags(wxSockFlags _flags);
   inline wxSockType GetType() const { return m_type; }
   
   void SetFlags(wxSockFlags _flags);
@@ -144,11 +126,11 @@ public:
   void SetEventHandler(wxEvtHandler& evt_hdlr, int id = -1);
   
   // Method called when it happens something on the socket
   void SetEventHandler(wxEvtHandler& evt_hdlr, int id = -1);
   
   // Method called when it happens something on the socket
-  void SetNotify(wxRequestNotify flags);
-  virtual void OnRequest(wxRequestEvent req_evt);
+  void SetNotify(GSocketEventFlags flags);
+  virtual void OnRequest(GSocketEvent req_evt);
 
   // Public internal callback
 
   // Public internal callback
-  virtual void OldOnNotify(wxRequestEvent WXUNUSED(evt));
+  virtual void OldOnNotify(GSocketEvent WXUNUSED(evt));
 
   // Some info on the socket...
   virtual bool GetPeer(wxSockAddress& addr_man) const;
 
   // Some info on the socket...
   virtual bool GetPeer(wxSockAddress& addr_man) const;
@@ -158,9 +140,9 @@ public:
   void Notify(bool notify);
 
   // So you can know what the socket driver is looking for ...
   void Notify(bool notify);
 
   // So you can know what the socket driver is looking for ...
-  inline wxRequestNotify NeededReq() const { return m_neededreq; }
+  inline GSocketEventFlags NeededReq() const { return m_neededreq; }
 
 
-  static wxRequestNotify EventToNotify(wxRequestEvent evt);
+  static GSocketEventFlags EventToNotify(GSocketEvent evt);
 
 protected:
   friend class wxSocketServer;
 
 protected:
   friend class wxSocketServer;
@@ -178,18 +160,13 @@ protected:
 #endif
   
   bool _Wait(long seconds, long microseconds, int type);
 #endif
   
   bool _Wait(long seconds, long microseconds, int type);
-  
-  // Set "my" handler
-  inline virtual void SetHandler(wxSocketHandler *handler)
-         { m_handler = handler; }
 
 
+  int DeferRead(char *buffer, size_t nbytes);
+  int DeferWrite(const char *buffer, size_t nbytes);
+  void DoDefer(GSocketEvent evt);
+  
   // Pushback library
   size_t GetPushback(char *buffer, size_t size, bool peek);
   // Pushback library
   size_t GetPushback(char *buffer, size_t size, bool peek);
-
-  // To prevent many read or write on the same socket at the same time
-  //   ==> cause strange things :-)
-  void WantSpeedBuffer(char *buffer, size_t size, wxRequestEvent req);
-  void WantBuffer(char *buffer, size_t size, wxRequestEvent req);
 };
 
 ////////////////////////////////////////////////////////////////////////
 };
 
 ////////////////////////////////////////////////////////////////////////
@@ -221,45 +198,7 @@ public:
 
   bool WaitOnConnect(long seconds = -1, long microseconds = 0);
 
 
   bool WaitOnConnect(long seconds = -1, long microseconds = 0);
 
-  virtual void OnRequest(wxRequestEvent flags);
-};
-
-////////////////////////////////////////////////////////////////////////
-
-class WXDLLEXPORT wxSocketHandler : public wxObject
-{
-  DECLARE_CLASS(wxSocketHandler)
-protected:
-  wxList *socks;
-
-public:
-  enum SockStatus { SOCK_NONE, SOCK_DATA, SOCK_CONNECT, SOCK_DISCONNECT,
-                   SOCK_ERROR };
-  static wxSocketHandler *master;
-
-  wxSocketHandler();
-  virtual ~wxSocketHandler();
-  
-  void Register(wxSocketBase* sock);
-  void UnRegister(wxSocketBase* sock);
-  
-  unsigned long Count() const;
-  
-  // seconds = -1 means indefinite wait
-  // seconds = 0 means no wait
-  // seconds > 0 means specified wait
-  
-  int Wait(long seconds = -1, long microseconds = 0);
-  void YieldSock();
-  
-  wxSocketServer *CreateServer
-                       (wxSockAddress& addr,
-                       wxSocketBase::wxSockFlags flags = wxSocketBase::NONE);
-  wxSocketClient *CreateClient
-                       (wxSocketBase::wxSockFlags flags = wxSocketBase::NONE);
-
-  // Create or reuse a socket handler
-  static wxSocketHandler& Master() { return *master; }
+  virtual void OnRequest(GSocketEvent flags);
 };
 
 class WXDLLEXPORT wxSocketEvent : public wxEvent {
 };
 
 class WXDLLEXPORT wxSocketEvent : public wxEvent {
@@ -267,13 +206,13 @@ class WXDLLEXPORT wxSocketEvent : public wxEvent {
 public:
   wxSocketEvent(int id = 0);
 
 public:
   wxSocketEvent(int id = 0);
 
-  wxSocketBase::wxRequestEvent SocketEvent() const { return m_skevt; }
+  GSocketEvent SocketEvent() const { return m_skevt; }
   wxSocketBase *Socket() const { return m_socket; }
 
   void CopyObject(wxObject& obj_d) const;
 
 public:
   wxSocketBase *Socket() const { return m_socket; }
 
   void CopyObject(wxObject& obj_d) const;
 
 public:
-  wxSocketBase::wxRequestEvent m_skevt;
+  GSocketEvent m_skevt;
   wxSocketBase *m_socket;
 };
 
   wxSocketBase *m_socket;
 };
 
index 1718f736641a6f265bb16a015eda03a625441191..0de57cdcf692831d393b6f6484327e1d4fdbf932 100644 (file)
@@ -145,7 +145,7 @@ public:
     wxTextCtrl& operator<<(long i);
     wxTextCtrl& operator<<(float f);
     wxTextCtrl& operator<<(double d);
     wxTextCtrl& operator<<(long i);
     wxTextCtrl& operator<<(float f);
     wxTextCtrl& operator<<(double d);
-    wxTextCtrl& operator<<(const char c);
+    wxTextCtrl& operator<<(const wxChar c);
 
     // obsolete functions
 #if WXWIN_COMPATIBILITY
 
     // obsolete functions
 #if WXWIN_COMPATIBILITY
index 646aabfe8ca3976e9e0054de585f54ffaa3e0382..feb050d03a863119d4ab3cc75897edb462ca02e7 100644 (file)
@@ -28,6 +28,7 @@
 #include "wx/url.h"
 #include "wx/protocol/http.h"
 #include "wx/thread.h"
 #include "wx/url.h"
 #include "wx/protocol/http.h"
 #include "wx/thread.h"
+#include "wx/progdlg.h"
 
 #if defined(__WXMOTIF__) || defined(__WXGTK__)
 #include "mondrian.xpm"
 
 #if defined(__WXMOTIF__) || defined(__WXGTK__)
 #include "mondrian.xpm"
@@ -58,6 +59,8 @@ public:
   void OnExecCloseConnection(wxCommandEvent& evt);
   void UpdateStatus();
 
   void OnExecCloseConnection(wxCommandEvent& evt);
   void UpdateStatus();
 
+  void Download(wxInputStream *input);
+
   DECLARE_EVENT_TABLE()
 };
 
   DECLARE_EVENT_TABLE()
 };
 
@@ -72,7 +75,7 @@ class MyClient: public wxSocketClient
 public:
   MyFrame *frame;
 
 public:
   MyFrame *frame;
 
-  void OnNotify(wxRequestNotify WXUNUSED(flags)) { frame->UpdateStatus(); }
+  void OnNotify(GSocketEventFlags WXUNUSED(flags)) { frame->UpdateStatus(); }
 };
 
 // ID for the menu quit command
 };
 
 // ID for the menu quit command
@@ -134,14 +137,10 @@ MyFrame::MyFrame():
   wxFrame(NULL, -1, "wxSocket client demo",
           wxDefaultPosition, wxSize(300, 200), wxDEFAULT_FRAME_STYLE)
 {
   wxFrame(NULL, -1, "wxSocket client demo",
           wxDefaultPosition, wxSize(300, 200), wxDEFAULT_FRAME_STYLE)
 {
-  // Init all
-  wxSocketHandler::Master();
-
   sock = new MyClient();
   sock->SetFlags((wxSocketBase::wxSockFlags) (wxSocketBase::WAITALL | wxSocketBase::SPEED));
   sock = new MyClient();
   sock->SetFlags((wxSocketBase::wxSockFlags) (wxSocketBase::WAITALL | wxSocketBase::SPEED));
-  wxSocketHandler::Master().Register(sock);
   sock->frame = this;
   sock->frame = this;
-  sock->SetNotify(wxSocketBase::REQ_LOST);
+  sock->SetNotify(GSOCK_LOST_FLAG);
   CreateStatusBar(2);
   UpdateStatus();
 }
   CreateStatusBar(2);
   UpdateStatus();
 }
@@ -169,6 +168,7 @@ void MyFrame::OnExecOpenConnection(wxCommandEvent& WXUNUSED(evt))
   addr.Service(3000);
   sock->SetNotify(0);
   sock->Connect(addr, TRUE);
   addr.Service(3000);
   sock->SetNotify(0);
   sock->Connect(addr, TRUE);
+  sock->SetFlags(wxSocketBase::NONE);
   if (!sock->IsConnected())
     wxMessageBox("Can't connect to the specified host", "Alert !");
 
   if (!sock->IsConnected())
     wxMessageBox("Can't connect to the specified host", "Alert !");
 
@@ -177,8 +177,7 @@ void MyFrame::OnExecOpenConnection(wxCommandEvent& WXUNUSED(evt))
 
 void MyFrame::OnExecCloseConnection(wxCommandEvent& WXUNUSED(evt))
 {
 
 void MyFrame::OnExecCloseConnection(wxCommandEvent& WXUNUSED(evt))
 {
-  if (sock)
-    sock->Close();
+  sock->Close();
   UpdateStatus();
 }
 
   UpdateStatus();
 }
 
@@ -271,6 +270,43 @@ void MyFrame::OnExecTest1(wxCommandEvent& WXUNUSED(evt))
   delete dlgbox;
 }
 
   delete dlgbox;
 }
 
+
+void MyFrame::Download(wxInputStream *input)
+{
+  wxProgressDialog progress("Downloading ...", "0% downloaded");
+  wxBufferedInputStream buf_in(*input);
+  wxFileOutputStream f_out("test.url");
+
+  size_t file_size = input->StreamSize();
+  size_t downloaded;
+  int BUFSIZE = (file_size > 100) ? (file_size / 100) : file_size;
+  int bytes_read = BUFSIZE;
+  wxString message;
+  int percents;
+
+  char *buf;
+
+// TODO: Support for streams which don't support StreamSize
+
+  buf = new char[BUFSIZE];
+
+  downloaded = 0;
+  bytes_read = BUFSIZE;
+  while (downloaded < file_size && bytes_read != 0) {
+    bytes_read = buf_in.Read(buf, BUFSIZE).LastRead();
+    f_out.Write(buf, bytes_read);
+    downloaded += bytes_read;
+
+    percents = downloaded * 100 / file_size;
+
+    message = _T("");
+    message << percents << _T("% downloaded");
+    progress.Update(percents, message);
+  }
+
+  delete[] buf;   
+}
+
 void MyFrame::OnExecUrlTest(wxCommandEvent& WXUNUSED(evt))
 {
   wxString urlname = wxGetTextFromUser("Enter an URL to get",
 void MyFrame::OnExecUrlTest(wxCommandEvent& WXUNUSED(evt))
 {
   wxString urlname = wxGetTextFromUser("Enter an URL to get",
@@ -284,11 +320,8 @@ void MyFrame::OnExecUrlTest(wxCommandEvent& WXUNUSED(evt))
     error.Printf(_T("Error in getting data from the URL. (error = %d)"), url.GetError());
     wxMessageBox(error, "Alert !");
   } else {
     error.Printf(_T("Error in getting data from the URL. (error = %d)"), url.GetError());
     wxMessageBox(error, "Alert !");
   } else {
-    wxFileOutputStream *str_out = new wxFileOutputStream("test.url");
-    str_out->Write(*datas);
+    Download(datas);
 
 
-    wxMessageBox(_T("Success !! Click on OK to see the text."), "OK");
     delete datas;
     delete datas;
-    delete str_out;
   }
 }
   }
 }
index 56f2dfc30317e7ccb04b8bbccfe346561a51dbec..c7bbd60c87308f35e54f5c223cf7ee1988d39da8 100644 (file)
@@ -111,7 +111,7 @@ void MyFrame::OnSockRequest(wxSocketEvent& evt)
   printf("OnSockRequest OK\n");
   printf("OnSockRequest (event = %d)\n",evt.SocketEvent());
   switch (evt.SocketEvent()) {
   printf("OnSockRequest OK\n");
   printf("OnSockRequest (event = %d)\n",evt.SocketEvent());
   switch (evt.SocketEvent()) {
-  case wxSocketBase::EVT_READ:
+  case GSOCK_INPUT:
     unsigned char c;
 
     sock->Read((char *)&c, 1);
     unsigned char c;
 
     sock->Read((char *)&c, 1);
@@ -119,7 +119,7 @@ void MyFrame::OnSockRequest(wxSocketEvent& evt)
       ExecTest1(sock);
 
     break;
       ExecTest1(sock);
 
     break;
-  case wxSocketBase::EVT_LOST:
+  case GSOCK_LOST:
     printf("Destroying socket\n");
     wxPendingDelete.Append(sock);
     UpdateStatus(-1);
     printf("Destroying socket\n");
     wxPendingDelete.Append(sock);
     UpdateStatus(-1);
@@ -127,7 +127,6 @@ void MyFrame::OnSockRequest(wxSocketEvent& evt)
     break;
   }
   printf("OnSockRequest Exiting\n");
     break;
   }
   printf("OnSockRequest Exiting\n");
-  sock->SetNotify(wxSocketBase::REQ_READ | wxSocketBase::REQ_LOST);
 }
 
 void MyFrame::OnSockRequestServer(wxSocketEvent& evt)
 }
 
 void MyFrame::OnSockRequestServer(wxSocketEvent& evt)
@@ -151,10 +150,10 @@ void MyFrame::OnSockRequestServer(wxSocketEvent& evt)
     return;
 
   UpdateStatus(1);
     return;
 
   UpdateStatus(1);
-  sock2->SetFlags(wxSocketBase::SPEED);
+  sock2->SetFlags(wxSocketBase::NONE);
   sock2->Notify(TRUE);
   sock2->SetEventHandler(*this, SKDEMO_SOCKET);
   sock2->Notify(TRUE);
   sock2->SetEventHandler(*this, SKDEMO_SOCKET);
-  server->SetNotify(wxSocketBase::REQ_ACCEPT);
+  sock2->SetNotify(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
 }
 
 // My frame Constructor
 }
 
 // My frame Constructor
@@ -166,11 +165,9 @@ MyFrame::MyFrame(wxFrame *frame):
   addr.Service(3000);
 
   // Init all
   addr.Service(3000);
 
   // Init all
-  wxSocketHandler::Master();
 
   sock = new wxSocketServer(addr);
 
   sock = new wxSocketServer(addr);
-  wxSocketHandler::Master().Register(sock);
-  sock->SetNotify(wxSocketBase::REQ_ACCEPT);
+  sock->SetNotify(GSOCK_CONNECTION_FLAG);
   sock->SetEventHandler(*this, SKDEMO_SOCKET_SERV);
   sock->SetFlags(wxSocketBase::SPEED);
   sock->Notify(TRUE);
   sock->SetEventHandler(*this, SKDEMO_SOCKET_SERV);
   sock->SetFlags(wxSocketBase::SPEED);
   sock->Notify(TRUE);
index f880a43134e3b1ec8f0c3f31ff0aa3c18f0f8679..4449ec42a2c6c0a1a18ab0ba56862b311c3a7e83 100644 (file)
@@ -56,7 +56,21 @@ bool wxFFile::Open(const wxChar *filename, const char *mode)
 {
     wxASSERT_MSG( !m_fp, _T("should close or detach the old file first") );
 
 {
     wxASSERT_MSG( !m_fp, _T("should close or detach the old file first") );
 
+#if wxUSE_UNICODE
+    char *tmp_fname;
+    size_t fname_len;
+
+    fname_len = wxStrlen(filename)+1;
+    tmp_fname = new char[fname_len];
+    wxWX2MB(tmp_fname, filename, fname_len);
+
+    m_fp = fopen(tmp_fname, mode);
+
+    delete tmp_fname;
+#else
     m_fp = fopen(filename, mode);
     m_fp = fopen(filename, mode);
+#endif
+
 
     if ( !m_fp )
     {
 
     if ( !m_fp )
     {
index b513f7e404c5673d2f45eb49f16808db620777f0..c9e56751ee3af5eab5abd6300ac49e6232382424 100644 (file)
@@ -69,6 +69,7 @@ wxFTP::wxFTP()
   m_passwd += wxGetHostName();
 
   SetNotify(0);
   m_passwd += wxGetHostName();
 
   SetNotify(0);
+  SetFlags(NONE);
 }
 
 wxFTP::~wxFTP()
 }
 
 wxFTP::~wxFTP()
@@ -81,11 +82,6 @@ wxFTP::~wxFTP()
 ////////////////////////////////////////////////////////////////
 bool wxFTP::Connect(wxSockAddress& addr, bool WXUNUSED(wait))
 {
 ////////////////////////////////////////////////////////////////
 bool wxFTP::Connect(wxSockAddress& addr, bool WXUNUSED(wait))
 {
-  if (!m_handler) {
-    m_lastError = wxPROTO_NOHNDLR;
-    return FALSE;
-  }
-
   if (!wxProtocol::Connect(addr)) {
     m_lastError = wxPROTO_NETERR;
     return FALSE;
   if (!wxProtocol::Connect(addr)) {
     m_lastError = wxPROTO_NETERR;
     return FALSE;
@@ -256,7 +252,7 @@ public:
   size_t StreamSize() const { return m_ftpsize; }
   virtual ~wxInputFTPStream(void)
   { 
   size_t StreamSize() const { return m_ftpsize; }
   virtual ~wxInputFTPStream(void)
   { 
-     if (LastError() != wxStream_NOERROR)
+     if (LastError() == wxStream_NOERROR)
        m_ftp->GetResult('2');
      else
        m_ftp->Abort();
        m_ftp->GetResult('2');
      else
        m_ftp->Abort();
@@ -284,15 +280,15 @@ wxSocketClient *wxFTP::GetPort()
 {
   wxIPV4address addr;
   wxSocketClient *client;
 {
   wxIPV4address addr;
   wxSocketClient *client;
-  struct sockaddr sin;
   int a[6];
   wxString straddr;
   int addr_pos;
   int a[6];
   wxString straddr;
   int addr_pos;
+  wxUint16 port;
+  wxUint32 hostaddr;
 
   if (!SendCommand(_T("PASV"), '2'))
     return NULL;
 
 
   if (!SendCommand(_T("PASV"), '2'))
     return NULL;
 
-  sin.sa_family = AF_INET;
   addr_pos = m_lastResult.Find(_T('('));
   if (addr_pos == -1) {
     m_lastError = wxPROTO_PROTERR;
   addr_pos = m_lastResult.Find(_T('('));
   if (addr_pos == -1) {
     m_lastError = wxPROTO_PROTERR;
@@ -300,16 +296,15 @@ wxSocketClient *wxFTP::GetPort()
   }
   straddr = m_lastResult(addr_pos+1, m_lastResult.Length());
   wxSscanf((const wxChar *)straddr,_T("%d,%d,%d,%d,%d,%d"),&a[2],&a[3],&a[4],&a[5],&a[0],&a[1]);
   }
   straddr = m_lastResult(addr_pos+1, m_lastResult.Length());
   wxSscanf((const wxChar *)straddr,_T("%d,%d,%d,%d,%d,%d"),&a[2],&a[3],&a[4],&a[5],&a[0],&a[1]);
-  sin.sa_data[2] = (char)a[2];
-  sin.sa_data[3] = (char)a[3];
-  sin.sa_data[4] = (char)a[4];
-  sin.sa_data[5] = (char)a[5];
-  sin.sa_data[0] = (char)a[0];
-  sin.sa_data[1] = (char)a[1];
 
 
-  addr.Disassemble(&sin, sizeof(sin));
+  hostaddr = (wxUint16)a[5] << 24 | (wxUint16)a[4] << 16 |
+             (wxUint16)a[3] << 8 | a[2]; 
+  addr.Hostname(hostaddr);
+
+  port = (wxUint16)a[0] << 8 | a[1];
+  addr.Service(port);
 
 
-  client = m_handler->CreateClient();
+  client = new wxSocketClient();
   if (!client->Connect(addr)) {
     delete client;
     return NULL;
   if (!client->Connect(addr)) {
     delete client;
     return NULL;
index 06cfbd02e8e5785647f434dd9be724713cb0b932..cb194e82d39564ebadb794ab80a7281a6d7802e6 100644 (file)
@@ -46,7 +46,7 @@ wxHTTP::wxHTTP()
   m_addr = NULL;
   m_read = FALSE;
 
   m_addr = NULL;
   m_read = FALSE;
 
-  SetNotify(REQ_LOST);
+  SetNotify(GSOCK_LOST_FLAG);
 }
 
 wxHTTP::~wxHTTP()
 }
 
 wxHTTP::~wxHTTP()
@@ -120,8 +120,8 @@ bool wxHTTP::ParseHeaders()
   m_read = TRUE;
 
   while (1) {
   m_read = TRUE;
 
   while (1) {
-    m_error = GetLine(this, line);
-    if (m_error != wxPROTO_NOERR)
+    m_perr = GetLine(this, line);
+    if (m_perr != wxPROTO_NOERR)
       return FALSE;
 
     if (line.Length() == 0)
       return FALSE;
 
     if (line.Length() == 0)
@@ -154,7 +154,7 @@ bool wxHTTP::Connect(const wxString& host)
   if (!addr->Hostname(host)) {
     delete m_addr;
     m_addr = NULL;
   if (!addr->Hostname(host)) {
     delete m_addr;
     m_addr = NULL;
-    m_error = wxPROTO_NETERR;
+    m_perr = wxPROTO_NETERR;
     return FALSE;
   }
 
     return FALSE;
   }
 
@@ -166,22 +166,25 @@ bool wxHTTP::Connect(const wxString& host)
 
 bool wxHTTP::Connect(wxSockAddress& addr, bool WXUNUSED(wait))
 {
 
 bool wxHTTP::Connect(wxSockAddress& addr, bool WXUNUSED(wait))
 {
-  struct sockaddr *raw_addr;
-  size_t len;
-
-  m_addr = (wxSockAddress *)(addr.GetClassInfo()->CreateObject());
-
-  addr.Build(raw_addr, len);
-  m_addr->Disassemble(raw_addr, len);
+  if (m_addr) {
+    delete m_addr;
+    m_addr = NULL;
+    Close();
+  }
 
 
+  m_addr = (wxSockAddress *) addr.Clone();
   return TRUE;
 }
 
 bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req)
 {
   wxChar *tmp_buf;
   return TRUE;
 }
 
 bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req)
 {
   wxChar *tmp_buf;
-  wxChar buf[200];
-  wxWX2MBbuf pathbuf(200);
+  wxChar buf[200]; // 200 is arbitrary.
+#if wxUNICODE
+  wxWX2MBbuf pathbuf((size_t)200);
+#else
+  const wxWX2MBbuf pathbuf;
+#endif
   wxString tmp_str;
 
   switch (req) {
   wxString tmp_str;
 
   switch (req) {
@@ -197,14 +200,14 @@ bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req)
   Notify(FALSE);
 
   tmp_str = wxURL::ConvertToValidURI(path);
   Notify(FALSE);
 
   tmp_str = wxURL::ConvertToValidURI(path);
-  wxSprintf(buf, _T("%s %s\n\r"), tmp_buf, tmp_str.GetData());
+  wxSprintf(buf, _T("%s %s HTTP/1.0\n\r"), tmp_buf, tmp_str.GetData());
   pathbuf = wxConvLibc.cWX2MB(buf);
   pathbuf = wxConvLibc.cWX2MB(buf);
-  Write(pathbuf, strlen(pathbuf));
+  Write(pathbuf, strlen(MBSTRINGCAST pathbuf));
   SendHeaders();
   Write("\n\r", 2);
 
   SendHeaders();
   Write("\n\r", 2);
 
-  m_error = GetLine(this, tmp_str);
-  if (m_error != wxPROTO_NOERR) {
+  m_perr = GetLine(this, tmp_str);
+  if (m_perr != wxPROTO_NOERR) {
     RestoreState();
     return FALSE;
   }
     RestoreState();
     return FALSE;
   }
@@ -228,7 +231,7 @@ bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req)
   case 200:
     break;
   default:
   case 200:
     break;
   default:
-    m_error = wxPROTO_NOFILE;
+    m_perr = wxPROTO_NOFILE;
     RestoreState();
     return FALSE;
   }
     RestoreState();
     return FALSE;
   }
@@ -242,12 +245,29 @@ class wxHTTPStream : public wxSocketInputStream {
 public:
   wxHTTP *m_http;
   size_t m_httpsize;
 public:
   wxHTTP *m_http;
   size_t m_httpsize;
+  unsigned long m_read_bytes;
 
   wxHTTPStream(wxHTTP *http) : wxSocketInputStream(*http), m_http(http) {}
   size_t StreamSize() const { return m_httpsize; }
   virtual ~wxHTTPStream(void) { m_http->Abort(); }
 
   wxHTTPStream(wxHTTP *http) : wxSocketInputStream(*http), m_http(http) {}
   size_t StreamSize() const { return m_httpsize; }
   virtual ~wxHTTPStream(void) { m_http->Abort(); }
+
+protected:
+  size_t OnSysRead(void *buffer, size_t bufsize);
 };
 
 };
 
+size_t wxHTTPStream::OnSysRead(void *buffer, size_t bufsize)
+{
+  size_t ret;
+
+  if (m_httpsize > 0 && m_read_bytes >= m_httpsize)
+    return 0;
+
+  ret = wxSocketInputStream::OnSysRead(buffer, bufsize);
+  m_read_bytes += ret;
+
+  return ret;
+}
+
 bool wxHTTP::Abort(void)
 {
   return wxSocketClient::Close();
 bool wxHTTP::Abort(void)
 {
   return wxSocketClient::Close();
@@ -258,7 +278,7 @@ wxInputStream *wxHTTP::GetInputStream(const wxString& path)
   wxHTTPStream *inp_stream = new wxHTTPStream(this);
 
   if (!m_addr || m_connected) {
   wxHTTPStream *inp_stream = new wxHTTPStream(this);
 
   if (!m_addr || m_connected) {
-    m_error = wxPROTO_CONNERR;
+    m_perr = wxPROTO_CONNERR;
     return NULL;
   }
 
     return NULL;
   }
 
@@ -268,11 +288,15 @@ wxInputStream *wxHTTP::GetInputStream(const wxString& path)
   if (!BuildRequest(path, wxHTTP_GET))
     return NULL;
 
   if (!BuildRequest(path, wxHTTP_GET))
     return NULL;
 
-  wxPrintf(_T("Len = %s\n"), WXSTRINGCAST GetHeader(_T("Content-Length")));
   if (!GetHeader(_T("Content-Length")).IsEmpty())
     inp_stream->m_httpsize = wxAtoi(WXSTRINGCAST GetHeader(_T("Content-Length")));
   if (!GetHeader(_T("Content-Length")).IsEmpty())
     inp_stream->m_httpsize = wxAtoi(WXSTRINGCAST GetHeader(_T("Content-Length")));
+  else
+    inp_stream->m_httpsize = (size_t)-1;
+
+  inp_stream->m_read_bytes = 0;
+
+  Notify(FALSE);
 
 
-  SetFlags(WAITALL);
   return inp_stream;
 }
 
   return inp_stream;
 }
 
index b71af7bd547d4ff0e481dca0f7ae94ae04158515..318f0706b30911bc5854c11f2b39781bc836968a 100644 (file)
@@ -47,6 +47,7 @@
 #include  "wx/file.h"
 #include  "wx/textfile.h"
 #include  "wx/utils.h"
 #include  "wx/file.h"
 #include  "wx/textfile.h"
 #include  "wx/utils.h"
+#include  "wx/wxchar.h"
 #include  "wx/log.h"
 
 // other standard headers
 #include  "wx/log.h"
 
 // other standard headers
@@ -322,7 +323,7 @@ void wxLog::TimeStamp(wxString *str)
         wxChar buf[256];
         time_t timeNow;
         (void)time(&timeNow);
         wxChar buf[256];
         time_t timeNow;
         (void)time(&timeNow);
-        wxStrftime(buf, WXSIZEOF(buf), ms_timestamp, localtime(&timeNow));
+//        wxStrftime(buf, WXSIZEOF(buf), ms_timestamp, localtime(&timeNow));
 
         str->Empty();
         *str << buf << _T(": ");
 
         str->Empty();
         *str << buf << _T(": ");
@@ -896,7 +897,7 @@ wxLog          *wxLog::ms_pLogger      = (wxLog *)NULL;
 bool            wxLog::ms_doLog        = TRUE;
 bool            wxLog::ms_bAutoCreate  = TRUE;
 
 bool            wxLog::ms_doLog        = TRUE;
 bool            wxLog::ms_bAutoCreate  = TRUE;
 
-const wxChar   *wxLog::ms_timestamp    = "%X";  // time only, no date
+const wxChar   *wxLog::ms_timestamp    = _T("%X");  // time only, no date
 
 wxTraceMask     wxLog::ms_ulTraceMask  = (wxTraceMask)0;
 wxArrayString   wxLog::ms_aTraceMasks;
 
 wxTraceMask     wxLog::ms_ulTraceMask  = (wxTraceMask)0;
 wxArrayString   wxLog::ms_aTraceMasks;
index 4555d350620e77356e03dc02ec3edb51ecf61465..04501d5e5d3f1417fae91fba6a9524561c2dfef8 100644 (file)
@@ -99,5 +99,16 @@ off_t wxMemoryOutputStream::OnSysTell() const
   return m_o_streambuf->Tell();
 }
 
   return m_o_streambuf->Tell();
 }
 
+size_t wxMemoryOutputStream::CopyTo(char *buffer, size_t len) const
+{
+  if (!buffer)
+    return 0;
+
+  if (len > StreamSize())
+    len = StreamSize();
+
+  memcpy(buffer, m_o_streambuf->GetBufferStart(), len);
+  return len;
+}
 
 #endif
 
 #endif
index ab9a1f78c68cef6e8035b2b2bd16ef499ef10305..e6f63b2ca39d6af83c38a96f952612f3c9664d6c 100644 (file)
@@ -22,9 +22,6 @@
 
 #if wxUSE_SOCKETS
 
 
 #if wxUSE_SOCKETS
 
-#ifndef WX_PRECOMP
-#endif
-
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <ctype.h>
 #include <memory.h>
 #endif
 
 #include <memory.h>
 #endif
 
-#include "wx/defs.h"
-#include "wx/object.h"
-
-#if defined(__WXMAC__)
-#include "/wx/mac/macsock.h"
-#endif
-
-#if defined(__WINDOWS__)
-#include <winsock.h>
-#endif // __WINDOWS__
-
-#if defined(__UNIX__)
-#ifdef VMS
-#include <socket.h>
-#include <in.h>
-#else
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#endif
-#include <unistd.h>
-#include <netdb.h>
-
-#ifdef __SUN__
-extern "C"
-{
-   struct hostent *gethostbyname(const char *name); 
-   int gethostname(char *name, int namelen); 
-};
-#endif
-
-#endif // __UNIX__
-
-#include "wx/sckaddr.h"
-
-#define CHECK_ADDRTYPE(var, type)
+#include <wx/defs.h>
+#include <wx/object.h>
+#include <wx/gsocket.h>
+#include <wx/sckaddr.h>
 
 #if !USE_SHARED_LIBRARY
 IMPLEMENT_ABSTRACT_CLASS(wxSockAddress, wxObject)
 
 #if !USE_SHARED_LIBRARY
 IMPLEMENT_ABSTRACT_CLASS(wxSockAddress, wxObject)
@@ -82,343 +46,178 @@ IMPLEMENT_DYNAMIC_CLASS(wxUNIXaddress, wxSockAddress)
 #endif
 #endif
 
 #endif
 #endif
 
-wxIPV4address::wxIPV4address()
+// ---------------------------------------------------------------------------
+// wxIPV4address
+// ---------------------------------------------------------------------------
+
+wxSockAddress::wxSockAddress()
 {
 {
-  m_addr = new sockaddr_in;
-  Clear();
+  m_address = GAddress_new();
 }
 
 }
 
-wxIPV4address::~wxIPV4address()
+wxSockAddress::~wxSockAddress()
 {
 {
+  GAddress_destroy(m_address);
 }
 
 }
 
-int wxIPV4address::SockAddrLen()
+void wxSockAddress::SetAddress(GAddress *address)
 {
 {
-  return sizeof(*m_addr);
+  GAddress_destroy(m_address);
+  m_address = GAddress_copy(address);
 }
 
 }
 
-int wxIPV4address::GetFamily()
+const wxSockAddress& wxSockAddress::operator=(const wxSockAddress& addr)
 {
 {
-  return AF_INET;
+  SetAddress(addr.GetAddress());
+  return *this;
 }
 
 }
 
-void wxIPV4address::Clear()
+void wxSockAddress::CopyObject(wxObject& dest) const
 {
 {
-  memset(m_addr, 0, sizeof(*m_addr));
-  m_addr->sin_family = AF_INET;
-  m_addr->sin_addr.s_addr = INADDR_ANY;
+  wxSockAddress *addr = (wxSockAddress *)&dest;
+
+  wxObject::CopyObject(dest);
+  addr->SetAddress(GetAddress());
 }
 
 }
 
-/*
-const wxSockAddress& wxIPV4address::operator =(const wxSockAddress& addr)
-{
-  wxIPV4address *ip_addr = (wxIPV4address *)&addr;
-  CHECK_ADDRTYPE(addr, wxIPV4address);
-  m_addr = ip_addr->m_addr;
-  return *this;
+void wxSockAddress::Clear()
+{ 
+  GAddress_destroy(m_address);
+  m_address = GAddress_new();
 }
 }
-*/
 
 
-bool wxIPV4address::Hostname(const wxString& name)
+// ---------------------------------------------------------------------------
+// wxIPV4address
+// ---------------------------------------------------------------------------
+
+wxIPV4address::wxIPV4address()
+  : wxSockAddress()
 {
 {
-  struct hostent *theHostent;
-  struct in_addr *addr;
-  
-  if (name.IsNull())
-    return FALSE;
-  
-  if (!name.IsNumber()) {
-    if ((theHostent = gethostbyname(name.fn_str())) == 0) {
-      return FALSE;
-    }
-  } else {
-#ifdef __WXMAC__
-    long len_addr = inet_addr(name.fn_str()).s_addr ;
-#else
-    long len_addr = inet_addr(name.fn_str());
-#endif
-    if (len_addr == -1)
-      return FALSE;
-    m_addr->sin_addr.s_addr = len_addr;
-    return TRUE;
-  }
+}
 
 
-  addr = (struct in_addr *) *(theHostent->h_addr_list);
+wxIPV4address::~wxIPV4address()
+{
+}
 
 
-  m_addr->sin_addr.s_addr = addr[0].s_addr;
-  return TRUE;
+bool wxIPV4address::Hostname(const wxString& name)
+{
+  return (GAddress_INET_SetHostName(m_address, name.fn_str()) == GSOCK_NOERROR);
 }
 
 bool wxIPV4address::Hostname(unsigned long addr)
 {
 }
 
 bool wxIPV4address::Hostname(unsigned long addr)
 {
-  m_addr->sin_addr.s_addr = htonl(addr);
-  return TRUE; 
+  /* Need API */
+  return TRUE;
 }
 
 bool wxIPV4address::Service(const wxString& name)
 {
 }
 
 bool wxIPV4address::Service(const wxString& name)
 {
-  struct servent *theServent;
-  
-  if (name.IsNull())
-    return FALSE;
-  
-  if (!name.IsNumber()) {
-    if ((theServent = getservbyname(name.fn_str(), "tcp")) == 0)
-      return FALSE;
-  } else {
-    if ((theServent = getservbyport(wxAtoi(name), "tcp")) == 0) {
-      m_addr->sin_port = htons(wxAtoi(name));
-      return TRUE;
-    }
-  }
-  
-  m_addr->sin_port = theServent->s_port;
-  return TRUE;
+  return (GAddress_INET_SetPortName(m_address, name.fn_str()) == GSOCK_NOERROR);
 }
 
 bool wxIPV4address::Service(unsigned short port)
 {
 }
 
 bool wxIPV4address::Service(unsigned short port)
 {
-  m_addr->sin_port = htons(port);
-  return TRUE;
+  return (GAddress_INET_SetPort(m_address, port) == GSOCK_NOERROR);
 }
 
 bool wxIPV4address::LocalHost()
 {
 }
 
 bool wxIPV4address::LocalHost()
 {
-  static char buf[256];
-  
-  if (gethostname(buf, sizeof(buf)) < 0)
-    return Hostname("localhost");
-  else
-    return Hostname(buf);
+  return (GAddress_INET_SetHostName(m_address, "localhost") == GSOCK_NOERROR);
 }
 
 wxString wxIPV4address::Hostname()
 {
 }
 
 wxString wxIPV4address::Hostname()
 {
-  struct hostent *h_ent;
-
-  h_ent = gethostbyaddr((char *)&(m_addr->sin_addr), sizeof(m_addr->sin_addr),
-                       GetFamily());
-                       
-  if (!h_ent)
-     return wxString("");
-  else
-     return wxString(h_ent->h_name);
-}
-
-unsigned short wxIPV4address::Service()
-{
-  return ntohs(m_addr->sin_port); 
-}
+   char hostname[1024];
 
 
-void wxIPV4address::Build(struct sockaddr *&addr, size_t& len)
-{
-  addr = (struct sockaddr *)m_addr;
-  len = sizeof(*m_addr);
+   hostname[0] = 0;
+   GAddress_INET_GetHostName(m_address, hostname, 1024);
+   return wxString(hostname);
 }
 
 }
 
-void wxIPV4address::Disassemble(struct sockaddr *addr, size_t len)
+unsigned short wxIPV4address::Service()
 {
 {
-  if (len != sizeof(*m_addr))
-    return;
-  *m_addr = *(struct sockaddr_in *)addr;
+  return GAddress_INET_GetPort(m_address); 
 }
 
 #ifdef IPV6_ENABLE
 }
 
 #ifdef IPV6_ENABLE
+// ---------------------------------------------------------------------------
+// wxIPV6address
+// ---------------------------------------------------------------------------
 
 wxIPV6address::wxIPV6address()
 
 wxIPV6address::wxIPV6address()
+  : wxSockAddress()
 {
 {
-  m_addr = new sockaddr_in6;
-  Clear();
 }
 
 wxIPV6address::~wxIPV6address()
 {
 }
 
 }
 
 wxIPV6address::~wxIPV6address()
 {
 }
 
-int wxIPV6address::SockAddrLen()
-{
-  return sizeof(*m_addr);
-}
-
-int wxIPV6address::GetFamily()
-{
-  return AF_INET6;
-}
-
-void wxIPV6address::Clear()
-{ 
-  memset(m_addr, 0, sizeof(*m_addr));
-  m_addr->sin6_family = AF_INET6;
-  m_addr->sin6_addr.s_addr = INADDR_ANY;
-}
-
-/*
-const wxSockAddress& wxIPV6address::operator =(const wxSockAddress& addr)
-{
-  wxIPV6address *ip_addr = (wxIPV6address *)&addr;
-
-  CHECK_ADDRTYPE(addr, wxIPV6address);
-  m_addr = ip_addr->m_addr;
-  return *this;
-}
-*/
-
 bool wxIPV6address::Hostname(const wxString& name)
 {
 bool wxIPV6address::Hostname(const wxString& name)
 {
-  struct hostent *theHostent;
-  struct in_addr *addr;
-  
-  if (name.IsNull())
-    return FALSE;
-  
-  if (!name.IsNumber()) {
-    hostent = gethostbyname2((char*) name, AF_INET6);
-    if (!theHostent)
-      return FALSE;
-  } else {
-    // Don't how to do
-    return FALSE;
-  }
-
-  addr = (struct in6_addr *) *(theHostent->h_addr_list);
-
-  m_addr->sin6_addr.s6_addr = addr[0].s6_addr;
-  return TRUE;
+  return (GAddress_INET_SetHostName(m_address, name.fn_str()) == GSOCK_NOERROR);
 }
 
 bool wxIPV6address::Hostname(unsigned char addr[16])
 {
 }
 
 bool wxIPV6address::Hostname(unsigned char addr[16])
 {
-  m_addr->sin6_addr.s6_addr = addr;
   return TRUE;
 }
 
 bool wxIPV6address::Service(const char *name)
 {
   return TRUE;
 }
 
 bool wxIPV6address::Service(const char *name)
 {
-  struct servent *theServent;
-  
-  if (!name || !strlen(name))
-    return FALSE;
-  
-  if (!isdigit(*name)) {
-    if ((theServent = getservbyname((char*) name, "tcp")) == 0)
-      return FALSE;
-  } else {
-    if ((theServent = getservbyport(atoi(name), "tcp")) == 0) {
-      m_addr->sin_port = htons(atoi(name));
-      return TRUE;
-    }
-  }
-  
-  m_addr->sin_port = theServent->s_port;
-  return TRUE;
+  return (GAddress_INET_SetPortName(m_address, name.fn_str()) == GSOCK_NOERROR);
 }
 
 bool wxIPV6address::Service(unsigned short port)
 {
 }
 
 bool wxIPV6address::Service(unsigned short port)
 {
-  m_addr->sin_port = htons(port);
-  return TRUE;
+  return (GAddress_INET_SetPort(m_address, port) == GSOCK_NOERROR);
 }
 
 bool wxIPV6address::LocalHost()
 {
 }
 
 bool wxIPV6address::LocalHost()
 {
-  static char buf[256];
-  
-  if (gethostname(buf, sizeof(buf)) < 0)
-    return Hostname("localhost");
-  else
-    return Hostname(buf);
+  return (GAddress_INET_SetHostName(m_address, "localhost") == GSOCK_NOERROR);
 }
 
 const wxString& wxIPV6address::Hostname()
 {
 }
 
 const wxString& wxIPV6address::Hostname()
 {
-  struct hostent *h_ent;
-
-  h_ent = gethostbyaddr((char *)&(m_addr->sin_addr), sizeof(m_addr->sin_addr),
-                       GetFamily());
-  return wxString(h_ent->h_name);
+  return wxString(GAddress_INET_GetHostName(m_address));
 }
 
 unsigned short wxIPV6address::Service()
 {
 }
 
 unsigned short wxIPV6address::Service()
 {
-  return ntohs(m_addr->sin_port); 
-}
-
-void wxIPV6address::Build(struct sockaddr& *addr, size_t& len)
-{
-  len = sizeof(*m_addr);
-  addr = m_addr;
-}
-
-void wxIPV6address::Disassemble(struct sockaddr& *addr, size_t len)
-{
-  if (len != sizeof(*m_addr))
-    return;
-  *m_addr = *(struct sockaddr_in6 *)addr;
+  return GAddress_INET_GetPort(m_address); 
 }
 
 #endif
 
 #ifdef __UNIX__
 }
 
 #endif
 
 #ifdef __UNIX__
-#include <sys/un.h>
+// ---------------------------------------------------------------------------
+// wxUNIXaddress
+// ---------------------------------------------------------------------------
 
 wxUNIXaddress::wxUNIXaddress()
 
 wxUNIXaddress::wxUNIXaddress()
+  : wxSockAddress()
 {
 {
-  m_addr = new sockaddr_un;
-  Clear();
 }
 
 wxUNIXaddress::~wxUNIXaddress()
 {
 }
 
 }
 
 wxUNIXaddress::~wxUNIXaddress()
 {
 }
 
-int wxUNIXaddress::SockAddrLen()
-{
-  return sizeof(*m_addr);
-}
-
-int wxUNIXaddress::GetFamily()
-{
-  return AF_UNIX;
-}
-
-void wxUNIXaddress::Clear()
-{
-  memset(m_addr, 0, sizeof(m_addr));
-  m_addr->sun_family = AF_UNIX;
-}
-
-/*
-const wxSockAddress& wxUNIXaddress::operator =(const wxSockAddress& addr)
-{
-  wxUNIXaddress *unx_addr = (wxUNIXaddress *)&addr;
-  CHECK_ADDRTYPE(addr, wxUNIXaddress);
-  m_addr = unx_addr->m_addr;
-  return *this;
-}
-*/
-
 void wxUNIXaddress::Filename(const wxString& fname)
 {
 void wxUNIXaddress::Filename(const wxString& fname)
 {
-  sprintf(m_addr->sun_path, "%s", MBSTRINGCAST fname.mb_str());
+  GAddress_UNIX_SetPath(m_address, fname.fn_str());
 }
 
 wxString wxUNIXaddress::Filename()
 {
 }
 
 wxString wxUNIXaddress::Filename()
 {
-  return wxString(m_addr->sun_path);
-}
+  char path[1024];
 
 
-void wxUNIXaddress::Build(struct sockaddr*& addr, size_t& len)
-{
-  addr = (struct sockaddr *)m_addr;
-  len = sizeof(*m_addr);
+  path[0] = 0;
+  GAddress_UNIX_GetPath(m_address, path, 1024);
+  return wxString(path);
 }
 
 }
 
-void wxUNIXaddress::Disassemble(struct sockaddr *addr, size_t len)
-{
-  if (len != sizeof(*m_addr))
-    return;
-  *m_addr = *(struct sockaddr_un *)addr;
-}
 #endif
 
 #endif 
 #endif
 
 #endif 
diff --git a/src/common/sckint.cpp b/src/common/sckint.cpp
deleted file mode 100644 (file)
index f2d5616..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
-///////////////////////////////////////////////////////////////////////////////
-// Name:       sckint.cpp
-// Purpose:    Socket internal classes
-// Authors:    Guilhem Lavaux
-// Created:    April 1999
-// Updated:
-// Copyright:  (C) 1999, 1998, 1997, Guilhem Lavaux
-// RCS_ID:     $Id$
-// License:    see wxWindows license
-///////////////////////////////////////////////////////////////////////////////
-#ifdef __GNUG__
-#pragma implementation "sckint.h"
-#endif
-
-// For compilers that support precompilation, includes "wx.h".
-#include "wx/wxprec.h"
-
-#ifdef __BORLANDC__
-#pragma hdrstop
-#endif
-
-#if wxUSE_SOCKETS
-
-#define WXSOCK_INTERNAL
-#include "wx/object.h"
-#include "wx/list.h"
-#include "wx/socket.h"
-#include "wx/thread.h"
-#include "wx/sckint.h"
-#include "wx/sckint.h"
-#include "wx/utils.h"
-
-// IRIX requires bstring.h be included to use select()
-#ifdef sgi
-    #include <bstring.h>
-#endif // IRIX
-
-#ifndef __WXSTUBS__
-
-#include <stdlib.h>
-#include <string.h>
-#include <ctype.h>
-
-// -----------------------
-// System specific headers
-// -----------------------
-
-#ifdef __WXMAC__
-// in order to avoid problems with our c library and double definitions
-#define close closesocket
-#define ioctl ioctlsocket
-
-#include <wx/mac/macsock.h>
-#endif
-
-#if defined(__WINDOWS__)
-#include <winsock.h>
-#endif // __WINDOWS__
-
-#if defined(__UNIX__)
-
-#ifdef VMS
-#include <socket.h>
-#else
-#include <sys/socket.h>
-#endif
-#include <sys/ioctl.h>
-
-#include <sys/time.h>
-#include <unistd.h>
-
-#ifdef sun
-#include <sys/filio.h>
-#endif
-
-#endif // __UNIX__
-
-#include <signal.h>
-#include <errno.h>
-
-#ifdef __VISUALC__
-#include <io.h>
-#endif
-
-// Constants
-#define READ_MASK wxSocketBase::REQ_READ | wxSocketBase::REQ_ACCEPT | wxSocketBase::REQ_LOST
-#define WRITE_MASK wxSocketBase::REQ_WRITE | wxSocketBase::REQ_CONNECT
-
-// --------------------------------------------------------------
-// --------- SocketWaiter ---------------------------------------
-// --------------------------------------------------------------
-
-#if wxUSE_THREADS
-SocketWaiter::SocketWaiter(wxSocketBase *socket,
-                                wxSocketInternal *internal)
-  : wxThread(), 
-    m_socket(socket), m_internal(internal), m_fd(internal->GetFD())
-{
-}
-
-SocketWaiter::~SocketWaiter()
-{
-}
-
-void SocketWaiter::ProcessReadEvent()
-{
-  int ret;
-  char c;
-
-  m_internal->AcquireFD();
-  ret = recv(m_fd, &c, 1, MSG_PEEK);
-  m_internal->ReleaseFD();
-  
-  // We are a server => emit a EVT_ACCEPT event.
-  if (ret == -1 && m_socket->GetType() == wxSocketBase::SOCK_SERVER) {
-    m_socket->OnRequest(wxSocketBase::EVT_ACCEPT);
-    return;
-  }
-  
-  // Else, no error => there is something to be read else
-  // we've lost the connection.
-  if (ret > 0) {
-    m_socket->OnRequest(wxSocketBase::EVT_READ);
-  } else {
-    m_socket->OnRequest(wxSocketBase::EVT_LOST);
-    m_internal->ReleaseData();  // In that case, we mustn't forget to unlock the mutex.
-    Exit(NULL);
-  }
-}
-
-void SocketWaiter::ProcessWriteEvent()
-{
-  if (m_socket->IsConnected())
-    m_socket->OnRequest(wxSocketBase::EVT_CONNECT);
-  else
-    m_socket->OnRequest(wxSocketBase::EVT_WRITE);
-}
-
-void *SocketWaiter::Entry()
-{
-  struct timeval tv;
-  fd_set sockrd_set, sockwr_set;
-  wxSocketEvent event;
-  int ret;
-
-  while (1) {
-    // We won't wait.
-    tv.tv_sec = 0;
-    tv.tv_usec = 0;
-
-    FD_ZERO(&sockrd_set);
-    FD_ZERO(&sockwr_set);
-
-    m_internal->AcquireData();
-
-    if ((m_socket->NeededReq() & READ_MASK) != 0)
-      FD_SET(m_fd, &sockrd_set);
-    if ((m_socket->NeededReq() & WRITE_MASK) != 0)
-      FD_SET(m_fd, &sockwr_set);
-
-    m_internal->AcquireFD();
-    ret = select(m_fd+1, &sockrd_set, &sockwr_set, NULL, &tv);
-    m_internal->ReleaseFD();
-
-    if (FD_ISSET(m_fd, &sockrd_set))
-      ProcessReadEvent();
-
-    if (FD_ISSET(m_fd, &sockwr_set))
-      ProcessWriteEvent();
-
-    m_internal->ReleaseData();
-
-#if wxUSE_THREADS
-#ifdef Yield
-#undef Yield
-#endif
-#endif
-
-   // We wait for 100 ms to prevent the CPU from burning.
-   wxUsleep(100);
-
-    // Check whether we should exit.
-    if (TestDestroy())
-      return NULL;
-  }
-  return NULL;
-}
-
-#endif
-
-// --------------------------------------------------------------
-// --------- SocketRequester ------------------------------------
-// --------------------------------------------------------------
-
-SocketRequester::SocketRequester(wxSocketBase *socket,
-                                wxSocketInternal *internal)
-  :
-#if wxUSE_THREADS
-    wxThread(),
-#endif
-    m_socket(socket), m_internal(internal), m_fd(internal->GetFD())
-{
-}
-
-SocketRequester::~SocketRequester()
-{
-}
-
-bool SocketRequester::WaitFor(wxSocketBase::wxRequestNotify req, int millisec)
-{
-  int ret;
-  struct timeval tv;
-  fd_set sockrd_set, sockwr_set;
-
-  // We won't wait.
-  tv.tv_sec = millisec / 1000;
-  tv.tv_usec = (millisec % 1000) * 1000;
-
-  FD_ZERO(&sockrd_set);
-  FD_ZERO(&sockwr_set);
-  if ((req & READ_MASK) != 0)  
-    FD_SET(m_fd, &sockrd_set);
-  if ((req & WRITE_MASK) != 0)
-    FD_SET(m_fd, &sockwr_set);
-  
-  m_internal->AcquireFD();
-  ret = select(m_fd+1, &sockrd_set, &sockwr_set, NULL, &tv);
-  m_internal->ReleaseFD();
-
-  return (ret != 0);
-}
-
-void SocketRequester::ProcessReadEvent(SockRequest *req)
-{
-  int ret;
-  size_t len;
-
-  // We'll wait for the first byte, in case a "timeout event" occurs it returns   // immediately
-  if (!WaitFor(wxSocketBase::REQ_READ, req->timeout)) {
-    m_internal->EndRequest(req);
-    return;
-  }
-
-  m_internal->AcquireFD();
-  ret = recv(m_fd, req->buffer, req->size,
-            (req->type == wxSocketBase::REQ_PEEK) ? MSG_PEEK : 0);
-  m_internal->ReleaseFD();
-
-  // An error occured, we exit.
-  if (ret < 0) {
-    req->error = errno;
-    m_internal->EndRequest(req);
-    return;
-  }
-  len = ret;
-
-  // If the buffer isn't full (and we want it to be full), we don't unqueue it.
-  if ((len < req->size) && (m_socket->GetFlags() & wxSocketBase::WAITALL)) {
-    req->size -= len;
-    req->io_nbytes += len;
-    req->buffer += len;
-
-    if (len == 0)
-      m_internal->EndRequest(req); 
-    return;
-  }
-  // The End.
-  req->io_nbytes += len;
-  m_internal->EndRequest(req);
-}
-
-void SocketRequester::ProcessWriteEvent(SockRequest *req)
-{
-  int ret;
-  size_t len;
-
-  if (!WaitFor(wxSocketBase::REQ_WRITE, req->timeout)) {
-    m_internal->EndRequest(req);
-    return;
-  }
-
-  m_internal->AcquireFD();
-  ret = send(m_fd, req->buffer, req->size, 0);
-  m_internal->ReleaseFD();
-  if (ret < 0) {
-    req->error = errno;
-    m_internal->EndRequest(req);
-    return;
-  }
-  len = ret;
-  if ((len < req->size) && ((m_socket->GetFlags() & wxSocketBase::WAITALL) != 0)) {
-    req->size -= len;
-    req->io_nbytes += len;
-    req->buffer += len;
-    return;
-  }
-  req->io_nbytes += len;
-  m_internal->EndRequest(req);
-}
-
-void SocketRequester::ProcessWaitEvent(SockRequest *req)
-{
-  if (WaitFor(req->type, req->timeout))
-    req->io_nbytes = 1; // We put 1 in the counter to tell the requester
-                        // there is no timeout.
-  else
-    req->io_nbytes = 0;
-
-  m_internal->EndRequest(req);
-}
-
-
-#if wxUSE_THREADS
-void *SocketRequester::Entry()
-{
-  SockRequest *req;
-
-  m_internal->m_request_locker.Lock();
-  while (1) {
-    // Wait for a new request or a destroy message.
-    req = m_internal->WaitForReq();
-    m_internal->m_end_requester.Lock();
-    if (req == NULL) {
-      m_internal->m_invalid_requester = TRUE;
-      m_internal->m_end_requester.Unlock();
-      m_internal->m_request_locker.Unlock();
-      return NULL;
-    }
-    m_internal->m_end_requester.Unlock();
-
-    if ((req->type & wxSocketBase::REQ_WAIT) != 0) {
-      ProcessWaitEvent(req);
-      continue;
-    }
-
-    switch (req->type) {
-    case wxSocketBase::REQ_READ:
-    case wxSocketBase::REQ_PEEK:
-      ProcessReadEvent(req);
-      break;
-    case wxSocketBase::REQ_WRITE:
-      ProcessWriteEvent(req);
-      break;
-    }
-  }
-  return NULL;
-}
-#endif
-
-// --------------------------------------------------------------
-// --------- wxSocketInternal -----------------------------------
-// --------------------------------------------------------------
-
-wxSocketInternal::wxSocketInternal(wxSocketBase *socket)
-{
-  m_socket = socket;
-  m_thread_requester = NULL;
-  m_thread_waiter = NULL;
-  m_invalid_requester = TRUE;
-}
-
-wxSocketInternal::~wxSocketInternal()
-{
-  StopRequester();
-  wxASSERT(m_thread_requester == NULL);
-  StopWaiter();
-  wxASSERT(m_thread_waiter == NULL);
-}
-
-// ----------------------------------------------------------------------
-// WaitForReq: it is called by SocketRequester and should return the next
-// socket request if available
-// ----------------------------------------------------------------------
-SockRequest *wxSocketInternal::WaitForReq()
-{
-#if wxUSE_THREADS
-  wxNode *node;
-
-  // First try.
-  node = m_requests.First();
-  if (node == NULL) {
-    m_socket_cond.Wait(m_request_locker, 10, 0);
-
-    // Second try, if it is unsuccessul we give up.
-    node = m_requests.First();
-    if (node == NULL)
-      return NULL;
-  }
-
-  return (SockRequest *)node->Data();
-#else
-  return NULL;
-#endif
-}
-
-// ----------------------------------------------------------------------
-// EndRequest: Should be called to finalize a request
-// ----------------------------------------------------------------------
-void wxSocketInternal::EndRequest(SockRequest *req)
-{
-  wxNode *node = NULL;
-
-  req->done = TRUE;
-
-  node = m_requests.Member((wxObject *)req);
-  if (node != NULL)
-    delete node;
-}
-
-void wxSocketInternal::AcquireData()
-{
-#if wxUSE_THREADS
-  m_socket_locker.Lock();
-#endif
-}
-
-void wxSocketInternal::ReleaseData()
-{
-#if wxUSE_THREADS
-  m_socket_locker.Unlock();
-#endif
-}
-
-void wxSocketInternal::AcquireFD()
-{
-#if wxUSE_THREADS
-  m_fd_locker.Lock();
-#endif
-}
-
-void wxSocketInternal::ReleaseFD()
-{
-#if wxUSE_THREADS
-  m_fd_locker.Unlock();
-#endif
-}
-
-void wxSocketInternal::ResumeRequester()
-{
-#if wxUSE_THREADS
-  wxThreadError err;
-
-  wxASSERT(m_invalid_requester);
-
-  m_end_requester.Lock();
-
-  if (m_thread_requester != NULL) {
-    m_thread_requester->Delete(); // We must join it.
-    delete m_thread_requester;
-  }
-
-  m_invalid_requester = FALSE;
-
-  m_end_requester.Unlock();
-
-  m_thread_requester = new SocketRequester(m_socket, this);
-
-  err = m_thread_requester->Create();
-  wxASSERT(err == wxTHREAD_NO_ERROR);
-
-  err = m_thread_requester->Run();
-  wxASSERT(err == wxTHREAD_NO_ERROR);
-#else
-  if (!m_invalid_requester) 
-    return;
-  m_thread_requester = new SocketRequester(m_socket, this);
-  m_invalid_requester = FALSE;
-#endif
-}
-
-void wxSocketInternal::StopRequester()
-{
-#if wxUSE_THREADS
-  m_end_requester.Lock();
-  if (m_invalid_requester) {
-    m_end_requester.Unlock();
-    if (m_thread_requester) {
-      m_thread_requester->Delete();
-      delete m_thread_requester;
-      m_thread_requester = NULL;
-    }
-    m_invalid_requester = TRUE;
-    return;
-  }
-  m_end_requester.Unlock();
-
-  wxASSERT(m_thread_requester != NULL);
-
-  m_request_locker.Lock();
-
-  // Send a signal to the requester.
-  m_socket_cond.Signal();
-
-  m_request_locker.Unlock();
-
-  // Finish the destruction of the requester.
-  m_thread_requester->Delete();
-
-  delete m_thread_requester;
-  m_thread_requester = NULL;
-  m_invalid_requester = TRUE;
-#else
-  delete m_thread_requester;
-  m_thread_requester = NULL;
-  m_invalid_requester = TRUE;
-#endif
-}
-
-void wxSocketInternal::ResumeWaiter()
-{
-#if wxUSE_THREADS
-  wxThreadError err;
-
-  if (m_thread_waiter != NULL)
-    return;
-
-  m_thread_waiter = new SocketWaiter(m_socket, this);
-
-  m_thread_waiter->SetPriority(WXTHREAD_MIN_PRIORITY);
-
-  err = m_thread_waiter->Create();
-  wxASSERT(err == wxTHREAD_NO_ERROR);
-
-  err = m_thread_waiter->Run();
-  wxASSERT(err == wxTHREAD_NO_ERROR);
-#endif
-}
-
-void wxSocketInternal::StopWaiter()
-{
-#if wxUSE_THREADS
-  if (m_thread_waiter == NULL)
-    return;
-
-  m_thread_waiter->Delete();
-
-  delete m_thread_waiter;
-  m_thread_waiter = NULL;
-#endif
-}
-
-// ----------------------------------------------------------------------
-// QueueRequest:
-// ----------------------------------------------------------------------
-void wxSocketInternal::QueueRequest(SockRequest *request, bool async)
-{
-  if (m_invalid_requester)
-    ResumeRequester();
-
-#if wxUSE_THREADS
-  if (async) {
-
-    m_request_locker.Lock();
-    request->done = FALSE;
-    m_requests.Append((wxObject *)request);
-    m_socket_cond.Signal();
-    m_request_locker.Unlock();
-    
-    // Wake up
-    
-    if (request->wait) {
-      if (wxThread::IsMain())
-        while (!request->done) {
-         wxYield();
-        }
-      else
-        while (!request->done) {
-          wxThread::Yield();
-        }
-    }
-  } else {
-    m_request_locker.Lock();
-#endif
-
-    if ((request->type & wxSocketBase::REQ_WAIT) != 0) {
-      m_thread_requester->ProcessWaitEvent(request);
-    } else {
-
-      request->done = FALSE;
-
-      switch (request->type) {
-      case wxSocketBase::REQ_PEEK:
-      case wxSocketBase::REQ_READ:
-        m_thread_requester->ProcessReadEvent(request);
-        break;
-      case wxSocketBase::REQ_WRITE:
-        m_thread_requester->ProcessWriteEvent(request);
-        break;
-      }
-    }
-    request->done = TRUE;
-#if wxUSE_THREADS
-    m_request_locker.Unlock();
-  }
-#endif
-}
-
-void wxSocketInternal::WaitForEnd(SockRequest *request)
-{
-#if wxUSE_THREADS
-  // TODOTODO
-#endif
-}
-
-#endif
-  // __WXSTUBS__
-
-#endif
-  // wxUSE_SOCKETS
index 694b94d33697ff4b96590722afcfc3c9716dc3d4..27dae77d322c6cab2f0dde33a4ee443b21e579dd 100644 (file)
@@ -60,10 +60,10 @@ enum {
 #endif
 
 void Server_OnRequest(wxSocketServer& server,
 #endif
 
 void Server_OnRequest(wxSocketServer& server,
-                     wxSocketBase::wxRequestEvent evt,
+                     GSocketEvent evt,
                      char *cdata);
 void Client_OnRequest(wxSocketBase& sock,
                      char *cdata);
 void Client_OnRequest(wxSocketBase& sock,
-                     wxSocketBase::wxRequestEvent evt,
+                     GSocketEvent evt,
                      char *cdata);
 
 // ---------------------------------------------------------------------------
                      char *cdata);
 
 // ---------------------------------------------------------------------------
@@ -91,13 +91,12 @@ wxConnectionBase *wxTCPClient::MakeConnection (const wxString& host,
                                                const wxString& topic)
 {
   wxIPV4address addr;
                                                const wxString& topic)
 {
   wxIPV4address addr;
-  wxSocketHandler *hsock = &wxSocketHandler::Master();
-  wxSocketClient *client = hsock->CreateClient();
+  wxSocketClient *client = new wxSocketClient();
   wxSocketStream *stream = new wxSocketStream(*client);
   wxDataInputStream data_is(*stream);
   wxDataOutputStream data_os(*stream);
   
   wxSocketStream *stream = new wxSocketStream(*client);
   wxDataInputStream data_is(*stream);
   wxDataOutputStream data_os(*stream);
   
-  client->SetNotify(wxSocketBase::REQ_READ | wxSocketBase::REQ_LOST);
+  client->SetNotify(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
   addr.Service(server_name);
   addr.Hostname(host);
 
   addr.Service(server_name);
   addr.Hostname(host);
 
@@ -156,15 +155,14 @@ wxTCPServer::wxTCPServer (void)
 bool wxTCPServer::Create(const wxString& server_name)
 {
   wxIPV4address addr;
 bool wxTCPServer::Create(const wxString& server_name)
 {
   wxIPV4address addr;
-  wxSocketHandler *hsock = &wxSocketHandler::Master();
   wxSocketServer *server;
 
   addr.Service(server_name);
 
   // Create a socket listening on specified port
   wxSocketServer *server;
 
   addr.Service(server_name);
 
   // Create a socket listening on specified port
-  server = hsock->CreateServer(addr);
+  server = new wxSocketServer(addr);
   server->Callback((wxSocketBase::wxSockCbk)Server_OnRequest);
   server->Callback((wxSocketBase::wxSockCbk)Server_OnRequest);
-  server->SetNotify(wxSocketBase::REQ_ACCEPT);
+  server->SetNotify(GSOCK_CONNECTION_FLAG);
 
   server->CallbackData((char *)this);
 
 
   server->CallbackData((char *)this);
 
@@ -338,7 +336,7 @@ bool wxTCPConnection::Advise (const wxString& item,
   return TRUE;
 }
 
   return TRUE;
 }
 
-void Client_OnRequest(wxSocketBase& sock, wxSocketBase::wxRequestEvent evt,
+void Client_OnRequest(wxSocketBase& sock, GSocketEvent evt,
                      char *cdata)
 {
   int msg = 0;
                      char *cdata)
 {
   int msg = 0;
@@ -350,7 +348,7 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketBase::wxRequestEvent evt,
   wxString item;
 
   // The socket handler signals us that we lost the connection: destroy all.
   wxString item;
 
   // The socket handler signals us that we lost the connection: destroy all.
-  if (evt == wxSocketBase::EVT_LOST) {
+  if (evt == GSOCK_LOST) {
     sock.Close();
     connection->OnDisconnect();
     return;
     sock.Close();
     connection->OnDisconnect();
     return;
@@ -466,20 +464,20 @@ void Client_OnRequest(wxSocketBase& sock, wxSocketBase::wxRequestEvent evt,
 }
 
 void Server_OnRequest(wxSocketServer& server,
 }
 
 void Server_OnRequest(wxSocketServer& server,
-                     wxSocketBase::wxRequestEvent evt, char *cdata)
+                     GSocketEvent evt, char *cdata)
 {
   wxTCPServer *ipcserv = (wxTCPServer *)cdata;
   wxSocketStream *stream;
   wxDataInputStream *codeci;
   wxDataOutputStream *codeco;
 
 {
   wxTCPServer *ipcserv = (wxTCPServer *)cdata;
   wxSocketStream *stream;
   wxDataInputStream *codeci;
   wxDataOutputStream *codeco;
 
-  if (evt != wxSocketBase::EVT_ACCEPT)
+  if (evt != GSOCK_CONNECTION)
     return;
 
   /* Accept the connection, getting a new socket */
   wxSocketBase *sock = server.Accept();
   sock->Notify(FALSE);
     return;
 
   /* Accept the connection, getting a new socket */
   wxSocketBase *sock = server.Accept();
   sock->Notify(FALSE);
-  sock->SetNotify(wxSocketBase::REQ_READ | wxSocketBase::REQ_LOST);
+  sock->SetNotify(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
 
   stream = new wxSocketStream(*sock);
   codeci = new wxDataInputStream(*stream);
 
   stream = new wxSocketStream(*sock);
   codeci = new wxDataInputStream(*stream);
index f7796cea3b7ca45f01d6952dc64696fb6855e9a8..df9392287032f0045abcff4d706f728e33f3ffdd 100644 (file)
@@ -42,15 +42,21 @@ wxSocketOutputStream::~wxSocketOutputStream()
 {
 }
 
 {
 }
 
-wxOutputStream& wxSocketOutputStream::Write(const void *buffer, size_t size)
-{
-  m_lastcount = m_o_socket->Write((const char *)buffer, size).LastCount();
-  return *this;
-}
-
 size_t wxSocketOutputStream::OnSysWrite(const void *buffer, size_t size)
 {
 size_t wxSocketOutputStream::OnSysWrite(const void *buffer, size_t size)
 {
-  return m_o_socket->Write((const char *)buffer, size).LastCount();
+  size_t ret;
+
+  ret = m_o_socket->Write((const char *)buffer, size).LastCount();
+  switch (m_o_socket->LastError()) {
+  case GSOCK_NOERROR:
+    m_lasterror = wxStream_NOERROR;
+    break;
+  default:
+    m_lasterror = wxStream_READ_ERR;
+    break;
+  }
+  return ret;
+
 }
 
 // ---------------------------------------------------------------------------
 }
 
 // ---------------------------------------------------------------------------
@@ -66,15 +72,20 @@ wxSocketInputStream::~wxSocketInputStream()
 {
 }
 
 {
 }
 
-wxInputStream& wxSocketInputStream::Read(void *buffer, size_t size)
-{
-  m_lastcount = m_i_socket->Read((char *)buffer, size).LastCount();
-  return *this;
-}
-
 size_t wxSocketInputStream::OnSysRead(void *buffer, size_t size)
 {
 size_t wxSocketInputStream::OnSysRead(void *buffer, size_t size)
 {
-  return m_i_socket->Read((char *)buffer, size).LastCount();
+  size_t ret;
+
+  ret = m_i_socket->Read((char *)buffer, size).LastCount();
+  switch (m_i_socket->LastError()) {
+  case GSOCK_NOERROR:
+    m_lasterror = wxStream_NOERROR;
+    break;
+  default:
+    m_lasterror = wxStream_WRITE_ERR;
+    break;
+  }
+  return ret;
 }
 
 // ---------------------------------------------------------------------------
 }
 
 // ---------------------------------------------------------------------------
index 052078b3b48ae5951831dce65d57556e85c69eec..4e12e8971bfd4affb1ab62808130a48d4a4d89fc 100644 (file)
@@ -1,11 +1,10 @@
 ////////////////////////////////////////////////////////////////////////////////
 // Name:       socket.cpp
 // Purpose:    Socket handler classes
 ////////////////////////////////////////////////////////////////////////////////
 // Name:       socket.cpp
 // Purpose:    Socket handler classes
-// Authors:    Guilhem Lavaux (completely rewritten from a basic API of Andrew
-//             Davidson(1995) in wxWeb)
+// Authors:    Guilhem Lavaux
 // Created:    April 1997
 // Created:    April 1997
-// Updated:    April 1999
-// Copyright:  (C) 1999 1998, 1997, Guilhem Lavaux
+// Updated:    July 1999
+// Copyright:  (C) 1999, 1998, 1997, Guilhem Lavaux
 // RCS_ID:     $Id$
 // License:    see wxWindows license
 ////////////////////////////////////////////////////////////////////////////////
 // RCS_ID:     $Id$
 // License:    see wxWindows license
 ////////////////////////////////////////////////////////////////////////////////
 #pragma implementation "socket.h"
 #endif
 
 #pragma implementation "socket.h"
 #endif
 
-#ifdef __MWERKS__
-typedef int socklen_t ;
-#endif
-
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 // For compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
@@ -34,132 +29,18 @@ typedef int socklen_t ;
 #include <wx/string.h>
 #include <wx/timer.h>
 #include <wx/utils.h>
 #include <wx/string.h>
 #include <wx/timer.h>
 #include <wx/utils.h>
-
-// IRIX requires bstring.h be included to use select()
-#ifdef sgi
-    #include <bstring.h>
-#endif // IRIX
-
-// Not enough OS behaviour defined for wxStubs
-#ifndef __WXSTUBS__
+#include <wx/log.h>
 
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 
 
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
 
-/////////////////////////////////////////////////////////////////////////////
-// System specific headers
-/////////////////////////////////////////////////////////////////////////////
-#ifdef __WXMAC__
-// in order to avoid problems with our c library and double definitions
-#define close closesocket
-#define ioctl ioctlsocket
-
-#include <wx/mac/macsock.h>
-
-#endif
-
-#if defined(__WINDOWS__)
-#include <winsock.h>
-#endif // __WINDOWS__
-
-#if defined(__UNIX__)
-
-#ifdef VMS
-#include <socket.h>
-#else
-#include <sys/socket.h>
-#endif
-#include <sys/ioctl.h>
-
-#include <sys/time.h>
-#include <unistd.h>
-
-#ifdef sun
-#include <sys/filio.h>
-#endif
-
-#endif // __UNIX__
-
-#include <signal.h>
-#include <errno.h>
-
-#ifdef __VISUALC__
-#include <io.h>
-#endif
-
 /////////////////////////////////////////////////////////////////////////////
 // wxSocket headers
 /////////////////////////////////////////////////////////////////////////////
 #include <wx/module.h>
 /////////////////////////////////////////////////////////////////////////////
 // wxSocket headers
 /////////////////////////////////////////////////////////////////////////////
 #include <wx/module.h>
-#define WXSOCK_INTERNAL
 #include <wx/sckaddr.h>
 #include <wx/socket.h>
 #include <wx/sckaddr.h>
 #include <wx/socket.h>
-#include <wx/sckint.h>
-
-// ----------------------
-// Some patch ----- BEGIN
-// ----------------------
-#ifdef __WINDOWS__
-#define close closesocket
-#define ioctl ioctlsocket
-#ifdef errno
-#undef errno
-#endif
-#define errno WSAGetLastError()
-#ifdef EWOULDBLOCK
-#undef EWOULDBLOCK
-#endif
-#define EWOULDBLOCK WSAEWOULDBLOCK
-#define ETIMEDOUT WSAETIMEDOUT
-#undef EINTR
-#define EINTR WSAEINTR
-#endif
-
-#ifndef __WINDOWS__
-#define INVALID_SOCKET -1
-#endif
-
-#ifdef __WINDOWS__
-// This is an MS TCP/IP routine and is not needed here. Some WinSock
-// implementations (such as PC-NFS) will require you to include this
-// or a similar routine (see appendix in WinSock doc or help file).
-
-#if defined( NEED_WSAFDIsSet ) || defined( __VISUALC__ )
-int PASCAL FAR __WSAFDIsSet(SOCKET fd, fd_set FAR *set)
-{
-  int i = set->fd_count;
-
-  while (i--)
-  {
-    if (set->fd_array[i] == fd)
-      return 1;
-  }
-
-  return 0;
-}
-#endif
-#endif
-
-// -------------------
-// Some patch ---- END
-// -------------------
-
-#ifdef GetClassInfo
-#undef GetClassInfo
-#endif
-
-// --------------------------------------------------------------
-// Module
-// --------------------------------------------------------------
-class wxSocketModule: public wxModule 
-{
-  DECLARE_DYNAMIC_CLASS(wxSocketModule)
-public:
-  wxSocketModule() {}
-  bool OnInit();
-  void OnExit();
-};
 
 // --------------------------------------------------------------
 // ClassInfos
 
 // --------------------------------------------------------------
 // ClassInfos
@@ -168,76 +49,76 @@ public:
 IMPLEMENT_CLASS(wxSocketBase, wxObject)
 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
 IMPLEMENT_CLASS(wxSocketBase, wxObject)
 IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
 IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
-IMPLEMENT_CLASS(wxSocketHandler, wxObject)
 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
 IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
-IMPLEMENT_DYNAMIC_CLASS(wxSocketModule, wxModule)
 #endif
 
 #endif
 
+class wxSocketState : public wxObject {
+public:
+  bool notify_state; 
+  GSocketEventFlags evt_notify_state;
+  wxSocketBase::wxSockFlags socket_flags;
+  wxSocketBase::wxSockCbk c_callback;
+  char *c_callback_data;
+
+public:
+  wxSocketState() : wxObject() {}
+};
+
 // --------------------------------------------------------------
 // --------- wxSocketBase CONSTRUCTOR ---------------------------
 // --------------------------------------------------------------
 wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags,
          wxSocketBase::wxSockType _type) :
   wxEvtHandler(),
 // --------------------------------------------------------------
 // --------- wxSocketBase CONSTRUCTOR ---------------------------
 // --------------------------------------------------------------
 wxSocketBase::wxSocketBase(wxSocketBase::wxSockFlags _flags,
          wxSocketBase::wxSockType _type) :
   wxEvtHandler(),
-  m_flags(_flags), m_type(_type), m_connected(FALSE), m_connecting(FALSE),
-  m_fd(INVALID_SOCKET), m_id(-1),
-  m_handler(0),
-  m_neededreq((wxRequestNotify)(REQ_READ | REQ_LOST)),
-  m_timeout(3600),
-  m_unread(NULL), m_unrd_size(0),
+  m_socket(NULL), m_flags(_flags), m_type(_type),
+  m_neededreq(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG),
+  m_lcount(0), m_timeout(3600),
+  m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
   m_cbk(NULL), m_cdata(NULL),
   m_cbk(NULL), m_cdata(NULL),
-  m_notify_state(FALSE)
+  m_connected(FALSE), m_notify_state(FALSE), m_id(-1),
+  m_defering(NO_DEFER),
+  m_states()
 {
 {
-  m_internal = new wxSocketInternal(this);
 }
 
 wxSocketBase::wxSocketBase() :
   wxEvtHandler(),
 }
 
 wxSocketBase::wxSocketBase() :
   wxEvtHandler(),
-  m_flags(WAITALL), m_type(SOCK_UNINIT), m_connected(FALSE),
-  m_connecting(FALSE), m_fd(INVALID_SOCKET),
-  m_id(-1), m_handler(0),
-  m_neededreq((wxRequestNotify)(REQ_READ | REQ_LOST)),
-  m_timeout(3600),
-  m_unread(NULL), m_unrd_size(0),
+  m_socket(NULL), m_flags((wxSockFlags)SPEED | WAITALL), m_type(SOCK_UNINIT),
+  m_neededreq(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG),
+  m_lcount(0), m_timeout(3600),
+  m_unread(NULL), m_unrd_size(0), m_unrd_cur(0),
   m_cbk(NULL), m_cdata(NULL),
   m_cbk(NULL), m_cdata(NULL),
-  m_notify_state(FALSE)
+  m_connected(FALSE), m_notify_state(FALSE), m_id(-1),
+  m_defering(NO_DEFER),
+  m_states()
 {
 {
-  m_internal = new wxSocketInternal(this);
 }
 
 // --------------------------------------------------------------
 }
 
 // --------------------------------------------------------------
-// wxSocketBase
+// wxSocketBase destructor
 // --------------------------------------------------------------
 
 wxSocketBase::~wxSocketBase()
 {
 // --------------------------------------------------------------
 
 wxSocketBase::~wxSocketBase()
 {
-  // First, close the file descriptor.
-  Close();
-
   if (m_unread)
     free(m_unread);
   if (m_unread)
     free(m_unread);
-  // Unregister from the handler database.
-  if (m_handler) 
-    m_handler->UnRegister(this);
 
 
-  // Destroy all saved states.
-  m_states.DeleteContents(TRUE);
+  // At last, close the file descriptor.
+  Close();
 
 
-  // Destroy the socket manager.
-  delete m_internal;
+  if (m_socket)
+    GSocket_destroy(m_socket);
 }
 
 bool wxSocketBase::Close()
 {
 }
 
 bool wxSocketBase::Close()
 {
-  if (m_fd != INVALID_SOCKET
+  if (m_socket
   {
     if (m_notify_state == TRUE)
       Notify(FALSE);
 
     // Shutdown the connection.
   {
     if (m_notify_state == TRUE)
       Notify(FALSE);
 
     // Shutdown the connection.
-    shutdown(m_fd, 2);
-    close(m_fd);
-    m_fd = INVALID_SOCKET;
+    GSocket_Shutdown(m_socket);
     m_connected = FALSE;
   }
 
     m_connected = FALSE;
   }
 
@@ -248,19 +129,75 @@ bool wxSocketBase::Close()
 // wxSocketBase base IO function
 // --------------------------------------------------------------
 
 // wxSocketBase base IO function
 // --------------------------------------------------------------
 
+int wxSocketBase::DeferRead(char *buffer, size_t nbytes)
+{
+  GSocketEventFlags old_event_flags;
+  bool old_notify_state;
+
+  wxASSERT(m_defering == NO_DEFER);
+
+  m_defering = DEFER_READ;
+
+  old_event_flags = NeededReq();
+  old_notify_state = m_notify_state;
+  
+  SetNotify(GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
+  Notify(TRUE);
+
+  m_defer_buffer = buffer;
+  m_defer_nbytes = nbytes;
+  while (m_defer_buffer != NULL)
+    wxYield();
+
+  Notify(old_notify_state);
+  SetNotify(old_event_flags);
+
+  m_defering = NO_DEFER;
+
+  return nbytes-m_defer_nbytes;
+}
+
 wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
 {
 wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
 {
+  int ret = 1;
+
   m_lcount = GetPushback(buffer, nbytes, FALSE);
   nbytes -= m_lcount;
   buffer += m_lcount;
 
   m_lcount = GetPushback(buffer, nbytes, FALSE);
   nbytes -= m_lcount;
   buffer += m_lcount;
 
+  if (!m_connected)
+    return *this;
+
   // If we have got the whole needed buffer or if we don't want to
   // wait then it returns immediately.
   if (!nbytes || (m_lcount && !(m_flags & WAITALL)) ) {
     return *this;
   }
 
   // If we have got the whole needed buffer or if we don't want to
   // wait then it returns immediately.
   if (!nbytes || (m_lcount && !(m_flags & WAITALL)) ) {
     return *this;
   }
 
-  WantBuffer(buffer, nbytes, EVT_READ);
+  if ((m_flags & SPEED) != 0) {
+
+    if ((m_flags & WAITALL) != 0) {
+      while (ret > 0 && nbytes > 0) {
+        ret = GSocket_Read(m_socket, buffer, nbytes);
+        m_lcount += ret;
+        buffer += ret;
+        nbytes -= ret;
+      }
+    // In case the last call was an error ...
+      if (ret < 0)
+        m_lcount ++;
+    } else {
+      ret = GSocket_Read(m_socket, buffer, nbytes);
+      if (ret > 0)
+        m_lcount += ret;
+    }
+
+  } else {
+    ret = DeferRead(buffer, nbytes);
+
+    if (ret > 0)
+      m_lcount += ret;
+  }
 
   return *this;
 }
 
   return *this;
 }
@@ -315,34 +252,62 @@ wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes)
   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 |= (size_t)(msg.sig[1] & 0xff) << 8;
   sig |= (size_t)(msg.sig[2] & 0xff) << 16;
   sig |= (size_t)(msg.sig[3] & 0xff) << 24;
+
 // ERROR
 // ERROR
-// we return *this either way, so a smart optimizer will
-// optimize the following sequence out; I'm leaving it in anyway
   if (sig != 0xdeadfeed)
   if (sig != 0xdeadfeed)
-    return *this;
+    wxLogDebug(_T("Warning: invalid signature returned to ReadMsg\n"));
 
   return *this;
 }
 
 wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
 {
 
   return *this;
 }
 
 wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
 {
-  m_lcount = GetPushback(buffer, nbytes, TRUE);
-  if (nbytes-m_lcount == 0) 
-  {
-    return *this;
-  }
-  buffer += m_lcount;
-  nbytes -= m_lcount;
-
-  WantBuffer(buffer, nbytes, EVT_PEEK);
+  Read(buffer, nbytes);
+  CreatePushbackAfter(buffer, nbytes);
 
   return *this;
 }
 
 
   return *this;
 }
 
+int wxSocketBase::DeferWrite(const char *buffer, size_t nbytes)
+{
+  GSocketEventFlags old_event_flags;
+  bool old_notify_state;
+
+  wxASSERT(m_defering == NO_DEFER);
+
+  m_defering = DEFER_WRITE;
+
+  old_event_flags = NeededReq();
+  old_notify_state = m_notify_state;
+
+  SetNotify(GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG);
+  Notify(TRUE);
+
+  m_defer_buffer = (char *)buffer;
+  m_defer_nbytes = nbytes;
+  while (m_defer_buffer != NULL)
+    wxYield();
+
+  Notify(old_notify_state);
+  SetNotify(old_event_flags);
+
+  m_defering = NO_DEFER;
+
+  return nbytes-m_defer_nbytes;
+}
+
 wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes)
 {
 wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes)
 {
-  m_lcount = 0;
-  WantBuffer((char *)buffer, nbytes, EVT_WRITE);
+  int ret;
+
+  if ((m_flags & SPEED) != 0)
+    ret = GSocket_Write(m_socket, buffer, nbytes);
+  else
+    ret = DeferWrite(buffer, nbytes);
+
+  if (ret != -1)
+    m_lcount += ret;
+
   return *this;
 }
 
   return *this;
 }
 
@@ -399,25 +364,43 @@ wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes)
 
 bool wxSocketBase::IsData() const
 {
 
 bool wxSocketBase::IsData() const
 {
-  struct timeval tv;
-  fd_set sock_set;
-
-  if (m_fd < 0)
+  if (!m_socket)
     return FALSE;
     return FALSE;
-  if (m_unrd_size > 0)
-    return TRUE;
 
 
-  m_internal->AcquireFD();
+  return (GSocket_DataAvailable(m_socket));
+}
+
+void wxSocketBase::DoDefer(GSocketEvent req_evt)
+{
+  int ret;
 
 
-  tv.tv_sec = 0;
-  tv.tv_usec = 0;
-  FD_ZERO(&sock_set);
-  FD_SET(m_fd, &sock_set);
-  select(m_fd+1, &sock_set, NULL, NULL, &tv);
+  if (req_evt == GSOCK_LOST) {
+    Close();
+    m_defer_buffer = NULL;
+    return;
+  }
+  switch (m_defering) {
+  case DEFER_READ:
+    ret = GSocket_Read(m_socket, m_defer_buffer, m_defer_nbytes);
+    break;
+  case DEFER_WRITE:
+    ret = GSocket_Write(m_socket, m_defer_buffer, m_defer_nbytes);
+    break;
+  default:
+    ret = -1;
+    break;
+  }
 
 
-  m_internal->ReleaseFD();
+  m_defer_nbytes -= ret;
 
 
-  return (FD_ISSET(m_fd, &sock_set) != 0);
+  if (ret < 0)
+    m_defer_nbytes++;
+
+  if ((m_flags & WAITALL) == 0 || m_defer_nbytes == 0 || ret < 0) {
+    m_defer_buffer = NULL;
+    Notify(FALSE);
+  } else
+    m_defer_buffer += ret;
 }
 
 // ---------------------------------------------------------------------
 }
 
 // ---------------------------------------------------------------------
@@ -443,64 +426,35 @@ void wxSocketBase::Discard()
 #undef MAX_BUFSIZE
 }
 
 #undef MAX_BUFSIZE
 }
 
-// If what? Who seems to need unsigned int?
-// BTW uint isn't even defined on wxMSW for VC++ for some reason. Even if it
-// were, getpeername/getsockname don't take unsigned int*, they take int*.
-//
-// Under glibc 2.0.7, socketbits.h declares socklen_t to be unsigned int
-// and it uses *socklen_t as the 3rd parameter. Robert.
-
-// JACS - How can we detect this?
-// Meanwhile, if your compiler complains about socklen_t,
-// switch lines below.
-
-#if wxHAVE_GLIBC2
-#   define wxSOCKET_INT socklen_t
-#else
-#   define wxSOCKET_INT int
-#endif
-
 // --------------------------------------------------------------
 // wxSocketBase socket info functions
 // --------------------------------------------------------------
 
 bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
 {
 // --------------------------------------------------------------
 // wxSocketBase socket info functions
 // --------------------------------------------------------------
 
 bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
 {
-  struct sockaddr my_addr;
-  wxSOCKET_INT len_addr = sizeof(my_addr);
+  GAddress *peer;
 
 
-  if (m_fd < 0)
+  if (!m_socket)
     return FALSE;
 
     return FALSE;
 
-  m_internal->AcquireFD();
+  peer = GSocket_GetPeer(m_socket);
+  addr_man.SetAddress(peer);
+  GAddress_destroy(peer);
 
 
-  if (getpeername(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0) {
-    m_internal->ReleaseFD();
-    return FALSE;
-  }
-
-  m_internal->ReleaseFD();
-  addr_man.Disassemble(&my_addr, len_addr);
   return TRUE;
 }
 
 bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
 {
   return TRUE;
 }
 
 bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
 {
-  struct sockaddr my_addr;
-  wxSOCKET_INT len_addr = sizeof(my_addr);
+  GAddress *local;
 
 
-  if (m_fd < 0)
+  if (!m_socket)
     return FALSE;
 
     return FALSE;
 
-  m_internal->AcquireFD();
-
-  if (getsockname(m_fd, (struct sockaddr *)&my_addr, &len_addr) < 0) {
-    m_internal->ReleaseFD();
-    return FALSE;
-  }
-  m_internal->ReleaseFD();
+  local = GSocket_GetLocal(m_socket);
+  addr_man.SetAddress(local);
+  GAddress_destroy(local);
 
 
-  addr_man.Disassemble(&my_addr, len_addr);
   return TRUE;
 }
 
   return TRUE;
 }
 
@@ -510,7 +464,9 @@ bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
 
 void wxSocketBase::SaveState()
 {
 
 void wxSocketBase::SaveState()
 {
-  SocketState *state = new SocketState;
+  wxSocketState *state;
+
+  state = new wxSocketState();
 
   state->notify_state     = m_notify_state;
   state->evt_notify_state = m_neededreq;
 
   state->notify_state     = m_notify_state;
   state->evt_notify_state = m_neededreq;
@@ -518,24 +474,22 @@ void wxSocketBase::SaveState()
   state->c_callback       = m_cbk;
   state->c_callback_data  = m_cdata;
 
   state->c_callback       = m_cbk;
   state->c_callback_data  = m_cdata;
 
-  m_states.Append((wxObject *)state);
+  m_states.Append(state);
 }
 
 void wxSocketBase::RestoreState()
 {
   wxNode *node;
 }
 
 void wxSocketBase::RestoreState()
 {
   wxNode *node;
-  SocketState *state;
+  wxSocketState *state;
 
   node = m_states.Last();
   if (!node)
     return;
 
 
   node = m_states.Last();
   if (!node)
     return;
 
-  state = (SocketState *)node->Data();
+  state = (wxSocketState *)node->Data();
 
   SetFlags(state->socket_flags);
 
   SetFlags(state->socket_flags);
-  m_internal->AcquireData();
   m_neededreq = state->evt_notify_state;
   m_neededreq = state->evt_notify_state;
-  m_internal->ReleaseData();
   m_cbk       = state->c_callback;
   m_cdata     = state->c_callback_data;
   Notify(state->notify_state);
   m_cbk       = state->c_callback;
   m_cdata     = state->c_callback_data;
   Notify(state->notify_state);
@@ -568,68 +522,89 @@ char *wxSocketBase::CallbackData(char *data)
 // --------- wxSocketBase wait functions ------------------------
 // --------------------------------------------------------------
 
 // --------- 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;
+
+  *state = event;
+}
+
 bool wxSocketBase::_Wait(long seconds, long milliseconds, int type)
 {
 bool wxSocketBase::_Wait(long seconds, long milliseconds, int type)
 {
-  SockRequest *req;
+  bool old_notify_state = m_notify_state;
+  int state = 0;
+  _wxSocketInternalTimer timer;
 
 
-  if ((!m_connected && !m_connecting) || m_fd < 0)
+  if (!m_connected || !m_socket)
     return FALSE;
 
     return FALSE;
 
-  req = new SockRequest;
+  timer.m_state = &state;
+
+  Notify(FALSE);
+
+  timer.Start(seconds * 1000 + milliseconds, TRUE);
+  GSocket_SetFallback(m_socket, type, wx_socket_wait, (char *)&state);
 
 
-  req->type = REQ_WAIT | type;
-  req->timeout = seconds * 1000 + milliseconds;
-  req->done = FALSE;
-  req->buffer = NULL;
-  req->size = 0;
-  req->error = 0;
-  req->wait = TRUE;
-  m_internal->QueueRequest(req, TRUE);
+  while (state == 0)
+    wxYield();
 
 
-  return (req->io_nbytes != 0);
+  GSocket_UnsetFallback(m_socket, type);
+  timer.Stop();
+
+  Notify(old_notify_state);
+
+  return (state != GSOCK_MAX_EVENT);
 }
 
 bool wxSocketBase::Wait(long seconds, long milliseconds)
 {
 }
 
 bool wxSocketBase::Wait(long seconds, long milliseconds)
 {
-  return _Wait(seconds, milliseconds, REQ_ACCEPT | REQ_CONNECT |
-                                      REQ_READ | REQ_WRITE | REQ_LOST);
+  return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG | GSOCK_OUTPUT_FLAG |
+                                      GSOCK_CONNECTION_FLAG | GSOCK_LOST_FLAG);
 }
 
 bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
 {
 }
 
 bool wxSocketBase::WaitForRead(long seconds, long milliseconds)
 {
-  return _Wait(seconds, milliseconds, REQ_READ | REQ_LOST);
+  return _Wait(seconds, milliseconds, GSOCK_INPUT_FLAG | GSOCK_LOST_FLAG);
 }
 
 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
 {
 }
 
 bool wxSocketBase::WaitForWrite(long seconds, long milliseconds)
 {
-  return _Wait(seconds, milliseconds, REQ_WRITE);
+  return _Wait(seconds, milliseconds, GSOCK_OUTPUT_FLAG | GSOCK_LOST_FLAG);
 }
 
 bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
 {
 }
 
 bool wxSocketBase::WaitForLost(long seconds, long milliseconds)
 {
-  return _Wait(seconds, milliseconds, REQ_LOST);
+  return _Wait(seconds, milliseconds, GSOCK_LOST_FLAG);
 }
 
 // --------------------------------------------------------------
 // --------- wxSocketBase callback management -------------------
 // --------------------------------------------------------------
 
 }
 
 // --------------------------------------------------------------
 // --------- wxSocketBase callback management -------------------
 // --------------------------------------------------------------
 
-wxSocketBase::wxRequestNotify wxSocketBase::EventToNotify(wxRequestEvent evt)
+GSocketEventFlags wxSocketBase::EventToNotify(GSocketEvent evt)
 {
   switch (evt) 
   {
 {
   switch (evt) 
   {
-  case EVT_READ:
-    return REQ_READ;
-  case EVT_PEEK:
-    return REQ_PEEK;
-  case EVT_WRITE:
-    return REQ_WRITE;
-  case EVT_LOST:
-    return REQ_LOST;
-  case EVT_ACCEPT:
-    return REQ_ACCEPT;
-  case EVT_CONNECT:
-    return REQ_CONNECT;
+  case GSOCK_INPUT:
+    return GSOCK_INPUT_FLAG;
+  case GSOCK_OUTPUT:
+    return GSOCK_OUTPUT_FLAG;
+  case GSOCK_CONNECTION:
+    return GSOCK_CONNECTION_FLAG;
+  case GSOCK_LOST_FLAG:
+    return GSOCK_LOST_FLAG;
+  default:
+    return 0;
   }
   return 0;
 }
   }
   return 0;
 }
@@ -637,10 +612,6 @@ wxSocketBase::wxRequestNotify wxSocketBase::EventToNotify(wxRequestEvent evt)
 void wxSocketBase::SetFlags(wxSockFlags _flags)
 {
   m_flags = _flags;
 void wxSocketBase::SetFlags(wxSockFlags _flags)
 {
   m_flags = _flags;
-  if (_flags & SPEED) {
-    // SPEED and WAITALL are antagonists.
-    m_flags = (wxSockFlags)(m_flags & ~WAITALL);
-  }
 }
 
 wxSocketBase::wxSockFlags wxSocketBase::GetFlags() const
 }
 
 wxSocketBase::wxSockFlags wxSocketBase::GetFlags() const
@@ -648,69 +619,66 @@ wxSocketBase::wxSockFlags wxSocketBase::GetFlags() const
   return m_flags;
 }
 
   return m_flags;
 }
 
-void wxSocketBase::SetNotify(wxRequestNotify flags)
+void wxSocketBase::SetNotify(GSocketEventFlags flags)
 {
   /* Check if server */
   if (m_type != SOCK_SERVER)
 {
   /* Check if server */
   if (m_type != SOCK_SERVER)
-    flags &= ~REQ_ACCEPT;
+    flags &= ~GSOCK_CONNECTION_FLAG;
 
 
-  m_internal->AcquireData();
   m_neededreq = flags;
   m_neededreq = flags;
-  m_internal->ReleaseData();
   if (m_neededreq == 0)
   if (m_neededreq == 0)
-    m_internal->StopWaiter();
+    Notify(FALSE);
   else
     Notify(m_notify_state);
 }
 
   else
     Notify(m_notify_state);
 }
 
+// --------------------------------------------------------------
+// Automatic notifier
+// --------------------------------------------------------------
+
+static void wx_socket_fallback(GSocket *socket, GSocketEvent event, char *cdata)
+{
+  wxSocketBase *sckobj = (wxSocketBase *)cdata;
+
+  sckobj->OnRequest(event);
+}
+
 void wxSocketBase::Notify(bool notify)
 {
   m_notify_state = notify;
 void wxSocketBase::Notify(bool notify)
 {
   m_notify_state = notify;
-  if (m_fd == INVALID_SOCKET)
+  if (!m_socket)
     return;
 
     return;
 
-  if (notify)
-    m_internal->ResumeWaiter();
-  else
-    m_internal->StopWaiter();
+  GSocket_UnsetFallback(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);
 }
 
 }
 
-void wxSocketBase::OnRequest(wxRequestEvent req_evt)
+void wxSocketBase::OnRequest(GSocketEvent req_evt)
 {
   wxSocketEvent event(m_id);
 {
   wxSocketEvent event(m_id);
-  wxRequestNotify notify = EventToNotify(req_evt);
+  GSocketEventFlags notify = EventToNotify(req_evt);
+
+  if (m_defering != NO_DEFER) {
+    DoDefer(req_evt);
+    return;
+  }
 
   if ((m_neededreq & notify) == notify) {
     event.m_socket = this;
     event.m_skevt = req_evt;
     ProcessEvent(event);
 
   if ((m_neededreq & notify) == notify) {
     event.m_socket = this;
     event.m_skevt = req_evt;
     ProcessEvent(event);
-    // TODOTODO
-    // OldOnNotify(req_evt);
-
-    // We disable the event reporting.
-    m_neededreq &= ~notify;
+    OldOnNotify(req_evt);
   }
   }
-}
-
-wxSocketEvent::wxSocketEvent(int id)
-  : wxEvent(id)
-{
-  wxEventType type = (wxEventType)wxEVT_SOCKET;
-
-  SetEventType(type);
-}
-
-void wxSocketEvent::CopyObject(wxObject& obj_d) const
-{
-  wxSocketEvent *event = (wxSocketEvent *)&obj_d;
-
-  wxEvent::CopyObject(obj_d);
 
 
-  event->m_skevt = m_skevt;
-  event->m_socket = m_socket;
+  if (req_evt == GSOCK_LOST)
+    Close();
 }
 
 }
 
-void wxSocketBase::OldOnNotify(wxRequestEvent evt)
+void wxSocketBase::OldOnNotify(GSocketEvent evt)
 {
 }
 
 {
 }
 
@@ -736,6 +704,7 @@ void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size)
     m_unread = (char *) realloc(m_unread, m_unrd_size+size);
   else
     m_unread = (char *) malloc(size);
     m_unread = (char *) realloc(m_unread, m_unrd_size+size);
   else
     m_unread = (char *) malloc(size);
+
   curr_pos = m_unread + m_unrd_size;
 
   memcpy(curr_pos, buffer, size);
   curr_pos = m_unread + m_unrd_size;
 
   memcpy(curr_pos, buffer, size);
@@ -744,18 +713,21 @@ void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size)
 
 void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size)
 {
 
 void wxSocketBase::CreatePushbackBefore(const char *buffer, size_t size)
 {
-  char *curr_pos, *new_buf;
-
-  new_buf = (char *) malloc(m_unrd_size+size);
-  curr_pos = new_buf + size;
+  if (m_unread == NULL)
+    m_unread = (char *)malloc(size);
+  else {
+    char *tmp;
 
 
-  memcpy(new_buf, buffer, size);
-  if (m_unrd_size != 0) {
-    memcpy(curr_pos, m_unread, m_unrd_size);
+    tmp = (char *)malloc(m_unrd_size + size);
+    memcpy(tmp+size, m_unread, m_unrd_size);
     free(m_unread);
     free(m_unread);
+
+    m_unread = tmp;
   }
   }
-  m_unread = new_buf;
+  
   m_unrd_size += size;
   m_unrd_size += size;
+
+  memcpy(m_unread, buffer, size);
 }
 
 size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek)
 }
 
 size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek)
@@ -763,63 +735,23 @@ size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek)
   if (!m_unrd_size)
     return 0;
 
   if (!m_unrd_size)
     return 0;
 
-  if (size > m_unrd_size)
-    size = m_unrd_size;
-  memcpy(buffer, m_unread, size);
+  if (size > (m_unrd_size-m_unrd_cur))
+    size = m_unrd_size-m_unrd_cur;
+  memcpy(buffer, (m_unread+m_unrd_cur), size);
 
   if (!peek) {
 
   if (!peek) {
-    m_unrd_size -= size;
-    if (m_unrd_size == 0) {
+    m_unrd_cur += size;
+    if (m_unrd_size == m_unrd_cur) {
       free(m_unread);
       m_unread = NULL;
       free(m_unread);
       m_unread = NULL;
+      m_unrd_size = 0;
+      m_unrd_cur  = 0;
     }
   }
 
   return size;
 }
 
     }
   }
 
   return size;
 }
 
-// --------------------------------------------------------------
-// --------- wxSocketBase buffer core requester -----------------
-// --------------------------------------------------------------
-
-void wxSocketBase::WantBuffer(char *buffer, size_t nbytes,
-            wxRequestEvent evt)
-{
-  bool buf_timed_out;
-
-  if (m_fd == INVALID_SOCKET || !m_handler || !m_connected)
-    return;
-
-  SockRequest *buf = new SockRequest;
-
-  SaveState();
-  buf->buffer = buffer;
-  buf->size = nbytes;
-  buf->done = FALSE;
-  buf->type = EventToNotify(evt);
-  buf->io_nbytes = 0;
-  buf->error = 0;
-  buf->wait = TRUE;
-  buf->timeout = 1000;
-  buf_timed_out = FALSE;
-
-  if ((m_flags & SPEED) != 0) 
-    m_internal->QueueRequest(buf, FALSE);
-  else
-    if ((m_flags & NOWAIT) != 0) 
-      m_internal->QueueRequest(buf, TRUE);
-    else 
-      m_internal->QueueRequest(buf, TRUE);
-  m_lcount += buf->io_nbytes;
-  if (buf_timed_out)
-    m_error = ETIMEDOUT;
-  else
-    m_error = buf->error;
-
-  delete buf;
-  RestoreState();
-}
-
 // --------------------------------------------------------------
 // wxSocketServer
 // --------------------------------------------------------------
 // --------------------------------------------------------------
 // wxSocketServer
 // --------------------------------------------------------------
@@ -828,28 +760,18 @@ wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
              wxSockFlags flags) :
   wxSocketBase(flags, SOCK_SERVER)
 {
              wxSockFlags flags) :
   wxSocketBase(flags, SOCK_SERVER)
 {
-  m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
+  m_socket = GSocket_new();
 
 
-  if (m_fd == INVALID_SOCKET)
+  if (!m_socket)
     return;
 
     return;
 
-  int flag = 1;
-  setsockopt(m_fd, SOL_SOCKET, SO_REUSEADDR, (char*)&flag, sizeof(int));
-
-  struct sockaddr *myaddr;
-  size_t len;
-
-  addr_man.Build(myaddr, len);
-  if (bind(m_fd, myaddr, addr_man.SockAddrLen()) < 0)
-    return;
-
-  if (listen(m_fd, 5) < 0) {
-    m_fd = INVALID_SOCKET;
+  GSocket_SetLocal(m_socket, addr_man.GetAddress());
+  if (GSocket_SetServer(m_socket) != GSOCK_NOERROR) {
+    GSocket_destroy(m_socket);
+    m_socket = NULL;
     return;
   }
 
     return;
   }
 
-  m_internal->SetFD(m_fd);
-
   Notify(TRUE);
 }
 
   Notify(TRUE);
 }
 
@@ -859,32 +781,14 @@ wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
 
 bool wxSocketServer::AcceptWith(wxSocketBase& sock)
 {
 
 bool wxSocketServer::AcceptWith(wxSocketBase& sock)
 {
-  int fd2;
-
-  m_internal->AcquireFD();
-  if ((fd2 = accept(m_fd, 0, 0)) < 0) {
-    m_internal->ReleaseFD();
-    return FALSE;
-  }
-  m_internal->ReleaseFD();
+  GSocket *child_socket;
 
 
-  struct linger linger;
-  linger.l_onoff = 0;
-  linger.l_linger = 1;
-
-  setsockopt(fd2, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));
-
-  int flag = 0;
-  setsockopt(fd2, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int));
+  child_socket = GSocket_WaitConnection(m_socket);
 
   sock.m_type = SOCK_INTERNAL;
 
   sock.m_type = SOCK_INTERNAL;
-  sock.m_fd = fd2;
+  sock.m_socket = child_socket;
   sock.m_connected = TRUE;
 
   sock.m_connected = TRUE;
 
-  sock.m_internal->SetFD(fd2);
-
-  sock.m_internal->ResumeWaiter();
-
   return TRUE;
 }
 
   return TRUE;
 }
 
@@ -897,9 +801,6 @@ wxSocketBase *wxSocketServer::Accept()
   if (!AcceptWith(*sock))
     return NULL;
 
   if (!AcceptWith(*sock))
     return NULL;
 
-  if (m_handler)
-    m_handler->Register(sock);
-
   return sock;
 }
 
   return sock;
 }
 
@@ -926,46 +827,28 @@ wxSocketClient::~wxSocketClient()
 // --------------------------------------------------------------
 bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) )
 {
 // --------------------------------------------------------------
 bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) )
 {
-  struct linger linger;
-
   if (IsConnected())
     Close();
 
   if (IsConnected())
     Close();
 
+  // This should never happen.
+  if (m_socket)
+    GSocket_destroy(m_socket);
+
   // Initializes all socket stuff ...
   // --------------------------------
   // Initializes all socket stuff ...
   // --------------------------------
-  m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
+  m_socket = GSocket_new();
 
 
-  if (m_fd < 0)
+  if (!m_socket)
     return FALSE;
 
   m_connected = FALSE;
 
     return FALSE;
 
   m_connected = FALSE;
 
-  linger.l_onoff = 1;
-  linger.l_linger = 5;
-  setsockopt(m_fd, SOL_SOCKET, SO_LINGER, (char*)&linger, sizeof(linger));
-
-  // Stay in touch with the state of things...
-
-  unsigned long flag = 1;
-  setsockopt(m_fd, SOL_SOCKET, SO_KEEPALIVE, (char*)&flag, sizeof(int));
-
-  // Disable the nagle algorithm, which delays sends till the
-  // buffer is full (or a certain time period has passed?)...
-
-#if defined(__WINDOWS__) || (defined(IPPROTO_TCP) && defined(TCP_NODELAY))
-  flag = 1;
-  setsockopt(m_fd, IPPROTO_TCP, TCP_NODELAY, (char*)&flag, sizeof(int));
-#endif
-
-  struct sockaddr *remote;
-  size_t len;
-
-  addr_man.Build(remote, len);
-
-  if (connect(m_fd, remote, len) != 0)
+  // Update the flags of m_socket.
+  SetFlags(m_flags);
+  GSocket_SetPeer(m_socket, addr_man.GetAddress());
+  if (GSocket_Connect(m_socket, GSOCK_STREAMED) != GSOCK_NOERROR) {
     return FALSE;
     return FALSE;
-
-  m_internal->SetFD(m_fd);
+  }
 
   // Enables bg events.
   // ------------------
 
   // Enables bg events.
   // ------------------
@@ -977,7 +860,7 @@ bool wxSocketClient::Connect(wxSockAddress& addr_man, bool WXUNUSED(wait) )
 
 bool wxSocketClient::WaitOnConnect(long seconds, long microseconds)
 {
 
 bool wxSocketClient::WaitOnConnect(long seconds, long microseconds)
 {
-  int ret = _Wait(seconds, microseconds, REQ_CONNECT | REQ_LOST);
+  int ret = _Wait(seconds, microseconds, GSOCK_CONNECTION_FLAG | GSOCK_LOST_FLAG);
 
   if (ret)
     m_connected = TRUE;
 
   if (ret)
     m_connected = TRUE;
@@ -985,13 +868,13 @@ bool wxSocketClient::WaitOnConnect(long seconds, long microseconds)
   return m_connected;
 }
 
   return m_connected;
 }
 
-void wxSocketClient::OnRequest(wxRequestEvent evt)
+void wxSocketClient::OnRequest(GSocketEvent evt)
 {
 {
-  if (evt == EVT_CONNECT
+  if (evt == GSOCK_CONNECTION
   {
     if (m_connected) 
     {
   {
     if (m_connected) 
     {
-      m_neededreq &= ~REQ_CONNECT;
+      m_neededreq &= ~GSOCK_CONNECTION_FLAG;
       return;
     }
     m_connected = TRUE;
       return;
     }
     m_connected = TRUE;
@@ -1000,198 +883,27 @@ void wxSocketClient::OnRequest(wxRequestEvent evt)
   wxSocketBase::OnRequest(evt);
 }
 
   wxSocketBase::OnRequest(evt);
 }
 
-/////////////////////////////////////////////////////////////////
-// wxSocketHandler ///////////////////////////////////////////////
-/////////////////////////////////////////////////////////////////
-
-wxSocketHandler *wxSocketHandler::master = NULL;
-#if defined(__WINDOWS__)
-static int win_initialized = 0;
-#endif
-
-// --------------------------------------------------------------
-// --------- wxSocketHandler CONSTRUCTOR ------------------------
-// --------------------------------------------------------------
-wxSocketHandler::wxSocketHandler()
-{
-#if defined(__WINDOWS__)
-  if (!win_initialized) 
-  {
-    WSADATA wsaData;
-
-    WSAStartup((1 << 8) | 1, &wsaData);
-    win_initialized = 1;
-  }
-#endif
-
-  socks = new wxList;
-
-#ifndef __WINDOWS__
-  signal(SIGPIPE, SIG_IGN);
-#endif
-}
-
 // --------------------------------------------------------------
 // --------------------------------------------------------------
-// --------- wxSocketHandler DESTRUCTOR -------------------------
+// wxSocketEvent
 // --------------------------------------------------------------
 // --------------------------------------------------------------
-wxSocketHandler::~wxSocketHandler()
-{
-  wxNode *next_node, *node = socks->First();
 
 
-  while (node) 
-  {
-    wxSocketBase* sock = (wxSocketBase*)node->Data();
-
-    delete sock;
-    next_node = node->Next();
-    delete node;
-    node = next_node;
-  }
-
-  delete socks;
-
-#ifdef __WINDOWS__
-  WSACleanup();
-  win_initialized = 0;
-#endif
-}
-
-// --------------------------------------------------------------
-// --------- wxSocketHandler registering functions --------------
-// --------------------------------------------------------------
-
-void wxSocketHandler::Register(wxSocketBase* sock)
-{
-  wxNode *node;
-
-  for (node = socks->First(); node != NULL; node = node->Next()) 
-  {
-    wxSocketBase* s = (wxSocketBase*)node->Data();
-
-    if (s == sock)
-      return;
-  }
-
-  if (sock) 
-  {
-    socks->Append(sock);
-    sock->SetHandler(this);
-  }
-}
-
-void wxSocketHandler::UnRegister(wxSocketBase* sock)
-{
-  wxNode *node;
-
-  for (node = socks->First(); node; node = node->Next()) 
-  {
-    wxSocketBase* s = (wxSocketBase*)node->Data();
-
-    if (s == sock) 
-    {
-      delete node;
-      sock->SetHandler(NULL);
-      return;
-    }
-  }
-}
-
-unsigned long wxSocketHandler::Count() const
-{
-  return socks->Number();
-}
-
-// --------------------------------------------------------------
-// --------- wxSocketHandler "big" wait functions ---------------
-// --------------------------------------------------------------
-
-int wxSocketHandler::Wait(long seconds, long microseconds)
-{
-  // TODO Needs the completely asynchronous notifier.
-
-  /*
-  int i;
-  int on_wait;
-  wxNode *node;
-  for (node = socks->First(), i=0; node; node = node->Next(), i++) 
-  {
-    wxSocketBase *sock = (wxSocketBase *)node->Data();
-
-    sock->SaveState();
-
-    sock->SetupCallbacks();
-
-    sock->Callback(handler_cbk);
-    sock->CallbackData((char *)&on_wait);
-  }
-  on_wait = 0;
-  if (seconds != -1)
-    s_wake.Start((seconds*1000) + (microseconds/1000), TRUE);
-
-  while (!on_wait)
-    PROCESS_EVENTS();
-
-  for (node = socks->First(), i=0; node; node = node->Next(), i++) 
-  {
-    wxSocketBase *sock = (wxSocketBase *)node->Data();
-
-    sock->RestoreState();
-  }
-
-  if (on_wait == -2)
-    return 0;
-
-  return on_wait;
-  */
-  return 0;
-}
-
-void wxSocketHandler::YieldSock()
-{
-  wxNode *node;
-
-  // Nothing to do anymore here except waiting for the queue emptying.
-  for (node = socks->First(); node; node=node->Next()) {
-    wxSocketBase *sock = (wxSocketBase *)node->Data();
-
-    sock->m_internal->WaitForEnd(NULL);
-  }
-}
-
-// --------------------------------------------------------------
-// --------- wxSocketHandler: create and register the socket ----
-// --------------------------------------------------------------
-wxSocketServer *wxSocketHandler::CreateServer(wxSockAddress& addr,
-                wxSocketBase::wxSockFlags flags)
+wxSocketEvent::wxSocketEvent(int id)
+  : wxEvent(id)
 {
 {
-  wxSocketServer *serv = new wxSocketServer(addr, flags);
+  wxEventType type = (wxEventType)wxEVT_SOCKET;
 
 
-  Register(serv);
-  return serv;
+  SetEventType(type);
 }
 
 }
 
-wxSocketClient *wxSocketHandler::CreateClient(wxSocketBase::wxSockFlags flags)
+void wxSocketEvent::CopyObject(wxObject& obj_d) const
 {
 {
-  wxSocketClient *client = new wxSocketClient(flags);
-
-  Register(client);
-  return client;
-}
+  wxSocketEvent *event = (wxSocketEvent *)&obj_d;
 
 
-bool wxSocketModule::OnInit() 
-{
-  wxSocketHandler::master = new wxSocketHandler();
-  return TRUE;
-}
+  wxEvent::CopyObject(obj_d);
 
 
-void wxSocketModule::OnExit() 
-{
-  delete wxSocketHandler::master;
-  wxSocketHandler::master = NULL;
+  event->m_skevt = m_skevt;
+  event->m_socket = m_socket;
 }
 
 }
 
-#endif
-  // __WXSTUBS__
-
 #endif
   // wxUSE_SOCKETS
 #endif
   // wxUSE_SOCKETS
index 9b83250f1c1886bd6c44f35f573c0c8b77904e84..61de20d228ea59d3bf87c71c3d35f4f49fbb3fd9 100644 (file)
@@ -480,6 +480,9 @@ size_t wxInputStream::GetWBack(char *buf, size_t bsize)
 {
   size_t s_toget = m_wbacksize-m_wbackcur;
 
 {
   size_t s_toget = m_wbacksize-m_wbackcur;
 
+  if (!m_wback)
+    return 0;
+
   if (bsize < s_toget)
     s_toget = bsize;
 
   if (bsize < s_toget)
     s_toget = bsize;
 
@@ -697,8 +700,8 @@ wxInputStream& wxBufferedInputStream::Read(void *buffer, size_t size)
   char *buf = (char *)buffer;
 
   retsize = GetWBack(buf, size);
   char *buf = (char *)buffer;
 
   retsize = GetWBack(buf, size);
+  m_lastcount = retsize;
   if (retsize == size) {
   if (retsize == size) {
-    m_lastcount = size;
     m_lasterror = wxStream_NOERROR;
     return *this;
   }
     m_lasterror = wxStream_NOERROR;
     return *this;
   }
@@ -753,6 +756,7 @@ wxBufferedOutputStream::~wxBufferedOutputStream()
 
 wxOutputStream& wxBufferedOutputStream::Write(const void *buffer, size_t size)
 {
 
 wxOutputStream& wxBufferedOutputStream::Write(const void *buffer, size_t size)
 {
+  m_lastcount = 0;
   m_o_streambuf->Write(buffer, size);
   return *this;
 }
   m_o_streambuf->Write(buffer, size);
   return *this;
 }
index ccaa6e3bfa3b41a1d608b40dfd7c4f05acb27cfc..d45fbb75057acaa8b29ec98c4378234a1fc404e1 100644 (file)
@@ -148,7 +148,7 @@ wxTextCtrl& wxTextCtrlBase::operator<<(long i)
     return *TEXTCTRL(this);
 }
 
     return *TEXTCTRL(this);
 }
 
-wxTextCtrl& wxTextCtrlBase::operator<<(const char c)
+wxTextCtrl& wxTextCtrlBase::operator<<(const wxChar c)
 {
     return operator<<(wxString(c));
 }
 {
     return operator<<(wxString(c));
 }
index 3c8aebe2dc8cda5b303362112c888c0d84bd72e6..06d802074922a130fa118246b3cb81b2e2b35d1f 100644 (file)
@@ -208,7 +208,6 @@ bool wxURL::FetchProtocol()
 
       m_protoinfo = info;
       m_protocol = (wxProtocol *)m_protoinfo->m_cinfo->CreateObject();
 
       m_protoinfo = info;
       m_protocol = (wxProtocol *)m_protoinfo->m_cinfo->CreateObject();
-      wxSocketHandler::Master().Register(m_protocol);
       return TRUE;
     }
     info = info->next;
       return TRUE;
     }
     info = info->next;
@@ -323,7 +322,7 @@ wxString wxURL::ConvertToValidURI(const wxString& uri)
 
     if (!isalpha(c) && c != _T('.') && c != _T('+') && c != _T('.') && 
                        c != _T('/')) {
 
     if (!isalpha(c) && c != _T('.') && c != _T('+') && c != _T('.') && 
                        c != _T('/')) {
-      hexa_code.Printf(_T("%02X"), c);
+      hexa_code.Printf(_T("%%%02X"), c);
       out_str += hexa_code;
     } else
       out_str += c;
       out_str += hexa_code;
     } else
       out_str += c;
index 599c2f2fad493e41c3291d6f4b14d2d08a305554..50c662d35ceeb33dd33ac5ac4b31e4f244042f2a 100644 (file)
@@ -138,7 +138,10 @@ wxFileOutputStream::~wxFileOutputStream()
 size_t wxFileOutputStream::OnSysWrite(const void *buffer, size_t size)
 {
   size_t ret = m_file->Write(buffer, size);
 size_t wxFileOutputStream::OnSysWrite(const void *buffer, size_t size)
 {
   size_t ret = m_file->Write(buffer, size);
-  m_lasterror = wxStream_EOF; // TODO
+  if (m_file->Error())
+    m_lasterror = wxStream_WRITE_ERR;
+  else
+    m_lasterror = wxStream_NOERROR;
   return ret;
 }
 
   return ret;
 }
 
index 83384cee93de67f89b87166ff3419df972d1ee92..616dce4f610fc4422aea8f9c4c2ad8b94556b8ab 100644 (file)
@@ -29,6 +29,8 @@ libwx_gtk_la_SOURCES = \
  win_gtk.c \
  extended.c \
  parser.c \
  win_gtk.c \
  extended.c \
  parser.c \
+ gsocket.c \
+ gsockgtk.c \
 \
  cmndata.cpp \
  config.cpp \
 \
  cmndata.cpp \
  config.cpp \
@@ -80,7 +82,6 @@ libwx_gtk_la_SOURCES = \
  resource.cpp \
  sckaddr.cpp \
  sckfile.cpp \
  resource.cpp \
  sckaddr.cpp \
  sckfile.cpp \
- sckint.cpp \
  sckipc.cpp \
  sckstrm.cpp \
  serbase.cpp \
  sckipc.cpp \
  sckstrm.cpp \
  serbase.cpp \
diff --git a/src/gtk/gsockgtk.c b/src/gtk/gsockgtk.c
new file mode 100644 (file)
index 0000000..85816cb
--- /dev/null
@@ -0,0 +1,100 @@
+#include <stdlib.h>
+#include <gdk/gdk.h>
+#include <glib.h>
+#include <wx/gsocket.h>
+#include "../unix/gsockunx.h"
+
+void _GSocket_GDK_Input(gpointer data, gint source, GdkInputCondition condition)
+{
+  GSocket *socket = (GSocket *)data;
+
+  switch (condition) {
+  case GDK_INPUT_READ:
+    _GSocket_Detected_Read(socket);
+    break;
+  case GDK_INPUT_WRITE:
+    _GSocket_Detected_Write(socket);
+    break;
+  default:
+    break;
+  } 
+}
+
+void _GSocket_GUI_Init(GSocket *socket)
+{
+  int i;
+  gint *m_id;
+
+  socket->m_gui_dependent = (char *)malloc(sizeof(gint)*3);
+  m_id = (gint *)(socket->m_gui_dependent);
+
+  for (i=0;i<3;i++)
+    m_id[i] = -1;
+}
+
+void _GSocket_GUI_Destroy(GSocket *socket)
+{
+  int i;
+  gint *m_id;
+
+  m_id = (gint *)(socket->m_gui_dependent);
+
+  for (i=0;i<3;i++)
+    if (m_id[i] == -1)
+      gdk_input_remove(m_id[i]);
+
+  free(socket->m_gui_dependent);
+}
+
+void _GSocket_Install_Fallback(GSocket *socket, GSocketEvent event)
+{
+  GdkInputCondition flag;
+  int c;
+  gint *m_id;
+
+  m_id = (gint *)(socket->m_gui_dependent);
+
+  switch (event) {
+  case GSOCK_CONNECTION:
+  case GSOCK_LOST:
+  case GSOCK_INPUT: c = 0; flag = GDK_INPUT_READ; break;
+  case GSOCK_OUTPUT: c = 1;flag = GDK_INPUT_WRITE; break;
+  default: return;
+  }
+
+  if (m_id[c] != -1)
+    gdk_input_remove(m_id[c]);
+
+  m_id[c] = gdk_input_add(socket->m_fd, flag, 
+                          _GSocket_GDK_Input, (gpointer)socket);
+}
+
+void _GSocket_Uninstall_Fallback(GSocket *socket, GSocketEvent event)
+{
+  int c;
+  gint *m_id;
+
+  m_id = (gint *)(socket->m_gui_dependent);
+
+  switch (event) {
+  case GSOCK_CONNECTION: 
+  case GSOCK_LOST:
+  case GSOCK_INPUT: c = 0; break;
+  case GSOCK_OUTPUT: c = 1; break;
+  default: return;
+  }
+
+  if (m_id[c] != -1)
+    gdk_input_remove(m_id[c]);
+
+  m_id[c] = -1;
+}
+
+unsigned long GSocket_GetEventID(GSocket *socket)
+{
+  return 0;
+}
+
+void GSocket_DoEvent(unsigned long evt_id)
+{
+}
index 83384cee93de67f89b87166ff3419df972d1ee92..616dce4f610fc4422aea8f9c4c2ad8b94556b8ab 100644 (file)
@@ -29,6 +29,8 @@ libwx_gtk_la_SOURCES = \
  win_gtk.c \
  extended.c \
  parser.c \
  win_gtk.c \
  extended.c \
  parser.c \
+ gsocket.c \
+ gsockgtk.c \
 \
  cmndata.cpp \
  config.cpp \
 \
  cmndata.cpp \
  config.cpp \
@@ -80,7 +82,6 @@ libwx_gtk_la_SOURCES = \
  resource.cpp \
  sckaddr.cpp \
  sckfile.cpp \
  resource.cpp \
  sckaddr.cpp \
  sckfile.cpp \
- sckint.cpp \
  sckipc.cpp \
  sckstrm.cpp \
  serbase.cpp \
  sckipc.cpp \
  sckstrm.cpp \
  serbase.cpp \
diff --git a/src/gtk1/gsockgtk.c b/src/gtk1/gsockgtk.c
new file mode 100644 (file)
index 0000000..85816cb
--- /dev/null
@@ -0,0 +1,100 @@
+#include <stdlib.h>
+#include <gdk/gdk.h>
+#include <glib.h>
+#include <wx/gsocket.h>
+#include "../unix/gsockunx.h"
+
+void _GSocket_GDK_Input(gpointer data, gint source, GdkInputCondition condition)
+{
+  GSocket *socket = (GSocket *)data;
+
+  switch (condition) {
+  case GDK_INPUT_READ:
+    _GSocket_Detected_Read(socket);
+    break;
+  case GDK_INPUT_WRITE:
+    _GSocket_Detected_Write(socket);
+    break;
+  default:
+    break;
+  } 
+}
+
+void _GSocket_GUI_Init(GSocket *socket)
+{
+  int i;
+  gint *m_id;
+
+  socket->m_gui_dependent = (char *)malloc(sizeof(gint)*3);
+  m_id = (gint *)(socket->m_gui_dependent);
+
+  for (i=0;i<3;i++)
+    m_id[i] = -1;
+}
+
+void _GSocket_GUI_Destroy(GSocket *socket)
+{
+  int i;
+  gint *m_id;
+
+  m_id = (gint *)(socket->m_gui_dependent);
+
+  for (i=0;i<3;i++)
+    if (m_id[i] == -1)
+      gdk_input_remove(m_id[i]);
+
+  free(socket->m_gui_dependent);
+}
+
+void _GSocket_Install_Fallback(GSocket *socket, GSocketEvent event)
+{
+  GdkInputCondition flag;
+  int c;
+  gint *m_id;
+
+  m_id = (gint *)(socket->m_gui_dependent);
+
+  switch (event) {
+  case GSOCK_CONNECTION:
+  case GSOCK_LOST:
+  case GSOCK_INPUT: c = 0; flag = GDK_INPUT_READ; break;
+  case GSOCK_OUTPUT: c = 1;flag = GDK_INPUT_WRITE; break;
+  default: return;
+  }
+
+  if (m_id[c] != -1)
+    gdk_input_remove(m_id[c]);
+
+  m_id[c] = gdk_input_add(socket->m_fd, flag, 
+                          _GSocket_GDK_Input, (gpointer)socket);
+}
+
+void _GSocket_Uninstall_Fallback(GSocket *socket, GSocketEvent event)
+{
+  int c;
+  gint *m_id;
+
+  m_id = (gint *)(socket->m_gui_dependent);
+
+  switch (event) {
+  case GSOCK_CONNECTION: 
+  case GSOCK_LOST:
+  case GSOCK_INPUT: c = 0; break;
+  case GSOCK_OUTPUT: c = 1; break;
+  default: return;
+  }
+
+  if (m_id[c] != -1)
+    gdk_input_remove(m_id[c]);
+
+  m_id[c] = -1;
+}
+
+unsigned long GSocket_GetEventID(GSocket *socket)
+{
+  return 0;
+}
+
+void GSocket_DoEvent(unsigned long evt_id)
+{
+}
diff --git a/src/unix/gsocket.c b/src/unix/gsocket.c
new file mode 100644 (file)
index 0000000..7456ccf
--- /dev/null
@@ -0,0 +1,940 @@
+/* -------------------------------------------------------------------------
+ * Project: GSocket (Generic Socket) for WX
+ * Name:    gsocket.c
+ * Purpose: GSocket main Unix file
+ * CVSID:   $Id$
+ * Log:     $Log$
+ * Log:     Revision 1.1  1999/07/22 17:51:54  GL
+ * Log:     Added GSocket for Unix (only GTK for the moment)
+ * Log:     Updated wxSocket to use GSocket API
+ * Log:     Added a progress bar to client.cpp
+ * Log:     Added CopyTo to wxMemoryOutputStream to copy the internal buffer to a specified buffer.
+ * Log:     Various changes/fixes to the high-level protocols FTP/HTTP
+ * Log:     Various Unicode fixes
+ * Log:     Removed sckint.*
+ * Log:
+ * Log:     Revision 1.2  1999/07/18 15:52:34  guilhem
+ * Log:     * Copyright, etc.
+ * Log:
+ * -------------------------------------------------------------------------
+ */
+
+#include <assert.h>
+#include <sys/ioctl.h>
+#ifdef vms
+#include <socket.h>
+#else
+#include <sys/socket.h>
+#endif
+#include <sys/un.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+
+#include <string.h>
+#include <unistd.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef sun
+#include <sys/filio.h>
+#endif
+
+#ifdef sgi
+  #include <bstring.h>
+#endif
+
+#include <signal.h>
+
+#include <wx/gsocket.h>
+#include "gsockunx.h"
+
+/* Constructors / Destructors */
+
+GSocket *GSocket_new()
+{
+  int i;
+  GSocket *socket;
+
+  socket = (GSocket *)malloc(sizeof(GSocket));
+
+  socket->m_fd                  = -1;
+  for (i=0;i<GSOCK_MAX_EVENT;i++) {
+    socket->m_fbacks[i]         = NULL;
+    socket->m_iocalls[i]        = FALSE;
+  }
+  socket->m_local               = NULL;
+  socket->m_peer                = NULL;
+  socket->m_error               = GSOCK_NOERROR;
+  socket->m_server             = FALSE;
+  socket->m_stream             = TRUE;
+  socket->m_gui_dependent      = NULL;
+  socket->m_blocking           = FALSE;
+
+  _GSocket_GUI_Init(socket);
+
+  return socket;
+}
+
+void GSocket_destroy(GSocket *socket)
+{
+  assert(socket != NULL);
+
+  _GSocket_GUI_Destroy(socket);
+
+  if (socket->m_fd != -1)
+    GSocket_Shutdown(socket);
+
+  if (socket->m_local)
+    GAddress_destroy(socket->m_local);
+
+  if (socket->m_peer)
+    GAddress_destroy(socket->m_peer);
+
+  free(socket);
+}
+
+void GSocket_Shutdown(GSocket *socket)
+{
+  int evt;
+
+  assert(socket != NULL);
+
+  if (socket->m_fd != -1) {
+    shutdown(socket->m_fd, 2);
+    close(socket->m_fd);
+    socket->m_fd = -1;
+  }
+
+  for (evt=0;evt<GSOCK_MAX_EVENT;evt++)
+    _GSocket_Uninstall_Fallback(socket, evt);
+}
+
+/* Address handling */
+
+GSocketError GSocket_SetLocal(GSocket *socket, GAddress *address)
+{
+  if (socket == NULL || (socket->m_fd != -1 && !socket->m_server))
+    return GSOCK_INVSOCK;
+
+  if (address == NULL || address->m_family == GSOCK_NOFAMILY)
+    return GSOCK_INVADDR;
+
+  if (socket->m_local)
+    GAddress_destroy(socket->m_local);
+
+  socket->m_local = GAddress_copy(address);
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GSocket_SetPeer(GSocket *socket, GAddress *address)
+{
+  if (socket == NULL)
+    return GSOCK_INVSOCK;
+
+  if (address == NULL || address->m_family == GSOCK_NOFAMILY) {
+    socket->m_error = GSOCK_INVADDR;
+    return GSOCK_INVADDR;
+  }
+
+  if (socket->m_peer)
+    GAddress_destroy(socket->m_peer);
+
+  socket->m_peer = GAddress_copy(address);
+
+  return GSOCK_NOERROR;
+}
+
+GAddress *GSocket_GetLocal(GSocket *socket)
+{
+  GAddress *address;
+  struct sockaddr addr;
+  socklen_t size;
+
+  assert(socket != NULL);
+
+  if (socket->m_local)
+    return GAddress_copy(socket->m_local);
+
+  if (socket->m_fd == -1) {
+    socket->m_error = GSOCK_INVSOCK;
+    return NULL;
+  }
+
+  size = sizeof(addr);
+
+  if (getsockname(socket->m_fd, &addr, &size) < 0) {
+    socket->m_error = GSOCK_IOERR;
+    return NULL;
+  }
+
+  address = GAddress_new();
+  _GAddress_translate_from(address, &addr, size);
+
+  return address;
+}
+
+GAddress *GSocket_GetPeer(GSocket *socket)
+{
+  assert(socket != NULL);
+
+  if (socket->m_peer)
+    return GAddress_copy(socket->m_peer);
+
+  return NULL;
+}
+
+/* Server specific parts */
+
+/*
+  GSocket_SetServer() setup the socket as a server. It uses the "Local" field
+  of GSocket. "Local" must be set by GSocket_SetLocal() before
+  GSocket_SetServer() is called. GSOCK_INVSOCK if socket has been initialized.
+  In the other cases, it returns GSOCK_INVADDR.
+*/
+GSocketError GSocket_SetServer(GSocket *sck)
+{
+  int type;
+
+  assert(sck != NULL);
+
+  if (sck->m_fd != -1) {
+    sck->m_error = GSOCK_INVSOCK;
+    return GSOCK_INVSOCK;
+  }
+
+  if (!sck->m_local) {
+    sck->m_error = GSOCK_INVADDR;
+    return GSOCK_INVADDR;
+  }
+
+  if (sck->m_stream)
+    type = SOCK_STREAM;
+  else
+    type = SOCK_DGRAM;
+
+  sck->m_fd = socket(sck->m_local->m_realfamily, type, 0);
+
+  if (sck->m_fd == -1) {
+    sck->m_error = GSOCK_IOERR;
+    return GSOCK_IOERR;
+  }
+
+  if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
+    close(sck->m_fd);
+    sck->m_fd = -1;
+    sck->m_error = GSOCK_IOERR;
+    return GSOCK_IOERR;
+  }
+
+  if (listen(sck->m_fd, 5) < 0) {
+    close(sck->m_fd);
+    sck->m_fd = -1;
+    sck->m_error = GSOCK_IOERR;
+    return GSOCK_IOERR;
+  }
+
+  sck->m_server = TRUE;
+
+  return GSOCK_NOERROR;
+     
+}
+
+/*
+  GSocket_WaitConnection() waits for an incoming client connection.
+*/
+GSocket *GSocket_WaitConnection(GSocket *socket)
+{
+  GSocket *connection;
+
+  assert(socket != NULL);
+
+  if (socket->m_fd == -1 || !socket->m_server) {
+    socket->m_error = GSOCK_INVSOCK;
+    return NULL;
+  }
+
+  _GSocket_Enable(socket, GSOCK_CONNECTION);
+
+  connection = GSocket_new();
+
+  connection->m_fd = accept(socket->m_fd, NULL, NULL);
+  if (connection->m_fd == -1) {
+    GSocket_destroy(connection);
+    socket->m_error = GSOCK_IOERR;
+    return NULL;
+  }
+
+  connection->m_stream   = TRUE;
+  connection->m_server   = FALSE;
+  connection->m_oriented = TRUE;
+
+  return connection;
+}
+
+/* Non oriented connections */
+
+GSocketError GSocket_SetNonOriented(GSocket *sck)
+{
+  assert(sck != NULL);
+
+  if (sck->m_fd != -1) {
+    sck->m_error = GSOCK_INVSOCK;
+    return GSOCK_INVSOCK;
+  }
+
+  if (!sck->m_local) {
+    sck->m_error = GSOCK_INVADDR;
+    return GSOCK_INVADDR;
+  }
+
+  sck->m_stream   = FALSE;
+  sck->m_server   = FALSE;
+  sck->m_oriented = FALSE;
+
+  sck->m_fd = socket(sck->m_local->m_realfamily, SOCK_DGRAM, 0);
+
+  if (bind(sck->m_fd, sck->m_local->m_addr, sck->m_local->m_len) < 0) {
+    close(sck->m_fd);
+    sck->m_fd    = -1;
+    sck->m_error = GSOCK_IOERR;
+    return GSOCK_IOERR;
+  }
+
+  return GSOCK_NOERROR;
+}
+
+/* Client specific parts */
+
+/*
+  GSocket_Connect() establishes a client connection to a server using the "Peer"
+  field of GSocket. "Peer" must be set by GSocket_SetPeer() before
+  GSocket_Connect() is called. In the other case, it returns GSOCK_INVADDR.
+*/
+GSocketError GSocket_Connect(GSocket *sck, GSocketStream stream)
+{
+  int type;
+
+  assert(sck != NULL);
+
+  if (sck->m_fd != -1) {
+    sck->m_error = GSOCK_INVSOCK;
+    return GSOCK_INVSOCK;
+  }
+
+  if (!sck->m_peer) {
+    sck->m_error = GSOCK_INVADDR;
+    return GSOCK_INVADDR;
+  }
+
+  sck->m_stream = (stream == GSOCK_STREAMED);
+  sck->m_oriented = TRUE;
+
+  if (sck->m_stream)
+    type = SOCK_STREAM;
+  else
+    type = SOCK_DGRAM;
+
+  sck->m_fd = socket(sck->m_peer->m_realfamily, type, 0);
+
+  if (sck->m_fd == -1) {
+    sck->m_error = GSOCK_IOERR;
+    return GSOCK_IOERR;
+  }
+
+  if (connect(sck->m_fd, sck->m_peer->m_addr,
+              sck->m_peer->m_len) != 0) {
+    close(sck->m_fd);
+    sck->m_fd = -1;
+    sck->m_error = GSOCK_IOERR;
+    return GSOCK_IOERR;
+  }
+  
+  sck->m_server = FALSE;
+
+  return GSOCK_NOERROR;
+}
+
+/* Generic IO */
+
+/* Like recv(), send(), ... */
+int GSocket_Read(GSocket *socket, char *buffer, int size)
+{
+  assert(socket != NULL);
+
+  if (socket->m_fd == -1 || socket->m_server) {
+    socket->m_error = GSOCK_INVSOCK;
+    return -1;
+  }
+
+  _GSocket_Enable(socket, GSOCK_INPUT);
+
+  if (socket->m_oriented)
+    return _GSocket_Recv_Stream(socket, buffer, size);
+  else
+    return _GSocket_Recv_Dgram(socket, buffer, size);
+}
+
+int GSocket_Write(GSocket *socket, const char *buffer,
+                 int size)
+{
+  assert(socket != NULL);
+
+  if (socket->m_fd == -1 || socket->m_server) {
+    socket->m_error = GSOCK_INVSOCK;
+    return -1;
+  }
+
+  _GSocket_Enable(socket, GSOCK_OUTPUT);
+
+  if (socket->m_oriented)
+    return _GSocket_Send_Stream(socket, buffer, size);
+  else
+    return _GSocket_Send_Dgram(socket, buffer, size);
+}
+
+bool GSocket_DataAvailable(GSocket *socket)
+{
+  fd_set read_set;
+  struct timeval tv;
+
+  assert(socket != NULL);
+
+  if (socket->m_fd == -1 || socket->m_server) {
+    socket->m_error = GSOCK_INVSOCK;
+    return FALSE;
+  }
+
+  FD_ZERO(&read_set);
+  FD_SET(socket->m_fd, &read_set);
+
+  tv.tv_sec = 0;
+  tv.tv_usec = 0;
+
+  select(socket->m_fd+1, &read_set, NULL, NULL, &tv);
+
+  return FD_ISSET(socket->m_fd, &read_set);
+}
+
+/* Flags */
+
+/*
+  GSocket_SetBlocking() puts the socket in non-blocking mode. This is useful
+  if we don't want to wait.
+*/
+void GSocket_SetBlocking(GSocket *socket, bool block)
+{
+  assert(socket != NULL);
+
+  socket->m_blocking = block;
+
+  if (socket->m_fd != -1)
+    ioctl(socket->m_fd, FIONBIO, &block);
+}
+
+/*
+  GSocket_GetError() returns the last error occured on the socket stream.
+*/
+
+GSocketError GSocket_GetError(GSocket *socket)
+{
+  assert(socket != NULL);
+
+  return socket->m_error;
+}
+
+/* Callbacks */
+
+/* 
+   Only one fallback is possible for each event (INPUT, OUTPUT, CONNECTION)
+   INPUT: The function is called when there is at least a byte in the 
+          input buffer
+   OUTPUT: The function is called when the system is sure the next write call
+           will not block
+   CONNECTION: Two cases is possible:
+             Client socket -> the connection is established
+            Server socket -> a client request a connection
+   LOST: the connection is lost
+
+   SetFallback accepts a combination of these flags so a same callback can
+   receive different events.
+
+   An event is generated only once and its state is reseted when the relative
+   IO call is requested.
+   For example: INPUT -> GSocket_Read()
+                CONNECTION -> GSocket_Accept()
+*/
+void GSocket_SetFallback(GSocket *socket, GSocketEventFlags event,
+                        GSocketFallback fallback, char *cdata)
+{
+  int count;
+
+  assert (socket != NULL);
+
+  for (count=0;count<GSOCK_MAX_EVENT;count++) {
+    if ((event & (1 << count)) != 0) {
+      socket->m_fbacks[count] = fallback;
+      socket->m_data[count] = cdata;
+
+      _GSocket_Install_Fallback(socket, count);
+      _GSocket_Enable(socket, count);
+    }
+  }
+}
+
+/*
+  UnsetFallback will disables all fallbacks specified by "event".
+  NOTE: event may be a combination of flags
+*/
+void GSocket_UnsetFallback(GSocket *socket, GSocketEventFlags event)
+{
+  int count = 0;
+
+  assert(socket != NULL);
+
+  for (count=0;count<GSOCK_MAX_EVENT;count++) {
+    if ((event & (1 << count)) != 0) {
+      _GSocket_Disable(socket, count);
+      socket->m_fbacks[count] = NULL;
+      _GSocket_Uninstall_Fallback(socket, count);
+    }
+  }
+}
+
+#define CALL_FALLBACK(socket, event) \
+if (socket->m_iocalls[event] && \
+    socket->m_fbacks[event]) {\
+  _GSocket_Disable(socket, event); \
+  socket->m_fbacks[event](socket, 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); \
+}
+
+void _GSocket_Enable(GSocket *socket, GSocketEvent event)
+{
+  socket->m_iocalls[event] = TRUE;
+  if (socket->m_fbacks[event])
+    _GSocket_Install_Fallback(socket, event);
+}
+
+void _GSocket_Disable(GSocket *socket, GSocketEvent event)
+{
+  socket->m_iocalls[event] = FALSE;
+  if (socket->m_fbacks[event])
+    _GSocket_Uninstall_Fallback(socket, event);
+}
+
+int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size)
+{
+  int ret;
+
+  MASK_SIGNAL();
+  ret = recv(socket->m_fd, buffer, size, 0);
+  UNMASK_SIGNAL();
+  if (ret == -1) {
+    socket->m_error = GSOCK_IOERR;
+    return -1;
+  }
+  return ret;
+}
+
+int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size)
+{
+  struct sockaddr from;
+  int fromlen, ret;
+
+  fromlen = sizeof(from);
+
+  MASK_SIGNAL();
+  ret = recvfrom(socket->m_fd, buffer, size, 0, &from, &fromlen);
+  UNMASK_SIGNAL();
+  if (ret == -1) {
+    socket->m_error = GSOCK_IOERR;
+    return -1;
+  }
+
+  if (!socket->m_peer)
+    socket->m_peer = GAddress_new();
+  _GAddress_translate_from(socket->m_peer, &from, fromlen);
+
+  return ret;
+}
+
+int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size)
+{
+  int ret;
+
+  MASK_SIGNAL();
+  ret = send(socket->m_fd, buffer, size, 0);
+  UNMASK_SIGNAL();
+  if (ret == -1) {
+    socket->m_error = GSOCK_IOERR;
+    return -1;
+  }
+  return ret;
+}
+
+int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size)
+{
+  struct sockaddr *addr;
+  int len, ret;
+
+  if (!socket->m_peer) {
+    socket->m_error = GSOCK_INVADDR;
+    return -1;
+  }
+
+  _GAddress_translate_to(socket->m_peer, &addr, &len);
+
+  MASK_SIGNAL();
+  ret = sendto(socket->m_fd, buffer, size, 0, addr, len);
+  UNMASK_SIGNAL();
+  if (ret == -1) {
+    socket->m_error = GSOCK_IOERR;
+    return -1;
+  }
+
+  free(addr);
+
+  return ret;
+}
+
+void _GSocket_Detected_Read(GSocket *socket)
+{
+  char c;
+  int ret;
+
+  if (socket->m_stream) {
+    ret = recv(socket->m_fd, &c, 1, MSG_PEEK);
+
+    if (ret < 0 && socket->m_server) {
+      CALL_FALLBACK(socket, GSOCK_CONNECTION);
+      return;
+    }
+
+    if (ret > 0) {
+      CALL_FALLBACK(socket, GSOCK_INPUT);
+    } else {
+      CALL_FALLBACK(socket, GSOCK_LOST);
+    }
+  }
+}
+
+void _GSocket_Detected_Write(GSocket *socket)
+{
+  CALL_FALLBACK(socket, GSOCK_OUTPUT);
+}
+
+#undef CALL_FALLBACK 
+#undef MASK_SIGNAL
+#undef UNMASK_SIGNAL
+
+/*
+ * -------------------------------------------------------------------------
+ * GAddress
+ * -------------------------------------------------------------------------
+ */
+
+#define CHECK_ADDRESS(address, family, retval) \
+{ \
+  if (address->m_family == GSOCK_NOFAMILY) \
+    _GAddress_Init_##family(address); \
+  if (address->m_family != GSOCK_##family) {\
+    address->m_error = GSOCK_INVADDR; \
+    return retval; \
+  } \
+}
+
+GAddress *GAddress_new()
+{
+  GAddress *address;
+
+  address = (GAddress *)malloc(sizeof(GAddress));
+
+  address->m_family  = GSOCK_NOFAMILY;
+  address->m_addr    = NULL;
+  address->m_len     = 0;
+
+  return address;
+}
+
+GAddress *GAddress_copy(GAddress *address)
+{
+  GAddress *addr2;
+
+  assert(address != NULL);
+
+  addr2 = (GAddress *)malloc(sizeof(GAddress));
+  memcpy(addr2, address, sizeof(GAddress));
+
+  if (address->m_addr) {
+    addr2->m_addr = (struct sockaddr *)malloc(addr2->m_len);
+    memcpy(addr2->m_addr, address->m_addr, addr2->m_len);
+  }
+
+  return addr2;
+}
+
+void GAddress_destroy(GAddress *address)
+{
+  assert(address != NULL);
+
+  free(address);
+}
+
+void GAddress_SetFamily(GAddress *address, GAddressType type)
+{
+  assert(address != NULL);
+
+  address->m_family = type;
+}
+
+GAddressType GAddress_GetFamily(GAddress *address)
+{
+  assert(address != NULL);
+
+  return address->m_family;
+}
+
+void _GAddress_translate_from(GAddress *address, struct sockaddr *addr, int len){
+  address->m_realfamily = addr->sa_family;
+  switch (addr->sa_family) {
+  case AF_INET:
+    address->m_family = GSOCK_INET;
+    break;
+  case AF_UNIX:
+    address->m_family = GSOCK_UNIX;
+    break;
+  case AF_INET6:
+    address->m_family = GSOCK_INET6;
+    break;
+  default:
+    /* TODO error */
+  }
+
+  if (address->m_addr)
+    free(address->m_addr);
+
+  address->m_len  = len;
+  address->m_addr = (struct sockaddr *)malloc(len);
+  memcpy(address->m_addr, addr, len);
+}
+
+void _GAddress_translate_to(GAddress *address,
+                            struct sockaddr **addr, int *len)
+{
+  if (!address->m_addr) {
+    /* TODO error */
+    return;
+  }
+
+  *len = address->m_len;
+  *addr = (struct sockaddr *)malloc(address->m_len);
+  memcpy(*addr, address->m_addr, address->m_len);
+}
+
+/*
+ * -------------------------------------------------------------------------
+ * Internet address family
+ * -------------------------------------------------------------------------
+ */
+
+void _GAddress_Init_INET(GAddress *address)
+{
+  address->m_len  = sizeof(struct sockaddr_in);
+  address->m_addr = (struct sockaddr *)malloc(address->m_len);
+  address->m_family = GSOCK_INET;
+  address->m_realfamily = PF_INET;
+  ((struct sockaddr_in *)address->m_addr)->sin_family = AF_INET;
+  ((struct sockaddr_in *)address->m_addr)->sin_addr.s_addr   = INADDR_ANY;
+}
+
+GSocketError GAddress_INET_SetHostName(GAddress *address, const char *hostname)
+{
+  struct hostent *he;
+  struct in_addr *addr;
+
+  assert(address != NULL);
+
+  CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+  addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
+
+  /* only name for the moment */
+  if (inet_aton(hostname, addr) == 0) {
+    struct in_addr *array_addr;
+
+    if ((he = gethostbyname(hostname)) == NULL) {
+      address->m_error = GSOCK_NOHOST;
+      return GSOCK_NOHOST;
+    }
+    array_addr = (struct in_addr *) *(he->h_addr_list);
+    addr->s_addr = array_addr[0].s_addr;
+  }
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_SetHostAddress(GAddress *address,
+                                          unsigned long hostaddr)
+{
+  struct in_addr *addr;
+
+  assert(address != NULL);
+
+  CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+  addr = &(((struct sockaddr_in *)address->m_addr)->sin_addr);
+  addr->s_addr = hostaddr;
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_SetPortName(GAddress *address, const char *port)
+{
+  struct servent *se;
+  struct sockaddr_in *addr;
+
+  assert(address != NULL);
+  CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+  if (!port) {
+    address->m_error = GSOCK_INVPORT;
+    return GSOCK_INVOP;
+  }
+  /* TODO: TCP or UDP */
+  se = getservbyname(port, "tcp");
+  if (!se) {
+    if (isdigit(port[0])) {
+      int port_int;
+
+      port_int = atoi(port);
+      addr = (struct sockaddr_in *)address->m_addr;
+      addr->sin_port = htons(port_int);
+      return GSOCK_NOERROR;
+    }
+
+    address->m_error = GSOCK_INVPORT;
+    return GSOCK_INVPORT;
+  }
+
+  addr = (struct sockaddr_in *)address->m_addr;
+  addr->sin_port = se->s_port;
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_SetPort(GAddress *address, unsigned short port)
+{
+  struct sockaddr_in *addr;
+
+  assert(address != NULL);
+  CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+  addr = (struct sockaddr_in *)address->m_addr;
+  addr->sin_port = htons(port);
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_INET_GetHostName(GAddress *address, char *hostname, size_t sbuf)
+{
+  struct hostent *he;
+  char *addr_buf;
+  struct sockaddr_in *addr;
+
+  assert(address != NULL); 
+  CHECK_ADDRESS(address, INET, GSOCK_INVADDR);
+
+  addr = (struct sockaddr_in *)address->m_addr;
+  addr_buf = (char *)&(addr->sin_addr);
+
+  he       = gethostbyaddr(addr_buf, sizeof(addr->sin_addr), AF_INET);
+  if (he == NULL) {
+    address->m_error = GSOCK_NOHOST;
+    return GSOCK_NOHOST;
+  }
+
+  strncpy(hostname, he->h_name, sbuf);
+
+  return GSOCK_NOERROR;
+}
+
+unsigned long GAddress_INET_GetHostAddress(GAddress *address)
+{
+  struct sockaddr_in *addr;
+
+  assert(address != NULL); 
+  CHECK_ADDRESS(address, INET, 0); 
+
+  addr = (struct sockaddr_in *)address->m_addr;
+
+  return addr->sin_addr.s_addr;
+}
+
+unsigned short GAddress_INET_GetPort(GAddress *address)
+{
+  struct sockaddr_in *addr;
+
+  assert(address != NULL); 
+  CHECK_ADDRESS(address, INET, 0); 
+
+  addr = (struct sockaddr_in *)address->m_addr;
+  return ntohs(addr->sin_port);
+}
+
+/*
+ * -------------------------------------------------------------------------
+ * Unix address family
+ * -------------------------------------------------------------------------
+ */
+
+void _GAddress_Init_UNIX(GAddress *address)
+{
+  address->m_len  = sizeof(struct sockaddr_un);
+  address->m_addr = (struct sockaddr *)malloc(address->m_len);
+  address->m_family = GSOCK_UNIX;
+  address->m_realfamily = PF_UNIX;
+  ((struct sockaddr_un *)address->m_addr)->sun_family = AF_UNIX;
+  ((struct sockaddr_un *)address->m_addr)->sun_path[0] = 0;
+}
+
+GSocketError GAddress_UNIX_SetPath(GAddress *address, const char *path)
+{
+  struct sockaddr_un *addr;
+
+  assert(address != NULL); 
+
+  CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR); 
+
+  addr = ((struct sockaddr_un *)address->m_addr);
+  memcpy(addr->sun_path, path, strlen(path));
+
+  return GSOCK_NOERROR;
+}
+
+GSocketError GAddress_UNIX_GetPath(GAddress *address, char *path, size_t sbuf)
+{
+  struct sockaddr_un *addr;
+
+  assert(address != NULL);
+  CHECK_ADDRESS(address, UNIX, GSOCK_INVADDR);
+
+  addr = (struct sockaddr_un *)address->m_addr;
+
+  strncpy(path, addr->sun_path, sbuf);
+
+  return GSOCK_NOERROR;
+}
diff --git a/src/unix/gsockunx.h b/src/unix/gsockunx.h
new file mode 100644 (file)
index 0000000..5294e6f
--- /dev/null
@@ -0,0 +1,57 @@
+#ifndef __GSOCK_UNX_H
+#define __GSOCK_UNX_H
+
+#include <wx/gsocket.h>
+
+/* Definition of GSocket */
+struct _GSocket {
+  int m_fd;
+  GAddress *m_local, *m_peer;
+  GSocketError m_error;
+
+  bool m_blocking, m_server, m_stream, m_oriented;
+
+  /* Fallbacks */
+  GSocketFallback m_fbacks[GSOCK_MAX_EVENT];
+  char *m_data[GSOCK_MAX_EVENT];
+
+  /* IO calls associated */
+  bool m_iocalls[GSOCK_MAX_EVENT];
+
+  char *m_gui_dependent;
+};
+
+/* Definition of GAddress */
+struct _GAddress {
+  struct sockaddr *m_addr;
+  size_t m_len;
+
+  GAddressType m_family;
+  int m_realfamily;
+
+  GSocketError m_error;
+};
+
+void _GSocket_Enable(GSocket *socket, GSocketEvent event);
+void _GSocket_Disable(GSocket *socket, GSocketEvent event);
+int _GSocket_Recv_Stream(GSocket *socket, char *buffer, int size);
+int _GSocket_Recv_Dgram(GSocket *socket, char *buffer, int size);
+int _GSocket_Send_Stream(GSocket *socket, const char *buffer, int size);
+int _GSocket_Send_Dgram(GSocket *socket, const char *buffer, int size);
+void _GSocket_Install_Fallback(GSocket *socket, GSocketEvent count);
+void _GSocket_Uninstall_Fallback(GSocket *socket, GSocketEvent count);
+void _GSocket_Detected_Read(GSocket *socket);
+void _GSocket_Detected_Write(GSocket *socket);
+void _GSocket_GUI_Init(GSocket *socket);
+void _GSocket_GUI_Destroy(GSocket *socket);
+void _GAddress_translate_from(GAddress *address,
+                              struct sockaddr *addr, int len);
+void _GAddress_translate_to(GAddress *address,
+                            struct sockaddr **addr, int *len);
+
+/* Internet address family */
+void _GAddress_Init_INET(GAddress *address);
+/* Local address family */
+void _GAddress_Init_UNIX(GAddress *address);
+
+#endif