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>
|
||||
|
||||
* IMAPFolder.cpp: fixed rename(): folder name is now updated.
|
||||
|
22
SConstruct
22
SConstruct
@ -28,26 +28,18 @@ import string
|
||||
libvmime_sources = [
|
||||
'address.cpp', 'address.hpp',
|
||||
'addressList.cpp', 'addressList.hpp',
|
||||
'addressListField.cpp', 'addressListField.hpp',
|
||||
'attachment.hpp',
|
||||
'base.cpp', 'base.hpp',
|
||||
'body.cpp', 'body.hpp',
|
||||
'bodyPart.cpp', 'bodyPart.hpp',
|
||||
'charset.cpp', 'charset.hpp',
|
||||
'charsetParameter.cpp', 'charsetParameter.hpp',
|
||||
'component.cpp', 'component.hpp',
|
||||
'constants.cpp', 'constants.hpp',
|
||||
'contentDispositionField.cpp', 'contentDispositionField.hpp',
|
||||
'contentEncodingField.cpp', 'contentEncodingField.hpp',
|
||||
'contentHandler.cpp', 'contentHandler.hpp',
|
||||
'contentTypeField.cpp', 'contentTypeField.hpp',
|
||||
'dateField.cpp', 'dateField.hpp',
|
||||
'dateParameter.cpp', 'dateParameter.hpp',
|
||||
'dateTime.cpp', 'dateTime.hpp',
|
||||
'defaultAttachment.cpp', 'defaultAttachment.hpp',
|
||||
'defaultField.cpp', 'defaultField.hpp',
|
||||
'defaultParameter.cpp', 'defaultParameter.hpp',
|
||||
'defaultParameterizedHeaderField.cpp', 'defaultParameterizedHeaderField.hpp',
|
||||
'disposition.cpp', 'disposition.hpp',
|
||||
'encoder.cpp', 'encoder.hpp',
|
||||
'encoder7bit.cpp', 'encoder7bit.hpp',
|
||||
@ -61,6 +53,8 @@ libvmime_sources = [
|
||||
'encoding.cpp', 'encoding.hpp',
|
||||
'exception.hpp',
|
||||
'fileAttachment.cpp', 'fileAttachment.hpp',
|
||||
'genericField.hpp',
|
||||
'genericParameter.hpp',
|
||||
'header.cpp', 'header.hpp',
|
||||
'headerFieldFactory.cpp', 'headerFieldFactory.hpp',
|
||||
'headerField.cpp', 'headerField.hpp',
|
||||
@ -69,12 +63,10 @@ libvmime_sources = [
|
||||
'mailboxField.cpp', 'mailboxField.hpp',
|
||||
'mailboxGroup.cpp', 'mailboxGroup.hpp',
|
||||
'mailboxList.cpp', 'mailboxList.hpp',
|
||||
'mailboxListField.cpp', 'mailboxListField.hpp',
|
||||
'mediaType.cpp', 'mediaType.hpp',
|
||||
'messageBuilder.cpp', 'messageBuilder.hpp',
|
||||
'message.cpp', 'message.hpp',
|
||||
'messageId.cpp', 'messageId.hpp',
|
||||
'messageIdField.cpp', 'messageIdField.hpp',
|
||||
'messageParser.cpp', 'messageParser.hpp',
|
||||
'options.cpp', 'options.hpp',
|
||||
'parameter.cpp', 'parameter.hpp',
|
||||
@ -84,12 +76,13 @@ libvmime_sources = [
|
||||
'plainTextPart.cpp', 'plainTextPart.hpp',
|
||||
'platformDependant.cpp', 'platformDependant.hpp',
|
||||
'propertySet.cpp', 'propertySet.hpp',
|
||||
'relayField.cpp', 'relayField.hpp',
|
||||
'relay.cpp', 'relay.hpp',
|
||||
'standardFields.hpp',
|
||||
'standardParams.hpp',
|
||||
'text.cpp', 'text.hpp',
|
||||
'textField.cpp', 'textField.hpp',
|
||||
'textParameter.cpp', 'textParameter.hpp',
|
||||
'textPartFactory.cpp', 'textPartFactory.hpp',
|
||||
'textPart.hpp',
|
||||
'typeAdapter.hpp',
|
||||
'types.hpp',
|
||||
'word.cpp', 'word.hpp',
|
||||
'vmime',
|
||||
@ -100,7 +93,8 @@ libvmime_sources = [
|
||||
'utility/singleton.cpp', 'utility/singleton.hpp',
|
||||
'utility/smartPtr.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 = [
|
||||
|
@ -257,7 +257,7 @@ public:
|
||||
gmt.tm_isdst = -1;
|
||||
|
||||
// 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 vmime::datetime(local.tm_year + 1900, local.tm_mon + 1, local.tm_mday,
|
||||
|
@ -45,14 +45,24 @@ int main()
|
||||
vmime::messageBuilder mb;
|
||||
|
||||
// Fill in the basic fields
|
||||
mb.expeditor() = vmime::mailbox("me@somewhere.com");
|
||||
mb.recipients().append(vmime::mailbox("you@elsewhere.com"));
|
||||
mb.blindCopyRecipients().append(vmime::mailbox("you-bcc@nowhere.com"));
|
||||
mb.subject() = vmime::text("My first message generated with vmime::messageBuilder");
|
||||
mb.setExpeditor(vmime::mailbox("me@somewhere.com"));
|
||||
|
||||
vmime::addressList to;
|
||||
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
|
||||
mb.textPart().text() = "I'm writing this short text to test message construction " \
|
||||
"using the vmime::messageBuilder component.";
|
||||
mb.getTextPart()->setText(vmime::contentHandler(
|
||||
"I'm writing this short text to test message construction " \
|
||||
"using the vmime::messageBuilder component."));
|
||||
|
||||
// Construction
|
||||
vmime::message* msg = mb.construct();
|
||||
@ -61,7 +71,7 @@ int main()
|
||||
std::cout << "Generated message:" << std::endl;
|
||||
std::cout << "==================" << std::endl;
|
||||
|
||||
vmime::outputStreamAdapter out(std::cout);
|
||||
vmime::utility::outputStreamAdapter out(std::cout);
|
||||
msg->generate(out);
|
||||
|
||||
// Destruction
|
||||
@ -77,7 +87,7 @@ int main()
|
||||
catch (std::exception& e)
|
||||
{
|
||||
std::cout << "std::exception: " << e.what() << std::endl;
|
||||
throw;
|
||||
//throw;
|
||||
}
|
||||
|
||||
std::cout << std::endl;
|
||||
|
@ -45,14 +45,24 @@ int main()
|
||||
vmime::messageBuilder mb;
|
||||
|
||||
// Fill in the basic fields
|
||||
mb.expeditor() = vmime::mailbox("me@somewhere.com");
|
||||
mb.recipients().append(vmime::mailbox("you@elsewhere.com"));
|
||||
mb.blindCopyRecipients().append(vmime::mailbox("you-bcc@nowhere.com"));
|
||||
mb.subject() = vmime::text("My first message generated with vmime::messageBuilder");
|
||||
mb.setExpeditor(vmime::mailbox("me@somewhere.com"));
|
||||
|
||||
vmime::addressList to;
|
||||
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
|
||||
mb.textPart().text() = "I'm writing this short text to test message construction " \
|
||||
"with attachment, using the vmime::messageBuilder component.";
|
||||
mb.getTextPart()->setText(vmime::contentHandler(
|
||||
"I'm writing this short text to test message construction " \
|
||||
"with attachment, using the vmime::messageBuilder component."));
|
||||
|
||||
// Adding an attachment
|
||||
vmime::fileAttachment* a = new vmime::fileAttachment
|
||||
@ -62,8 +72,8 @@ int main()
|
||||
vmime::text("My first attachment") // description
|
||||
);
|
||||
|
||||
a->fileInfo().setFilename("example2.cpp");
|
||||
a->fileInfo().setCreationDate(vmime::datetime("30 Apr 2003 14:30:00 +0200"));
|
||||
a->getFileInfo().setFilename("example2.cpp");
|
||||
a->getFileInfo().setCreationDate(vmime::datetime("30 Apr 2003 14:30:00 +0200"));
|
||||
|
||||
mb.attach(a);
|
||||
|
||||
|
@ -45,10 +45,19 @@ int main()
|
||||
vmime::messageBuilder mb;
|
||||
|
||||
// Fill in the basic fields
|
||||
mb.expeditor() = vmime::mailbox("me@somewhere.com");
|
||||
mb.recipients().append(vmime::mailbox("you@elsewhere.com"));
|
||||
mb.blindCopyRecipients().append(vmime::mailbox("you-bcc@nowhere.com"));
|
||||
mb.subject() = vmime::text("My first message generated with vmime::messageBuilder");
|
||||
mb.setExpeditor(vmime::mailbox("me@somewhere.com"));
|
||||
|
||||
vmime::addressList to;
|
||||
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"
|
||||
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.
|
||||
// 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
|
||||
// -- 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));
|
||||
|
||||
// -- message text
|
||||
textPart.text() = 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.setText(vmime::contentHandler(vmime::string("This is the <b>HTML text</b>.<br/><img src=\"") + cid + vmime::string("\"/>")));
|
||||
textPart.setPlainText(vmime::contentHandler(vmime::string("This is the plain text (without HTML formatting).")));
|
||||
|
||||
// Construction
|
||||
vmime::message* msg = mb.construct();
|
||||
|
@ -44,28 +44,28 @@ int main()
|
||||
vmime::messageParser mp("<...MIME message content...>");
|
||||
|
||||
// Enumerate text parts
|
||||
for (std::vector <vmime::textPart*>::const_iterator i = mp.textParts().begin() ;
|
||||
i != mp.textParts().end() ; ++i)
|
||||
for (int i = 0 ; i < mp.getTextPartCount() ; ++i)
|
||||
{
|
||||
const vmime::textPart& part = **i;
|
||||
const vmime::textPart& part = *mp.getTextPartAt(i);
|
||||
|
||||
// Output content-type of the part
|
||||
std::cout << part.type().generate() << std::endl;
|
||||
std::cout << part.getType().generate() << std::endl;
|
||||
|
||||
// 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);
|
||||
|
||||
// HTML text is in "hp.text()"
|
||||
// Corresponding plain text is in "hp.plainText()"
|
||||
// HTML text is in "hp.getText()"
|
||||
// Corresponding plain text is in "hp.getPlainText()"
|
||||
|
||||
// Enumerate embedded objects (eg. images)
|
||||
for (vmime::htmlTextPart::const_iterator i = hp.embeddedObjects.begin() ;
|
||||
i != hp.embeddedObjects.end() ; ++i)
|
||||
for (int j = 0 ; j < hp.getObjectCount() ; ++j)
|
||||
{
|
||||
// Identifier (content-id or content-location) is in "(*i).id()"
|
||||
// Object data is in "(*i).data()"
|
||||
const vmime::htmlTextPart::embeddedObject& obj = *hp.getObjectAt(j);
|
||||
|
||||
// Identifier (content-id or content-location) is in "obj.getId()"
|
||||
// Object data is in "obj.getData()"
|
||||
}
|
||||
}
|
||||
// text/plain
|
||||
@ -73,7 +73,7 @@ int main()
|
||||
{
|
||||
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...>");
|
||||
|
||||
// Enumerate attachments
|
||||
for (std::vector <vmime::attachment*>::const_iterator i = mp.attachments().begin() ;
|
||||
i != mp.attachments().end() ; ++i)
|
||||
for (int i = 0 ; i < mp.getAttachmentCount() ; ++i)
|
||||
{
|
||||
// Media type (content type) is in "(*i).type()"
|
||||
// Description is in "(*i).description()"
|
||||
// Data is in "(*i).data()"
|
||||
const vmime::attachment& att = *mp.getAttachmentAt(i);
|
||||
|
||||
// Media type (content type) is in "att.getType()"
|
||||
// Description is in "att.getDescription()"
|
||||
// Data is in "att.getData()"
|
||||
}
|
||||
}
|
||||
// VMime exception
|
||||
|
@ -49,19 +49,19 @@ class my_auth : public vmime::messaging::authenticator
|
||||
|
||||
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];
|
||||
|
||||
for (int j = 0 ; j < level * 2 ; ++j)
|
||||
std::cout << " ";
|
||||
|
||||
std::cout << part.number() << ". "
|
||||
<< part.type().generate()
|
||||
<< " [" << part.size() << " byte(s)]"
|
||||
std::cout << part.getNumber() << ". "
|
||||
<< part.getType().generate()
|
||||
<< " [" << part.getSize() << " byte(s)]"
|
||||
<< 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
|
||||
//
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
vmime::encoderFactory* ef = vmime::encoderFactory::getInstance();
|
||||
|
||||
std::cout << "Available encoders:" << std::endl;
|
||||
|
||||
for (vmime::encoderFactory::iterator it = ef->begin() ;
|
||||
it != ef->end() ; ++it)
|
||||
for (int i = 0 ; i < ef->getEncoderCount() ; ++i)
|
||||
{
|
||||
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::cout << " - " << *it2 << std::endl;
|
||||
std::vector <vmime::string> props = e->getAvailableProperties();
|
||||
|
||||
for (std::vector <vmime::string>::const_iterator it = props.begin() ; it != props.end() ; ++it)
|
||||
std::cout << " - " << *it << std::endl;
|
||||
|
||||
delete (e);
|
||||
}
|
||||
@ -108,21 +109,22 @@ int main()
|
||||
|
||||
std::cout << "Available messaging services:" << std::endl;
|
||||
|
||||
for (vmime::messaging::serviceFactory::const_iterator it = sf->begin() ;
|
||||
it != sf->end() ; ++it)
|
||||
for (int i = 0 ; i < sf->getServiceCount() ; ++i)
|
||||
{
|
||||
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::cout << " - " << (*it).infos().propertyPrefix() + *it2 << std::endl;
|
||||
std::vector <vmime::string> props = serv.getInfos().getAvailableProperties();
|
||||
|
||||
for (std::vector <vmime::string>::const_iterator it = props.begin() ; it != props.end() ; ++it)
|
||||
std::cout << " - " << serv.getInfos().getPropertyPrefix() + *it << std::endl;
|
||||
}
|
||||
#endif
|
||||
|
||||
vmime::messaging::session sess;
|
||||
sess.properties()["store.protocol"] = "imap";
|
||||
sess.properties()["transport.protocol"] = "smtp";
|
||||
sess.getProperties()["store.protocol"] = "imap";
|
||||
sess.getProperties()["transport.protocol"] = "smtp";
|
||||
|
||||
my_auth auth;
|
||||
|
||||
@ -136,12 +138,12 @@ int main()
|
||||
// Transport protocol configuration
|
||||
vmime::messaging::transport* tr = sess.getTransport();
|
||||
|
||||
//sess.properties()[tr->infos().propertyPrefix() + "auth.username"] = "username";
|
||||
//sess.properties()[tr->infos().propertyPrefix() + "auth.password"] = "password";
|
||||
//sess.getProperties()[tr->getInfos().getPropertyPrefix() + "auth.username"] = "username";
|
||||
//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
|
||||
tr->connect();
|
||||
@ -151,8 +153,8 @@ int main()
|
||||
|
||||
// Recipients list
|
||||
vmime::mailboxList to;
|
||||
to.append(vmime::mailbox("you@somewhere.com"));
|
||||
to.append(vmime::mailbox("somebody.else@anywhere.com"));
|
||||
to.appendMailbox(new vmime::mailbox("you@somewhere.com"));
|
||||
to.appendMailbox(new vmime::mailbox("somebody.else@anywhere.com"));
|
||||
|
||||
std::istringstream iss("[MESSAGE DATA: HEADER + BODY]");
|
||||
tr->send(from, to, iss);
|
||||
@ -176,15 +178,15 @@ int main()
|
||||
vmime::messaging::store* st = sess.getStore(&auth);
|
||||
|
||||
// Store protocol configuration
|
||||
//sess.properties()[st->infos().propertyPrefix() + "auth.username"] = "username";
|
||||
//sess.properties()[st->infos().propertyPrefix() + "auth.password"] = "password";
|
||||
//sess.getProperties()[st->getInfos().getPropertyPrefix() + "auth.username"] = "username";
|
||||
//sess.getProperties()[st->getInfos().getPropertyPrefix() + "auth.password"] = "password";
|
||||
|
||||
sess.properties()[st->infos().propertyPrefix() + "server.address"] = "imap.mydomain.com";
|
||||
//sess.properties()[st->infos().propertyPrefix() + "server.port"] = 110;
|
||||
//sess.properties()[st->infos().propertyPrefix() + "server.socket-factory"] = "default";
|
||||
sess.getProperties()[st->getInfos().getPropertyPrefix() + "server.address"] = "imap.mydomain.com";
|
||||
//sess.getProperties()[st->getInfos().getPropertyPrefix() + "server.port"] = 110;
|
||||
//sess.getProperties()[st->getInfos().getPropertyPrefix() + "server.socket-factory"] = "default";
|
||||
|
||||
//sess.properties()[st->infos().propertyPrefix() + "options.apop"] = false;
|
||||
//sess.properties()[st->infos().propertyPrefix() + "options.apop.fallback"] = true;
|
||||
//sess.getProperties()[st->getInfos().getPropertyPrefix() + "options.apop"] = false;
|
||||
//sess.getProperties()[st->getInfos().getPropertyPrefix() + "options.apop.fallback"] = true;
|
||||
|
||||
// Connection
|
||||
st->connect();
|
||||
@ -205,7 +207,7 @@ int main()
|
||||
|
||||
// To retrieve the whole message
|
||||
std::ostringstream oss;
|
||||
vmime::outputStreamAdapter out(oss);
|
||||
vmime::utility::outputStreamAdapter out(oss);
|
||||
|
||||
m->extract(out);
|
||||
|
||||
@ -223,55 +225,55 @@ int main()
|
||||
std::cout << "STRUCTURE:" << std::endl;
|
||||
std::cout << "==========" << std::endl;
|
||||
|
||||
printStructure(m->structure());
|
||||
printStructure(m->getStructure());
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "Size = " << m->size() << " byte(s)" << std::endl;
|
||||
std::cout << "UID = " << m->uniqueId() << std::endl;
|
||||
std::cout << "Size = " << m->getSize() << " byte(s)" << std::endl;
|
||||
std::cout << "UID = " << m->getUniqueId() << std::endl;
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "ENVELOPE:" << std::endl;
|
||||
std::cout << "=========" << std::endl;
|
||||
try { std::cout << m->header().fields.From().generate() << std::endl; } catch (...) { }
|
||||
try { std::cout << m->header().fields.To().generate() << std::endl; } catch (...) { }
|
||||
try { std::cout << m->header().fields.Date().generate() << std::endl; } catch (...) { }
|
||||
try { std::cout << m->header().fields.Subject().generate() << std::endl; } catch (...) { }
|
||||
try { std::cout << m->getHeader().From().generate() << std::endl; } catch (...) { }
|
||||
try { std::cout << m->getHeader().To().generate() << std::endl; } catch (...) { }
|
||||
try { std::cout << m->getHeader().Date().generate() << std::endl; } catch (...) { }
|
||||
try { std::cout << m->getHeader().Subject().generate() << std::endl; } catch (...) { }
|
||||
|
||||
std::cout << std::endl;
|
||||
|
||||
std::cout << "FULL HEADER:" << 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;
|
||||
|
||||
vmime::outputStreamAdapter out2(std::cout);
|
||||
m->extractPart(m->structure()[1][2][1], out2, NULL); //, 0, 10);
|
||||
vmime::utility::outputStreamAdapter out2(std::cout);
|
||||
m->extractPart(m->getStructure()[1][2][1], out2, NULL); //, 0, 10);
|
||||
|
||||
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;
|
||||
|
||||
// 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);
|
||||
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);
|
||||
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);
|
||||
std::cout << "Flags = " << m->flags() << std::endl;
|
||||
f->setMessageFlags(m->number(), m->number(), vmime::messaging::message::FLAG_REPLIED, vmime::messaging::message::FLAG_MODE_REMOVE);
|
||||
std::cout << "Flags = " << m->flags() << std::endl;
|
||||
f->setMessageFlags(m->getNumber(), m->getNumber(), vmime::messaging::message::FLAG_REPLIED, vmime::messaging::message::FLAG_MODE_ADD);
|
||||
std::cout << "Flags = " << m->getFlags() << std::endl;
|
||||
f->setMessageFlags(m->getNumber(), m->getNumber(), vmime::messaging::message::FLAG_REPLIED, vmime::messaging::message::FLAG_MODE_REMOVE);
|
||||
std::cout << "Flags = " << m->getFlags() << std::endl;
|
||||
|
||||
|
||||
std::cout << "=========================================================" << std::endl;
|
||||
@ -312,7 +314,7 @@ int main()
|
||||
if (!g->exists())
|
||||
g->create(vmime::messaging::folder::TYPE_CONTAINS_MESSAGES);
|
||||
|
||||
f->copyMessages(g->fullPath());
|
||||
f->copyMessages(g->getFullPath());
|
||||
|
||||
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
|
||||
|
@ -45,33 +45,13 @@ protected:
|
||||
|
||||
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
|
||||
* if this is a mailboxGroup -or- no email specified if this is
|
||||
* a mailbox).
|
||||
*
|
||||
* @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.
|
||||
*
|
||||
@ -79,6 +59,8 @@ public:
|
||||
*/
|
||||
virtual const bool isGroup() const = 0;
|
||||
|
||||
virtual address* clone() const = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/** Parse an address from an input buffer.
|
||||
|
@ -19,6 +19,8 @@
|
||||
|
||||
#include "addressList.hpp"
|
||||
#include "parserHelpers.hpp"
|
||||
#include "exception.hpp"
|
||||
#include "mailboxList.hpp"
|
||||
|
||||
|
||||
namespace vmime
|
||||
@ -30,23 +32,23 @@ addressList::addressList()
|
||||
}
|
||||
|
||||
|
||||
addressList::addressList(const class addressList& addressList)
|
||||
addressList::addressList(const addressList& addrList)
|
||||
: component()
|
||||
{
|
||||
copyFrom(addressList);
|
||||
copyFrom(addrList);
|
||||
}
|
||||
|
||||
|
||||
addressList::~addressList()
|
||||
{
|
||||
clear();
|
||||
removeAllAddresses();
|
||||
}
|
||||
|
||||
|
||||
void addressList::parse(const string& buffer, const string::size_type position,
|
||||
const string::size_type end, string::size_type* newPosition)
|
||||
{
|
||||
clear();
|
||||
removeAllAddresses();
|
||||
|
||||
string::size_type pos = position;
|
||||
|
||||
@ -69,11 +71,11 @@ void addressList::generate(utility::outputStream& os, const string::size_type ma
|
||||
if (!m_list.empty())
|
||||
{
|
||||
string::size_type pos = curLinePos;
|
||||
const_iterator i = m_list.begin();
|
||||
std::vector <address*>::const_iterator i = m_list.begin();
|
||||
|
||||
for ( ; ; )
|
||||
{
|
||||
(*i).generate(os, maxLineLength - 2, pos, &pos);
|
||||
(*i)->generate(os, maxLineLength - 2, pos, &pos);
|
||||
|
||||
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.
|
||||
*
|
||||
* @return number of addresses in the list
|
||||
*/
|
||||
|
||||
const std::vector <address*>::size_type addressList::size() const
|
||||
void addressList::copyFrom(const component& other)
|
||||
{
|
||||
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.
|
||||
*
|
||||
* @return number of addresses in the list
|
||||
*/
|
||||
|
||||
const std::vector <address*>::size_type addressList::count() const
|
||||
addressList& addressList::operator=(const addressList& other)
|
||||
{
|
||||
return (m_list.size());
|
||||
copyFrom(other);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
||||
/** Test whether the list is empty.
|
||||
*
|
||||
* @return true if the list is empty, false otherwise
|
||||
*/
|
||||
|
||||
const bool addressList::empty() const
|
||||
addressList& addressList::operator=(const mailboxList& other)
|
||||
{
|
||||
return (m_list.empty());
|
||||
copyFrom(other);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
||||
/** Append an address to the list.
|
||||
*
|
||||
* @param addr the address to add
|
||||
*/
|
||||
|
||||
void addressList::append(const address& addr)
|
||||
addressList* addressList::clone() const
|
||||
{
|
||||
m_list.push_back(addr.clone());
|
||||
return new addressList(*this);
|
||||
}
|
||||
|
||||
|
||||
/** Insert an address at the specified position in the list.
|
||||
*
|
||||
* @param it position of the new address
|
||||
* @param addr the address to insert
|
||||
*/
|
||||
|
||||
void addressList::insert(const iterator it, const address& addr)
|
||||
void addressList::appendAddress(address* addr)
|
||||
{
|
||||
m_list.insert(it.m_iterator, addr.clone());
|
||||
m_list.push_back(addr);
|
||||
}
|
||||
|
||||
|
||||
/** Remove the address at the specified position.
|
||||
*
|
||||
* @param it position of the address to remove
|
||||
*/
|
||||
|
||||
void addressList::erase(const iterator it)
|
||||
void addressList::insertAddressBefore(address* beforeAddress, address* addr)
|
||||
{
|
||||
delete (*it.m_iterator);
|
||||
m_list.erase(it.m_iterator);
|
||||
const std::vector <address*>::iterator it = std::find
|
||||
(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);
|
||||
}
|
||||
|
||||
|
||||
void addressList::copyFrom(const addressList& source)
|
||||
const int addressList::getAddressCount() const
|
||||
{
|
||||
clear();
|
||||
|
||||
for (std::vector <address*>::const_iterator i = source.m_list.begin() ; i != source.m_list.end() ; ++i)
|
||||
m_list.push_back((*i)->clone());
|
||||
return (m_list.size());
|
||||
}
|
||||
|
||||
|
||||
addressList& addressList::operator=(const addressList& source)
|
||||
const bool addressList::isEmpty() const
|
||||
{
|
||||
copyFrom(source);
|
||||
return (*this);
|
||||
return (m_list.empty());
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
@ -31,106 +31,124 @@ namespace vmime
|
||||
{
|
||||
|
||||
|
||||
class mailboxList;
|
||||
|
||||
|
||||
/** A list of addresses.
|
||||
*/
|
||||
|
||||
class addressList : public component
|
||||
{
|
||||
friend class addressListField;
|
||||
friend class mailboxListField;
|
||||
|
||||
public:
|
||||
|
||||
addressList();
|
||||
addressList(const class addressList& addressList);
|
||||
addressList(const addressList& addrList);
|
||||
|
||||
~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
|
||||
{
|
||||
friend class addressList;
|
||||
friend class const_iterator;
|
||||
/** Add a address at the end of the list.
|
||||
*
|
||||
* @param addr address to append
|
||||
*/
|
||||
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) { }
|
||||
iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
||||
/** Insert a new address before the specified position.
|
||||
*
|
||||
* @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); }
|
||||
address* operator->() const { return (*m_iterator); }
|
||||
/** Insert a new address after the specified position.
|
||||
*
|
||||
* @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); }
|
||||
iterator& operator++(int) { ++m_iterator; return (*this); }
|
||||
/** Remove the specified address from the list.
|
||||
*
|
||||
* @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); }
|
||||
const bool operator!=(const iterator& it) const { return (!(*this == it)); }
|
||||
/** Remove the address at the specified position.
|
||||
*
|
||||
* @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
|
||||
{
|
||||
friend class addressList;
|
||||
/** Tests whether the list of addresses is empty.
|
||||
*
|
||||
* @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) { }
|
||||
const_iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
||||
const_iterator(const const_iterator& it) : m_iterator(it.m_iterator) { }
|
||||
/** Return the address at the specified position.
|
||||
*
|
||||
* @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); }
|
||||
const_iterator& operator=(const iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
||||
/** Return the address list.
|
||||
*
|
||||
* @return list of addresses
|
||||
*/
|
||||
const std::vector <const address*> getAddressList() const;
|
||||
|
||||
const address& operator*() const { return (**m_iterator); }
|
||||
const address* operator->() const { return (*m_iterator); }
|
||||
/** Return the address list.
|
||||
*
|
||||
* @return list of addresses
|
||||
*/
|
||||
const std::vector <address*> getAddressList();
|
||||
|
||||
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())); }
|
||||
|
||||
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:
|
||||
private:
|
||||
|
||||
std::vector <address*> m_list;
|
||||
|
||||
void copyFrom(const addressList& source);
|
||||
|
||||
public:
|
||||
|
||||
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& operator=(const attachment& attach) = 0;
|
||||
|
||||
/** Return the media type of this 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 attachment description
|
||||
*/
|
||||
virtual const text& description() const = 0;
|
||||
virtual const text& getDescription() const = 0;
|
||||
|
||||
/** Return the data contained in this attachment.
|
||||
* @return attachment data
|
||||
*/
|
||||
virtual const contentHandler& data() const = 0;
|
||||
virtual const contentHandler& getData() const = 0;
|
||||
|
||||
/** Return the encoding used for this attachment.
|
||||
* @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.
|
||||
* @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 "utility/stringUtils.hpp"
|
||||
|
||||
// For initializing
|
||||
#include "encoderFactory.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.
|
||||
const string NEW_LINE_SEQUENCE("\r\n ");
|
||||
const string::size_type NEW_LINE_SEQUENCE_LENGTH(1); // space
|
||||
const string NEW_LINE_SEQUENCE = "\r\n ";
|
||||
const string::size_type NEW_LINE_SEQUENCE_LENGTH = 1; // space
|
||||
|
||||
/** The CR-LF sequence.
|
||||
*/
|
||||
const string CRLF("\r\n");
|
||||
const string CRLF = "\r\n";
|
||||
|
||||
|
||||
/** The current MIME version supported by VMime.
|
||||
*/
|
||||
const string MIME_VERSION("1.0");
|
||||
const string MIME_VERSION = "1.0";
|
||||
|
||||
|
||||
// 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.
|
||||
*
|
||||
* @param os output stream
|
||||
@ -252,14 +113,15 @@ void encodeAndFoldText(utility::outputStream& os, const text& in, const string::
|
||||
{
|
||||
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 string& buffer = w.buffer();
|
||||
const word& w = *in.getWordAt(wi);
|
||||
const string& buffer = w.getBuffer();
|
||||
|
||||
// Calculate the number of ASCII chars to check whether encoding is needed
|
||||
// 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) ||
|
||||
(!(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...
|
||||
|
||||
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
|
||||
// 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.
|
||||
|
||||
#if 1
|
||||
if (curLineLength != 1 && wi != in.begin())
|
||||
if (curLineLength != 1 && wi != 0)
|
||||
os << " "; // Separate from previous word
|
||||
#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::value_type encoding = (asciiPercent <= 40) ? 'B' : 'Q';
|
||||
|
||||
string wordStart("=?" + w.charset().name() + "?" + encoding + "?");
|
||||
string wordStart("=?" + w.getCharset().getName() + "?" + encoding + "?");
|
||||
string wordEnd("?=");
|
||||
|
||||
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')
|
||||
{
|
||||
theEncoder->properties()["rfc2047"] = true;
|
||||
theEncoder->getProperties()["rfc2047"] = true;
|
||||
|
||||
// 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
|
||||
@ -480,7 +342,7 @@ void encodeAndFoldText(utility::outputStream& os, const text& in, const string::
|
||||
}
|
||||
|
||||
#if 1
|
||||
if (curLineLength != 1 && wi != in.begin())
|
||||
if (curLineLength != 1 && wi != 0)
|
||||
{
|
||||
os << " "; // Separate from previous word
|
||||
++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
|
||||
// of white-spaces between encoded words.
|
||||
|
||||
out.clear();
|
||||
out.removeAllWords();
|
||||
|
||||
string::const_iterator p = inStart;
|
||||
const string::const_iterator end = inEnd;
|
||||
@ -608,14 +470,14 @@ void decodeAndUnfoldText(const string::const_iterator& inStart, const string::co
|
||||
|
||||
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
|
||||
{
|
||||
prevWordCharset = defaultCharset;
|
||||
out.append(word(string(prevPos, textEnd), defaultCharset));
|
||||
out.appendWord(new word(string(prevPos, textEnd), defaultCharset));
|
||||
prevIsEncoded = false;
|
||||
}
|
||||
}
|
||||
@ -670,7 +532,7 @@ void decodeAndUnfoldText(const string::const_iterator& inStart, const string::co
|
||||
else if (*encPos == 'Q' || *encPos == 'q')
|
||||
{
|
||||
theEncoder = new encoderQP;
|
||||
theEncoder->properties()["rfc2047"] = true;
|
||||
theEncoder->getProperties()["rfc2047"] = true;
|
||||
}
|
||||
|
||||
if (theEncoder)
|
||||
@ -698,13 +560,16 @@ void decodeAndUnfoldText(const string::const_iterator& inStart, const string::co
|
||||
|
||||
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
|
||||
{
|
||||
out.append(word(string(prevPos, wordPos), defaultCharset));
|
||||
out.appendWord(new word
|
||||
(string(prevPos, wordPos), 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
|
||||
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
|
||||
{
|
||||
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
|
||||
@ -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
|
||||
|
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
|
||||
|
||||
template <class CONTAINER>
|
||||
@ -125,14 +92,10 @@ namespace vmime
|
||||
|
||||
|
||||
// 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 decodeAndUnfoldText(const string& in, 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
|
||||
@ -210,6 +173,9 @@ namespace vmime
|
||||
// Mime version
|
||||
extern const string MIME_VERSION;
|
||||
|
||||
/** Utility classes. */
|
||||
namespace utility { }
|
||||
|
||||
} // vmime
|
||||
|
||||
|
||||
|
376
src/body.cpp
376
src/body.cpp
@ -23,7 +23,6 @@
|
||||
#include "options.hpp"
|
||||
|
||||
#include "contentTypeField.hpp"
|
||||
#include "contentEncodingField.hpp"
|
||||
|
||||
#include "utility/random.hpp"
|
||||
|
||||
@ -34,16 +33,28 @@ namespace vmime
|
||||
{
|
||||
|
||||
|
||||
body::body(bodyPart& part)
|
||||
: parts(*this), m_part(part), m_header(part.header())
|
||||
body::body()
|
||||
: 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,
|
||||
const string::size_type end, string::size_type* newPosition)
|
||||
{
|
||||
parts.clear();
|
||||
removeAllParts();
|
||||
|
||||
// Check whether the body is a MIME-multipart
|
||||
bool isMultipart = false;
|
||||
@ -52,15 +63,15 @@ void body::parse(const string& buffer, const string::size_type position,
|
||||
try
|
||||
{
|
||||
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;
|
||||
|
||||
try
|
||||
{
|
||||
boundary = ctf.boundary();
|
||||
boundary = ctf.getBoundary();
|
||||
}
|
||||
catch (exceptions::no_such_parameter&)
|
||||
{
|
||||
@ -170,13 +181,17 @@ void body::parse(const string& buffer, const string::size_type position,
|
||||
throw;
|
||||
}
|
||||
|
||||
parts.m_parts.push_back(part);
|
||||
part->m_parent = m_part;
|
||||
|
||||
m_parts.push_back(part);
|
||||
}
|
||||
|
||||
partStart = pos;
|
||||
pos = buffer.find(boundarySep, partStart);
|
||||
}
|
||||
|
||||
m_contents.setData("");
|
||||
|
||||
if (partStart < 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
|
||||
{
|
||||
// Extract the (encoded) contents
|
||||
m_contents.set(buffer, position, end, encoding());
|
||||
m_contents.setData(buffer, position, end, getEncoding());
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
// MIME-Multipart
|
||||
if (parts.size() != 0)
|
||||
if (getPartCount() != 0)
|
||||
{
|
||||
string boundary;
|
||||
|
||||
try
|
||||
if (m_header == NULL)
|
||||
{
|
||||
contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||
(m_header.fields.find(headerField::ContentType));
|
||||
boundary = generateRandomBoundaryString();
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||
(*m_header->findField(fields::CONTENT_TYPE));
|
||||
|
||||
boundary = ctf.boundary();
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
{
|
||||
// Warning: no content-type and no boundary string specified!
|
||||
boundary = generateRandomBoundaryString();
|
||||
}
|
||||
catch (exceptions::no_such_parameter&)
|
||||
{
|
||||
// Warning: no boundary string specified!
|
||||
boundary = generateRandomBoundaryString();
|
||||
boundary = ctf.getBoundary();
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
{
|
||||
// Warning: no content-type and no boundary string specified!
|
||||
boundary = generateRandomBoundaryString();
|
||||
}
|
||||
catch (exceptions::no_such_parameter&)
|
||||
{
|
||||
// Warning: no boundary string specified!
|
||||
boundary = generateRandomBoundaryString();
|
||||
}
|
||||
}
|
||||
|
||||
const string& prologText =
|
||||
m_prologText.empty()
|
||||
? (isRootPart()
|
||||
? options::getInstance()->multipart.prologText()
|
||||
? options::getInstance()->multipart.getPrologText()
|
||||
: NULL_STRING
|
||||
)
|
||||
: m_prologText;
|
||||
@ -229,14 +251,14 @@ void body::generate(utility::outputStream& os, const string::size_type maxLineLe
|
||||
const string& epilogText =
|
||||
m_epilogText.empty()
|
||||
? (isRootPart()
|
||||
? options::getInstance()->multipart.epilogText()
|
||||
? options::getInstance()->multipart.getEpilogText()
|
||||
: NULL_STRING
|
||||
)
|
||||
: m_epilogText;
|
||||
|
||||
if (!prologText.empty())
|
||||
{
|
||||
encodeAndFoldText(os, text(word(prologText, charset())), maxLineLength, 0,
|
||||
encodeAndFoldText(os, text(word(prologText, getCharset())), maxLineLength, 0,
|
||||
NULL, encodeAndFoldFlags::forceNoEncoding | encodeAndFoldFlags::noNewLineSequence);
|
||||
|
||||
os << CRLF;
|
||||
@ -244,12 +266,11 @@ void body::generate(utility::outputStream& os, const string::size_type maxLineLe
|
||||
|
||||
os << "--" << boundary;
|
||||
|
||||
for (std::vector <bodyPart*>::const_iterator
|
||||
p = parts.m_parts.begin() ; p != parts.m_parts.end() ; ++p)
|
||||
for (int p = 0 ; p < getPartCount() ; ++p)
|
||||
{
|
||||
os << CRLF;
|
||||
|
||||
(*p)->generate(os, maxLineLength, 0);
|
||||
getPartAt(p)->generate(os, maxLineLength, 0);
|
||||
|
||||
os << CRLF << "--" << boundary;
|
||||
}
|
||||
@ -258,7 +279,7 @@ void body::generate(utility::outputStream& os, const string::size_type maxLineLe
|
||||
|
||||
if (!epilogText.empty())
|
||||
{
|
||||
encodeAndFoldText(os, text(word(epilogText, charset())), maxLineLength, 0,
|
||||
encodeAndFoldText(os, text(word(epilogText, getCharset())), maxLineLength, 0,
|
||||
NULL, encodeAndFoldFlags::forceNoEncoding | encodeAndFoldFlags::noNewLineSequence);
|
||||
|
||||
os << CRLF;
|
||||
@ -271,7 +292,7 @@ void body::generate(utility::outputStream& os, const string::size_type maxLineLe
|
||||
else
|
||||
{
|
||||
// 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] = '_';
|
||||
|
||||
// Generate a string of random characters
|
||||
unsigned int r = utility::random::time();
|
||||
unsigned int r = utility::random::getTime();
|
||||
unsigned int m = sizeof(unsigned int);
|
||||
|
||||
for (size_t i = 2 ; i < (sizeof(boundary) / sizeof(boundary[0]) - 1) ; ++i)
|
||||
@ -326,7 +347,7 @@ const string body::generateRandomBoundaryString()
|
||||
|
||||
if (--m == 0)
|
||||
{
|
||||
r = utility::random::next();
|
||||
r = utility::random::getNext();
|
||||
m = sizeof(unsigned int);
|
||||
}
|
||||
}
|
||||
@ -363,12 +384,14 @@ const bool body::isValidBoundary(const string& boundary)
|
||||
// Quick-access functions
|
||||
//
|
||||
|
||||
const mediaType body::contentType() const
|
||||
const mediaType body::getContentType() const
|
||||
{
|
||||
try
|
||||
{
|
||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>(m_header.fields.find(headerField::ContentType));
|
||||
return (ctf.value());
|
||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||
(*m_header->findField(fields::CONTENT_TYPE));
|
||||
|
||||
return (ctf.getValue());
|
||||
}
|
||||
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
|
||||
{
|
||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>(m_header.fields.find(headerField::ContentType));
|
||||
const class charset& cs = ctf.charset();
|
||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||
(*m_header->findField(fields::CONTENT_TYPE));
|
||||
|
||||
const class charset& cs = ctf.getCharset();
|
||||
|
||||
return (cs);
|
||||
}
|
||||
@ -400,12 +425,14 @@ const class charset body::charset() const
|
||||
}
|
||||
|
||||
|
||||
const class encoding body::encoding() const
|
||||
const encoding body::getEncoding() const
|
||||
{
|
||||
try
|
||||
{
|
||||
const contentEncodingField& cef = m_header.fields.ContentTransferEncoding();
|
||||
return (cef.value());
|
||||
const contentEncodingField& cef = dynamic_cast<contentEncodingField&>
|
||||
(*m_header->findField(fields::CONTENT_TRANSFER_ENCODING));
|
||||
|
||||
return (cef.getValue());
|
||||
}
|
||||
catch (exceptions::no_such_field&)
|
||||
{
|
||||
@ -417,126 +444,259 @@ const class encoding body::encoding() 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;
|
||||
m_epilogText = b.m_epilogText;
|
||||
body* bdy = new body(NULL);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Parts container //
|
||||
/////////////////////
|
||||
|
||||
|
||||
body::partsContainer::partsContainer(class body& body)
|
||||
: m_body(body)
|
||||
const string& body::getPrologText() const
|
||||
{
|
||||
return (m_prologText);
|
||||
}
|
||||
|
||||
|
||||
// Part insertion
|
||||
void body::partsContainer::append(bodyPart* part)
|
||||
void body::setPrologText(const string& prologText)
|
||||
{
|
||||
part->m_parent = &(m_body.m_part);
|
||||
m_prologText = prologText;
|
||||
}
|
||||
|
||||
m_parts.push_back(part);
|
||||
|
||||
// Check whether we have a boundary string
|
||||
try
|
||||
const string& body::getEpilogText() const
|
||||
{
|
||||
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&>
|
||||
(m_body.m_header.fields.find(headerField::ContentType));
|
||||
|
||||
// Check whether we have a boundary string
|
||||
try
|
||||
{
|
||||
const string boundary = ctf.boundary();
|
||||
contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||
(*m_header->findField(fields::CONTENT_TYPE));
|
||||
|
||||
if (boundary.empty() || !isValidBoundary(boundary))
|
||||
throw exceptions::no_such_parameter("boundary"); // to generate a new one
|
||||
try
|
||||
{
|
||||
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.
|
||||
ctf.boundary() = generateRandomBoundaryString();
|
||||
}
|
||||
// No "Content-Type" field: create a new one and generate
|
||||
// a random boundary string.
|
||||
contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||
(*m_header->getField(fields::CONTENT_TYPE));
|
||||
|
||||
if (ctf.value().type() != mediaTypes::MULTIPART)
|
||||
{
|
||||
// Warning: multi-part body but the Content-Type is
|
||||
// not specified as "multipart/..."
|
||||
ctf.setValue(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED));
|
||||
ctf.setBoundary(generateRandomBoundaryString());
|
||||
}
|
||||
}
|
||||
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::partsContainer::remove(const iterator it)
|
||||
void body::insertPartBefore(bodyPart* beforePart, bodyPart* part)
|
||||
{
|
||||
delete (*it.m_iterator);
|
||||
m_parts.erase(it.m_iterator);
|
||||
initNewPart(part);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
p->m_parent = &(m_body.m_part);
|
||||
|
||||
parts.push_back(p);
|
||||
list.push_back(*it);
|
||||
}
|
||||
|
||||
for (std::vector <bodyPart*>::iterator it = m_parts.begin() ; it != m_parts.end() ; ++it)
|
||||
delete (*it);
|
||||
return (list);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
body(bodyPart& part);
|
||||
body(bodyPart* parentPart);
|
||||
|
||||
public:
|
||||
|
||||
// A sub-class for part manipulation
|
||||
class partsContainer
|
||||
{
|
||||
friend class body;
|
||||
body();
|
||||
~body();
|
||||
|
||||
protected:
|
||||
/** Add a part at the end of the list.
|
||||
*
|
||||
* @param part part to append
|
||||
*/
|
||||
void appendPart(bodyPart* part);
|
||||
|
||||
partsContainer(class body& body);
|
||||
~partsContainer();
|
||||
/** Insert a new part before the specified part.
|
||||
*
|
||||
* @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
|
||||
class const_iterator;
|
||||
/** Insert a new part after the specified part.
|
||||
*
|
||||
* @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
|
||||
{
|
||||
friend class body::partsContainer::const_iterator;
|
||||
friend class body::partsContainer;
|
||||
/** Insert a new part after the specified position.
|
||||
*
|
||||
* @param pos position of the part before the new part
|
||||
* @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) { }
|
||||
iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
||||
/** Remove all parts from the list.
|
||||
*/
|
||||
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); }
|
||||
bodyPart* operator->() const { return (*m_iterator); }
|
||||
/** Tests whether the list of parts is empty.
|
||||
*
|
||||
* @return true if there is no part, false otherwise
|
||||
*/
|
||||
const bool isEmpty() const;
|
||||
|
||||
iterator& operator++() { ++m_iterator; return (*this); }
|
||||
iterator operator++(int) { iterator i(*this); ++m_iterator; return (i); }
|
||||
/** Return the part at the specified position.
|
||||
*
|
||||
* @param pos position
|
||||
* @return part at position 'pos'
|
||||
*/
|
||||
bodyPart* getPartAt(const int pos);
|
||||
|
||||
iterator& operator--() { --m_iterator; return (*this); }
|
||||
iterator operator--(int) { iterator i(*this); --m_iterator; return (i); }
|
||||
/** Return the part at the specified position.
|
||||
*
|
||||
* @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); }
|
||||
iterator& operator-=(difference_type n) { m_iterator -= n; return (*this); }
|
||||
/** Return the part list.
|
||||
*
|
||||
* @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); }
|
||||
const bool operator!=(const iterator& it) const { return (!(*this == it)); }
|
||||
/** Set the prolog text.
|
||||
*
|
||||
* @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
|
||||
{
|
||||
public:
|
||||
/** Return a read-only reference to body contents.
|
||||
*
|
||||
* @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) { }
|
||||
const_iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
||||
const_iterator(const const_iterator& it) : m_iterator(it.m_iterator) { }
|
||||
/** Set the body contents.
|
||||
*
|
||||
* @param contents new body contents
|
||||
*/
|
||||
void setContents(const contentHandler& contents);
|
||||
|
||||
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); }
|
||||
/** Return the media type of the data contained in the body contents.
|
||||
* 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); }
|
||||
const bodyPart* operator->() const { return (*m_iterator); }
|
||||
/** Return the charset of the data contained in the body contents.
|
||||
* 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); }
|
||||
const_iterator operator++(int) { const_iterator i(*this); ++m_iterator; return (i); }
|
||||
/** Return the encoding used to encode the body contents.
|
||||
* 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); }
|
||||
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 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
|
||||
/** Generate a new random boundary string.
|
||||
*
|
||||
* @return randomly generated boundary string
|
||||
*/
|
||||
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);
|
||||
|
||||
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_epilogText;
|
||||
|
||||
contentHandler m_contents;
|
||||
|
||||
bodyPart& m_part;
|
||||
header& m_header;
|
||||
bodyPart* m_part;
|
||||
header* m_header;
|
||||
|
||||
std::vector <bodyPart*> m_parts;
|
||||
|
||||
const bool isRootPart() const;
|
||||
|
||||
void initNewPart(bodyPart* part);
|
||||
|
||||
public:
|
||||
|
||||
using component::parse;
|
||||
|
@ -25,7 +25,7 @@ namespace vmime
|
||||
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
|
@ -37,24 +37,28 @@ namespace vmime
|
||||
|
||||
class bodyPart : public component
|
||||
{
|
||||
friend class body;
|
||||
|
||||
public:
|
||||
|
||||
bodyPart();
|
||||
|
||||
const class header& header() const { return (m_header); }
|
||||
class header& header() { return (m_header); }
|
||||
const header* getHeader() const;
|
||||
header* getHeader();
|
||||
|
||||
const class body& body() const { return (m_body); }
|
||||
class body& body() { return (m_body); }
|
||||
const body* getBody() const;
|
||||
body* getBody();
|
||||
|
||||
bodyPart* parent() const { return (m_parent); }
|
||||
bodyPart* getParentPart() const;
|
||||
|
||||
bodyPart* clone() const;
|
||||
void copyFrom(const component& other);
|
||||
bodyPart& operator=(const bodyPart& other);
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
class header m_header;
|
||||
class body m_body;
|
||||
header m_header;
|
||||
body m_body;
|
||||
|
||||
bodyPart* m_parent;
|
||||
|
||||
@ -66,11 +70,6 @@ public:
|
||||
// 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;
|
||||
|
||||
|
||||
// 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 "platformDependant.hpp"
|
||||
|
||||
#include "utility/stringUtils.hpp"
|
||||
|
||||
|
||||
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,
|
||||
const charset& source, const charset& dest)
|
||||
{
|
||||
// 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)
|
||||
{
|
||||
@ -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>
|
||||
void charset::iconvert(const STRINGF& in, STRINGT& out, const charset& from, const charset& to)
|
||||
{
|
||||
// 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 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
|
||||
|
||||
/** 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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
iconvert(in, out, charset("WCHAR_T"), ch);
|
||||
@ -248,37 +216,21 @@ void charset::encode(const wstring& in, string& out, const charset& ch)
|
||||
#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)
|
||||
{
|
||||
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()
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@ -292,7 +244,7 @@ charset& charset::operator=(const string& name)
|
||||
|
||||
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
|
||||
|
@ -41,28 +41,74 @@ 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);
|
||||
|
||||
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();
|
||||
|
||||
#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);
|
||||
|
||||
/** 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);
|
||||
#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);
|
||||
|
||||
// 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);
|
||||
|
||||
protected:
|
||||
charset* clone() const;
|
||||
void copyFrom(const component& other);
|
||||
|
||||
private:
|
||||
|
||||
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 "base.hpp"
|
||||
|
||||
#include <sstream>
|
||||
|
||||
@ -26,6 +27,11 @@ namespace vmime
|
||||
{
|
||||
|
||||
|
||||
component::~component()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void component::parse(const string& buffer)
|
||||
{
|
||||
parse(buffer, 0, buffer.length(), NULL);
|
||||
|
@ -34,11 +34,9 @@ namespace vmime
|
||||
|
||||
class component
|
||||
{
|
||||
protected:
|
||||
public:
|
||||
|
||||
virtual ~component() {}
|
||||
|
||||
protected:
|
||||
virtual ~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;
|
||||
|
||||
public:
|
||||
|
||||
/** Generate RFC-2822/MIME data for this component.
|
||||
*
|
||||
* \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
|
||||
* @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.
|
||||
*
|
||||
@ -75,6 +71,21 @@ public:
|
||||
* @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;
|
||||
|
||||
/** 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
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
namespace vmime
|
||||
{
|
||||
// Media types (predefined types)
|
||||
/** Constants for media types. */
|
||||
namespace mediaTypes
|
||||
{
|
||||
// Types
|
||||
@ -67,7 +67,7 @@ namespace vmime
|
||||
}
|
||||
|
||||
|
||||
// Encoding types
|
||||
/** Constants for encoding types. */
|
||||
namespace encodingTypes
|
||||
{
|
||||
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
|
||||
{
|
||||
extern const string::value_type* const INLINE;
|
||||
@ -87,7 +87,7 @@ namespace vmime
|
||||
}
|
||||
|
||||
|
||||
// Charsets
|
||||
/** Constants for charsets. */
|
||||
namespace charsets
|
||||
{
|
||||
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_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 "exception.hpp"
|
||||
|
||||
#include "standardParams.hpp"
|
||||
|
||||
|
||||
namespace vmime
|
||||
{
|
||||
@ -30,32 +32,69 @@ contentDispositionField::contentDispositionField()
|
||||
}
|
||||
|
||||
|
||||
void contentDispositionField::parseValue(const string& buffer, const string::size_type position,
|
||||
const string::size_type end)
|
||||
contentDispositionField::contentDispositionField(contentDispositionField&)
|
||||
: 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;
|
||||
return (*this);
|
||||
dynamic_cast <dateParameter&>(*getParameter("creation-date")).setValue(creationDate);
|
||||
}
|
||||
|
||||
|
||||
void contentDispositionField::copyFrom(const headerField& field)
|
||||
const datetime& contentDispositionField::getModificationDate() const
|
||||
{
|
||||
const contentDispositionField& source = dynamic_cast<const contentDispositionField&>(field);
|
||||
m_value = source.m_value;
|
||||
return (dynamic_cast <const dateParameter&>(*findParameter("modification-date")).getValue());
|
||||
}
|
||||
|
||||
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 "disposition.hpp"
|
||||
#include "genericField.hpp"
|
||||
|
||||
#include "dateParameter.hpp"
|
||||
#include "textParameter.hpp"
|
||||
#include "disposition.hpp"
|
||||
#include "dateTime.hpp"
|
||||
|
||||
|
||||
namespace vmime
|
||||
{
|
||||
|
||||
|
||||
class contentDispositionField : public parameterizedHeaderField
|
||||
class contentDispositionField : public parameterizedHeaderField, public genericField <disposition>
|
||||
{
|
||||
friend class headerFieldFactory::registerer <contentDispositionField>;
|
||||
|
||||
protected:
|
||||
|
||||
contentDispositionField();
|
||||
contentDispositionField(contentDispositionField&);
|
||||
|
||||
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); }
|
||||
disposition& value() { return (m_value); }
|
||||
const datetime& getReadDate() const;
|
||||
void setReadDate(const datetime& readDate);
|
||||
|
||||
const datetime& creationDate() const { return (dynamic_cast<const dateParameter&>(parameters.find("creation-date")).value()); }
|
||||
datetime& creationDate() { return (dynamic_cast<dateParameter&>(parameters.get("creation-date")).value()); }
|
||||
const string getFilename() const;
|
||||
void setFilename(const string& filename);
|
||||
|
||||
const datetime& modificationDate() const { return (dynamic_cast<const dateParameter&>(parameters.find("modification-date")).value()); }
|
||||
datetime& modificationDate() { return (dynamic_cast<dateParameter&>(parameters.get("modification-date")).value()); }
|
||||
|
||||
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;
|
||||
const string getSize() const;
|
||||
void setSize(const string& size);
|
||||
};
|
||||
|
||||
|
||||
|
@ -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_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_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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
set(buffer, NO_ENCODING);
|
||||
setData(buffer, NO_ENCODING);
|
||||
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> theEncoder(enc.getEncoder());
|
||||
|
||||
theEncoder->properties()["maxlinelength"] = maxLineLength;
|
||||
theEncoder->getProperties()["maxlinelength"] = maxLineLength;
|
||||
|
||||
switch (m_type)
|
||||
{
|
||||
@ -234,7 +234,7 @@ void contentHandler::generate(utility::outputStream& os, const vmime::encoding&
|
||||
else
|
||||
{
|
||||
utility::auto_ptr <encoder> theEncoder(enc.getEncoder());
|
||||
theEncoder->properties()["maxlinelength"] = maxLineLength;
|
||||
theEncoder->getProperties()["maxlinelength"] = maxLineLength;
|
||||
|
||||
// Encode the contents
|
||||
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)
|
||||
{
|
||||
@ -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);
|
||||
}
|
||||
@ -360,7 +360,7 @@ const bool contentHandler::isEncoded() const
|
||||
}
|
||||
|
||||
|
||||
const vmime::encoding& contentHandler::encoding() const
|
||||
const vmime::encoding& contentHandler::getEncoding() const
|
||||
{
|
||||
return (m_encoding);
|
||||
}
|
||||
|
@ -62,10 +62,10 @@ public:
|
||||
//
|
||||
// The 'length' parameter is optional (user-defined). You can pass 0 if you want,
|
||||
// VMime does not make use of it.
|
||||
void set(const utility::stringProxy& str, const vmime::encoding& enc = NO_ENCODING);
|
||||
void set(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 set(utility::inputStream* const is, const utility::stream::size_type length, const bool own, const vmime::encoding& enc = NO_ENCODING);
|
||||
void setData(const utility::stringProxy& str, const vmime::encoding& enc = NO_ENCODING);
|
||||
void setData(const string& buffer, 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 setData(utility::inputStream* const is, const utility::stream::size_type length, const bool own, const vmime::encoding& enc = NO_ENCODING);
|
||||
|
||||
// For compatibility
|
||||
contentHandler& operator=(const string& buffer);
|
||||
@ -82,16 +82,16 @@ public:
|
||||
|
||||
// Returns the actual length of the data. WARNING: this can return 0 if no
|
||||
// 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.
|
||||
const bool isEncoded() const;
|
||||
|
||||
// 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.
|
||||
const bool empty() const;
|
||||
const bool isEmpty() const;
|
||||
|
||||
private:
|
||||
|
||||
|
@ -20,6 +20,8 @@
|
||||
#include "contentTypeField.hpp"
|
||||
#include "exception.hpp"
|
||||
|
||||
#include "standardParams.hpp"
|
||||
|
||||
|
||||
namespace vmime
|
||||
{
|
||||
@ -30,32 +32,33 @@ contentTypeField::contentTypeField()
|
||||
}
|
||||
|
||||
|
||||
void contentTypeField::parseValue(const string& buffer,
|
||||
const string::size_type position, const string::size_type end)
|
||||
contentTypeField::contentTypeField(contentTypeField&)
|
||||
: 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;
|
||||
return (*this);
|
||||
dynamic_cast <defaultParameter&>(*getParameter("boundary")).setValue(boundary);
|
||||
}
|
||||
|
||||
|
||||
void contentTypeField::copyFrom(const headerField& field)
|
||||
const charset& contentTypeField::getCharset() const
|
||||
{
|
||||
const contentTypeField& source = dynamic_cast<const contentTypeField&>(field);
|
||||
m_value = source.m_value;
|
||||
return (dynamic_cast <const charsetParameter&>(*findParameter("charset")).getValue());
|
||||
}
|
||||
|
||||
parameterizedHeaderField::copyFrom(field);
|
||||
|
||||
void contentTypeField::setCharset(const charset& ch)
|
||||
{
|
||||
dynamic_cast <charsetParameter&>(*getParameter("charset")).setValue(ch);
|
||||
}
|
||||
|
||||
|
||||
|
@ -22,47 +22,32 @@
|
||||
|
||||
|
||||
#include "parameterizedHeaderField.hpp"
|
||||
#include "genericField.hpp"
|
||||
|
||||
#include "mediaType.hpp"
|
||||
#include "charset.hpp"
|
||||
|
||||
#include "textParameter.hpp"
|
||||
#include "charsetParameter.hpp"
|
||||
|
||||
|
||||
namespace vmime
|
||||
{
|
||||
|
||||
|
||||
class contentTypeField : public parameterizedHeaderField
|
||||
class contentTypeField : public parameterizedHeaderField, public genericField <mediaType>
|
||||
{
|
||||
friend class headerFieldFactory::registerer <contentTypeField>;
|
||||
|
||||
protected:
|
||||
|
||||
contentTypeField();
|
||||
contentTypeField(contentTypeField&);
|
||||
|
||||
public:
|
||||
|
||||
void copyFrom(const headerField& field);
|
||||
const string getBoundary() const;
|
||||
void setBoundary(const string& boundary);
|
||||
|
||||
contentTypeField& operator=(const mediaType& type);
|
||||
|
||||
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;
|
||||
const charset& getCharset() const;
|
||||
void setCharset(const charset& ch);
|
||||
};
|
||||
|
||||
|
||||
|
@ -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))
|
||||
{
|
||||
// Month day
|
||||
comp_t day = 0;
|
||||
int day = 0;
|
||||
|
||||
do
|
||||
{
|
||||
@ -221,7 +221,7 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
||||
if (p < pend && isdigit(*p))
|
||||
{
|
||||
// Year
|
||||
comp_t year = 0;
|
||||
int year = 0;
|
||||
|
||||
do
|
||||
{
|
||||
@ -249,7 +249,7 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
||||
if (p < pend && isdigit(*p))
|
||||
{
|
||||
// Hour
|
||||
comp_t hour = 0;
|
||||
int hour = 0;
|
||||
|
||||
do
|
||||
{
|
||||
@ -271,7 +271,7 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
||||
if (p < pend && isdigit(*p))
|
||||
{
|
||||
// Minute
|
||||
comp_t minute = 0;
|
||||
int minute = 0;
|
||||
|
||||
do
|
||||
{
|
||||
@ -293,7 +293,7 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
||||
if (p < pend && isdigit(*p))
|
||||
{
|
||||
// Second
|
||||
comp_t second = 0;
|
||||
int second = 0;
|
||||
|
||||
do
|
||||
{
|
||||
@ -342,7 +342,7 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
||||
++p;
|
||||
|
||||
// Zone offset (in hour/minutes)
|
||||
comp_t offset = 0;
|
||||
int offset = 0;
|
||||
|
||||
do
|
||||
{
|
||||
@ -351,8 +351,8 @@ void datetime::parse(const string& buffer, const string::size_type position,
|
||||
}
|
||||
while (p < pend && isdigit(*p));
|
||||
|
||||
const comp_t hourOff = offset / 100;
|
||||
const comp_t minOff = offset % 100;
|
||||
const int hourOff = offset / 100;
|
||||
const int minOff = offset % 100;
|
||||
|
||||
if (sign == '+')
|
||||
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",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
|
||||
|
||||
const comp_t z = ((m_zone < 0) ? -m_zone : m_zone);
|
||||
const comp_t zh = z / 60;
|
||||
const comp_t zm = z % 60;
|
||||
const int z = ((m_zone < 0) ? -m_zone : m_zone);
|
||||
const int zh = z / 60;
|
||||
const int zm = z % 60;
|
||||
|
||||
std::ostringstream oss;
|
||||
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_minute << ":"
|
||||
<< 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_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,
|
||||
const comp_t hour, const comp_t minute, const comp_t second,
|
||||
const comp_t zone)
|
||||
datetime::datetime(const int year, const int month, const int day,
|
||||
const int hour, const int minute, const int second,
|
||||
const int zone)
|
||||
: m_year(year), m_month(month), m_day(day),
|
||||
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_month = d.m_month;
|
||||
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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
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;
|
||||
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;
|
||||
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,
|
||||
const comp_t second, const comp_t zone)
|
||||
void datetime::setTime(const int hour, const int minute,
|
||||
const int second, const int zone)
|
||||
{
|
||||
m_hour = hour;
|
||||
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_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;
|
||||
comp_t m = month;
|
||||
int y = year;
|
||||
int m = month;
|
||||
|
||||
// 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
|
||||
const comp_t cent = y / 100;
|
||||
const int cent = y / 100;
|
||||
y %= 100;
|
||||
|
||||
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
|
||||
|
@ -36,13 +36,10 @@ class datetime : public component
|
||||
{
|
||||
public:
|
||||
|
||||
// Data type for a date/time component
|
||||
typedef int comp_t;
|
||||
|
||||
// Constructors
|
||||
datetime();
|
||||
datetime(const comp_t year, const comp_t month, const comp_t 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);
|
||||
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 string& date);
|
||||
|
||||
@ -172,58 +169,60 @@ public:
|
||||
SAT = 6
|
||||
};
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
// Date components
|
||||
comp_t m_year;
|
||||
comp_t m_month;
|
||||
comp_t m_day;
|
||||
int m_year;
|
||||
int m_month;
|
||||
int m_day;
|
||||
|
||||
// Time components
|
||||
comp_t m_hour;
|
||||
comp_t m_minute;
|
||||
comp_t m_second;
|
||||
comp_t m_zone;
|
||||
int m_hour;
|
||||
int m_minute;
|
||||
int m_second;
|
||||
int m_zone;
|
||||
|
||||
public:
|
||||
|
||||
// Get
|
||||
const comp_t year() const { return (m_year); }
|
||||
const comp_t month() const { return (m_month); }
|
||||
const comp_t day() const { return (m_day); }
|
||||
const comp_t hour() const { return (m_hour); }
|
||||
const comp_t minute() const { return (m_minute); }
|
||||
const comp_t second() const { return (m_second); }
|
||||
const comp_t zone() const { return (m_zone); }
|
||||
const int getYear() const;
|
||||
const int getMonth() const;
|
||||
const int getDay() const;
|
||||
const int getHour() const;
|
||||
const int getMinute() const;
|
||||
const int getSecond() const;
|
||||
const int getZone() const;
|
||||
|
||||
void getTime(comp_t& hour, comp_t& minute, comp_t& second, comp_t& zone) const;
|
||||
void getTime(comp_t& hour, comp_t& minute, comp_t& second) const;
|
||||
void getDate(comp_t& year, comp_t& month, comp_t& day) const;
|
||||
void getTime(int& hour, int& minute, int& second, int& zone) const;
|
||||
void getTime(int& hour, int& minute, int& second) const;
|
||||
void getDate(int& year, int& month, int& day) const;
|
||||
|
||||
// Set
|
||||
comp_t& year() { return (m_year); }
|
||||
comp_t& month() { return (m_month); }
|
||||
comp_t& day() { return (m_day); }
|
||||
comp_t& hour() { return (m_hour); }
|
||||
comp_t& minute() { return (m_minute); }
|
||||
comp_t& second() { return (m_second); }
|
||||
comp_t& zone() { return (m_zone); }
|
||||
void setYear(const int year);
|
||||
void setMonth(const int month);
|
||||
void setDay(const int day);
|
||||
void setHour(const int hour);
|
||||
void setMinute(const int minute);
|
||||
void setSecond(const int second);
|
||||
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 setDate(const comp_t year, const comp_t month, const comp_t day);
|
||||
void setTime(const int hour = 0, const int minute = 0, const int second = 0, const int zone = GMT);
|
||||
void setDate(const int year, const int month, const int day);
|
||||
|
||||
// Assignment
|
||||
datetime& operator=(const datetime& d);
|
||||
datetime& operator=(const datetime& other);
|
||||
datetime& operator=(const string& s);
|
||||
|
||||
void copyFrom(const datetime& d);
|
||||
void copyFrom(const component& other);
|
||||
|
||||
datetime* clone() const;
|
||||
|
||||
// Current date and time
|
||||
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:
|
||||
|
||||
|
@ -31,7 +31,7 @@ defaultAttachment::defaultAttachment()
|
||||
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
@ -51,15 +51,12 @@ defaultAttachment::defaultAttachment(const defaultAttachment& attach)
|
||||
}
|
||||
|
||||
|
||||
attachment& defaultAttachment::operator=(const attachment& attach)
|
||||
defaultAttachment& defaultAttachment::operator=(const defaultAttachment& attach)
|
||||
{
|
||||
const defaultAttachment& att =
|
||||
dynamic_cast <const defaultAttachment&>(attach);
|
||||
|
||||
m_type = att.m_type;
|
||||
m_desc = att.m_desc;
|
||||
m_data = att.m_data;
|
||||
m_encoding = att.m_encoding;
|
||||
m_type = attach.m_type;
|
||||
m_desc = attach.m_desc;
|
||||
m_data = attach.m_data;
|
||||
m_encoding = attach.m_encoding;
|
||||
|
||||
return (*this);
|
||||
}
|
||||
@ -69,7 +66,7 @@ void defaultAttachment::generateIn(bodyPart& parent) const
|
||||
{
|
||||
// Create and append a new part for this attachment
|
||||
bodyPart* part = new bodyPart;
|
||||
parent.body().parts.append(part);
|
||||
parent.getBody()->appendPart(part);
|
||||
|
||||
generatePart(*part);
|
||||
}
|
||||
@ -78,13 +75,37 @@ void defaultAttachment::generateIn(bodyPart& parent) const
|
||||
void defaultAttachment::generatePart(bodyPart& part) const
|
||||
{
|
||||
// Set header fields
|
||||
part.header().fields.ContentType() = m_type;
|
||||
if (!m_desc.empty()) part.header().fields.ContentDescription() = m_desc;
|
||||
part.header().fields.ContentTransferEncoding() = m_encoding;
|
||||
part.header().fields.ContentDisposition() = disposition(dispositionTypes::ATTACHMENT);
|
||||
part.getHeader()->ContentType().setValue(m_type);
|
||||
if (!m_desc.isEmpty()) part.getHeader()->ContentDescription().setValue(m_desc);
|
||||
part.getHeader()->ContentTransferEncoding().setValue(m_encoding);
|
||||
part.getHeader()->ContentDisposition().setValue(disposition(dispositionTypes::ATTACHMENT));
|
||||
|
||||
// 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:
|
||||
|
||||
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 defaultAttachment& attach);
|
||||
|
||||
attachment& operator=(const attachment& attach);
|
||||
defaultAttachment& operator=(const defaultAttachment& attach);
|
||||
|
||||
const mediaType& type() const { return (m_type); }
|
||||
const text& description() const { return (m_desc); }
|
||||
const contentHandler& data() const { return (m_data); }
|
||||
const class encoding& encoding() const { return (m_encoding); }
|
||||
const mediaType& getType() const;
|
||||
const text& getDescription() const;
|
||||
const contentHandler& getData() const;
|
||||
const encoding& getEncoding() const;
|
||||
|
||||
protected:
|
||||
|
||||
mediaType m_type; // Media type (eg. "application/octet-stream")
|
||||
text m_desc; // Description (eg. "The image you requested")
|
||||
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).
|
||||
void generateIn(bodyPart& parent) const;
|
||||
|
||||
protected:
|
||||
|
||||
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 "utility/stringUtils.hpp"
|
||||
|
||||
|
||||
namespace vmime
|
||||
@ -31,7 +32,7 @@ disposition::disposition()
|
||||
|
||||
|
||||
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,
|
||||
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)
|
||||
*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)
|
||||
{
|
||||
m_name = toLower(name);
|
||||
m_name = stringUtils::toLower(name);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
@ -40,20 +40,32 @@ public:
|
||||
disposition(const string& name);
|
||||
disposition(const disposition& disp);
|
||||
|
||||
public:
|
||||
|
||||
const string& name() const { return (m_name); }
|
||||
string& name() { return (m_name); }
|
||||
/** Return the disposition type.
|
||||
* 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);
|
||||
|
||||
const bool operator==(const disposition& value) const;
|
||||
const bool operator!=(const disposition& value) const;
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
string m_name;
|
||||
|
||||
|
@ -35,31 +35,31 @@ encoder::~encoder()
|
||||
}
|
||||
|
||||
|
||||
const propertySet& encoder::properties() const
|
||||
const propertySet& encoder::getProperties() const
|
||||
{
|
||||
return (m_props);
|
||||
}
|
||||
|
||||
|
||||
propertySet& encoder::properties()
|
||||
propertySet& encoder::getProperties()
|
||||
{
|
||||
return (m_props);
|
||||
}
|
||||
|
||||
|
||||
const propertySet& encoder::results() const
|
||||
const propertySet& encoder::getResults() const
|
||||
{
|
||||
return (m_results);
|
||||
}
|
||||
|
||||
|
||||
propertySet& encoder::results()
|
||||
propertySet& encoder::getResults()
|
||||
{
|
||||
return (m_results);
|
||||
}
|
||||
|
||||
|
||||
const std::vector <string> encoder::availableProperties() const
|
||||
const std::vector <string> encoder::getAvailableProperties() const
|
||||
{
|
||||
std::vector <string> list;
|
||||
return (list);
|
||||
|
@ -57,30 +57,30 @@ public:
|
||||
*
|
||||
* @return properties of the encoder
|
||||
*/
|
||||
const propertySet& properties() const;
|
||||
const propertySet& getProperties() const;
|
||||
|
||||
/** Return the properties of the encoder.
|
||||
*
|
||||
* @return properties of the encoder
|
||||
*/
|
||||
propertySet& properties();
|
||||
propertySet& getProperties();
|
||||
|
||||
/** Return a list of property names that can be set for
|
||||
* this encoder.
|
||||
*
|
||||
* @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 results returned by the encoder
|
||||
*/
|
||||
const propertySet& results() const;
|
||||
const propertySet& getResults() const;
|
||||
|
||||
protected:
|
||||
|
||||
propertySet& results();
|
||||
propertySet& getResults();
|
||||
|
||||
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");
|
||||
|
||||
@ -70,7 +70,7 @@ const utility::stream::size_type encoderB64::encode(utility::inputStream& in, ut
|
||||
{
|
||||
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 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 decode(utility::inputStream& in, utility::outputStream& out);
|
||||
|
||||
const std::vector <string> availableProperties() const;
|
||||
const std::vector <string> getAvailableProperties() const;
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -46,24 +46,58 @@ encoderFactory::encoderFactory()
|
||||
|
||||
encoderFactory::~encoderFactory()
|
||||
{
|
||||
for (NameMap::iterator it = m_nameMap.begin() ; it != m_nameMap.end() ; ++it)
|
||||
delete ((*it).second);
|
||||
for (std::vector <registeredEncoder*>::const_iterator it = m_encoders.begin() ;
|
||||
it != m_encoders.end() ; ++it)
|
||||
{
|
||||
delete (*it);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
return (NULL);
|
||||
res.push_back(*it);
|
||||
}
|
||||
|
||||
return (res);
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "encoder.hpp"
|
||||
#include "utility/singleton.hpp"
|
||||
#include "utility/stringUtils.hpp"
|
||||
|
||||
|
||||
namespace vmime
|
||||
@ -43,6 +44,7 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
/** Information about a registered encoder. */
|
||||
class registeredEncoder
|
||||
{
|
||||
friend class encoderFactory;
|
||||
@ -53,9 +55,9 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
virtual encoder* create() = 0;
|
||||
virtual encoder* create() const = 0;
|
||||
|
||||
virtual const string& name() const = 0;
|
||||
virtual const string& getName() const = 0;
|
||||
};
|
||||
|
||||
private:
|
||||
@ -71,12 +73,12 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
encoder* create()
|
||||
encoder* create() const
|
||||
{
|
||||
return new E;
|
||||
}
|
||||
|
||||
const string& name() const
|
||||
const string& getName() const
|
||||
{
|
||||
return (m_name);
|
||||
}
|
||||
@ -87,93 +89,56 @@ private:
|
||||
};
|
||||
|
||||
|
||||
typedef std::map <string, registeredEncoder*> NameMap;
|
||||
NameMap m_nameMap;
|
||||
std::vector <registeredEncoder*> m_encoders;
|
||||
|
||||
public:
|
||||
|
||||
/** Register a new encoder by its encoding name.
|
||||
*
|
||||
* @param name encoding name
|
||||
*/
|
||||
template <class E>
|
||||
void registerName(const string& name)
|
||||
{
|
||||
const string _name = toLower(name);
|
||||
m_nameMap.insert(NameMap::value_type(_name,
|
||||
new registeredEncoderImpl <E>(_name)));
|
||||
m_encoders.push_back(new registeredEncoderImpl <E>(stringUtils::toLower(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);
|
||||
|
||||
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
|
||||
{
|
||||
friend class encoderFactory;
|
||||
|
||||
public:
|
||||
|
||||
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()); }
|
||||
/** Return a list of all registered encoders.
|
||||
*
|
||||
* @return list of registered encoders
|
||||
*/
|
||||
const std::vector <const registeredEncoder*> getEncoderList() const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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");
|
||||
|
||||
@ -84,10 +84,10 @@ const utility::stream::size_type encoderQP::encode(utility::inputStream& in, uti
|
||||
in.reset(); // may not work...
|
||||
|
||||
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 text = properties().get <bool>("text", false); // binary mode by default
|
||||
const bool rfc2047 = getProperties().getProperty <bool>("rfc2047", false);
|
||||
const bool text = getProperties().getProperty <bool>("text", false); // binary mode by default
|
||||
|
||||
const bool cutLines = (propMaxLineLength != (string::size_type) -1);
|
||||
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...
|
||||
|
||||
// Process the data
|
||||
const bool rfc2047 = properties().get <bool>("rfc2047", false);
|
||||
const bool rfc2047 = getProperties().getProperty <bool>("rfc2047", false);
|
||||
|
||||
char buffer[16384];
|
||||
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 decode(utility::inputStream& in, utility::outputStream& out);
|
||||
|
||||
const std::vector <string> availableProperties() const;
|
||||
const std::vector <string> getAvailableProperties() const;
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -27,15 +27,15 @@ namespace vmime
|
||||
|
||||
encoderUUE::encoderUUE()
|
||||
{
|
||||
properties()["mode"] = 644;
|
||||
properties()["filename"] = "no_name";
|
||||
properties()["maxlinelength"] = 46;
|
||||
getProperties()["mode"] = 644;
|
||||
getProperties()["filename"] = "no_name";
|
||||
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");
|
||||
|
||||
@ -63,11 +63,11 @@ const utility::stream::size_type encoderUUE::encode(utility::inputStream& in, ut
|
||||
{
|
||||
in.reset(); // may not work...
|
||||
|
||||
const string propFilename = properties().get <string>("filename", "");
|
||||
const string propMode = properties().get <string>("mode", "644");
|
||||
const string propFilename = getProperties().getProperty <string>("filename", "");
|
||||
const string propMode = getProperties().getProperty <string>("mode", "644");
|
||||
|
||||
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));
|
||||
|
||||
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;
|
||||
|
||||
results()["mode"] = string(modeStart, p);
|
||||
getResults()["mode"] = string(modeStart, 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;
|
||||
|
||||
results()["filename"] = string(filenameStart, p);
|
||||
getResults()["filename"] = string(filenameStart, p);
|
||||
}
|
||||
// No filename or mode specified
|
||||
else
|
||||
{
|
||||
results()["filename"] = "untitled";
|
||||
results()["mode"] = 644;
|
||||
getResults()["filename"] = "untitled";
|
||||
getResults()["mode"] = 644;
|
||||
}
|
||||
|
||||
continue;
|
||||
|
@ -40,7 +40,7 @@ public:
|
||||
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 std::vector <string> availableProperties() const;
|
||||
const std::vector <string> getAvailableProperties() const;
|
||||
};
|
||||
|
||||
|
||||
|
@ -35,7 +35,7 @@ encoding::encoding()
|
||||
|
||||
|
||||
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,
|
||||
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)
|
||||
*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);
|
||||
}
|
||||
|
||||
|
||||
encoding& encoding::operator=(const string& name)
|
||||
{
|
||||
m_name = toLower(name);
|
||||
m_name = stringUtils::toLower(name);
|
||||
return (*this);
|
||||
}
|
||||
|
||||
|
||||
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 */)
|
||||
{
|
||||
// TODO: a better solution to do that?
|
||||
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
|
||||
|
@ -46,27 +46,56 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
const string& name() const { return (m_name); }
|
||||
string& name() { return (m_name); }
|
||||
/** Return the name of the encoding.
|
||||
* 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);
|
||||
|
||||
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);
|
||||
|
||||
/** 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);
|
||||
|
||||
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;
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
string m_name;
|
||||
|
||||
|
@ -45,6 +45,8 @@ public:
|
||||
};
|
||||
|
||||
|
||||
/** List of all VMime 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
|
||||
{
|
||||
public:
|
||||
|
@ -40,7 +40,7 @@ fileAttachment::fileAttachment(const string& filename, const mediaType& type, co
|
||||
|
||||
|
||||
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_desc = desc;
|
||||
@ -62,7 +62,7 @@ void fileAttachment::setData(const string& filename)
|
||||
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);
|
||||
|
||||
contentDispositionField& cdf = part.header().fields.ContentDisposition();
|
||||
contentDispositionField& cdf = part.getHeader()->ContentDisposition();
|
||||
|
||||
if (m_fileInfo.hasSize()) cdf.size() = toString(m_fileInfo.getSize());
|
||||
if (m_fileInfo.hasFilename()) cdf.filename() = m_fileInfo.getFilename();
|
||||
if (m_fileInfo.hasCreationDate()) cdf.creationDate() = m_fileInfo.getCreationDate();
|
||||
if (m_fileInfo.hasModificationDate()) cdf.modificationDate() = m_fileInfo.getModificationDate();
|
||||
if (m_fileInfo.hasReadDate()) cdf.readDate() = m_fileInfo.getReadDate();
|
||||
if (m_fileInfo.hasSize()) cdf.setSize(stringUtils::toString(m_fileInfo.getSize()));
|
||||
if (m_fileInfo.hasFilename()) cdf.setFilename(m_fileInfo.getFilename());
|
||||
if (m_fileInfo.hasCreationDate()) cdf.setCreationDate(m_fileInfo.getCreationDate());
|
||||
if (m_fileInfo.hasModificationDate()) cdf.setModificationDate(m_fileInfo.getModificationDate());
|
||||
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
|
||||
//
|
||||
|
@ -33,7 +33,7 @@ class fileAttachment : public defaultAttachment
|
||||
public:
|
||||
|
||||
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
|
||||
{
|
||||
@ -71,14 +71,14 @@ public:
|
||||
datetime* m_readDate;
|
||||
};
|
||||
|
||||
const class fileInfo& fileInfo() const { return (m_fileInfo); }
|
||||
class fileInfo& fileInfo() { return (m_fileInfo); }
|
||||
const fileInfo& getFileInfo() const;
|
||||
fileInfo& getFileInfo();
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
void setData(const string& filename);
|
||||
|
||||
class fileInfo m_fileInfo;
|
||||
fileInfo m_fileInfo;
|
||||
|
||||
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()
|
||||
{
|
||||
removeAllFields();
|
||||
}
|
||||
|
||||
|
||||
@ -59,7 +60,7 @@ void header::parse(const string& buffer, const string::size_type position,
|
||||
{
|
||||
string::size_type pos = position;
|
||||
|
||||
fields.clear();
|
||||
removeAllFields();
|
||||
|
||||
while (pos < end)
|
||||
{
|
||||
@ -181,8 +182,8 @@ void header::parse(const string& buffer, const string::size_type position,
|
||||
}
|
||||
|
||||
// Add a new field to list
|
||||
fields.m_fields.push_back(headerFieldFactory::getInstance()->
|
||||
create(headerField::nameToType(name), name, contents));
|
||||
m_fields.push_back(headerFieldFactory::getInstance()->
|
||||
create(name, contents));
|
||||
}
|
||||
}
|
||||
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
|
||||
{
|
||||
// Generate the fields
|
||||
for (std::vector <headerField*>::const_iterator
|
||||
it = fields.m_fields.begin() ; it != fields.m_fields.end() ; ++it)
|
||||
for (std::vector <headerField*>::const_iterator it = m_fields.begin() ;
|
||||
it != m_fields.end() ; ++it)
|
||||
{
|
||||
(*it)->generate(os, maxLineLength);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////
|
||||
// Fields container //
|
||||
//////////////////////
|
||||
|
||||
|
||||
header::fieldsContainer::fieldsContainer()
|
||||
const bool header::hasField(const string& fieldName) const
|
||||
{
|
||||
}
|
||||
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();
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
const bool header::fieldsContainer::has(const string& fieldName) const
|
||||
headerField* header::findField(const string& fieldName) const
|
||||
{
|
||||
headerField::Types type = headerField::nameToType(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);
|
||||
const string name = stringUtils::toLower(fieldName);
|
||||
|
||||
// Find the first field that matches the specified name
|
||||
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);
|
||||
for ( ; pos != end && stringUtils::toLower((*pos)->getName()) != name ; ++pos);
|
||||
|
||||
// No field with this name can be found
|
||||
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 (**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;
|
||||
|
||||
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);
|
||||
const string name = stringUtils::toLower(fieldName);
|
||||
|
||||
std::vector <headerField*> result;
|
||||
|
||||
@ -365,7 +344,7 @@ std::vector <headerField*> header::fieldsContainer::findAllByName(const string&
|
||||
for ( ; pos != end ; ++pos)
|
||||
{
|
||||
// Add the header if it matches the specified type
|
||||
if (toLower((*pos)->name()) == name)
|
||||
if (stringUtils::toLower((*pos)->getName()) == name)
|
||||
{
|
||||
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
|
||||
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);
|
||||
const string name = stringUtils::toLower(fieldName);
|
||||
|
||||
// Find the first field that matches the specified name
|
||||
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);
|
||||
for ( ; pos != end && stringUtils::toLower((*pos)->getName()) != name ; ++pos);
|
||||
|
||||
// If no field with this name can be found, create a new one
|
||||
if (pos == end)
|
||||
{
|
||||
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 (*field);
|
||||
return (field);
|
||||
}
|
||||
// Else, return a reference to the existing field
|
||||
else
|
||||
{
|
||||
return (**pos);
|
||||
return (*pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void header::fieldsContainer::insertSorted(headerField* field)
|
||||
void header::appendField(headerField* field)
|
||||
{
|
||||
const headerField::Types type = field->type();
|
||||
std::vector <headerField*>::iterator i;
|
||||
|
||||
for (i = m_fields.begin() ; (i != m_fields.end()) && ((*i)->type() < type) ; ++i);
|
||||
|
||||
m_fields.insert(i, field);
|
||||
m_fields.push_back(field);
|
||||
}
|
||||
|
||||
|
||||
// Field insertion
|
||||
void header::fieldsContainer::append(const headerField& field)
|
||||
void header::insertFieldBefore(headerField* beforeField, 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::fieldsContainer::remove(const iterator it)
|
||||
void header::insertFieldAfter(headerField* afterField, headerField* field)
|
||||
{
|
||||
delete (*it.m_iterator);
|
||||
m_fields.erase(it.m_iterator);
|
||||
const std::vector <headerField*>::iterator it = std::find
|
||||
(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)
|
||||
delete (*it);
|
||||
|
||||
m_fields.clear();
|
||||
m_fields.insert(m_fields.begin() + pos + 1, field);
|
||||
}
|
||||
|
||||
|
||||
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)
|
||||
fields.push_back((*it)->clone());
|
||||
if (it == m_fields.end())
|
||||
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());
|
||||
std::copy(fields.begin(), fields.end(), m_fields.begin());
|
||||
m_fields.erase(it);
|
||||
}
|
||||
|
||||
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 "headerFieldFactory.hpp"
|
||||
|
||||
#include "addressListField.hpp"
|
||||
#include "mailboxListField.hpp"
|
||||
#include "mailboxField.hpp"
|
||||
#include "textField.hpp"
|
||||
#include "dateField.hpp"
|
||||
#include "contentTypeField.hpp"
|
||||
#include "contentEncodingField.hpp"
|
||||
#include "defaultField.hpp"
|
||||
#include "contentDispositionField.hpp"
|
||||
#include "messageIdField.hpp"
|
||||
|
||||
#include "standardFields.hpp"
|
||||
#include "standardParams.hpp"
|
||||
|
||||
|
||||
namespace vmime
|
||||
@ -61,196 +57,166 @@ public:
|
||||
header();
|
||||
~header();
|
||||
|
||||
// A sub-class for field manipulation
|
||||
class fieldsContainer
|
||||
{
|
||||
friend class header;
|
||||
#define FIELD_ACCESS(methodName, fieldName, type) \
|
||||
type& methodName() { return dynamic_cast <type&> \
|
||||
(*getField(fields::fieldName)); } \
|
||||
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();
|
||||
~fieldsContainer();
|
||||
FIELD_ACCESS(To, TO, addressListField)
|
||||
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
|
||||
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))); }
|
||||
#undef FIELD_ACCESS
|
||||
|
||||
const mailboxField& From() const { return (dynamic_cast<mailboxField&>(find(headerField::From))); }
|
||||
const mailboxField& Sender() const { return (dynamic_cast<mailboxField&>(find(headerField::Sender))); }
|
||||
const mailboxField& ReplyTo() const { return (dynamic_cast<mailboxField&>(find(headerField::ReplyTo))); }
|
||||
const mailboxField& DeliveredTo() const { return (dynamic_cast<mailboxField&>(find(headerField::DeliveredTo))); }
|
||||
const addressListField& To() const { return (dynamic_cast<addressListField&>(find(headerField::To))); }
|
||||
const addressListField& Cc() const { return (dynamic_cast<addressListField&>(find(headerField::Cc))); }
|
||||
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 name exists.
|
||||
*
|
||||
* @return true if at least one field with the specified name
|
||||
* exists, or false otherwise
|
||||
*/
|
||||
const bool hasField(const string& fieldName) const;
|
||||
|
||||
// Checks whether (at least) one field with this type/name exists
|
||||
const bool has(const headerField::Types fieldType) const;
|
||||
const bool has(const string& fieldName) const;
|
||||
/** Find the first field that matches the specified name.
|
||||
* If no field is found, an exception is thrown.
|
||||
*
|
||||
* @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.
|
||||
// If no field is found, an exception is thrown.
|
||||
headerField& find(const headerField::Types fieldType) const;
|
||||
headerField& find(const string& fieldName) const;
|
||||
/** Find all fields that match the specified name.
|
||||
* If no field is found, an empty vector is returned.
|
||||
*
|
||||
* @return list of fields with the specified name
|
||||
*/
|
||||
std::vector <headerField*> findAllFields(const string& fieldName);
|
||||
|
||||
// Find all fields that matche the specified type/name.
|
||||
// If no field is found, an empty vector is returned.
|
||||
std::vector <headerField*> findAllByType(const headerField::Types fieldType);
|
||||
std::vector <headerField*> findAllByName(const string& fieldName);
|
||||
/** Find the first field that matches the specified name.
|
||||
* If no field is found, one will be created and inserted into
|
||||
* the header.
|
||||
*
|
||||
* @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.
|
||||
// If no field is found, one will be created.
|
||||
headerField& get(const headerField::Types fieldType);
|
||||
headerField& get(const string& fieldName);
|
||||
/** Add a field at the end of the list.
|
||||
*
|
||||
* @param field field to append
|
||||
*/
|
||||
void appendField(headerField* field);
|
||||
|
||||
// Field iterator
|
||||
class const_iterator;
|
||||
/** Insert a new field before the specified field.
|
||||
*
|
||||
* @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
|
||||
{
|
||||
friend class header::fieldsContainer::const_iterator;
|
||||
friend class header::fieldsContainer;
|
||||
/** Insert a new field before the specified position.
|
||||
*
|
||||
* @param pos position at which to insert the new field (0 to insert at
|
||||
* 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) { }
|
||||
iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
||||
/** Remove the specified field from the list.
|
||||
*
|
||||
* @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); }
|
||||
headerField* operator->() const { return (*m_iterator); }
|
||||
/** Remove all fields from the list.
|
||||
*/
|
||||
void removeAllFields();
|
||||
|
||||
iterator& operator++() { ++m_iterator; return (*this); }
|
||||
iterator operator++(int) { iterator i(*this); ++m_iterator; return (i); }
|
||||
/** Return the number of fields in the list.
|
||||
*
|
||||
* @return number of fields
|
||||
*/
|
||||
const int getFieldCount() const;
|
||||
|
||||
iterator& operator--() { --m_iterator; return (*this); }
|
||||
iterator operator--(int) { iterator i(*this); --m_iterator; return (i); }
|
||||
/** Tests whether the list of fields is empty.
|
||||
*
|
||||
* @return true if there is no field, false otherwise
|
||||
*/
|
||||
const bool isEmpty() const;
|
||||
|
||||
iterator& operator+=(difference_type n) { m_iterator += n; return (*this); }
|
||||
iterator& operator-=(difference_type n) { m_iterator -= n; return (*this); }
|
||||
/** Return the field at the specified position.
|
||||
*
|
||||
* @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); }
|
||||
const bool operator!=(const iterator& it) const { return (!(*this == it)); }
|
||||
/** Return the field list.
|
||||
*
|
||||
* @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
|
||||
{
|
||||
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);
|
||||
std::vector <headerField*> m_fields;
|
||||
|
||||
public:
|
||||
|
||||
|
@ -26,13 +26,13 @@ namespace vmime
|
||||
|
||||
|
||||
headerField::headerField()
|
||||
: m_type(Custom), m_name("Undefined")
|
||||
: m_name("X-Undefined")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
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* field = NULL;
|
||||
|
||||
if (m_type == Custom)
|
||||
field = headerFieldFactory::getInstance()->create(m_name);
|
||||
else
|
||||
field = headerFieldFactory::getInstance()->create(m_type);
|
||||
headerField* field = headerFieldFactory::getInstance()->create(m_name);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
m_name = field.m_name;
|
||||
getValue().parse(buffer, position, end, newPosition);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
{
|
||||
if (m_type == Custom)
|
||||
{
|
||||
os << m_name + ": ";
|
||||
os << m_name + ": ";
|
||||
|
||||
if (newLinePos)
|
||||
*newLinePos = curLinePos + m_name.length() + 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
const string name = typeToName(m_type);
|
||||
|
||||
os << name + ": ";
|
||||
|
||||
if (newLinePos)
|
||||
*newLinePos = curLinePos + name.length() + 2;
|
||||
}
|
||||
getValue().generate(os, maxLineLength, curLinePos + m_name.length() + 2, newLinePos);
|
||||
}
|
||||
|
||||
|
||||
/** Return the field type corresponding to the specified name.
|
||||
*
|
||||
* @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)
|
||||
const string headerField::getName() const
|
||||
{
|
||||
switch (name[0])
|
||||
{
|
||||
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 (m_name);
|
||||
}
|
||||
|
||||
|
||||
/** 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
|
||||
{
|
||||
return (m_type == Custom);
|
||||
return (m_name.length() > 2 && m_name[0] == 'X' && m_name[1] == '-');
|
||||
}
|
||||
|
||||
|
||||
|
@ -45,65 +45,53 @@ public:
|
||||
|
||||
~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
|
||||
// in the message header)
|
||||
enum Types
|
||||
{
|
||||
Received, // Relay
|
||||
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;
|
||||
/** Return the name of this field.
|
||||
*
|
||||
* @return field name
|
||||
*/
|
||||
const string getName() 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;
|
||||
|
||||
virtual void copyFrom(const headerField& field);
|
||||
headerField& operator=(const headerField& field);
|
||||
headerField* clone() const;
|
||||
/** Return the read-only value object attached to this field.
|
||||
*
|
||||
* @return read-only value object
|
||||
*/
|
||||
virtual const component& getValue() const = 0;
|
||||
|
||||
static const Types nameToType(const string& name);
|
||||
static const string typeToName(const Types type);
|
||||
/** Return the value object attached to this field.
|
||||
*
|
||||
* @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;
|
||||
|
||||
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;
|
||||
|
||||
private:
|
||||
|
||||
string m_name;
|
||||
};
|
||||
|
||||
|
||||
|
@ -20,21 +20,11 @@
|
||||
#include "headerFieldFactory.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 "contentTypeField.hpp"
|
||||
#include "contentEncodingField.hpp"
|
||||
#include "contentDispositionField.hpp"
|
||||
#include "messageIdField.hpp"
|
||||
|
||||
|
||||
namespace vmime
|
||||
@ -43,28 +33,28 @@ namespace vmime
|
||||
|
||||
headerFieldFactory::headerFieldFactory()
|
||||
{
|
||||
// Register some default field types
|
||||
registerType <mailboxField>(headerField::From);
|
||||
registerType <addressListField>(headerField::To);
|
||||
registerType <addressListField>(headerField::Cc);
|
||||
registerType <addressListField>(headerField::Bcc);
|
||||
registerType <mailboxField>(headerField::Sender);
|
||||
registerType <dateField>(headerField::Date);
|
||||
registerType <relayField>(headerField::Received);
|
||||
registerType <textField>(headerField::Subject);
|
||||
registerType <mailboxField>(headerField::ReplyTo);
|
||||
registerType <mailboxField>(headerField::DeliveredTo);
|
||||
registerType <textField>(headerField::Organization);
|
||||
registerType <textField>(headerField::UserAgent);
|
||||
registerType <mailboxField>(headerField::ReturnPath);
|
||||
registerType <contentTypeField>(headerField::ContentType);
|
||||
registerType <contentEncodingField>(headerField::ContentTransferEncoding);
|
||||
registerType <textField>(headerField::ContentDescription);
|
||||
registerType <defaultField>(headerField::MimeVersion);
|
||||
registerType <contentDispositionField>(headerField::ContentDisposition);
|
||||
registerType <messageIdField>(headerField::ContentId);
|
||||
registerType <messageIdField>(headerField::MessageId);
|
||||
registerType <defaultField>(headerField::ContentLocation);
|
||||
// Register some default fields
|
||||
registerName <mailboxField>(vmime::fields::FROM);
|
||||
registerName <addressListField>(vmime::fields::TO);
|
||||
registerName <addressListField>(vmime::fields::CC);
|
||||
registerName <addressListField>(vmime::fields::BCC);
|
||||
registerName <mailboxField>(vmime::fields::SENDER);
|
||||
registerName <dateField>(vmime::fields::DATE);
|
||||
registerName <relayField>(vmime::fields::RECEIVED);
|
||||
registerName <textField>(vmime::fields::SUBJECT);
|
||||
registerName <mailboxField>(vmime::fields::REPLY_TO);
|
||||
registerName <mailboxField>(vmime::fields::DELIVERED_TO);
|
||||
registerName <textField>(vmime::fields::ORGANIZATION);
|
||||
registerName <textField>(vmime::fields::USER_AGENT);
|
||||
registerName <mailboxField>(vmime::fields::RETURN_PATH);
|
||||
registerName <contentTypeField>(vmime::fields::CONTENT_TYPE);
|
||||
registerName <contentEncodingField>(vmime::fields::CONTENT_TRANSFER_ENCODING);
|
||||
registerName <textField>(vmime::fields::CONTENT_DESCRIPTION);
|
||||
registerName <defaultField>(vmime::fields::MIME_VERSION);
|
||||
registerName <contentDispositionField>(vmime::fields::CONTENT_DISPOSITION);
|
||||
registerName <messageIdField>(vmime::fields::CONTENT_ID);
|
||||
registerName <messageIdField>(vmime::fields::MESSAGE_ID);
|
||||
registerName <defaultField>(vmime::fields::CONTENT_LOCATION);
|
||||
}
|
||||
|
||||
|
||||
@ -76,63 +66,24 @@ headerFieldFactory::~headerFieldFactory()
|
||||
headerField* headerFieldFactory::create
|
||||
(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
|
||||
{
|
||||
NameMap::const_iterator pos = m_nameMap.find(toLower(name));
|
||||
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 = registerer <defaultField>::creator();
|
||||
}
|
||||
}
|
||||
|
||||
field->m_name = name;
|
||||
|
||||
headerField* headerFieldFactory::create(const headerField::Types type,
|
||||
const string& name, const string& body)
|
||||
{
|
||||
if (type == headerField::Custom)
|
||||
{
|
||||
return (create(name, body));
|
||||
}
|
||||
else
|
||||
{
|
||||
TypeMap::const_iterator pos = m_typeMap.find(type);
|
||||
if (body != NULL_STRING)
|
||||
field->parse(body);
|
||||
|
||||
if (pos != m_typeMap.end())
|
||||
{
|
||||
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();
|
||||
}
|
||||
}
|
||||
return (field);
|
||||
}
|
||||
|
||||
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "headerField.hpp"
|
||||
#include "utility/singleton.hpp"
|
||||
#include "utility/stringUtils.hpp"
|
||||
|
||||
|
||||
namespace vmime
|
||||
@ -40,10 +41,8 @@ protected:
|
||||
|
||||
typedef headerField* (*AllocFunc)(void);
|
||||
typedef std::map <string, AllocFunc> NameMap;
|
||||
typedef std::map <headerField::Types, AllocFunc> TypeMap;
|
||||
|
||||
NameMap m_nameMap;
|
||||
TypeMap m_typeMap;
|
||||
|
||||
public:
|
||||
|
||||
@ -63,19 +62,10 @@ public:
|
||||
template <class T>
|
||||
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 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()
|
||||
{
|
||||
free_container(m_objects);
|
||||
}
|
||||
|
||||
|
||||
const mediaType htmlTextPart::type() const
|
||||
const mediaType htmlTextPart::getType() const
|
||||
{
|
||||
return (mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML));
|
||||
}
|
||||
@ -38,26 +39,26 @@ const mediaType htmlTextPart::type() 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
|
||||
{
|
||||
// Plain text
|
||||
if (!m_plainText.empty())
|
||||
if (!m_plainText.isEmpty())
|
||||
{
|
||||
// -- Create a new part
|
||||
bodyPart* part = new bodyPart();
|
||||
parent.body().parts.append(part);
|
||||
parent.getBody()->appendPart(part);
|
||||
|
||||
// -- Set header fields
|
||||
part->header().fields.ContentType() = mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN);
|
||||
part->header().fields.ContentType().charset() = m_charset;
|
||||
part->header().fields.ContentTransferEncoding() = encoding(encodingTypes::QUOTED_PRINTABLE);
|
||||
part->getHeader()->ContentType().setValue(mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN));
|
||||
part->getHeader()->ContentType().setCharset(m_charset);
|
||||
part->getHeader()->ContentTransferEncoding().setValue(encoding(encodingTypes::QUOTED_PRINTABLE));
|
||||
|
||||
// -- Set contents
|
||||
part->body().contents() = m_plainText;
|
||||
part->getBody()->setContents(m_plainText);
|
||||
}
|
||||
|
||||
// HTML text
|
||||
@ -65,51 +66,51 @@ void htmlTextPart::generateIn(bodyPart& /* message */, bodyPart& parent) const
|
||||
bodyPart* htmlPart = new bodyPart();
|
||||
|
||||
// -- Set header fields
|
||||
htmlPart->header().fields.ContentType() = mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML);
|
||||
htmlPart->header().fields.ContentType().charset() = m_charset;
|
||||
htmlPart->header().fields.ContentTransferEncoding() = encoding(encodingTypes::QUOTED_PRINTABLE);
|
||||
htmlPart->getHeader()->ContentType().setValue(mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML));
|
||||
htmlPart->getHeader()->ContentType().setCharset(m_charset);
|
||||
htmlPart->getHeader()->ContentTransferEncoding().setValue(encoding(encodingTypes::QUOTED_PRINTABLE));
|
||||
|
||||
// -- Set contents
|
||||
htmlPart->body().contents() = m_text;
|
||||
htmlPart->getBody()->setContents(m_text);
|
||||
|
||||
// Handle the case we have embedded objects
|
||||
if (!embeddedObjects.empty())
|
||||
if (!m_objects.empty())
|
||||
{
|
||||
// Create a "multipart/related" body part
|
||||
bodyPart* relPart = new bodyPart();
|
||||
parent.body().parts.append(relPart);
|
||||
parent.getBody()->appendPart(relPart);
|
||||
|
||||
relPart->header().fields.ContentType() = mediaType
|
||||
(mediaTypes::MULTIPART, mediaTypes::MULTIPART_RELATED);
|
||||
relPart->getHeader()->ContentType().
|
||||
setValue(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_RELATED));
|
||||
|
||||
// Add the HTML part into this part
|
||||
relPart->body().parts.append(htmlPart);
|
||||
relPart->getBody()->appendPart(htmlPart);
|
||||
|
||||
// Also add images into this part
|
||||
for (embeddedObjectsContainer::const_iterator i = embeddedObjects.begin() ;
|
||||
i != embeddedObjects.end() ; ++i)
|
||||
// Also add objects into this part
|
||||
for (std::vector <embeddedObject*>::const_iterator it = m_objects.begin() ;
|
||||
it != m_objects.end() ; ++it)
|
||||
{
|
||||
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:")
|
||||
id = id.substr(4);
|
||||
|
||||
objPart->header().fields.ContentType() = (*i).type();
|
||||
objPart->header().fields.ContentId() = messageId("<" + id + ">");
|
||||
objPart->header().fields.ContentDisposition() = disposition(dispositionTypes::INLINE);
|
||||
objPart->header().fields.ContentTransferEncoding() = (*i).encoding();
|
||||
objPart->getHeader()->ContentType().setValue((*it)->getType());
|
||||
objPart->getHeader()->ContentId().setValue(messageId("<" + id + ">"));
|
||||
objPart->getHeader()->ContentDisposition().setValue(disposition(dispositionTypes::INLINE));
|
||||
objPart->getHeader()->ContentTransferEncoding().setValue((*it)->getEncoding());
|
||||
//encoding(encodingTypes::BASE64);
|
||||
|
||||
objPart->body().contents() = (*i).data();
|
||||
objPart->getBody()->setContents((*it)->getData());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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,
|
||||
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
|
||||
{
|
||||
dynamic_cast<messageIdField&>((*p).header().fields.find(headerField::ContentId));
|
||||
cidParts.push_back(&(*p));
|
||||
dynamic_cast<messageIdField&>(*p.getHeader()->findField(fields::CONTENT_ID));
|
||||
cidParts.push_back(&p);
|
||||
}
|
||||
catch (exceptions::no_such_field)
|
||||
{
|
||||
@ -130,8 +133,8 @@ void htmlTextPart::findEmbeddedParts(const bodyPart& part,
|
||||
// Maybe there is a "Content-Location" field...
|
||||
try
|
||||
{
|
||||
dynamic_cast<messageIdField&>((*p).header().fields.find(headerField::ContentId));
|
||||
locParts.push_back(&(*p));
|
||||
dynamic_cast<messageIdField&>(*p.getHeader()->findField(fields::CONTENT_ID));
|
||||
locParts.push_back(&p);
|
||||
}
|
||||
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
|
||||
{
|
||||
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)
|
||||
{
|
||||
// No "Content-type" field: assume "application/octet-stream".
|
||||
}
|
||||
|
||||
embeddedObjects.m_list.push_back(new embeddedObject
|
||||
(part.body().contents(), part.body().encoding(), id, type));
|
||||
m_objects.push_back(new embeddedObject
|
||||
(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;
|
||||
utility::outputStreamAdapter adapter(oss);
|
||||
|
||||
textPart.body().contents().extract(adapter);
|
||||
textPart.getBody()->getContents().extract(adapter);
|
||||
|
||||
const string data = oss.str();
|
||||
|
||||
m_text = textPart.body().contents();
|
||||
m_text = textPart.getBody()->getContents();
|
||||
|
||||
try
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// This part is referenced in the HTML text.
|
||||
// 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)
|
||||
{
|
||||
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.
|
||||
// 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
|
||||
{
|
||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||
(part.header().fields.find(headerField::ContentType));
|
||||
(*part.getHeader()->findField(fields::CONTENT_TYPE));
|
||||
|
||||
if (ctf.value().type() == mediaTypes::MULTIPART &&
|
||||
ctf.value().subType() == mediaTypes::MULTIPART_ALTERNATIVE)
|
||||
if (ctf.getValue().getType() == mediaTypes::MULTIPART &&
|
||||
ctf.getValue().getSubType() == mediaTypes::MULTIPART_ALTERNATIVE)
|
||||
{
|
||||
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"
|
||||
&(*p) == &textPart) // if not...
|
||||
const bodyPart* p = part.getBody()->getPartAt(i);
|
||||
|
||||
if (p == &parent || // if "text/html" is in "multipart/related"
|
||||
p == &textPart) // if not...
|
||||
{
|
||||
foundPart = &(*p);
|
||||
}
|
||||
@ -262,18 +267,19 @@ bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& paren
|
||||
bool found = false;
|
||||
|
||||
// Now, search for the alternative plain text part
|
||||
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)
|
||||
{
|
||||
const bodyPart& p = *part.getBody()->getPartAt(i);
|
||||
|
||||
try
|
||||
{
|
||||
const contentTypeField& ctf = dynamic_cast<contentTypeField&>
|
||||
((*p).header().fields.find(headerField::ContentType));
|
||||
(*p.getHeader()->findField(fields::CONTENT_TYPE));
|
||||
|
||||
if (ctf.value().type() == mediaTypes::TEXT &&
|
||||
ctf.value().subType() == mediaTypes::TEXT_PLAIN)
|
||||
if (ctf.getValue().getType() == mediaTypes::TEXT &&
|
||||
ctf.getValue().getSubType() == mediaTypes::TEXT_PLAIN)
|
||||
{
|
||||
m_plainText = (*p).body().contents();
|
||||
m_plainText = p.getBody()->getContents();
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
@ -297,44 +303,82 @@ bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& paren
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////
|
||||
// Embedded objects container //
|
||||
////////////////////////////////
|
||||
|
||||
|
||||
htmlTextPart::embeddedObjectsContainer::~embeddedObjectsContainer()
|
||||
const charset& htmlTextPart::getCharset() const
|
||||
{
|
||||
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)
|
||||
return (**o);
|
||||
if ((*o)->getId() == id)
|
||||
return (*o);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -342,29 +386,64 @@ const bool htmlTextPart::embeddedObjectsContainer::has(const string& id) const
|
||||
}
|
||||
|
||||
|
||||
const string htmlTextPart::embeddedObjectsContainer::add
|
||||
(const contentHandler& data, const vmime::encoding& enc, const mediaType& type)
|
||||
const string htmlTextPart::addObject(const contentHandler& data,
|
||||
const vmime::encoding& enc, const mediaType& type)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
const string htmlTextPart::embeddedObjectsContainer::add
|
||||
(const contentHandler& data, const mediaType& type)
|
||||
const string htmlTextPart::addObject(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& data, const mediaType& type)
|
||||
const string htmlTextPart::addObject(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
|
||||
{
|
||||
protected:
|
||||
@ -40,127 +43,128 @@ protected:
|
||||
|
||||
public:
|
||||
|
||||
const mediaType type() const;
|
||||
const mediaType getType() const;
|
||||
|
||||
const vmime::charset& charset() const { return (m_charset); }
|
||||
vmime::charset& charset() { return (m_charset); }
|
||||
const charset& getCharset() const;
|
||||
void setCharset(const charset& ch);
|
||||
|
||||
const contentHandler& plainText() const { return (m_plainText); }
|
||||
contentHandler& plainText() { return (m_plainText); }
|
||||
const contentHandler& getPlainText() const;
|
||||
void setPlainText(const contentHandler& plainText);
|
||||
|
||||
const contentHandler& text() const { return (m_text); }
|
||||
contentHandler& text() { return (m_text); }
|
||||
const contentHandler& getText() const;
|
||||
void setText(const contentHandler& text);
|
||||
|
||||
// Embedded object (eg. image for <IMG> tag)
|
||||
/** Embedded object (eg: image for <IMG> tag).
|
||||
*/
|
||||
class embeddedObject
|
||||
{
|
||||
public:
|
||||
|
||||
embeddedObject(const contentHandler& data, const vmime::encoding& enc,
|
||||
const string& id, const mediaType& type)
|
||||
: m_data(data), m_encoding(enc), m_id(id), m_type(type)
|
||||
{
|
||||
}
|
||||
embeddedObject(const contentHandler& data, const encoding& enc,
|
||||
const string& id, const mediaType& type);
|
||||
|
||||
public:
|
||||
/** Return data stored in this embedded object.
|
||||
*
|
||||
* @return stored data
|
||||
*/
|
||||
const contentHandler& getData() const;
|
||||
|
||||
const contentHandler& data() const { return (m_data); }
|
||||
const vmime::encoding& encoding() const { return (m_encoding); }
|
||||
const string& id() const { return (m_id); }
|
||||
const mediaType& type() const { return (m_type); }
|
||||
/** Return the encoding used for data in this
|
||||
* embedded object.
|
||||
*
|
||||
* @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:
|
||||
|
||||
contentHandler m_data;
|
||||
vmime::encoding m_encoding;
|
||||
encoding m_encoding;
|
||||
string m_id;
|
||||
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.
|
||||
const bool has(const string& id) const;
|
||||
const embeddedObject& find(const string& id) const;
|
||||
/** Return the embedded object at the specified position.
|
||||
*
|
||||
* @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.
|
||||
const string add(const string& data, const mediaType& type);
|
||||
const string add(const contentHandler& data, const mediaType& type);
|
||||
const string add(const contentHandler& data, const encoding& enc, const mediaType& type);
|
||||
/** Embed an object and returns a string which identifies it.
|
||||
*
|
||||
* \deprecated Use the addObject() methods which take a 'contentHandler'
|
||||
* 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
|
||||
class const_iterator
|
||||
{
|
||||
public:
|
||||
/** Embed an object and returns a string which identifies it.
|
||||
*
|
||||
* @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 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) { }
|
||||
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:
|
||||
private:
|
||||
|
||||
contentHandler m_plainText;
|
||||
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 addEmbeddedObject(const bodyPart& part, const string& id);
|
||||
@ -170,7 +174,7 @@ protected:
|
||||
const int getPartCount() 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)
|
||||
: address(), m_name(mailbox.m_name), m_email(mailbox.m_email)
|
||||
mailbox::mailbox(const mailbox& mbox)
|
||||
: 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())
|
||||
{
|
||||
m_email = name;
|
||||
m_name.clear();
|
||||
m_name.removeAllWords();
|
||||
}
|
||||
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,
|
||||
const string::size_type curLinePos, string::size_type* newLinePos) const
|
||||
{
|
||||
if (m_name.empty())
|
||||
if (m_name.isEmpty())
|
||||
{
|
||||
bool newLine = false;
|
||||
|
||||
@ -352,11 +352,11 @@ void mailbox::generate(utility::outputStream& os, const string::size_type maxLin
|
||||
// and/or contain the special chars.
|
||||
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() ;
|
||||
!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_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);
|
||||
}
|
||||
|
||||
|
||||
const bool mailbox::empty() const
|
||||
const bool mailbox::isEmpty() const
|
||||
{
|
||||
return (m_email.empty());
|
||||
}
|
||||
@ -446,7 +453,7 @@ const bool mailbox::empty() const
|
||||
|
||||
void mailbox::clear()
|
||||
{
|
||||
m_name.clear();
|
||||
m_name.removeAllWords();
|
||||
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
|
||||
|
@ -40,7 +40,7 @@ class mailbox : public address
|
||||
public:
|
||||
|
||||
mailbox();
|
||||
mailbox(const class mailbox& mailbox);
|
||||
mailbox(const mailbox& mbox);
|
||||
mailbox(const string& email);
|
||||
mailbox(const text& name, const string& email);
|
||||
|
||||
@ -48,35 +48,36 @@ public:
|
||||
*
|
||||
* @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
|
||||
*/
|
||||
text& name() { return (m_name); }
|
||||
void setName(const text& name);
|
||||
|
||||
/** Return the 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
|
||||
*/
|
||||
string& email() { return (m_email); }
|
||||
void setEmail(const string& email);
|
||||
|
||||
// Comparison
|
||||
const bool operator==(const class mailbox& mailbox) const;
|
||||
const bool operator!=(const class mailbox& mailbox) const;
|
||||
|
||||
// Assignment
|
||||
void copyFrom(const address& addr);
|
||||
address* clone() const;
|
||||
void copyFrom(const component& other);
|
||||
mailbox* clone() const;
|
||||
mailbox& operator=(const mailbox& other);
|
||||
|
||||
const bool empty() const;
|
||||
const bool isEmpty() const;
|
||||
|
||||
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,
|
||||
const string::size_type end, string::size_type* newPosition)
|
||||
{
|
||||
m_mailbox.clear();
|
||||
getValue().clear();
|
||||
|
||||
// Here, we cannot simply call "m_mailbox.parse()" because it
|
||||
// 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
|
||||
mailboxGroup* group = static_cast <mailboxGroup*>(parsedAddress);
|
||||
|
||||
if (!group->empty())
|
||||
m_mailbox = *(group->begin());
|
||||
if (!group->isEmpty())
|
||||
getValue() = *(group->getMailboxAt(0));
|
||||
}
|
||||
else
|
||||
{
|
||||
// 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
|
||||
|
@ -21,10 +21,7 @@
|
||||
#define VMIME_MAILBOXFIELD_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "base.hpp"
|
||||
#include "component.hpp"
|
||||
|
||||
#include "headerFieldFactory.hpp"
|
||||
#include "genericField.hpp"
|
||||
#include "mailbox.hpp"
|
||||
|
||||
|
||||
@ -32,35 +29,18 @@ namespace vmime
|
||||
{
|
||||
|
||||
|
||||
class mailboxField : public headerField
|
||||
class mailboxField : public genericField <mailbox>
|
||||
{
|
||||
friend class headerFieldFactory::registerer <mailboxField>;
|
||||
|
||||
protected:
|
||||
|
||||
mailboxField();
|
||||
mailboxField(const mailboxField&);
|
||||
|
||||
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 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 "parserHelpers.hpp"
|
||||
#include "exception.hpp"
|
||||
|
||||
|
||||
namespace vmime
|
||||
@ -30,10 +31,10 @@ mailboxGroup::mailboxGroup()
|
||||
}
|
||||
|
||||
|
||||
mailboxGroup::mailboxGroup(const class mailboxGroup& mailboxGroup)
|
||||
mailboxGroup::mailboxGroup(const mailboxGroup& mboxGroup)
|
||||
: address()
|
||||
{
|
||||
copyFrom(mailboxGroup);
|
||||
copyFrom(mboxGroup);
|
||||
}
|
||||
|
||||
|
||||
@ -45,7 +46,7 @@ mailboxGroup::mailboxGroup(const text& name)
|
||||
|
||||
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
|
||||
// the contents of the sub-group into this group...
|
||||
for (mailboxGroup::const_iterator
|
||||
it = group->begin() ; it != group->end() ; ++it)
|
||||
for (int i = 0 ; i < group->getMailboxCount() ; ++i)
|
||||
{
|
||||
m_list.push_back(static_cast <mailbox*>((*it).clone()));
|
||||
m_list.push_back(group->getMailboxAt(i)->clone());
|
||||
}
|
||||
|
||||
delete (parsedAddress);
|
||||
@ -119,11 +119,11 @@ void mailboxGroup::generate(utility::outputStream& os, const string::size_type m
|
||||
// and/or contain the special chars.
|
||||
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() ;
|
||||
!forceEncode && c != buffer.end() ; ++c)
|
||||
@ -158,7 +158,8 @@ void mailboxGroup::generate(utility::outputStream& os, const string::size_type m
|
||||
os << ":";
|
||||
++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())
|
||||
{
|
||||
@ -171,7 +172,7 @@ void mailboxGroup::generate(utility::outputStream& os, const string::size_type m
|
||||
++pos;
|
||||
}
|
||||
|
||||
(*it).generate(os, maxLineLength - 2, pos, &pos);
|
||||
(*it)->generate(os, maxLineLength - 2, pos, &pos);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
// Mailbox insertion
|
||||
void mailboxGroup::append(const mailbox& field)
|
||||
mailboxGroup& mailboxGroup::operator=(const component& other)
|
||||
{
|
||||
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::erase(const iterator it)
|
||||
void mailboxGroup::setName(const text& name)
|
||||
{
|
||||
delete (*it.m_iterator);
|
||||
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()));
|
||||
m_name = name;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
@ -38,102 +38,123 @@ class mailboxGroup : public address
|
||||
public:
|
||||
|
||||
mailboxGroup();
|
||||
mailboxGroup(const class mailboxGroup& mailboxGroup);
|
||||
mailboxGroup(const mailboxGroup& mboxGroup);
|
||||
mailboxGroup(const text& name);
|
||||
|
||||
~mailboxGroup();
|
||||
|
||||
// Properties set/get
|
||||
const text& name() const { return (m_name); }
|
||||
text& name() { return (m_name); }
|
||||
|
||||
// Assignment
|
||||
void copyFrom(const address& addr);
|
||||
address* clone() const;
|
||||
void copyFrom(const component& other);
|
||||
mailboxGroup* clone() const;
|
||||
mailboxGroup& operator=(const component& other);
|
||||
|
||||
public:
|
||||
/** Return the name of the group.
|
||||
*
|
||||
* @return group name
|
||||
*/
|
||||
const text& getName() const;
|
||||
|
||||
// Mailbox iterator
|
||||
class const_iterator;
|
||||
/** Set the name of the group.
|
||||
*
|
||||
* @param name group name
|
||||
*/
|
||||
void setName(const text& name);
|
||||
|
||||
class iterator
|
||||
{
|
||||
friend class mailboxGroup;
|
||||
friend class const_iterator;
|
||||
/** Add a mailbox at the end of the list.
|
||||
*
|
||||
* @param mbox mailbox to append
|
||||
*/
|
||||
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) { }
|
||||
iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
||||
/** 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);
|
||||
|
||||
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); }
|
||||
mailbox* operator->() const { return (*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++() { ++m_iterator; return (*this); }
|
||||
iterator& operator++(int) { ++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);
|
||||
|
||||
const bool operator==(const iterator& it) const { return (it.m_iterator == m_iterator); }
|
||||
const bool operator!=(const iterator& it) const { return (!(*this == it)); }
|
||||
/** Remove the mailbox at the specified position.
|
||||
*
|
||||
* @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
|
||||
{
|
||||
friend class mailboxGroup;
|
||||
/** Tests whether the list of mailboxes is empty.
|
||||
*
|
||||
* @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) { }
|
||||
const_iterator(const iterator& it) : m_iterator(it.m_iterator) { }
|
||||
const_iterator(const const_iterator& it) : m_iterator(it.m_iterator) { }
|
||||
/** Return the mailbox at the specified position.
|
||||
*
|
||||
* @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); }
|
||||
const_iterator& operator=(const iterator& it) { m_iterator = it.m_iterator; return (*this); }
|
||||
|
||||
const mailbox& operator*() const { return (**m_iterator); }
|
||||
const mailbox* operator->() const { return (*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 <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 <const mailbox*> getMailboxList() const;
|
||||
|
||||
/** Return the mailbox list.
|
||||
*
|
||||
* @return list of mailboxes
|
||||
*/
|
||||
const std::vector <mailbox*> getMailboxList();
|
||||
|
||||
const bool isGroup() const;
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
text m_name;
|
||||
std::vector <mailbox*> m_list;
|
||||
|
@ -18,28 +18,150 @@
|
||||
//
|
||||
|
||||
#include "mailboxList.hpp"
|
||||
#include "exception.hpp"
|
||||
|
||||
|
||||
namespace vmime
|
||||
{
|
||||
|
||||
|
||||
// Address insertion
|
||||
void mailboxList::append(const address& addr)
|
||||
mailboxList::mailboxList()
|
||||
{
|
||||
// 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).
|
||||
*/
|
||||
|
||||
class mailboxList : public addressList
|
||||
class mailboxList : protected addressList
|
||||
{
|
||||
friend class mailboxGroup;
|
||||
|
||||
public:
|
||||
|
||||
//
|
||||
// The following functions have the same name and work *exactly* like
|
||||
// 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.
|
||||
//
|
||||
// This class works exactly like 'addressList' except it prevents user
|
||||
// from inserting mailbox groups where it is not allowed by the RFC.
|
||||
|
||||
// Address iterator
|
||||
class const_iterator;
|
||||
mailboxList();
|
||||
mailboxList(const mailboxList& mboxList);
|
||||
|
||||
class iterator
|
||||
{
|
||||
friend class mailboxList;
|
||||
friend class const_iterator;
|
||||
/** Add a mailbox at the end of the list.
|
||||
*
|
||||
* @param mbox mailbox to append
|
||||
*/
|
||||
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); }
|
||||
mailbox* operator->() const { return static_cast<mailbox*>(*m_iterator); }
|
||||
/** Remove the mailbox at the specified position.
|
||||
*
|
||||
* @param pos position of the mailbox to remove
|
||||
*/
|
||||
void removeMailbox(const int pos);
|
||||
|
||||
iterator& operator++() { ++m_iterator; return (*this); }
|
||||
iterator& operator++(int) { ++m_iterator; return (*this); }
|
||||
/** Remove all mailboxes from the list.
|
||||
*/
|
||||
void removeAllMailboxes();
|
||||
|
||||
const bool operator==(const iterator& it) const { return (it.m_iterator == m_iterator); }
|
||||
const bool operator!=(const iterator& it) const { return (!(*this == it)); }
|
||||
/** Return the number of mailboxes in the list.
|
||||
*
|
||||
* @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
|
||||
{
|
||||
friend class mailboxList;
|
||||
/** Return the mailbox at the specified position.
|
||||
*
|
||||
* @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) { }
|
||||
|
||||
public:
|
||||
|
||||
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 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);
|
||||
/** Return the mailbox list.
|
||||
*
|
||||
* @return list of mailboxes
|
||||
*/
|
||||
const std::vector <mailbox*> getMailboxList();
|
||||
};
|
||||
|
||||
|
||||
|
@ -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)
|
||||
: 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;
|
||||
|
||||
m_type = toLower(string(buffer.begin() + typeStart,
|
||||
buffer.begin() + position + (p - pstart)));
|
||||
m_type = stringUtils::toLower(string(buffer.begin() + typeStart,
|
||||
buffer.begin() + position + (p - pstart)));
|
||||
|
||||
if (p < pend)
|
||||
{
|
||||
@ -64,8 +64,8 @@ void mediaType::parse(const string& buffer, const string::size_type position,
|
||||
++p;
|
||||
|
||||
// Extract the sub-type
|
||||
m_subType = toLower(string(buffer.begin() + position + (p - pstart),
|
||||
buffer.begin() + end));
|
||||
m_subType = stringUtils::toLower(string(buffer.begin() + position + (p - pstart),
|
||||
buffer.begin() + end));
|
||||
}
|
||||
|
||||
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,
|
||||
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)
|
||||
{
|
||||
@ -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)
|
||||
{
|
||||
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
|
||||
|
@ -21,6 +21,7 @@
|
||||
#define VMIME_MEDIATYPE_HPP_INCLUDED
|
||||
|
||||
|
||||
#include "base.hpp"
|
||||
#include "component.hpp"
|
||||
|
||||
|
||||
@ -44,17 +45,46 @@ public:
|
||||
const bool operator==(const mediaType& type) const;
|
||||
const bool operator!=(const mediaType& type) const;
|
||||
|
||||
mediaType& operator=(const mediaType& type);
|
||||
mediaType& operator=(const string& type);
|
||||
|
||||
const string& type() const { return (m_type); };
|
||||
string& type() { return (m_type); }
|
||||
mediaType* clone() const;
|
||||
void copyFrom(const component& other);
|
||||
mediaType& operator=(const mediaType& other);
|
||||
|
||||
const string& subType() const { return (m_subType); };
|
||||
string& subType() { return (m_subType); }
|
||||
/** Return the media type.
|
||||
* See the constants in vmime::mediaTypes.
|
||||
*
|
||||
* @return media type
|
||||
*/
|
||||
const string& getType() const;
|
||||
|
||||
void set(const string& type) { parse(type); }
|
||||
void set(const string& type, const string& subType) { m_type = type; m_subType = subType; }
|
||||
/** Set the media type.
|
||||
* 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:
|
||||
|
||||
|
@ -48,28 +48,28 @@ message* messageBuilder::construct() const
|
||||
message* msg = new message;
|
||||
|
||||
// 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();
|
||||
|
||||
if (m_to.empty() || (*m_to.begin()).empty())
|
||||
if (m_to.isEmpty() || m_to.getAddressAt(0)->isEmpty())
|
||||
throw exceptions::no_recipient();
|
||||
|
||||
msg->header().fields.From() = m_from;
|
||||
msg->header().fields.To() = m_to;
|
||||
msg->getHeader()->From().setValue(m_from);
|
||||
msg->getHeader()->To().setValue(m_to);
|
||||
|
||||
if (!m_cc.empty())
|
||||
msg->header().fields.Cc() = m_cc;
|
||||
if (!m_cc.isEmpty())
|
||||
msg->getHeader()->Cc().setValue(m_cc);
|
||||
|
||||
if (!m_bcc.empty())
|
||||
msg->header().fields.Bcc() = m_bcc;
|
||||
if (!m_bcc.isEmpty())
|
||||
msg->getHeader()->Bcc().setValue(m_bcc);
|
||||
|
||||
// Add a "Date" field
|
||||
msg->header().fields.Date() = datetime::now();
|
||||
msg->getHeader()->Date().setValue(datetime::now());
|
||||
|
||||
// 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
|
||||
// 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)
|
||||
{
|
||||
// Set parent part (message) to "multipart/mixed"
|
||||
msg->header().fields.ContentType() = mediaType
|
||||
(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED);
|
||||
msg->getHeader()->ContentType().setValue
|
||||
(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED));
|
||||
|
||||
// Create a sub-part "multipart/alternative" for text parts
|
||||
bodyPart* subPart = new bodyPart;
|
||||
msg->body().parts.append(subPart);
|
||||
msg->getBody()->appendPart(subPart);
|
||||
|
||||
subPart->header().fields.ContentType() = mediaType
|
||||
(mediaTypes::MULTIPART, mediaTypes::MULTIPART_ALTERNATIVE);
|
||||
subPart->getHeader()->ContentType().setValue
|
||||
(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_ALTERNATIVE));
|
||||
|
||||
// Generate the text parts into this sub-part (normally, this
|
||||
// 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 (!m_attach.empty())
|
||||
{
|
||||
msg->header().fields.ContentType() = mediaType
|
||||
(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED);
|
||||
msg->getHeader()->ContentType().setValue
|
||||
(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_MIXED));
|
||||
}
|
||||
// Else, set it to "multipart/alternative" if there are more than one text part.
|
||||
else if (m_textPart->getPartCount() > 1)
|
||||
{
|
||||
msg->header().fields.ContentType() = mediaType
|
||||
(mediaTypes::MULTIPART, mediaTypes::MULTIPART_ALTERNATIVE);
|
||||
msg->getHeader()->ContentType().setValue
|
||||
(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_ALTERNATIVE));
|
||||
}
|
||||
}
|
||||
|
||||
// Generate the attachments
|
||||
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);
|
||||
}
|
||||
@ -136,19 +137,22 @@ message* messageBuilder::construct() const
|
||||
|
||||
// If there is only one part in the message, move it into the message
|
||||
// (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
|
||||
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)
|
||||
msg->header().fields.get((*f).name()) = *f;
|
||||
for (std::vector <const headerField*>::const_iterator it = fields.begin() ;
|
||||
it != fields.end() ; ++it)
|
||||
{
|
||||
*(msg->getHeader()->getField((*it)->getName())) = **it;
|
||||
}
|
||||
|
||||
// Second, copy the body contents and sub-parts (this also remove
|
||||
// the body part we are copying...)
|
||||
msg->body() = part.body();
|
||||
msg->getBody()->copyFrom(*part.getBody());
|
||||
}
|
||||
|
||||
return (msg);
|
||||
@ -163,7 +167,7 @@ void messageBuilder::attach(attachment* attach)
|
||||
|
||||
void messageBuilder::constructTextPart(const mediaType& type)
|
||||
{
|
||||
class textPart* part = NULL;
|
||||
textPart* part = NULL;
|
||||
|
||||
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:
|
||||
|
||||
// Expeditor and recipients
|
||||
const mailbox& expeditor() const { return (m_from); }
|
||||
mailbox& expeditor() { return (m_from); }
|
||||
/** Return the expeditor of the message (From:).
|
||||
*
|
||||
* @return expeditor of the message
|
||||
*/
|
||||
const mailbox& getExpeditor() const;
|
||||
|
||||
const addressList& recipients() const { return (m_to); }
|
||||
addressList& recipients() { return (m_to); }
|
||||
/** Set the expeditor of the message (From:).
|
||||
*
|
||||
* @param expeditor expeditor of the message
|
||||
*/
|
||||
void setExpeditor(const mailbox& expeditor);
|
||||
|
||||
const addressList& copyRecipients() const { return (m_cc); }
|
||||
addressList& copyRecipients() { return (m_cc); }
|
||||
/** Return the recipients of the message (To:).
|
||||
*
|
||||
* return recipients of the message
|
||||
*/
|
||||
const addressList& getRecipients() const;
|
||||
|
||||
const addressList& blindCopyRecipients() const { return (m_bcc); }
|
||||
addressList& blindCopyRecipients() { return (m_bcc); }
|
||||
/** Set the recipients of the message (To:).
|
||||
*
|
||||
* @param recipients list of recipients
|
||||
*/
|
||||
void setRecipients(const addressList& recipients);
|
||||
|
||||
// Subject
|
||||
const text& subject() const { return (m_subject); }
|
||||
text& subject() { return (m_subject); }
|
||||
/** Return the copy recipients of the message (Cc:).
|
||||
*
|
||||
* @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);
|
||||
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);
|
||||
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;
|
||||
|
||||
protected:
|
||||
private:
|
||||
|
||||
mailbox m_from;
|
||||
|
||||
@ -87,7 +182,7 @@ protected:
|
||||
|
||||
text m_subject;
|
||||
|
||||
class textPart* m_textPart;
|
||||
textPart* m_textPart;
|
||||
|
||||
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);
|
||||
}
|
||||
@ -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)
|
||||
{
|
||||
parse(id);
|
||||
@ -164,12 +156,12 @@ messageId messageId::generateId()
|
||||
|
||||
left << "vmime";
|
||||
left << '.';
|
||||
left << std::hex << utility::random::time();
|
||||
left << std::hex << utility::random::getTime();
|
||||
left << '.';
|
||||
left << std::hex << utility::random::process();
|
||||
left << std::hex << utility::random::getProcess();
|
||||
left << '.';
|
||||
left << std::hex << utility::random::next();
|
||||
left << std::hex << utility::random::next();
|
||||
left << std::hex << utility::random::getNext();
|
||||
left << std::hex << utility::random::getNext();
|
||||
|
||||
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
|
||||
|
@ -43,24 +43,55 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
const string& left() const { return (m_left); }
|
||||
string& left() { return (m_left); }
|
||||
/** Return the left part of the message identifier.
|
||||
*
|
||||
* @return left part of message identifier
|
||||
*/
|
||||
const string& getLeft() const;
|
||||
|
||||
const string& right() const { return (m_right); }
|
||||
string& right() { return (m_right); }
|
||||
/** Set the left part of the message identifier.
|
||||
*
|
||||
* @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);
|
||||
|
||||
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();
|
||||
|
||||
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_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 "textPartFactory.hpp"
|
||||
|
||||
#include "relayField.hpp"
|
||||
|
||||
|
||||
namespace vmime
|
||||
{
|
||||
@ -60,28 +58,36 @@ messageParser::~messageParser()
|
||||
void messageParser::parse(const message& msg)
|
||||
{
|
||||
// Header fields (if field is present, copy its value, else do nothing)
|
||||
#define TRY_FIELD(x) try { x; } catch (exceptions::no_such_field) { }
|
||||
TRY_FIELD(m_from = dynamic_cast<mailboxField&>(msg.header().fields.find(headerField::From)).value());
|
||||
#define TRY_FIELD(var, type, name) \
|
||||
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_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_from, mailboxField, fields::FROM);
|
||||
|
||||
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
|
||||
|
||||
// Date
|
||||
try
|
||||
{
|
||||
vmime::relayField& recv = static_cast<vmime::relayField&>(msg.header().fields.find(headerField::Received));
|
||||
m_date = recv.date();
|
||||
vmime::relayField& recv = dynamic_cast <vmime::relayField&>
|
||||
(*msg.getHeader()->findField(fields::RECEIVED));
|
||||
|
||||
m_date = recv.getValue().getDate();
|
||||
}
|
||||
catch (vmime::exceptions::no_such_field&)
|
||||
{
|
||||
try
|
||||
{
|
||||
vmime::dateField& date = static_cast<vmime::dateField&>(msg.header().fields.find(headerField::Date));
|
||||
m_date = date.value();
|
||||
vmime::dateField& date = dynamic_cast <vmime::dateField&>
|
||||
(*msg.getHeader()->findField(fields::DATE));
|
||||
|
||||
m_date = date.getValue();
|
||||
}
|
||||
catch (vmime::exceptions::no_such_field&)
|
||||
{
|
||||
@ -100,10 +106,11 @@ void messageParser::parse(const message& msg)
|
||||
void messageParser::findAttachments(const bodyPart& part)
|
||||
{
|
||||
// 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 body& bdy = (*p).body();
|
||||
const bodyPart& p = *part.getBody()->getPartAt(i);
|
||||
const header& hdr = *p.getHeader();
|
||||
const body& bdy = *p.getBody();
|
||||
|
||||
// Is this part an attachment?
|
||||
bool isAttachment = false;
|
||||
@ -112,9 +119,9 @@ void messageParser::findAttachments(const bodyPart& part)
|
||||
try
|
||||
{
|
||||
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;
|
||||
isAttachment = true;
|
||||
@ -129,9 +136,9 @@ void messageParser::findAttachments(const bodyPart& part)
|
||||
try
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -140,8 +147,11 @@ void messageParser::findAttachments(const bodyPart& part)
|
||||
mediaTypes::APPLICATION_OCTET_STREAM);
|
||||
}
|
||||
|
||||
if (type.type() != mediaTypes::TEXT && type.type() != mediaTypes::MULTIPART)
|
||||
if (type.getType() != mediaTypes::TEXT &&
|
||||
type.getType() != mediaTypes::MULTIPART)
|
||||
{
|
||||
isAttachment = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (isAttachment)
|
||||
@ -152,9 +162,9 @@ void messageParser::findAttachments(const bodyPart& part)
|
||||
try
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -169,9 +179,9 @@ void messageParser::findAttachments(const bodyPart& part)
|
||||
try
|
||||
{
|
||||
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)
|
||||
{
|
||||
@ -180,12 +190,12 @@ void messageParser::findAttachments(const bodyPart& part)
|
||||
|
||||
// Construct the attachment object
|
||||
attachment* attach = new defaultAttachment
|
||||
(bdy.contents(), bdy.encoding(), type, description);
|
||||
(bdy.getContents(), bdy.getEncoding(), type, description);
|
||||
|
||||
if (contentDispField != NULL)
|
||||
{
|
||||
m_attachInfo.insert(std::map <attachment*, contentDispositionField*>::
|
||||
value_type(attach, static_cast <contentDispositionField*>
|
||||
value_type(attach, dynamic_cast <contentDispositionField*>
|
||||
(contentDispField->clone())));
|
||||
}
|
||||
|
||||
@ -194,8 +204,8 @@ void messageParser::findAttachments(const bodyPart& part)
|
||||
}
|
||||
|
||||
// Try to find attachments in sub-parts
|
||||
if (bdy.parts.size())
|
||||
findAttachments(*p);
|
||||
if (bdy.getPartCount())
|
||||
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
|
||||
// "text/*", take this part.
|
||||
if (part.body().parts.count() == 0)
|
||||
if (part.getBody()->getPartCount() == 0)
|
||||
{
|
||||
mediaType type(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN);
|
||||
bool accept = false;
|
||||
@ -212,11 +222,11 @@ void messageParser::findTextParts(const bodyPart& msg, const bodyPart& part)
|
||||
try
|
||||
{
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -251,17 +261,18 @@ bool messageParser::findSubTextParts(const bodyPart& msg, const bodyPart& part)
|
||||
|
||||
std::vector <const bodyPart*> textParts;
|
||||
|
||||
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
|
||||
{
|
||||
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)
|
||||
@ -273,14 +284,15 @@ bool messageParser::findSubTextParts(const bodyPart& msg, const bodyPart& part)
|
||||
if (textParts.size())
|
||||
{
|
||||
// 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&>
|
||||
((*p)->header().fields.find(headerField::ContentType));
|
||||
(*(*p)->getHeader()->findField(fields::CONTENT_TYPE));
|
||||
|
||||
try
|
||||
{
|
||||
textPart* textPart = textPartFactory::getInstance()->create(ctf.value());
|
||||
textPart* textPart = textPartFactory::getInstance()->create(ctf.getValue());
|
||||
textPart->parse(msg, part, **p);
|
||||
|
||||
m_textParts.push_back(textPart);
|
||||
@ -298,10 +310,9 @@ bool messageParser::findSubTextParts(const bodyPart& msg, const bodyPart& part)
|
||||
{
|
||||
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 = findSubTextParts(msg, *p);
|
||||
found = findSubTextParts(msg, *part.getBody()->getPartAt(i));
|
||||
}
|
||||
|
||||
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
|
||||
it = m_attachInfo.find(a);
|
||||
it = m_attachInfo.find(const_cast <attachment*>(a));
|
||||
|
||||
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
|
||||
|
@ -46,27 +46,88 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
// Expeditor and recipients
|
||||
const mailbox& expeditor() const { return (m_from); }
|
||||
/** Return the expeditor of the message (From:).
|
||||
*
|
||||
* @return expeditor of the message
|
||||
*/
|
||||
const mailbox& getExpeditor() const;
|
||||
|
||||
const addressList& recipients() const { return (m_to); }
|
||||
const addressList& copyRecipients() const { return (m_cc); }
|
||||
const addressList& blindCopyRecipients() const { return (m_bcc); }
|
||||
/** Return the recipients of the message (To:).
|
||||
*
|
||||
* return recipients of the message
|
||||
*/
|
||||
const addressList& getRecipients() const;
|
||||
|
||||
// Subject
|
||||
const text& subject() const { return (m_subject); }
|
||||
/** Return the copy recipients of the message (Cc:).
|
||||
*
|
||||
* @return copy recipients of the message
|
||||
*/
|
||||
const addressList& getCopyRecipients() const;
|
||||
|
||||
// Date
|
||||
const datetime& date() const { return (m_date); }
|
||||
/** Return the blind-copy recipients of the message (Bcc:).
|
||||
*
|
||||
* @return blind-copy recipients of the message
|
||||
*/
|
||||
const addressList& getBlindCopyRecipients() const;
|
||||
|
||||
// Attachments
|
||||
const std::vector <attachment*>& attachments() const { return (m_attach); }
|
||||
const contentDispositionField* attachmentInfo(attachment* a) const;
|
||||
/** Return the subject of the message.
|
||||
*
|
||||
* @return subject of the message
|
||||
*/
|
||||
const text& getSubject() const;
|
||||
|
||||
// Text parts
|
||||
const std::vector <textPart*>& textParts() const { return (m_textParts); }
|
||||
/** Return the date of the message.
|
||||
*
|
||||
* @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;
|
||||
|
||||
|
@ -59,24 +59,24 @@ void IMAPConnection::connect()
|
||||
m_state = STATE_NONE;
|
||||
m_hierarchySeparator = '\0';
|
||||
|
||||
const string address = m_store->session().properties()[m_store->infos().propertyPrefix() + "server.address"];
|
||||
const port_t port = m_store->session().properties().get(m_store->infos().propertyPrefix() + "server.port", m_store->infos().defaultPort());
|
||||
const string address = m_store->getSession()->getProperties()[m_store->getInfos().getPropertyPrefix() + "server.address"];
|
||||
const port_t port = m_store->getSession()->getProperties().getProperty(m_store->getInfos().getPropertyPrefix() + "server.port", m_store->getInfos().getDefaultPort());
|
||||
|
||||
// Create the time-out handler
|
||||
if (session().properties().exists
|
||||
(m_store->infos().propertyPrefix() + "timeout.factory"))
|
||||
if (m_store->getSession()->getProperties().hasProperty
|
||||
(m_store->getInfos().getPropertyPrefix() + "timeout.factory"))
|
||||
{
|
||||
timeoutHandlerFactory* tof = platformDependant::getHandler()->
|
||||
getTimeoutHandlerFactory(session().properties()
|
||||
[m_store->infos().propertyPrefix() + "timeout.factory"]);
|
||||
getTimeoutHandlerFactory(m_store->getSession()->getProperties()
|
||||
[m_store->getInfos().getPropertyPrefix() + "timeout.factory"]);
|
||||
|
||||
m_timeoutHandler = tof->create();
|
||||
}
|
||||
|
||||
// Create and connect the socket
|
||||
socketFactory* sf = platformDependant::getHandler()->getSocketFactory
|
||||
(m_store->session().properties().get
|
||||
(m_store->infos().propertyPrefix() + "server.socket-factory", string("default")));
|
||||
(m_store->getSession()->getProperties().getProperty
|
||||
(m_store->getInfos().getPropertyPrefix() + "server.socket-factory", string("default")));
|
||||
|
||||
m_socket = sf->create();
|
||||
m_socket->connect(address, port);
|
||||
@ -109,8 +109,8 @@ void IMAPConnection::connect()
|
||||
|
||||
// TODO: other authentication methods
|
||||
|
||||
send(true, "LOGIN " + IMAPUtils::quoteString(auth.username())
|
||||
+ " " + IMAPUtils::quoteString(auth.password()), true);
|
||||
send(true, "LOGIN " + IMAPUtils::quoteString(auth.getUsername())
|
||||
+ " " + IMAPUtils::quoteString(auth.getPassword()), true);
|
||||
|
||||
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