📄 imapfolder.cpp
字号:
const string flagList = IMAPUtils::messageFlagList(flags); if (!flagList.empty()) { command << flagList; // 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"); } }}void IMAPFolder::addMessage(ref <vmime::message> msg, const int flags, vmime::datetime* date, utility::progressListener* progress){ std::ostringstream oss; utility::outputStreamAdapter ossAdapter(oss); msg->generate(ossAdapter); const std::string& str = oss.str(); utility::inputStreamStringAdapter strAdapter(str); addMessage(strAdapter, str.length(), flags, date, progress);}void IMAPFolder::addMessage(utility::inputStream& is, const int size, const int flags, vmime::datetime* date, 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"); 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 << "APPEND " << IMAPUtils::quoteString(IMAPUtils::pathToString (m_connection->hierarchySeparator(), getFullPath())) << ' '; const string flagList = IMAPUtils::messageFlagList(flags); if (flags != message::FLAG_UNDEFINED && !flagList.empty()) { command << flagList; command << ' '; } if (date != NULL) { command << IMAPUtils::dateTime(*date); command << ' '; } command << '{' << size << '}'; // Send the request m_connection->send(true, command.str(), true); // Get the response utility::auto_ptr <IMAPParser::response> resp(m_connection->readResponse()); bool ok = false; const std::vector <IMAPParser::continue_req_or_response_data*>& respList = resp->continue_req_or_response_data(); for (std::vector <IMAPParser::continue_req_or_response_data*>::const_iterator it = respList.begin() ; !ok && (it != respList.end()) ; ++it) { if ((*it)->continue_req()) ok = true; } if (!ok) { throw exceptions::command_error("APPEND", m_connection->getParser()->lastLine(), "bad response"); } // Send message data const int total = size; int current = 0; if (progress) progress->start(total); char buffer[65536]; while (!is.eof()) { // Read some data from the input stream const int read = is.read(buffer, sizeof(buffer)); current += read; // Put read data into socket output stream m_connection->sendRaw(buffer, read); // Notify progress if (progress) progress->progress(current, total); } m_connection->send(false, "", true); if (progress) progress->stop(total); // Get the response utility::auto_ptr <IMAPParser::response> finalResp(m_connection->readResponse()); if (finalResp->isBad() || finalResp->response_done()->response_tagged()-> resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("APPEND", m_connection->getParser()->lastLine(), "bad response"); } // Notify message added std::vector <int> nums; nums.push_back(m_messageCount + 1); events::messageCountEvent event (thisRef().dynamicCast <folder>(), events::messageCountEvent::TYPE_ADDED, nums); m_messageCount++; notifyMessageCount(event); // Notify folders with the same path for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ; it != store->m_folders.end() ; ++it) { if ((*it) != this && (*it)->getFullPath() == m_path) { events::messageCountEvent event ((*it)->thisRef().dynamicCast <folder>(), events::messageCountEvent::TYPE_ADDED, nums); (*it)->m_messageCount++; (*it)->notifyMessageCount(event); } }}void IMAPFolder::expunge(){ 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"); // Send the request m_connection->send(true, "EXPUNGE", 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("EXPUNGE", m_connection->getParser()->lastLine(), "bad response"); } // Update the numbering of the messages const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList = resp->continue_req_or_response_data(); std::vector <int> nums; 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("EXPUNGE", m_connection->getParser()->lastLine(), "invalid response"); } const IMAPParser::message_data* messageData = (*it)->response_data()->message_data(); // We are only interested in responses of type "EXPUNGE" if (messageData == NULL || messageData->type() != IMAPParser::message_data::EXPUNGE) { continue; } const int number = messageData->number(); nums.push_back(number); for (std::vector <IMAPMessage*>::iterator jt = m_messages.begin() ; jt != m_messages.end() ; ++jt) { if ((*jt)->m_num == number) (*jt)->m_expunged = true; else if ((*jt)->m_num > number) (*jt)->m_num--; } } m_messageCount -= nums.size(); // Notify message expunged events::messageCountEvent event (thisRef().dynamicCast <folder>(), events::messageCountEvent::TYPE_REMOVED, nums); notifyMessageCount(event); // Notify folders with the same path for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ; it != store->m_folders.end() ; ++it) { if ((*it) != this && (*it)->getFullPath() == m_path) { (*it)->m_messageCount = m_messageCount; events::messageCountEvent event ((*it)->thisRef().dynamicCast <folder>(), events::messageCountEvent::TYPE_REMOVED, nums); (*it)->notifyMessageCount(event); } }}void IMAPFolder::rename(const folder::path& newPath){ ref <IMAPStore> store = m_store.acquire(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (m_path.isEmpty() || newPath.isEmpty()) throw exceptions::illegal_operation("Cannot rename root folder"); else if (m_path.getSize() == 1 && m_name.getBuffer() == "INBOX") throw exceptions::illegal_operation("Cannot rename 'INBOX' folder"); else if (!store->isValidFolderName(newPath.getLastComponent())) throw exceptions::invalid_folder_name(); // Build the request text std::ostringstream command; command.imbue(std::locale::classic()); command << "RENAME "; command << IMAPUtils::quoteString(IMAPUtils::pathToString (m_connection->hierarchySeparator(), getFullPath())) << " "; command << IMAPUtils::quoteString(IMAPUtils::pathToString (m_connection->hierarchySeparator(), newPath)); // 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("RENAME", m_connection->getParser()->lastLine(), "bad response"); } // Notify folder renamed folder::path oldPath(m_path); m_path = newPath; m_name = newPath.getLastComponent(); events::folderEvent event (thisRef().dynamicCast <folder>(), events::folderEvent::TYPE_RENAMED, oldPath, newPath); notifyFolder(event); // Notify folders with the same path and sub-folders for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ; it != store->m_folders.end() ; ++it) { if ((*it) != this && (*it)->getFullPath() == oldPath) { (*it)->m_path = newPath; (*it)->m_name = newPath.getLastComponent(); events::folderEvent event ((*it)->thisRef().dynamicCast <folder>(), events::folderEvent::TYPE_RENAMED, oldPath, newPath); (*it)->notifyFolder(event); } else if ((*it) != this && oldPath.isParentOf((*it)->getFullPath())) { folder::path oldPath((*it)->m_path); (*it)->m_path.renameParent(oldPath, newPath); events::folderEvent event ((*it)->thisRef().dynamicCast <folder>(), events::folderEvent::TYPE_RENAMED, oldPath, (*it)->m_path); (*it)->notifyFolder(event); } }}void IMAPFolder::copyMessage(const folder::path& dest, 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"); // Construct set std::ostringstream set; set.imbue(std::locale::classic()); set << num; // Delegate message copy copyMessages(set.str(), dest); // Notify message count changed std::vector <int> nums; nums.push_back(num); for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ; it != store->m_folders.end() ; ++it) { if ((*it)->getFullPath() == dest) { events::messageCountEvent event ((*it)->thisRef().dynamicCast <folder>(), events::messageCountEvent::TYPE_ADDED, nums); (*it)->m_messageCount++; (*it)->notifyMessageCount(event); } }}void IMAPFolder::copyMessages(const folder::path& dest, const int from, const int to){ 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 (from < 1 || (to < from && to != -1)) throw exceptions::invalid_argument(); // Construct set std::ostringstream set; set.imbue(std::locale::classic()); if (to == -1) set << from << ":*"; else set << from << ":" << to; // Delegate message copy copyMessages(set.str(), dest); // Notify message count changed const int to2 = (to == -1) ? m_messageCount : to; const int count = to - from + 1; std::vector <int> nums; nums.resize(count); for (int i = from, j = 0 ; i <= to2 ; ++i, ++j) nums[j] = i; for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ; it != store->m_folders.end() ; ++it) { if ((*it)->getFullPath() == dest) { events::messageCountEvent event ((*it)->thisRef().dynamicCast <folder>(), events::messageCountEvent::TYPE_ADDED, nums); (*it)->m_messageCount += count; (*it)->notifyMessageCount(event); } }}void IMAPFolder::copyMessages(const folder::path& dest, const std::vector <int>& nums){ ref <IMAPStore> store = m_store.acquire(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); // Delegate message copy copyMessages(IMAPUtils::listToSet(nums, m_messageCount), dest); // Notify message count changed const int count = nums.size(); for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ; it != store->m_folders.end() ; ++it) { if ((*it)->getFullPath() == dest) { events::messageCountEvent event ((*it)->thisRef().dynamicCast <folder>(), events::messageCountEvent::TYPE_ADDED, nums); (*it)->m_messageCount += count; (*it)->notifyMessageCount(event); } }}void IMAPFolder::copyMessages(const string& set, const folder::path& dest){ // Build the request text std::ostringstream command; command.imbue(std::locale::classic()); command << "COPY " << set << " "; command << IMAPUtils::quoteString(IMAPUtils::pathToString (m_connection->hierarchySeparator(), dest)); // 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("COPY", m_connection->getParser()->lastLine(), "bad response"); }}void IMAPFolder::status(int& count, int& unseen){ ref <IMAPStore> store = m_store.acquire(); count = 0; unseen = 0; // Build the request text std::ostringstream command; command.imbue(std::locale::classic()); command << "STATUS "; command << IMAPUtils::quoteString(IMAPUtils::pathToString (m_connection->hierarchySeparator(), getFullPath())); command << " (MESSAGES UNSEEN)"; // 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("STATUS", m_connection->getParser()->lastLine(), "bad response"); } const std::vector <IMAPParser::continue_req_or_response_data*>& respDataList = resp->continue_req_or_response_data(); 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("STATUS", m_connection->getParser()->lastLine(), "invalid response"); } const IMAPParser::response_data* responseData = (*it)->response_data(); if (responseData->mailbox_data() && responseData->mailbox_data()->type() == IMAPParser::mailbox_data::STATUS) { const std::vector <IMAPParser::status_info*>& statusList = responseData->mailbox_data()->status_info_list(); for (std::vector <IMAPParser::status_info*>::const_iterator jt = statusList.begin() ; jt != statusList.end() ; ++jt) { switch ((*jt)->status_att()->type()) { case IMAPParser::status_att::MESSAGES: count = (*jt)->number()->value(); break; case IMAPParser::status_att::UNSEEN: unseen = (*jt)->number()->value(); break; default: break; } } } } // Notify message count changed (new messages) if (m_messageCount != count) { const int oldCount = m_messageCount; m_messageCount = count; if (count > oldCount) { std::vector <int> nums; nums.reserve(count - oldCount); for (int i = oldCount + 1, j = 0 ; i <= count ; ++i, ++j) nums[j] = i; events::messageCountEvent event (thisRef().dynamicCast <folder>(), events::messageCountEvent::TYPE_ADDED, nums); notifyMessageCount(event); // Notify folders with the same path for (std::list <IMAPFolder*>::iterator it = store->m_folders.begin() ; it != store->m_folders.end() ; ++it) { if ((*it) != this && (*it)->getFullPath() == m_path) { (*it)->m_messageCount = count; events::messageCountEvent event ((*it)->thisRef().dynamicCast <folder>(), events::messageCountEvent::TYPE_ADDED, nums); (*it)->notifyMessageCount(event); } } } }}} // imap} // net} // vmime
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -