aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ChangeLog5
-rw-r--r--SConstruct3
-rw-r--r--src/attachmentHelper.cpp201
-rw-r--r--src/bodyPartAttachment.cpp164
-rw-r--r--src/messageParser.cpp181
-rw-r--r--tests/parser/attachmentHelperTest.cpp113
-rw-r--r--vmime/attachment.hpp1
-rw-r--r--vmime/attachmentHelper.hpp95
-rw-r--r--vmime/bodyPartAttachment.hpp73
-rw-r--r--vmime/messageParser.hpp16
-rw-r--r--vmime/vmime.hpp2
11 files changed, 674 insertions, 180 deletions
diff --git a/ChangeLog b/ChangeLog
index a6a0e713..dde267a2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,6 +2,11 @@
VERSION 0.7.2cvs
================
+2005-10-13 Vincent Richard <[email protected]>
+
+ * attachmentHelper.{hpp|cpp}: the attachmentHelper allows listing all
+ attachments in a message, as well as adding new attachments.
+
2005-10-06 Vincent Richard <[email protected]>
* utility/progressionListener.{hpp|cpp}: renamed 'progressionListener'
diff --git a/SConstruct b/SConstruct
index 708d53a3..c7e90923 100644
--- a/SConstruct
+++ b/SConstruct
@@ -76,9 +76,11 @@ libvmime_sources = [
'address.cpp', 'address.hpp',
'addressList.cpp', 'addressList.hpp',
'attachment.hpp',
+ 'attachmentHelper.cpp', 'attachmentHelper.hpp',
'base.cpp', 'base.hpp',
'body.cpp', 'body.hpp',
'bodyPart.cpp', 'bodyPart.hpp',
+ 'bodyPartAttachment.cpp', 'bodyPartAttachment.hpp',
'charset.cpp', 'charset.hpp',
'component.cpp', 'component.hpp',
'constants.cpp', 'constants.hpp',
@@ -327,6 +329,7 @@ libvmimetest_common = [
libvmimetest_sources = [
'tests/testRunner.cpp',
# ============================== Parser ==============================
+ 'tests/parser/attachmentHelperTest.cpp',
'tests/parser/bodyPartTest.cpp',
'tests/parser/datetimeTest.cpp',
'tests/parser/dispositionTest.cpp',
diff --git a/src/attachmentHelper.cpp b/src/attachmentHelper.cpp
new file mode 100644
index 00000000..0388ae7c
--- /dev/null
+++ b/src/attachmentHelper.cpp
@@ -0,0 +1,201 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2005 Vincent Richard <[email protected]>
+//
+// 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/attachmentHelper.hpp"
+
+#include "vmime/bodyPartAttachment.hpp"
+
+
+namespace vmime
+{
+
+
+// static
+const bool attachmentHelper::isBodyPartAnAttachment(ref <const bodyPart> part)
+{
+ try
+ {
+ const contentDispositionField& cdf = dynamic_cast<contentDispositionField&>
+ (*part->getHeader()->findField(fields::CONTENT_DISPOSITION));
+
+ if (cdf.getValue().getName() != contentDispositionTypes::INLINE)
+ return true;
+ }
+ catch (exceptions::no_such_field)
+ {
+ // No "Content-disposition" field: assume "attachment" if
+ // type is not "text/..." or "multipart/...".
+ mediaType type;
+
+ try
+ {
+ const contentTypeField& ctf = dynamic_cast<contentTypeField&>
+ (*part->getHeader()->findField(fields::CONTENT_TYPE));
+
+ type = ctf.getValue();
+ }
+ catch (exceptions::no_such_field)
+ {
+ // No "Content-type" field: assume "application/octet-stream".
+ type = mediaType(mediaTypes::APPLICATION,
+ mediaTypes::APPLICATION_OCTET_STREAM);
+ }
+
+ if (type.getType() != mediaTypes::TEXT &&
+ type.getType() != mediaTypes::MULTIPART)
+ {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+
+// static
+ref <const attachment>
+ attachmentHelper::getBodyPartAttachment(ref <const bodyPart> part)
+{
+ if (!isBodyPartAnAttachment(part))
+ return NULL;
+
+ return vmime::create <bodyPartAttachment>(part);
+}
+
+
+// static
+const std::vector <ref <const attachment> >
+ attachmentHelper::findAttachmentsInMessage(ref <const message> msg)
+{
+ return findAttachmentsInBodyPart(msg);
+}
+
+
+// static
+const std::vector <ref <const attachment> >
+ attachmentHelper::findAttachmentsInBodyPart(ref <const bodyPart> part)
+{
+ std::vector <ref <const attachment> > atts;
+
+ // Test this part
+ if (isBodyPartAnAttachment(part))
+ {
+ atts.push_back(getBodyPartAttachment(part));
+ }
+ // Find in sub-parts
+ else
+ {
+ ref <const body> bdy = part->getBody();
+
+ for (int i = 0 ; i < bdy->getPartCount() ; ++i)
+ {
+ std::vector <ref <const attachment> > partAtts =
+ findAttachmentsInBodyPart(bdy->getPartAt(i));
+
+ for (unsigned int j = 0 ; j < partAtts.size() ; ++i)
+ atts.push_back(partAtts[j]);
+ }
+ }
+
+ return atts;
+}
+
+
+// static
+void attachmentHelper::addAttachment(ref <message> msg, ref <attachment> att)
+{
+ // We simply search for a "multipart/mixed" part. If no one exists,
+ // create it in the root part. This (very simple) algorithm should
+ // work in the most cases.
+
+ vmime::mediaType mpMixed(vmime::mediaTypes::MULTIPART,
+ vmime::mediaTypes::MULTIPART_MIXED);
+
+ ref <bodyPart> part = findBodyPart(msg, mpMixed);
+
+ if (part == NULL) // create it
+ {
+ // Create a new container part for the parts that were in
+ // the root part of the message
+ ref <bodyPart> container = vmime::create <bodyPart>();
+
+ try
+ {
+ container->getHeader()->ContentType()->
+ setValue(msg->getHeader()->ContentType()->getValue());
+ }
+ catch (exceptions::no_such_field&)
+ {
+ // Ignore
+ }
+
+ msg->getHeader()->removeAllFields(vmime::fields::CONTENT_DISPOSITION);
+ msg->getHeader()->removeAllFields(vmime::fields::CONTENT_TRANSFER_ENCODING);
+
+ // Move parts from the root part to this new part
+ const std::vector <ref <bodyPart> > partList =
+ msg->getBody()->getPartList();
+
+ msg->getBody()->removeAllParts();
+
+ for (unsigned int i = 0 ; i < partList.size() ; ++i)
+ container->getBody()->appendPart(partList[i]);
+
+ // Set the root part to 'multipart/mixed'
+ msg->getHeader()->ContentType()->setValue(mpMixed);
+
+ msg->getBody()->appendPart(container);
+
+ part = msg;
+ }
+
+ // Generate the attachment part
+ att->generateIn(*part);
+}
+
+
+// static
+ref <bodyPart> attachmentHelper::findBodyPart
+ (ref <bodyPart> part, const mediaType& type)
+{
+ if (part->getBody()->getContentType() == type)
+ return part;
+
+ // Try in sub-parts
+ ref <body> bdy = part->getBody();
+
+ for (int i = 0 ; i < bdy->getPartCount() ; ++i)
+ {
+ ref <bodyPart> found =
+ findBodyPart(bdy->getPartAt(i), type);
+
+ if (found != NULL)
+ return found;
+ }
+
+ return NULL;
+}
+
+
+} // vmime
+
diff --git a/src/bodyPartAttachment.cpp b/src/bodyPartAttachment.cpp
new file mode 100644
index 00000000..adf605d3
--- /dev/null
+++ b/src/bodyPartAttachment.cpp
@@ -0,0 +1,164 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2005 Vincent Richard <[email protected]>
+//
+// 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/bodyPartAttachment.hpp"
+
+
+namespace vmime
+{
+
+
+bodyPartAttachment::bodyPartAttachment(ref <const bodyPart> part)
+ : m_part(part)
+{
+}
+
+
+const mediaType bodyPartAttachment::getType() const
+{
+ mediaType type;
+
+ try
+ {
+ type = getContentType()->getValue();
+ }
+ catch (exceptions::no_such_field&)
+ {
+ // No "Content-type" field: assume "application/octet-stream".
+ type = mediaType(mediaTypes::APPLICATION,
+ mediaTypes::APPLICATION_OCTET_STREAM);
+ }
+
+ return type;
+}
+
+
+const word bodyPartAttachment::getName() const
+{
+ word name;
+
+ // Try the 'filename' parameter of 'Content-Disposition' field
+ try
+ {
+ name = getContentDisposition()->getFilename();
+ }
+ catch (exceptions::no_such_field&)
+ {
+ // No 'Content-Disposition' field
+ }
+ catch (exceptions::no_such_parameter&)
+ {
+ // No 'filename' parameter
+ }
+
+ // Try the 'name' parameter of 'Content-Type' field
+ if (name.getBuffer().empty())
+ {
+ try
+ {
+ ref <defaultParameter> prm = getContentType()->
+ findParameter("name").dynamicCast <defaultParameter>();
+
+ if (prm != NULL)
+ name = prm->getValue();
+ }
+ catch (exceptions::no_such_field&)
+ {
+ // No 'Content-Type' field
+ }
+ catch (exceptions::no_such_parameter&)
+ {
+ // No attachment name available
+ }
+ }
+
+ return name;
+}
+
+
+const text bodyPartAttachment::getDescription() const
+{
+ text description;
+
+ try
+ {
+ const textField& cd = dynamic_cast <textField&>
+ (*getHeader()->findField(fields::CONTENT_DESCRIPTION));
+
+ description = cd.getValue();
+ }
+ catch (exceptions::no_such_field&)
+ {
+ // No description available.
+ }
+
+ return description;
+}
+
+
+const encoding bodyPartAttachment::getEncoding() const
+{
+ return m_part->getBody()->getEncoding();
+}
+
+
+const ref <const contentHandler> bodyPartAttachment::getData() const
+{
+ return m_part->getBody()->getContents();
+}
+
+
+ref <const object> bodyPartAttachment::getPart() const
+{
+ return m_part;
+}
+
+
+ref <const header> bodyPartAttachment::getHeader() const
+{
+ return m_part->getHeader();
+}
+
+
+ref <const contentDispositionField> bodyPartAttachment::getContentDisposition() const
+{
+ return getHeader()->findField(fields::CONTENT_DISPOSITION).
+ dynamicCast <const contentDispositionField>();
+}
+
+
+ref <const contentTypeField> bodyPartAttachment::getContentType() const
+{
+ return getHeader()->findField(fields::CONTENT_TYPE).
+ dynamicCast <const contentTypeField>();
+}
+
+
+void bodyPartAttachment::generateIn(bodyPart& /* parent */) const
+{
+ // Not used
+}
+
+
+} // vmime
+
diff --git a/src/messageParser.cpp b/src/messageParser.cpp
index b6e11fb7..4a96cf10 100644
--- a/src/messageParser.cpp
+++ b/src/messageParser.cpp
@@ -23,6 +23,8 @@
#include "vmime/messageParser.hpp"
+#include "vmime/attachmentHelper.hpp"
+
#include "vmime/defaultAttachment.hpp"
#include "vmime/textPartFactory.hpp"
@@ -33,14 +35,14 @@ namespace vmime
messageParser::messageParser(const string& buffer)
{
- vmime::message msg;
- msg.parse(buffer);
+ ref <message> msg = vmime::create <message>();
+ msg->parse(buffer);
parse(msg);
}
-messageParser::messageParser(const message& msg)
+messageParser::messageParser(ref <const message> msg)
{
parse(msg);
}
@@ -51,13 +53,13 @@ messageParser::~messageParser()
}
-void messageParser::parse(const message& msg)
+void messageParser::parse(ref <const message> msg)
{
// Header fields (if field is present, copy its value, else do nothing)
#ifndef VMIME_BUILDING_DOC
#define TRY_FIELD(var, type, name) \
- try { var = dynamic_cast<type&>(*msg.getHeader()->findField(name)).getValue(); } \
+ try { var = dynamic_cast<type&>(*msg->getHeader()->findField(name)).getValue(); } \
catch (exceptions::no_such_field) { }
TRY_FIELD(m_from, mailboxField, fields::FROM);
@@ -76,7 +78,7 @@ void messageParser::parse(const message& msg)
try
{
vmime::relayField& recv = dynamic_cast <vmime::relayField&>
- (*msg.getHeader()->findField(fields::RECEIVED));
+ (*msg->getHeader()->findField(fields::RECEIVED));
m_date = recv.getValue().getDate();
}
@@ -85,7 +87,7 @@ void messageParser::parse(const message& msg)
try
{
vmime::dateField& date = dynamic_cast <vmime::dateField&>
- (*msg.getHeader()->findField(fields::DATE));
+ (*msg->getHeader()->findField(fields::DATE));
m_date = date.getValue();
}
@@ -99,151 +101,13 @@ void messageParser::parse(const message& msg)
findAttachments(msg);
// Text parts
- findTextParts(msg, msg);
+ findTextParts(*msg, *msg);
}
-void messageParser::findAttachments(const bodyPart& part)
+void messageParser::findAttachments(ref <const message> msg)
{
- // We simply search for parts that are not "Content-disposition: inline".
- for (int i = 0 ; i < part.getBody()->getPartCount() ; ++i)
- {
- const bodyPart& p = *part.getBody()->getPartAt(i);
- const header& hdr = *p.getHeader();
- const body& bdy = *p.getBody();
-
- // Is this part an attachment?
- bool isAttachment = false;
- const contentDispositionField* contentDispField = NULL;
-
- try
- {
- const contentDispositionField& cdf = dynamic_cast<contentDispositionField&>
- (*hdr.findField(fields::CONTENT_DISPOSITION));
-
- if (cdf.getValue().getName() != contentDispositionTypes::INLINE)
- {
- contentDispField = &cdf;
- isAttachment = true;
- }
- }
- catch (exceptions::no_such_field)
- {
- // No "Content-disposition" field: assume "attachment" if
- // type is not "text/..." or "multipart/...".
- mediaType type;
-
- try
- {
- const contentTypeField& ctf = dynamic_cast<contentTypeField&>
- (*hdr.findField(fields::CONTENT_TYPE));
-
- type = ctf.getValue();
- }
- catch (exceptions::no_such_field)
- {
- // No "Content-type" field: assume "application/octet-stream".
- type = mediaType(mediaTypes::APPLICATION,
- mediaTypes::APPLICATION_OCTET_STREAM);
- }
-
- if (type.getType() != mediaTypes::TEXT &&
- type.getType() != mediaTypes::MULTIPART)
- {
- isAttachment = true;
- }
- }
-
- if (isAttachment)
- {
- // Determine the media type of this attachment
- const contentTypeField* contTypeField = NULL;
- mediaType type;
-
- try
- {
- const contentTypeField& ctf = dynamic_cast<contentTypeField&>
- (*hdr.findField(fields::CONTENT_TYPE));
-
- type = ctf.getValue();
-
- contTypeField = &ctf;
- }
- catch (exceptions::no_such_field)
- {
- // No "Content-type" field: assume "application/octet-stream".
- type = mediaType(mediaTypes::APPLICATION,
- mediaTypes::APPLICATION_OCTET_STREAM);
- }
-
- // Get the description (if available)
- text description;
-
- try
- {
- const textField& cd = dynamic_cast<textField&>
- (*hdr.findField(fields::CONTENT_DESCRIPTION));
-
- description = cd.getValue();
- }
- catch (exceptions::no_such_field)
- {
- // No description available.
- }
-
- // Get the name/filename (if available)
- word name;
-
- // -- try the 'filename' parameter of 'Content-Disposition' field
- if (contentDispField != NULL)
- {
- try
- {
- name = contentDispField->getFilename();
- }
- catch (exceptions::no_such_parameter)
- {
- // No 'filename' parameter
- }
- }
-
- // -- try the 'name' parameter of 'Content-Type' field
- if (name.getBuffer().empty() && contTypeField != NULL)
- {
- try
- {
- ref <defaultParameter> prm = contTypeField->
- findParameter("name").dynamicCast <defaultParameter>();
-
- if (prm != NULL)
- name = prm->getValue();
- }
- catch (exceptions::no_such_parameter)
- {
- // No attachment name available.
- }
- }
-
- // Construct the attachment object
- ref <attachment> attach = vmime::create <defaultAttachment>
- (bdy.getContents()->clone().dynamicCast <contentHandler>(),
- bdy.getEncoding(), type, description, name);
-
- if (contentDispField != NULL)
- {
- m_attachInfo.insert(std::map <attachment*, ref <contentDispositionField> >::
- value_type(attach.get(), contentDispField->clone().
- dynamicCast <contentDispositionField>()));
- }
-
- // Add the attachment to the list
- m_attach.push_back(attach);
- }
-
- // Try to find attachments in sub-parts
- if (bdy.getPartCount())
- findAttachments(p);
- }
+ m_attach = attachmentHelper::findAttachmentsInMessage(msg);
}
@@ -357,15 +221,6 @@ bool messageParser::findSubTextParts(const bodyPart& msg, const bodyPart& part)
}
-const ref <const contentDispositionField> messageParser::getAttachmentInfo(const ref <const attachment> a) const
-{
- std::map <attachment*, ref <contentDispositionField> >::const_iterator
- it = m_attachInfo.find(ref <attachment>(a.constCast <attachment>()).get());
-
- return (it != m_attachInfo.end() ? (*it).second : NULL);
-}
-
-
const mailbox& messageParser::getExpeditor() const
{
return (m_from);
@@ -404,17 +259,7 @@ const datetime& messageParser::getDate() const
const std::vector <ref <const attachment> > messageParser::getAttachmentList() const
{
- std::vector <ref <const attachment> > res;
-
- res.reserve(m_attach.size());
-
- for (std::vector <ref <attachment> >::const_iterator it = m_attach.begin() ;
- it != m_attach.end() ; ++it)
- {
- res.push_back(*it);
- }
-
- return (res);
+ return m_attach;
}
diff --git a/tests/parser/attachmentHelperTest.cpp b/tests/parser/attachmentHelperTest.cpp
new file mode 100644
index 00000000..a8bb34c8
--- /dev/null
+++ b/tests/parser/attachmentHelperTest.cpp
@@ -0,0 +1,113 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2005 Vincent Richard <[email protected]>
+//
+// 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 "tests/testUtils.hpp"
+
+
+#define VMIME_TEST_SUITE attachmentHelperTest
+#define VMIME_TEST_SUITE_MODULE "Parser"
+
+
+VMIME_TEST_SUITE_BEGIN
+
+ VMIME_TEST_LIST_BEGIN
+ VMIME_TEST(testAddAttachment1)
+ VMIME_TEST(testAddAttachment2)
+ // TODO: add more tests
+ VMIME_TEST_LIST_END
+
+
+ static const vmime::string getStructure(vmime::ref <vmime::bodyPart> part)
+ {
+ vmime::ref <vmime::body> bdy = part->getBody();
+
+ vmime::string res = part->getBody()->getContentType().generate();
+
+ if (bdy->getPartCount() == 0)
+ return res;
+
+ res += "[";
+
+ for (int i = 0 ; i < bdy->getPartCount() ; ++i)
+ {
+ vmime::ref <vmime::bodyPart> subPart = bdy->getPartAt(i);
+
+ if (i != 0)
+ res += ",";
+
+ res += getStructure(subPart);
+ }
+
+ return res + "]";
+ }
+
+ void testAddAttachment1()
+ {
+ vmime::string data =
+"Content-Type: text/plain\r\n"
+"\r\n"
+"The text\r\n"
+"";
+
+ vmime::ref <vmime::message> msg = vmime::create <vmime::message>();
+ msg->parse(data);
+
+ vmime::ref <vmime::attachment> att = vmime::create <vmime::defaultAttachment>
+ (vmime::create <vmime::stringContentHandler>("test"),
+ vmime::mediaType("image/jpeg"));
+
+ vmime::attachmentHelper::addAttachment(msg, att);
+
+ VASSERT_EQ("1", "multipart/mixed[text/plain,image/jpeg]", getStructure(msg));
+ }
+
+ void testAddAttachment2()
+ {
+ vmime::string data =
+"Content-Type: multipart/mixed; boundary=\"foo\"\r\n"
+"\r\n"
+"--foo\r\n"
+"Content-Type: text/plain\r\n"
+"\r\n"
+"The text\r\n"
+"--foo\r\n"
+"Content-Type: application/octet-stream\r\n"
+"\r\n"
+"Blah\r\n"
+"--foo--\r\n"
+"";
+
+ vmime::ref <vmime::message> msg = vmime::create <vmime::message>();
+ msg->parse(data);
+
+ vmime::ref <vmime::attachment> att = vmime::create <vmime::defaultAttachment>
+ (vmime::create <vmime::stringContentHandler>("test"),
+ vmime::mediaType("image/jpeg"));
+
+ vmime::attachmentHelper::addAttachment(msg, att);
+
+ VASSERT_EQ("1", "multipart/mixed[text/plain,application/octet-stream,image/jpeg]", getStructure(msg));
+ }
+
+VMIME_TEST_SUITE_END
+
diff --git a/vmime/attachment.hpp b/vmime/attachment.hpp
index 222b5fa7..43c1ce47 100644
--- a/vmime/attachment.hpp
+++ b/vmime/attachment.hpp
@@ -45,6 +45,7 @@ class attachment : public object
{
friend class messageBuilder;
friend class messageParser;
+ friend class attachmentHelper;
protected:
diff --git a/vmime/attachmentHelper.hpp b/vmime/attachmentHelper.hpp
new file mode 100644
index 00000000..6316962f
--- /dev/null
+++ b/vmime/attachmentHelper.hpp
@@ -0,0 +1,95 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2005 Vincent Richard <[email protected]>
+//
+// 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.
+//
+
+#ifndef VMIME_ATTACHMENTHELPER_HPP_INCLUDED
+#define VMIME_ATTACHMENTHELPER_HPP_INCLUDED
+
+
+#include "vmime/config.hpp"
+
+#include "vmime/attachment.hpp"
+#include "vmime/message.hpp"
+
+#if VMIME_HAVE_MESSAGING_FEATURES
+ #include "vmime/net/message.hpp"
+#endif
+
+
+namespace vmime
+{
+
+
+/** Retrieve attachment information from message parts.
+ */
+class attachmentHelper
+{
+public:
+
+ /** Test whether a body part is an attachment.
+ *
+ * @param part message part to test
+ * @return true if the part is an attachment, false otherwise
+ */
+ static const bool isBodyPartAnAttachment(ref <const bodyPart> part);
+
+ /** Return attachment information in the specified body part.
+ * If the specified body part does not contain attachment
+ * information (ie. is not an attachment), NULL is returned.
+ *
+ * @param part message part in which to search
+ * @return a list of attachments found
+ */
+ static ref <const attachment>
+ getBodyPartAttachment(ref <const bodyPart> part);
+
+ /** Find all attachments contained in the specified message.
+ * This is simply a recursive call to getBodyPartAttachment().
+ *
+ * @param msg message in which to search
+ * @return a list of attachments found
+ */
+ static const std::vector <ref <const attachment> >
+ findAttachmentsInMessage(ref <const message> msg);
+
+ /** Add an attachment to the specified message.
+ *
+ * @param msg message into which to add the attachment
+ * @param att attachment to add
+ */
+ static void addAttachment(ref <message> msg, ref <attachment> att);
+
+protected:
+
+ static const std::vector <ref <const attachment> >
+ findAttachmentsInBodyPart(ref <const bodyPart> part);
+
+ static ref <bodyPart> findBodyPart
+ (ref <bodyPart> part, const mediaType& type);
+};
+
+
+} // vmime
+
+
+#endif // VMIME_ATTACHMENTHELPER_HPP_INCLUDED
+
diff --git a/vmime/bodyPartAttachment.hpp b/vmime/bodyPartAttachment.hpp
new file mode 100644
index 00000000..c079b0d6
--- /dev/null
+++ b/vmime/bodyPartAttachment.hpp
@@ -0,0 +1,73 @@
+//
+// VMime library (http://www.vmime.org)
+// Copyright (C) 2002-2005 Vincent Richard <[email protected]>
+//
+// 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.
+//
+
+#ifndef VMIME_BODYPARTATTACHMENT_HPP_INCLUDED
+#define VMIME_BODYPARTATTACHMENT_HPP_INCLUDED
+
+
+#include "vmime/attachment.hpp"
+
+
+namespace vmime
+{
+
+
+/** An attachment related to a local body part.
+ */
+class bodyPartAttachment : public attachment
+{
+ friend class creator;
+
+protected:
+
+ bodyPartAttachment(ref <const bodyPart> part);
+
+public:
+
+ const mediaType getType() const;
+ const word getName() const;
+ const text getDescription() const;
+ const encoding getEncoding() const;
+
+ const ref <const contentHandler> getData() const;
+
+ ref <const object> getPart() const;
+ ref <const header> getHeader() const;
+
+private:
+
+ void generateIn(bodyPart& parent) const;
+
+ ref <const contentDispositionField> getContentDisposition() const;
+ ref <const contentTypeField> getContentType() const;
+
+
+ ref <const bodyPart> m_part;
+};
+
+
+} // vmime
+
+
+#endif // VMIME_BODYPARTATTACHMENT_HPP_INCLUDED
+
diff --git a/vmime/messageParser.hpp b/vmime/messageParser.hpp
index f2629fcf..73bd4769 100644
--- a/vmime/messageParser.hpp
+++ b/vmime/messageParser.hpp
@@ -45,7 +45,7 @@ class messageParser
public:
messageParser(const string& buffer);
- messageParser(const message& msg);
+ messageParser(ref <const message> msg);
~messageParser();
public:
@@ -105,13 +105,6 @@ public:
*/
const std::vector <ref <const attachment> > getAttachmentList() const;
- /** Return information about the specified attachment.
- *
- * @param a attachment to retrieve information about
- * @return information about the specified attachment
- */
- const ref <const contentDispositionField> getAttachmentInfo(const ref <const attachment> a) const;
-
/** Return the text parts of the message.
*
* @return list of text parts in the message
@@ -143,14 +136,13 @@ private:
datetime m_date;
- std::vector <ref <attachment> > m_attach;
- std::map <attachment*, ref <contentDispositionField> > m_attachInfo;
+ std::vector <ref <const attachment> > m_attach;
std::vector <ref <textPart> > m_textParts;
- void parse(const message& msg);
+ void parse(ref <const message> msg);
- void findAttachments(const bodyPart& part);
+ void findAttachments(ref <const message> msg);
void findTextParts(const bodyPart& msg, const bodyPart& part);
bool findSubTextParts(const bodyPart& msg, const bodyPart& part);
diff --git a/vmime/vmime.hpp b/vmime/vmime.hpp
index c7a0b4f6..8e6f3dd3 100644
--- a/vmime/vmime.hpp
+++ b/vmime/vmime.hpp
@@ -77,6 +77,8 @@
#include "vmime/plainTextPart.hpp"
#include "vmime/htmlTextPart.hpp"
+#include "vmime/attachmentHelper.hpp"
+
// MDN
#include "vmime/mdn/MDNHelper.hpp"