aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/attachmentHelper.cpp63
-rw-r--r--src/body.cpp130
-rw-r--r--src/bodyPartAttachment.cpp68
-rw-r--r--src/header.cpp10
-rw-r--r--src/htmlTextPart.cpp71
-rw-r--r--src/mdn/receivedMDNInfos.cpp29
-rw-r--r--src/messageParser.cpp64
-rw-r--r--src/misc/importanceHelper.cpp34
-rw-r--r--src/net/transport.cpp68
-rw-r--r--src/plainTextPart.cpp23
-rw-r--r--tests/misc/importanceHelperTest.cpp4
-rw-r--r--vmime/header.hpp36
12 files changed, 297 insertions, 303 deletions
diff --git a/src/attachmentHelper.cpp b/src/attachmentHelper.cpp
index 7168fd93..152daeed 100644
--- a/src/attachmentHelper.cpp
+++ b/src/attachmentHelper.cpp
@@ -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
- {
- 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 <const mediaType>();
+ if (ctf)
+ {
+ type = *ctf->getValue <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,23 +215,16 @@ 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))
{
- if (msg->getHeader()->hasField(fields::CONTENT_TYPE))
- {
- container->getHeader()->ContentType()->setValue
- (msg->getHeader()->ContentType()->getValue());
- }
-
- if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING))
- {
- container->getHeader()->ContentTransferEncoding()->setValue
- (msg->getHeader()->ContentTransferEncoding()->getValue());
- }
+ container->getHeader()->ContentType()->setValue
+ (msg->getHeader()->ContentType()->getValue());
}
- catch (exceptions::no_such_field&)
+
+ if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING))
{
- // Ignore
+ container->getHeader()->ContentTransferEncoding()->setValue
+ (msg->getHeader()->ContentTransferEncoding()->getValue());
}
// Move parts from the root part to this new part
diff --git a/src/body.cpp b/src/body.cpp
index 8d6bab3f..8251ab1f 100644
--- a/src/body.cpp
+++ b/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 =
- m_part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
+ 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 =
- m_part->getHeader()->findField(fields::CONTENT_TRANSFER_ENCODING);
+ 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
- {
- shared_ptr <contentTypeField> ctf =
- m_part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
+ // 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&)
+ {
+ // No boundary string specified
+ boundary = generateRandomBoundaryString();
+ }
}
- catch (exceptions::no_such_parameter&)
+ else
{
- // Warning: no boundary string specified!
+ // 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);
+ 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)
{
+ shared_ptr <contentTypeField> ctf =
+ m_part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
+
// If a Content-Type field exists, set charset
- try
+ if (ctf)
{
- shared_ptr <contentTypeField> ctf =
- m_part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
-
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,19 +696,22 @@ 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);
+ const shared_ptr <const contentTypeField> ctf =
+ m_part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
- return (ctf->getCharset());
- }
- catch (exceptions::no_such_parameter&)
+ if (ctf)
{
- // Defaults to "us-ascii" (RFC-1521)
- return (vmime::charset(charsets::US_ASCII));
+ try
+ {
+ return (ctf->getCharset());
+ }
+ catch (exceptions::no_such_parameter&)
+ {
+ // 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 =
- m_part->getHeader()->findField(fields::CONTENT_TRANSFER_ENCODING);
+ shared_ptr <const headerField> cef =
+ m_part->getHeader()->findField(fields::CONTENT_TRANSFER_ENCODING);
+ if (cef)
+ {
return *cef->getValue <encoding>();
}
- catch (exceptions::no_such_field&)
+ else
{
if (m_contents->isEncoded())
- {
return m_contents->getEncoding();
- }
- else
- {
- // Defaults to "7bit" (RFC-1521)
- return vmime::encoding(encodingTypes::SEVEN_BIT);
- }
}
+
+ // 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);
+ 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());
diff --git a/src/bodyPartAttachment.cpp b/src/bodyPartAttachment.cpp
index c8361238..7b9adf01 100644
--- a/src/bodyPartAttachment.cpp
+++ b/src/bodyPartAttachment.cpp
@@ -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,
- mediaTypes::APPLICATION_OCTET_STREAM);
+ return mediaType(mediaTypes::APPLICATION,
+ mediaTypes::APPLICATION_OCTET_STREAM);
}
-
- return type;
}
@@ -58,36 +56,46 @@ const word bodyPartAttachment::getName() const
word name;
// Try the 'filename' parameter of 'Content-Disposition' field
- try
+ shared_ptr <const contentDispositionField> cdf = getContentDisposition();
+
+ if (cdf)
{
- name = getContentDisposition()->getFilename();
+ try
+ {
+ name = cdf->getFilename();
+ }
+ catch (exceptions::no_such_parameter&)
+ {
+ // No 'filename' parameter
+ }
}
- catch (exceptions::no_such_field&)
+ else
{
// 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
- {
- shared_ptr <parameter> prm = getContentType()->findParameter("name");
+ shared_ptr <const contentTypeField> ctf = getContentType();
- if (prm != NULL)
- name = prm->getValue();
- }
- catch (exceptions::no_such_field&)
+ if (ctf)
{
- // No 'Content-Type' field
+ try
+ {
+ shared_ptr <const parameter> prm = ctf->findParameter("name");
+
+ if (prm != NULL)
+ name = prm->getValue();
+ }
+ catch (exceptions::no_such_parameter&)
+ {
+ // No attachment name available
+ }
}
- catch (exceptions::no_such_parameter&)
+ else
{
- // No attachment name available
+ // No 'Content-Type' field
}
}
@@ -99,14 +107,14 @@ const text bodyPartAttachment::getDescription() const
{
text description;
- try
- {
- shared_ptr <const headerField> cd =
- getHeader()->findField(fields::CONTENT_DESCRIPTION);
+ 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.
}
diff --git a/src/header.cpp b/src/header.cpp
index 8e04cadc..2dc07b8f 100644
--- a/src/header.cpp
+++ b/src/header.cpp
@@ -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);
- }
+ return (*pos);
}
diff --git a/src/htmlTextPart.cpp b/src/htmlTextPart.cpp
index 0aabbdc4..e97161cb 100644
--- a/src/htmlTextPart.cpp
+++ b/src/htmlTextPart.cpp
@@ -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,20 +194,24 @@ void htmlTextPart::parse(shared_ptr <const bodyPart> message, shared_ptr <const
m_text = textPart->getBody()->getContents()->clone();
- try
- {
- const shared_ptr <const contentTypeField> ctf =
- textPart->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
+ // 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.
+ }
}
- catch (exceptions::no_such_parameter)
+ else
{
- // No "charset" parameter.
+ // No "Content-type" field.
}
// Extract embedded objects. The algorithm is quite simple: for each previously
@@ -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);
+ 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,10 +291,11 @@ 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 shared_ptr <const headerField> ctf =
- p->getHeader()->findField(fields::CONTENT_TYPE);
const mediaType type = *ctf->getValue <mediaType>();
@@ -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.
}
diff --git a/src/mdn/receivedMDNInfos.cpp b/src/mdn/receivedMDNInfos.cpp
index 1c523be7..53b2281e 100644
--- a/src/mdn/receivedMDNInfos.cpp
+++ b/src/mdn/receivedMDNInfos.cpp
@@ -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 */ }
-
- try { m_disp = *fields.Disposition()->getValue <disposition>(); }
- catch (exceptions::no_such_field&) { /* Ignore */ }
-
- try
- {
- text t = *fields.findField("Received-content-MIC")->getValue <text>();
- m_contentMIC = t.generate();
- }
- catch (exceptions::no_such_field&) { /* Ignore */ }
+ shared_ptr <messageId> omid =
+ fields.findFieldValue <messageId>(fields::ORIGINAL_MESSAGE_ID);
+
+ if (omid)
+ m_omid = *omid;
+
+ 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();
}
}
}
diff --git a/src/messageParser.cpp b/src/messageParser.cpp
index 41be3803..5fe219f3 100644
--- a/src/messageParser.cpp
+++ b/src/messageParser.cpp
@@ -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,22 +82,20 @@ 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&)
+ else
{
- try
- {
- const headerField& date = *msg->getHeader()->findField(fields::DATE);
- m_date = *date.getValue <datetime>();
- }
- catch (vmime::exceptions::no_such_field&)
- {
+ shared_ptr <const headerField> date = msg->getHeader()->findField(fields::DATE);
+
+ if (date)
+ m_date = *date->getValue <datetime>();
+ else
m_date = datetime::now();
- }
}
// Attachments
@@ -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);
+ 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.
}
diff --git a/src/misc/importanceHelper.cpp b/src/misc/importanceHelper.cpp
index 8066cc5f..b13f7466 100644
--- a/src/misc/importanceHelper.cpp
+++ b/src/misc/importanceHelper.cpp
@@ -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");
+ shared_ptr <headerField> fld;
+
+ if ((fld = hdr->findField("X-Priority")))
hdr->removeField(fld);
- }
- catch (exceptions::no_such_field)
- {
- // Ignore
- }
- try
- {
- shared_ptr <headerField> fld = hdr->findField("Importance");
+ 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);
diff --git a/src/net/transport.cpp b/src/net/transport.cpp
index eae4a024..dd7281d0 100644
--- a/src/net/transport.cpp
+++ b/src/net/transport.cpp
@@ -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
- mailbox sender;
+ shared_ptr <mailbox> senderMbox =
+ msg->getHeader()->findFieldValue <mailbox>(fields::SENDER);
- try
- {
- const mailbox& mbox =
- *msg->getHeader()->findField(fields::SENDER)->getValue <mailbox>();
+ mailbox sender;
- 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
diff --git a/src/plainTextPart.cpp b/src/plainTextPart.cpp
index e1959af1..bdb76c4d 100644
--- a/src/plainTextPart.cpp
+++ b/src/plainTextPart.cpp
@@ -75,20 +75,23 @@ void plainTextPart::parse(shared_ptr <const bodyPart> /* message */,
{
m_text = vmime::clone(textPart->getBody()->getContents());
- try
- {
- const contentTypeField& ctf =
- *textPart->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
+ 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.
+ }
}
- catch (exceptions::no_such_parameter&)
+ else
{
- // No "charset" parameter.
+ // No "Content-type" field.
}
}
diff --git a/tests/misc/importanceHelperTest.cpp b/tests/misc/importanceHelperTest.cpp
index 9a4b86f7..53c5c679 100644
--- a/tests/misc/importanceHelperTest.cpp
+++ b/tests/misc/importanceHelperTest.cpp
@@ -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"));
}
diff --git a/vmime/header.hpp b/vmime/header.hpp
index b073e8cb..96548b48 100644
--- a/vmime/header.hpp
+++ b/vmime/header.hpp
@@ -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.
*