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