summaryrefslogtreecommitdiff
path: root/Userland/Libraries/LibIMAP/Parser.h
blob: 281f3ce8d62fe6042f4146f6561605672ba639f4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
/*
 * Copyright (c) 2021, Kyle Pereira <hey@xylepereira.me>
 *
 * SPDX-License-Identifier: BSD-2-Clause
 */

#pragma once

#include <AK/ByteBuffer.h>
#include <AK/Result.h>
#include <LibIMAP/Objects.h>

namespace IMAP {
class Client;

struct ParseStatus {
    bool successful;
    Optional<Response> response;
};

class Parser {
public:
    ParseStatus parse(ByteBuffer&& buffer, bool expecting_tag);

private:
    static MailboxFlag parse_mailbox_flag(StringView);

    void consume(StringView);
    bool try_consume(StringView);
    StringView consume_while(Function<bool(u8)> should_consume);
    StringView consume_until_end_of_line();

    bool at_end() { return position >= m_buffer.size(); };

    unsigned parse_number();
    Optional<unsigned> try_parse_number();

    void parse_response_done();
    void parse_untagged();
    void parse_capability_response();

    StringView parse_atom();
    StringView parse_quoted_string();
    StringView parse_literal_string();
    StringView parse_string();
    StringView parse_astring();
    Optional<StringView> parse_nstring();

    ResponseStatus parse_status();
    ListItem parse_list_item();
    FetchCommand::DataItem parse_fetch_data_item();
    FetchResponseData parse_fetch_response();
    Optional<Vector<Address>> parse_address_list();
    Address parse_address();
    HashMap<String, String> parse_body_fields_params();
    BodyStructure parse_body_structure();
    BodyStructure parse_one_part_body();
    BodyExtension parse_body_extension();
    Tuple<String, HashMap<String, String>> parse_disposition();
    Vector<String> parse_langs();
    Envelope parse_envelope();

    template<typename T>
    Vector<T> parse_list(T (*converter)(StringView));

    // To retain state if parsing is not finished
    ByteBuffer m_buffer;
    SolidResponse m_response;
    unsigned position { 0 };
    bool m_incomplete { false };
    bool m_parsing_failed { false };
};
}