Do not throw exception for normal code flow (exceptions::no_such_field).
This commit is contained in:
parent
b075256d8d
commit
96077ce7e6
@ -41,12 +41,14 @@ namespace vmime
|
||||
bool attachmentHelper::isBodyPartAnAttachment
|
||||
(shared_ptr <const bodyPart> part, const unsigned int options)
|
||||
{
|
||||
try
|
||||
{
|
||||
const contentDispositionField& cdf =
|
||||
*part->getHeader()->findField <contentDispositionField>(fields::CONTENT_DISPOSITION);
|
||||
// First, try with "Content-Disposition" field.
|
||||
// If not present, we will try with "Content-Type" field.
|
||||
shared_ptr <const contentDispositionField> cdf =
|
||||
part->getHeader()->findField <contentDispositionField>(fields::CONTENT_DISPOSITION);
|
||||
|
||||
const contentDisposition disp = *cdf.getValue <const contentDisposition>();
|
||||
if (cdf)
|
||||
{
|
||||
const contentDisposition disp = *cdf->getValue <contentDisposition>();
|
||||
|
||||
if (disp.getName() != contentDispositionTypes::INLINE)
|
||||
return true;
|
||||
@ -68,26 +70,22 @@ bool attachmentHelper::isBodyPartAnAttachment
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
{
|
||||
// Will try using Content-Type
|
||||
}
|
||||
|
||||
// Assume "attachment" if type is not "text/..." or "multipart/...".
|
||||
mediaType type;
|
||||
bool hasContentTypeName = false;
|
||||
|
||||
try
|
||||
shared_ptr <const contentTypeField> ctf =
|
||||
part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
|
||||
if (ctf)
|
||||
{
|
||||
const contentTypeField& ctf =
|
||||
*part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
type = *ctf->getValue <mediaType>();
|
||||
|
||||
type = *ctf.getValue <const mediaType>();
|
||||
|
||||
if (ctf.hasParameter("name"))
|
||||
if (ctf->hasParameter("name"))
|
||||
hasContentTypeName = true;
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
else
|
||||
{
|
||||
// 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
|
||||
@ -132,14 +130,14 @@ shared_ptr <const attachment> attachmentHelper::getBodyPartAttachment
|
||||
|
||||
mediaType type;
|
||||
|
||||
try
|
||||
{
|
||||
const contentTypeField& ctf =
|
||||
*part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
shared_ptr <const contentTypeField> ctf =
|
||||
part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
|
||||
type = *ctf.getValue <mediaType>();
|
||||
if (ctf)
|
||||
{
|
||||
type = *ctf->getValue <mediaType>();
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
else
|
||||
{
|
||||
// No "Content-type" field: assume "application/octet-stream".
|
||||
type = mediaType(mediaTypes::APPLICATION,
|
||||
@ -217,8 +215,6 @@ void attachmentHelper::addAttachment(shared_ptr <message> msg, shared_ptr <attac
|
||||
// the root part of the message
|
||||
shared_ptr <bodyPart> container = make_shared <bodyPart>();
|
||||
|
||||
try
|
||||
{
|
||||
if (msg->getHeader()->hasField(fields::CONTENT_TYPE))
|
||||
{
|
||||
container->getHeader()->ContentType()->setValue
|
||||
@ -230,11 +226,6 @@ void attachmentHelper::addAttachment(shared_ptr <message> msg, shared_ptr <attac
|
||||
container->getHeader()->ContentTransferEncoding()->setValue
|
||||
(msg->getHeader()->ContentTransferEncoding()->getValue());
|
||||
}
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
|
||||
// Move parts from the root part to this new part
|
||||
const std::vector <shared_ptr <bodyPart> > partList =
|
||||
|
94
src/body.cpp
94
src/body.cpp
@ -150,15 +150,16 @@ void body::parseImpl
|
||||
return;
|
||||
}
|
||||
|
||||
// Check whether the body is a MIME-multipart
|
||||
// Check whether the body is a MIME-multipart.
|
||||
// If it is, also get (or try to guess) the boundary separator.
|
||||
bool isMultipart = false;
|
||||
string boundary;
|
||||
|
||||
try
|
||||
{
|
||||
const shared_ptr <const contentTypeField> ctf =
|
||||
shared_ptr <const contentTypeField> ctf =
|
||||
m_part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
|
||||
if (ctf)
|
||||
{
|
||||
const mediaType type = *ctf->getValue <mediaType>();
|
||||
|
||||
if (type.getType() == mediaTypes::MULTIPART)
|
||||
@ -239,10 +240,6 @@ void body::parseImpl
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
{
|
||||
// No "Content-Type" field...
|
||||
}
|
||||
|
||||
// This is a multi-part body
|
||||
if (isMultipart && !boundary.empty())
|
||||
@ -353,14 +350,14 @@ void body::parseImpl
|
||||
{
|
||||
encoding enc;
|
||||
|
||||
try
|
||||
{
|
||||
const shared_ptr <headerField> cef =
|
||||
shared_ptr <const headerField> cef =
|
||||
m_part->getHeader()->findField(fields::CONTENT_TRANSFER_ENCODING);
|
||||
|
||||
if (cef)
|
||||
{
|
||||
enc = *cef->getValue <encoding>();
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
else
|
||||
{
|
||||
// Defaults to "7bit" (RFC-1521)
|
||||
enc = vmime::encoding(encodingTypes::SEVEN_BIT);
|
||||
@ -432,21 +429,26 @@ void body::generateImpl
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
// Use current boundary string, if specified. If no "Content-Type" field is
|
||||
// present, or the boundary is not specified, generate a random one
|
||||
shared_ptr <contentTypeField> ctf =
|
||||
m_part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
|
||||
boundary = ctf->getBoundary();
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
if (ctf)
|
||||
{
|
||||
// Warning: no content-type and no boundary string specified!
|
||||
boundary = generateRandomBoundaryString();
|
||||
try
|
||||
{
|
||||
boundary = ctf->getBoundary();
|
||||
}
|
||||
catch (exceptions::no_such_parameter&)
|
||||
{
|
||||
// Warning: no boundary string specified!
|
||||
// No boundary string specified
|
||||
boundary = generateRandomBoundaryString();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No Content-Type (and no boundary string specified)
|
||||
boundary = generateRandomBoundaryString();
|
||||
}
|
||||
}
|
||||
@ -658,14 +660,14 @@ void body::setContentType(const mediaType& type)
|
||||
|
||||
const mediaType body::getContentType() const
|
||||
{
|
||||
try
|
||||
{
|
||||
shared_ptr <const contentTypeField> ctf =
|
||||
m_part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
|
||||
return (*ctf->getValue <mediaType>());
|
||||
if (ctf)
|
||||
{
|
||||
return *ctf->getValue <mediaType>();
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
else
|
||||
{
|
||||
// Defaults to "text/plain" (RFC-1521)
|
||||
return (mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN));
|
||||
@ -675,17 +677,17 @@ const mediaType body::getContentType() const
|
||||
|
||||
void body::setCharset(const charset& chset)
|
||||
{
|
||||
// If a Content-Type field exists, set charset
|
||||
try
|
||||
{
|
||||
shared_ptr <contentTypeField> ctf =
|
||||
m_part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
|
||||
// If a Content-Type field exists, set charset
|
||||
if (ctf)
|
||||
{
|
||||
ctf->setCharset(chset);
|
||||
}
|
||||
// Else, create a new Content-Type field of default type "text/plain"
|
||||
// and set charset on it
|
||||
catch (exceptions::no_such_field&)
|
||||
else
|
||||
{
|
||||
setContentType(mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN), chset);
|
||||
}
|
||||
@ -694,11 +696,13 @@ void body::setCharset(const charset& chset)
|
||||
|
||||
const charset body::getCharset() const
|
||||
{
|
||||
try
|
||||
{
|
||||
const shared_ptr <const contentTypeField> ctf =
|
||||
m_part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
|
||||
if (ctf)
|
||||
{
|
||||
try
|
||||
{
|
||||
return (ctf->getCharset());
|
||||
}
|
||||
catch (exceptions::no_such_parameter&)
|
||||
@ -706,7 +710,8 @@ const charset body::getCharset() const
|
||||
// Defaults to "us-ascii" (RFC-1521)
|
||||
return (vmime::charset(charsets::US_ASCII));
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Defaults to "us-ascii" (RFC-1521)
|
||||
return (vmime::charset(charsets::US_ASCII));
|
||||
@ -722,25 +727,21 @@ void body::setEncoding(const encoding& enc)
|
||||
|
||||
const encoding body::getEncoding() const
|
||||
{
|
||||
try
|
||||
{
|
||||
const shared_ptr <const headerField> cef =
|
||||
shared_ptr <const headerField> cef =
|
||||
m_part->getHeader()->findField(fields::CONTENT_TRANSFER_ENCODING);
|
||||
|
||||
if (cef)
|
||||
{
|
||||
return *cef->getValue <encoding>();
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
{
|
||||
if (m_contents->isEncoded())
|
||||
{
|
||||
return m_contents->getEncoding();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (m_contents->isEncoded())
|
||||
return m_contents->getEncoding();
|
||||
}
|
||||
|
||||
// Defaults to "7bit" (RFC-1521)
|
||||
return vmime::encoding(encodingTypes::SEVEN_BIT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -879,11 +880,11 @@ void body::initNewPart(shared_ptr <bodyPart> part)
|
||||
shared_ptr <header> hdr = m_part->getHeader();
|
||||
|
||||
// Check whether we have a boundary string
|
||||
try
|
||||
{
|
||||
shared_ptr <contentTypeField> ctf =
|
||||
hdr->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
|
||||
if (ctf)
|
||||
{
|
||||
try
|
||||
{
|
||||
const string boundary = ctf->getBoundary();
|
||||
@ -903,12 +904,11 @@ void body::initNewPart(shared_ptr <bodyPart> part)
|
||||
// not specified as "multipart/..."
|
||||
}
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
else
|
||||
{
|
||||
// No "Content-Type" field: create a new one and generate
|
||||
// a random boundary string.
|
||||
shared_ptr <contentTypeField> ctf =
|
||||
hdr->getField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
ctf = hdr->getField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
|
||||
ctf->setValue(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED));
|
||||
ctf->setBoundary(generateRandomBoundaryString());
|
||||
|
@ -36,20 +36,18 @@ bodyPartAttachment::bodyPartAttachment(shared_ptr <const bodyPart> part)
|
||||
|
||||
const mediaType bodyPartAttachment::getType() const
|
||||
{
|
||||
mediaType type;
|
||||
shared_ptr <const contentTypeField> ctf = getContentType();
|
||||
|
||||
try
|
||||
if (ctf)
|
||||
{
|
||||
type = *getContentType()->getValue <mediaType>();
|
||||
return *ctf->getValue <mediaType>();
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
else
|
||||
{
|
||||
// No "Content-type" field: assume "application/octet-stream".
|
||||
type = mediaType(mediaTypes::APPLICATION,
|
||||
return mediaType(mediaTypes::APPLICATION,
|
||||
mediaTypes::APPLICATION_OCTET_STREAM);
|
||||
}
|
||||
|
||||
return type;
|
||||
}
|
||||
|
||||
|
||||
@ -58,38 +56,48 @@ const word bodyPartAttachment::getName() const
|
||||
word name;
|
||||
|
||||
// Try the 'filename' parameter of 'Content-Disposition' field
|
||||
shared_ptr <const contentDispositionField> cdf = getContentDisposition();
|
||||
|
||||
if (cdf)
|
||||
{
|
||||
try
|
||||
{
|
||||
name = getContentDisposition()->getFilename();
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
{
|
||||
// No 'Content-Disposition' field
|
||||
name = cdf->getFilename();
|
||||
}
|
||||
catch (exceptions::no_such_parameter&)
|
||||
{
|
||||
// No 'filename' parameter
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No 'Content-Disposition' field
|
||||
}
|
||||
|
||||
// Try the 'name' parameter of 'Content-Type' field
|
||||
if (name.getBuffer().empty())
|
||||
{
|
||||
shared_ptr <const contentTypeField> ctf = getContentType();
|
||||
|
||||
if (ctf)
|
||||
{
|
||||
try
|
||||
{
|
||||
shared_ptr <parameter> prm = getContentType()->findParameter("name");
|
||||
shared_ptr <const parameter> prm = ctf->findParameter("name");
|
||||
|
||||
if (prm != NULL)
|
||||
name = prm->getValue();
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
{
|
||||
// No 'Content-Type' field
|
||||
}
|
||||
catch (exceptions::no_such_parameter&)
|
||||
{
|
||||
// No attachment name available
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No 'Content-Type' field
|
||||
}
|
||||
}
|
||||
|
||||
return name;
|
||||
}
|
||||
@ -99,14 +107,14 @@ const text bodyPartAttachment::getDescription() const
|
||||
{
|
||||
text description;
|
||||
|
||||
try
|
||||
{
|
||||
shared_ptr <const headerField> cd =
|
||||
getHeader()->findField(fields::CONTENT_DESCRIPTION);
|
||||
|
||||
if (cd)
|
||||
{
|
||||
description = *cd->getValue <text>();
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
else
|
||||
{
|
||||
// No description available.
|
||||
}
|
||||
|
@ -171,14 +171,10 @@ shared_ptr <headerField> header::findField(const string& fieldName) const
|
||||
|
||||
// No field with this name can be found
|
||||
if (pos == m_fields.end())
|
||||
{
|
||||
throw exceptions::no_such_field();
|
||||
}
|
||||
return null;
|
||||
|
||||
// Else, return a reference to the existing field
|
||||
else
|
||||
{
|
||||
return (*pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -135,27 +135,13 @@ void htmlTextPart::findEmbeddedParts(const bodyPart& part,
|
||||
{
|
||||
shared_ptr <const bodyPart> p = part.getBody()->getPartAt(i);
|
||||
|
||||
// For a part to be an embedded object, it must have a
|
||||
// For a part to be an embedded object, it must have either a
|
||||
// Content-Id field or a Content-Location field.
|
||||
try
|
||||
{
|
||||
p->getHeader()->findField(fields::CONTENT_ID);
|
||||
if (p->getHeader()->hasField(fields::CONTENT_ID))
|
||||
cidParts.push_back(p);
|
||||
}
|
||||
catch (exceptions::no_such_field)
|
||||
{
|
||||
// No "Content-id" field.
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
p->getHeader()->findField(fields::CONTENT_LOCATION);
|
||||
if (p->getHeader()->hasField(fields::CONTENT_LOCATION))
|
||||
locParts.push_back(p);
|
||||
}
|
||||
catch (exceptions::no_such_field)
|
||||
{
|
||||
// No "Content-Location" field.
|
||||
}
|
||||
|
||||
findEmbeddedParts(*p, cidParts, locParts);
|
||||
}
|
||||
@ -172,12 +158,14 @@ void htmlTextPart::addEmbeddedObject(const bodyPart& part, const string& id,
|
||||
|
||||
mediaType type;
|
||||
|
||||
try
|
||||
shared_ptr <const headerField> ctf =
|
||||
part.getHeader()->findField(fields::CONTENT_TYPE);
|
||||
|
||||
if (ctf)
|
||||
{
|
||||
const shared_ptr <const headerField> ctf = part.getHeader()->ContentType();
|
||||
type = *ctf->getValue <mediaType>();
|
||||
}
|
||||
catch (exceptions::no_such_field)
|
||||
else
|
||||
{
|
||||
// No "Content-type" field: assume "application/octet-stream".
|
||||
}
|
||||
@ -206,21 +194,25 @@ void htmlTextPart::parse(shared_ptr <const bodyPart> message, shared_ptr <const
|
||||
|
||||
m_text = textPart->getBody()->getContents()->clone();
|
||||
|
||||
try
|
||||
{
|
||||
const shared_ptr <const contentTypeField> ctf =
|
||||
// Find charset
|
||||
shared_ptr <const contentTypeField> ctf =
|
||||
textPart->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
|
||||
m_charset = ctf->getCharset();
|
||||
}
|
||||
catch (exceptions::no_such_field)
|
||||
if (ctf)
|
||||
{
|
||||
// No "Content-type" field.
|
||||
try
|
||||
{
|
||||
m_charset = ctf->getCharset();
|
||||
}
|
||||
catch (exceptions::no_such_parameter)
|
||||
{
|
||||
// No "charset" parameter.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No "Content-type" field.
|
||||
}
|
||||
|
||||
// Extract embedded objects. The algorithm is quite simple: for each previously
|
||||
// found inline part, we check if its CID/Location is contained in the HTML text.
|
||||
@ -267,11 +259,11 @@ void htmlTextPart::parse(shared_ptr <const bodyPart> message, shared_ptr <const
|
||||
bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& parent, const bodyPart& textPart)
|
||||
{
|
||||
// We search for the nearest "multipart/alternative" part.
|
||||
try
|
||||
{
|
||||
const shared_ptr <const headerField> ctf =
|
||||
part.getHeader()->findField(fields::CONTENT_TYPE);
|
||||
|
||||
if (ctf)
|
||||
{
|
||||
const mediaType type = *ctf->getValue <mediaType>();
|
||||
|
||||
if (type.getType() == mediaTypes::MULTIPART &&
|
||||
@ -299,11 +291,12 @@ bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& paren
|
||||
{
|
||||
const shared_ptr <const bodyPart> p = part.getBody()->getPartAt(i);
|
||||
|
||||
try
|
||||
{
|
||||
const shared_ptr <const headerField> ctf =
|
||||
p->getHeader()->findField(fields::CONTENT_TYPE);
|
||||
|
||||
if (ctf)
|
||||
{
|
||||
|
||||
const mediaType type = *ctf->getValue <mediaType>();
|
||||
|
||||
if (type.getType() == mediaTypes::TEXT &&
|
||||
@ -313,7 +306,7 @@ bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& paren
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
catch (exceptions::no_such_field)
|
||||
else
|
||||
{
|
||||
// No "Content-type" field.
|
||||
}
|
||||
@ -326,7 +319,7 @@ bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& paren
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (exceptions::no_such_field)
|
||||
else
|
||||
{
|
||||
// No "Content-type" field.
|
||||
}
|
||||
|
@ -110,18 +110,23 @@ void receivedMDNInfos::extract()
|
||||
header fields;
|
||||
fields.parse(oss.str());
|
||||
|
||||
try { m_omid = *fields.OriginalMessageId()->getValue <messageId>(); }
|
||||
catch (exceptions::no_such_field&) { /* Ignore */ }
|
||||
shared_ptr <messageId> omid =
|
||||
fields.findFieldValue <messageId>(fields::ORIGINAL_MESSAGE_ID);
|
||||
|
||||
try { m_disp = *fields.Disposition()->getValue <disposition>(); }
|
||||
catch (exceptions::no_such_field&) { /* Ignore */ }
|
||||
if (omid)
|
||||
m_omid = *omid;
|
||||
|
||||
try
|
||||
{
|
||||
text t = *fields.findField("Received-content-MIC")->getValue <text>();
|
||||
m_contentMIC = t.generate();
|
||||
}
|
||||
catch (exceptions::no_such_field&) { /* Ignore */ }
|
||||
shared_ptr <disposition> disp =
|
||||
fields.findFieldValue <disposition>(fields::DISPOSITION);
|
||||
|
||||
if (disp)
|
||||
m_disp = *disp;
|
||||
|
||||
shared_ptr <text> contentMIC =
|
||||
fields.findFieldValue <text>("Received-content-MIC");
|
||||
|
||||
if (contentMIC)
|
||||
m_contentMIC = contentMIC->generate();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -63,8 +63,11 @@ void messageParser::parse(shared_ptr <const message> msg)
|
||||
#ifndef VMIME_BUILDING_DOC
|
||||
|
||||
#define TRY_FIELD(var, type, name) \
|
||||
try { var = *msg->getHeader()->findField(name)->getValue <type>(); } \
|
||||
catch (exceptions::no_such_field) { }
|
||||
{ \
|
||||
shared_ptr <type> fldValue = msg->getHeader()->findFieldValue <type>(name); \
|
||||
if (fldValue) \
|
||||
var = *fldValue; \
|
||||
}
|
||||
|
||||
TRY_FIELD(m_from, mailbox, fields::FROM);
|
||||
|
||||
@ -79,23 +82,21 @@ void messageParser::parse(shared_ptr <const message> msg)
|
||||
#endif // VMIME_BUILDING_DOC
|
||||
|
||||
// Date
|
||||
try
|
||||
shared_ptr <const headerField> recv = msg->getHeader()->findField(fields::RECEIVED);
|
||||
|
||||
if (recv)
|
||||
{
|
||||
const headerField& recv = *msg->getHeader()->findField(fields::RECEIVED);
|
||||
m_date = recv.getValue <relay>()->getDate();
|
||||
m_date = recv->getValue <relay>()->getDate();
|
||||
}
|
||||
catch (vmime::exceptions::no_such_field&)
|
||||
{
|
||||
try
|
||||
{
|
||||
const headerField& date = *msg->getHeader()->findField(fields::DATE);
|
||||
m_date = *date.getValue <datetime>();
|
||||
}
|
||||
catch (vmime::exceptions::no_such_field&)
|
||||
else
|
||||
{
|
||||
shared_ptr <const headerField> date = msg->getHeader()->findField(fields::DATE);
|
||||
|
||||
if (date)
|
||||
m_date = *date->getValue <datetime>();
|
||||
else
|
||||
m_date = datetime::now();
|
||||
}
|
||||
}
|
||||
|
||||
// Attachments
|
||||
findAttachments(msg);
|
||||
@ -120,13 +121,12 @@ void messageParser::findTextParts(shared_ptr <const bodyPart> msg, shared_ptr <c
|
||||
mediaType type(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN);
|
||||
bool accept = false;
|
||||
|
||||
try
|
||||
{
|
||||
const contentTypeField& ctf =
|
||||
*msg->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
shared_ptr <const contentTypeField> ctf =
|
||||
msg->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
|
||||
const mediaType ctfType =
|
||||
*ctf.getValue <mediaType>();
|
||||
if (ctf)
|
||||
{
|
||||
const mediaType ctfType = *ctf->getValue <mediaType>();
|
||||
|
||||
if (ctfType.getType() == mediaTypes::TEXT)
|
||||
{
|
||||
@ -134,7 +134,7 @@ void messageParser::findTextParts(shared_ptr <const bodyPart> msg, shared_ptr <c
|
||||
accept = true;
|
||||
}
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
else
|
||||
{
|
||||
// No "Content-type" field: assume "text/plain".
|
||||
accept = true;
|
||||
@ -169,24 +169,24 @@ bool messageParser::findSubTextParts(shared_ptr <const bodyPart> msg, shared_ptr
|
||||
{
|
||||
const shared_ptr <const bodyPart> p = part->getBody()->getPartAt(i);
|
||||
|
||||
try
|
||||
{
|
||||
const contentTypeField& ctf =
|
||||
*p->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
shared_ptr <const contentTypeField> ctf =
|
||||
p->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
|
||||
const mediaType type = *ctf.getValue <mediaType>();
|
||||
if (ctf)
|
||||
{
|
||||
const mediaType type = *ctf->getValue <mediaType>();
|
||||
contentDisposition disp; // default should be inline
|
||||
|
||||
if (type.getType() == mediaTypes::TEXT)
|
||||
{
|
||||
try
|
||||
{
|
||||
shared_ptr <const contentDispositionField> cdf = p->getHeader()->
|
||||
findField <contentDispositionField>(fields::CONTENT_DISPOSITION);
|
||||
|
||||
if (cdf)
|
||||
{
|
||||
disp = *cdf->getValue <contentDisposition>();
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
else
|
||||
{
|
||||
// No "Content-Disposition" field, assume default
|
||||
}
|
||||
@ -195,7 +195,7 @@ bool messageParser::findSubTextParts(shared_ptr <const bodyPart> msg, shared_ptr
|
||||
textParts.push_back(p);
|
||||
}
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
else
|
||||
{
|
||||
// No "Content-type" field.
|
||||
}
|
||||
|
@ -39,25 +39,13 @@ void importanceHelper::resetImportance(shared_ptr <message> msg)
|
||||
|
||||
void importanceHelper::resetImportanceHeader(shared_ptr <header> hdr)
|
||||
{
|
||||
try
|
||||
{
|
||||
shared_ptr <headerField> fld = hdr->findField("X-Priority");
|
||||
hdr->removeField(fld);
|
||||
}
|
||||
catch (exceptions::no_such_field)
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
shared_ptr <headerField> fld;
|
||||
|
||||
try
|
||||
{
|
||||
shared_ptr <headerField> fld = hdr->findField("Importance");
|
||||
if ((fld = hdr->findField("X-Priority")))
|
||||
hdr->removeField(fld);
|
||||
|
||||
if ((fld = hdr->findField("Importance")))
|
||||
hdr->removeField(fld);
|
||||
}
|
||||
catch (exceptions::no_such_field)
|
||||
{
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -70,9 +58,10 @@ importanceHelper::Importance importanceHelper::getImportance(shared_ptr <const m
|
||||
importanceHelper::Importance importanceHelper::getImportanceHeader(shared_ptr <const header> hdr)
|
||||
{
|
||||
// Try "X-Priority" field
|
||||
try
|
||||
shared_ptr <const headerField> fld = hdr->findField("X-Priority");
|
||||
|
||||
if (fld)
|
||||
{
|
||||
const shared_ptr <const headerField> fld = hdr->findField("X-Priority");
|
||||
const string value = fld->getValue <text>()->getWholeBuffer();
|
||||
|
||||
int n = IMPORTANCE_NORMAL;
|
||||
@ -93,12 +82,13 @@ importanceHelper::Importance importanceHelper::getImportanceHeader(shared_ptr <c
|
||||
|
||||
return (i);
|
||||
}
|
||||
catch (exceptions::no_such_field)
|
||||
else
|
||||
{
|
||||
// Try "Importance" field
|
||||
try
|
||||
fld = hdr->findField("Importance");
|
||||
|
||||
if (fld)
|
||||
{
|
||||
const shared_ptr <const headerField> fld = hdr->findField("Importance");
|
||||
const string value = utility::stringUtils::toLower(utility::stringUtils::trim
|
||||
(fld->getValue <text>()->getWholeBuffer()));
|
||||
|
||||
@ -109,7 +99,7 @@ importanceHelper::Importance importanceHelper::getImportanceHeader(shared_ptr <c
|
||||
else
|
||||
return (IMPORTANCE_NORMAL);
|
||||
}
|
||||
catch (exceptions::no_such_field)
|
||||
else
|
||||
{
|
||||
// Default
|
||||
return (IMPORTANCE_NORMAL);
|
||||
|
@ -125,64 +125,48 @@ static void extractMailboxes
|
||||
void transport::send(shared_ptr <vmime::message> msg, utility::progressListener* progress)
|
||||
{
|
||||
// Extract expeditor
|
||||
mailbox expeditor;
|
||||
shared_ptr <mailbox> fromMbox =
|
||||
msg->getHeader()->findFieldValue <mailbox>(fields::FROM);
|
||||
|
||||
try
|
||||
{
|
||||
const mailbox& mbox =
|
||||
*msg->getHeader()->findField(fields::FROM)->getValue <mailbox>();
|
||||
|
||||
expeditor = mbox;
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
{
|
||||
if (!fromMbox)
|
||||
throw exceptions::no_expeditor();
|
||||
}
|
||||
|
||||
mailbox expeditor = *fromMbox;
|
||||
|
||||
// Extract sender
|
||||
shared_ptr <mailbox> senderMbox =
|
||||
msg->getHeader()->findFieldValue <mailbox>(fields::SENDER);
|
||||
|
||||
mailbox sender;
|
||||
|
||||
try
|
||||
{
|
||||
const mailbox& mbox =
|
||||
*msg->getHeader()->findField(fields::SENDER)->getValue <mailbox>();
|
||||
|
||||
sender = mbox;
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
{
|
||||
if (!senderMbox)
|
||||
sender = expeditor;
|
||||
}
|
||||
else
|
||||
sender = *senderMbox;
|
||||
|
||||
// Extract recipients
|
||||
mailboxList recipients;
|
||||
|
||||
try
|
||||
{
|
||||
const addressList& to =
|
||||
*msg->getHeader()->findField(fields::TO)->getValue <addressList>();
|
||||
// -- "To" field
|
||||
shared_ptr <addressList> addresses =
|
||||
msg->getHeader()->findFieldValue <addressList>(fields::TO);
|
||||
|
||||
extractMailboxes(recipients, to);
|
||||
}
|
||||
catch (exceptions::no_such_field&) { }
|
||||
if (addresses)
|
||||
extractMailboxes(recipients, *addresses);
|
||||
|
||||
try
|
||||
{
|
||||
const addressList& cc =
|
||||
*msg->getHeader()->findField(fields::CC)->getValue <addressList>();
|
||||
// -- "Cc" field
|
||||
addresses =
|
||||
msg->getHeader()->findFieldValue <addressList>(fields::CC);
|
||||
|
||||
extractMailboxes(recipients, cc);
|
||||
}
|
||||
catch (exceptions::no_such_field&) { }
|
||||
if (addresses)
|
||||
extractMailboxes(recipients, *addresses);
|
||||
|
||||
try
|
||||
{
|
||||
const addressList& bcc =
|
||||
*msg->getHeader()->findField(fields::BCC)->getValue <addressList>();
|
||||
// -- "Bcc" field
|
||||
addresses =
|
||||
msg->getHeader()->findFieldValue <addressList>(fields::BCC);
|
||||
|
||||
extractMailboxes(recipients, bcc);
|
||||
}
|
||||
catch (exceptions::no_such_field&) { }
|
||||
if (addresses)
|
||||
extractMailboxes(recipients, *addresses);
|
||||
|
||||
// Process message header by removing fields that should be removed
|
||||
// before transmitting the message to MSA, and adding missing fields
|
||||
|
@ -75,21 +75,24 @@ void plainTextPart::parse(shared_ptr <const bodyPart> /* message */,
|
||||
{
|
||||
m_text = vmime::clone(textPart->getBody()->getContents());
|
||||
|
||||
shared_ptr <const contentTypeField> ctf =
|
||||
textPart->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
|
||||
if (ctf)
|
||||
{
|
||||
try
|
||||
{
|
||||
const contentTypeField& ctf =
|
||||
*textPart->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
|
||||
|
||||
m_charset = ctf.getCharset();
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
{
|
||||
// No "Content-type" field.
|
||||
m_charset = ctf->getCharset();
|
||||
}
|
||||
catch (exceptions::no_such_parameter&)
|
||||
{
|
||||
// No "charset" parameter.
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// No "Content-type" field.
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -59,8 +59,8 @@ VMIME_TEST_SUITE_BEGIN(importanceHelperTest)
|
||||
|
||||
vmime::misc::importanceHelper::resetImportanceHeader(hdr);
|
||||
|
||||
VASSERT_THROW("3", hdr->findField("Importance"), vmime::exceptions::no_such_field);
|
||||
VASSERT_THROW("4", hdr->findField("X-Priority"), vmime::exceptions::no_such_field);
|
||||
VASSERT_NULL("3", hdr->findField("Importance"));
|
||||
VASSERT_NULL("4", hdr->findField("X-Priority"));
|
||||
}
|
||||
|
||||
|
||||
|
@ -90,6 +90,7 @@ public:
|
||||
#undef FIELD_ACCESS
|
||||
|
||||
/** Checks whether (at least) one field with this name exists.
|
||||
* Field name is case-insensitive.
|
||||
*
|
||||
* @return true if at least one field with the specified name
|
||||
* exists, or false otherwise
|
||||
@ -97,18 +98,21 @@ public:
|
||||
bool hasField(const string& fieldName) const;
|
||||
|
||||
/** Find the first field that matches the specified name.
|
||||
* If no field is found, an exception is thrown.
|
||||
* Field name is case-insensitive.
|
||||
* If no field is found, NULL is returned.
|
||||
*
|
||||
* @throw exceptions::no_such_field if no field with this name exists
|
||||
* @return first field with the specified name
|
||||
* @return first field with the specified name, or NULL if no field
|
||||
* with this name was found
|
||||
*/
|
||||
shared_ptr <headerField> findField(const string& fieldName) const;
|
||||
|
||||
/** Find the first field that matches the specified name,
|
||||
* casted to the specified type.
|
||||
* If no field is found, an exception is thrown.
|
||||
* casted to the specified field type. Field name is case-insensitive.
|
||||
* If no field is found, or the field is not of the specified type,
|
||||
* NULL is returned.
|
||||
*
|
||||
* @return value object
|
||||
* @return first field with the specified name, or NULL if no field
|
||||
* with this name was found
|
||||
*/
|
||||
template <typename T>
|
||||
shared_ptr <T> findField(const string& fieldName) const
|
||||
@ -116,6 +120,26 @@ public:
|
||||
return dynamicCast <T>(findField(fieldName));
|
||||
}
|
||||
|
||||
/** Find the value of the first field that matches the specified name,
|
||||
* casted to the specified value type. Field name is case-insensitive.
|
||||
* If no field is found, or the field value is not of the specified
|
||||
* type, NULL is returned.
|
||||
*
|
||||
* @return value of the first field with the specified name, or NULL
|
||||
* if no field with this name was found, or the value is not of the
|
||||
* specified type
|
||||
*/
|
||||
template <typename T>
|
||||
shared_ptr <T> findFieldValue(const string& fieldName) const
|
||||
{
|
||||
shared_ptr <headerField> field = findField(fieldName);
|
||||
|
||||
if (field)
|
||||
return dynamicCast <T>(field->getValue());
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Find all fields that match the specified name.
|
||||
* If no field is found, an empty vector is returned.
|
||||
*
|
||||
|
Loading…
Reference in New Issue
Block a user