From 394224e7ab4e94d4ef8bd2a24d54db29104176c8 Mon Sep 17 00:00:00 2001 From: Vincent Richard Date: Thu, 11 Jul 2013 17:08:46 +0200 Subject: [PATCH] Updated IMAP parser to support STATUS response extensions. --- src/net/imap/IMAPFolder.cpp | 18 ++--- vmime/net/imap/IMAPParser.hpp | 140 +++++++++++++++++----------------- 2 files changed, 78 insertions(+), 80 deletions(-) diff --git a/src/net/imap/IMAPFolder.cpp b/src/net/imap/IMAPFolder.cpp index 4ad581d0..1ee8ac3f 100644 --- a/src/net/imap/IMAPFolder.cpp +++ b/src/net/imap/IMAPFolder.cpp @@ -1816,22 +1816,22 @@ void IMAPFolder::status(int& count, int& unseen) if (responseData->mailbox_data() && responseData->mailbox_data()->type() == IMAPParser::mailbox_data::STATUS) { - const std::vector & statusList = - responseData->mailbox_data()->status_info_list(); + const IMAPParser::status_att_list* statusAttList = + responseData->mailbox_data()->status_att_list(); - for (std::vector ::const_iterator - jt = statusList.begin() ; jt != statusList.end() ; ++jt) + for (std::vector ::const_iterator + jt = statusAttList->values().begin() ; jt != statusAttList->values().end() ; ++jt) { - switch ((*jt)->status_att()->type()) + switch ((*jt)->type()) { - case IMAPParser::status_att::MESSAGES: + case IMAPParser::status_att_val::MESSAGES: - count = (*jt)->number()->value(); + count = (*jt)->value_as_number()->value(); break; - case IMAPParser::status_att::UNSEEN: + case IMAPParser::status_att_val::UNSEEN: - unseen = (*jt)->number()->value(); + unseen = (*jt)->value_as_number()->value(); break; default: diff --git a/vmime/net/imap/IMAPParser.hpp b/vmime/net/imap/IMAPParser.hpp index ce5f29ab..41252a92 100644 --- a/vmime/net/imap/IMAPParser.hpp +++ b/vmime/net/imap/IMAPParser.hpp @@ -553,11 +553,11 @@ public: private: const bool m_nonZero; - unsigned int m_value; + unsigned long m_value; public: - unsigned int value() const { return (m_value); } + unsigned long value() const { return (m_value); } }; @@ -1959,11 +1959,14 @@ public: // - // status_att ::= "MESSAGES" / "RECENT" / "UIDNEXT" / - // "UIDVALIDITY" / "UNSEEN" + // status-att-val = ("MESSAGES" SP number) / + // ("RECENT" SP number) / + // ("UIDNEXT" SP nz-number) / + // ("UIDVALIDITY" SP nz-number) / + // ("UNSEEN" SP number) // - class status_att : public component + class status_att_val : public component { public: @@ -1995,6 +1998,9 @@ public: m_type = UNSEEN; } + parser.check (line, &pos); + m_value = parser.get (line, &pos); + *currentPos = pos; } @@ -2011,10 +2017,55 @@ public: private: Type m_type; + IMAPParser::component* m_value; public: Type type() const { return (m_type); } + + const IMAPParser::number* value_as_number() const + { + return dynamic_cast (m_value); + } + }; + + + // status-att-list = status-att-val *(SP status-att-val) + + class status_att_list : public component + { + public: + + ~status_att_list() + { + for (std::vector ::iterator it = m_values.begin() ; + it != m_values.end() ; ++it) + { + delete *it; + } + } + + void go(IMAPParser& parser, string& line, string::size_type* currentPos) + { + DEBUG_ENTER_COMPONENT("status_att_list"); + + string::size_type pos = *currentPos; + + m_values.push_back(parser.get (line, &pos)); + + while (parser.check (line, &pos, true)) + m_values.push_back(parser.get (line, &pos)); + + *currentPos = pos; + } + + private: + + std::vector m_values; + + public: + + const std::vector & values() const { return m_values; } }; @@ -2210,9 +2261,9 @@ public: parser.check >(line, &pos); - m_datetime.setHour(std::min(std::max(nh->value(), 0u), 23u)); - m_datetime.setMinute(std::min(std::max(nmi->value(), 0u), 59u)); - m_datetime.setSecond(std::min(std::max(ns->value(), 0u), 59u)); + m_datetime.setHour(std::min(std::max(nh->value(), 0ul), 23ul)); + m_datetime.setMinute(std::min(std::max(nmi->value(), 0ul), 59ul)); + m_datetime.setSecond(std::min(std::max(ns->value(), 0ul), 59ul)); const int zone = static_cast (nz->value()); const int zh = zone / 100; // hour offset @@ -2220,7 +2271,7 @@ public: m_datetime.setZone(((zh * 60) + zm) * sign); - m_datetime.setDay(std::min(std::max(nd->value(), 1u), 31u)); + m_datetime.setDay(std::min(std::max(nd->value(), 1ul), 31ul)); m_datetime.setYear(ny->value()); const string month(utility::stringUtils::toLower(amo->value())); @@ -4308,50 +4359,6 @@ public: }; - // - // status_info ::= status_att SPACE number - // - - class status_info : public component - { - public: - - status_info() - : m_status_att(NULL), m_number(NULL) - { - } - - ~status_info() - { - delete (m_status_att); - delete (m_number); - } - - void go(IMAPParser& parser, string& line, string::size_type* currentPos) - { - DEBUG_ENTER_COMPONENT("status_info"); - - string::size_type pos = *currentPos; - - m_status_att = parser.get (line, &pos); - parser.check (line, &pos); - m_number = parser.get (line, &pos); - - *currentPos = pos; - } - - private: - - IMAPParser::status_att* m_status_att; - IMAPParser::number* m_number; - - public: - - const IMAPParser::status_att* status_att() const { return (m_status_att); } - const IMAPParser::number* number() const { return (m_number); } - }; - - // // mailbox_data ::= "FLAGS" SPACE mailbox_flag_list / // "LIST" SPACE mailbox_list / @@ -4359,7 +4366,7 @@ public: // "MAILBOX" SPACE text / // "SEARCH" [SPACE 1#nz_number] / // "STATUS" SPACE mailbox SPACE - // "(" #::iterator it = m_status_info_list.begin() ; - it != m_status_info_list.end() ; ++it) - { - delete (*it); - } + delete m_status_att_list; } void go(IMAPParser& parser, string& line, string::size_type* currentPos) @@ -4474,9 +4477,7 @@ public: m_type = SEARCH; } // "STATUS" SPACE mailbox SPACE - // "(" #(line, &pos, "status"); @@ -4485,15 +4486,12 @@ public: m_mailbox = parser.get (line, &pos); parser.check (line, &pos); + parser.check >(line, &pos); - m_status_info_list.push_back(parser.get (line, &pos)); + m_status_att_list = parser.get (line, &pos, true); - while (!parser.check >(line, &pos, true)) - { - parser.check (line, &pos); - m_status_info_list.push_back(parser.get (line, &pos)); - } + parser.check >(line, &pos); m_type = STATUS; } @@ -4525,7 +4523,7 @@ public: IMAPParser::mailbox* m_mailbox; IMAPParser::text* m_text; std::vector m_search_nz_number_list; - std::vector m_status_info_list; + IMAPParser::status_att_list* m_status_att_list; public: @@ -4537,7 +4535,7 @@ public: const IMAPParser::mailbox* mailbox() const { return (m_mailbox); } const IMAPParser::text* text() const { return (m_text); } const std::vector & search_nz_number_list() const { return (m_search_nz_number_list); } - const std::vector & status_info_list() const { return (m_status_info_list); } + const IMAPParser::status_att_list* status_att_list() const { return m_status_att_list; } };