⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imapfolder.cpp

📁 MIME解析的代码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//// VMime library (http://www.vmime.org)// Copyright (C) 2002-2008 Vincent Richard <vincent@vincent-richard.net>//// 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 2 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.//#include "vmime/net/imap/IMAPFolder.hpp"#include "vmime/net/imap/IMAPStore.hpp"#include "vmime/net/imap/IMAPParser.hpp"#include "vmime/net/imap/IMAPMessage.hpp"#include "vmime/net/imap/IMAPUtils.hpp"#include "vmime/net/imap/IMAPConnection.hpp"#include "vmime/message.hpp"#include "vmime/exception.hpp"#include "vmime/utility/smartPtr.hpp"#include <algorithm>#include <sstream>namespace vmime {namespace net {namespace imap {IMAPFolder::IMAPFolder(const folder::path& path, ref <IMAPStore> store, const int type, const int flags)	: m_store(store), m_connection(store->connection()), m_path(path),	  m_name(path.isEmpty() ? folder::path::component("") : path.getLastComponent()), m_mode(-1),	  m_open(false), m_type(type), m_flags(flags), m_messageCount(0), m_uidValidity(0){	store->registerFolder(this);}IMAPFolder::~IMAPFolder(){	ref <IMAPStore> store = m_store.acquire();	if (store)	{		if (m_open)			close(false);		store->unregisterFolder(this);	}	else if (m_open)	{		m_connection = NULL;		onClose();	}}int IMAPFolder::getMode() const{	if (!isOpen())		throw exceptions::illegal_state("Folder not open");	return (m_mode);}int IMAPFolder::getType(){	if (!isOpen())		throw exceptions::illegal_state("Folder not open");	// Root folder	if (m_path.isEmpty())	{		return (TYPE_CONTAINS_FOLDERS);	}	else	{		if (m_type == TYPE_UNDEFINED)			testExistAndGetType();		return (m_type);	}}int IMAPFolder::getFlags(){	if (!isOpen())		throw exceptions::illegal_state("Folder not open");	// Root folder	if (m_path.isEmpty())	{		return (FLAG_CHILDREN | FLAG_NO_OPEN);	}	else	{		if (m_flags == FLAG_UNDEFINED)			testExistAndGetType();		return (m_flags);	}}const folder::path::component IMAPFolder::getName() const{	return (m_name);}const folder::path IMAPFolder::getFullPath() const{	return (m_path);}void IMAPFolder::open(const int mode, bool failIfModeIsNotAvailable){	ref <IMAPStore> store = m_store.acquire();	if (!store)		throw exceptions::illegal_state("Store disconnected");	// Open a connection for this folder	ref <IMAPConnection> connection =		vmime::create <IMAPConnection>(store, store->getAuthenticator());	try	{		connection->connect();		// Emit the "SELECT" command		//		// Example:  C: A142 SELECT INBOX		//           S: * 172 EXISTS		//           S: * 1 RECENT		//           S: * OK [UNSEEN 12] Message 12 is first unseen		//           S: * OK [UIDVALIDITY 3857529045] UIDs valid		//           S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)		//           S: * OK [PERMANENTFLAGS (\Deleted \Seen \*)] Limited		//           S: A142 OK [READ-WRITE] SELECT completed		std::ostringstream oss;		if (mode == MODE_READ_ONLY)			oss << "EXAMINE ";		else			oss << "SELECT ";		oss << IMAPUtils::quoteString(IMAPUtils::pathToString				(connection->hierarchySeparator(), getFullPath()));		connection->send(true, oss.str(), true);		// Read the response		utility::auto_ptr <IMAPParser::response> resp(connection->readResponse());		if (resp->isBad() || resp->response_done()->response_tagged()->				resp_cond_state()->status() != IMAPParser::resp_cond_state::OK)		{			throw exceptions::command_error("SELECT",				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("SELECT",					connection->getParser()->lastLine(), "invalid response");			}			const IMAPParser::response_data* responseData = (*it)->response_data();			// OK Untagged responses: UNSEEN, PERMANENTFLAGS, UIDVALIDITY (optional)			if (responseData->resp_cond_state())			{				const IMAPParser::resp_text_code* code =					responseData->resp_cond_state()->resp_text()->resp_text_code();				if (code != NULL)				{					switch (code->type())					{					case IMAPParser::resp_text_code::UIDVALIDITY:						m_uidValidity = code->nz_number()->value();						break;					default:						break;					}				}			}			// Untagged responses: FLAGS, EXISTS, RECENT (required)			else if (responseData->mailbox_data())			{				switch (responseData->mailbox_data()->type())				{				default: break;				case IMAPParser::mailbox_data::FLAGS:				{					m_type = IMAPUtils::folderTypeFromFlags						(responseData->mailbox_data()->mailbox_flag_list());					m_flags = IMAPUtils::folderFlagsFromFlags						(responseData->mailbox_data()->mailbox_flag_list());					break;				}				case IMAPParser::mailbox_data::EXISTS:				{					m_messageCount = responseData->mailbox_data()->number()->value();					break;				}				case IMAPParser::mailbox_data::RECENT:				{					// TODO					break;				}				}			}		}		// Check for access mode (read-only or read-write)		const IMAPParser::resp_text_code* respTextCode = resp->response_done()->			response_tagged()->resp_cond_state()->resp_text()->resp_text_code();		if (respTextCode)		{			const int openMode =				(respTextCode->type() == IMAPParser::resp_text_code::READ_WRITE)					? MODE_READ_WRITE : MODE_READ_ONLY;			if (failIfModeIsNotAvailable &&			    mode == MODE_READ_WRITE && openMode == MODE_READ_ONLY)			{				throw exceptions::operation_not_supported();			}		}		m_connection = connection;		m_open = true;		m_mode = mode;	}	catch (std::exception&)	{		throw;	}}void IMAPFolder::close(const bool expunge){	ref <IMAPStore> store = m_store.acquire();	if (!store)		throw exceptions::illegal_state("Store disconnected");	if (!isOpen())		throw exceptions::illegal_state("Folder not open");	ref <IMAPConnection> oldConnection = m_connection;	// Emit the "CLOSE" command to expunge messages marked	// as deleted (this is fastest than "EXPUNGE")	if (expunge)	{		if (m_mode == MODE_READ_ONLY)			throw exceptions::operation_not_supported();		oldConnection->send(true, "CLOSE", true);	}	// Close this folder connection	oldConnection->disconnect();	// Now use default store connection	m_connection = m_store.acquire()->connection();	m_open = false;	m_mode = -1;	m_uidValidity = 0;	onClose();}void IMAPFolder::onClose(){	for (std::vector <IMAPMessage*>::iterator it = m_messages.begin() ;	     it != m_messages.end() ; ++it)	{		(*it)->onFolderClosed();	}	m_messages.clear();}void IMAPFolder::create(const int type){	ref <IMAPStore> store = m_store.acquire();	if (!store)		throw exceptions::illegal_state("Store disconnected");	else if (isOpen())		throw exceptions::illegal_state("Folder is open");	else if (exists())		throw exceptions::illegal_state("Folder already exists");	else if (!store->isValidFolderName(m_name))		throw exceptions::invalid_folder_name();	// Emit the "CREATE" command	//	// Example:   C: A003 CREATE owatagusiam/	//            S: A003 OK CREATE completed	//            C: A004 CREATE owatagusiam/blurdybloop	//            S: A004 OK CREATE completed	string mailbox = IMAPUtils::pathToString		(m_connection->hierarchySeparator(), getFullPath());	if (type & TYPE_CONTAINS_FOLDERS)		mailbox += m_connection->hierarchySeparator();	std::ostringstream oss;	oss << "CREATE " << IMAPUtils::quoteString(mailbox);	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("CREATE",			m_connection->getParser()->lastLine(), "bad response");	}	// Notify folder created	events::folderEvent event		(thisRef().dynamicCast <folder>(),		 events::folderEvent::TYPE_CREATED, m_path, m_path);	notifyFolder(event);}void IMAPFolder::destroy(){	ref <IMAPStore> store = m_store.acquire();	if (!store)		throw exceptions::illegal_state("Store disconnected");	if (isOpen())		throw exceptions::illegal_state("Folder is open");	const string mailbox = IMAPUtils::pathToString		(m_connection->hierarchySeparator(), getFullPath());	std::ostringstream oss;	oss << "DELETE " << IMAPUtils::quoteString(mailbox);	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("DELETE",			m_connection->getParser()->lastLine(), "bad response");	}	// Notify folder deleted	events::folderEvent event		(thisRef().dynamicCast <folder>(),		 events::folderEvent::TYPE_DELETED, m_path, m_path);	notifyFolder(event);}bool IMAPFolder::exists(){	ref <IMAPStore> store = m_store.acquire();	if (!isOpen() && !store)		throw exceptions::illegal_state("Store disconnected");	return (testExistAndGetType() != TYPE_UNDEFINED);}int IMAPFolder::testExistAndGetType(){	m_type = TYPE_UNDEFINED;	// To test whether a folder exists, we simple list it using	// the "LIST" command, and there should be one unique mailbox	// with this name...	//	// Eg. Test whether '/foo/bar' exists	//	//     C: a005 list "" foo/bar	//     S: * LIST (\NoSelect) "/" foo/bar	//     S: a005 OK LIST completed	//	// ==> OK, exists	//	// Test whether '/foo/bar/zap' exists	//	//     C: a005 list "" foo/bar/zap	//     S: a005 OK LIST completed	//	// ==> NO, does not exist	std::ostringstream oss;	oss << "LIST \"\" ";	oss << IMAPUtils::quoteString(IMAPUtils::pathToString		(m_connection->hierarchySeparator(), getFullPath()));	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");	}	// Check whether the result mailbox list contains this folder	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("LIST",				m_connection->getParser()->lastLine(), "invalid response");		}		const IMAPParser::mailbox_data* mailboxData =			(*it)->response_data()->mailbox_data();		// We are only interested in responses of type "LIST"		if (mailboxData != NULL && mailboxData->type() == IMAPParser::mailbox_data::LIST)		{			// Get the folder type/flags at the same time			m_type = IMAPUtils::folderTypeFromFlags				(mailboxData->mailbox_list()->mailbox_flag_list());			m_flags = IMAPUtils::folderFlagsFromFlags				(mailboxData->mailbox_list()->mailbox_flag_list());		}	}	return (m_type);}bool IMAPFolder::isOpen() const{	return (m_open);}ref <message> IMAPFolder::getMessage(const int num){	if (!isOpen())		throw exceptions::illegal_state("Folder not open");	if (num < 1 || num > m_messageCount)		throw exceptions::message_not_found();	return vmime::create <IMAPMessage>(thisRef().dynamicCast <IMAPFolder>(), num);}std::vector <ref <message> > IMAPFolder::getMessages(const int from, const int to){	const int messageCount = getMessageCount();	const int to2 = (to == -1 ? messageCount : to);	if (!isOpen())		throw exceptions::illegal_state("Folder not open");	else if (to2 < from || from < 1 || to2 < 1 || from > messageCount || to2 > messageCount)		throw exceptions::message_not_found();	std::vector <ref <message> > v;	ref <IMAPFolder> thisFolder = thisRef().dynamicCast <IMAPFolder>();	for (int i = from ; i <= to2 ; ++i)		v.push_back(vmime::create <IMAPMessage>(thisFolder, i));	return (v);}std::vector <ref <message> > IMAPFolder::getMessages(const std::vector <int>& nums){	if (!isOpen())		throw exceptions::illegal_state("Folder not open");	std::vector <ref <message> > v;	ref <IMAPFolder> thisFolder = thisRef().dynamicCast <IMAPFolder>();	for (std::vector <int>::const_iterator it = nums.begin() ; it != nums.end() ; ++it)		v.push_back(vmime::create <IMAPMessage>(thisFolder, *it));	return (v);}int IMAPFolder::getMessageCount(){	if (!isOpen())		throw exceptions::illegal_state("Folder not open");	return (m_messageCount);}ref <folder> IMAPFolder::getFolder(const folder::path::component& name){	ref <IMAPStore> store = m_store.acquire();	if (!store)		throw exceptions::illegal_state("Store disconnected");	return vmime::create <IMAPFolder>(m_path / name, store);}std::vector <ref <folder> > IMAPFolder::getFolders(const bool recursive){	ref <IMAPStore> store = m_store.acquire();	if (!isOpen() && !store)		throw exceptions::illegal_state("Store disconnected");	// Eg. List folders in '/foo/bar'	//	//     C: a005 list "foo/bar" *	//     S: * LIST (\NoSelect) "/" foo/bar	//     S: * LIST (\NoInferiors) "/" foo/bar/zap	//     S: a005 OK LIST completed	std::ostringstream oss;	oss << "LIST ";	const string pathString = IMAPUtils::pathToString		(m_connection->hierarchySeparator(), getFullPath());	if (recursive)	{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -