#268 Code style fixes + moved specific bits to IMAP namespace

This commit is contained in:
Vincent Richard 2021-11-25 21:23:50 +01:00
parent c6e3b759bc
commit 80ad529d5a
16 changed files with 790 additions and 687 deletions

View File

@ -775,14 +775,6 @@ void datetime::getDate(int& year, int& month, int& day) const {
}
string datetime::getDate() const {
std::ostringstream date;
date << m_day << "-" << monthNames[m_month - 1] << "-" << m_year;
return date.str();
}
void datetime::setTime(
const int hour,
const int minute,

View File

@ -216,8 +216,6 @@ public:
void getTime(int& hour, int& minute, int& second) const;
void getDate(int& year, int& month, int& day) const;
string getDate() const;
// Set
void setYear(const int year);
void setMonth(const int month);

View File

@ -43,7 +43,6 @@
#include "vmime/net/folderStatus.hpp"
#include "vmime/net/fetchAttributes.hpp"
#include "vmime/net/folderAttributes.hpp"
#include "vmime/net/searchAttributes.hpp"
#include "vmime/utility/path.hpp"
#include "vmime/utility/stream.hpp"
@ -407,36 +406,6 @@ public:
*/
virtual std::vector <size_t> getMessageNumbersStartingOnUID(const message::uid& uid) = 0;
/** Return the sequence numbers of messages matching the searchAttributes.
*
* @param sa the searchAttributes containing search tokens to match messages to
* @param charset optional charset name, the string tokens are assumed to be encoded
* in the provided encoding OR need to be in US-ASCII if no charset is provided
* @throw exceptions::net_exception if an error occurs
*
* Quirks: some servers will not accept any encoding other than US-ASCII,
* other servers will accept UTF-8 but will fail utf-8
*/
virtual std::vector <size_t> getMessageNumbersMatchingSearchAttributes(
const searchAttributes& sa,
const vmime::charset* charset = nullptr
) = 0;
/** Return the UIDs of messages matching the searchAttributes.
*
* @param sa the searchAttributes containing search tokens to match messages to
* @param charset optional charset name, the string tokens are assumed to be encoded
* in the provided encoding OR need to be in US-ASCII if no charset is provided
* @throw exceptions::net_exception if an error occurs
*
* Quirks: some servers will not accept any encoding other than US-ASCII,
* other servers will accept UTF-8 but will fail utf-8
*/
virtual std::vector <message::uid> getMessageUIDsMatchingSearchAttributes(
const searchAttributes& sa,
const vmime::charset* charset = nullptr
) = 0;
// Event listeners
void addMessageChangedListener(events::messageChangedListener* l);
void removeMessageChangedListener(events::messageChangedListener* l);

View File

@ -66,7 +66,7 @@ public:
static shared_ptr <IMAPCommand> APPEND(const string& mailboxName, const std::vector <string>& flags, vmime::datetime* date, const size_t size);
static shared_ptr <IMAPCommand> COPY(const messageSet& msgs, const string& mailboxName);
static shared_ptr <IMAPCommand> SEARCH(const std::vector <string>& keys, const vmime::charset* charset);
static shared_ptr <IMAPCommand> UIDSEARCH(const std::vector <string>& keys, const vmime::charset* charset);
static shared_ptr <IMAPCommand> UIDSEARCH(const std::vector <string>& keys, const vmime::charset* charset);
static shared_ptr <IMAPCommand> STARTTLS();
static shared_ptr <IMAPCommand> CAPABILITY();
static shared_ptr <IMAPCommand> NOOP();

View File

@ -1501,8 +1501,9 @@ std::vector <size_t> IMAPFolder::getMessageNumbersStartingOnUID(const message::u
return seqNumbers;
}
std::vector <size_t> IMAPFolder::getMessageNumbersMatchingSearchAttributes(
const searchAttributes& sa,
const IMAPSearchAttributes& sa,
const vmime::charset* charset
) {
@ -1548,8 +1549,9 @@ std::vector <size_t> IMAPFolder::getMessageNumbersMatchingSearchAttributes(
return seqNumbers;
}
std::vector <message::uid> IMAPFolder::getMessageUIDsMatchingSearchAttributes(
const searchAttributes& sa,
const IMAPSearchAttributes& sa,
const vmime::charset* charset
) {
@ -1593,7 +1595,8 @@ std::vector <message::uid> IMAPFolder::getMessageUIDsMatchingSearchAttributes(
processStatusUpdate(resp.get());
return uidNumbers;
}
}
void IMAPFolder::processStatusUpdate(const IMAPParser::response* resp) {

View File

@ -39,6 +39,7 @@
#include "vmime/net/folder.hpp"
#include "vmime/net/imap/IMAPParser.hpp"
#include "vmime/net/imap/IMAPSearchAttributes.hpp"
namespace vmime {
@ -94,16 +95,36 @@ public:
std::vector <shared_ptr <message> > getMessages(const messageSet& msgs);
std::vector <size_t> getMessageNumbersStartingOnUID(const message::uid& uid);
std::vector <size_t> getMessageNumbersMatchingSearchAttributes(
const searchAttributes& sa,
const vmime::charset* charset = nullptr
) override;
std::vector <message::uid> getMessageUIDsMatchingSearchAttributes(
const searchAttributes& sa,
/** Return the sequence numbers of messages matching the searchAttributes.
*
* @param sa the searchAttributes containing search tokens to match messages to
* @param charset optional charset name, the string tokens are assumed to be encoded
* in the provided encoding OR need to be in US-ASCII if no charset is provided
* @throw exceptions::net_exception if an error occurs
*
* Quirks: some servers will not accept any encoding other than US-ASCII,
* other servers will accept UTF-8 but will fail utf-8
*/
std::vector <size_t> getMessageNumbersMatchingSearchAttributes(
const IMAPSearchAttributes& sa,
const vmime::charset* charset = nullptr
) override;
);
/** Return the UIDs of messages matching the searchAttributes.
*
* @param sa the searchAttributes containing search tokens to match messages to
* @param charset optional charset name, the string tokens are assumed to be encoded
* in the provided encoding OR need to be in US-ASCII if no charset is provided
* @throw exceptions::net_exception if an error occurs
*
* Quirks: some servers will not accept any encoding other than US-ASCII,
* other servers will accept UTF-8 but will fail utf-8
*/
std::vector <message::uid> getMessageUIDsMatchingSearchAttributes(
const IMAPSearchAttributes& sa,
const vmime::charset* charset = nullptr
);
size_t getMessageCount();

View File

@ -0,0 +1,574 @@
#include "vmime/net/imap/IMAPSearchAttributes.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
#include "vmime/net/imap/IMAPUtils.hpp"
namespace vmime {
namespace net {
namespace imap {
namespace helpers {
class keylessToken : public IMAPSearchToken {
public:
keylessToken(const char* token)
: IMAPSearchToken(token) {
}
void generate(std::ostringstream& out) const {
out << m_token;
}
};
template <class TYPE>
class typedSearchToken : public IMAPSearchToken {
public:
typedSearchToken(const char* token, const TYPE& keyword)
: IMAPSearchToken(token)
, m_keyword(keyword) {
}
typedSearchToken(const char* token, const TYPE&& keyword)
: IMAPSearchToken(token)
, m_keyword(std::move(keyword)) {
}
protected:
TYPE m_keyword;
};
// Represents a string search token with the search string quoted
class stringToken : public typedSearchToken <string> {
public:
stringToken(const char* token, const string& keyword)
: typedSearchToken(token, keyword) {
}
void generate(std::ostringstream& out) const override {
out << m_token << " \"" << m_keyword << "\"";
};
};
class headerToken : public typedSearchToken <const char*> {
public:
headerToken(const char* token, const char* header)
: typedSearchToken(token, header) {
}
headerToken(const char* token, const char* header, const string& headerKeyword)
: typedSearchToken(token, header)
, m_headerKeyword(headerKeyword) {
}
void generate(std::ostringstream& out) const override {
out << m_token << " " << m_keyword << " \"" << m_headerKeyword << "\"";
};
protected:
string m_headerKeyword;
};
class dateToken : public typedSearchToken <vmime::datetime> {
public:
dateToken(const char* token, const vmime::datetime& date)
: typedSearchToken(token, date) {
}
// RFC claims that we need to disregard time information
void generate(std::ostringstream& out) const override {
out << m_token << " " << IMAPUtils::searchDate(m_keyword);
};
};
class numberToken : public typedSearchToken< int > {
public:
numberToken(const char* token, uint32_t keyword)
: typedSearchToken(token, keyword) {
}
void generate(std::ostringstream& out) const override {
out << m_token << " " << m_keyword;
};
};
class flagToken : public typedSearchToken <vmime::net::message::Flags> {
public:
flagToken(const char* token, vmime::net::message::Flags keyword)
: typedSearchToken(token, keyword) {
}
void generate(std::ostringstream& out) const override {
out << m_token << " ";
switch (m_keyword) {
case vmime::net::message::Flags::FLAG_SEEN: out << "Seen"; break;
case vmime::net::message::Flags::FLAG_REPLIED: out << "Answered"; break;
case vmime::net::message::Flags::FLAG_MARKED: out << "Flagged"; break;
case vmime::net::message::Flags::FLAG_DRAFT: out << "Draft"; break;
case vmime::net::message::Flags::FLAG_DELETED: out << "Deleted"; break;
default: throw exceptions::operation_not_supported();
}
};
};
class tokenMessageSetEnumerator : public messageSetEnumerator {
public:
tokenMessageSetEnumerator()
: m_first(true) {
m_oss.imbue(std::locale::classic());
}
void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) {
if (!m_first) {
m_oss << ",";
}
if (range.getFirst() == range.getLast()) {
m_oss << range.getFirst();
} else if (range.getLast() == size_t(-1)) {
m_oss << range.getFirst() << ":*";
} else {
m_oss << range.getFirst() << ":" << range.getLast();
}
m_first = false;
}
void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& range) {
if (!m_first) {
m_oss << ",";
}
if (range.getFirst() == range.getLast()) {
m_oss << range.getFirst();
} else if (range.getLast() == size_t(-1)) {
m_oss << range.getFirst() << ":*";
} else {
m_oss << range.getFirst() << ":" << range.getLast();
}
m_first = false;
}
const std::string str() const {
return m_oss.str();
}
private:
std::ostringstream m_oss;
bool m_first;
};
class messageSetToken : public typedSearchToken <vmime::net::messageSet> {
public:
messageSetToken(const char *token, const vmime::net::messageSet& keyword)
: typedSearchToken(token, keyword) {
}
messageSetToken(const char *token, const vmime::net::messageSet&& keyword)
: typedSearchToken(token, std::move(keyword)) {
}
void generate(std::ostringstream& out) const override {
if (*m_token) {
out << m_token << " (";
}
else {
out << "(";
}
tokenMessageSetEnumerator enu;
m_keyword.enumerate(enu);
out << enu.str();
out << ")";
}
};
// Contains a list of tokens which the server will interpret as AND
class tokenVectorToken : public typedSearchToken <std::vector <vmime::shared_ptr <const IMAPSearchToken>>> {
public:
tokenVectorToken(const char* token, const std::vector <vmime::shared_ptr <const IMAPSearchToken>>& tokensAndKeywords)
: typedSearchToken(token, tokensAndKeywords) {
if (0 == m_keyword.size()) {
throw exceptions::invalid_argument();
}
}
tokenVectorToken(const char* token, const std::vector <vmime::shared_ptr <const IMAPSearchToken>>&& tokensAndKeywords)
: typedSearchToken(token, tokensAndKeywords) {
if (0 == m_keyword.size()) {
throw exceptions::invalid_argument();
}
}
void generate(std::ostringstream& out) const override {
out << m_token;
if (*m_token) {
out << " (";
} else {
out << "(";
}
m_keyword[0]->generate(out);
for (size_t i = 1; i < m_keyword.size(); i++) {
out << " ";
m_keyword[i]->generate(out);
}
out << ")";
};
};
// A pair of tokens, used with OR
class tokenPairToken : public typedSearchToken <std::pair <vmime::shared_ptr <const IMAPSearchToken>, vmime::shared_ptr <const IMAPSearchToken>>> {
public:
tokenPairToken(const char* token, const std::pair <vmime::shared_ptr <const IMAPSearchToken>, vmime::shared_ptr <const IMAPSearchToken>>& pair)
: typedSearchToken(token, pair) {
}
void generate(std::ostringstream& out) const override {
out << m_token << " ";
m_keyword.first->generate(out);
out << " ";
m_keyword.second->generate(out);
};
};
} // helpers
IMAPSearchTokenPtr IMAPSearchTokenFactory::AND(const std::vector <IMAPSearchTokenPtr> &&keywords) {
return vmime::make_shared <helpers::tokenVectorToken>("", std::move(keywords));
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::ANSWERED() {
return vmime::make_shared <helpers::keylessToken>("ANSWERED");
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::BCC(const string& keyword) {
return vmime::make_shared <helpers::stringToken>("BCC", keyword);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::BEFORE(const datetime& keyword) {
return vmime::make_shared <helpers::dateToken>("BEFORE", keyword);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::BODY(const string& keyword) {
return vmime::make_shared <helpers::stringToken>("BODY", keyword);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::CC(const string& keyword) {
return vmime::make_shared <helpers::stringToken>("CC", keyword);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::DELETED() {
return vmime::make_shared <helpers::keylessToken>("DELETED");
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::DRAFT() {
return vmime::make_shared <helpers::keylessToken>("DRAFT");
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::FLAGGED() {
return vmime::make_shared <helpers::keylessToken>("FLAGGED");
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::FROM(const string& keyword) {
return vmime::make_shared <helpers::stringToken>("FROM", keyword);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::HEADER(const char* fieldName) {
return vmime::make_shared <helpers::headerToken>("HEADER", fieldName);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::HEADER(const char* fieldName, const string& fieldContents) {
return vmime::make_shared <helpers::headerToken>("HEADER", fieldName, fieldContents);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::KEYWORD(vmime::net::message::Flags flag) {
return vmime::make_shared <helpers::flagToken>("KEYWORD", flag);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::LARGER(uint32_t size) {
return vmime::make_shared <helpers::numberToken>("LARGER", size);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::MESSAGESET(const vmime::net::messageSet& set) {
return vmime::make_shared <helpers::messageSetToken>("", set);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::MESSAGESET(const vmime::net::messageSet&& set) {
return vmime::make_shared <helpers::messageSetToken>("", std::move(set));
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::NEW() {
return vmime::make_shared <helpers::keylessToken>("NEW");
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::NOT(const IMAPSearchTokenPtr& token) {
return vmime::make_shared <helpers::tokenVectorToken>("NOT", std::vector <vmime::shared_ptr <const IMAPSearchToken>>({token}));
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::OLD() {
return vmime::make_shared <helpers::keylessToken>("OLD");
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::ON(const datetime& date) {
return vmime::make_shared <helpers::dateToken>("ON", date);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::OR(const IMAPSearchTokenPtr& tokenA, const IMAPSearchTokenPtr& tokenB) {
return vmime::make_shared <helpers::tokenPairToken>("OR", std::make_pair(tokenA, tokenB));
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::RECENT() {
return vmime::make_shared <helpers::keylessToken>("RECENT");
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::SEEN() {
return vmime::make_shared <helpers::keylessToken>("SEEN");
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::SENTBEFORE(const datetime& date) {
return vmime::make_shared <helpers::dateToken>("SENTBEFORE", date);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::SENTON(const datetime& date) {
return vmime::make_shared <helpers::dateToken>("SENTON", date);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::SENTSINCE(const datetime& date) {
return vmime::make_shared <helpers::dateToken>("SENTSINCE", date);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::SINCE(const datetime& date) {
return vmime::make_shared <helpers::dateToken>("SINCE", date);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::SMALLER(uint32_t size) {
return vmime::make_shared <helpers::numberToken>("SMALLER", size);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::SUBJECT(const string& keyword) {
return vmime::make_shared <helpers::stringToken>("SUBJECT", keyword);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::TEXT(const string& keyword) {
return vmime::make_shared <helpers::stringToken>("TEXT", keyword);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::TO(const string& keyword) {
return vmime::make_shared <helpers::stringToken>("TO", keyword);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::UID(const vmime::net::messageSet& set) {
return vmime::make_shared <helpers::messageSetToken>("UID", set);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::UID(const vmime::net::messageSet&& set) {
return vmime::make_shared <helpers::messageSetToken>("UID", std::move(set));
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::UNANSWERED() {
return vmime::make_shared <helpers::keylessToken>("UNANSWERED");
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::UNDELETED() {
return vmime::make_shared <helpers::keylessToken>("UNDELETED");
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::UNDRAFT() {
return vmime::make_shared <helpers::keylessToken>("UNDRAFT");
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::UNFLAGGED() {
return vmime::make_shared <helpers::keylessToken>("UNFLAGGED");
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::UNKEYWORD(vmime::net::message::Flags flag) {
return vmime::make_shared <helpers::flagToken>("UNKEYWORD", flag);
}
IMAPSearchTokenPtr IMAPSearchTokenFactory::UNSEEN() {
return vmime::make_shared <helpers::keylessToken>("UNSEEN");
}
IMAPSearchAttributes::IMAPSearchAttributes(std::vector <vmime::shared_ptr <const IMAPSearchToken>>&& tokens)
: m_andTokens(std::move(tokens)) {
}
void IMAPSearchAttributes::add(const vmime::shared_ptr <const IMAPSearchToken>& token) {
m_andTokens.push_back(token);
}
std::vector <string> IMAPSearchAttributes::generate() const {
std::vector< string > keys;
for (auto& token : m_andTokens) {
std::ostringstream key;
key.imbue(std::locale::classic());
token->generate(key);
keys.push_back(key.str());
}
return keys;
}
} // imap
} // net
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP

View File

@ -0,0 +1,150 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#ifndef VMIME_NET_IMAP_IMAPSEARCHATTRIBUTES_HPP_INCLUDED
#define VMIME_NET_IMAP_IMAPSEARCHATTRIBUTES_HPP_INCLUDED
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
#include <vector>
#include "vmime/types.hpp"
#include "vmime/utility/stringUtils.hpp"
#include "vmime/dateTime.hpp"
#include "vmime/net/message.hpp"
#include "vmime/net/messageSet.hpp"
namespace vmime {
namespace net {
namespace imap {
class IMAPSearchToken : public object {
public:
IMAPSearchToken(const char* token)
: m_token(token) {
if (nullptr == m_token) {
throw exceptions::invalid_argument();
}
}
virtual void generate(std::ostringstream& out) const = 0;
protected:
const char* m_token;
};
typedef vmime::shared_ptr <const IMAPSearchToken> IMAPSearchTokenPtr;
class IMAPSearchTokenFactory : public object {
public:
static IMAPSearchTokenPtr AND(const std::vector <IMAPSearchTokenPtr>&);
static IMAPSearchTokenPtr AND(const std::vector <IMAPSearchTokenPtr>&&);
static IMAPSearchTokenPtr ANSWERED();
static IMAPSearchTokenPtr BCC(const string&);
static IMAPSearchTokenPtr BEFORE(const datetime&);
static IMAPSearchTokenPtr BODY(const string&);
static IMAPSearchTokenPtr CC(const string&);
static IMAPSearchTokenPtr DELETED();
static IMAPSearchTokenPtr DRAFT();
static IMAPSearchTokenPtr FLAGGED();
static IMAPSearchTokenPtr FROM(const string&);
static IMAPSearchTokenPtr HEADER(const char* fieldName);
static IMAPSearchTokenPtr HEADER(const char* filedName, const string& fieldContents);
static IMAPSearchTokenPtr KEYWORD(vmime::net::message::Flags);
static IMAPSearchTokenPtr LARGER(uint32_t);
static IMAPSearchTokenPtr MESSAGESET(const vmime::net::messageSet&);
static IMAPSearchTokenPtr MESSAGESET(const vmime::net::messageSet&&);
static IMAPSearchTokenPtr NEW();
static IMAPSearchTokenPtr NOT(const IMAPSearchTokenPtr&);
static IMAPSearchTokenPtr OLD();
static IMAPSearchTokenPtr ON(const datetime&);
static IMAPSearchTokenPtr OR(const IMAPSearchTokenPtr&, const IMAPSearchTokenPtr&);
static IMAPSearchTokenPtr RECENT();
static IMAPSearchTokenPtr SEEN();
static IMAPSearchTokenPtr SENTBEFORE(const datetime&);
static IMAPSearchTokenPtr SENTON(const datetime&);
static IMAPSearchTokenPtr SENTSINCE(const datetime&);
static IMAPSearchTokenPtr SINCE(const datetime&);
static IMAPSearchTokenPtr SMALLER(uint32_t);
static IMAPSearchTokenPtr SUBJECT(const string&);
static IMAPSearchTokenPtr TEXT(const string&);
static IMAPSearchTokenPtr TO(const string&);
static IMAPSearchTokenPtr UID(const vmime::net::messageSet&);
static IMAPSearchTokenPtr UID(const vmime::net::messageSet&&);
static IMAPSearchTokenPtr UNANSWERED();
static IMAPSearchTokenPtr UNDELETED();
static IMAPSearchTokenPtr UNDRAFT();
static IMAPSearchTokenPtr UNFLAGGED();
static IMAPSearchTokenPtr UNKEYWORD(vmime::net::message::Flags);
static IMAPSearchTokenPtr UNSEEN();
};
/** Holds a set of attributes to match messages against when searching folder contents.
*/
class VMIME_EXPORT IMAPSearchAttributes : public object {
public:
IMAPSearchAttributes() = default;
IMAPSearchAttributes(std::vector <vmime::shared_ptr <const IMAPSearchToken>>&&);
/** Adds a new search token that will be used to match messages against. Multiple tokens are
* treated as an AND operation.
*
* @param token the search token to add
*/
void add(const vmime::shared_ptr <const IMAPSearchToken>& token);
std::vector <string> generate() const;
protected:
std::vector <vmime::shared_ptr <const IMAPSearchToken>> m_andTokens;
};
} // imap
} // net
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES && VMIME_HAVE_MESSAGING_PROTO_IMAP
#endif // VMIME_NET_IMAP_IMAPSEARCHATTRIBUTES_HPP_INCLUDED

View File

@ -43,6 +43,12 @@ namespace net {
namespace imap {
static const char* IMAP_MONTH_NAMES[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
// static
const string IMAPUtils::quoteString(const string& text) {
@ -545,6 +551,22 @@ const std::vector <string> IMAPUtils::messageFlagList(const int flags) {
}
// static
const string IMAPUtils::searchDate(const vmime::datetime& date) {
std::ostringstream res;
res.imbue(std::locale::classic());
res << date.getDay();
res << '-';
res << IMAP_MONTH_NAMES[std::min(std::max(date.getMonth() - 1, 0), 11)];
res << '-';
res << date.getYear();
return res.str();
}
// static
const string IMAPUtils::dateTime(const vmime::datetime& date) {
@ -567,12 +589,7 @@ const string IMAPUtils::dateTime(const vmime::datetime& date) {
res << '-';
static const char* monthNames[12] = {
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
};
res << monthNames[std::min(std::max(date.getMonth() - 1, 0), 11)];
res << IMAP_MONTH_NAMES[std::min(std::max(date.getMonth() - 1, 0), 11)];
res << '-';

View File

@ -85,6 +85,13 @@ public:
static const std::vector <string> messageFlagList(const int flags);
/** Format a date to IMAP SEARCH date format (eg. 25-Nov-2021).
*
* @param date date to format
* @return IMAP SEARCH-formatted date
*/
static const string searchDate(const vmime::datetime& date);
/** Format a date/time to IMAP date/time format.
*
* @param date date/time to format

View File

@ -1355,21 +1355,7 @@ std::vector <size_t> maildirFolder::getMessageNumbersStartingOnUID(const message
throw exceptions::operation_not_supported();
}
std::vector <size_t> maildirFolder::getMessageNumbersMatchingSearchAttributes(
const searchAttributes&,
const vmime::charset*
) {
throw exceptions::operation_not_supported();
}
std::vector <message::uid> maildirFolder::getMessageUIDsMatchingSearchAttributes(
const searchAttributes&,
const vmime::charset*
) {
throw exceptions::operation_not_supported();
}
} // maildir
} // net

View File

@ -147,16 +147,6 @@ public:
std::vector <size_t> getMessageNumbersStartingOnUID(const message::uid& uid);
std::vector <size_t> getMessageNumbersMatchingSearchAttributes(
const searchAttributes& sa,
const vmime::charset* charset = nullptr
) override;
std::vector <message::uid> getMessageUIDsMatchingSearchAttributes(
const searchAttributes& sa,
const vmime::charset* charset = nullptr
) override;
private:
void scanFolder();

View File

@ -812,21 +812,6 @@ std::vector <size_t> POP3Folder::getMessageNumbersStartingOnUID(const message::u
throw exceptions::operation_not_supported();
}
std::vector <size_t> POP3Folder::getMessageNumbersMatchingSearchAttributes(
const searchAttributes&,
const vmime::charset*
) {
throw exceptions::operation_not_supported();
}
std::vector <message::uid> POP3Folder::getMessageUIDsMatchingSearchAttributes(
const searchAttributes&,
const vmime::charset*
) {
throw exceptions::operation_not_supported();
}
} // pop3
} // net

View File

@ -144,16 +144,6 @@ public:
std::vector <size_t> getMessageNumbersStartingOnUID(const message::uid& uid);
std::vector <size_t> getMessageNumbersMatchingSearchAttributes(
const searchAttributes& sa,
const vmime::charset* charset = nullptr
) override;
std::vector <message::uid> getMessageUIDsMatchingSearchAttributes(
const searchAttributes& sa,
const vmime::charset* charset = nullptr
) override;
private:
void registerMessage(POP3Message* msg);

View File

@ -1,440 +0,0 @@
#include "vmime/net/searchAttributes.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES
namespace vmime {
namespace net {
namespace helpers {
class keylessToken : public searchToken {
public:
keylessToken(const char* token)
: searchToken(token) {
}
void generate(std::ostringstream& out) const {
out << m_token;
}
};
template < class TYPE >
class typedSearchToken : public searchToken {
public:
typedSearchToken(const char* token, const TYPE& keyword)
: searchToken(token)
, m_keyword(keyword) {
}
typedSearchToken(const char* token, const TYPE&& keyword)
: searchToken(token)
, m_keyword(std::move(keyword)) {
}
protected:
TYPE m_keyword;
};
// Represents a string search token with the search string quoted
class stringToken : public typedSearchToken< string > {
public:
stringToken(const char* token, const string& keyword)
: typedSearchToken(token, keyword) {
}
void generate(std::ostringstream& out) const override {
out << m_token << " \"" << m_keyword << "\"";
};
};
class headerToken : public typedSearchToken< const char* > {
public:
headerToken(const char* token, const char* header)
: typedSearchToken(token, header) {
}
headerToken(const char* token, const char* header, const string& headerKeyword)
: typedSearchToken(token, header)
, m_headerKeyword(headerKeyword) {
}
void generate(std::ostringstream& out) const override {
out << m_token << " " << m_keyword << " \"" << m_headerKeyword << "\"";
};
protected:
string m_headerKeyword;
};
class dateToken : public typedSearchToken< vmime::datetime > {
public:
dateToken(const char* token, const vmime::datetime& date)
: typedSearchToken(token, date) {
}
// RFC claims that we need to disregard time information
void generate(std::ostringstream& out) const override {
out << m_token << " " << m_keyword.getDate();
};
};
class numberToken : public typedSearchToken< int > {
public:
numberToken(const char* token, uint32_t keyword)
: typedSearchToken(token, keyword) {
}
void generate(std::ostringstream& out) const override {
out << m_token << " " << m_keyword;
};
};
class flagToken : public typedSearchToken< vmime::net::message::Flags > {
public:
flagToken(const char* token, vmime::net::message::Flags keyword)
: typedSearchToken(token, keyword) {
}
void generate(std::ostringstream& out) const override {
out << m_token << " ";
switch (m_keyword) {
case vmime::net::message::Flags::FLAG_SEEN: out << "Seen"; break;
case vmime::net::message::Flags::FLAG_REPLIED: out << "Answered"; break;
case vmime::net::message::Flags::FLAG_MARKED: out << "Flagged"; break;
case vmime::net::message::Flags::FLAG_DRAFT: out << "Draft"; break;
case vmime::net::message::Flags::FLAG_DELETED: out << "Deleted"; break;
default: throw exceptions::operation_not_supported();
}
};
};
class tokenMessageSetEnumerator : public messageSetEnumerator {
public:
tokenMessageSetEnumerator()
: m_first(true) {
m_oss.imbue(std::locale::classic());
}
void enumerateNumberMessageRange(const vmime::net::numberMessageRange& range) {
if (!m_first) {
m_oss << ",";
}
if (range.getFirst() == range.getLast()) {
m_oss << range.getFirst();
} else if (range.getLast() == size_t(-1)) {
m_oss << range.getFirst() << ":*";
} else {
m_oss << range.getFirst() << ":" << range.getLast();
}
m_first = false;
}
void enumerateUIDMessageRange(const vmime::net::UIDMessageRange& range) {
if (!m_first) {
m_oss << ",";
}
if (range.getFirst() == range.getLast()) {
m_oss << range.getFirst();
} else if (range.getLast() == size_t(-1)) {
m_oss << range.getFirst() << ":*";
} else {
m_oss << range.getFirst() << ":" << range.getLast();
}
m_first = false;
}
const std::string str() const {
return m_oss.str();
}
private:
std::ostringstream m_oss;
bool m_first;
};
class messageSetToken : public typedSearchToken< vmime::net::messageSet > {
public:
messageSetToken(const char *token, const vmime::net::messageSet& keyword)
: typedSearchToken(token, keyword) {
}
messageSetToken(const char *token, const vmime::net::messageSet&& keyword)
: typedSearchToken(token, std::move(keyword)) {
}
void generate(std::ostringstream& out) const override {
if (*m_token) {
out << m_token << " (";
}
else {
out << "(";
}
tokenMessageSetEnumerator enu;
m_keyword.enumerate(enu);
out << enu.str();
out << ")";
}
};
// Contains a list of tokens which the server will interpret as AND
class tokenVectorToken : public typedSearchToken< std::vector< vmime::shared_ptr< const searchToken > > > {
public:
tokenVectorToken(const char* token, const std::vector< vmime::shared_ptr< const searchToken > >& tokensAndKeywords)
: typedSearchToken(token, tokensAndKeywords) {
if (0 == m_keyword.size()) {
throw exceptions::invalid_argument();
}
}
tokenVectorToken(const char* token, const std::vector< vmime::shared_ptr< const searchToken > >&& tokensAndKeywords)
: typedSearchToken(token, tokensAndKeywords) {
if (0 == m_keyword.size()) {
throw exceptions::invalid_argument();
}
}
void generate(std::ostringstream& out) const override {
out << m_token;
if (*m_token)
out << " (";
else
out << "(";
m_keyword[0]->generate(out);
for (size_t i = 1; i < m_keyword.size(); i++) {
out << " ";
m_keyword[i]->generate(out);
}
out << ")";
};
};
// A pair of tokens, used with OR
class tokenPairToken : public typedSearchToken< std::pair< vmime::shared_ptr< const searchToken >, vmime::shared_ptr< const searchToken > > > {
public:
tokenPairToken(const char* token, const std::pair< vmime::shared_ptr< const searchToken >, vmime::shared_ptr< const searchToken > >& pair)
: typedSearchToken(token, pair) {
}
void generate(std::ostringstream& out) const override {
out << m_token << " ";
m_keyword.first->generate(out);
out << " ";
m_keyword.second->generate(out);
};
};
} // namespace helpers
searchTokenPtr searchTokenFactory::AND(const std::vector< searchTokenPtr >&&keywords) {
return vmime::make_shared<helpers::tokenVectorToken>("", std::move(keywords));
}
searchTokenPtr searchTokenFactory::ANSWERED() {
return vmime::make_shared<helpers::keylessToken>("ANSWERED");
}
searchTokenPtr searchTokenFactory::BCC(const string& keyword) {
return vmime::make_shared<helpers::stringToken>("BCC", keyword);
}
searchTokenPtr searchTokenFactory::BEFORE(const datetime& keyword) {
return vmime::make_shared<helpers::dateToken>("BEFORE", keyword);
}
searchTokenPtr searchTokenFactory::BODY(const string& keyword) {
return vmime::make_shared<helpers::stringToken>("BODY", keyword);
}
searchTokenPtr searchTokenFactory::CC(const string& keyword) {
return vmime::make_shared<helpers::stringToken>("CC", keyword);
}
searchTokenPtr searchTokenFactory::DELETED() {
return vmime::make_shared<helpers::keylessToken>("DELETED");
}
searchTokenPtr searchTokenFactory::DRAFT() {
return vmime::make_shared<helpers::keylessToken>("DRAFT");
}
searchTokenPtr searchTokenFactory::FLAGGED() {
return vmime::make_shared<helpers::keylessToken>("FLAGGED");
}
searchTokenPtr searchTokenFactory::FROM(const string& keyword) {
return vmime::make_shared<helpers::stringToken>("FROM", keyword);
}
searchTokenPtr searchTokenFactory::HEADER(const char* fieldName) {
return vmime::make_shared<helpers::headerToken>("HEADER", fieldName);
}
searchTokenPtr searchTokenFactory::HEADER(const char* fieldName, const string& fieldContents) {
return vmime::make_shared<helpers::headerToken>("HEADER", fieldName, fieldContents);
}
searchTokenPtr searchTokenFactory::KEYWORD(vmime::net::message::Flags flag) {
return vmime::make_shared<helpers::flagToken>("KEYWORD", flag);
}
searchTokenPtr searchTokenFactory::LARGER(uint32_t size) {
return vmime::make_shared<helpers::numberToken>("LARGER", size);
}
searchTokenPtr searchTokenFactory::MESSAGESET(const vmime::net::messageSet& set) {
return vmime::make_shared<helpers::messageSetToken>("", set);
}
searchTokenPtr searchTokenFactory::MESSAGESET(const vmime::net::messageSet&& set) {
return vmime::make_shared<helpers::messageSetToken>("", std::move(set));
}
searchTokenPtr searchTokenFactory::NEW() {
return vmime::make_shared<helpers::keylessToken>("NEW");
}
searchTokenPtr searchTokenFactory::NOT(const searchTokenPtr& token) {
return vmime::make_shared<helpers::tokenVectorToken>("NOT", std::vector< vmime::shared_ptr< const searchToken > >({token}));
}
searchTokenPtr searchTokenFactory::OLD() {
return vmime::make_shared<helpers::keylessToken>("OLD");
}
searchTokenPtr searchTokenFactory::ON(const datetime& date) {
return vmime::make_shared<helpers::dateToken>("ON", date);
}
searchTokenPtr searchTokenFactory::OR(const searchTokenPtr& tokenA, const searchTokenPtr& tokenB) {
return vmime::make_shared<helpers::tokenPairToken>("OR", std::make_pair(tokenA, tokenB));
}
searchTokenPtr searchTokenFactory::RECENT() {
return vmime::make_shared<helpers::keylessToken>("RECENT");
}
searchTokenPtr searchTokenFactory::SEEN() {
return vmime::make_shared<helpers::keylessToken>("SEEN");
}
searchTokenPtr searchTokenFactory::SENTBEFORE(const datetime& date) {
return vmime::make_shared<helpers::dateToken>("SENTBEFORE", date);
}
searchTokenPtr searchTokenFactory::SENTON(const datetime& date) {
return vmime::make_shared<helpers::dateToken>("SENTON", date);
}
searchTokenPtr searchTokenFactory::SENTSINCE(const datetime& date) {
return vmime::make_shared<helpers::dateToken>("SENTSINCE", date);
}
searchTokenPtr searchTokenFactory::SINCE(const datetime& date) {
return vmime::make_shared<helpers::dateToken>("SINCE", date);
}
searchTokenPtr searchTokenFactory::SMALLER(uint32_t size) {
return vmime::make_shared<helpers::numberToken>("SMALLER", size);
}
searchTokenPtr searchTokenFactory::SUBJECT(const string& keyword) {
return vmime::make_shared<helpers::stringToken>("SUBJECT", keyword);
}
searchTokenPtr searchTokenFactory::TEXT(const string& keyword) {
return vmime::make_shared<helpers::stringToken>("TEXT", keyword);
}
searchTokenPtr searchTokenFactory::TO(const string& keyword) {
return vmime::make_shared<helpers::stringToken>("TO", keyword);
}
searchTokenPtr searchTokenFactory::UID(const vmime::net::messageSet& set) {
return vmime::make_shared<helpers::messageSetToken>("UID", set);
}
searchTokenPtr searchTokenFactory::UID(const vmime::net::messageSet&& set) {
return vmime::make_shared<helpers::messageSetToken>("UID", std::move(set));
}
searchTokenPtr searchTokenFactory::UNANSWERED() {
return vmime::make_shared<helpers::keylessToken>("UNANSWERED");
}
searchTokenPtr searchTokenFactory::UNDELETED() {
return vmime::make_shared<helpers::keylessToken>("UNDELETED");
}
searchTokenPtr searchTokenFactory::UNDRAFT() {
return vmime::make_shared<helpers::keylessToken>("UNDRAFT");
}
searchTokenPtr searchTokenFactory::UNFLAGGED() {
return vmime::make_shared<helpers::keylessToken>("UNFLAGGED");
}
searchTokenPtr searchTokenFactory::UNKEYWORD(vmime::net::message::Flags flag) {
return vmime::make_shared<helpers::flagToken>("UNKEYWORD", flag);
}
searchTokenPtr searchTokenFactory::UNSEEN() {
return vmime::make_shared<helpers::keylessToken>("UNSEEN");
}
searchAttributes::searchAttributes(std::vector< vmime::shared_ptr< const searchToken > >&& tokens)
: m_andTokens(std::move(tokens)) {
}
void searchAttributes::add(const vmime::shared_ptr< const searchToken >& token) {
m_andTokens.push_back(token);
}
std::vector< string > searchAttributes::generate() const {
std::vector< string > keys;
for (auto& token : m_andTokens) {
std::ostringstream key;
key.imbue(std::locale::classic());
token->generate(key);
keys.push_back(key.str());
}
return keys;
}
} // net
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES

View File

@ -1,139 +0,0 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 3 of
// the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License along
// with this program; if not, write to the Free Software Foundation, Inc.,
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
//
// Linking this library statically or dynamically with other modules is making
// a combined work based on this library. Thus, the terms and conditions of
// the GNU General Public License cover the whole combination.
//
#ifndef VMIME_NET_SEARCHATTRIBUTES_HPP_INCLUDED
#define VMIME_NET_SEARCHATTRIBUTES_HPP_INCLUDED
#include "vmime/config.hpp"
#if VMIME_HAVE_MESSAGING_FEATURES
#include <vector>
#include "vmime/types.hpp"
#include "vmime/utility/stringUtils.hpp"
#include "vmime/dateTime.hpp"
#include "vmime/net/message.hpp"
#include "vmime/net/messageSet.hpp"
namespace vmime {
namespace net {
class searchToken : public object {
public:
searchToken(const char* token)
: m_token(token) {
if (nullptr == m_token) {
throw exceptions::invalid_argument();
}
}
virtual void generate(std::ostringstream& out) const = 0;
protected:
const char* m_token;
};
typedef vmime::shared_ptr< const searchToken> searchTokenPtr;
class searchTokenFactory : public object {
public:
static searchTokenPtr AND(const std::vector< searchTokenPtr >&);
static searchTokenPtr AND(const std::vector< searchTokenPtr >&&);
static searchTokenPtr ANSWERED();
static searchTokenPtr BCC(const string&);
static searchTokenPtr BEFORE(const datetime&);
static searchTokenPtr BODY(const string&);
static searchTokenPtr CC(const string&);
static searchTokenPtr DELETED();
static searchTokenPtr DRAFT();
static searchTokenPtr FLAGGED();
static searchTokenPtr FROM(const string&);
static searchTokenPtr HEADER(const char* fieldName);
static searchTokenPtr HEADER(const char* filedName, const string& fieldContents);
static searchTokenPtr KEYWORD(vmime::net::message::Flags);
static searchTokenPtr LARGER(uint32_t);
static searchTokenPtr MESSAGESET(const vmime::net::messageSet&);
static searchTokenPtr MESSAGESET(const vmime::net::messageSet&&);
static searchTokenPtr NEW();
static searchTokenPtr NOT(const searchTokenPtr&);
static searchTokenPtr OLD();
static searchTokenPtr ON(const datetime&);
static searchTokenPtr OR(const searchTokenPtr&, const searchTokenPtr&);
static searchTokenPtr RECENT();
static searchTokenPtr SEEN();
static searchTokenPtr SENTBEFORE(const datetime&);
static searchTokenPtr SENTON(const datetime&);
static searchTokenPtr SENTSINCE(const datetime&);
static searchTokenPtr SINCE(const datetime&);
static searchTokenPtr SMALLER(uint32_t);
static searchTokenPtr SUBJECT(const string&);
static searchTokenPtr TEXT(const string&);
static searchTokenPtr TO(const string&);
static searchTokenPtr UID(const vmime::net::messageSet&);
static searchTokenPtr UID(const vmime::net::messageSet&&);
static searchTokenPtr UNANSWERED();
static searchTokenPtr UNDELETED();
static searchTokenPtr UNDRAFT();
static searchTokenPtr UNFLAGGED();
static searchTokenPtr UNKEYWORD(vmime::net::message::Flags);
static searchTokenPtr UNSEEN();
};
/** Holds a set of attributes to match messages against when searching folder contents.
*/
class VMIME_EXPORT searchAttributes : public object {
public:
searchAttributes() = default;
searchAttributes(std::vector< vmime::shared_ptr< const searchToken > >&&);
/** Adds a new search token that will be used to match messages against. Multiple tokens are
* treated as an AND operation.
*
* @param token the search token to add
*/
void add(const vmime::shared_ptr< const searchToken >& token);
std::vector< string > generate() const;
protected:
std::vector< vmime::shared_ptr< const searchToken > > m_andTokens;
};
} // net
} // vmime
#endif // VMIME_HAVE_MESSAGING_FEATURES
#endif // VMIME_NET_SEARCHATTRIBUTES_HPP_INCLUDED