summaryrefslogtreecommitdiffstats
path: root/kopete/protocols/jabber/libiris/iris/xmpp-core/xmlprotocol.h
blob: 5bf2cbdae5acbd53acf045624e3569afaa534a64 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
/*
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#ifndef XMLPROTOCOL_H
#define XMLPROTOCOL_H

#include<qdom.h>
#include<qvaluelist.h>
#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 QByteArray &);
		QByteArray 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; }
		QString xmlEncoding() const;
		QString elementToString(const QDomElement &e, bool clip=false);

		class TransferItem
		{
		public:
			TransferItem();
			TransferItem(const QString &str, bool sent, bool external=false);
			TransferItem(const QDomElement &elem, bool sent, bool external=false);

			bool isSent; // else, received
			bool isString; // else, is element
			bool isExternal; // not owned by protocol
			QString str;
			QDomElement elem;
		};
		QValueList<TransferItem> transferItemList;
		void setIncomingAsExternal();

	protected:
		virtual QDomElement 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 QDomElement &e)=0;
		virtual void itemWritten(int id, int size);

		// 'debug'
		virtual void stringSend(const QString &s);
		virtual void stringRecv(const QString &s);
		virtual void elementSend(const QDomElement &e);
		virtual void elementRecv(const QDomElement &e);

		void startConnect();
		void startAccept();
		bool close();
		int writeString(const QString &s, int id, bool external);
		int writeElement(const QDomElement &e, int id, bool external, bool clip=false);
		QByteArray resetStream();

	private:
		enum { SendOpen, RecvOpen, Open, Closing };
		class TrackItem
		{
		public:
			enum Type { Raw, Close, Custom };
			int type, id, size;
		};

		bool incoming;
		QDomDocument elemDoc;
		QDomElement elem;
		QString tagOpen, tagClose;
		int state;
		bool peerClosed;
		bool closeWritten;

		Parser xml;
		QByteArray outData;
		QValueList<TrackItem> trackQueue;

		void init();
		int internalWriteData(const QByteArray &a, TrackItem::Type t, int id=-1);
		int internalWriteString(const QString &s, TrackItem::Type t, int id=-1);
		void sendTagOpen();
		void sendTagClose();
		bool baseStep(const Parser::Event &pe);
	};
}

#endif