aboutsummaryrefslogtreecommitdiffstats
path: root/vmime/net/imap/IMAPParser.hpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--vmime/net/imap/IMAPParser.hpp837
1 files changed, 573 insertions, 264 deletions
diff --git a/vmime/net/imap/IMAPParser.hpp b/vmime/net/imap/IMAPParser.hpp
index 41252a92..af871c27 100644
--- a/vmime/net/imap/IMAPParser.hpp
+++ b/vmime/net/imap/IMAPParser.hpp
@@ -1288,6 +1288,211 @@ public:
};
+ // seq-number = nz-number / "*"
+ // ; message sequence number (COPY, FETCH, STORE
+ // ; commands) or unique identifier (UID COPY,
+ // ; UID FETCH, UID STORE commands).
+
+ class seq_number : public component
+ {
+ public:
+
+ seq_number()
+ : m_number(NULL), m_star(false)
+ {
+ }
+
+ ~seq_number()
+ {
+ delete m_number;
+ }
+
+ void go(IMAPParser& parser, string& line, string::size_type* currentPos)
+ {
+ DEBUG_ENTER_COMPONENT("seq_number");
+
+ string::size_type pos = *currentPos;
+
+ if (parser.check <one_char <'*'> >(line, &pos, true))
+ {
+ m_star = true;
+ m_number = NULL;
+ }
+ else
+ {
+ m_star = false;
+ m_number = parser.get <IMAPParser::number>(line, &pos);
+ }
+
+ *currentPos = pos;
+ }
+
+ private:
+
+ IMAPParser::number* m_number;
+ bool m_star;
+
+ public:
+
+ const IMAPParser::number* number() const { return m_number; }
+ bool star() const { return m_star; }
+ };
+
+
+ // seq-range = seq-number ":" seq-number
+ // ; two seq-number values and all values between
+ // ; these two regardless of order.
+ // ; Example: 2:4 and 4:2 are equivalent and indicate
+ // ; values 2, 3, and 4.
+
+ class seq_range : public component
+ {
+ public:
+
+ seq_range()
+ : m_first(NULL), m_last(NULL)
+ {
+ }
+
+ ~seq_range()
+ {
+ delete m_first;
+ delete m_last;
+ }
+
+ void go(IMAPParser& parser, string& line, string::size_type* currentPos)
+ {
+ DEBUG_ENTER_COMPONENT("seq_range");
+
+ string::size_type pos = *currentPos;
+
+ m_first = parser.get <seq_number>(line, &pos);
+
+ parser.check <one_char <'*'> >(line, &pos);
+
+ m_last = parser.get <seq_number>(line, &pos);
+
+ *currentPos = pos;
+ }
+
+ private:
+
+ IMAPParser::seq_number* m_first;
+ IMAPParser::seq_number* m_last;
+
+ public:
+
+ const IMAPParser::seq_number* first() const { return m_first; }
+ const IMAPParser::seq_number* last() const { return m_last; }
+ };
+
+
+ // sequence-set = (seq-number / seq-range) *("," sequence-set)
+ // ; set of seq-number values, regardless of order.
+ // ; Servers MAY coalesce overlaps and/or execute the
+ // ; sequence in any order.
+ // ; Example: a message sequence number set of
+ // ; 2,4:7,9,12:* for a mailbox with 15 messages is
+ // ; equivalent to 2,4,5,6,7,9,12,13,14,15
+
+ class sequence_set : public component
+ {
+ public:
+
+ sequence_set()
+ : m_number(NULL), m_range(NULL), m_nextSet(NULL)
+ {
+ }
+
+ ~sequence_set()
+ {
+ delete m_number;
+ delete m_range;
+ delete m_nextSet;
+ }
+
+ void go(IMAPParser& parser, string& line, string::size_type* currentPos)
+ {
+ DEBUG_ENTER_COMPONENT("sequence_set");
+
+ string::size_type pos = *currentPos;
+
+ if ((m_range = parser.get <IMAPParser::seq_range>(line, &pos, true)) == NULL)
+ m_number = parser.get <IMAPParser::seq_number>(line, &pos);
+
+ if (parser.check <one_char <','> >(line, &pos, true))
+ m_nextSet = parser.get <sequence_set>(line, &pos);
+
+ *currentPos = pos;
+ }
+
+ private:
+
+ IMAPParser::seq_number* m_number;
+ IMAPParser::seq_range* m_range;
+ IMAPParser::sequence_set* m_nextSet;
+
+ public:
+
+ const IMAPParser::seq_number* seq_number() const { return m_number; }
+ const IMAPParser::seq_range* seq_range() const { return m_range; }
+ const IMAPParser::sequence_set* next_sequence_set() const { return m_nextSet; }
+ };
+
+
+ // mod-sequence-value = 1*DIGIT
+ // ;; Positive unsigned 64-bit integer
+ // ;; (mod-sequence)
+ // ;; (1 <= n < 18,446,744,073,709,551,615)
+
+ class mod_sequence_value : public component
+ {
+ public:
+
+ mod_sequence_value()
+ : m_value(0)
+ {
+ }
+
+ void go(IMAPParser& /* parser */, string& line, string::size_type* currentPos)
+ {
+ DEBUG_ENTER_COMPONENT("mod_sequence_value");
+
+ string::size_type pos = *currentPos;
+
+ bool valid = true;
+ vmime_uint64 val = 0;
+
+ while (valid && pos < line.length())
+ {
+ const char c = line[pos];
+
+ if (c >= '0' && c <= '9')
+ {
+ val = (val * 10) + (c - '0');
+ ++pos;
+ }
+ else
+ {
+ valid = false;
+ }
+ }
+
+ m_value = val;
+
+ *currentPos = pos;
+ }
+
+ private:
+
+ vmime_uint64 m_value;
+
+ public:
+
+ const vmime_uint64 value() const { return m_value; }
+ };
+
+
//
// flag ::= "\Answered" / "\Flagged" / "\Deleted" /
// "\Seen" / "\Draft" / flag_keyword / flag_extension
@@ -1666,249 +1871,6 @@ public:
//
- // resp_text_code ::= "ALERT" / "PARSE" /
- // "PERMANENTFLAGS" SPACE "(" #(flag / "\*") ")" /
- // "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
- // "UIDVALIDITY" SPACE nz_number /
- // "UNSEEN" SPACE nz_number /
- // atom [SPACE 1*<any TEXT_CHAR except "]">]
-
- class resp_text_code : public component
- {
- public:
-
- resp_text_code()
- : m_nz_number(NULL), m_atom(NULL), m_flag_list(NULL), m_text(NULL)
- {
- }
-
- ~resp_text_code()
- {
- delete (m_nz_number);
- delete (m_atom);
- delete (m_flag_list);
- delete (m_text);
- }
-
- void go(IMAPParser& parser, string& line, string::size_type* currentPos)
- {
- DEBUG_ENTER_COMPONENT("resp_text_code");
-
- string::size_type pos = *currentPos;
-
- // "ALERT"
- if (parser.checkWithArg <special_atom>(line, &pos, "alert", true))
- {
- m_type = ALERT;
- }
- // "PARSE"
- else if (parser.checkWithArg <special_atom>(line, &pos, "parse", true))
- {
- m_type = PARSE;
- }
- // "PERMANENTFLAGS" SPACE flag_list
- else if (parser.checkWithArg <special_atom>(line, &pos, "permanentflags", true))
- {
- m_type = PERMANENTFLAGS;
-
- parser.check <SPACE>(line, &pos);
-
- m_flag_list = parser.get <IMAPParser::flag_list>(line, &pos);
- }
- // "READ-ONLY"
- else if (parser.checkWithArg <special_atom>(line, &pos, "read-only", true))
- {
- m_type = READ_ONLY;
- }
- // "READ-WRITE"
- else if (parser.checkWithArg <special_atom>(line, &pos, "read-write", true))
- {
- m_type = READ_WRITE;
- }
- // "TRYCREATE"
- else if (parser.checkWithArg <special_atom>(line, &pos, "trycreate", true))
- {
- m_type = TRYCREATE;
- }
- // "UIDVALIDITY" SPACE nz_number
- else if (parser.checkWithArg <special_atom>(line, &pos, "uidvalidity", true))
- {
- m_type = UIDVALIDITY;
-
- parser.check <SPACE>(line, &pos);
- m_nz_number = parser.get <IMAPParser::nz_number>(line, &pos);
- }
- // "UNSEEN" SPACE nz_number
- else if (parser.checkWithArg <special_atom>(line, &pos, "unseen", true))
- {
- m_type = UNSEEN;
-
- parser.check <SPACE>(line, &pos);
- m_nz_number = parser.get <IMAPParser::nz_number>(line, &pos);
- }
- // atom [SPACE 1*<any TEXT_CHAR except "]">]
- else
- {
- m_type = OTHER;
-
- m_atom = parser.get <IMAPParser::atom>(line, &pos);
-
- if (parser.check <SPACE>(line, &pos, true))
- m_text = parser.get <text_except <']'> >(line, &pos);
- }
-
- *currentPos = pos;
- }
-
-
- enum Type
- {
- ALERT,
- PARSE,
- PERMANENTFLAGS,
- READ_ONLY,
- READ_WRITE,
- TRYCREATE,
- UIDVALIDITY,
- UNSEEN,
- OTHER
- };
-
- private:
-
- Type m_type;
-
- IMAPParser::nz_number* m_nz_number;
- IMAPParser::atom* m_atom;
- IMAPParser::flag_list* m_flag_list;
- IMAPParser::text* m_text;
-
- public:
-
- Type type() const { return (m_type); }
-
- const IMAPParser::nz_number* nz_number() const { return (m_nz_number); }
- const IMAPParser::atom* atom() const { return (m_atom); }
- const IMAPParser::flag_list* flag_list() const { return (m_flag_list); }
- const IMAPParser::text* text() const { return (m_text); }
- };
-
-
- //
- // resp_text ::= ["[" resp_text_code "]" SPACE] (text_mime2 / text)
- // ;; text SHOULD NOT begin with "[" or "="
-
- class resp_text : public component
- {
- public:
-
- resp_text()
- : m_resp_text_code(NULL)
- {
- }
-
- ~resp_text()
- {
- delete (m_resp_text_code);
- }
-
- void go(IMAPParser& parser, string& line, string::size_type* currentPos)
- {
- DEBUG_ENTER_COMPONENT("resp_text");
-
- string::size_type pos = *currentPos;
-
- if (parser.check <one_char <'['> >(line, &pos, true))
- {
- m_resp_text_code = parser.get <IMAPParser::resp_text_code>(line, &pos);
-
- parser.check <one_char <']'> >(line, &pos);
- parser.check <SPACE>(line, &pos, true);
- }
-
- text_mime2* text1 = parser.get <text_mime2>(line, &pos, true);
-
- if (text1 != NULL)
- {
- m_text = text1->value();
- delete (text1);
- }
- else
- {
- IMAPParser::text* text2 =
- parser.get <IMAPParser::text>(line, &pos, true);
-
- if (text2 != NULL)
- {
- m_text = text2->value();
- delete (text2);
- }
- else
- {
- // Empty response text
- }
- }
-
- *currentPos = pos;
- }
-
- private:
-
- IMAPParser::resp_text_code* m_resp_text_code;
- string m_text;
-
- public:
-
- const IMAPParser::resp_text_code* resp_text_code() const { return (m_resp_text_code); }
- const string& text() const { return (m_text); }
- };
-
-
- //
- // continue_req ::= "+" SPACE (resp_text / base64)
- //
-
- class continue_req : public component
- {
- public:
-
- continue_req()
- : m_resp_text(NULL)
- {
- }
-
- ~continue_req()
- {
- delete (m_resp_text);
- }
-
- void go(IMAPParser& parser, string& line, string::size_type* currentPos)
- {
- DEBUG_ENTER_COMPONENT("continue_req");
-
- string::size_type pos = *currentPos;
-
- parser.check <one_char <'+'> >(line, &pos);
- parser.check <SPACE>(line, &pos);
-
- m_resp_text = parser.get <IMAPParser::resp_text>(line, &pos);
-
- parser.check <CRLF>(line, &pos);
-
- *currentPos = pos;
- }
-
- private:
-
- IMAPParser::resp_text* m_resp_text;
-
- public:
-
- const IMAPParser::resp_text* resp_text() const { return (m_resp_text); }
- };
-
-
- //
// auth_type ::= atom
// ;; Defined by [IMAP-AUTH]
//
@@ -1965,6 +1927,13 @@ public:
// ("UIDVALIDITY" SP nz-number) /
// ("UNSEEN" SP number)
//
+ // IMAP Extension for Conditional STORE (RFC-4551):
+ //
+ // status-att-val =/ "HIGHESTMODSEQ" SP mod-sequence-valzer
+ // ;; extends non-terminal defined in [IMAPABNF].
+ // ;; Value 0 denotes that the mailbox doesn't
+ // ;; support persistent mod-sequences
+ //
class status_att_val : public component
{
@@ -1976,30 +1945,41 @@ public:
string::size_type pos = *currentPos;
- if (parser.checkWithArg <special_atom>(line, &pos, "messages", true))
- {
- m_type = MESSAGES;
- }
- else if (parser.checkWithArg <special_atom>(line, &pos, "recent", true))
- {
- m_type = RECENT;
- }
- else if (parser.checkWithArg <special_atom>(line, &pos, "uidnext", true))
- {
- m_type = UIDNEXT;
- }
- else if (parser.checkWithArg <special_atom>(line, &pos, "uidvalidity", true))
+ // "HIGHESTMODSEQ" SP mod-sequence-valzer
+ if (parser.checkWithArg <special_atom>(line, &pos, "highestmodseq", true))
{
- m_type = UIDVALIDITY;
+ m_type = HIGHESTMODSEQ;
+
+ parser.check <SPACE>(line, &pos);
+ m_value = parser.get <IMAPParser::mod_sequence_value>(line, &pos);
}
else
{
- parser.checkWithArg <special_atom>(line, &pos, "unseen");
- m_type = UNSEEN;
- }
+ if (parser.checkWithArg <special_atom>(line, &pos, "messages", true))
+ {
+ m_type = MESSAGES;
+ }
+ else if (parser.checkWithArg <special_atom>(line, &pos, "recent", true))
+ {
+ m_type = RECENT;
+ }
+ else if (parser.checkWithArg <special_atom>(line, &pos, "uidnext", true))
+ {
+ m_type = UIDNEXT;
+ }
+ else if (parser.checkWithArg <special_atom>(line, &pos, "uidvalidity", true))
+ {
+ m_type = UIDVALIDITY;
+ }
+ else
+ {
+ parser.checkWithArg <special_atom>(line, &pos, "unseen");
+ m_type = UNSEEN;
+ }
- parser.check <SPACE>(line, &pos);
- m_value = parser.get <IMAPParser::number>(line, &pos);
+ parser.check <SPACE>(line, &pos);
+ m_value = parser.get <IMAPParser::number>(line, &pos);
+ }
*currentPos = pos;
}
@@ -2007,6 +1987,10 @@ public:
enum Type
{
+ // Extensions
+ HIGHESTMODSEQ,
+
+ // Standard IMAP
MESSAGES,
RECENT,
UIDNEXT,
@@ -2027,6 +2011,11 @@ public:
{
return dynamic_cast <IMAPParser::number *>(m_value);
}
+
+ const IMAPParser::mod_sequence_value* value_as_mod_sequence_value() const
+ {
+ return dynamic_cast <IMAPParser::mod_sequence_value *>(m_value);
+ }
};
@@ -3882,6 +3871,9 @@ public:
// "BODY" section ["<" number ">"] SPACE nstring /
// "UID" SPACE uniqueid
//
+ // IMAP Extension for Conditional STORE (RFC-4551):
+ //
+ // msg_att_item /= "MODSEQ" SP "(" mod_sequence_value ")"
class msg_att_item : public component
{
@@ -3890,7 +3882,7 @@ public:
msg_att_item()
: m_date_time(NULL), m_number(NULL), m_envelope(NULL),
m_uniqueid(NULL), m_nstring(NULL), m_body(NULL), m_flag_list(NULL),
- m_section(NULL)
+ m_section(NULL), m_mod_sequence_value(NULL)
{
}
@@ -3905,6 +3897,7 @@ public:
delete (m_body);
delete (m_flag_list);
delete (m_section);
+ delete m_mod_sequence_value;
}
void go(IMAPParser& parser, string& line, string::size_type* currentPos)
@@ -4015,6 +4008,18 @@ public:
m_body = parser.get <IMAPParser::body>(line, &pos);
}
}
+ // "MODSEQ" SP "(" mod_sequence_value ")"
+ else if (parser.checkWithArg <special_atom>(line, &pos, "modseq", true))
+ {
+ m_type = MODSEQ;
+
+ parser.check <SPACE>(line, &pos);
+ parser.check <one_char <'('> >(line, &pos);
+
+ m_mod_sequence_value = parser.get <IMAPParser::mod_sequence_value>(line, &pos);
+
+ parser.check <one_char <')'> >(line, &pos);
+ }
// "UID" SPACE uniqueid
else
{
@@ -4042,7 +4047,8 @@ public:
BODY,
BODY_SECTION,
BODY_STRUCTURE,
- UID
+ UID,
+ MODSEQ
};
private:
@@ -4057,6 +4063,7 @@ public:
IMAPParser::xbody* m_body;
IMAPParser::flag_list* m_flag_list;
IMAPParser::section* m_section;
+ IMAPParser::mod_sequence_value* m_mod_sequence_value;
public:
@@ -4070,6 +4077,7 @@ public:
const IMAPParser::xbody* body() const { return (m_body); }
const IMAPParser::flag_list* flag_list() const { return (m_flag_list); }
const IMAPParser::section* section() const { return (m_section); }
+ const IMAPParser::mod_sequence_value* mod_sequence_value() { return m_mod_sequence_value; }
};
@@ -4189,6 +4197,307 @@ public:
//
+ // resp_text_code ::= "ALERT" / "PARSE" /
+ // capability-data /
+ // "PERMANENTFLAGS" SPACE "(" #(flag / "\*") ")" /
+ // "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
+ // "UIDVALIDITY" SPACE nz_number /
+ // "UNSEEN" SPACE nz_number /
+ // atom [SPACE 1*<any TEXT_CHAR except "]">]
+ //
+ // IMAP Extension for Conditional STORE (RFC-4551):
+ //
+ // resp-text-code =/ "HIGHESTMODSEQ" SP mod-sequence-value /
+ // "NOMODSEQ" /
+ // "MODIFIED" SP set
+
+ class resp_text_code : public component
+ {
+ public:
+
+ resp_text_code()
+ : m_nz_number(NULL), m_atom(NULL), m_flag_list(NULL),
+ m_text(NULL), m_capability_data(NULL)
+ {
+ }
+
+ ~resp_text_code()
+ {
+ delete (m_nz_number);
+ delete (m_atom);
+ delete (m_flag_list);
+ delete (m_text);
+ delete m_capability_data;
+ }
+
+ void go(IMAPParser& parser, string& line, string::size_type* currentPos)
+ {
+ DEBUG_ENTER_COMPONENT("resp_text_code");
+
+ string::size_type pos = *currentPos;
+
+ // "ALERT"
+ if (parser.checkWithArg <special_atom>(line, &pos, "alert", true))
+ {
+ m_type = ALERT;
+ }
+ // "PARSE"
+ else if (parser.checkWithArg <special_atom>(line, &pos, "parse", true))
+ {
+ m_type = PARSE;
+ }
+ // capability_data
+ else if ((m_capability_data = parser.get <IMAPParser::capability_data>(line, &pos, true)))
+ {
+ m_type = CAPABILITY;
+ }
+ // "PERMANENTFLAGS" SPACE flag_list
+ else if (parser.checkWithArg <special_atom>(line, &pos, "permanentflags", true))
+ {
+ m_type = PERMANENTFLAGS;
+
+ parser.check <SPACE>(line, &pos);
+
+ m_flag_list = parser.get <IMAPParser::flag_list>(line, &pos);
+ }
+ // "READ-ONLY"
+ else if (parser.checkWithArg <special_atom>(line, &pos, "read-only", true))
+ {
+ m_type = READ_ONLY;
+ }
+ // "READ-WRITE"
+ else if (parser.checkWithArg <special_atom>(line, &pos, "read-write", true))
+ {
+ m_type = READ_WRITE;
+ }
+ // "TRYCREATE"
+ else if (parser.checkWithArg <special_atom>(line, &pos, "trycreate", true))
+ {
+ m_type = TRYCREATE;
+ }
+ // "UIDVALIDITY" SPACE nz_number
+ else if (parser.checkWithArg <special_atom>(line, &pos, "uidvalidity", true))
+ {
+ m_type = UIDVALIDITY;
+
+ parser.check <SPACE>(line, &pos);
+ m_nz_number = parser.get <IMAPParser::nz_number>(line, &pos);
+ }
+ // "UIDNEXT" SPACE nz_number
+ else if (parser.checkWithArg <special_atom>(line, &pos, "uidnext", true))
+ {
+ m_type = UIDNEXT;
+
+ parser.check <SPACE>(line, &pos);
+ m_nz_number = parser.get <IMAPParser::nz_number>(line, &pos);
+ }
+ // "UNSEEN" SPACE nz_number
+ else if (parser.checkWithArg <special_atom>(line, &pos, "unseen", true))
+ {
+ m_type = UNSEEN;
+
+ parser.check <SPACE>(line, &pos);
+ m_nz_number = parser.get <IMAPParser::nz_number>(line, &pos);
+ }
+ // "HIGHESTMODSEQ" SP mod-sequence-value
+ else if (parser.checkWithArg <special_atom>(line, &pos, "highestmodseq", true))
+ {
+ m_type = HIGHESTMODSEQ;
+
+ parser.check <SPACE>(line, &pos);
+ m_mod_sequence_value = parser.get <IMAPParser::mod_sequence_value>(line, &pos);
+ }
+ // "NOMODSEQ"
+ else if (parser.checkWithArg <special_atom>(line, &pos, "nomodseq", true))
+ {
+ m_type = NOMODSEQ;
+ }
+ // "MODIFIED" SP sequence-set
+ else if (parser.checkWithArg <special_atom>(line, &pos, "modified", true))
+ {
+ m_type = MODIFIED;
+
+ parser.check <SPACE>(line, &pos);
+
+ m_sequence_set = parser.get <IMAPParser::sequence_set>(line, &pos);
+ }
+ // atom [SPACE 1*<any TEXT_CHAR except "]">]
+ else
+ {
+ m_type = OTHER;
+
+ m_atom = parser.get <IMAPParser::atom>(line, &pos);
+
+ if (parser.check <SPACE>(line, &pos, true))
+ m_text = parser.get <text_except <']'> >(line, &pos);
+ }
+
+ *currentPos = pos;
+ }
+
+
+ enum Type
+ {
+ // Extensions
+ HIGHESTMODSEQ,
+ NOMODSEQ,
+ MODIFIED,
+
+ // Standard IMAP
+ ALERT,
+ PARSE,
+ CAPABILITY,
+ PERMANENTFLAGS,
+ READ_ONLY,
+ READ_WRITE,
+ TRYCREATE,
+ UIDVALIDITY,
+ UIDNEXT,
+ UNSEEN,
+ OTHER
+ };
+
+ private:
+
+ Type m_type;
+
+ IMAPParser::nz_number* m_nz_number;
+ IMAPParser::atom* m_atom;
+ IMAPParser::flag_list* m_flag_list;
+ IMAPParser::text* m_text;
+ IMAPParser::mod_sequence_value* m_mod_sequence_value;
+ IMAPParser::sequence_set* m_sequence_set;
+ IMAPParser::capability_data* m_capability_data;
+
+ public:
+
+ Type type() const { return (m_type); }
+
+ const IMAPParser::nz_number* nz_number() const { return (m_nz_number); }
+ const IMAPParser::atom* atom() const { return (m_atom); }
+ const IMAPParser::flag_list* flag_list() const { return (m_flag_list); }
+ const IMAPParser::text* text() const { return (m_text); }
+ const IMAPParser::mod_sequence_value* mod_sequence_value() const { return m_mod_sequence_value; }
+ const IMAPParser::sequence_set* sequence_set() const { return m_sequence_set; }
+ const IMAPParser::capability_data* capability_data() const { return m_capability_data; }
+ };
+
+
+ //
+ // resp_text ::= ["[" resp_text_code "]" SPACE] (text_mime2 / text)
+ // ;; text SHOULD NOT begin with "[" or "="
+
+ class resp_text : public component
+ {
+ public:
+
+ resp_text()
+ : m_resp_text_code(NULL)
+ {
+ }
+
+ ~resp_text()
+ {
+ delete (m_resp_text_code);
+ }
+
+ void go(IMAPParser& parser, string& line, string::size_type* currentPos)
+ {
+ DEBUG_ENTER_COMPONENT("resp_text");
+
+ string::size_type pos = *currentPos;
+
+ if (parser.check <one_char <'['> >(line, &pos, true))
+ {
+ m_resp_text_code = parser.get <IMAPParser::resp_text_code>(line, &pos);
+
+ parser.check <one_char <']'> >(line, &pos);
+ parser.check <SPACE>(line, &pos, true);
+ }
+
+ text_mime2* text1 = parser.get <text_mime2>(line, &pos, true);
+
+ if (text1 != NULL)
+ {
+ m_text = text1->value();
+ delete (text1);
+ }
+ else
+ {
+ IMAPParser::text* text2 =
+ parser.get <IMAPParser::text>(line, &pos, true);
+
+ if (text2 != NULL)
+ {
+ m_text = text2->value();
+ delete (text2);
+ }
+ else
+ {
+ // Empty response text
+ }
+ }
+
+ *currentPos = pos;
+ }
+
+ private:
+
+ IMAPParser::resp_text_code* m_resp_text_code;
+ string m_text;
+
+ public:
+
+ const IMAPParser::resp_text_code* resp_text_code() const { return (m_resp_text_code); }
+ const string& text() const { return (m_text); }
+ };
+
+
+ //
+ // continue_req ::= "+" SPACE (resp_text / base64)
+ //
+
+ class continue_req : public component
+ {
+ public:
+
+ continue_req()
+ : m_resp_text(NULL)
+ {
+ }
+
+ ~continue_req()
+ {
+ delete (m_resp_text);
+ }
+
+ void go(IMAPParser& parser, string& line, string::size_type* currentPos)
+ {
+ DEBUG_ENTER_COMPONENT("continue_req");
+
+ string::size_type pos = *currentPos;
+
+ parser.check <one_char <'+'> >(line, &pos);
+ parser.check <SPACE>(line, &pos);
+
+ m_resp_text = parser.get <IMAPParser::resp_text>(line, &pos);
+
+ parser.check <CRLF>(line, &pos);
+
+ *currentPos = pos;
+ }
+
+ private:
+
+ IMAPParser::resp_text* m_resp_text;
+
+ public:
+
+ const IMAPParser::resp_text* resp_text() const { return (m_resp_text); }
+ };
+
+
+ //
// resp_cond_state ::= ("OK" / "NO" / "BAD") SPACE resp_text
// ;; Status condition
//