summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibIMAP
diff options
context:
space:
mode:
authorx-yl <kylepereira@mail.com>2021-06-01 17:42:12 +0400
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2021-06-11 23:58:28 +0430
commit0f42ea6770af1e086b07fb8309ca0af6848097c9 (patch)
tree57f6f55776caa5371c6f847a79f7717c2e420e8f /Userland/Libraries/LibIMAP
parentac712b07f9cfc5494bd259976addebabedc091d2 (diff)
downloadserenity-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.cpp2
-rw-r--r--Userland/Libraries/LibIMAP/Objects.h16
-rw-r--r--Userland/Libraries/LibIMAP/Parser.cpp28
-rw-r--r--Userland/Libraries/LibIMAP/Parser.h9
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();
};
}