]> git.saurik.com Git - wxWidgets.git/commitdiff
* Added wxsocket lib and sample (I hope I don't forget some file)
authorGuilhem Lavaux <lavaux@easynet.fr>
Sun, 6 Sep 1998 18:28:00 +0000 (18:28 +0000)
committerGuilhem Lavaux <lavaux@easynet.fr>
Sun, 6 Sep 1998 18:28:00 +0000 (18:28 +0000)
* Updated some wx data and makefiles
* Updates on wxStream (reorganization)
 makefile for Windows will nearly follow
 wxSocket should work on wxGTK (I've tested it)

* IPC over Network is included

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

42 files changed:
include/wx/datstrm.h
include/wx/fstream.h
include/wx/protocol/file.h [new file with mode: 0644]
include/wx/protocol/ftp.h [new file with mode: 0644]
include/wx/protocol/http.h [new file with mode: 0644]
include/wx/protocol/protocol.h [new file with mode: 0644]
include/wx/sckaddr.h [new file with mode: 0644]
include/wx/sckipc.h [new file with mode: 0644]
include/wx/sckstrm.h [new file with mode: 0644]
include/wx/socket.h [new file with mode: 0644]
include/wx/stream.h
include/wx/tokenzr.h [new file with mode: 0644]
include/wx/url.h [new file with mode: 0644]
samples/wxsocket/Makefile [new file with mode: 0644]
samples/wxsocket/Makefile.in [new file with mode: 0644]
samples/wxsocket/client.cpp [new file with mode: 0644]
samples/wxsocket/client.def [new file with mode: 0644]
samples/wxsocket/client.rc [new file with mode: 0644]
samples/wxsocket/connect.ico [new file with mode: 0644]
samples/wxsocket/makefile.b32 [new file with mode: 0644]
samples/wxsocket/makefile.g95 [new file with mode: 0644]
samples/wxsocket/makefile.nt [new file with mode: 0644]
samples/wxsocket/mondrian.ico [new file with mode: 0644]
samples/wxsocket/mondrian.xpm [new file with mode: 0644]
samples/wxsocket/server.cpp [new file with mode: 0644]
samples/wxsocket/server.def [new file with mode: 0644]
samples/wxsocket/server.rc [new file with mode: 0644]
src/common/datstrm.cpp
src/common/ftp.cpp [new file with mode: 0644]
src/common/http.cpp [new file with mode: 0644]
src/common/protocol.cpp [new file with mode: 0644]
src/common/sckaddr.cpp [new file with mode: 0644]
src/common/sckfile.cpp [new file with mode: 0644]
src/common/sckipc.cpp [new file with mode: 0644]
src/common/sckstrm.cpp [new file with mode: 0644]
src/common/socket.cpp [new file with mode: 0644]
src/common/stream.cpp
src/common/tokenzr.cpp [new file with mode: 0644]
src/common/url.cpp [new file with mode: 0644]
src/gtk.inc
src/gtk/data.cpp
src/gtk1/data.cpp

index de87a83323daf2f35cd2d7f0d5276aeb76b689f9..230d5253b6b59b3be267edfcb73425ec293106a0 100644 (file)
@@ -18,7 +18,7 @@
 
 #include <wx/stream.h>
 
-class wxDataInputStream: public wxFilterInputStream {
+class wxDataInputStream: virtual public wxFilterInputStream {
 public:
   wxDataInputStream(wxInputStream& s);
   virtual ~wxDataInputStream();
@@ -31,7 +31,7 @@ public:
   wxString ReadString();
 };
 
-class wxDataOutputStream: public wxFilterOutputStream {
+class wxDataOutputStream: virtual public wxFilterOutputStream {
  public:
   wxDataOutputStream(wxOutputStream& s);
   virtual ~wxDataOutputStream();
@@ -44,5 +44,11 @@ class wxDataOutputStream: public wxFilterOutputStream {
   void WriteString(const wxString& string);
 };
 
+class wxDataStream: public wxDataInputStream, public wxDataOutputStream,
+                    public wxFilterStream {
+ public:
+  wxDataStream(wxStream& stream);
+};
+
 #endif
     // _WX_DATSTREAM_H_
index 3fb395951c87e43486414f68f064bec588bdd602..dbe1abb1f8b8046921ed57532a79250deda4ef1e 100644 (file)
@@ -22,7 +22,8 @@ protected:
   bool m_file_destroy;
 };
 
-class wxFileInputStream: public wxInputStream, virtual public wxFileStreamBase {
+class wxFileInputStream: virtual public wxInputStream,
+                         virtual public wxFileStreamBase {
  public:
   wxFileInputStream(const wxString& fileName);
   virtual ~wxFileInputStream();
@@ -39,7 +40,8 @@ class wxFileInputStream: public wxInputStream, virtual public wxFileStreamBase {
   off_t DoTellInput() const;
 };
 
-class wxFileOutputStream: public wxOutputStream, virtual public wxFileStreamBase {
+class wxFileOutputStream: virtual public wxOutputStream,
+                          virtual public wxFileStreamBase {
  public:
   wxFileOutputStream(const wxString& fileName);
   virtual ~wxFileOutputStream();
@@ -60,7 +62,8 @@ class wxFileOutputStream: public wxOutputStream, virtual public wxFileStreamBase
   off_t DoTellOutput() const;
 };
 
-class wxFileStream: public wxFileInputStream, public wxFileOutputStream {
+class wxFileStream: public wxStream,
+                    public wxFileInputStream, public wxFileOutputStream {
  public:
   wxFileStream(const wxString& fileName);
   virtual ~wxFileStream();
diff --git a/include/wx/protocol/file.h b/include/wx/protocol/file.h
new file mode 100644 (file)
index 0000000..773cdcc
--- /dev/null
@@ -0,0 +1,35 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        file.h
+// Purpose:     File protocol
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     1997
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997, 1998 Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+#ifndef __WX_PROTO_FILE_H__
+#define __WX_PROTO_FILE_H__
+
+#ifdef __GNUG__
+#pragma interface "sckfile.h"
+#endif
+
+#include "wx/protocol/protocol.h"
+#include "wx/url.h"
+
+class WXDLLEXPORT wxFileProto: public wxProtocol {
+  DECLARE_DYNAMIC_CLASS(wxFileProto)
+  DECLARE_PROTOCOL(wxFileProto)
+protected:
+  wxProtocolError m_error;
+public:
+  wxFileProto();
+  ~wxFileProto();
+
+  wxProtocolError GetError() { return m_error; }
+  bool Abort() { return TRUE; }
+  wxInputStream *GetInputStream(const wxString& path);
+};
+
+#endif
diff --git a/include/wx/protocol/ftp.h b/include/wx/protocol/ftp.h
new file mode 100644 (file)
index 0000000..7fca01f
--- /dev/null
@@ -0,0 +1,74 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        ftp.h
+// Purpose:     FTP protocol
+// Author:      Vadim Zeitlin
+// Modified by:
+// Created:     07/07/1997
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997, 1998 Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+#ifndef __WX_FTP_H__
+#define __WX_FTP_H__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/object.h"
+#include "wx/sckaddr.h"
+#include "wx/protocol/protocol.h"
+#include "wx/url.h"
+
+class WXDLLEXPORT wxFTP : public wxProtocol {
+  DECLARE_DYNAMIC_CLASS(wxFTP)
+  DECLARE_PROTOCOL(wxFTP)
+public:
+  typedef enum { ASCII, BINARY } wxFTPmode;
+
+  wxFTP();
+  ~wxFTP();
+
+  bool Close();
+  bool Connect(wxSockAddress& addr);
+  bool Connect(const wxString& host);
+
+  void SetUser(const wxString& user) { m_user = user; }
+  void SetPassword(const wxString& passwd) { m_passwd = passwd; }
+
+  // Low-level methods
+  bool SendCommand(const wxString& command, char exp_ret);
+  inline virtual wxProtocolError GetError()
+      { return m_lastError; }
+  const wxString& GetLastResult();             // Get the complete return 
+
+  // Filesystem commands
+  bool ChDir(const wxString& dir);
+  bool MkDir(const wxString& dir);
+  bool RmDir(const wxString& dir);
+  wxString Pwd();
+  bool Rename(const wxString& src, const wxString& dst);
+  bool RmFile(const wxString& path);
+
+  // Download methods
+  bool Abort();
+  wxInputStream *GetInputStream(const wxString& path);
+  wxOutputStream *GetOutputStream(const wxString& path);
+
+  // List method
+  wxList *GetList(const wxString& wildcard);
+
+protected:
+  wxString m_user, m_passwd;
+  wxString m_lastResult;
+  wxProtocolError m_lastError;
+  bool m_streaming;
+
+  friend class wxInputFTPStream;
+  friend class wxOutputFTPStream;
+
+  wxSocketClient *GetPort();
+  bool GetResult(char exp);
+};
+
+#endif
diff --git a/include/wx/protocol/http.h b/include/wx/protocol/http.h
new file mode 100644 (file)
index 0000000..97282b5
--- /dev/null
@@ -0,0 +1,48 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        http.h
+// Purpose:     HTTP protocol
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     August 1997
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997, 1998 Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+#ifndef _WX_HTTP_H
+#define _WX_HTTP_H
+
+#include "wx/list.h"
+#include "wx/protocol/protocol.h"
+
+class WXDLLEXPORT wxHTTP : public wxProtocol {
+  DECLARE_DYNAMIC_CLASS(wxHTTP)
+  DECLARE_PROTOCOL(wxHTTP)
+protected:
+  wxProtocolError m_perr;
+  wxList m_headers;
+  bool m_read;
+  wxSockAddress *m_addr;
+public:
+  wxHTTP();
+  ~wxHTTP();
+
+  bool Connect(const wxString& host);
+  bool Connect(wxSockAddress& addr);
+  bool Abort();
+  wxInputStream *GetInputStream(const wxString& path);
+  inline wxProtocolError GetError() { return m_perr; }
+  wxString GetContentType();
+
+  void SetHeader(const wxString& header, const wxString& h_data);
+  wxString GetHeader(const wxString& header);
+
+protected:
+  typedef enum {
+    wxHTTP_GET
+  } wxHTTP_Req;
+  bool BuildRequest(const wxString& path, wxHTTP_Req req);
+  void SendHeaders();
+  bool ParseHeaders();
+};
+
+#endif
diff --git a/include/wx/protocol/protocol.h b/include/wx/protocol/protocol.h
new file mode 100644 (file)
index 0000000..c3773a7
--- /dev/null
@@ -0,0 +1,79 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        protocol.h
+// Purpose:     Protocol base class
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     10/07/1997
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997, 1998 Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+#ifndef _WX_PROTOCOL_PROTOCOL_H
+#define _WX_PROTOCOL_PROTOCOL_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/stream.h"
+#include "wx/socket.h"
+
+typedef enum {
+ wxPROTO_NOERR = 0,
+ wxPROTO_NETERR,
+ wxPROTO_PROTERR,
+ wxPROTO_CONNERR,
+ wxPROTO_INVVAL,
+ wxPROTO_NOHNDLR,
+ wxPROTO_NOFILE,
+ wxPROTO_ABRT,
+ wxPROTO_RCNCT,
+ wxPROTO_STREAMING 
+} wxProtocolError;
+
+// For protocols
+#define DECLARE_PROTOCOL(class) \
+public: \
+  static wxProtoInfo g_proto_##class;
+
+#define IMPLEMENT_PROTOCOL(class, name, serv, host) \
+wxProtoInfo class::g_proto_##class(name, serv, host, CLASSINFO(class));
+
+class WXDLLEXPORT wxProtoInfo : public wxObject {
+  DECLARE_DYNAMIC_CLASS(wxProtoInfo)
+protected:
+  wxProtoInfo *next;
+  wxString m_protoname;
+  wxString prefix;
+  wxString m_servname;
+  wxClassInfo *m_cinfo;
+  bool m_needhost;
+
+  friend class wxURL;
+public:
+  wxProtoInfo(const char *name, const char *serv_name, const bool need_host1,
+              wxClassInfo *info);
+};
+
+class WXDLLEXPORT wxProtocol : public wxSocketClient {
+  DECLARE_ABSTRACT_CLASS(wxProtocol)
+public:
+  wxProtocol();
+
+  bool Reconnect();
+  virtual bool Connect(const wxString& host) { return FALSE; } 
+  virtual bool Connect(wxSockAddress& addr) { return wxSocketClient::Connect(addr); }
+
+  virtual bool Abort() = 0;
+  virtual wxInputStream *GetInputStream(const wxString& path) = 0;
+  virtual wxProtocolError GetError() = 0;
+  virtual wxString GetContentType() { return (char *)NULL; }
+  virtual void SetUser(const wxString& user) {}
+  virtual void SetPassword(const wxString& passwd) {}
+};
+
+wxProtocolError WXDLLEXPORT GetLine(wxSocketBase *sock, wxString& result);
+
+#endif
diff --git a/include/wx/sckaddr.h b/include/wx/sckaddr.h
new file mode 100644 (file)
index 0000000..392a9d1
--- /dev/null
@@ -0,0 +1,136 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        sckaddr.h
+// Purpose:     Network address classes
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     26/04/1997
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997, 1998 Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+#ifndef _WX_NETWORK_ADDRESS_H
+#define _WX_NETWORK_ADDRESS_H
+
+#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
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#ifdef WXPREC
+#include <wx/wxprec.h>
+#else
+#include <wx/wx.h>
+#endif
+
+class WXDLLEXPORT wxSockAddress : public wxObject {
+  DECLARE_ABSTRACT_CLASS(wxSockAddress)
+public:
+  typedef enum { IPV4=1, IPV6=2, UNIX=3 } Addr;
+
+  wxSockAddress() {};
+  virtual ~wxSockAddress() {};
+
+  virtual void Clear() = 0;
+
+  virtual void Build(struct sockaddr*& addr, size_t& len) = 0;
+  virtual void Disassemble(struct sockaddr *addr, size_t len) = 0;
+  virtual int SockAddrLen() = 0;
+
+  virtual int GetFamily() = 0;
+  virtual int Type() = 0;
+};
+
+class WXDLLEXPORT wxIPV4address : public wxSockAddress {
+  DECLARE_DYNAMIC_CLASS(wxIPV4address)
+private:
+  struct sockaddr_in *m_addr;
+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();
+
+  wxString Hostname();
+  unsigned short Service();
+
+  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; }
+};
+
+#ifdef ENABLE_IPV6
+class WXDLLEXPORT wxIPV6address : public wxSockAddress {
+  DECLARE_DYNAMIC_CLASS(wxIPV6address)
+private:
+  struct sockaddr_in6 *m_addr;
+public:
+  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 Service(unsigned short port);
+  bool LocalHost();
+
+  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
+
+#ifdef __UNIX__
+#include <sys/un.h>
+
+class WXDLLEXPORT wxUNIXaddress : public wxSockAddress {
+  DECLARE_DYNAMIC_CLASS(wxUNIXaddress)
+private:
+  struct sockaddr_un *m_addr;
+public:
+  wxUNIXaddress();
+  ~wxUNIXaddress();
+
+  void Clear();
+//  const wxSockAddress& operator =(const wxSockAddress& addr);
+
+  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
+
+#endif
diff --git a/include/wx/sckipc.h b/include/wx/sckipc.h
new file mode 100644 (file)
index 0000000..8ca86b2
--- /dev/null
@@ -0,0 +1,132 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        sckipc.h
+// Purpose:     Interprocess communication
+// Author:      Julian Smart/Guilhem Lavaux (big rewrite)
+// Modified by: Guilhem Lavaux 1997
+// Created:     1993
+// RCS-ID:      $Id$
+// Copyright:   (c) 1993 Julian Smart
+//              (c) 1997, 1998 Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+#ifndef _WX_SCKIPC_H
+#define _WX_SCKIPC_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/defs.h"
+#include "wx/setup.h"
+#include "wx/ipcbase.h"
+#include "wx/socket.h"
+#include "wx/sckstrm.h"
+#include "wx/datstrm.h"
+
+/*
+ * Mini-DDE implementation
+
+   Most transactions involve a topic name and an item name (choose these
+   as befits your application).
+
+   A client can:
+
+   - ask the server to execute commands (data) associated with a topic
+   - request data from server by topic and item
+   - poke data into the server
+   - ask the server to start an advice loop on topic/item
+   - ask the server to stop an advice loop
+
+   A server can:
+
+   - respond to execute, request, poke and advice start/stop
+   - send advise data to client
+
+   Note that this limits the server in the ways it can send data to the
+   client, i.e. it can't send unsolicited information.
+ *
+ */
+
+class wxTCPServer;
+class wxTCPClient;
+class wxTCPConnection: public wxConnectionBase
+{
+  DECLARE_DYNAMIC_CLASS(wxTCPConnection)
+  
+protected:
+  wxSocketBase *m_sock;
+  wxSocketStream *m_sockstrm;
+  wxDataStream *m_codec;
+  wxString m_topic;
+
+  friend class wxTCPServer;
+  friend class wxTCPClient;
+  friend void Client_OnRequest(wxSocketBase&,
+                              wxSocketBase::wxRequestEvent, char *);
+  friend void Server_OnRequest(wxSocketServer&,
+                              wxSocketBase::wxRequestEvent, char *);
+public:
+
+  wxTCPConnection(char *buffer, int size);
+  wxTCPConnection();
+  virtual ~wxTCPConnection();
+
+  // Calls that CLIENT can make
+  bool Execute(char *data, int size = -1,
+               wxDataFormat format = wxDF_TEXT);
+  char *Request(const wxString& item, int *size = NULL,
+                wxDataFormat format = wxDF_TEXT);
+  bool Poke(const wxString& item, char *data, int size = -1,
+            wxDataFormat format = wxDF_TEXT);
+  bool StartAdvise(const wxString& item);
+  bool StopAdvise(const wxString& item);
+
+  // Calls that SERVER can make
+  bool Advise(const wxString& item, char *data, int size = -1,
+              wxDataFormat format = wxDF_TEXT);
+
+  // Calls that both can make
+  bool Disconnect();
+
+  // Called when we lost the peer.
+  bool OnDisconnect() { return TRUE; }
+
+  // To enable the compressor
+  void Compress(bool on);
+};
+
+class wxTCPServer: public wxServerBase
+{
+  DECLARE_DYNAMIC_CLASS(wxTCPServer)
+
+public:
+  wxTCPConnection *topLevelConnection;
+
+  wxTCPServer();
+  virtual ~wxTCPServer();
+  
+  // Returns FALSE if can't create server (e.g. port number is already in use)
+  virtual bool Create(const wxString& server_name); 
+  virtual wxConnectionBase *OnAcceptConnection(const wxString& topic);
+};
+
+class wxTCPClient: public wxClientBase
+{
+  DECLARE_DYNAMIC_CLASS(wxTCPClient)
+
+public: 
+  wxTCPClient();
+  virtual ~wxTCPClient();
+
+  virtual bool ValidHost(const wxString& host);
+    // Call this to make a connection.
+    // Returns NULL if cannot.
+  virtual wxConnectionBase *MakeConnection(const wxString& host,
+                                           const wxString& server,
+                                           const wxString& topic);
+  
+  // Tailor this to return own connection.
+  virtual wxConnectionBase *OnMakeConnection();
+};
+
+#endif // ipcsock.h
diff --git a/include/wx/sckstrm.h b/include/wx/sckstrm.h
new file mode 100644 (file)
index 0000000..3d55f1b
--- /dev/null
@@ -0,0 +1,62 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        sckstrm.h
+// Purpose:     wxSocket*Stream
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     17/07/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifndef __SCK_STREAM_H__
+#define __SCK_STREAM_H__
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/stream.h"
+#include "wx/socket.h"
+
+class WXDLLEXPORT wxSocketOutputStream : public wxOutputStream
+{
+ public:
+  wxSocketOutputStream(wxSocketBase& s);
+  virtual ~wxSocketOutputStream();
+
+  wxOutputStream& Write(const void *buffer, size_t size);
+  off_t SeekO(off_t pos, wxSeekMode mode) { return -1; }
+  off_t TellO() { return -1; }
+
+  bool Bad() { return m_o_socket->IsDisconnected(); }
+  size_t LastWrite() { return m_o_socket->LastCount(); }
+ protected:
+  wxSocketBase *m_o_socket;
+};
+
+class WXDLLEXPORT wxSocketInputStream : public wxInputStream
+{
+ public:
+  wxSocketInputStream(wxSocketBase& s);
+  ~wxSocketInputStream();
+
+  wxInputStream& Read(void *buffer, size_t size);
+  off_t SeekI(off_t pos, wxSeekMode mode) { return -1; }
+  off_t TellI() { return -1; }
+
+  bool Eof() { return m_i_socket->IsDisconnected(); }
+  size_t LastRead() { return m_i_socket->LastCount(); }
+ protected:
+  wxSocketBase *m_i_socket;
+};
+
+class WXDLLEXPORT wxSocketStream : public wxSocketInputStream,
+                                   public wxSocketOutputStream,
+                                  public wxStream {
+
+ public:
+  wxSocketStream(wxSocketBase& i_s, wxSocketBase& o_s);
+  wxSocketStream(wxSocketBase& s);
+};
+
+#endif
diff --git a/include/wx/socket.h b/include/wx/socket.h
new file mode 100644 (file)
index 0000000..a65b468
--- /dev/null
@@ -0,0 +1,336 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        socket.h
+// Purpose:     Socket handling classes
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     April 1997
+// RCS-ID:      $Id$
+// Copyright:   (c) Guilhem Lavaux
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifndef _WX_NETWORK_SOCKET_H
+#define _WX_NETWORK_SOCKET_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+// ---------------------------------------------------------------------------
+// Windows(tm) specific
+// ---------------------------------------------------------------------------
+#if defined(__WINDOWS__) && defined(WXSOCK_INTERNAL)
+#include <winsock.h>
+#include <wx/msw/private.h>
+
+struct wxSockInternal {
+  UINT my_msg;
+};
+
+struct wxSockHandlerInternal {
+  HWND sockWin;
+  UINT firstAvailableMsg;
+};
+#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>
+
+// ---------------------------------------------------------------------------
+// Athena specific
+// ---------------------------------------------------------------------------
+#if defined(__WXXT__) || defined(__WXMOTIF__)
+#include <X11/Intrinsic.h>
+
+struct wxSockInternal {
+  XtInputId sock_inputid, sock_outputid, sock_exceptid;
+};
+#endif
+
+// ---------------------------------------------------------------------------
+// GTK specific
+// ---------------------------------------------------------------------------
+#if defined(__WXGTK__)
+#include <gdk/gdk.h>
+
+struct wxSockInternal {
+  gint sock_inputid, sock_outputid, sock_exceptid;
+};
+#endif
+
+#endif // defined(__UNIX__) && defined(WXSOCK_INTERNAL)
+
+// ---------------------------------------------------------------------------
+// wxSocket headers (generic)
+// ---------------------------------------------------------------------------
+#ifdef WXPREC
+#include <wx/wxprec.h>
+#else
+#include <wx/wx.h>
+#endif
+#include "wx/sckaddr.h"
+
+class WXDLLEXPORT wxSocketEvent;
+class WXDLLEXPORT wxSocketHandler;
+class WXDLLEXPORT wxSocketBase : public wxEvtHandler
+{
+  DECLARE_CLASS(wxSocketBase)
+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};
+  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;
+  typedef void (*wxSockCbk)(wxSocketBase& sock,wxRequestEvent evt,char *cdata);
+
+protected:
+  wxList req_list[EVT_WRITE+1];
+
+  // Internal use for SaveState() and RestoreState()
+  class wxSockState : public wxObject {
+  public:
+    bool cbk_on;
+    wxSockCbk cbk;
+    char *cdata;
+    bool notif;
+    wxRequestNotify cbk_set;
+    wxSockFlags flags;
+  };
+  typedef struct {
+    char sig[4];
+    char len[4];
+  } SockMsg;
+  enum wxSockType { SOCK_CLIENT, SOCK_SERVER, SOCK_INTERNAL, SOCK_UNINIT }; 
+
+  wxSockFlags m_flags;
+  wxSockType m_type;                   // wxSocket type
+  bool m_connected, m_connecting;      // State of the socket
+  int m_fd;                            // Socket file descriptors
+  int m_waitflags;                     // Wait flags
+  wxList m_states;                     // States list
+  wxSockCbk m_cbk;                     // C callback
+  char *m_cdata;                       // C callback data
+  int m_id;                            // Socket id (for event handler)
+  wxSocketHandler *m_handler;          // the current socket handler
+  wxRequestNotify m_neededreq;         // Specify which requet signals we need
+  bool m_cbkon;
+  char *m_unread;                      // The unread buf
+  size_t m_unrd_size;                  // The size of the unread buf
+  bool m_processing;                   // To prevent some endless loop
+  unsigned long m_timeout;
+  int m_wantbuf;
+  size_t m_lcount;                     // Last IO request size
+  int m_error;                         // Last IO error
+  bool m_notifyme;
+
+  struct wxSockInternal *m_internal;   // System specific variables
+
+public:
+  wxSocketBase();
+  virtual ~wxSocketBase();
+  virtual bool Close();
+
+  // Base IO
+  wxSocketBase& Peek(char* buffer, size_t nbytes);
+  wxSocketBase& Read(char* buffer, size_t nbytes);
+  wxSocketBase& Write(const char *buffer, size_t nbytes);
+  wxSocketBase& WriteMsg(const char *buffer, size_t nbytes);
+  wxSocketBase& ReadMsg(char* buffer, size_t nbytes);
+  wxSocketBase& Unread(const char *buffer, size_t nbytes);
+  void Discard();
+
+  // Try not to use this two methods (they sould be protected)
+  void CreatePushbackAfter(const char *buffer, size_t size);
+  void CreatePushbackBefore(const char *buffer, size_t size);
+
+  // Status
+  inline bool Ok() const { return (m_fd < 0 ? 0 : 1); };
+  inline bool Error() const { return (m_error != 0); };
+  inline bool IsConnected() const { return m_connected; };
+  inline bool IsDisconnected() const { return !IsConnected(); };
+  inline bool IsNoWait() const { return m_flags & NOWAIT; };
+  bool IsData() const;
+  inline size_t LastCount() const { return m_lcount; }
+  inline int LastError() const { return m_error; }
+  
+  inline void SetFlags(wxSockFlags _flags);
+  inline void SetTimeout(unsigned long sec) { m_timeout = sec; }
+
+  // seconds = -1 means infinite wait
+  // seconds = 0 means no wait
+  // seconds > 0 means specified wait
+  bool Wait(long seconds = -1, long microseconds = 0);
+  bool WaitForRead(long seconds = -1, long microseconds = 0);
+  bool WaitForWrite(long seconds = -1, long microseconds = 0);
+  bool WaitForLost(long seconds = -1, long microseconds = 0);
+  
+  // Save the current state of Socket
+  void SaveState();
+  void RestoreState();
+
+  // Setup external callback
+  wxSockCbk Callback(wxSockCbk cbk_);
+  char *CallbackData(char *data);
+
+  // Setup event handler
+  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);
+
+  // Public internal callback
+  virtual void OldOnNotify(wxRequestEvent WXUNUSED(evt));
+
+  // Some info on the socket...
+  virtual bool GetPeer(wxSockAddress& addr_man) const;
+  virtual bool GetLocal(wxSockAddress& addr_man) const;
+
+  // Install or uninstall callbacks
+  void Notify(bool notify);
+
+  // So you can know what the socket driver is looking for ...
+  inline wxRequestNotify NeededReq() const { return m_neededreq; }
+
+  static wxRequestNotify EventToNotify(wxRequestEvent evt);
+
+protected:
+  friend class wxSocketServer;
+  friend class wxSocketHandler;
+
+  wxSocketBase(wxSockFlags flags, wxSockType type);
+  
+  bool _Wait(long seconds, long microseconds, int type);
+  
+  // Set "my" handler
+  inline virtual void SetHandler(wxSocketHandler *handler)
+         { m_handler = handler; }
+
+  // Activate or disactivate callback
+  void SetupCallbacks();
+  void DestroyCallbacks();
+
+  // 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);
+
+  virtual bool DoRequests(wxRequestEvent req);
+};
+
+////////////////////////////////////////////////////////////////////////
+
+class WXDLLEXPORT wxSocketServer : public wxSocketBase
+{
+  DECLARE_CLASS(wxSocketServer)
+public:
+
+  // 'service' can be a name or a port-number
+
+  wxSocketServer(wxSockAddress& addr_man, wxSockFlags flags = wxSocketBase::NONE);
+
+  wxSocketBase* Accept();
+  bool AcceptWith(wxSocketBase& sock);
+  virtual void OnRequest(wxRequestEvent flags);
+};
+
+////////////////////////////////////////////////////////////////////////
+
+class WXDLLEXPORT wxSocketClient : public wxSocketBase
+{
+  DECLARE_CLASS(wxSocketClient)
+public:
+
+  wxSocketClient(wxSockFlags flags = wxSocketBase::NONE);
+  virtual ~wxSocketClient();
+
+  virtual bool Connect(wxSockAddress& addr_man, bool wait = TRUE);
+
+  bool WaitOnConnect(long seconds = -1);
+
+  virtual void OnRequest(wxRequestEvent flags);
+};
+
+////////////////////////////////////////////////////////////////////////
+
+class WXDLLEXPORT wxSocketHandler : public wxObject
+{
+  DECLARE_CLASS(wxSocketHandler)
+protected:
+  static wxSocketHandler *master;
+#if defined(__WINDOWS__)
+  wxList *smsg_list;
+  struct wxSockHandlerInternal *internal;
+#endif
+  wxList *socks;
+
+public:
+  enum SockStatus { SOCK_NONE, SOCK_DATA, SOCK_CONNECT, SOCK_DISCONNECT,
+                   SOCK_ERROR };
+
+  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) ? (master) : (master = new wxSocketHandler())); }
+
+#if defined(WXSOCK_INTERNAL) && defined(__WINDOWS__)
+
+  friend LRESULT APIENTRY _EXPORT wxSocketHandlerWndProc(HWND hWnd,
+                        UINT message, WPARAM wParam, LPARAM lParam);
+
+  UINT NewMessage(wxSocketBase *sock);
+  void DestroyMessage(UINT msg);
+
+  HWND GetHWND() const;
+#endif
+};
+
+class WXDLLEXPORT wxSocketEvent : public wxEvent {
+  DECLARE_DYNAMIC_CLASS(wxSocketEvent)
+public:
+  wxSocketEvent(int id = 0);
+
+  wxSocketBase::wxRequestEvent SocketEvent() const { return m_skevt; }
+public:
+  wxSocketBase::wxRequestEvent m_skevt;
+};
+
+typedef void (wxEvtHandler::*wxSocketEventFunction)(wxSocketEvent&);
+
+#define wxEVT_SOCKET wxEVT_FIRST+301
+
+#define EVT_SOCKET(id, func) { wxEVT_SOCKET, id, 0, (wxObjectEventFunction) (wxEventFunction) (wxSocketEventFunction) & func },
+
+#endif
index d966c7da37d4f45f8a9341eae95d3735e0e647a1..428dbaab1f46636c26425466a6aeefc7ea2c926f 100644 (file)
@@ -29,6 +29,10 @@ typedef wxOutputStream& (*__wxOutputManip)(wxOutputStream&);
 
 wxOutputStream& WXDLLEXPORT wxEndL(wxOutputStream& o_stream);
 
+// ---------------------------------------------------------------------------
+// Stream buffer
+// ---------------------------------------------------------------------------
+
 class WXDLLEXPORT wxStreamBuffer {
  public:
   wxStreamBuffer(wxInputStream& stream);
@@ -63,16 +67,17 @@ class WXDLLEXPORT wxStreamBuffer {
   wxOutputStream *m_ostream;
 };
 
-/*
- * wxStream: base classes
- */
+// ---------------------------------------------------------------------------
+// wxStream: base classes
+// ---------------------------------------------------------------------------
+
 class WXDLLEXPORT wxInputStream {
  public:
   wxInputStream();
   virtual ~wxInputStream();
 
   // IO functions
-  virtual char Peek() = 0;
+  virtual char Peek() { return 0; }
   virtual char GetC();
   virtual wxInputStream& Read(void *buffer, size_t size);
   wxInputStream& Read(wxOutputStream& stream_out);
@@ -108,9 +113,11 @@ class WXDLLEXPORT wxInputStream {
 
   wxInputStream(wxStreamBuffer *buffer);
 
-  virtual size_t DoRead(void *buffer, size_t size) = 0;
-  virtual off_t DoSeekInput(off_t pos, wxSeekMode mode) = 0;
-  virtual off_t DoTellInput() const = 0;
+  virtual size_t DoRead(void *buffer, size_t size) { return 0; }
+  virtual off_t DoSeekInput(off_t pos, wxSeekMode mode)
+         { return wxInvalidOffset; }
+  virtual off_t DoTellInput() const
+         { return wxInvalidOffset; }
 
  protected:
   bool m_eof, m_i_destroybuf;
@@ -158,9 +165,11 @@ class WXDLLEXPORT wxOutputStream {
 
   wxOutputStream(wxStreamBuffer *buffer);
 
-  virtual size_t DoWrite(const void *buffer, size_t size) = 0;
-  virtual off_t DoSeekOutput(off_t pos, wxSeekMode mode) = 0;
-  virtual off_t DoTellOutput() const = 0;
+  virtual size_t DoWrite(const void *buffer, size_t size) { return 0; }
+  virtual off_t DoSeekOutput(off_t pos, wxSeekMode mode)
+            { return wxInvalidOffset; }
+  virtual off_t DoTellOutput() const
+            { return wxInvalidOffset; }
 
  protected:
   bool m_bad, m_o_destroybuf;
@@ -168,48 +177,65 @@ class WXDLLEXPORT wxOutputStream {
   wxStreamBuffer *m_o_streambuf;
 };
 
-/*
- * "Filter" streams
- */
+class wxStream: virtual public wxInputStream,
+               virtual public wxOutputStream
+{
+ public:
+  wxStream();
+};
+
+// ---------------------------------------------------------------------------
+// "Filter" streams
+// ---------------------------------------------------------------------------
 
-class WXDLLEXPORT wxFilterInputStream: public wxInputStream {
+class WXDLLEXPORT wxFilterInputStream: virtual public wxInputStream {
  public:
+  wxFilterInputStream();
   wxFilterInputStream(wxInputStream& stream);
-  virtual ~wxFilterInputStream();
+  ~wxFilterInputStream();
 
-  virtual char Peek() { return m_parent_i_stream->Peek(); }
+  char Peek() { return m_parent_i_stream->Peek(); }
 
-  virtual bool Eof() const { return m_parent_i_stream->Eof(); } 
-  virtual size_t LastRead() const { return m_parent_i_stream->LastRead(); } 
-  virtual off_t TellI() const { return m_parent_i_stream->TellI(); }
+  bool Eof() const { return m_parent_i_stream->Eof(); } 
+  size_t LastRead() const { return m_parent_i_stream->LastRead(); } 
+  off_t TellI() const { return m_parent_i_stream->TellI(); }
 
  protected:
-  virtual size_t DoRead(void *buffer, size_t size);
-  virtual off_t DoSeekInput(off_t pos, wxSeekMode mode);
-  virtual off_t DoTellInput() const;
+  size_t DoRead(void *buffer, size_t size);
+  off_t DoSeekInput(off_t pos, wxSeekMode mode);
+  off_t DoTellInput() const;
 
  protected:
   wxInputStream *m_parent_i_stream;
 };
 
-class WXDLLEXPORT wxFilterOutputStream: public wxOutputStream {
+class WXDLLEXPORT wxFilterOutputStream: virtual public wxOutputStream {
  public:
+  wxFilterOutputStream();
   wxFilterOutputStream(wxOutputStream& stream);
   virtual ~wxFilterOutputStream();
 
-  virtual bool Bad() const { return m_parent_o_stream->Bad(); }
-  virtual size_t LastWrite() const { return m_parent_o_stream->LastWrite(); }
-  virtual off_t TellO() const { return m_parent_o_stream->TellO(); }
+  bool Bad() const { return m_parent_o_stream->Bad(); }
+  size_t LastWrite() const { return m_parent_o_stream->LastWrite(); }
+  off_t TellO() const { return m_parent_o_stream->TellO(); }
 
  protected:
   // The forward is implicitely done by wxStreamBuffer.
 
-  virtual size_t DoWrite(const void *buffer, size_t size);
-  virtual off_t DoSeekOutput(off_t pos, wxSeekMode mode);
-  virtual off_t DoTellOutput() const;
+  size_t DoWrite(const void *buffer, size_t size);
+  off_t DoSeekOutput(off_t pos, wxSeekMode mode);
+  off_t DoTellOutput() const;
 
  protected:
   wxOutputStream *m_parent_o_stream;
 };
 
+class WXDLLEXPORT wxFilterStream: public wxStream,
+                                 virtual public wxFilterInputStream,
+                                 virtual public wxFilterOutputStream {
+ public:
+  wxFilterStream(wxStream& stream);
+  wxFilterStream();
+};
+
 #endif
diff --git a/include/wx/tokenzr.h b/include/wx/tokenzr.h
new file mode 100644 (file)
index 0000000..7942996
--- /dev/null
@@ -0,0 +1,40 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        tokenzr.h
+// Purpose:     String tokenizer
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     04/22/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Guilhem Lavaux
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef _WX_TOKENZRH
+#define _WX_TOKENZRH
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+#include "wx/object.h"
+#include "wx/string.h"
+
+class wxStringTokenizer : wxObject {
+public:
+  wxStringTokenizer(const wxString& to_tokenize,
+                    const wxString& delims = " \t\r\n",
+                    bool ret_delim = FALSE);
+  ~wxStringTokenizer();
+
+  int CountTokens();
+  bool HasMoreToken();
+  wxString NextToken();
+  wxString GetString() { return m_string; }
+protected:
+  off_t FindDelims(const wxString& str, const wxString& delims);
+protected:
+  wxString m_string, m_delims;
+  bool m_retdelims;
+};
+
+#endif
diff --git a/include/wx/url.h b/include/wx/url.h
new file mode 100644 (file)
index 0000000..dae1c6e
--- /dev/null
@@ -0,0 +1,70 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        url.h
+// Purpose:     URL parser
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     20/07/1997
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997, 1998 Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+#ifndef _WX_URL_H
+#define _WX_URL_H
+
+#ifdef __GNUG__
+#pragma interface
+#endif
+
+// wxWindows header
+#include "wx/object.h"
+
+// wxSocket headers
+#include "wx/protocol/protocol.h"
+#include "wx/protocol/http.h"
+
+typedef enum {
+  wxURL_NOERR = 0,
+  wxURL_SNTXERR,
+  wxURL_NOPROTO,
+  wxURL_NOHOST,
+  wxURL_NOPATH,
+  wxURL_CONNERR,
+  wxURL_PROTOERR
+} wxURLError;
+  
+class WXDLLEXPORT wxURL : public wxObject {
+  DECLARE_DYNAMIC_CLASS(wxURL)
+protected:
+  static wxProtoInfo *g_protocols;
+  static wxHTTP g_proxy;
+  wxProtoInfo *m_protoinfo;
+  wxProtocol *m_protocol;
+  wxHTTP m_proxy;
+  wxURLError m_error;
+  wxString m_protoname, m_hostname, m_servname, m_path, m_url;
+
+  bool PrepProto(wxString& url);
+  bool PrepHost(wxString& url);
+  bool PrepPath(wxString& url);
+  bool ParseURL();
+  void CleanData();
+  bool FetchProtocol();
+
+  friend class wxProtoInfo;
+public:
+
+  wxURL(const wxString& url);
+  virtual ~wxURL();
+
+  inline wxString GetProtocolName() const
+        { return m_protoinfo->m_protoname; }
+  inline wxProtocol& GetProtocol() { return *m_protocol; }
+  inline wxURLError GetError() const { return m_error; }
+
+  wxInputStream *GetInputStream();
+
+  static void SetDefaultProxy(const wxString& url_proxy);
+  void SetProxy(const wxString& url_proxy);
+};
+
+#endif
diff --git a/samples/wxsocket/Makefile b/samples/wxsocket/Makefile
new file mode 100644 (file)
index 0000000..bccce53
--- /dev/null
@@ -0,0 +1 @@
+include ../../setup/general/makeapp
diff --git a/samples/wxsocket/Makefile.in b/samples/wxsocket/Makefile.in
new file mode 100644 (file)
index 0000000..68ded4e
--- /dev/null
@@ -0,0 +1,28 @@
+# WXXT base directory
+WXBASEDIR=@WXBASEDIR@
+
+# set the OS type for compilation
+OS=@OS@
+# compile a library only
+RULE=bin2
+
+# define library name
+BIN_TARGET=client
+BIN2_TARGET=server
+# define library sources
+BIN_SRC= client.cpp
+BIN2_SRC= server.cpp
+
+#define library objects
+BIN_OBJ= client.o
+BIN2_OBJ= server.o
+
+# additional things needed to link
+BIN_LINK=
+BIN2_LINK=
+
+# additional things needed to compile
+ADD_COMPILE=
+
+# include the definitions now
+include ../../../template.mak
diff --git a/samples/wxsocket/client.cpp b/samples/wxsocket/client.cpp
new file mode 100644 (file)
index 0000000..4d27104
--- /dev/null
@@ -0,0 +1,281 @@
+/*
+ * File:       client.cpp
+ * Purpose:    wxSocket: client demo
+ * Author:     LAVAUX Guilhem (from minimal.cc)
+ * Created:    June 1997
+ * Updated:    
+ * Copyright:  (c) 1993, AIAI, University of Edinburgh
+ *             (C) 1997, LAVAUX Guilhem
+ */
+#ifdef __GNUG__
+#pragma implementation
+#pragma interface
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+#include "wx/socket.h"
+#include "wx/url.h"
+#include "wx/protocol/http.h"
+
+// Define a new application type
+class MyApp: public wxApp
+{ public:
+    virtual bool OnInit(void);
+};
+
+class MyClient;
+
+// Define a new frame type
+class MyFrame: public wxFrame
+{ 
+  DECLARE_CLASS(MyFrame)
+public:
+  MyClient *sock;
+
+  MyFrame(void);
+  virtual ~MyFrame();
+  void OnCloseTest(wxCommandEvent& evt);
+  void OnExecTest1(wxCommandEvent& evt);
+  void OnExecUrlTest(wxCommandEvent& evt);
+  void OnQuitApp(wxCommandEvent& evt);
+  void OnExecOpenConnection(wxCommandEvent& evt);
+  void OnExecCloseConnection(wxCommandEvent& evt);
+  void UpdateStatus();
+
+  DECLARE_EVENT_TABLE()
+};
+
+
+IMPLEMENT_CLASS(MyFrame, wxFrame)
+
+/*
+ * Define a new derived SocketClient
+ */
+class MyClient: public wxSocketClient
+{
+public:
+  MyFrame *frame;
+
+  void OnNotify(wxRequestNotify WXUNUSED(flags)) { frame->UpdateStatus(); }
+};
+
+// ID for the menu quit command
+const SKDEMO_QUIT    = 101;
+const SKDEMO_CONNECT = 102;
+const SKDEMO_TEST1   = 103;
+const SKDEMO_TEST2   = 104;
+const SKDEMO_CLOSE   = 105;
+const SKDEMO_TEST3   = 106;
+const ID_TEST_CLOSE  = 107;
+
+IMPLEMENT_APP(MyApp)
+
+/*
+ * `Main program' equivalent, creating windows and returning main app frame
+ */
+bool MyApp::OnInit(void)
+{
+  // Create the main frame window
+  MyFrame *frame = new MyFrame();
+
+  // Give it an icon
+#ifdef wx_msw
+  frame->SetIcon(new wxIcon("mondrian"));
+#endif
+#ifdef wx_x
+  frame->SetIcon(new wxIcon("mondrian.xbm"));
+#endif
+
+  // Make a menubar
+  wxMenu *file_menu = new wxMenu();
+
+  file_menu->Append(SKDEMO_QUIT, "Exit");
+  wxMenuBar *menu_bar = new wxMenuBar;
+  menu_bar->Append(file_menu, "File");
+
+  wxMenu *socket_menu = new wxMenu();
+  socket_menu->Append(SKDEMO_CONNECT, "Open session");
+  socket_menu->AppendSeparator();
+  socket_menu->Append(SKDEMO_TEST1, "Start test 1");
+  socket_menu->Append(SKDEMO_TEST2, "Start test 2");
+  socket_menu->AppendSeparator();
+  socket_menu->Append(SKDEMO_CLOSE, "Close session");
+  socket_menu->AppendSeparator();
+  socket_menu->Append(SKDEMO_TEST3, "Start URL test");
+
+  menu_bar->Append(socket_menu, "Socket");
+
+  frame->SetMenuBar(menu_bar);
+
+  // Make a panel with a message
+  (void)new wxPanel(frame, 0, 0, 300, 100);
+
+  // Show the frame
+  frame->Show(TRUE);
+  
+  // Return the main frame window
+  return true;
+}
+
+/*
+ * MyFrame Constructor
+ */
+MyFrame::MyFrame():
+  wxFrame(NULL, -1, "wxSocket client demo",
+          wxDefaultPosition, wxSize(300, 200), wxDEFAULT_FRAME_STYLE)
+{
+  // Init all
+  wxSocketHandler::Master();
+
+  sock = new MyClient();
+  sock->SetFlags(wxSocketBase::WAITALL);
+  wxSocketHandler::Master().Register(sock);
+  sock->frame = this;
+  sock->SetNotify(wxSocketBase::REQ_LOST);
+  CreateStatusBar(2);
+  UpdateStatus();
+}
+
+MyFrame::~MyFrame()
+{
+  delete sock;
+}
+
+void MyFrame::OnQuitApp(wxCommandEvent& WXUNUSED(evt))
+{
+  Close(TRUE);
+}
+
+void MyFrame::OnExecOpenConnection(wxCommandEvent& WXUNUSED(evt))
+{
+  wxIPV4address addr;
+    
+  if (sock->IsConnected())
+    sock->Close();
+
+  wxString hname = wxGetTextFromUser("Enter the address of the wxSocket Sample Server", 
+                                  "Connect ...", "localhost");
+  addr.Hostname(hname);
+  addr.Service(3000);
+  sock->SetNotify(0);
+  sock->Connect(addr, TRUE);
+  if (!sock->IsConnected())
+    wxMessageBox("Can't connect to the specified host", "Alert !");
+
+  UpdateStatus();
+}
+
+void MyFrame::OnExecCloseConnection(wxCommandEvent& WXUNUSED(evt))
+{
+  if (sock)
+    sock->Close();
+  UpdateStatus();
+}
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+  EVT_BUTTON(ID_TEST_CLOSE, MyFrame::OnCloseTest)
+  EVT_MENU(SKDEMO_TEST1, MyFrame::OnExecTest1)
+  EVT_MENU(SKDEMO_TEST3, MyFrame::OnExecUrlTest)
+  EVT_MENU(SKDEMO_QUIT, MyFrame::OnQuitApp)
+  EVT_MENU(SKDEMO_CONNECT, MyFrame::OnExecOpenConnection)
+  EVT_MENU(SKDEMO_CLOSE, MyFrame::OnExecCloseConnection)
+END_EVENT_TABLE()
+
+void MyFrame::OnCloseTest(wxCommandEvent& evt)
+{
+  wxButton *button = (wxButton *)evt.GetEventObject();
+  wxDialog *dlg = (wxDialog *)button->GetParent();
+
+  dlg->EndModal(0);
+}
+
+void MyFrame::UpdateStatus()
+{
+  if (!sock->IsConnected()) {
+    SetStatusText("Not connected", 0);
+    SetStatusText("", 1);
+  } else {
+    wxIPV4address addr;
+    char s[100];
+
+    sock->GetPeer(addr);
+    sprintf(s, "Connected to %s", (const char *)addr.Hostname());
+    SetStatusText(s, 0);
+    sprintf(s, "Service: %d", addr.Service());
+    SetStatusText(s, 1);
+  } 
+}
+
+void MyFrame::OnExecTest1(wxCommandEvent& WXUNUSED(evt))
+{
+  if (!sock->IsConnected())
+    return;
+
+  wxDialog *dlgbox = new wxDialog(this, -1, "Test 1", wxDefaultPosition, wxSize(410, 270));
+  wxTextCtrl *text_win = new wxTextCtrl(dlgbox, -1, "",
+                                        wxPoint(0, 0), wxSize(400, 200),
+                                       wxTE_MULTILINE);
+  (void)new wxButton(dlgbox, ID_TEST_CLOSE, "Close",
+                     wxPoint(100, 210), wxSize(100, 40));
+  char *buf, *buf2;
+
+  dlgbox->Layout();
+  dlgbox->Show(TRUE);
+
+  text_win->WriteText("Initializing test 1 ...\n");
+  
+  /* Init */
+  buf = copystring("Salut ! Salut ! Salut ! Salut Toto\n");
+  buf2 = new char[strlen(buf)+1];
+  char c = 0xbe;
+  sock->WriteMsg(&c, 1);
+
+  /* No 1 */
+  text_win->WriteText("Sending some byte to the server ...");
+  sock->Write(buf, strlen(buf)+1);
+  text_win->WriteText("done\n");
+  text_win->WriteText("Receiving some byte from the server ...");
+  sock->Read(buf2, strlen(buf)+1);
+  text_win->WriteText("done\n");
+  
+  text_win->WriteText("Comparing the two buffers ...");
+  if (memcmp(buf, buf2, strlen(buf)+1) != 0) {
+    text_win->WriteText("Fail\n");
+    sock->Close();
+    UpdateStatus();
+  } else
+    text_win->WriteText("done\nTest 1 passed !\n");
+
+  dlgbox->Layout();
+  dlgbox->ShowModal();
+
+  delete [] buf;
+  delete [] buf2;
+  delete text_win;
+  delete dlgbox;
+}
+
+void MyFrame::OnExecUrlTest(wxCommandEvent& WXUNUSED(evt))
+{
+  wxString urlname = wxGetTextFromUser("Enter the address of the wxSocket Sample Server",
+                                     "Connect ...", "localhost");
+
+  wxURL url(urlname);
+  wxInputStream *datas = url.GetInputStream();
+
+  if (!datas)
+    wxMessageBox("Error in getting data from the URL.", "Alert !");
+  else {
+    wxMessageBox("Success !!", "OK !");
+    delete datas;
+  }
+}
diff --git a/samples/wxsocket/client.def b/samples/wxsocket/client.def
new file mode 100644 (file)
index 0000000..786b7d6
--- /dev/null
@@ -0,0 +1,8 @@
+NAME         Client
+DESCRIPTION  'Client'
+EXETYPE      WINDOWS
+STUB         'WINSTUB.EXE'
+CODE         PRELOAD MOVEABLE DISCARDABLE
+DATA         PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE     1024
+STACKSIZE    8192
diff --git a/samples/wxsocket/client.rc b/samples/wxsocket/client.rc
new file mode 100644 (file)
index 0000000..fbba8ad
--- /dev/null
@@ -0,0 +1,3 @@
+mondrian ICON mondrian.ico
+conn_icn ICON connect.ico
+#include "wx.rc"
diff --git a/samples/wxsocket/connect.ico b/samples/wxsocket/connect.ico
new file mode 100644 (file)
index 0000000..74f006f
Binary files /dev/null and b/samples/wxsocket/connect.ico differ
diff --git a/samples/wxsocket/makefile.b32 b/samples/wxsocket/makefile.b32
new file mode 100644 (file)
index 0000000..ef99515
--- /dev/null
@@ -0,0 +1,86 @@
+#
+# File:                makefile.b32
+# Author:      Patrick Halke, modified by Guilhem Lavaux
+# Created:     1997
+# Updated:     
+# Copyright:   (c) 1993, AIAI, University of Edinburgh
+#
+# "%W% %G%"
+#
+# Makefile : Builds 32bit wxstring library for Windows 3.1
+# and Borland C++ 4.x
+
+WXDIR = $(WXWIN)
+
+!include $(WXDIR)\src\makeb32.env
+
+WXLIBDIR = $(WXDIR)\lib
+WXLIB = $(WXDIR)\lib\wx32.lib
+SOCKETLIB = $(WXDIR)\lib\wxsocket.lib $(WXDIR)\lib\zlib.lib
+WXINC = $(WXDIR)\include\msw
+WXBASESRC = $(WXDIR)\src\base
+WXBASEINC = $(WXDIR)\include\base
+LIBS=$(WXLIB) $(SOCKETLIB) cw32 import32
+
+!ifndef DEBUG
+DEBUG=0
+!endif
+
+!if "$(FINAL)" == "0"
+LINKFLAGS=/v /Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -Od
+DEBUG_FLAGS= -v -DDEBUG=$(DEBUG)
+!else
+LINKFLAGS=/Tpe /L$(WXLIBDIR);$(BCCDIR)\lib
+OPT = -O2
+DEBUG_FLAGS = -DDEBUG=$(DEBUG)
+!endif
+
+CPPFLAGS=$(DEBUG_FLAGS) $(OPT) @$(CFG)
+
+CLIENT_TARGET=client
+SERVER_TARGET=server
+CLIENT_OBJECTS=client.obj
+SERVER_OBJECTS=server.obj
+
+.c.obj:
+       bcc32 $(CPPFLAGS) -P- -c {$< }
+
+all:    $(CLIENT_TARGET).exe $(SERVER_TARGET).exe
+
+$(CLIENT_TARGET).exe:   $(CLIENT_OBJECTS) $(CLIENT_TARGET).def $(CLIENT_TARGET).res
+  tlink32 $(LINKFLAGS) @&&!
+  c0w32.obj $(CLIENT_OBJECTS)
+  $(CLIENT_TARGET)
+  nul
+  $(LIBS)
+  $(CLIENT_TARGET).def
+!
+          brc32 -K $(CLIENT_TARGET).res
+
+client.obj:     client.cpp
+
+$(CLIENT_TARGET).res :      $(CLIENT_TARGET).rc $(WXDIR)\include\msw\wx.rc
+    brc32 -r /i$(BCCDIR)\include /i$(WXDIR)\include\msw /i$(WXDIR)\contrib\fafa $(CLIENT_TARGET)
+
+$(SERVER_TARGET).exe:   $(SERVER_OBJECTS) $(SERVER_TARGET).def $(SERVER_TARGET).res
+  tlink32 $(LINKFLAGS) @&&!
+  c0w32.obj $(SERVER_OBJECTS)
+  $(SERVER_TARGET)
+  nul
+  $(LIBS)
+  $(SERVER_TARGET).def
+!
+        brc32 -K $(SERVER_TARGET).res
+
+server.obj:     server.cpp
+
+$(SERVER_TARGET).res:   $(SERVER_TARGET).rc $(WXDIR)\include\msw\wx.rc
+    brc32 -r /i$(BCCDIR)\include /i$(WXDIR)\include\msw /i$(WXDIR)\contrib\fafa $(SERVER_TARGET)
+
+clean:
+        -erase *.obj
+        -erase *.exe
+        -erase *.res
+        -erase *.map
+        -erase *.rws
diff --git a/samples/wxsocket/makefile.g95 b/samples/wxsocket/makefile.g95
new file mode 100644 (file)
index 0000000..82457a1
--- /dev/null
@@ -0,0 +1,75 @@
+#
+# File:                makefile.unx
+# Author:      Stefan Hammes
+# Created:     1995
+# Updated:     
+# Copyright:   (c) 1995
+#
+# "%W% %G%"
+#
+# Makefile for wxString example (UNIX).
+# Change the WXDIR directory, and CPPFLAGS and LDFLAGS, for your system.
+
+WXDIR = ../..
+
+# All common UNIX compiler flags and options are now in
+# this central makefile.
+include $(WXDIR)/src/makeg95.env
+
+WXSOCKDIR = $(WXDIR)/contrib/wxsock
+WXSOCKLIB = $(WXSOCKDIR)/libwxsock.a
+
+OBJECTS = $(OBJDIR)/wx_sock.$(OBJSUFF) $(OBJDIR)/wx_addr.$(OBJSUFF) \
+       $(OBJDIR)/wx_pkman.$(OBJSUFF) $(OBJDIR)/wx_skflt.$(OBJSUFF) \
+       $(OBJDIR)/wx_lzw.$(OBJSUFF) \
+       $(OBJDIR)/wx_url.$(OBJSUFF) $(OBJDIR)/wx_ftp.$(OBJSUFF) \
+       $(OBJDIR)/wx_file.$(OBJSUFF) $(OBJDIR)/wx_nipc.$(OBJSUFF) \
+       $(OBJDIR)/wx_wipc.$(OBJSUFF) $(OBJDIR)/wx_sipc.$(OBJSUFF)
+
+TESTOBJECTS = $(OBJDIR)/test.$(OBJSUFF)
+TESTPROGRAM = $(WXSTRINGDIR)/test$(GUISUFFIX)
+
+LDFLAGS =  $(XLIB) -L$(WXSOCKDIR) -L$(WXDIR)/lib
+
+XVIEWLDLIBS = -lwxstring_ol -lwx_ol -lxview -lolgx -lX11 -lm $(COMPLIBS)
+MOTIFLDLIBS = -lwxstring_motif -lwx_motif -lXm -lXt -lX11 -lm $(COMPLIBS)
+HPLDLIBS = -lwxstring_hp -lwx_hp -lXm -lXt -lX11 -lm $(HPCOMPLIBS)
+# Default
+LDLIBS=$(MOTIFLDLIBS)
+
+all:   $(OBJDIR) $(WXSOCKLIB)
+
+demo:  $(TESTPROGRAM)
+
+.SUFFIXES:
+
+# Comment this out if 'say' doesn't speak on your system, or make it beep perhaps!
+done:
+       say dun
+
+wx:
+       cd $(WXDIR)/src/x; $(MAKE) -f makefile.unx GUI=$(GUI)
+
+$(OBJDIR):
+       mkdir $(OBJDIR)
+
+$(WXSOCKLIB): $(OBJECTS)       
+       rm -f $@
+       ar $(AROPTIONS) libwxsock.a $(OBJECTS)
+       $(RANLIB) libwxsock.a
+
+$(OBJDIR)/wx_sock.$(OBJSUFF):  wx_sock.$(SRCSUFF) wx_sock.h
+       $(CC) -c $(CPPFLAGS) -o $@ wx_sock.$(SRCSUFF)
+
+$(OBJDIR)/wx_addr.$(OBJSUFF):  wx_addr.$(SRCSUFF) wx_addr.h
+       $(CC) -c $(CPPFLAGS) -o $@ wx_addr.$(SRCSUFF)
+
+$(OBJDIR)/test.$(OBJSUFF):   test.$(SRCSUFF)
+       $(CC) -c $(CPPFLAGS) -o $@ test.$(SRCSUFF)
+
+$(TESTPROGRAM): $(OBJDIR)/test.$(OBJSUFF) $(WXLIB) $(WXSOCKLIB)
+       $(CC) $(CPPFLAGS) $(LDFLAGS) -o test$(GUISUFFIX) $(OBJDIR)/test.$(OBJSUFF) $(XVIEW_LINK) $(LDLIBS)
+
+clean:
+       rm -f $(OBJECTS) test$(GUISUFFIX) $(WXSTRINGLIB) $(OBJDIR)/test.$(OBJSUFF) core
+
diff --git a/samples/wxsocket/makefile.nt b/samples/wxsocket/makefile.nt
new file mode 100644 (file)
index 0000000..06defd3
--- /dev/null
@@ -0,0 +1,58 @@
+#
+# File:                makefile.nt
+# Author:      Stefan Hammes (stefan.hammes@urz.uni-heidelberg.de) / Julian Smart / Petr Houser (1996)
+# Created:     1995
+# Updated:=09
+# 
+# "%W% %G%"
+#
+# Makefile : Builds wxSock library for Windows NT / Win95
+!include <..\..\..\src\ntwxwin.mak>
+
+# Change WXDIR or WXWIN to wherever wxWindows is found
+#WXWIN = $(WX)
+WXDIR = $(WXWIN)
+WXINC = $(WXDIR)\include\msw
+
+WXSOCKDIR = $(WXDIR)\contrib\wxsock
+WXSOCKINC = $(WXSOCKDIR)
+WXSOCKLIB = $(WXSOCKDIR)\lib\wxsock.lib $(WXSOCKDIR)\lib\zlib.lib
+INC=-I$(WXBASEINC) -I$(WXINC) -I$(WXSOCKINC)
+
+WXLIB = $(WXDIR)\lib\wx.lib
+
+LIBS=$(WXSOCKLIB) wsock32.lib $(LIBS)
+#LIBS=$(WXLIB) $(WXSTRINGLIB) oldnames libw llibcew llibce commdlg shell
+
+all: client.exe server.exe
+
+wx:
+        cd $(WXDIR)\src\msw
+        nmake -f makefile.nt
+       cd $(ITSYDIR)
+
+client.exe:      $(WXDIR)\src\msw\dummy.obj $(WXLIB) $(WXSTRINGLIB) client.obj\
+                 client.res
+       $(link) -out:client.exe $(LINKFLAGS) $(DUMMYOBJ) client.obj \
+                                client.res $(LIBS)
+
+server.exe:      $(WXDIR)\src\msw\dummy.obj $(WXLIB) $(WXSTRINGLIB) server.obj
+       $(link) -out:server.exe $(LINKFLAGS) $(DUMMYOBJ) server.obj $(LIBS)
+
+client.obj:      client.$(SRCSUFF)
+       $(cc) $(CPPFLAGS2) /c /Tp $*.$(SRCSUFF)
+
+client.res:      client.rc $(WXDIR)\include\msw\wx.rc
+        $(rc) -r /i$(WXDIR)\include\msw /i$(WXDIR)\contrib\fafa -fo$@ client.rc
+
+
+server.obj:      server.$(SRCSUFF)
+        $(cc) $(CPPFLAGS2) /c /Tp $*.$(SRCSUFF)
+
+clean:
+       -erase *.obj
+       -erase *.exe
+       -erase *.lib
+       -erase *.res
+        -erase *.sbr
+        -erase *.pdb
diff --git a/samples/wxsocket/mondrian.ico b/samples/wxsocket/mondrian.ico
new file mode 100644 (file)
index 0000000..2310c5d
Binary files /dev/null and b/samples/wxsocket/mondrian.ico differ
diff --git a/samples/wxsocket/mondrian.xpm b/samples/wxsocket/mondrian.xpm
new file mode 100644 (file)
index 0000000..409f27a
--- /dev/null
@@ -0,0 +1,44 @@
+/* XPM */
+static char *mondrian_xpm[] = {
+/* columns rows colors chars-per-pixel */
+"32 32 6 1",
+"  c Black",
+". c Blue",
+"X c #00bf00",
+"o c Red",
+"O c Yellow",
+"+ c Gray100",
+/* pixels */
+"                                ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+" oooooo +++++++++++++++++++++++ ",
+"                                ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++ .... ",
+" ++++++ ++++++++++++++++++      ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++ ++++++++++++++++++ ++++ ",
+" ++++++                    ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+" ++++++ OOOOOOOOOOOO XXXXX ++++ ",
+"                                "
+};
diff --git a/samples/wxsocket/server.cpp b/samples/wxsocket/server.cpp
new file mode 100644 (file)
index 0000000..2c52190
--- /dev/null
@@ -0,0 +1,189 @@
+/*
+ * File:       server.cpp
+ * Purpose:    wxSocket: server demo
+ * Author:     LAVAUX Guilhem (from minimal.cc)
+ * Created:    June 1997
+ * Updated:    
+ * Copyright:  (c) 1993, AIAI, University of Edinburgh
+ *             (C) 1997, LAVAUX Guilhem
+ */
+#ifdef __GNUG__
+#pragma implementation
+#pragma interface
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include "wx/wxprec.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include "wx/wx.h"
+#endif
+#include "wx/socket.h"
+
+// Define a new application type
+class MyApp: public wxApp
+{ public:
+    bool OnInit(void);
+};
+
+class MyServer;
+
+// Define a new frame type
+class MyFrame: public wxFrame
+{ 
+  DECLARE_EVENT_TABLE()
+public:
+  MyServer *sock;
+  int nb_clients;
+
+  MyFrame(wxFrame *frame);
+  virtual ~MyFrame();
+  void Menu_Exit(wxCommandEvent& evt);
+  void ExecTest1(wxSocketBase *sock_o);
+  void UpdateStatus(int incr);
+};
+
+#define SKDEMO_QUIT 101
+
+BEGIN_EVENT_TABLE(MyFrame, wxFrame)
+  EVT_MENU(SKDEMO_QUIT, MyFrame::Menu_Exit)
+END_EVENT_TABLE()
+
+class MySock: public wxSocketBase {
+public:
+  MyFrame *frame;
+
+  void OldOnNotify(wxRequestEvent flags);
+};
+
+class MyServer: public wxSocketServer {
+public:
+  MyFrame *frame;
+
+  MyServer(wxSockAddress& addr) : wxSocketServer(addr) { }
+  void OldOnNotify(wxRequestEvent flags);
+};
+
+IMPLEMENT_APP(MyApp)
+
+// `Main program' equivalent, creating windows and returning main app frame
+bool MyApp::OnInit(void)
+{
+  // Create the main frame window
+  MyFrame *frame = new MyFrame(NULL);
+
+  // Give it an icon
+#ifdef wx_msw
+  frame->SetIcon(new wxIcon("mondrian"));
+#endif
+#ifdef wx_x
+  frame->SetIcon(new wxIcon("aiai.xbm"));
+#endif
+
+  // Make a menubar
+  wxMenu *file_menu = new wxMenu;
+
+  file_menu->Append(SKDEMO_QUIT, "E&xit");
+  wxMenuBar *menu_bar = new wxMenuBar;
+  menu_bar->Append(file_menu, "File");
+  frame->SetMenuBar(menu_bar);
+
+  // Make a panel with a message
+  (void)new wxPanel(frame, 0, 0, 300, 100);
+
+  // Show the frame
+  frame->Show(TRUE);
+  
+  // Return the main frame window
+  return TRUE;
+}
+
+void MySock::OldOnNotify(wxRequestEvent flags)
+{
+  extern wxList wxPendingDelete;
+
+  switch (flags) {
+  case EVT_READ:
+    unsigned char c;
+
+    ReadMsg((char *)&c, 1);
+    if (c == 0xbe)
+      frame->ExecTest1(this);
+
+    break;
+  case EVT_LOST:
+    frame->UpdateStatus(-1);
+    wxPendingDelete.Append(this);
+    break;
+  }
+}
+
+void MyServer::OldOnNotify(wxRequestEvent WXUNUSED(flags))
+{
+  MySock *sock2 = new MySock();
+
+  if (!AcceptWith(*sock2))
+    return;
+
+  m_handler->Register(sock2);
+
+  sock2->SetFlags(NONE);
+  sock2->frame = frame;
+  sock2->SetNotify(REQ_READ | REQ_LOST);
+  sock2->Notify(TRUE);
+  frame->UpdateStatus(1);
+}
+
+// My frame Constructor
+MyFrame::MyFrame(wxFrame *frame):
+  wxFrame(frame, -1, "wxSocket sample (server)", wxDefaultPosition,
+          wxSize(300, 200))
+{
+  wxIPV4address addr;
+  addr.Service(3000);
+
+  // Init all
+  wxSocketHandler::Master();
+
+  sock = new MyServer(addr);
+  wxSocketHandler::Master().Register(sock);
+  sock->frame = this;
+  sock->SetNotify(wxSocketBase::REQ_ACCEPT);
+  sock->Notify(TRUE);
+  nb_clients = 0;
+
+  CreateStatusBar(1);
+  UpdateStatus(0);
+}
+
+MyFrame::~MyFrame()
+{
+  delete sock;
+}
+
+// Intercept menu commands
+void MyFrame::Menu_Exit(wxCommandEvent& event)
+{
+  Close(TRUE);
+}
+
+void MyFrame::ExecTest1(wxSocketBase *sock_o)
+{
+  char *buf = new char[50];
+  size_t l;
+
+  l = sock_o->Read(buf, 50).LastCount();
+  sock_o->Write(buf, l);
+}
+
+void MyFrame::UpdateStatus(int incr)
+{
+  char s[30];
+  nb_clients += incr;
+  sprintf(s, "%d clients connected", nb_clients);
+  SetStatusText(s);
+}
diff --git a/samples/wxsocket/server.def b/samples/wxsocket/server.def
new file mode 100644 (file)
index 0000000..21027a5
--- /dev/null
@@ -0,0 +1,8 @@
+NAME         Server
+DESCRIPTION  'Server'
+EXETYPE      WINDOWS
+STUB         'WINSTUB.EXE'
+CODE         PRELOAD MOVEABLE DISCARDABLE
+DATA         PRELOAD MOVEABLE MULTIPLE
+HEAPSIZE     4096
+STACKSIZE    8192
diff --git a/samples/wxsocket/server.rc b/samples/wxsocket/server.rc
new file mode 100644 (file)
index 0000000..44854d6
--- /dev/null
@@ -0,0 +1,4 @@
+mondrian ICON "mondrian.ico"
+conn_icn ICON "connect.ico"
+#include "wx.rc"
+
index 93850acd65e90aa9615f1d6caca4c17c08a8aee0..8056bdadedc5693536d51efcb5bf5d4d23bad2a7 100644 (file)
 
 #include "wx/datstrm.h"
 
+// ---------------------------------------------------------------------------
+// wxDataInputStream
+// ---------------------------------------------------------------------------
+
 wxDataInputStream::wxDataInputStream(wxInputStream& s)
   : wxFilterInputStream(s)
 {
@@ -126,6 +130,10 @@ wxString wxDataInputStream::ReadString()
   return wx_string;
 }
 
+// ---------------------------------------------------------------------------
+// wxDataOutputStream
+// ---------------------------------------------------------------------------
+
 wxDataOutputStream::wxDataOutputStream(wxOutputStream& s)
  : wxFilterOutputStream(s)
 {
@@ -192,3 +200,12 @@ void wxDataOutputStream::WriteDouble(double d)
 #endif
   Write(buf, 10);
 }
+
+// ---------------------------------------------------------------------------
+// wxDataStream
+// ---------------------------------------------------------------------------
+
+wxDataStream::wxDataStream(wxStream& stream)
+ : wxDataInputStream(stream), wxDataOutputStream(stream)
+{
+}
diff --git a/src/common/ftp.cpp b/src/common/ftp.cpp
new file mode 100644 (file)
index 0000000..461dd93
--- /dev/null
@@ -0,0 +1,378 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        ftp.cpp
+// Purpose:     FTP protocol
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     07/07/1997
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997, 1998 Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "ftp.h"
+#endif
+#include <memory.h>
+#include <stdlib.h>
+#include "wx/string.h"
+#include "wx/utils.h"
+// #include "wx/data.h"
+#define WXSOCK_INTERNAL
+#include "wx/sckaddr.h"
+#undef WXSOCK_INTERNAL
+#include "wx/socket.h"
+#include "wx/url.h"
+#include "wx/sckstrm.h"
+#include "wx/protocol/protocol.h"
+#include "wx/protocol/ftp.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#define FTP_BSIZE 1024
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxFTP, wxProtocol)
+IMPLEMENT_PROTOCOL(wxFTP, "ftp", "ftp", TRUE)
+#endif
+
+////////////////////////////////////////////////////////////////
+////// wxFTP constructor and destructor ////////////////////////
+////////////////////////////////////////////////////////////////
+
+wxFTP::wxFTP()
+  : wxProtocol()
+{
+  char tmp[256];
+
+  m_lastError = wxPROTO_NOERR;
+  m_streaming = FALSE;
+
+  m_user = "anonymous";
+  wxGetUserName(tmp, 256);
+  m_passwd.sprintf("%s@",tmp);
+  wxGetHostName(tmp, 256);
+  m_passwd += tmp;
+
+  SetNotify(0);
+}
+
+wxFTP::~wxFTP()
+{
+  SendCommand("QUIT", '2');
+}
+
+////////////////////////////////////////////////////////////////
+////// wxFTP connect and login methods /////////////////////////
+////////////////////////////////////////////////////////////////
+bool wxFTP::Connect(wxSockAddress& addr)
+{
+  if (!m_handler) {
+    m_lastError = wxPROTO_NOHNDLR;
+    return FALSE;
+  }
+
+  if (!wxProtocol::Connect(addr)) {
+    m_lastError = wxPROTO_NETERR;
+    return FALSE;
+  }
+
+  if (!m_user || !m_passwd) {
+    m_lastError = wxPROTO_CONNERR;
+    return FALSE;
+  }
+
+  wxString command;
+
+  if (!GetResult('2')) {
+    Close();
+    return FALSE;
+  }
+
+  command.sprintf("USER %s", (const char *)m_user);
+  if (!SendCommand(command, '3')) {
+    Close();
+    return FALSE;
+  }
+
+  command.sprintf("PASS %s", (const char *)m_passwd);
+  if (!SendCommand(command, '2')) {
+    Close();
+    return FALSE;
+  }
+
+  return TRUE;
+}
+
+bool wxFTP::Connect(const wxString& host)
+{
+  wxIPV4address addr;
+  wxString my_host = host;
+
+  addr.Hostname(my_host);
+  addr.Service("ftp");
+
+  return Connect(addr);
+}
+
+bool wxFTP::Close()
+{
+  if (m_streaming) {
+    m_lastError = wxPROTO_STREAMING;
+    return FALSE;
+  }
+  if (m_connected)
+    SendCommand(wxString("QUIT"), '2');
+  return wxSocketClient::Close();
+}
+
+////////////////////////////////////////////////////////////////
+////// wxFTP low-level methods /////////////////////////////////
+////////////////////////////////////////////////////////////////
+bool wxFTP::SendCommand(const wxString& command, char exp_ret)
+{
+  wxString tmp_str;
+
+  if (m_streaming) {
+    m_lastError = wxPROTO_STREAMING;
+    return FALSE;
+  }
+  tmp_str = command + "\r\n";
+  if (Write((char *)tmp_str.GetData(), tmp_str.Length()).Error()) {
+    m_lastError = wxPROTO_NETERR;
+    return FALSE;
+  }
+  return GetResult(exp_ret);
+}
+
+bool wxFTP::GetResult(char exp)
+{
+  if ((m_lastError = GetLine(this, m_lastResult)))
+    return FALSE;
+  if (m_lastResult[0UL] != exp) {
+    m_lastError = wxPROTO_PROTERR;
+    return FALSE;
+  }
+
+  if (m_lastResult[3UL] == '-') {
+    wxString key = m_lastResult.Left((size_t)3);
+
+    key += ' ';
+
+    while (m_lastResult.Index(key) != 0) {
+      if ((m_lastError = GetLine(this, m_lastResult)))
+        return FALSE;
+    }
+  }
+  return TRUE;
+}
+
+////////////////////////////////////////////////////////////////
+////// wxFTP low-level methods /////////////////////////////////
+////////////////////////////////////////////////////////////////
+bool wxFTP::ChDir(const wxString& dir)
+{
+  wxString str = dir;
+
+  str.Prepend("CWD ");
+  return SendCommand(str, '2');
+}
+
+bool wxFTP::MkDir(const wxString& dir)
+{
+  wxString str = dir;
+  str.Prepend("MKD ");
+  return SendCommand(str, '2');
+}
+
+bool wxFTP::RmDir(const wxString& dir)
+{
+  wxString str = dir;
+  
+  str.Prepend("PWD ");
+  return SendCommand(str, '2');
+}
+
+wxString wxFTP::Pwd()
+{
+  int beg, end;
+
+  if (!SendCommand("PWD", '2'))
+    return wxString((char *)NULL);
+  
+  beg = m_lastResult.Find('\"',FALSE);
+  end = m_lastResult.Find('\"',TRUE);
+
+  return wxString(beg+1, end);
+}
+
+bool wxFTP::Rename(const wxString& src, const wxString& dst)
+{
+  wxString str;
+
+  str = "RNFR " + src;
+  if (!SendCommand(str, '3'))
+    return FALSE;
+
+  str = "RNTO " + dst;
+  return SendCommand(str, '2');
+}
+
+bool wxFTP::RmFile(const wxString& path)
+{
+  wxString str;
+
+  str = "DELE ";
+  str += path;
+  return SendCommand(str, '2');
+}
+
+////////////////////////////////////////////////////////////////
+////// wxFTP download*upload ///////////////////////////////////
+////////////////////////////////////////////////////////////////
+
+class wxInputFTPStream : public wxSocketInputStream {
+public:
+  wxFTP *m_ftp;
+
+  wxInputFTPStream(wxFTP *ftp_clt, wxSocketBase *sock)
+    : wxSocketInputStream(*sock), m_ftp(ftp_clt) {}
+  virtual ~wxInputFTPStream(void)
+  { 
+     if (Eof())
+       m_ftp->GetResult('2');
+     else
+       m_ftp->Abort();
+     delete m_i_socket;
+  }
+};
+
+class wxOutputFTPStream : public wxSocketOutputStream {
+public:
+  wxFTP *m_ftp;
+
+  wxOutputFTPStream(wxFTP *ftp_clt, wxSocketBase *sock)
+    : wxSocketOutputStream(*sock), m_ftp(ftp_clt) {}
+  virtual ~wxOutputFTPStream(void)
+  {
+     if (Bad())
+       m_ftp->GetResult('2');
+     else
+       m_ftp->Abort();
+     delete m_o_socket;
+  }
+};
+
+wxSocketClient *wxFTP::GetPort()
+{
+  wxIPV4address addr;
+  wxSocketClient *client;
+  struct sockaddr sin;
+  int a[6];
+  wxString straddr;
+  int addr_pos;
+
+  if (!SendCommand("PASV", '2'))
+    return NULL;
+
+  sin.sa_family = AF_INET;
+  addr_pos = m_lastResult.Find('(');
+  if (addr_pos == -1) {
+    m_lastError = wxPROTO_PROTERR;
+    return NULL;
+  }
+  straddr = m_lastResult(addr_pos+1, m_lastResult.Length());
+  sscanf((const char *)straddr,"%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));
+
+  client = m_handler->CreateClient();
+  if (!client->Connect(addr)) {
+    delete client;
+    return NULL;
+  }
+  client->Notify(FALSE);
+
+  return client;
+}
+
+bool wxFTP::Abort(void)
+{
+  m_streaming = FALSE;
+  if (!SendCommand("ABOR", '4'))
+    return FALSE;
+  return GetResult('2');
+}
+
+wxInputStream *wxFTP::GetInputStream(const wxString& path)
+{
+  wxString tmp_str;
+
+  if (!SendCommand("TYPE I", '2'))
+    return NULL;
+
+  wxSocketClient *sock = GetPort();
+
+  if (!sock) {
+    m_lastError = wxPROTO_NETERR;
+    return NULL;
+  }
+
+  tmp_str = "RETR " + path;
+  if (!SendCommand(tmp_str, '1'))
+    return NULL;
+
+  return new wxInputFTPStream(this, sock);
+}
+
+wxOutputStream *wxFTP::GetOutputStream(const wxString& path)
+{
+  wxString tmp_str;
+
+  if (!SendCommand("TYPE I", '2'))
+    return NULL;
+
+  wxSocketClient *sock = GetPort();
+
+  tmp_str = "STOR " + path;
+  if (!SendCommand(tmp_str, '1'))
+    return FALSE;
+
+  return new wxOutputFTPStream(this, sock);
+}
+
+wxList *wxFTP::GetList(const wxString& wildcard)
+{
+  wxList *file_list = new wxList;
+  wxSocketBase *sock = GetPort();
+  wxString tmp_str = "NLST";
+
+  if (!wildcard.IsNull())
+    tmp_str += wildcard;
+
+  if (!SendCommand(tmp_str, '1')) {
+    delete sock;
+    delete file_list;
+    return NULL;
+  }
+
+  while (GetLine(sock, tmp_str) == wxPROTO_NOERR) {
+    file_list->Append((wxObject *)(new wxString(tmp_str)));
+  }
+
+  if (!GetResult('2')) {
+    delete sock;
+    file_list->DeleteContents(TRUE);
+    delete file_list;
+    return NULL;
+  }
+
+  return file_list;
+}
diff --git a/src/common/http.cpp b/src/common/http.cpp
new file mode 100644 (file)
index 0000000..4f90e22
--- /dev/null
@@ -0,0 +1,251 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        http.cpp
+// Purpose:     HTTP protocol
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     August 1997
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997, 1998 Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "http.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "wx/string.h"
+#include "wx/tokenzr.h"
+#include "wx/socket.h"
+#include "wx/protocol/protocol.h"
+#include "wx/protocol/http.h"
+#include "wx/sckstrm.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxHTTP, wxProtocol)
+IMPLEMENT_PROTOCOL(wxHTTP, "http", "80", TRUE)
+#endif
+
+#define HTTP_BSIZE 2048
+
+wxHTTP::wxHTTP()
+  : wxProtocol(),
+    m_headers(wxKEY_STRING)
+{
+  m_addr = NULL;
+  m_read = FALSE;
+
+  SetNotify(REQ_LOST);
+}
+
+wxHTTP::~wxHTTP()
+{
+  // wxString isn't a wxObject
+  wxNode *node = m_headers.First(); 
+  wxString *string;
+
+  while (node) {
+    string = (wxString *)node->Data();
+    delete string;
+    node = node->Next();
+  }
+}
+
+wxString wxHTTP::GetContentType()
+{
+  return GetHeader("Content-Type");
+}
+
+void wxHTTP::SetHeader(const wxString& header, const wxString& h_data)
+{
+  if (m_read) {
+    m_headers.Clear();
+    m_read = FALSE;
+  }
+
+  wxNode *node = m_headers.Find(header);
+
+  if (!node)
+    m_headers.Append(header, (wxObject *)(new wxString(h_data)));
+  else {
+    wxString *str = (wxString *)node->Data();
+    (*str) = h_data;
+  }
+}
+
+wxString wxHTTP::GetHeader(const wxString& header)
+{
+  wxNode *node = m_headers.Find(header);
+  if (!node)
+    return (char *)NULL;
+
+  return *((wxString *)node->Data());
+}
+
+void wxHTTP::SendHeaders()
+{
+  wxNode *head = m_headers.First();
+
+  while (head) {
+    wxString *str = (wxString *)head->Data();
+    char buf[100];
+
+    sprintf(buf, "%s: %s\n\r", head->key.string, str->GetData());
+    Write(buf, strlen(buf));
+
+    head = head->Next();
+  }
+}
+
+bool wxHTTP::ParseHeaders()
+{
+  wxString line;
+
+  m_headers.Clear();
+  m_read = TRUE;
+
+  while (1) {
+    m_error = GetLine(this, line);
+    if (m_error != wxPROTO_NOERR)
+      return FALSE;
+
+    if (line.Length() == 0)
+      break;
+
+    int pos = line.Find(':');
+    if (pos == -1)
+      return FALSE;
+
+    wxString left_str = line(0, pos);
+    wxString right_str = line(pos+1, line.Length());
+
+    right_str = right_str.Strip(wxString::leading);
+
+    wxString *str = new wxString(right_str);
+
+    m_headers.Append(left_str, (wxObject *) str);
+  }
+  return TRUE;
+}
+
+bool wxHTTP::Connect(const wxString& host)
+{
+  wxIPV4address *addr;
+
+  if (m_connected) {
+    delete m_addr;
+    m_addr = NULL;
+    Close();
+  }
+
+  m_addr = addr = new wxIPV4address();
+
+  if (!addr->Hostname(host)) {
+    delete m_addr;
+    m_addr = NULL;
+    m_error = wxPROTO_NETERR;
+    return FALSE;
+  }
+
+  if (!addr->Service("http"))
+    addr->Service(80);
+
+  return TRUE;
+}
+
+bool wxHTTP::Connect(wxSockAddress& addr)
+{
+  struct sockaddr *raw_addr;
+  size_t len;
+
+  m_addr = (wxSockAddress *)(addr.GetClassInfo()->CreateObject());
+
+  addr.Build(raw_addr, len);
+  m_addr->Disassemble(raw_addr, len);
+
+  return TRUE;
+}
+
+bool wxHTTP::BuildRequest(const wxString& path, wxHTTP_Req req)
+{
+  char *tmp_buf;
+  char buf[HTTP_BSIZE];
+
+  switch (req) {
+  case wxHTTP_GET:
+    tmp_buf = "GET";
+    break;
+  default:
+    return FALSE;
+  }
+
+  sprintf(buf, "%s %s HTTP/1.0\n\r", tmp_buf, (const char *)path);
+  Write(buf, strlen(buf));
+  SendHeaders();
+  sprintf(buf, "\n\r");
+  Write(buf, strlen(buf));
+
+  wxString tmp_str;
+
+  m_error = GetLine(this, tmp_str);
+  if (m_error != wxPROTO_NOERR)
+    return FALSE;
+
+  if (!tmp_str.Contains("HTTP/")) {
+    // TODO: support HTTP v0.9 which can have no header.
+    SetHeader("Content-Length", "-1");
+    SetHeader("Content-Type", "none/none");
+    return TRUE;
+  }
+
+  wxStringTokenizer token(tmp_str,' ');
+  wxString tmp_str2;
+
+  token.NextToken();
+  tmp_str2 = token.NextToken();
+
+  switch (atoi(tmp_str2)) {
+  case 200:
+    break;
+  default:
+    m_error = wxPROTO_NOFILE;
+    return FALSE;
+  }
+
+  return ParseHeaders();
+}
+
+class wxHTTPStream : public wxSocketInputStream {
+public:
+  wxHTTP *m_http;
+  wxHTTPStream(wxHTTP *http) : wxSocketInputStream(*http), m_http(http) {}
+  virtual ~wxHTTPStream(void) { m_http->Abort(); }
+};
+
+bool wxHTTP::Abort(void)
+{
+  return wxSocketClient::Close();
+}
+
+wxInputStream *wxHTTP::GetInputStream(const wxString& path)
+{
+  wxHTTPStream *inp_stream = new wxHTTPStream(this);
+
+  if (!m_addr || m_connected) {
+    m_error = wxPROTO_CONNERR;
+    return NULL;
+  }
+
+  if (!wxProtocol::Connect(*m_addr))
+    return NULL;
+
+  if (!BuildRequest(path, wxHTTP_GET))
+    return NULL;
+
+  return inp_stream;
+}
diff --git a/src/common/protocol.cpp b/src/common/protocol.cpp
new file mode 100644 (file)
index 0000000..21df7e8
--- /dev/null
@@ -0,0 +1,109 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        protocol.cpp
+// Purpose:     Implement protocol base class
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     07/07/1997
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997, 1998 Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "protocol.h"
+#endif
+
+#ifdef WXPREC
+#include <wx/wxprec.h>
+#else
+#include <wx/wx.h>
+#endif
+
+#include "wx/protocol/protocol.h"
+#include "wx/url.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+/////////////////////////////////////////////////////////////////
+// wxProtoInfo
+/////////////////////////////////////////////////////////////////
+
+/*
+ * --------------------------------------------------------------
+ * --------- wxProtoInfo CONSTRUCTOR ----------------------------
+ * --------------------------------------------------------------
+ */
+
+wxProtoInfo::wxProtoInfo(const char *name, const char *serv,
+                         const bool need_host1, wxClassInfo *info)
+{
+  m_protoname = name;
+  m_servname = serv;
+  m_cinfo = info;
+  m_needhost = need_host1;
+  next = wxURL::g_protocols;
+  wxURL::g_protocols = this;
+}
+
+/////////////////////////////////////////////////////////////////
+// wxProtocol ///////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+
+IMPLEMENT_ABSTRACT_CLASS(wxProtocol, wxSocketClient)
+
+wxProtocol::wxProtocol()
+ : wxSocketClient()
+{
+}
+
+bool wxProtocol::Reconnect()
+{
+  wxIPV4address addr;
+
+  if (!GetPeer(addr)) {
+    Close();
+    return FALSE;
+  }
+  if (!Close())
+    return FALSE;
+  if (!Connect(addr))
+    return FALSE;
+  return TRUE;
+}
+
+wxProtocolError GetLine(wxSocketBase *sock, wxString& result) {
+#define PROTO_BSIZE 2048
+  size_t avail, size;
+  char tmp_buf[PROTO_BSIZE], tmp_str[PROTO_BSIZE];
+  char *ret;
+  bool found;
+
+  avail = sock->Read(tmp_buf, PROTO_BSIZE).LastCount();
+  if (sock->LastError() != 0 || avail == 0)
+    return wxPROTO_NETERR;
+
+  memcpy(tmp_str, tmp_buf, avail);
+
+// Not implemented on all systems
+// ret = (char *)memccpy(tmp_str, tmp_buf, '\n', avail);
+  found = FALSE;
+  for (ret=tmp_str;ret < (tmp_str+avail); ret++)
+     if (*ret == '\n') {
+       found = TRUE;
+       break;
+     }
+
+  if (!found)
+    return wxPROTO_PROTERR;
+  *ret = 0;
+
+  result = tmp_str;
+  result = result.Left(result.Length()-1);
+
+  size = ret-tmp_str+1;
+  sock->CreatePushbackBefore(&tmp_buf[size], avail-size);
+  return wxPROTO_NOERR;
+#undef PROTO_BSIZE
+}
diff --git a/src/common/sckaddr.cpp b/src/common/sckaddr.cpp
new file mode 100644 (file)
index 0000000..55a9521
--- /dev/null
@@ -0,0 +1,391 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        sckaddr.cpp
+// Purpose:     Network address manager
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     26/04/97
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997, 1998 Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "sckaddr.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <memory.h>
+
+#include "wx/defs.h"
+#include "wx/object.h"
+
+#if defined(__WINDOWS__)
+#include <winsock.h>
+#endif // __WINDOWS__
+
+#if defined(__UNIX__)
+
+#ifdef VMS
+#include <socket.h>
+#include <in.h>
+#else
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#endif
+#include <unistd.h>
+#include <netdb.h>
+
+#endif // __UNIX__
+
+#include "wx/sckaddr.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#define CHECK_ADDRTYPE(var, type)
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_ABSTRACT_CLASS(wxSockAddress, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxIPV4address, wxSockAddress)
+#ifdef ENABLE_IPV6
+IMPLEMENT_DYNAMIC_CLASS(wxIPV6address, wxSockAddress)
+#endif
+#ifdef __UNIX__
+IMPLEMENT_DYNAMIC_CLASS(wxUNIXaddress, wxSockAddress)
+#endif
+#endif
+
+wxIPV4address::wxIPV4address()
+{
+  m_addr = new sockaddr_in;
+  Clear();
+}
+
+wxIPV4address::~wxIPV4address()
+{
+}
+
+int wxIPV4address::SockAddrLen()
+{
+  return sizeof(*m_addr);
+}
+
+int wxIPV4address::GetFamily()
+{
+  return AF_INET;
+}
+
+void wxIPV4address::Clear()
+{
+  memset(m_addr, 0, sizeof(*m_addr));
+  m_addr->sin_family = AF_INET;
+  m_addr->sin_addr.s_addr = INADDR_ANY;
+}
+
+/*
+const wxSockAddress& wxIPV4address::operator =(const wxSockAddress& addr)
+{
+  wxIPV4address *ip_addr = (wxIPV4address *)&addr;
+  CHECK_ADDRTYPE(addr, wxIPV4address);
+  m_addr = ip_addr->m_addr;
+  return *this;
+}
+*/
+
+bool wxIPV4address::Hostname(const wxString& name)
+{
+  struct hostent *hostent;
+  struct in_addr *addr;
+  
+  if (name.IsNull())
+    return FALSE;
+  
+  if (!name.IsNumber()) {
+    if ((hostent = gethostbyname(name.GetData())) == 0) {
+      return FALSE;
+    }
+  } else {
+    long len_addr = inet_addr(name.GetData());
+    if (len_addr == -1)
+      return FALSE;
+    m_addr->sin_addr.s_addr = len_addr;
+    return TRUE;
+  }
+
+  addr = (struct in_addr *) *(hostent->h_addr_list);
+
+  m_addr->sin_addr.s_addr = addr[0].s_addr;
+  return TRUE;
+}
+
+bool wxIPV4address::Hostname(unsigned long addr)
+{
+  m_addr->sin_addr.s_addr = htonl(addr);
+  return TRUE; 
+}
+
+bool wxIPV4address::Service(const wxString& name)
+{
+  struct servent *servent;
+  
+  if (name.IsNull())
+    return FALSE;
+  
+  if (!name.IsNumber()) {
+    if ((servent = getservbyname(name, "tcp")) == 0)
+      return FALSE;
+  } else {
+    if ((servent = getservbyport(atoi(name), "tcp")) == 0) {
+      m_addr->sin_port = htons(atoi(name));
+      return TRUE;
+    }
+  }
+  
+  m_addr->sin_port = servent->s_port;
+  return TRUE;
+}
+
+bool wxIPV4address::Service(unsigned short port)
+{
+  m_addr->sin_port = htons(port);
+  return TRUE;
+}
+
+bool wxIPV4address::LocalHost()
+{
+  static char buf[256];
+  
+  if (gethostname(buf, sizeof(buf)) < 0)
+    return Hostname("localhost");
+  else
+    return Hostname(buf);
+}
+
+wxString wxIPV4address::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);
+}
+
+unsigned short wxIPV4address::Service()
+{
+  return ntohs(m_addr->sin_port); 
+}
+
+void wxIPV4address::Build(struct sockaddr *&addr, size_t& len)
+{
+  addr = (struct sockaddr *)m_addr;
+  len = sizeof(*m_addr);
+}
+
+void wxIPV4address::Disassemble(struct sockaddr *addr, size_t len)
+{
+  if (len != sizeof(*m_addr))
+    return;
+  *m_addr = *(struct sockaddr_in *)addr;
+}
+
+#ifdef IPV6_ENABLE
+
+wxIPV6address::wxIPV6address()
+{
+  m_addr = new sockaddr_in6;
+  Clear();
+}
+
+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)
+{
+  struct hostent *hostent;
+  struct in_addr *addr;
+  
+  if (name.IsNull())
+    return FALSE;
+  
+  if (!name.IsNumber()) {
+    hostent = gethostbyname2((char*) name, AF_INET6);
+    if (!hostent)
+      return FALSE;
+  } else {
+    // Don't how to do
+    return FALSE;
+  }
+
+  addr = (struct in6_addr *) *(hostent->h_addr_list);
+
+  m_addr->sin6_addr.s6_addr = addr[0].s6_addr;
+  return TRUE;
+}
+
+bool wxIPV6address::Hostname(unsigned char addr[16])
+{
+  m_addr->sin6_addr.s6_addr = addr;
+  return TRUE;
+}
+
+bool wxIPV6address::Service(const char *name)
+{
+  struct servent *servent;
+  
+  if (!name || !strlen(name))
+    return FALSE;
+  
+  if (!isdigit(*name)) {
+    if ((servent = getservbyname((char*) name, "tcp")) == 0)
+      return FALSE;
+  } else {
+    if ((servent = getservbyport(atoi(name), "tcp")) == 0) {
+      m_addr->sin_port = htons(atoi(name));
+      return TRUE;
+    }
+  }
+  
+  m_addr->sin_port = servent->s_port;
+  return TRUE;
+}
+
+bool wxIPV6address::Service(unsigned short port)
+{
+  m_addr->sin_port = htons(port);
+  return TRUE;
+}
+
+bool wxIPV6address::LocalHost()
+{
+  static char buf[256];
+  
+  if (gethostname(buf, sizeof(buf)) < 0)
+    return Hostname("localhost");
+  else
+    return Hostname(buf);
+}
+
+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);
+}
+
+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;
+}
+
+#endif
+
+#ifdef __UNIX__
+#include <sys/un.h>
+
+wxUNIXaddress::wxUNIXaddress()
+{
+  m_addr = new sockaddr_un;
+  Clear();
+}
+
+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)
+{
+  sprintf(m_addr->sun_path, "%s", WXSTRINGCAST fname);
+}
+
+wxString wxUNIXaddress::Filename()
+{
+  return wxString(m_addr->sun_path);
+}
+
+void wxUNIXaddress::Build(struct sockaddr*& addr, size_t& len)
+{
+  addr = (struct sockaddr *)m_addr;
+  len = sizeof(*m_addr);
+}
+
+void wxUNIXaddress::Disassemble(struct sockaddr *addr, size_t len)
+{
+  if (len != sizeof(*m_addr))
+    return;
+  *m_addr = *(struct sockaddr_un *)addr;
+}
+#endif
diff --git a/src/common/sckfile.cpp b/src/common/sckfile.cpp
new file mode 100644 (file)
index 0000000..b1e60ae
--- /dev/null
@@ -0,0 +1,40 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        sckfile.cpp
+// Purpose:     File protocol
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     20/07/97
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997, 1998 Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "sckfile.h"
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <wx/fstream.h>
+#include "wx/protocol/file.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxFileProto, wxProtocol)
+IMPLEMENT_PROTOCOL(wxFileProto, "file", NULL, FALSE)
+#endif
+
+wxFileProto::wxFileProto()
+  : wxProtocol()
+{
+}
+
+wxFileProto::~wxFileProto()
+{
+}
+
+wxInputStream *wxFileProto::GetInputStream(const wxString& path)
+{
+  return new wxFileInputStream(path);
+}
diff --git a/src/common/sckipc.cpp b/src/common/sckipc.cpp
new file mode 100644 (file)
index 0000000..55fcb31
--- /dev/null
@@ -0,0 +1,503 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        sckipc.cpp
+// Purpose:     Interprocess communication implementation (wxSocket version)
+// Author:      Julian Smart, Guilhem Lavaux
+// Modified by: Guilhem Lavaux (big rewrite) May 1997, 1998
+// Created:     1993
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart 1993, Guilhem Lavaux 1997, 1998
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "sckipc.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#ifdef WXPREC
+#include <wx/wxprec.h>
+#else
+#include <wx/wx.h>
+#endif
+
+#include "wx/socket.h"
+#include "wx/sckipc.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_DYNAMIC_CLASS(wxTCPServer, wxServerBase)
+IMPLEMENT_DYNAMIC_CLASS(wxTCPClient, wxClientBase)
+IMPLEMENT_DYNAMIC_CLASS(wxTCPConnection, wxConnectionBase)
+#endif
+
+// It seems to be already defined somewhere in the Xt includes.
+#ifndef __XT__
+// Message codes
+enum {
+  IPC_EXECUTE = 1,
+  IPC_REQUEST,
+  IPC_POKE,
+  IPC_ADVISE_START,
+  IPC_ADVISE_REQUEST,
+  IPC_ADVISE,
+  IPC_ADVISE_STOP,
+  IPC_REQUEST_REPLY,
+  IPC_FAIL,
+  IPC_CONNECT,
+  IPC_DISCONNECT
+};
+#endif
+
+void Server_OnRequest(wxSocketServer& server,
+                     wxSocketBase::wxRequestEvent evt,
+                     char *cdata);
+void Client_OnRequest(wxSocketBase& sock,
+                     wxSocketBase::wxRequestEvent evt,
+                     char *cdata);
+
+// ---------------------------------------------------------------------------
+// wxTCPClient
+// ---------------------------------------------------------------------------
+
+wxTCPClient::wxTCPClient (void)
+  : wxClientBase()
+{
+}
+
+wxTCPClient::~wxTCPClient (void)
+{
+}
+
+bool wxTCPClient::ValidHost(const wxString& host)
+{
+  wxIPV4address addr;
+
+  return addr.Hostname(host);
+}
+
+wxConnectionBase *wxTCPClient::MakeConnection (const wxString& host,
+                                               const wxString& server_name,
+                                               const wxString& topic)
+{
+  wxIPV4address addr;
+  wxSocketHandler *hsock = &wxSocketHandler::Master();
+  wxSocketClient *client = hsock->CreateClient();
+  wxSocketStream *stream = new wxSocketStream(*client);
+  wxDataStream data_s(*stream);
+  
+  client->SetNotify(wxSocketBase::REQ_READ | wxSocketBase::REQ_LOST);
+  addr.Service(server_name);
+  addr.Hostname(host);
+
+  if (!client->Connect(addr)) {
+    delete client;
+    return NULL;
+  }
+  client->Notify(FALSE);
+
+  // Send topic name, and enquire whether this has succeeded
+  unsigned char msg;
+  
+  data_s.Write8(IPC_CONNECT);
+  data_s.WriteString(topic);
+  
+  msg = data_s.Read8();
+  
+  // OK! Confirmation.
+  if (msg == IPC_CONNECT) {
+    wxTCPConnection *connection = (wxTCPConnection *)OnMakeConnection ();
+    if (connection) {
+      if (!connection->IsKindOf(CLASSINFO(wxTCPConnection))) {
+        delete connection;
+        return NULL;
+      }
+      connection->m_topic = topic;
+      client->Callback(Client_OnRequest);
+      client->CallbackData((char *)connection);
+      client->Notify(TRUE);
+      return connection;
+    } else {
+      delete client;
+      return NULL;
+    }
+  } else {
+    delete client;
+    return NULL;
+  }
+  return NULL;
+}
+
+wxConnectionBase *wxTCPClient::OnMakeConnection()
+{
+  return new wxTCPConnection;
+}
+
+// ---------------------------------------------------------------------------
+// wxTCPServer
+// ---------------------------------------------------------------------------
+
+wxTCPServer::wxTCPServer (void)
+  : wxServerBase()
+{
+}
+
+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
+  server = hsock->CreateServer(addr);
+  server->Callback((wxSocketBase::wxSockCbk)Server_OnRequest);
+  server->SetNotify(wxSocketBase::REQ_ACCEPT);
+
+  server->CallbackData((char *)this);
+
+  return TRUE;
+}
+
+wxTCPServer::~wxTCPServer (void)
+{
+}
+
+wxConnectionBase *wxTCPServer::OnAcceptConnection(const wxString& topic)
+{
+  return new wxTCPConnection();
+}
+
+// ---------------------------------------------------------------------------
+// wxTCPConnection
+// ---------------------------------------------------------------------------
+
+wxTCPConnection::wxTCPConnection (void)
+  : wxConnectionBase(),
+    m_sock(NULL), m_sockstrm(NULL), m_codec(NULL)
+{
+}
+
+wxTCPConnection::~wxTCPConnection (void)
+{
+  wxDELETE(m_sock);
+  wxDELETE(m_codec);
+  wxDELETE(m_sockstrm);
+}
+
+void wxTCPConnection::Compress(bool on)
+{
+  // Use wxLZWStream
+}
+
+// Calls that CLIENT can make.
+bool wxTCPConnection::Disconnect (void)
+{
+  // Send the the disconnect message to the peer.
+  m_codec->Write8(IPC_DISCONNECT);
+  m_sock->Close();
+
+  return TRUE;
+}
+
+bool wxTCPConnection::Execute (char *data, int size, wxDataFormat format)
+{
+  if (!m_sock->IsConnected())
+    return FALSE;
+
+  // Prepare EXECUTE message
+  m_codec->Write8(IPC_EXECUTE);
+  m_codec->Write8(format);
+  if (size < 0)
+    m_codec->WriteString(data);
+  else {
+    m_codec->Write32(size);
+    m_codec->Write(data, size);
+  }
+
+  return TRUE;
+}
+
+char *wxTCPConnection::Request (const wxString& item, int *size, wxDataFormat format)
+{
+  if (!m_sock->IsConnected())
+    return NULL;
+
+  m_codec->Write8(IPC_REQUEST);
+  m_codec->WriteString(item);
+  m_codec->Write8(format);
+
+  // If Unpack doesn't initialize it.
+  int ret;
+
+  ret = m_codec->Read8();
+  if (ret == IPC_FAIL)
+    return NULL;
+  else {
+    size_t s;
+    char *data = NULL;
+
+    s = m_codec->Read32();
+    data = new char[s];
+    m_codec->Read(data, s);
+
+    if (size)
+      *size = s;
+    return data;
+  }
+}
+
+bool wxTCPConnection::Poke (const wxString& item, char *data, int size, wxDataFormat format)
+{
+  if (!m_sock->IsConnected())
+    return FALSE;
+
+  m_codec->Write8(IPC_POKE);
+  m_codec->WriteString(item);
+  m_codec->Write8(format);
+  if (size < 0)
+    m_codec->WriteString(data);
+  else {
+    m_codec->Write32(size);
+    m_codec->Write(data, size);
+  }
+
+  return TRUE;
+}
+
+bool wxTCPConnection::StartAdvise (const wxString& item)
+{
+  int ret;
+
+  if (!m_sock->IsConnected())
+    return FALSE;
+
+  m_codec->Write8(IPC_ADVISE_START);
+  m_codec->WriteString(item);
+
+  ret = m_codec->Read8();
+
+  if (ret != IPC_FAIL)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+bool wxTCPConnection::StopAdvise (const wxString& item)
+{
+  int msg;
+
+  if (!m_sock->IsConnected())
+    return FALSE;
+
+  m_codec->Write8(IPC_ADVISE_STOP);
+  m_codec->WriteString(item);
+
+  msg = m_codec->Read8();
+
+  if (msg != IPC_FAIL)
+    return TRUE;
+  else
+    return FALSE;
+}
+
+// Calls that SERVER can make
+bool wxTCPConnection::Advise (const wxString& item,
+                              char *data, int size, wxDataFormat format)
+{
+  if (!m_sock->IsConnected())
+    return FALSE;
+
+  m_codec->Write8(IPC_ADVISE);
+  m_codec->WriteString(item);
+  m_codec->Write8(format);
+  if (size < 0)
+    m_codec->WriteString(data);
+  else {
+    m_codec->Write32(size);
+    m_codec->Write(data, size);
+  }
+
+  return TRUE;
+}
+
+void Client_OnRequest(wxSocketBase& sock, wxSocketBase::wxRequestEvent evt,
+                     char *cdata)
+{
+  int msg = 0;
+  wxTCPConnection *connection = (wxTCPConnection *)cdata;
+  wxDataStream *codec;
+  wxString topic_name = connection->m_topic;
+  wxString item;
+
+  // The socket handler signals us that we lost the connection: destroy all.
+  if (evt == wxSocketBase::EVT_LOST) {
+    sock.Close();
+    connection->OnDisconnect();
+    return;
+  }
+
+  // Receive message number.
+  codec = connection->m_codec;
+  msg = codec->Read8();
+
+  switch (msg) {
+  case IPC_EXECUTE: {
+    char *data;
+    size_t size; 
+    wxDataFormat format;
+    
+    format = (wxDataFormat)codec->Read8();
+    size = codec->Read32();
+    data = new char[size];
+    codec->Read(data, size);
+
+    connection->OnExecute (topic_name, data, size, format);
+
+    delete [] data;
+    break;
+  }
+  case IPC_ADVISE: {
+    char *data;
+    size_t size;
+    wxDataFormat format;
+
+    item = codec->ReadString();
+    format = (wxDataFormat)codec->Read8();
+    size = codec->Read32();
+    data = new char[size];
+    codec->Read(data, size);
+    
+    connection->OnAdvise (topic_name, item, data, size, format);
+
+    delete [] data;
+    break;
+  }
+  case IPC_ADVISE_START: {
+    item = codec->ReadString();
+
+    bool ok = connection->OnStartAdvise (topic_name, item);
+    if (ok)
+      codec->Write8(IPC_ADVISE_START);
+    else
+      codec->Write8(IPC_FAIL);
+
+    break;
+  }
+  case IPC_ADVISE_STOP: {
+    item = codec->ReadString();
+
+    bool ok = connection->OnStopAdvise (topic_name, item);
+    if (ok)
+      codec->Write8(IPC_ADVISE_STOP);
+    else
+      codec->Write8(IPC_FAIL);
+
+    break;
+  }
+  case IPC_POKE: {
+    wxDataFormat format;
+    size_t size;
+    char *data;
+
+    item = codec->ReadString();
+    format = (wxDataFormat)codec->Read8();
+    size = codec->Read32();
+    data = new char[size];
+    codec->Read(data, size);
+    
+    connection->OnPoke (topic_name, item, data, size, format);
+
+    delete [] data;
+
+    break;
+  }
+  case IPC_REQUEST: {
+    wxDataFormat format;
+
+    item = codec->ReadString();
+    format = (wxDataFormat)codec->Read8();
+
+    int user_size = -1;
+    char *user_data = connection->OnRequest (topic_name, item, &user_size, format);
+
+    if (user_data) {
+      codec->Write8(IPC_REQUEST_REPLY);
+      if (user_size != -1) {
+        codec->Write32(user_size);
+        codec->Write(user_data, user_size);
+      } else
+        codec->WriteString(user_data);
+    } else
+      codec->Write8(IPC_FAIL);
+
+    break;
+  }
+  case IPC_DISCONNECT: {
+    sock.Close();
+    connection->OnDisconnect();
+    break;
+  }
+  default:
+    codec->Write8(IPC_FAIL);
+    break;
+  }
+}
+
+void Server_OnRequest(wxSocketServer& server,
+                     wxSocketBase::wxRequestEvent evt, char *cdata)
+{
+  wxTCPServer *ipcserv = (wxTCPServer *)cdata;
+  wxSocketStream *stream;
+  wxDataStream *codec;
+
+  if (evt != wxSocketBase::EVT_ACCEPT)
+    return;
+
+  /* Accept the connection, getting a new socket */
+  wxSocketBase *sock = server.Accept();
+  sock->Notify(FALSE);
+  sock->SetNotify(wxSocketBase::REQ_READ | wxSocketBase::REQ_LOST);
+
+  stream = new wxSocketStream(*sock);
+  codec = new wxDataStream(*stream);
+
+  if (!sock->Ok())
+    return;
+
+  int msg;
+  msg = codec->Read8();
+
+  if (msg == IPC_CONNECT) {
+    wxString topic_name;
+    topic_name = codec->ReadString();
+
+    /* Register new socket with the notifier */
+    wxTCPConnection *new_connection =
+         (wxTCPConnection *)ipcserv->OnAcceptConnection (topic_name);
+    if (new_connection) {
+      if (!new_connection->IsKindOf(CLASSINFO(wxTCPConnection))) {
+        delete new_connection;
+        codec->Write8(IPC_FAIL);
+        return;
+      }
+      // Acknowledge success
+      codec->Write8(IPC_CONNECT);
+      
+      new_connection->m_topic = topic_name;
+      new_connection->m_sockstrm = stream;
+      new_connection->m_codec = codec;
+      sock->Callback(Client_OnRequest);
+      sock->CallbackData((char *)new_connection);
+      sock->Notify(TRUE);
+    } else {
+      // Send failure message
+      codec->Write8(IPC_FAIL);
+    }
+  }
+}
diff --git a/src/common/sckstrm.cpp b/src/common/sckstrm.cpp
new file mode 100644 (file)
index 0000000..c0846c4
--- /dev/null
@@ -0,0 +1,68 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        sckstrm.h
+// Purpose:     wxSocket*Stream
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     17/07/97
+// RCS-ID:      $Id$
+// Copyright:   (c)
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__
+#pragma implementation "sckstrm.h"
+#endif
+
+#include "wx/stream.h"
+#include "wx/socket.h"
+#include "wx/sckstrm.h"
+
+// ---------------------------------------------------------------------------
+// wxSocketOutputStream
+// ---------------------------------------------------------------------------
+
+wxSocketOutputStream::wxSocketOutputStream(wxSocketBase& s)
+  : m_o_socket(&s)
+{
+}
+
+wxSocketOutputStream::~wxSocketOutputStream()
+{
+}
+
+wxOutputStream& wxSocketOutputStream::Write(const void *buffer, size_t size)
+{
+  m_o_socket->Write((const char *)buffer, size);
+  return *this;
+}
+
+// ---------------------------------------------------------------------------
+// wxSocketInputStream
+// ---------------------------------------------------------------------------
+
+wxSocketInputStream::wxSocketInputStream(wxSocketBase& s)
+ : m_i_socket(&s)
+{
+}
+
+wxSocketInputStream::~wxSocketInputStream()
+{
+}
+
+wxInputStream& wxSocketInputStream::Read(void *buffer, size_t size)
+{
+  m_i_socket->Read((char *)buffer, size);
+  return *this;
+}
+
+// ---------------------------------------------------------------------------
+// wxSocketStream (IO)
+// ---------------------------------------------------------------------------
+wxSocketStream::wxSocketStream(wxSocketBase& i_s, wxSocketBase& o_s)
+  : wxSocketInputStream(i_s), wxSocketOutputStream(o_s)
+{
+}
+
+wxSocketStream::wxSocketStream(wxSocketBase& s)
+  : wxSocketInputStream(s), wxSocketOutputStream(s)
+{
+}
diff --git a/src/common/socket.cpp b/src/common/socket.cpp
new file mode 100644 (file)
index 0000000..f880c2d
--- /dev/null
@@ -0,0 +1,1532 @@
+////////////////////////////////////////////////////////////////////////////////
+// Name:       socket.cpp
+// Purpose:    Socket handler classes
+// Authors:    Guilhem Lavaux (completely rewritten from a basic API of Andrew
+//             Davidson(1995) in wxWeb)
+// Created:    April 1997
+// Updated:    March 1998
+// Copyright:  (C) 1998, 1997, Guilhem Lavaux
+// RCS_ID:     $Id$
+// License:    see wxWindows license
+////////////////////////////////////////////////////////////////////////////////
+#ifdef __GNUG__     
+#pragma implementation "socket.h"
+#pragma interface
+#pragma implementation "socket.cpp"
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// wxWindows headers
+/////////////////////////////////////////////////////////////////////////////
+#include <wx/defs.h>
+#include <wx/object.h>
+#include <wx/string.h>
+#include <wx/timer.h>
+#include <wx/utils.h>
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+/////////////////////////////////////////////////////////////////////////////
+// System specific headers
+/////////////////////////////////////////////////////////////////////////////
+#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>
+
+#endif // __UNIX__
+
+#include <signal.h>
+#include <errno.h>
+
+#if defined(__WXMOTIF__) || defined(__WXXT__)
+#include <X11/Intrinsic.h>
+
+/////////////////////////////
+// Needs internal variables
+/////////////////////////////
+#ifdef __WXXT__
+#define Uses_XtIntrinsic
+#endif
+
+#endif
+
+#if defined(__WXGTK__)
+#include <gtk/gtk.h>
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// wxSocket headers
+/////////////////////////////////////////////////////////////////////////////
+#define WXSOCK_INTERNAL
+#include "wx/sckaddr.h"
+#include "wx/socket.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Some patch ///// BEGIN
+/////////////////////////////////////////////////////////////////////////////
+#ifdef __WINDOWS__
+#define close closesocket
+#define ioctl ioctlsocket
+#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 __WXMOTIF__
+#define wxAPP_CONTEXT wxTheApp->appContext
+#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( _MSC_VER )
+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
+
+#if defined(__WINDOWS__)
+#define PROCESS_EVENTS() wxYield()
+#elif defined(__WXXT__) || defined(__WXMOTIF__)
+#define PROCESS_EVENTS() XtAppProcessEvent(wxAPP_CONTEXT, XtIMAll)
+#elif defined(__WXGTK__)
+#define PROCESS_EVENTS() gtk_main_iteration()
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+// Some patch ///// END
+/////////////////////////////////////////////////////////////////////////////
+
+// --------------------------------------------------------------
+// ClassInfos
+// --------------------------------------------------------------
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_CLASS(wxSocketBase, wxObject)
+IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
+IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
+IMPLEMENT_CLASS(wxSocketHandler, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
+#endif
+
+class wxSockWakeUp : public wxTimer {
+public:
+  int *my_id;
+  int n_val;
+  wxSocketBase *sock;
+
+  wxSockWakeUp(wxSocketBase *_sock, int *id, int new_val) {
+    my_id = id; n_val = new_val;
+    sock = _sock;
+  }
+  virtual void Notify() {
+    *my_id = n_val;
+    if (sock) sock->Notify(FALSE);
+  }
+};
+
+/// Socket request
+class SockRequest : public wxObject {
+public:
+  char *buffer;
+  size_t size, nbytes;
+  bool done;
+  int error;
+  wxSockWakeUp *auto_wakeup;
+  wxSocketBase::wxRequestNotify type;
+};
+
+/////////////////////////////////////////////////////////////////////////////
+// Some internal define
+/////////////////////////////////////////////////////////////////////////////
+
+// --------------------------------------------------------------
+// --------- 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_waitflags(0), m_cbk(0), m_cdata(0), m_id(-1),
+  m_handler(0),
+  m_neededreq((wxRequestNotify)(REQ_READ | REQ_LOST)),
+  m_cbkon(FALSE),
+  m_unread(NULL), m_unrd_size(0),
+  m_processing(FALSE),
+  m_timeout(3600), m_wantbuf(0)
+{
+  m_internal = new wxSockInternal;
+#if defined(__WXXT__) || defined(__WXMOTIF__) || defined(__WXGTK__)
+  m_internal->sock_inputid = 0;
+  m_internal->sock_outputid = 0;
+  m_internal->sock_exceptid = 0;
+#endif
+#ifdef __WINDOWS__
+  m_internal->my_msg = 0;
+#endif
+}
+
+wxSocketBase::wxSocketBase() :
+  wxEvtHandler(),
+  m_flags(WAITALL), m_type(SOCK_UNINIT), m_connected(FALSE),
+  m_connecting(FALSE), m_fd(INVALID_SOCKET), m_waitflags(0),
+  m_cbk(0), m_cdata(0),
+  m_id(-1), m_handler(0),
+  m_neededreq((wxRequestNotify)(REQ_READ | REQ_LOST)),
+  m_cbkon(FALSE),
+  m_unread(NULL), m_unrd_size(0),
+  m_processing(FALSE),
+  m_timeout(3600), m_wantbuf(0)
+{
+  m_internal = new wxSockInternal;
+#if defined(__WXXT__) || defined(__WXMOTIF__) || defined(__WXGTK__)
+  m_internal->sock_inputid = 0;
+  m_internal->sock_outputid = 0;
+  m_internal->sock_exceptid = 0;
+#endif
+#ifdef __WINDOWS__
+  m_internal->my_msg = 0;
+#endif
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketBase CONSTRUCTOR ---------------------------
+// --------------------------------------------------------------
+wxSocketBase::~wxSocketBase()
+{
+  DestroyCallbacks();
+  Close();
+
+  if (m_unread)
+    free(m_unread);
+  if (m_handler) {
+#ifdef __WINDOWS__
+    if (m_internal->my_msg)
+      m_handler->DestroyMessage(m_internal->my_msg);
+#endif
+    m_handler->UnRegister(this);
+  }
+  m_states.DeleteContents(TRUE);
+
+  delete m_internal;
+}
+
+bool wxSocketBase::Close()
+{
+  if (m_fd != INVALID_SOCKET) {
+    for (int i=0;i<3;i++) {
+      wxNode *n, *node = req_list[i].First();
+
+      while (node) {
+        SockRequest *req = (SockRequest *)node->Data();
+        req->done = TRUE;
+        
+        n = node->Next();
+        delete node;
+        node = n;
+      }
+    }
+
+    DestroyCallbacks();
+    shutdown(m_fd, 2);
+    close(m_fd);
+    m_fd = INVALID_SOCKET;
+    m_connected = FALSE;
+  }
+
+  return TRUE;
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketBase base IO functions ---------------------
+// --------------------------------------------------------------
+wxSocketBase& wxSocketBase::Read(char* buffer, size_t nbytes)
+{
+  m_lcount = GetPushback(buffer, nbytes, FALSE);
+
+  // 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);
+
+  return *this;
+}
+
+wxSocketBase& wxSocketBase::Peek(char* buffer, size_t nbytes)
+{
+  size_t nbytes_old = nbytes;
+
+  nbytes -= GetPushback(buffer, nbytes, TRUE);
+  if (!nbytes) {
+    m_lcount = nbytes_old;
+    return *this;
+  }
+
+  WantBuffer(buffer, nbytes, EVT_PEEK);
+
+  return *this;
+}
+
+wxSocketBase& wxSocketBase::Write(const char *buffer, size_t nbytes)
+{
+  WantBuffer((char *)buffer, nbytes, EVT_WRITE);
+  return *this;
+}
+
+wxSocketBase& wxSocketBase::ReadMsg(char* buffer, size_t nbytes)
+{
+  SockMsg msg;
+  size_t len, len2, sig;
+  
+  Read((char *)&msg, sizeof(msg));
+  if (m_lcount != sizeof(msg))
+    return *this;
+
+  sig = msg.sig[0] & 0xff;
+  sig |= (size_t)(msg.sig[1] & 0xff) << 8;
+  sig |= (size_t)(msg.sig[2] & 0xff) << 16;
+  sig |= (size_t)(msg.sig[3] & 0xff) << 24;
+
+  if (sig != 0xfeeddead)
+    return *this;
+  len = msg.len[0] & 0xff;
+  len |= (size_t)(msg.len[1] & 0xff) << 8;
+  len |= (size_t)(msg.len[2] & 0xff) << 16;
+  len |= (size_t)(msg.len[3] & 0xff) << 24;
+  len2 = len;
+  if (len > nbytes)
+    len = nbytes;
+  else
+    len2 = 0;
+
+  if (Read(buffer, len).LastCount() != len)
+    return *this;
+  if (len2 && (Read(NULL, len2).LastCount() != len2))
+    return *this;
+  if (Read((char *)&msg, sizeof(msg)).LastCount() != sizeof(msg))
+    return *this;
+
+  sig = msg.sig[0] & 0xff;
+  sig |= (size_t)(msg.sig[1] & 0xff) << 8;
+  sig |= (size_t)(msg.sig[2] & 0xff) << 16;
+  sig |= (size_t)(msg.sig[3] & 0xff) << 24;
+// ERROR
+  if (sig != 0xdeadfeed)
+    return *this;
+
+  return *this;
+}
+
+wxSocketBase& wxSocketBase::WriteMsg(const char *buffer, size_t nbytes)
+{
+  SockMsg msg;
+  
+  msg.sig[0] = 0xad;
+  msg.sig[1] = 0xde;
+  msg.sig[2] = 0xed;
+  msg.sig[3] = 0xfe;
+
+  msg.len[0] = nbytes & 0xff;
+  msg.len[1] = (nbytes >> 8) & 0xff;
+  msg.len[2] = (nbytes >> 16) & 0xff;
+  msg.len[3] = (nbytes >> 24) & 0xff;
+
+  if (Write((char *)&msg, sizeof(msg)).LastCount() < sizeof(msg))
+    return *this;
+  if (Write(buffer, nbytes).LastCount() < nbytes)
+    return *this; 
+
+  msg.sig[0] = 0xed;
+  msg.sig[1] = 0xfe;
+  msg.sig[2] = 0xad;
+  msg.sig[3] = 0xde;
+  msg.len[0] = msg.len[1] = msg.len[2] = msg.len[3] = 0; 
+  Write((char *)&msg, sizeof(msg));
+
+  return *this;
+}
+
+wxSocketBase& wxSocketBase::Unread(const char *buffer, size_t nbytes)
+{
+  CreatePushbackAfter(buffer, nbytes);
+  return *this;
+}
+
+bool wxSocketBase::IsData() const
+{
+  struct timeval tv;
+  fd_set sock_set;
+
+  if (m_fd < 0)
+    return FALSE;
+  if (m_unrd_size > 0)
+    return TRUE;
+
+  tv.tv_sec = 0;
+  tv.tv_usec = 0;
+  FD_ZERO(&sock_set);
+  FD_SET(m_fd, &sock_set);
+  select(FD_SETSIZE, &sock_set, NULL, NULL, &tv);
+  return FD_ISSET(m_fd, &sock_set);
+}
+
+// ---------------------------------------------------------------------
+// --------- wxSocketBase Discard(): deletes all byte in the input queue
+// ---------------------------------------------------------------------
+void wxSocketBase::Discard()
+{
+#define MAX_BUFSIZE (10*1024)
+  char *my_data = new char[MAX_BUFSIZE];
+  size_t recv_size = MAX_BUFSIZE;
+
+  SaveState();
+  SetFlags((wxSockFlags)(NOWAIT | SPEED));
+  
+  while (recv_size == MAX_BUFSIZE) {
+    recv_size = Read(my_data, MAX_BUFSIZE).LastCount();
+  }
+
+  RestoreState();
+  delete [] my_data;
+
+#undef MAX_BUFSIZE
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketBase socket info functions -----------------
+// --------------------------------------------------------------
+bool wxSocketBase::GetPeer(wxSockAddress& addr_man) const
+{
+  struct sockaddr my_addr;
+  size_t len_addr = sizeof(my_addr);
+
+  if (m_fd < 0)
+    return FALSE;
+
+#ifdef __WINDOWS__
+  if (getpeername(m_fd, (struct sockaddr *)&my_addr, (int *)&len_addr) < 0)
+#else
+  if (getpeername(m_fd, (struct sockaddr *)&my_addr, (unsigned int *)&len_addr) < 0)
+#endif
+    return FALSE; 
+
+  addr_man.Disassemble(&my_addr, len_addr);
+  return TRUE;
+}
+
+bool wxSocketBase::GetLocal(wxSockAddress& addr_man) const
+{
+  struct sockaddr my_addr;
+  size_t len_addr = sizeof(my_addr);
+
+  if (m_fd < 0)
+    return FALSE;
+
+#ifdef __WINDOWS__
+  if (getsockname(m_fd, (struct sockaddr *)&my_addr, (int *)&len_addr) < 0)
+#else
+  if (getsockname(m_fd, (struct sockaddr *)&my_addr, (unsigned int *)&len_addr) < 0)
+#endif
+    return FALSE;
+
+  addr_man.Disassemble(&my_addr, len_addr);
+  return TRUE;
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketBase wait functions ------------------------
+// --------------------------------------------------------------
+void wxSocketBase::SaveState()
+{
+  wxSockState *state = new wxSockState;
+
+  state->cbk_on = m_cbkon;
+  state->cbk_set= m_neededreq;
+  state->cbk    = m_cbk;
+  state->cdata  = m_cdata;
+  state->flags  = m_flags;
+  state->notif  = m_notifyme;
+
+  m_states.Append(state);
+}
+
+void wxSocketBase::RestoreState()
+{
+  wxNode *node;
+
+  node = m_states.Last();
+  if (!node)
+    return;
+
+  wxSockState *state = (wxSockState *)node->Data();
+  SetFlags(state->flags);
+  m_neededreq = state->cbk_set;
+  m_cbk       = state->cbk;
+  m_cdata     = state->cdata;
+  m_notifyme  = state->notif;
+  if (state->cbk_on)
+    SetupCallbacks();
+  else
+    DestroyCallbacks();
+
+  delete node;
+  delete state;
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketBase wait functions ------------------------
+// --------------------------------------------------------------
+//
+bool wxSocketBase::_Wait(long seconds, long microseconds, int type)
+{
+  if ((!m_connected && !m_connecting) || m_fd < 0)
+    return FALSE;
+
+  wxSockWakeUp wakeup(this, &m_waitflags, 0);
+
+  SaveState();
+  SetNotify((wxRequestNotify)type);
+  SetupCallbacks();
+
+  if (seconds != -1)
+    wakeup.Start((int)(seconds*1000 + (microseconds / 1000)), TRUE);
+  
+  m_waitflags = 0x80 | type;
+  while (m_waitflags & 0x80)
+    PROCESS_EVENTS();
+
+  RestoreState();
+
+  if (m_waitflags & 0x40) {
+    m_waitflags = 0;
+    return TRUE;
+  }
+  m_waitflags = 0;
+
+  return FALSE;
+}
+
+bool wxSocketBase::Wait(long seconds, long microseconds)
+{
+  return _Wait(seconds, microseconds, REQ_ACCEPT | REQ_CONNECT |
+                                      REQ_READ | REQ_WRITE | REQ_LOST);
+}
+
+bool wxSocketBase::WaitForRead(long seconds, long microseconds)
+{
+  return _Wait(seconds, microseconds, REQ_READ | REQ_LOST);
+}
+
+bool wxSocketBase::WaitForWrite(long seconds, long microseconds)
+{
+  return _Wait(seconds, microseconds, REQ_WRITE);
+}
+
+bool wxSocketBase::WaitForLost(long seconds, long microseconds)
+{
+  return _Wait(seconds, microseconds, REQ_LOST);
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketBase callback management -------------------
+// --------------------------------------------------------------
+
+#if defined(__WXMOTIF__) || defined(__WXXT__) || defined(__WXGTK__)
+#if defined(__WXMOTIF__) || defined(__WXXT__)
+static void wx_socket_read(XtPointer client, int *fid,
+                          XtInputId *WXUNUSED(id))
+#define fd *fid
+#else
+static void wx_socket_read(gpointer client, gint fd,
+                           GdkInputCondition WXUNUSED(cond))
+#define fd fd
+#endif
+{
+  wxSocketBase *sock = (wxSocketBase *)client;
+  char c;
+  int i;
+
+  i = recv(fd, &c, 1, MSG_PEEK);
+
+  if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT)) {
+    sock->OnRequest(wxSocketBase::EVT_ACCEPT);
+    return;
+  }
+
+  if (i != 0) {
+    if (!(sock->NeededReq() & wxSocketBase::REQ_READ))
+      return;
+
+    sock->OnRequest(wxSocketBase::EVT_READ);
+  } else {
+    if (!(sock->NeededReq() & wxSocketBase::REQ_LOST)) {
+      sock->Close();
+      return;
+    }
+
+    sock->OnRequest(wxSocketBase::EVT_LOST);
+  }
+}
+#undef fd
+
+#if defined(__WXMOTIF__) || defined(__WXXT__)
+static void wx_socket_write(XtPointer client, int *WXUNUSED(fid),
+                           XtInputId *WXUNUSED(id))
+#else
+static void wx_socket_write(gpointer client, gint WXUNUSED(fd),
+                           GdkInputCondition WXUNUSED(cond))
+#endif
+{
+  wxSocketBase *sock = (wxSocketBase *)client;
+
+  if (!sock->IsConnected())
+    sock->OnRequest(wxSocketBase::EVT_CONNECT);
+  else
+    sock->OnRequest(wxSocketBase::EVT_WRITE);
+}
+#endif
+
+#ifdef wx_xview
+Notify_value wx_sock_read_xview (Notify_client client, int fd)
+{
+  wxSocketBase *sock = (wxSocketBase *)client;
+  char c;
+  int i;
+
+  i = recv(fd, &c, 1, MSG_PEEK);
+
+  if (i == -1 && (sock->NeededReq() & wxSocketBase::REQ_ACCEPT)) {
+    sock->OnRequest(wxSocketBase::EVT_ACCEPT);
+    return;
+  }
+
+  /* Bytes arrived */
+  if (i != 0) {
+    if (!(sock->NeededReq() & wxSocketBase::REQ_READ))
+      return (Notify_value) FALSE;
+
+    sock->OnRequest(wxSocketBase::EVT_READ);
+  } else {
+    if (!(sock->NeededReq() & wxSocketBase::REQ_LOST))
+      return;
+
+    sock->OnRequest(wxSocketBase::EVT_LOST);
+  }
+
+  return (Notify_value) FALSE;
+}
+
+Notify_value wx_sock_write_xview (Notify_client client, int fd)
+{
+  wxSocketBase *sock = (wxSocketBase *)client;
+
+  if (!sock->IsConnected())
+    sock->OnRequest(wxSocketBase::EVT_CONNECT);
+  else
+    sock->OnRequest(wxSocketBase::EVT_WRITE);
+
+  return (Notify_value) TRUE;
+}
+#endif
+
+wxSocketBase::wxRequestNotify wxSocketBase::EventToNotify(wxRequestEvent 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;
+  }
+  return 0;
+}
+
+void wxSocketBase::SetFlags(wxSockFlags _flags)
+{
+  m_flags = _flags;
+  if (_flags & SPEED) {
+    unsigned long flag = 0;
+    ioctl(m_fd, FIONBIO, &flag);
+
+    // SPEED and WAITALL are antagonists.
+    m_flags = (wxSockFlags)(m_flags & ~WAITALL);
+
+    Notify(FALSE);
+  } else {
+    unsigned long flag = 1;
+    ioctl(m_fd, FIONBIO, &flag);
+  }
+}
+
+void wxSocketBase::SetNotify(wxRequestNotify flags)
+{
+  wxRequestNotify old_needed_req = m_neededreq;
+  if (flags & REQ_ACCEPT) {
+    /* Check if server */
+    if (!(GetClassInfo()->IsKindOf(CLASSINFO(wxSocketServer))))
+      flags &= ~REQ_ACCEPT;
+  }
+  m_neededreq = flags;
+  if (m_cbkon && old_needed_req != flags)
+    SetupCallbacks();
+}
+
+void wxSocketBase::SetupCallbacks()
+{
+  if (m_fd == INVALID_SOCKET || !m_handler || (m_flags & SPEED))
+    return;
+
+#if defined(__WXMOTIF__) || defined(__WXXT__) || defined(__WXGTK__)
+  if (m_cbkon)
+    DestroyCallbacks();
+  if (m_neededreq & (REQ_ACCEPT | REQ_READ | REQ_LOST)) {
+#ifdef __WXGTK__
+    m_internal->sock_inputid = gdk_input_add(m_fd, GDK_INPUT_READ,
+                                           wx_socket_read, (gpointer)this);
+#else
+    m_internal->sock_inputid = XtAppAddInput (wxAPP_CONTEXT, m_fd,
+                                       (XtPointer *) XtInputReadMask,
+                                       (XtInputCallbackProc) wx_socket_read,
+                                       (XtPointer) this);
+#endif
+  }
+  if (m_neededreq & (REQ_CONNECT | REQ_WRITE)) {
+#ifdef __WXGTK__
+    m_internal->sock_inputid = gdk_input_add(m_fd, GDK_INPUT_WRITE,
+                                             wx_socket_write, (gpointer)this);
+#else
+    m_internal->sock_outputid = XtAppAddInput (wxAPP_CONTEXT, m_fd,
+                                       (XtPointer *) XtInputWriteMask,
+                                       (XtInputCallbackProc) wx_socket_write,
+                                       (XtPointer) this);
+#endif
+  }
+#endif
+#ifdef __WINDOWS__
+  WORD mask = 0;
+
+  if (m_neededreq & REQ_READ)
+    mask |= FD_READ;
+  if (m_neededreq & REQ_WRITE)
+    mask |= FD_WRITE;
+  if (m_neededreq & REQ_LOST)
+    mask |= FD_CLOSE;
+  if (m_neededreq & REQ_ACCEPT)
+    mask |= FD_ACCEPT;
+  if (m_neededreq & REQ_CONNECT)
+    mask |= FD_CONNECT;
+
+  if (!m_internal->my_msg)
+    m_internal->my_msg = m_handler->NewMessage(this);
+  WSAAsyncSelect(m_fd, m_handler->GetHWND(), m_internal->my_msg, mask);
+#endif
+  m_cbkon = TRUE;
+  m_processing = FALSE;
+}
+
+void wxSocketBase::DestroyCallbacks()
+{
+  if (!m_cbkon || !m_handler)
+    return;
+  m_cbkon = FALSE;
+  m_processing = FALSE;
+#if defined(__WXMOTIF__) || defined(__WXXT__)
+  if (m_internal->sock_inputid > 0)
+    XtRemoveInput(m_internal->sock_inputid);
+  m_internal->sock_inputid = 0;
+  if (m_internal->sock_outputid > 0)
+    XtRemoveInput(m_internal->sock_outputid);
+  m_internal->sock_outputid = 0;
+#endif
+#ifdef __WXGTK__
+  if (m_internal->sock_inputid > 0)
+    gdk_input_remove(m_internal->sock_inputid);
+  m_internal->sock_inputid = 0;
+  if (m_internal->sock_outputid > 0)
+    gdk_input_remove(m_internal->sock_outputid);
+  m_internal->sock_outputid = 0;
+#endif
+#ifdef __WINDOWS__
+  WSAAsyncSelect(m_fd, m_handler->GetHWND(), 0, 0);
+#endif
+}
+
+void wxSocketBase::Notify(bool notify)
+{
+  if (m_notifyme == notify)
+    return;
+  if (notify)
+    SetupCallbacks();
+  else
+    DestroyCallbacks();
+  m_notifyme = notify;
+}
+
+void wxSocketBase::OnRequest(wxRequestEvent req_evt)
+{
+  wxRequestNotify req_notif = EventToNotify(req_evt);
+
+  // Mask the current event
+  SetNotify(m_neededreq & ~req_notif);
+
+  if (req_evt <= EVT_WRITE && DoRequests(req_evt))
+    return;
+
+  if (m_waitflags & 0xF0) {
+    // Wake up
+    if ((m_waitflags & 0x0F) == req_evt) {
+      m_waitflags = 0x80;
+#ifndef __WXGTK__
+      DestroyCallbacks();  // I disable it to prevent infinite loop on X11.
+#endif
+    }
+    return;
+  }
+
+  if (req_evt == EVT_LOST) {
+    m_connected = FALSE;
+    Close();
+  }
+  if (m_notifyme)
+    OldOnNotify(req_evt);
+
+  // Unmask
+  SetNotify(m_neededreq | req_notif);
+}
+
+wxSocketEvent::wxSocketEvent(int id)
+  : wxEvent(id)
+{
+  wxEventType type = (wxEventType)wxEVT_SOCKET;
+
+  SetEventType(type);
+}
+
+void wxSocketBase::OldOnNotify(wxRequestEvent evt)
+{
+  wxSocketEvent event(m_id);
+
+  event.SetEventObject(this);
+  event.m_skevt = evt;
+  ProcessEvent(event);
+
+  if (m_cbk)
+    m_cbk(*this, evt, m_cdata);
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketBase functions [Callback, CallbackData] ----
+// --------------------------------------------------------------
+wxSocketBase::wxSockCbk wxSocketBase::Callback(wxSocketBase::wxSockCbk _cbk)
+{
+  wxSockCbk old_cbk = m_cbk;
+
+  m_cbk = _cbk;
+  return old_cbk;
+}
+
+char *wxSocketBase::CallbackData(char *cdata_)
+{
+  char *old_cdata = m_cdata;
+
+  m_cdata = cdata_;
+  return old_cdata;
+}
+
+void wxSocketBase::SetEventHandler(wxEvtHandler& h_evt, int id)
+{
+  SetNextHandler(&h_evt);
+  m_id = id;
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketBase pushback library ----------------------
+// --------------------------------------------------------------
+void wxSocketBase::CreatePushbackAfter(const char *buffer, size_t size)
+{
+  char *curr_pos;
+
+  m_unread = (char *) realloc(m_unread, m_unrd_size+size);
+  curr_pos = m_unread + m_unrd_size;
+
+  memcpy(curr_pos, buffer, size);
+  m_unrd_size += 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;
+
+  memcpy(new_buf, buffer, size);
+  memcpy(curr_pos, m_unread, m_unrd_size);
+
+  free(m_unread);
+  m_unread = new_buf;
+  m_unrd_size += size;
+}
+
+size_t wxSocketBase::GetPushback(char *buffer, size_t size, bool peek)
+{
+  if (!m_unrd_size)
+    return 0;
+
+  if (size > m_unrd_size)
+    size = m_unrd_size;
+  memcpy(buffer, m_unread, size);
+
+  if (!peek) {
+    m_unrd_size -= size;
+    if (!m_unrd_size) {
+      free(m_unread);
+      m_unread = NULL;
+    }
+  }
+
+  return size;
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketBase "multi-thread" core -------------------
+// --------------------------------------------------------------
+
+bool wxSocketBase::DoRequests(wxRequestEvent req_flag)
+{
+  wxNode *node = req_list[req_flag].First();
+  size_t len;
+  int ret;
+
+  if (!node)
+    return FALSE;
+
+  SockRequest *req = (SockRequest *)node->Data();
+
+  delete node;
+
+  switch (req->type) {
+  case EVT_READ:
+  case EVT_PEEK:
+    ret = recv(m_fd, req->buffer, req->size,
+              (req->type == EVT_PEEK) ? MSG_PEEK : 0);
+    if (ret < 0) {
+      req->error = errno;
+      req->done = TRUE;
+      break;
+    }
+    len = ret;
+    if ((len < req->size) && (m_flags & WAITALL)) {
+      req->size -= len;
+      req->nbytes += len;
+      req->buffer += len;
+      req->auto_wakeup->Start(m_timeout*1000, TRUE);
+      req_list[req_flag].Insert(req);
+      break;
+    }
+    req->done = TRUE;
+    req->nbytes += len;
+#ifndef __WXGTK__
+    DestroyCallbacks();
+#endif
+    break;
+  case EVT_WRITE:
+    ret = send(m_fd, req->buffer, req->size, 0);
+    if (ret < 0) {
+      req->error = errno;
+      req->done = TRUE;
+      break;
+    }
+    len = ret;
+    if ((len < req->size) && (m_flags & WAITALL)) {
+      req->size -= len;
+      req->nbytes += len;
+      req->buffer += len;
+      req->auto_wakeup->Start(m_timeout*1000, TRUE);
+      req_list[req_flag].Insert(req);
+      break;
+    }
+    req->done = TRUE;
+    req->nbytes += len;
+#ifndef __WXGTK__
+    DestroyCallbacks();
+#endif
+    break;
+  default:
+    return FALSE;
+  }
+  return TRUE;
+}
+
+void wxSocketBase::WantSpeedBuffer(char *buffer, size_t nbytes,
+                                   wxRequestEvent evt)
+{
+  int ret;
+
+  switch (evt) {
+  case EVT_PEEK:
+  case EVT_READ:
+    ret = read(m_fd, buffer, nbytes);
+    break;
+  case EVT_WRITE:
+    ret = write(m_fd, buffer, nbytes);
+    break;
+  }
+  if (ret < 0) {
+    m_lcount = 0;
+    m_error = errno;
+  } else
+    m_lcount = ret;
+}
+
+void wxSocketBase::WantBuffer(char *buffer, size_t nbytes,
+                             wxRequestEvent evt)
+{
+  bool buf_timed_out;
+
+  if (m_fd == INVALID_SOCKET || !m_handler || !m_connected)
+    return;
+
+  if (m_flags & SPEED) {
+    WantSpeedBuffer(buffer, nbytes, evt);
+    return;
+  }
+
+  SockRequest *buf = new SockRequest;
+  wxSockWakeUp s_wake(NULL, (int *)&buf_timed_out, (int)TRUE);
+  
+  m_wantbuf++;
+  req_list[evt].Append(buf);
+
+  SaveState();
+  SetNotify(REQ_LOST | EventToNotify(evt));
+  SetupCallbacks();
+  buf->buffer = buffer;
+  buf->size = nbytes;
+  buf->done = FALSE;
+  buf->type = evt;
+  buf->nbytes = 0;
+  buf->auto_wakeup = &s_wake;
+  buf->error = 0;
+  buf_timed_out = FALSE;
+
+  s_wake.Start(m_timeout*1000, TRUE);
+  if (m_flags & NOWAIT) {
+    DoRequests(evt);
+  } else {
+    while (!buf->done && !buf_timed_out)
+      PROCESS_EVENTS();
+  }
+  m_wantbuf--;
+  m_lcount = buf->nbytes;
+  if (buf_timed_out)
+    m_error = ETIMEDOUT;
+  else
+    m_error = buf->error;
+
+  delete buf;
+  RestoreState();
+}
+
+// --------------------------------------------------------------
+// wxSocketServer ///////////////////////////////////////////////
+// --------------------------------------------------------------
+
+// --------------------------------------------------------------
+// --------- wxSocketServer CONSTRUCTOR -------------------------
+// --------------------------------------------------------------
+wxSocketServer::wxSocketServer(wxSockAddress& addr_man,
+                              wxSockFlags flags) :
+  wxSocketBase(flags, SOCK_SERVER)
+{
+  m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
+
+  if (m_fd == INVALID_SOCKET)
+    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;
+    return;
+  }
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketServer Accept ------------------------------
+// --------------------------------------------------------------
+bool wxSocketServer::AcceptWith(wxSocketBase& sock)
+{
+  int fd2;
+  
+  if ((fd2 = accept(m_fd, 0, 0)) < 0)
+    return FALSE;
+
+  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));
+  
+  if (!(sock.m_flags & SPEED)) {
+    unsigned long flag2 = 1;
+    ioctl(fd2, FIONBIO, &flag2);
+  }
+  sock.m_type = SOCK_INTERNAL;
+  sock.m_fd = fd2;
+  sock.m_connected = TRUE;
+
+  return TRUE;
+}
+
+wxSocketBase *wxSocketServer::Accept()
+{
+  wxSocketBase* sock = new wxSocketBase();
+
+  sock->SetFlags((wxSockFlags)m_flags);
+
+  if (!AcceptWith(*sock))
+    return NULL;
+
+  if (m_handler)
+    m_handler->Register(sock);
+
+  return sock;
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketServer callbacks ---------------------------
+// --------------------------------------------------------------
+void wxSocketServer::OnRequest(wxRequestEvent evt)
+{
+  if (evt == EVT_ACCEPT) {
+    OldOnNotify(EVT_ACCEPT);
+  }
+}
+
+// --------------------------------------------------------------
+// wxSocketClient ///////////////////////////////////////////////
+// --------------------------------------------------------------
+
+// --------- wxSocketClient CONSTRUCTOR -------------------------
+// --------------------------------------------------------------
+wxSocketClient::wxSocketClient(wxSockFlags _flags) :
+       wxSocketBase(_flags, SOCK_CLIENT)
+{
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketClient DESTRUCTOR --------------------------
+// --------------------------------------------------------------
+wxSocketClient::~wxSocketClient()
+{
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketClient Connect functions -------------------
+// --------------------------------------------------------------
+bool wxSocketClient::Connect(wxSockAddress& addr_man, bool wait)
+{
+  struct linger linger;
+
+  if (IsConnected())
+    Close();
+
+  m_fd = socket(addr_man.GetFamily(), SOCK_STREAM, 0);
+  
+  if (m_fd < 0)
+    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)
+    return FALSE;
+
+  if (!(m_flags & SPEED)) {
+    flag = 1;
+    ioctl(m_fd, FIONBIO, &flag);
+  }
+  
+  Notify(TRUE);
+
+  m_connected = TRUE;
+  return TRUE;
+}
+
+bool wxSocketClient::WaitOnConnect(long seconds)
+{
+  int ret = _Wait(seconds, 0, REQ_CONNECT | REQ_LOST);
+  
+  if (ret)
+    m_connected = TRUE;
+  
+  return m_connected; 
+}
+
+void wxSocketClient::OnRequest(wxRequestEvent evt)
+{
+  if (evt == EVT_CONNECT) {
+    if (m_connected) {
+      SetNotify(m_neededreq & ~REQ_CONNECT);
+      return;
+    }
+    m_waitflags = 0x40;
+    m_connected = TRUE; 
+    OldOnNotify(EVT_CONNECT);
+    DestroyCallbacks();
+    return;
+  }
+  wxSocketBase::OnRequest(evt);
+}
+
+/////////////////////////////////////////////////////////////////
+// wxSocketHandler ///////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+
+wxSocketHandler *wxSocketHandler::master = NULL;
+#if defined(__WINDOWS__)
+static int win_initialized = 0;
+#endif
+
+// --------------------------------------------------------------
+// --------- wxSocketHandler CONSTRUCTOR ------------------------
+// --------------------------------------------------------------
+#ifdef __WINDOWS__
+
+extern char wxPanelClassName[];
+
+LRESULT APIENTRY _EXPORT wxSocketHandlerWndProc(HWND hWnd, UINT message,
+   WPARAM wParam, LPARAM lParam)
+{
+  wxSocketHandler *h_sock = (wxSocketHandler *)GetWindowLong(hWnd, GWL_USERDATA);
+  wxNode *node = h_sock->smsg_list->Find(message);
+  wxSocketBase *sock;
+  wxSocketBase::wxRequestEvent sk_req;
+  UINT event = WSAGETSELECTEVENT(lParam);
+
+  if (!node)
+    return DefWindowProc(hWnd, message, wParam, lParam);
+
+  sock = (wxSocketBase *)node->Data();
+
+  switch (event) {
+  case FD_READ:
+    sk_req = wxSocketBase::EVT_READ;
+    break;
+  case FD_WRITE:
+    sk_req = wxSocketBase::EVT_WRITE;
+    break;
+  case FD_CLOSE:
+    sk_req = wxSocketBase::EVT_LOST;
+    break;
+  case FD_ACCEPT:
+    sk_req = wxSocketBase::EVT_ACCEPT;
+    break;
+  case FD_CONNECT:
+    sk_req = wxSocketBase::EVT_CONNECT;
+    break;
+  }
+  sock->OnRequest(sk_req);
+
+  return (LRESULT)0;
+}
+
+FARPROC wxSocketSubClassProc = NULL;
+
+#endif
+
+wxSocketHandler::wxSocketHandler()
+{
+#if defined(__WINDOWS__)
+  if (!win_initialized) {
+    WSADATA wsaData;
+
+    WSAStartup((1 << 8) | 1, &wsaData);
+    win_initialized = 1;
+  }
+  internal = new wxSockHandlerInternal;
+  internal->sockWin = ::CreateWindow(wxPanelClassName, NULL, 0,
+               0, 0, 0, 0, NULL, (HMENU) NULL,
+               wxhInstance, 0);
+
+  // Subclass the window
+  if (!wxSocketSubClassProc)
+    wxSocketSubClassProc = MakeProcInstance((FARPROC) wxSocketHandlerWndProc, wxhInstance);
+  ::SetWindowLong(internal->sockWin, GWL_WNDPROC, (LONG) wxSocketSubClassProc);
+  ::SetWindowLong(internal->sockWin, GWL_USERDATA, (LONG) this);
+
+  internal->firstAvailableMsg = 5000;
+  smsg_list = new wxList(wxKEY_INTEGER);
+#endif
+
+  socks = new wxList;
+
+#ifndef __WINDOWS__
+  signal(SIGPIPE, SIG_IGN);
+#endif
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketHandler DESTRUCTOR -------------------------
+// --------------------------------------------------------------
+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__
+  delete smsg_list;
+
+  ::DestroyWindow(internal->sockWin);
+  WSACleanup();
+  win_initialized = 0;
+
+  delete internal;
+#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);
+    sock->SetupCallbacks();
+  }
+}
+
+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->DestroyCallbacks();
+      sock->SetHandler(NULL);
+      return;
+    }
+  }
+}
+
+unsigned long wxSocketHandler::Count() const
+{
+  return socks->Number();
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketHandler "big" wait functions ---------------
+// --------------------------------------------------------------
+void handler_cbk(wxSocketBase& sock,
+                wxSocketBase::wxRequestEvent WXUNUSED(flags),
+                char *cdata)
+{
+  int *a_wait = (int *)cdata;
+
+  (*a_wait)++;
+  sock.Notify(FALSE);
+}
+
+int wxSocketHandler::Wait(long seconds, long microseconds)
+{
+  int i;
+  int on_wait;
+  wxSockWakeUp s_wake(NULL, &on_wait, -2);
+  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;
+}
+
+void wxSocketHandler::YieldSock()
+{
+  wxNode *node;
+
+  for (node = socks->First(); node; node = node->Next() ) {
+    wxSocketBase *sock = (wxSocketBase *)node->Data();
+
+    sock->SaveState();
+
+    sock->SetFlags(wxSocketBase::SPEED);
+    if (sock->IsData())
+      sock->DoRequests(wxSocketBase::EVT_READ);
+    sock->DoRequests(wxSocketBase::EVT_WRITE);
+
+    sock->RestoreState();
+  }
+}
+
+// --------------------------------------------------------------
+// --------- wxSocketHandler: create and register the socket ----
+// --------------------------------------------------------------
+wxSocketServer *wxSocketHandler::CreateServer(wxSockAddress& addr,
+                                             wxSocketBase::wxSockFlags flags)
+{
+  wxSocketServer *serv = new wxSocketServer(addr, flags);
+
+  Register(serv);
+  return serv;
+}
+
+wxSocketClient *wxSocketHandler::CreateClient(wxSocketBase::wxSockFlags flags)
+{
+  wxSocketClient *client = new wxSocketClient(flags);
+
+  Register(client);
+  return client;
+}
+
+#ifdef __WINDOWS__
+// --------------------------------------------------------------
+// --------- wxSocketHandler: Windows specific methods ----------
+// --------------------------------------------------------------
+UINT wxSocketHandler::NewMessage(wxSocketBase *sock)
+{
+  internal->firstAvailableMsg++;
+  smsg_list->Append(internal->firstAvailableMsg, sock);
+  return internal->firstAvailableMsg;
+}
+
+void wxSocketHandler::DestroyMessage(UINT msg)
+{
+  wxNode *node = smsg_list->Find(msg);
+  delete node;
+}
+
+HWND wxSocketHandler::GetHWND() const
+{
+  return internal->sockWin;
+}
+
+#endif
index f25f6381fb7bc13c26f23af4bf3bf796b6d9e6b9..d546ab473f105de674d389e5d20b18e70a39afe6 100644 (file)
@@ -549,9 +549,23 @@ wxOutputStream& wxOutputStream::operator<<(wxObject& obj)
   return *this;
 }
 
+// ----------------------------------------------------------------------------
+// wxStream
+// ----------------------------------------------------------------------------
+
+wxStream::wxStream()
+  : wxInputStream(), wxOutputStream()
+{
+}
+
 // ----------------------------------------------------------------------------
 // wxFilterInputStream
 // ----------------------------------------------------------------------------
+wxFilterInputStream::wxFilterInputStream()
+  : wxInputStream(NULL)
+{
+}
+
 wxFilterInputStream::wxFilterInputStream(wxInputStream& stream)
   : wxInputStream(NULL)
 {
@@ -578,10 +592,14 @@ off_t wxFilterInputStream::DoTellInput() const
   return m_parent_i_stream->TellI();
 }
 
-
 // ----------------------------------------------------------------------------
 // wxFilterOutputStream
 // ----------------------------------------------------------------------------
+wxFilterOutputStream::wxFilterOutputStream()
+  : wxOutputStream(NULL)
+{
+}
+
 wxFilterOutputStream::wxFilterOutputStream(wxOutputStream& stream)
   : wxOutputStream(NULL)
 {
@@ -608,6 +626,19 @@ off_t wxFilterOutputStream::DoTellOutput() const
   return m_parent_o_stream->TellO();
 }
 
+// ----------------------------------------------------------------------------
+// wxFilterStream
+// ----------------------------------------------------------------------------
+
+wxFilterStream::wxFilterStream()
+{
+}
+
+wxFilterStream::wxFilterStream(wxStream& stream)
+  : wxFilterInputStream(stream), wxFilterOutputStream(stream)
+{
+}
+
 // ----------------------------------------------------------------------------
 // Some IOManip function
 // ----------------------------------------------------------------------------
diff --git a/src/common/tokenzr.cpp b/src/common/tokenzr.cpp
new file mode 100644 (file)
index 0000000..eb99237
--- /dev/null
@@ -0,0 +1,104 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        tokenzr.cpp
+// Purpose:     String tokenizer
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     04/22/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Guilhem Lavaux
+// Licence:     wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "tokenzr.h"
+#endif
+
+#include "wx/object.h"
+#include "wx/string.h"
+#include "wx/tokenzr.h"
+
+wxStringTokenizer::wxStringTokenizer(const wxString& to_tokenize,
+                                     const wxString& delims,
+                                    bool ret_delims)
+  : wxObject()
+{
+  m_string = to_tokenize;
+  m_delims = delims;
+  m_retdelims = ret_delims;
+}
+
+wxStringTokenizer::~wxStringTokenizer()
+{
+}
+
+off_t wxStringTokenizer::FindDelims(const wxString& str, const wxString& delims)
+{
+  int i, j;
+  register int s_len = str.Length(),
+               len = delims.Length();
+
+  for (i=0;i<s_len;i++) {
+    register char c = str[i];
+
+    for (j=0;j<len;j++)
+      if (delims[j] == c)
+        return i;
+  }
+  return -1;
+}
+
+int wxStringTokenizer::CountTokens()
+{
+  wxString p_string = m_string;
+  bool found = TRUE;
+  int pos, count = 1; 
+
+  if (p_string.Length() == 0)
+    return 0;
+
+  while (found) {
+    pos = FindDelims(p_string, m_delims);
+    if (pos != -1) {
+      count++;
+      p_string = p_string(0, pos);
+    } else
+      found = FALSE;
+  }
+  return count;
+}
+
+bool wxStringTokenizer::HasMoreToken()
+{
+  return (m_string.Length() != 0);
+}
+
+wxString wxStringTokenizer::NextToken()
+{
+  register off_t pos, pos2;
+  wxString r_string;
+
+  if (m_string.IsNull())
+    return m_string;
+
+  pos = FindDelims(m_string, m_delims);
+  if (pos == -1) {
+    r_string = m_string;
+    m_string = (char *)NULL;
+    
+    return r_string;
+  }
+
+  if (m_retdelims) {
+    if (!pos) {
+      pos++;
+      pos2 = 1;
+    } else
+      pos2 = pos;
+  } else
+      pos2 = pos + 1;
+  
+  r_string = m_string.Left((size_t)pos);
+  m_string = m_string.Mid((size_t)pos2);
+
+  return r_string;
+}
diff --git a/src/common/url.cpp b/src/common/url.cpp
new file mode 100644 (file)
index 0000000..39ad2b6
--- /dev/null
@@ -0,0 +1,277 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        url.cpp
+// Purpose:     URL parser
+// Author:      Guilhem Lavaux
+// Modified by:
+// Created:     20/07/1997
+// RCS-ID:      $Id$
+// Copyright:   (c) 1997, 1998 Guilhem Lavaux
+// Licence:     wxWindows license
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+#pragma implementation "url.h"
+#endif
+#include <string.h>
+#include <ctype.h>
+
+// wxWindows headers
+#include <wx/string.h>
+#include <wx/list.h>
+#include <wx/utils.h>
+
+// wxSocket header
+#include "wx/url.h"
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#if !USE_SHARED_LIBRARY
+IMPLEMENT_CLASS(wxProtoInfo, wxObject)
+IMPLEMENT_CLASS(wxURL, wxObject)
+#endif
+
+// Protocols list
+wxProtoInfo *wxURL::g_protocols = NULL;
+wxHTTP wxURL::g_proxy;
+
+/////////////////////////////////////////////////////////////////
+// wxURL ////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////
+
+/*
+ * --------------------------------------------------------------
+ * --------- wxURL CONSTRUCTOR DESTRUCTOR -----------------------
+ * --------------------------------------------------------------
+ */
+
+wxURL::wxURL(const wxString& url)
+{
+  m_protocol = NULL;
+  if (g_proxy.IsConnected()) {
+    m_protocol = &g_proxy;
+    m_protoname = "proxy";
+    m_path = url;
+    return;
+  }
+  m_url = url;
+  m_error = wxURL_NOERR;
+}
+
+bool wxURL::ParseURL()
+{
+  wxString last_url = m_url;
+
+  // Clean up
+  CleanData();
+
+  // Extract protocol name
+  if (!PrepProto(last_url)) {
+    m_error = wxURL_SNTXERR;
+    return FALSE;
+  }
+
+  // Find and create the protocol object
+  if (!FetchProtocol()) {
+    m_error = wxURL_NOPROTO;
+    return FALSE;
+  }
+
+  // Do we need a host name ?
+  if (m_protoinfo->m_needhost) {
+    // Extract it
+    if (!PrepHost(last_url)) {
+      m_error = wxURL_SNTXERR;
+      return FALSE;
+    }
+  }
+
+  // Extract full path
+  if (!PrepPath(last_url)) {
+    m_error = wxURL_NOPATH;
+    return FALSE;
+  }
+
+  m_error = wxURL_NOERR;
+  return TRUE;
+}
+
+void wxURL::CleanData()
+{
+  if (m_protoname != "proxy")
+    delete m_protocol;
+}
+
+wxURL::~wxURL()
+{
+  CleanData();
+}
+
+/*
+ * --------------------------------------------------------------
+ * --------- wxURL urls decoders --------------------------------
+ * --------------------------------------------------------------
+ */
+bool wxURL::PrepProto(wxString& url)
+{
+  int pos;
+
+  // Find end
+  pos = url.Find(':');
+  if (pos == -1)
+    return FALSE;
+
+  m_protoname = url(0, pos);
+
+  url = url(pos+1, url.Length());
+
+  return TRUE;
+}
+
+bool wxURL::PrepHost(wxString& url)
+{
+  int pos, pos2;
+
+  if ((url[0UL] != '/') || (url[1UL] != '/'))
+    return FALSE;
+
+  url = url(2, url.Length());
+
+  pos = url.Find('/');
+  if (pos == -1)
+    return FALSE;
+
+  pos2 = url.Find(':');
+  if (pos2 != -1 && pos2 < pos) {
+    m_servname = url(pos2, pos);
+    if (!m_servname.IsNumber())
+      return FALSE;
+    pos2 = pos;
+  }
+
+  m_hostname = url(0, pos);
+
+  url = url(url.Find('/'), url.Length());
+
+  return TRUE;
+}
+
+bool wxURL::PrepPath(wxString& url)
+{
+  if (url.Length() != 0)
+    m_path = url;
+  else
+    m_path = "/";
+  return TRUE;
+}
+
+bool wxURL::FetchProtocol()
+{
+  wxProtoInfo *info = g_protocols;
+
+  while (info) {
+    if (m_protoname == info->m_protoname) {
+      if (m_servname.IsNull())
+        m_servname = info->m_servname;
+
+      m_protoinfo = info;
+      m_protocol = (wxProtocol *)m_protoinfo->m_cinfo->CreateObject();
+      wxSocketHandler::Master().Register(m_protocol);
+      return TRUE;
+    }
+    info = info->next;
+  }
+  return FALSE;
+}
+
+/*
+ * --------------------------------------------------------------
+ * --------- wxURL get ------------------------------------------
+ * --------------------------------------------------------------
+ */
+wxInputStream *wxURL::GetInputStream(void)
+{
+  wxIPV4address addr;
+  wxInputStream *the_i_stream = NULL;
+
+  if (!m_protocol)
+    if (!ParseURL())
+      return NULL;
+
+  if (!m_protocol) {
+    m_error = wxURL_NOPROTO;
+    return NULL;
+  }
+
+  m_error = wxURL_NOERR;
+  if (m_protoinfo->m_needhost) {
+    if (!addr.Hostname(m_hostname)) {
+      m_error = wxURL_NOHOST;
+      return NULL;
+    }
+
+    addr.Service(m_servname);
+
+    if (!m_protocol->Connect(addr)) {
+      m_error = wxURL_CONNERR;
+      return NULL;
+    }
+  }
+
+  the_i_stream = m_protocol->GetInputStream(m_path);
+  if (!the_i_stream) {
+    m_error = wxURL_PROTOERR;
+    return NULL;
+  }
+
+  return the_i_stream;
+}
+
+void wxURL::SetDefaultProxy(const wxString& url_proxy)
+{
+  g_proxy.Close();
+
+  if (url_proxy.IsNull())
+    return;
+
+  wxString tmp_str = url_proxy;
+  int pos = tmp_str.Find(':');
+  wxString hostname = tmp_str(0, pos),
+           port = tmp_str(pos, tmp_str.Length()-pos);
+  wxIPV4address addr;
+
+  addr.Hostname(hostname);
+  addr.Service(port);
+  
+  g_proxy.Connect(addr);
+}
+
+void wxURL::SetProxy(const wxString& url_proxy)
+{
+  if (url_proxy.IsNull()) {
+    m_proxy.Close();
+    return;
+  }
+
+  CleanData();
+
+  wxString tmp_str;
+  wxString hostname, port;
+  int pos;
+  wxIPV4address addr;
+
+  tmp_str = url_proxy;
+  pos = tmp_str.Find(':');
+  hostname = tmp_str(0, pos);
+  port = tmp_str(pos, tmp_str.Length()-pos);
+
+  addr.Hostname(hostname);
+  addr.Service(port);
+
+  m_proxy.Connect(addr);
+
+  m_protocol = &m_proxy;
+  m_protoname = "proxy";
+  m_path = url_proxy;
+}
index 76e934d2ce120c3bf188b5d8cc9424f7a343567b..8465dc4630dd83022bff520cd675e0b9fa1029b8 100644 (file)
@@ -51,9 +51,19 @@ LIB_CPP_SRC=\
  common/mstream.cpp \
  common/zstream.cpp \
  common/objstrm.cpp \
+ common/sckstrm.cpp \
  common/validate.cpp \
  common/valtext.cpp \
  common/wxexpr.cpp \
+ common/tokenzr.cpp \
+ common/socket.cpp \
+ common/sckaddr.cpp \
+ common/protocol.cpp \
+ common/url.cpp \
+ common/http.cpp \
+ common/ftp.cpp \
+ common/sckfile.cpp \
+ common/sckipc.cpp \
 \
  gtk/accel.cpp \
  gtk/app.cpp \
index 8e02841a18957872208a782f00c0aeb0bb28f0a9..a0ab3cea95018e2a238dddd6e745aed734a7ed4e 100644 (file)
@@ -400,6 +400,50 @@ IMPLEMENT_DYNAMIC_CLASS(wxToolBar95, wxToolBarBase)
 
 #endif
 
+#include "wx/sckaddr.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxIPV4address, wxSockAddress)
+#ifdef ENABLE_IPV6
+IMPLEMENT_DYNAMIC_CLASS(wxIPV6address, wxSockAddress)
+#endif
+#ifndef __UNIX__
+IMPLEMENT_DYNAMIC_CLASS(wxUNIXaddress, wxSockAddress)
+#endif
+
+#include "wx/socket.h"
+
+IMPLEMENT_CLASS(wxSocketBase, wxEvtHandler)
+IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
+IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
+IMPLEMENT_CLASS(wxSocketHandler, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
+
+#include "wx/url.h"
+
+IMPLEMENT_CLASS(wxProtoInfo, wxObject)
+IMPLEMENT_CLASS(wxURL, wxObject)
+
+#include "wx/protocol/http.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxHTTP, wxProtocol)
+IMPLEMENT_PROTOCOL(wxHTTP, "http", "80", TRUE)
+
+#include "wx/protocol/ftp.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxFTP, wxProtocol)
+IMPLEMENT_PROTOCOL(wxFTP, "ftp", "ftp", TRUE)
+
+#include "wx/protocol/sckfile.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxFileProto, wxProtocol)
+IMPLEMENT_PROTOCOL(wxFileProto, "file", NULL, FALSE)
+
+#include "wx/sckipc.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxTCPServer, wxServerBase)
+IMPLEMENT_DYNAMIC_CLASS(wxTCPClient, wxClientBase)
+IMPLEMENT_DYNAMIC_CLASS(wxTCPConnection, wxConnectionBase)
+
 #include "wx/statusbr.h"
 
 IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow)
index 8e02841a18957872208a782f00c0aeb0bb28f0a9..a0ab3cea95018e2a238dddd6e745aed734a7ed4e 100644 (file)
@@ -400,6 +400,50 @@ IMPLEMENT_DYNAMIC_CLASS(wxToolBar95, wxToolBarBase)
 
 #endif
 
+#include "wx/sckaddr.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxIPV4address, wxSockAddress)
+#ifdef ENABLE_IPV6
+IMPLEMENT_DYNAMIC_CLASS(wxIPV6address, wxSockAddress)
+#endif
+#ifndef __UNIX__
+IMPLEMENT_DYNAMIC_CLASS(wxUNIXaddress, wxSockAddress)
+#endif
+
+#include "wx/socket.h"
+
+IMPLEMENT_CLASS(wxSocketBase, wxEvtHandler)
+IMPLEMENT_CLASS(wxSocketClient, wxSocketBase)
+IMPLEMENT_CLASS(wxSocketServer, wxSocketBase)
+IMPLEMENT_CLASS(wxSocketHandler, wxObject)
+IMPLEMENT_DYNAMIC_CLASS(wxSocketEvent, wxEvent)
+
+#include "wx/url.h"
+
+IMPLEMENT_CLASS(wxProtoInfo, wxObject)
+IMPLEMENT_CLASS(wxURL, wxObject)
+
+#include "wx/protocol/http.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxHTTP, wxProtocol)
+IMPLEMENT_PROTOCOL(wxHTTP, "http", "80", TRUE)
+
+#include "wx/protocol/ftp.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxFTP, wxProtocol)
+IMPLEMENT_PROTOCOL(wxFTP, "ftp", "ftp", TRUE)
+
+#include "wx/protocol/sckfile.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxFileProto, wxProtocol)
+IMPLEMENT_PROTOCOL(wxFileProto, "file", NULL, FALSE)
+
+#include "wx/sckipc.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxTCPServer, wxServerBase)
+IMPLEMENT_DYNAMIC_CLASS(wxTCPClient, wxClientBase)
+IMPLEMENT_DYNAMIC_CLASS(wxTCPConnection, wxConnectionBase)
+
 #include "wx/statusbr.h"
 
 IMPLEMENT_DYNAMIC_CLASS(wxStatusBar, wxWindow)