xref: /haiku/src/add-ons/mail_daemon/inbound_protocols/imap/imap_lib/Response.h (revision 372b901dfeada686207d00bbcce456f748bbda12)
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 
16 namespace IMAP {
17 
18 
19 class Argument;
20 class Response;
21 
22 
23 class RFC3501Encoding {
24 public:
25 								RFC3501Encoding();
26 								~RFC3501Encoding();
27 
28 			BString				Encode(const BString& clearText) const;
29 			BString				Decode(const BString& encodedText) const;
30 
31 private:
32 			void				_ToUTF8(BString& string, uint32 c) const;
33 			void				_Unshift(BString& string, int32& bitsToWrite,
34 									int32& sextet, bool& shifted) const;
35 };
36 
37 
38 class ArgumentList : public BObjectList<Argument> {
39 public:
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 
60 class Argument {
61 public:
62 								Argument();
63 	virtual						~Argument();
64 
65 	virtual	BString				ToString() const = 0;
66 };
67 
68 
69 class ListArgument : public Argument {
70 public:
71 								ListArgument(char kind);
72 
73 			ArgumentList&		List() { return fList; }
74 			char				Kind() { return fKind; }
75 
76 	virtual	BString				ToString() const;
77 
78 private:
79 			ArgumentList		fList;
80 			char				fKind;
81 };
82 
83 
84 class StringArgument : public Argument {
85 public:
86 								StringArgument(const BString& string);
87 								StringArgument(const StringArgument& other);
88 
89 			const BString&		String() { return fString; }
90 
91 	virtual	BString				ToString() const;
92 
93 private:
94 			BString				fString;
95 };
96 
97 
98 class ParseException : public std::exception {
99 public:
100 								ParseException();
101 								ParseException(const char* format, ...);
102 
103 			const char*			Message() const { return fBuffer; }
104 
105 protected:
106 			char				fBuffer[64];
107 };
108 
109 
110 class StreamException : public std::exception {
111 public:
112 								StreamException(status_t status);
113 
114 			status_t			Status() const { return fStatus; }
115 
116 private:
117 			status_t			fStatus;
118 };
119 
120 
121 class ExpectedParseException : public ParseException {
122 public:
123 								ExpectedParseException(char expected,
124 									char instead);
125 
126 protected:
127 			const char*			CharToString(char* buffer, size_t size, char c);
128 };
129 
130 
131 class LiteralHandler {
132 public:
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 
142 class Response : public ArgumentList {
143 public:
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 
154 protected:
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 
175 private:
176 			void				_SkipLiteral(BDataIO& stream, size_t size);
177 
178 protected:
179 			LiteralHandler*		fLiteralHandler;
180 			uint32				fTag;
181 			bool				fContinuation;
182 			bool				fHasNextChar;
183 			char				fNextChar;
184 };
185 
186 
187 class ResponseParser {
188 public:
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 
198 private:
199 								ResponseParser(const ResponseParser& other);
200 
201 protected:
202 			BDataIO*			fStream;
203 			LiteralHandler*		fLiteralHandler;
204 };
205 
206 
207 }	// namespace IMAP
208 
209 
210 #endif // RESPONSE_H
211