diff options
author | x-yl <kylepereira@mail.com> | 2021-06-01 17:42:12 +0400 |
---|---|---|
committer | Ali Mohammad Pur <Ali.mpfard@gmail.com> | 2021-06-11 23:58:28 +0430 |
commit | 0f42ea6770af1e086b07fb8309ca0af6848097c9 (patch) | |
tree | 57f6f55776caa5371c6f847a79f7717c2e420e8f /Userland/Libraries/LibIMAP | |
parent | ac712b07f9cfc5494bd259976addebabedc091d2 (diff) | |
download | serenity-0f42ea6770af1e086b07fb8309ca0af6848097c9.zip |
LibIMAP: Support for CAPABILITY command & response
This involves parsing messages with untagged responses
Diffstat (limited to 'Userland/Libraries/LibIMAP')
-rw-r--r-- | Userland/Libraries/LibIMAP/Client.cpp | 2 | ||||
-rw-r--r-- | Userland/Libraries/LibIMAP/Objects.h | 16 | ||||
-rw-r--r-- | Userland/Libraries/LibIMAP/Parser.cpp | 28 | ||||
-rw-r--r-- | Userland/Libraries/LibIMAP/Parser.h | 9 |
4 files changed, 55 insertions, 0 deletions
diff --git a/Userland/Libraries/LibIMAP/Client.cpp b/Userland/Libraries/LibIMAP/Client.cpp index 160b51131c..77570c6ac6 100644 --- a/Userland/Libraries/LibIMAP/Client.cpp +++ b/Userland/Libraries/LibIMAP/Client.cpp @@ -112,6 +112,8 @@ static ReadonlyBytes command_byte_buffer(CommandType command) switch (command) { case CommandType::Noop: return "NOOP"sv.bytes(); + case CommandType::Capability: + return "CAPABILITY"sv.bytes(); } VERIFY_NOT_REACHED(); } diff --git a/Userland/Libraries/LibIMAP/Objects.h b/Userland/Libraries/LibIMAP/Objects.h index 037b9387b5..daaf5fbe55 100644 --- a/Userland/Libraries/LibIMAP/Objects.h +++ b/Userland/Libraries/LibIMAP/Objects.h @@ -17,10 +17,12 @@ namespace IMAP { enum class CommandType { + Capability, Noop, }; enum class ResponseType : unsigned { + Capability = 1u << 0, }; class Parser; @@ -65,8 +67,22 @@ public: m_response_type = m_response_type | static_cast<unsigned>(response_type); } + void add_capabilities(Vector<String>&& capabilities) + { + m_capabilities = move(capabilities); + add_response_type(ResponseType::Capability); + } + + Vector<String>& capabilities() + { + VERIFY(contains_response_type(ResponseType::Capability)); + return m_capabilities; + } + private: unsigned m_response_type; + + Vector<String> m_capabilities; }; class SolidResponse { diff --git a/Userland/Libraries/LibIMAP/Parser.cpp b/Userland/Libraries/LibIMAP/Parser.cpp index 1c872e242a..48e9db7ab5 100644 --- a/Userland/Libraries/LibIMAP/Parser.cpp +++ b/Userland/Libraries/LibIMAP/Parser.cpp @@ -27,6 +27,10 @@ ParseStatus Parser::parse(ByteBuffer&& buffer, bool expecting_tag) return { true, { ContinueRequest { data } } }; } + while (try_consume("*")) { + parse_untagged(); + } + if (expecting_tag) { if (at_end()) { m_incomplete = true; @@ -117,6 +121,30 @@ unsigned Parser::parse_number() return number.value(); } +void Parser::parse_untagged() +{ + consume(" "); + + if (try_consume("CAPABILITY")) { + parse_capability_response(); + } else { + auto x = parse_while([](u8 x) { return x != '\r'; }); + consume("\r\n"); + dbgln("ignored {}", x); + } +} + +void Parser::parse_capability_response() +{ + auto capability = AK::Vector<String>(); + while (!try_consume("\r\n")) { + consume(" "); + auto x = String(parse_atom()); + capability.append(x); + } + m_response.data().add_capabilities(move(capability)); +} + StringView Parser::parse_atom() { auto is_non_atom_char = [](u8 x) { diff --git a/Userland/Libraries/LibIMAP/Parser.h b/Userland/Libraries/LibIMAP/Parser.h index 9a4ee07e5e..e2967ef128 100644 --- a/Userland/Libraries/LibIMAP/Parser.h +++ b/Userland/Libraries/LibIMAP/Parser.h @@ -32,13 +32,22 @@ private: bool try_consume(StringView); bool at_end() { return position >= m_buffer.size(); }; + void parse_response_done(); + void consume(StringView x); + unsigned parse_number(); Optional<unsigned> try_parse_number(); + void parse_untagged(); + StringView parse_atom(); + ResponseStatus parse_status(); + StringView parse_while(Function<bool(u8)> should_consume); + + void parse_capability_response(); }; } |