Added an option to recognize inline objects as attachments.
This commit is contained in:
parent
f1b5d7d7e2
commit
def04e4ba5
@ -36,7 +36,8 @@ namespace vmime
|
|||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
bool attachmentHelper::isBodyPartAnAttachment(ref <const bodyPart> part)
|
bool attachmentHelper::isBodyPartAnAttachment
|
||||||
|
(ref <const bodyPart> part, const unsigned int options)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -49,54 +50,63 @@ bool attachmentHelper::isBodyPartAnAttachment(ref <const bodyPart> part)
|
|||||||
if (disp.getName() != contentDispositionTypes::INLINE)
|
if (disp.getName() != contentDispositionTypes::INLINE)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// If the Content-Disposition is 'inline' and there is no
|
if ((options & INLINE_OBJECTS) == 0)
|
||||||
// Content-Id or Content-Location field, it may be an attachment
|
|
||||||
if (!part->getHeader()->hasField(vmime::fields::CONTENT_ID) &&
|
|
||||||
!part->getHeader()->hasField(vmime::fields::CONTENT_LOCATION))
|
|
||||||
{
|
{
|
||||||
// If this is the root part, it might not be an attachment
|
// If the Content-Disposition is 'inline' and there is no
|
||||||
if (part->getParentPart() == NULL)
|
// Content-Id or Content-Location field, it may be an attachment
|
||||||
return false;
|
if (!part->getHeader()->hasField(vmime::fields::CONTENT_ID) &&
|
||||||
|
!part->getHeader()->hasField(vmime::fields::CONTENT_LOCATION))
|
||||||
|
{
|
||||||
|
// If this is the root part, it might not be an attachment
|
||||||
|
if (part->getParentPart() == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_field&)
|
catch (exceptions::no_such_field&)
|
||||||
{
|
{
|
||||||
// No "Content-disposition" field: assume "attachment" if
|
// Will try using Content-Type
|
||||||
// type is not "text/..." or "multipart/...".
|
}
|
||||||
mediaType type;
|
|
||||||
|
|
||||||
try
|
// Assume "attachment" if type is not "text/..." or "multipart/...".
|
||||||
{
|
mediaType type;
|
||||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
|
||||||
(*part->getHeader()->findField(fields::CONTENT_TYPE));
|
|
||||||
|
|
||||||
type = *ctf.getValue().dynamicCast <const mediaType>();
|
try
|
||||||
}
|
{
|
||||||
catch (exceptions::no_such_field&)
|
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
{
|
(*part->getHeader()->findField(fields::CONTENT_TYPE));
|
||||||
// If this is the root part and no Content-Type field is present,
|
|
||||||
// then this may not be a MIME message, so do not assume it is
|
|
||||||
// an attachment
|
|
||||||
if (part->getParentPart() == NULL)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// No "Content-type" field: assume "application/octet-stream".
|
type = *ctf.getValue().dynamicCast <const mediaType>();
|
||||||
type = mediaType(mediaTypes::APPLICATION,
|
}
|
||||||
mediaTypes::APPLICATION_OCTET_STREAM);
|
catch (exceptions::no_such_field&)
|
||||||
}
|
{
|
||||||
|
// If this is the root part and no Content-Type field is present,
|
||||||
|
// then this may not be a MIME message, so do not assume it is
|
||||||
|
// an attachment
|
||||||
|
if (part->getParentPart() == NULL)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (type.getType() != mediaTypes::TEXT &&
|
// No "Content-type" field: assume "application/octet-stream".
|
||||||
type.getType() != mediaTypes::MULTIPART)
|
type = mediaType(mediaTypes::APPLICATION,
|
||||||
|
mediaTypes::APPLICATION_OCTET_STREAM);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type.getType() != mediaTypes::TEXT &&
|
||||||
|
type.getType() != mediaTypes::MULTIPART)
|
||||||
|
{
|
||||||
|
if ((options & INLINE_OBJECTS) == 0)
|
||||||
{
|
{
|
||||||
// If a "Content-Id" field is present, it might be an
|
// If a "Content-Id" field is present, it might be an
|
||||||
// embedded object (MHTML messages)
|
// embedded object (MHTML messages)
|
||||||
if (part->getHeader()->hasField(vmime::fields::CONTENT_ID))
|
if (part->getHeader()->hasField(vmime::fields::CONTENT_ID))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -104,10 +114,10 @@ bool attachmentHelper::isBodyPartAnAttachment(ref <const bodyPart> part)
|
|||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
ref <const attachment>
|
ref <const attachment> attachmentHelper::getBodyPartAttachment
|
||||||
attachmentHelper::getBodyPartAttachment(ref <const bodyPart> part)
|
(ref <const bodyPart> part, const unsigned int options)
|
||||||
{
|
{
|
||||||
if (!isBodyPartAnAttachment(part))
|
if (!isBodyPartAnAttachment(part, options))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
mediaType type;
|
mediaType type;
|
||||||
@ -140,22 +150,24 @@ ref <const attachment>
|
|||||||
|
|
||||||
// static
|
// static
|
||||||
const std::vector <ref <const attachment> >
|
const std::vector <ref <const attachment> >
|
||||||
attachmentHelper::findAttachmentsInMessage(ref <const message> msg)
|
attachmentHelper::findAttachmentsInMessage
|
||||||
|
(ref <const message> msg, const unsigned int options)
|
||||||
{
|
{
|
||||||
return findAttachmentsInBodyPart(msg);
|
return findAttachmentsInBodyPart(msg, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
const std::vector <ref <const attachment> >
|
const std::vector <ref <const attachment> >
|
||||||
attachmentHelper::findAttachmentsInBodyPart(ref <const bodyPart> part)
|
attachmentHelper::findAttachmentsInBodyPart
|
||||||
|
(ref <const bodyPart> part, const unsigned int options)
|
||||||
{
|
{
|
||||||
std::vector <ref <const attachment> > atts;
|
std::vector <ref <const attachment> > atts;
|
||||||
|
|
||||||
// Test this part
|
// Test this part
|
||||||
if (isBodyPartAnAttachment(part))
|
if (isBodyPartAnAttachment(part, options))
|
||||||
{
|
{
|
||||||
atts.push_back(getBodyPartAttachment(part));
|
atts.push_back(getBodyPartAttachment(part, options));
|
||||||
}
|
}
|
||||||
// Find in sub-parts
|
// Find in sub-parts
|
||||||
else
|
else
|
||||||
@ -165,7 +177,7 @@ const std::vector <ref <const attachment> >
|
|||||||
for (int i = 0 ; i < bdy->getPartCount() ; ++i)
|
for (int i = 0 ; i < bdy->getPartCount() ; ++i)
|
||||||
{
|
{
|
||||||
std::vector <ref <const attachment> > partAtts =
|
std::vector <ref <const attachment> > partAtts =
|
||||||
findAttachmentsInBodyPart(bdy->getPartAt(i));
|
findAttachmentsInBodyPart(bdy->getPartAt(i), options);
|
||||||
|
|
||||||
std::copy(partAtts.begin(), partAtts.end(), std::back_inserter(atts));
|
std::copy(partAtts.begin(), partAtts.end(), std::back_inserter(atts));
|
||||||
}
|
}
|
||||||
|
@ -30,10 +30,6 @@
|
|||||||
#include "vmime/attachment.hpp"
|
#include "vmime/attachment.hpp"
|
||||||
#include "vmime/message.hpp"
|
#include "vmime/message.hpp"
|
||||||
|
|
||||||
#if VMIME_HAVE_MESSAGING_FEATURES
|
|
||||||
#include "vmime/net/message.hpp"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
{
|
{
|
||||||
@ -45,31 +41,57 @@ class attachmentHelper
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/** Options for use with the following functions:
|
||||||
|
* findAttachmentsInMessage,
|
||||||
|
* getBodyPartAttachment,
|
||||||
|
* and isBodyPartAnAttachment.
|
||||||
|
*/
|
||||||
|
enum FindOptions
|
||||||
|
{
|
||||||
|
INLINE_OBJECTS = (1 << 0) /**< Recognize and return inline objects. The aim is to
|
||||||
|
consider MHTML objects (parts with a "Content-Id" or
|
||||||
|
a "Content-Location", such as inline images) as attachments. */
|
||||||
|
};
|
||||||
|
|
||||||
/** Test whether a body part is an attachment.
|
/** Test whether a body part is an attachment.
|
||||||
*
|
*
|
||||||
* @param part message part to test
|
* @param part message part to test
|
||||||
|
* @param options search options (see FindOptions)
|
||||||
* @return true if the part is an attachment, false otherwise
|
* @return true if the part is an attachment, false otherwise
|
||||||
*/
|
*/
|
||||||
static bool isBodyPartAnAttachment(ref <const bodyPart> part);
|
static bool isBodyPartAnAttachment(ref <const bodyPart> part, const unsigned int options = 0);
|
||||||
|
|
||||||
/** Return attachment information in the specified body part.
|
/** Return attachment information in the specified body part.
|
||||||
* If the specified body part does not contain attachment
|
* If the specified body part does not contain attachment
|
||||||
* information (ie. is not an attachment), NULL is returned.
|
* information (ie. is not an attachment), NULL is returned.
|
||||||
*
|
*
|
||||||
* @param part message part in which to search
|
* @param part message part in which to search
|
||||||
|
* @param options search options (see FindOptions)
|
||||||
* @return attachment found in the part, or NULL
|
* @return attachment found in the part, or NULL
|
||||||
*/
|
*/
|
||||||
static ref <const attachment>
|
static ref <const attachment>
|
||||||
getBodyPartAttachment(ref <const bodyPart> part);
|
getBodyPartAttachment(ref <const bodyPart> part, const unsigned int options = 0);
|
||||||
|
|
||||||
|
/** Find all attachments contained in the specified part
|
||||||
|
* and all its children parts.
|
||||||
|
* This is simply a recursive call to getBodyPartAttachment().
|
||||||
|
*
|
||||||
|
* @param part part in which to search
|
||||||
|
* @param options search options (see FindOptions)
|
||||||
|
* @return a list of attachments found
|
||||||
|
*/
|
||||||
|
static const std::vector <ref <const attachment> >
|
||||||
|
findAttachmentsInBodyPart(ref <const bodyPart> part, const unsigned int options = 0);
|
||||||
|
|
||||||
/** Find all attachments contained in the specified message.
|
/** Find all attachments contained in the specified message.
|
||||||
* This is simply a recursive call to getBodyPartAttachment().
|
* This is simply a recursive call to getBodyPartAttachment().
|
||||||
*
|
*
|
||||||
* @param msg message in which to search
|
* @param msg message in which to search
|
||||||
|
* @param options search options (see FindOptions)
|
||||||
* @return a list of attachments found
|
* @return a list of attachments found
|
||||||
*/
|
*/
|
||||||
static const std::vector <ref <const attachment> >
|
static const std::vector <ref <const attachment> >
|
||||||
findAttachmentsInMessage(ref <const message> msg);
|
findAttachmentsInMessage(ref <const message> msg, const unsigned int options = 0);
|
||||||
|
|
||||||
/** Add an attachment to the specified message.
|
/** Add an attachment to the specified message.
|
||||||
*
|
*
|
||||||
@ -87,9 +109,6 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
static const std::vector <ref <const attachment> >
|
|
||||||
findAttachmentsInBodyPart(ref <const bodyPart> part);
|
|
||||||
|
|
||||||
static ref <bodyPart> findBodyPart
|
static ref <bodyPart> findBodyPart
|
||||||
(ref <bodyPart> part, const mediaType& type);
|
(ref <bodyPart> part, const mediaType& type);
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user