📄 maildirfolder.cpp
字号:
}void maildirFolder::copyMessageImpl(const utility::file::path& tmpDirPath, const utility::file::path& curDirPath, const utility::file::path::component& filename, utility::inputStream& is, const utility::stream::size_type size, utility::progressListener* progress){ utility::fileSystemFactory* fsf = platform::getHandler()->getFileSystemFactory(); ref <utility::file> file = fsf->create(tmpDirPath / filename); if (progress) progress->start(size); // First, write the message into 'tmp'... try { file->createFile(); ref <utility::fileWriter> fw = file->getFileWriter(); ref <utility::outputStream> os = fw->getOutputStream(); utility::stream::value_type buffer[65536]; utility::stream::size_type total = 0; while (!is.eof()) { const utility::stream::size_type read = is.read(buffer, sizeof(buffer)); if (read != 0) { os->write(buffer, read); total += read; } if (progress) progress->progress(total, size); } } catch (exception& e) { if (progress) progress->stop(size); // Delete temporary file try { ref <utility::file> file = fsf->create(tmpDirPath / filename); file->remove(); } catch (exceptions::filesystem_exception&) { // Ignore } throw exceptions::command_error("ADD", "", "", e); } // ...then, move it to 'cur' try { file->rename(curDirPath / filename); } catch (exception& e) { if (progress) progress->stop(size); // Delete temporary file try { ref <utility::file> file = fsf->create(tmpDirPath / filename); file->remove(); } catch (exceptions::filesystem_exception&) { // Ignore } throw exceptions::command_error("ADD", "", "", e); } if (progress) progress->stop(size);}void maildirFolder::copyMessage(const folder::path& dest, const int num){ ref <maildirStore> store = m_store.acquire(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); copyMessages(dest, num, num);}void maildirFolder::copyMessages(const folder::path& dest, const int from, const int to){ ref <maildirStore> 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 the list of message numbers 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; // Copy messages copyMessagesImpl(dest, nums);}void maildirFolder::copyMessages(const folder::path& dest, const std::vector <int>& nums){ ref <maildirStore> store = m_store.acquire(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); // Copy messages copyMessagesImpl(dest, nums);}void maildirFolder::copyMessagesImpl(const folder::path& dest, const std::vector <int>& nums){ ref <maildirStore> store = m_store.acquire(); utility::fileSystemFactory* fsf = platform::getHandler()->getFileSystemFactory(); utility::file::path curDirPath = store->getFormat()->folderPathToFileSystemPath (m_path, maildirFormat::CUR_DIRECTORY); utility::file::path destCurDirPath = store->getFormat()-> folderPathToFileSystemPath(dest, maildirFormat::CUR_DIRECTORY); utility::file::path destTmpDirPath = store->getFormat()-> folderPathToFileSystemPath(dest, maildirFormat::TMP_DIRECTORY); // Create destination directories try { ref <utility::file> destTmpDir = fsf->create(destTmpDirPath); destTmpDir->createDirectory(true); } catch (exceptions::filesystem_exception&) { // Don't throw now, it will fail later... } try { ref <utility::file> destCurDir = fsf->create(destCurDirPath); destCurDir->createDirectory(true); } catch (exceptions::filesystem_exception&) { // Don't throw now, it will fail later... } // Copy messages try { for (std::vector <int>::const_iterator it = nums.begin() ; it != nums.end() ; ++it) { const int num = *it; const messageInfos& msg = m_messageInfos[num - 1]; const int flags = maildirUtils::extractFlags(msg.path); const utility::file::path::component filename = maildirUtils::buildFilename(maildirUtils::generateId(), flags); ref <utility::file> file = fsf->create(curDirPath / msg.path); ref <utility::fileReader> fr = file->getFileReader(); ref <utility::inputStream> is = fr->getInputStream(); copyMessageImpl(destTmpDirPath, destCurDirPath, filename, *is, file->getLength(), NULL); } } catch (exception& e) { notifyMessagesCopied(dest); throw exceptions::command_error("COPY", "", "", e); } notifyMessagesCopied(dest);}void maildirFolder::notifyMessagesCopied(const folder::path& dest){ ref <maildirStore> store = m_store.acquire(); for (std::list <maildirFolder*>::iterator it = store->m_folders.begin() ; it != store->m_folders.end() ; ++it) { if ((*it) != this && (*it)->getFullPath() == dest) { // We only need to update the first folder we found as calling // status() will notify all the folders with the same path. int count, unseen; (*it)->status(count, unseen); return; } }}void maildirFolder::status(int& count, int& unseen){ ref <maildirStore> store = m_store.acquire(); const int oldCount = m_messageCount; scanFolder(); count = m_messageCount; unseen = m_unreadMessageCount; // Notify message count changed (new messages) 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 <maildirFolder*>::iterator it = store->m_folders.begin() ; it != store->m_folders.end() ; ++it) { if ((*it) != this && (*it)->getFullPath() == m_path) { (*it)->m_messageCount = m_messageCount; (*it)->m_unreadMessageCount = m_unreadMessageCount; (*it)->m_messageInfos.resize(m_messageInfos.size()); std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin()); events::messageCountEvent event ((*it)->thisRef().dynamicCast <folder>(), events::messageCountEvent::TYPE_ADDED, nums); (*it)->notifyMessageCount(event); } } }}void maildirFolder::expunge(){ ref <maildirStore> 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"); utility::fileSystemFactory* fsf = platform::getHandler()->getFileSystemFactory(); utility::file::path curDirPath = store->getFormat()-> folderPathToFileSystemPath(m_path, maildirFormat::CUR_DIRECTORY); std::vector <int> nums; int unreadCount = 0; for (int num = 1 ; num <= m_messageCount ; ++num) { messageInfos& infos = m_messageInfos[num - 1]; if (infos.type == messageInfos::TYPE_DELETED) { nums.push_back(num); for (std::vector <maildirMessage*>::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { if ((*it)->m_num == num) (*it)->m_expunged = true; else if ((*it)->m_num > num) (*it)->m_num--; } if (maildirUtils::extractFlags(infos.path) & message::FLAG_SEEN) ++unreadCount; // Delete file from file system try { ref <utility::file> file = fsf->create(curDirPath / infos.path); file->remove(); } catch (exceptions::filesystem_exception& e) { // Ignore (not important) } } } if (!nums.empty()) { for (int i = nums.size() - 1 ; i >= 0 ; --i) m_messageInfos.erase(m_messageInfos.begin() + i); } m_messageCount -= nums.size(); m_unreadMessageCount -= unreadCount; // 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 <maildirFolder*>::iterator it = store->m_folders.begin() ; it != store->m_folders.end() ; ++it) { if ((*it) != this && (*it)->getFullPath() == m_path) { (*it)->m_messageCount = m_messageCount; (*it)->m_unreadMessageCount = m_unreadMessageCount; (*it)->m_messageInfos.resize(m_messageInfos.size()); std::copy(m_messageInfos.begin(), m_messageInfos.end(), (*it)->m_messageInfos.begin()); events::messageCountEvent event ((*it)->thisRef().dynamicCast <folder>(), events::messageCountEvent::TYPE_REMOVED, nums); (*it)->notifyMessageCount(event); } }}ref <folder> maildirFolder::getParent(){ if (m_path.isEmpty()) return NULL; else return vmime::create <maildirFolder>(m_path.getParent(), m_store.acquire());}ref <const store> maildirFolder::getStore() const{ return m_store.acquire();}ref <store> maildirFolder::getStore(){ return m_store.acquire();}void maildirFolder::fetchMessages(std::vector <ref <message> >& msg, const int options, utility::progressListener* progress){ ref <maildirStore> store = m_store.acquire(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); const int total = msg.size(); int current = 0; if (progress) progress->start(total); ref <maildirFolder> thisFolder = thisRef().dynamicCast <maildirFolder>(); for (std::vector <ref <message> >::iterator it = msg.begin() ; it != msg.end() ; ++it) { (*it).dynamicCast <maildirMessage>()->fetch(thisFolder, options); if (progress) progress->progress(++current, total); } if (progress) progress->stop(total);}void maildirFolder::fetchMessage(ref <message> msg, const int options){ ref <maildirStore> store = m_store.acquire(); if (!store) throw exceptions::illegal_state("Store disconnected"); else if (!isOpen()) throw exceptions::illegal_state("Folder not open"); msg.dynamicCast <maildirMessage>()->fetch (thisRef().dynamicCast <maildirFolder>(), options);}int maildirFolder::getFetchCapabilities() const{ return (FETCH_ENVELOPE | FETCH_STRUCTURE | FETCH_CONTENT_INFO | FETCH_FLAGS | FETCH_SIZE | FETCH_FULL_HEADER | FETCH_UID | FETCH_IMPORTANCE);}const utility::file::path maildirFolder::getMessageFSPath(const int number) const{ utility::file::path curDirPath = m_store.acquire()->getFormat()-> folderPathToFileSystemPath(m_path, maildirFormat::CUR_DIRECTORY); return (curDirPath / m_messageInfos[number - 1].path);}} // maildir} // net} // vmime
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -