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