aboutsummaryrefslogtreecommitdiffstats
path: root/src/vmime/net/searchAttributes.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/vmime/net/searchAttributes.cpp')
-rw-r--r--src/vmime/net/searchAttributes.cpp440
1 files changed, 440 insertions, 0 deletions
diff --git a/src/vmime/net/searchAttributes.cpp b/src/vmime/net/searchAttributes.cpp
new file mode 100644
index 00000000..20639ae4
--- /dev/null
+++ b/src/vmime/net/searchAttributes.cpp
@@ -0,0 +1,440 @@
+#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