diff --git a/ChangeLog b/ChangeLog index 8fcdf1a7..90d86856 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,12 @@ VERSION 0.6.4cvs ================ +2005-03-23 Vincent Richard + + * messaging/POP3*: fixed incorrect message size. Fixed a bug in + deleteMessages() when 'to == -1' and last message not being + deleted (thanks to Stefan Uhrig). + 2005-03-17 Vincent Richard * base.{cpp|hpp}: renamed 'MIME_VERSION' to 'SUPPORTED_MIME_VERSION'. diff --git a/src/messaging/POP3Folder.cpp b/src/messaging/POP3Folder.cpp index 096c9db6..c70005c6 100644 --- a/src/messaging/POP3Folder.cpp +++ b/src/messaging/POP3Folder.cpp @@ -314,6 +314,51 @@ void POP3Folder::fetchMessages(std::vector & msg, const int options, progress->progress(++current, total); } + if (options & FETCH_SIZE) + { + // Send the "LIST" command + std::ostringstream command; + command << "LIST"; + + m_store->sendRequest(command.str()); + + // Get the response + string response; + m_store->readResponse(response, true, NULL); + + if (m_store->isSuccessResponse(response)) + { + m_store->stripFirstLine(response, response, NULL); + + // C: LIST + // S: +OK + // S: 1 47548 + // S: 2 12653 + // S: . + std::map result; + parseMultiListOrUidlResponse(response, result); + + for (std::vector ::iterator it = msg.begin() ; + it != msg.end() ; ++it) + { + POP3Message* m = dynamic_cast (*it); + + std::map ::const_iterator x = result.find(m->m_num); + + if (x != result.end()) + { + int size = 0; + + std::istringstream iss((*x).second); + iss >> size; + + m->m_size = size; + } + } + } + + } + if (options & FETCH_UID) { // Send the "UIDL" command @@ -335,50 +380,18 @@ void POP3Folder::fetchMessages(std::vector & msg, const int options, // S: 1 whqtswO00WBw418f9t5JxYwZ // S: 2 QhdPYR:00WBw1Ph7x7 // S: . - - std::istringstream iss(response); - std::map ids; - - string line; - - while (std::getline(iss, line)) - { - string::iterator it = line.begin(); - - while (it != line.end() && (*it == ' ' || *it == '\t')) - ++it; - - if (it != line.end()) - { - int number = 0; - - while (it != line.end() && (*it >= '0' && *it <= '9')) - { - number = (number * 10) + (*it - '0'); - ++it; - } - - while (it != line.end() && !(*it == ' ' || *it == '\t')) ++it; - while (it != line.end() && (*it == ' ' || *it == '\t')) ++it; - - if (it != line.end()) - { - ids.insert(std::map ::value_type - (number, string(it, line.end()))); - } - } - } + std::map result; + parseMultiListOrUidlResponse(response, result); for (std::vector ::iterator it = msg.begin() ; it != msg.end() ; ++it) { POP3Message* m = dynamic_cast (*it); - std::map ::const_iterator id = - ids.find(m->m_num); + std::map ::const_iterator x = result.find(m->m_num); - if (id != ids.end()) - m->m_uid = (*id).second; + if (x != result.end()) + m->m_uid = (*x).second; } } } @@ -397,11 +410,47 @@ void POP3Folder::fetchMessage(message* msg, const int options) dynamic_cast (msg)->fetch(this, options); + if (options & FETCH_SIZE) + { + // Send the "LIST" command + std::ostringstream command; + command << "LIST " << msg->getNumber(); + + m_store->sendRequest(command.str()); + + // Get the response + string response; + m_store->readResponse(response, false, NULL); + + if (m_store->isSuccessResponse(response)) + { + m_store->stripResponseCode(response, response); + + // C: LIST 2 + // S: +OK 2 4242 + string::iterator it = response.begin(); + + while (it != response.end() && (*it == ' ' || *it == '\t')) ++it; + while (it != response.end() && !(*it == ' ' || *it == '\t')) ++it; + while (it != response.end() && (*it == ' ' || *it == '\t')) ++it; + + if (it != response.end()) + { + int size = 0; + + std::istringstream iss(string(it, response.end())); + iss >> size; + + dynamic_cast (msg)->m_size = size; + } + } + } + if (options & FETCH_UID) { // Send the "UIDL" command std::ostringstream command; - command << "UIDL"; + command << "UIDL " << msg->getNumber(); m_store->sendRequest(command.str()); @@ -504,7 +553,9 @@ void POP3Folder::deleteMessages(const int from, const int to) else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); - for (int i = from ; i < to ; ++i) + const int to2 = (to == -1 ? m_messageCount : to); + + for (int i = from ; i <= to2 ; ++i) { std::ostringstream command; command << "DELE " << i; @@ -666,5 +717,41 @@ void POP3Folder::expunge() } +void POP3Folder::parseMultiListOrUidlResponse(const string& response, std::map & result) +{ + std::istringstream iss(response); + std::map ids; + + string line; + + while (std::getline(iss, line)) + { + string::iterator it = line.begin(); + + while (it != line.end() && (*it == ' ' || *it == '\t')) + ++it; + + if (it != line.end()) + { + int number = 0; + + while (it != line.end() && (*it >= '0' && *it <= '9')) + { + number = (number * 10) + (*it - '0'); + ++it; + } + + while (it != line.end() && !(*it == ' ' || *it == '\t')) ++it; + while (it != line.end() && (*it == ' ' || *it == '\t')) ++it; + + if (it != line.end()) + { + result.insert(std::map ::value_type(number, string(it, line.end()))); + } + } + } +} + + } // messaging } // vmime diff --git a/src/messaging/POP3Message.cpp b/src/messaging/POP3Message.cpp index 633f9491..d9ef2989 100644 --- a/src/messaging/POP3Message.cpp +++ b/src/messaging/POP3Message.cpp @@ -29,7 +29,7 @@ namespace messaging { POP3Message::POP3Message(POP3Folder* folder, const int num) - : m_folder(folder), m_num(num), m_header(NULL) + : m_folder(folder), m_num(num), m_size(-1), m_header(NULL) { m_folder->registerMessage(this); } @@ -64,13 +64,10 @@ const message::uid POP3Message::getUniqueId() const const int POP3Message::getSize() const { - if (!m_folder) - throw exceptions::illegal_state("Folder closed"); + if (m_size == -1) + throw exceptions::unfetched_object(); - POP3Folder::MessageMap::const_iterator it = - m_folder->m_messages.find(const_cast (this)); - - return ((it != m_folder->m_messages.end()) ? (*it).second : 0); + return (m_size); } diff --git a/vmime/messaging/POP3Folder.hpp b/vmime/messaging/POP3Folder.hpp index a7af9ade..2e5b88b9 100644 --- a/vmime/messaging/POP3Folder.hpp +++ b/vmime/messaging/POP3Folder.hpp @@ -120,6 +120,8 @@ private: void onClose(); + void parseMultiListOrUidlResponse(const string& response, std::map & result); + POP3Store* m_store; diff --git a/vmime/messaging/POP3Message.hpp b/vmime/messaging/POP3Message.hpp index 5a843c1c..b7535fe9 100644 --- a/vmime/messaging/POP3Message.hpp +++ b/vmime/messaging/POP3Message.hpp @@ -77,6 +77,7 @@ private: POP3Folder* m_folder; int m_num; uid m_uid; + int m_size; header* m_header; };