Return real message UID from IMAP server. Added function to return the current UID validity.

This commit is contained in:
Vincent Richard 2013-07-21 14:24:18 +02:00
parent 9a9794cb7d
commit cec80c6335
5 changed files with 28 additions and 65 deletions

View File

@ -596,10 +596,10 @@ std::vector <ref <message> > IMAPFolder::getMessagesByUID(const std::vector <mes
std::ostringstream cmd; std::ostringstream cmd;
cmd.imbue(std::locale::classic()); cmd.imbue(std::locale::classic());
cmd << "UID FETCH " << IMAPUtils::extractUIDFromGlobalUID(uids[0]); cmd << "UID FETCH " << uids[0];
for (std::vector <message::uid>::size_type i = 1, n = uids.size() ; i < n ; ++i) for (std::vector <message::uid>::size_type i = 1, n = uids.size() ; i < n ; ++i)
cmd << "," << IMAPUtils::extractUIDFromGlobalUID(uids[i]); cmd << "," << uids[i];
cmd << " UID"; cmd << " UID";
@ -639,7 +639,7 @@ std::vector <ref <message> > IMAPFolder::getMessagesByUID(const std::vector <mes
// Get Process fetch response for this message // Get Process fetch response for this message
const int msgNum = static_cast <int>(messageData->number()); const int msgNum = static_cast <int>(messageData->number());
message::uid msgUID, msgFullUID; message::uid msgUID;
// Find UID in message attributes // Find UID in message attributes
const std::vector <IMAPParser::msg_att_item*> atts = messageData->msg_att()->items(); const std::vector <IMAPParser::msg_att_item*> atts = messageData->msg_att()->items();
@ -649,9 +649,7 @@ std::vector <ref <message> > IMAPFolder::getMessagesByUID(const std::vector <mes
{ {
if ((*it)->type() == IMAPParser::msg_att_item::UID) if ((*it)->type() == IMAPParser::msg_att_item::UID)
{ {
msgFullUID = IMAPUtils::makeGlobalUID(m_status->getUIDValidity(), (*it)->unique_id()->value());
msgUID = (*it)->unique_id()->value(); msgUID = (*it)->unique_id()->value();
break; break;
} }
} }
@ -659,7 +657,7 @@ std::vector <ref <message> > IMAPFolder::getMessagesByUID(const std::vector <mes
if (!msgUID.empty()) if (!msgUID.empty())
{ {
ref <IMAPFolder> thisFolder = thisRef().dynamicCast <IMAPFolder>(); ref <IMAPFolder> thisFolder = thisRef().dynamicCast <IMAPFolder>();
messages.push_back(vmime::create <IMAPMessage>(thisFolder, msgNum, msgFullUID)); messages.push_back(vmime::create <IMAPMessage>(thisFolder, msgNum, msgUID));
} }
} }
@ -676,6 +674,15 @@ int IMAPFolder::getMessageCount()
} }
vmime_uint32 IMAPFolder::getUIDValidity() const
{
if (!isOpen())
throw exceptions::illegal_state("Folder not open");
return m_status->getUIDValidity();
}
vmime_uint64 IMAPFolder::getHighestModSequence() const vmime_uint64 IMAPFolder::getHighestModSequence() const
{ {
if (!isOpen()) if (!isOpen())

View File

@ -295,7 +295,7 @@ void IMAPMessage::extractImpl(ref <const messagePart> p, utility::outputStream&
if (m_uid.empty()) if (m_uid.empty())
command << "FETCH " << m_num << " BODY"; command << "FETCH " << m_num << " BODY";
else else
command << "UID FETCH " << IMAPUtils::extractUIDFromGlobalUID(m_uid) << " BODY"; command << "UID FETCH " << m_uid << " BODY";
/* /*
BODY[] header + body BODY[] header + body
@ -393,7 +393,7 @@ int IMAPMessage::processFetchResponse
} }
case IMAPParser::msg_att_item::UID: case IMAPParser::msg_att_item::UID:
{ {
m_uid = IMAPUtils::makeGlobalUID(folder->m_status->getUIDValidity(), (*it)->unique_id()->value()); m_uid = (*it)->unique_id()->value();
break; break;
} }
case IMAPParser::msg_att_item::MODSEQ: case IMAPParser::msg_att_item::MODSEQ:

View File

@ -554,10 +554,10 @@ const string IMAPUtils::listToSet(const std::vector <message::uid>& list)
std::ostringstream res; std::ostringstream res;
res.imbue(std::locale::classic()); res.imbue(std::locale::classic());
res << extractUIDFromGlobalUID(list[0]); res << list[0];
for (std::vector <message::uid>::size_type i = 1, n = list.size() ; i < n ; ++i) for (std::vector <message::uid>::size_type i = 1, n = list.size() ; i < n ; ++i)
res << "," << extractUIDFromGlobalUID(list[i]); res << "," << list[i];
return res.str(); return res.str();
} }
@ -756,46 +756,6 @@ void IMAPUtils::convertAddressList
} }
// static
vmime_uint32 IMAPUtils::extractUIDFromGlobalUID(const message::uid& uid)
{
message::uid::size_type colonPos = uid.find(':');
if (colonPos == message::uid::npos)
{
std::istringstream iss(uid);
iss.imbue(std::locale::classic());
vmime_uint32 n = 0;
iss >> n;
return n;
}
else
{
std::istringstream iss(uid.substr(colonPos + 1));
iss.imbue(std::locale::classic());
vmime_uint32 n = 0;
iss >> n;
return n;
}
}
// static
const message::uid IMAPUtils::makeGlobalUID(const vmime_uint32 UIDValidity, const vmime_uint32 messageUID)
{
std::ostringstream oss;
oss.imbue(std::locale::classic());
oss << UIDValidity << ":" << messageUID;
return message::uid(oss.str());
}
} // imap } // imap
} // net } // net
} // vmime } // vmime

View File

@ -138,6 +138,17 @@ public:
int getFetchCapabilities() const; int getFetchCapabilities() const;
/** Returns the UID validity of the folder for the current session.
* If the server is capable of persisting UIDs accross sessions,
* this value should never change for a folder. If the UID validity
* differs across sessions, then the UIDs obtained during a previous
* session may not correspond to the UIDs of the same messages in
* this session.
*
* @return UID validity of the folder
*/
vmime_uint32 getUIDValidity() const;
/** Returns the highest modification sequence of this folder, ie the /** Returns the highest modification sequence of this folder, ie the
* modification sequence of the last message that changed in this * modification sequence of the last message that changed in this
* folder. * folder.

View File

@ -130,21 +130,6 @@ public:
*/ */
static void convertAddressList(const IMAPParser::address_list& src, mailboxList& dest); static void convertAddressList(const IMAPParser::address_list& src, mailboxList& dest);
/** Extract the message UID from a globally unique UID.
*
* @param uid globally unique UID (as returned by makeGlobalUID(), for example)
* @return message UID
*/
static vmime_uint32 extractUIDFromGlobalUID(const message::uid& uid);
/** Construct a globally unique UID from UID Validity and a message UID.
*
* @param UIDValidity UID Validity of the folder
* @param messageUID UID of the message
* @return global UID
*/
static const message::uid makeGlobalUID(const vmime_uint32 UIDValidity, const vmime_uint32 messageUID);
private: private:
static const string buildFetchRequestImpl static const string buildFetchRequestImpl