Added support for APPENDUID/COPYUID (UIDPLUS extension for IMAP).
This commit is contained in:
parent
28398076c2
commit
fab5cd79b6
@ -563,6 +563,8 @@ static void connectStore()
|
|||||||
choices.push_back("Status");
|
choices.push_back("Status");
|
||||||
choices.push_back("List folders");
|
choices.push_back("List folders");
|
||||||
choices.push_back("Change folder");
|
choices.push_back("Change folder");
|
||||||
|
choices.push_back("Add message (to the current folder)");
|
||||||
|
choices.push_back("Copy message (into the current folder)");
|
||||||
choices.push_back("Return to main menu");
|
choices.push_back("Return to main menu");
|
||||||
|
|
||||||
const int choice = printMenu(choices);
|
const int choice = printMenu(choices);
|
||||||
@ -570,7 +572,7 @@ static void connectStore()
|
|||||||
// Request message number
|
// Request message number
|
||||||
vmime::shared_ptr <vmime::net::message> msg;
|
vmime::shared_ptr <vmime::net::message> msg;
|
||||||
|
|
||||||
if (choice != 6 && choice != 7 && choice != 8)
|
if (choice == 1 || choice == 2 || choice == 3 || choice == 4 || choice == 5 || choice == 10)
|
||||||
{
|
{
|
||||||
std::cout << "Enter message number: ";
|
std::cout << "Enter message number: ";
|
||||||
std::cout.flush();
|
std::cout.flush();
|
||||||
@ -583,7 +585,7 @@ static void connectStore()
|
|||||||
int num = 0;
|
int num = 0;
|
||||||
iss >> num;
|
iss >> num;
|
||||||
|
|
||||||
if (num < 1 || num > count)
|
if (num < 1 || num > f->getMessageCount())
|
||||||
{
|
{
|
||||||
std::cerr << "Invalid message number." << std::endl;
|
std::cerr << "Invalid message number." << std::endl;
|
||||||
continue;
|
continue;
|
||||||
@ -722,8 +724,91 @@ static void connectStore()
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Main menu
|
// Add message
|
||||||
case 9:
|
case 9:
|
||||||
|
{
|
||||||
|
vmime::messageBuilder mb;
|
||||||
|
|
||||||
|
mb.setExpeditor(vmime::mailbox("me@somewhere.com"));
|
||||||
|
|
||||||
|
vmime::addressList to;
|
||||||
|
to.appendAddress(vmime::make_shared <vmime::mailbox>("you@elsewhere.com"));
|
||||||
|
mb.setRecipients(to);
|
||||||
|
|
||||||
|
mb.setSubject(vmime::text("Test message from VMime example6"));
|
||||||
|
mb.getTextPart()->setText(vmime::make_shared <vmime::stringContentHandler>(
|
||||||
|
"Body of test message from VMime example6."));
|
||||||
|
|
||||||
|
vmime::shared_ptr <vmime::message> msg = mb.construct();
|
||||||
|
|
||||||
|
vmime::net::messageSet set = f->addMessage(msg);
|
||||||
|
|
||||||
|
if (set.isEmpty())
|
||||||
|
{
|
||||||
|
std::cout << "Message has successfully been added, "
|
||||||
|
<< "but its UID/number is not known." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const vmime::net::messageRange& range = set.getRangeAt(0);
|
||||||
|
|
||||||
|
if (set.isUIDSet())
|
||||||
|
{
|
||||||
|
const vmime::net::message::uid uid =
|
||||||
|
dynamic_cast <const vmime::net::UIDMessageRange&>(range).getFirst();
|
||||||
|
|
||||||
|
std::cout << "Message has successfully been added, "
|
||||||
|
<< "its UID is '" << uid << "'." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const int number =
|
||||||
|
dynamic_cast <const vmime::net::numberMessageRange&>(range).getFirst();
|
||||||
|
|
||||||
|
std::cout << "Message has successfully been added, "
|
||||||
|
<< "its number is '" << number << "'." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Copy message
|
||||||
|
case 10:
|
||||||
|
{
|
||||||
|
vmime::net::messageSet set = f->copyMessages(f->getFullPath(),
|
||||||
|
vmime::net::messageSet::byNumber(msg->getNumber()));
|
||||||
|
|
||||||
|
if (set.isEmpty())
|
||||||
|
{
|
||||||
|
std::cout << "Message has successfully been copied, "
|
||||||
|
<< "but its UID/number is not known." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const vmime::net::messageRange& range = set.getRangeAt(0);
|
||||||
|
|
||||||
|
if (set.isUIDSet())
|
||||||
|
{
|
||||||
|
const vmime::net::message::uid uid =
|
||||||
|
dynamic_cast <const vmime::net::UIDMessageRange&>(range).getFirst();
|
||||||
|
|
||||||
|
std::cout << "Message has successfully been copied, "
|
||||||
|
<< "its UID is '" << uid << "'." << std::endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const int number =
|
||||||
|
dynamic_cast <const vmime::net::numberMessageRange&>(range).getFirst();
|
||||||
|
|
||||||
|
std::cout << "Message has successfully been copied, "
|
||||||
|
<< "its number is '" << number << "'." << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// Main menu
|
||||||
|
case 11:
|
||||||
|
|
||||||
f->close(true); // 'true' to expunge deleted messages
|
f->close(true); // 'true' to expunge deleted messages
|
||||||
cont = false;
|
cont = false;
|
||||||
|
@ -269,9 +269,16 @@ public:
|
|||||||
* @param flags flags for the new message
|
* @param flags flags for the new message
|
||||||
* @param date date/time for the new message (if NULL, the current time is used)
|
* @param date date/time for the new message (if NULL, the current time is used)
|
||||||
* @param progress progress listener, or NULL if not used
|
* @param progress progress listener, or NULL if not used
|
||||||
|
* @return a message set containing the number or UID of the new message, or
|
||||||
|
* an empty set if the information could not be obtained (ie. the server does not
|
||||||
|
* support returning the number or UID of an added message)
|
||||||
* @throw exceptions::net_exception if an error occurs
|
* @throw exceptions::net_exception if an error occurs
|
||||||
*/
|
*/
|
||||||
virtual void addMessage(shared_ptr <vmime::message> msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL) = 0;
|
virtual messageSet addMessage
|
||||||
|
(shared_ptr <vmime::message> msg,
|
||||||
|
const int flags = message::FLAG_UNDEFINED,
|
||||||
|
vmime::datetime* date = NULL,
|
||||||
|
utility::progressListener* progress = NULL) = 0;
|
||||||
|
|
||||||
/** Add a message to this folder.
|
/** Add a message to this folder.
|
||||||
*
|
*
|
||||||
@ -280,17 +287,29 @@ public:
|
|||||||
* @param flags flags for the new message
|
* @param flags flags for the new message
|
||||||
* @param date date/time for the new message (if NULL, the current time is used)
|
* @param date date/time for the new message (if NULL, the current time is used)
|
||||||
* @param progress progress listener, or NULL if not used
|
* @param progress progress listener, or NULL if not used
|
||||||
|
* @return a message set containing the number or UID of the new message, or
|
||||||
|
* an empty set if the information could not be obtained (ie. the server does not
|
||||||
|
* support returning the number or UID of an added message)
|
||||||
* @throw exceptions::net_exception if an error occurs
|
* @throw exceptions::net_exception if an error occurs
|
||||||
*/
|
*/
|
||||||
virtual void addMessage(utility::inputStream& is, const size_t size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL) = 0;
|
virtual messageSet addMessage
|
||||||
|
(utility::inputStream& is,
|
||||||
|
const size_t size,
|
||||||
|
const int flags = message::FLAG_UNDEFINED,
|
||||||
|
vmime::datetime* date = NULL,
|
||||||
|
utility::progressListener* progress = NULL) = 0;
|
||||||
|
|
||||||
/** Copy messages from this folder to another folder.
|
/** Copy messages from this folder to another folder.
|
||||||
*
|
*
|
||||||
* @param dest destination folder path
|
* @param dest destination folder path
|
||||||
* @param msgs index set of messages to copy
|
* @param msgs index set of messages to copy
|
||||||
|
* @return a message set containing the number(s) or UID(s) of the copied message(s),
|
||||||
|
* or an empty set if the information could not be obtained (ie. the server does not
|
||||||
|
* support returning the number or UID of a copied message)
|
||||||
* @throw exceptions::net_exception if an error occurs
|
* @throw exceptions::net_exception if an error occurs
|
||||||
*/
|
*/
|
||||||
virtual void copyMessages(const folder::path& dest, const messageSet& msgs) = 0;
|
virtual messageSet copyMessages
|
||||||
|
(const folder::path& dest, const messageSet& msgs) = 0;
|
||||||
|
|
||||||
/** Request folder status without opening it.
|
/** Request folder status without opening it.
|
||||||
*
|
*
|
||||||
|
@ -990,8 +990,9 @@ void IMAPFolder::setMessageFlags(const messageSet& msgs, const int flags, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void IMAPFolder::addMessage(shared_ptr <vmime::message> msg, const int flags,
|
messageSet IMAPFolder::addMessage
|
||||||
vmime::datetime* date, utility::progressListener* progress)
|
(shared_ptr <vmime::message> msg, const int flags,
|
||||||
|
vmime::datetime* date, utility::progressListener* progress)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
utility::outputStreamAdapter ossAdapter(oss);
|
utility::outputStreamAdapter ossAdapter(oss);
|
||||||
@ -1001,12 +1002,13 @@ void IMAPFolder::addMessage(shared_ptr <vmime::message> msg, const int flags,
|
|||||||
const string& str = oss.str();
|
const string& str = oss.str();
|
||||||
utility::inputStreamStringAdapter strAdapter(str);
|
utility::inputStreamStringAdapter strAdapter(str);
|
||||||
|
|
||||||
addMessage(strAdapter, str.length(), flags, date, progress);
|
return addMessage(strAdapter, str.length(), flags, date, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void IMAPFolder::addMessage(utility::inputStream& is, const size_t size, const int flags,
|
messageSet IMAPFolder::addMessage
|
||||||
vmime::datetime* date, utility::progressListener* progress)
|
(utility::inputStream& is, const size_t size, const int flags,
|
||||||
|
vmime::datetime* date, utility::progressListener* progress)
|
||||||
{
|
{
|
||||||
shared_ptr <IMAPStore> store = m_store.lock();
|
shared_ptr <IMAPStore> store = m_store.lock();
|
||||||
|
|
||||||
@ -1063,6 +1065,8 @@ void IMAPFolder::addMessage(utility::inputStream& is, const size_t size, const i
|
|||||||
resp->getErrorLog(), "bad response");
|
resp->getErrorLog(), "bad response");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
processStatusUpdate(resp.get());
|
||||||
|
|
||||||
// Send message data
|
// Send message data
|
||||||
const size_t total = size;
|
const size_t total = size;
|
||||||
size_t current = 0;
|
size_t current = 0;
|
||||||
@ -1105,7 +1109,15 @@ void IMAPFolder::addMessage(utility::inputStream& is, const size_t size, const i
|
|||||||
resp->getErrorLog(), "bad response");
|
resp->getErrorLog(), "bad response");
|
||||||
}
|
}
|
||||||
|
|
||||||
processStatusUpdate(resp.get());
|
processStatusUpdate(finalResp.get());
|
||||||
|
|
||||||
|
const IMAPParser::resp_text_code* respTextCode =
|
||||||
|
finalResp->response_done()->response_tagged()->resp_cond_state()->resp_text()->resp_text_code();
|
||||||
|
|
||||||
|
if (respTextCode->type() == IMAPParser::resp_text_code::APPENDUID)
|
||||||
|
return IMAPUtils::buildMessageSet(respTextCode->uid_set());
|
||||||
|
|
||||||
|
return messageSet::empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1209,7 +1221,7 @@ void IMAPFolder::rename(const folder::path& newPath)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void IMAPFolder::copyMessages(const folder::path& dest, const messageSet& set)
|
messageSet IMAPFolder::copyMessages(const folder::path& dest, const messageSet& set)
|
||||||
{
|
{
|
||||||
shared_ptr <IMAPStore> store = m_store.lock();
|
shared_ptr <IMAPStore> store = m_store.lock();
|
||||||
|
|
||||||
@ -1240,6 +1252,14 @@ void IMAPFolder::copyMessages(const folder::path& dest, const messageSet& set)
|
|||||||
}
|
}
|
||||||
|
|
||||||
processStatusUpdate(resp.get());
|
processStatusUpdate(resp.get());
|
||||||
|
|
||||||
|
const IMAPParser::resp_text_code* respTextCode =
|
||||||
|
resp->response_done()->response_tagged()->resp_cond_state()->resp_text()->resp_text_code();
|
||||||
|
|
||||||
|
if (respTextCode->type() == IMAPParser::resp_text_code::COPYUID)
|
||||||
|
return IMAPUtils::buildMessageSet(respTextCode->uid_set2());
|
||||||
|
|
||||||
|
return messageSet::empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -105,10 +105,20 @@ public:
|
|||||||
|
|
||||||
void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET);
|
void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET);
|
||||||
|
|
||||||
void addMessage(shared_ptr <vmime::message> msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL);
|
messageSet addMessage
|
||||||
void addMessage(utility::inputStream& is, const size_t size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL);
|
(shared_ptr <vmime::message> msg,
|
||||||
|
const int flags = message::FLAG_UNDEFINED,
|
||||||
|
vmime::datetime* date = NULL,
|
||||||
|
utility::progressListener* progress = NULL);
|
||||||
|
|
||||||
void copyMessages(const folder::path& dest, const messageSet& msgs);
|
messageSet addMessage
|
||||||
|
(utility::inputStream& is,
|
||||||
|
const size_t size,
|
||||||
|
const int flags = message::FLAG_UNDEFINED,
|
||||||
|
vmime::datetime* date = NULL,
|
||||||
|
utility::progressListener* progress = NULL);
|
||||||
|
|
||||||
|
messageSet copyMessages(const folder::path& dest, const messageSet& msgs);
|
||||||
|
|
||||||
void status(int& count, int& unseen);
|
void status(int& count, int& unseen);
|
||||||
shared_ptr <folderStatus> getStatus();
|
shared_ptr <folderStatus> getStatus();
|
||||||
|
@ -551,6 +551,119 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// uniqueid ::= nz_number
|
||||||
|
// ;; Strictly ascending
|
||||||
|
//
|
||||||
|
|
||||||
|
class uniqueid : public nz_number
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
uniqueid() : nz_number()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// uid-range = (uniqueid ":" uniqueid)
|
||||||
|
// ; two uniqueid values and all values
|
||||||
|
// ; between these two regards of order.
|
||||||
|
// ; Example: 2:4 and 4:2 are equivalent.
|
||||||
|
|
||||||
|
class uid_range : public component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
uid_range()
|
||||||
|
: m_uniqueid1(NULL), m_uniqueid2(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~uid_range()
|
||||||
|
{
|
||||||
|
delete m_uniqueid1;
|
||||||
|
delete m_uniqueid2;
|
||||||
|
}
|
||||||
|
|
||||||
|
void go(IMAPParser& parser, string& line, size_t* currentPos)
|
||||||
|
{
|
||||||
|
DEBUG_ENTER_COMPONENT("uid_range");
|
||||||
|
|
||||||
|
size_t pos = *currentPos;
|
||||||
|
|
||||||
|
m_uniqueid1 = parser.get <uniqueid>(line, &pos);
|
||||||
|
parser.check <one_char <','> >(line, &pos);
|
||||||
|
m_uniqueid2 = parser.get <uniqueid>(line, &pos);
|
||||||
|
|
||||||
|
*currentPos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
uniqueid* m_uniqueid1;
|
||||||
|
uniqueid* m_uniqueid2;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
uniqueid* uniqueid1() const { return m_uniqueid1; }
|
||||||
|
uniqueid* uniqueid2() const { return m_uniqueid2; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// uid-set = (uniqueid / uid-range) *("," uid-set)
|
||||||
|
//
|
||||||
|
|
||||||
|
class uid_set : public component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
uid_set()
|
||||||
|
: m_uniqueid(NULL), m_uid_range(NULL), m_next_uid_set(NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~uid_set()
|
||||||
|
{
|
||||||
|
delete m_uniqueid;
|
||||||
|
delete m_uid_range;
|
||||||
|
delete m_next_uid_set;
|
||||||
|
}
|
||||||
|
|
||||||
|
void go(IMAPParser& parser, string& line, size_t* currentPos)
|
||||||
|
{
|
||||||
|
DEBUG_ENTER_COMPONENT("uid_set");
|
||||||
|
|
||||||
|
size_t pos = *currentPos;
|
||||||
|
|
||||||
|
// We have either a 'uid_range' or a 'uniqueid'
|
||||||
|
if (!(m_uid_range = parser.get <IMAPParser::uid_range>(line, &pos, true)))
|
||||||
|
m_uniqueid = parser.get <IMAPParser::uniqueid>(line, &pos);
|
||||||
|
|
||||||
|
// And maybe another 'uid-set' following
|
||||||
|
if (parser.check <one_char <','> >(line, &pos, true))
|
||||||
|
m_next_uid_set = parser.get <IMAPParser::uid_set>(line, &pos);
|
||||||
|
|
||||||
|
*currentPos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
IMAPParser::uniqueid* m_uniqueid;
|
||||||
|
IMAPParser::uid_range* m_uid_range;
|
||||||
|
|
||||||
|
IMAPParser::uid_set* m_next_uid_set;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
IMAPParser::uniqueid* uniqueid() const { return m_uniqueid; }
|
||||||
|
IMAPParser::uid_range* uid_range() const { return m_uid_range; }
|
||||||
|
|
||||||
|
IMAPParser::uid_set* next_uid_set() const { return m_next_uid_set; }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// text ::= 1*TEXT_CHAR
|
// text ::= 1*TEXT_CHAR
|
||||||
//
|
//
|
||||||
@ -3850,10 +3963,6 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// uniqueid ::= nz_number
|
|
||||||
// ;; Strictly ascending
|
|
||||||
//
|
|
||||||
// msg_att_item ::= "ENVELOPE" SPACE envelope /
|
// msg_att_item ::= "ENVELOPE" SPACE envelope /
|
||||||
// "FLAGS" SPACE "(" #(flag / "\Recent") ")" /
|
// "FLAGS" SPACE "(" #(flag / "\Recent") ")" /
|
||||||
// "INTERNALDATE" SPACE date_time /
|
// "INTERNALDATE" SPACE date_time /
|
||||||
@ -4020,7 +4129,7 @@ public:
|
|||||||
parser.checkWithArg <special_atom>(line, &pos, "uid");
|
parser.checkWithArg <special_atom>(line, &pos, "uid");
|
||||||
parser.check <SPACE>(line, &pos);
|
parser.check <SPACE>(line, &pos);
|
||||||
|
|
||||||
m_uniqueid = parser.get <nz_number>(line, &pos);
|
m_uniqueid = parser.get <uniqueid>(line, &pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
*currentPos = pos;
|
*currentPos = pos;
|
||||||
@ -4050,7 +4159,7 @@ public:
|
|||||||
IMAPParser::date_time* m_date_time;
|
IMAPParser::date_time* m_date_time;
|
||||||
IMAPParser::number* m_number;
|
IMAPParser::number* m_number;
|
||||||
IMAPParser::envelope* m_envelope;
|
IMAPParser::envelope* m_envelope;
|
||||||
IMAPParser::nz_number* m_uniqueid;
|
IMAPParser::uniqueid* m_uniqueid;
|
||||||
IMAPParser::nstring* m_nstring;
|
IMAPParser::nstring* m_nstring;
|
||||||
IMAPParser::xbody* m_body;
|
IMAPParser::xbody* m_body;
|
||||||
IMAPParser::flag_list* m_flag_list;
|
IMAPParser::flag_list* m_flag_list;
|
||||||
@ -4064,7 +4173,7 @@ public:
|
|||||||
const IMAPParser::date_time* date_time() const { return (m_date_time); }
|
const IMAPParser::date_time* date_time() const { return (m_date_time); }
|
||||||
const IMAPParser::number* number() const { return (m_number); }
|
const IMAPParser::number* number() const { return (m_number); }
|
||||||
const IMAPParser::envelope* envelope() const { return (m_envelope); }
|
const IMAPParser::envelope* envelope() const { return (m_envelope); }
|
||||||
const IMAPParser::nz_number* unique_id() const { return (m_uniqueid); }
|
const IMAPParser::uniqueid* unique_id() const { return (m_uniqueid); }
|
||||||
const IMAPParser::nstring* nstring() const { return (m_nstring); }
|
const IMAPParser::nstring* nstring() const { return (m_nstring); }
|
||||||
const IMAPParser::xbody* body() const { return (m_body); }
|
const IMAPParser::xbody* body() const { return (m_body); }
|
||||||
const IMAPParser::flag_list* flag_list() const { return (m_flag_list); }
|
const IMAPParser::flag_list* flag_list() const { return (m_flag_list); }
|
||||||
@ -4195,6 +4304,7 @@ public:
|
|||||||
// "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
|
// "READ-ONLY" / "READ-WRITE" / "TRYCREATE" /
|
||||||
// "UIDVALIDITY" SPACE nz_number /
|
// "UIDVALIDITY" SPACE nz_number /
|
||||||
// "UNSEEN" SPACE nz_number /
|
// "UNSEEN" SPACE nz_number /
|
||||||
|
// "UIDNEXT" SPACE nz-number /
|
||||||
// atom [SPACE 1*<any TEXT_CHAR except "]">]
|
// atom [SPACE 1*<any TEXT_CHAR except "]">]
|
||||||
//
|
//
|
||||||
// IMAP Extension for Conditional STORE (RFC-4551):
|
// IMAP Extension for Conditional STORE (RFC-4551):
|
||||||
@ -4202,6 +4312,12 @@ public:
|
|||||||
// resp-text-code =/ "HIGHESTMODSEQ" SP mod-sequence-value /
|
// resp-text-code =/ "HIGHESTMODSEQ" SP mod-sequence-value /
|
||||||
// "NOMODSEQ" /
|
// "NOMODSEQ" /
|
||||||
// "MODIFIED" SP set
|
// "MODIFIED" SP set
|
||||||
|
//
|
||||||
|
// IMAP UIDPLUS Extension (RFC-4315):
|
||||||
|
//
|
||||||
|
// resp-text-code =/ "APPENDUID" SP nz-number SP append-uid /
|
||||||
|
// "COPYUID" SP nz-number SP uid-set SP uid-set /
|
||||||
|
// "UIDNOTSTICKY"
|
||||||
|
|
||||||
class resp_text_code : public component
|
class resp_text_code : public component
|
||||||
{
|
{
|
||||||
@ -4313,6 +4429,33 @@ public:
|
|||||||
|
|
||||||
m_sequence_set = parser.get <IMAPParser::sequence_set>(line, &pos);
|
m_sequence_set = parser.get <IMAPParser::sequence_set>(line, &pos);
|
||||||
}
|
}
|
||||||
|
// "APPENDUID" SP nz-number SP append-uid
|
||||||
|
else if (parser.checkWithArg <special_atom>(line, &pos, "appenduid", true))
|
||||||
|
{
|
||||||
|
m_type = APPENDUID;
|
||||||
|
|
||||||
|
parser.check <SPACE>(line, &pos);
|
||||||
|
m_nz_number = parser.get <IMAPParser::nz_number>(line, &pos);
|
||||||
|
parser.check <SPACE>(line, &pos);
|
||||||
|
m_uid_set = parser.get <IMAPParser::uid_set>(line, &pos);
|
||||||
|
}
|
||||||
|
// "COPYUID" SP nz-number SP uid-set SP uid-set
|
||||||
|
else if (parser.checkWithArg <special_atom>(line, &pos, "copyuid", true))
|
||||||
|
{
|
||||||
|
m_type = COPYUID;
|
||||||
|
|
||||||
|
parser.check <SPACE>(line, &pos);
|
||||||
|
m_nz_number = parser.get <IMAPParser::nz_number>(line, &pos);
|
||||||
|
parser.check <SPACE>(line, &pos);
|
||||||
|
m_uid_set = parser.get <IMAPParser::uid_set>(line, &pos);
|
||||||
|
parser.check <SPACE>(line, &pos);
|
||||||
|
m_uid_set2 = parser.get <IMAPParser::uid_set>(line, &pos);
|
||||||
|
}
|
||||||
|
// "UIDNOTSTICKY"
|
||||||
|
else if (parser.checkWithArg <special_atom>(line, &pos, "uidnotsticky", true))
|
||||||
|
{
|
||||||
|
m_type = UIDNOTSTICKY;
|
||||||
|
}
|
||||||
// atom [SPACE 1*<any TEXT_CHAR except "]">]
|
// atom [SPACE 1*<any TEXT_CHAR except "]">]
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -4334,6 +4477,9 @@ public:
|
|||||||
HIGHESTMODSEQ,
|
HIGHESTMODSEQ,
|
||||||
NOMODSEQ,
|
NOMODSEQ,
|
||||||
MODIFIED,
|
MODIFIED,
|
||||||
|
APPENDUID,
|
||||||
|
COPYUID,
|
||||||
|
UIDNOTSTICKY,
|
||||||
|
|
||||||
// Standard IMAP
|
// Standard IMAP
|
||||||
ALERT,
|
ALERT,
|
||||||
@ -4360,6 +4506,8 @@ public:
|
|||||||
IMAPParser::mod_sequence_value* m_mod_sequence_value;
|
IMAPParser::mod_sequence_value* m_mod_sequence_value;
|
||||||
IMAPParser::sequence_set* m_sequence_set;
|
IMAPParser::sequence_set* m_sequence_set;
|
||||||
IMAPParser::capability_data* m_capability_data;
|
IMAPParser::capability_data* m_capability_data;
|
||||||
|
IMAPParser::uid_set* m_uid_set;
|
||||||
|
IMAPParser::uid_set* m_uid_set2;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -4372,6 +4520,8 @@ public:
|
|||||||
const IMAPParser::mod_sequence_value* mod_sequence_value() const { return m_mod_sequence_value; }
|
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::sequence_set* sequence_set() const { return m_sequence_set; }
|
||||||
const IMAPParser::capability_data* capability_data() const { return m_capability_data; }
|
const IMAPParser::capability_data* capability_data() const { return m_capability_data; }
|
||||||
|
const IMAPParser::uid_set* uid_set() const { return (m_uid_set); }
|
||||||
|
const IMAPParser::uid_set* uid_set2() const { return (m_uid_set2); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -749,6 +749,30 @@ const std::vector <int> IMAPUtils::messageSetToNumberList(const messageSet& msgs
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// static
|
||||||
|
messageSet IMAPUtils::buildMessageSet(const IMAPParser::uid_set* uidSet)
|
||||||
|
{
|
||||||
|
messageSet set = messageSet::empty();
|
||||||
|
|
||||||
|
for ( ; uidSet ; uidSet = uidSet->next_uid_set())
|
||||||
|
{
|
||||||
|
if (uidSet->uid_range())
|
||||||
|
{
|
||||||
|
set.addRange(UIDMessageRange
|
||||||
|
(message::uid(uidSet->uid_range()->uniqueid1()->value()),
|
||||||
|
message::uid(uidSet->uid_range()->uniqueid2()->value())));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
set.addRange(UIDMessageRange
|
||||||
|
(message::uid(uidSet->uniqueid()->value())));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // imap
|
} // imap
|
||||||
} // net
|
} // net
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -112,6 +112,13 @@ public:
|
|||||||
*/
|
*/
|
||||||
static const std::vector <int> messageSetToNumberList(const messageSet& msgs);
|
static const std::vector <int> messageSetToNumberList(const messageSet& msgs);
|
||||||
|
|
||||||
|
/** Constructs a message set from a parser 'uid_set' structure.
|
||||||
|
*
|
||||||
|
* @param uidSet UID set, as returned by the parser
|
||||||
|
* @return message set
|
||||||
|
*/
|
||||||
|
static messageSet buildMessageSet(const IMAPParser::uid_set* uidSet);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
static const string buildFetchRequestImpl
|
static const string buildFetchRequestImpl
|
||||||
|
@ -704,8 +704,9 @@ void maildirFolder::setMessageFlags
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void maildirFolder::addMessage(shared_ptr <vmime::message> msg, const int flags,
|
messageSet maildirFolder::addMessage
|
||||||
vmime::datetime* date, utility::progressListener* progress)
|
(shared_ptr <vmime::message> msg, const int flags,
|
||||||
|
vmime::datetime* date, utility::progressListener* progress)
|
||||||
{
|
{
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
utility::outputStreamAdapter ossAdapter(oss);
|
utility::outputStreamAdapter ossAdapter(oss);
|
||||||
@ -715,12 +716,13 @@ void maildirFolder::addMessage(shared_ptr <vmime::message> msg, const int flags,
|
|||||||
const string& str = oss.str();
|
const string& str = oss.str();
|
||||||
utility::inputStreamStringAdapter strAdapter(str);
|
utility::inputStreamStringAdapter strAdapter(str);
|
||||||
|
|
||||||
addMessage(strAdapter, str.length(), flags, date, progress);
|
return addMessage(strAdapter, str.length(), flags, date, progress);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void maildirFolder::addMessage(utility::inputStream& is, const size_t size,
|
messageSet maildirFolder::addMessage
|
||||||
const int flags, vmime::datetime* /* date */, utility::progressListener* progress)
|
(utility::inputStream& is, const size_t size,
|
||||||
|
const int flags, vmime::datetime* /* date */, utility::progressListener* progress)
|
||||||
{
|
{
|
||||||
shared_ptr <maildirStore> store = m_store.lock();
|
shared_ptr <maildirStore> store = m_store.lock();
|
||||||
|
|
||||||
@ -810,6 +812,8 @@ void maildirFolder::addMessage(utility::inputStream& is, const size_t size,
|
|||||||
(*it)->notifyMessageCount(event);
|
(*it)->notifyMessageCount(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return messageSet::empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -902,7 +906,7 @@ void maildirFolder::copyMessageImpl(const utility::file::path& tmpDirPath,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void maildirFolder::copyMessages(const folder::path& dest, const messageSet& msgs)
|
messageSet maildirFolder::copyMessages(const folder::path& dest, const messageSet& msgs)
|
||||||
{
|
{
|
||||||
shared_ptr <maildirStore> store = m_store.lock();
|
shared_ptr <maildirStore> store = m_store.lock();
|
||||||
|
|
||||||
@ -972,6 +976,8 @@ void maildirFolder::copyMessages(const folder::path& dest, const messageSet& msg
|
|||||||
}
|
}
|
||||||
|
|
||||||
notifyMessagesCopied(dest);
|
notifyMessagesCopied(dest);
|
||||||
|
|
||||||
|
return messageSet::empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -102,10 +102,10 @@ public:
|
|||||||
|
|
||||||
void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET);
|
void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET);
|
||||||
|
|
||||||
void addMessage(shared_ptr <vmime::message> msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL);
|
messageSet addMessage(shared_ptr <vmime::message> msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL);
|
||||||
void addMessage(utility::inputStream& is, const size_t size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL);
|
messageSet addMessage(utility::inputStream& is, const size_t size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL);
|
||||||
|
|
||||||
void copyMessages(const folder::path& dest, const messageSet& msgs);
|
messageSet copyMessages(const folder::path& dest, const messageSet& msgs);
|
||||||
|
|
||||||
void status(int& count, int& unseen);
|
void status(int& count, int& unseen);
|
||||||
shared_ptr <folderStatus> getStatus();
|
shared_ptr <folderStatus> getStatus();
|
||||||
|
@ -163,6 +163,13 @@ messageSet::~messageSet()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// static
|
||||||
|
messageSet messageSet::empty()
|
||||||
|
{
|
||||||
|
return messageSet();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
messageSet messageSet::byNumber(const int number)
|
messageSet messageSet::byNumber(const int number)
|
||||||
{
|
{
|
||||||
@ -365,5 +372,17 @@ bool messageSet::isUIDSet() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t messageSet::getRangeCount() const
|
||||||
|
{
|
||||||
|
return m_ranges.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const messageRange& messageSet::getRangeAt(const size_t i) const
|
||||||
|
{
|
||||||
|
return *m_ranges[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // net
|
} // net
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -214,6 +214,12 @@ public:
|
|||||||
|
|
||||||
messageSet(const messageSet& other);
|
messageSet(const messageSet& other);
|
||||||
|
|
||||||
|
/** Constructs an empty set.
|
||||||
|
*
|
||||||
|
* @return new empty message set
|
||||||
|
*/
|
||||||
|
static messageSet empty();
|
||||||
|
|
||||||
/** Constructs a new message set and initializes it with a single
|
/** Constructs a new message set and initializes it with a single
|
||||||
* message represented by its sequence number.
|
* message represented by its sequence number.
|
||||||
*
|
*
|
||||||
@ -320,6 +326,19 @@ public:
|
|||||||
*/
|
*/
|
||||||
bool isUIDSet() const;
|
bool isUIDSet() const;
|
||||||
|
|
||||||
|
/** Returns the number of ranges contained in this set.
|
||||||
|
*
|
||||||
|
* @return range count
|
||||||
|
*/
|
||||||
|
size_t getRangeCount() const;
|
||||||
|
|
||||||
|
/** Returns the message range at the specified index.
|
||||||
|
*
|
||||||
|
* @param i range index (from 0 to getRangeCount())
|
||||||
|
* @return a reference to the message range at the specified index
|
||||||
|
*/
|
||||||
|
const messageRange& getRangeAt(const size_t i) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
messageSet();
|
messageSet();
|
||||||
|
@ -601,7 +601,7 @@ void POP3Folder::rename(const folder::path& /* newPath */)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void POP3Folder::addMessage
|
messageSet POP3Folder::addMessage
|
||||||
(shared_ptr <vmime::message> /* msg */, const int /* flags */,
|
(shared_ptr <vmime::message> /* msg */, const int /* flags */,
|
||||||
vmime::datetime* /* date */, utility::progressListener* /* progress */)
|
vmime::datetime* /* date */, utility::progressListener* /* progress */)
|
||||||
{
|
{
|
||||||
@ -609,7 +609,7 @@ void POP3Folder::addMessage
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void POP3Folder::addMessage
|
messageSet POP3Folder::addMessage
|
||||||
(utility::inputStream& /* is */, const size_t /* size */, const int /* flags */,
|
(utility::inputStream& /* is */, const size_t /* size */, const int /* flags */,
|
||||||
vmime::datetime* /* date */, utility::progressListener* /* progress */)
|
vmime::datetime* /* date */, utility::progressListener* /* progress */)
|
||||||
{
|
{
|
||||||
@ -617,7 +617,8 @@ void POP3Folder::addMessage
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void POP3Folder::copyMessages(const folder::path& /* dest */, const messageSet& /* msgs */)
|
messageSet POP3Folder::copyMessages
|
||||||
|
(const folder::path& /* dest */, const messageSet& /* msgs */)
|
||||||
{
|
{
|
||||||
throw exceptions::operation_not_supported();
|
throw exceptions::operation_not_supported();
|
||||||
}
|
}
|
||||||
|
@ -99,10 +99,10 @@ public:
|
|||||||
|
|
||||||
void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET);
|
void setMessageFlags(const messageSet& msgs, const int flags, const int mode = message::FLAG_MODE_SET);
|
||||||
|
|
||||||
void addMessage(shared_ptr <vmime::message> msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL);
|
messageSet addMessage(shared_ptr <vmime::message> msg, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL);
|
||||||
void addMessage(utility::inputStream& is, const size_t size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL);
|
messageSet addMessage(utility::inputStream& is, const size_t size, const int flags = message::FLAG_UNDEFINED, vmime::datetime* date = NULL, utility::progressListener* progress = NULL);
|
||||||
|
|
||||||
void copyMessages(const folder::path& dest, const messageSet& msgs);
|
messageSet copyMessages(const folder::path& dest, const messageSet& msgs);
|
||||||
|
|
||||||
void status(int& count, int& unseen);
|
void status(int& count, int& unseen);
|
||||||
shared_ptr <folderStatus> getStatus();
|
shared_ptr <folderStatus> getStatus();
|
||||||
|
Loading…
Reference in New Issue
Block a user