Added helper function to construct parsed message from net message. Splitted IMAP source files.

This commit is contained in:
Vincent Richard 2010-05-18 13:52:27 +00:00
parent 13ae80a4c7
commit 9196d5c342
19 changed files with 835 additions and 199 deletions

View File

@ -2,6 +2,11 @@
VERSION 0.9.1svn 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> 2009-09-06 Vincent Richard <vincent@vincent-richard.net>
* Relicensed VMime under the GNU GPL license version 3. Dual licensing * Relicensed VMime under the GNU GPL license version 3. Dual licensing

View File

@ -261,6 +261,9 @@ libvmime_messaging_proto_sources = [
'net/imap/IMAPMessage.cpp', 'net/imap/IMAPMessage.hpp', 'net/imap/IMAPMessage.cpp', 'net/imap/IMAPMessage.hpp',
'net/imap/IMAPTag.cpp', 'net/imap/IMAPTag.hpp', 'net/imap/IMAPTag.cpp', 'net/imap/IMAPTag.hpp',
'net/imap/IMAPUtils.cpp', 'net/imap/IMAPUtils.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', 'net/imap/IMAPParser.hpp',
] ]
], ],

View File

@ -37,6 +37,15 @@ bodyPart::bodyPart()
} }
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, void bodyPart::parse(const string& buffer, const string::size_type position,
const string::size_type end, string::size_type* newPosition) const string::size_type end, string::size_type* newPosition)
{ {

View File

@ -300,7 +300,8 @@ const std::vector <ref <const component> > headerField::getChildComponents() con
{ {
std::vector <ref <const component> > list; std::vector <ref <const component> > list;
list.push_back(m_value); if (m_value)
list.push_back(m_value);
return (list); return (list);
} }

View File

@ -27,6 +27,9 @@
#include "vmime/net/imap/IMAPStore.hpp" #include "vmime/net/imap/IMAPStore.hpp"
#include "vmime/net/imap/IMAPConnection.hpp" #include "vmime/net/imap/IMAPConnection.hpp"
#include "vmime/net/imap/IMAPUtils.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 <sstream>
#include <iterator> #include <iterator>
@ -38,198 +41,6 @@ namespace net {
namespace imap { 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 #ifndef VMIME_BUILDING_DOC
// //
@ -400,7 +211,22 @@ void IMAPMessage::fetchPartHeader(ref <part> p)
extract(p, ossAdapter, NULL, 0, -1, true, true); 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 @@ void IMAPMessage::extract(ref <const part> p, utility::outputStream& os,
if (p != NULL) if (p != NULL)
{ {
ref <const IMAPpart> currentPart = p.dynamicCast <const IMAPpart>(); ref <const IMAPPart> currentPart = p.dynamicCast <const IMAPPart>();
std::vector <int> numbers; std::vector <int> numbers;
numbers.push_back(currentPart->getNumber()); numbers.push_back(currentPart->getNumber());
@ -446,8 +272,17 @@ void IMAPMessage::extract(ref <const part> p, utility::outputStream& os,
command << "FETCH " << m_num << " BODY"; command << "FETCH " << m_num << " BODY";
if (peek) command << ".PEEK"; if (peek) command << ".PEEK";
command << "["; 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 << "]"; command << "]";
if (start != 0 || length != -1) if (start != 0 || length != -1)
@ -621,7 +456,7 @@ void IMAPMessage::processFetchResponse
} }
case IMAPParser::msg_att_item::BODY_STRUCTURE: case IMAPParser::msg_att_item::BODY_STRUCTURE:
{ {
m_structure = vmime::create <IMAPstructure>((*it)->body()); m_structure = vmime::create <IMAPStructure>((*it)->body());
break; break;
} }
case IMAPParser::msg_att_item::RFC822_HEADER: case IMAPParser::msg_att_item::RFC822_HEADER:
@ -796,6 +631,80 @@ void IMAPMessage::setFlags(const int flags, const int mode)
} }
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 } // imap
} // net } // net
} // vmime } // vmime

View File

@ -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

152
src/net/imap/IMAPPart.cpp Normal file
View File

@ -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

View File

@ -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

View File

@ -524,6 +524,20 @@ ref <header> maildirMessage::getOrCreateHeader()
} }
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 } // maildir
} // net } // net
} // vmime } // vmime

View File

@ -218,6 +218,20 @@ void POP3Message::setFlags(const int /* flags */, const int /* mode */)
} }
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 } // pop3
} // net } // net
} // vmime } // vmime

View File

@ -46,6 +46,7 @@ class bodyPart : public component
public: public:
bodyPart(); bodyPart();
bodyPart(weak_ref <vmime::bodyPart> parentPart);
/** Return the header section of this part. /** Return the header section of this part.
* *

View File

@ -87,7 +87,8 @@ public:
virtual void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const = 0; 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 /** 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 * @return length of data
*/ */

View File

@ -28,6 +28,8 @@
#include "vmime/net/message.hpp" #include "vmime/net/message.hpp"
#include "vmime/net/folder.hpp" #include "vmime/net/folder.hpp"
#include "vmime/net/imap/IMAPParser.hpp"
namespace vmime { namespace vmime {
namespace net { namespace net {
@ -75,12 +77,29 @@ public:
void fetchPartHeader(ref <part> p); void fetchPartHeader(ref <part> p);
ref <vmime::message> getParsedMessage();
private: private:
void fetch(ref <IMAPFolder> folder, const int options); void fetch(ref <IMAPFolder> folder, const int options);
void processFetchResponse(const int options, const IMAPParser::msg_att* msgAtt); 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; 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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -75,6 +75,8 @@ public:
void fetchPartHeader(ref <part> p); void fetchPartHeader(ref <part> p);
ref <vmime::message> getParsedMessage();
private: private:
void fetch(ref <maildirFolder> folder, const int options); void fetch(ref <maildirFolder> folder, const int options);

View File

@ -31,6 +31,8 @@
#include "vmime/utility/progressListener.hpp" #include "vmime/utility/progressListener.hpp"
#include "vmime/utility/stream.hpp" #include "vmime/utility/stream.hpp"
#include "vmime/message.hpp"
namespace vmime { namespace vmime {
namespace net { namespace net {
@ -286,6 +288,16 @@ public:
* @param p the part for which to fetch the header * @param p the part for which to fetch the header
*/ */
virtual void fetchPartHeader(ref <part> p) = 0; 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;
}; };

View File

@ -77,6 +77,8 @@ public:
void fetchPartHeader(ref <part> p); void fetchPartHeader(ref <part> p);
ref <vmime::message> getParsedMessage();
private: private:
void fetch(ref <POP3Folder> folder, const int options); void fetch(ref <POP3Folder> folder, const int options);