Refactoring (see ChangeLog).
This commit is contained in:
parent
6f7f1674f7
commit
2949fb51f1
41
ChangeLog
41
ChangeLog
@ -1,7 +1,46 @@
|
|||||||
|
|
||||||
VERSION 0.5.2-CVS
|
VERSION 0.6.0-cvs
|
||||||
=================
|
=================
|
||||||
|
|
||||||
|
2004-10-21 Vincent Richard <vincent@vincent-richard.net>
|
||||||
|
|
||||||
|
* A _LOT_ of cleaning/refactoring in VMime code:
|
||||||
|
|
||||||
|
- got rid of field types (only using field names now).
|
||||||
|
|
||||||
|
- removed iterators on 'header', 'text', 'addressList', 'mailboxGroup',
|
||||||
|
'propertySet' and 'bodyPart': use access functions instead (iterators
|
||||||
|
made the code difficult to understand). You can always use standard
|
||||||
|
iterators on the container returned by getFieldList(), and so on.
|
||||||
|
|
||||||
|
- migrated to get/set convention for accessors (most of time, just add
|
||||||
|
'get' or 'set' before method name, depending on what it does).
|
||||||
|
|
||||||
|
- dropped 'comp_t' typedef on 'datetime' (useless).
|
||||||
|
|
||||||
|
- moved a lot of code from header (.hpp) to implementation files (.cpp).
|
||||||
|
|
||||||
|
- made all objects cloneable and copiable at the 'component' level:
|
||||||
|
methods component::clone() and component::copyFrom().
|
||||||
|
|
||||||
|
- made a 'typeAdapter' to allow using fondamental/no-vmime types in
|
||||||
|
header field and parameter values.
|
||||||
|
|
||||||
|
- implicit 'operator=' on header fields to set value is not allowed
|
||||||
|
anymore: use setValue() instead or you will get a std::bad_cast
|
||||||
|
exception.
|
||||||
|
|
||||||
|
- 'textParameter' renamed to 'defaultParameter'.
|
||||||
|
|
||||||
|
- vmime::makeWordsFromText() is now vmime::text::newFromString().
|
||||||
|
|
||||||
|
- changed a lot of return type value from reference to pointer, to
|
||||||
|
to avoid confusion.
|
||||||
|
|
||||||
|
2004-10-05 Vincent Richard <vincent@vincent-richard.net>
|
||||||
|
|
||||||
|
* added clone() method on 'component' object.
|
||||||
|
|
||||||
2004-09-09 Vincent Richard <vincent@vincent-richard.net>
|
2004-09-09 Vincent Richard <vincent@vincent-richard.net>
|
||||||
|
|
||||||
* IMAPFolder.cpp: fixed rename(): folder name is now updated.
|
* IMAPFolder.cpp: fixed rename(): folder name is now updated.
|
||||||
|
22
SConstruct
22
SConstruct
@ -28,26 +28,18 @@ import string
|
|||||||
libvmime_sources = [
|
libvmime_sources = [
|
||||||
'address.cpp', 'address.hpp',
|
'address.cpp', 'address.hpp',
|
||||||
'addressList.cpp', 'addressList.hpp',
|
'addressList.cpp', 'addressList.hpp',
|
||||||
'addressListField.cpp', 'addressListField.hpp',
|
|
||||||
'attachment.hpp',
|
'attachment.hpp',
|
||||||
'base.cpp', 'base.hpp',
|
'base.cpp', 'base.hpp',
|
||||||
'body.cpp', 'body.hpp',
|
'body.cpp', 'body.hpp',
|
||||||
'bodyPart.cpp', 'bodyPart.hpp',
|
'bodyPart.cpp', 'bodyPart.hpp',
|
||||||
'charset.cpp', 'charset.hpp',
|
'charset.cpp', 'charset.hpp',
|
||||||
'charsetParameter.cpp', 'charsetParameter.hpp',
|
|
||||||
'component.cpp', 'component.hpp',
|
'component.cpp', 'component.hpp',
|
||||||
'constants.cpp', 'constants.hpp',
|
'constants.cpp', 'constants.hpp',
|
||||||
'contentDispositionField.cpp', 'contentDispositionField.hpp',
|
'contentDispositionField.cpp', 'contentDispositionField.hpp',
|
||||||
'contentEncodingField.cpp', 'contentEncodingField.hpp',
|
|
||||||
'contentHandler.cpp', 'contentHandler.hpp',
|
'contentHandler.cpp', 'contentHandler.hpp',
|
||||||
'contentTypeField.cpp', 'contentTypeField.hpp',
|
'contentTypeField.cpp', 'contentTypeField.hpp',
|
||||||
'dateField.cpp', 'dateField.hpp',
|
|
||||||
'dateParameter.cpp', 'dateParameter.hpp',
|
|
||||||
'dateTime.cpp', 'dateTime.hpp',
|
'dateTime.cpp', 'dateTime.hpp',
|
||||||
'defaultAttachment.cpp', 'defaultAttachment.hpp',
|
'defaultAttachment.cpp', 'defaultAttachment.hpp',
|
||||||
'defaultField.cpp', 'defaultField.hpp',
|
|
||||||
'defaultParameter.cpp', 'defaultParameter.hpp',
|
|
||||||
'defaultParameterizedHeaderField.cpp', 'defaultParameterizedHeaderField.hpp',
|
|
||||||
'disposition.cpp', 'disposition.hpp',
|
'disposition.cpp', 'disposition.hpp',
|
||||||
'encoder.cpp', 'encoder.hpp',
|
'encoder.cpp', 'encoder.hpp',
|
||||||
'encoder7bit.cpp', 'encoder7bit.hpp',
|
'encoder7bit.cpp', 'encoder7bit.hpp',
|
||||||
@ -61,6 +53,8 @@ libvmime_sources = [
|
|||||||
'encoding.cpp', 'encoding.hpp',
|
'encoding.cpp', 'encoding.hpp',
|
||||||
'exception.hpp',
|
'exception.hpp',
|
||||||
'fileAttachment.cpp', 'fileAttachment.hpp',
|
'fileAttachment.cpp', 'fileAttachment.hpp',
|
||||||
|
'genericField.hpp',
|
||||||
|
'genericParameter.hpp',
|
||||||
'header.cpp', 'header.hpp',
|
'header.cpp', 'header.hpp',
|
||||||
'headerFieldFactory.cpp', 'headerFieldFactory.hpp',
|
'headerFieldFactory.cpp', 'headerFieldFactory.hpp',
|
||||||
'headerField.cpp', 'headerField.hpp',
|
'headerField.cpp', 'headerField.hpp',
|
||||||
@ -69,12 +63,10 @@ libvmime_sources = [
|
|||||||
'mailboxField.cpp', 'mailboxField.hpp',
|
'mailboxField.cpp', 'mailboxField.hpp',
|
||||||
'mailboxGroup.cpp', 'mailboxGroup.hpp',
|
'mailboxGroup.cpp', 'mailboxGroup.hpp',
|
||||||
'mailboxList.cpp', 'mailboxList.hpp',
|
'mailboxList.cpp', 'mailboxList.hpp',
|
||||||
'mailboxListField.cpp', 'mailboxListField.hpp',
|
|
||||||
'mediaType.cpp', 'mediaType.hpp',
|
'mediaType.cpp', 'mediaType.hpp',
|
||||||
'messageBuilder.cpp', 'messageBuilder.hpp',
|
'messageBuilder.cpp', 'messageBuilder.hpp',
|
||||||
'message.cpp', 'message.hpp',
|
'message.cpp', 'message.hpp',
|
||||||
'messageId.cpp', 'messageId.hpp',
|
'messageId.cpp', 'messageId.hpp',
|
||||||
'messageIdField.cpp', 'messageIdField.hpp',
|
|
||||||
'messageParser.cpp', 'messageParser.hpp',
|
'messageParser.cpp', 'messageParser.hpp',
|
||||||
'options.cpp', 'options.hpp',
|
'options.cpp', 'options.hpp',
|
||||||
'parameter.cpp', 'parameter.hpp',
|
'parameter.cpp', 'parameter.hpp',
|
||||||
@ -84,12 +76,13 @@ libvmime_sources = [
|
|||||||
'plainTextPart.cpp', 'plainTextPart.hpp',
|
'plainTextPart.cpp', 'plainTextPart.hpp',
|
||||||
'platformDependant.cpp', 'platformDependant.hpp',
|
'platformDependant.cpp', 'platformDependant.hpp',
|
||||||
'propertySet.cpp', 'propertySet.hpp',
|
'propertySet.cpp', 'propertySet.hpp',
|
||||||
'relayField.cpp', 'relayField.hpp',
|
'relay.cpp', 'relay.hpp',
|
||||||
|
'standardFields.hpp',
|
||||||
|
'standardParams.hpp',
|
||||||
'text.cpp', 'text.hpp',
|
'text.cpp', 'text.hpp',
|
||||||
'textField.cpp', 'textField.hpp',
|
|
||||||
'textParameter.cpp', 'textParameter.hpp',
|
|
||||||
'textPartFactory.cpp', 'textPartFactory.hpp',
|
'textPartFactory.cpp', 'textPartFactory.hpp',
|
||||||
'textPart.hpp',
|
'textPart.hpp',
|
||||||
|
'typeAdapter.hpp',
|
||||||
'types.hpp',
|
'types.hpp',
|
||||||
'word.cpp', 'word.hpp',
|
'word.cpp', 'word.hpp',
|
||||||
'vmime',
|
'vmime',
|
||||||
@ -100,7 +93,8 @@ libvmime_sources = [
|
|||||||
'utility/singleton.cpp', 'utility/singleton.hpp',
|
'utility/singleton.cpp', 'utility/singleton.hpp',
|
||||||
'utility/smartPtr.hpp',
|
'utility/smartPtr.hpp',
|
||||||
'utility/stream.cpp', 'utility/stream.hpp',
|
'utility/stream.cpp', 'utility/stream.hpp',
|
||||||
'utility/stringProxy.cpp', 'utility/stringProxy.hpp'
|
'utility/stringProxy.cpp', 'utility/stringProxy.hpp',
|
||||||
|
'utility/stringUtils.cpp', 'utility/stringUtils.hpp'
|
||||||
]
|
]
|
||||||
|
|
||||||
libvmime_examples_sources = [
|
libvmime_examples_sources = [
|
||||||
|
@ -257,7 +257,7 @@ public:
|
|||||||
gmt.tm_isdst = -1;
|
gmt.tm_isdst = -1;
|
||||||
|
|
||||||
// Calculate the difference (in seconds)
|
// Calculate the difference (in seconds)
|
||||||
const vmime::datetime::comp_t diff = ::std::mktime(&local) - ::std::mktime(&gmt);
|
const int diff = ::std::mktime(&local) - ::std::mktime(&gmt);
|
||||||
|
|
||||||
// Return the date
|
// Return the date
|
||||||
return vmime::datetime(local.tm_year + 1900, local.tm_mon + 1, local.tm_mday,
|
return vmime::datetime(local.tm_year + 1900, local.tm_mon + 1, local.tm_mday,
|
||||||
|
@ -45,14 +45,24 @@ int main()
|
|||||||
vmime::messageBuilder mb;
|
vmime::messageBuilder mb;
|
||||||
|
|
||||||
// Fill in the basic fields
|
// Fill in the basic fields
|
||||||
mb.expeditor() = vmime::mailbox("me@somewhere.com");
|
mb.setExpeditor(vmime::mailbox("me@somewhere.com"));
|
||||||
mb.recipients().append(vmime::mailbox("you@elsewhere.com"));
|
|
||||||
mb.blindCopyRecipients().append(vmime::mailbox("you-bcc@nowhere.com"));
|
vmime::addressList to;
|
||||||
mb.subject() = vmime::text("My first message generated with vmime::messageBuilder");
|
to.appendAddress(new vmime::mailbox("you@elsewhere.com"));
|
||||||
|
|
||||||
|
mb.setRecipients(to);
|
||||||
|
|
||||||
|
vmime::addressList bcc;
|
||||||
|
bcc.appendAddress(new vmime::mailbox("you-bcc@nowhere.com"));
|
||||||
|
|
||||||
|
mb.setBlindCopyRecipients(bcc);
|
||||||
|
|
||||||
|
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
|
||||||
|
|
||||||
// Message body
|
// Message body
|
||||||
mb.textPart().text() = "I'm writing this short text to test message construction " \
|
mb.getTextPart()->setText(vmime::contentHandler(
|
||||||
"using the vmime::messageBuilder component.";
|
"I'm writing this short text to test message construction " \
|
||||||
|
"using the vmime::messageBuilder component."));
|
||||||
|
|
||||||
// Construction
|
// Construction
|
||||||
vmime::message* msg = mb.construct();
|
vmime::message* msg = mb.construct();
|
||||||
@ -61,7 +71,7 @@ int main()
|
|||||||
std::cout << "Generated message:" << std::endl;
|
std::cout << "Generated message:" << std::endl;
|
||||||
std::cout << "==================" << std::endl;
|
std::cout << "==================" << std::endl;
|
||||||
|
|
||||||
vmime::outputStreamAdapter out(std::cout);
|
vmime::utility::outputStreamAdapter out(std::cout);
|
||||||
msg->generate(out);
|
msg->generate(out);
|
||||||
|
|
||||||
// Destruction
|
// Destruction
|
||||||
@ -77,7 +87,7 @@ int main()
|
|||||||
catch (std::exception& e)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
std::cout << "std::exception: " << e.what() << std::endl;
|
std::cout << "std::exception: " << e.what() << std::endl;
|
||||||
throw;
|
//throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
@ -45,14 +45,24 @@ int main()
|
|||||||
vmime::messageBuilder mb;
|
vmime::messageBuilder mb;
|
||||||
|
|
||||||
// Fill in the basic fields
|
// Fill in the basic fields
|
||||||
mb.expeditor() = vmime::mailbox("me@somewhere.com");
|
mb.setExpeditor(vmime::mailbox("me@somewhere.com"));
|
||||||
mb.recipients().append(vmime::mailbox("you@elsewhere.com"));
|
|
||||||
mb.blindCopyRecipients().append(vmime::mailbox("you-bcc@nowhere.com"));
|
vmime::addressList to;
|
||||||
mb.subject() = vmime::text("My first message generated with vmime::messageBuilder");
|
to.appendAddress(new vmime::mailbox("you@elsewhere.com"));
|
||||||
|
|
||||||
|
mb.setRecipients(to);
|
||||||
|
|
||||||
|
vmime::addressList bcc;
|
||||||
|
bcc.appendAddress(new vmime::mailbox("you-bcc@nowhere.com"));
|
||||||
|
|
||||||
|
mb.setBlindCopyRecipients(bcc);
|
||||||
|
|
||||||
|
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
|
||||||
|
|
||||||
// Message body
|
// Message body
|
||||||
mb.textPart().text() = "I'm writing this short text to test message construction " \
|
mb.getTextPart()->setText(vmime::contentHandler(
|
||||||
"with attachment, using the vmime::messageBuilder component.";
|
"I'm writing this short text to test message construction " \
|
||||||
|
"with attachment, using the vmime::messageBuilder component."));
|
||||||
|
|
||||||
// Adding an attachment
|
// Adding an attachment
|
||||||
vmime::fileAttachment* a = new vmime::fileAttachment
|
vmime::fileAttachment* a = new vmime::fileAttachment
|
||||||
@ -62,8 +72,8 @@ int main()
|
|||||||
vmime::text("My first attachment") // description
|
vmime::text("My first attachment") // description
|
||||||
);
|
);
|
||||||
|
|
||||||
a->fileInfo().setFilename("example2.cpp");
|
a->getFileInfo().setFilename("example2.cpp");
|
||||||
a->fileInfo().setCreationDate(vmime::datetime("30 Apr 2003 14:30:00 +0200"));
|
a->getFileInfo().setCreationDate(vmime::datetime("30 Apr 2003 14:30:00 +0200"));
|
||||||
|
|
||||||
mb.attach(a);
|
mb.attach(a);
|
||||||
|
|
||||||
|
@ -45,10 +45,19 @@ int main()
|
|||||||
vmime::messageBuilder mb;
|
vmime::messageBuilder mb;
|
||||||
|
|
||||||
// Fill in the basic fields
|
// Fill in the basic fields
|
||||||
mb.expeditor() = vmime::mailbox("me@somewhere.com");
|
mb.setExpeditor(vmime::mailbox("me@somewhere.com"));
|
||||||
mb.recipients().append(vmime::mailbox("you@elsewhere.com"));
|
|
||||||
mb.blindCopyRecipients().append(vmime::mailbox("you-bcc@nowhere.com"));
|
vmime::addressList to;
|
||||||
mb.subject() = vmime::text("My first message generated with vmime::messageBuilder");
|
to.appendAddress(new vmime::mailbox("you@elsewhere.com"));
|
||||||
|
|
||||||
|
mb.setRecipients(to);
|
||||||
|
|
||||||
|
vmime::addressList bcc;
|
||||||
|
bcc.appendAddress(new vmime::mailbox("you-bcc@nowhere.com"));
|
||||||
|
|
||||||
|
mb.setBlindCopyRecipients(bcc);
|
||||||
|
|
||||||
|
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
|
||||||
|
|
||||||
// Set the content-type to "text/html"
|
// Set the content-type to "text/html"
|
||||||
mb.constructTextPart(vmime::mediaType
|
mb.constructTextPart(vmime::mediaType
|
||||||
@ -56,16 +65,16 @@ int main()
|
|||||||
|
|
||||||
// Fill in the text part: the message is available in two formats: HTML and plain text.
|
// Fill in the text part: the message is available in two formats: HTML and plain text.
|
||||||
// HTML text part also includes an inline image (embedded into the message).
|
// HTML text part also includes an inline image (embedded into the message).
|
||||||
vmime::htmlTextPart& textPart = dynamic_cast<vmime::htmlTextPart&>(mb.textPart());
|
vmime::htmlTextPart& textPart = dynamic_cast<vmime::htmlTextPart&>(*mb.getTextPart());
|
||||||
|
|
||||||
// -- embed an image (the returned "CID" (content identifier) is used to reference
|
// -- embed an image (the returned "CID" (content identifier) is used to reference
|
||||||
// -- the image into HTML content).
|
// -- the image into HTML content).
|
||||||
vmime::string cid = textPart.embeddedObjects.add("<...IMAGE DATA...>",
|
vmime::string cid = textPart.addObject("<...IMAGE DATA...>",
|
||||||
vmime::mediaType(vmime::mediaTypes::IMAGE, vmime::mediaTypes::IMAGE_JPEG));
|
vmime::mediaType(vmime::mediaTypes::IMAGE, vmime::mediaTypes::IMAGE_JPEG));
|
||||||
|
|
||||||
// -- message text
|
// -- message text
|
||||||
textPart.text() = vmime::string("This is the <b>HTML text</b>.<br/><img src=\"") + cid + vmime::string("\"/>");
|
textPart.setText(vmime::contentHandler(vmime::string("This is the <b>HTML text</b>.<br/><img src=\"") + cid + vmime::string("\"/>")));
|
||||||
textPart.plainText() = vmime::string("This is the plain text (without HTML formatting).");
|
textPart.setPlainText(vmime::contentHandler(vmime::string("This is the plain text (without HTML formatting).")));
|
||||||
|
|
||||||
// Construction
|
// Construction
|
||||||
vmime::message* msg = mb.construct();
|
vmime::message* msg = mb.construct();
|
||||||
|
@ -44,28 +44,28 @@ int main()
|
|||||||
vmime::messageParser mp("<...MIME message content...>");
|
vmime::messageParser mp("<...MIME message content...>");
|
||||||
|
|
||||||
// Enumerate text parts
|
// Enumerate text parts
|
||||||
for (std::vector <vmime::textPart*>::const_iterator i = mp.textParts().begin() ;
|
for (int i = 0 ; i < mp.getTextPartCount() ; ++i)
|
||||||
i != mp.textParts().end() ; ++i)
|
|
||||||
{
|
{
|
||||||
const vmime::textPart& part = **i;
|
const vmime::textPart& part = *mp.getTextPartAt(i);
|
||||||
|
|
||||||
// Output content-type of the part
|
// Output content-type of the part
|
||||||
std::cout << part.type().generate() << std::endl;
|
std::cout << part.getType().generate() << std::endl;
|
||||||
|
|
||||||
// text/html
|
// text/html
|
||||||
if (part.type().subType() == vmime::mediaTypes::TEXT_HTML)
|
if (part.getType().getSubType() == vmime::mediaTypes::TEXT_HTML)
|
||||||
{
|
{
|
||||||
const vmime::htmlTextPart& hp = dynamic_cast<const vmime::htmlTextPart&>(part);
|
const vmime::htmlTextPart& hp = dynamic_cast<const vmime::htmlTextPart&>(part);
|
||||||
|
|
||||||
// HTML text is in "hp.text()"
|
// HTML text is in "hp.getText()"
|
||||||
// Corresponding plain text is in "hp.plainText()"
|
// Corresponding plain text is in "hp.getPlainText()"
|
||||||
|
|
||||||
// Enumerate embedded objects (eg. images)
|
// Enumerate embedded objects (eg. images)
|
||||||
for (vmime::htmlTextPart::const_iterator i = hp.embeddedObjects.begin() ;
|
for (int j = 0 ; j < hp.getObjectCount() ; ++j)
|
||||||
i != hp.embeddedObjects.end() ; ++i)
|
|
||||||
{
|
{
|
||||||
// Identifier (content-id or content-location) is in "(*i).id()"
|
const vmime::htmlTextPart::embeddedObject& obj = *hp.getObjectAt(j);
|
||||||
// Object data is in "(*i).data()"
|
|
||||||
|
// Identifier (content-id or content-location) is in "obj.getId()"
|
||||||
|
// Object data is in "obj.getData()"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// text/plain
|
// text/plain
|
||||||
@ -73,7 +73,7 @@ int main()
|
|||||||
{
|
{
|
||||||
const vmime::textPart& tp = dynamic_cast<const vmime::textPart&>(part);
|
const vmime::textPart& tp = dynamic_cast<const vmime::textPart&>(part);
|
||||||
|
|
||||||
// Text is in "tp.text()"
|
// Text is in "tp.getText()"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -45,12 +45,13 @@ int main()
|
|||||||
vmime::messageParser mp("<...MIME message content...>");
|
vmime::messageParser mp("<...MIME message content...>");
|
||||||
|
|
||||||
// Enumerate attachments
|
// Enumerate attachments
|
||||||
for (std::vector <vmime::attachment*>::const_iterator i = mp.attachments().begin() ;
|
for (int i = 0 ; i < mp.getAttachmentCount() ; ++i)
|
||||||
i != mp.attachments().end() ; ++i)
|
|
||||||
{
|
{
|
||||||
// Media type (content type) is in "(*i).type()"
|
const vmime::attachment& att = *mp.getAttachmentAt(i);
|
||||||
// Description is in "(*i).description()"
|
|
||||||
// Data is in "(*i).data()"
|
// Media type (content type) is in "att.getType()"
|
||||||
|
// Description is in "att.getDescription()"
|
||||||
|
// Data is in "att.getData()"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// VMime exception
|
// VMime exception
|
||||||
|
@ -49,19 +49,19 @@ class my_auth : public vmime::messaging::authenticator
|
|||||||
|
|
||||||
void printStructure(const vmime::messaging::structure& s, int level = 0)
|
void printStructure(const vmime::messaging::structure& s, int level = 0)
|
||||||
{
|
{
|
||||||
for (int i = 1 ; i <= s.count() ; ++i)
|
for (int i = 1 ; i <= s.getCount() ; ++i)
|
||||||
{
|
{
|
||||||
const vmime::messaging::part& part = s[i];
|
const vmime::messaging::part& part = s[i];
|
||||||
|
|
||||||
for (int j = 0 ; j < level * 2 ; ++j)
|
for (int j = 0 ; j < level * 2 ; ++j)
|
||||||
std::cout << " ";
|
std::cout << " ";
|
||||||
|
|
||||||
std::cout << part.number() << ". "
|
std::cout << part.getNumber() << ". "
|
||||||
<< part.type().generate()
|
<< part.getType().generate()
|
||||||
<< " [" << part.size() << " byte(s)]"
|
<< " [" << part.getSize() << " byte(s)]"
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
|
|
||||||
printStructure(part.structure(), level + 1);
|
printStructure(part.getStructure(), level + 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,22 +76,23 @@ int main()
|
|||||||
// Test the new enumeration system for encoders
|
// Test the new enumeration system for encoders
|
||||||
//
|
//
|
||||||
|
|
||||||
#if 0
|
#if 1
|
||||||
vmime::encoderFactory* ef = vmime::encoderFactory::getInstance();
|
vmime::encoderFactory* ef = vmime::encoderFactory::getInstance();
|
||||||
|
|
||||||
std::cout << "Available encoders:" << std::endl;
|
std::cout << "Available encoders:" << std::endl;
|
||||||
|
|
||||||
for (vmime::encoderFactory::iterator it = ef->begin() ;
|
for (int i = 0 ; i < ef->getEncoderCount() ; ++i)
|
||||||
it != ef->end() ; ++it)
|
|
||||||
{
|
{
|
||||||
std::cout << " * " << (*it).name() << std::endl;
|
const vmime::encoderFactory::registeredEncoder& enc = *ef->getEncoderAt(i);
|
||||||
|
|
||||||
vmime::encoder* e = (*it).create();
|
std::cout << " * " << enc.getName() << std::endl;
|
||||||
|
|
||||||
std::vector <vmime::string> props = e->availableProperties();
|
vmime::encoder* e = enc.create();
|
||||||
|
|
||||||
for (std::vector <vmime::string>::const_iterator it2 = props.begin() ; it2 != props.end() ; ++it2)
|
std::vector <vmime::string> props = e->getAvailableProperties();
|
||||||
std::cout << " - " << *it2 << std::endl;
|
|
||||||
|
for (std::vector <vmime::string>::const_iterator it = props.begin() ; it != props.end() ; ++it)
|
||||||
|
std::cout << " - " << *it << std::endl;
|
||||||
|
|
||||||
delete (e);
|
delete (e);
|
||||||
}
|
}
|
||||||
@ -108,21 +109,22 @@ int main()
|
|||||||
|
|
||||||
std::cout << "Available messaging services:" << std::endl;
|
std::cout << "Available messaging services:" << std::endl;
|
||||||
|
|
||||||
for (vmime::messaging::serviceFactory::const_iterator it = sf->begin() ;
|
for (int i = 0 ; i < sf->getServiceCount() ; ++i)
|
||||||
it != sf->end() ; ++it)
|
|
||||||
{
|
{
|
||||||
std::cout << " * " << (*it).name() << " (" << (*it).infos().defaultPort() << ")" << std::endl;
|
const vmime::messaging::serviceFactory::registeredService& serv = *sf->getServiceAt(i);
|
||||||
|
|
||||||
std::vector <vmime::string> props = (*it).infos().availableProperties();
|
std::cout << " * " << serv.getName() << " (" << serv.getInfos().getDefaultPort() << ")" << std::endl;
|
||||||
|
|
||||||
for (std::vector <vmime::string>::const_iterator it2 = props.begin() ; it2 != props.end() ; ++it2)
|
std::vector <vmime::string> props = serv.getInfos().getAvailableProperties();
|
||||||
std::cout << " - " << (*it).infos().propertyPrefix() + *it2 << std::endl;
|
|
||||||
|
for (std::vector <vmime::string>::const_iterator it = props.begin() ; it != props.end() ; ++it)
|
||||||
|
std::cout << " - " << serv.getInfos().getPropertyPrefix() + *it << std::endl;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vmime::messaging::session sess;
|
vmime::messaging::session sess;
|
||||||
sess.properties()["store.protocol"] = "imap";
|
sess.getProperties()["store.protocol"] = "imap";
|
||||||
sess.properties()["transport.protocol"] = "smtp";
|
sess.getProperties()["transport.protocol"] = "smtp";
|
||||||
|
|
||||||
my_auth auth;
|
my_auth auth;
|
||||||
|
|
||||||
@ -136,12 +138,12 @@ int main()
|
|||||||
// Transport protocol configuration
|
// Transport protocol configuration
|
||||||
vmime::messaging::transport* tr = sess.getTransport();
|
vmime::messaging::transport* tr = sess.getTransport();
|
||||||
|
|
||||||
//sess.properties()[tr->infos().propertyPrefix() + "auth.username"] = "username";
|
//sess.getProperties()[tr->getInfos().getPropertyPrefix() + "auth.username"] = "username";
|
||||||
//sess.properties()[tr->infos().propertyPrefix() + "auth.password"] = "password";
|
//sess.getProperties()[tr->getInfos().getPropertyPrefix() + "auth.password"] = "password";
|
||||||
|
|
||||||
sess.properties()[tr->infos().propertyPrefix() + "server.address"] = "smtp.mydomain.com";
|
sess.getProperties()[tr->getInfos().getPropertyPrefix() + "server.address"] = "smtp.mydomain.com";
|
||||||
|
|
||||||
//sess.properties()[tr->infos().propertyPrefix() + "options.need-authentification"] = true;
|
//sess.getProperties()[tr->getInfos().getPropertyPrefix() + "options.need-authentification"] = true;
|
||||||
|
|
||||||
// Connection
|
// Connection
|
||||||
tr->connect();
|
tr->connect();
|
||||||
@ -151,8 +153,8 @@ int main()
|
|||||||
|
|
||||||
// Recipients list
|
// Recipients list
|
||||||
vmime::mailboxList to;
|
vmime::mailboxList to;
|
||||||
to.append(vmime::mailbox("you@somewhere.com"));
|
to.appendMailbox(new vmime::mailbox("you@somewhere.com"));
|
||||||
to.append(vmime::mailbox("somebody.else@anywhere.com"));
|
to.appendMailbox(new vmime::mailbox("somebody.else@anywhere.com"));
|
||||||
|
|
||||||
std::istringstream iss("[MESSAGE DATA: HEADER + BODY]");
|
std::istringstream iss("[MESSAGE DATA: HEADER + BODY]");
|
||||||
tr->send(from, to, iss);
|
tr->send(from, to, iss);
|
||||||
@ -176,15 +178,15 @@ int main()
|
|||||||
vmime::messaging::store* st = sess.getStore(&auth);
|
vmime::messaging::store* st = sess.getStore(&auth);
|
||||||
|
|
||||||
// Store protocol configuration
|
// Store protocol configuration
|
||||||
//sess.properties()[st->infos().propertyPrefix() + "auth.username"] = "username";
|
//sess.getProperties()[st->getInfos().getPropertyPrefix() + "auth.username"] = "username";
|
||||||
//sess.properties()[st->infos().propertyPrefix() + "auth.password"] = "password";
|
//sess.getProperties()[st->getInfos().getPropertyPrefix() + "auth.password"] = "password";
|
||||||
|
|
||||||
sess.properties()[st->infos().propertyPrefix() + "server.address"] = "imap.mydomain.com";
|
sess.getProperties()[st->getInfos().getPropertyPrefix() + "server.address"] = "imap.mydomain.com";
|
||||||
//sess.properties()[st->infos().propertyPrefix() + "server.port"] = 110;
|
//sess.getProperties()[st->getInfos().getPropertyPrefix() + "server.port"] = 110;
|
||||||
//sess.properties()[st->infos().propertyPrefix() + "server.socket-factory"] = "default";
|
//sess.getProperties()[st->getInfos().getPropertyPrefix() + "server.socket-factory"] = "default";
|
||||||
|
|
||||||
//sess.properties()[st->infos().propertyPrefix() + "options.apop"] = false;
|
//sess.getProperties()[st->getInfos().getPropertyPrefix() + "options.apop"] = false;
|
||||||
//sess.properties()[st->infos().propertyPrefix() + "options.apop.fallback"] = true;
|
//sess.getProperties()[st->getInfos().getPropertyPrefix() + "options.apop.fallback"] = true;
|
||||||
|
|
||||||
// Connection
|
// Connection
|
||||||
st->connect();
|
st->connect();
|
||||||
@ -205,7 +207,7 @@ int main()
|
|||||||
|
|
||||||
// To retrieve the whole message
|
// To retrieve the whole message
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
vmime::outputStreamAdapter out(oss);
|
vmime::utility::outputStreamAdapter out(oss);
|
||||||
|
|
||||||
m->extract(out);
|
m->extract(out);
|
||||||
|
|
||||||
@ -223,55 +225,55 @@ int main()
|
|||||||
std::cout << "STRUCTURE:" << std::endl;
|
std::cout << "STRUCTURE:" << std::endl;
|
||||||
std::cout << "==========" << std::endl;
|
std::cout << "==========" << std::endl;
|
||||||
|
|
||||||
printStructure(m->structure());
|
printStructure(m->getStructure());
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
std::cout << "Size = " << m->size() << " byte(s)" << std::endl;
|
std::cout << "Size = " << m->getSize() << " byte(s)" << std::endl;
|
||||||
std::cout << "UID = " << m->uniqueId() << std::endl;
|
std::cout << "UID = " << m->getUniqueId() << std::endl;
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
std::cout << "ENVELOPE:" << std::endl;
|
std::cout << "ENVELOPE:" << std::endl;
|
||||||
std::cout << "=========" << std::endl;
|
std::cout << "=========" << std::endl;
|
||||||
try { std::cout << m->header().fields.From().generate() << std::endl; } catch (...) { }
|
try { std::cout << m->getHeader().From().generate() << std::endl; } catch (...) { }
|
||||||
try { std::cout << m->header().fields.To().generate() << std::endl; } catch (...) { }
|
try { std::cout << m->getHeader().To().generate() << std::endl; } catch (...) { }
|
||||||
try { std::cout << m->header().fields.Date().generate() << std::endl; } catch (...) { }
|
try { std::cout << m->getHeader().Date().generate() << std::endl; } catch (...) { }
|
||||||
try { std::cout << m->header().fields.Subject().generate() << std::endl; } catch (...) { }
|
try { std::cout << m->getHeader().Subject().generate() << std::endl; } catch (...) { }
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
|
|
||||||
std::cout << "FULL HEADER:" << std::endl;
|
std::cout << "FULL HEADER:" << std::endl;
|
||||||
std::cout << "============" << std::endl;
|
std::cout << "============" << std::endl;
|
||||||
std::cout << m->header().generate() << std::endl;
|
std::cout << m->getHeader().generate() << std::endl;
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << "=========================================================" << std::endl;
|
std::cout << "=========================================================" << std::endl;
|
||||||
|
|
||||||
vmime::outputStreamAdapter out2(std::cout);
|
vmime::utility::outputStreamAdapter out2(std::cout);
|
||||||
m->extractPart(m->structure()[1][2][1], out2, NULL); //, 0, 10);
|
m->extractPart(m->getStructure()[1][2][1], out2, NULL); //, 0, 10);
|
||||||
|
|
||||||
std::cout << "=========================================================" << std::endl;
|
std::cout << "=========================================================" << std::endl;
|
||||||
|
|
||||||
std::cout << std::endl;
|
std::cout << std::endl;
|
||||||
std::cout << "=========================================================" << std::endl;
|
std::cout << "=========================================================" << std::endl;
|
||||||
|
|
||||||
m->fetchPartHeader(m->structure()[1][2][1]);
|
m->fetchPartHeader(m->getStructure()[1][2][1]);
|
||||||
|
|
||||||
std::cout << m->structure()[1][2][1].header().generate() << std::endl;
|
std::cout << m->getStructure()[1][2][1].getHeader().generate() << std::endl;
|
||||||
|
|
||||||
std::cout << "=========================================================" << std::endl;
|
std::cout << "=========================================================" << std::endl;
|
||||||
|
|
||||||
// Flags manipulation
|
// Flags manipulation
|
||||||
std::cout << "Flags = " << m->flags() << std::endl;
|
std::cout << "Flags = " << m->getFlags() << std::endl;
|
||||||
m->setFlags(vmime::messaging::message::FLAG_REPLIED, vmime::messaging::message::FLAG_MODE_ADD);
|
m->setFlags(vmime::messaging::message::FLAG_REPLIED, vmime::messaging::message::FLAG_MODE_ADD);
|
||||||
std::cout << "Flags = " << m->flags() << std::endl;
|
std::cout << "Flags = " << m->getFlags() << std::endl;
|
||||||
m->setFlags(vmime::messaging::message::FLAG_REPLIED, vmime::messaging::message::FLAG_MODE_REMOVE);
|
m->setFlags(vmime::messaging::message::FLAG_REPLIED, vmime::messaging::message::FLAG_MODE_REMOVE);
|
||||||
std::cout << "Flags = " << m->flags() << std::endl;
|
std::cout << "Flags = " << m->getFlags() << std::endl;
|
||||||
|
|
||||||
f->setMessageFlags(m->number(), m->number(), vmime::messaging::message::FLAG_REPLIED, vmime::messaging::message::FLAG_MODE_ADD);
|
f->setMessageFlags(m->getNumber(), m->getNumber(), vmime::messaging::message::FLAG_REPLIED, vmime::messaging::message::FLAG_MODE_ADD);
|
||||||
std::cout << "Flags = " << m->flags() << std::endl;
|
std::cout << "Flags = " << m->getFlags() << std::endl;
|
||||||
f->setMessageFlags(m->number(), m->number(), vmime::messaging::message::FLAG_REPLIED, vmime::messaging::message::FLAG_MODE_REMOVE);
|
f->setMessageFlags(m->getNumber(), m->getNumber(), vmime::messaging::message::FLAG_REPLIED, vmime::messaging::message::FLAG_MODE_REMOVE);
|
||||||
std::cout << "Flags = " << m->flags() << std::endl;
|
std::cout << "Flags = " << m->getFlags() << std::endl;
|
||||||
|
|
||||||
|
|
||||||
std::cout << "=========================================================" << std::endl;
|
std::cout << "=========================================================" << std::endl;
|
||||||
@ -312,7 +314,7 @@ int main()
|
|||||||
if (!g->exists())
|
if (!g->exists())
|
||||||
g->create(vmime::messaging::folder::TYPE_CONTAINS_MESSAGES);
|
g->create(vmime::messaging::folder::TYPE_CONTAINS_MESSAGES);
|
||||||
|
|
||||||
f->copyMessages(g->fullPath());
|
f->copyMessages(g->getFullPath());
|
||||||
|
|
||||||
delete (g);
|
delete (g);
|
||||||
}
|
}
|
||||||
|
@ -191,11 +191,4 @@ address* address::parseNext(const string& buffer, const string::size_type positi
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
address& address::operator=(const address& addr)
|
|
||||||
{
|
|
||||||
copyFrom(addr);
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -45,33 +45,13 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Copy data from another object to this object.
|
|
||||||
* Both objects must be the same type.
|
|
||||||
*
|
|
||||||
* @param addr other object
|
|
||||||
*/
|
|
||||||
address& operator=(const address& addr);
|
|
||||||
|
|
||||||
/** Duplicate this object.
|
|
||||||
*
|
|
||||||
* @return a copy of this object
|
|
||||||
*/
|
|
||||||
virtual address* clone() const = 0;
|
|
||||||
|
|
||||||
/** Copy data from another object to this object.
|
|
||||||
* Both objects must be the same type.
|
|
||||||
*
|
|
||||||
* @param addr other object
|
|
||||||
*/
|
|
||||||
virtual void copyFrom(const address& addr) = 0;
|
|
||||||
|
|
||||||
/** Check whether this address is empty (no mailboxes specified
|
/** Check whether this address is empty (no mailboxes specified
|
||||||
* if this is a mailboxGroup -or- no email specified if this is
|
* if this is a mailboxGroup -or- no email specified if this is
|
||||||
* a mailbox).
|
* a mailbox).
|
||||||
*
|
*
|
||||||
* @return true if this address is empty
|
* @return true if this address is empty
|
||||||
*/
|
*/
|
||||||
virtual const bool empty() const = 0;
|
virtual const bool isEmpty() const = 0;
|
||||||
|
|
||||||
/** Test whether this is object is a mailboxGroup.
|
/** Test whether this is object is a mailboxGroup.
|
||||||
*
|
*
|
||||||
@ -79,6 +59,8 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual const bool isGroup() const = 0;
|
virtual const bool isGroup() const = 0;
|
||||||
|
|
||||||
|
virtual address* clone() const = 0;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
/** Parse an address from an input buffer.
|
/** Parse an address from an input buffer.
|
||||||
|
@ -19,6 +19,8 @@
|
|||||||
|
|
||||||
#include "addressList.hpp"
|
#include "addressList.hpp"
|
||||||
#include "parserHelpers.hpp"
|
#include "parserHelpers.hpp"
|
||||||
|
#include "exception.hpp"
|
||||||
|
#include "mailboxList.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
@ -30,23 +32,23 @@ addressList::addressList()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
addressList::addressList(const class addressList& addressList)
|
addressList::addressList(const addressList& addrList)
|
||||||
: component()
|
: component()
|
||||||
{
|
{
|
||||||
copyFrom(addressList);
|
copyFrom(addrList);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
addressList::~addressList()
|
addressList::~addressList()
|
||||||
{
|
{
|
||||||
clear();
|
removeAllAddresses();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::parse(const string& buffer, const string::size_type position,
|
void addressList::parse(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
clear();
|
removeAllAddresses();
|
||||||
|
|
||||||
string::size_type pos = position;
|
string::size_type pos = position;
|
||||||
|
|
||||||
@ -69,11 +71,11 @@ void addressList::generate(utility::outputStream& os, const string::size_type ma
|
|||||||
if (!m_list.empty())
|
if (!m_list.empty())
|
||||||
{
|
{
|
||||||
string::size_type pos = curLinePos;
|
string::size_type pos = curLinePos;
|
||||||
const_iterator i = m_list.begin();
|
std::vector <address*>::const_iterator i = m_list.begin();
|
||||||
|
|
||||||
for ( ; ; )
|
for ( ; ; )
|
||||||
{
|
{
|
||||||
(*i).generate(os, maxLineLength - 2, pos, &pos);
|
(*i)->generate(os, maxLineLength - 2, pos, &pos);
|
||||||
|
|
||||||
if (++i != m_list.end())
|
if (++i != m_list.end())
|
||||||
{
|
{
|
||||||
@ -92,97 +94,158 @@ void addressList::generate(utility::outputStream& os, const string::size_type ma
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Return the number of addresses in the list.
|
void addressList::copyFrom(const component& other)
|
||||||
*
|
|
||||||
* @return number of addresses in the list
|
|
||||||
*/
|
|
||||||
|
|
||||||
const std::vector <address*>::size_type addressList::size() const
|
|
||||||
{
|
{
|
||||||
return (m_list.size());
|
const addressList& addrList = dynamic_cast <const addressList&>(other);
|
||||||
|
|
||||||
|
removeAllAddresses();
|
||||||
|
|
||||||
|
for (std::vector <address*>::const_iterator it = addrList.m_list.begin() ;
|
||||||
|
it != addrList.m_list.end() ; ++it)
|
||||||
|
{
|
||||||
|
m_list.push_back(static_cast <address*>((*it)->clone()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Return the number of addresses in the list.
|
addressList& addressList::operator=(const addressList& other)
|
||||||
*
|
|
||||||
* @return number of addresses in the list
|
|
||||||
*/
|
|
||||||
|
|
||||||
const std::vector <address*>::size_type addressList::count() const
|
|
||||||
{
|
{
|
||||||
return (m_list.size());
|
copyFrom(other);
|
||||||
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Test whether the list is empty.
|
addressList& addressList::operator=(const mailboxList& other)
|
||||||
*
|
|
||||||
* @return true if the list is empty, false otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
const bool addressList::empty() const
|
|
||||||
{
|
{
|
||||||
return (m_list.empty());
|
copyFrom(other);
|
||||||
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Append an address to the list.
|
addressList* addressList::clone() const
|
||||||
*
|
|
||||||
* @param addr the address to add
|
|
||||||
*/
|
|
||||||
|
|
||||||
void addressList::append(const address& addr)
|
|
||||||
{
|
{
|
||||||
m_list.push_back(addr.clone());
|
return new addressList(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Insert an address at the specified position in the list.
|
void addressList::appendAddress(address* addr)
|
||||||
*
|
|
||||||
* @param it position of the new address
|
|
||||||
* @param addr the address to insert
|
|
||||||
*/
|
|
||||||
|
|
||||||
void addressList::insert(const iterator it, const address& addr)
|
|
||||||
{
|
{
|
||||||
m_list.insert(it.m_iterator, addr.clone());
|
m_list.push_back(addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Remove the address at the specified position.
|
void addressList::insertAddressBefore(address* beforeAddress, address* addr)
|
||||||
*
|
|
||||||
* @param it position of the address to remove
|
|
||||||
*/
|
|
||||||
|
|
||||||
void addressList::erase(const iterator it)
|
|
||||||
{
|
{
|
||||||
delete (*it.m_iterator);
|
const std::vector <address*>::iterator it = std::find
|
||||||
m_list.erase(it.m_iterator);
|
(m_list.begin(), m_list.end(), beforeAddress);
|
||||||
|
|
||||||
|
if (it == m_list.end())
|
||||||
|
throw exceptions::no_such_address();
|
||||||
|
|
||||||
|
m_list.insert(it, addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Remove all the addresses from the list.
|
void addressList::insertAddressBefore(const int pos, address* addr)
|
||||||
*/
|
{
|
||||||
|
m_list.insert(m_list.begin() + pos, addr);
|
||||||
|
}
|
||||||
|
|
||||||
void addressList::clear()
|
|
||||||
|
void addressList::insertAddressAfter(address* afterAddress, address* addr)
|
||||||
|
{
|
||||||
|
const std::vector <address*>::iterator it = std::find
|
||||||
|
(m_list.begin(), m_list.end(), afterAddress);
|
||||||
|
|
||||||
|
if (it == m_list.end())
|
||||||
|
throw exceptions::no_such_address();
|
||||||
|
|
||||||
|
m_list.insert(it + 1, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void addressList::insertAddressAfter(const int pos, address* addr)
|
||||||
|
{
|
||||||
|
m_list.insert(m_list.begin() + pos + 1, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void addressList::removeAddress(address* addr)
|
||||||
|
{
|
||||||
|
const std::vector <address*>::iterator it = std::find
|
||||||
|
(m_list.begin(), m_list.end(), addr);
|
||||||
|
|
||||||
|
if (it == m_list.end())
|
||||||
|
throw exceptions::no_such_address();
|
||||||
|
|
||||||
|
delete (*it);
|
||||||
|
|
||||||
|
m_list.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void addressList::removeAddress(const int pos)
|
||||||
|
{
|
||||||
|
const std::vector <address*>::iterator it = m_list.begin() + pos;
|
||||||
|
|
||||||
|
delete (*it);
|
||||||
|
|
||||||
|
m_list.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void addressList::removeAllAddresses()
|
||||||
{
|
{
|
||||||
free_container(m_list);
|
free_container(m_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void addressList::copyFrom(const addressList& source)
|
const int addressList::getAddressCount() const
|
||||||
{
|
{
|
||||||
clear();
|
return (m_list.size());
|
||||||
|
|
||||||
for (std::vector <address*>::const_iterator i = source.m_list.begin() ; i != source.m_list.end() ; ++i)
|
|
||||||
m_list.push_back((*i)->clone());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
addressList& addressList::operator=(const addressList& source)
|
const bool addressList::isEmpty() const
|
||||||
{
|
{
|
||||||
copyFrom(source);
|
return (m_list.empty());
|
||||||
return (*this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
address* addressList::getAddressAt(const int pos)
|
||||||
|
{
|
||||||
|
return (m_list[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const address* const addressList::getAddressAt(const int pos) const
|
||||||
|
{
|
||||||
|
return (m_list[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector <const address*> addressList::getAddressList() const
|
||||||
|
{
|
||||||
|
std::vector <const address*> list;
|
||||||
|
|
||||||
|
list.reserve(m_list.size());
|
||||||
|
|
||||||
|
for (std::vector <address*>::const_iterator it = m_list.begin() ;
|
||||||
|
it != m_list.end() ; ++it)
|
||||||
|
{
|
||||||
|
list.push_back(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector <address*> addressList::getAddressList()
|
||||||
|
{
|
||||||
|
return (m_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -31,106 +31,124 @@ namespace vmime
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
class mailboxList;
|
||||||
|
|
||||||
|
|
||||||
/** A list of addresses.
|
/** A list of addresses.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class addressList : public component
|
class addressList : public component
|
||||||
{
|
{
|
||||||
friend class addressListField;
|
|
||||||
friend class mailboxListField;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
addressList();
|
addressList();
|
||||||
addressList(const class addressList& addressList);
|
addressList(const addressList& addrList);
|
||||||
|
|
||||||
~addressList();
|
~addressList();
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
addressList& operator=(const addressList& source);
|
addressList* clone() const;
|
||||||
|
void copyFrom(const component& other);
|
||||||
|
addressList& operator=(const addressList& other);
|
||||||
|
addressList& operator=(const mailboxList& other);
|
||||||
|
|
||||||
// Address iterator
|
|
||||||
class const_iterator;
|
|
||||||
|
|
||||||
class iterator
|
/** Add a address at the end of the list.
|
||||||
{
|
*
|
||||||
friend class addressList;
|
* @param addr address to append
|
||||||
friend class const_iterator;
|
*/
|
||||||
|
void appendAddress(address* addr);
|
||||||
|
|
||||||
public:
|
/** Insert a new address before the specified address.
|
||||||
|
*
|
||||||
|
* @param beforeAddress address before which the new address will be inserted
|
||||||
|
* @param addr address to insert
|
||||||
|
* @throw exceptions::no_such_address if the address is not in the list
|
||||||
|
*/
|
||||||
|
void insertAddressBefore(address* beforeAddress, address* addr);
|
||||||
|
|
||||||
iterator(std::vector <address*>::iterator it) : m_iterator(it) { }
|
/** Insert a new address before the specified position.
|
||||||
iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
*
|
||||||
|
* @param pos position at which to insert the new address (0 to insert at
|
||||||
|
* the beginning of the list)
|
||||||
|
* @param addr address to insert
|
||||||
|
*/
|
||||||
|
void insertAddressBefore(const int pos, address* addr);
|
||||||
|
|
||||||
iterator& operator=(const iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
/** Insert a new address after the specified address.
|
||||||
|
*
|
||||||
|
* @param afterAddress address after which the new address will be inserted
|
||||||
|
* @param addr address to insert
|
||||||
|
* @throw exceptions::no_such_address if the address is not in the list
|
||||||
|
*/
|
||||||
|
void insertAddressAfter(address* afterAddress, address* addr);
|
||||||
|
|
||||||
address& operator*() const { return (**m_iterator); }
|
/** Insert a new address after the specified position.
|
||||||
address* operator->() const { return (*m_iterator); }
|
*
|
||||||
|
* @param pos position of the address before the new address
|
||||||
|
* @param addr address to insert
|
||||||
|
*/
|
||||||
|
void insertAddressAfter(const int pos, address* addr);
|
||||||
|
|
||||||
iterator& operator++() { ++m_iterator; return (*this); }
|
/** Remove the specified address from the list.
|
||||||
iterator& operator++(int) { ++m_iterator; return (*this); }
|
*
|
||||||
|
* @param addr address to remove
|
||||||
|
* @throw exceptions::no_such_address if the address is not in the list
|
||||||
|
*/
|
||||||
|
void removeAddress(address* addr);
|
||||||
|
|
||||||
const bool operator==(const iterator& it) const { return (it.m_iterator == m_iterator); }
|
/** Remove the address at the specified position.
|
||||||
const bool operator!=(const iterator& it) const { return (!(*this == it)); }
|
*
|
||||||
|
* @param pos position of the address to remove
|
||||||
|
*/
|
||||||
|
void removeAddress(const int pos);
|
||||||
|
|
||||||
private:
|
/** Remove all addresses from the list.
|
||||||
|
*/
|
||||||
|
void removeAllAddresses();
|
||||||
|
|
||||||
std::vector <address*>::iterator m_iterator;
|
/** Return the number of addresses in the list.
|
||||||
};
|
*
|
||||||
|
* @return number of addresses
|
||||||
|
*/
|
||||||
|
const int getAddressCount() const;
|
||||||
|
|
||||||
class const_iterator
|
/** Tests whether the list of addresses is empty.
|
||||||
{
|
*
|
||||||
friend class addressList;
|
* @return true if there is no address, false otherwise
|
||||||
|
*/
|
||||||
|
const bool isEmpty() const;
|
||||||
|
|
||||||
public:
|
/** Return the address at the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position
|
||||||
|
* @return address at position 'pos'
|
||||||
|
*/
|
||||||
|
address* getAddressAt(const int pos);
|
||||||
|
|
||||||
const_iterator(std::vector <address*>::const_iterator it) : m_iterator(it) { }
|
/** Return the address at the specified position.
|
||||||
const_iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
*
|
||||||
const_iterator(const const_iterator& it) : m_iterator(it.m_iterator) { }
|
* @param pos position
|
||||||
|
* @return address at position 'pos'
|
||||||
|
*/
|
||||||
|
const address* const getAddressAt(const int pos) const;
|
||||||
|
|
||||||
const_iterator& operator=(const const_iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
/** Return the address list.
|
||||||
const_iterator& operator=(const iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
*
|
||||||
|
* @return list of addresses
|
||||||
|
*/
|
||||||
|
const std::vector <const address*> getAddressList() const;
|
||||||
|
|
||||||
const address& operator*() const { return (**m_iterator); }
|
/** Return the address list.
|
||||||
const address* operator->() const { return (*m_iterator); }
|
*
|
||||||
|
* @return list of addresses
|
||||||
|
*/
|
||||||
|
const std::vector <address*> getAddressList();
|
||||||
|
|
||||||
const_iterator& operator++() { ++m_iterator; return (*this); }
|
private:
|
||||||
const_iterator& operator++(int) { ++m_iterator; return (*this); }
|
|
||||||
|
|
||||||
const bool operator==(const const_iterator& it) const { return (it.m_iterator == m_iterator); }
|
|
||||||
const bool operator!=(const const_iterator& it) const { return (!(*this == it)); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::vector <address*>::const_iterator m_iterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
iterator begin() { return (m_list.begin()); }
|
|
||||||
iterator end() { return (m_list.end()); }
|
|
||||||
|
|
||||||
const_iterator begin() const { return (const_iterator(m_list.begin())); }
|
|
||||||
const_iterator end() const { return (const_iterator(m_list.end())); }
|
|
||||||
|
|
||||||
const std::vector <address*>::size_type size() const;
|
|
||||||
const std::vector <address*>::size_type count() const;
|
|
||||||
const bool empty() const;
|
|
||||||
|
|
||||||
const address& operator[](const std::vector <address*>::size_type x) const { return (*m_list[x]); }
|
|
||||||
address& operator[](const std::vector <address*>::size_type x) { return (*m_list[x]); }
|
|
||||||
|
|
||||||
virtual void append(const address& addr);
|
|
||||||
virtual void insert(const iterator it, const address& addr);
|
|
||||||
|
|
||||||
void erase(const iterator it);
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
std::vector <address*> m_list;
|
std::vector <address*> m_list;
|
||||||
|
|
||||||
void copyFrom(const addressList& source);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using component::parse;
|
using component::parse;
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "addressListField.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
addressListField::addressListField()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void addressListField::parse(const string& buffer, const string::size_type position,
|
|
||||||
const string::size_type end, string::size_type* newPosition)
|
|
||||||
{
|
|
||||||
m_list.parse(buffer, position, end, newPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void addressListField::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
||||||
{
|
|
||||||
string::size_type pos = curLinePos;
|
|
||||||
|
|
||||||
headerField::generate(os, maxLineLength, pos, &pos);
|
|
||||||
|
|
||||||
m_list.generate(os, maxLineLength, pos, newLinePos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
addressListField& addressListField::operator=(const addressList& list)
|
|
||||||
{
|
|
||||||
m_list.copyFrom(list);
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void addressListField::copyFrom(const headerField& field)
|
|
||||||
{
|
|
||||||
const addressListField& source = dynamic_cast<const addressListField&>(field);
|
|
||||||
m_list = source.m_list;
|
|
||||||
|
|
||||||
headerField::copyFrom(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
||||||
|
|
@ -1,70 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef VMIME_ADDRESSLISTFIELD_HPP_INCLUDED
|
|
||||||
#define VMIME_ADDRESSLISTFIELD_HPP_INCLUDED
|
|
||||||
|
|
||||||
|
|
||||||
#include "base.hpp"
|
|
||||||
#include "component.hpp"
|
|
||||||
|
|
||||||
#include "headerFieldFactory.hpp"
|
|
||||||
#include "addressList.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class addressListField : public headerField
|
|
||||||
{
|
|
||||||
friend class headerFieldFactory::registerer <addressListField>;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
addressListField();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void copyFrom(const headerField& field);
|
|
||||||
|
|
||||||
addressListField& operator=(const addressList& list);
|
|
||||||
|
|
||||||
const addressList& value() const { return (m_list); }
|
|
||||||
addressList& value() { return (m_list); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
addressList m_list;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
using headerField::parse;
|
|
||||||
using headerField::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
||||||
|
|
||||||
|
|
||||||
#endif // VMIME_ADDRESSLISTFIELD_HPP_INCLUDED
|
|
@ -47,27 +47,25 @@ public:
|
|||||||
|
|
||||||
virtual ~attachment() { }
|
virtual ~attachment() { }
|
||||||
|
|
||||||
virtual attachment& operator=(const attachment& attach) = 0;
|
|
||||||
|
|
||||||
/** Return the media type of this attachment.
|
/** Return the media type of this attachment.
|
||||||
* @return content type of the attachment
|
* @return content type of the attachment
|
||||||
*/
|
*/
|
||||||
virtual const mediaType& type() const = 0;
|
virtual const mediaType& getType() const = 0;
|
||||||
|
|
||||||
/** Return the description of this attachment.
|
/** Return the description of this attachment.
|
||||||
* @return attachment description
|
* @return attachment description
|
||||||
*/
|
*/
|
||||||
virtual const text& description() const = 0;
|
virtual const text& getDescription() const = 0;
|
||||||
|
|
||||||
/** Return the data contained in this attachment.
|
/** Return the data contained in this attachment.
|
||||||
* @return attachment data
|
* @return attachment data
|
||||||
*/
|
*/
|
||||||
virtual const contentHandler& data() const = 0;
|
virtual const contentHandler& getData() const = 0;
|
||||||
|
|
||||||
/** Return the encoding used for this attachment.
|
/** Return the encoding used for this attachment.
|
||||||
* @return attachment data encoding
|
* @return attachment data encoding
|
||||||
*/
|
*/
|
||||||
virtual const class encoding& encoding() const = 0;
|
virtual const encoding& getEncoding() const = 0;
|
||||||
|
|
||||||
/** Generate the attachment in the specified body part.
|
/** Generate the attachment in the specified body part.
|
||||||
* @param parent body part in which to generate the attachment
|
* @param parent body part in which to generate the attachment
|
||||||
|
280
src/base.cpp
280
src/base.cpp
@ -30,6 +30,8 @@
|
|||||||
|
|
||||||
#include "parserHelpers.hpp"
|
#include "parserHelpers.hpp"
|
||||||
|
|
||||||
|
#include "utility/stringUtils.hpp"
|
||||||
|
|
||||||
// For initializing
|
// For initializing
|
||||||
#include "encoderFactory.hpp"
|
#include "encoderFactory.hpp"
|
||||||
#include "headerFieldFactory.hpp"
|
#include "headerFieldFactory.hpp"
|
||||||
@ -75,17 +77,17 @@ const string libversion() { return (VMIME_VERSION " (" __DATE__ " " __TIME__ ")"
|
|||||||
|
|
||||||
|
|
||||||
// New line sequence to be used when folding header fields.
|
// New line sequence to be used when folding header fields.
|
||||||
const string NEW_LINE_SEQUENCE("\r\n ");
|
const string NEW_LINE_SEQUENCE = "\r\n ";
|
||||||
const string::size_type NEW_LINE_SEQUENCE_LENGTH(1); // space
|
const string::size_type NEW_LINE_SEQUENCE_LENGTH = 1; // space
|
||||||
|
|
||||||
/** The CR-LF sequence.
|
/** The CR-LF sequence.
|
||||||
*/
|
*/
|
||||||
const string CRLF("\r\n");
|
const string CRLF = "\r\n";
|
||||||
|
|
||||||
|
|
||||||
/** The current MIME version supported by VMime.
|
/** The current MIME version supported by VMime.
|
||||||
*/
|
*/
|
||||||
const string MIME_VERSION("1.0");
|
const string MIME_VERSION = "1.0";
|
||||||
|
|
||||||
|
|
||||||
// Line length limits
|
// Line length limits
|
||||||
@ -96,147 +98,6 @@ namespace lineLengthLimits
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
/** Test two strings for equality (case insensitive).
|
|
||||||
* WARNING: use this with ASCII-only strings.
|
|
||||||
*
|
|
||||||
* @param s1 first string
|
|
||||||
* @param s2 second string (must be in lower-case!)
|
|
||||||
* @param n length of the second string
|
|
||||||
* @return true if the two strings compare equally, false otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool isStringEqualNoCase(const string& s1, const char* s2, const string::size_type n)
|
|
||||||
{
|
|
||||||
// 'n' is the number of characters to compare
|
|
||||||
// 's2' must be in lowercase letters only
|
|
||||||
if (s1.length() < n)
|
|
||||||
return (false);
|
|
||||||
|
|
||||||
bool equal = true;
|
|
||||||
|
|
||||||
for (string::size_type i = 0 ; equal && i < n ; ++i)
|
|
||||||
equal = (std::tolower(s1[i], std::locale()) == s2[i]);
|
|
||||||
|
|
||||||
return (equal);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Test two strings for equality (case insensitive).
|
|
||||||
* WARNING: use this with ASCII-only strings.
|
|
||||||
*
|
|
||||||
* @param s1 first string
|
|
||||||
* @param s2 second string
|
|
||||||
* @return true if the two strings compare equally, false otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool isStringEqualNoCase(const string& s1, const string& s2)
|
|
||||||
{
|
|
||||||
if (s1.length() != s2.length())
|
|
||||||
return (false);
|
|
||||||
|
|
||||||
bool equal = true;
|
|
||||||
const string::const_iterator end = s1.end();
|
|
||||||
|
|
||||||
for (string::const_iterator i = s1.begin(), j = s2.begin(); i != end ; ++i, ++j)
|
|
||||||
equal = (std::tolower(*i, std::locale()) == std::tolower(*j, std::locale()));
|
|
||||||
|
|
||||||
return (equal);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Test two strings for equality (case insensitive).
|
|
||||||
* WARNING: use this with ASCII-only strings.
|
|
||||||
*
|
|
||||||
* @param begin start position of the first string
|
|
||||||
* @param end end position of the first string
|
|
||||||
* @param s second string (must be in lower-case!)
|
|
||||||
* @param n length of the second string
|
|
||||||
* @return true if the two strings compare equally, false otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
bool isStringEqualNoCase(const string::const_iterator begin, const string::const_iterator end,
|
|
||||||
const char* s, const string::size_type n)
|
|
||||||
{
|
|
||||||
if ((string::size_type)(end - begin) < n)
|
|
||||||
return (false);
|
|
||||||
|
|
||||||
bool equal = true;
|
|
||||||
char* c = const_cast<char*>(s);
|
|
||||||
string::size_type r = n;
|
|
||||||
|
|
||||||
for (string::const_iterator i = begin ; equal && r && *c ; ++i, ++c, --r)
|
|
||||||
equal = (std::tolower(*i, std::locale()) == *c);
|
|
||||||
|
|
||||||
return (r == 0 && equal);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Transform all the characters in a string to lower-case.
|
|
||||||
* WARNING: use this with ASCII-only strings.
|
|
||||||
*
|
|
||||||
* @param str the string to transform
|
|
||||||
* @return a new string in lower-case
|
|
||||||
*/
|
|
||||||
|
|
||||||
const string toLower(const string& str)
|
|
||||||
{
|
|
||||||
string out(str);
|
|
||||||
const string::iterator end = out.end();
|
|
||||||
|
|
||||||
for (string::iterator i = out.begin() ; i != end ; ++i)
|
|
||||||
*i = std::tolower(*i, std::locale());
|
|
||||||
|
|
||||||
return (out);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Strip the space characters (SPC, TAB, CR, LF) at the beginning
|
|
||||||
* and at the end of the specified string.
|
|
||||||
*
|
|
||||||
* @param str string in which to strip spaces
|
|
||||||
* @return a new string with space characters removed
|
|
||||||
*/
|
|
||||||
|
|
||||||
const string trim(const string& str)
|
|
||||||
{
|
|
||||||
string::const_iterator b = str.begin();
|
|
||||||
string::const_iterator e = str.end();
|
|
||||||
|
|
||||||
if (b != e)
|
|
||||||
{
|
|
||||||
for ( ; b != e && isspace(*b) ; ++b);
|
|
||||||
for ( ; e != b && isspace(*(e - 1)) ; --e);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (string(b, e));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Return the number of 7-bit US-ASCII characters in a string.
|
|
||||||
*
|
|
||||||
* @param begin start position
|
|
||||||
* @param end end position
|
|
||||||
* @return number of ASCII characters
|
|
||||||
*/
|
|
||||||
|
|
||||||
string::size_type countASCIIchars
|
|
||||||
(const string::const_iterator begin, const string::const_iterator end)
|
|
||||||
{
|
|
||||||
string::size_type count = 0;
|
|
||||||
|
|
||||||
for (string::const_iterator i = begin ; i != end ; ++i)
|
|
||||||
{
|
|
||||||
if (isascii(*i))
|
|
||||||
{
|
|
||||||
if (*i != '=' || *(i + 1) != '?') // To avoid bad behaviour...
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (count);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Encode and fold text in respect to RFC-2047.
|
/** Encode and fold text in respect to RFC-2047.
|
||||||
*
|
*
|
||||||
* @param os output stream
|
* @param os output stream
|
||||||
@ -252,14 +113,15 @@ void encodeAndFoldText(utility::outputStream& os, const text& in, const string::
|
|||||||
{
|
{
|
||||||
string::size_type curLineLength = firstLineOffset;
|
string::size_type curLineLength = firstLineOffset;
|
||||||
|
|
||||||
for (text::const_iterator wi = in.begin() ; wi != in.end() ; ++wi)
|
for (int wi = 0 ; wi < in.getWordCount() ; ++wi)
|
||||||
{
|
{
|
||||||
const word& w = *wi;
|
const word& w = *in.getWordAt(wi);
|
||||||
const string& buffer = w.buffer();
|
const string& buffer = w.getBuffer();
|
||||||
|
|
||||||
// Calculate the number of ASCII chars to check whether encoding is needed
|
// Calculate the number of ASCII chars to check whether encoding is needed
|
||||||
// and _which_ encoding to use.
|
// and _which_ encoding to use.
|
||||||
const string::size_type asciiCount = countASCIIchars(buffer.begin(), buffer.end());
|
const string::size_type asciiCount =
|
||||||
|
stringUtils::countASCIIchars(buffer.begin(), buffer.end());
|
||||||
|
|
||||||
bool noEncoding = (flags & encodeAndFoldFlags::forceNoEncoding) ||
|
bool noEncoding = (flags & encodeAndFoldFlags::forceNoEncoding) ||
|
||||||
(!(flags & encodeAndFoldFlags::forceEncoding) && asciiCount == buffer.length());
|
(!(flags & encodeAndFoldFlags::forceEncoding) && asciiCount == buffer.length());
|
||||||
@ -305,7 +167,7 @@ void encodeAndFoldText(utility::outputStream& os, const text& in, const string::
|
|||||||
// we write the full line no matter of the max line length...
|
// we write the full line no matter of the max line length...
|
||||||
|
|
||||||
if (!newLine && p != end && lastWSpos == end &&
|
if (!newLine && p != end && lastWSpos == end &&
|
||||||
wi != in.begin() && curLineStart == buffer.begin())
|
wi != 0 && curLineStart == buffer.begin())
|
||||||
{
|
{
|
||||||
// Here, we are continuing on the line of previous encoded
|
// Here, we are continuing on the line of previous encoded
|
||||||
// word, but there is not even enough space to put the
|
// word, but there is not even enough space to put the
|
||||||
@ -359,7 +221,7 @@ void encodeAndFoldText(utility::outputStream& os, const text& in, const string::
|
|||||||
// last white-space.
|
// last white-space.
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
if (curLineLength != 1 && wi != in.begin())
|
if (curLineLength != 1 && wi != 0)
|
||||||
os << " "; // Separate from previous word
|
os << " "; // Separate from previous word
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -419,7 +281,7 @@ void encodeAndFoldText(utility::outputStream& os, const text& in, const string::
|
|||||||
const string::size_type asciiPercent = (100 * asciiCount) / buffer.length();
|
const string::size_type asciiPercent = (100 * asciiCount) / buffer.length();
|
||||||
const string::value_type encoding = (asciiPercent <= 40) ? 'B' : 'Q';
|
const string::value_type encoding = (asciiPercent <= 40) ? 'B' : 'Q';
|
||||||
|
|
||||||
string wordStart("=?" + w.charset().name() + "?" + encoding + "?");
|
string wordStart("=?" + w.getCharset().getName() + "?" + encoding + "?");
|
||||||
string wordEnd("?=");
|
string wordEnd("?=");
|
||||||
|
|
||||||
const string::size_type minWordLength = wordStart.length() + wordEnd.length();
|
const string::size_type minWordLength = wordStart.length() + wordEnd.length();
|
||||||
@ -465,7 +327,7 @@ void encodeAndFoldText(utility::outputStream& os, const text& in, const string::
|
|||||||
|
|
||||||
if (encoding == 'Q')
|
if (encoding == 'Q')
|
||||||
{
|
{
|
||||||
theEncoder->properties()["rfc2047"] = true;
|
theEncoder->getProperties()["rfc2047"] = true;
|
||||||
|
|
||||||
// In the case of Quoted-Printable encoding, we cannot simply encode input
|
// In the case of Quoted-Printable encoding, we cannot simply encode input
|
||||||
// buffer line by line. So, we encode the whole buffer and we will fold it
|
// buffer line by line. So, we encode the whole buffer and we will fold it
|
||||||
@ -480,7 +342,7 @@ void encodeAndFoldText(utility::outputStream& os, const text& in, const string::
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if 1
|
#if 1
|
||||||
if (curLineLength != 1 && wi != in.begin())
|
if (curLineLength != 1 && wi != 0)
|
||||||
{
|
{
|
||||||
os << " "; // Separate from previous word
|
os << " "; // Separate from previous word
|
||||||
++curLineLength;
|
++curLineLength;
|
||||||
@ -585,7 +447,7 @@ void decodeAndUnfoldText(const string::const_iterator& inStart, const string::co
|
|||||||
// NOTE: See RFC-2047, Pages 11-12 for knowing about handling
|
// NOTE: See RFC-2047, Pages 11-12 for knowing about handling
|
||||||
// of white-spaces between encoded words.
|
// of white-spaces between encoded words.
|
||||||
|
|
||||||
out.clear();
|
out.removeAllWords();
|
||||||
|
|
||||||
string::const_iterator p = inStart;
|
string::const_iterator p = inStart;
|
||||||
const string::const_iterator end = inEnd;
|
const string::const_iterator end = inEnd;
|
||||||
@ -608,14 +470,14 @@ void decodeAndUnfoldText(const string::const_iterator& inStart, const string::co
|
|||||||
|
|
||||||
if (textEnd != prevPos)
|
if (textEnd != prevPos)
|
||||||
{
|
{
|
||||||
if (out.size() && prevWordCharset == defaultCharset)
|
if (!out.isEmpty() && prevWordCharset == defaultCharset)
|
||||||
{
|
{
|
||||||
out.back().buffer() += string(prevPos, textEnd);
|
out.getWordAt(out.getWordCount() - 1)->getBuffer() += string(prevPos, textEnd);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prevWordCharset = defaultCharset;
|
prevWordCharset = defaultCharset;
|
||||||
out.append(word(string(prevPos, textEnd), defaultCharset));
|
out.appendWord(new word(string(prevPos, textEnd), defaultCharset));
|
||||||
prevIsEncoded = false;
|
prevIsEncoded = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -670,7 +532,7 @@ void decodeAndUnfoldText(const string::const_iterator& inStart, const string::co
|
|||||||
else if (*encPos == 'Q' || *encPos == 'q')
|
else if (*encPos == 'Q' || *encPos == 'q')
|
||||||
{
|
{
|
||||||
theEncoder = new encoderQP;
|
theEncoder = new encoderQP;
|
||||||
theEncoder->properties()["rfc2047"] = true;
|
theEncoder->getProperties()["rfc2047"] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (theEncoder)
|
if (theEncoder)
|
||||||
@ -698,13 +560,16 @@ void decodeAndUnfoldText(const string::const_iterator& inStart, const string::co
|
|||||||
|
|
||||||
if (p != wordPos) // if not empty
|
if (p != wordPos) // if not empty
|
||||||
{
|
{
|
||||||
if (out.size() && prevWordCharset == defaultCharset)
|
if (!out.isEmpty() && prevWordCharset == defaultCharset)
|
||||||
{
|
{
|
||||||
out.back().buffer() += string(prevPos, wordPos);
|
out.getWordAt(out.getWordCount() - 1)->
|
||||||
|
getBuffer() += string(prevPos, wordPos);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
out.append(word(string(prevPos, wordPos), defaultCharset));
|
out.appendWord(new word
|
||||||
|
(string(prevPos, wordPos), defaultCharset));
|
||||||
|
|
||||||
prevWordCharset = defaultCharset;
|
prevWordCharset = defaultCharset;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -713,14 +578,15 @@ void decodeAndUnfoldText(const string::const_iterator& inStart, const string::co
|
|||||||
// Append this fresh decoded word to output text
|
// Append this fresh decoded word to output text
|
||||||
charset thisCharset(string(charsetPos, charsetEnd));
|
charset thisCharset(string(charsetPos, charsetEnd));
|
||||||
|
|
||||||
if (out.size() && prevWordCharset == thisCharset)
|
if (!out.isEmpty() && prevWordCharset == thisCharset)
|
||||||
{
|
{
|
||||||
out.back().buffer() += decodedBuffer;
|
out.getWordAt(out.getWordCount() - 1)->
|
||||||
|
getBuffer() += decodedBuffer;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prevWordCharset = thisCharset;
|
prevWordCharset = thisCharset;
|
||||||
out.append(word(decodedBuffer, thisCharset));
|
out.appendWord(new word(decodedBuffer, thisCharset));
|
||||||
}
|
}
|
||||||
|
|
||||||
// This word has been decoded: we can advance in the input buffer
|
// This word has been decoded: we can advance in the input buffer
|
||||||
@ -753,90 +619,6 @@ void decodeAndUnfoldText(const string& in, text& out)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** This function can be used to make several encoded words from a text.
|
|
||||||
* All the characters in the text must be in the same specified charset.
|
|
||||||
*
|
|
||||||
* <p>Eg: giving:</p>
|
|
||||||
* <pre> <iso-8859-1> "Linux dans un t'el'ephone mobile"
|
|
||||||
* ("=?iso-8859-1?Q?Linux_dans_un_t=E9l=E9phone_mobile?=")
|
|
||||||
* </pre><p>it will return:</p>
|
|
||||||
* <pre> <:us-ascii> "Linux dans un "
|
|
||||||
* <iso-8859-1> "t'el'ephone "
|
|
||||||
* <us-ascii> "mobile"
|
|
||||||
* ("Linux dans un =?iso-8859-1?Q?t=E9l=E9phone_?= mobile")
|
|
||||||
* </pre>
|
|
||||||
*
|
|
||||||
* @param in input string
|
|
||||||
* @param ch input charset
|
|
||||||
* @param out output text
|
|
||||||
*/
|
|
||||||
|
|
||||||
void makeWordsFromText(const string& in, const charset& ch, text& out)
|
|
||||||
{
|
|
||||||
const string::const_iterator end = in.end();
|
|
||||||
string::const_iterator p = in.begin();
|
|
||||||
string::const_iterator start = in.begin();
|
|
||||||
|
|
||||||
bool is8bit = false; // is the current word 8-bit?
|
|
||||||
bool prevIs8bit = false; // is previous word 8-bit?
|
|
||||||
unsigned int count = 0; // total number of words
|
|
||||||
|
|
||||||
out.clear();
|
|
||||||
|
|
||||||
for ( ; ; )
|
|
||||||
{
|
|
||||||
if (p == end || isspace(*p))
|
|
||||||
{
|
|
||||||
if (p != end)
|
|
||||||
++p;
|
|
||||||
|
|
||||||
if (is8bit)
|
|
||||||
{
|
|
||||||
if (prevIs8bit)
|
|
||||||
{
|
|
||||||
// No need to create a new encoded word, just append
|
|
||||||
// the current word to the previous one.
|
|
||||||
out.back().buffer() += string(start, p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
out.append(word(string(start, p), ch));
|
|
||||||
prevIs8bit = true;
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (count && !prevIs8bit)
|
|
||||||
{
|
|
||||||
out.back().buffer() += string(start, p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
out.append(word(string(start, p), charset(charsets::US_ASCII)));
|
|
||||||
prevIs8bit = false;
|
|
||||||
++count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p == end)
|
|
||||||
break;
|
|
||||||
|
|
||||||
is8bit = false;
|
|
||||||
start = p;
|
|
||||||
}
|
|
||||||
else if (!isascii(*p))
|
|
||||||
{
|
|
||||||
is8bit = true;
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
++p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// V-Mime Initializer
|
// V-Mime Initializer
|
||||||
|
40
src/base.hpp
40
src/base.hpp
@ -79,39 +79,6 @@ namespace vmime
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//
|
|
||||||
// Some helpful functions
|
|
||||||
//
|
|
||||||
|
|
||||||
bool isStringEqualNoCase(const string& s1, const char* s2, const string::size_type n);
|
|
||||||
bool isStringEqualNoCase(const string& s1, const string& s2);
|
|
||||||
bool isStringEqualNoCase(const string::const_iterator begin, const string::const_iterator end, const char* s, const string::size_type n);
|
|
||||||
|
|
||||||
|
|
||||||
const string toLower(const string& str);
|
|
||||||
const string trim(const string& str);
|
|
||||||
|
|
||||||
template <class TYPE>
|
|
||||||
const string toString(const TYPE& value)
|
|
||||||
{
|
|
||||||
std::ostringstream oss;
|
|
||||||
oss << value;
|
|
||||||
|
|
||||||
return (oss.str());
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class TYPE>
|
|
||||||
const TYPE fromString(const string& value)
|
|
||||||
{
|
|
||||||
TYPE ret;
|
|
||||||
|
|
||||||
std::istringstream iss(value);
|
|
||||||
iss >> ret;
|
|
||||||
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Free the pointer elements in a STL container and empty the container
|
// Free the pointer elements in a STL container and empty the container
|
||||||
|
|
||||||
template <class CONTAINER>
|
template <class CONTAINER>
|
||||||
@ -125,14 +92,10 @@ namespace vmime
|
|||||||
|
|
||||||
|
|
||||||
// Field contents encoding (RFC-2047 and folding)
|
// Field contents encoding (RFC-2047 and folding)
|
||||||
string::size_type countASCIIchars(const string::const_iterator begin, const string::const_iterator end);
|
|
||||||
|
|
||||||
void encodeAndFoldText(utility::outputStream& os, const text& in, const string::size_type maxLineLength, const string::size_type firstLineOffset, string::size_type* lastLineLength, const int flags);
|
void encodeAndFoldText(utility::outputStream& os, const text& in, const string::size_type maxLineLength, const string::size_type firstLineOffset, string::size_type* lastLineLength, const int flags);
|
||||||
void decodeAndUnfoldText(const string& in, text& out);
|
void decodeAndUnfoldText(const string& in, text& out);
|
||||||
void decodeAndUnfoldText(const string::const_iterator& inStart, const string::const_iterator& inEnd, text& out);
|
void decodeAndUnfoldText(const string::const_iterator& inStart, const string::const_iterator& inEnd, text& out);
|
||||||
|
|
||||||
void makeWordsFromText(const string& in, const charset& ch, text& out);
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Some constants
|
// Some constants
|
||||||
@ -210,6 +173,9 @@ namespace vmime
|
|||||||
// Mime version
|
// Mime version
|
||||||
extern const string MIME_VERSION;
|
extern const string MIME_VERSION;
|
||||||
|
|
||||||
|
/** Utility classes. */
|
||||||
|
namespace utility { }
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
|
||||||
|
|
||||||
|
376
src/body.cpp
376
src/body.cpp
@ -23,7 +23,6 @@
|
|||||||
#include "options.hpp"
|
#include "options.hpp"
|
||||||
|
|
||||||
#include "contentTypeField.hpp"
|
#include "contentTypeField.hpp"
|
||||||
#include "contentEncodingField.hpp"
|
|
||||||
|
|
||||||
#include "utility/random.hpp"
|
#include "utility/random.hpp"
|
||||||
|
|
||||||
@ -34,16 +33,28 @@ namespace vmime
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
body::body(bodyPart& part)
|
body::body()
|
||||||
: parts(*this), m_part(part), m_header(part.header())
|
: m_part(NULL), m_header(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
body::body(bodyPart* parentPart)
|
||||||
|
: m_part(parentPart), m_header(parentPart != NULL ? parentPart->getHeader() : NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
body::~body()
|
||||||
|
{
|
||||||
|
removeAllParts();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void body::parse(const string& buffer, const string::size_type position,
|
void body::parse(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
parts.clear();
|
removeAllParts();
|
||||||
|
|
||||||
// Check whether the body is a MIME-multipart
|
// Check whether the body is a MIME-multipart
|
||||||
bool isMultipart = false;
|
bool isMultipart = false;
|
||||||
@ -52,15 +63,15 @@ void body::parse(const string& buffer, const string::size_type position,
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
const contentTypeField& ctf = dynamic_cast <contentTypeField&>
|
const contentTypeField& ctf = dynamic_cast <contentTypeField&>
|
||||||
(m_header.fields.find(headerField::ContentType));
|
(*m_header->findField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
if (ctf.value().type() == mediaTypes::MULTIPART)
|
if (ctf.getValue().getType() == mediaTypes::MULTIPART)
|
||||||
{
|
{
|
||||||
isMultipart = true;
|
isMultipart = true;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
boundary = ctf.boundary();
|
boundary = ctf.getBoundary();
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_parameter&)
|
catch (exceptions::no_such_parameter&)
|
||||||
{
|
{
|
||||||
@ -170,13 +181,17 @@ void body::parse(const string& buffer, const string::size_type position,
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
parts.m_parts.push_back(part);
|
part->m_parent = m_part;
|
||||||
|
|
||||||
|
m_parts.push_back(part);
|
||||||
}
|
}
|
||||||
|
|
||||||
partStart = pos;
|
partStart = pos;
|
||||||
pos = buffer.find(boundarySep, partStart);
|
pos = buffer.find(boundarySep, partStart);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_contents.setData("");
|
||||||
|
|
||||||
if (partStart < end)
|
if (partStart < end)
|
||||||
m_epilogText = string(buffer.begin() + partStart, buffer.begin() + end);
|
m_epilogText = string(buffer.begin() + partStart, buffer.begin() + end);
|
||||||
}
|
}
|
||||||
@ -184,7 +199,7 @@ void body::parse(const string& buffer, const string::size_type position,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Extract the (encoded) contents
|
// Extract the (encoded) contents
|
||||||
m_contents.set(buffer, position, end, encoding());
|
m_contents.setData(buffer, position, end, getEncoding());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newPosition)
|
if (newPosition)
|
||||||
@ -196,32 +211,39 @@ void body::generate(utility::outputStream& os, const string::size_type maxLineLe
|
|||||||
const string::size_type /* curLinePos */, string::size_type* newLinePos) const
|
const string::size_type /* curLinePos */, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
// MIME-Multipart
|
// MIME-Multipart
|
||||||
if (parts.size() != 0)
|
if (getPartCount() != 0)
|
||||||
{
|
{
|
||||||
string boundary;
|
string boundary;
|
||||||
|
|
||||||
try
|
if (m_header == NULL)
|
||||||
{
|
{
|
||||||
contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
boundary = generateRandomBoundaryString();
|
||||||
(m_header.fields.find(headerField::ContentType));
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
|
(*m_header->findField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
boundary = ctf.boundary();
|
boundary = ctf.getBoundary();
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_field&)
|
catch (exceptions::no_such_field&)
|
||||||
{
|
{
|
||||||
// Warning: no content-type and no boundary string specified!
|
// Warning: no content-type and no boundary string specified!
|
||||||
boundary = generateRandomBoundaryString();
|
boundary = generateRandomBoundaryString();
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_parameter&)
|
catch (exceptions::no_such_parameter&)
|
||||||
{
|
{
|
||||||
// Warning: no boundary string specified!
|
// Warning: no boundary string specified!
|
||||||
boundary = generateRandomBoundaryString();
|
boundary = generateRandomBoundaryString();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const string& prologText =
|
const string& prologText =
|
||||||
m_prologText.empty()
|
m_prologText.empty()
|
||||||
? (isRootPart()
|
? (isRootPart()
|
||||||
? options::getInstance()->multipart.prologText()
|
? options::getInstance()->multipart.getPrologText()
|
||||||
: NULL_STRING
|
: NULL_STRING
|
||||||
)
|
)
|
||||||
: m_prologText;
|
: m_prologText;
|
||||||
@ -229,14 +251,14 @@ void body::generate(utility::outputStream& os, const string::size_type maxLineLe
|
|||||||
const string& epilogText =
|
const string& epilogText =
|
||||||
m_epilogText.empty()
|
m_epilogText.empty()
|
||||||
? (isRootPart()
|
? (isRootPart()
|
||||||
? options::getInstance()->multipart.epilogText()
|
? options::getInstance()->multipart.getEpilogText()
|
||||||
: NULL_STRING
|
: NULL_STRING
|
||||||
)
|
)
|
||||||
: m_epilogText;
|
: m_epilogText;
|
||||||
|
|
||||||
if (!prologText.empty())
|
if (!prologText.empty())
|
||||||
{
|
{
|
||||||
encodeAndFoldText(os, text(word(prologText, charset())), maxLineLength, 0,
|
encodeAndFoldText(os, text(word(prologText, getCharset())), maxLineLength, 0,
|
||||||
NULL, encodeAndFoldFlags::forceNoEncoding | encodeAndFoldFlags::noNewLineSequence);
|
NULL, encodeAndFoldFlags::forceNoEncoding | encodeAndFoldFlags::noNewLineSequence);
|
||||||
|
|
||||||
os << CRLF;
|
os << CRLF;
|
||||||
@ -244,12 +266,11 @@ void body::generate(utility::outputStream& os, const string::size_type maxLineLe
|
|||||||
|
|
||||||
os << "--" << boundary;
|
os << "--" << boundary;
|
||||||
|
|
||||||
for (std::vector <bodyPart*>::const_iterator
|
for (int p = 0 ; p < getPartCount() ; ++p)
|
||||||
p = parts.m_parts.begin() ; p != parts.m_parts.end() ; ++p)
|
|
||||||
{
|
{
|
||||||
os << CRLF;
|
os << CRLF;
|
||||||
|
|
||||||
(*p)->generate(os, maxLineLength, 0);
|
getPartAt(p)->generate(os, maxLineLength, 0);
|
||||||
|
|
||||||
os << CRLF << "--" << boundary;
|
os << CRLF << "--" << boundary;
|
||||||
}
|
}
|
||||||
@ -258,7 +279,7 @@ void body::generate(utility::outputStream& os, const string::size_type maxLineLe
|
|||||||
|
|
||||||
if (!epilogText.empty())
|
if (!epilogText.empty())
|
||||||
{
|
{
|
||||||
encodeAndFoldText(os, text(word(epilogText, charset())), maxLineLength, 0,
|
encodeAndFoldText(os, text(word(epilogText, getCharset())), maxLineLength, 0,
|
||||||
NULL, encodeAndFoldFlags::forceNoEncoding | encodeAndFoldFlags::noNewLineSequence);
|
NULL, encodeAndFoldFlags::forceNoEncoding | encodeAndFoldFlags::noNewLineSequence);
|
||||||
|
|
||||||
os << CRLF;
|
os << CRLF;
|
||||||
@ -271,7 +292,7 @@ void body::generate(utility::outputStream& os, const string::size_type maxLineLe
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Generate the contents
|
// Generate the contents
|
||||||
m_contents.generate(os, encoding(), maxLineLength);
|
m_contents.generate(os, getEncoding(), maxLineLength);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -316,7 +337,7 @@ const string body::generateRandomBoundaryString()
|
|||||||
boundary[1] = '_';
|
boundary[1] = '_';
|
||||||
|
|
||||||
// Generate a string of random characters
|
// Generate a string of random characters
|
||||||
unsigned int r = utility::random::time();
|
unsigned int r = utility::random::getTime();
|
||||||
unsigned int m = sizeof(unsigned int);
|
unsigned int m = sizeof(unsigned int);
|
||||||
|
|
||||||
for (size_t i = 2 ; i < (sizeof(boundary) / sizeof(boundary[0]) - 1) ; ++i)
|
for (size_t i = 2 ; i < (sizeof(boundary) / sizeof(boundary[0]) - 1) ; ++i)
|
||||||
@ -326,7 +347,7 @@ const string body::generateRandomBoundaryString()
|
|||||||
|
|
||||||
if (--m == 0)
|
if (--m == 0)
|
||||||
{
|
{
|
||||||
r = utility::random::next();
|
r = utility::random::getNext();
|
||||||
m = sizeof(unsigned int);
|
m = sizeof(unsigned int);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -363,12 +384,14 @@ const bool body::isValidBoundary(const string& boundary)
|
|||||||
// Quick-access functions
|
// Quick-access functions
|
||||||
//
|
//
|
||||||
|
|
||||||
const mediaType body::contentType() const
|
const mediaType body::getContentType() const
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>(m_header.fields.find(headerField::ContentType));
|
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
return (ctf.value());
|
(*m_header->findField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
|
return (ctf.getValue());
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_field&)
|
catch (exceptions::no_such_field&)
|
||||||
{
|
{
|
||||||
@ -378,12 +401,14 @@ const mediaType body::contentType() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const class charset body::charset() const
|
const charset body::getCharset() const
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>(m_header.fields.find(headerField::ContentType));
|
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
const class charset& cs = ctf.charset();
|
(*m_header->findField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
|
const class charset& cs = ctf.getCharset();
|
||||||
|
|
||||||
return (cs);
|
return (cs);
|
||||||
}
|
}
|
||||||
@ -400,12 +425,14 @@ const class charset body::charset() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const class encoding body::encoding() const
|
const encoding body::getEncoding() const
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const contentEncodingField& cef = m_header.fields.ContentTransferEncoding();
|
const contentEncodingField& cef = dynamic_cast<contentEncodingField&>
|
||||||
return (cef.value());
|
(*m_header->findField(fields::CONTENT_TRANSFER_ENCODING));
|
||||||
|
|
||||||
|
return (cef.getValue());
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_field&)
|
catch (exceptions::no_such_field&)
|
||||||
{
|
{
|
||||||
@ -417,126 +444,259 @@ const class encoding body::encoding() const
|
|||||||
|
|
||||||
const bool body::isRootPart() const
|
const bool body::isRootPart() const
|
||||||
{
|
{
|
||||||
return (m_part.parent() == NULL);
|
return (m_part == NULL || m_part->getParentPart() == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
body& body::operator=(const body& b)
|
body* body::clone() const
|
||||||
{
|
{
|
||||||
m_prologText = b.m_prologText;
|
body* bdy = new body(NULL);
|
||||||
m_epilogText = b.m_epilogText;
|
|
||||||
|
|
||||||
m_contents = b.m_contents;
|
bdy->copyFrom(*this);
|
||||||
|
|
||||||
parts = b.parts;
|
return (bdy);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void body::copyFrom(const component& other)
|
||||||
|
{
|
||||||
|
const body& bdy = dynamic_cast <const body&>(other);
|
||||||
|
|
||||||
|
m_prologText = bdy.m_prologText;
|
||||||
|
m_epilogText = bdy.m_epilogText;
|
||||||
|
|
||||||
|
m_contents = bdy.m_contents;
|
||||||
|
|
||||||
|
removeAllParts();
|
||||||
|
|
||||||
|
for (int p = 0 ; p < bdy.getPartCount() ; ++p)
|
||||||
|
{
|
||||||
|
bodyPart* part = bdy.getPartAt(p)->clone();
|
||||||
|
|
||||||
|
part->m_parent = m_part;
|
||||||
|
|
||||||
|
m_parts.push_back(part);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
body& body::operator=(const body& other)
|
||||||
|
{
|
||||||
|
copyFrom(other);
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/////////////////////
|
const string& body::getPrologText() const
|
||||||
// Parts container //
|
|
||||||
/////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
body::partsContainer::partsContainer(class body& body)
|
|
||||||
: m_body(body)
|
|
||||||
{
|
{
|
||||||
|
return (m_prologText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Part insertion
|
void body::setPrologText(const string& prologText)
|
||||||
void body::partsContainer::append(bodyPart* part)
|
|
||||||
{
|
{
|
||||||
part->m_parent = &(m_body.m_part);
|
m_prologText = prologText;
|
||||||
|
}
|
||||||
|
|
||||||
m_parts.push_back(part);
|
|
||||||
|
|
||||||
// Check whether we have a boundary string
|
const string& body::getEpilogText() const
|
||||||
try
|
{
|
||||||
|
return (m_epilogText);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void body::setEpilogText(const string& epilogText)
|
||||||
|
{
|
||||||
|
m_epilogText = epilogText;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const contentHandler& body::getContents() const
|
||||||
|
{
|
||||||
|
return (m_contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
contentHandler& body::getContents()
|
||||||
|
{
|
||||||
|
return (m_contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void body::setContents(const contentHandler& contents)
|
||||||
|
{
|
||||||
|
m_contents = contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void body::initNewPart(bodyPart* part)
|
||||||
|
{
|
||||||
|
part->m_parent = m_part;
|
||||||
|
|
||||||
|
if (m_header != NULL)
|
||||||
{
|
{
|
||||||
contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
// Check whether we have a boundary string
|
||||||
(m_body.m_header.fields.find(headerField::ContentType));
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const string boundary = ctf.boundary();
|
contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
|
(*m_header->findField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
if (boundary.empty() || !isValidBoundary(boundary))
|
try
|
||||||
throw exceptions::no_such_parameter("boundary"); // to generate a new one
|
{
|
||||||
|
const string boundary = ctf.getBoundary();
|
||||||
|
|
||||||
|
if (boundary.empty() || !isValidBoundary(boundary))
|
||||||
|
ctf.setBoundary(generateRandomBoundaryString());
|
||||||
|
}
|
||||||
|
catch (exceptions::no_such_parameter&)
|
||||||
|
{
|
||||||
|
// No "boundary" parameter: generate a random one.
|
||||||
|
ctf.setBoundary(generateRandomBoundaryString());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ctf.getValue().getType() != mediaTypes::MULTIPART)
|
||||||
|
{
|
||||||
|
// Warning: multi-part body but the Content-Type is
|
||||||
|
// not specified as "multipart/..."
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_parameter&)
|
catch (exceptions::no_such_field&)
|
||||||
{
|
{
|
||||||
// No "boundary" parameter: generate a random one.
|
// No "Content-Type" field: create a new one and generate
|
||||||
ctf.boundary() = generateRandomBoundaryString();
|
// a random boundary string.
|
||||||
}
|
contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
|
(*m_header->getField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
if (ctf.value().type() != mediaTypes::MULTIPART)
|
ctf.setValue(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED));
|
||||||
{
|
ctf.setBoundary(generateRandomBoundaryString());
|
||||||
// Warning: multi-part body but the Content-Type is
|
|
||||||
// not specified as "multipart/..."
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_field&)
|
|
||||||
{
|
|
||||||
// No "Content-Type" field: create a new one and generate
|
|
||||||
// a random boundary string.
|
|
||||||
contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
|
||||||
(m_body.m_header.fields.get(headerField::ContentType));
|
|
||||||
|
|
||||||
ctf.value() = mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED);
|
|
||||||
ctf.boundary() = generateRandomBoundaryString();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void body::partsContainer::insert(const iterator it, bodyPart* part)
|
void body::appendPart(bodyPart* part)
|
||||||
{
|
{
|
||||||
part->m_parent = &(m_body.m_part);
|
initNewPart(part);
|
||||||
|
|
||||||
m_parts.insert(it.m_iterator, part);
|
m_parts.push_back(part);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Part removing
|
void body::insertPartBefore(bodyPart* beforePart, bodyPart* part)
|
||||||
void body::partsContainer::remove(const iterator it)
|
|
||||||
{
|
{
|
||||||
delete (*it.m_iterator);
|
initNewPart(part);
|
||||||
m_parts.erase(it.m_iterator);
|
|
||||||
|
const std::vector <bodyPart*>::iterator it = std::find
|
||||||
|
(m_parts.begin(), m_parts.end(), beforePart);
|
||||||
|
|
||||||
|
if (it == m_parts.end())
|
||||||
|
throw exceptions::no_such_part();
|
||||||
|
|
||||||
|
m_parts.insert(it, part);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void body::partsContainer::clear()
|
void body::insertPartBefore(const int pos, bodyPart* part)
|
||||||
|
{
|
||||||
|
initNewPart(part);
|
||||||
|
|
||||||
|
m_parts.insert(m_parts.begin() + pos, part);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void body::insertPartAfter(bodyPart* afterPart, bodyPart* part)
|
||||||
|
{
|
||||||
|
initNewPart(part);
|
||||||
|
|
||||||
|
const std::vector <bodyPart*>::iterator it = std::find
|
||||||
|
(m_parts.begin(), m_parts.end(), afterPart);
|
||||||
|
|
||||||
|
if (it == m_parts.end())
|
||||||
|
throw exceptions::no_such_part();
|
||||||
|
|
||||||
|
m_parts.insert(it + 1, part);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void body::insertPartAfter(const int pos, bodyPart* part)
|
||||||
|
{
|
||||||
|
initNewPart(part);
|
||||||
|
|
||||||
|
m_parts.insert(m_parts.begin() + pos + 1, part);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void body::removePart(bodyPart* part)
|
||||||
|
{
|
||||||
|
const std::vector <bodyPart*>::iterator it = std::find
|
||||||
|
(m_parts.begin(), m_parts.end(), part);
|
||||||
|
|
||||||
|
if (it == m_parts.end())
|
||||||
|
throw exceptions::no_such_part();
|
||||||
|
|
||||||
|
delete (*it);
|
||||||
|
|
||||||
|
m_parts.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void body::removePart(const int pos)
|
||||||
|
{
|
||||||
|
delete (m_parts[pos]);
|
||||||
|
|
||||||
|
m_parts.erase(m_parts.begin() + pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void body::removeAllParts()
|
||||||
{
|
{
|
||||||
free_container(m_parts);
|
free_container(m_parts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
body::partsContainer::~partsContainer()
|
const int body::getPartCount() const
|
||||||
{
|
{
|
||||||
clear();
|
return (m_parts.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
body::partsContainer& body::partsContainer::operator=(const partsContainer& c)
|
const bool body::isEmpty() const
|
||||||
{
|
{
|
||||||
std::vector <bodyPart*> parts;
|
return (m_parts.size() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
for (std::vector <bodyPart*>::const_iterator it = c.m_parts.begin() ; it != c.m_parts.end() ; ++it)
|
|
||||||
|
bodyPart* body::getPartAt(const int pos)
|
||||||
|
{
|
||||||
|
return (m_parts[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const bodyPart* const body::getPartAt(const int pos) const
|
||||||
|
{
|
||||||
|
return (m_parts[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector <const bodyPart*> body::getPartList() const
|
||||||
|
{
|
||||||
|
std::vector <const bodyPart*> list;
|
||||||
|
|
||||||
|
list.reserve(m_parts.size());
|
||||||
|
|
||||||
|
for (std::vector <bodyPart*>::const_iterator it = m_parts.begin() ;
|
||||||
|
it != m_parts.end() ; ++it)
|
||||||
{
|
{
|
||||||
bodyPart* p = (*it)->clone();
|
list.push_back(*it);
|
||||||
p->m_parent = &(m_body.m_part);
|
|
||||||
|
|
||||||
parts.push_back(p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::vector <bodyPart*>::iterator it = m_parts.begin() ; it != m_parts.end() ; ++it)
|
return (list);
|
||||||
delete (*it);
|
}
|
||||||
|
|
||||||
m_parts.resize(parts.size());
|
|
||||||
std::copy(parts.begin(), parts.end(), m_parts.begin());
|
|
||||||
|
|
||||||
return (*this);
|
const std::vector <bodyPart*> body::getPartList()
|
||||||
|
{
|
||||||
|
return (m_parts);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
286
src/body.hpp
286
src/body.hpp
@ -47,176 +47,206 @@ class body : public component
|
|||||||
{
|
{
|
||||||
friend class bodyPart;
|
friend class bodyPart;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
body(bodyPart& part);
|
body(bodyPart* parentPart);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// A sub-class for part manipulation
|
body();
|
||||||
class partsContainer
|
~body();
|
||||||
{
|
|
||||||
friend class body;
|
|
||||||
|
|
||||||
protected:
|
/** Add a part at the end of the list.
|
||||||
|
*
|
||||||
|
* @param part part to append
|
||||||
|
*/
|
||||||
|
void appendPart(bodyPart* part);
|
||||||
|
|
||||||
partsContainer(class body& body);
|
/** Insert a new part before the specified part.
|
||||||
~partsContainer();
|
*
|
||||||
|
* @param beforePart part before which the new part will be inserted
|
||||||
|
* @param part part to insert
|
||||||
|
* @throw exceptions::no_such_part if the part is not in the list
|
||||||
|
*/
|
||||||
|
void insertPartBefore(bodyPart* beforePart, bodyPart* part);
|
||||||
|
|
||||||
public:
|
/** Insert a new part before the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position at which to insert the new part (0 to insert at
|
||||||
|
* the beginning of the list)
|
||||||
|
* @param part part to insert
|
||||||
|
*/
|
||||||
|
void insertPartBefore(const int pos, bodyPart* part);
|
||||||
|
|
||||||
// Part iterator
|
/** Insert a new part after the specified part.
|
||||||
class const_iterator;
|
*
|
||||||
|
* @param afterPart part after which the new part will be inserted
|
||||||
|
* @param part part to insert
|
||||||
|
* @throw exceptions::no_such_part if the part is not in the list
|
||||||
|
*/
|
||||||
|
void insertPartAfter(bodyPart* afterPart, bodyPart* part);
|
||||||
|
|
||||||
class iterator
|
/** Insert a new part after the specified position.
|
||||||
{
|
*
|
||||||
friend class body::partsContainer::const_iterator;
|
* @param pos position of the part before the new part
|
||||||
friend class body::partsContainer;
|
* @param part part to insert
|
||||||
|
*/
|
||||||
|
void insertPartAfter(const int pos, bodyPart* part);
|
||||||
|
|
||||||
public:
|
/** Remove the specified part from the list.
|
||||||
|
*
|
||||||
|
* @param part part to remove
|
||||||
|
* @throw exceptions::no_such_part if the part is not in the list
|
||||||
|
*/
|
||||||
|
void removePart(bodyPart* part);
|
||||||
|
|
||||||
typedef std::vector <bodyPart*>::iterator::difference_type difference_type;
|
/** Remove the part at the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position of the part to remove
|
||||||
|
*/
|
||||||
|
void removePart(const int pos);
|
||||||
|
|
||||||
iterator(std::vector <bodyPart*>::iterator it) : m_iterator(it) { }
|
/** Remove all parts from the list.
|
||||||
iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
*/
|
||||||
|
void removeAllParts();
|
||||||
|
|
||||||
iterator& operator=(const iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
/** Return the number of parts in the list.
|
||||||
|
*
|
||||||
|
* @return number of parts
|
||||||
|
*/
|
||||||
|
const int getPartCount() const;
|
||||||
|
|
||||||
bodyPart& operator*() const { return (**m_iterator); }
|
/** Tests whether the list of parts is empty.
|
||||||
bodyPart* operator->() const { return (*m_iterator); }
|
*
|
||||||
|
* @return true if there is no part, false otherwise
|
||||||
|
*/
|
||||||
|
const bool isEmpty() const;
|
||||||
|
|
||||||
iterator& operator++() { ++m_iterator; return (*this); }
|
/** Return the part at the specified position.
|
||||||
iterator operator++(int) { iterator i(*this); ++m_iterator; return (i); }
|
*
|
||||||
|
* @param pos position
|
||||||
|
* @return part at position 'pos'
|
||||||
|
*/
|
||||||
|
bodyPart* getPartAt(const int pos);
|
||||||
|
|
||||||
iterator& operator--() { --m_iterator; return (*this); }
|
/** Return the part at the specified position.
|
||||||
iterator operator--(int) { iterator i(*this); --m_iterator; return (i); }
|
*
|
||||||
|
* @param pos position
|
||||||
|
* @return part at position 'pos'
|
||||||
|
*/
|
||||||
|
const bodyPart* const getPartAt(const int pos) const;
|
||||||
|
|
||||||
iterator& operator+=(difference_type n) { m_iterator += n; return (*this); }
|
/** Return the part list.
|
||||||
iterator& operator-=(difference_type n) { m_iterator -= n; return (*this); }
|
*
|
||||||
|
* @return list of parts
|
||||||
|
*/
|
||||||
|
const std::vector <const bodyPart*> getPartList() const;
|
||||||
|
|
||||||
iterator operator-(difference_type x) const { return iterator(m_iterator - x); }
|
/** Return the part list.
|
||||||
|
*
|
||||||
|
* @return list of parts
|
||||||
|
*/
|
||||||
|
const std::vector <bodyPart*> getPartList();
|
||||||
|
|
||||||
bodyPart& operator[](difference_type n) const { return *(m_iterator[n]); }
|
/** Return the prolog text.
|
||||||
|
*
|
||||||
|
* @return prolog text
|
||||||
|
*/
|
||||||
|
const string& getPrologText() const;
|
||||||
|
|
||||||
const bool operator==(const iterator& it) const { return (it.m_iterator == m_iterator); }
|
/** Set the prolog text.
|
||||||
const bool operator!=(const iterator& it) const { return (!(*this == it)); }
|
*
|
||||||
|
* @param prologText new prolog text
|
||||||
|
*/
|
||||||
|
void setPrologText(const string& prologText);
|
||||||
|
|
||||||
protected:
|
/** Return the epilog text.
|
||||||
|
*
|
||||||
|
* @return epilog text
|
||||||
|
*/
|
||||||
|
const string& getEpilogText() const;
|
||||||
|
|
||||||
std::vector <bodyPart*>::iterator m_iterator;
|
/** Set the epilog text.
|
||||||
};
|
*
|
||||||
|
* @param epilogText new epilog text
|
||||||
|
*/
|
||||||
|
void setEpilogText(const string& epilogText);
|
||||||
|
|
||||||
class const_iterator
|
/** Return a read-only reference to body contents.
|
||||||
{
|
*
|
||||||
public:
|
* @return read-only body contents
|
||||||
|
*/
|
||||||
|
const contentHandler& getContents() const;
|
||||||
|
|
||||||
typedef std::vector <bodyPart*>::const_iterator::difference_type difference_type;
|
/** Return a modifiable reference to body contents.
|
||||||
|
*
|
||||||
|
* @return body contents
|
||||||
|
*/
|
||||||
|
contentHandler& getContents();
|
||||||
|
|
||||||
const_iterator(std::vector <bodyPart*>::const_iterator it) : m_iterator(it) { }
|
/** Set the body contents.
|
||||||
const_iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
*
|
||||||
const_iterator(const const_iterator& it) : m_iterator(it.m_iterator) { }
|
* @param contents new body contents
|
||||||
|
*/
|
||||||
|
void setContents(const contentHandler& contents);
|
||||||
|
|
||||||
const_iterator& operator=(const const_iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
/** Return the media type of the data contained in the body contents.
|
||||||
const_iterator& operator=(const iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
* This is a shortcut for getHeader()->ContentType()->getValue()
|
||||||
|
* on the parent part.
|
||||||
|
*
|
||||||
|
* @return media type of body contents
|
||||||
|
*/
|
||||||
|
const mediaType getContentType() const;
|
||||||
|
|
||||||
const bodyPart& operator*() const { return (**m_iterator); }
|
/** Return the charset of the data contained in the body contents.
|
||||||
const bodyPart* operator->() const { return (*m_iterator); }
|
* This is a shortcut for getHeader()->ContentType()->getCharset()
|
||||||
|
* on the parent part.
|
||||||
|
*
|
||||||
|
* @return charset of body contents
|
||||||
|
*/
|
||||||
|
const charset getCharset() const;
|
||||||
|
|
||||||
const_iterator& operator++() { ++m_iterator; return (*this); }
|
/** Return the encoding used to encode the body contents.
|
||||||
const_iterator operator++(int) { const_iterator i(*this); ++m_iterator; return (i); }
|
* This is a shortcut for getHeader()->ContentTransferEncoding()->getValue()
|
||||||
|
* on the parent part.
|
||||||
|
*
|
||||||
|
* @return encoding of body contents
|
||||||
|
*/
|
||||||
|
const encoding getEncoding() const;
|
||||||
|
|
||||||
const_iterator& operator--() { --m_iterator; return (*this); }
|
/** Generate a new random boundary string.
|
||||||
const_iterator operator--(int) { const_iterator i(*this); --m_iterator; return (i); }
|
*
|
||||||
|
* @return randomly generated boundary string
|
||||||
const_iterator& operator+=(difference_type n) { m_iterator += n; return (*this); }
|
*/
|
||||||
const_iterator& operator-=(difference_type n) { m_iterator -= n; return (*this); }
|
|
||||||
|
|
||||||
const_iterator operator-(difference_type x) const { return const_iterator(m_iterator - x); }
|
|
||||||
|
|
||||||
const bodyPart& operator[](difference_type n) const { return *(m_iterator[n]); }
|
|
||||||
|
|
||||||
const bool operator==(const const_iterator& it) const { return (it.m_iterator == m_iterator); }
|
|
||||||
const bool operator!=(const const_iterator& it) const { return (!(*this == it)); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
std::vector <bodyPart*>::const_iterator m_iterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
iterator begin() { return (m_parts.begin()); }
|
|
||||||
iterator end() { return (m_parts.end()); }
|
|
||||||
|
|
||||||
const_iterator begin() const { return (const_iterator(m_parts.begin())); }
|
|
||||||
const_iterator end() const { return (const_iterator(m_parts.end())); }
|
|
||||||
|
|
||||||
const bodyPart& operator[](const std::vector <bodyPart*>::size_type x) const { return (*m_parts[x]); }
|
|
||||||
bodyPart& operator[](const std::vector <bodyPart*>::size_type x) { return (*m_parts[x]); }
|
|
||||||
|
|
||||||
// Part insertion
|
|
||||||
void append(bodyPart* part);
|
|
||||||
void insert(const iterator it, bodyPart* part);
|
|
||||||
|
|
||||||
// Part removing
|
|
||||||
void remove(const iterator it);
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
// Part count
|
|
||||||
const size_t count() const { return (m_parts.size()); }
|
|
||||||
const size_t size() const { return (m_parts.size()); }
|
|
||||||
|
|
||||||
bodyPart& front() { return (*m_parts.front()); }
|
|
||||||
const bodyPart& front() const { return (*m_parts.front()); }
|
|
||||||
bodyPart& back() { return (*m_parts.back()); }
|
|
||||||
const bodyPart& back() const { return (*m_parts.back()); }
|
|
||||||
|
|
||||||
partsContainer& operator=(const partsContainer& c);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
body& m_body;
|
|
||||||
|
|
||||||
std::vector <bodyPart*> m_parts;
|
|
||||||
|
|
||||||
} parts;
|
|
||||||
|
|
||||||
typedef partsContainer::iterator iterator;
|
|
||||||
typedef partsContainer::const_iterator const_iterator;
|
|
||||||
|
|
||||||
|
|
||||||
const string& prologText() const { return (m_prologText); }
|
|
||||||
string& prologText() { return (m_prologText); }
|
|
||||||
|
|
||||||
const string& epilogText() const { return (m_epilogText); }
|
|
||||||
string& epilogText() { return (m_epilogText); }
|
|
||||||
|
|
||||||
const contentHandler& contents() const { return (m_contents); }
|
|
||||||
contentHandler& contents() { return (m_contents); }
|
|
||||||
|
|
||||||
// Quick-access functions
|
|
||||||
const mediaType contentType() const;
|
|
||||||
const class charset charset() const;
|
|
||||||
const class encoding encoding() const;
|
|
||||||
|
|
||||||
// Boundary string functions
|
|
||||||
static const string generateRandomBoundaryString();
|
static const string generateRandomBoundaryString();
|
||||||
|
|
||||||
|
/** Test a boundary string for validity (as defined in RFC #1521, page 19).
|
||||||
|
*
|
||||||
|
* @param boundary boundary string to test
|
||||||
|
* @return true if the boundary string is valid, false otherwise
|
||||||
|
*/
|
||||||
static const bool isValidBoundary(const string& boundary);
|
static const bool isValidBoundary(const string& boundary);
|
||||||
|
|
||||||
body& operator=(const body& b);
|
body* clone() const;
|
||||||
|
void copyFrom(const component& other);
|
||||||
|
body& operator=(const body& other);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
string m_prologText;
|
string m_prologText;
|
||||||
string m_epilogText;
|
string m_epilogText;
|
||||||
|
|
||||||
contentHandler m_contents;
|
contentHandler m_contents;
|
||||||
|
|
||||||
bodyPart& m_part;
|
bodyPart* m_part;
|
||||||
header& m_header;
|
header* m_header;
|
||||||
|
|
||||||
|
std::vector <bodyPart*> m_parts;
|
||||||
|
|
||||||
const bool isRootPart() const;
|
const bool isRootPart() const;
|
||||||
|
|
||||||
|
void initNewPart(bodyPart* part);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
using component::parse;
|
using component::parse;
|
||||||
|
@ -25,7 +25,7 @@ namespace vmime
|
|||||||
|
|
||||||
|
|
||||||
bodyPart::bodyPart()
|
bodyPart::bodyPart()
|
||||||
: m_body(*this), m_parent(NULL)
|
: m_body(this), m_parent(NULL)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,12 +64,59 @@ bodyPart* bodyPart::clone() const
|
|||||||
bodyPart* p = new bodyPart;
|
bodyPart* p = new bodyPart;
|
||||||
|
|
||||||
p->m_parent = NULL;
|
p->m_parent = NULL;
|
||||||
p->m_header = m_header;
|
|
||||||
p->m_body = m_body;
|
p->m_header.copyFrom(m_header);
|
||||||
|
p->m_body.copyFrom(m_body);
|
||||||
|
|
||||||
return (p);
|
return (p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void bodyPart::copyFrom(const component& other)
|
||||||
|
{
|
||||||
|
const bodyPart& bp = dynamic_cast <const bodyPart&>(other);
|
||||||
|
|
||||||
|
m_header = bp.m_header;
|
||||||
|
m_body = bp.m_body;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bodyPart& bodyPart::operator=(const bodyPart& other)
|
||||||
|
{
|
||||||
|
copyFrom(other);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const header* bodyPart::getHeader() const
|
||||||
|
{
|
||||||
|
return (&m_header);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
header* bodyPart::getHeader()
|
||||||
|
{
|
||||||
|
return (&m_header);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const body* bodyPart::getBody() const
|
||||||
|
{
|
||||||
|
return (&m_body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
body* bodyPart::getBody()
|
||||||
|
{
|
||||||
|
return (&m_body);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bodyPart* bodyPart::getParentPart() const
|
||||||
|
{
|
||||||
|
return (m_parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
|
||||||
|
@ -37,24 +37,28 @@ namespace vmime
|
|||||||
|
|
||||||
class bodyPart : public component
|
class bodyPart : public component
|
||||||
{
|
{
|
||||||
|
friend class body;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
bodyPart();
|
bodyPart();
|
||||||
|
|
||||||
const class header& header() const { return (m_header); }
|
const header* getHeader() const;
|
||||||
class header& header() { return (m_header); }
|
header* getHeader();
|
||||||
|
|
||||||
const class body& body() const { return (m_body); }
|
const body* getBody() const;
|
||||||
class body& body() { return (m_body); }
|
body* getBody();
|
||||||
|
|
||||||
bodyPart* parent() const { return (m_parent); }
|
bodyPart* getParentPart() const;
|
||||||
|
|
||||||
bodyPart* clone() const;
|
bodyPart* clone() const;
|
||||||
|
void copyFrom(const component& other);
|
||||||
|
bodyPart& operator=(const bodyPart& other);
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
class header m_header;
|
header m_header;
|
||||||
class body m_body;
|
body m_body;
|
||||||
|
|
||||||
bodyPart* m_parent;
|
bodyPart* m_parent;
|
||||||
|
|
||||||
@ -66,11 +70,6 @@ public:
|
|||||||
// Component parsing & assembling
|
// Component parsing & assembling
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
||||||
|
|
||||||
|
|
||||||
// This is here because of a bug in g++ < 3.4
|
|
||||||
friend class body;
|
|
||||||
friend class body::partsContainer;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -21,6 +21,8 @@
|
|||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
#include "platformDependant.hpp"
|
#include "platformDependant.hpp"
|
||||||
|
|
||||||
|
#include "utility/stringUtils.hpp"
|
||||||
|
|
||||||
|
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
@ -72,20 +74,11 @@ void charset::generate(utility::outputStream& os, const string::size_type /* max
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Convert the contents of an input stream in a specified charset
|
|
||||||
* to another charset and write the result to an output stream.
|
|
||||||
*
|
|
||||||
* @param in input stream to read data from
|
|
||||||
* @param out output stream to write the converted data
|
|
||||||
* @param source input charset
|
|
||||||
* @param dest output charset
|
|
||||||
*/
|
|
||||||
|
|
||||||
void charset::convert(utility::inputStream& in, utility::outputStream& out,
|
void charset::convert(utility::inputStream& in, utility::outputStream& out,
|
||||||
const charset& source, const charset& dest)
|
const charset& source, const charset& dest)
|
||||||
{
|
{
|
||||||
// Get an iconv descriptor
|
// Get an iconv descriptor
|
||||||
const iconv_t cd = iconv_open(dest.name().c_str(), source.name().c_str());
|
const iconv_t cd = iconv_open(dest.getName().c_str(), source.getName().c_str());
|
||||||
|
|
||||||
if (cd != (iconv_t) -1)
|
if (cd != (iconv_t) -1)
|
||||||
{
|
{
|
||||||
@ -158,20 +151,11 @@ void charset::convert(utility::inputStream& in, utility::outputStream& out,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Convert a string buffer in a specified charset to a string
|
|
||||||
* buffer in another charset.
|
|
||||||
*
|
|
||||||
* @param in input buffer
|
|
||||||
* @param out output buffer
|
|
||||||
* @param from input charset
|
|
||||||
* @param to output charset
|
|
||||||
*/
|
|
||||||
|
|
||||||
template <class STRINGF, class STRINGT>
|
template <class STRINGF, class STRINGT>
|
||||||
void charset::iconvert(const STRINGF& in, STRINGT& out, const charset& from, const charset& to)
|
void charset::iconvert(const STRINGF& in, STRINGT& out, const charset& from, const charset& to)
|
||||||
{
|
{
|
||||||
// Get an iconv descriptor
|
// Get an iconv descriptor
|
||||||
const iconv_t cd = iconv_open(to.name().c_str(), from.name().c_str());
|
const iconv_t cd = iconv_open(to.getName().c_str(), from.getName().c_str());
|
||||||
|
|
||||||
typedef typename STRINGF::value_type ivt;
|
typedef typename STRINGF::value_type ivt;
|
||||||
typedef typename STRINGT::value_type ovt;
|
typedef typename STRINGT::value_type ovt;
|
||||||
@ -218,28 +202,12 @@ void charset::iconvert(const STRINGF& in, STRINGT& out, const charset& from, con
|
|||||||
|
|
||||||
#if VMIME_WIDE_CHAR_SUPPORT
|
#if VMIME_WIDE_CHAR_SUPPORT
|
||||||
|
|
||||||
/** Convert a string buffer in the specified charset to a wide-char
|
|
||||||
* string buffer.
|
|
||||||
*
|
|
||||||
* @param in input buffer
|
|
||||||
* @param out output buffer
|
|
||||||
* @param ch input charset
|
|
||||||
*/
|
|
||||||
|
|
||||||
void charset::decode(const string& in, wstring& out, const charset& ch)
|
void charset::decode(const string& in, wstring& out, const charset& ch)
|
||||||
{
|
{
|
||||||
iconvert(in, out, ch, charset("WCHAR_T"));
|
iconvert(in, out, ch, charset("WCHAR_T"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Convert a wide-char string buffer to a string buffer in the
|
|
||||||
* specified charset.
|
|
||||||
*
|
|
||||||
* @param in input buffer
|
|
||||||
* @param out output buffer
|
|
||||||
* @param ch output charset
|
|
||||||
*/
|
|
||||||
|
|
||||||
void charset::encode(const wstring& in, string& out, const charset& ch)
|
void charset::encode(const wstring& in, string& out, const charset& ch)
|
||||||
{
|
{
|
||||||
iconvert(in, out, charset("WCHAR_T"), ch);
|
iconvert(in, out, charset("WCHAR_T"), ch);
|
||||||
@ -248,37 +216,21 @@ void charset::encode(const wstring& in, string& out, const charset& ch)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/** Convert a string buffer from one charset to another charset.
|
|
||||||
*
|
|
||||||
* @param in input buffer
|
|
||||||
* @param out output buffer
|
|
||||||
* @param source input charset
|
|
||||||
* @param dest output charset
|
|
||||||
*/
|
|
||||||
|
|
||||||
void charset::convert(const string& in, string& out, const charset& source, const charset& dest)
|
void charset::convert(const string& in, string& out, const charset& source, const charset& dest)
|
||||||
{
|
{
|
||||||
iconvert(in, out, source, dest);
|
iconvert(in, out, source, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Returns the default charset used on the system.
|
|
||||||
*
|
|
||||||
* This function simply calls <code>platformDependantHandler::getLocaleCharset()</code>
|
|
||||||
* and is provided for convenience.
|
|
||||||
*
|
|
||||||
* @return system default charset
|
|
||||||
*/
|
|
||||||
|
|
||||||
const charset charset::getLocaleCharset()
|
const charset charset::getLocaleCharset()
|
||||||
{
|
{
|
||||||
return (platformDependant::getHandler()->getLocaleCharset());
|
return (platformDependant::getHandler()->getLocaleCharset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
charset& charset::operator=(const charset& source)
|
charset& charset::operator=(const charset& other)
|
||||||
{
|
{
|
||||||
m_name = source.m_name;
|
copyFrom(other);
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -292,7 +244,7 @@ charset& charset::operator=(const string& name)
|
|||||||
|
|
||||||
const bool charset::operator==(const charset& value) const
|
const bool charset::operator==(const charset& value) const
|
||||||
{
|
{
|
||||||
return (isStringEqualNoCase(m_name, value.m_name));
|
return (stringUtils::isStringEqualNoCase(m_name, value.m_name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -302,4 +254,22 @@ const bool charset::operator!=(const charset& value) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
charset* charset::clone() const
|
||||||
|
{
|
||||||
|
return new charset(m_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string& charset::getName() const
|
||||||
|
{
|
||||||
|
return (m_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void charset::copyFrom(const component& other)
|
||||||
|
{
|
||||||
|
m_name = dynamic_cast <const charset&>(other).m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -41,28 +41,74 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
const string name() const { return (m_name); }
|
/** Return the ISO name of the charset.
|
||||||
|
*
|
||||||
|
* @return charset name
|
||||||
|
*/
|
||||||
|
const string& getName() const;
|
||||||
|
|
||||||
charset& operator=(const charset& source);
|
charset& operator=(const charset& other);
|
||||||
charset& operator=(const string& name);
|
charset& operator=(const string& name);
|
||||||
|
|
||||||
const bool operator==(const charset& value) const;
|
const bool operator==(const charset& value) const;
|
||||||
const bool operator!=(const charset& value) const;
|
const bool operator!=(const charset& value) const;
|
||||||
|
|
||||||
|
/** Returns the default charset used on the system.
|
||||||
|
*
|
||||||
|
* This function simply calls <code>platformDependantHandler::getLocaleCharset()</code>
|
||||||
|
* and is provided for convenience.
|
||||||
|
*
|
||||||
|
* @return system default charset
|
||||||
|
*/
|
||||||
static const charset getLocaleCharset();
|
static const charset getLocaleCharset();
|
||||||
|
|
||||||
#if VMIME_WIDE_CHAR_SUPPORT
|
#if VMIME_WIDE_CHAR_SUPPORT
|
||||||
|
/** Convert a string buffer in the specified charset to a wide-char
|
||||||
|
* string buffer.
|
||||||
|
*
|
||||||
|
* @param in input buffer
|
||||||
|
* @param out output buffer
|
||||||
|
* @param ch input charset
|
||||||
|
*/
|
||||||
static void decode(const string& in, wstring& out, const charset& ch);
|
static void decode(const string& in, wstring& out, const charset& ch);
|
||||||
|
|
||||||
|
/** Convert a wide-char string buffer to a string buffer in the
|
||||||
|
* specified charset.
|
||||||
|
*
|
||||||
|
* @param in input buffer
|
||||||
|
* @param out output buffer
|
||||||
|
* @param ch output charset
|
||||||
|
*/
|
||||||
static void encode(const wstring& in, string& out, const charset& ch);
|
static void encode(const wstring& in, string& out, const charset& ch);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// In-memory conversion
|
/** Convert a string buffer from one charset to another
|
||||||
|
* charset (in-memory conversion)
|
||||||
|
*
|
||||||
|
* \deprecated Use the new convert() method, which takes
|
||||||
|
* an outputStream parameter.
|
||||||
|
*
|
||||||
|
* @param in input buffer
|
||||||
|
* @param out output buffer
|
||||||
|
* @param source input charset
|
||||||
|
* @param dest output charset
|
||||||
|
*/
|
||||||
static void convert(const string& in, string& out, const charset& source, const charset& dest);
|
static void convert(const string& in, string& out, const charset& source, const charset& dest);
|
||||||
|
|
||||||
// Stream conversion
|
/** Convert the contents of an input stream in a specified charset
|
||||||
|
* to another charset and write the result to an output stream.
|
||||||
|
*
|
||||||
|
* @param in input stream to read data from
|
||||||
|
* @param out output stream to write the converted data
|
||||||
|
* @param source input charset
|
||||||
|
* @param dest output charset
|
||||||
|
*/
|
||||||
static void convert(utility::inputStream& in, utility::outputStream& out, const charset& source, const charset& dest);
|
static void convert(utility::inputStream& in, utility::outputStream& out, const charset& source, const charset& dest);
|
||||||
|
|
||||||
protected:
|
charset* clone() const;
|
||||||
|
void copyFrom(const component& other);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
string m_name;
|
string m_name;
|
||||||
|
|
||||||
|
@ -1,50 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "charsetParameter.hpp"
|
|
||||||
#include "parserHelpers.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
void charsetParameter::parseValue(const string& buffer, const string::size_type position,
|
|
||||||
const string::size_type end)
|
|
||||||
{
|
|
||||||
m_value.parse(buffer, position, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const string charsetParameter::generateValue() const
|
|
||||||
{
|
|
||||||
return (m_value.name());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void charsetParameter::copyFrom(const parameter& param)
|
|
||||||
{
|
|
||||||
const charsetParameter& source = dynamic_cast<const charsetParameter&>(param);
|
|
||||||
m_value = source.m_value;
|
|
||||||
|
|
||||||
defaultParameter::copyFrom(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
@ -1,55 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef VMIME_CHARSETPARAMETER_HPP_INCLUDED
|
|
||||||
#define VMIME_CHARSETPARAMETER_HPP_INCLUDED
|
|
||||||
|
|
||||||
|
|
||||||
#include "defaultParameter.hpp"
|
|
||||||
#include "charset.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class charsetParameter : public defaultParameter
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
charset m_value;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void copyFrom(const parameter& param);
|
|
||||||
|
|
||||||
const charset& value() const { return (m_value); }
|
|
||||||
charset& value() { return (m_value); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void parseValue(const string& buffer, const string::size_type position, const string::size_type end);
|
|
||||||
const string generateValue() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
||||||
|
|
||||||
|
|
||||||
#endif // VMIME_CHARSETPARAMETER_HPP_INCLUDED
|
|
@ -18,6 +18,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "component.hpp"
|
#include "component.hpp"
|
||||||
|
#include "base.hpp"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@ -26,6 +27,11 @@ namespace vmime
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
component::~component()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void component::parse(const string& buffer)
|
void component::parse(const string& buffer)
|
||||||
{
|
{
|
||||||
parse(buffer, 0, buffer.length(), NULL);
|
parse(buffer, 0, buffer.length(), NULL);
|
||||||
|
@ -34,11 +34,9 @@ namespace vmime
|
|||||||
|
|
||||||
class component
|
class component
|
||||||
{
|
{
|
||||||
protected:
|
public:
|
||||||
|
|
||||||
virtual ~component() {}
|
virtual ~component();
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
/** Parse RFC-822/MIME data for this component.
|
/** Parse RFC-822/MIME data for this component.
|
||||||
*
|
*
|
||||||
@ -55,8 +53,6 @@ protected:
|
|||||||
*/
|
*/
|
||||||
virtual void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL) = 0;
|
virtual void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL) = 0;
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
/** Generate RFC-2822/MIME data for this component.
|
/** Generate RFC-2822/MIME data for this component.
|
||||||
*
|
*
|
||||||
* \deprecated Use the new generate() method, which takes an outputStream parameter.
|
* \deprecated Use the new generate() method, which takes an outputStream parameter.
|
||||||
@ -65,7 +61,7 @@ public:
|
|||||||
* @param curLinePos length of the current line in the output buffer
|
* @param curLinePos length of the current line in the output buffer
|
||||||
* @return generated data
|
* @return generated data
|
||||||
*/
|
*/
|
||||||
virtual const string generate(const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0) const;
|
const string generate(const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0) const;
|
||||||
|
|
||||||
/** Generate RFC-2822/MIME data for this component.
|
/** Generate RFC-2822/MIME data for this component.
|
||||||
*
|
*
|
||||||
@ -75,6 +71,21 @@ public:
|
|||||||
* @param newLinePos will receive the new line position (length of the last line written)
|
* @param newLinePos will receive the new line position (length of the last line written)
|
||||||
*/
|
*/
|
||||||
virtual void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const = 0;
|
virtual void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const = 0;
|
||||||
|
|
||||||
|
/** Clone this component.
|
||||||
|
*
|
||||||
|
* @return a copy of this component
|
||||||
|
*/
|
||||||
|
virtual component* clone() const = 0;
|
||||||
|
|
||||||
|
/** Replace data in this component by data in other component.
|
||||||
|
* Both components must be of the same type.
|
||||||
|
*
|
||||||
|
* @throw std::bad_cast_exception if the components are not
|
||||||
|
* of the same (dynamic) type
|
||||||
|
* @param other other component to copy data from
|
||||||
|
*/
|
||||||
|
virtual void copyFrom(const component& other) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -148,4 +148,34 @@ namespace charsets
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Fields
|
||||||
|
namespace fields
|
||||||
|
{
|
||||||
|
const string::value_type* const RECEIVED = "Received";
|
||||||
|
const string::value_type* const FROM = "From";
|
||||||
|
const string::value_type* const SENDER = "Sender";
|
||||||
|
const string::value_type* const REPLY_TO = "Reply-To";
|
||||||
|
const string::value_type* const TO = "To";
|
||||||
|
const string::value_type* const CC = "Cc";
|
||||||
|
const string::value_type* const BCC = "Bcc";
|
||||||
|
const string::value_type* const DATE = "Date";
|
||||||
|
const string::value_type* const SUBJECT = "Subject";
|
||||||
|
const string::value_type* const ORGANIZATION = "Organization";
|
||||||
|
const string::value_type* const USER_AGENT = "User-Agent";
|
||||||
|
const string::value_type* const DELIVERED_TO = "Delivered-To";
|
||||||
|
const string::value_type* const RETURN_PATH = "Return-Path";
|
||||||
|
const string::value_type* const MIME_VERSION = "Mime-Version";
|
||||||
|
const string::value_type* const MESSAGE_ID = "Message-Id";
|
||||||
|
const string::value_type* const CONTENT_TYPE = "Content-Type";
|
||||||
|
const string::value_type* const CONTENT_TRANSFER_ENCODING = "Content-Transfer-Encoding";
|
||||||
|
const string::value_type* const CONTENT_DESCRIPTION = "Content-Description";
|
||||||
|
const string::value_type* const CONTENT_DISPOSITION = "Content-Disposition";
|
||||||
|
const string::value_type* const CONTENT_ID = "Content-Id";
|
||||||
|
const string::value_type* const CONTENT_LOCATION = "Content-Location";
|
||||||
|
|
||||||
|
const string::value_type* const X_MAILER = "X-Mailer";
|
||||||
|
const string::value_type* const X_PRIORITY = "X-Priority";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
{
|
{
|
||||||
// Media types (predefined types)
|
/** Constants for media types. */
|
||||||
namespace mediaTypes
|
namespace mediaTypes
|
||||||
{
|
{
|
||||||
// Types
|
// Types
|
||||||
@ -67,7 +67,7 @@ namespace vmime
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Encoding types
|
/** Constants for encoding types. */
|
||||||
namespace encodingTypes
|
namespace encodingTypes
|
||||||
{
|
{
|
||||||
extern const string::value_type* const SEVEN_BIT;
|
extern const string::value_type* const SEVEN_BIT;
|
||||||
@ -79,7 +79,7 @@ namespace vmime
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Disposition types (RFC-2183)
|
/** Constants for disposition types (RFC-2183). */
|
||||||
namespace dispositionTypes
|
namespace dispositionTypes
|
||||||
{
|
{
|
||||||
extern const string::value_type* const INLINE;
|
extern const string::value_type* const INLINE;
|
||||||
@ -87,7 +87,7 @@ namespace vmime
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Charsets
|
/** Constants for charsets. */
|
||||||
namespace charsets
|
namespace charsets
|
||||||
{
|
{
|
||||||
extern const string::value_type* const ISO8859_1;
|
extern const string::value_type* const ISO8859_1;
|
||||||
@ -150,6 +150,35 @@ namespace vmime
|
|||||||
extern const string::value_type* const WINDOWS_1257;
|
extern const string::value_type* const WINDOWS_1257;
|
||||||
extern const string::value_type* const WINDOWS_1258;
|
extern const string::value_type* const WINDOWS_1258;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Constants for standard field names. */
|
||||||
|
namespace fields
|
||||||
|
{
|
||||||
|
extern const string::value_type* const RECEIVED;
|
||||||
|
extern const string::value_type* const FROM;
|
||||||
|
extern const string::value_type* const SENDER;
|
||||||
|
extern const string::value_type* const REPLY_TO;
|
||||||
|
extern const string::value_type* const TO;
|
||||||
|
extern const string::value_type* const CC;
|
||||||
|
extern const string::value_type* const BCC;
|
||||||
|
extern const string::value_type* const DATE;
|
||||||
|
extern const string::value_type* const SUBJECT;
|
||||||
|
extern const string::value_type* const ORGANIZATION;
|
||||||
|
extern const string::value_type* const USER_AGENT;
|
||||||
|
extern const string::value_type* const DELIVERED_TO;
|
||||||
|
extern const string::value_type* const RETURN_PATH;
|
||||||
|
extern const string::value_type* const MIME_VERSION;
|
||||||
|
extern const string::value_type* const MESSAGE_ID;
|
||||||
|
extern const string::value_type* const CONTENT_TYPE;
|
||||||
|
extern const string::value_type* const CONTENT_TRANSFER_ENCODING;
|
||||||
|
extern const string::value_type* const CONTENT_DESCRIPTION;
|
||||||
|
extern const string::value_type* const CONTENT_DISPOSITION;
|
||||||
|
extern const string::value_type* const CONTENT_ID;
|
||||||
|
extern const string::value_type* const CONTENT_LOCATION;
|
||||||
|
|
||||||
|
extern const string::value_type* const X_MAILER;
|
||||||
|
extern const string::value_type* const X_PRIORITY;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#include "contentDispositionField.hpp"
|
#include "contentDispositionField.hpp"
|
||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
|
|
||||||
|
#include "standardParams.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
{
|
{
|
||||||
@ -30,32 +32,69 @@ contentDispositionField::contentDispositionField()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentDispositionField::parseValue(const string& buffer, const string::size_type position,
|
contentDispositionField::contentDispositionField(contentDispositionField&)
|
||||||
const string::size_type end)
|
: headerField(), parameterizedHeaderField(), genericField <disposition>()
|
||||||
{
|
{
|
||||||
m_value.parse(buffer, position, end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string contentDispositionField::generateValue() const
|
const datetime& contentDispositionField::getCreationDate() const
|
||||||
{
|
{
|
||||||
return (m_value.generate());
|
return (dynamic_cast <const dateParameter&>(*findParameter("creation-date")).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
contentDispositionField& contentDispositionField::operator=(const disposition& type)
|
void contentDispositionField::setCreationDate(const datetime& creationDate)
|
||||||
{
|
{
|
||||||
m_value = type;
|
dynamic_cast <dateParameter&>(*getParameter("creation-date")).setValue(creationDate);
|
||||||
return (*this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentDispositionField::copyFrom(const headerField& field)
|
const datetime& contentDispositionField::getModificationDate() const
|
||||||
{
|
{
|
||||||
const contentDispositionField& source = dynamic_cast<const contentDispositionField&>(field);
|
return (dynamic_cast <const dateParameter&>(*findParameter("modification-date")).getValue());
|
||||||
m_value = source.m_value;
|
}
|
||||||
|
|
||||||
parameterizedHeaderField::copyFrom(field);
|
|
||||||
|
void contentDispositionField::setModificationDate(const datetime& modificationDate)
|
||||||
|
{
|
||||||
|
dynamic_cast <dateParameter&>(*getParameter("modification-date")).setValue(modificationDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const datetime& contentDispositionField::getReadDate() const
|
||||||
|
{
|
||||||
|
return (dynamic_cast <const dateParameter&>(*findParameter("read-date")).getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void contentDispositionField::setReadDate(const datetime& readDate)
|
||||||
|
{
|
||||||
|
dynamic_cast <dateParameter&>(*getParameter("read-date")).setValue(readDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string contentDispositionField::getFilename() const
|
||||||
|
{
|
||||||
|
return (dynamic_cast <const defaultParameter&>(*findParameter("filename")).getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void contentDispositionField::setFilename(const string& filename)
|
||||||
|
{
|
||||||
|
dynamic_cast <defaultParameter&>(*getParameter("filename")).setValue(filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string contentDispositionField::getSize() const
|
||||||
|
{
|
||||||
|
return (dynamic_cast <const defaultParameter&>(*findParameter("size")).getValue());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void contentDispositionField::setSize(const string& size)
|
||||||
|
{
|
||||||
|
dynamic_cast <defaultParameter&>(*getParameter("size")).setValue(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,54 +22,41 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "parameterizedHeaderField.hpp"
|
#include "parameterizedHeaderField.hpp"
|
||||||
#include "disposition.hpp"
|
#include "genericField.hpp"
|
||||||
|
|
||||||
#include "dateParameter.hpp"
|
#include "disposition.hpp"
|
||||||
#include "textParameter.hpp"
|
#include "dateTime.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
class contentDispositionField : public parameterizedHeaderField
|
class contentDispositionField : public parameterizedHeaderField, public genericField <disposition>
|
||||||
{
|
{
|
||||||
friend class headerFieldFactory::registerer <contentDispositionField>;
|
friend class headerFieldFactory::registerer <contentDispositionField>;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
contentDispositionField();
|
contentDispositionField();
|
||||||
|
contentDispositionField(contentDispositionField&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void copyFrom(const headerField& field);
|
const datetime& getCreationDate() const;
|
||||||
|
void setCreationDate(const datetime& creationDate);
|
||||||
|
|
||||||
contentDispositionField& operator=(const disposition& type);
|
const datetime& getModificationDate() const;
|
||||||
|
void setModificationDate(const datetime& modificationDate);
|
||||||
|
|
||||||
const disposition& value() const { return (m_value); }
|
const datetime& getReadDate() const;
|
||||||
disposition& value() { return (m_value); }
|
void setReadDate(const datetime& readDate);
|
||||||
|
|
||||||
const datetime& creationDate() const { return (dynamic_cast<const dateParameter&>(parameters.find("creation-date")).value()); }
|
const string getFilename() const;
|
||||||
datetime& creationDate() { return (dynamic_cast<dateParameter&>(parameters.get("creation-date")).value()); }
|
void setFilename(const string& filename);
|
||||||
|
|
||||||
const datetime& modificationDate() const { return (dynamic_cast<const dateParameter&>(parameters.find("modification-date")).value()); }
|
const string getSize() const;
|
||||||
datetime& modificationDate() { return (dynamic_cast<dateParameter&>(parameters.get("modification-date")).value()); }
|
void setSize(const string& size);
|
||||||
|
|
||||||
const datetime& readDate() const { return (dynamic_cast<const dateParameter&>(parameters.find("read-date")).value()); }
|
|
||||||
datetime& readDate() { return (dynamic_cast<dateParameter&>(parameters.get("read-date")).value()); }
|
|
||||||
|
|
||||||
const string& filename() const { return (dynamic_cast<const textParameter&>(parameters.find("filename")).value()); }
|
|
||||||
string& filename() { return (dynamic_cast<textParameter&>(parameters.get("filename")).value()); }
|
|
||||||
|
|
||||||
const string& size() const { return (dynamic_cast<const textParameter&>(parameters.find("size")).value()); }
|
|
||||||
string& size() { return (dynamic_cast<textParameter&>(parameters.get("size")).value()); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
disposition m_value;
|
|
||||||
|
|
||||||
void parseValue(const string& buffer, const string::size_type position, const string::size_type end);
|
|
||||||
const string generateValue() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,62 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "contentEncodingField.hpp"
|
|
||||||
#include "exception.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
contentEncodingField::contentEncodingField()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void contentEncodingField::parseValue(const string& buffer, const string::size_type position,
|
|
||||||
const string::size_type end)
|
|
||||||
{
|
|
||||||
m_value.parse(buffer, position, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const string contentEncodingField::generateValue() const
|
|
||||||
{
|
|
||||||
return (m_value.generate());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
contentEncodingField& contentEncodingField::operator=(const encoding& type)
|
|
||||||
{
|
|
||||||
m_value = type;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void contentEncodingField::copyFrom(const headerField& field)
|
|
||||||
{
|
|
||||||
const contentEncodingField& source = dynamic_cast<const contentEncodingField&>(field);
|
|
||||||
m_value = source.m_value;
|
|
||||||
|
|
||||||
parameterizedHeaderField::copyFrom(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
@ -1,61 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef VMIME_CONTENTENCODINGFIELD_HPP_INCLUDED
|
|
||||||
#define VMIME_CONTENTENCODINGFIELD_HPP_INCLUDED
|
|
||||||
|
|
||||||
|
|
||||||
#include "defaultParameterizedHeaderField.hpp"
|
|
||||||
#include "encoding.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class contentEncodingField : public parameterizedHeaderField
|
|
||||||
{
|
|
||||||
friend class headerFieldFactory::registerer <contentEncodingField>;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
contentEncodingField();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void copyFrom(const headerField& field);
|
|
||||||
|
|
||||||
contentEncodingField& operator=(const encoding& type);
|
|
||||||
|
|
||||||
const encoding& value() const { return (m_value); }
|
|
||||||
encoding& value() { return (m_value); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
encoding m_value;
|
|
||||||
|
|
||||||
void parseValue(const string& buffer, const string::size_type position, const string::size_type end);
|
|
||||||
const string generateValue() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
||||||
|
|
||||||
|
|
||||||
#endif // VMIME_CONTENTENCODINGFIELD_HPP_INCLUDED
|
|
@ -69,7 +69,7 @@ contentHandler& contentHandler::operator=(const contentHandler& cts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentHandler::set(const utility::stringProxy& str, const vmime::encoding& enc)
|
void contentHandler::setData(const utility::stringProxy& str, const vmime::encoding& enc)
|
||||||
{
|
{
|
||||||
m_type = TYPE_STRING;
|
m_type = TYPE_STRING;
|
||||||
m_encoding = enc;
|
m_encoding = enc;
|
||||||
@ -81,7 +81,7 @@ void contentHandler::set(const utility::stringProxy& str, const vmime::encoding&
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentHandler::set(const string& buffer, const vmime::encoding& enc)
|
void contentHandler::setData(const string& buffer, const vmime::encoding& enc)
|
||||||
{
|
{
|
||||||
m_type = TYPE_STRING;
|
m_type = TYPE_STRING;
|
||||||
m_encoding = enc;
|
m_encoding = enc;
|
||||||
@ -93,7 +93,7 @@ void contentHandler::set(const string& buffer, const vmime::encoding& enc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentHandler::set(const string& buffer, const string::size_type start,
|
void contentHandler::setData(const string& buffer, const string::size_type start,
|
||||||
const string::size_type end, const vmime::encoding& enc)
|
const string::size_type end, const vmime::encoding& enc)
|
||||||
{
|
{
|
||||||
m_type = TYPE_STRING;
|
m_type = TYPE_STRING;
|
||||||
@ -106,7 +106,7 @@ void contentHandler::set(const string& buffer, const string::size_type start,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentHandler::set(utility::inputStream* const is, const string::size_type length,
|
void contentHandler::setData(utility::inputStream* const is, const utility::stream::size_type length,
|
||||||
const bool own, const vmime::encoding& enc)
|
const bool own, const vmime::encoding& enc)
|
||||||
{
|
{
|
||||||
m_type = TYPE_STREAM;
|
m_type = TYPE_STREAM;
|
||||||
@ -131,7 +131,7 @@ void contentHandler::set(utility::inputStream* const is, const string::size_type
|
|||||||
|
|
||||||
contentHandler& contentHandler::operator=(const string& buffer)
|
contentHandler& contentHandler::operator=(const string& buffer)
|
||||||
{
|
{
|
||||||
set(buffer, NO_ENCODING);
|
setData(buffer, NO_ENCODING);
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ void contentHandler::generate(utility::outputStream& os, const vmime::encoding&
|
|||||||
utility::auto_ptr <encoder> theDecoder(m_encoding.getEncoder());
|
utility::auto_ptr <encoder> theDecoder(m_encoding.getEncoder());
|
||||||
utility::auto_ptr <encoder> theEncoder(enc.getEncoder());
|
utility::auto_ptr <encoder> theEncoder(enc.getEncoder());
|
||||||
|
|
||||||
theEncoder->properties()["maxlinelength"] = maxLineLength;
|
theEncoder->getProperties()["maxlinelength"] = maxLineLength;
|
||||||
|
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
{
|
{
|
||||||
@ -234,7 +234,7 @@ void contentHandler::generate(utility::outputStream& os, const vmime::encoding&
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
utility::auto_ptr <encoder> theEncoder(enc.getEncoder());
|
utility::auto_ptr <encoder> theEncoder(enc.getEncoder());
|
||||||
theEncoder->properties()["maxlinelength"] = maxLineLength;
|
theEncoder->getProperties()["maxlinelength"] = maxLineLength;
|
||||||
|
|
||||||
// Encode the contents
|
// Encode the contents
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
@ -335,7 +335,7 @@ void contentHandler::extract(utility::outputStream& os) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string::size_type contentHandler::length() const
|
const string::size_type contentHandler::getLength() const
|
||||||
{
|
{
|
||||||
switch (m_type)
|
switch (m_type)
|
||||||
{
|
{
|
||||||
@ -348,7 +348,7 @@ const string::size_type contentHandler::length() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const bool contentHandler::empty() const
|
const bool contentHandler::isEmpty() const
|
||||||
{
|
{
|
||||||
return (m_type == TYPE_NONE);
|
return (m_type == TYPE_NONE);
|
||||||
}
|
}
|
||||||
@ -360,7 +360,7 @@ const bool contentHandler::isEncoded() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const vmime::encoding& contentHandler::encoding() const
|
const vmime::encoding& contentHandler::getEncoding() const
|
||||||
{
|
{
|
||||||
return (m_encoding);
|
return (m_encoding);
|
||||||
}
|
}
|
||||||
|
@ -62,10 +62,10 @@ public:
|
|||||||
//
|
//
|
||||||
// The 'length' parameter is optional (user-defined). You can pass 0 if you want,
|
// The 'length' parameter is optional (user-defined). You can pass 0 if you want,
|
||||||
// VMime does not make use of it.
|
// VMime does not make use of it.
|
||||||
void set(const utility::stringProxy& str, const vmime::encoding& enc = NO_ENCODING);
|
void setData(const utility::stringProxy& str, const vmime::encoding& enc = NO_ENCODING);
|
||||||
void set(const string& buffer, const vmime::encoding& enc = NO_ENCODING);
|
void setData(const string& buffer, const vmime::encoding& enc = NO_ENCODING);
|
||||||
void set(const string& buffer, const string::size_type start, const string::size_type end, const vmime::encoding& enc = NO_ENCODING);
|
void setData(const string& buffer, const string::size_type start, const string::size_type end, const vmime::encoding& enc = NO_ENCODING);
|
||||||
void set(utility::inputStream* const is, const utility::stream::size_type length, const bool own, const vmime::encoding& enc = NO_ENCODING);
|
void setData(utility::inputStream* const is, const utility::stream::size_type length, const bool own, const vmime::encoding& enc = NO_ENCODING);
|
||||||
|
|
||||||
// For compatibility
|
// For compatibility
|
||||||
contentHandler& operator=(const string& buffer);
|
contentHandler& operator=(const string& buffer);
|
||||||
@ -82,16 +82,16 @@ public:
|
|||||||
|
|
||||||
// Returns the actual length of the data. WARNING: this can return 0 if no
|
// Returns the actual length of the data. WARNING: this can return 0 if no
|
||||||
// length was specified when setting data of this object.
|
// length was specified when setting data of this object.
|
||||||
const string::size_type length() const;
|
const string::size_type getLength() const;
|
||||||
|
|
||||||
// Returns 'true' if the data managed by this object is encoded.
|
// Returns 'true' if the data managed by this object is encoded.
|
||||||
const bool isEncoded() const;
|
const bool isEncoded() const;
|
||||||
|
|
||||||
// Returns the encoding used for the data (or "binary" if not encoded).
|
// Returns the encoding used for the data (or "binary" if not encoded).
|
||||||
const vmime::encoding& encoding() const;
|
const vmime::encoding& getEncoding() const;
|
||||||
|
|
||||||
// Returns 'true' if there is no data set.
|
// Returns 'true' if there is no data set.
|
||||||
const bool empty() const;
|
const bool isEmpty() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -20,6 +20,8 @@
|
|||||||
#include "contentTypeField.hpp"
|
#include "contentTypeField.hpp"
|
||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
|
|
||||||
|
#include "standardParams.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
{
|
{
|
||||||
@ -30,32 +32,33 @@ contentTypeField::contentTypeField()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentTypeField::parseValue(const string& buffer,
|
contentTypeField::contentTypeField(contentTypeField&)
|
||||||
const string::size_type position, const string::size_type end)
|
: headerField(), parameterizedHeaderField(), genericField <mediaType>()
|
||||||
{
|
{
|
||||||
m_value.parse(buffer, position, end);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string contentTypeField::generateValue() const
|
const string contentTypeField::getBoundary() const
|
||||||
{
|
{
|
||||||
return (m_value.generate());
|
return (dynamic_cast <const defaultParameter&>(*findParameter("boundary")).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
contentTypeField& contentTypeField::operator=(const mediaType& type)
|
void contentTypeField::setBoundary(const string& boundary)
|
||||||
{
|
{
|
||||||
m_value = type;
|
dynamic_cast <defaultParameter&>(*getParameter("boundary")).setValue(boundary);
|
||||||
return (*this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void contentTypeField::copyFrom(const headerField& field)
|
const charset& contentTypeField::getCharset() const
|
||||||
{
|
{
|
||||||
const contentTypeField& source = dynamic_cast<const contentTypeField&>(field);
|
return (dynamic_cast <const charsetParameter&>(*findParameter("charset")).getValue());
|
||||||
m_value = source.m_value;
|
}
|
||||||
|
|
||||||
parameterizedHeaderField::copyFrom(field);
|
|
||||||
|
void contentTypeField::setCharset(const charset& ch)
|
||||||
|
{
|
||||||
|
dynamic_cast <charsetParameter&>(*getParameter("charset")).setValue(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,47 +22,32 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "parameterizedHeaderField.hpp"
|
#include "parameterizedHeaderField.hpp"
|
||||||
|
#include "genericField.hpp"
|
||||||
|
|
||||||
#include "mediaType.hpp"
|
#include "mediaType.hpp"
|
||||||
#include "charset.hpp"
|
#include "charset.hpp"
|
||||||
|
|
||||||
#include "textParameter.hpp"
|
|
||||||
#include "charsetParameter.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
class contentTypeField : public parameterizedHeaderField
|
class contentTypeField : public parameterizedHeaderField, public genericField <mediaType>
|
||||||
{
|
{
|
||||||
friend class headerFieldFactory::registerer <contentTypeField>;
|
friend class headerFieldFactory::registerer <contentTypeField>;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
contentTypeField();
|
contentTypeField();
|
||||||
|
contentTypeField(contentTypeField&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void copyFrom(const headerField& field);
|
const string getBoundary() const;
|
||||||
|
void setBoundary(const string& boundary);
|
||||||
|
|
||||||
contentTypeField& operator=(const mediaType& type);
|
const charset& getCharset() const;
|
||||||
|
void setCharset(const charset& ch);
|
||||||
const mediaType& value() const { return (m_value); }
|
|
||||||
mediaType& value() { return (m_value); }
|
|
||||||
|
|
||||||
const string& boundary() const { return (dynamic_cast<const textParameter&>(parameters.find("boundary")).value()); }
|
|
||||||
string& boundary() { return (dynamic_cast<textParameter&>(parameters.get("boundary")).value()); }
|
|
||||||
|
|
||||||
const class charset& charset() const { return (dynamic_cast<const charsetParameter&>(parameters.find("charset")).value()); }
|
|
||||||
class charset& charset() { return (dynamic_cast<charsetParameter&>(parameters.get("charset")).value()); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
mediaType m_value;
|
|
||||||
|
|
||||||
void parseValue(const string& buffer, const string::size_type position, const string::size_type end);
|
|
||||||
const string generateValue() const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "dateField.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
dateField::dateField()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dateField::parse(const string& buffer, const string::size_type position,
|
|
||||||
const string::size_type end, string::size_type* newPosition)
|
|
||||||
{
|
|
||||||
m_datetime.parse(buffer, position, end, newPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dateField::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
||||||
{
|
|
||||||
string::size_type pos = curLinePos;
|
|
||||||
|
|
||||||
headerField::generate(os, maxLineLength, pos, &pos);
|
|
||||||
|
|
||||||
m_datetime.generate(os, maxLineLength, pos, newLinePos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dateField& dateField::operator=(const class datetime& datetime)
|
|
||||||
{
|
|
||||||
m_datetime = datetime;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dateField::copyFrom(const headerField& field)
|
|
||||||
{
|
|
||||||
const dateField& source = dynamic_cast<const dateField&>(field);
|
|
||||||
m_datetime = source.m_datetime;
|
|
||||||
|
|
||||||
headerField::copyFrom(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
@ -1,70 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef VMIME_DATEFIELD_HPP_INCLUDED
|
|
||||||
#define VMIME_DATEFIELD_HPP_INCLUDED
|
|
||||||
|
|
||||||
|
|
||||||
#include "base.hpp"
|
|
||||||
#include "component.hpp"
|
|
||||||
|
|
||||||
#include "headerFieldFactory.hpp"
|
|
||||||
#include "dateTime.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class dateField : public headerField
|
|
||||||
{
|
|
||||||
friend class headerFieldFactory::registerer <dateField>;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
dateField();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void copyFrom(const headerField& field);
|
|
||||||
|
|
||||||
dateField& operator=(const class datetime& datetime);
|
|
||||||
|
|
||||||
const datetime& value() const { return (m_datetime); }
|
|
||||||
datetime& value() { return (m_datetime); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
datetime m_datetime;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
using headerField::parse;
|
|
||||||
using headerField::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
||||||
|
|
||||||
|
|
||||||
#endif // VMIME_DATEFIELD_HPP_INCLUDED
|
|
@ -1,50 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "dateParameter.hpp"
|
|
||||||
#include "parserHelpers.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
void dateParameter::parseValue(const string& buffer, const string::size_type position,
|
|
||||||
const string::size_type end)
|
|
||||||
{
|
|
||||||
m_value.parse(buffer, position, end);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const string dateParameter::generateValue() const
|
|
||||||
{
|
|
||||||
return (m_value.generate());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void dateParameter::copyFrom(const parameter& param)
|
|
||||||
{
|
|
||||||
const dateParameter& source = dynamic_cast<const dateParameter&>(param);
|
|
||||||
m_value = source.m_value;
|
|
||||||
|
|
||||||
defaultParameter::copyFrom(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
@ -86,7 +86,7 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
|||||||
if (p < pend && isdigit(*p))
|
if (p < pend && isdigit(*p))
|
||||||
{
|
{
|
||||||
// Month day
|
// Month day
|
||||||
comp_t day = 0;
|
int day = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -221,7 +221,7 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
|||||||
if (p < pend && isdigit(*p))
|
if (p < pend && isdigit(*p))
|
||||||
{
|
{
|
||||||
// Year
|
// Year
|
||||||
comp_t year = 0;
|
int year = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -249,7 +249,7 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
|||||||
if (p < pend && isdigit(*p))
|
if (p < pend && isdigit(*p))
|
||||||
{
|
{
|
||||||
// Hour
|
// Hour
|
||||||
comp_t hour = 0;
|
int hour = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -271,7 +271,7 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
|||||||
if (p < pend && isdigit(*p))
|
if (p < pend && isdigit(*p))
|
||||||
{
|
{
|
||||||
// Minute
|
// Minute
|
||||||
comp_t minute = 0;
|
int minute = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -293,7 +293,7 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
|||||||
if (p < pend && isdigit(*p))
|
if (p < pend && isdigit(*p))
|
||||||
{
|
{
|
||||||
// Second
|
// Second
|
||||||
comp_t second = 0;
|
int second = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -342,7 +342,7 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
|||||||
++p;
|
++p;
|
||||||
|
|
||||||
// Zone offset (in hour/minutes)
|
// Zone offset (in hour/minutes)
|
||||||
comp_t offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
@ -351,8 +351,8 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
while (p < pend && isdigit(*p));
|
while (p < pend && isdigit(*p));
|
||||||
|
|
||||||
const comp_t hourOff = offset / 100;
|
const int hourOff = offset / 100;
|
||||||
const comp_t minOff = offset % 100;
|
const int minOff = offset % 100;
|
||||||
|
|
||||||
if (sign == '+')
|
if (sign == '+')
|
||||||
m_zone = hourOff * 60 + minOff;
|
m_zone = hourOff * 60 + minOff;
|
||||||
@ -538,13 +538,13 @@ void datetime::generate(utility::outputStream& os, const string::size_type /* ma
|
|||||||
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
{ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||||
|
|
||||||
const comp_t z = ((m_zone < 0) ? -m_zone : m_zone);
|
const int z = ((m_zone < 0) ? -m_zone : m_zone);
|
||||||
const comp_t zh = z / 60;
|
const int zh = z / 60;
|
||||||
const comp_t zm = z % 60;
|
const int zm = z % 60;
|
||||||
|
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
oss << dayNames[dayOfWeek(m_year, m_month, m_day)] << ", "
|
oss << dayNames[dayOfWeek(m_year, m_month, m_day)] << ", "
|
||||||
<< m_day << " " << monthNames[month() - 1] << " " << year()
|
<< m_day << " " << monthNames[m_month - 1] << " " << m_year
|
||||||
<< " " << std::setfill('0') << std::setw(2) << m_hour << ":"
|
<< " " << std::setfill('0') << std::setw(2) << m_hour << ":"
|
||||||
<< std::setfill('0') << std::setw(2) << m_minute << ":"
|
<< std::setfill('0') << std::setw(2) << m_minute << ":"
|
||||||
<< std::setfill('0') << std::setw(2) << m_second
|
<< std::setfill('0') << std::setw(2) << m_second
|
||||||
@ -566,16 +566,16 @@ datetime::datetime()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
datetime::datetime(const comp_t year, const comp_t month, const comp_t day)
|
datetime::datetime(const int year, const int month, const int day)
|
||||||
: m_year(year), m_month(month), m_day(day),
|
: m_year(year), m_month(month), m_day(day),
|
||||||
m_hour(0), m_minute(0), m_second(0), m_zone(0)
|
m_hour(0), m_minute(0), m_second(0), m_zone(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
datetime::datetime(const comp_t year, const comp_t month, const comp_t day,
|
datetime::datetime(const int year, const int month, const int day,
|
||||||
const comp_t hour, const comp_t minute, const comp_t second,
|
const int hour, const int minute, const int second,
|
||||||
const comp_t zone)
|
const int zone)
|
||||||
: m_year(year), m_month(month), m_day(day),
|
: m_year(year), m_month(month), m_day(day),
|
||||||
m_hour(hour), m_minute(minute), m_second(second), m_zone(zone)
|
m_hour(hour), m_minute(minute), m_second(second), m_zone(zone)
|
||||||
{
|
{
|
||||||
@ -600,8 +600,10 @@ datetime::~datetime()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void datetime::copyFrom(const datetime& d)
|
void datetime::copyFrom(const component& other)
|
||||||
{
|
{
|
||||||
|
const datetime& d = dynamic_cast <const datetime&>(other);
|
||||||
|
|
||||||
m_year = d.m_year;
|
m_year = d.m_year;
|
||||||
m_month = d.m_month;
|
m_month = d.m_month;
|
||||||
m_day = d.m_day;
|
m_day = d.m_day;
|
||||||
@ -612,9 +614,9 @@ void datetime::copyFrom(const datetime& d)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
datetime& datetime::operator=(const datetime& d)
|
datetime& datetime::operator=(const datetime& other)
|
||||||
{
|
{
|
||||||
copyFrom(d);
|
copyFrom(other);
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -626,7 +628,7 @@ datetime& datetime::operator=(const string& s)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void datetime::getTime(comp_t& hour, comp_t& minute, comp_t& second, comp_t& zone) const
|
void datetime::getTime(int& hour, int& minute, int& second, int& zone) const
|
||||||
{
|
{
|
||||||
hour = m_hour;
|
hour = m_hour;
|
||||||
minute = m_minute;
|
minute = m_minute;
|
||||||
@ -635,7 +637,7 @@ void datetime::getTime(comp_t& hour, comp_t& minute, comp_t& second, comp_t& zon
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void datetime::getTime(comp_t& hour, comp_t& minute, comp_t& second) const
|
void datetime::getTime(int& hour, int& minute, int& second) const
|
||||||
{
|
{
|
||||||
hour = m_hour;
|
hour = m_hour;
|
||||||
minute = m_minute;
|
minute = m_minute;
|
||||||
@ -643,7 +645,7 @@ void datetime::getTime(comp_t& hour, comp_t& minute, comp_t& second) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void datetime::getDate(comp_t& year, comp_t& month, comp_t& day) const
|
void datetime::getDate(int& year, int& month, int& day) const
|
||||||
{
|
{
|
||||||
year = m_year;
|
year = m_year;
|
||||||
month = m_month;
|
month = m_month;
|
||||||
@ -651,8 +653,8 @@ void datetime::getDate(comp_t& year, comp_t& month, comp_t& day) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void datetime::setTime(const comp_t hour, const comp_t minute,
|
void datetime::setTime(const int hour, const int minute,
|
||||||
const comp_t second, const comp_t zone)
|
const int second, const int zone)
|
||||||
{
|
{
|
||||||
m_hour = hour;
|
m_hour = hour;
|
||||||
m_minute = minute;
|
m_minute = minute;
|
||||||
@ -661,7 +663,7 @@ void datetime::setTime(const comp_t hour, const comp_t minute,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void datetime::setDate(const comp_t year, const comp_t month, const comp_t day)
|
void datetime::setDate(const int year, const int month, const int day)
|
||||||
{
|
{
|
||||||
m_year = year;
|
m_year = year;
|
||||||
m_month = month;
|
m_month = month;
|
||||||
@ -669,10 +671,10 @@ void datetime::setDate(const comp_t year, const comp_t month, const comp_t day)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const datetime::comp_t datetime::dayOfWeek(const comp_t year, const comp_t month, const comp_t day)
|
const int datetime::dayOfWeek(const int year, const int month, const int day)
|
||||||
{
|
{
|
||||||
comp_t y = year;
|
int y = year;
|
||||||
comp_t m = month;
|
int m = month;
|
||||||
|
|
||||||
// From RFC-3339 - Appendix B. Day of the Week
|
// From RFC-3339 - Appendix B. Day of the Week
|
||||||
|
|
||||||
@ -686,7 +688,7 @@ const datetime::comp_t datetime::dayOfWeek(const comp_t year, const comp_t month
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Split by century
|
// Split by century
|
||||||
const comp_t cent = y / 100;
|
const int cent = y / 100;
|
||||||
y %= 100;
|
y %= 100;
|
||||||
|
|
||||||
return (((26 * m - 2) / 10 + day + y + (y >> 2) + (cent >> 2) + 5 * cent) % 7);
|
return (((26 * m - 2) / 10 + day + y + (y >> 2) + (cent >> 2) + 5 * cent) % 7);
|
||||||
@ -699,4 +701,27 @@ const datetime datetime::now()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
datetime* datetime::clone() const
|
||||||
|
{
|
||||||
|
return new datetime(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const int datetime::getYear() const { return (m_year); }
|
||||||
|
const int datetime::getMonth() const { return (m_month); }
|
||||||
|
const int datetime::getDay() const { return (m_day); }
|
||||||
|
const int datetime::getHour() const { return (m_hour); }
|
||||||
|
const int datetime::getMinute() const { return (m_minute); }
|
||||||
|
const int datetime::getSecond() const { return (m_second); }
|
||||||
|
const int datetime::getZone() const { return (m_zone); }
|
||||||
|
|
||||||
|
void datetime::setYear(const int year) { m_year = year; }
|
||||||
|
void datetime::setMonth(const int month) { m_month = std::min(std::max(month, 1), 12); }
|
||||||
|
void datetime::setDay(const int day) { m_day = day; }
|
||||||
|
void datetime::setHour(const int hour) { m_hour = hour; }
|
||||||
|
void datetime::setMinute(const int minute) { m_minute = minute; }
|
||||||
|
void datetime::setSecond(const int second) { m_second = second; }
|
||||||
|
void datetime::setZone(const int zone) { m_zone = zone; }
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -36,13 +36,10 @@ class datetime : public component
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Data type for a date/time component
|
|
||||||
typedef int comp_t;
|
|
||||||
|
|
||||||
// Constructors
|
// Constructors
|
||||||
datetime();
|
datetime();
|
||||||
datetime(const comp_t year, const comp_t month, const comp_t day);
|
datetime(const int year, const int month, const int day);
|
||||||
datetime(const comp_t year, const comp_t month, const comp_t day, const comp_t hour, const comp_t minute, const comp_t second, const comp_t zone = GMT);
|
datetime(const int year, const int month, const int day, const int hour, const int minute, const int second, const int zone = GMT);
|
||||||
datetime(const datetime& d);
|
datetime(const datetime& d);
|
||||||
datetime(const string& date);
|
datetime(const string& date);
|
||||||
|
|
||||||
@ -172,58 +169,60 @@ public:
|
|||||||
SAT = 6
|
SAT = 6
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
// Date components
|
// Date components
|
||||||
comp_t m_year;
|
int m_year;
|
||||||
comp_t m_month;
|
int m_month;
|
||||||
comp_t m_day;
|
int m_day;
|
||||||
|
|
||||||
// Time components
|
// Time components
|
||||||
comp_t m_hour;
|
int m_hour;
|
||||||
comp_t m_minute;
|
int m_minute;
|
||||||
comp_t m_second;
|
int m_second;
|
||||||
comp_t m_zone;
|
int m_zone;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Get
|
// Get
|
||||||
const comp_t year() const { return (m_year); }
|
const int getYear() const;
|
||||||
const comp_t month() const { return (m_month); }
|
const int getMonth() const;
|
||||||
const comp_t day() const { return (m_day); }
|
const int getDay() const;
|
||||||
const comp_t hour() const { return (m_hour); }
|
const int getHour() const;
|
||||||
const comp_t minute() const { return (m_minute); }
|
const int getMinute() const;
|
||||||
const comp_t second() const { return (m_second); }
|
const int getSecond() const;
|
||||||
const comp_t zone() const { return (m_zone); }
|
const int getZone() const;
|
||||||
|
|
||||||
void getTime(comp_t& hour, comp_t& minute, comp_t& second, comp_t& zone) const;
|
void getTime(int& hour, int& minute, int& second, int& zone) const;
|
||||||
void getTime(comp_t& hour, comp_t& minute, comp_t& second) const;
|
void getTime(int& hour, int& minute, int& second) const;
|
||||||
void getDate(comp_t& year, comp_t& month, comp_t& day) const;
|
void getDate(int& year, int& month, int& day) const;
|
||||||
|
|
||||||
// Set
|
// Set
|
||||||
comp_t& year() { return (m_year); }
|
void setYear(const int year);
|
||||||
comp_t& month() { return (m_month); }
|
void setMonth(const int month);
|
||||||
comp_t& day() { return (m_day); }
|
void setDay(const int day);
|
||||||
comp_t& hour() { return (m_hour); }
|
void setHour(const int hour);
|
||||||
comp_t& minute() { return (m_minute); }
|
void setMinute(const int minute);
|
||||||
comp_t& second() { return (m_second); }
|
void setSecond(const int second);
|
||||||
comp_t& zone() { return (m_zone); }
|
void setZone(const int zone);
|
||||||
|
|
||||||
void setTime(const comp_t hour = 0, const comp_t minute = 0, const comp_t second = 0, const comp_t zone = GMT);
|
void setTime(const int hour = 0, const int minute = 0, const int second = 0, const int zone = GMT);
|
||||||
void setDate(const comp_t year, const comp_t month, const comp_t day);
|
void setDate(const int year, const int month, const int day);
|
||||||
|
|
||||||
// Assignment
|
// Assignment
|
||||||
datetime& operator=(const datetime& d);
|
datetime& operator=(const datetime& other);
|
||||||
datetime& operator=(const string& s);
|
datetime& operator=(const string& s);
|
||||||
|
|
||||||
void copyFrom(const datetime& d);
|
void copyFrom(const component& other);
|
||||||
|
|
||||||
|
datetime* clone() const;
|
||||||
|
|
||||||
// Current date and time
|
// Current date and time
|
||||||
static const datetime now();
|
static const datetime now();
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
static const comp_t dayOfWeek(const comp_t year, const comp_t month, const comp_t day);
|
static const int dayOfWeek(const int year, const int month, const int day);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ defaultAttachment::defaultAttachment()
|
|||||||
|
|
||||||
|
|
||||||
defaultAttachment::defaultAttachment(const contentHandler& data,
|
defaultAttachment::defaultAttachment(const contentHandler& data,
|
||||||
const class encoding& enc, const mediaType& type, const text& desc)
|
const encoding& enc, const mediaType& type, const text& desc)
|
||||||
: m_type(type), m_desc(desc), m_data(data), m_encoding(enc)
|
: m_type(type), m_desc(desc), m_data(data), m_encoding(enc)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -51,15 +51,12 @@ defaultAttachment::defaultAttachment(const defaultAttachment& attach)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
attachment& defaultAttachment::operator=(const attachment& attach)
|
defaultAttachment& defaultAttachment::operator=(const defaultAttachment& attach)
|
||||||
{
|
{
|
||||||
const defaultAttachment& att =
|
m_type = attach.m_type;
|
||||||
dynamic_cast <const defaultAttachment&>(attach);
|
m_desc = attach.m_desc;
|
||||||
|
m_data = attach.m_data;
|
||||||
m_type = att.m_type;
|
m_encoding = attach.m_encoding;
|
||||||
m_desc = att.m_desc;
|
|
||||||
m_data = att.m_data;
|
|
||||||
m_encoding = att.m_encoding;
|
|
||||||
|
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
@ -69,7 +66,7 @@ void defaultAttachment::generateIn(bodyPart& parent) const
|
|||||||
{
|
{
|
||||||
// Create and append a new part for this attachment
|
// Create and append a new part for this attachment
|
||||||
bodyPart* part = new bodyPart;
|
bodyPart* part = new bodyPart;
|
||||||
parent.body().parts.append(part);
|
parent.getBody()->appendPart(part);
|
||||||
|
|
||||||
generatePart(*part);
|
generatePart(*part);
|
||||||
}
|
}
|
||||||
@ -78,13 +75,37 @@ void defaultAttachment::generateIn(bodyPart& parent) const
|
|||||||
void defaultAttachment::generatePart(bodyPart& part) const
|
void defaultAttachment::generatePart(bodyPart& part) const
|
||||||
{
|
{
|
||||||
// Set header fields
|
// Set header fields
|
||||||
part.header().fields.ContentType() = m_type;
|
part.getHeader()->ContentType().setValue(m_type);
|
||||||
if (!m_desc.empty()) part.header().fields.ContentDescription() = m_desc;
|
if (!m_desc.isEmpty()) part.getHeader()->ContentDescription().setValue(m_desc);
|
||||||
part.header().fields.ContentTransferEncoding() = m_encoding;
|
part.getHeader()->ContentTransferEncoding().setValue(m_encoding);
|
||||||
part.header().fields.ContentDisposition() = disposition(dispositionTypes::ATTACHMENT);
|
part.getHeader()->ContentDisposition().setValue(disposition(dispositionTypes::ATTACHMENT));
|
||||||
|
|
||||||
// Set contents
|
// Set contents
|
||||||
part.body().contents() = m_data;
|
part.getBody()->getContents() = m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const mediaType& defaultAttachment::getType() const
|
||||||
|
{
|
||||||
|
return (m_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const text& defaultAttachment::getDescription() const
|
||||||
|
{
|
||||||
|
return (m_desc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const contentHandler& defaultAttachment::getData() const
|
||||||
|
{
|
||||||
|
return (m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const encoding& defaultAttachment::getEncoding() const
|
||||||
|
{
|
||||||
|
return (m_encoding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,27 +38,31 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
defaultAttachment(const contentHandler& data, const class encoding& enc, const mediaType& type, const text& desc = NULL_TEXT);
|
defaultAttachment(const contentHandler& data, const encoding& enc, const mediaType& type, const text& desc = NULL_TEXT);
|
||||||
defaultAttachment(const contentHandler& data, const mediaType& type, const text& desc = NULL_TEXT);
|
defaultAttachment(const contentHandler& data, const mediaType& type, const text& desc = NULL_TEXT);
|
||||||
defaultAttachment(const defaultAttachment& attach);
|
defaultAttachment(const defaultAttachment& attach);
|
||||||
|
|
||||||
attachment& operator=(const attachment& attach);
|
defaultAttachment& operator=(const defaultAttachment& attach);
|
||||||
|
|
||||||
const mediaType& type() const { return (m_type); }
|
const mediaType& getType() const;
|
||||||
const text& description() const { return (m_desc); }
|
const text& getDescription() const;
|
||||||
const contentHandler& data() const { return (m_data); }
|
const contentHandler& getData() const;
|
||||||
const class encoding& encoding() const { return (m_encoding); }
|
const encoding& getEncoding() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
mediaType m_type; // Media type (eg. "application/octet-stream")
|
mediaType m_type; // Media type (eg. "application/octet-stream")
|
||||||
text m_desc; // Description (eg. "The image you requested")
|
text m_desc; // Description (eg. "The image you requested")
|
||||||
contentHandler m_data; // Attachment data (eg. the file contents)
|
contentHandler m_data; // Attachment data (eg. the file contents)
|
||||||
class encoding m_encoding; // Encoding
|
encoding m_encoding; // Encoding
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
// No need to override "generateIn", use "generatePart" instead (see below).
|
// No need to override "generateIn", use "generatePart" instead (see below).
|
||||||
void generateIn(bodyPart& parent) const;
|
void generateIn(bodyPart& parent) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
virtual void generatePart(bodyPart& part) const;
|
virtual void generatePart(bodyPart& part) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,71 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "defaultField.hpp"
|
|
||||||
#include "text.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
defaultField::defaultField()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void defaultField::parse(const string& buffer, const string::size_type position,
|
|
||||||
const string::size_type end, string::size_type* newPosition)
|
|
||||||
{
|
|
||||||
m_text = string(buffer.begin() + position, buffer.begin() + end);
|
|
||||||
|
|
||||||
if (newPosition)
|
|
||||||
*newPosition = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void defaultField::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
||||||
{
|
|
||||||
string::size_type pos = curLinePos;
|
|
||||||
|
|
||||||
headerField::generate(os, maxLineLength, pos, &pos);
|
|
||||||
|
|
||||||
encodeAndFoldText(os, vmime::text(word(m_text, charset())), maxLineLength,
|
|
||||||
pos, newLinePos, encodeAndFoldFlags::forceNoEncoding);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
defaultField& defaultField::operator=(const string& text)
|
|
||||||
{
|
|
||||||
m_text = text;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void defaultField::copyFrom(const headerField& field)
|
|
||||||
{
|
|
||||||
const defaultField& source = dynamic_cast<const defaultField&>(field);
|
|
||||||
m_text = source.m_text;
|
|
||||||
|
|
||||||
headerField::copyFrom(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
@ -1,70 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef VMIME_DEFAULTFIELD_HPP_INCLUDED
|
|
||||||
#define VMIME_DEFAULTFIELD_HPP_INCLUDED
|
|
||||||
|
|
||||||
|
|
||||||
#include "base.hpp"
|
|
||||||
#include "component.hpp"
|
|
||||||
|
|
||||||
#include "headerFieldFactory.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class defaultField : public headerField
|
|
||||||
{
|
|
||||||
friend class headerFieldFactory;
|
|
||||||
friend class headerFieldFactory::registerer <defaultField>;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
defaultField();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void copyFrom(const headerField& field);
|
|
||||||
|
|
||||||
defaultField& operator=(const string& text);
|
|
||||||
|
|
||||||
const string& value() const { return (m_text); }
|
|
||||||
string& value() { return (m_text); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
string m_text;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
using headerField::parse;
|
|
||||||
using headerField::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
||||||
|
|
||||||
|
|
||||||
#endif // VMIME_DEFAULTFIELD_HPP_INCLUDED
|
|
@ -1,117 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "defaultParameter.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
void defaultParameter::parse(const string& buffer, const string::size_type position,
|
|
||||||
const string::size_type end, string::size_type* newPosition)
|
|
||||||
{
|
|
||||||
parseValue(buffer, position, end);
|
|
||||||
|
|
||||||
if (newPosition)
|
|
||||||
*newPosition = end;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void defaultParameter::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
||||||
{
|
|
||||||
string::size_type pos = curLinePos;
|
|
||||||
|
|
||||||
const string value = quotedValue();
|
|
||||||
|
|
||||||
pos += m_name.length() + value.length() + 2;
|
|
||||||
|
|
||||||
if (pos > maxLineLength)
|
|
||||||
{
|
|
||||||
os << NEW_LINE_SEQUENCE;
|
|
||||||
pos = NEW_LINE_SEQUENCE_LENGTH;
|
|
||||||
}
|
|
||||||
|
|
||||||
os << m_name << "=" << value;
|
|
||||||
|
|
||||||
if (newLinePos)
|
|
||||||
*newLinePos = pos;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const string defaultParameter::quotedValue() const
|
|
||||||
{
|
|
||||||
const string value(generateValue());
|
|
||||||
|
|
||||||
std::ostringstream ss;
|
|
||||||
string::const_iterator start = value.begin();
|
|
||||||
bool quoted = false;
|
|
||||||
|
|
||||||
for (string::const_iterator i = value.begin() ; i != value.end() ; ++i)
|
|
||||||
{
|
|
||||||
switch (*i)
|
|
||||||
{
|
|
||||||
// Characters that need to be quoted _and_ escaped
|
|
||||||
case '"':
|
|
||||||
case '\\':
|
|
||||||
|
|
||||||
ss << string(start, i) << "\\" << *i;
|
|
||||||
|
|
||||||
start = i + 1;
|
|
||||||
quoted = true;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
// Other characters that need quoting
|
|
||||||
case ' ':
|
|
||||||
case '\t':
|
|
||||||
case '(':
|
|
||||||
case ')':
|
|
||||||
case '<':
|
|
||||||
case '>':
|
|
||||||
case '@':
|
|
||||||
case ',':
|
|
||||||
case ';':
|
|
||||||
case ':':
|
|
||||||
case '/':
|
|
||||||
case '[':
|
|
||||||
case ']':
|
|
||||||
case '?':
|
|
||||||
case '=':
|
|
||||||
|
|
||||||
quoted = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (start != value.end())
|
|
||||||
ss << string(start, value.end());
|
|
||||||
|
|
||||||
return (quoted ? ("\"" + ss.str() + "\"") : (ss.str()));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void defaultParameter::copyFrom(const parameter& param)
|
|
||||||
{
|
|
||||||
parameter::copyFrom(param);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
@ -1,55 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef VMIME_DEFAULTPARAMETER_HPP_INCLUDED
|
|
||||||
#define VMIME_DEFAULTPARAMETER_HPP_INCLUDED
|
|
||||||
|
|
||||||
|
|
||||||
#include "parameter.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class defaultParameter : public parameter
|
|
||||||
{
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void copyFrom(const parameter& param);
|
|
||||||
|
|
||||||
virtual void parseValue(const string& buffer, const string::size_type position, const string::size_type end) = 0;
|
|
||||||
virtual const string generateValue() const = 0;
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
const string quotedValue() const;
|
|
||||||
|
|
||||||
// No need to override these in class that derive from "defaultParameter".
|
|
||||||
// "defaultParameter" provides a default handling for value parsing/building.
|
|
||||||
// Instead, you must define two functions: "parseValue" and "generateValue" (see above).
|
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
||||||
|
|
||||||
|
|
||||||
#endif // VMIME_DEFAULTPARAMETER_HPP_INCLUDED
|
|
@ -1,62 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "defaultParameterizedHeaderField.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
defaultParameterizedHeaderField::defaultParameterizedHeaderField()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void defaultParameterizedHeaderField::parseValue(const string& buffer,
|
|
||||||
const string::size_type position, const string::size_type end)
|
|
||||||
{
|
|
||||||
m_value = string(buffer.begin() + position, buffer.begin() + end);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const string defaultParameterizedHeaderField::generateValue() const
|
|
||||||
{
|
|
||||||
return (m_value);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void defaultParameterizedHeaderField::copyFrom(const headerField& field)
|
|
||||||
{
|
|
||||||
const defaultParameterizedHeaderField& source = dynamic_cast
|
|
||||||
<const defaultParameterizedHeaderField&>(field);
|
|
||||||
m_value = source.m_value;
|
|
||||||
|
|
||||||
parameterizedHeaderField::copyFrom(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
defaultParameterizedHeaderField& defaultParameterizedHeaderField::operator=(const string& value)
|
|
||||||
{
|
|
||||||
m_value = value;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
@ -1,63 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef VMIME_DEFAULTPARAMETERIZEDHEADERFIELD_HPP_INCLUDED
|
|
||||||
#define VMIME_DEFAULTPARAMETERIZEDHEADERFIELD_HPP_INCLUDED
|
|
||||||
|
|
||||||
|
|
||||||
#include "parameterizedHeaderField.hpp"
|
|
||||||
#include "base.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class defaultParameterizedHeaderField : public parameterizedHeaderField
|
|
||||||
{
|
|
||||||
friend class headerFieldFactory::registerer <defaultParameterizedHeaderField>;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
defaultParameterizedHeaderField();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void copyFrom(const headerField& field);
|
|
||||||
|
|
||||||
defaultParameterizedHeaderField& operator=(const string& value);
|
|
||||||
|
|
||||||
const string& value() const { return (m_value); }
|
|
||||||
string& value() { return (m_value); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
string m_value;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void parseValue(const string& buffer, const string::size_type position, const string::size_type end);
|
|
||||||
const string generateValue() const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
||||||
|
|
||||||
|
|
||||||
#endif // VMIME_DEFAULTPARAMETERIZEDHEADERFIELD_HPP_INCLUDED
|
|
@ -18,6 +18,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "disposition.hpp"
|
#include "disposition.hpp"
|
||||||
|
#include "utility/stringUtils.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
@ -31,7 +32,7 @@ disposition::disposition()
|
|||||||
|
|
||||||
|
|
||||||
disposition::disposition(const string& name)
|
disposition::disposition(const string& name)
|
||||||
: m_name(toLower(name))
|
: m_name(stringUtils::toLower(name))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ disposition::disposition(const disposition& type)
|
|||||||
void disposition::parse(const string& buffer, const string::size_type position,
|
void disposition::parse(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
m_name = toLower(string(buffer.begin() + position, buffer.begin() + end));
|
m_name = stringUtils::toLower(string(buffer.begin() + position, buffer.begin() + end));
|
||||||
|
|
||||||
if (newPosition)
|
if (newPosition)
|
||||||
*newPosition = end;
|
*newPosition = end;
|
||||||
@ -62,23 +63,16 @@ void disposition::generate(utility::outputStream& os, const string::size_type /*
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
disposition& disposition::operator=(const disposition& source)
|
|
||||||
{
|
|
||||||
m_name = source.m_name;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
disposition& disposition::operator=(const string& name)
|
disposition& disposition::operator=(const string& name)
|
||||||
{
|
{
|
||||||
m_name = toLower(name);
|
m_name = stringUtils::toLower(name);
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const bool disposition::operator==(const disposition& value) const
|
const bool disposition::operator==(const disposition& value) const
|
||||||
{
|
{
|
||||||
return (toLower(m_name) == value.m_name);
|
return (stringUtils::toLower(m_name) == value.m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -88,4 +82,37 @@ const bool disposition::operator!=(const disposition& value) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
disposition* disposition::clone() const
|
||||||
|
{
|
||||||
|
return new disposition(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void disposition::copyFrom(const component& other)
|
||||||
|
{
|
||||||
|
const disposition& d = dynamic_cast <const disposition&>(other);
|
||||||
|
|
||||||
|
m_name = d.m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
disposition& disposition::operator=(const disposition& other)
|
||||||
|
{
|
||||||
|
copyFrom(other);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string& disposition::getName() const
|
||||||
|
{
|
||||||
|
return (m_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void disposition::setName(const string& name)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -40,20 +40,32 @@ public:
|
|||||||
disposition(const string& name);
|
disposition(const string& name);
|
||||||
disposition(const disposition& disp);
|
disposition(const disposition& disp);
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
const string& name() const { return (m_name); }
|
/** Return the disposition type.
|
||||||
string& name() { return (m_name); }
|
* See the constants in vmime::dispositionTypes.
|
||||||
|
*
|
||||||
|
* @return name of the encoding (eg. "inline")
|
||||||
|
*/
|
||||||
|
const string& getName() const;
|
||||||
|
|
||||||
|
/** Set the disposition type.
|
||||||
|
* See the constants in vmime::dispositionTypes.
|
||||||
|
*
|
||||||
|
* @param name name of the encoding
|
||||||
|
*/
|
||||||
|
void setName(const string& name);
|
||||||
|
|
||||||
|
disposition* clone() const;
|
||||||
|
void copyFrom(const component& other);
|
||||||
|
disposition& operator=(const disposition& other);
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
disposition& operator=(const disposition& source);
|
|
||||||
disposition& operator=(const string& name);
|
disposition& operator=(const string& name);
|
||||||
|
|
||||||
const bool operator==(const disposition& value) const;
|
const bool operator==(const disposition& value) const;
|
||||||
const bool operator!=(const disposition& value) const;
|
const bool operator!=(const disposition& value) const;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
string m_name;
|
string m_name;
|
||||||
|
|
||||||
|
@ -35,31 +35,31 @@ encoder::~encoder()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const propertySet& encoder::properties() const
|
const propertySet& encoder::getProperties() const
|
||||||
{
|
{
|
||||||
return (m_props);
|
return (m_props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
propertySet& encoder::properties()
|
propertySet& encoder::getProperties()
|
||||||
{
|
{
|
||||||
return (m_props);
|
return (m_props);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const propertySet& encoder::results() const
|
const propertySet& encoder::getResults() const
|
||||||
{
|
{
|
||||||
return (m_results);
|
return (m_results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
propertySet& encoder::results()
|
propertySet& encoder::getResults()
|
||||||
{
|
{
|
||||||
return (m_results);
|
return (m_results);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <string> encoder::availableProperties() const
|
const std::vector <string> encoder::getAvailableProperties() const
|
||||||
{
|
{
|
||||||
std::vector <string> list;
|
std::vector <string> list;
|
||||||
return (list);
|
return (list);
|
||||||
|
@ -57,30 +57,30 @@ public:
|
|||||||
*
|
*
|
||||||
* @return properties of the encoder
|
* @return properties of the encoder
|
||||||
*/
|
*/
|
||||||
const propertySet& properties() const;
|
const propertySet& getProperties() const;
|
||||||
|
|
||||||
/** Return the properties of the encoder.
|
/** Return the properties of the encoder.
|
||||||
*
|
*
|
||||||
* @return properties of the encoder
|
* @return properties of the encoder
|
||||||
*/
|
*/
|
||||||
propertySet& properties();
|
propertySet& getProperties();
|
||||||
|
|
||||||
/** Return a list of property names that can be set for
|
/** Return a list of property names that can be set for
|
||||||
* this encoder.
|
* this encoder.
|
||||||
*
|
*
|
||||||
* @return list of property names
|
* @return list of property names
|
||||||
*/
|
*/
|
||||||
virtual const std::vector <string> availableProperties() const;
|
virtual const std::vector <string> getAvailableProperties() const;
|
||||||
|
|
||||||
/** Return the results returned by this encoder.
|
/** Return the results returned by this encoder.
|
||||||
*
|
*
|
||||||
* @return results returned by the encoder
|
* @return results returned by the encoder
|
||||||
*/
|
*/
|
||||||
const propertySet& results() const;
|
const propertySet& getResults() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
propertySet& results();
|
propertySet& getResults();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -30,9 +30,9 @@ encoderB64::encoderB64()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <string> encoderB64::availableProperties() const
|
const std::vector <string> encoderB64::getAvailableProperties() const
|
||||||
{
|
{
|
||||||
std::vector <string> list(encoder::availableProperties());
|
std::vector <string> list(encoder::getAvailableProperties());
|
||||||
|
|
||||||
list.push_back("maxlinelength");
|
list.push_back("maxlinelength");
|
||||||
|
|
||||||
@ -70,7 +70,7 @@ const utility::stream::size_type encoderB64::encode(utility::inputStream& in, ut
|
|||||||
{
|
{
|
||||||
in.reset(); // may not work...
|
in.reset(); // may not work...
|
||||||
|
|
||||||
const int propMaxLineLength = properties().get <int>("maxlinelength", -1);
|
const int propMaxLineLength = getProperties().getProperty <int>("maxlinelength", -1);
|
||||||
|
|
||||||
const bool cutLines = (propMaxLineLength != -1);
|
const bool cutLines = (propMaxLineLength != -1);
|
||||||
const int maxLineLength = std::min(propMaxLineLength, 76);
|
const int maxLineLength = std::min(propMaxLineLength, 76);
|
||||||
|
@ -40,7 +40,7 @@ public:
|
|||||||
const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out);
|
const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out);
|
||||||
const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out);
|
const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out);
|
||||||
|
|
||||||
const std::vector <string> availableProperties() const;
|
const std::vector <string> getAvailableProperties() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -46,24 +46,58 @@ encoderFactory::encoderFactory()
|
|||||||
|
|
||||||
encoderFactory::~encoderFactory()
|
encoderFactory::~encoderFactory()
|
||||||
{
|
{
|
||||||
for (NameMap::iterator it = m_nameMap.begin() ; it != m_nameMap.end() ; ++it)
|
for (std::vector <registeredEncoder*>::const_iterator it = m_encoders.begin() ;
|
||||||
delete ((*it).second);
|
it != m_encoders.end() ; ++it)
|
||||||
|
{
|
||||||
|
delete (*it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
encoder* encoderFactory::create(const string& name)
|
encoder* encoderFactory::create(const string& name)
|
||||||
{
|
{
|
||||||
NameMap::const_iterator pos = m_nameMap.find(toLower(name));
|
return (getEncoderByName(name)->create());
|
||||||
|
}
|
||||||
|
|
||||||
if (pos != m_nameMap.end())
|
|
||||||
|
const encoderFactory::registeredEncoder* encoderFactory::getEncoderByName(const string& name) const
|
||||||
|
{
|
||||||
|
const string lcName(stringUtils::toLower(name));
|
||||||
|
|
||||||
|
for (std::vector <registeredEncoder*>::const_iterator it = m_encoders.begin() ;
|
||||||
|
it != m_encoders.end() ; ++it)
|
||||||
{
|
{
|
||||||
return ((*pos).second)->create();
|
if ((*it)->getName() == lcName)
|
||||||
|
return (*it);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
throw exceptions::no_encoder_available();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const int encoderFactory::getEncoderCount() const
|
||||||
|
{
|
||||||
|
return (m_encoders.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const encoderFactory::registeredEncoder* encoderFactory::getEncoderAt(const int pos) const
|
||||||
|
{
|
||||||
|
return (m_encoders[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector <const encoderFactory::registeredEncoder*> encoderFactory::getEncoderList() const
|
||||||
|
{
|
||||||
|
std::vector <const registeredEncoder*> res;
|
||||||
|
|
||||||
|
for (std::vector <registeredEncoder*>::const_iterator it = m_encoders.begin() ;
|
||||||
|
it != m_encoders.end() ; ++it)
|
||||||
{
|
{
|
||||||
throw exceptions::no_encoder_available();
|
res.push_back(*it);
|
||||||
return (NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "encoder.hpp"
|
#include "encoder.hpp"
|
||||||
#include "utility/singleton.hpp"
|
#include "utility/singleton.hpp"
|
||||||
|
#include "utility/stringUtils.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
@ -43,6 +44,7 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/** Information about a registered encoder. */
|
||||||
class registeredEncoder
|
class registeredEncoder
|
||||||
{
|
{
|
||||||
friend class encoderFactory;
|
friend class encoderFactory;
|
||||||
@ -53,9 +55,9 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual encoder* create() = 0;
|
virtual encoder* create() const = 0;
|
||||||
|
|
||||||
virtual const string& name() const = 0;
|
virtual const string& getName() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -71,12 +73,12 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
encoder* create()
|
encoder* create() const
|
||||||
{
|
{
|
||||||
return new E;
|
return new E;
|
||||||
}
|
}
|
||||||
|
|
||||||
const string& name() const
|
const string& getName() const
|
||||||
{
|
{
|
||||||
return (m_name);
|
return (m_name);
|
||||||
}
|
}
|
||||||
@ -87,93 +89,56 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
typedef std::map <string, registeredEncoder*> NameMap;
|
std::vector <registeredEncoder*> m_encoders;
|
||||||
NameMap m_nameMap;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
/** Register a new encoder by its encoding name.
|
||||||
|
*
|
||||||
|
* @param name encoding name
|
||||||
|
*/
|
||||||
template <class E>
|
template <class E>
|
||||||
void registerName(const string& name)
|
void registerName(const string& name)
|
||||||
{
|
{
|
||||||
const string _name = toLower(name);
|
m_encoders.push_back(new registeredEncoderImpl <E>(stringUtils::toLower(name)));
|
||||||
m_nameMap.insert(NameMap::value_type(_name,
|
|
||||||
new registeredEncoderImpl <E>(_name)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Create a new encoder instance from an encoding name.
|
||||||
|
*
|
||||||
|
* @param name encoding name (eg. "base64")
|
||||||
|
* @return a new encoder instance for the specified encoding
|
||||||
|
* @throw exceptions::no_encoder_available if no encoder is registered
|
||||||
|
* for this encoding
|
||||||
|
*/
|
||||||
encoder* create(const string& name);
|
encoder* create(const string& name);
|
||||||
|
|
||||||
const registeredEncoder& operator[](const string& name) const;
|
/** Return information about a registered encoder.
|
||||||
|
*
|
||||||
|
* @param name encoding name
|
||||||
|
* @return information about this encoder
|
||||||
|
* @throw exceptions::no_encoder_available if no encoder is registered
|
||||||
|
* for this encoding
|
||||||
|
*/
|
||||||
|
const registeredEncoder* getEncoderByName(const string& name) const;
|
||||||
|
|
||||||
|
/** Return the number of registered encoders.
|
||||||
|
*
|
||||||
|
* @return number of registered encoders
|
||||||
|
*/
|
||||||
|
const int getEncoderCount() const;
|
||||||
|
|
||||||
class iterator;
|
/** Return the registered encoder at the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position of the registered encoder to return
|
||||||
|
* @return registered encoder at the specified position
|
||||||
|
*/
|
||||||
|
const registeredEncoder* getEncoderAt(const int pos) const;
|
||||||
|
|
||||||
class const_iterator
|
/** Return a list of all registered encoders.
|
||||||
{
|
*
|
||||||
friend class encoderFactory;
|
* @return list of registered encoders
|
||||||
|
*/
|
||||||
public:
|
const std::vector <const registeredEncoder*> getEncoderList() const;
|
||||||
|
|
||||||
const_iterator() { }
|
|
||||||
const_iterator(const const_iterator& it) : m_it(it.m_it) { }
|
|
||||||
const_iterator(const iterator& it) : m_it(it.m_it) { }
|
|
||||||
|
|
||||||
const_iterator& operator=(const const_iterator& it) { m_it = it.m_it; return (*this); }
|
|
||||||
|
|
||||||
const registeredEncoder& operator*() const { return (*(*m_it).second); }
|
|
||||||
const registeredEncoder* operator->() const { return ((*m_it).second); }
|
|
||||||
|
|
||||||
const_iterator& operator++() { ++m_it; return (*this); }
|
|
||||||
const_iterator operator++(int) { return (m_it++); }
|
|
||||||
|
|
||||||
const_iterator& operator--() { --m_it; return (*this); }
|
|
||||||
const_iterator operator--(int) { return (m_it--); }
|
|
||||||
|
|
||||||
const bool operator==(const const_iterator& it) const { return (m_it == it.m_it); }
|
|
||||||
const bool operator!=(const const_iterator& it) const { return (m_it != it.m_it); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
const_iterator(const NameMap::const_iterator it) : m_it(it) { }
|
|
||||||
|
|
||||||
NameMap::const_iterator m_it;
|
|
||||||
};
|
|
||||||
|
|
||||||
class iterator
|
|
||||||
{
|
|
||||||
friend class encoderFactory;
|
|
||||||
friend class encoderFactory::const_iterator;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
iterator() { }
|
|
||||||
iterator(const iterator& it) : m_it(it.m_it) { }
|
|
||||||
|
|
||||||
iterator& operator=(const iterator& it) { m_it = it.m_it; return (*this); }
|
|
||||||
|
|
||||||
registeredEncoder& operator*() const { return (*(*m_it).second); }
|
|
||||||
registeredEncoder* operator->() const { return ((*m_it).second); }
|
|
||||||
|
|
||||||
iterator& operator++() { ++m_it; return (*this); }
|
|
||||||
iterator operator++(int) { return (m_it++); }
|
|
||||||
|
|
||||||
iterator& operator--() { --m_it; return (*this); }
|
|
||||||
iterator operator--(int) { return (m_it--); }
|
|
||||||
|
|
||||||
const bool operator==(const iterator& it) const { return (m_it == it.m_it); }
|
|
||||||
const bool operator!=(const iterator& it) const { return (m_it != it.m_it); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
iterator(const NameMap::iterator it) : m_it(it) { }
|
|
||||||
|
|
||||||
NameMap::iterator m_it;
|
|
||||||
};
|
|
||||||
|
|
||||||
iterator begin() { return iterator(m_nameMap.begin()); }
|
|
||||||
iterator end() { return iterator(m_nameMap.end()); }
|
|
||||||
|
|
||||||
const_iterator begin() const { return const_iterator(m_nameMap.begin()); }
|
|
||||||
const_iterator end() const { return const_iterator(m_nameMap.end()); }
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,9 +30,9 @@ encoderQP::encoderQP()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <string> encoderQP::availableProperties() const
|
const std::vector <string> encoderQP::getAvailableProperties() const
|
||||||
{
|
{
|
||||||
std::vector <string> list(encoder::availableProperties());
|
std::vector <string> list(encoder::getAvailableProperties());
|
||||||
|
|
||||||
list.push_back("maxlinelength");
|
list.push_back("maxlinelength");
|
||||||
|
|
||||||
@ -84,10 +84,10 @@ const utility::stream::size_type encoderQP::encode(utility::inputStream& in, uti
|
|||||||
in.reset(); // may not work...
|
in.reset(); // may not work...
|
||||||
|
|
||||||
const string::size_type propMaxLineLength =
|
const string::size_type propMaxLineLength =
|
||||||
properties().get <string::size_type>("maxlinelength", (string::size_type) -1);
|
getProperties().getProperty <string::size_type>("maxlinelength", (string::size_type) -1);
|
||||||
|
|
||||||
const bool rfc2047 = properties().get <bool>("rfc2047", false);
|
const bool rfc2047 = getProperties().getProperty <bool>("rfc2047", false);
|
||||||
const bool text = properties().get <bool>("text", false); // binary mode by default
|
const bool text = getProperties().getProperty <bool>("text", false); // binary mode by default
|
||||||
|
|
||||||
const bool cutLines = (propMaxLineLength != (string::size_type) -1);
|
const bool cutLines = (propMaxLineLength != (string::size_type) -1);
|
||||||
const string::size_type maxLineLength = std::min(propMaxLineLength, (string::size_type) 74);
|
const string::size_type maxLineLength = std::min(propMaxLineLength, (string::size_type) 74);
|
||||||
@ -279,7 +279,7 @@ const utility::stream::size_type encoderQP::decode(utility::inputStream& in, uti
|
|||||||
in.reset(); // may not work...
|
in.reset(); // may not work...
|
||||||
|
|
||||||
// Process the data
|
// Process the data
|
||||||
const bool rfc2047 = properties().get <bool>("rfc2047", false);
|
const bool rfc2047 = getProperties().getProperty <bool>("rfc2047", false);
|
||||||
|
|
||||||
char buffer[16384];
|
char buffer[16384];
|
||||||
int bufferLength = 0;
|
int bufferLength = 0;
|
||||||
|
@ -40,7 +40,7 @@ public:
|
|||||||
const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out);
|
const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out);
|
||||||
const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out);
|
const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out);
|
||||||
|
|
||||||
const std::vector <string> availableProperties() const;
|
const std::vector <string> getAvailableProperties() const;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -27,15 +27,15 @@ namespace vmime
|
|||||||
|
|
||||||
encoderUUE::encoderUUE()
|
encoderUUE::encoderUUE()
|
||||||
{
|
{
|
||||||
properties()["mode"] = 644;
|
getProperties()["mode"] = 644;
|
||||||
properties()["filename"] = "no_name";
|
getProperties()["filename"] = "no_name";
|
||||||
properties()["maxlinelength"] = 46;
|
getProperties()["maxlinelength"] = 46;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const std::vector <string> encoderUUE::availableProperties() const
|
const std::vector <string> encoderUUE::getAvailableProperties() const
|
||||||
{
|
{
|
||||||
std::vector <string> list(encoder::availableProperties());
|
std::vector <string> list(encoder::getAvailableProperties());
|
||||||
|
|
||||||
list.push_back("maxlinelength");
|
list.push_back("maxlinelength");
|
||||||
|
|
||||||
@ -63,11 +63,11 @@ const utility::stream::size_type encoderUUE::encode(utility::inputStream& in, ut
|
|||||||
{
|
{
|
||||||
in.reset(); // may not work...
|
in.reset(); // may not work...
|
||||||
|
|
||||||
const string propFilename = properties().get <string>("filename", "");
|
const string propFilename = getProperties().getProperty <string>("filename", "");
|
||||||
const string propMode = properties().get <string>("mode", "644");
|
const string propMode = getProperties().getProperty <string>("mode", "644");
|
||||||
|
|
||||||
const string::size_type maxLineLength =
|
const string::size_type maxLineLength =
|
||||||
std::min(properties().get <string::size_type>("maxlinelength", 46),
|
std::min(getProperties().getProperty <string::size_type>("maxlinelength", 46),
|
||||||
static_cast <string::size_type>(46));
|
static_cast <string::size_type>(46));
|
||||||
|
|
||||||
utility::stream::size_type total = 0;
|
utility::stream::size_type total = 0;
|
||||||
@ -206,7 +206,7 @@ const utility::stream::size_type encoderUUE::decode(utility::inputStream& in, ut
|
|||||||
|
|
||||||
while (*p && !isspace(*p)) ++p;
|
while (*p && !isspace(*p)) ++p;
|
||||||
|
|
||||||
results()["mode"] = string(modeStart, p);
|
getResults()["mode"] = string(modeStart, p);
|
||||||
|
|
||||||
while (*p && isspace(*p)) ++p;
|
while (*p && isspace(*p)) ++p;
|
||||||
|
|
||||||
@ -214,13 +214,13 @@ const utility::stream::size_type encoderUUE::decode(utility::inputStream& in, ut
|
|||||||
|
|
||||||
while (*p && !(*p == '\r' || *p == '\n')) ++p;
|
while (*p && !(*p == '\r' || *p == '\n')) ++p;
|
||||||
|
|
||||||
results()["filename"] = string(filenameStart, p);
|
getResults()["filename"] = string(filenameStart, p);
|
||||||
}
|
}
|
||||||
// No filename or mode specified
|
// No filename or mode specified
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
results()["filename"] = "untitled";
|
getResults()["filename"] = "untitled";
|
||||||
results()["mode"] = 644;
|
getResults()["mode"] = 644;
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
@ -40,7 +40,7 @@ public:
|
|||||||
const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out);
|
const utility::stream::size_type encode(utility::inputStream& in, utility::outputStream& out);
|
||||||
const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out);
|
const utility::stream::size_type decode(utility::inputStream& in, utility::outputStream& out);
|
||||||
|
|
||||||
const std::vector <string> availableProperties() const;
|
const std::vector <string> getAvailableProperties() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ encoding::encoding()
|
|||||||
|
|
||||||
|
|
||||||
encoding::encoding(const string& name)
|
encoding::encoding(const string& name)
|
||||||
: m_name(toLower(name))
|
: m_name(stringUtils::toLower(name))
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +49,7 @@ encoding::encoding(const encoding& enc)
|
|||||||
void encoding::parse(const string& buffer, const string::size_type position,
|
void encoding::parse(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
m_name = toLower(string(buffer.begin() + position, buffer.begin() + end));
|
m_name = stringUtils::toLower(string(buffer.begin() + position, buffer.begin() + end));
|
||||||
|
|
||||||
if (newPosition)
|
if (newPosition)
|
||||||
*newPosition = end;
|
*newPosition = end;
|
||||||
@ -72,23 +72,23 @@ encoder* encoding::getEncoder() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
encoding& encoding::operator=(const encoding& source)
|
encoding& encoding::operator=(const encoding& other)
|
||||||
{
|
{
|
||||||
m_name = source.m_name;
|
copyFrom(other);
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
encoding& encoding::operator=(const string& name)
|
encoding& encoding::operator=(const string& name)
|
||||||
{
|
{
|
||||||
m_name = toLower(name);
|
m_name = stringUtils::toLower(name);
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const bool encoding::operator==(const encoding& value) const
|
const bool encoding::operator==(const encoding& value) const
|
||||||
{
|
{
|
||||||
return (toLower(m_name) == value.m_name);
|
return (stringUtils::toLower(m_name) == value.m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -154,8 +154,35 @@ const encoding encoding::decide
|
|||||||
|
|
||||||
const encoding encoding::decide(const contentHandler& /* data */)
|
const encoding encoding::decide(const contentHandler& /* data */)
|
||||||
{
|
{
|
||||||
|
// TODO: a better solution to do that?
|
||||||
return (encoding(encodingTypes::BASE64));
|
return (encoding(encodingTypes::BASE64));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
encoding* encoding::clone() const
|
||||||
|
{
|
||||||
|
return new encoding(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void encoding::copyFrom(const component& other)
|
||||||
|
{
|
||||||
|
const encoding& e = dynamic_cast <const encoding&>(other);
|
||||||
|
|
||||||
|
m_name = e.m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string& encoding::getName() const
|
||||||
|
{
|
||||||
|
return (m_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void encoding::setName(const string& name)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -46,27 +46,56 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
const string& name() const { return (m_name); }
|
/** Return the name of the encoding.
|
||||||
string& name() { return (m_name); }
|
* See the constants in vmime::encodingTypes.
|
||||||
|
*
|
||||||
|
* @return name of the encoding (eg. "quoted-printable")
|
||||||
|
*/
|
||||||
|
const string& getName() const;
|
||||||
|
|
||||||
public:
|
/** Set the name of the encoding.
|
||||||
|
* See the constants in vmime::encodingTypes.
|
||||||
|
*
|
||||||
|
* @param name name of the encoding
|
||||||
|
*/
|
||||||
|
void setName(const string& name);
|
||||||
|
|
||||||
encoding& operator=(const encoding& source);
|
encoding& operator=(const encoding& other);
|
||||||
encoding& operator=(const string& name);
|
encoding& operator=(const string& name);
|
||||||
|
|
||||||
const bool operator==(const encoding& value) const;
|
const bool operator==(const encoding& value) const;
|
||||||
const bool operator!=(const encoding& value) const;
|
const bool operator!=(const encoding& value) const;
|
||||||
|
|
||||||
// Decide which encoding to use based on the data
|
/** Decide which encoding to use based on the specified data.
|
||||||
|
*
|
||||||
|
* \deprecated Use the new decide() method which takes a contentHandler parameter.
|
||||||
|
*
|
||||||
|
* @param begin start iterator in buffer
|
||||||
|
* @param end end iterator in buffer
|
||||||
|
* @return suitable encoding for specified data
|
||||||
|
*/
|
||||||
static const encoding decide(const string::const_iterator begin, const string::const_iterator end);
|
static const encoding decide(const string::const_iterator begin, const string::const_iterator end);
|
||||||
|
|
||||||
|
/** Decide which encoding to use based on the specified data.
|
||||||
|
*
|
||||||
|
* @param data data used to determine encoding
|
||||||
|
* @return suitable encoding for specified data
|
||||||
|
*/
|
||||||
static const encoding decide(const contentHandler& data);
|
static const encoding decide(const contentHandler& data);
|
||||||
|
|
||||||
public:
|
encoding* clone() const;
|
||||||
|
void copyFrom(const component& other);
|
||||||
|
|
||||||
// Obtain an encoder/decoder for the current encoding type
|
/** Use encoderFactory to obtain an encoder/decoder object
|
||||||
|
* for the current encoding type.
|
||||||
|
*
|
||||||
|
* @throw exceptions::no_encoder_available if no encoder
|
||||||
|
* is registered for the encoding
|
||||||
|
* @return a new encoder object for the encoding type
|
||||||
|
*/
|
||||||
encoder* getEncoder() const;
|
encoder* getEncoder() const;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
string m_name;
|
string m_name;
|
||||||
|
|
||||||
|
@ -45,6 +45,8 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/** List of all VMime exceptions. */
|
||||||
|
|
||||||
namespace exceptions
|
namespace exceptions
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -95,6 +97,33 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class no_such_part : public vmime::exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
no_such_part() : exception("Part not found.") {}
|
||||||
|
~no_such_part() throw() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class no_such_mailbox : public vmime::exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
no_such_mailbox() : exception("Mailbox not found.") {}
|
||||||
|
~no_such_mailbox() throw() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class no_such_address : public vmime::exception
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
no_such_address() : exception("Address not found.") {}
|
||||||
|
~no_such_address() throw() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
class open_file_error : public vmime::exception
|
class open_file_error : public vmime::exception
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -40,7 +40,7 @@ fileAttachment::fileAttachment(const string& filename, const mediaType& type, co
|
|||||||
|
|
||||||
|
|
||||||
fileAttachment::fileAttachment(const string& filename, const mediaType& type,
|
fileAttachment::fileAttachment(const string& filename, const mediaType& type,
|
||||||
const class encoding& enc, const text& desc)
|
const encoding& enc, const text& desc)
|
||||||
{
|
{
|
||||||
m_type = type;
|
m_type = type;
|
||||||
m_desc = desc;
|
m_desc = desc;
|
||||||
@ -62,7 +62,7 @@ void fileAttachment::setData(const string& filename)
|
|||||||
throw exceptions::open_file_error();
|
throw exceptions::open_file_error();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_data.set(new utility::inputStreamPointerAdapter(file, true), 0, true);
|
m_data.setData(new utility::inputStreamPointerAdapter(file, true), 0, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -70,16 +70,29 @@ void fileAttachment::generatePart(bodyPart& part) const
|
|||||||
{
|
{
|
||||||
defaultAttachment::generatePart(part);
|
defaultAttachment::generatePart(part);
|
||||||
|
|
||||||
contentDispositionField& cdf = part.header().fields.ContentDisposition();
|
contentDispositionField& cdf = part.getHeader()->ContentDisposition();
|
||||||
|
|
||||||
if (m_fileInfo.hasSize()) cdf.size() = toString(m_fileInfo.getSize());
|
if (m_fileInfo.hasSize()) cdf.setSize(stringUtils::toString(m_fileInfo.getSize()));
|
||||||
if (m_fileInfo.hasFilename()) cdf.filename() = m_fileInfo.getFilename();
|
if (m_fileInfo.hasFilename()) cdf.setFilename(m_fileInfo.getFilename());
|
||||||
if (m_fileInfo.hasCreationDate()) cdf.creationDate() = m_fileInfo.getCreationDate();
|
if (m_fileInfo.hasCreationDate()) cdf.setCreationDate(m_fileInfo.getCreationDate());
|
||||||
if (m_fileInfo.hasModificationDate()) cdf.modificationDate() = m_fileInfo.getModificationDate();
|
if (m_fileInfo.hasModificationDate()) cdf.setModificationDate(m_fileInfo.getModificationDate());
|
||||||
if (m_fileInfo.hasReadDate()) cdf.readDate() = m_fileInfo.getReadDate();
|
if (m_fileInfo.hasReadDate()) cdf.setReadDate(m_fileInfo.getReadDate());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const fileAttachment::fileInfo& fileAttachment::getFileInfo() const
|
||||||
|
{
|
||||||
|
return (m_fileInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
fileAttachment::fileInfo& fileAttachment::getFileInfo()
|
||||||
|
{
|
||||||
|
return (m_fileInfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// fileAttachment::fileInfo
|
// fileAttachment::fileInfo
|
||||||
//
|
//
|
||||||
|
@ -33,7 +33,7 @@ class fileAttachment : public defaultAttachment
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
fileAttachment(const string& filename, const mediaType& type, const text& desc = NULL_TEXT);
|
fileAttachment(const string& filename, const mediaType& type, const text& desc = NULL_TEXT);
|
||||||
fileAttachment(const string& filename, const mediaType& type, const class encoding& enc, const text& desc = NULL_TEXT);
|
fileAttachment(const string& filename, const mediaType& type, const encoding& enc, const text& desc = NULL_TEXT);
|
||||||
|
|
||||||
class fileInfo
|
class fileInfo
|
||||||
{
|
{
|
||||||
@ -71,14 +71,14 @@ public:
|
|||||||
datetime* m_readDate;
|
datetime* m_readDate;
|
||||||
};
|
};
|
||||||
|
|
||||||
const class fileInfo& fileInfo() const { return (m_fileInfo); }
|
const fileInfo& getFileInfo() const;
|
||||||
class fileInfo& fileInfo() { return (m_fileInfo); }
|
fileInfo& getFileInfo();
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
void setData(const string& filename);
|
void setData(const string& filename);
|
||||||
|
|
||||||
class fileInfo m_fileInfo;
|
fileInfo m_fileInfo;
|
||||||
|
|
||||||
void generatePart(bodyPart& part) const;
|
void generatePart(bodyPart& part) const;
|
||||||
};
|
};
|
||||||
|
91
src/genericField.hpp
Normal file
91
src/genericField.hpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
//
|
||||||
|
// VMime library (http://vmime.sourceforge.net)
|
||||||
|
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef VMIME_GENERICFIELD_HPP_INCLUDED
|
||||||
|
#define VMIME_GENERICFIELD_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "headerField.hpp"
|
||||||
|
#include "headerFieldFactory.hpp"
|
||||||
|
|
||||||
|
#include "typeAdapter.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace vmime
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/** Generic implementation for headerField.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <class VALUE_TYPE>
|
||||||
|
class genericField : virtual public headerField
|
||||||
|
{
|
||||||
|
friend class headerFieldFactory::registerer <genericField <VALUE_TYPE> >;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
genericField() { }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
genericField <VALUE_TYPE>& operator=(const genericField <VALUE_TYPE>& other)
|
||||||
|
{
|
||||||
|
copyFrom(other);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const VALUE_TYPE& getValue() const
|
||||||
|
{
|
||||||
|
return (m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE_TYPE& getValue()
|
||||||
|
{
|
||||||
|
return (m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class TYPE>
|
||||||
|
void setValue(const TYPE& value)
|
||||||
|
{
|
||||||
|
m_value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValue(const component& value)
|
||||||
|
{
|
||||||
|
const VALUE_TYPE& v = dynamic_cast <const VALUE_TYPE&>(value);
|
||||||
|
m_value = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
VALUE_TYPE m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class genericField <string> : public genericField <typeAdapter <string> >
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // vmime
|
||||||
|
|
||||||
|
|
||||||
|
#endif // VMIME_GENERICFIELD_HPP_INCLUDED
|
91
src/genericParameter.hpp
Normal file
91
src/genericParameter.hpp
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
//
|
||||||
|
// VMime library (http://vmime.sourceforge.net)
|
||||||
|
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of
|
||||||
|
// the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef VMIME_GENERICPARAMETER_HPP_INCLUDED
|
||||||
|
#define VMIME_GENERICPARAMETER_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "parameter.hpp"
|
||||||
|
#include "parameterFactory.hpp"
|
||||||
|
|
||||||
|
#include "typeAdapter.hpp"
|
||||||
|
|
||||||
|
|
||||||
|
namespace vmime
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/** Generic implementation for parameter.
|
||||||
|
*/
|
||||||
|
|
||||||
|
template <class VALUE_TYPE>
|
||||||
|
class genericParameter : public parameter
|
||||||
|
{
|
||||||
|
friend class parameterFactory::registerer <genericParameter <VALUE_TYPE> >;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
genericParameter() { }
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
genericParameter <VALUE_TYPE>& operator=(const genericParameter <VALUE_TYPE>& other)
|
||||||
|
{
|
||||||
|
copyFrom(other);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
const VALUE_TYPE& getValue() const
|
||||||
|
{
|
||||||
|
return (m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
VALUE_TYPE& getValue()
|
||||||
|
{
|
||||||
|
return (m_value);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class TYPE>
|
||||||
|
void setValue(const TYPE& value)
|
||||||
|
{
|
||||||
|
m_value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setValue(const component& value)
|
||||||
|
{
|
||||||
|
const VALUE_TYPE& v = dynamic_cast <const VALUE_TYPE&>(value);
|
||||||
|
m_value = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
VALUE_TYPE m_value;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template <>
|
||||||
|
class genericParameter <string> : public genericParameter <typeAdapter <string> >
|
||||||
|
{
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // vmime
|
||||||
|
|
||||||
|
|
||||||
|
#endif // VMIME_GENERICPARAMETER_HPP_INCLUDED
|
336
src/header.cpp
336
src/header.cpp
@ -32,6 +32,7 @@ header::header()
|
|||||||
|
|
||||||
header::~header()
|
header::~header()
|
||||||
{
|
{
|
||||||
|
removeAllFields();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -59,7 +60,7 @@ void header::parse(const string& buffer, const string::size_type position,
|
|||||||
{
|
{
|
||||||
string::size_type pos = position;
|
string::size_type pos = position;
|
||||||
|
|
||||||
fields.clear();
|
removeAllFields();
|
||||||
|
|
||||||
while (pos < end)
|
while (pos < end)
|
||||||
{
|
{
|
||||||
@ -181,8 +182,8 @@ void header::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Add a new field to list
|
// Add a new field to list
|
||||||
fields.m_fields.push_back(headerFieldFactory::getInstance()->
|
m_fields.push_back(headerFieldFactory::getInstance()->
|
||||||
create(headerField::nameToType(name), name, contents));
|
create(name, contents));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -220,8 +221,8 @@ void header::generate(utility::outputStream& os, const string::size_type maxLine
|
|||||||
const string::size_type /* curLinePos */, string::size_type* newLinePos) const
|
const string::size_type /* curLinePos */, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
// Generate the fields
|
// Generate the fields
|
||||||
for (std::vector <headerField*>::const_iterator
|
for (std::vector <headerField*>::const_iterator it = m_fields.begin() ;
|
||||||
it = fields.m_fields.begin() ; it != fields.m_fields.end() ; ++it)
|
it != m_fields.end() ; ++it)
|
||||||
{
|
{
|
||||||
(*it)->generate(os, maxLineLength);
|
(*it)->generate(os, maxLineLength);
|
||||||
os << CRLF;
|
os << CRLF;
|
||||||
@ -232,93 +233,91 @@ void header::generate(utility::outputStream& os, const string::size_type maxLine
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
header& header::operator=(const header& h)
|
header* header::clone() const
|
||||||
{
|
{
|
||||||
fields = h.fields;
|
header* hdr = new header();
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
hdr->m_fields.reserve(m_fields.size());
|
||||||
|
|
||||||
|
for (std::vector <headerField*>::const_iterator it = m_fields.begin() ;
|
||||||
|
it != m_fields.end() ; ++it)
|
||||||
|
{
|
||||||
|
hdr->m_fields.push_back((*it)->clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (std::exception&)
|
||||||
|
{
|
||||||
|
free_container(hdr->m_fields);
|
||||||
|
|
||||||
|
delete (hdr);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (hdr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void header::copyFrom(const component& other)
|
||||||
|
{
|
||||||
|
const header& h = dynamic_cast <const header&>(other);
|
||||||
|
|
||||||
|
std::vector <headerField*> fields;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
fields.reserve(h.m_fields.size());
|
||||||
|
|
||||||
|
for (std::vector <headerField*>::const_iterator it = h.m_fields.begin() ;
|
||||||
|
it != h.m_fields.end() ; ++it)
|
||||||
|
{
|
||||||
|
fields.push_back((*it)->clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
free_container(m_fields);
|
||||||
|
|
||||||
|
m_fields.resize(fields.size());
|
||||||
|
|
||||||
|
std::copy(fields.begin(), fields.end(), m_fields.begin());
|
||||||
|
}
|
||||||
|
catch (std::exception&)
|
||||||
|
{
|
||||||
|
free_container(fields);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
header& header::operator=(const header& other)
|
||||||
|
{
|
||||||
|
copyFrom(other);
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const bool header::hasField(const string& fieldName) const
|
||||||
//////////////////////
|
|
||||||
// Fields container //
|
|
||||||
//////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
header::fieldsContainer::fieldsContainer()
|
|
||||||
{
|
{
|
||||||
}
|
const string name = stringUtils::toLower(fieldName);
|
||||||
|
|
||||||
|
|
||||||
header::fieldsContainer::~fieldsContainer()
|
|
||||||
{
|
|
||||||
for (std::vector <headerField*>::iterator i = m_fields.begin() ; i != m_fields.end() ; ++i)
|
|
||||||
delete (*i);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Checks whether (at least) one field with this type/name exists
|
|
||||||
const bool header::fieldsContainer::has(const headerField::Types fieldType) const
|
|
||||||
{
|
|
||||||
std::vector <headerField*>::const_iterator pos = m_fields.begin();
|
std::vector <headerField*>::const_iterator pos = m_fields.begin();
|
||||||
const std::vector <headerField*>::const_iterator end = m_fields.end();
|
const std::vector <headerField*>::const_iterator end = m_fields.end();
|
||||||
|
|
||||||
for ( ; pos != end && (*pos)->type() != fieldType ; ++pos);
|
for ( ; pos != end && stringUtils::toLower((*pos)->getName()) != name ; ++pos);
|
||||||
|
|
||||||
return (pos != end);
|
return (pos != end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const bool header::fieldsContainer::has(const string& fieldName) const
|
headerField* header::findField(const string& fieldName) const
|
||||||
{
|
{
|
||||||
headerField::Types type = headerField::nameToType(fieldName);
|
const string name = stringUtils::toLower(fieldName);
|
||||||
if (type != headerField::Custom) return (has(type));
|
|
||||||
|
|
||||||
const string name = toLower(fieldName);
|
|
||||||
|
|
||||||
std::vector <headerField*>::const_iterator pos = m_fields.begin();
|
|
||||||
const std::vector <headerField*>::const_iterator end = m_fields.end();
|
|
||||||
|
|
||||||
for ( ; pos != end && toLower((*pos)->name()) != name ; ++pos);
|
|
||||||
|
|
||||||
return (pos != end);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
headerField& header::fieldsContainer::find(const headerField::Types fieldType) const
|
|
||||||
{
|
|
||||||
// Find the first field that matches the specified type
|
|
||||||
std::vector <headerField*>::const_iterator pos = m_fields.begin();
|
|
||||||
const std::vector <headerField*>::const_iterator end = m_fields.end();
|
|
||||||
|
|
||||||
for ( ; pos != end && (*pos)->type() != fieldType ; ++pos);
|
|
||||||
|
|
||||||
// No field with this type can be found
|
|
||||||
if (pos == end)
|
|
||||||
{
|
|
||||||
throw exceptions::no_such_field();
|
|
||||||
}
|
|
||||||
// Else, return a reference to the existing field
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (**pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
headerField& header::fieldsContainer::find(const string& fieldName) const
|
|
||||||
{
|
|
||||||
headerField::Types type = headerField::nameToType(fieldName);
|
|
||||||
if (type != headerField::Custom) return (find(type));
|
|
||||||
|
|
||||||
const string name = toLower(fieldName);
|
|
||||||
|
|
||||||
// Find the first field that matches the specified name
|
// Find the first field that matches the specified name
|
||||||
std::vector <headerField*>::const_iterator pos = m_fields.begin();
|
std::vector <headerField*>::const_iterator pos = m_fields.begin();
|
||||||
const std::vector <headerField*>::const_iterator end = m_fields.end();
|
const std::vector <headerField*>::const_iterator end = m_fields.end();
|
||||||
|
|
||||||
for ( ; pos != end && toLower((*pos)->name()) != name ; ++pos);
|
for ( ; pos != end && stringUtils::toLower((*pos)->getName()) != name ; ++pos);
|
||||||
|
|
||||||
// No field with this name can be found
|
// No field with this name can be found
|
||||||
if (pos == end)
|
if (pos == end)
|
||||||
@ -328,34 +327,14 @@ headerField& header::fieldsContainer::find(const string& fieldName) const
|
|||||||
// Else, return a reference to the existing field
|
// Else, return a reference to the existing field
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return (**pos);
|
return (*pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector <headerField*> header::fieldsContainer::findAllByType(const headerField::Types fieldType)
|
std::vector <headerField*> header::findAllFields(const string& fieldName)
|
||||||
{
|
{
|
||||||
std::vector <headerField*> result;
|
const string name = stringUtils::toLower(fieldName);
|
||||||
|
|
||||||
std::vector <headerField*>::const_iterator pos = m_fields.begin();
|
|
||||||
const std::vector <headerField*>::const_iterator end = m_fields.end();
|
|
||||||
|
|
||||||
for ( ; pos != end ; ++pos)
|
|
||||||
{
|
|
||||||
// Add the header if it matches the specified type
|
|
||||||
if ((*pos)->type() == fieldType)
|
|
||||||
{
|
|
||||||
result.push_back(*pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::vector <headerField*> header::fieldsContainer::findAllByName(const string& fieldName)
|
|
||||||
{
|
|
||||||
const string name = toLower(fieldName);
|
|
||||||
|
|
||||||
std::vector <headerField*> result;
|
std::vector <headerField*> result;
|
||||||
|
|
||||||
@ -365,7 +344,7 @@ std::vector <headerField*> header::fieldsContainer::findAllByName(const string&
|
|||||||
for ( ; pos != end ; ++pos)
|
for ( ; pos != end ; ++pos)
|
||||||
{
|
{
|
||||||
// Add the header if it matches the specified type
|
// Add the header if it matches the specified type
|
||||||
if (toLower((*pos)->name()) == name)
|
if (stringUtils::toLower((*pos)->getName()) == name)
|
||||||
{
|
{
|
||||||
result.push_back(*pos);
|
result.push_back(*pos);
|
||||||
}
|
}
|
||||||
@ -375,116 +354,157 @@ std::vector <headerField*> header::fieldsContainer::findAllByName(const string&
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
headerField& header::fieldsContainer::get(const headerField::Types fieldType)
|
headerField* header::getField(const string& fieldName)
|
||||||
{
|
{
|
||||||
// Find the first field that matches the specified type
|
const string name = stringUtils::toLower(fieldName);
|
||||||
std::vector <headerField*>::const_iterator pos = m_fields.begin();
|
|
||||||
const std::vector <headerField*>::const_iterator end = m_fields.end();
|
|
||||||
|
|
||||||
for ( ; pos != end && (*pos)->type() != fieldType ; ++pos);
|
|
||||||
|
|
||||||
// If no field with this type can be found, create a new one
|
|
||||||
if (pos == end)
|
|
||||||
{
|
|
||||||
headerField* field = headerFieldFactory::getInstance()->create(fieldType);
|
|
||||||
insertSorted(field);
|
|
||||||
|
|
||||||
// Return a reference to the new field
|
|
||||||
return (*field);
|
|
||||||
}
|
|
||||||
// Else, return a reference to the existing field
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return (**pos);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
headerField& header::fieldsContainer::get(const string& fieldName)
|
|
||||||
{
|
|
||||||
headerField::Types type = headerField::nameToType(fieldName);
|
|
||||||
if (type != headerField::Custom) return (get(type));
|
|
||||||
|
|
||||||
const string name = toLower(fieldName);
|
|
||||||
|
|
||||||
// Find the first field that matches the specified name
|
// Find the first field that matches the specified name
|
||||||
std::vector <headerField*>::const_iterator pos = m_fields.begin();
|
std::vector <headerField*>::const_iterator pos = m_fields.begin();
|
||||||
const std::vector <headerField*>::const_iterator end = m_fields.end();
|
const std::vector <headerField*>::const_iterator end = m_fields.end();
|
||||||
|
|
||||||
for ( ; pos != end && toLower((*pos)->name()) != name ; ++pos);
|
for ( ; pos != end && stringUtils::toLower((*pos)->getName()) != name ; ++pos);
|
||||||
|
|
||||||
// If no field with this name can be found, create a new one
|
// If no field with this name can be found, create a new one
|
||||||
if (pos == end)
|
if (pos == end)
|
||||||
{
|
{
|
||||||
headerField* field = headerFieldFactory::getInstance()->create(fieldName);
|
headerField* field = headerFieldFactory::getInstance()->create(fieldName);
|
||||||
insertSorted(field);
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
appendField(field);
|
||||||
|
}
|
||||||
|
catch (std::exception&)
|
||||||
|
{
|
||||||
|
delete (field);
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
// Return a reference to the new field
|
// Return a reference to the new field
|
||||||
return (*field);
|
return (field);
|
||||||
}
|
}
|
||||||
// Else, return a reference to the existing field
|
// Else, return a reference to the existing field
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return (**pos);
|
return (*pos);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void header::fieldsContainer::insertSorted(headerField* field)
|
void header::appendField(headerField* field)
|
||||||
{
|
{
|
||||||
const headerField::Types type = field->type();
|
m_fields.push_back(field);
|
||||||
std::vector <headerField*>::iterator i;
|
|
||||||
|
|
||||||
for (i = m_fields.begin() ; (i != m_fields.end()) && ((*i)->type() < type) ; ++i);
|
|
||||||
|
|
||||||
m_fields.insert(i, field);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Field insertion
|
void header::insertFieldBefore(headerField* beforeField, headerField* field)
|
||||||
void header::fieldsContainer::append(const headerField& field)
|
|
||||||
{
|
{
|
||||||
m_fields.push_back(field.clone());
|
const std::vector <headerField*>::iterator it = std::find
|
||||||
|
(m_fields.begin(), m_fields.end(), beforeField);
|
||||||
|
|
||||||
|
if (it == m_fields.end())
|
||||||
|
throw exceptions::no_such_field();
|
||||||
|
|
||||||
|
m_fields.insert(it, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void header::fieldsContainer::insert(const iterator it, const headerField& field)
|
void header::insertFieldBefore(const int pos, headerField* field)
|
||||||
{
|
{
|
||||||
m_fields.insert(it.m_iterator, field.clone());
|
m_fields.insert(m_fields.begin() + pos, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Field removing
|
void header::insertFieldAfter(headerField* afterField, headerField* field)
|
||||||
void header::fieldsContainer::remove(const iterator it)
|
|
||||||
{
|
{
|
||||||
delete (*it.m_iterator);
|
const std::vector <headerField*>::iterator it = std::find
|
||||||
m_fields.erase(it.m_iterator);
|
(m_fields.begin(), m_fields.end(), afterField);
|
||||||
|
|
||||||
|
if (it == m_fields.end())
|
||||||
|
throw exceptions::no_such_field();
|
||||||
|
|
||||||
|
m_fields.insert(it + 1, field);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void header::fieldsContainer::clear()
|
void header::insertFieldAfter(const int pos, headerField* field)
|
||||||
{
|
{
|
||||||
for (std::vector <headerField*>::iterator it = m_fields.begin() ; it != m_fields.end() ; ++it)
|
m_fields.insert(m_fields.begin() + pos + 1, field);
|
||||||
delete (*it);
|
|
||||||
|
|
||||||
m_fields.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
header::fieldsContainer& header::fieldsContainer::operator=(const fieldsContainer& c)
|
void header::removeField(headerField* field)
|
||||||
{
|
{
|
||||||
std::vector <headerField*> fields;
|
const std::vector <headerField*>::iterator it = std::find
|
||||||
|
(m_fields.begin(), m_fields.end(), field);
|
||||||
|
|
||||||
for (std::vector <headerField*>::const_iterator it = c.m_fields.begin() ; it != c.m_fields.end() ; ++it)
|
if (it == m_fields.end())
|
||||||
fields.push_back((*it)->clone());
|
throw exceptions::no_such_field();
|
||||||
|
|
||||||
for (std::vector <headerField*>::iterator it = m_fields.begin() ; it != m_fields.end() ; ++it)
|
delete (*it);
|
||||||
delete (*it);
|
|
||||||
|
|
||||||
m_fields.resize(fields.size());
|
m_fields.erase(it);
|
||||||
std::copy(fields.begin(), fields.end(), m_fields.begin());
|
}
|
||||||
|
|
||||||
return (*this);
|
|
||||||
|
void header::removeField(const int pos)
|
||||||
|
{
|
||||||
|
const std::vector <headerField*>::iterator it = m_fields.begin() + pos;
|
||||||
|
|
||||||
|
delete (*it);
|
||||||
|
|
||||||
|
m_fields.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void header::removeAllFields()
|
||||||
|
{
|
||||||
|
free_container(m_fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const int header::getFieldCount() const
|
||||||
|
{
|
||||||
|
return (m_fields.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const bool header::isEmpty() const
|
||||||
|
{
|
||||||
|
return (m_fields.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
headerField* header::getFieldAt(const int pos)
|
||||||
|
{
|
||||||
|
return (m_fields[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const headerField* const header::getFieldAt(const int pos) const
|
||||||
|
{
|
||||||
|
return (m_fields[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector <const headerField*> header::getFieldList() const
|
||||||
|
{
|
||||||
|
std::vector <const headerField*> list;
|
||||||
|
|
||||||
|
list.reserve(m_fields.size());
|
||||||
|
|
||||||
|
for (std::vector <headerField*>::const_iterator it = m_fields.begin() ;
|
||||||
|
it != m_fields.end() ; ++it)
|
||||||
|
{
|
||||||
|
list.push_back(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector <headerField*> header::getFieldList()
|
||||||
|
{
|
||||||
|
return (m_fields);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
310
src/header.hpp
310
src/header.hpp
@ -28,16 +28,12 @@
|
|||||||
#include "headerField.hpp"
|
#include "headerField.hpp"
|
||||||
#include "headerFieldFactory.hpp"
|
#include "headerFieldFactory.hpp"
|
||||||
|
|
||||||
#include "addressListField.hpp"
|
|
||||||
#include "mailboxListField.hpp"
|
|
||||||
#include "mailboxField.hpp"
|
#include "mailboxField.hpp"
|
||||||
#include "textField.hpp"
|
|
||||||
#include "dateField.hpp"
|
|
||||||
#include "contentTypeField.hpp"
|
#include "contentTypeField.hpp"
|
||||||
#include "contentEncodingField.hpp"
|
|
||||||
#include "defaultField.hpp"
|
|
||||||
#include "contentDispositionField.hpp"
|
#include "contentDispositionField.hpp"
|
||||||
#include "messageIdField.hpp"
|
|
||||||
|
#include "standardFields.hpp"
|
||||||
|
#include "standardParams.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
@ -61,196 +57,166 @@ public:
|
|||||||
header();
|
header();
|
||||||
~header();
|
~header();
|
||||||
|
|
||||||
// A sub-class for field manipulation
|
#define FIELD_ACCESS(methodName, fieldName, type) \
|
||||||
class fieldsContainer
|
type& methodName() { return dynamic_cast <type&> \
|
||||||
{
|
(*getField(fields::fieldName)); } \
|
||||||
friend class header;
|
const type& methodName() const { return dynamic_cast <const type&> \
|
||||||
|
(*findField(fields::fieldName)); }
|
||||||
|
|
||||||
protected:
|
FIELD_ACCESS(From, FROM, mailboxField)
|
||||||
|
FIELD_ACCESS(Sender, SENDER, mailboxField)
|
||||||
|
FIELD_ACCESS(ReplyTo, REPLY_TO, mailboxField)
|
||||||
|
FIELD_ACCESS(DeliveredTo, DELIVERED_TO, mailboxField)
|
||||||
|
|
||||||
fieldsContainer();
|
FIELD_ACCESS(To, TO, addressListField)
|
||||||
~fieldsContainer();
|
FIELD_ACCESS(Cc, CC, addressListField)
|
||||||
|
FIELD_ACCESS(Bcc, BCC, addressListField)
|
||||||
|
FIELD_ACCESS(Date, DATE, dateField)
|
||||||
|
FIELD_ACCESS(Subject, SUBJECT, textField)
|
||||||
|
FIELD_ACCESS(Organization, ORGANIZATION, textField)
|
||||||
|
FIELD_ACCESS(UserAgent, USER_AGENT, textField)
|
||||||
|
|
||||||
public:
|
FIELD_ACCESS(ContentType, CONTENT_TYPE, contentTypeField)
|
||||||
|
FIELD_ACCESS(ContentDescription, CONTENT_DESCRIPTION, textField)
|
||||||
|
FIELD_ACCESS(ContentTransferEncoding, CONTENT_TRANSFER_ENCODING, contentEncodingField)
|
||||||
|
FIELD_ACCESS(MimeVersion, MIME_VERSION, defaultField)
|
||||||
|
FIELD_ACCESS(ContentDisposition, CONTENT_DISPOSITION, contentDispositionField)
|
||||||
|
FIELD_ACCESS(ContentId, CONTENT_ID, messageIdField)
|
||||||
|
FIELD_ACCESS(MessageId, MESSAGE_ID, messageIdField)
|
||||||
|
FIELD_ACCESS(ContentLocation, CONTENT_LOCATION, defaultField)
|
||||||
|
|
||||||
// Field access
|
#undef FIELD_ACCESS
|
||||||
mailboxField& From() { return (dynamic_cast<mailboxField&>(get(headerField::From))); }
|
|
||||||
mailboxField& Sender() { return (dynamic_cast<mailboxField&>(get(headerField::Sender))); }
|
|
||||||
mailboxField& ReplyTo() { return (dynamic_cast<mailboxField&>(get(headerField::ReplyTo))); }
|
|
||||||
mailboxField& DeliveredTo() { return (dynamic_cast<mailboxField&>(get(headerField::DeliveredTo))); }
|
|
||||||
addressListField& To() { return (dynamic_cast<addressListField&>(get(headerField::To))); }
|
|
||||||
addressListField& Cc() { return (dynamic_cast<addressListField&>(get(headerField::Cc))); }
|
|
||||||
addressListField& Bcc() { return (dynamic_cast<addressListField&>(get(headerField::Bcc))); }
|
|
||||||
dateField& Date() { return (dynamic_cast<dateField&>(get(headerField::Date))); }
|
|
||||||
textField& Subject() { return (dynamic_cast<textField&>(get(headerField::Subject))); }
|
|
||||||
textField& Organization() { return (dynamic_cast<textField&>(get(headerField::Organization))); }
|
|
||||||
textField& UserAgent() { return (dynamic_cast<textField&>(get(headerField::UserAgent))); }
|
|
||||||
contentTypeField& ContentType() { return (dynamic_cast<contentTypeField&>(get(headerField::ContentType))); }
|
|
||||||
textField& ContentDescription() { return (dynamic_cast<textField&>(get(headerField::ContentDescription))); }
|
|
||||||
contentEncodingField& ContentTransferEncoding() { return (dynamic_cast<contentEncodingField&>(get(headerField::ContentTransferEncoding))); }
|
|
||||||
defaultField& MimeVersion() { return (dynamic_cast<defaultField&>(get(headerField::MimeVersion))); }
|
|
||||||
contentDispositionField& ContentDisposition() { return (dynamic_cast<contentDispositionField&>(get(headerField::ContentDisposition))); }
|
|
||||||
messageIdField& ContentId() { return (dynamic_cast<messageIdField&>(get(headerField::ContentId))); }
|
|
||||||
messageIdField& MessageId() { return (dynamic_cast<messageIdField&>(get(headerField::MessageId))); }
|
|
||||||
defaultField& ContentLocation() { return (dynamic_cast<defaultField&>(get(headerField::ContentLocation))); }
|
|
||||||
|
|
||||||
const mailboxField& From() const { return (dynamic_cast<mailboxField&>(find(headerField::From))); }
|
/** Checks whether (at least) one field with this name exists.
|
||||||
const mailboxField& Sender() const { return (dynamic_cast<mailboxField&>(find(headerField::Sender))); }
|
*
|
||||||
const mailboxField& ReplyTo() const { return (dynamic_cast<mailboxField&>(find(headerField::ReplyTo))); }
|
* @return true if at least one field with the specified name
|
||||||
const mailboxField& DeliveredTo() const { return (dynamic_cast<mailboxField&>(find(headerField::DeliveredTo))); }
|
* exists, or false otherwise
|
||||||
const addressListField& To() const { return (dynamic_cast<addressListField&>(find(headerField::To))); }
|
*/
|
||||||
const addressListField& Cc() const { return (dynamic_cast<addressListField&>(find(headerField::Cc))); }
|
const bool hasField(const string& fieldName) const;
|
||||||
const addressListField& Bcc() const { return (dynamic_cast<addressListField&>(find(headerField::Bcc))); }
|
|
||||||
const dateField& Date() const { return (dynamic_cast<dateField&>(find(headerField::Date))); }
|
|
||||||
const textField& Subject() const { return (dynamic_cast<textField&>(find(headerField::Subject))); }
|
|
||||||
const textField& Organization() const { return (dynamic_cast<textField&>(find(headerField::Organization))); }
|
|
||||||
const textField& UserAgent() const { return (dynamic_cast<textField&>(find(headerField::UserAgent))); }
|
|
||||||
const contentTypeField& ContentType() const { return (dynamic_cast<contentTypeField&>(find(headerField::ContentType))); }
|
|
||||||
const textField& ContentDescription() const { return (dynamic_cast<textField&>(find(headerField::ContentDescription))); }
|
|
||||||
const contentEncodingField& ContentTransferEncoding() const { return (dynamic_cast<contentEncodingField&>(find(headerField::ContentTransferEncoding))); }
|
|
||||||
const defaultField& MimeVersion() const { return (dynamic_cast<defaultField&>(find(headerField::MimeVersion))); }
|
|
||||||
const contentDispositionField& ContentDisposition() const { return (dynamic_cast<contentDispositionField&>(find(headerField::ContentDisposition))); }
|
|
||||||
const messageIdField& ContentId() const { return (dynamic_cast<messageIdField&>(find(headerField::ContentId))); }
|
|
||||||
const messageIdField& MessageId() const { return (dynamic_cast<messageIdField&>(find(headerField::MessageId))); }
|
|
||||||
const defaultField& ContentLocation() const { return (dynamic_cast<defaultField&>(find(headerField::ContentLocation))); }
|
|
||||||
|
|
||||||
// Checks whether (at least) one field with this type/name exists
|
/** Find the first field that matches the specified name.
|
||||||
const bool has(const headerField::Types fieldType) const;
|
* If no field is found, an exception is thrown.
|
||||||
const bool has(const string& fieldName) const;
|
*
|
||||||
|
* @throw exceptions::no_such_field if no field with this name exists
|
||||||
|
* @return first field with the specified name
|
||||||
|
*/
|
||||||
|
headerField* findField(const string& fieldName) const;
|
||||||
|
|
||||||
// Find the first field that matches the specified type/name.
|
/** Find all fields that match the specified name.
|
||||||
// If no field is found, an exception is thrown.
|
* If no field is found, an empty vector is returned.
|
||||||
headerField& find(const headerField::Types fieldType) const;
|
*
|
||||||
headerField& find(const string& fieldName) const;
|
* @return list of fields with the specified name
|
||||||
|
*/
|
||||||
|
std::vector <headerField*> findAllFields(const string& fieldName);
|
||||||
|
|
||||||
// Find all fields that matche the specified type/name.
|
/** Find the first field that matches the specified name.
|
||||||
// If no field is found, an empty vector is returned.
|
* If no field is found, one will be created and inserted into
|
||||||
std::vector <headerField*> findAllByType(const headerField::Types fieldType);
|
* the header.
|
||||||
std::vector <headerField*> findAllByName(const string& fieldName);
|
*
|
||||||
|
* @return first field with the specified name or a new field
|
||||||
|
* if no field is found
|
||||||
|
*/
|
||||||
|
headerField* getField(const string& fieldName);
|
||||||
|
|
||||||
// Find the first field that matches the specified type/name.
|
/** Add a field at the end of the list.
|
||||||
// If no field is found, one will be created.
|
*
|
||||||
headerField& get(const headerField::Types fieldType);
|
* @param field field to append
|
||||||
headerField& get(const string& fieldName);
|
*/
|
||||||
|
void appendField(headerField* field);
|
||||||
|
|
||||||
// Field iterator
|
/** Insert a new field before the specified field.
|
||||||
class const_iterator;
|
*
|
||||||
|
* @param beforeField field before which the new field will be inserted
|
||||||
|
* @param field field to insert
|
||||||
|
* @throw exceptions::no_such_field if the field is not in the list
|
||||||
|
*/
|
||||||
|
void insertFieldBefore(headerField* beforeField, headerField* field);
|
||||||
|
|
||||||
class iterator
|
/** Insert a new field before the specified position.
|
||||||
{
|
*
|
||||||
friend class header::fieldsContainer::const_iterator;
|
* @param pos position at which to insert the new field (0 to insert at
|
||||||
friend class header::fieldsContainer;
|
* the beginning of the list)
|
||||||
|
* @param field field to insert
|
||||||
|
*/
|
||||||
|
void insertFieldBefore(const int pos, headerField* field);
|
||||||
|
|
||||||
public:
|
/** Insert a new field after the specified field.
|
||||||
|
*
|
||||||
|
* @param afterField field after which the new field will be inserted
|
||||||
|
* @param field field to insert
|
||||||
|
* @throw exceptions::no_such_field if the field is not in the list
|
||||||
|
*/
|
||||||
|
void insertFieldAfter(headerField* afterField, headerField* field);
|
||||||
|
|
||||||
typedef std::vector <headerField*>::iterator::difference_type difference_type;
|
/** Insert a new field after the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position of the field before the new field
|
||||||
|
* @param field field to insert
|
||||||
|
*/
|
||||||
|
void insertFieldAfter(const int pos, headerField* field);
|
||||||
|
|
||||||
iterator(std::vector <headerField*>::iterator it) : m_iterator(it) { }
|
/** Remove the specified field from the list.
|
||||||
iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
*
|
||||||
|
* @param field field to remove
|
||||||
|
* @throw exceptions::no_such_field if the field is not in the list
|
||||||
|
*/
|
||||||
|
void removeField(headerField* field);
|
||||||
|
|
||||||
iterator& operator=(const iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
/** Remove the field at the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position of the field to remove
|
||||||
|
*/
|
||||||
|
void removeField(const int pos);
|
||||||
|
|
||||||
headerField& operator*() const { return (**m_iterator); }
|
/** Remove all fields from the list.
|
||||||
headerField* operator->() const { return (*m_iterator); }
|
*/
|
||||||
|
void removeAllFields();
|
||||||
|
|
||||||
iterator& operator++() { ++m_iterator; return (*this); }
|
/** Return the number of fields in the list.
|
||||||
iterator operator++(int) { iterator i(*this); ++m_iterator; return (i); }
|
*
|
||||||
|
* @return number of fields
|
||||||
|
*/
|
||||||
|
const int getFieldCount() const;
|
||||||
|
|
||||||
iterator& operator--() { --m_iterator; return (*this); }
|
/** Tests whether the list of fields is empty.
|
||||||
iterator operator--(int) { iterator i(*this); --m_iterator; return (i); }
|
*
|
||||||
|
* @return true if there is no field, false otherwise
|
||||||
|
*/
|
||||||
|
const bool isEmpty() const;
|
||||||
|
|
||||||
iterator& operator+=(difference_type n) { m_iterator += n; return (*this); }
|
/** Return the field at the specified position.
|
||||||
iterator& operator-=(difference_type n) { m_iterator -= n; return (*this); }
|
*
|
||||||
|
* @param pos position
|
||||||
|
* @return field at position 'pos'
|
||||||
|
*/
|
||||||
|
headerField* getFieldAt(const int pos);
|
||||||
|
|
||||||
iterator operator-(difference_type x) const { return iterator(m_iterator - x); }
|
/** Return the field at the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position
|
||||||
|
* @return field at position 'pos'
|
||||||
|
*/
|
||||||
|
const headerField* const getFieldAt(const int pos) const;
|
||||||
|
|
||||||
headerField& operator[](difference_type n) const { return *(m_iterator[n]); }
|
/** Return the field list.
|
||||||
|
*
|
||||||
|
* @return list of fields
|
||||||
|
*/
|
||||||
|
const std::vector <const headerField*> getFieldList() const;
|
||||||
|
|
||||||
const bool operator==(const iterator& it) const { return (it.m_iterator == m_iterator); }
|
/** Return the field list.
|
||||||
const bool operator!=(const iterator& it) const { return (!(*this == it)); }
|
*
|
||||||
|
* @return list of fields
|
||||||
|
*/
|
||||||
|
const std::vector <headerField*> getFieldList();
|
||||||
|
|
||||||
protected:
|
header* clone() const;
|
||||||
|
void copyFrom(const component& other);
|
||||||
|
header& operator=(const header& other);
|
||||||
|
|
||||||
std::vector <headerField*>::iterator m_iterator;
|
private:
|
||||||
};
|
|
||||||
|
|
||||||
class const_iterator
|
std::vector <headerField*> m_fields;
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
typedef std::vector <headerField*>::const_iterator::difference_type difference_type;
|
|
||||||
|
|
||||||
const_iterator(std::vector <headerField*>::const_iterator it) : m_iterator(it) { }
|
|
||||||
const_iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
|
||||||
const_iterator(const const_iterator& it) : m_iterator(it.m_iterator) { }
|
|
||||||
|
|
||||||
const_iterator& operator=(const const_iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
|
||||||
const_iterator& operator=(const iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
|
||||||
|
|
||||||
const headerField& operator*() const { return (**m_iterator); }
|
|
||||||
const headerField* operator->() const { return (*m_iterator); }
|
|
||||||
|
|
||||||
const_iterator& operator++() { ++m_iterator; return (*this); }
|
|
||||||
const_iterator operator++(int) { const_iterator i(*this); ++m_iterator; return (i); }
|
|
||||||
|
|
||||||
const_iterator& operator--() { --m_iterator; return (*this); }
|
|
||||||
const_iterator operator--(int) { const_iterator i(*this); --m_iterator; return (i); }
|
|
||||||
|
|
||||||
const_iterator& operator+=(difference_type n) { m_iterator += n; return (*this); }
|
|
||||||
const_iterator& operator-=(difference_type n) { m_iterator -= n; return (*this); }
|
|
||||||
|
|
||||||
const_iterator operator-(difference_type x) const { return const_iterator(m_iterator - x); }
|
|
||||||
|
|
||||||
const headerField& operator[](difference_type n) const { return *(m_iterator[n]); }
|
|
||||||
|
|
||||||
const bool operator==(const const_iterator& it) const { return (it.m_iterator == m_iterator); }
|
|
||||||
const bool operator!=(const const_iterator& it) const { return (!(*this == it)); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
std::vector <headerField*>::const_iterator m_iterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
iterator begin() { return (m_fields.begin()); }
|
|
||||||
iterator end() { return (m_fields.end()); }
|
|
||||||
|
|
||||||
const_iterator begin() const { return (const_iterator(m_fields.begin())); }
|
|
||||||
const_iterator end() const { return (const_iterator(m_fields.end())); }
|
|
||||||
|
|
||||||
// Field insertion
|
|
||||||
void append(const headerField& field);
|
|
||||||
void insert(const iterator it, const headerField& field);
|
|
||||||
|
|
||||||
// Field removing
|
|
||||||
void remove(const iterator it);
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
// Field count
|
|
||||||
const std::vector <headerField*>::size_type count() const { return (m_fields.size()); }
|
|
||||||
const std::vector <headerField*>::size_type size() const { return (m_fields.size()); }
|
|
||||||
const bool empty() const { return (m_fields.empty()); }
|
|
||||||
|
|
||||||
headerField& front() { return (*m_fields.front()); }
|
|
||||||
const headerField& front() const { return (*m_fields.front()); }
|
|
||||||
headerField& back() { return (*m_fields.back()); }
|
|
||||||
const headerField& back() const { return (*m_fields.back()); }
|
|
||||||
|
|
||||||
fieldsContainer& operator=(const fieldsContainer& c);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
void insertSorted(headerField* field);
|
|
||||||
|
|
||||||
std::vector <headerField*> m_fields;
|
|
||||||
|
|
||||||
} fields;
|
|
||||||
|
|
||||||
typedef fieldsContainer::iterator iterator;
|
|
||||||
typedef fieldsContainer::const_iterator const_iterator;
|
|
||||||
|
|
||||||
header& operator=(const header& h);
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -26,13 +26,13 @@ namespace vmime
|
|||||||
|
|
||||||
|
|
||||||
headerField::headerField()
|
headerField::headerField()
|
||||||
: m_type(Custom), m_name("Undefined")
|
: m_name("X-Undefined")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
headerField::headerField(const string& fieldName)
|
headerField::headerField(const string& fieldName)
|
||||||
: m_type(Custom), m_name(fieldName)
|
: m_name(fieldName)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,12 +44,7 @@ headerField::~headerField()
|
|||||||
|
|
||||||
headerField* headerField::clone() const
|
headerField* headerField::clone() const
|
||||||
{
|
{
|
||||||
headerField* field = NULL;
|
headerField* field = headerFieldFactory::getInstance()->create(m_name);
|
||||||
|
|
||||||
if (m_type == Custom)
|
|
||||||
field = headerFieldFactory::getInstance()->create(m_name);
|
|
||||||
else
|
|
||||||
field = headerFieldFactory::getInstance()->create(m_type);
|
|
||||||
|
|
||||||
field->copyFrom(*this);
|
field->copyFrom(*this);
|
||||||
|
|
||||||
@ -57,209 +52,46 @@ headerField* headerField::clone() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const bool headerField::operator<(const headerField& field) const
|
void headerField::copyFrom(const component& other)
|
||||||
{
|
{
|
||||||
return (m_type < field.m_type);
|
const headerField& hf = dynamic_cast <const headerField&>(other);
|
||||||
|
|
||||||
|
getValue().copyFrom(hf.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
headerField& headerField::operator=(const headerField& field)
|
headerField& headerField::operator=(const headerField& other)
|
||||||
{
|
{
|
||||||
copyFrom(field);
|
copyFrom(other);
|
||||||
return (*this);
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void headerField::copyFrom(const headerField& field)
|
void headerField::parse(const string& buffer, const string::size_type position, const string::size_type end,
|
||||||
|
string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
m_type = field.m_type;
|
getValue().parse(buffer, position, end, newPosition);
|
||||||
m_name = field.m_name;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void headerField::generate(utility::outputStream& os, const string::size_type /* maxLineLength */,
|
void headerField::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
if (m_type == Custom)
|
os << m_name + ": ";
|
||||||
{
|
|
||||||
os << m_name + ": ";
|
|
||||||
|
|
||||||
if (newLinePos)
|
getValue().generate(os, maxLineLength, curLinePos + m_name.length() + 2, newLinePos);
|
||||||
*newLinePos = curLinePos + m_name.length() + 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const string name = typeToName(m_type);
|
|
||||||
|
|
||||||
os << name + ": ";
|
|
||||||
|
|
||||||
if (newLinePos)
|
|
||||||
*newLinePos = curLinePos + name.length() + 2;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Return the field type corresponding to the specified name.
|
const string headerField::getName() const
|
||||||
*
|
|
||||||
* @param name field name
|
|
||||||
* @return field type (see headerField::Types) or headerField::custom
|
|
||||||
* if this is a custom field
|
|
||||||
*/
|
|
||||||
|
|
||||||
const headerField::Types headerField::nameToType(const string& name)
|
|
||||||
{
|
{
|
||||||
switch (name[0])
|
return (m_name);
|
||||||
{
|
|
||||||
case 'B':
|
|
||||||
case 'b':
|
|
||||||
{
|
|
||||||
if (isStringEqualNoCase(name, "bcc", 3)) return (Bcc);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'C':
|
|
||||||
case 'c':
|
|
||||||
{
|
|
||||||
if (isStringEqualNoCase(name, "cc", 2)) return (Cc);
|
|
||||||
else if (isStringEqualNoCase(name, "content-type", 12)) return (ContentType);
|
|
||||||
else if (isStringEqualNoCase(name, "content-transfer-encoding", 25)) return (ContentTransferEncoding);
|
|
||||||
else if (isStringEqualNoCase(name, "content-description", 19)) return (ContentDescription);
|
|
||||||
else if (isStringEqualNoCase(name, "content-disposition", 19)) return (ContentDisposition);
|
|
||||||
else if (isStringEqualNoCase(name, "content-id", 10)) return (ContentId);
|
|
||||||
else if (isStringEqualNoCase(name, "content-location", 16)) return (ContentLocation);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'd':
|
|
||||||
case 'D':
|
|
||||||
{
|
|
||||||
if (isStringEqualNoCase(name, "date", 4)) return (Date);
|
|
||||||
else if (isStringEqualNoCase(name, "delivered-to", 12)) return (DeliveredTo);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'f':
|
|
||||||
case 'F':
|
|
||||||
{
|
|
||||||
if (isStringEqualNoCase(name, "from", 4)) return (From);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'm':
|
|
||||||
case 'M':
|
|
||||||
{
|
|
||||||
if (isStringEqualNoCase(name, "mime-version", 12)) return (MimeVersion);
|
|
||||||
else if (isStringEqualNoCase(name, "message-id", 10)) return (MessageId);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'o':
|
|
||||||
case 'O':
|
|
||||||
{
|
|
||||||
if (isStringEqualNoCase(name, "organization", 12)) return (Organization);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'r':
|
|
||||||
case 'R':
|
|
||||||
{
|
|
||||||
if (isStringEqualNoCase(name, "received", 8)) return (Received);
|
|
||||||
else if (isStringEqualNoCase(name, "reply-to", 8)) return (ReplyTo);
|
|
||||||
else if (isStringEqualNoCase(name, "return-path", 11)) return (ReturnPath);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 's':
|
|
||||||
case 'S':
|
|
||||||
{
|
|
||||||
if (isStringEqualNoCase(name, "sender", 6)) return (Sender);
|
|
||||||
else if (isStringEqualNoCase(name, "subject", 7)) return (Subject);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 't':
|
|
||||||
case 'T':
|
|
||||||
{
|
|
||||||
if (isStringEqualNoCase(name, "to", 2)) return (To);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'u':
|
|
||||||
case 'U':
|
|
||||||
{
|
|
||||||
if (isStringEqualNoCase(name, "user-agent", 10)) return (UserAgent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return (Custom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/** Return the name for the specified field type.
|
|
||||||
* Eg: returns "From" for headerField::From.
|
|
||||||
*
|
|
||||||
* @param type field type
|
|
||||||
* @return name for the specified field type
|
|
||||||
*/
|
|
||||||
|
|
||||||
const string headerField::typeToName(const Types type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case From: return "From";
|
|
||||||
case Sender: return "Sender";
|
|
||||||
case To: return "To";
|
|
||||||
case Cc: return "Cc";
|
|
||||||
case Bcc: return "Bcc";
|
|
||||||
case Date: return "Date";
|
|
||||||
case Received: return "Received";
|
|
||||||
case Subject: return "Subject";
|
|
||||||
case ReplyTo: return "Reply-To";
|
|
||||||
case Organization: return "Organization";
|
|
||||||
case DeliveredTo: return "Delivered-To";
|
|
||||||
case UserAgent: return "User-Agent";
|
|
||||||
case ReturnPath: return "Return-Path";
|
|
||||||
case ContentType: return "Content-Type";
|
|
||||||
case ContentTransferEncoding: return "Content-Transfer-Encoding";
|
|
||||||
case ContentDescription: return "Content-Description";
|
|
||||||
case MimeVersion: return "Mime-Version";
|
|
||||||
case ContentDisposition: return "Content-Disposition";
|
|
||||||
case ContentId: return "Content-Id";
|
|
||||||
case MessageId: return "Message-Id";
|
|
||||||
case ContentLocation: return "Content-Location";
|
|
||||||
|
|
||||||
case Custom:
|
|
||||||
case Last:
|
|
||||||
return "?";
|
|
||||||
};
|
|
||||||
|
|
||||||
return "?";
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Return the type of this field.
|
|
||||||
*
|
|
||||||
* @return field type (see headerField::Types)
|
|
||||||
*/
|
|
||||||
|
|
||||||
const headerField::Types headerField::type() const
|
|
||||||
{
|
|
||||||
return (m_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Return the name of this field.
|
|
||||||
*
|
|
||||||
* @return field name
|
|
||||||
*/
|
|
||||||
|
|
||||||
const string headerField::name() const
|
|
||||||
{
|
|
||||||
return ((m_type == Custom) ? m_name : typeToName(m_type));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/** Check whether this field is a custom field.
|
|
||||||
*
|
|
||||||
* @return true if the field is a custom field, false otherwise
|
|
||||||
*/
|
|
||||||
|
|
||||||
const bool headerField::isCustom() const
|
const bool headerField::isCustom() const
|
||||||
{
|
{
|
||||||
return (m_type == Custom);
|
return (m_name.length() > 2 && m_name[0] == 'X' && m_name[1] == '-');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -45,65 +45,53 @@ public:
|
|||||||
|
|
||||||
~headerField();
|
~headerField();
|
||||||
|
|
||||||
public:
|
headerField* clone() const;
|
||||||
|
void copyFrom(const component& other);
|
||||||
|
headerField& operator=(const headerField& other);
|
||||||
|
|
||||||
// Header field types (in the order in which they will appear
|
/** Return the name of this field.
|
||||||
// in the message header)
|
*
|
||||||
enum Types
|
* @return field name
|
||||||
{
|
*/
|
||||||
Received, // Relay
|
const string getName() const;
|
||||||
From, // Expeditor
|
|
||||||
Sender, // Sender
|
|
||||||
ReplyTo, // Reply-To
|
|
||||||
To, // Recipient(s)
|
|
||||||
Cc, // Carbon copy recipient(s)
|
|
||||||
Bcc, // Blind carbon-copy recipient(s)
|
|
||||||
Date, // Date sent
|
|
||||||
Subject, // Subject
|
|
||||||
Organization, // Organization
|
|
||||||
UserAgent, // User agent
|
|
||||||
DeliveredTo, // Delivered-To
|
|
||||||
ReturnPath, // Return-Path
|
|
||||||
MimeVersion, // Mime-Version
|
|
||||||
MessageId, // Message-Id
|
|
||||||
ContentType, // Content-Type
|
|
||||||
ContentTransferEncoding, // Content-Transfer-Encoding
|
|
||||||
ContentDescription, // Content-Description
|
|
||||||
ContentDisposition, // Content-Disposition
|
|
||||||
ContentId, // Content-Id
|
|
||||||
ContentLocation, // Content-Location
|
|
||||||
|
|
||||||
Custom, // Unknown or custom field (eg. X-Priority, X-Mailer, etc.)
|
|
||||||
|
|
||||||
Last
|
|
||||||
};
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
Types m_type;
|
|
||||||
string m_name; // In case of custom field
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
const bool operator<(const headerField& field) const;
|
|
||||||
|
|
||||||
const Types type() const;
|
|
||||||
const string name() const;
|
|
||||||
|
|
||||||
|
/** Check whether this field is a custom (non-standard) field.
|
||||||
|
* Custom fields have a name beginning with "X-".
|
||||||
|
*
|
||||||
|
* @return true if the field is a custom field, false otherwise
|
||||||
|
*/
|
||||||
const bool isCustom() const;
|
const bool isCustom() const;
|
||||||
|
|
||||||
virtual void copyFrom(const headerField& field);
|
/** Return the read-only value object attached to this field.
|
||||||
headerField& operator=(const headerField& field);
|
*
|
||||||
headerField* clone() const;
|
* @return read-only value object
|
||||||
|
*/
|
||||||
|
virtual const component& getValue() const = 0;
|
||||||
|
|
||||||
static const Types nameToType(const string& name);
|
/** Return the value object attached to this field.
|
||||||
static const string typeToName(const Types type);
|
*
|
||||||
|
* @return value object
|
||||||
|
*/
|
||||||
|
virtual component& getValue() = 0;
|
||||||
|
|
||||||
|
/** Set the value of this field.
|
||||||
|
*
|
||||||
|
* @throw std::bad_cast_exception if the value type is
|
||||||
|
* incompatible with the header field type
|
||||||
|
* @param value value object
|
||||||
|
*/
|
||||||
|
virtual void setValue(const component& value) = 0;
|
||||||
|
|
||||||
|
|
||||||
// Component assembling
|
using component::parse;
|
||||||
using component::generate;
|
using component::generate;
|
||||||
|
|
||||||
|
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
string m_name;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -20,21 +20,11 @@
|
|||||||
#include "headerFieldFactory.hpp"
|
#include "headerFieldFactory.hpp"
|
||||||
#include "exception.hpp"
|
#include "exception.hpp"
|
||||||
|
|
||||||
#include "defaultField.hpp"
|
#include "standardFields.hpp"
|
||||||
|
|
||||||
#include "mailboxField.hpp"
|
|
||||||
#include "addressListField.hpp"
|
|
||||||
#include "addressListField.hpp"
|
|
||||||
#include "addressListField.hpp"
|
|
||||||
#include "mailboxField.hpp"
|
|
||||||
#include "dateField.hpp"
|
|
||||||
#include "relayField.hpp"
|
|
||||||
#include "textField.hpp"
|
|
||||||
#include "mailboxField.hpp"
|
#include "mailboxField.hpp"
|
||||||
#include "contentTypeField.hpp"
|
#include "contentTypeField.hpp"
|
||||||
#include "contentEncodingField.hpp"
|
|
||||||
#include "contentDispositionField.hpp"
|
#include "contentDispositionField.hpp"
|
||||||
#include "messageIdField.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
@ -43,28 +33,28 @@ namespace vmime
|
|||||||
|
|
||||||
headerFieldFactory::headerFieldFactory()
|
headerFieldFactory::headerFieldFactory()
|
||||||
{
|
{
|
||||||
// Register some default field types
|
// Register some default fields
|
||||||
registerType <mailboxField>(headerField::From);
|
registerName <mailboxField>(vmime::fields::FROM);
|
||||||
registerType <addressListField>(headerField::To);
|
registerName <addressListField>(vmime::fields::TO);
|
||||||
registerType <addressListField>(headerField::Cc);
|
registerName <addressListField>(vmime::fields::CC);
|
||||||
registerType <addressListField>(headerField::Bcc);
|
registerName <addressListField>(vmime::fields::BCC);
|
||||||
registerType <mailboxField>(headerField::Sender);
|
registerName <mailboxField>(vmime::fields::SENDER);
|
||||||
registerType <dateField>(headerField::Date);
|
registerName <dateField>(vmime::fields::DATE);
|
||||||
registerType <relayField>(headerField::Received);
|
registerName <relayField>(vmime::fields::RECEIVED);
|
||||||
registerType <textField>(headerField::Subject);
|
registerName <textField>(vmime::fields::SUBJECT);
|
||||||
registerType <mailboxField>(headerField::ReplyTo);
|
registerName <mailboxField>(vmime::fields::REPLY_TO);
|
||||||
registerType <mailboxField>(headerField::DeliveredTo);
|
registerName <mailboxField>(vmime::fields::DELIVERED_TO);
|
||||||
registerType <textField>(headerField::Organization);
|
registerName <textField>(vmime::fields::ORGANIZATION);
|
||||||
registerType <textField>(headerField::UserAgent);
|
registerName <textField>(vmime::fields::USER_AGENT);
|
||||||
registerType <mailboxField>(headerField::ReturnPath);
|
registerName <mailboxField>(vmime::fields::RETURN_PATH);
|
||||||
registerType <contentTypeField>(headerField::ContentType);
|
registerName <contentTypeField>(vmime::fields::CONTENT_TYPE);
|
||||||
registerType <contentEncodingField>(headerField::ContentTransferEncoding);
|
registerName <contentEncodingField>(vmime::fields::CONTENT_TRANSFER_ENCODING);
|
||||||
registerType <textField>(headerField::ContentDescription);
|
registerName <textField>(vmime::fields::CONTENT_DESCRIPTION);
|
||||||
registerType <defaultField>(headerField::MimeVersion);
|
registerName <defaultField>(vmime::fields::MIME_VERSION);
|
||||||
registerType <contentDispositionField>(headerField::ContentDisposition);
|
registerName <contentDispositionField>(vmime::fields::CONTENT_DISPOSITION);
|
||||||
registerType <messageIdField>(headerField::ContentId);
|
registerName <messageIdField>(vmime::fields::CONTENT_ID);
|
||||||
registerType <messageIdField>(headerField::MessageId);
|
registerName <messageIdField>(vmime::fields::MESSAGE_ID);
|
||||||
registerType <defaultField>(headerField::ContentLocation);
|
registerName <defaultField>(vmime::fields::CONTENT_LOCATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -76,63 +66,24 @@ headerFieldFactory::~headerFieldFactory()
|
|||||||
headerField* headerFieldFactory::create
|
headerField* headerFieldFactory::create
|
||||||
(const string& name, const string& body)
|
(const string& name, const string& body)
|
||||||
{
|
{
|
||||||
const headerField::Types type = headerField::nameToType(name);
|
NameMap::const_iterator pos = m_nameMap.find(stringUtils::toLower(name));
|
||||||
|
headerField* field = NULL;
|
||||||
|
|
||||||
if (type != headerField::Custom)
|
if (pos != m_nameMap.end())
|
||||||
{
|
{
|
||||||
return (create(type, name, body));
|
field = ((*pos).second)();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
NameMap::const_iterator pos = m_nameMap.find(toLower(name));
|
field = registerer <defaultField>::creator();
|
||||||
headerField* field = NULL;
|
|
||||||
|
|
||||||
if (pos != m_nameMap.end())
|
|
||||||
{
|
|
||||||
field = ((*pos).second)();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
field = new defaultField;
|
|
||||||
}
|
|
||||||
|
|
||||||
field->m_type = headerField::Custom;
|
|
||||||
field->m_name = name;
|
|
||||||
|
|
||||||
if (body != NULL_STRING)
|
|
||||||
field->parse(body);
|
|
||||||
|
|
||||||
return (field);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
field->m_name = name;
|
||||||
|
|
||||||
headerField* headerFieldFactory::create(const headerField::Types type,
|
if (body != NULL_STRING)
|
||||||
const string& name, const string& body)
|
field->parse(body);
|
||||||
{
|
|
||||||
if (type == headerField::Custom)
|
|
||||||
{
|
|
||||||
return (create(name, body));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
TypeMap::const_iterator pos = m_typeMap.find(type);
|
|
||||||
|
|
||||||
if (pos != m_typeMap.end())
|
return (field);
|
||||||
{
|
|
||||||
headerField* field = ((*pos).second)();
|
|
||||||
|
|
||||||
field->m_type = type;
|
|
||||||
if (name != NULL_STRING) field->m_name = name;
|
|
||||||
if (body != NULL_STRING) field->parse(body);
|
|
||||||
|
|
||||||
return (field);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
throw exceptions::bad_field_type();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -23,6 +23,7 @@
|
|||||||
|
|
||||||
#include "headerField.hpp"
|
#include "headerField.hpp"
|
||||||
#include "utility/singleton.hpp"
|
#include "utility/singleton.hpp"
|
||||||
|
#include "utility/stringUtils.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
@ -40,10 +41,8 @@ protected:
|
|||||||
|
|
||||||
typedef headerField* (*AllocFunc)(void);
|
typedef headerField* (*AllocFunc)(void);
|
||||||
typedef std::map <string, AllocFunc> NameMap;
|
typedef std::map <string, AllocFunc> NameMap;
|
||||||
typedef std::map <headerField::Types, AllocFunc> TypeMap;
|
|
||||||
|
|
||||||
NameMap m_nameMap;
|
NameMap m_nameMap;
|
||||||
TypeMap m_typeMap;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@ -63,19 +62,10 @@ public:
|
|||||||
template <class T>
|
template <class T>
|
||||||
void registerName(const string& name)
|
void registerName(const string& name)
|
||||||
{
|
{
|
||||||
m_nameMap.insert(NameMap::value_type(toLower(name), ®isterer<T>::creator));
|
m_nameMap.insert(NameMap::value_type(stringUtils::toLower(name), ®isterer<T>::creator));
|
||||||
}
|
}
|
||||||
|
|
||||||
headerField* create(const string& name, const string& body = NULL_STRING);
|
headerField* create(const string& name, const string& body = NULL_STRING);
|
||||||
headerField* create(const headerField::Types type, const string& name = NULL_STRING, const string& body = NULL_STRING);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
template <class T>
|
|
||||||
void registerType(const headerField::Types type)
|
|
||||||
{
|
|
||||||
m_typeMap.insert(TypeMap::value_type(type, ®isterer<T>::creator));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,10 +27,11 @@ namespace vmime
|
|||||||
|
|
||||||
htmlTextPart::~htmlTextPart()
|
htmlTextPart::~htmlTextPart()
|
||||||
{
|
{
|
||||||
|
free_container(m_objects);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const mediaType htmlTextPart::type() const
|
const mediaType htmlTextPart::getType() const
|
||||||
{
|
{
|
||||||
return (mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML));
|
return (mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML));
|
||||||
}
|
}
|
||||||
@ -38,26 +39,26 @@ const mediaType htmlTextPart::type() const
|
|||||||
|
|
||||||
const int htmlTextPart::getPartCount() const
|
const int htmlTextPart::getPartCount() const
|
||||||
{
|
{
|
||||||
return (m_plainText.empty() ? 1 : 2);
|
return (m_plainText.isEmpty() ? 1 : 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void htmlTextPart::generateIn(bodyPart& /* message */, bodyPart& parent) const
|
void htmlTextPart::generateIn(bodyPart& /* message */, bodyPart& parent) const
|
||||||
{
|
{
|
||||||
// Plain text
|
// Plain text
|
||||||
if (!m_plainText.empty())
|
if (!m_plainText.isEmpty())
|
||||||
{
|
{
|
||||||
// -- Create a new part
|
// -- Create a new part
|
||||||
bodyPart* part = new bodyPart();
|
bodyPart* part = new bodyPart();
|
||||||
parent.body().parts.append(part);
|
parent.getBody()->appendPart(part);
|
||||||
|
|
||||||
// -- Set header fields
|
// -- Set header fields
|
||||||
part->header().fields.ContentType() = mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN);
|
part->getHeader()->ContentType().setValue(mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN));
|
||||||
part->header().fields.ContentType().charset() = m_charset;
|
part->getHeader()->ContentType().setCharset(m_charset);
|
||||||
part->header().fields.ContentTransferEncoding() = encoding(encodingTypes::QUOTED_PRINTABLE);
|
part->getHeader()->ContentTransferEncoding().setValue(encoding(encodingTypes::QUOTED_PRINTABLE));
|
||||||
|
|
||||||
// -- Set contents
|
// -- Set contents
|
||||||
part->body().contents() = m_plainText;
|
part->getBody()->setContents(m_plainText);
|
||||||
}
|
}
|
||||||
|
|
||||||
// HTML text
|
// HTML text
|
||||||
@ -65,51 +66,51 @@ void htmlTextPart::generateIn(bodyPart& /* message */, bodyPart& parent) const
|
|||||||
bodyPart* htmlPart = new bodyPart();
|
bodyPart* htmlPart = new bodyPart();
|
||||||
|
|
||||||
// -- Set header fields
|
// -- Set header fields
|
||||||
htmlPart->header().fields.ContentType() = mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML);
|
htmlPart->getHeader()->ContentType().setValue(mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML));
|
||||||
htmlPart->header().fields.ContentType().charset() = m_charset;
|
htmlPart->getHeader()->ContentType().setCharset(m_charset);
|
||||||
htmlPart->header().fields.ContentTransferEncoding() = encoding(encodingTypes::QUOTED_PRINTABLE);
|
htmlPart->getHeader()->ContentTransferEncoding().setValue(encoding(encodingTypes::QUOTED_PRINTABLE));
|
||||||
|
|
||||||
// -- Set contents
|
// -- Set contents
|
||||||
htmlPart->body().contents() = m_text;
|
htmlPart->getBody()->setContents(m_text);
|
||||||
|
|
||||||
// Handle the case we have embedded objects
|
// Handle the case we have embedded objects
|
||||||
if (!embeddedObjects.empty())
|
if (!m_objects.empty())
|
||||||
{
|
{
|
||||||
// Create a "multipart/related" body part
|
// Create a "multipart/related" body part
|
||||||
bodyPart* relPart = new bodyPart();
|
bodyPart* relPart = new bodyPart();
|
||||||
parent.body().parts.append(relPart);
|
parent.getBody()->appendPart(relPart);
|
||||||
|
|
||||||
relPart->header().fields.ContentType() = mediaType
|
relPart->getHeader()->ContentType().
|
||||||
(mediaTypes::MULTIPART, mediaTypes::MULTIPART_RELATED);
|
setValue(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_RELATED));
|
||||||
|
|
||||||
// Add the HTML part into this part
|
// Add the HTML part into this part
|
||||||
relPart->body().parts.append(htmlPart);
|
relPart->getBody()->appendPart(htmlPart);
|
||||||
|
|
||||||
// Also add images into this part
|
// Also add objects into this part
|
||||||
for (embeddedObjectsContainer::const_iterator i = embeddedObjects.begin() ;
|
for (std::vector <embeddedObject*>::const_iterator it = m_objects.begin() ;
|
||||||
i != embeddedObjects.end() ; ++i)
|
it != m_objects.end() ; ++it)
|
||||||
{
|
{
|
||||||
bodyPart* objPart = new bodyPart();
|
bodyPart* objPart = new bodyPart();
|
||||||
relPart->body().parts.append(objPart);
|
relPart->getBody()->appendPart(objPart);
|
||||||
|
|
||||||
string id = (*i).id();
|
string id = (*it)->getId();
|
||||||
|
|
||||||
if (id.substr(0, 4) == "CID:")
|
if (id.substr(0, 4) == "CID:")
|
||||||
id = id.substr(4);
|
id = id.substr(4);
|
||||||
|
|
||||||
objPart->header().fields.ContentType() = (*i).type();
|
objPart->getHeader()->ContentType().setValue((*it)->getType());
|
||||||
objPart->header().fields.ContentId() = messageId("<" + id + ">");
|
objPart->getHeader()->ContentId().setValue(messageId("<" + id + ">"));
|
||||||
objPart->header().fields.ContentDisposition() = disposition(dispositionTypes::INLINE);
|
objPart->getHeader()->ContentDisposition().setValue(disposition(dispositionTypes::INLINE));
|
||||||
objPart->header().fields.ContentTransferEncoding() = (*i).encoding();
|
objPart->getHeader()->ContentTransferEncoding().setValue((*it)->getEncoding());
|
||||||
//encoding(encodingTypes::BASE64);
|
//encoding(encodingTypes::BASE64);
|
||||||
|
|
||||||
objPart->body().contents() = (*i).data();
|
objPart->getBody()->setContents((*it)->getData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Add the HTML part into the parent part
|
// Add the HTML part into the parent part
|
||||||
parent.body().parts.append(htmlPart);
|
parent.getBody()->appendPart(htmlPart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,12 +118,14 @@ void htmlTextPart::generateIn(bodyPart& /* message */, bodyPart& parent) const
|
|||||||
void htmlTextPart::findEmbeddedParts(const bodyPart& part,
|
void htmlTextPart::findEmbeddedParts(const bodyPart& part,
|
||||||
std::vector <const bodyPart*>& cidParts, std::vector <const bodyPart*>& locParts)
|
std::vector <const bodyPart*>& cidParts, std::vector <const bodyPart*>& locParts)
|
||||||
{
|
{
|
||||||
for (body::const_iterator p = part.body().parts.begin() ; p != part.body().parts.end() ; ++p)
|
for (int i = 0 ; i < part.getBody()->getPartCount() ; ++i)
|
||||||
{
|
{
|
||||||
|
const bodyPart& p = *part.getBody()->getPartAt(i);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
dynamic_cast<messageIdField&>((*p).header().fields.find(headerField::ContentId));
|
dynamic_cast<messageIdField&>(*p.getHeader()->findField(fields::CONTENT_ID));
|
||||||
cidParts.push_back(&(*p));
|
cidParts.push_back(&p);
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_field)
|
catch (exceptions::no_such_field)
|
||||||
{
|
{
|
||||||
@ -130,8 +133,8 @@ void htmlTextPart::findEmbeddedParts(const bodyPart& part,
|
|||||||
// Maybe there is a "Content-Location" field...
|
// Maybe there is a "Content-Location" field...
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
dynamic_cast<messageIdField&>((*p).header().fields.find(headerField::ContentId));
|
dynamic_cast<messageIdField&>(*p.getHeader()->findField(fields::CONTENT_ID));
|
||||||
locParts.push_back(&(*p));
|
locParts.push_back(&p);
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_field)
|
catch (exceptions::no_such_field)
|
||||||
{
|
{
|
||||||
@ -140,7 +143,7 @@ void htmlTextPart::findEmbeddedParts(const bodyPart& part,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
findEmbeddedParts((*p), cidParts, locParts);
|
findEmbeddedParts(p, cidParts, locParts);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -152,17 +155,17 @@ void htmlTextPart::addEmbeddedObject(const bodyPart& part, const string& id)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
(part.header().fields.find(headerField::ContentType));
|
(*part.getHeader()->findField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
type = ctf.value();
|
type = ctf.getValue();
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_field)
|
catch (exceptions::no_such_field)
|
||||||
{
|
{
|
||||||
// No "Content-type" field: assume "application/octet-stream".
|
// No "Content-type" field: assume "application/octet-stream".
|
||||||
}
|
}
|
||||||
|
|
||||||
embeddedObjects.m_list.push_back(new embeddedObject
|
m_objects.push_back(new embeddedObject
|
||||||
(part.body().contents(), part.body().encoding(), id, type));
|
(part.getBody()->getContents(), part.getBody()->getEncoding(), id, type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -178,18 +181,18 @@ void htmlTextPart::parse(const bodyPart& message, const bodyPart& parent, const
|
|||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
utility::outputStreamAdapter adapter(oss);
|
utility::outputStreamAdapter adapter(oss);
|
||||||
|
|
||||||
textPart.body().contents().extract(adapter);
|
textPart.getBody()->getContents().extract(adapter);
|
||||||
|
|
||||||
const string data = oss.str();
|
const string data = oss.str();
|
||||||
|
|
||||||
m_text = textPart.body().contents();
|
m_text = textPart.getBody()->getContents();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
(textPart.header().fields.find(headerField::ContentType));
|
(*textPart.getHeader()->findField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
m_charset = ctf.charset();
|
m_charset = ctf.getCharset();
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_field)
|
catch (exceptions::no_such_field)
|
||||||
{
|
{
|
||||||
@ -205,28 +208,28 @@ void htmlTextPart::parse(const bodyPart& message, const bodyPart& parent, const
|
|||||||
for (std::vector <const bodyPart*>::const_iterator p = cidParts.begin() ; p != cidParts.end() ; ++p)
|
for (std::vector <const bodyPart*>::const_iterator p = cidParts.begin() ; p != cidParts.end() ; ++p)
|
||||||
{
|
{
|
||||||
const messageIdField& midField = dynamic_cast<messageIdField&>
|
const messageIdField& midField = dynamic_cast<messageIdField&>
|
||||||
((**p).header().fields.find(headerField::ContentId));
|
(*(*p)->getHeader()->findField(fields::CONTENT_ID));
|
||||||
|
|
||||||
const string searchFor("CID:" + midField.value().id());
|
const string searchFor("CID:" + midField.getValue().getId());
|
||||||
|
|
||||||
if (data.find(searchFor) != string::npos)
|
if (data.find(searchFor) != string::npos)
|
||||||
{
|
{
|
||||||
// This part is referenced in the HTML text.
|
// This part is referenced in the HTML text.
|
||||||
// Add it to the embedded object list.
|
// Add it to the embedded object list.
|
||||||
addEmbeddedObject(**p, "CID:" + midField.value().id());
|
addEmbeddedObject(**p, "CID:" + midField.getValue().getId());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::vector <const bodyPart*>::const_iterator p = locParts.begin() ; p != locParts.end() ; ++p)
|
for (std::vector <const bodyPart*>::const_iterator p = locParts.begin() ; p != locParts.end() ; ++p)
|
||||||
{
|
{
|
||||||
const defaultField& locField = dynamic_cast<defaultField&>
|
const defaultField& locField = dynamic_cast<defaultField&>
|
||||||
((**p).header().fields.find(headerField::ContentLocation));
|
(*(*p)->getHeader()->findField(fields::CONTENT_LOCATION));
|
||||||
|
|
||||||
if (data.find(locField.value()) != string::npos)
|
if (data.find(locField.getValue()) != string::npos)
|
||||||
{
|
{
|
||||||
// This part is referenced in the HTML text.
|
// This part is referenced in the HTML text.
|
||||||
// Add it to the embedded object list.
|
// Add it to the embedded object list.
|
||||||
addEmbeddedObject(**p, locField.value());
|
addEmbeddedObject(**p, locField.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,17 +244,19 @@ bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& paren
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
(part.header().fields.find(headerField::ContentType));
|
(*part.getHeader()->findField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
if (ctf.value().type() == mediaTypes::MULTIPART &&
|
if (ctf.getValue().getType() == mediaTypes::MULTIPART &&
|
||||||
ctf.value().subType() == mediaTypes::MULTIPART_ALTERNATIVE)
|
ctf.getValue().getSubType() == mediaTypes::MULTIPART_ALTERNATIVE)
|
||||||
{
|
{
|
||||||
bodyPart const* foundPart = NULL;
|
bodyPart const* foundPart = NULL;
|
||||||
|
|
||||||
for (body::const_iterator p = part.body().parts.begin() ; !foundPart && p != part.body().parts.end() ; ++p)
|
for (int i = 0 ; i < part.getBody()->getPartCount() ; ++i)
|
||||||
{
|
{
|
||||||
if (&(*p) == &parent || // if "text/html" is in "multipart/related"
|
const bodyPart* p = part.getBody()->getPartAt(i);
|
||||||
&(*p) == &textPart) // if not...
|
|
||||||
|
if (p == &parent || // if "text/html" is in "multipart/related"
|
||||||
|
p == &textPart) // if not...
|
||||||
{
|
{
|
||||||
foundPart = &(*p);
|
foundPart = &(*p);
|
||||||
}
|
}
|
||||||
@ -262,18 +267,19 @@ bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& paren
|
|||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
// Now, search for the alternative plain text part
|
// Now, search for the alternative plain text part
|
||||||
for (body::const_iterator p = part.body().parts.begin() ;
|
for (int i = 0 ; !found && i < part.getBody()->getPartCount() ; ++i)
|
||||||
!found && p != part.body().parts.end() ; ++p)
|
|
||||||
{
|
{
|
||||||
|
const bodyPart& p = *part.getBody()->getPartAt(i);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
((*p).header().fields.find(headerField::ContentType));
|
(*p.getHeader()->findField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
if (ctf.value().type() == mediaTypes::TEXT &&
|
if (ctf.getValue().getType() == mediaTypes::TEXT &&
|
||||||
ctf.value().subType() == mediaTypes::TEXT_PLAIN)
|
ctf.getValue().getSubType() == mediaTypes::TEXT_PLAIN)
|
||||||
{
|
{
|
||||||
m_plainText = (*p).body().contents();
|
m_plainText = p.getBody()->getContents();
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -297,44 +303,82 @@ bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& paren
|
|||||||
|
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
for (body::const_iterator p = part.body().parts.begin() ; !found && p != part.body().parts.end() ; ++p)
|
for (int i = 0 ; !found && i < part.getBody()->getPartCount() ; ++i)
|
||||||
{
|
{
|
||||||
found = findPlainTextPart(*p, parent, textPart);
|
found = findPlainTextPart(*part.getBody()->getPartAt(i), parent, textPart);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (found);
|
return (found);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const charset& htmlTextPart::getCharset() const
|
||||||
////////////////////////////////
|
|
||||||
// Embedded objects container //
|
|
||||||
////////////////////////////////
|
|
||||||
|
|
||||||
|
|
||||||
htmlTextPart::embeddedObjectsContainer::~embeddedObjectsContainer()
|
|
||||||
{
|
{
|
||||||
free_container(m_list);
|
return (m_charset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const htmlTextPart::embeddedObject& htmlTextPart::embeddedObjectsContainer::find(const string& id) const
|
void htmlTextPart::setCharset(const charset& ch)
|
||||||
{
|
{
|
||||||
for (std::vector <embeddedObject*>::const_iterator o = m_list.begin() ; o != m_list.end() ; ++o)
|
m_charset = ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const contentHandler& htmlTextPart::getPlainText() const
|
||||||
|
{
|
||||||
|
return (m_plainText);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void htmlTextPart::setPlainText(const contentHandler& plainText)
|
||||||
|
{
|
||||||
|
m_plainText = plainText;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const contentHandler& htmlTextPart::getText() const
|
||||||
|
{
|
||||||
|
return (m_text);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void htmlTextPart::setText(const contentHandler& text)
|
||||||
|
{
|
||||||
|
m_text = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const int htmlTextPart::getObjectCount() const
|
||||||
|
{
|
||||||
|
return (m_objects.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const htmlTextPart::embeddedObject* htmlTextPart::getObjectAt(const int pos) const
|
||||||
|
{
|
||||||
|
return (m_objects[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const htmlTextPart::embeddedObject* htmlTextPart::findObject(const string& id) const
|
||||||
|
{
|
||||||
|
for (std::vector <embeddedObject*>::const_iterator o = m_objects.begin() ;
|
||||||
|
o != m_objects.end() ; ++o)
|
||||||
{
|
{
|
||||||
if ((**o).id() == id)
|
if ((*o)->getId() == id)
|
||||||
return (**o);
|
return (*o);
|
||||||
}
|
}
|
||||||
|
|
||||||
throw exceptions::no_object_found();
|
throw exceptions::no_object_found();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const bool htmlTextPart::embeddedObjectsContainer::has(const string& id) const
|
const bool htmlTextPart::hasObject(const string& id) const
|
||||||
{
|
{
|
||||||
for (std::vector <embeddedObject*>::const_iterator o = m_list.begin() ; o != m_list.end() ; ++o)
|
for (std::vector <embeddedObject*>::const_iterator o = m_objects.begin() ;
|
||||||
|
o != m_objects.end() ; ++o)
|
||||||
{
|
{
|
||||||
if ((**o).id() == id)
|
if ((*o)->getId() == id)
|
||||||
return (true);
|
return (true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -342,29 +386,64 @@ const bool htmlTextPart::embeddedObjectsContainer::has(const string& id) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string htmlTextPart::embeddedObjectsContainer::add
|
const string htmlTextPart::addObject(const contentHandler& data,
|
||||||
(const contentHandler& data, const vmime::encoding& enc, const mediaType& type)
|
const vmime::encoding& enc, const mediaType& type)
|
||||||
{
|
{
|
||||||
const messageId mid(messageId::generateId());
|
const messageId mid(messageId::generateId());
|
||||||
const string id = "CID:" + mid.id();
|
const string id = "CID:" + mid.getId();
|
||||||
|
|
||||||
m_list.push_back(new embeddedObject(data, enc, id, type));
|
m_objects.push_back(new embeddedObject(data, enc, id, type));
|
||||||
|
|
||||||
return (id);
|
return (id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string htmlTextPart::embeddedObjectsContainer::add
|
const string htmlTextPart::addObject(const contentHandler& data, const mediaType& type)
|
||||||
(const contentHandler& data, const mediaType& type)
|
|
||||||
{
|
{
|
||||||
return (add(data, encoding::decide(data), type));
|
return (addObject(data, encoding::decide(data), type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string htmlTextPart::embeddedObjectsContainer::add
|
const string htmlTextPart::addObject(const string& data, const mediaType& type)
|
||||||
(const string& data, const mediaType& type)
|
|
||||||
{
|
{
|
||||||
return (add(contentHandler(data), encoding::decide(data), type));
|
return (addObject(contentHandler(data), encoding::decide(data), type));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// htmlTextPart::embeddedObject
|
||||||
|
//
|
||||||
|
|
||||||
|
htmlTextPart::embeddedObject::embeddedObject
|
||||||
|
(const contentHandler& data, const encoding& enc,
|
||||||
|
const string& id, const mediaType& type)
|
||||||
|
: m_data(data), m_encoding(enc), m_id(id), m_type(type)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const contentHandler& htmlTextPart::embeddedObject::getData() const
|
||||||
|
{
|
||||||
|
return (m_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const vmime::encoding& htmlTextPart::embeddedObject::getEncoding() const
|
||||||
|
{
|
||||||
|
return (m_encoding);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string& htmlTextPart::embeddedObject::getId() const
|
||||||
|
{
|
||||||
|
return (m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const mediaType& htmlTextPart::embeddedObject::getType() const
|
||||||
|
{
|
||||||
|
return (m_type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,6 +32,9 @@ namespace vmime
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/** Text part of type 'text/html'.
|
||||||
|
*/
|
||||||
|
|
||||||
class htmlTextPart : public textPart
|
class htmlTextPart : public textPart
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
@ -40,127 +43,128 @@ protected:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
const mediaType type() const;
|
const mediaType getType() const;
|
||||||
|
|
||||||
const vmime::charset& charset() const { return (m_charset); }
|
const charset& getCharset() const;
|
||||||
vmime::charset& charset() { return (m_charset); }
|
void setCharset(const charset& ch);
|
||||||
|
|
||||||
const contentHandler& plainText() const { return (m_plainText); }
|
const contentHandler& getPlainText() const;
|
||||||
contentHandler& plainText() { return (m_plainText); }
|
void setPlainText(const contentHandler& plainText);
|
||||||
|
|
||||||
const contentHandler& text() const { return (m_text); }
|
const contentHandler& getText() const;
|
||||||
contentHandler& text() { return (m_text); }
|
void setText(const contentHandler& text);
|
||||||
|
|
||||||
// Embedded object (eg. image for <IMG> tag)
|
/** Embedded object (eg: image for <IMG> tag).
|
||||||
|
*/
|
||||||
class embeddedObject
|
class embeddedObject
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
embeddedObject(const contentHandler& data, const vmime::encoding& enc,
|
embeddedObject(const contentHandler& data, const encoding& enc,
|
||||||
const string& id, const mediaType& type)
|
const string& id, const mediaType& type);
|
||||||
: m_data(data), m_encoding(enc), m_id(id), m_type(type)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
/** Return data stored in this embedded object.
|
||||||
|
*
|
||||||
|
* @return stored data
|
||||||
|
*/
|
||||||
|
const contentHandler& getData() const;
|
||||||
|
|
||||||
const contentHandler& data() const { return (m_data); }
|
/** Return the encoding used for data in this
|
||||||
const vmime::encoding& encoding() const { return (m_encoding); }
|
* embedded object.
|
||||||
const string& id() const { return (m_id); }
|
*
|
||||||
const mediaType& type() const { return (m_type); }
|
* @return data encoding
|
||||||
|
*/
|
||||||
|
const vmime::encoding& getEncoding() const;
|
||||||
|
|
||||||
|
/** Return the identifier of this embedded object.
|
||||||
|
*
|
||||||
|
* @return object identifier
|
||||||
|
*/
|
||||||
|
const string& getId() const;
|
||||||
|
|
||||||
|
/** Return the content type of data stored in
|
||||||
|
* this embedded object.
|
||||||
|
*
|
||||||
|
* @return data type
|
||||||
|
*/
|
||||||
|
const mediaType& getType() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
contentHandler m_data;
|
contentHandler m_data;
|
||||||
vmime::encoding m_encoding;
|
encoding m_encoding;
|
||||||
string m_id;
|
string m_id;
|
||||||
mediaType m_type;
|
mediaType m_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Embedded objects container
|
|
||||||
class embeddedObjectsContainer
|
|
||||||
{
|
|
||||||
friend class htmlTextPart;
|
|
||||||
|
|
||||||
protected:
|
/** Test the existence of an embedded object given its identifier.
|
||||||
|
*
|
||||||
|
* @param id object identifier
|
||||||
|
* @return true if an object with this identifier exists,
|
||||||
|
* false otherwise
|
||||||
|
*/
|
||||||
|
const bool hasObject(const string& id) const;
|
||||||
|
|
||||||
~embeddedObjectsContainer();
|
/** Return the embedded object with the specified identifier.
|
||||||
|
*
|
||||||
|
* @throw exceptions::no_object_found() if no object has been found
|
||||||
|
* @param id object identifier
|
||||||
|
* @return embedded object with the specified identifier
|
||||||
|
*/
|
||||||
|
const embeddedObject* findObject(const string& id) const;
|
||||||
|
|
||||||
public:
|
/** Return the number of embedded objects.
|
||||||
|
*
|
||||||
|
* @return number of embedded objects
|
||||||
|
*/
|
||||||
|
const int getObjectCount() const;
|
||||||
|
|
||||||
// Test the existence/get an embedded object given its identifier.
|
/** Return the embedded object at the specified position.
|
||||||
const bool has(const string& id) const;
|
*
|
||||||
const embeddedObject& find(const string& id) const;
|
* @param pos position of the embedded object
|
||||||
|
* @return embedded object at position 'pos'
|
||||||
|
*/
|
||||||
|
const embeddedObject* getObjectAt(const int pos) const;
|
||||||
|
|
||||||
// Embed an object and returns a string which identifies it.
|
/** Embed an object and returns a string which identifies it.
|
||||||
const string add(const string& data, const mediaType& type);
|
*
|
||||||
const string add(const contentHandler& data, const mediaType& type);
|
* \deprecated Use the addObject() methods which take a 'contentHandler'
|
||||||
const string add(const contentHandler& data, const encoding& enc, const mediaType& type);
|
* parameter type instead.
|
||||||
|
*
|
||||||
|
* @param data object data
|
||||||
|
* @param type data type
|
||||||
|
* @return an unique object identifier used to identify the new
|
||||||
|
* object among all other embedded objects
|
||||||
|
*/
|
||||||
|
const string addObject(const string& data, const mediaType& type);
|
||||||
|
|
||||||
// Embedded objects enumerator
|
/** Embed an object and returns a string which identifies it.
|
||||||
class const_iterator
|
*
|
||||||
{
|
* @param data object data
|
||||||
public:
|
* @param type data type
|
||||||
|
* @return an unique object identifier used to identify the new
|
||||||
|
* object among all other embedded objects
|
||||||
|
*/
|
||||||
|
const string addObject(const contentHandler& data, const mediaType& type);
|
||||||
|
|
||||||
typedef std::vector <embeddedObject*>::const_iterator::difference_type difference_type;
|
/** Embed an object and returns a string which identifies it.
|
||||||
|
*
|
||||||
|
* @param data object data
|
||||||
|
* @param enc data encoding
|
||||||
|
* @param type data type
|
||||||
|
* @return an unique object identifier used to identify the new
|
||||||
|
* object among all other embedded objects
|
||||||
|
*/
|
||||||
|
const string addObject(const contentHandler& data, const encoding& enc, const mediaType& type);
|
||||||
|
|
||||||
const_iterator(std::vector <embeddedObject*>::const_iterator it) : m_iterator(it) { }
|
private:
|
||||||
const_iterator(const const_iterator& it) : m_iterator(it.m_iterator) { }
|
|
||||||
|
|
||||||
const_iterator& operator=(const const_iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
|
||||||
|
|
||||||
const embeddedObject& operator*() const { return (**m_iterator); }
|
|
||||||
const embeddedObject* operator->() const { return (*m_iterator); }
|
|
||||||
|
|
||||||
const_iterator& operator++() { ++m_iterator; return (*this); }
|
|
||||||
const_iterator operator++(int) { const_iterator i(*this); ++m_iterator; return (i); }
|
|
||||||
|
|
||||||
const_iterator& operator--() { --m_iterator; return (*this); }
|
|
||||||
const_iterator operator--(int) { const_iterator i(*this); --m_iterator; return (i); }
|
|
||||||
|
|
||||||
const_iterator& operator+=(difference_type n) { m_iterator += n; return (*this); }
|
|
||||||
const_iterator& operator-=(difference_type n) { m_iterator -= n; return (*this); }
|
|
||||||
|
|
||||||
const_iterator operator-(difference_type x) const { return const_iterator(m_iterator - x); }
|
|
||||||
|
|
||||||
const embeddedObject& operator[](difference_type n) const { return *(m_iterator[n]); }
|
|
||||||
|
|
||||||
const bool operator==(const const_iterator& it) const { return (it.m_iterator == m_iterator); }
|
|
||||||
const bool operator!=(const const_iterator& it) const { return (!(*this == it)); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
std::vector <embeddedObject*>::const_iterator m_iterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
const_iterator begin() const { return (const_iterator(m_list.begin())); }
|
|
||||||
const_iterator end() const { return (const_iterator(m_list.end())); }
|
|
||||||
|
|
||||||
// Object count
|
|
||||||
const std::vector <embeddedObject*>::size_type count() const { return (m_list.size()); }
|
|
||||||
const std::vector <embeddedObject*>::size_type size() const { return (m_list.size()); }
|
|
||||||
const bool empty() const { return (m_list.empty()); }
|
|
||||||
|
|
||||||
embeddedObject& front() { return (*m_list.front()); }
|
|
||||||
const embeddedObject& front() const { return (*m_list.front()); }
|
|
||||||
embeddedObject& back() { return (*m_list.back()); }
|
|
||||||
const embeddedObject& back() const { return (*m_list.back()); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
std::vector <embeddedObject*> m_list;
|
|
||||||
|
|
||||||
} embeddedObjects;
|
|
||||||
|
|
||||||
typedef embeddedObjectsContainer::const_iterator const_iterator;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
contentHandler m_plainText;
|
contentHandler m_plainText;
|
||||||
contentHandler m_text;
|
contentHandler m_text;
|
||||||
vmime::charset m_charset;
|
charset m_charset;
|
||||||
|
|
||||||
|
std::vector <embeddedObject*> m_objects;
|
||||||
|
|
||||||
void findEmbeddedParts(const bodyPart& part, std::vector <const bodyPart*>& cidParts, std::vector <const bodyPart*>& locParts);
|
void findEmbeddedParts(const bodyPart& part, std::vector <const bodyPart*>& cidParts, std::vector <const bodyPart*>& locParts);
|
||||||
void addEmbeddedObject(const bodyPart& part, const string& id);
|
void addEmbeddedObject(const bodyPart& part, const string& id);
|
||||||
@ -170,7 +174,7 @@ protected:
|
|||||||
const int getPartCount() const;
|
const int getPartCount() const;
|
||||||
|
|
||||||
void generateIn(bodyPart& message, bodyPart& parent) const;
|
void generateIn(bodyPart& message, bodyPart& parent) const;
|
||||||
virtual void parse(const bodyPart& message, const bodyPart& parent, const bodyPart& textPart);
|
void parse(const bodyPart& message, const bodyPart& parent, const bodyPart& textPart);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -30,8 +30,8 @@ mailbox::mailbox()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mailbox::mailbox(const class mailbox& mailbox)
|
mailbox::mailbox(const mailbox& mbox)
|
||||||
: address(), m_name(mailbox.m_name), m_email(mailbox.m_email)
|
: address(), m_name(mbox.m_name), m_email(mbox.m_email)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -305,7 +305,7 @@ void mailbox::parse(const string& buffer, const string::size_type position,
|
|||||||
if (address.empty() && !name.empty())
|
if (address.empty() && !name.empty())
|
||||||
{
|
{
|
||||||
m_email = name;
|
m_email = name;
|
||||||
m_name.clear();
|
m_name.removeAllWords();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -321,7 +321,7 @@ void mailbox::parse(const string& buffer, const string::size_type position,
|
|||||||
void mailbox::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void mailbox::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
if (m_name.empty())
|
if (m_name.isEmpty())
|
||||||
{
|
{
|
||||||
bool newLine = false;
|
bool newLine = false;
|
||||||
|
|
||||||
@ -352,11 +352,11 @@ void mailbox::generate(utility::outputStream& os, const string::size_type maxLin
|
|||||||
// and/or contain the special chars.
|
// and/or contain the special chars.
|
||||||
bool forceEncode = false;
|
bool forceEncode = false;
|
||||||
|
|
||||||
for (text::const_iterator w = m_name.begin() ; !forceEncode && w != m_name.end() ; ++w)
|
for (int w = 0 ; !forceEncode && w != m_name.getWordCount() ; ++w)
|
||||||
{
|
{
|
||||||
if ((*w).charset() == charset(charsets::US_ASCII))
|
if (m_name.getWordAt(w)->getCharset() == charset(charsets::US_ASCII))
|
||||||
{
|
{
|
||||||
const string& buffer = (*w).buffer();
|
const string& buffer = m_name.getWordAt(w)->getBuffer();
|
||||||
|
|
||||||
for (string::const_iterator c = buffer.begin() ;
|
for (string::const_iterator c = buffer.begin() ;
|
||||||
!forceEncode && c != buffer.end() ; ++c)
|
!forceEncode && c != buffer.end() ; ++c)
|
||||||
@ -423,22 +423,29 @@ const bool mailbox::operator!=(const class mailbox& mailbox) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mailbox::copyFrom(const address& addr)
|
void mailbox::copyFrom(const component& other)
|
||||||
{
|
{
|
||||||
const mailbox& source = dynamic_cast<const mailbox&>(addr);
|
const mailbox& source = dynamic_cast <const mailbox&>(other);
|
||||||
|
|
||||||
m_name = source.m_name;
|
m_name = source.m_name;
|
||||||
m_email = source.m_email;
|
m_email = source.m_email;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
address* mailbox::clone() const
|
mailbox& mailbox::operator=(const mailbox& other)
|
||||||
|
{
|
||||||
|
copyFrom(other);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mailbox* mailbox::clone() const
|
||||||
{
|
{
|
||||||
return new mailbox(*this);
|
return new mailbox(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const bool mailbox::empty() const
|
const bool mailbox::isEmpty() const
|
||||||
{
|
{
|
||||||
return (m_email.empty());
|
return (m_email.empty());
|
||||||
}
|
}
|
||||||
@ -446,7 +453,7 @@ const bool mailbox::empty() const
|
|||||||
|
|
||||||
void mailbox::clear()
|
void mailbox::clear()
|
||||||
{
|
{
|
||||||
m_name.clear();
|
m_name.removeAllWords();
|
||||||
m_email.clear();
|
m_email.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -457,4 +464,28 @@ const bool mailbox::isGroup() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const text& mailbox::getName() const
|
||||||
|
{
|
||||||
|
return (m_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailbox::setName(const text& name)
|
||||||
|
{
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string& mailbox::getEmail() const
|
||||||
|
{
|
||||||
|
return (m_email);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailbox::setEmail(const string& email)
|
||||||
|
{
|
||||||
|
m_email = email;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -40,7 +40,7 @@ class mailbox : public address
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
mailbox();
|
mailbox();
|
||||||
mailbox(const class mailbox& mailbox);
|
mailbox(const mailbox& mbox);
|
||||||
mailbox(const string& email);
|
mailbox(const string& email);
|
||||||
mailbox(const text& name, const string& email);
|
mailbox(const text& name, const string& email);
|
||||||
|
|
||||||
@ -48,35 +48,36 @@ public:
|
|||||||
*
|
*
|
||||||
* @return full name of the mailbox
|
* @return full name of the mailbox
|
||||||
*/
|
*/
|
||||||
const text& name() const { return (m_name); }
|
const text& getName() const;
|
||||||
|
|
||||||
/** Return the full name of the mailbox (empty if not specified).
|
/** Set the full name of the mailbox.
|
||||||
*
|
*
|
||||||
* @return full name of the mailbox
|
* @return full name of the mailbox
|
||||||
*/
|
*/
|
||||||
text& name() { return (m_name); }
|
void setName(const text& name);
|
||||||
|
|
||||||
/** Return the email of the mailbox.
|
/** Return the email of the mailbox.
|
||||||
*
|
*
|
||||||
* @return email of the mailbox
|
* @return email of the mailbox
|
||||||
*/
|
*/
|
||||||
const string& email() const { return (m_email); }
|
const string& getEmail() const;
|
||||||
|
|
||||||
/** Return the email of the mailbox.
|
/** Set the email of the mailbox.
|
||||||
*
|
*
|
||||||
* @return email of the mailbox
|
* @return email of the mailbox
|
||||||
*/
|
*/
|
||||||
string& email() { return (m_email); }
|
void setEmail(const string& email);
|
||||||
|
|
||||||
// Comparison
|
// Comparison
|
||||||
const bool operator==(const class mailbox& mailbox) const;
|
const bool operator==(const class mailbox& mailbox) const;
|
||||||
const bool operator!=(const class mailbox& mailbox) const;
|
const bool operator!=(const class mailbox& mailbox) const;
|
||||||
|
|
||||||
// Assignment
|
// Assignment
|
||||||
void copyFrom(const address& addr);
|
void copyFrom(const component& other);
|
||||||
address* clone() const;
|
mailbox* clone() const;
|
||||||
|
mailbox& operator=(const mailbox& other);
|
||||||
|
|
||||||
const bool empty() const;
|
const bool isEmpty() const;
|
||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
|
@ -30,10 +30,16 @@ mailboxField::mailboxField()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mailboxField::mailboxField(const mailboxField&)
|
||||||
|
: headerField(), genericField <mailbox>()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void mailboxField::parse(const string& buffer, const string::size_type position,
|
void mailboxField::parse(const string& buffer, const string::size_type position,
|
||||||
const string::size_type end, string::size_type* newPosition)
|
const string::size_type end, string::size_type* newPosition)
|
||||||
{
|
{
|
||||||
m_mailbox.clear();
|
getValue().clear();
|
||||||
|
|
||||||
// Here, we cannot simply call "m_mailbox.parse()" because it
|
// Here, we cannot simply call "m_mailbox.parse()" because it
|
||||||
// may have more than one address specified (even if this field
|
// may have more than one address specified (even if this field
|
||||||
@ -48,13 +54,13 @@ void mailboxField::parse(const string& buffer, const string::size_type position,
|
|||||||
// mailbox of the group
|
// mailbox of the group
|
||||||
mailboxGroup* group = static_cast <mailboxGroup*>(parsedAddress);
|
mailboxGroup* group = static_cast <mailboxGroup*>(parsedAddress);
|
||||||
|
|
||||||
if (!group->empty())
|
if (!group->isEmpty())
|
||||||
m_mailbox = *(group->begin());
|
getValue() = *(group->getMailboxAt(0));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Parse only if it is a mailbox
|
// Parse only if it is a mailbox
|
||||||
m_mailbox = *static_cast <mailbox*>(parsedAddress);
|
getValue() = *static_cast <mailbox*>(parsedAddress);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -65,31 +71,4 @@ void mailboxField::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mailboxField::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
||||||
{
|
|
||||||
string::size_type pos = curLinePos;
|
|
||||||
|
|
||||||
headerField::generate(os, maxLineLength, pos, &pos);
|
|
||||||
|
|
||||||
m_mailbox.generate(os, maxLineLength, pos, newLinePos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
mailboxField& mailboxField::operator=(const class mailbox& mailbox)
|
|
||||||
{
|
|
||||||
m_mailbox = mailbox;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void mailboxField::copyFrom(const headerField& field)
|
|
||||||
{
|
|
||||||
const mailboxField& source = dynamic_cast<const mailboxField&>(field);
|
|
||||||
m_mailbox = source.m_mailbox;
|
|
||||||
|
|
||||||
headerField::copyFrom(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -21,10 +21,7 @@
|
|||||||
#define VMIME_MAILBOXFIELD_HPP_INCLUDED
|
#define VMIME_MAILBOXFIELD_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
#include "base.hpp"
|
#include "genericField.hpp"
|
||||||
#include "component.hpp"
|
|
||||||
|
|
||||||
#include "headerFieldFactory.hpp"
|
|
||||||
#include "mailbox.hpp"
|
#include "mailbox.hpp"
|
||||||
|
|
||||||
|
|
||||||
@ -32,35 +29,18 @@ namespace vmime
|
|||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
class mailboxField : public headerField
|
class mailboxField : public genericField <mailbox>
|
||||||
{
|
{
|
||||||
friend class headerFieldFactory::registerer <mailboxField>;
|
friend class headerFieldFactory::registerer <mailboxField>;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
mailboxField();
|
mailboxField();
|
||||||
|
mailboxField(const mailboxField&);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void copyFrom(const headerField& field);
|
|
||||||
|
|
||||||
mailboxField& operator=(const class mailbox& mailbox);
|
|
||||||
|
|
||||||
const mailbox& value() const { return (m_mailbox); }
|
|
||||||
mailbox& value() { return (m_mailbox); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
mailbox m_mailbox;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
using headerField::parse;
|
|
||||||
using headerField::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -19,6 +19,7 @@
|
|||||||
|
|
||||||
#include "mailboxGroup.hpp"
|
#include "mailboxGroup.hpp"
|
||||||
#include "parserHelpers.hpp"
|
#include "parserHelpers.hpp"
|
||||||
|
#include "exception.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
@ -30,10 +31,10 @@ mailboxGroup::mailboxGroup()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mailboxGroup::mailboxGroup(const class mailboxGroup& mailboxGroup)
|
mailboxGroup::mailboxGroup(const mailboxGroup& mboxGroup)
|
||||||
: address()
|
: address()
|
||||||
{
|
{
|
||||||
copyFrom(mailboxGroup);
|
copyFrom(mboxGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -45,7 +46,7 @@ mailboxGroup::mailboxGroup(const text& name)
|
|||||||
|
|
||||||
mailboxGroup::~mailboxGroup()
|
mailboxGroup::~mailboxGroup()
|
||||||
{
|
{
|
||||||
clear();
|
removeAllMailboxes();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -85,10 +86,9 @@ void mailboxGroup::parse(const string& buffer, const string::size_type position,
|
|||||||
|
|
||||||
// Sub-groups are not allowed in mailbox groups: so, we add all
|
// Sub-groups are not allowed in mailbox groups: so, we add all
|
||||||
// the contents of the sub-group into this group...
|
// the contents of the sub-group into this group...
|
||||||
for (mailboxGroup::const_iterator
|
for (int i = 0 ; i < group->getMailboxCount() ; ++i)
|
||||||
it = group->begin() ; it != group->end() ; ++it)
|
|
||||||
{
|
{
|
||||||
m_list.push_back(static_cast <mailbox*>((*it).clone()));
|
m_list.push_back(group->getMailboxAt(i)->clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
delete (parsedAddress);
|
delete (parsedAddress);
|
||||||
@ -119,11 +119,11 @@ void mailboxGroup::generate(utility::outputStream& os, const string::size_type m
|
|||||||
// and/or contain the special chars.
|
// and/or contain the special chars.
|
||||||
bool forceEncode = false;
|
bool forceEncode = false;
|
||||||
|
|
||||||
for (text::const_iterator w = m_name.begin() ; !forceEncode && w != m_name.end() ; ++w)
|
for (int w = 0 ; !forceEncode && w < m_name.getWordCount() ; ++w)
|
||||||
{
|
{
|
||||||
if ((*w).charset() == charset(charsets::US_ASCII))
|
if (m_name.getWordAt(w)->getCharset() == charset(charsets::US_ASCII))
|
||||||
{
|
{
|
||||||
const string& buffer = (*w).buffer();
|
const string& buffer = m_name.getWordAt(w)->getBuffer();
|
||||||
|
|
||||||
for (string::const_iterator c = buffer.begin() ;
|
for (string::const_iterator c = buffer.begin() ;
|
||||||
!forceEncode && c != buffer.end() ; ++c)
|
!forceEncode && c != buffer.end() ; ++c)
|
||||||
@ -158,7 +158,8 @@ void mailboxGroup::generate(utility::outputStream& os, const string::size_type m
|
|||||||
os << ":";
|
os << ":";
|
||||||
++pos;
|
++pos;
|
||||||
|
|
||||||
for (const_iterator it = m_list.begin() ; it != m_list.end() ; ++it)
|
for (std::vector <mailbox*>::const_iterator it = m_list.begin() ;
|
||||||
|
it != m_list.end() ; ++it)
|
||||||
{
|
{
|
||||||
if (it != m_list.begin())
|
if (it != m_list.begin())
|
||||||
{
|
{
|
||||||
@ -171,7 +172,7 @@ void mailboxGroup::generate(utility::outputStream& os, const string::size_type m
|
|||||||
++pos;
|
++pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*it).generate(os, maxLineLength - 2, pos, &pos);
|
(*it)->generate(os, maxLineLength - 2, pos, &pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
os << ";";
|
os << ";";
|
||||||
@ -182,49 +183,44 @@ void mailboxGroup::generate(utility::outputStream& os, const string::size_type m
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
address* mailboxGroup::clone() const
|
void mailboxGroup::copyFrom(const component& other)
|
||||||
|
{
|
||||||
|
const mailboxGroup& source = dynamic_cast <const mailboxGroup&>(other);
|
||||||
|
|
||||||
|
m_name = source.m_name;
|
||||||
|
|
||||||
|
removeAllMailboxes();
|
||||||
|
|
||||||
|
for (std::vector <mailbox*>::const_iterator it = source.m_list.begin() ;
|
||||||
|
it != source.m_list.end() ; ++it)
|
||||||
|
{
|
||||||
|
m_list.push_back((*it)->clone());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mailboxGroup* mailboxGroup::clone() const
|
||||||
{
|
{
|
||||||
return new mailboxGroup(*this);
|
return new mailboxGroup(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Mailbox insertion
|
mailboxGroup& mailboxGroup::operator=(const component& other)
|
||||||
void mailboxGroup::append(const mailbox& field)
|
|
||||||
{
|
{
|
||||||
m_list.push_back(static_cast<mailbox*>(field.clone()));
|
copyFrom(other);
|
||||||
|
return (*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mailboxGroup::insert(const iterator it, const mailbox& field)
|
const text& mailboxGroup::getName() const
|
||||||
{
|
{
|
||||||
m_list.insert(it.m_iterator, static_cast<mailbox*>(field.clone()));
|
return (m_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// Mailbox removing
|
void mailboxGroup::setName(const text& name)
|
||||||
void mailboxGroup::erase(const iterator it)
|
|
||||||
{
|
{
|
||||||
delete (*it.m_iterator);
|
m_name = name;
|
||||||
m_list.erase(it.m_iterator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void mailboxGroup::clear()
|
|
||||||
{
|
|
||||||
free_container(m_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void mailboxGroup::copyFrom(const address& addr)
|
|
||||||
{
|
|
||||||
const mailboxGroup& source = dynamic_cast<const mailboxGroup&>(addr);
|
|
||||||
|
|
||||||
m_name = source.m_name;
|
|
||||||
|
|
||||||
clear();
|
|
||||||
|
|
||||||
for (std::vector <mailbox*>::const_iterator i = source.m_list.begin() ; i != source.m_list.end() ; ++i)
|
|
||||||
m_list.push_back(static_cast<mailbox*>((*i)->clone()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -234,4 +230,122 @@ const bool mailboxGroup::isGroup() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const bool mailboxGroup::isEmpty() const
|
||||||
|
{
|
||||||
|
return (m_list.empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxGroup::appendMailbox(mailbox* mbox)
|
||||||
|
{
|
||||||
|
m_list.push_back(mbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxGroup::insertMailboxBefore(mailbox* beforeMailbox, mailbox* mbox)
|
||||||
|
{
|
||||||
|
const std::vector <mailbox*>::iterator it = std::find
|
||||||
|
(m_list.begin(), m_list.end(), beforeMailbox);
|
||||||
|
|
||||||
|
if (it == m_list.end())
|
||||||
|
throw exceptions::no_such_mailbox();
|
||||||
|
|
||||||
|
m_list.insert(it, mbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxGroup::insertMailboxBefore(const int pos, mailbox* mbox)
|
||||||
|
{
|
||||||
|
m_list.insert(m_list.begin() + pos, mbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxGroup::insertMailboxAfter(mailbox* afterMailbox, mailbox* mbox)
|
||||||
|
{
|
||||||
|
const std::vector <mailbox*>::iterator it = std::find
|
||||||
|
(m_list.begin(), m_list.end(), afterMailbox);
|
||||||
|
|
||||||
|
if (it == m_list.end())
|
||||||
|
throw exceptions::no_such_mailbox();
|
||||||
|
|
||||||
|
m_list.insert(it + 1, mbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxGroup::insertMailboxAfter(const int pos, mailbox* mbox)
|
||||||
|
{
|
||||||
|
m_list.insert(m_list.begin() + pos + 1, mbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxGroup::removeMailbox(mailbox* mbox)
|
||||||
|
{
|
||||||
|
const std::vector <mailbox*>::iterator it = std::find
|
||||||
|
(m_list.begin(), m_list.end(), mbox);
|
||||||
|
|
||||||
|
if (it == m_list.end())
|
||||||
|
throw exceptions::no_such_mailbox();
|
||||||
|
|
||||||
|
delete (*it);
|
||||||
|
|
||||||
|
m_list.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxGroup::removeMailbox(const int pos)
|
||||||
|
{
|
||||||
|
const std::vector <mailbox*>::iterator it = m_list.begin() + pos;
|
||||||
|
|
||||||
|
delete (*it);
|
||||||
|
|
||||||
|
m_list.erase(it);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxGroup::removeAllMailboxes()
|
||||||
|
{
|
||||||
|
free_container(m_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const int mailboxGroup::getMailboxCount() const
|
||||||
|
{
|
||||||
|
return (m_list.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mailbox* mailboxGroup::getMailboxAt(const int pos)
|
||||||
|
{
|
||||||
|
return (m_list[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const mailbox* const mailboxGroup::getMailboxAt(const int pos) const
|
||||||
|
{
|
||||||
|
return (m_list[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector <const mailbox*> mailboxGroup::getMailboxList() const
|
||||||
|
{
|
||||||
|
std::vector <const mailbox*> list;
|
||||||
|
|
||||||
|
list.reserve(m_list.size());
|
||||||
|
|
||||||
|
for (std::vector <mailbox*>::const_iterator it = m_list.begin() ;
|
||||||
|
it != m_list.end() ; ++it)
|
||||||
|
{
|
||||||
|
list.push_back(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector <mailbox*> mailboxGroup::getMailboxList()
|
||||||
|
{
|
||||||
|
return (m_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -38,102 +38,123 @@ class mailboxGroup : public address
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
mailboxGroup();
|
mailboxGroup();
|
||||||
mailboxGroup(const class mailboxGroup& mailboxGroup);
|
mailboxGroup(const mailboxGroup& mboxGroup);
|
||||||
mailboxGroup(const text& name);
|
mailboxGroup(const text& name);
|
||||||
|
|
||||||
~mailboxGroup();
|
~mailboxGroup();
|
||||||
|
|
||||||
// Properties set/get
|
|
||||||
const text& name() const { return (m_name); }
|
|
||||||
text& name() { return (m_name); }
|
|
||||||
|
|
||||||
// Assignment
|
void copyFrom(const component& other);
|
||||||
void copyFrom(const address& addr);
|
mailboxGroup* clone() const;
|
||||||
address* clone() const;
|
mailboxGroup& operator=(const component& other);
|
||||||
|
|
||||||
public:
|
/** Return the name of the group.
|
||||||
|
*
|
||||||
|
* @return group name
|
||||||
|
*/
|
||||||
|
const text& getName() const;
|
||||||
|
|
||||||
// Mailbox iterator
|
/** Set the name of the group.
|
||||||
class const_iterator;
|
*
|
||||||
|
* @param name group name
|
||||||
|
*/
|
||||||
|
void setName(const text& name);
|
||||||
|
|
||||||
class iterator
|
/** Add a mailbox at the end of the list.
|
||||||
{
|
*
|
||||||
friend class mailboxGroup;
|
* @param mbox mailbox to append
|
||||||
friend class const_iterator;
|
*/
|
||||||
|
void appendMailbox(mailbox* mbox);
|
||||||
|
|
||||||
public:
|
/** Insert a new mailbox before the specified mailbox.
|
||||||
|
*
|
||||||
|
* @param beforeMailbox mailbox before which the new mailbox will be inserted
|
||||||
|
* @param mbox mailbox to insert
|
||||||
|
* @throw exceptions::no_such_mailbox if the mailbox is not in the list
|
||||||
|
*/
|
||||||
|
void insertMailboxBefore(mailbox* beforeMailbox, mailbox* mbox);
|
||||||
|
|
||||||
iterator(std::vector <mailbox*>::iterator it) : m_iterator(it) { }
|
/** Insert a new mailbox before the specified position.
|
||||||
iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
*
|
||||||
|
* @param pos position at which to insert the new mailbox (0 to insert at
|
||||||
|
* the beginning of the list)
|
||||||
|
* @param mbox mailbox to insert
|
||||||
|
*/
|
||||||
|
void insertMailboxBefore(const int pos, mailbox* mbox);
|
||||||
|
|
||||||
iterator& operator=(const iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
/** Insert a new mailbox after the specified mailbox.
|
||||||
|
*
|
||||||
|
* @param afterMailbox mailbox after which the new mailbox will be inserted
|
||||||
|
* @param mbox mailbox to insert
|
||||||
|
* @throw exceptions::no_such_mailbox if the mailbox is not in the list
|
||||||
|
*/
|
||||||
|
void insertMailboxAfter(mailbox* afterMailbox, mailbox* mbox);
|
||||||
|
|
||||||
mailbox& operator*() const { return (**m_iterator); }
|
/** Insert a new mailbox after the specified position.
|
||||||
mailbox* operator->() const { return (*m_iterator); }
|
*
|
||||||
|
* @param pos position of the mailbox before the new mailbox
|
||||||
|
* @param mbox mailbox to insert
|
||||||
|
*/
|
||||||
|
void insertMailboxAfter(const int pos, mailbox* mbox);
|
||||||
|
|
||||||
iterator& operator++() { ++m_iterator; return (*this); }
|
/** Remove the specified mailbox from the list.
|
||||||
iterator& operator++(int) { ++m_iterator; return (*this); }
|
*
|
||||||
|
* @param mbox mailbox to remove
|
||||||
|
* @throw exceptions::no_such_mailbox if the mailbox is not in the list
|
||||||
|
*/
|
||||||
|
void removeMailbox(mailbox* mbox);
|
||||||
|
|
||||||
const bool operator==(const iterator& it) const { return (it.m_iterator == m_iterator); }
|
/** Remove the mailbox at the specified position.
|
||||||
const bool operator!=(const iterator& it) const { return (!(*this == it)); }
|
*
|
||||||
|
* @param pos position of the mailbox to remove
|
||||||
|
*/
|
||||||
|
void removeMailbox(const int pos);
|
||||||
|
|
||||||
private:
|
/** Remove all mailboxes from the list.
|
||||||
|
*/
|
||||||
|
void removeAllMailboxes();
|
||||||
|
|
||||||
std::vector <mailbox*>::iterator m_iterator;
|
/** Return the number of mailboxes in the list.
|
||||||
};
|
*
|
||||||
|
* @return number of mailboxes
|
||||||
|
*/
|
||||||
|
const int getMailboxCount() const;
|
||||||
|
|
||||||
class const_iterator
|
/** Tests whether the list of mailboxes is empty.
|
||||||
{
|
*
|
||||||
friend class mailboxGroup;
|
* @return true if there is no mailbox, false otherwise
|
||||||
|
*/
|
||||||
|
const bool isEmpty() const;
|
||||||
|
|
||||||
public:
|
/** Return the mailbox at the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position
|
||||||
|
* @return mailbox at position 'pos'
|
||||||
|
*/
|
||||||
|
mailbox* getMailboxAt(const int pos);
|
||||||
|
|
||||||
const_iterator(std::vector <mailbox*>::const_iterator it) : m_iterator(it) { }
|
/** Return the mailbox at the specified position.
|
||||||
const_iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
*
|
||||||
const_iterator(const const_iterator& it) : m_iterator(it.m_iterator) { }
|
* @param pos position
|
||||||
|
* @return mailbox at position 'pos'
|
||||||
|
*/
|
||||||
|
const mailbox* const getMailboxAt(const int pos) const;
|
||||||
|
|
||||||
const_iterator& operator=(const const_iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
/** Return the mailbox list.
|
||||||
const_iterator& operator=(const iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
*
|
||||||
|
* @return list of mailboxes
|
||||||
const mailbox& operator*() const { return (**m_iterator); }
|
*/
|
||||||
const mailbox* operator->() const { return (*m_iterator); }
|
const std::vector <const mailbox*> getMailboxList() const;
|
||||||
|
|
||||||
const_iterator& operator++() { ++m_iterator; return (*this); }
|
|
||||||
const_iterator& operator++(int) { ++m_iterator; return (*this); }
|
|
||||||
|
|
||||||
const bool operator==(const const_iterator& it) const { return (it.m_iterator == m_iterator); }
|
|
||||||
const bool operator!=(const const_iterator& it) const { return (!(*this == it)); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::vector <mailbox*>::const_iterator m_iterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
iterator begin() { return (m_list.begin()); }
|
|
||||||
iterator end() { return (m_list.end()); }
|
|
||||||
|
|
||||||
const_iterator begin() const { return (const_iterator(m_list.begin())); }
|
|
||||||
const_iterator end() const { return (const_iterator(m_list.end())); }
|
|
||||||
|
|
||||||
const std::vector <mailbox*>::size_type size() const { return (m_list.size()); }
|
|
||||||
const std::vector <mailbox*>::size_type count() const { return (m_list.size()); }
|
|
||||||
const bool empty() const { return (m_list.empty()); }
|
|
||||||
|
|
||||||
const mailbox& operator[](const std::vector <mailbox*>::size_type x) const { return (*m_list[x]); }
|
|
||||||
mailbox& operator[](const std::vector <mailbox*>::size_type x) { return (*m_list[x]); }
|
|
||||||
|
|
||||||
// Mailbox insertion
|
|
||||||
virtual void append(const mailbox& field);
|
|
||||||
virtual void insert(const iterator it, const mailbox& field);
|
|
||||||
|
|
||||||
// Mailbox removing
|
|
||||||
void erase(const iterator it);
|
|
||||||
void clear();
|
|
||||||
|
|
||||||
|
/** Return the mailbox list.
|
||||||
|
*
|
||||||
|
* @return list of mailboxes
|
||||||
|
*/
|
||||||
|
const std::vector <mailbox*> getMailboxList();
|
||||||
|
|
||||||
const bool isGroup() const;
|
const bool isGroup() const;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
text m_name;
|
text m_name;
|
||||||
std::vector <mailbox*> m_list;
|
std::vector <mailbox*> m_list;
|
||||||
|
@ -18,28 +18,150 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#include "mailboxList.hpp"
|
#include "mailboxList.hpp"
|
||||||
|
#include "exception.hpp"
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
// Address insertion
|
mailboxList::mailboxList()
|
||||||
void mailboxList::append(const address& addr)
|
|
||||||
{
|
{
|
||||||
// Ensure this is a "mailbox" object
|
|
||||||
const mailbox& mb = dynamic_cast<const mailbox&>(addr);
|
|
||||||
|
|
||||||
m_list.push_back(mb.clone());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void mailboxList::insert(const iterator it, const address& addr)
|
mailboxList::mailboxList(const mailboxList& mboxList)
|
||||||
|
: addressList(mboxList)
|
||||||
{
|
{
|
||||||
// Ensure this is a "mailbox" object
|
}
|
||||||
const mailbox& mb = dynamic_cast<const mailbox&>(addr);
|
|
||||||
|
|
||||||
m_list.insert(it.m_iterator, mb.clone());
|
|
||||||
|
void mailboxList::appendMailbox(mailbox* mbox)
|
||||||
|
{
|
||||||
|
addressList::appendAddress(mbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxList::insertMailboxBefore(mailbox* beforeMailbox, mailbox* mbox)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
addressList::insertAddressBefore(beforeMailbox, mbox);
|
||||||
|
}
|
||||||
|
catch (exceptions::no_such_address&)
|
||||||
|
{
|
||||||
|
throw exceptions::no_such_mailbox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxList::insertMailboxBefore(const int pos, mailbox* mbox)
|
||||||
|
{
|
||||||
|
addressList::insertAddressBefore(pos, mbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxList::insertMailboxAfter(mailbox* afterMailbox, mailbox* mbox)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
addressList::insertAddressAfter(afterMailbox, mbox);
|
||||||
|
}
|
||||||
|
catch (exceptions::no_such_address&)
|
||||||
|
{
|
||||||
|
throw exceptions::no_such_mailbox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxList::insertMailboxAfter(const int pos, mailbox* mbox)
|
||||||
|
{
|
||||||
|
addressList::insertAddressAfter(pos, mbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxList::removeMailbox(mailbox* mbox)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
addressList::removeAddress(mbox);
|
||||||
|
}
|
||||||
|
catch (exceptions::no_such_address&)
|
||||||
|
{
|
||||||
|
throw exceptions::no_such_mailbox();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxList::removeMailbox(const int pos)
|
||||||
|
{
|
||||||
|
addressList::removeAddress(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mailboxList::removeAllMailboxes()
|
||||||
|
{
|
||||||
|
addressList::removeAllAddresses();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const int mailboxList::getMailboxCount() const
|
||||||
|
{
|
||||||
|
return (addressList::getAddressCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const bool mailboxList::isEmpty() const
|
||||||
|
{
|
||||||
|
return (addressList::isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mailbox* mailboxList::getMailboxAt(const int pos)
|
||||||
|
{
|
||||||
|
return static_cast <mailbox*>(addressList::getAddressAt(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const mailbox* const mailboxList::getMailboxAt(const int pos) const
|
||||||
|
{
|
||||||
|
return static_cast <const mailbox*>(addressList::getAddressAt(pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector <const mailbox*> mailboxList::getMailboxList() const
|
||||||
|
{
|
||||||
|
const std::vector <const address*> addrList = addressList::getAddressList();
|
||||||
|
std::vector <const mailbox*> res;
|
||||||
|
|
||||||
|
for (std::vector <const address*>::const_iterator it = addrList.begin() ;
|
||||||
|
it != addrList.end() ; ++it)
|
||||||
|
{
|
||||||
|
const mailbox* mbox = dynamic_cast <const mailbox*>(*it);
|
||||||
|
|
||||||
|
if (mbox != NULL)
|
||||||
|
res.push_back(mbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector <mailbox*> mailboxList::getMailboxList()
|
||||||
|
{
|
||||||
|
const std::vector <address*> addrList = addressList::getAddressList();
|
||||||
|
std::vector <mailbox*> res;
|
||||||
|
|
||||||
|
for (std::vector <address*>::const_iterator it = addrList.begin() ;
|
||||||
|
it != addrList.end() ; ++it)
|
||||||
|
{
|
||||||
|
mailbox* mbox = dynamic_cast <mailbox*>(*it);
|
||||||
|
|
||||||
|
if (mbox != NULL)
|
||||||
|
res.push_back(mbox);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (res);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -32,92 +32,109 @@ namespace vmime
|
|||||||
/** A list of mailboxes (basic type).
|
/** A list of mailboxes (basic type).
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class mailboxList : public addressList
|
class mailboxList : protected addressList
|
||||||
{
|
{
|
||||||
friend class mailboxGroup;
|
friend class mailboxGroup;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
//
|
// This class works exactly like 'addressList' except it prevents user
|
||||||
// The following functions have the same name and work *exactly* like
|
// from inserting mailbox groups where it is not allowed by the RFC.
|
||||||
// the ones in "addressList", except we don't accept anything other
|
|
||||||
// than objects of type "mailbox" (instead of a generic "address").
|
|
||||||
//
|
|
||||||
// This prevents user from inserting mailbox groups where it is not
|
|
||||||
// allowed by the RFC.
|
|
||||||
//
|
|
||||||
|
|
||||||
// Address iterator
|
mailboxList();
|
||||||
class const_iterator;
|
mailboxList(const mailboxList& mboxList);
|
||||||
|
|
||||||
class iterator
|
/** Add a mailbox at the end of the list.
|
||||||
{
|
*
|
||||||
friend class mailboxList;
|
* @param mbox mailbox to append
|
||||||
friend class const_iterator;
|
*/
|
||||||
|
void appendMailbox(mailbox* mbox);
|
||||||
|
|
||||||
protected:
|
/** Insert a new mailbox before the specified mailbox.
|
||||||
|
*
|
||||||
|
* @param beforeMailbox mailbox before which the new mailbox will be inserted
|
||||||
|
* @param mbox mailbox to insert
|
||||||
|
* @throw exceptions::no_such_mailbox if the mailbox is not in the list
|
||||||
|
*/
|
||||||
|
void insertMailboxBefore(mailbox* beforeMailbox, mailbox* mbox);
|
||||||
|
|
||||||
iterator(std::vector <address*>::iterator it) : m_iterator(it) { }
|
/** Insert a new mailbox before the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position at which to insert the new mailbox (0 to insert at
|
||||||
|
* the beginning of the list)
|
||||||
|
* @param mbox mailbox to insert
|
||||||
|
*/
|
||||||
|
void insertMailboxBefore(const int pos, mailbox* mbox);
|
||||||
|
|
||||||
public:
|
/** Insert a new mailbox after the specified mailbox.
|
||||||
|
*
|
||||||
|
* @param afterMailbox mailbox after which the new mailbox will be inserted
|
||||||
|
* @param mbox mailbox to insert
|
||||||
|
* @throw exceptions::no_such_mailbox if the mailbox is not in the list
|
||||||
|
*/
|
||||||
|
void insertMailboxAfter(mailbox* afterMailbox, mailbox* mbox);
|
||||||
|
|
||||||
iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
/** Insert a new mailbox after the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position of the mailbox before the new mailbox
|
||||||
|
* @param mbox mailbox to insert
|
||||||
|
*/
|
||||||
|
void insertMailboxAfter(const int pos, mailbox* mbox);
|
||||||
|
|
||||||
iterator& operator=(const iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
/** Remove the specified mailbox from the list.
|
||||||
|
*
|
||||||
|
* @param mbox mailbox to remove
|
||||||
|
* @throw exceptions::no_such_mailbox if the mailbox is not in the list
|
||||||
|
*/
|
||||||
|
void removeMailbox(mailbox* mbox);
|
||||||
|
|
||||||
mailbox& operator*() const { return static_cast<mailbox&>(**m_iterator); }
|
/** Remove the mailbox at the specified position.
|
||||||
mailbox* operator->() const { return static_cast<mailbox*>(*m_iterator); }
|
*
|
||||||
|
* @param pos position of the mailbox to remove
|
||||||
|
*/
|
||||||
|
void removeMailbox(const int pos);
|
||||||
|
|
||||||
iterator& operator++() { ++m_iterator; return (*this); }
|
/** Remove all mailboxes from the list.
|
||||||
iterator& operator++(int) { ++m_iterator; return (*this); }
|
*/
|
||||||
|
void removeAllMailboxes();
|
||||||
|
|
||||||
const bool operator==(const iterator& it) const { return (it.m_iterator == m_iterator); }
|
/** Return the number of mailboxes in the list.
|
||||||
const bool operator!=(const iterator& it) const { return (!(*this == it)); }
|
*
|
||||||
|
* @return number of mailboxes
|
||||||
|
*/
|
||||||
|
const int getMailboxCount() const;
|
||||||
|
|
||||||
private:
|
/** Tests whether the list of mailboxes is empty.
|
||||||
|
*
|
||||||
|
* @return true if there is no mailbox, false otherwise
|
||||||
|
*/
|
||||||
|
const bool isEmpty() const;
|
||||||
|
|
||||||
std::vector <address*>::iterator m_iterator;
|
/** Return the mailbox at the specified position.
|
||||||
};
|
*
|
||||||
|
* @param pos position
|
||||||
|
* @return mailbox at position 'pos'
|
||||||
|
*/
|
||||||
|
mailbox* getMailboxAt(const int pos);
|
||||||
|
|
||||||
class const_iterator
|
/** Return the mailbox at the specified position.
|
||||||
{
|
*
|
||||||
friend class mailboxList;
|
* @param pos position
|
||||||
|
* @return mailbox at position 'pos'
|
||||||
|
*/
|
||||||
|
const mailbox* const getMailboxAt(const int pos) const;
|
||||||
|
|
||||||
protected:
|
/** Return the mailbox list.
|
||||||
|
*
|
||||||
|
* @return list of mailboxes
|
||||||
|
*/
|
||||||
|
const std::vector <const mailbox*> getMailboxList() const;
|
||||||
|
|
||||||
const_iterator(std::vector <address*>::const_iterator it) : m_iterator(it) { }
|
/** Return the mailbox list.
|
||||||
|
*
|
||||||
public:
|
* @return list of mailboxes
|
||||||
|
*/
|
||||||
const_iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
const std::vector <mailbox*> getMailboxList();
|
||||||
const_iterator(const const_iterator& it) : m_iterator(it.m_iterator) { }
|
|
||||||
|
|
||||||
const_iterator& operator=(const const_iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
|
||||||
const_iterator& operator=(const iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
|
||||||
|
|
||||||
const mailbox& operator*() const { return static_cast<const mailbox&>(**m_iterator); }
|
|
||||||
const mailbox* operator->() const { return static_cast<const mailbox*>(*m_iterator); }
|
|
||||||
|
|
||||||
const_iterator& operator++() { ++m_iterator; return (*this); }
|
|
||||||
const_iterator& operator++(int) { ++m_iterator; return (*this); }
|
|
||||||
|
|
||||||
const bool operator==(const const_iterator& it) const { return (it.m_iterator == m_iterator); }
|
|
||||||
const bool operator!=(const const_iterator& it) const { return (!(*this == it)); }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
std::vector <address*>::const_iterator m_iterator;
|
|
||||||
};
|
|
||||||
|
|
||||||
iterator begin() { return (m_list.begin()); }
|
|
||||||
iterator end() { return (m_list.end()); }
|
|
||||||
|
|
||||||
const_iterator begin() const { return (const_iterator(m_list.begin())); }
|
|
||||||
const_iterator end() const { return (const_iterator(m_list.end())); }
|
|
||||||
|
|
||||||
// Address insertion
|
|
||||||
void append(const address& addr);
|
|
||||||
void insert(const iterator it, const address& addr);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -1,60 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "mailboxListField.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
mailboxListField::mailboxListField()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void mailboxListField::parse(const string& buffer, const string::size_type position,
|
|
||||||
const string::size_type end, string::size_type* newPosition)
|
|
||||||
{
|
|
||||||
m_list.parse(buffer, position, end, newPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void mailboxListField::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
||||||
{
|
|
||||||
string::size_type pos = curLinePos;
|
|
||||||
|
|
||||||
headerField::generate(os, maxLineLength, pos, &pos);
|
|
||||||
|
|
||||||
m_list.generate(os, maxLineLength, pos, newLinePos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void mailboxListField::copyFrom(const headerField& field)
|
|
||||||
{
|
|
||||||
const mailboxListField& source = dynamic_cast<const mailboxListField&>(field);
|
|
||||||
m_list = source.m_list;
|
|
||||||
|
|
||||||
headerField::copyFrom(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
||||||
|
|
@ -1,68 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef VMIME_MAILBOXLISTFIELD_HPP_INCLUDED
|
|
||||||
#define VMIME_MAILBOXLISTFIELD_HPP_INCLUDED
|
|
||||||
|
|
||||||
|
|
||||||
#include "base.hpp"
|
|
||||||
#include "component.hpp"
|
|
||||||
|
|
||||||
#include "headerFieldFactory.hpp"
|
|
||||||
#include "mailboxList.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class mailboxListField : public headerField
|
|
||||||
{
|
|
||||||
friend class headerFieldFactory::registerer <mailboxListField>;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
mailboxListField();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void copyFrom(const headerField& field);
|
|
||||||
|
|
||||||
const mailboxList& value() const { return (m_list); }
|
|
||||||
mailboxList& value() { return (m_list); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
mailboxList m_list;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
using headerField::parse;
|
|
||||||
using headerField::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
||||||
|
|
||||||
|
|
||||||
#endif // VMIME_MAILBOXLISTFIELD_HPP_INCLUDED
|
|
@ -38,8 +38,8 @@ mediaType::mediaType(const string& type)
|
|||||||
|
|
||||||
|
|
||||||
mediaType::mediaType(const string& type, const string& subType)
|
mediaType::mediaType(const string& type, const string& subType)
|
||||||
|
: m_type(stringUtils::toLower(type)), m_subType(stringUtils::toLower(subType))
|
||||||
{
|
{
|
||||||
set(type, subType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -55,8 +55,8 @@ void mediaType::parse(const string& buffer, const string::size_type position,
|
|||||||
|
|
||||||
while (p < pend && *p != '/') ++p;
|
while (p < pend && *p != '/') ++p;
|
||||||
|
|
||||||
m_type = toLower(string(buffer.begin() + typeStart,
|
m_type = stringUtils::toLower(string(buffer.begin() + typeStart,
|
||||||
buffer.begin() + position + (p - pstart)));
|
buffer.begin() + position + (p - pstart)));
|
||||||
|
|
||||||
if (p < pend)
|
if (p < pend)
|
||||||
{
|
{
|
||||||
@ -64,8 +64,8 @@ void mediaType::parse(const string& buffer, const string::size_type position,
|
|||||||
++p;
|
++p;
|
||||||
|
|
||||||
// Extract the sub-type
|
// Extract the sub-type
|
||||||
m_subType = toLower(string(buffer.begin() + position + (p - pstart),
|
m_subType = stringUtils::toLower(string(buffer.begin() + position + (p - pstart),
|
||||||
buffer.begin() + end));
|
buffer.begin() + end));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newPosition)
|
if (newPosition)
|
||||||
@ -76,7 +76,7 @@ void mediaType::parse(const string& buffer, const string::size_type position,
|
|||||||
void mediaType::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
void mediaType::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||||
{
|
{
|
||||||
const string value = toLower(m_type) + "/" + toLower(m_subType);
|
const string value = m_type + "/" + m_subType;
|
||||||
|
|
||||||
if (curLinePos + value.length() > maxLineLength)
|
if (curLinePos + value.length() > maxLineLength)
|
||||||
{
|
{
|
||||||
@ -108,15 +108,6 @@ const bool mediaType::operator!=(const mediaType& type) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
mediaType& mediaType::operator=(const mediaType& type)
|
|
||||||
{
|
|
||||||
m_type = type.m_type;
|
|
||||||
m_subType = type.m_subType;
|
|
||||||
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
mediaType& mediaType::operator=(const string& type)
|
mediaType& mediaType::operator=(const string& type)
|
||||||
{
|
{
|
||||||
parse(type);
|
parse(type);
|
||||||
@ -124,4 +115,56 @@ mediaType& mediaType::operator=(const string& type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mediaType* mediaType::clone() const
|
||||||
|
{
|
||||||
|
return new mediaType(m_type, m_subType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mediaType::copyFrom(const component& other)
|
||||||
|
{
|
||||||
|
const mediaType& mt = dynamic_cast <const mediaType&>(other);
|
||||||
|
|
||||||
|
m_type = mt.m_type;
|
||||||
|
m_subType = mt.m_subType;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mediaType& mediaType::operator=(const mediaType& other)
|
||||||
|
{
|
||||||
|
copyFrom(other);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string& mediaType::getType() const
|
||||||
|
{
|
||||||
|
return (m_type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mediaType::setType(const string& type)
|
||||||
|
{
|
||||||
|
m_type = stringUtils::toLower(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string& mediaType::getSubType() const
|
||||||
|
{
|
||||||
|
return (m_subType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mediaType::setSubType(const string& subType)
|
||||||
|
{
|
||||||
|
m_subType = stringUtils::toLower(subType);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mediaType::setFromString(const string& type)
|
||||||
|
{
|
||||||
|
parse(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#define VMIME_MEDIATYPE_HPP_INCLUDED
|
#define VMIME_MEDIATYPE_HPP_INCLUDED
|
||||||
|
|
||||||
|
|
||||||
|
#include "base.hpp"
|
||||||
#include "component.hpp"
|
#include "component.hpp"
|
||||||
|
|
||||||
|
|
||||||
@ -44,17 +45,46 @@ public:
|
|||||||
const bool operator==(const mediaType& type) const;
|
const bool operator==(const mediaType& type) const;
|
||||||
const bool operator!=(const mediaType& type) const;
|
const bool operator!=(const mediaType& type) const;
|
||||||
|
|
||||||
mediaType& operator=(const mediaType& type);
|
|
||||||
mediaType& operator=(const string& type);
|
mediaType& operator=(const string& type);
|
||||||
|
|
||||||
const string& type() const { return (m_type); };
|
mediaType* clone() const;
|
||||||
string& type() { return (m_type); }
|
void copyFrom(const component& other);
|
||||||
|
mediaType& operator=(const mediaType& other);
|
||||||
|
|
||||||
const string& subType() const { return (m_subType); };
|
/** Return the media type.
|
||||||
string& subType() { return (m_subType); }
|
* See the constants in vmime::mediaTypes.
|
||||||
|
*
|
||||||
|
* @return media type
|
||||||
|
*/
|
||||||
|
const string& getType() const;
|
||||||
|
|
||||||
void set(const string& type) { parse(type); }
|
/** Set the media type.
|
||||||
void set(const string& type, const string& subType) { m_type = type; m_subType = subType; }
|
* See the constants in vmime::mediaTypes.
|
||||||
|
*
|
||||||
|
* @param type media type
|
||||||
|
*/
|
||||||
|
void setType(const string& type);
|
||||||
|
|
||||||
|
/** Return the media subtype.
|
||||||
|
* See the constants in vmime::mediaTypes.
|
||||||
|
*
|
||||||
|
* @return media subtype
|
||||||
|
*/
|
||||||
|
const string& getSubType() const;
|
||||||
|
|
||||||
|
/** Set the media subtype.
|
||||||
|
* See the constants in vmime::mediaTypes.
|
||||||
|
*
|
||||||
|
* @param subType media subtype
|
||||||
|
*/
|
||||||
|
void setSubType(const string& subType);
|
||||||
|
|
||||||
|
/** Set the media type and subtype from a string
|
||||||
|
* in the form "type/subtype" (eg: "image/jpeg").
|
||||||
|
*
|
||||||
|
* @param type media type and subtype
|
||||||
|
*/
|
||||||
|
void setFromString(const string& type);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
|
@ -48,28 +48,28 @@ message* messageBuilder::construct() const
|
|||||||
message* msg = new message;
|
message* msg = new message;
|
||||||
|
|
||||||
// Generate the header fields
|
// Generate the header fields
|
||||||
msg->header().fields.Subject() = m_subject;
|
msg->getHeader()->Subject().setValue(m_subject);
|
||||||
|
|
||||||
if (m_from.empty())
|
if (m_from.isEmpty())
|
||||||
throw exceptions::no_expeditor();
|
throw exceptions::no_expeditor();
|
||||||
|
|
||||||
if (m_to.empty() || (*m_to.begin()).empty())
|
if (m_to.isEmpty() || m_to.getAddressAt(0)->isEmpty())
|
||||||
throw exceptions::no_recipient();
|
throw exceptions::no_recipient();
|
||||||
|
|
||||||
msg->header().fields.From() = m_from;
|
msg->getHeader()->From().setValue(m_from);
|
||||||
msg->header().fields.To() = m_to;
|
msg->getHeader()->To().setValue(m_to);
|
||||||
|
|
||||||
if (!m_cc.empty())
|
if (!m_cc.isEmpty())
|
||||||
msg->header().fields.Cc() = m_cc;
|
msg->getHeader()->Cc().setValue(m_cc);
|
||||||
|
|
||||||
if (!m_bcc.empty())
|
if (!m_bcc.isEmpty())
|
||||||
msg->header().fields.Bcc() = m_bcc;
|
msg->getHeader()->Bcc().setValue(m_bcc);
|
||||||
|
|
||||||
// Add a "Date" field
|
// Add a "Date" field
|
||||||
msg->header().fields.Date() = datetime::now();
|
msg->getHeader()->Date().setValue(datetime::now());
|
||||||
|
|
||||||
// Add a "Mime-Version" header field
|
// Add a "Mime-Version" header field
|
||||||
msg->header().fields.MimeVersion().value() = MIME_VERSION;
|
msg->getHeader()->MimeVersion().setValue(string(MIME_VERSION));
|
||||||
|
|
||||||
// If there is one or more attachments (or other parts that are
|
// If there is one or more attachments (or other parts that are
|
||||||
// not "text/...") and if there is more than one parts for the
|
// not "text/...") and if there is more than one parts for the
|
||||||
@ -92,15 +92,15 @@ message* messageBuilder::construct() const
|
|||||||
if (!m_attach.empty() && m_textPart->getPartCount() > 1)
|
if (!m_attach.empty() && m_textPart->getPartCount() > 1)
|
||||||
{
|
{
|
||||||
// Set parent part (message) to "multipart/mixed"
|
// Set parent part (message) to "multipart/mixed"
|
||||||
msg->header().fields.ContentType() = mediaType
|
msg->getHeader()->ContentType().setValue
|
||||||
(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED);
|
(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED));
|
||||||
|
|
||||||
// Create a sub-part "multipart/alternative" for text parts
|
// Create a sub-part "multipart/alternative" for text parts
|
||||||
bodyPart* subPart = new bodyPart;
|
bodyPart* subPart = new bodyPart;
|
||||||
msg->body().parts.append(subPart);
|
msg->getBody()->appendPart(subPart);
|
||||||
|
|
||||||
subPart->header().fields.ContentType() = mediaType
|
subPart->getHeader()->ContentType().setValue
|
||||||
(mediaTypes::MULTIPART, mediaTypes::MULTIPART_ALTERNATIVE);
|
(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_ALTERNATIVE));
|
||||||
|
|
||||||
// Generate the text parts into this sub-part (normally, this
|
// Generate the text parts into this sub-part (normally, this
|
||||||
// sub-part will have the "multipart/alternative" content-type...)
|
// sub-part will have the "multipart/alternative" content-type...)
|
||||||
@ -114,21 +114,22 @@ message* messageBuilder::construct() const
|
|||||||
// If any attachment, set message content-type to "multipart/mixed"
|
// If any attachment, set message content-type to "multipart/mixed"
|
||||||
if (!m_attach.empty())
|
if (!m_attach.empty())
|
||||||
{
|
{
|
||||||
msg->header().fields.ContentType() = mediaType
|
msg->getHeader()->ContentType().setValue
|
||||||
(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED);
|
(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED));
|
||||||
}
|
}
|
||||||
// Else, set it to "multipart/alternative" if there are more than one text part.
|
// Else, set it to "multipart/alternative" if there are more than one text part.
|
||||||
else if (m_textPart->getPartCount() > 1)
|
else if (m_textPart->getPartCount() > 1)
|
||||||
{
|
{
|
||||||
msg->header().fields.ContentType() = mediaType
|
msg->getHeader()->ContentType().setValue
|
||||||
(mediaTypes::MULTIPART, mediaTypes::MULTIPART_ALTERNATIVE);
|
(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_ALTERNATIVE));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate the attachments
|
// Generate the attachments
|
||||||
if (!m_attach.empty())
|
if (!m_attach.empty())
|
||||||
{
|
{
|
||||||
for (std::vector <attachment*>::const_iterator a = m_attach.begin() ; a != m_attach.end() ; ++a)
|
for (std::vector <attachment*>::const_iterator a = m_attach.begin() ;
|
||||||
|
a != m_attach.end() ; ++a)
|
||||||
{
|
{
|
||||||
(*a)->generateIn(*msg);
|
(*a)->generateIn(*msg);
|
||||||
}
|
}
|
||||||
@ -136,19 +137,22 @@ message* messageBuilder::construct() const
|
|||||||
|
|
||||||
// If there is only one part in the message, move it into the message
|
// If there is only one part in the message, move it into the message
|
||||||
// (hence, the message will not be multipart...)
|
// (hence, the message will not be multipart...)
|
||||||
if (msg->body().parts.size() == 1)
|
if (msg->getBody()->getPartCount() == 1)
|
||||||
{
|
{
|
||||||
const bodyPart& part = msg->body().parts.front();
|
const bodyPart& part = *msg->getBody()->getPartAt(0);
|
||||||
|
|
||||||
// First, copy (and replace) the header fields
|
// First, copy (and replace) the header fields
|
||||||
const header::fieldsContainer& hdr = part.header().fields;
|
const std::vector <const headerField*> fields = part.getHeader()->getFieldList();
|
||||||
|
|
||||||
for (header::const_iterator f = hdr.begin() ; f != hdr.end() ; ++f)
|
for (std::vector <const headerField*>::const_iterator it = fields.begin() ;
|
||||||
msg->header().fields.get((*f).name()) = *f;
|
it != fields.end() ; ++it)
|
||||||
|
{
|
||||||
|
*(msg->getHeader()->getField((*it)->getName())) = **it;
|
||||||
|
}
|
||||||
|
|
||||||
// Second, copy the body contents and sub-parts (this also remove
|
// Second, copy the body contents and sub-parts (this also remove
|
||||||
// the body part we are copying...)
|
// the body part we are copying...)
|
||||||
msg->body() = part.body();
|
msg->getBody()->copyFrom(*part.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
return (msg);
|
return (msg);
|
||||||
@ -163,7 +167,7 @@ void messageBuilder::attach(attachment* attach)
|
|||||||
|
|
||||||
void messageBuilder::constructTextPart(const mediaType& type)
|
void messageBuilder::constructTextPart(const mediaType& type)
|
||||||
{
|
{
|
||||||
class textPart* part = NULL;
|
textPart* part = NULL;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -179,9 +183,117 @@ void messageBuilder::constructTextPart(const mediaType& type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class textPart& messageBuilder::textPart()
|
textPart* messageBuilder::getTextPart()
|
||||||
{
|
{
|
||||||
return (*m_textPart);
|
return (m_textPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const mailbox& messageBuilder::getExpeditor() const
|
||||||
|
{
|
||||||
|
return (m_from);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void messageBuilder::setExpeditor(const mailbox& expeditor)
|
||||||
|
{
|
||||||
|
m_from = expeditor;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const addressList& messageBuilder::getRecipients() const
|
||||||
|
{
|
||||||
|
return (m_to);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void messageBuilder::setRecipients(const addressList& recipients)
|
||||||
|
{
|
||||||
|
m_to = recipients;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const addressList& messageBuilder::getCopyRecipients() const
|
||||||
|
{
|
||||||
|
return (m_cc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void messageBuilder::setCopyRecipients(const addressList& cc)
|
||||||
|
{
|
||||||
|
m_cc = cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const addressList& messageBuilder::getBlindCopyRecipients() const
|
||||||
|
{
|
||||||
|
return (m_bcc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void messageBuilder::setBlindCopyRecipients(const addressList& bcc)
|
||||||
|
{
|
||||||
|
m_bcc = bcc;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const text& messageBuilder::getSubject() const
|
||||||
|
{
|
||||||
|
return (m_subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void messageBuilder::setSubject(const text& subject)
|
||||||
|
{
|
||||||
|
m_subject = subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void messageBuilder::removeAttachment(const int pos)
|
||||||
|
{
|
||||||
|
delete (m_attach[pos]);
|
||||||
|
|
||||||
|
m_attach.erase(m_attach.begin() + pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const attachment* messageBuilder::getAttachmentAt(const int pos) const
|
||||||
|
{
|
||||||
|
return (m_attach[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
attachment* messageBuilder::getAttachmentAt(const int pos)
|
||||||
|
{
|
||||||
|
return (m_attach[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const int messageBuilder::getAttachmentCount() const
|
||||||
|
{
|
||||||
|
return (m_attach.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector <const attachment*> messageBuilder::getAttachmentList() const
|
||||||
|
{
|
||||||
|
std::vector <const attachment*> res;
|
||||||
|
|
||||||
|
res.reserve(m_attach.size());
|
||||||
|
|
||||||
|
for (std::vector <attachment*>::const_iterator it = m_attach.begin() ;
|
||||||
|
it != m_attach.end() ; ++it)
|
||||||
|
{
|
||||||
|
res.push_back(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector <attachment*> messageBuilder::getAttachmentList()
|
||||||
|
{
|
||||||
|
return (m_attach);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,35 +49,130 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Expeditor and recipients
|
/** Return the expeditor of the message (From:).
|
||||||
const mailbox& expeditor() const { return (m_from); }
|
*
|
||||||
mailbox& expeditor() { return (m_from); }
|
* @return expeditor of the message
|
||||||
|
*/
|
||||||
|
const mailbox& getExpeditor() const;
|
||||||
|
|
||||||
const addressList& recipients() const { return (m_to); }
|
/** Set the expeditor of the message (From:).
|
||||||
addressList& recipients() { return (m_to); }
|
*
|
||||||
|
* @param expeditor expeditor of the message
|
||||||
|
*/
|
||||||
|
void setExpeditor(const mailbox& expeditor);
|
||||||
|
|
||||||
const addressList& copyRecipients() const { return (m_cc); }
|
/** Return the recipients of the message (To:).
|
||||||
addressList& copyRecipients() { return (m_cc); }
|
*
|
||||||
|
* return recipients of the message
|
||||||
|
*/
|
||||||
|
const addressList& getRecipients() const;
|
||||||
|
|
||||||
const addressList& blindCopyRecipients() const { return (m_bcc); }
|
/** Set the recipients of the message (To:).
|
||||||
addressList& blindCopyRecipients() { return (m_bcc); }
|
*
|
||||||
|
* @param recipients list of recipients
|
||||||
|
*/
|
||||||
|
void setRecipients(const addressList& recipients);
|
||||||
|
|
||||||
// Subject
|
/** Return the copy recipients of the message (Cc:).
|
||||||
const text& subject() const { return (m_subject); }
|
*
|
||||||
text& subject() { return (m_subject); }
|
* @return copy recipients of the message
|
||||||
|
*/
|
||||||
|
const addressList& getCopyRecipients() const;
|
||||||
|
|
||||||
// Attachements
|
/** Set the copy recipients of the message (Cc:).
|
||||||
|
*
|
||||||
|
* @param cc list of copy recipients
|
||||||
|
*/
|
||||||
|
void setCopyRecipients(const addressList& cc);
|
||||||
|
|
||||||
|
/** Return the blind-copy recipients of the message (Bcc:).
|
||||||
|
*
|
||||||
|
* @return blind-copy recipients of the message
|
||||||
|
*/
|
||||||
|
const addressList& getBlindCopyRecipients() const;
|
||||||
|
|
||||||
|
/** Set the blind-copy recipients of the message (Bcc:).
|
||||||
|
*
|
||||||
|
* @param bcc list of blind-copy recipients
|
||||||
|
*/
|
||||||
|
void setBlindCopyRecipients(const addressList& bcc);
|
||||||
|
|
||||||
|
/** Return the subject of the message.
|
||||||
|
*
|
||||||
|
* @return subject of the message
|
||||||
|
*/
|
||||||
|
const text& getSubject() const;
|
||||||
|
|
||||||
|
/** Set the subject of the message.
|
||||||
|
*
|
||||||
|
* @param subject message subject
|
||||||
|
*/
|
||||||
|
void setSubject(const text& subject);
|
||||||
|
|
||||||
|
/** Attach a new object to the message.
|
||||||
|
*
|
||||||
|
* @param attach new attachment
|
||||||
|
*/
|
||||||
void attach(attachment* attach);
|
void attach(attachment* attach);
|
||||||
const std::vector <attachment*>& attachments() const { return (m_attach); }
|
|
||||||
|
|
||||||
// Text parts
|
/** Remove the attachment at the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position of the attachment to remove
|
||||||
|
*/
|
||||||
|
void removeAttachment(const int pos);
|
||||||
|
|
||||||
|
/** Return the attachment at the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position of the attachment
|
||||||
|
* @return attachment at the specified position
|
||||||
|
*/
|
||||||
|
const attachment* getAttachmentAt(const int pos) const;
|
||||||
|
|
||||||
|
/** Return the attachment at the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position of the attachment
|
||||||
|
* @return attachment at the specified position
|
||||||
|
*/
|
||||||
|
attachment* getAttachmentAt(const int pos);
|
||||||
|
|
||||||
|
/** Return the number of attachments in the message.
|
||||||
|
*
|
||||||
|
* @return number of attachments
|
||||||
|
*/
|
||||||
|
const int getAttachmentCount() const;
|
||||||
|
|
||||||
|
/** Return the list of attachments.
|
||||||
|
*
|
||||||
|
* @return list of attachments
|
||||||
|
*/
|
||||||
|
const std::vector <const attachment*> getAttachmentList() const;
|
||||||
|
|
||||||
|
/** Return the list of attachments.
|
||||||
|
*
|
||||||
|
* @return list of attachments
|
||||||
|
*/
|
||||||
|
const std::vector <attachment*> getAttachmentList();
|
||||||
|
|
||||||
|
/** Change the type of the text part and construct a new part.
|
||||||
|
*
|
||||||
|
* @param type media type of the text part
|
||||||
|
*/
|
||||||
void constructTextPart(const mediaType& type);
|
void constructTextPart(const mediaType& type);
|
||||||
class textPart& textPart();
|
|
||||||
|
|
||||||
// Construction
|
/** Return the text part of the message.
|
||||||
|
*
|
||||||
|
* @return text part of the message
|
||||||
|
*/
|
||||||
|
textPart* getTextPart();
|
||||||
|
|
||||||
|
/** Construct a new message based on the information specified
|
||||||
|
* in this object.
|
||||||
|
*
|
||||||
|
* @return a new message
|
||||||
|
*/
|
||||||
message* construct() const;
|
message* construct() const;
|
||||||
|
|
||||||
protected:
|
private:
|
||||||
|
|
||||||
mailbox m_from;
|
mailbox m_from;
|
||||||
|
|
||||||
@ -87,7 +182,7 @@ protected:
|
|||||||
|
|
||||||
text m_subject;
|
text m_subject;
|
||||||
|
|
||||||
class textPart* m_textPart;
|
textPart* m_textPart;
|
||||||
|
|
||||||
std::vector <attachment*> m_attach;
|
std::vector <attachment*> m_attach;
|
||||||
};
|
};
|
||||||
|
@ -127,7 +127,7 @@ void messageId::parse(const string& buffer, const string::size_type position,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const string messageId::id() const
|
const string messageId::getId() const
|
||||||
{
|
{
|
||||||
return (m_left + '@' + m_right);
|
return (m_left + '@' + m_right);
|
||||||
}
|
}
|
||||||
@ -143,14 +143,6 @@ void messageId::generate(utility::outputStream& os, const string::size_type /* m
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
messageId& messageId::operator=(const messageId& source)
|
|
||||||
{
|
|
||||||
m_left = source.m_left;
|
|
||||||
m_right = source.m_right;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
messageId& messageId::operator=(const string& id)
|
messageId& messageId::operator=(const string& id)
|
||||||
{
|
{
|
||||||
parse(id);
|
parse(id);
|
||||||
@ -164,12 +156,12 @@ messageId messageId::generateId()
|
|||||||
|
|
||||||
left << "vmime";
|
left << "vmime";
|
||||||
left << '.';
|
left << '.';
|
||||||
left << std::hex << utility::random::time();
|
left << std::hex << utility::random::getTime();
|
||||||
left << '.';
|
left << '.';
|
||||||
left << std::hex << utility::random::process();
|
left << std::hex << utility::random::getProcess();
|
||||||
left << '.';
|
left << '.';
|
||||||
left << std::hex << utility::random::next();
|
left << std::hex << utility::random::getNext();
|
||||||
left << std::hex << utility::random::next();
|
left << std::hex << utility::random::getNext();
|
||||||
|
|
||||||
return (messageId(left.str(), platformDependant::getHandler()->getHostName()));
|
return (messageId(left.str(), platformDependant::getHandler()->getHostName()));
|
||||||
}
|
}
|
||||||
@ -181,4 +173,56 @@ const bool messageId::operator==(const messageId& mid) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const bool messageId::operator!=(const messageId& mid) const
|
||||||
|
{
|
||||||
|
return !(*this == mid);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
messageId* messageId::clone() const
|
||||||
|
{
|
||||||
|
return new messageId(*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void messageId::copyFrom(const component& other)
|
||||||
|
{
|
||||||
|
const messageId& mid = dynamic_cast <const messageId&>(other);
|
||||||
|
|
||||||
|
m_left = mid.m_left;
|
||||||
|
m_right = mid.m_right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
messageId& messageId::operator=(const messageId& other)
|
||||||
|
{
|
||||||
|
copyFrom(other);
|
||||||
|
return (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string& messageId::getLeft() const
|
||||||
|
{
|
||||||
|
return (m_left);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void messageId::setLeft(const string& left)
|
||||||
|
{
|
||||||
|
m_left = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const string& messageId::getRight() const
|
||||||
|
{
|
||||||
|
return (m_right);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void messageId::setRight(const string& right)
|
||||||
|
{
|
||||||
|
m_right = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -43,24 +43,55 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
const string& left() const { return (m_left); }
|
/** Return the left part of the message identifier.
|
||||||
string& left() { return (m_left); }
|
*
|
||||||
|
* @return left part of message identifier
|
||||||
|
*/
|
||||||
|
const string& getLeft() const;
|
||||||
|
|
||||||
const string& right() const { return (m_right); }
|
/** Set the left part of the message identifier.
|
||||||
string& right() { return (m_right); }
|
*
|
||||||
|
* @param left left part of message identifier
|
||||||
|
*/
|
||||||
|
void setLeft(const string& left);
|
||||||
|
|
||||||
|
/** Return the right part of the message identifier.
|
||||||
|
*
|
||||||
|
* @return right part of message identifier
|
||||||
|
*/
|
||||||
|
const string& getRight() const;
|
||||||
|
|
||||||
|
/** Set the right part of the message identifier.
|
||||||
|
*
|
||||||
|
* @param right right part of message identifier
|
||||||
|
*/
|
||||||
|
void setRight(const string& right);
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
messageId& operator=(const messageId& source);
|
|
||||||
messageId& operator=(const string& id);
|
messageId& operator=(const string& id);
|
||||||
|
|
||||||
const bool operator==(const messageId& mid) const;
|
const bool operator==(const messageId& mid) const;
|
||||||
|
const bool operator!=(const messageId& mid) const;
|
||||||
|
|
||||||
|
/** Generate a random message identifier.
|
||||||
|
*
|
||||||
|
* @return randomly created message identifier
|
||||||
|
*/
|
||||||
static messageId generateId();
|
static messageId generateId();
|
||||||
|
|
||||||
const string id() const;
|
/** Return the message identifier constructed by using
|
||||||
|
* the right part and the left part, separated by
|
||||||
|
* a '@' character.
|
||||||
|
*
|
||||||
|
* @return full message identifier
|
||||||
|
*/
|
||||||
|
const string getId() const;
|
||||||
|
|
||||||
protected:
|
messageId* clone() const;
|
||||||
|
void copyFrom(const component& other);
|
||||||
|
messageId& operator=(const messageId& other);
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
string m_left;
|
string m_left;
|
||||||
string m_right;
|
string m_right;
|
||||||
|
@ -1,66 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#include "messageIdField.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
messageIdField::messageIdField()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void messageIdField::parse(const string& buffer, const string::size_type position,
|
|
||||||
const string::size_type end, string::size_type* newPosition)
|
|
||||||
{
|
|
||||||
m_id.parse(buffer, position, end, newPosition);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void messageIdField::generate(utility::outputStream& os, const string::size_type maxLineLength,
|
|
||||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
|
||||||
{
|
|
||||||
string::size_type pos = curLinePos;
|
|
||||||
|
|
||||||
headerField::generate(os, maxLineLength, pos, &pos);
|
|
||||||
|
|
||||||
m_id.generate(os, maxLineLength, pos, newLinePos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
messageIdField& messageIdField::operator=(const messageId& mid)
|
|
||||||
{
|
|
||||||
m_id = mid;
|
|
||||||
return (*this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void messageIdField::copyFrom(const headerField& field)
|
|
||||||
{
|
|
||||||
const messageIdField& source = dynamic_cast<const messageIdField&>(field);
|
|
||||||
m_id = source.m_id;
|
|
||||||
|
|
||||||
headerField::copyFrom(field);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
@ -1,70 +0,0 @@
|
|||||||
//
|
|
||||||
// VMime library (http://vmime.sourceforge.net)
|
|
||||||
// Copyright (C) 2002-2004 Vincent Richard <vincent@vincent-richard.net>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of
|
|
||||||
// the License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful,
|
|
||||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef VMIME_MESSAGEIDFIELD_HPP_INCLUDED
|
|
||||||
#define VMIME_MESSAGEIDFIELD_HPP_INCLUDED
|
|
||||||
|
|
||||||
|
|
||||||
#include "base.hpp"
|
|
||||||
#include "component.hpp"
|
|
||||||
|
|
||||||
#include "headerFieldFactory.hpp"
|
|
||||||
#include "messageId.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
|
||||||
{
|
|
||||||
|
|
||||||
|
|
||||||
class messageIdField : public headerField
|
|
||||||
{
|
|
||||||
friend class headerFieldFactory::registerer <messageIdField>;
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
messageIdField();
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
void copyFrom(const headerField& field);
|
|
||||||
|
|
||||||
messageIdField& operator=(const messageId& mid);
|
|
||||||
|
|
||||||
const messageId& value() const { return (m_id); }
|
|
||||||
messageId& value() { return (m_id); }
|
|
||||||
|
|
||||||
protected:
|
|
||||||
|
|
||||||
messageId m_id;
|
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
using headerField::parse;
|
|
||||||
using headerField::generate;
|
|
||||||
|
|
||||||
// Component parsing & assembling
|
|
||||||
void parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition = NULL);
|
|
||||||
void generate(utility::outputStream& os, const string::size_type maxLineLength = lineLengthLimits::infinite, const string::size_type curLinePos = 0, string::size_type* newLinePos = NULL) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
|
||||||
|
|
||||||
|
|
||||||
#endif // VMIME_MESSAGEIDFIELD_HPP_INCLUDED
|
|
@ -22,8 +22,6 @@
|
|||||||
#include "defaultAttachment.hpp"
|
#include "defaultAttachment.hpp"
|
||||||
#include "textPartFactory.hpp"
|
#include "textPartFactory.hpp"
|
||||||
|
|
||||||
#include "relayField.hpp"
|
|
||||||
|
|
||||||
|
|
||||||
namespace vmime
|
namespace vmime
|
||||||
{
|
{
|
||||||
@ -60,28 +58,36 @@ messageParser::~messageParser()
|
|||||||
void messageParser::parse(const message& msg)
|
void messageParser::parse(const message& msg)
|
||||||
{
|
{
|
||||||
// Header fields (if field is present, copy its value, else do nothing)
|
// Header fields (if field is present, copy its value, else do nothing)
|
||||||
#define TRY_FIELD(x) try { x; } catch (exceptions::no_such_field) { }
|
#define TRY_FIELD(var, type, name) \
|
||||||
TRY_FIELD(m_from = dynamic_cast<mailboxField&>(msg.header().fields.find(headerField::From)).value());
|
try { var = dynamic_cast<type&>(*msg.getHeader()->findField(name)).getValue(); } \
|
||||||
|
catch (exceptions::no_such_field) { }
|
||||||
|
|
||||||
TRY_FIELD(m_to = dynamic_cast<addressListField&>(msg.header().fields.find(headerField::To)).value());
|
TRY_FIELD(m_from, mailboxField, fields::FROM);
|
||||||
TRY_FIELD(m_cc = dynamic_cast<addressListField&>(msg.header().fields.find(headerField::Cc)).value());
|
|
||||||
TRY_FIELD(m_bcc = dynamic_cast<addressListField&>(msg.header().fields.find(headerField::Bcc)).value());
|
TRY_FIELD(m_to, addressListField, fields::TO);
|
||||||
|
TRY_FIELD(m_cc, addressListField, fields::CC);
|
||||||
|
TRY_FIELD(m_bcc, addressListField, fields::BCC);
|
||||||
|
|
||||||
|
TRY_FIELD(m_subject, textField, fields::SUBJECT);
|
||||||
|
|
||||||
TRY_FIELD(m_subject = dynamic_cast<textField&>(msg.header().fields.find(headerField::Subject)).value());
|
|
||||||
#undef TRY_FIELD
|
#undef TRY_FIELD
|
||||||
|
|
||||||
// Date
|
// Date
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
vmime::relayField& recv = static_cast<vmime::relayField&>(msg.header().fields.find(headerField::Received));
|
vmime::relayField& recv = dynamic_cast <vmime::relayField&>
|
||||||
m_date = recv.date();
|
(*msg.getHeader()->findField(fields::RECEIVED));
|
||||||
|
|
||||||
|
m_date = recv.getValue().getDate();
|
||||||
}
|
}
|
||||||
catch (vmime::exceptions::no_such_field&)
|
catch (vmime::exceptions::no_such_field&)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
vmime::dateField& date = static_cast<vmime::dateField&>(msg.header().fields.find(headerField::Date));
|
vmime::dateField& date = dynamic_cast <vmime::dateField&>
|
||||||
m_date = date.value();
|
(*msg.getHeader()->findField(fields::DATE));
|
||||||
|
|
||||||
|
m_date = date.getValue();
|
||||||
}
|
}
|
||||||
catch (vmime::exceptions::no_such_field&)
|
catch (vmime::exceptions::no_such_field&)
|
||||||
{
|
{
|
||||||
@ -100,10 +106,11 @@ void messageParser::parse(const message& msg)
|
|||||||
void messageParser::findAttachments(const bodyPart& part)
|
void messageParser::findAttachments(const bodyPart& part)
|
||||||
{
|
{
|
||||||
// We simply search for parts that are not "Content-disposition: inline".
|
// We simply search for parts that are not "Content-disposition: inline".
|
||||||
for (body::const_iterator p = part.body().parts.begin() ; p != part.body().parts.end() ; ++p)
|
for (int i = 0 ; i < part.getBody()->getPartCount() ; ++i)
|
||||||
{
|
{
|
||||||
const header& hdr = (*p).header();
|
const bodyPart& p = *part.getBody()->getPartAt(i);
|
||||||
const body& bdy = (*p).body();
|
const header& hdr = *p.getHeader();
|
||||||
|
const body& bdy = *p.getBody();
|
||||||
|
|
||||||
// Is this part an attachment?
|
// Is this part an attachment?
|
||||||
bool isAttachment = false;
|
bool isAttachment = false;
|
||||||
@ -112,9 +119,9 @@ void messageParser::findAttachments(const bodyPart& part)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
const contentDispositionField& cdf = dynamic_cast<contentDispositionField&>
|
const contentDispositionField& cdf = dynamic_cast<contentDispositionField&>
|
||||||
(hdr.fields.find(headerField::ContentDisposition));
|
(*hdr.findField(fields::CONTENT_DISPOSITION));
|
||||||
|
|
||||||
if (cdf.value().name() != dispositionTypes::INLINE)
|
if (cdf.getValue().getName() != dispositionTypes::INLINE)
|
||||||
{
|
{
|
||||||
contentDispField = &cdf;
|
contentDispField = &cdf;
|
||||||
isAttachment = true;
|
isAttachment = true;
|
||||||
@ -129,9 +136,9 @@ void messageParser::findAttachments(const bodyPart& part)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
(hdr.fields.find(headerField::ContentType));
|
(*hdr.findField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
type = ctf.value();
|
type = ctf.getValue();
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_field)
|
catch (exceptions::no_such_field)
|
||||||
{
|
{
|
||||||
@ -140,8 +147,11 @@ void messageParser::findAttachments(const bodyPart& part)
|
|||||||
mediaTypes::APPLICATION_OCTET_STREAM);
|
mediaTypes::APPLICATION_OCTET_STREAM);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type.type() != mediaTypes::TEXT && type.type() != mediaTypes::MULTIPART)
|
if (type.getType() != mediaTypes::TEXT &&
|
||||||
|
type.getType() != mediaTypes::MULTIPART)
|
||||||
|
{
|
||||||
isAttachment = true;
|
isAttachment = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAttachment)
|
if (isAttachment)
|
||||||
@ -152,9 +162,9 @@ void messageParser::findAttachments(const bodyPart& part)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
(hdr.fields.find(headerField::ContentType));
|
(*hdr.findField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
type = ctf.value();
|
type = ctf.getValue();
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_field)
|
catch (exceptions::no_such_field)
|
||||||
{
|
{
|
||||||
@ -169,9 +179,9 @@ void messageParser::findAttachments(const bodyPart& part)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
const textField& cd = dynamic_cast<textField&>
|
const textField& cd = dynamic_cast<textField&>
|
||||||
(hdr.fields.find(headerField::ContentDescription));
|
(*hdr.findField(fields::CONTENT_DESCRIPTION));
|
||||||
|
|
||||||
description = cd.value();
|
description = cd.getValue();
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_field)
|
catch (exceptions::no_such_field)
|
||||||
{
|
{
|
||||||
@ -180,12 +190,12 @@ void messageParser::findAttachments(const bodyPart& part)
|
|||||||
|
|
||||||
// Construct the attachment object
|
// Construct the attachment object
|
||||||
attachment* attach = new defaultAttachment
|
attachment* attach = new defaultAttachment
|
||||||
(bdy.contents(), bdy.encoding(), type, description);
|
(bdy.getContents(), bdy.getEncoding(), type, description);
|
||||||
|
|
||||||
if (contentDispField != NULL)
|
if (contentDispField != NULL)
|
||||||
{
|
{
|
||||||
m_attachInfo.insert(std::map <attachment*, contentDispositionField*>::
|
m_attachInfo.insert(std::map <attachment*, contentDispositionField*>::
|
||||||
value_type(attach, static_cast <contentDispositionField*>
|
value_type(attach, dynamic_cast <contentDispositionField*>
|
||||||
(contentDispField->clone())));
|
(contentDispField->clone())));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,8 +204,8 @@ void messageParser::findAttachments(const bodyPart& part)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Try to find attachments in sub-parts
|
// Try to find attachments in sub-parts
|
||||||
if (bdy.parts.size())
|
if (bdy.getPartCount())
|
||||||
findAttachments(*p);
|
findAttachments(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -204,7 +214,7 @@ void messageParser::findTextParts(const bodyPart& msg, const bodyPart& part)
|
|||||||
{
|
{
|
||||||
// Handle the case in which the message is not multipart: if the body part is
|
// Handle the case in which the message is not multipart: if the body part is
|
||||||
// "text/*", take this part.
|
// "text/*", take this part.
|
||||||
if (part.body().parts.count() == 0)
|
if (part.getBody()->getPartCount() == 0)
|
||||||
{
|
{
|
||||||
mediaType type(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN);
|
mediaType type(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN);
|
||||||
bool accept = false;
|
bool accept = false;
|
||||||
@ -212,11 +222,11 @@ void messageParser::findTextParts(const bodyPart& msg, const bodyPart& part)
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
(msg.header().fields.find(headerField::ContentType));
|
(*msg.getHeader()->findField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
if (ctf.value().type() == mediaTypes::TEXT)
|
if (ctf.getValue().getType() == mediaTypes::TEXT)
|
||||||
{
|
{
|
||||||
type = ctf.value();
|
type = ctf.getValue();
|
||||||
accept = true;
|
accept = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,17 +261,18 @@ bool messageParser::findSubTextParts(const bodyPart& msg, const bodyPart& part)
|
|||||||
|
|
||||||
std::vector <const bodyPart*> textParts;
|
std::vector <const bodyPart*> textParts;
|
||||||
|
|
||||||
for (body::const_iterator p = part.body().parts.begin() ;
|
for (int i = 0 ; i < part.getBody()->getPartCount() ; ++i)
|
||||||
p != part.body().parts.end() ; ++p)
|
|
||||||
{
|
{
|
||||||
|
const bodyPart& p = *part.getBody()->getPartAt(i);
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
((*p).header().fields.find(headerField::ContentType));
|
(*p.getHeader()->findField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
if (ctf.value().type() == mediaTypes::TEXT)
|
if (ctf.getValue().getType() == mediaTypes::TEXT)
|
||||||
{
|
{
|
||||||
textParts.push_back(&(*p));
|
textParts.push_back(&p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (exceptions::no_such_field)
|
catch (exceptions::no_such_field)
|
||||||
@ -273,14 +284,15 @@ bool messageParser::findSubTextParts(const bodyPart& msg, const bodyPart& part)
|
|||||||
if (textParts.size())
|
if (textParts.size())
|
||||||
{
|
{
|
||||||
// Okay. So we have found at least one text part
|
// Okay. So we have found at least one text part
|
||||||
for (std::vector <const bodyPart*>::const_iterator p = textParts.begin() ; p != textParts.end() ; ++p)
|
for (std::vector <const bodyPart*>::const_iterator p = textParts.begin() ;
|
||||||
|
p != textParts.end() ; ++p)
|
||||||
{
|
{
|
||||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||||
((*p)->header().fields.find(headerField::ContentType));
|
(*(*p)->getHeader()->findField(fields::CONTENT_TYPE));
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
textPart* textPart = textPartFactory::getInstance()->create(ctf.value());
|
textPart* textPart = textPartFactory::getInstance()->create(ctf.getValue());
|
||||||
textPart->parse(msg, part, **p);
|
textPart->parse(msg, part, **p);
|
||||||
|
|
||||||
m_textParts.push_back(textPart);
|
m_textParts.push_back(textPart);
|
||||||
@ -298,10 +310,9 @@ bool messageParser::findSubTextParts(const bodyPart& msg, const bodyPart& part)
|
|||||||
{
|
{
|
||||||
bool found = false;
|
bool found = false;
|
||||||
|
|
||||||
for (body::const_iterator p = part.body().parts.begin() ;
|
for (int i = 0 ; !found && (i < part.getBody()->getPartCount()) ; ++i)
|
||||||
!found && p != part.body().parts.end() ; ++p)
|
|
||||||
{
|
{
|
||||||
found = findSubTextParts(msg, *p);
|
found = findSubTextParts(msg, *part.getBody()->getPartAt(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
return found;
|
return found;
|
||||||
@ -309,13 +320,105 @@ bool messageParser::findSubTextParts(const bodyPart& msg, const bodyPart& part)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const contentDispositionField* messageParser::attachmentInfo(attachment* a) const
|
const contentDispositionField* messageParser::getAttachmentInfo(const attachment* a) const
|
||||||
{
|
{
|
||||||
std::map <attachment*, contentDispositionField*>::const_iterator
|
std::map <attachment*, contentDispositionField*>::const_iterator
|
||||||
it = m_attachInfo.find(a);
|
it = m_attachInfo.find(const_cast <attachment*>(a));
|
||||||
|
|
||||||
return (it != m_attachInfo.end() ? (*it).second : NULL);
|
return (it != m_attachInfo.end() ? (*it).second : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const mailbox& messageParser::getExpeditor() const
|
||||||
|
{
|
||||||
|
return (m_from);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const addressList& messageParser::getRecipients() const
|
||||||
|
{
|
||||||
|
return (m_to);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const addressList& messageParser::getCopyRecipients() const
|
||||||
|
{
|
||||||
|
return (m_cc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const addressList& messageParser::getBlindCopyRecipients() const
|
||||||
|
{
|
||||||
|
return (m_bcc);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const text& messageParser::getSubject() const
|
||||||
|
{
|
||||||
|
return (m_subject);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const datetime& messageParser::getDate() const
|
||||||
|
{
|
||||||
|
return (m_date);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector <const attachment*> messageParser::getAttachmentList() const
|
||||||
|
{
|
||||||
|
std::vector <const attachment*> res;
|
||||||
|
|
||||||
|
res.reserve(m_attach.size());
|
||||||
|
|
||||||
|
for (std::vector <attachment*>::const_iterator it = m_attach.begin() ;
|
||||||
|
it != m_attach.end() ; ++it)
|
||||||
|
{
|
||||||
|
res.push_back(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const int messageParser::getAttachmentCount() const
|
||||||
|
{
|
||||||
|
return (m_attach.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const attachment* messageParser::getAttachmentAt(const int pos) const
|
||||||
|
{
|
||||||
|
return (m_attach[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const std::vector <const textPart*> messageParser::getTextPartList() const
|
||||||
|
{
|
||||||
|
std::vector <const textPart*> res;
|
||||||
|
|
||||||
|
res.reserve(m_textParts.size());
|
||||||
|
|
||||||
|
for (std::vector <textPart*>::const_iterator it = m_textParts.begin() ;
|
||||||
|
it != m_textParts.end() ; ++it)
|
||||||
|
{
|
||||||
|
res.push_back(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (res);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const int messageParser::getTextPartCount() const
|
||||||
|
{
|
||||||
|
return (m_textParts.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
const textPart* messageParser::getTextPartAt(const int pos) const
|
||||||
|
{
|
||||||
|
return (m_textParts[pos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} // vmime
|
} // vmime
|
||||||
|
@ -46,27 +46,88 @@ public:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Expeditor and recipients
|
/** Return the expeditor of the message (From:).
|
||||||
const mailbox& expeditor() const { return (m_from); }
|
*
|
||||||
|
* @return expeditor of the message
|
||||||
|
*/
|
||||||
|
const mailbox& getExpeditor() const;
|
||||||
|
|
||||||
const addressList& recipients() const { return (m_to); }
|
/** Return the recipients of the message (To:).
|
||||||
const addressList& copyRecipients() const { return (m_cc); }
|
*
|
||||||
const addressList& blindCopyRecipients() const { return (m_bcc); }
|
* return recipients of the message
|
||||||
|
*/
|
||||||
|
const addressList& getRecipients() const;
|
||||||
|
|
||||||
// Subject
|
/** Return the copy recipients of the message (Cc:).
|
||||||
const text& subject() const { return (m_subject); }
|
*
|
||||||
|
* @return copy recipients of the message
|
||||||
|
*/
|
||||||
|
const addressList& getCopyRecipients() const;
|
||||||
|
|
||||||
// Date
|
/** Return the blind-copy recipients of the message (Bcc:).
|
||||||
const datetime& date() const { return (m_date); }
|
*
|
||||||
|
* @return blind-copy recipients of the message
|
||||||
|
*/
|
||||||
|
const addressList& getBlindCopyRecipients() const;
|
||||||
|
|
||||||
// Attachments
|
/** Return the subject of the message.
|
||||||
const std::vector <attachment*>& attachments() const { return (m_attach); }
|
*
|
||||||
const contentDispositionField* attachmentInfo(attachment* a) const;
|
* @return subject of the message
|
||||||
|
*/
|
||||||
|
const text& getSubject() const;
|
||||||
|
|
||||||
// Text parts
|
/** Return the date of the message.
|
||||||
const std::vector <textPart*>& textParts() const { return (m_textParts); }
|
*
|
||||||
|
* @return date of the message
|
||||||
|
*/
|
||||||
|
const datetime& getDate() const;
|
||||||
|
|
||||||
protected:
|
/** Return the number of attachments in the message.
|
||||||
|
*
|
||||||
|
* @return number of attachments
|
||||||
|
*/
|
||||||
|
const int getAttachmentCount() const;
|
||||||
|
|
||||||
|
/** Return the attachment at the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position of the attachment
|
||||||
|
* @return attachment at position 'pos'
|
||||||
|
*/
|
||||||
|
const attachment* getAttachmentAt(const int pos) const;
|
||||||
|
|
||||||
|
/** Return the attachments of the message.
|
||||||
|
*
|
||||||
|
* @return list of attachments in the message
|
||||||
|
*/
|
||||||
|
const std::vector <const attachment*> getAttachmentList() const;
|
||||||
|
|
||||||
|
/** Return information about the specified attachment.
|
||||||
|
*
|
||||||
|
* @param a attachment to retrieve information about
|
||||||
|
* @return information about the specified attachment
|
||||||
|
*/
|
||||||
|
const contentDispositionField* getAttachmentInfo(const attachment* a) const;
|
||||||
|
|
||||||
|
/** Return the text parts of the message.
|
||||||
|
*
|
||||||
|
* @return list of text parts in the message
|
||||||
|
*/
|
||||||
|
const std::vector <const textPart*> getTextPartList() const;
|
||||||
|
|
||||||
|
/** Return the number of text parts in the message.
|
||||||
|
*
|
||||||
|
* @return number of text parts
|
||||||
|
*/
|
||||||
|
const int getTextPartCount() const;
|
||||||
|
|
||||||
|
/** Return the text part at the specified position.
|
||||||
|
*
|
||||||
|
* @param pos position of the text part
|
||||||
|
* @return text part at position 'pos'
|
||||||
|
*/
|
||||||
|
const textPart* getTextPartAt(const int pos) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
mailbox m_from;
|
mailbox m_from;
|
||||||
|
|
||||||
|
@ -59,24 +59,24 @@ void IMAPConnection::connect()
|
|||||||
m_state = STATE_NONE;
|
m_state = STATE_NONE;
|
||||||
m_hierarchySeparator = '\0';
|
m_hierarchySeparator = '\0';
|
||||||
|
|
||||||
const string address = m_store->session().properties()[m_store->infos().propertyPrefix() + "server.address"];
|
const string address = m_store->getSession()->getProperties()[m_store->getInfos().getPropertyPrefix() + "server.address"];
|
||||||
const port_t port = m_store->session().properties().get(m_store->infos().propertyPrefix() + "server.port", m_store->infos().defaultPort());
|
const port_t port = m_store->getSession()->getProperties().getProperty(m_store->getInfos().getPropertyPrefix() + "server.port", m_store->getInfos().getDefaultPort());
|
||||||
|
|
||||||
// Create the time-out handler
|
// Create the time-out handler
|
||||||
if (session().properties().exists
|
if (m_store->getSession()->getProperties().hasProperty
|
||||||
(m_store->infos().propertyPrefix() + "timeout.factory"))
|
(m_store->getInfos().getPropertyPrefix() + "timeout.factory"))
|
||||||
{
|
{
|
||||||
timeoutHandlerFactory* tof = platformDependant::getHandler()->
|
timeoutHandlerFactory* tof = platformDependant::getHandler()->
|
||||||
getTimeoutHandlerFactory(session().properties()
|
getTimeoutHandlerFactory(m_store->getSession()->getProperties()
|
||||||
[m_store->infos().propertyPrefix() + "timeout.factory"]);
|
[m_store->getInfos().getPropertyPrefix() + "timeout.factory"]);
|
||||||
|
|
||||||
m_timeoutHandler = tof->create();
|
m_timeoutHandler = tof->create();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create and connect the socket
|
// Create and connect the socket
|
||||||
socketFactory* sf = platformDependant::getHandler()->getSocketFactory
|
socketFactory* sf = platformDependant::getHandler()->getSocketFactory
|
||||||
(m_store->session().properties().get
|
(m_store->getSession()->getProperties().getProperty
|
||||||
(m_store->infos().propertyPrefix() + "server.socket-factory", string("default")));
|
(m_store->getInfos().getPropertyPrefix() + "server.socket-factory", string("default")));
|
||||||
|
|
||||||
m_socket = sf->create();
|
m_socket = sf->create();
|
||||||
m_socket->connect(address, port);
|
m_socket->connect(address, port);
|
||||||
@ -109,8 +109,8 @@ void IMAPConnection::connect()
|
|||||||
|
|
||||||
// TODO: other authentication methods
|
// TODO: other authentication methods
|
||||||
|
|
||||||
send(true, "LOGIN " + IMAPUtils::quoteString(auth.username())
|
send(true, "LOGIN " + IMAPUtils::quoteString(auth.getUsername())
|
||||||
+ " " + IMAPUtils::quoteString(auth.password()), true);
|
+ " " + IMAPUtils::quoteString(auth.getPassword()), true);
|
||||||
|
|
||||||
utility::auto_ptr <IMAPParser::response> resp(m_parser->readResponse());
|
utility::auto_ptr <IMAPParser::response> resp(m_parser->readResponse());
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user