Code

improve streaming
[inkscape.git] / src / pedro / pedroxmpp.h
index d938a25fd76dfc6830b2e6d8c3dc21284f16ab69..34b6d039067a2faf76c8584dc4584782c55ee770 100644 (file)
@@ -6,7 +6,7 @@
  * Authors:
  *   Bob Jamison
  *
- * Copyright (C) 2005 Bob Jamison
+ * Copyright (C) 2005-2006 Bob Jamison
  *
  *  This library is free software; you can redistribute it and/or
  *  modify it under the terms of the GNU Lesser General Public
@@ -25,6 +25,7 @@
 
 #include <stdio.h>
 #include <vector>
+#include <map>
 
 #include <string>
 
@@ -84,60 +85,200 @@ public:
     DOMString show;
 };
 
+
+
+
+
+/**
+ * Class that emits information from a client
+ */
 class XmppEvent
 {
 
 public:
 
-typedef enum
-    {
-    EVENT_NONE,
-    EVENT_STATUS,
-    EVENT_ERROR,
-    EVENT_CONNECTED,
-    EVENT_DISCONNECTED,
-    EVENT_PRESENCE,
-    EVENT_ROSTER,
-    EVENT_MESSAGE,
-    EVENT_MUC_JOIN,
-    EVENT_MUC_LEAVE,
-    EVENT_MUC_PRESENCE,
-    EVENT_MUC_MESSAGE,
-    EVENT_STREAM_RECEIVE_INIT,
-    EVENT_STREAM_RECEIVE,
-    EVENT_STREAM_RECEIVE_CLOSE,
-    EVENT_FILE_ACCEPTED,
-    EVENT_FILE_RECEIVE
-    } XmppEventType;
+    /**
+     * People might want to refer to these docs to understand
+     * the XMPP terminology used here.
+     * http://www.ietf.org/rfc/rfc3920.txt      -- Xmpp Core
+     * http://www.ietf.org/rfc/rfc3921.txt      -- Messaging and presence
+     * http://www.jabber.org/jeps/jep-0077.html -- In-Band registration
+     * http://www.jabber.org/jeps/jep-0045.html -- Multiuser Chat
+     * http://www.jabber.org/jeps/jep-0047.html -- In-Band byte streams
+     * http://www.jabber.org/jeps/jep-0096.html -- File transfer
+     */
 
+    /**
+     *  No event type.  Default
+     */
+    static const int EVENT_NONE                 =  0;
 
     /**
-     *
+     *  Client emits a status message.  Message is in getData().
+     */
+    static const int EVENT_STATUS               =  1;
+
+    /**
+     *  Client emits an error message.  Message is in getData().
+     */
+    static const int EVENT_ERROR                =  2;
+
+    /**
+     *  Client has connected to a host.  Host name is in getData().
+     */
+    static const int EVENT_CONNECTED            = 10;
+
+    /**
+     *  Client has disconnected from a host.  Host name is in getData().
+     */
+    static const int EVENT_DISCONNECTED         = 11;
+
+    /**
+     *  Client has begun speaking to the server in SSL.  This is usually
+     *  emitted just before EVENT_CONNECTED,  since authorization has not
+     *  yet taken place.
+     */
+    static const int EVENT_SSL_STARTED          = 12;
+
+    /**
+     *  Client has successfully registered a new account on a server.
+     *  The server is in getFrom(), the user in getTo()
+     */
+    static const int EVENT_REGISTRATION_NEW     = 20;
+
+    /**
+     *  Client has successfully changed the password of an existing account on a server.
+     *  The server is in getFrom(), the user in getTo()
+     */
+    static const int EVENT_REGISTRATION_CHANGE_PASS  = 21;
+
+    /**
+     *  Client has successfully cancelled an existing account on a server.
+     *  The server is in getFrom(), the user in getTo()
+     */
+    static const int EVENT_REGISTRATION_CANCEL  = 22;
+
+    /**
+     *  A <presence> packet has been received.
+     *  getFrom()     returns the full jabber id
+     *  getPresence() returns the available/unavailable boolean
+     *  getShow()     returns the jabber 'show' string: 'show', 'away', 'xa', etc
+     *  getStatus()   returns a status message, sent from a client
+     *  Note: if a presence packet is determined to be MUC, it is
+     *    rather sent as an EVENT_MUC_JOIN, LEAVE, or PRESENCE
+     */
+    static const int EVENT_PRESENCE             = 30;
+
+    /**
+     *  Client has just received a complete roster.  The collected information
+     *  can be found at client.getRoster(), and is a std::vector of XmppUser
+     *  records.
+     */
+    static const int EVENT_ROSTER               = 31;
+
+    /**
+     *  Client has just received a message packet.
+     *  getFrom() returns the full jabber id of the sender
+     *  getData() returns the text of the message
+     *  getDom()  returns the DOM treelet for this stanza.  This is provided
+     *                to make message extension easier.
+     *  Note: if a message packet is determined to be MUC, it is
+     *    rather sent as an EVENT_MUC_MESSAGE
+     */
+    static const int EVENT_MESSAGE              = 32;
+
+    /**
+     *  THIS user has just joined a multi-user chat group.
+     *  getGroup()    returns the group name
+     *  getFrom()     returns the nick of the user in the group
+     *  getPresence() returns the available/unavailable boolean
+     *  getShow()     returns the jabber 'show' string: 'show', 'away', 'xa', etc
+     *  getStatus()   returns a status message, sent from a client
+     */
+    static const int EVENT_MUC_JOIN             = 40;
+
+    /**
+     *  THIS user has just left a multi-user chat group.
+     *  getGroup()    returns the group name
+     *  getFrom()     returns the nick of the user in the group
+     *  getPresence() returns the available/unavailable boolean
+     *  getShow()     returns the jabber 'show' string: 'show', 'away', 'xa', etc
+     *  getStatus()   returns a status message, sent from a client
+     */
+    static const int EVENT_MUC_LEAVE            = 41;
+
+    /**
+     *  Presence for another user in a multi-user chat room.
+     *  getGroup()    returns the group name
+     *  getFrom()     returns the nick of the user in the group
+     *  getPresence() returns the available/unavailable boolean
+     *  getShow()     returns the jabber 'show' string: 'show', 'away', 'xa', etc
+     *  getStatus()   returns a status message, sent from a client
+     */
+    static const int EVENT_MUC_PRESENCE         = 42;
+
+    /**
+     *  Client has just received a message packet from a multi-user chat room
+     *  getGroup() returns the group name
+     *  getFrom()  returns the full jabber id of the sender
+     *  getData()  returns the text of the message
+     *  getDom()   returns the DOM treelet for this stanza.  This is provided
+     *             to make message extension easier.
+     */
+    static const int EVENT_MUC_MESSAGE          = 43;
+
+    /**
+     *  Client has begun receiving a stream
+     */
+    static const int EVENT_STREAM_RECEIVE_INIT  = 50;
+
+    /**
+     *  Client receives another stream packet.
+     */
+    static const int EVENT_STREAM_RECEIVE       = 51;
+
+    /**
+     * Client has received the end of a stream
+     */
+    static const int EVENT_STREAM_RECEIVE_CLOSE = 52;
+
+    /**
+     * Other client has accepted a file.
+     */
+    static const int EVENT_FILE_ACCEPTED        = 60;
+
+    /**
+     * This client has just received a file.
+     */
+    static const int EVENT_FILE_RECEIVE         = 61;
+
+    /**
+     *  Constructs an event with one of the types above.
      */
     XmppEvent(int type);
 
     /**
-     *
+     *  Copy constructor
      */
     XmppEvent(const XmppEvent &other);
 
     /**
-     *
+     *  Assignment
      */
     virtual XmppEvent &operator=(const XmppEvent &other);
 
     /**
-     *
+     *  Destructor
      */
     virtual ~XmppEvent();
 
     /**
-     *
+     *  Assignment
      */
     virtual void assign(const XmppEvent &other);
 
     /**
-     *
+     *  Return the event type.
      */
     virtual int getType() const;
 
@@ -337,35 +478,46 @@ private:
 };
 
 
