예제 #1
0
void POP3Message::fetch(shared_ptr <POP3Folder> msgFolder, const fetchAttributes& options)
{
	shared_ptr <POP3Folder> folder = m_folder.lock();

	if (folder != msgFolder)
		throw exceptions::folder_not_found();

	// STRUCTURE and FLAGS attributes are not supported by POP3
	if (options.has(fetchAttributes::STRUCTURE | fetchAttributes::FLAGS))
		throw exceptions::operation_not_supported();

	// Check for the real need to fetch the full header
	static const int optionsRequiringHeader =
		fetchAttributes::ENVELOPE | fetchAttributes::CONTENT_INFO |
		fetchAttributes::FULL_HEADER | fetchAttributes::IMPORTANCE;

	if (!options.has(optionsRequiringHeader))
		return;

	// No need to differenciate between ENVELOPE, CONTENT_INFO, ...
	// since POP3 only permits to retrieve the whole header and not
	// fields in particular.

	// Emit the "TOP" command
	shared_ptr <POP3Store> store = folder->m_store.lock();

	POP3Command::TOP(m_num, 0)->send(store->getConnection());

	try
	{
		string buffer;
		utility::outputStreamStringAdapter bufferStream(buffer);

		POP3Response::readLargeResponse(store->getConnection(),
			bufferStream, /* progress */ NULL, /* predictedSize */ 0);

		m_header = make_shared <header>();
		m_header->parse(buffer);
	}
	catch (exceptions::command_error& e)
	{
		throw exceptions::command_error("TOP", e.response());
	}
}
예제 #2
0
void maildirMessage::fetch(shared_ptr <maildirFolder> msgFolder, const fetchAttributes& options)
{
	shared_ptr <maildirFolder> folder = m_folder.lock();

	if (folder != msgFolder)
		throw exceptions::folder_not_found();

	shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();

	const utility::file::path path = folder->getMessageFSPath(m_num);
	shared_ptr <utility::file> file = fsf->create(path);

	if (options.has(fetchAttributes::FLAGS))
		m_flags = maildirUtils::extractFlags(path.getLastComponent());

	if (options.has(fetchAttributes::SIZE))
		m_size = file->getLength();

	if (options.has(fetchAttributes::UID))
		m_uid = maildirUtils::extractId(path.getLastComponent()).getBuffer();

	if (options.has(fetchAttributes::ENVELOPE | fetchAttributes::CONTENT_INFO |
	                fetchAttributes::FULL_HEADER | fetchAttributes::STRUCTURE |
	                fetchAttributes::IMPORTANCE))
	{
		string contents;

		shared_ptr <utility::fileReader> reader = file->getFileReader();
		shared_ptr <utility::inputStream> is = reader->getInputStream();

		// Need whole message contents for structure
		if (options.has(fetchAttributes::STRUCTURE))
		{
			byte_t buffer[16384];

			contents.reserve(file->getLength());

			while (!is->eof())
			{
				const size_t read = is->read(buffer, sizeof(buffer));
				vmime::utility::stringUtils::appendBytesToString(contents, buffer, read);
			}
		}
		// Need only header
		else
		{
			byte_t buffer[1024];

			contents.reserve(4096);

			while (!is->eof())
			{
				const size_t read = is->read(buffer, sizeof(buffer));
				vmime::utility::stringUtils::appendBytesToString(contents, buffer, read);

				const size_t sep1 = contents.rfind("\r\n\r\n");
				const size_t sep2 = contents.rfind("\n\n");

				if (sep1 != string::npos)
				{
					contents.erase(contents.begin() + sep1 + 4, contents.end());
					break;
				}
				else if (sep2 != string::npos)
				{
					contents.erase(contents.begin() + sep2 + 2, contents.end());
					break;
				}
			}
		}

		vmime::message msg;
		msg.parse(contents);

		// Extract structure
		if (options.has(fetchAttributes::STRUCTURE))
		{
			m_structure = make_shared <maildirMessageStructure>(shared_ptr <maildirMessagePart>(), msg);
		}

		// Extract some header fields or whole header
		if (options.has(fetchAttributes::ENVELOPE |
		                fetchAttributes::CONTENT_INFO |
		                fetchAttributes::FULL_HEADER |
		                fetchAttributes::IMPORTANCE))
		{
			getOrCreateHeader()->copyFrom(*(msg.getHeader()));
		}
	}
}