/* * xmlprotocol.h - state machine for 'jabber-like' protocols * Copyright (C) 2004 Justin Karneges * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * */ #ifndef XMLPROTOCOL_H #define XMLPROTOCOL_H #include #include #include"parser.h" #define NS_XML "http://www.w3.org/XML/1998/namespace" namespace XMPP { class XmlProtocol { public: enum Need { NNotify, // need a data send and/or recv update NCustom = 10 }; enum Event { EError, // unrecoverable error, see errorCode for details ESend, // data needs to be sent, use takeOutgoingData() ERecvOpen, // breakpoint after root element open tag is received EPeerClosed, // root element close tag received EClosed, // finished closing ECustom = 10 }; enum Error { ErrParse, // there was an error parsing the xml ErrCustom = 10 }; enum Notify { NSend = 0x01, // need to know if data has been written NRecv = 0x02 // need incoming data }; XmlProtocol(); virtual ~XmlProtocol(); virtual void reset(); // byte I/O for the stream void addIncomingData(const TQByteArray &); TQByteArray takeOutgoingData(); void outgoingDataWritten(int); // advance the state machine bool processStep(); // set these before returning from a step int need, event, errorCode, notify; inline bool isIncoming() const { return incoming; } TQString xmlEncoding() const; TQString elementToString(const TQDomElement &e, bool clip=false); class TransferItem { public: TransferItem(); TransferItem(const TQString &str, bool sent, bool external=false); TransferItem(const TQDomElement &elem, bool sent, bool external=false); bool isSent; // else, received bool isString; // else, is element bool isExternal; // not owned by protocol TQString str; TQDomElement elem; }; TQValueList transferItemList; void setIncomingAsExternal(); protected: virtual TQDomElement docElement()=0; virtual void handleDocOpen(const Parser::Event &pe)=0; virtual bool handleError()=0; virtual bool handleCloseFinished()=0; virtual bool stepAdvancesParser() const=0; virtual bool stepRequiresElement() const; virtual bool doStep(const TQDomElement &e)=0; virtual void itemWritten(int id, int size); // 'debug' virtual void stringSend(const TQString &s); virtual void stringRecv(const TQString &s); virtual void elementSend(const TQDomElement &e); virtual void elementRecv(const TQDomElement &e); void startConnect(); void startAccept(); bool close(); int writeString(const TQString &s, int id, bool external); int writeElement(const TQDomElement &e, int id, bool external, bool clip=false); TQByteArray resetStream(); private: enum { SendOpen, RecvOpen, Open, Closing }; class TrackItem { public: enum Type { Raw, Close, Custom }; int type, id, size; }; bool incoming; TQDomDocument elemDoc; TQDomElement elem; TQString tagOpen, tagClose; int state; bool peerClosed; bool closeWritten; Parser xml; TQByteArray outData; TQValueList trackQueue; void init(); int internalWriteData(const TQByteArray &a, TrackItem::Type t, int id=-1); int internalWriteString(const TQString &s, TrackItem::Type t, int id=-1); void sendTagOpen(); void sendTagClose(); bool baseStep(const Parser::Event &pe); }; } #endif