+
+
+
+
 //########################################################################
 //# X M P P    E V E N T    L I S T E N E R
 //########################################################################
 
+/**
+ * Class that receives and processes an XmppEvent.  Users should inherit
+ * from this class, and overload processXmppEvent() to perform their event
+ * handling
+ */
 class XmppEventListener
 {
 public:
 
     /**
-     *
+     *  Constructor  
      */
     XmppEventListener()
         {}
 
     /**
-     *
+     *  Assignment
      */
     XmppEventListener(const XmppEventListener &other)
         {}
 
 
     /**
-     *
+     * Destructor
      */
     virtual ~XmppEventListener()
         {}
 
     /**
-     *
+     *  Overload this method to provide your application-specific
+     *  event handling.  Use event.getType() to decide what to do
+     *  with the event.
      */
     virtual void processXmppEvent(const XmppEvent &event)
         {}
@@ -378,22 +530,30 @@ public:
 //# X M P P    E V E N T    T A R G E T
 //########################################################################
 
+/**
+ * A base class for classes that emit XmppEvents.
+ *
+ * Note: terminology: 'target' is the common term for this, although it
+ * seems odd that a 'target' is the source of the events.  It is clearer
+ * if you consider that the greater system targets this class with events,
+ * and this class delegates the handling to its listeners.
+ */
 class XmppEventTarget
 {
 public:
 
     /**
-     *
+     * Constructor
      */
     XmppEventTarget();
 
     /**
-     *
+     *  Copy constructor
      */
     XmppEventTarget(const XmppEventTarget &other);
 
     /**
-     *
+     * Destructor
      */
     virtual ~XmppEventTarget();
 
@@ -419,37 +579,46 @@ public:
     //###########################
 
     /**
-     *
-     */
-    virtual void dispatchXmppEvent(const XmppEvent &event);
-
-    /**
-     *
+     *  Subscribe a subclass of XmppEventListener to this target's events.
      */
     virtual void addXmppEventListener(const XmppEventListener &listener);
 
     /**
-     *
+     *  Unsubscribe a subclass of XmppEventListener from this target's events.
      */
     virtual void removeXmppEventListener(const XmppEventListener &listener);
 
     /**
-     *
+     *  Remove all event subscribers
      */
     virtual void clearXmppEventListeners();
 
     /**
-     *
+     *  This sends an event to all registered listeners.
+     */
+    virtual void dispatchXmppEvent(const XmppEvent &event);
+
+    /**
+     *  By enabling this, you provide an alternate way to get XmppEvents.
+     *  Any event sent to dispatchXmppEvent() is also sent to this queue,
+     *  so that it can be later be picked up by eventQueuePop();
+     *  This can sometimes be good for GUI's which can't always respond
+     *  repidly or asynchronously.
      */
     void eventQueueEnable(bool val);
 
     /**
-     *
+     *  Return true if there is one or more XmppEvents waiting in the event
+     *  queue.  This is used to avoid calling eventQueuePop() when there is
+     *  nothing in the queue.
      */
     int eventQueueAvailable();
 
     /**
-     *
+     *  Return the next XmppEvent in the queue.  Users should check that
+     *  eventQueueAvailable() is greater than 0 before calling this.  If
+     *  people forget to do this, an event of type XmppEvent::EVENT_NONE
+     *  is generated and returned.
      */
     XmppEvent eventQueuePop();
 
@@ -474,12 +643,16 @@ private:
 //# X M P P    C L I E N T
 //########################################################################
 
-
+//forward declarations
 class TcpSocket;
 class XmppChat;
 class XmppGroupChat;
 class XmppStream;
 
+
+/**
+ *  This is the actual XMPP (Jabber) client.
+ */
 class XmppClient : public XmppEventTarget
 {
 
@@ -490,22 +663,22 @@ public:
     //###########################
 
     /**
-     *
+     * Constructor
      */
     XmppClient();
 
     /**
-     *
+     *  Copy constructor
      */
     XmppClient(const XmppClient &other);
 
     /**
-     *
+     *  Assignment
      */
     void assign(const XmppClient &other);
 
     /**
-     *
+     * Destructor
      */
     virtual ~XmppClient();
 
@@ -515,12 +688,14 @@ public:
     //###########################
 
     /**
-     *
+     *  Pause execution of the app for a given number of
+     *  milliseconds.  Use this rarely, only when really needed.
      */
     virtual bool pause(unsigned long millis);
 
     /**
-     *
+     *  Process a string so that it can safely be
+     *  placed in XML as PCDATA
      */
     DOMString toXml(const DOMString &str);
 
@@ -552,6 +727,10 @@ public:
      */
     virtual bool write(char *fmt, ...);
 
+    //#######################
+    //# V A R I A B L E S
+    //#######################
+
     /**
      *
      */
@@ -628,17 +807,33 @@ public:
     virtual void setResource(const DOMString &val)
         { resource = val; }
 
+    /**
+     *
+     */
+    virtual void setJid(const DOMString &val)
+        { jid = val; }
+
     /**
      *
      */
     virtual DOMString getJid()
         { return jid; }
+
+
+
     /**
      *
      */
     virtual int getMsgId()
         { return msgId++; }
 
+
+
+    //#######################
+    //# P R O C E S S I N G
+    //#######################
+
+
     /**
      *
      */
@@ -689,7 +884,30 @@ public:
      *
      */
     virtual void rosterShow(const DOMString &jid, const DOMString &show);
-    
+
+    //#######################
+    //# REGISTRATION
+    //#######################
+
+    /**
+     *  Set whether the client should to in-band registration
+     *  before authentication.  Causes inBandRegistrationNew() to be called
+     *  synchronously, before async is started.
+     */
+    virtual void setDoRegister(bool val)
+        { doRegister = val; }
+
+    /**
+     * Change the password of an existing account with a server
+     */
+    bool inBandRegistrationChangePassword(const DOMString &newPassword);
+
+    /**
+     * Cancel an existing account with a server
+     */
+    bool inBandRegistrationCancel();
+
+
     //#######################
     //# CHAT (individual)
     //#######################
@@ -757,7 +975,7 @@ public:
      *
      */
     virtual std::vector<XmppUser>
-          XmppClient::groupChatGetUserList(const DOMString &groupJid);
+             groupChatGetUserList(const DOMString &groupJid);
 
     /**
      *
@@ -810,46 +1028,31 @@ public:
     /**
      *
      */
-    virtual int outputStreamOpen(const DOMString &jid,
+    virtual bool outputStreamOpen(const DOMString &jid,
                                  const DOMString &streamId);
 
     /**
      *
      */
-    virtual int outputStreamWrite(int streamId,
-                          const unsigned char *buf, unsigned long len);
+    virtual bool outputStreamWrite(const DOMString &streamId,
+               const std::vector<unsigned char> &buf);
 
     /**
      *
      */
-    virtual int outputStreamClose(int streamId);
+    virtual bool outputStreamClose(const DOMString &streamId);
 
     /**
      *
      */
-    virtual int inputStreamOpen(const DOMString &jid,
+    virtual bool inputStreamOpen(const DOMString &jid,
                                 const DOMString &streamId,
                                 const DOMString &iqId);
 
     /**
      *
      */
-    virtual int inputStreamAvailable(int streamId);
-
-    /**
-     *
-     */
-    virtual std::vector<unsigned char> inputStreamRead(int streamId);
-
-    /**
-     *
-     */
-    virtual bool inputStreamClosing(int streamId);
-
-    /**
-     *
-     */
-    virtual int inputStreamClose(int streamId);
+    virtual bool inputStreamClose(const DOMString &streamId);
 
 
     //#######################
@@ -934,27 +1137,42 @@ private:
 
     bool iqAuthenticate(const DOMString &streamId);
 
+    /**
+     * Register a new account with a server.  Not done by user
+     */
+    bool inBandRegistrationNew();
+
     bool keepGoing;
 
+    bool doRegister;
+
     static const int writeBufLen = 2048;
 
     unsigned char writeBuf[writeBufLen];
 
     std::vector<XmppGroupChat *>groupChats;
 
-    static const int outputStreamCount = 16;
+    //#### Roster
+    std::vector<XmppUser>roster;
+
 
-    XmppStream *outputStreams[outputStreamCount];
+    //#### Streams
+    
+    bool processInBandByteStreamMessage(Element *root);
+    
+    DOMString streamPacket;
 
-    static const int inputStreamCount = 16;
+    std::map<DOMString, XmppStream *> outputStreams;
 
-    XmppStream *inputStreams[inputStreamCount];
+    std::map<DOMString, XmppStream *> inputStreams;
 
-    static const int fileSendCount = 16;
 
-    XmppStream *fileSends[fileSendCount];
+    //#### File send
+    
+    bool processFileMessage(Element *root);
+
+    std::map<DOMString, XmppStream *> fileSends;
 
-    std::vector<XmppUser>roster;
 };
 
 
@@ -994,7 +1212,7 @@ public:
     /**
      *
      */
-    virtual void userAdd(const DOMString &nick, 
+    virtual void userAdd(const DOMString &nick,
                          const DOMString &jid);
     /**
      *