📄 imapfolder.cpp
字号:
oss << IMAPUtils::quoteString(pathString); oss << " *"; } else { if (pathString.empty()) // don't add sep for root folder oss << "\"\""; else oss << IMAPUtils::quoteString(pathString + m_connection->hierarchySeparator()); oss << " %"; } m_connection->send(true, oss.str(), true); utility::auto_ptr <IMAPParser::response> resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("LIST", m_connection->getParser()->lastLine(), "bad response"); } const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList = resp->continue_req_or_response_data(); std::vector <ref <folder> > v; for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator it = respDataList.begin() ; it != respDataList.end() ; ++it) { if ((*it)->response_data() == NULL) { throw exceptions::command_error("LIST", m_connection->getParser()->lastLine(), "invalid response"); } const IMAPParser::mailbox_data* mailboxData = (*it)->response_data()->mailbox_data(); if (mailboxData == NULL || mailboxData->type() != IMAPParser::mailbox_data::LIST) continue; // Get folder path const class IMAPParser::mailbox* mailbox = mailboxData->mailbox_list()->mailbox(); folder::path path = IMAPUtils::stringToPath (mailboxData->mailbox_list()->quoted_char(), mailbox->name()); if (recursive || m_path.isDirectParentOf(path)) { // Append folder to list const class IMAPParser::mailbox_flag_list* mailbox_flag_list = mailboxData->mailbox_list()->mailbox_flag_list(); v.push_back(vmime::create <IMAPFolder>(path, store, IMAPUtils::folderTypeFromFlags(mailbox_flag_list), IMAPUtils::folderFlagsFromFlags(mailbox_flag_list))); } } return (v);}void IMAPFolder::fetchMessages(std::vector <ref <message> >& msg, const int options, utility::progressListener* progress){ ref <IMAPStore> store = m_store.acquire(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); // Build message numbers list std::vector <int> list; list.reserve(msg.size()); std::map <int, ref <IMAPMessage> > numberToMsg; for (std::vector <ref <message> >::iterator it = msg.begin() ; it != msg.end() ; ++it) { list.push_back((*it)->getNumber()); numberToMsg[(*it)->getNumber()] = (*it).dynamicCast <IMAPMessage>(); } // Send the request const string command = IMAPUtils::buildFetchRequest(list, options); m_connection->send(true, command, true); // Get the response utility::auto_ptr <IMAPParser::response> resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("FETCH", m_connection->getParser()->lastLine(), "bad response"); } const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList = resp->continue_req_or_response_data(); const int total = msg.size(); int current = 0; if (progress) progress->start(total); try { for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator it = respDataList.begin() ; it != respDataList.end() ; ++it) { if ((*it)->response_data() == NULL) { throw exceptions::command_error("FETCH", m_connection->getParser()->lastLine(), "invalid response"); } const IMAPParser::message_data* messageData = (*it)->response_data()->message_data(); // We are only interested in responses of type "FETCH" if (messageData == NULL || messageData->type() != IMAPParser::message_data::FETCH) continue; // Process fetch response for this message const int num = static_cast <int>(messageData->number()); std::map <int, ref <IMAPMessage> >::iterator msg = numberToMsg.find(num); if (msg != numberToMsg.end()) { (*msg).second->processFetchResponse(options, messageData->msg_att()); if (progress) progress->progress(++current, total); } } } catch (...) { if (progress) progress->stop(total); throw; } if (progress) progress->stop(total);}void IMAPFolder::fetchMessage(ref <message> msg, const int options){ ref <IMAPStore> store = m_store.acquire(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); msg.dynamicCast <IMAPMessage>()->fetch(thisRef().dynamicCast <IMAPFolder>(), options);}int IMAPFolder::getFetchCapabilities() const{ return (FETCH_ENVELOPE | FETCH_CONTENT_INFO | FETCH_STRUCTURE | FETCH_FLAGS | FETCH_SIZE | FETCH_FULL_HEADER | FETCH_UID | FETCH_IMPORTANCE);}ref <folder> IMAPFolder::getParent(){ if (m_path.isEmpty()) return NULL; else return vmime::create <IMAPFolder>(m_path.getParent(), m_store.acquire());}ref <const store> IMAPFolder::getStore() const{ return m_store.acquire();}ref <store> IMAPFolder::getStore(){ return m_store.acquire();}void IMAPFolder::registerMessage(IMAPMessage* msg){ m_messages.push_back(msg);}void IMAPFolder::unregisterMessage(IMAPMessage* msg){ std::vector <IMAPMessage*>::iterator it = std::find(m_messages.begin(), m_messages.end(), msg); if (it != m_messages.end()) m_messages.erase(it);}void IMAPFolder::onStoreDisconnected(){ m_store = NULL;}void IMAPFolder::deleteMessage(const int num){ ref <IMAPStore> store = m_store.acquire(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); else if (m_mode == MODE_READ_ONLY) throw exceptions::illegal_state("Folder is read-only"); // Build the request text std::ostringstream command; command.imbue(std::locale::classic()); command << "STORE " << num << " +FLAGS.SILENT (\\Deleted)"; // Send the request m_connection->send(true, command.str(), true); // Get the response utility::auto_ptr <IMAPParser::response> resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("STORE", m_connection->getParser()->lastLine(), "bad response"); } // Update local flags for (std::vector <IMAPMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if ((*it)->getNumber() == num && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags |= message::FLAG_DELETED; } } // Notify message flags changed std::vector <int> nums; nums.push_back(num); events::messageChangedEvent event (thisRef().dynamicCast <folder>(), events::messageChangedEvent::TYPE_FLAGS, nums); notifyMessageChanged(event);}void IMAPFolder::deleteMessages(const int from, const int to){ ref <IMAPStore> store = m_store.acquire(); if (from < 1 || (to < from && to != -1)) throw exceptions::invalid_argument(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); else if (m_mode == MODE_READ_ONLY) throw exceptions::illegal_state("Folder is read-only"); // Build the request text std::ostringstream command; command.imbue(std::locale::classic()); command << "STORE " << from << ":"; if (to == -1) command << m_messageCount; else command << to; command << " +FLAGS.SILENT (\\Deleted)"; // Send the request m_connection->send(true, command.str(), true); // Get the response utility::auto_ptr <IMAPParser::response> resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("STORE", m_connection->getParser()->lastLine(), "bad response"); } // Update local flags const int to2 = (to == -1) ? m_messageCount : to; const int count = to - from + 1; for (std::vector <IMAPMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags |= message::FLAG_DELETED; } } // Notify message flags changed std::vector <int> nums; nums.resize(count); for (int i = from, j = 0 ; i <= to2 ; ++i, ++j) nums[j] = i; events::messageChangedEvent event (thisRef().dynamicCast <folder>(), events::messageChangedEvent::TYPE_FLAGS, nums); notifyMessageChanged(event);}void IMAPFolder::deleteMessages(const std::vector <int>& nums){ ref <IMAPStore> store = m_store.acquire(); if (nums.empty()) throw exceptions::invalid_argument(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); else if (m_mode == MODE_READ_ONLY) throw exceptions::illegal_state("Folder is read-only"); // Sort the list of message numbers std::vector <int> list; list.resize(nums.size()); std::copy(nums.begin(), nums.end(), list.begin()); std::sort(list.begin(), list.end()); // Build the request text std::ostringstream command; command.imbue(std::locale::classic()); command << "STORE "; command << IMAPUtils::listToSet(list, m_messageCount, true); command << " +FLAGS.SILENT (\\Deleted)"; // Send the request m_connection->send(true, command.str(), true); // Get the response utility::auto_ptr <IMAPParser::response> resp(m_connection->readResponse()); if (resp->isBad() || resp->response_done()->response_tagged()-> resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("STORE", m_connection->getParser()->lastLine(), "bad response"); } // Update local flags for (std::vector <IMAPMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if (std::binary_search(list.begin(), list.end(), (*it)->getNumber())) { if ((*it)->m_flags != message::FLAG_UNDEFINED) (*it)->m_flags |= message::FLAG_DELETED; } } // Notify message flags changed events::messageChangedEvent event (thisRef().dynamicCast <folder>(), events::messageChangedEvent::TYPE_FLAGS, list); notifyMessageChanged(event);}void IMAPFolder::setMessageFlags(const int from, const int to, const int flags, const int mode){ ref <IMAPStore> store = m_store.acquire(); if (from < 1 || (to < from && to != -1)) throw exceptions::invalid_argument(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); else if (m_mode == MODE_READ_ONLY) throw exceptions::illegal_state("Folder is read-only"); std::ostringstream oss; oss.imbue(std::locale::classic()); if (to == -1) oss << from << ":*"; else oss << from << ":" << to; setMessageFlags(oss.str(), flags, mode); // Update local flags const int to2 = (to == -1) ? m_messageCount : to; const int count = to - from + 1; switch (mode) { case message::FLAG_MODE_ADD: { for (std::vector <IMAPMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags |= flags; } } break; } case message::FLAG_MODE_REMOVE: { for (std::vector <IMAPMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags &= ~flags; } } break; } default: case message::FLAG_MODE_SET: { for (std::vector <IMAPMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags = flags; } } break; } } // Notify message flags changed std::vector <int> nums; nums.resize(count); for (int i = from, j = 0 ; i <= to2 ; ++i, ++j) nums[j] = i; events::messageChangedEvent event (thisRef().dynamicCast <folder>(), events::messageChangedEvent::TYPE_FLAGS, nums); notifyMessageChanged(event);}void IMAPFolder::setMessageFlags(const std::vector <int>& nums, const int flags, const int mode){ ref <IMAPStore> store = m_store.acquire(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); else if (m_mode == MODE_READ_ONLY) throw exceptions::illegal_state("Folder is read-only"); // Sort the list of message numbers std::vector <int> list; list.resize(nums.size()); std::copy(nums.begin(), nums.end(), list.begin()); std::sort(list.begin(), list.end()); // Delegates call setMessageFlags(IMAPUtils::listToSet(list, m_messageCount, true), flags, mode); // Update local flags switch (mode) { case message::FLAG_MODE_ADD: { for (std::vector <IMAPMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags |= flags; } } break; } case message::FLAG_MODE_REMOVE: { for (std::vector <IMAPMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags &= ~flags; } } break; } default: case message::FLAG_MODE_SET: { for (std::vector <IMAPMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags = flags; } } break; } } // Notify message flags changed events::messageChangedEvent event (thisRef().dynamicCast <folder>(), events::messageChangedEvent::TYPE_FLAGS, nums); notifyMessageChanged(event);}void IMAPFolder::setMessageFlags(const string& set, const int flags, const int mode){ // Build the request text std::ostringstream command; command.imbue(std::locale::classic()); command << "STORE " << set; switch (mode) { case message::FLAG_MODE_ADD: command << " +FLAGS.SILENT "; break; case message::FLAG_MODE_REMOVE: command << " -FLAGS.SILENT "; break; default: case message::FLAG_MODE_SET: command << " FLAGS.SILENT "; break; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -