1/*
2 * Copyright 2011-2016, Axel D��rfler, axeld@pinc-software.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef RESPONSE_H
6#define RESPONSE_H
7
8
9#include <stdexcept>
10
11#include <DataIO.h>
12#include <ObjectList.h>
13#include <String.h>
14
15
16namespace IMAP {
17
18
19class Argument;
20class Response;
21
22
23class RFC3501Encoding {
24public:
25								RFC3501Encoding();
26								~RFC3501Encoding();
27
28			BString				Encode(const BString& clearText) const;
29			BString				Decode(const BString& encodedText) const;
30
31private:
32			void				_ToUTF8(BString& string, uint32 c) const;
33			void				_Unshift(BString& string, int32& bitsToWrite,
34									int32& sextet, bool& shifted) const;
35};
36
37
38class ArgumentList : public BObjectList<Argument> {
39public:
40								ArgumentList();
41								~ArgumentList();
42
43			bool				Contains(const char* string) const;
44			BString				StringAt(int32 index) const;
45			bool				IsStringAt(int32 index) const;
46			bool				EqualsAt(int32 index,
47									const char* string) const;
48
49			ArgumentList&		ListAt(int32 index) const;
50			bool				IsListAt(int32 index) const;
51			bool				IsListAt(int32 index, char kind) const;
52
53			uint32				NumberAt(int32 index) const;
54			bool				IsNumberAt(int32 index) const;
55
56			BString				ToString() const;
57};
58
59
60class Argument {
61public:
62								Argument();
63	virtual						~Argument();
64
65	virtual	BString				ToString() const = 0;
66};
67
68
69class ListArgument : public Argument {
70public:
71								ListArgument(char kind);
72
73			ArgumentList&		List() { return fList; }
74			char				Kind() { return fKind; }
75
76	virtual	BString				ToString() const;
77
78private:
79			ArgumentList		fList;
80			char				fKind;
81};
82
83
84class StringArgument : public Argument {
85public:
86								StringArgument(const BString& string);
87								StringArgument(const StringArgument& other);
88
89			const BString&		String() { return fString; }
90
91	virtual	BString				ToString() const;
92
93private:
94			BString				fString;
95};
96
97
98class ParseException : public std::exception {
99public:
100								ParseException();
101								ParseException(const char* format, ...);
102
103			const char*			Message() const { return fBuffer; }
104
105protected:
106			char				fBuffer[64];
107};
108
109
110class StreamException : public std::exception {
111public:
112								StreamException(status_t status);
113
114			status_t			Status() const { return fStatus; }
115
116private:
117			status_t			fStatus;
118};
119
120
121class ExpectedParseException : public ParseException {
122public:
123								ExpectedParseException(char expected,
124									char instead);
125
126protected:
127			const char*			CharToString(char* buffer, size_t size, char c);
128};
129
130
131class LiteralHandler {
132public:
133								LiteralHandler();
134	virtual						~LiteralHandler();
135
136	virtual bool				HandleLiteral(Response& response,
137									ArgumentList& arguments, BDataIO& stream,
138									size_t& length) = 0;
139};
140
141
142class Response : public ArgumentList {
143public:
144								Response();
145								~Response();
146
147			void				Parse(BDataIO& stream, LiteralHandler* handler);
148
149			bool				IsUntagged() const { return fTag == 0; }
150			uint32				Tag() const { return fTag; }
151			bool				IsCommand(const char* command) const;
152			bool				IsContinuation() const { return fContinuation; }
153
154protected:
155			char				ParseLine(ArgumentList& arguments,
156									BDataIO& stream);
157			void				ParseList(ArgumentList& arguments,
158									BDataIO& stream, char start, char end);
159			void				ParseQuoted(ArgumentList& arguments,
160									BDataIO& stream);
161			void				ParseLiteral(ArgumentList& arguments,
162									BDataIO& stream);
163			void				ParseString(ArgumentList& arguments,
164									BDataIO& stream);
165
166			BString				ExtractString(BDataIO& stream);
167			size_t				ExtractNumber(BDataIO& stream);
168
169			void				Consume(BDataIO& stream, char c);
170
171			char				Next(BDataIO& stream);
172			char				Peek(BDataIO& stream);
173			char				Read(BDataIO& stream);
174
175private:
176			void				_SkipLiteral(BDataIO& stream, size_t size);
177
178protected:
179			LiteralHandler*		fLiteralHandler;
180			uint32				fTag;
181			bool				fContinuation;
182			bool				fHasNextChar;
183			char				fNextChar;
184};
185
186
187class ResponseParser {
188public:
189								ResponseParser(BDataIO& stream);
190								~ResponseParser();
191
192			void				SetTo(BDataIO& stream);
193			void				SetLiteralHandler(LiteralHandler* handler);
194
195			status_t			NextResponse(Response& response,
196									bigtime_t timeout);
197
198private:
199								ResponseParser(const ResponseParser& other);
200
201protected:
202			BDataIO*			fStream;
203			LiteralHandler*		fLiteralHandler;
204};
205
206
207}	// namespace IMAP
208
209
210#endif // RESPONSE_H
211