changeset 998:1b1c09973721

upgrade package vmime to 0.9.1-svn-r551 Also added missing zlib dependency for test-vmime.exe. r551 merges our previously used patch. r547 | vincent-richard | 2010-05-18 15:52:27 +0200 (Tue, 18 May 2010) | 1 line Added helper function to construct parsed message from net message. Splitted IMAP source files. r548 | vincent-richard | 2010-05-20 11:57:51 +0200 (Thu, 20 May 2010) | 1 line Fixed type size. r549 | vincent-richard | 2010-05-20 12:00:19 +0200 (Thu, 20 May 2010) | 1 line Fixed unit tests build on OSX. r550 | vincent-richard | 2010-05-20 17:28:51 +0200 (Thu, 20 May 2010) | 1 line Fixed case-sensitive include. r551 | vincent-richard | 2010-05-21 08:01:33 +0200 (Fri, 21 May 2010) | 1 line Fixed missing #include.
author Mark Brand <mabrand@mabrand.nl>
date Fri, 21 May 2010 09:26:45 +0200
parents 4e37546b3877
children 6f07657ea028
files src/vmime-0.9.1-svn-r551-20100520.patch src/vmime-99999-fix-pthreads.patch src/vmime.mk
diffstat 3 files changed, 1338 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/vmime-0.9.1-svn-r551-20100520.patch	Fri May 21 09:26:45 2010 +0200
@@ -0,0 +1,1337 @@
+This file is part of mingw-cross-env.
+See doc/index.html for further information.
+
+diff -urN a/ChangeLog b/ChangeLog
+--- a/ChangeLog	2010-05-21 09:06:26.955934365 +0200
++++ b/ChangeLog	2010-05-21 09:07:53.363928193 +0200
+@@ -2,6 +2,11 @@
+ VERSION 0.9.1svn
+ ================
+ 
++2010-05-18  Vincent Richard  <vincent@vincent-richard.net>
++
++ * net/*: added helper function vmime::net::message::getParsedMessage()
++   to construct a RFC-822 parsed message from a net message.
++
+ 2009-09-06  Vincent Richard  <vincent@vincent-richard.net>
+ 
+  * Relicensed VMime under the GNU GPL license version 3. Dual licensing
+diff -urN a/SConstruct b/SConstruct
+--- a/SConstruct	2010-05-21 09:06:27.116428601 +0200
++++ b/SConstruct	2010-05-21 09:07:53.367948000 +0200
+@@ -261,6 +261,9 @@
+ 			'net/imap/IMAPMessage.cpp',      'net/imap/IMAPMessage.hpp',
+ 			'net/imap/IMAPTag.cpp',          'net/imap/IMAPTag.hpp',
+ 			'net/imap/IMAPUtils.cpp',        'net/imap/IMAPUtils.hpp',
++			'net/imap/IMAPMessagePartContentHandler.cpp', 'net/imap/IMAPMessagePartContentHandler.hpp',
++			'net/imap/IMAPStructure.cpp',    'net/imap/IMAPStructure.hpp',
++			'net/imap/IMAPPart.cpp',         'net/imap/IMAPPart.hpp',
+ 			'net/imap/IMAPParser.hpp',
+ 		]
+ 	],
+@@ -959,6 +962,10 @@
+ 		env = env.Clone()
+ 		env.Append(LIBS = ['cppunit', 'dl', packageVersionedGenericName + '-debug', 'pthread'])
+ 		env.Append(LIBPATH=['.'])
++
++		if sys.platform == "mac" or sys.platform == "darwin":
++			env.Append(LIBS = ['iconv', 'gcrypt'])
++
+ 		Default(
+ 			env.Program(
+ 				target = 'run-tests',
+diff -urN a/src/bodyPart.cpp b/src/bodyPart.cpp
+--- a/src/bodyPart.cpp	2010-05-21 09:06:26.964428162 +0200
++++ b/src/bodyPart.cpp	2010-05-21 09:07:53.367948000 +0200
+@@ -37,6 +37,15 @@
+ }
+ 
+ 
++bodyPart::bodyPart(weak_ref <vmime::bodyPart> parentPart)
++	: m_header(vmime::create <header>()),
++	  m_body(vmime::create <body>()),
++	  m_parent(parentPart)
++{
++	m_body->setParentPart(thisRef().dynamicCast <bodyPart>());
++}
++
++
+ void bodyPart::parse(const string& buffer, const string::size_type position,
+ 	const string::size_type end, string::size_type* newPosition)
+ {
+diff -urN a/src/headerField.cpp b/src/headerField.cpp
+--- a/src/headerField.cpp	2010-05-21 09:06:27.120433672 +0200
++++ b/src/headerField.cpp	2010-05-21 09:07:53.367948000 +0200
+@@ -300,7 +300,8 @@
+ {
+ 	std::vector <ref <const component> > list;
+ 
+-	list.push_back(m_value);
++	if (m_value)
++		list.push_back(m_value);
+ 
+ 	return (list);
+ }
+diff -urN a/src/net/imap/IMAPMessage.cpp b/src/net/imap/IMAPMessage.cpp
+--- a/src/net/imap/IMAPMessage.cpp	2010-05-21 09:06:26.984436060 +0200
++++ b/src/net/imap/IMAPMessage.cpp	2010-05-21 09:07:53.363928193 +0200
+@@ -27,6 +27,9 @@
+ #include "vmime/net/imap/IMAPStore.hpp"
+ #include "vmime/net/imap/IMAPConnection.hpp"
+ #include "vmime/net/imap/IMAPUtils.hpp"
++#include "vmime/net/imap/IMAPStructure.hpp"
++#include "vmime/net/imap/IMAPPart.hpp"
++#include "vmime/net/imap/IMAPMessagePartContentHandler.hpp"
+ 
+ #include <sstream>
+ #include <iterator>
+@@ -38,198 +41,6 @@
+ namespace imap {
+ 
+ 
+-//
+-// IMAPpart
+-//
+-
+-class IMAPstructure;
+-
+-class IMAPpart : public part
+-{
+-private:
+-
+-	friend class vmime::creator;
+-
+-	IMAPpart(ref <IMAPpart> parent, const int number, const IMAPParser::body_type_mpart* mpart);
+-	IMAPpart(ref <IMAPpart> parent, const int number, const IMAPParser::body_type_1part* part);
+-
+-public:
+-
+-	ref <const structure> getStructure() const;
+-	ref <structure> getStructure();
+-
+-	ref <const IMAPpart> getParent() const { return m_parent.acquire(); }
+-
+-	const mediaType& getType() const { return (m_mediaType); }
+-	int getSize() const { return (m_size); }
+-	int getNumber() const { return (m_number); }
+-
+-	ref <const header> getHeader() const
+-	{
+-		if (m_header == NULL)
+-			throw exceptions::unfetched_object();
+-		else
+-			return m_header;
+-	}
+-
+-
+-	static ref <IMAPpart> create
+-		(ref <IMAPpart> parent, const int number, const IMAPParser::body* body)
+-	{
+-		if (body->body_type_mpart())
+-		{
+-			ref <IMAPpart> part = vmime::create <IMAPpart>(parent, number, body->body_type_mpart());
+-			part->m_structure = vmime::create <IMAPstructure>(part, body->body_type_mpart()->list());
+-
+-			return part;
+-		}
+-		else
+-		{
+-			return vmime::create <IMAPpart>(parent, number, body->body_type_1part());
+-		}
+-	}
+-
+-
+-	header& getOrCreateHeader()
+-	{
+-		if (m_header != NULL)
+-			return (*m_header);
+-		else
+-			return (*(m_header = vmime::create <header>()));
+-	}
+-
+-private:
+-
+-	ref <IMAPstructure> m_structure;
+-	weak_ref <IMAPpart> m_parent;
+-	ref <header> m_header;
+-
+-	int m_number;
+-	int m_size;
+-	mediaType m_mediaType;
+-};
+-
+-
+-
+-//
+-// IMAPstructure
+-//
+-
+-class IMAPstructure : public structure
+-{
+-public:
+-
+-	IMAPstructure()
+-	{
+-	}
+-
+-	IMAPstructure(const IMAPParser::body* body)
+-	{
+-		m_parts.push_back(IMAPpart::create(NULL, 0, body));
+-	}
+-
+-	IMAPstructure(ref <IMAPpart> parent, const std::vector <IMAPParser::body*>& list)
+-	{
+-		int number = 0;
+-
+-		for (std::vector <IMAPParser::body*>::const_iterator
+-		     it = list.begin() ; it != list.end() ; ++it, ++number)
+-		{
+-			m_parts.push_back(IMAPpart::create(parent, number, *it));
+-		}
+-	}
+-
+-
+-	ref <const part> getPartAt(const int x) const
+-	{
+-		return m_parts[x];
+-	}
+-
+-	ref <part> getPartAt(const int x)
+-	{
+-		return m_parts[x];
+-	}
+-
+-	int getPartCount() const
+-	{
+-		return m_parts.size();
+-	}
+-
+-
+-	static ref <IMAPstructure> emptyStructure()
+-	{
+-		return (m_emptyStructure);
+-	}
+-
+-private:
+-
+-	static ref <IMAPstructure> m_emptyStructure;
+-
+-	std::vector <ref <IMAPpart> > m_parts;
+-};
+-
+-
+-ref <IMAPstructure> IMAPstructure::m_emptyStructure = vmime::create <IMAPstructure>();
+-
+-
+-
+-IMAPpart::IMAPpart(ref <IMAPpart> parent, const int number, const IMAPParser::body_type_mpart* mpart)
+-	: m_parent(parent), m_header(NULL), m_number(number), m_size(0)
+-{
+-	m_mediaType = vmime::mediaType
+-		("multipart", mpart->media_subtype()->value());
+-}
+-
+-
+-IMAPpart::IMAPpart(ref <IMAPpart> parent, const int number, const IMAPParser::body_type_1part* part)
+-	: m_parent(parent), m_header(NULL), m_number(number), m_size(0)
+-{
+-	if (part->body_type_text())
+-	{
+-		m_mediaType = vmime::mediaType
+-			("text", part->body_type_text()->
+-				media_text()->media_subtype()->value());
+-
+-		m_size = part->body_type_text()->body_fields()->body_fld_octets()->value();
+-	}
+-	else if (part->body_type_msg())
+-	{
+-		m_mediaType = vmime::mediaType
+-			("message", part->body_type_msg()->
+-				media_message()->media_subtype()->value());
+-	}
+-	else
+-	{
+-		m_mediaType = vmime::mediaType
+-			(part->body_type_basic()->media_basic()->media_type()->value(),
+-			 part->body_type_basic()->media_basic()->media_subtype()->value());
+-
+-		m_size = part->body_type_basic()->body_fields()->body_fld_octets()->value();
+-	}
+-
+-	m_structure = NULL;
+-}
+-
+-
+-ref <const structure> IMAPpart::getStructure() const
+-{
+-	if (m_structure != NULL)
+-		return (m_structure);
+-	else
+-		return (IMAPstructure::emptyStructure());
+-}
+-
+-
+-ref <structure> IMAPpart::getStructure()
+-{
+-	if (m_structure != NULL)
+-		return (m_structure);
+-	else
+-		return (IMAPstructure::emptyStructure());
+-}
+-
+-
+-
+ #ifndef VMIME_BUILDING_DOC
+ 
+ //
+@@ -400,7 +211,22 @@
+ 
+ 	extract(p, ossAdapter, NULL, 0, -1, true, true);
+ 
+-	p.dynamicCast <IMAPpart>()->getOrCreateHeader().parse(oss.str());
++	p.dynamicCast <IMAPPart>()->getOrCreateHeader().parse(oss.str());
++}
++
++
++void IMAPMessage::fetchPartHeaderForStructure(ref <structure> str)
++{
++	for (int i = 0, n = str->getPartCount() ; i < n ; ++i)
++	{
++		ref <class part> part = str->getPartAt(i);
++
++		// Fetch header of current part
++		fetchPartHeader(part);
++
++		// Fetch header of sub-parts
++		fetchPartHeaderForStructure(part->getStructure());
++	}
+ }
+ 
+ 
+@@ -418,7 +244,7 @@
+ 
+ 	if (p != NULL)
+ 	{
+-		ref <const IMAPpart> currentPart = p.dynamicCast <const IMAPpart>();
++		ref <const IMAPPart> currentPart = p.dynamicCast <const IMAPPart>();
+ 		std::vector <int> numbers;
+ 
+ 		numbers.push_back(currentPart->getNumber());
+@@ -446,8 +272,17 @@
+ 	command << "FETCH " << m_num << " BODY";
+ 	if (peek) command << ".PEEK";
+ 	command << "[";
+-	command << section.str();
+-	if (headerOnly) command << ".MIME";   // "MIME" not "HEADER" for parts
++
++	if (section.str().empty() && headerOnly)
++	{
++		command << "HEADER";
++	}
++	else
++	{
++		command << section.str();
++		if (headerOnly) command << ".MIME";   // "MIME" not "HEADER" for parts
++	}
++
+ 	command << "]";
+ 
+ 	if (start != 0 || length != -1)
+@@ -621,7 +456,7 @@
+ 		}
+ 		case IMAPParser::msg_att_item::BODY_STRUCTURE:
+ 		{
+-			m_structure = vmime::create <IMAPstructure>((*it)->body());
++			m_structure = vmime::create <IMAPStructure>((*it)->body());
+ 			break;
+ 		}
+ 		case IMAPParser::msg_att_item::RFC822_HEADER:
+@@ -796,6 +631,80 @@
+ }
+ 
+ 
++void IMAPMessage::constructParsedMessage(ref <bodyPart> parentPart, ref <structure> str, int level)
++{
++	if (level == 0)
++	{
++		ref <class part> part = str->getPartAt(0);
++
++		// Copy header
++		ref <const header> hdr = part->getHeader();
++		parentPart->getHeader()->copyFrom(*hdr);
++
++		// Initialize body
++		parentPart->getBody()->setContents
++			(vmime::create <IMAPMessagePartContentHandler>
++				(thisRef().dynamicCast <IMAPMessage>(),
++				 part, parentPart->getBody()->getEncoding()));
++
++		constructParsedMessage(parentPart, part->getStructure(), 1);
++	}
++	else
++	{
++		for (int i = 0, n = str->getPartCount() ; i < n ; ++i)
++		{
++			ref <class part> part = str->getPartAt(i);
++
++			ref <bodyPart> childPart = vmime::create <bodyPart>();
++
++			// Copy header
++			ref <const header> hdr = part->getHeader();
++			childPart->getHeader()->copyFrom(*hdr);
++
++			// Initialize body
++			childPart->getBody()->setContents
++				(vmime::create <IMAPMessagePartContentHandler>
++					(thisRef().dynamicCast <IMAPMessage>(),
++					 part, childPart->getBody()->getEncoding()));
++
++			// Add child part
++			parentPart->getBody()->appendPart(childPart);
++
++			// Construct sub parts
++			constructParsedMessage(childPart, part->getStructure(), ++level);
++		}
++	}
++}
++
++
++ref <vmime::message> IMAPMessage::getParsedMessage()
++{
++	// Fetch structure
++	ref <structure> structure = NULL;
++
++	try
++	{
++		structure = getStructure();
++	}
++	catch (exceptions::unfetched_object&)
++	{
++		fetch(m_folder.acquire(), IMAPFolder::FETCH_STRUCTURE);
++		structure = getStructure();
++	}
++
++	// Fetch header for each part
++	fetchPartHeaderForStructure(structure);
++
++	// Construct message from structure
++	ref <vmime::message> msg = vmime::create <vmime::message>();
++
++	constructParsedMessage(msg, structure);
++
++	return msg;
++}
++
++
+ } // imap
+ } // net
+ } // vmime
++
+diff -urN a/src/net/imap/IMAPMessagePartContentHandler.cpp b/src/net/imap/IMAPMessagePartContentHandler.cpp
+--- a/src/net/imap/IMAPMessagePartContentHandler.cpp	1970-01-01 01:00:00.000000000 +0100
++++ b/src/net/imap/IMAPMessagePartContentHandler.cpp	2010-05-21 09:07:53.363928193 +0200
+@@ -0,0 +1,179 @@
++//
++// VMime library (http://www.vmime.org)
++// Copyright (C) 2002-2009 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 3 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/IMAPMessagePartContentHandler.hpp"
++
++
++namespace vmime {
++namespace net {
++namespace imap {
++
++
++IMAPMessagePartContentHandler::IMAPMessagePartContentHandler
++	(ref <IMAPMessage> msg, ref <class part> part, const vmime::encoding& encoding)
++	: m_message(msg), m_part(part), m_encoding(encoding)
++{
++}
++
++
++ref <contentHandler> IMAPMessagePartContentHandler::clone() const
++{
++	return create <IMAPMessagePartContentHandler>
++		(m_message.acquire().constCast <IMAPMessage>(),
++		 m_part.acquire().constCast <part>(),
++		 m_encoding);
++}
++
++
++void IMAPMessagePartContentHandler::generate
++	(utility::outputStream& os, const vmime::encoding& enc, const string::size_type maxLineLength) const
++{
++	ref <IMAPMessage> msg = m_message.acquire().constCast <IMAPMessage>();
++	ref <part> part = m_part.acquire().constCast <class part>();
++
++	// Data is already encoded
++	if (isEncoded())
++	{
++		// The data is already encoded but the encoding specified for
++		// the generation is different from the current one. We need
++		// to re-encode data: decode from input buffer to temporary
++		// buffer, and then re-encode to output stream...
++		if (m_encoding != enc)
++		{
++			// Extract part contents to temporary buffer
++			std::ostringstream oss;
++			utility::outputStreamAdapter tmp(oss);
++
++			msg->extractPart(part, tmp, NULL);
++
++			// Decode to another temporary buffer
++			utility::inputStreamStringProxyAdapter in(oss.str());
++
++			std::ostringstream oss2;
++			utility::outputStreamAdapter tmp2(oss2);
++
++			ref <utility::encoder::encoder> theDecoder = m_encoding.getEncoder();
++			theDecoder->decode(in, tmp2);
++
++			// Reencode to output stream
++			string str = oss2.str();
++			utility::inputStreamStringAdapter tempIn(str);
++
++			ref <utility::encoder::encoder> theEncoder = enc.getEncoder();
++			theEncoder->getProperties()["maxlinelength"] = maxLineLength;
++			theEncoder->encode(tempIn, os);
++		}
++		// No encoding to perform
++		else
++		{
++			msg->extractPart(part, os);
++		}
++	}
++	// Need to encode data before
++	else
++	{
++		// Extract part contents to temporary buffer
++		std::ostringstream oss;
++		utility::outputStreamAdapter tmp(oss);
++
++		msg->extractPart(part, tmp, NULL);
++
++		// Encode temporary buffer to output stream
++		ref <utility::encoder::encoder> theEncoder = enc.getEncoder();
++		theEncoder->getProperties()["maxlinelength"] = maxLineLength;
++
++		utility::inputStreamStringAdapter is(oss.str());
++
++		theEncoder->encode(is, os);
++	}
++}
++
++
++void IMAPMessagePartContentHandler::extract
++	(utility::outputStream& os, utility::progressListener* progress) const
++{
++	ref <IMAPMessage> msg = m_message.acquire().constCast <IMAPMessage>();
++	ref <part> part = m_part.acquire().constCast <class part>();
++
++	// No decoding to perform
++	if (!isEncoded())
++	{
++		msg->extractPart(part, os, progress);
++	}
++	// Need to decode data
++	else
++	{
++		// Extract part contents to temporary buffer
++		std::ostringstream oss;
++		utility::outputStreamAdapter tmp(oss);
++
++		msg->extractPart(part, tmp, NULL);
++
++		// Encode temporary buffer to output stream
++		utility::inputStreamStringAdapter is(oss.str());
++		utility::progressListenerSizeAdapter plsa(progress, getLength());
++
++		ref <utility::encoder::encoder> theDecoder = m_encoding.getEncoder();
++		theDecoder->decode(is, os, &plsa);
++	}
++}
++
++
++void IMAPMessagePartContentHandler::extractRaw
++	(utility::outputStream& os, utility::progressListener* progress) const
++{
++	ref <IMAPMessage> msg = m_message.acquire().constCast <IMAPMessage>();
++	ref <part> part = m_part.acquire().constCast <class part>();
++
++	msg->extractPart(part, os, progress);
++}
++
++
++string::size_type IMAPMessagePartContentHandler::getLength() const
++{
++	return m_part.acquire()->getSize();
++}
++
++
++bool IMAPMessagePartContentHandler::isEncoded() const
++{
++	return m_encoding != NO_ENCODING;
++}
++
++
++const vmime::encoding& IMAPMessagePartContentHandler::getEncoding() const
++{
++	return m_encoding;
++}
++
++
++bool IMAPMessagePartContentHandler::isEmpty() const
++{
++	return getLength() == 0;
++}
++
++
++} // imap
++} // net
++} // vmime
++
+diff -urN a/src/net/imap/IMAPPart.cpp b/src/net/imap/IMAPPart.cpp
+--- a/src/net/imap/IMAPPart.cpp	1970-01-01 01:00:00.000000000 +0100
++++ b/src/net/imap/IMAPPart.cpp	2010-05-21 09:07:53.367948000 +0200
+@@ -0,0 +1,152 @@
++//
++// VMime library (http://www.vmime.org)
++// Copyright (C) 2002-2009 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 3 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/IMAPPart.hpp"
++#include "vmime/net/imap/IMAPStructure.hpp"
++
++
++namespace vmime {
++namespace net {
++namespace imap {
++
++
++IMAPPart::IMAPPart(ref <IMAPPart> parent, const int number, const IMAPParser::body_type_mpart* mpart)
++	: m_parent(parent), m_header(NULL), m_number(number), m_size(0)
++{
++	m_mediaType = vmime::mediaType
++		("multipart", mpart->media_subtype()->value());
++}
++
++
++IMAPPart::IMAPPart(ref <IMAPPart> parent, const int number, const IMAPParser::body_type_1part* part)
++	: m_parent(parent), m_header(NULL), m_number(number), m_size(0)
++{
++	if (part->body_type_text())
++	{
++		m_mediaType = vmime::mediaType
++			("text", part->body_type_text()->
++				media_text()->media_subtype()->value());
++
++		m_size = part->body_type_text()->body_fields()->body_fld_octets()->value();
++	}
++	else if (part->body_type_msg())
++	{
++		m_mediaType = vmime::mediaType
++			("message", part->body_type_msg()->
++				media_message()->media_subtype()->value());
++	}
++	else
++	{
++		m_mediaType = vmime::mediaType
++			(part->body_type_basic()->media_basic()->media_type()->value(),
++			 part->body_type_basic()->media_basic()->media_subtype()->value());
++
++		m_size = part->body_type_basic()->body_fields()->body_fld_octets()->value();
++	}
++
++	m_structure = NULL;
++}
++
++
++ref <const structure> IMAPPart::getStructure() const
++{
++	if (m_structure != NULL)
++		return m_structure;
++	else
++		return IMAPStructure::emptyStructure();
++}
++
++
++ref <structure> IMAPPart::getStructure()
++{
++	if (m_structure != NULL)
++		return m_structure;
++	else
++		return IMAPStructure::emptyStructure();
++}
++
++
++ref <const IMAPPart> IMAPPart::getParent() const
++{
++	return m_parent.acquire();
++}
++
++
++const mediaType& IMAPPart::getType() const
++{
++	return m_mediaType;
++}
++
++
++int IMAPPart::getSize() const
++{
++	return m_size;
++}
++
++
++int IMAPPart::getNumber() const
++{
++	return m_number;
++}
++
++
++ref <const header> IMAPPart::getHeader() const
++{
++	if (m_header == NULL)
++		throw exceptions::unfetched_object();
++	else
++		return m_header;
++}
++
++
++// static
++ref <IMAPPart> IMAPPart::create
++	(ref <IMAPPart> parent, const int number, const IMAPParser::body* body)
++{
++	if (body->body_type_mpart())
++	{
++		ref <IMAPPart> part = vmime::create <IMAPPart>(parent, number, body->body_type_mpart());
++		part->m_structure = vmime::create <IMAPStructure>(part, body->body_type_mpart()->list());
++
++		return part;
++	}
++	else
++	{
++		return vmime::create <IMAPPart>(parent, number, body->body_type_1part());
++	}
++}
++
++
++header& IMAPPart::getOrCreateHeader()
++{
++	if (m_header != NULL)
++		return *m_header;
++	else
++		return *(m_header = vmime::create <header>());
++}
++
++
++} // imap
++} // net
++} // vmime
++
+diff -urN a/src/net/imap/IMAPStructure.cpp b/src/net/imap/IMAPStructure.cpp
+--- a/src/net/imap/IMAPStructure.cpp	1970-01-01 01:00:00.000000000 +0100
++++ b/src/net/imap/IMAPStructure.cpp	2010-05-21 09:07:53.363928193 +0200
+@@ -0,0 +1,85 @@
++//
++// VMime library (http://www.vmime.org)
++// Copyright (C) 2002-2009 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 3 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/IMAPStructure.hpp"
++#include "vmime/net/imap/IMAPPart.hpp"
++
++
++namespace vmime {
++namespace net {
++namespace imap {
++
++
++IMAPStructure::IMAPStructure()
++{
++}
++
++
++IMAPStructure::IMAPStructure(const IMAPParser::body* body)
++{
++	m_parts.push_back(IMAPPart::create(NULL, 0, body));
++}
++
++
++IMAPStructure::IMAPStructure(ref <IMAPPart> parent, const std::vector <IMAPParser::body*>& list)
++{
++	int number = 0;
++
++	for (std::vector <IMAPParser::body*>::const_iterator
++	     it = list.begin() ; it != list.end() ; ++it, ++number)
++	{
++		m_parts.push_back(IMAPPart::create(parent, number, *it));
++	}
++}
++
++
++ref <const part> IMAPStructure::getPartAt(const int x) const
++{
++	return m_parts[x];
++}
++
++
++ref <part> IMAPStructure::getPartAt(const int x)
++{
++	return m_parts[x];
++}
++
++
++int IMAPStructure::getPartCount() const
++{
++	return m_parts.size();
++}
++
++
++// static
++ref <IMAPStructure> IMAPStructure::emptyStructure()
++{
++	static ref <IMAPStructure> emptyStructure = vmime::create <IMAPStructure>();
++	return emptyStructure;
++}
++
++
++} // imap
++} // net
++} // vmime
++
+diff -urN a/src/net/maildir/maildirMessage.cpp b/src/net/maildir/maildirMessage.cpp
+--- a/src/net/maildir/maildirMessage.cpp	2010-05-21 09:06:26.988432541 +0200
++++ b/src/net/maildir/maildirMessage.cpp	2010-05-21 09:07:53.363928193 +0200
+@@ -524,6 +524,20 @@
+ }
+ 
+ 
++ref <vmime::message> maildirMessage::getParsedMessage()
++{
++	std::ostringstream oss;
++	utility::outputStreamAdapter os(oss);
++
++	extract(os);
++
++	vmime::ref <vmime::message> msg = vmime::create <vmime::message>();
++	msg->parse(oss.str());
++
++	return msg;
++}
++
++
+ } // maildir
+ } // net
+ } // vmime
+diff -urN a/src/net/pop3/POP3Message.cpp b/src/net/pop3/POP3Message.cpp
+--- a/src/net/pop3/POP3Message.cpp	2010-05-21 09:06:26.991933216 +0200
++++ b/src/net/pop3/POP3Message.cpp	2010-05-21 09:07:53.363928193 +0200
+@@ -218,6 +218,20 @@
+ }
+ 
+ 
++ref <vmime::message> POP3Message::getParsedMessage()
++{
++	std::ostringstream oss;
++	utility::outputStreamAdapter os(oss);
++
++	extract(os);
++
++	vmime::ref <vmime::message> msg = vmime::create <vmime::message>();
++	msg->parse(oss.str());
++
++	return msg;
++}
++
++
+ } // pop3
+ } // net
+ } // vmime
+diff -urN a/src/net/tls/TLSSession.cpp b/src/net/tls/TLSSession.cpp
+--- a/src/net/tls/TLSSession.cpp	2010-05-21 09:06:26.999930787 +0200
++++ b/src/net/tls/TLSSession.cpp	2010-05-21 09:07:53.367948000 +0200
+@@ -27,6 +27,7 @@
+ #include "vmime/config.hpp"
+ 
+ #if VMIME_HAVE_PTHREAD
++#	include <pthread.h>
+ #	include <gcrypt.h>
+ #	include <errno.h>
+ #endif // VMIME_HAVE_PTHREAD
+diff -urN a/src/security/digest/sha1/sha1MessageDigest.cpp b/src/security/digest/sha1/sha1MessageDigest.cpp
+--- a/src/security/digest/sha1/sha1MessageDigest.cpp	2010-05-21 09:06:27.012432100 +0200
++++ b/src/security/digest/sha1/sha1MessageDigest.cpp	2010-05-21 09:07:53.367948000 +0200
+@@ -135,7 +135,7 @@
+ 
+ void sha1MessageDigest::finalize()
+ {
+-	unsigned long i, j;
++	unsigned int i, j;
+ 	unsigned char finalcount[8];
+ 
+ 	for (i = 0 ; i < 8 ; i++)
+@@ -162,8 +162,8 @@
+ 	i = j = 0;
+ 
+ 	std::memset(m_buffer, 0, 64);
+-	std::memset(m_state, 0, 5 * sizeof(unsigned long));
+-	std::memset(m_count, 0, 2 * sizeof(unsigned long));
++	std::memset(m_state, 0, 5 * sizeof(unsigned int));
++	std::memset(m_count, 0, 2 * sizeof(unsigned int));
+ 	std::memset(&finalcount, 0, 8);
+ }
+ 
+@@ -192,17 +192,17 @@
+   * This is the core of the algorithm.
+   */
+ void sha1MessageDigest::transform
+-	(unsigned long state[5], const unsigned char buffer[64])
++	(unsigned int state[5], const unsigned char buffer[64])
+ {
+-	unsigned long a, b, c, d, e;
++	unsigned int a, b, c, d, e;
+ 
+ 	typedef union
+ 	{
+ 		unsigned char c[64];
+-		unsigned long l[16];
++		unsigned int l[16];
+ 	} CHAR64LONG16;
+ 
+-	assert(sizeof(unsigned long) == 4);
++	assert(sizeof(unsigned int) == 4);
+ 
+ 	CHAR64LONG16* block;
+ 	static unsigned char workspace[64];
+diff -urN a/vmime/bodyPart.hpp b/vmime/bodyPart.hpp
+--- a/vmime/bodyPart.hpp	2010-05-21 09:06:27.043934681 +0200
++++ b/vmime/bodyPart.hpp	2010-05-21 09:07:53.375934467 +0200
+@@ -46,6 +46,7 @@
+ public:
+ 
+ 	bodyPart();
++	bodyPart(weak_ref <vmime::bodyPart> parentPart);
+ 
+ 	/** Return the header section of this part.
+ 	  *
+diff -urN a/vmime/contentHandler.hpp b/vmime/contentHandler.hpp
+--- a/vmime/contentHandler.hpp	2010-05-21 09:06:27.043934681 +0200
++++ b/vmime/contentHandler.hpp	2010-05-21 09:07:53.371933656 +0200
+@@ -87,7 +87,8 @@
+ 	virtual void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const = 0;
+ 
+ 	/** Returns the actual length of data. WARNING: this can return 0 if no
+-	  * length was specified when setting data of this object.
++	  * length was specified when setting data of this object, or if the
++	  * length is not known).
+ 	  *
+ 	  * @return length of data
+ 	  */
+diff -urN a/vmime/net/imap/IMAPMessage.hpp b/vmime/net/imap/IMAPMessage.hpp
+--- a/vmime/net/imap/IMAPMessage.hpp	2010-05-21 09:06:27.060431845 +0200
++++ b/vmime/net/imap/IMAPMessage.hpp	2010-05-21 09:07:53.371933656 +0200
+@@ -28,6 +28,8 @@
+ #include "vmime/net/message.hpp"
+ #include "vmime/net/folder.hpp"
+ 
++#include "vmime/net/imap/IMAPParser.hpp"
++
+ 
+ namespace vmime {
+ namespace net {
+@@ -75,12 +77,29 @@
+ 
+ 	void fetchPartHeader(ref <part> p);
+ 
++	ref <vmime::message> getParsedMessage();
++
+ private:
+ 
+ 	void fetch(ref <IMAPFolder> folder, const int options);
+ 
+ 	void processFetchResponse(const int options, const IMAPParser::msg_att* msgAtt);
+ 
++	/** Recursively fetch part header for all parts in the structure.
++	  *
++	  * @param str structure for which to fetch parts headers
++	  */
++	void fetchPartHeaderForStructure(ref <structure> str);
++
++	/** Recursively contruct parsed message from structure.
++	  * Called by getParsedMessage().
++	  *
++	  * @param parentPart root body part (the message)
++	  * @param str structure for which to construct part
++	  * @param level current nesting level (0 is root)
++	  */
++	void constructParsedMessage(ref <bodyPart> parentPart, ref <structure> str, int level = 0);
++
+ 	void extract(ref <const part> p, utility::outputStream& os, utility::progressListener* progress, const int start, const int length, const bool headerOnly, const bool peek) const;
+ 
+ 
+diff -urN a/vmime/net/imap/IMAPMessagePartContentHandler.hpp b/vmime/net/imap/IMAPMessagePartContentHandler.hpp
+--- a/vmime/net/imap/IMAPMessagePartContentHandler.hpp	1970-01-01 01:00:00.000000000 +0100
++++ b/vmime/net/imap/IMAPMessagePartContentHandler.hpp	2010-05-21 09:07:53.371933656 +0200
+@@ -0,0 +1,73 @@
++//
++// VMime library (http://www.vmime.org)
++// Copyright (C) 2002-2009 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 3 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.
++//
++
++#ifndef VMIME_NET_IMAP_IMAPMESSAGEPARTCONTENTHANDLER_HPP_INCLUDED
++#define VMIME_NET_IMAP_IMAPMESSAGEPARTCONTENTHANDLER_HPP_INCLUDED
++
++
++#include "vmime/contentHandler.hpp"
++#include "vmime/net/imap/IMAPMessage.hpp"
++
++
++namespace vmime {
++namespace net {
++namespace imap {
++
++
++class IMAPMessagePartContentHandler : public contentHandler
++{
++public:
++
++	IMAPMessagePartContentHandler(ref <IMAPMessage> msg, ref <class part> part, const vmime::encoding& encoding);
++
++	ref <contentHandler> clone() const;
++
++	void generate(utility::outputStream& os, const vmime::encoding& enc, const string::size_type maxLineLength = lineLengthLimits::infinite) const;
++
++	void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const;
++	void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const;
++
++	string::size_type getLength() const;
++
++	bool isEncoded() const;
++
++	const vmime::encoding& getEncoding() const;
++
++	bool isEmpty() const;
++
++private:
++
++	weak_ref <IMAPMessage> m_message;
++	weak_ref <part> m_part;
++
++	vmime::encoding m_encoding;
++};
++
++
++} // imap
++} // net
++} // vmime
++
++
++#endif // VMIME_NET_IMAP_IMAPMESSAGEPARTCONTENTHANDLER_HPP_INCLUDED
++
+diff -urN a/vmime/net/imap/IMAPPart.hpp b/vmime/net/imap/IMAPPart.hpp
+--- a/vmime/net/imap/IMAPPart.hpp	1970-01-01 01:00:00.000000000 +0100
++++ b/vmime/net/imap/IMAPPart.hpp	2010-05-21 09:07:53.371933656 +0200
+@@ -0,0 +1,88 @@
++//
++// VMime library (http://www.vmime.org)
++// Copyright (C) 2002-2009 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 3 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.
++//
++
++#ifndef VMIME_NET_IMAP_IMAPPART_HPP_INCLUDED
++#define VMIME_NET_IMAP_IMAPPART_HPP_INCLUDED
++
++
++#include "vmime/net/message.hpp"
++
++#include "vmime/net/imap/IMAPParser.hpp"
++
++
++namespace vmime {
++namespace net {
++namespace imap {
++
++
++class IMAPStructure;
++
++
++class IMAPPart : public part
++{
++private:
++
++	friend class vmime::creator;
++
++	IMAPPart(ref <IMAPPart> parent, const int number, const IMAPParser::body_type_mpart* mpart);
++	IMAPPart(ref <IMAPPart> parent, const int number, const IMAPParser::body_type_1part* part);
++
++public:
++
++	ref <const structure> getStructure() const;
++	ref <structure> getStructure();
++
++	ref <const IMAPPart> getParent() const;
++
++	const mediaType& getType() const;
++	int getSize() const;
++	int getNumber() const;
++
++	ref <const header> getHeader() const;
++
++
++	static ref <IMAPPart> create
++		(ref <IMAPPart> parent, const int number, const IMAPParser::body* body);
++
++
++	header& getOrCreateHeader();
++
++private:
++
++	ref <IMAPStructure> m_structure;
++	weak_ref <IMAPPart> m_parent;
++	ref <header> m_header;
++
++	int m_number;
++	int m_size;
++	mediaType m_mediaType;
++};
++
++
++} // imap
++} // net
++} // vmime
++
++
++#endif // VMIME_NET_IMAP_IMAPPART_HPP_INCLUDED
++
+diff -urN a/vmime/net/imap/IMAPStructure.hpp b/vmime/net/imap/IMAPStructure.hpp
+--- a/vmime/net/imap/IMAPStructure.hpp	1970-01-01 01:00:00.000000000 +0100
++++ b/vmime/net/imap/IMAPStructure.hpp	2010-05-21 09:07:53.371933656 +0200
+@@ -0,0 +1,67 @@
++//
++// VMime library (http://www.vmime.org)
++// Copyright (C) 2002-2009 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 3 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.
++//
++
++#ifndef VMIME_NET_IMAP_IMAPSTRUCTURE_HPP_INCLUDED
++#define VMIME_NET_IMAP_IMAPSTRUCTURE_HPP_INCLUDED
++
++
++#include "vmime/net/message.hpp"
++
++#include "vmime/net/imap/IMAPParser.hpp"
++
++
++namespace vmime {
++namespace net {
++namespace imap {
++
++
++class IMAPPart;
++
++
++class IMAPStructure : public structure
++{
++public:
++
++	IMAPStructure();
++	IMAPStructure(const IMAPParser::body* body);
++	IMAPStructure(ref <IMAPPart> parent, const std::vector <IMAPParser::body*>& list);
++
++	ref <const part> getPartAt(const int x) const;
++	ref <part> getPartAt(const int x);
++	int getPartCount() const;
++
++	static ref <IMAPStructure> emptyStructure();
++
++private:
++
++	std::vector <ref <IMAPPart> > m_parts;
++};
++
++
++} // imap
++} // net
++} // vmime
++
++
++#endif // VMIME_NET_IMAP_IMAPSTRUCTURE_HPP_INCLUDED
++
+diff -urN a/vmime/net/maildir/maildirMessage.hpp b/vmime/net/maildir/maildirMessage.hpp
+--- a/vmime/net/maildir/maildirMessage.hpp	2010-05-21 09:06:27.064432936 +0200
++++ b/vmime/net/maildir/maildirMessage.hpp	2010-05-21 09:07:53.371933656 +0200
+@@ -75,6 +75,8 @@
+ 
+ 	void fetchPartHeader(ref <part> p);
+ 
++	ref <vmime::message> getParsedMessage();
++
+ private:
+ 
+ 	void fetch(ref <maildirFolder> folder, const int options);
+diff -urN a/vmime/net/message.hpp b/vmime/net/message.hpp
+--- a/vmime/net/message.hpp	2010-05-21 09:06:27.067930607 +0200
++++ b/vmime/net/message.hpp	2010-05-21 09:07:53.371933656 +0200
+@@ -31,6 +31,8 @@
+ #include "vmime/utility/progressListener.hpp"
+ #include "vmime/utility/stream.hpp"
+ 
++#include "vmime/message.hpp"
++
+ 
+ namespace vmime {
+ namespace net {
+@@ -286,6 +288,16 @@
+ 	  * @param p the part for which to fetch the header
+ 	  */
+ 	virtual void fetchPartHeader(ref <part> p) = 0;
++
++	/** Get the RFC-822 message for this abstract message.
++	  * Warning: This may require getting some data (ie: structure and headers) from
++	  * the server, which is done automatically. Actual message contents (ie: body)
++	  * will not be fetched if possible (IMAP allows it, whereas POP3 will require
++	  * to fetch the whole message).
++	  *
++	  * @return a RFC-822-parsed message
++	  */
++	virtual ref <vmime::message> getParsedMessage() = 0;
+ };
+ 
+ 
+diff -urN a/vmime/net/pop3/POP3Message.hpp b/vmime/net/pop3/POP3Message.hpp
+--- a/vmime/net/pop3/POP3Message.hpp	2010-05-21 09:06:27.067930607 +0200
++++ b/vmime/net/pop3/POP3Message.hpp	2010-05-21 09:07:53.371933656 +0200
+@@ -77,6 +77,8 @@
+ 
+ 	void fetchPartHeader(ref <part> p);
+ 
++	ref <vmime::message> getParsedMessage();
++
+ private:
+ 
+ 	void fetch(ref <POP3Folder> folder, const int options);
+diff -urN a/vmime/security/digest/sha1/sha1MessageDigest.hpp b/vmime/security/digest/sha1/sha1MessageDigest.hpp
+--- a/vmime/security/digest/sha1/sha1MessageDigest.hpp	2010-05-21 09:06:27.088435636 +0200
++++ b/vmime/security/digest/sha1/sha1MessageDigest.hpp	2010-05-21 09:07:53.371933656 +0200
+@@ -59,10 +59,10 @@
+ 
+ 	void init();
+ 
+-	static void transform(unsigned long state[5], const byte_t buffer[64]);
++	static void transform(unsigned int state[5], const byte_t buffer[64]);
+ 
+-	unsigned long m_state[5];
+-	unsigned long m_count[2];
++	unsigned int m_state[5];
++	unsigned int m_count[2];
+ 	byte_t m_buffer[64];
+ 
+ 	byte_t m_digest[20];
--- a/src/vmime-99999-fix-pthreads.patch	Fri May 21 03:37:31 2010 +0200
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,17 +0,0 @@
-This file is part of mingw-cross-env.
-See doc/index.html for further information.
-
-This patch has been taken from:
-https://sourceforge.net/tracker/?func=detail&aid=3004924&group_id=69724&atid=525570
-
-diff -urN a/src/net/tls/TLSSession.cpp b/src/net/tls/TLSSession.cpp
---- a/src/net/tls/TLSSession.cpp	2010-05-20 12:19:24.163128483 +0200
-+++ b/src/net/tls/TLSSession.cpp	2010-05-20 12:21:31.979114130 +0200
-@@ -27,6 +27,7 @@
- #include "vmime/config.hpp"
- 
- #if VMIME_HAVE_PTHREAD
-+#	include <pthread.h>
- #	include <gcrypt.h>
- #	include <errno.h>
- #endif // VMIME_HAVE_PTHREAD
--- a/src/vmime.mk	Fri May 21 03:37:31 2010 +0200
+++ b/src/vmime.mk	Fri May 21 09:26:45 2010 +0200
@@ -10,7 +10,7 @@
 $(PKG)_FILE     := libvmime-$($(PKG)_VERSION).tar.bz2
 $(PKG)_WEBSITE  := http://vmime.sourceforge.net/
 $(PKG)_URL      := http://$(SOURCEFORGE_MIRROR)/project/vmime/vmime/0.9/$($(PKG)_FILE)
-$(PKG)_DEPS     := gcc libiconv gnutls libgsasl pthreads
+$(PKG)_DEPS     := gcc libiconv gnutls libgsasl pthreads zlib
 
 define $(PKG)_UPDATE
     $(call SOURCEFORGE_FILES,http://sourceforge.net/projects/vmime/files/vmime/) | \