diff --git a/ChangeLog b/ChangeLog index d05be1bd..4001d9e8 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,7 +1,46 @@ -VERSION 0.5.2-CVS +VERSION 0.6.0-cvs ================= +2004-10-21 Vincent Richard + + * 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 + + * added clone() method on 'component' object. + 2004-09-09 Vincent Richard * IMAPFolder.cpp: fixed rename(): folder name is now updated. diff --git a/SConstruct b/SConstruct index 1bbd0662..93b0d23a 100644 --- a/SConstruct +++ b/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 = [ diff --git a/VERSION b/VERSION index 2411653a..09a3acfa 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.5.2 \ No newline at end of file +0.6.0 \ No newline at end of file diff --git a/examples/common.inc b/examples/common.inc index 6bef8037..ed9c4f4b 100644 --- a/examples/common.inc +++ b/examples/common.inc @@ -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, diff --git a/examples/example1.cpp b/examples/example1.cpp index 191a2adf..b639a4bc 100644 --- a/examples/example1.cpp +++ b/examples/example1.cpp @@ -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; diff --git a/examples/example2.cpp b/examples/example2.cpp index 183b6d02..6e7f81c6 100644 --- a/examples/example2.cpp +++ b/examples/example2.cpp @@ -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); diff --git a/examples/example3.cpp b/examples/example3.cpp index c8cc0f2f..d2b41754 100644 --- a/examples/example3.cpp +++ b/examples/example3.cpp @@ -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(mb.textPart()); + vmime::htmlTextPart& textPart = dynamic_cast(*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 HTML text.
"); - textPart.plainText() = vmime::string("This is the plain text (without HTML formatting)."); + textPart.setText(vmime::contentHandler(vmime::string("This is the HTML text.
"))); + textPart.setPlainText(vmime::contentHandler(vmime::string("This is the plain text (without HTML formatting)."))); // Construction vmime::message* msg = mb.construct(); diff --git a/examples/example4.cpp b/examples/example4.cpp index 164e4be9..605452fe 100644 --- a/examples/example4.cpp +++ b/examples/example4.cpp @@ -44,28 +44,28 @@ int main() vmime::messageParser mp("<...MIME message content...>"); // Enumerate text parts - for (std::vector ::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(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(part); - // Text is in "tp.text()" + // Text is in "tp.getText()" } } } diff --git a/examples/example5.cpp b/examples/example5.cpp index a36d8c09..e5a7c93b 100644 --- a/examples/example5.cpp +++ b/examples/example5.cpp @@ -45,12 +45,13 @@ int main() vmime::messageParser mp("<...MIME message content...>"); // Enumerate attachments - for (std::vector ::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 diff --git a/examples/example6.cpp b/examples/example6.cpp index 6bea365e..78fe0f3d 100644 --- a/examples/example6.cpp +++ b/examples/example6.cpp @@ -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 props = e->availableProperties(); + vmime::encoder* e = enc.create(); - for (std::vector ::const_iterator it2 = props.begin() ; it2 != props.end() ; ++it2) - std::cout << " - " << *it2 << std::endl; + std::vector props = e->getAvailableProperties(); + + for (std::vector ::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 props = (*it).infos().availableProperties(); + std::cout << " * " << serv.getName() << " (" << serv.getInfos().getDefaultPort() << ")" << std::endl; - for (std::vector ::const_iterator it2 = props.begin() ; it2 != props.end() ; ++it2) - std::cout << " - " << (*it).infos().propertyPrefix() + *it2 << std::endl; + std::vector props = serv.getInfos().getAvailableProperties(); + + for (std::vector ::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); } diff --git a/src/address.cpp b/src/address.cpp index 481cc209..f37918f5 100644 --- a/src/address.cpp +++ b/src/address.cpp @@ -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 diff --git a/src/address.hpp b/src/address.hpp index a3d8cedb..5fc00541 100644 --- a/src/address.hpp +++ b/src/address.hpp @@ -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. diff --git a/src/addressList.cpp b/src/addressList.cpp index c532c16d..93f0cc5b 100644 --- a/src/addressList.cpp +++ b/src/addressList.cpp @@ -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 ::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 ::size_type addressList::size() const +void addressList::copyFrom(const component& other) { - return (m_list.size()); + const addressList& addrList = dynamic_cast (other); + + removeAllAddresses(); + + for (std::vector ::const_iterator it = addrList.m_list.begin() ; + it != addrList.m_list.end() ; ++it) + { + m_list.push_back(static_cast ((*it)->clone())); + } } -/** Return the number of addresses in the list. - * - * @return number of addresses in the list - */ - -const std::vector ::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 ::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 ::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 ::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 ::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 ::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 addressList::getAddressList() const +{ + std::vector list; + + list.reserve(m_list.size()); + + for (std::vector ::const_iterator it = m_list.begin() ; + it != m_list.end() ; ++it) + { + list.push_back(*it); + } + + return (list); +} + + +const std::vector addressList::getAddressList() +{ + return (m_list); +} + + + + } // vmime diff --git a/src/addressList.hpp b/src/addressList.hpp index 03a53e57..6048936a 100644 --- a/src/addressList.hpp +++ b/src/addressList.hpp @@ -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 ::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 ::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 ::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 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 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 ::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 ::size_type size() const; - const std::vector ::size_type count() const; - const bool empty() const; - - const address& operator[](const std::vector ::size_type x) const { return (*m_list[x]); } - address& operator[](const std::vector ::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 m_list; - void copyFrom(const addressList& source); - public: using component::parse; diff --git a/src/addressListField.cpp b/src/addressListField.cpp deleted file mode 100644 index 020d6b10..00000000 --- a/src/addressListField.cpp +++ /dev/null @@ -1,67 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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(field); - m_list = source.m_list; - - headerField::copyFrom(field); -} - - -} // vmime - diff --git a/src/addressListField.hpp b/src/addressListField.hpp deleted file mode 100644 index 1cc63ff6..00000000 --- a/src/addressListField.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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 ; - -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 diff --git a/src/attachment.hpp b/src/attachment.hpp index 083f98d8..7110d98e 100644 --- a/src/attachment.hpp +++ b/src/attachment.hpp @@ -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 diff --git a/src/base.cpp b/src/base.cpp index 84fdc9fc..6d0197c5 100644 --- a/src/base.cpp +++ b/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(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. - * - *

Eg: giving:

- *
   <iso-8859-1> "Linux dans un t'el'ephone mobile"
-  *    ("=?iso-8859-1?Q?Linux_dans_un_t=E9l=E9phone_mobile?=")
-  * 

it will return:

- *
   <: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")
-  * 
- * - * @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 diff --git a/src/base.hpp b/src/base.hpp index a00d9c7d..79203fdf 100644 --- a/src/base.hpp +++ b/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 - const string toString(const TYPE& value) - { - std::ostringstream oss; - oss << value; - - return (oss.str()); - } - - template - 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 @@ -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 diff --git a/src/body.cpp b/src/body.cpp index 1b5c853b..78f92b4d 100644 --- a/src/body.cpp +++ b/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 - (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 - (m_header.fields.find(headerField::ContentType)); + boundary = generateRandomBoundaryString(); + } + else + { + try + { + contentTypeField& ctf = dynamic_cast + (*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 ::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(m_header.fields.find(headerField::ContentType)); - return (ctf.value()); + const contentTypeField& ctf = dynamic_cast + (*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(m_header.fields.find(headerField::ContentType)); - const class charset& cs = ctf.charset(); + const contentTypeField& ctf = dynamic_cast + (*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 + (*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 (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 - (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 + (*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 + (*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 - (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 ::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 ::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 ::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 parts; + return (m_parts.size() == 0); +} - for (std::vector ::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 body::getPartList() const +{ + std::vector list; + + list.reserve(m_parts.size()); + + for (std::vector ::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 ::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 body::getPartList() +{ + return (m_parts); } diff --git a/src/body.hpp b/src/body.hpp index 9e43744c..b12ebcc7 100644 --- a/src/body.hpp +++ b/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 ::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 ::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 getPartList() const; - iterator operator-(difference_type x) const { return iterator(m_iterator - x); } + /** Return the part list. + * + * @return list of parts + */ + const std::vector 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 ::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 ::const_iterator::difference_type difference_type; + /** Return a modifiable reference to body contents. + * + * @return body contents + */ + contentHandler& getContents(); - const_iterator(std::vector ::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 ::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 ::size_type x) const { return (*m_parts[x]); } - bodyPart& operator[](const std::vector ::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 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 m_parts; const bool isRootPart() const; + void initNewPart(bodyPart* part); + public: using component::parse; diff --git a/src/bodyPart.cpp b/src/bodyPart.cpp index 522a34cd..ec046ce2 100644 --- a/src/bodyPart.cpp +++ b/src/bodyPart.cpp @@ -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 (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 diff --git a/src/bodyPart.hpp b/src/bodyPart.hpp index 21e59b79..e8127a0c 100644 --- a/src/bodyPart.hpp +++ b/src/bodyPart.hpp @@ -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; }; diff --git a/src/charset.cpp b/src/charset.cpp index 5d5b872c..ffa5aea0 100644 --- a/src/charset.cpp +++ b/src/charset.cpp @@ -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 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 platformDependantHandler::getLocaleCharset() - * 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 (other).m_name; +} + + } // vmime diff --git a/src/charset.hpp b/src/charset.hpp index 4d7f8c5b..1a42afbb 100644 --- a/src/charset.hpp +++ b/src/charset.hpp @@ -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 platformDependantHandler::getLocaleCharset() + * 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; diff --git a/src/charsetParameter.cpp b/src/charsetParameter.cpp deleted file mode 100644 index ccbe7b43..00000000 --- a/src/charsetParameter.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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(param); - m_value = source.m_value; - - defaultParameter::copyFrom(param); -} - - -} // vmime diff --git a/src/charsetParameter.hpp b/src/charsetParameter.hpp deleted file mode 100644 index 4e5e89d9..00000000 --- a/src/charsetParameter.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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 diff --git a/src/component.cpp b/src/component.cpp index b8c65cd1..b387b9c5 100644 --- a/src/component.cpp +++ b/src/component.cpp @@ -18,6 +18,7 @@ // #include "component.hpp" +#include "base.hpp" #include @@ -26,6 +27,11 @@ namespace vmime { +component::~component() +{ +} + + void component::parse(const string& buffer) { parse(buffer, 0, buffer.length(), NULL); diff --git a/src/component.hpp b/src/component.hpp index f7c874d7..adb8825c 100644 --- a/src/component.hpp +++ b/src/component.hpp @@ -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; }; diff --git a/src/constants.cpp b/src/constants.cpp index c46c7a25..f4bccee0 100644 --- a/src/constants.cpp +++ b/src/constants.cpp @@ -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 diff --git a/src/constants.hpp b/src/constants.hpp index 1970e626..4e7d13c0 100644 --- a/src/constants.hpp +++ b/src/constants.hpp @@ -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; + } } diff --git a/src/contentDispositionField.cpp b/src/contentDispositionField.cpp index c076633f..d3b3eb4a 100644 --- a/src/contentDispositionField.cpp +++ b/src/contentDispositionField.cpp @@ -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 () { - m_value.parse(buffer, position, end); } -const string contentDispositionField::generateValue() const +const datetime& contentDispositionField::getCreationDate() const { - return (m_value.generate()); + return (dynamic_cast (*findParameter("creation-date")).getValue()); } -contentDispositionField& contentDispositionField::operator=(const disposition& type) +void contentDispositionField::setCreationDate(const datetime& creationDate) { - m_value = type; - return (*this); + dynamic_cast (*getParameter("creation-date")).setValue(creationDate); } -void contentDispositionField::copyFrom(const headerField& field) +const datetime& contentDispositionField::getModificationDate() const { - const contentDispositionField& source = dynamic_cast(field); - m_value = source.m_value; + return (dynamic_cast (*findParameter("modification-date")).getValue()); +} - parameterizedHeaderField::copyFrom(field); + +void contentDispositionField::setModificationDate(const datetime& modificationDate) +{ + dynamic_cast (*getParameter("modification-date")).setValue(modificationDate); +} + + +const datetime& contentDispositionField::getReadDate() const +{ + return (dynamic_cast (*findParameter("read-date")).getValue()); +} + + +void contentDispositionField::setReadDate(const datetime& readDate) +{ + dynamic_cast (*getParameter("read-date")).setValue(readDate); +} + + +const string contentDispositionField::getFilename() const +{ + return (dynamic_cast (*findParameter("filename")).getValue()); +} + + +void contentDispositionField::setFilename(const string& filename) +{ + dynamic_cast (*getParameter("filename")).setValue(filename); +} + + +const string contentDispositionField::getSize() const +{ + return (dynamic_cast (*findParameter("size")).getValue()); +} + + +void contentDispositionField::setSize(const string& size) +{ + dynamic_cast (*getParameter("size")).setValue(size); } diff --git a/src/contentDispositionField.hpp b/src/contentDispositionField.hpp index d0cf0b88..38a7caa2 100644 --- a/src/contentDispositionField.hpp +++ b/src/contentDispositionField.hpp @@ -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 { friend class headerFieldFactory::registerer ; 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(parameters.find("creation-date")).value()); } - datetime& creationDate() { return (dynamic_cast(parameters.get("creation-date")).value()); } + const string getFilename() const; + void setFilename(const string& filename); - const datetime& modificationDate() const { return (dynamic_cast(parameters.find("modification-date")).value()); } - datetime& modificationDate() { return (dynamic_cast(parameters.get("modification-date")).value()); } - - const datetime& readDate() const { return (dynamic_cast(parameters.find("read-date")).value()); } - datetime& readDate() { return (dynamic_cast(parameters.get("read-date")).value()); } - - const string& filename() const { return (dynamic_cast(parameters.find("filename")).value()); } - string& filename() { return (dynamic_cast(parameters.get("filename")).value()); } - - const string& size() const { return (dynamic_cast(parameters.find("size")).value()); } - string& size() { return (dynamic_cast(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); }; diff --git a/src/contentEncodingField.cpp b/src/contentEncodingField.cpp deleted file mode 100644 index f16fd551..00000000 --- a/src/contentEncodingField.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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(field); - m_value = source.m_value; - - parameterizedHeaderField::copyFrom(field); -} - - -} // vmime diff --git a/src/contentEncodingField.hpp b/src/contentEncodingField.hpp deleted file mode 100644 index 18d01ca7..00000000 --- a/src/contentEncodingField.hpp +++ /dev/null @@ -1,61 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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 ; - -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 diff --git a/src/contentHandler.cpp b/src/contentHandler.cpp index e33d0e5c..195055ed 100644 --- a/src/contentHandler.cpp +++ b/src/contentHandler.cpp @@ -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 theDecoder(m_encoding.getEncoder()); utility::auto_ptr 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 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); } diff --git a/src/contentHandler.hpp b/src/contentHandler.hpp index a0ffd3d9..a6ea884a 100644 --- a/src/contentHandler.hpp +++ b/src/contentHandler.hpp @@ -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: diff --git a/src/contentTypeField.cpp b/src/contentTypeField.cpp index 3149606e..69da97ae 100644 --- a/src/contentTypeField.cpp +++ b/src/contentTypeField.cpp @@ -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 () { - m_value.parse(buffer, position, end); } -const string contentTypeField::generateValue() const +const string contentTypeField::getBoundary() const { - return (m_value.generate()); + return (dynamic_cast (*findParameter("boundary")).getValue()); } -contentTypeField& contentTypeField::operator=(const mediaType& type) +void contentTypeField::setBoundary(const string& boundary) { - m_value = type; - return (*this); + dynamic_cast (*getParameter("boundary")).setValue(boundary); } -void contentTypeField::copyFrom(const headerField& field) +const charset& contentTypeField::getCharset() const { - const contentTypeField& source = dynamic_cast(field); - m_value = source.m_value; + return (dynamic_cast (*findParameter("charset")).getValue()); +} - parameterizedHeaderField::copyFrom(field); + +void contentTypeField::setCharset(const charset& ch) +{ + dynamic_cast (*getParameter("charset")).setValue(ch); } diff --git a/src/contentTypeField.hpp b/src/contentTypeField.hpp index 5244e454..69ea5d5c 100644 --- a/src/contentTypeField.hpp +++ b/src/contentTypeField.hpp @@ -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 { friend class headerFieldFactory::registerer ; 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(parameters.find("boundary")).value()); } - string& boundary() { return (dynamic_cast(parameters.get("boundary")).value()); } - - const class charset& charset() const { return (dynamic_cast(parameters.find("charset")).value()); } - class charset& charset() { return (dynamic_cast(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); }; diff --git a/src/dateField.cpp b/src/dateField.cpp deleted file mode 100644 index ed673505..00000000 --- a/src/dateField.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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(field); - m_datetime = source.m_datetime; - - headerField::copyFrom(field); -} - - -} // vmime diff --git a/src/dateField.hpp b/src/dateField.hpp deleted file mode 100644 index 76f47128..00000000 --- a/src/dateField.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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 ; - -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 diff --git a/src/dateParameter.cpp b/src/dateParameter.cpp deleted file mode 100644 index f0f4d8cd..00000000 --- a/src/dateParameter.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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(param); - m_value = source.m_value; - - defaultParameter::copyFrom(param); -} - - -} // vmime diff --git a/src/dateTime.cpp b/src/dateTime.cpp index ceaec6f1..002769f0 100644 --- a/src/dateTime.cpp +++ b/src/dateTime.cpp @@ -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 (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 diff --git a/src/dateTime.hpp b/src/dateTime.hpp index b50e6483..7d1157e4 100644 --- a/src/dateTime.hpp +++ b/src/dateTime.hpp @@ -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: diff --git a/src/defaultAttachment.cpp b/src/defaultAttachment.cpp index 20f649cb..db3f9ca3 100644 --- a/src/defaultAttachment.cpp +++ b/src/defaultAttachment.cpp @@ -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 (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); } diff --git a/src/defaultAttachment.hpp b/src/defaultAttachment.hpp index 2cf11638..c9198598 100644 --- a/src/defaultAttachment.hpp +++ b/src/defaultAttachment.hpp @@ -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; }; diff --git a/src/defaultField.cpp b/src/defaultField.cpp deleted file mode 100644 index 77392725..00000000 --- a/src/defaultField.cpp +++ /dev/null @@ -1,71 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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(field); - m_text = source.m_text; - - headerField::copyFrom(field); -} - - -} // vmime diff --git a/src/defaultField.hpp b/src/defaultField.hpp deleted file mode 100644 index c855ca8c..00000000 --- a/src/defaultField.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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 ; - -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 diff --git a/src/defaultParameter.cpp b/src/defaultParameter.cpp deleted file mode 100644 index 2d9e72db..00000000 --- a/src/defaultParameter.cpp +++ /dev/null @@ -1,117 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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 diff --git a/src/defaultParameter.hpp b/src/defaultParameter.hpp deleted file mode 100644 index feb8c6f9..00000000 --- a/src/defaultParameter.hpp +++ /dev/null @@ -1,55 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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 diff --git a/src/defaultParameterizedHeaderField.cpp b/src/defaultParameterizedHeaderField.cpp deleted file mode 100644 index 9ca8d154..00000000 --- a/src/defaultParameterizedHeaderField.cpp +++ /dev/null @@ -1,62 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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 - (field); - m_value = source.m_value; - - parameterizedHeaderField::copyFrom(field); -} - - -defaultParameterizedHeaderField& defaultParameterizedHeaderField::operator=(const string& value) -{ - m_value = value; - return (*this); -} - - -} // vmime diff --git a/src/defaultParameterizedHeaderField.hpp b/src/defaultParameterizedHeaderField.hpp deleted file mode 100644 index d85fde59..00000000 --- a/src/defaultParameterizedHeaderField.hpp +++ /dev/null @@ -1,63 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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 ; - -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 diff --git a/src/disposition.cpp b/src/disposition.cpp index 7f8962f0..dd4a59b8 100644 --- a/src/disposition.cpp +++ b/src/disposition.cpp @@ -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 (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 diff --git a/src/disposition.hpp b/src/disposition.hpp index c994a723..4ca2fe92 100644 --- a/src/disposition.hpp +++ b/src/disposition.hpp @@ -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; diff --git a/src/encoder.cpp b/src/encoder.cpp index 6634f7bb..9fabd5a8 100644 --- a/src/encoder.cpp +++ b/src/encoder.cpp @@ -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 encoder::availableProperties() const +const std::vector encoder::getAvailableProperties() const { std::vector list; return (list); diff --git a/src/encoder.hpp b/src/encoder.hpp index 1aa97d49..2103d896 100644 --- a/src/encoder.hpp +++ b/src/encoder.hpp @@ -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 availableProperties() const; + virtual const std::vector 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: diff --git a/src/encoderB64.cpp b/src/encoderB64.cpp index 25b15ad9..c45d719f 100644 --- a/src/encoderB64.cpp +++ b/src/encoderB64.cpp @@ -30,9 +30,9 @@ encoderB64::encoderB64() } -const std::vector encoderB64::availableProperties() const +const std::vector encoderB64::getAvailableProperties() const { - std::vector list(encoder::availableProperties()); + std::vector 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 ("maxlinelength", -1); + const int propMaxLineLength = getProperties().getProperty ("maxlinelength", -1); const bool cutLines = (propMaxLineLength != -1); const int maxLineLength = std::min(propMaxLineLength, 76); diff --git a/src/encoderB64.hpp b/src/encoderB64.hpp index ff978985..93c0b7f3 100644 --- a/src/encoderB64.hpp +++ b/src/encoderB64.hpp @@ -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 availableProperties() const; + const std::vector getAvailableProperties() const; protected: diff --git a/src/encoderFactory.cpp b/src/encoderFactory.cpp index 6da09dbb..15c9e959 100644 --- a/src/encoderFactory.cpp +++ b/src/encoderFactory.cpp @@ -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 ::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 ::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 encoderFactory::getEncoderList() const +{ + std::vector res; + + for (std::vector ::const_iterator it = m_encoders.begin() ; + it != m_encoders.end() ; ++it) { - throw exceptions::no_encoder_available(); - return (NULL); + res.push_back(*it); } + + return (res); } diff --git a/src/encoderFactory.hpp b/src/encoderFactory.hpp index cbd52048..a5d39c6e 100644 --- a/src/encoderFactory.hpp +++ b/src/encoderFactory.hpp @@ -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 NameMap; - NameMap m_nameMap; + std::vector m_encoders; public: + /** Register a new encoder by its encoding name. + * + * @param name encoding name + */ template void registerName(const string& name) { - const string _name = toLower(name); - m_nameMap.insert(NameMap::value_type(_name, - new registeredEncoderImpl (_name))); + m_encoders.push_back(new registeredEncoderImpl (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 getEncoderList() const; }; diff --git a/src/encoderQP.cpp b/src/encoderQP.cpp index 46125c93..637d0b9e 100644 --- a/src/encoderQP.cpp +++ b/src/encoderQP.cpp @@ -30,9 +30,9 @@ encoderQP::encoderQP() } -const std::vector encoderQP::availableProperties() const +const std::vector encoderQP::getAvailableProperties() const { - std::vector list(encoder::availableProperties()); + std::vector 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 ("maxlinelength", (string::size_type) -1); + getProperties().getProperty ("maxlinelength", (string::size_type) -1); - const bool rfc2047 = properties().get ("rfc2047", false); - const bool text = properties().get ("text", false); // binary mode by default + const bool rfc2047 = getProperties().getProperty ("rfc2047", false); + const bool text = getProperties().getProperty ("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 ("rfc2047", false); + const bool rfc2047 = getProperties().getProperty ("rfc2047", false); char buffer[16384]; int bufferLength = 0; diff --git a/src/encoderQP.hpp b/src/encoderQP.hpp index 519f43f1..2029c8b9 100644 --- a/src/encoderQP.hpp +++ b/src/encoderQP.hpp @@ -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 availableProperties() const; + const std::vector getAvailableProperties() const; protected: diff --git a/src/encoderUUE.cpp b/src/encoderUUE.cpp index 78dffa0c..dbc31ce8 100644 --- a/src/encoderUUE.cpp +++ b/src/encoderUUE.cpp @@ -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 encoderUUE::availableProperties() const +const std::vector encoderUUE::getAvailableProperties() const { - std::vector list(encoder::availableProperties()); + std::vector 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 ("filename", ""); - const string propMode = properties().get ("mode", "644"); + const string propFilename = getProperties().getProperty ("filename", ""); + const string propMode = getProperties().getProperty ("mode", "644"); const string::size_type maxLineLength = - std::min(properties().get ("maxlinelength", 46), + std::min(getProperties().getProperty ("maxlinelength", 46), static_cast (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; diff --git a/src/encoderUUE.hpp b/src/encoderUUE.hpp index c7784474..44945de9 100644 --- a/src/encoderUUE.hpp +++ b/src/encoderUUE.hpp @@ -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 availableProperties() const; + const std::vector getAvailableProperties() const; }; diff --git a/src/encoding.cpp b/src/encoding.cpp index c797cf18..3211f2a7 100644 --- a/src/encoding.cpp +++ b/src/encoding.cpp @@ -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 (other); + + m_name = e.m_name; +} + + +const string& encoding::getName() const +{ + return (m_name); +} + + +void encoding::setName(const string& name) +{ + m_name = name; +} + + } // vmime diff --git a/src/encoding.hpp b/src/encoding.hpp index ca344fff..52e48bd5 100644 --- a/src/encoding.hpp +++ b/src/encoding.hpp @@ -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; diff --git a/src/exception.hpp b/src/exception.hpp index b7880d31..815fd1d4 100644 --- a/src/exception.hpp +++ b/src/exception.hpp @@ -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: diff --git a/src/fileAttachment.cpp b/src/fileAttachment.cpp index ca7ff789..d13eb3de 100644 --- a/src/fileAttachment.cpp +++ b/src/fileAttachment.cpp @@ -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 // diff --git a/src/fileAttachment.hpp b/src/fileAttachment.hpp index 66cb258d..d25af394 100644 --- a/src/fileAttachment.hpp +++ b/src/fileAttachment.hpp @@ -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; }; diff --git a/src/genericField.hpp b/src/genericField.hpp new file mode 100644 index 00000000..e83f25f2 --- /dev/null +++ b/src/genericField.hpp @@ -0,0 +1,91 @@ +// +// VMime library (http://vmime.sourceforge.net) +// Copyright (C) 2002-2004 Vincent Richard +// +// 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 genericField : virtual public headerField +{ + friend class headerFieldFactory::registerer >; + +protected: + + genericField() { } + +public: + + genericField & operator=(const genericField & other) + { + copyFrom(other); + return (*this); + } + + const VALUE_TYPE& getValue() const + { + return (m_value); + } + + VALUE_TYPE& getValue() + { + return (m_value); + } + + template + void setValue(const TYPE& value) + { + m_value = value; + } + + void setValue(const component& value) + { + const VALUE_TYPE& v = dynamic_cast (value); + m_value = v; + } + +private: + + VALUE_TYPE m_value; +}; + + +template <> +class genericField : public genericField > +{ +}; + + +} // vmime + + +#endif // VMIME_GENERICFIELD_HPP_INCLUDED diff --git a/src/genericParameter.hpp b/src/genericParameter.hpp new file mode 100644 index 00000000..abd01ccf --- /dev/null +++ b/src/genericParameter.hpp @@ -0,0 +1,91 @@ +// +// VMime library (http://vmime.sourceforge.net) +// Copyright (C) 2002-2004 Vincent Richard +// +// 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 genericParameter : public parameter +{ + friend class parameterFactory::registerer >; + +protected: + + genericParameter() { } + +public: + + genericParameter & operator=(const genericParameter & other) + { + copyFrom(other); + return (*this); + } + + const VALUE_TYPE& getValue() const + { + return (m_value); + } + + VALUE_TYPE& getValue() + { + return (m_value); + } + + template + void setValue(const TYPE& value) + { + m_value = value; + } + + void setValue(const component& value) + { + const VALUE_TYPE& v = dynamic_cast (value); + m_value = v; + } + +private: + + VALUE_TYPE m_value; +}; + + +template <> +class genericParameter : public genericParameter > +{ +}; + + +} // vmime + + +#endif // VMIME_GENERICPARAMETER_HPP_INCLUDED diff --git a/src/header.cpp b/src/header.cpp index eb972de0..317189b8 100644 --- a/src/header.cpp +++ b/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 ::const_iterator - it = fields.m_fields.begin() ; it != fields.m_fields.end() ; ++it) + for (std::vector ::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 ::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 (other); + + std::vector fields; + + try + { + fields.reserve(h.m_fields.size()); + + for (std::vector ::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 ::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 ::const_iterator pos = m_fields.begin(); const std::vector ::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 ::const_iterator pos = m_fields.begin(); - const std::vector ::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 ::const_iterator pos = m_fields.begin(); - const std::vector ::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 ::const_iterator pos = m_fields.begin(); const std::vector ::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 header::fieldsContainer::findAllByType(const headerField::Types fieldType) +std::vector header::findAllFields(const string& fieldName) { - std::vector result; - - std::vector ::const_iterator pos = m_fields.begin(); - const std::vector ::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 header::fieldsContainer::findAllByName(const string& fieldName) -{ - const string name = toLower(fieldName); + const string name = stringUtils::toLower(fieldName); std::vector result; @@ -365,7 +344,7 @@ std::vector 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 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 ::const_iterator pos = m_fields.begin(); - const std::vector ::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 ::const_iterator pos = m_fields.begin(); const std::vector ::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 ::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 ::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 ::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 ::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 fields; + const std::vector ::iterator it = std::find + (m_fields.begin(), m_fields.end(), field); - for (std::vector ::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 ::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 ::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 header::getFieldList() const +{ + std::vector list; + + list.reserve(m_fields.size()); + + for (std::vector ::const_iterator it = m_fields.begin() ; + it != m_fields.end() ; ++it) + { + list.push_back(*it); + } + + return (list); +} + + +const std::vector header::getFieldList() +{ + return (m_fields); } diff --git a/src/header.hpp b/src/header.hpp index b675e6fc..bf0b74e9 100644 --- a/src/header.hpp +++ b/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 \ + (*getField(fields::fieldName)); } \ + const type& methodName() const { return dynamic_cast \ + (*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(get(headerField::From))); } - mailboxField& Sender() { return (dynamic_cast(get(headerField::Sender))); } - mailboxField& ReplyTo() { return (dynamic_cast(get(headerField::ReplyTo))); } - mailboxField& DeliveredTo() { return (dynamic_cast(get(headerField::DeliveredTo))); } - addressListField& To() { return (dynamic_cast(get(headerField::To))); } - addressListField& Cc() { return (dynamic_cast(get(headerField::Cc))); } - addressListField& Bcc() { return (dynamic_cast(get(headerField::Bcc))); } - dateField& Date() { return (dynamic_cast(get(headerField::Date))); } - textField& Subject() { return (dynamic_cast(get(headerField::Subject))); } - textField& Organization() { return (dynamic_cast(get(headerField::Organization))); } - textField& UserAgent() { return (dynamic_cast(get(headerField::UserAgent))); } - contentTypeField& ContentType() { return (dynamic_cast(get(headerField::ContentType))); } - textField& ContentDescription() { return (dynamic_cast(get(headerField::ContentDescription))); } - contentEncodingField& ContentTransferEncoding() { return (dynamic_cast(get(headerField::ContentTransferEncoding))); } - defaultField& MimeVersion() { return (dynamic_cast(get(headerField::MimeVersion))); } - contentDispositionField& ContentDisposition() { return (dynamic_cast(get(headerField::ContentDisposition))); } - messageIdField& ContentId() { return (dynamic_cast(get(headerField::ContentId))); } - messageIdField& MessageId() { return (dynamic_cast(get(headerField::MessageId))); } - defaultField& ContentLocation() { return (dynamic_cast(get(headerField::ContentLocation))); } +#undef FIELD_ACCESS - const mailboxField& From() const { return (dynamic_cast(find(headerField::From))); } - const mailboxField& Sender() const { return (dynamic_cast(find(headerField::Sender))); } - const mailboxField& ReplyTo() const { return (dynamic_cast(find(headerField::ReplyTo))); } - const mailboxField& DeliveredTo() const { return (dynamic_cast(find(headerField::DeliveredTo))); } - const addressListField& To() const { return (dynamic_cast(find(headerField::To))); } - const addressListField& Cc() const { return (dynamic_cast(find(headerField::Cc))); } - const addressListField& Bcc() const { return (dynamic_cast(find(headerField::Bcc))); } - const dateField& Date() const { return (dynamic_cast(find(headerField::Date))); } - const textField& Subject() const { return (dynamic_cast(find(headerField::Subject))); } - const textField& Organization() const { return (dynamic_cast(find(headerField::Organization))); } - const textField& UserAgent() const { return (dynamic_cast(find(headerField::UserAgent))); } - const contentTypeField& ContentType() const { return (dynamic_cast(find(headerField::ContentType))); } - const textField& ContentDescription() const { return (dynamic_cast(find(headerField::ContentDescription))); } - const contentEncodingField& ContentTransferEncoding() const { return (dynamic_cast(find(headerField::ContentTransferEncoding))); } - const defaultField& MimeVersion() const { return (dynamic_cast(find(headerField::MimeVersion))); } - const contentDispositionField& ContentDisposition() const { return (dynamic_cast(find(headerField::ContentDisposition))); } - const messageIdField& ContentId() const { return (dynamic_cast(find(headerField::ContentId))); } - const messageIdField& MessageId() const { return (dynamic_cast(find(headerField::MessageId))); } - const defaultField& ContentLocation() const { return (dynamic_cast(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 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 findAllByType(const headerField::Types fieldType); - std::vector 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 ::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 ::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 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 getFieldList(); - protected: + header* clone() const; + void copyFrom(const component& other); + header& operator=(const header& other); - std::vector ::iterator m_iterator; - }; +private: - class const_iterator - { - public: - - typedef std::vector ::const_iterator::difference_type difference_type; - - const_iterator(std::vector ::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 ::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 ::size_type count() const { return (m_fields.size()); } - const std::vector ::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 m_fields; - - } fields; - - typedef fieldsContainer::iterator iterator; - typedef fieldsContainer::const_iterator const_iterator; - - header& operator=(const header& h); + std::vector m_fields; public: diff --git a/src/headerField.cpp b/src/headerField.cpp index 20f90251..db03c68e 100644 --- a/src/headerField.cpp +++ b/src/headerField.cpp @@ -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 (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] == '-'); } diff --git a/src/headerField.hpp b/src/headerField.hpp index 70a74eff..3bdc3116 100644 --- a/src/headerField.hpp +++ b/src/headerField.hpp @@ -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; }; diff --git a/src/headerFieldFactory.cpp b/src/headerFieldFactory.cpp index 0187c26d..19862b6a 100644 --- a/src/headerFieldFactory.cpp +++ b/src/headerFieldFactory.cpp @@ -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 (headerField::From); - registerType (headerField::To); - registerType (headerField::Cc); - registerType (headerField::Bcc); - registerType (headerField::Sender); - registerType (headerField::Date); - registerType (headerField::Received); - registerType (headerField::Subject); - registerType (headerField::ReplyTo); - registerType (headerField::DeliveredTo); - registerType (headerField::Organization); - registerType (headerField::UserAgent); - registerType (headerField::ReturnPath); - registerType (headerField::ContentType); - registerType (headerField::ContentTransferEncoding); - registerType (headerField::ContentDescription); - registerType (headerField::MimeVersion); - registerType (headerField::ContentDisposition); - registerType (headerField::ContentId); - registerType (headerField::MessageId); - registerType (headerField::ContentLocation); + // Register some default fields + registerName (vmime::fields::FROM); + registerName (vmime::fields::TO); + registerName (vmime::fields::CC); + registerName (vmime::fields::BCC); + registerName (vmime::fields::SENDER); + registerName (vmime::fields::DATE); + registerName (vmime::fields::RECEIVED); + registerName (vmime::fields::SUBJECT); + registerName (vmime::fields::REPLY_TO); + registerName (vmime::fields::DELIVERED_TO); + registerName (vmime::fields::ORGANIZATION); + registerName (vmime::fields::USER_AGENT); + registerName (vmime::fields::RETURN_PATH); + registerName (vmime::fields::CONTENT_TYPE); + registerName (vmime::fields::CONTENT_TRANSFER_ENCODING); + registerName (vmime::fields::CONTENT_DESCRIPTION); + registerName (vmime::fields::MIME_VERSION); + registerName (vmime::fields::CONTENT_DISPOSITION); + registerName (vmime::fields::CONTENT_ID); + registerName (vmime::fields::MESSAGE_ID); + registerName (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 ::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); } diff --git a/src/headerFieldFactory.hpp b/src/headerFieldFactory.hpp index 13024fd6..5471eb69 100644 --- a/src/headerFieldFactory.hpp +++ b/src/headerFieldFactory.hpp @@ -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 NameMap; - typedef std::map TypeMap; NameMap m_nameMap; - TypeMap m_typeMap; public: @@ -63,19 +62,10 @@ public: template void registerName(const string& name) { - m_nameMap.insert(NameMap::value_type(toLower(name), ®isterer::creator)); + m_nameMap.insert(NameMap::value_type(stringUtils::toLower(name), ®isterer::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 - void registerType(const headerField::Types type) - { - m_typeMap.insert(TypeMap::value_type(type, ®isterer::creator)); - } }; diff --git a/src/htmlTextPart.cpp b/src/htmlTextPart.cpp index f864272d..596d9718 100644 --- a/src/htmlTextPart.cpp +++ b/src/htmlTextPart.cpp @@ -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 ::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 & cidParts, std::vector & 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((*p).header().fields.find(headerField::ContentId)); - cidParts.push_back(&(*p)); + dynamic_cast(*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((*p).header().fields.find(headerField::ContentId)); - locParts.push_back(&(*p)); + dynamic_cast(*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 - (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 - (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_iterator p = cidParts.begin() ; p != cidParts.end() ; ++p) { const messageIdField& midField = dynamic_cast - ((**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_iterator p = locParts.begin() ; p != locParts.end() ; ++p) { const defaultField& locField = dynamic_cast - ((**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 - (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 - ((*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 ::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 ::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 ::const_iterator o = m_list.begin() ; o != m_list.end() ; ++o) + for (std::vector ::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); } diff --git a/src/htmlTextPart.hpp b/src/htmlTextPart.hpp index eeb7b618..777bfcae 100644 --- a/src/htmlTextPart.hpp +++ b/src/htmlTextPart.hpp @@ -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 tag) + /** Embedded object (eg: image for 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 ::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 ::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 ::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 ::size_type count() const { return (m_list.size()); } - const std::vector ::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 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 m_objects; void findEmbeddedParts(const bodyPart& part, std::vector & cidParts, std::vector & 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); }; diff --git a/src/mailbox.cpp b/src/mailbox.cpp index f5da6843..bb5d3c5d 100644 --- a/src/mailbox.cpp +++ b/src/mailbox.cpp @@ -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(addr); + const mailbox& source = dynamic_cast (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 diff --git a/src/mailbox.hpp b/src/mailbox.hpp index 3fa79045..e3f458e0 100644 --- a/src/mailbox.hpp +++ b/src/mailbox.hpp @@ -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(); diff --git a/src/mailboxField.cpp b/src/mailboxField.cpp index e4e0164c..3cd7d910 100644 --- a/src/mailboxField.cpp +++ b/src/mailboxField.cpp @@ -30,10 +30,16 @@ mailboxField::mailboxField() } +mailboxField::mailboxField(const mailboxField&) + : headerField(), genericField () +{ +} + + 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 (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 (parsedAddress); + getValue() = *static_cast (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(field); - m_mailbox = source.m_mailbox; - - headerField::copyFrom(field); -} - - } // vmime diff --git a/src/mailboxField.hpp b/src/mailboxField.hpp index 13cd8e49..a8213613 100644 --- a/src/mailboxField.hpp +++ b/src/mailboxField.hpp @@ -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 { friend class headerFieldFactory::registerer ; 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; }; diff --git a/src/mailboxGroup.cpp b/src/mailboxGroup.cpp index ff708313..c266a331 100644 --- a/src/mailboxGroup.cpp +++ b/src/mailboxGroup.cpp @@ -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 ((*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 ::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 (other); + + m_name = source.m_name; + + removeAllMailboxes(); + + for (std::vector ::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(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(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(addr); - - m_name = source.m_name; - - clear(); - - for (std::vector ::const_iterator i = source.m_list.begin() ; i != source.m_list.end() ; ++i) - m_list.push_back(static_cast((*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 ::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 ::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 ::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 ::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 mailboxGroup::getMailboxList() const +{ + std::vector list; + + list.reserve(m_list.size()); + + for (std::vector ::const_iterator it = m_list.begin() ; + it != m_list.end() ; ++it) + { + list.push_back(*it); + } + + return (list); +} + + +const std::vector mailboxGroup::getMailboxList() +{ + return (m_list); +} + + } // vmime diff --git a/src/mailboxGroup.hpp b/src/mailboxGroup.hpp index 0187f37c..3cf1266c 100644 --- a/src/mailboxGroup.hpp +++ b/src/mailboxGroup.hpp @@ -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 ::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 ::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 ::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 ::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 ::size_type size() const { return (m_list.size()); } - const std::vector ::size_type count() const { return (m_list.size()); } - const bool empty() const { return (m_list.empty()); } - - const mailbox& operator[](const std::vector ::size_type x) const { return (*m_list[x]); } - mailbox& operator[](const std::vector ::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 getMailboxList() const; + /** Return the mailbox list. + * + * @return list of mailboxes + */ + const std::vector getMailboxList(); const bool isGroup() const; -protected: +private: text m_name; std::vector m_list; diff --git a/src/mailboxList.cpp b/src/mailboxList.cpp index ded7ede1..f8944e29 100644 --- a/src/mailboxList.cpp +++ b/src/mailboxList.cpp @@ -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(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(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 (addressList::getAddressAt(pos)); +} + + +const mailbox* const mailboxList::getMailboxAt(const int pos) const +{ + return static_cast (addressList::getAddressAt(pos)); +} + + +const std::vector mailboxList::getMailboxList() const +{ + const std::vector addrList = addressList::getAddressList(); + std::vector res; + + for (std::vector ::const_iterator it = addrList.begin() ; + it != addrList.end() ; ++it) + { + const mailbox* mbox = dynamic_cast (*it); + + if (mbox != NULL) + res.push_back(mbox); + } + + return (res); +} + + +const std::vector mailboxList::getMailboxList() +{ + const std::vector addrList = addressList::getAddressList(); + std::vector res; + + for (std::vector ::const_iterator it = addrList.begin() ; + it != addrList.end() ; ++it) + { + mailbox* mbox = dynamic_cast (*it); + + if (mbox != NULL) + res.push_back(mbox); + } + + return (res); } diff --git a/src/mailboxList.hpp b/src/mailboxList.hpp index 28c6152b..7c4ed40c 100644 --- a/src/mailboxList.hpp +++ b/src/mailboxList.hpp @@ -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 ::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(**m_iterator); } - mailbox* operator->() const { return static_cast(*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 ::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 getMailboxList() const; - const_iterator(std::vector ::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(**m_iterator); } - const mailbox* operator->() const { return static_cast(*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 ::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 getMailboxList(); }; diff --git a/src/mailboxListField.cpp b/src/mailboxListField.cpp deleted file mode 100644 index 69c328f5..00000000 --- a/src/mailboxListField.cpp +++ /dev/null @@ -1,60 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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(field); - m_list = source.m_list; - - headerField::copyFrom(field); -} - - -} // vmime - diff --git a/src/mailboxListField.hpp b/src/mailboxListField.hpp deleted file mode 100644 index 6e01c278..00000000 --- a/src/mailboxListField.hpp +++ /dev/null @@ -1,68 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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 ; - -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 diff --git a/src/mediaType.cpp b/src/mediaType.cpp index 6681a0dc..34e28cab 100644 --- a/src/mediaType.cpp +++ b/src/mediaType.cpp @@ -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 (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 diff --git a/src/mediaType.hpp b/src/mediaType.hpp index f4148e5c..a5bf1a09 100644 --- a/src/mediaType.hpp +++ b/src/mediaType.hpp @@ -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: diff --git a/src/messageBuilder.cpp b/src/messageBuilder.cpp index 52ee6390..7c51ec8a 100644 --- a/src/messageBuilder.cpp +++ b/src/messageBuilder.cpp @@ -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 ::const_iterator a = m_attach.begin() ; a != m_attach.end() ; ++a) + for (std::vector ::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 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_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 messageBuilder::getAttachmentList() const +{ + std::vector res; + + res.reserve(m_attach.size()); + + for (std::vector ::const_iterator it = m_attach.begin() ; + it != m_attach.end() ; ++it) + { + res.push_back(*it); + } + + return (res); +} + + +const std::vector messageBuilder::getAttachmentList() +{ + return (m_attach); } diff --git a/src/messageBuilder.hpp b/src/messageBuilder.hpp index ce7d34b1..f928d1d5 100644 --- a/src/messageBuilder.hpp +++ b/src/messageBuilder.hpp @@ -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 & 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 getAttachmentList() const; + + /** Return the list of attachments. + * + * @return list of attachments + */ + const std::vector 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 m_attach; }; diff --git a/src/messageId.cpp b/src/messageId.cpp index 1ea99d1f..666136f5 100644 --- a/src/messageId.cpp +++ b/src/messageId.cpp @@ -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 (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 diff --git a/src/messageId.hpp b/src/messageId.hpp index e280dfaf..85b9fd2f 100644 --- a/src/messageId.hpp +++ b/src/messageId.hpp @@ -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; diff --git a/src/messageIdField.cpp b/src/messageIdField.cpp deleted file mode 100644 index ecdb901c..00000000 --- a/src/messageIdField.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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(field); - m_id = source.m_id; - - headerField::copyFrom(field); -} - - -} // vmime diff --git a/src/messageIdField.hpp b/src/messageIdField.hpp deleted file mode 100644 index 4809e5ed..00000000 --- a/src/messageIdField.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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 ; - -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 diff --git a/src/messageParser.cpp b/src/messageParser.cpp index d68c95e9..dd2cb690 100644 --- a/src/messageParser.cpp +++ b/src/messageParser.cpp @@ -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(msg.header().fields.find(headerField::From)).value()); +#define TRY_FIELD(var, type, name) \ + try { var = dynamic_cast(*msg.getHeader()->findField(name)).getValue(); } \ + catch (exceptions::no_such_field) { } - TRY_FIELD(m_to = dynamic_cast(msg.header().fields.find(headerField::To)).value()); - TRY_FIELD(m_cc = dynamic_cast(msg.header().fields.find(headerField::Cc)).value()); - TRY_FIELD(m_bcc = dynamic_cast(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(msg.header().fields.find(headerField::Subject)).value()); #undef TRY_FIELD // Date try { - vmime::relayField& recv = static_cast(msg.header().fields.find(headerField::Received)); - m_date = recv.date(); + vmime::relayField& recv = dynamic_cast + (*msg.getHeader()->findField(fields::RECEIVED)); + + m_date = recv.getValue().getDate(); } catch (vmime::exceptions::no_such_field&) { try { - vmime::dateField& date = static_cast(msg.header().fields.find(headerField::Date)); - m_date = date.value(); + vmime::dateField& date = dynamic_cast + (*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 - (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 - (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 - (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 - (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 :: - value_type(attach, static_cast + value_type(attach, dynamic_cast (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 - (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 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 - ((*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_iterator p = textParts.begin() ; p != textParts.end() ; ++p) + for (std::vector ::const_iterator p = textParts.begin() ; + p != textParts.end() ; ++p) { const contentTypeField& ctf = dynamic_cast - ((*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 ::const_iterator - it = m_attachInfo.find(a); + it = m_attachInfo.find(const_cast (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 messageParser::getAttachmentList() const +{ + std::vector res; + + res.reserve(m_attach.size()); + + for (std::vector ::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 messageParser::getTextPartList() const +{ + std::vector res; + + res.reserve(m_textParts.size()); + + for (std::vector ::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 diff --git a/src/messageParser.hpp b/src/messageParser.hpp index d3dc1478..f6853e9f 100644 --- a/src/messageParser.hpp +++ b/src/messageParser.hpp @@ -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 & 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 & 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 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 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; diff --git a/src/messaging/IMAPConnection.cpp b/src/messaging/IMAPConnection.cpp index 007cf353..63c96841 100644 --- a/src/messaging/IMAPConnection.cpp +++ b/src/messaging/IMAPConnection.cpp @@ -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 resp(m_parser->readResponse()); diff --git a/src/messaging/IMAPConnection.hpp b/src/messaging/IMAPConnection.hpp index ae92f1e3..0cd9b144 100644 --- a/src/messaging/IMAPConnection.hpp +++ b/src/messaging/IMAPConnection.hpp @@ -72,11 +72,11 @@ public: IMAPParser::response* readResponse(IMAPParser::literalHandler* lh = NULL); - const IMAPTag* tag() const { return (m_tag); } - const IMAPParser* parser() const { return (m_parser); } + const IMAPTag* getTag() const { return (m_tag); } + const IMAPParser* getParser() const { return (m_parser); } - const IMAPStore* store() const { return (m_store); } - IMAPStore* store() { return (m_store); } + const IMAPStore* getStore() const { return (m_store); } + IMAPStore* getStore() { return (m_store); } private: diff --git a/src/messaging/IMAPFolder.cpp b/src/messaging/IMAPFolder.cpp index 717e4817..4aef1afe 100644 --- a/src/messaging/IMAPFolder.cpp +++ b/src/messaging/IMAPFolder.cpp @@ -38,7 +38,7 @@ namespace messaging { IMAPFolder::IMAPFolder(const folder::path& path, IMAPStore* store, const int type, const int flags) : m_store(store), m_connection(m_store->connection()), m_path(path), - m_name(path.last()), m_mode(-1), m_open(false), m_type(type), m_flags(flags), + m_name(path.getLastComponent()), m_mode(-1), m_open(false), m_type(type), m_flags(flags), m_messageCount(0), m_uidValidity(0) { m_store->registerFolder(this); @@ -62,7 +62,7 @@ IMAPFolder::~IMAPFolder() } -const int IMAPFolder::mode() const +const int IMAPFolder::getMode() const { if (!isOpen()) throw exceptions::illegal_state("Folder not open"); @@ -71,13 +71,13 @@ const int IMAPFolder::mode() const } -const int IMAPFolder::type() +const int IMAPFolder::getType() { if (!isOpen()) throw exceptions::illegal_state("Folder not open"); // Root folder - if (m_path.empty()) + if (m_path.isEmpty()) { return (TYPE_CONTAINS_FOLDERS); } @@ -91,13 +91,13 @@ const int IMAPFolder::type() } -const int IMAPFolder::flags() +const int IMAPFolder::getFlags() { if (!isOpen()) throw exceptions::illegal_state("Folder not open"); // Root folder - if (m_path.empty()) + if (m_path.isEmpty()) { return (FLAG_CHILDREN | FLAG_NO_OPEN); } @@ -111,13 +111,13 @@ const int IMAPFolder::flags() } -const folder::path::component IMAPFolder::name() const +const folder::path::component IMAPFolder::getName() const { return (m_name); } -const folder::path IMAPFolder::fullPath() const +const folder::path IMAPFolder::getFullPath() const { return (m_path); } @@ -155,7 +155,7 @@ void IMAPFolder::open(const int mode, bool failIfModeIsNotAvailable) oss << "SELECT "; oss << IMAPUtils::quoteString(IMAPUtils::pathToString - (connection->hierarchySeparator(), fullPath())); + (connection->hierarchySeparator(), getFullPath())); connection->send(true, oss.str(), true); @@ -166,7 +166,7 @@ void IMAPFolder::open(const int mode, bool failIfModeIsNotAvailable) resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("SELECT", - connection->parser()->lastLine(), "bad response"); + connection->getParser()->lastLine(), "bad response"); } const std::vector & respDataList = @@ -178,7 +178,7 @@ void IMAPFolder::open(const int mode, bool failIfModeIsNotAvailable) if ((*it)->response_data() == NULL) { throw exceptions::command_error("SELECT", - connection->parser()->lastLine(), "invalid response"); + connection->getParser()->lastLine(), "invalid response"); } const IMAPParser::response_data* responseData = (*it)->response_data(); @@ -332,7 +332,7 @@ void IMAPFolder::create(const int type) // S: A004 OK CREATE completed string mailbox = IMAPUtils::pathToString - (m_connection->hierarchySeparator(), fullPath()); + (m_connection->hierarchySeparator(), getFullPath()); if (type & TYPE_CONTAINS_FOLDERS) mailbox += m_connection->hierarchySeparator(); @@ -349,7 +349,7 @@ void IMAPFolder::create(const int type) resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("CREATE", - m_connection->parser()->lastLine(), "bad response"); + m_connection->getParser()->lastLine(), "bad response"); } // Notify folder created @@ -393,7 +393,7 @@ const int IMAPFolder::testExistAndGetType() std::ostringstream oss; oss << "LIST \"\" "; oss << IMAPUtils::quoteString(IMAPUtils::pathToString - (m_connection->hierarchySeparator(), fullPath())); + (m_connection->hierarchySeparator(), getFullPath())); m_connection->send(true, oss.str(), true); @@ -404,7 +404,7 @@ const int IMAPFolder::testExistAndGetType() resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("LIST", - m_connection->parser()->lastLine(), "bad response"); + m_connection->getParser()->lastLine(), "bad response"); } // Check whether the result mailbox list contains this folder @@ -417,7 +417,7 @@ const int IMAPFolder::testExistAndGetType() if ((*it)->response_data() == NULL) { throw exceptions::command_error("LIST", - m_connection->parser()->lastLine(), "invalid response"); + m_connection->getParser()->lastLine(), "invalid response"); } const IMAPParser::mailbox_data* mailboxData = @@ -518,7 +518,7 @@ std::vector IMAPFolder::getFolders(const bool recursive) std::ostringstream oss; oss << "LIST "; oss << IMAPUtils::quoteString - (IMAPUtils::pathToString(m_connection->hierarchySeparator(), fullPath())); + (IMAPUtils::pathToString(m_connection->hierarchySeparator(), getFullPath())); if (recursive) oss << " *"; @@ -533,7 +533,7 @@ std::vector IMAPFolder::getFolders(const bool recursive) if (resp->isBad() || resp->response_done()->response_tagged()-> resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { - throw exceptions::command_error("LIST", m_connection->parser()->lastLine(), "bad response"); + throw exceptions::command_error("LIST", m_connection->getParser()->lastLine(), "bad response"); } const std::vector & respDataList = @@ -550,7 +550,7 @@ std::vector IMAPFolder::getFolders(const bool recursive) if ((*it)->response_data() == NULL) { throw exceptions::command_error("LIST", - m_connection->parser()->lastLine(), "invalid response"); + m_connection->getParser()->lastLine(), "invalid response"); } const IMAPParser::mailbox_data* mailboxData = @@ -638,19 +638,19 @@ const int IMAPFolder::getFetchCapabilities() const folder* IMAPFolder::getParent() { - return (m_path.empty() ? NULL : new IMAPFolder(m_path.parent(), m_store)); + return (m_path.isEmpty() ? NULL : new IMAPFolder(m_path.getParent(), m_store)); } -const class store& IMAPFolder::store() const +const store* IMAPFolder::getStore() const { - return (*m_store); + return (m_store); } -class store& IMAPFolder::store() +store* IMAPFolder::getStore() { - return (*m_store); + return (m_store); } @@ -695,14 +695,14 @@ void IMAPFolder::deleteMessage(const int num) resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("STORE", - m_connection->parser()->lastLine(), "bad response"); + m_connection->getParser()->lastLine(), "bad response"); } // Update local flags for (std::vector ::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { - if ((*it)->number() == num && + if ((*it)->getNumber() == num && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags |= message::FLAG_DELETED; @@ -750,7 +750,7 @@ void IMAPFolder::deleteMessages(const int from, const int to) resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("STORE", - m_connection->parser()->lastLine(), "bad response"); + m_connection->getParser()->lastLine(), "bad response"); } // Update local flags @@ -760,7 +760,7 @@ void IMAPFolder::deleteMessages(const int from, const int to) for (std::vector ::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { - if ((*it)->number() >= from && (*it)->number() <= to2 && + if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags |= message::FLAG_DELETED; @@ -816,14 +816,14 @@ void IMAPFolder::deleteMessages(const std::vector & nums) resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("STORE", - m_connection->parser()->lastLine(), "bad response"); + m_connection->getParser()->lastLine(), "bad response"); } // Update local flags for (std::vector ::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { - if (std::binary_search(list.begin(), list.end(), (*it)->number())) + if (std::binary_search(list.begin(), list.end(), (*it)->getNumber())) { if ((*it)->m_flags != message::FLAG_UNDEFINED) (*it)->m_flags |= message::FLAG_DELETED; @@ -869,7 +869,7 @@ void IMAPFolder::setMessageFlags(const int from, const int to, const int flags, for (std::vector ::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { - if ((*it)->number() >= from && (*it)->number() <= to2 && + if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags |= flags; @@ -883,7 +883,7 @@ void IMAPFolder::setMessageFlags(const int from, const int to, const int flags, for (std::vector ::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { - if ((*it)->number() >= from && (*it)->number() <= to2 && + if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags &= ~flags; @@ -898,7 +898,7 @@ void IMAPFolder::setMessageFlags(const int from, const int to, const int flags, for (std::vector ::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { - if ((*it)->number() >= from && (*it)->number() <= to2 && + if ((*it)->getNumber() >= from && (*it)->getNumber() <= to2 && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags = flags; @@ -951,7 +951,7 @@ void IMAPFolder::setMessageFlags(const std::vector & nums, const int flags, for (std::vector ::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { - if (std::binary_search(list.begin(), list.end(), (*it)->number()) && + if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags |= flags; @@ -965,7 +965,7 @@ void IMAPFolder::setMessageFlags(const std::vector & nums, const int flags, for (std::vector ::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { - if (std::binary_search(list.begin(), list.end(), (*it)->number()) && + if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags &= ~flags; @@ -980,7 +980,7 @@ void IMAPFolder::setMessageFlags(const std::vector & nums, const int flags, for (std::vector ::iterator it = m_messages.begin() ; it != m_messages.end() ; ++it) { - if (std::binary_search(list.begin(), list.end(), (*it)->number()) && + if (std::binary_search(list.begin(), list.end(), (*it)->getNumber()) && (*it)->m_flags != message::FLAG_UNDEFINED) { (*it)->m_flags = flags; @@ -1029,7 +1029,7 @@ void IMAPFolder::setMessageFlags(const string& set, const int flags, const int m resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("STORE", - m_connection->parser()->lastLine(), "bad response"); + m_connection->getParser()->lastLine(), "bad response"); } } } @@ -1063,7 +1063,7 @@ void IMAPFolder::addMessage(utility::inputStream& is, const int size, const int // Build the request text std::ostringstream command; command << "APPEND " << IMAPUtils::quoteString(IMAPUtils::pathToString - (m_connection->hierarchySeparator(), fullPath())) << ' '; + (m_connection->hierarchySeparator(), getFullPath())) << ' '; const string flagList = IMAPUtils::messageFlagList(flags); @@ -1101,7 +1101,7 @@ void IMAPFolder::addMessage(utility::inputStream& is, const int size, const int if (!ok) { throw exceptions::command_error("APPEND", - m_connection->parser()->lastLine(), "bad response"); + m_connection->getParser()->lastLine(), "bad response"); } // Send message data @@ -1139,7 +1139,7 @@ void IMAPFolder::addMessage(utility::inputStream& is, const int size, const int resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("APPEND", - m_connection->parser()->lastLine(), "bad response"); + m_connection->getParser()->lastLine(), "bad response"); } // Notify message added @@ -1172,7 +1172,7 @@ void IMAPFolder::expunge() resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("EXPUNGE", - m_connection->parser()->lastLine(), "bad response"); + m_connection->getParser()->lastLine(), "bad response"); } // Update the numbering of the messages @@ -1187,7 +1187,7 @@ void IMAPFolder::expunge() if ((*it)->response_data() == NULL) { throw exceptions::command_error("EXPUNGE", - m_connection->parser()->lastLine(), "invalid response"); + m_connection->getParser()->lastLine(), "invalid response"); } const IMAPParser::message_data* messageData = @@ -1233,7 +1233,7 @@ void IMAPFolder::rename(const folder::path& newPath) std::ostringstream command; command << "RENAME "; command << IMAPUtils::quoteString(IMAPUtils::pathToString - (m_connection->hierarchySeparator(), fullPath())) << " "; + (m_connection->hierarchySeparator(), getFullPath())) << " "; command << IMAPUtils::quoteString(IMAPUtils::pathToString (m_connection->hierarchySeparator(), newPath)); @@ -1247,14 +1247,14 @@ void IMAPFolder::rename(const folder::path& newPath) resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("RENAME", - m_connection->parser()->lastLine(), "bad response"); + m_connection->getParser()->lastLine(), "bad response"); } // Notify folder renamed folder::path oldPath(m_path); m_path = newPath; - m_name = newPath.last(); + m_name = newPath.getLastComponent(); events::folderEvent event(this, events::folderEvent::TYPE_RENAMED, oldPath, newPath); notifyFolder(event); @@ -1284,7 +1284,7 @@ void IMAPFolder::copyMessage(const folder::path& dest, const int num) for (std::list ::iterator it = m_store->m_folders.begin() ; it != m_store->m_folders.end() ; ++it) { - if ((*it)->fullPath() == dest) + if ((*it)->getFullPath() == dest) { (*it)->m_messageCount++; (*it)->notifyMessageCount(event); @@ -1328,7 +1328,7 @@ void IMAPFolder::copyMessages(const folder::path& dest, const int from, const in for (std::list ::iterator it = m_store->m_folders.begin() ; it != m_store->m_folders.end() ; ++it) { - if ((*it)->fullPath() == dest) + if ((*it)->getFullPath() == dest) { (*it)->m_messageCount += count; (*it)->notifyMessageCount(event); @@ -1355,7 +1355,7 @@ void IMAPFolder::copyMessages(const folder::path& dest, const std::vector & for (std::list ::iterator it = m_store->m_folders.begin() ; it != m_store->m_folders.end() ; ++it) { - if ((*it)->fullPath() == dest) + if ((*it)->getFullPath() == dest) { (*it)->m_messageCount += count; (*it)->notifyMessageCount(event); @@ -1382,7 +1382,7 @@ void IMAPFolder::copyMessages(const string& set, const folder::path& dest) resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("COPY", - m_connection->parser()->lastLine(), "bad response"); + m_connection->getParser()->lastLine(), "bad response"); } } @@ -1396,7 +1396,7 @@ void IMAPFolder::status(int& count, int& unseen) std::ostringstream command; command << "STATUS "; command << IMAPUtils::quoteString(IMAPUtils::pathToString - (m_connection->hierarchySeparator(), fullPath())); + (m_connection->hierarchySeparator(), getFullPath())); command << "(MESSAGES UNSEEN)"; // Send the request @@ -1409,7 +1409,7 @@ void IMAPFolder::status(int& count, int& unseen) resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("STATUS", - m_store->m_connection->parser()->lastLine(), "bad response"); + m_store->m_connection->getParser()->lastLine(), "bad response"); } const std::vector & respDataList = @@ -1421,7 +1421,7 @@ void IMAPFolder::status(int& count, int& unseen) if ((*it)->response_data() == NULL) { throw exceptions::command_error("STATUS", - m_store->m_connection->parser()->lastLine(), "invalid response"); + m_store->m_connection->getParser()->lastLine(), "invalid response"); } const IMAPParser::response_data* responseData = (*it)->response_data(); @@ -1475,7 +1475,7 @@ void IMAPFolder::status(int& count, int& unseen) for (std::list ::iterator it = m_store->m_folders.begin() ; it != m_store->m_folders.end() ; ++it) { - if ((*it)->fullPath() == m_path) + if ((*it)->getFullPath() == m_path) { (*it)->m_messageCount = count; (*it)->notifyMessageCount(event); diff --git a/src/messaging/IMAPFolder.hpp b/src/messaging/IMAPFolder.hpp index bbedb030..fae0a302 100644 --- a/src/messaging/IMAPFolder.hpp +++ b/src/messaging/IMAPFolder.hpp @@ -42,7 +42,7 @@ class IMAPConnection; class IMAPFolder : public folder { -protected: +private: friend class IMAPStore; friend class IMAPMessage; @@ -55,14 +55,14 @@ protected: public: - const int mode() const; + const int getMode() const; - const int type(); + const int getType(); - const int flags(); + const int getFlags(); - const folder::path::component name() const; - const folder::path fullPath() const; + const folder::path::component getName() const; + const folder::path getFullPath() const; void open(const int mode, bool failIfModeIsNotAvailable = false); void close(const bool expunge); @@ -102,8 +102,8 @@ public: folder* getParent(); - const class store& store() const; - class store& store(); + const store* getStore() const; + store* getStore(); void fetchMessages(std::vector & msg, const int options, progressionListener* progress = NULL); diff --git a/src/messaging/IMAPMessage.cpp b/src/messaging/IMAPMessage.cpp index 056c0304..56a3287f 100644 --- a/src/messaging/IMAPMessage.cpp +++ b/src/messaging/IMAPMessage.cpp @@ -66,16 +66,16 @@ private: public: - const class structure& structure() const; - class structure& structure(); + const structure& getStructure() const; + structure& getStructure(); - const IMAPpart* parent() const { return (m_parent); } + const IMAPpart* getParent() const { return (m_parent); } - const mediaType& type() const { return (m_mediaType); } - const int size() const { return (m_size); } - const int number() const { return (m_number); } + const mediaType& getType() const { return (m_mediaType); } + const int getSize() const { return (m_size); } + const int getNumber() const { return (m_number); } - const class header& header() const; + const header& getHeader() const; static IMAPpart* create(IMAPpart* parent, const int number, const IMAPParser::body* body) @@ -150,7 +150,7 @@ public: return (*m_parts[x - 1]); } - const int count() const + const int getCount() const { return (m_parts.size()); } @@ -213,7 +213,7 @@ IMAPpart::IMAPpart(IMAPpart* parent, const int number, const IMAPParser::body_ty } -const class header& IMAPpart::header() const +const class header& IMAPpart::getHeader() const { if (m_header == NULL) throw exceptions::unfetched_object(); @@ -222,7 +222,7 @@ const class header& IMAPpart::header() const } -const class structure& IMAPpart::structure() const +const class structure& IMAPpart::getStructure() const { if (m_structure != NULL) return (*m_structure); @@ -231,7 +231,7 @@ const class structure& IMAPpart::structure() const } -class structure& IMAPpart::structure() +class structure& IMAPpart::getStructure() { if (m_structure != NULL) return (*m_structure); @@ -307,19 +307,19 @@ void IMAPMessage::onFolderClosed() } -const int IMAPMessage::number() const +const int IMAPMessage::getNumber() const { return (m_num); } -const message::uid IMAPMessage::uniqueId() const +const message::uid IMAPMessage::getUniqueId() const { return (m_uid); } -const int IMAPMessage::size() const +const int IMAPMessage::getSize() const { if (m_size == -1) throw exceptions::unfetched_object(); @@ -334,7 +334,7 @@ const bool IMAPMessage::isExpunged() const } -const int IMAPMessage::flags() const +const int IMAPMessage::getFlags() const { if (m_flags == FLAG_UNDEFINED) throw exceptions::unfetched_object(); @@ -343,7 +343,7 @@ const int IMAPMessage::flags() const } -const class structure& IMAPMessage::structure() const +const structure& IMAPMessage::getStructure() const { if (m_structure == NULL) throw exceptions::unfetched_object(); @@ -352,7 +352,7 @@ const class structure& IMAPMessage::structure() const } -class structure& IMAPMessage::structure() +structure& IMAPMessage::getStructure() { if (m_structure == NULL) throw exceptions::unfetched_object(); @@ -361,7 +361,7 @@ class structure& IMAPMessage::structure() } -const class header& IMAPMessage::header() const +const header& IMAPMessage::getHeader() const { if (m_header == NULL) throw exceptions::unfetched_object(); @@ -418,13 +418,13 @@ void IMAPMessage::extract(const part* p, utility::outputStream& os, progressionL const IMAPpart* currentPart = static_cast (p); std::vector numbers; - numbers.push_back(currentPart->number()); - currentPart = currentPart->parent(); + numbers.push_back(currentPart->getNumber()); + currentPart = currentPart->getParent(); while (currentPart != NULL) { - numbers.push_back(currentPart->number()); - currentPart = currentPart->parent(); + numbers.push_back(currentPart->getNumber()); + currentPart = currentPart->getParent(); } numbers.erase(numbers.end() - 1); @@ -458,7 +458,7 @@ void IMAPMessage::extract(const part* p, utility::outputStream& os, progressionL resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("FETCH", - m_folder->m_connection->parser()->lastLine(), "bad response"); + m_folder->m_connection->getParser()->lastLine(), "bad response"); } @@ -532,7 +532,7 @@ void IMAPMessage::fetch(IMAPFolder* folder, const int options) resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("FETCH", - m_folder->m_connection->parser()->lastLine(), "bad response"); + m_folder->m_connection->getParser()->lastLine(), "bad response"); } const std::vector & respDataList = @@ -544,7 +544,7 @@ void IMAPMessage::fetch(IMAPFolder* folder, const int options) if ((*it)->response_data() == NULL) { throw exceptions::command_error("FETCH", - m_folder->m_connection->parser()->lastLine(), "invalid response"); + m_folder->m_connection->getParser()->lastLine(), "invalid response"); } const IMAPParser::message_data* messageData = @@ -598,54 +598,54 @@ void IMAPMessage::processFetchResponse vmime::header& hdr = getOrCreateHeader(); // Date - hdr.fields.Date() = env->env_date()->value(); + hdr.Date().setValue(env->env_date()->value()); // Subject text subject; decodeAndUnfoldText(env->env_subject()->value(), subject); - hdr.fields.Subject() = subject; + hdr.Subject().setValue(subject); // From mailboxList from; convertAddressList(*(env->env_from()), from); - if (!from.empty()) - hdr.fields.From() = *(from.begin()); + if (!from.isEmpty()) + hdr.From().setValue(*(from.getMailboxAt(0))); // To mailboxList to; convertAddressList(*(env->env_to()), to); - hdr.fields.To() = to; + hdr.To().setValue(to); // Sender mailboxList sender; convertAddressList(*(env->env_sender()), sender); - if (!sender.empty()) - hdr.fields.Sender() = *(sender.begin()); + if (!sender.isEmpty()) + hdr.Sender().setValue(*(sender.getMailboxAt(0))); // Reply-to mailboxList replyTo; convertAddressList(*(env->env_reply_to()), replyTo); - if (!replyTo.empty()) - hdr.fields.ReplyTo() = *(replyTo.begin()); + if (!replyTo.isEmpty()) + hdr.ReplyTo().setValue(*(replyTo.getMailboxAt(0))); // Cc mailboxList cc; convertAddressList(*(env->env_cc()), cc); - if (!cc.empty()) - hdr.fields.Cc() = cc; + if (!cc.isEmpty()) + hdr.Cc().setValue(cc); // Bcc mailboxList bcc; convertAddressList(*(env->env_bcc()), bcc); - if (!bcc.empty()) - hdr.fields.Bcc() = bcc; + if (!bcc.isEmpty()) + hdr.Bcc().setValue(bcc); } break; @@ -678,11 +678,12 @@ void IMAPMessage::processFetchResponse tempHeader.parse((*it)->nstring()->value()); vmime::header& hdr = getOrCreateHeader(); + std::vector fields = tempHeader.getFieldList(); - for (header::const_iterator jt = tempHeader.fields.begin() ; - jt != tempHeader.fields.end() ; ++jt) + for (std::vector ::const_iterator jt = fields.begin() ; + jt != fields.end() ; ++jt) { - hdr.fields.append(*jt); + hdr.appendField((*jt)->clone()); } } } @@ -728,7 +729,7 @@ void IMAPMessage::convertAddressList string email = addr.addr_mailbox()->value() + "@" + addr.addr_host()->value(); - dest.append(mailbox(name, email)); + dest.appendMailbox(new mailbox(name, email)); } } @@ -786,7 +787,7 @@ void IMAPMessage::setFlags(const int flags, const int mode) resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { throw exceptions::command_error("STORE", - m_folder->m_connection->parser()->lastLine(), "bad response"); + m_folder->m_connection->getParser()->lastLine(), "bad response"); } // Update the local flags for this message @@ -834,7 +835,7 @@ void IMAPMessage::setFlags(const int flags, const int mode) for (std::list ::iterator it = m_folder->m_store->m_folders.begin() ; it != m_folder->m_store->m_folders.end() ; ++it) { - if ((*it)->fullPath() == m_folder->m_path) + if ((*it)->getFullPath() == m_folder->m_path) (*it)->notifyMessageChanged(event); } } diff --git a/src/messaging/IMAPMessage.hpp b/src/messaging/IMAPMessage.hpp index 74c7a36f..0bf874b9 100644 --- a/src/messaging/IMAPMessage.hpp +++ b/src/messaging/IMAPMessage.hpp @@ -39,7 +39,7 @@ class IMAPstructure; class IMAPMessage : public message { -protected: +private: friend class IMAPFolder; @@ -50,20 +50,20 @@ protected: public: - const int number() const; + const int getNumber() const; - const uid uniqueId() const; + const uid getUniqueId() const; - const int size() const; + const int getSize() const; const bool isExpunged() const; - const class structure& structure() const; - class structure& structure(); + const structure& getStructure() const; + structure& getStructure(); - const class header& header() const; + const header& getHeader() const; - const int flags() const; + const int getFlags() const; void setFlags(const int flags, const int mode = FLAG_MODE_SET); void extract(utility::outputStream& os, progressionListener* progress = NULL, const int start = 0, const int length = -1) const; diff --git a/src/messaging/IMAPParser.hpp b/src/messaging/IMAPParser.hpp index 2e4a56ab..ed61b72f 100644 --- a/src/messaging/IMAPParser.hpp +++ b/src/messaging/IMAPParser.hpp @@ -26,6 +26,7 @@ #include "../charset.hpp" #include "../exception.hpp" #include "../utility/smartPtr.hpp" +#include "../utility/stringUtils.hpp" #include "../encoderB64.hpp" #include "../encoderQP.hpp" @@ -1145,7 +1146,7 @@ public: { // Quoted-printable theEncoder = new encoderQP; - theEncoder->properties()["rfc2047"] = true; + theEncoder->getProperties()["rfc2047"] = true; } else if (theEncoding->value()[0] == 'b' || theEncoding->value()[0] == 'B') { @@ -1229,7 +1230,7 @@ public: else { atom* at = parser.get (line, &pos); - const string name = toLower(at->value()); + const string name = stringUtils::toLower(at->value()); delete (at); if (name == "answered") @@ -1401,7 +1402,7 @@ public: parser.check >(line, &pos); atom* at = parser.get (line, &pos); - const string name = toLower(at->value()); + const string name = stringUtils::toLower(at->value()); delete (at); if (name == "marked") @@ -1800,7 +1801,7 @@ public: DEBUG_ENTER_COMPONENT("auth_type"); atom* at = parser.get (line, currentPos); - m_name = toLower(at->value()); + m_name = stringUtils::toLower(at->value()); delete (at); if (m_name == "kerberos_v4") @@ -2109,21 +2110,21 @@ public: parser.check >(line, &pos); - m_datetime.hour() = std::min(std::max(nh->value(), 0u), 23u); - m_datetime.minute() = std::min(std::max(nmi->value(), 0u), 59u); - m_datetime.second() = std::min(std::max(ns->value(), 0u), 59u); + m_datetime.setHour(std::min(std::max(nh->value(), 0u), 23u)); + m_datetime.setMinute(std::min(std::max(nmi->value(), 0u), 59u)); + m_datetime.setSecond(std::min(std::max(ns->value(), 0u), 59u)); const int zone = static_cast (nz->value()); const int zh = zone / 100; // hour offset const int zm = zone % 100; // minute offset - m_datetime.zone() = ((zh * 60) + zm) * sign; + m_datetime.setZone(((zh * 60) + zm) * sign); - m_datetime.day() = std::min(std::max(nd->value(), 1u), 31u); - m_datetime.year() = ny->value(); + m_datetime.setDay(std::min(std::max(nd->value(), 1u), 31u)); + m_datetime.setYear(ny->value()); - const string month(vmime::toLower(amo->value())); - vmime::datetime::comp_t mon = vmime::datetime::JANUARY; + const string month(stringUtils::toLower(amo->value())); + int mon = vmime::datetime::JANUARY; if (month.length() >= 3) { @@ -2177,7 +2178,7 @@ public: } } - m_datetime.month() = mon; + m_datetime.setMonth(mon); *currentPos = pos; } diff --git a/src/messaging/IMAPStore.cpp b/src/messaging/IMAPStore.cpp index 7d2bc823..bf15b705 100644 --- a/src/messaging/IMAPStore.cpp +++ b/src/messaging/IMAPStore.cpp @@ -72,8 +72,8 @@ private: // IMAPStore // -IMAPStore::IMAPStore(class session& sess, class authenticator* auth) - : store(sess, infosInstance(), auth), +IMAPStore::IMAPStore(session* sess, authenticator* auth) + : store(sess, getInfosInstance(), auth), m_connection(NULL), m_oneTimeAuth(NULL) { } @@ -92,7 +92,7 @@ authenticator* IMAPStore::oneTimeAuthenticator() } -const string IMAPStore::protocolName() const +const string IMAPStore::getProtocolName() const { return "imap"; } @@ -130,7 +130,7 @@ void IMAPStore::connect() if (isConnected()) throw exceptions::already_connected(); - m_oneTimeAuth = new IMAPauthenticator(&authenticator()); + m_oneTimeAuth = new IMAPauthenticator(getAuthenticator()); m_connection = new IMAPConnection(this, m_oneTimeAuth); @@ -189,7 +189,7 @@ void IMAPStore::noop() if (resp->isBad() || resp->response_done()->response_tagged()-> resp_cond_state()->status() != IMAPParser::resp_cond_state::OK) { - throw exceptions::command_error("NOOP", m_connection->parser()->lastLine()); + throw exceptions::command_error("NOOP", m_connection->getParser()->lastLine()); } } @@ -220,19 +220,31 @@ void IMAPStore::unregisterFolder(IMAPFolder* folder) IMAPStore::_infos IMAPStore::sm_infos; -const port_t IMAPStore::_infos::defaultPort() const +const serviceInfos& IMAPStore::getInfosInstance() +{ + return (sm_infos); +} + + +const serviceInfos& IMAPStore::getInfos() const +{ + return (sm_infos); +} + + +const port_t IMAPStore::_infos::getDefaultPort() const { return (143); } -const string IMAPStore::_infos::propertyPrefix() const +const string IMAPStore::_infos::getPropertyPrefix() const { return "store.imap."; } -const std::vector IMAPStore::_infos::availableProperties() const +const std::vector IMAPStore::_infos::getAvailableProperties() const { std::vector list; diff --git a/src/messaging/IMAPStore.hpp b/src/messaging/IMAPStore.hpp index cab9419f..67145896 100644 --- a/src/messaging/IMAPStore.hpp +++ b/src/messaging/IMAPStore.hpp @@ -48,17 +48,17 @@ class IMAPStore : public store public: - IMAPStore(class session& sess, class authenticator* auth); + IMAPStore(session* sess, authenticator* auth); ~IMAPStore(); - const string protocolName() const; + const string getProtocolName() const; folder* getDefaultFolder(); folder* getRootFolder(); folder* getFolder(const folder::path& path); - static const serviceInfos& infosInstance() { return (sm_infos); } - const serviceInfos& infos() const { return (sm_infos); } + static const serviceInfos& getInfosInstance(); + const serviceInfos& getInfos() const; void connect(); const bool isConnected() const; @@ -95,10 +95,10 @@ private: { public: - const port_t defaultPort() const; + const port_t getDefaultPort() const; - const string propertyPrefix() const; - const std::vector availableProperties() const; + const string getPropertyPrefix() const; + const std::vector getAvailableProperties() const; }; static _infos sm_infos; diff --git a/src/messaging/IMAPUtils.cpp b/src/messaging/IMAPUtils.cpp index 2413c86d..a0fdfb8a 100644 --- a/src/messaging/IMAPUtils.cpp +++ b/src/messaging/IMAPUtils.cpp @@ -110,7 +110,7 @@ const string IMAPUtils::pathToString { string result; - for (int i = 0 ; i < path.size() ; ++i) + for (int i = 0 ; i < path.getSize() ; ++i) { if (i > 0) result += hierarchySeparator; result += toModifiedUTF7(hierarchySeparator, path[i]); @@ -497,8 +497,8 @@ const string IMAPUtils::dateTime(const vmime::datetime& date) res << '"'; // Date - if (date.day() < 10) res << ' '; - res << date.day(); + if (date.getDay() < 10) res << ' '; + res << date.getDay(); res << '-'; @@ -506,33 +506,33 @@ const string IMAPUtils::dateTime(const vmime::datetime& date) { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; - res << monthNames[std::min(std::max(date.month() - 1, 0), 11)]; + res << monthNames[std::min(std::max(date.getMonth() - 1, 0), 11)]; res << '-'; - if (date.year() < 10) res << '0'; - if (date.year() < 100) res << '0'; - if (date.year() < 1000) res << '0'; - res << date.year(); + if (date.getYear() < 10) res << '0'; + if (date.getYear() < 100) res << '0'; + if (date.getYear() < 1000) res << '0'; + res << date.getYear(); res << ' '; // Time - if (date.hour() < 10) res << '0'; - res << date.hour() << ':'; + if (date.getHour() < 10) res << '0'; + res << date.getHour() << ':'; - if (date.minute() < 10) res << '0'; - res << date.minute() << ':'; + if (date.getMinute() < 10) res << '0'; + res << date.getMinute() << ':'; - if (date.second() < 10) res << '0'; - res << date.second(); + if (date.getSecond() < 10) res << '0'; + res << date.getSecond(); res << ' '; // Zone - const int zs = (date.zone() < 0 ? -1 : 1); - const int zh = (date.zone() * zs) / 60; - const int zm = (date.zone() * zs) % 60; + const int zs = (date.getZone() < 0 ? -1 : 1); + const int zh = (date.getZone() * zs) / 60; + const int zm = (date.getZone() * zs) % 60; res << (zs < 0 ? '-' : '+'); diff --git a/src/messaging/POP3Folder.cpp b/src/messaging/POP3Folder.cpp index 663d03b5..e820ab3f 100644 --- a/src/messaging/POP3Folder.cpp +++ b/src/messaging/POP3Folder.cpp @@ -30,7 +30,7 @@ namespace messaging { POP3Folder::POP3Folder(const folder::path& path, POP3Store* store) - : m_store(store), m_path(path), m_name(path.last()), m_mode(-1), m_open(false) + : m_store(store), m_path(path), m_name(path.getLastComponent()), m_mode(-1), m_open(false) { m_store->registerFolder(this); } @@ -52,7 +52,7 @@ POP3Folder::~POP3Folder() } -const int POP3Folder::mode() const +const int POP3Folder::getMode() const { if (!isOpen()) throw exceptions::illegal_state("Folder not open"); @@ -61,33 +61,33 @@ const int POP3Folder::mode() const } -const int POP3Folder::type() +const int POP3Folder::getType() { if (!isOpen()) throw exceptions::illegal_state("Folder not open"); - if (m_path.empty()) + if (m_path.isEmpty()) return (TYPE_CONTAINS_FOLDERS); - else if (m_path.size() == 1 && m_path[0].buffer() == "INBOX") + else if (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX") return (TYPE_CONTAINS_MESSAGES); else throw exceptions::folder_not_found(); } -const int POP3Folder::flags() +const int POP3Folder::getFlags() { return (0); } -const folder::path::component POP3Folder::name() const +const folder::path::component POP3Folder::getName() const { return (m_name); } -const folder::path POP3Folder::fullPath() const +const folder::path POP3Folder::getFullPath() const { return (m_path); } @@ -98,7 +98,7 @@ void POP3Folder::open(const int mode, bool failIfModeIsNotAvailable) if (!m_store) throw exceptions::illegal_state("Store disconnected"); - if (m_path.empty()) + if (m_path.isEmpty()) { if (mode != MODE_READ_ONLY && failIfModeIsNotAvailable) throw exceptions::operation_not_supported(); @@ -108,7 +108,7 @@ void POP3Folder::open(const int mode, bool failIfModeIsNotAvailable) m_messageCount = 0; } - else if (m_path.size() == 1 && m_path[0].buffer() == "INBOX") + else if (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX") { m_store->sendRequest("STAT"); @@ -178,7 +178,7 @@ const bool POP3Folder::exists() if (!m_store) throw exceptions::illegal_state("Store disconnected"); - return (m_path.empty() || (m_path.size() == 1 && m_path[0].buffer() == "INBOX")); + return (m_path.isEmpty() || (m_path.getSize() == 1 && m_path[0].getBuffer() == "INBOX")); } @@ -275,7 +275,7 @@ std::vector POP3Folder::getFolders(const bool /* recursive */) if (!m_store) throw exceptions::illegal_state("Store disconnected"); - if (m_path.empty()) + if (m_path.isEmpty()) { std::vector v; v.push_back(new POP3Folder(folder::path::component("INBOX"), m_store)); @@ -438,25 +438,25 @@ const int POP3Folder::getFetchCapabilities() const folder* POP3Folder::getParent() { - return (m_path.empty() ? NULL : new POP3Folder(m_path.parent(), m_store)); + return (m_path.isEmpty() ? NULL : new POP3Folder(m_path.getParent(), m_store)); } -const class store& POP3Folder::store() const +const store* POP3Folder::getStore() const { - return (*m_store); + return (m_store); } -class store& POP3Folder::store() +store* POP3Folder::getStore() { - return (*m_store); + return (m_store); } void POP3Folder::registerMessage(POP3Message* msg) { - m_messages.insert(MessageMap::value_type(msg, msg->number())); + m_messages.insert(MessageMap::value_type(msg, msg->getNumber())); } @@ -639,7 +639,7 @@ void POP3Folder::status(int& count, int& unseen) for (std::list ::iterator it = m_store->m_folders.begin() ; it != m_store->m_folders.end() ; ++it) { - if ((*it)->fullPath() == m_path) + if ((*it)->getFullPath() == m_path) { (*it)->m_messageCount = count; (*it)->notifyMessageCount(event); diff --git a/src/messaging/POP3Folder.hpp b/src/messaging/POP3Folder.hpp index cfb83bef..7afaaa1d 100644 --- a/src/messaging/POP3Folder.hpp +++ b/src/messaging/POP3Folder.hpp @@ -42,7 +42,7 @@ class POP3Message; class POP3Folder : public folder { -protected: +private: friend class POP3Store; friend class POP3Message; @@ -54,14 +54,14 @@ protected: public: - const int mode() const; + const int getMode() const; - const int type(); + const int getType(); - const int flags(); + const int getFlags(); - const folder::path::component name() const; - const folder::path fullPath() const; + const folder::path::component getName() const; + const folder::path getFullPath() const; void open(const int mode, bool failIfModeIsNotAvailable = false); void close(const bool expunge); @@ -101,8 +101,8 @@ public: folder* getParent(); - const class store& store() const; - class store& store(); + const store* getStore() const; + store* getStore(); void fetchMessages(std::vector & msg, const int options, progressionListener* progress = NULL); diff --git a/src/messaging/POP3Message.cpp b/src/messaging/POP3Message.cpp index 66b3f466..d072fdc8 100644 --- a/src/messaging/POP3Message.cpp +++ b/src/messaging/POP3Message.cpp @@ -63,19 +63,19 @@ void POP3Message::onFolderClosed() } -const int POP3Message::number() const +const int POP3Message::getNumber() const { return (m_num); } -const message::uid POP3Message::uniqueId() const +const message::uid POP3Message::getUniqueId() const { return (m_uid); } -const int POP3Message::size() const +const int POP3Message::getSize() const { if (!m_folder) throw exceptions::illegal_state("Folder closed"); @@ -93,25 +93,25 @@ const bool POP3Message::isExpunged() const } -const int POP3Message::flags() const +const int POP3Message::getFlags() const { return (FLAG_RECENT); } -const class structure& POP3Message::structure() const +const structure& POP3Message::getStructure() const { throw exceptions::operation_not_supported(); } -class structure& POP3Message::structure() +structure& POP3Message::getStructure() { throw exceptions::operation_not_supported(); } -const class header& POP3Message::header() const +const header& POP3Message::getHeader() const { if (m_header == NULL) throw exceptions::unfetched_object(); diff --git a/src/messaging/POP3Message.hpp b/src/messaging/POP3Message.hpp index 193624b8..96c1f78e 100644 --- a/src/messaging/POP3Message.hpp +++ b/src/messaging/POP3Message.hpp @@ -35,7 +35,7 @@ namespace messaging { class POP3Message : public message { -protected: +private: friend class POP3Folder; @@ -46,20 +46,20 @@ protected: public: - const int number() const; + const int getNumber() const; - const uid uniqueId() const; + const uid getUniqueId() const; - const int size() const; + const int getSize() const; const bool isExpunged() const; - const class structure& structure() const; - class structure& structure(); + const structure& getStructure() const; + structure& getStructure(); - const class header& header() const; + const header& getHeader() const; - const int flags() const; + const int getFlags() const; void setFlags(const int flags, const int mode = FLAG_MODE_SET); void extract(utility::outputStream& os, progressionListener* progress = NULL, const int start = 0, const int length = -1) const; @@ -77,7 +77,7 @@ private: int m_num; uid m_uid; - class header* m_header; + header* m_header; }; diff --git a/src/messaging/POP3Store.cpp b/src/messaging/POP3Store.cpp index c105bc4b..6d762997 100644 --- a/src/messaging/POP3Store.cpp +++ b/src/messaging/POP3Store.cpp @@ -33,8 +33,8 @@ namespace vmime { namespace messaging { -POP3Store::POP3Store(class session& sess, class authenticator* auth) - : store(sess, infosInstance(), auth), m_socket(NULL), +POP3Store::POP3Store(session* sess, authenticator* auth) + : store(sess, getInfosInstance(), auth), m_socket(NULL), m_authentified(false), m_timeoutHandler(NULL) { } @@ -49,7 +49,7 @@ POP3Store::~POP3Store() } -const string POP3Store::protocolName() const +const string POP3Store::getProtocolName() const { return "pop3"; } @@ -87,23 +87,23 @@ void POP3Store::connect() if (isConnected()) throw exceptions::already_connected(); - const string address = session().properties()[sm_infos.propertyPrefix() + "server.address"]; - const port_t port = session().properties().get(sm_infos.propertyPrefix() + "server.port", sm_infos.defaultPort()); + const string address = getSession()->getProperties()[sm_infos.getPropertyPrefix() + "server.address"]; + const port_t port = getSession()->getProperties().getProperty(sm_infos.getPropertyPrefix() + "server.port", sm_infos.getDefaultPort()); // Create the time-out handler - if (session().properties().exists - (sm_infos.propertyPrefix() + "timeout.factory")) + if (getSession()->getProperties().hasProperty + (sm_infos.getPropertyPrefix() + "timeout.factory")) { timeoutHandlerFactory* tof = platformDependant::getHandler()-> - getTimeoutHandlerFactory(session().properties() - [sm_infos.propertyPrefix() + "timeout.factory"]); + getTimeoutHandlerFactory(getSession()->getProperties() + [sm_infos.getPropertyPrefix() + "timeout.factory"]); m_timeoutHandler = tof->create(); } // Create and connect the socket socketFactory* sf = platformDependant::getHandler()->getSocketFactory - (session().properties().get(sm_infos.propertyPrefix() + "server.socket-factory", string("default"))); + (getSession()->getProperties().getProperty(sm_infos.getPropertyPrefix() + "server.socket-factory", string("default"))); m_socket = sf->create(); m_socket->connect(address, port); @@ -120,7 +120,7 @@ void POP3Store::connect() { bool authentified = false; - const authenticationInfos auth = authenticator().requestAuthInfos(); + const authenticationInfos auth = getAuthenticator()->requestAuthInfos(); // Secured authentication with APOP (if requested and if available) // @@ -128,13 +128,13 @@ void POP3Store::connect() // --- S: +OK vincent is a valid mailbox messageId mid(response); - if (session().properties().get(sm_infos.propertyPrefix() + "options.apop", false)) + if (getSession()->getProperties().getProperty(sm_infos.getPropertyPrefix() + "options.apop", false)) { - if (mid.left().length() && mid.right().length()) + if (mid.getLeft().length() && mid.getRight().length()) { // is the result of MD5 applied to "password" - sendRequest("APOP " + auth.username() + " " - + utility::md5(mid.generate() + auth.password()).hex()); + sendRequest("APOP " + auth.getUsername() + " " + + utility::md5(mid.generate() + auth.getPassword()).hex()); readResponse(response, false); if (isSuccessResponse(response)) @@ -143,7 +143,7 @@ void POP3Store::connect() } else { - if (session().properties().get(sm_infos.propertyPrefix() + + if (getSession()->getProperties().getProperty(sm_infos.getPropertyPrefix() + "options.apop.fallback", false) == false) { internalDisconnect(); @@ -154,7 +154,7 @@ void POP3Store::connect() else { // APOP not supported - if (session().properties().get(sm_infos.propertyPrefix() + + if (getSession()->getProperties().getProperty(sm_infos.getPropertyPrefix() + "options.apop.fallback", false) == false) { // Can't fallback on basic authentification @@ -174,12 +174,12 @@ void POP3Store::connect() // C: PASS couic // S: +OK vincent's maildrop has 2 messages (320 octets) - sendRequest("USER " + auth.username()); + sendRequest("USER " + auth.getUsername()); readResponse(response, false); if (isSuccessResponse(response)) { - sendRequest("PASS " + auth.password()); + sendRequest("PASS " + auth.getPassword()); readResponse(response, false); if (!isSuccessResponse(response)) @@ -565,19 +565,31 @@ void POP3Store::unregisterFolder(POP3Folder* folder) POP3Store::_infos POP3Store::sm_infos; -const port_t POP3Store::_infos::defaultPort() const +const serviceInfos& POP3Store::getInfosInstance() +{ + return (sm_infos); +} + + +const serviceInfos& POP3Store::getInfos() const +{ + return (sm_infos); +} + + +const port_t POP3Store::_infos::getDefaultPort() const { return (110); } -const string POP3Store::_infos::propertyPrefix() const +const string POP3Store::_infos::getPropertyPrefix() const { return "store.pop3."; } -const std::vector POP3Store::_infos::availableProperties() const +const std::vector POP3Store::_infos::getAvailableProperties() const { std::vector list; diff --git a/src/messaging/POP3Store.hpp b/src/messaging/POP3Store.hpp index b9d6bd87..ae0f9fd4 100644 --- a/src/messaging/POP3Store.hpp +++ b/src/messaging/POP3Store.hpp @@ -42,17 +42,17 @@ class POP3Store : public store public: - POP3Store(class session& sess, class authenticator* auth); + POP3Store(session* sess, authenticator* auth); ~POP3Store(); - const string protocolName() const; + const string getProtocolName() const; folder* getDefaultFolder(); folder* getRootFolder(); folder* getFolder(const folder::path& path); - static const serviceInfos& infosInstance() { return (sm_infos); } - const serviceInfos& infos() const { return (sm_infos); } + static const serviceInfos& getInfosInstance(); + const serviceInfos& getInfos() const; void connect(); const bool isConnected() const; @@ -93,10 +93,10 @@ private: { public: - const port_t defaultPort() const; + const port_t getDefaultPort() const; - const string propertyPrefix() const; - const std::vector availableProperties() const; + const string getPropertyPrefix() const; + const std::vector getAvailableProperties() const; }; static _infos sm_infos; diff --git a/src/messaging/SMTPTransport.cpp b/src/messaging/SMTPTransport.cpp index 309f3e06..d0401a51 100644 --- a/src/messaging/SMTPTransport.cpp +++ b/src/messaging/SMTPTransport.cpp @@ -31,8 +31,8 @@ namespace vmime { namespace messaging { -SMTPTransport::SMTPTransport(class session& sess, class authenticator* auth) - : transport(sess, infosInstance(), auth), m_socket(NULL), +SMTPTransport::SMTPTransport(session* sess, authenticator* auth) + : transport(sess, getInfosInstance(), auth), m_socket(NULL), m_authentified(false), m_extendedSMTP(false), m_timeoutHandler(NULL) { } @@ -47,7 +47,7 @@ SMTPTransport::~SMTPTransport() } -const string SMTPTransport::protocolName() const +const string SMTPTransport::getProtocolName() const { return "smtp"; } @@ -58,23 +58,23 @@ void SMTPTransport::connect() if (isConnected()) throw exceptions::already_connected(); - const string address = session().properties()[sm_infos.propertyPrefix() + "server.address"]; - const port_t port = session().properties().get(sm_infos.propertyPrefix() + "server.port", sm_infos.defaultPort()); + const string address = getSession()->getProperties()[sm_infos.getPropertyPrefix() + "server.address"]; + const port_t port = getSession()->getProperties().getProperty(sm_infos.getPropertyPrefix() + "server.port", sm_infos.getDefaultPort()); // Create the time-out handler - if (session().properties().exists - (sm_infos.propertyPrefix() + "timeout.factory")) + if (getSession()->getProperties().hasProperty + (sm_infos.getPropertyPrefix() + "timeout.factory")) { timeoutHandlerFactory* tof = platformDependant::getHandler()-> - getTimeoutHandlerFactory(session().properties() - [sm_infos.propertyPrefix() + "timeout.factory"]); + getTimeoutHandlerFactory(getSession()->getProperties() + [sm_infos.getPropertyPrefix() + "timeout.factory"]); m_timeoutHandler = tof->create(); } // Create and connect the socket socketFactory* sf = platformDependant::getHandler()->getSocketFactory - (session().properties().get(sm_infos.propertyPrefix() + "server.socket-factory", string("default"))); + (getSession()->getProperties().getProperty(sm_infos.getPropertyPrefix() + "server.socket-factory", string("default"))); m_socket = sf->create(); m_socket->connect(address, port); @@ -126,8 +126,8 @@ void SMTPTransport::connect() } // Authentication - if (session().properties().get - (sm_infos.propertyPrefix() + "options.need-authentication", false) == true) + if (getSession()->getProperties().getProperty + (sm_infos.getPropertyPrefix() + "options.need-authentication", false) == true) { if (!m_extendedSMTP) { @@ -135,7 +135,7 @@ void SMTPTransport::connect() throw exceptions::command_error("AUTH", "ESMTP not supported."); } - const authenticationInfos auth = authenticator().requestAuthInfos(); + const authenticationInfos auth = getAuthenticator()->requestAuthInfos(); bool authentified = false; enum AuthMethods @@ -169,9 +169,9 @@ void SMTPTransport::connect() base64.decode(in, out); } - hmac_md5(challenge, auth.password(), challengeHex); + hmac_md5(challenge, auth.getPassword(), challengeHex); - string decoded = auth.username() + " " + challengeHex; + string decoded = auth.getUsername() + " " + challengeHex; string encoded; { @@ -259,10 +259,12 @@ void SMTPTransport::noop() static void extractMailboxes (mailboxList& recipients, const addressList& list) { - for (addressList::const_iterator it = list.begin() ; - it != list.end() ; ++it) + for (int i = 0 ; i < list.getAddressCount() ; ++i) { - recipients.append((*it)); + mailbox* mbox = dynamic_cast (list.getAddressAt(i)->clone()); + + if (mbox != NULL) + recipients.appendMailbox(mbox); } } @@ -275,8 +277,8 @@ void SMTPTransport::send(vmime::message* msg, progressionListener* progress) try { const mailboxField& from = dynamic_cast - (msg->header().fields.find(headerField::From)); - expeditor = from.value(); + (*msg->getHeader()->findField(fields::FROM)); + expeditor = from.getValue(); } catch (exceptions::no_such_field&) { @@ -289,24 +291,24 @@ void SMTPTransport::send(vmime::message* msg, progressionListener* progress) try { const addressListField& to = dynamic_cast - (msg->header().fields.find(headerField::To)); - extractMailboxes(recipients, to.value()); + (*msg->getHeader()->findField(fields::TO)); + extractMailboxes(recipients, to.getValue()); } catch (exceptions::no_such_field&) { } try { const addressListField& cc = dynamic_cast - (msg->header().fields.find(headerField::Cc)); - extractMailboxes(recipients, cc.value()); + (*msg->getHeader()->findField(fields::CC)); + extractMailboxes(recipients, cc.getValue()); } catch (exceptions::no_such_field&) { } try { const addressListField& bcc = dynamic_cast - (msg->header().fields.find(headerField::Bcc)); - extractMailboxes(recipients, bcc.value()); + (*msg->getHeader()->findField(fields::BCC)); + extractMailboxes(recipients, bcc.getValue()); } catch (exceptions::no_such_field&) { } @@ -330,15 +332,15 @@ void SMTPTransport::send(const mailbox& expeditor, const mailboxList& recipients progressionListener* progress) { // If no recipient/expeditor was found, throw an exception - if (recipients.empty()) + if (recipients.isEmpty()) throw exceptions::no_recipient(); - else if (expeditor.empty()) + else if (expeditor.isEmpty()) throw exceptions::no_expeditor(); // Emit the "MAIL" command string response; - sendRequest("MAIL FROM: <" + expeditor.email() + ">"); + sendRequest("MAIL FROM: <" + expeditor.getEmail() + ">"); readResponse(response); if (responseCode(response) != 250) @@ -348,10 +350,11 @@ void SMTPTransport::send(const mailbox& expeditor, const mailboxList& recipients } // Emit a "RCPT TO" command for each recipient - for (mailboxList::const_iterator it = recipients.begin() ; - it != recipients.end() ; ++it) + for (int i = 0 ; i < recipients.getMailboxCount() ; ++i) { - sendRequest("RCPT TO: <" + (*it).email() + ">"); + const mailbox& mbox = *recipients.getMailboxAt(i); + + sendRequest("RCPT TO: <" + mbox.getEmail() + ">"); readResponse(response); if (responseCode(response) != 250) @@ -538,19 +541,31 @@ void SMTPTransport::readResponse(string& buffer) SMTPTransport::_infos SMTPTransport::sm_infos; -const port_t SMTPTransport::_infos::defaultPort() const +const serviceInfos& SMTPTransport::getInfosInstance() +{ + return (sm_infos); +} + + +const serviceInfos& SMTPTransport::getInfos() const +{ + return (sm_infos); +} + + +const port_t SMTPTransport::_infos::getDefaultPort() const { return (25); } -const string SMTPTransport::_infos::propertyPrefix() const +const string SMTPTransport::_infos::getPropertyPrefix() const { return "transport.smtp."; } -const std::vector SMTPTransport::_infos::availableProperties() const +const std::vector SMTPTransport::_infos::getAvailableProperties() const { std::vector list; diff --git a/src/messaging/SMTPTransport.hpp b/src/messaging/SMTPTransport.hpp index fa5abfcf..b63da5c3 100644 --- a/src/messaging/SMTPTransport.hpp +++ b/src/messaging/SMTPTransport.hpp @@ -38,13 +38,13 @@ class SMTPTransport : public transport { public: - SMTPTransport(class session& sess, class authenticator* auth); + SMTPTransport(session* sess, authenticator* auth); ~SMTPTransport(); - const string protocolName() const; + const string getProtocolName() const; - static const serviceInfos& infosInstance() { return (sm_infos); } - const serviceInfos& infos() const { return (sm_infos); } + static const serviceInfos& getInfosInstance(); + const serviceInfos& getInfos() const; void connect(); const bool isConnected() const; @@ -78,10 +78,10 @@ private: { public: - const port_t defaultPort() const; + const port_t getDefaultPort() const; - const string propertyPrefix() const; - const std::vector availableProperties() const; + const string getPropertyPrefix() const; + const std::vector getAvailableProperties() const; }; static _infos sm_infos; diff --git a/src/messaging/authenticationInfos.cpp b/src/messaging/authenticationInfos.cpp index 3c5acca7..70579ff1 100644 --- a/src/messaging/authenticationInfos.cpp +++ b/src/messaging/authenticationInfos.cpp @@ -36,5 +36,17 @@ authenticationInfos::authenticationInfos(const authenticationInfos& infos) } +const string& authenticationInfos::getUsername() const +{ + return (m_username); +} + + +const string& authenticationInfos::getPassword() const +{ + return (m_password); +} + + } // messaging } // vmime diff --git a/src/messaging/authenticationInfos.hpp b/src/messaging/authenticationInfos.hpp index fd2da2fa..ff049419 100644 --- a/src/messaging/authenticationInfos.hpp +++ b/src/messaging/authenticationInfos.hpp @@ -42,13 +42,13 @@ public: * * @return account name */ - const string& username() const { return (m_username); } + const string& getUsername() const; /** Return the user account password. * * @return account password */ - const string& password() const { return (m_password); } + const string& getPassword() const; private: diff --git a/src/messaging/folder.hpp b/src/messaging/folder.hpp index 574ac1b0..0e92d50c 100644 --- a/src/messaging/folder.hpp +++ b/src/messaging/folder.hpp @@ -37,6 +37,9 @@ namespace vmime { namespace messaging { +class store; + + /** Abstract representation of a folder in a message store. */ @@ -90,31 +93,31 @@ public: * * @return folder type (see folder::Types) */ - virtual const int type() = 0; + virtual const int getType() = 0; /** Return the flags of this folder. * * @return folder flags (see folder::Flags) */ - virtual const int flags() = 0; + virtual const int getFlags() = 0; /** Return the mode in which the folder has been open. * * @return folder opening mode (see folder::Modes) */ - virtual const int mode() const = 0; + virtual const int getMode() const = 0; /** Return the name of this folder. * * @return folder name */ - virtual const folder::path::component name() const = 0; + virtual const folder::path::component getName() const = 0; /** Return the fully qualified path name of this folder. * * @return absolute path of the folder */ - virtual const folder::path fullPath() const = 0; + virtual const folder::path getFullPath() const = 0; /** Open this folder. * @@ -297,13 +300,13 @@ public: * * @return the store object to which this folder is attached */ - virtual const class store& store() const = 0; + virtual const store* getStore() const = 0; /** Return a reference to the store to which this folder belongs. * * @return the store object to which this folder is attached */ - virtual class store& store() = 0; + virtual store* getStore() = 0; /** Possible fetchable objects. */ diff --git a/src/messaging/maildirFolder.cpp b/src/messaging/maildirFolder.cpp index 903de91d..155b48fc 100644 --- a/src/messaging/maildirFolder.cpp +++ b/src/messaging/maildirFolder.cpp @@ -32,7 +32,7 @@ namespace messaging { maildirFolder::maildirFolder(const folder::path& path, maildirStore* store) - : m_store(store), m_path(path), m_name(path.last()), m_mode(-1), m_open(false) + : m_store(store), m_path(path), m_name(path.getLastComponent()), m_mode(-1), m_open(false) { m_store->registerFolder(this); } @@ -60,7 +60,7 @@ void maildirFolder::onStoreDisconnected() } -const int maildirFolder::mode() const +const int maildirFolder::getMode() const { if (!isOpen()) throw exceptions::illegal_state("Folder not open"); @@ -69,16 +69,16 @@ const int maildirFolder::mode() const } -const int maildirFolder::type() +const int maildirFolder::getType() { - if (m_path.empty()) + if (m_path.isEmpty()) return (TYPE_CONTAINS_FOLDERS); else return (TYPE_CONTAINS_FOLDERS | TYPE_CONTAINS_MESSAGES); } -const int maildirFolder::flags() +const int maildirFolder::getFlags() { int flags = 0; @@ -104,13 +104,13 @@ const int maildirFolder::flags() } -const folder::path::component maildirFolder::name() const +const folder::path::component maildirFolder::getName() const { return (m_name); } -const folder::path maildirFolder::fullPath() const +const folder::path maildirFolder::getFullPath() const { return (m_path); } @@ -132,13 +132,40 @@ void maildirFolder::open(const int mode, bool /* failIfModeIsNotAvailable */) void maildirFolder::close(const bool expunge) { - // TODO + if (!m_store) + throw exceptions::illegal_state("Store disconnected"); + + if (!isOpen()) + throw exceptions::illegal_state("Folder not open"); + + m_open = false; + m_mode = -1; + + onClose(); } void maildirFolder::onClose() { - // TODO + for (std::vector ::iterator it = m_messages.begin() ; + it != m_messages.end() ; ++it) + { + (*it)->onFolderClosed(); + } + + m_messages.clear(); +} + + +void maildirFolder::registerMessage(maildirMessage* msg) +{ + m_messages.push_back(msg); +} + + +void maildirFolder::unregisterMessage(maildirMessage* msg) +{ + std::remove(m_messages.begin(), m_messages.end(), msg); } @@ -152,14 +179,14 @@ void maildirFolder::create(const int type) throw exceptions::illegal_state("Folder already exists"); // Folder name cannot start with '.' - if (!m_path.empty()) + if (!m_path.isEmpty()) { - const path::component& comp = m_path.last(); + const path::component& comp = m_path.getLastComponent(); - const int length = comp.buffer().length(); + const int length = comp.getBuffer().length(); int pos = 0; - while ((pos < length) && (comp.buffer()[pos] == '.')) + while ((pos < length) && (comp.getBuffer()[pos] == '.')) ++pos; if (pos != 0) @@ -246,7 +273,7 @@ void maildirFolder::scanFolder() while (nit->hasMoreElements()) { utility::auto_ptr file = nit->nextElement(); - unreadMessageFilenames.push_back(file->fullPath().last()); + unreadMessageFilenames.push_back(file->fullPath().getLastComponent()); } // Seen messages (cur/) @@ -256,7 +283,7 @@ void maildirFolder::scanFolder() while (cit->hasMoreElements()) { utility::auto_ptr file = cit->nextElement(); - messageFilenames.push_back(file->fullPath().last()); + messageFilenames.push_back(file->fullPath().getLastComponent()); } // TODO: update m_messageFilenames @@ -384,7 +411,7 @@ void maildirFolder::listFolders(std::vector & list, const bool recursiv if (maildirUtils::isSubfolderDirectory(*file)) { - const utility::path subPath = m_path / file->fullPath().last(); + const utility::path subPath = m_path / file->fullPath().getLastComponent(); maildirFolder* subFolder = new maildirFolder(subPath, m_store); list.push_back(subFolder); @@ -494,10 +521,12 @@ void maildirFolder::status(int& count, int& unseen) for (std::list ::iterator it = m_store->m_folders.begin() ; it != m_store->m_folders.end() ; ++it) { - if ((*it)->fullPath() == m_path) + if ((*it)->getFullPath() == m_path) { (*it)->m_messageCount = count; (*it)->notifyMessageCount(event); + + (*it)->scanFolder(); } } } @@ -512,19 +541,19 @@ void maildirFolder::expunge() folder* maildirFolder::getParent() { - return (m_path.empty() ? NULL : new maildirFolder(m_path.parent(), m_store)); + return (m_path.isEmpty() ? NULL : new maildirFolder(m_path.getParent(), m_store)); } -const class store& maildirFolder::store() const +const store* maildirFolder::getStore() const { - return (*m_store); + return (m_store); } -class store& maildirFolder::store() +store* maildirFolder::getStore() { - return (*m_store); + return (m_store); } diff --git a/src/messaging/maildirFolder.hpp b/src/messaging/maildirFolder.hpp index 37578157..65835219 100644 --- a/src/messaging/maildirFolder.hpp +++ b/src/messaging/maildirFolder.hpp @@ -40,7 +40,7 @@ class maildirStore; class maildirFolder : public folder { -protected: +private: friend class maildirStore; friend class maildirMessage; @@ -53,14 +53,14 @@ protected: public: - const int mode() const; + const int getMode() const; - const int type(); + const int getType(); - const int flags(); + const int getFlags(); - const folder::path::component name() const; - const folder::path fullPath() const; + const folder::path::component getName() const; + const folder::path getFullPath() const; void open(const int mode, bool failIfModeIsNotAvailable = false); void close(const bool expunge); @@ -100,8 +100,8 @@ public: folder* getParent(); - const class store& store() const; - class store& store(); + const store* getStore() const; + store* getStore(); void fetchMessages(std::vector & msg, const int options, progressionListener* progress = NULL); @@ -111,6 +111,18 @@ public: private: + void scanFolder(); + + void listFolders(std::vector & list, const bool recursive); + + void registerMessage(maildirMessage* msg); + void unregisterMessage(maildirMessage* msg); + + void onStoreDisconnected(); + + void onClose(); + + maildirStore* m_store; folder::path m_path; @@ -125,15 +137,7 @@ private: std::vector m_unreadMessageFilenames; std::vector m_messageFilenames; - void scanFolder(); - - void listFolders(std::vector & list, const bool recursive); - - - - void onStoreDisconnected(); - - void onClose(); + std::vector m_messages; }; diff --git a/src/messaging/maildirMessage.cpp b/src/messaging/maildirMessage.cpp index c14831c3..65d41447 100644 --- a/src/messaging/maildirMessage.cpp +++ b/src/messaging/maildirMessage.cpp @@ -18,11 +18,92 @@ // #include "maildirMessage.hpp" +#include "maildirFolder.hpp" namespace vmime { namespace messaging { +maildirMessage::maildirMessage(maildirFolder* folder, const int num) + : m_folder(folder), m_num(num) +{ + m_folder->registerMessage(this); +} + + +maildirMessage::~maildirMessage() +{ + if (m_folder) + m_folder->unregisterMessage(this); +} + + +void maildirMessage::onFolderClosed() +{ + m_folder = NULL; +} + + +const int maildirMessage::getNumber() const +{ +} + + +const message::uid maildirMessage::getUniqueId() const +{ +} + + +const int maildirMessage::getSize() const +{ +} + + +const bool maildirMessage::isExpunged() const +{ +} + + +const structure& maildirMessage::getStructure() const +{ +} + + +structure& maildirMessage::getStructure() +{ +} + + +const header& maildirMessage::getHeader() const +{ +} + + +const int maildirMessage::getFlags() const +{ +} + + +void maildirMessage::setFlags(const int flags, const int mode) +{ +} + + +void maildirMessage::extract(utility::outputStream& os, progressionListener* progress, const int start, const int length) const +{ +} + + +void maildirMessage::extractPart(const part& p, utility::outputStream& os, progressionListener* progress, const int start, const int length) const +{ +} + + +void maildirMessage::fetchPartHeader(part& p) +{ +} + + } // messaging } // vmime diff --git a/src/messaging/maildirMessage.hpp b/src/messaging/maildirMessage.hpp index 3ea6afbf..83e7758f 100644 --- a/src/messaging/maildirMessage.hpp +++ b/src/messaging/maildirMessage.hpp @@ -39,7 +39,7 @@ class maildirMessage : public message { friend class maildirFolder; -protected: +private: maildirMessage(maildirFolder* folder, const int num); maildirMessage(const maildirMessage&) : message() { } @@ -48,26 +48,35 @@ protected: public: - const int number() const; + const int getNumber() const; - const uid uniqueId() const; + const uid getUniqueId() const; - const int size() const; + const int getSize() const; const bool isExpunged() const; - const class structure& structure() const; - class structure& structure(); + const structure& getStructure() const; + structure& getStructure(); - const class header& header() const; + const header& getHeader() const; - const int flags() const; + const int getFlags() const; void setFlags(const int flags, const int mode = FLAG_MODE_SET); void extract(utility::outputStream& os, progressionListener* progress = NULL, const int start = 0, const int length = -1) const; void extractPart(const part& p, utility::outputStream& os, progressionListener* progress = NULL, const int start = 0, const int length = -1) const; void fetchPartHeader(part& p); + +protected: + + void onFolderClosed(); + + + maildirFolder* m_folder; + + int m_num; }; diff --git a/src/messaging/maildirStore.cpp b/src/messaging/maildirStore.cpp index 520e6bbb..e4df0e68 100644 --- a/src/messaging/maildirStore.cpp +++ b/src/messaging/maildirStore.cpp @@ -29,8 +29,8 @@ namespace vmime { namespace messaging { -maildirStore::maildirStore(class session& sess, class authenticator* auth) - : store(sess, infosInstance(), auth), m_connected(false) +maildirStore::maildirStore(session* sess, authenticator* auth) + : store(sess, getInfosInstance(), auth), m_connected(false) { } @@ -42,7 +42,7 @@ maildirStore::~maildirStore() } -const string maildirStore::protocolName() const +const string maildirStore::getProtocolName() const { return "maildir"; } @@ -81,7 +81,7 @@ void maildirStore::connect() throw exceptions::already_connected(); m_fsPath = platformDependant::getHandler()->getFileSystemFactory()-> - stringToPath(session().properties()[infos().propertyPrefix() + "server.rootpath"]); + stringToPath(getSession()->getProperties()[getInfos().getPropertyPrefix() + "server.rootpath"]); m_connected = true; } @@ -139,19 +139,31 @@ const utility::path& maildirStore::getFileSystemPath() const maildirStore::_infos maildirStore::sm_infos; -const port_t maildirStore::_infos::defaultPort() const +const serviceInfos& maildirStore::getInfosInstance() +{ + return (sm_infos); +} + + +const serviceInfos& maildirStore::getInfos() const +{ + return (sm_infos); +} + + +const port_t maildirStore::_infos::getDefaultPort() const { return (0); } -const string maildirStore::_infos::propertyPrefix() const +const string maildirStore::_infos::getPropertyPrefix() const { return "store.maildir."; } -const std::vector maildirStore::_infos::availableProperties() const +const std::vector maildirStore::_infos::getAvailableProperties() const { std::vector list; diff --git a/src/messaging/maildirStore.hpp b/src/messaging/maildirStore.hpp index 62acb13e..b1a56329 100644 --- a/src/messaging/maildirStore.hpp +++ b/src/messaging/maildirStore.hpp @@ -47,17 +47,17 @@ class maildirStore : public store public: - maildirStore(class session& sess, class authenticator* auth); + maildirStore(session* sess, authenticator* auth); ~maildirStore(); - const string protocolName() const; + const string getProtocolName() const; folder* getDefaultFolder(); folder* getRootFolder(); folder* getFolder(const folder::path& path); - static const serviceInfos& infosInstance() { return (sm_infos); } - const serviceInfos& infos() const { return (sm_infos); } + static const serviceInfos& getInfosInstance(); + const serviceInfos& getInfos() const; void connect(); const bool isConnected() const; @@ -85,10 +85,10 @@ private: { public: - const port_t defaultPort() const; + const port_t getDefaultPort() const; - const string propertyPrefix() const; - const std::vector availableProperties() const; + const string getPropertyPrefix() const; + const std::vector getAvailableProperties() const; }; static _infos sm_infos; diff --git a/src/messaging/maildirUtils.cpp b/src/messaging/maildirUtils.cpp index 28df6902..2d294c0f 100644 --- a/src/messaging/maildirUtils.cpp +++ b/src/messaging/maildirUtils.cpp @@ -25,9 +25,9 @@ namespace vmime { namespace messaging { -const vmime::word maildirUtils::TMP_DIR("tmp"); // ensure reliable delivery (not to be listed) -const vmime::word maildirUtils::CUR_DIR("cur"); // no longer new messages -const vmime::word maildirUtils::NEW_DIR("new"); // unread messages +const vmime::word maildirUtils::TMP_DIR("tmp", vmime::charset(vmime::charsets::US_ASCII)); // ensure reliable delivery (not to be listed) +const vmime::word maildirUtils::CUR_DIR("cur", vmime::charset(vmime::charsets::US_ASCII)); // no longer new messages +const vmime::word maildirUtils::NEW_DIR("new", vmime::charset(vmime::charsets::US_ASCII)); // unread messages const utility::file::path maildirUtils::getFolderFSPath @@ -35,7 +35,9 @@ const utility::file::path maildirUtils::getFolderFSPath { // Root path utility::file::path path(store->getFileSystemPath()); - const int count = (mode == FOLDER_PATH_CONTAINER ? folderPath.size() : folderPath.size() - 1); + + const int count = (mode == FOLDER_PATH_CONTAINER + ? folderPath.getSize() : folderPath.getSize() - 1); // Parent folders for (int i = 0 ; i < count ; ++i) @@ -43,16 +45,16 @@ const utility::file::path maildirUtils::getFolderFSPath utility::file::path::component comp(folderPath[i]); // TODO: may not work with all encodings... - comp.buffer() = "." + comp.buffer() + ".directory"; + comp.setBuffer("." + comp.getBuffer() + ".directory"); path /= comp; } // Last component - if (folderPath.size() != 0 && + if (folderPath.getSize() != 0 && mode != FOLDER_PATH_CONTAINER) { - path /= folderPath.last(); + path /= folderPath.getLastComponent(); switch (mode) { @@ -73,8 +75,8 @@ const bool maildirUtils::isSubfolderDirectory(const utility::file& file) // A directory which name does not start with '.' // is listed as a sub-folder... if (file.isDirectory() && - file.fullPath().last().buffer().size() >= 1 && - file.fullPath().last().buffer()[0] != '.') + file.fullPath().getLastComponent().getBuffer().length() >= 1 && + file.fullPath().getLastComponent().getBuffer()[0] != '.') { return (true); } @@ -83,5 +85,36 @@ const bool maildirUtils::isSubfolderDirectory(const utility::file& file) } +/* +const int maildirUtils::extractFlags(const utility::file::path::component& comp) +{ + string::size_type sep = comp.buffer().rfind(':'); + if (sep == string::npos) return (0); + + const string flagsString(comp.buffer().begin() + sep + 1, comp.buffer().end()); + const string::size_type count = flagsString.length(); + + int flags = 0; + + for (string::size_type i = 0 ; i < count ; ++i) + { + switch (flagsString[i]) + { + case 'S': case 's': flags |= message::FLAG_SEEN; break; + case 'R': case 'r': flags |= message::FLAG_REPLIED; break; + } + } + + return (flags); +} + + +const utility::file::component maildirUtils::changeFlags + (const utility::file::component& comp, const int flags) +{ +} +*/ + + } // messaging } // vmime diff --git a/src/messaging/message.cpp b/src/messaging/message.cpp index 0bb1aaca..871799c3 100644 --- a/src/messaging/message.cpp +++ b/src/messaging/message.cpp @@ -26,19 +26,19 @@ namespace messaging { const part& part::operator[](const int x) const { - return (structure()[x]); + return (getStructure()[x]); } part& part::operator[](const int x) { - return (structure()[x]); + return (getStructure()[x]); } -const int part::count() const +const int part::getCount() const { - return (structure().count()); + return (getStructure().getCount()); } diff --git a/src/messaging/message.hpp b/src/messaging/message.hpp index 120aca27..825e1021 100644 --- a/src/messaging/message.hpp +++ b/src/messaging/message.hpp @@ -30,6 +30,9 @@ namespace vmime { namespace messaging { +class structure; + + /** A MIME part in a message. */ @@ -48,38 +51,38 @@ public: * * @return structure of the part */ - virtual const class structure& structure() const = 0; + virtual const structure& getStructure() const = 0; /** Return the structure of this part. * * @return structure of the part */ - virtual class structure& structure() = 0; + virtual structure& getStructure() = 0; /** Return the header section for this part (you must fetch header * before using this function: see message::fetchPartHeader). * * @return header section */ - virtual const class header& header() const = 0; + virtual const header& getHeader() const = 0; /** Return the media-type of the content in this part. * * @return content media type */ - virtual const mediaType& type() const = 0; + virtual const mediaType& getType() const = 0; /** Return the size of this part. * * @return size of the part (in bytes) */ - virtual const int size() const = 0; + virtual const int getSize() const = 0; /** Return the part sequence number (index) * * @return part number */ - virtual const int number() const = 0; // begin at 1 + virtual const int getNumber() const = 0; // begin at 1 /** Return the sub-part at the specified position. * This provide easy access to parts: @@ -103,7 +106,7 @@ public: * * @return number of sub-parts */ - const int count() const; + const int getCount() const; }; @@ -139,7 +142,7 @@ public: * * @return number of parts */ - virtual const int count() const = 0; + virtual const int getCount() const = 0; }; @@ -165,38 +168,38 @@ public: * * @return MIME structure of the message */ - virtual const class structure& structure() const = 0; + virtual const structure& getStructure() const = 0; /** Return the MIME structure of the message (must fetch before). * * @return MIME structure of the message */ - virtual class structure& structure() = 0; + virtual structure& getStructure() = 0; /** Return a reference to the header fields of the message (must fetch before). * * @return header section of the message */ - virtual const class header& header() const = 0; + virtual const header& getHeader() const = 0; /** Return the sequence number of this message. This number is * used to reference the message in the folder. * * @return sequence number of the message */ - virtual const int number() const = 0; + virtual const int getNumber() const = 0; /** Return the unique identified of this message (must fetch before). * * @return UID of the message */ - virtual const uid uniqueId() const = 0; + virtual const uid getUniqueId() const = 0; /** Return the size of the message (must fetch before). * * @return size of the message (in bytes) */ - virtual const int size() const = 0; + virtual const int getSize() const = 0; /** Check whether this message has been expunged * (ie: definitively deleted). @@ -233,7 +236,7 @@ public: * * @return flags of the message */ - virtual const int flags() const = 0; + virtual const int getFlags() const = 0; /** Set the flags of this message. * @@ -244,7 +247,7 @@ public: /** Extract the whole message data (header + contents). * - * WARNING: partial fetch might not be supported by the underlying protocol. + * \warning Partial fetch might not be supported by the underlying protocol. * * @param os output stream in which to write message data * @param progress progression listener, or NULL if not used @@ -256,7 +259,7 @@ public: /** Extract the specified (MIME) part of the message (header + contents). * - * WARNING: partial fetch might not be supported by the underlying protocol. + * \warning Partial fetch might not be supported by the underlying protocol. * * @param p part to extract * @param os output stream in which to write part data diff --git a/src/messaging/service.cpp b/src/messaging/service.cpp index 5a55fb4f..5f69600d 100644 --- a/src/messaging/service.cpp +++ b/src/messaging/service.cpp @@ -26,9 +26,9 @@ namespace vmime { namespace messaging { -service::service(class session& sess, const serviceInfos& infos, class authenticator* auth) +service::service(session* sess, const serviceInfos& infos, authenticator* auth) : m_deleteAuth(auth == NULL), m_session(sess), m_auth(auth ? auth : - new defaultAuthenticator(sess.properties(), infos.propertyPrefix())) + new defaultAuthenticator(sess->getProperties(), infos.getPropertyPrefix())) { } @@ -40,5 +40,29 @@ service::~service() } +const session* service::getSession() const +{ + return (m_session); +} + + +session* service::getSession() +{ + return (m_session); +} + + +const authenticator* service::getAuthenticator() const +{ + return (m_auth); +} + + +authenticator* service::getAuthenticator() +{ + return (m_auth); +} + + } // messaging } // vmime diff --git a/src/messaging/service.hpp b/src/messaging/service.hpp index d4a59c7f..cfab3611 100644 --- a/src/messaging/service.hpp +++ b/src/messaging/service.hpp @@ -39,7 +39,7 @@ class service { protected: - service(class session& sess, const serviceInfos& infos, class authenticator* auth); + service(session* sess, const serviceInfos& infos, authenticator* auth); public: @@ -56,31 +56,31 @@ public: * * @return type of service */ - virtual const Type type() const = 0; + virtual const Type getType() const = 0; /** Return the protocol name of this service. * * @return protocol name */ - virtual const string protocolName() const = 0; + virtual const string getProtocolName() const = 0; /** Return the session object associated with this service instance. * * @return session object */ - const class session& session() const { return (m_session); } + const session* getSession() const; /** Return the session object associated with this service instance. * * @return session object */ - class session& session() { return (m_session); } + session* getSession(); /** Return information about this service. * * @return information about the service */ - virtual const serviceInfos& infos() const = 0; + virtual const serviceInfos& getInfos() const = 0; /** Connect to service. */ @@ -106,13 +106,13 @@ public: * * @return authenticator object */ - const class authenticator& authenticator() const { return (*m_auth); } + const authenticator* getAuthenticator() const; /** Return the authenticator object used with this service instance. * * @return authenticator object */ - class authenticator& authenticator() { return (*m_auth); } + authenticator* getAuthenticator(); // Basic service registerer template @@ -123,7 +123,7 @@ public: initializer(const string& protocol) { serviceFactory::getInstance()-> - template registerName (protocol); + template registerServiceByProtocol (protocol); } }; @@ -131,8 +131,8 @@ private: bool m_deleteAuth; - class session& m_session; - class authenticator* m_auth; + session* m_session; + authenticator* m_auth; }; diff --git a/src/messaging/serviceFactory.cpp b/src/messaging/serviceFactory.cpp index 35ff3a98..b6a69313 100644 --- a/src/messaging/serviceFactory.cpp +++ b/src/messaging/serviceFactory.cpp @@ -37,65 +37,83 @@ serviceFactory::serviceFactory() serviceFactory::~serviceFactory() { - for (ProtoMap::iterator it = m_protoMap.begin() ; it != m_protoMap.end() ; ++it) - delete ((*it).second); -} - - -service* serviceFactory::create - (session& sess, const string& protocol, authenticator* auth) -{ - ProtoMap::const_iterator pos = m_protoMap.find(toLower(protocol)); - - if (pos != m_protoMap.end()) + for (std::vector ::const_iterator it = m_services.begin() ; + it != m_services.end() ; ++it) { - return ((*pos).second)->create(sess, auth); - } - else - { - throw exceptions::no_service_available(); - return (NULL); + delete (*it); } } service* serviceFactory::create - (session& sess, const url& u, authenticator* auth) + (session* sess, const string& protocol, authenticator* auth) { - service* serv = create(sess, u.protocol(), auth); + return (getServiceByProtocol(protocol)->create(sess, auth)); +} - sess.properties()[serv->infos().propertyPrefix() + "server.address"] = u.host(); - if (u.port() != url::UNSPECIFIED_PORT) - sess.properties()[serv->infos().propertyPrefix() + "server.port"] = u.port(); +service* serviceFactory::create + (session* sess, const url& u, authenticator* auth) +{ + service* serv = create(sess, u.getProtocol(), auth); + + sess->getProperties()[serv->getInfos().getPropertyPrefix() + "server.address"] = u.getHost(); + + if (u.getPort() != url::UNSPECIFIED_PORT) + sess->getProperties()[serv->getInfos().getPropertyPrefix() + "server.port"] = u.getPort(); // Path portion of the URL is used to point a specific folder (empty = root) //if (!u.path().empty()) - // sess.properties()[serv->infos().propertyPrefix() + "server.path"] = u.path(); + // sess->properties()[serv->getInfos().getPropertyPrefix() + "server.path"] = u.getPath(); - if (!u.username().empty()) + if (!u.getUsername().empty()) { - sess.properties()[serv->infos().propertyPrefix() + "auth.username"] = u.username(); - sess.properties()[serv->infos().propertyPrefix() + "auth.password"] = u.password(); + sess->getProperties()[serv->getInfos().getPropertyPrefix() + "auth.username"] = u.getUsername(); + sess->getProperties()[serv->getInfos().getPropertyPrefix() + "auth.password"] = u.getPassword(); } return (serv); } -const serviceFactory::registeredService& serviceFactory::operator[] - (const string& protocol) const +const serviceFactory::registeredService* serviceFactory::getServiceByProtocol(const string& protocol) const { - ProtoMap::const_iterator pos = m_protoMap.find(toLower(protocol)); + const string name(stringUtils::toLower(protocol)); - if (pos != m_protoMap.end()) + for (std::vector ::const_iterator it = m_services.begin() ; + it != m_services.end() ; ++it) { - return *((*pos).second); + if ((*it)->getName() == name) + return (*it); } - else + + throw exceptions::no_service_available(); +} + + +const int serviceFactory::getServiceCount() const +{ + return (m_services.size()); +} + + +const serviceFactory::registeredService* serviceFactory::getServiceAt(const int pos) const +{ + return (m_services[pos]); +} + + +const std::vector serviceFactory::getServiceList() const +{ + std::vector res; + + for (std::vector ::const_iterator it = m_services.begin() ; + it != m_services.end() ; ++it) { - throw exceptions::no_service_available(); + res.push_back(*it); } + + return (res); } diff --git a/src/messaging/serviceFactory.hpp b/src/messaging/serviceFactory.hpp index 9aa8e46a..2ade7e69 100644 --- a/src/messaging/serviceFactory.hpp +++ b/src/messaging/serviceFactory.hpp @@ -26,6 +26,7 @@ #include "../types.hpp" #include "../base.hpp" #include "../utility/singleton.hpp" +#include "../utility/stringUtils.hpp" #include "serviceInfos.hpp" #include "authenticator.hpp" @@ -49,13 +50,14 @@ class serviceFactory : public utility::singleton { friend class utility::singleton ; -protected: +private: serviceFactory(); ~serviceFactory(); public: + /** Information about a registered service. */ class registeredService { friend class serviceFactory; @@ -66,10 +68,10 @@ public: public: - virtual service* create(session& sess, authenticator* auth) = 0; + virtual service* create(session* sess, authenticator* auth) const = 0; - virtual const string& name() const = 0; - virtual const serviceInfos& infos() const = 0; + virtual const string& getName() const = 0; + virtual const serviceInfos& getInfos() const = 0; }; private: @@ -82,23 +84,23 @@ private: protected: registeredServiceImpl(const string& name) - : m_name(name), m_servInfos(S::infosInstance()) + : m_name(name), m_servInfos(S::getInfosInstance()) { } public: - service* create(session& sess, authenticator* auth) + service* create(session* sess, authenticator* auth) const { return new S(sess, auth); } - const serviceInfos& infos() const + const serviceInfos& getInfos() const { return (m_servInfos); } - const string& name() const + const string& getName() const { return (m_name); } @@ -109,94 +111,71 @@ private: const serviceInfos& m_servInfos; }; - typedef std::map ProtoMap; - ProtoMap m_protoMap; + std::vector m_services; public: + /** Register a new service by its protocol name. + * + * @param protocol protocol name + */ template - void registerName(const string& protocol) + void registerServiceByProtocol(const string& protocol) { - const string name = vmime::toLower(protocol); - m_protoMap.insert(ProtoMap::value_type(name, - new registeredServiceImpl (name))); + const string name = stringUtils::toLower(protocol); + m_services.push_back(new registeredServiceImpl (name)); } - service* create(session& sess, const string& protocol, authenticator* auth = NULL); - service* create(session& sess, const url& u, authenticator* auth = NULL); + /** Create a new service instance from a protocol name. + * + * @param sess session + * @param protocol protocol name (eg. "pop3") + * @param auth authenticator used to provide credentials (can be NULL if not used) + * @return a new service instance for the specified protocol + * @throw exceptions::no_service_available if no service is registered + * for this protocol + */ + service* create(session* sess, const string& protocol, authenticator* auth = NULL); - const registeredService& operator[](const string& protocol) const; + /** Create a new service instance from a URL. + * + * @param sess session + * @param u full URL with at least protocol and server (you can also specify + * port, username and password) + * @param auth authenticator used to provide credentials (can be NULL if not used) + * @return a new service instance for the specified protocol + * @throw exceptions::no_service_available if no service is registered + * for this protocol + */ + service* create(session* sess, const url& u, authenticator* auth = NULL); + /** Return information about a registered protocol. + * + * @param protocol protocol name + * @return information about this protocol + * @throw exceptions::no_service_available if no service is registered + * for this protocol + */ + const registeredService* getServiceByProtocol(const string& protocol) const; - class iterator; + /** Return the number of registered services. + * + * @return number of registered services + */ + const int getServiceCount() const; - class const_iterator - { - friend class serviceFactory; + /** Return the registered service at the specified position. + * + * @param pos position of the registered service to return + * @return registered service at the specified position + */ + const registeredService* getServiceAt(const int pos) const; - 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 registeredService& operator*() const { return (*(*m_it).second); } - const registeredService* 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 ProtoMap::const_iterator it) : m_it(it) { } - - ProtoMap::const_iterator m_it; - }; - - class iterator - { - friend class serviceFactory; - friend class serviceFactory::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); } - - registeredService& operator*() const { return (*(*m_it).second); } - registeredService* 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 ProtoMap::iterator it) : m_it(it) { } - - ProtoMap::iterator m_it; - }; - - iterator begin() { return iterator(m_protoMap.begin()); } - iterator end() { return iterator(m_protoMap.end()); } - - const_iterator begin() const { return const_iterator(m_protoMap.begin()); } - const_iterator end() const { return const_iterator(m_protoMap.end()); } + /** Return a list of all registered services. + * + * @return list of registered services + */ + const std::vector getServiceList() const; }; diff --git a/src/messaging/serviceInfos.hpp b/src/messaging/serviceInfos.hpp index 9da5ab26..3215ab7d 100644 --- a/src/messaging/serviceInfos.hpp +++ b/src/messaging/serviceInfos.hpp @@ -51,20 +51,20 @@ public: * * @return default port number */ - virtual const port_t defaultPort() const = 0; + virtual const port_t getDefaultPort() const = 0; /** Return the property prefix used by this service. * Use this to set/get properties in the session object. * * @return property prefix */ - virtual const string propertyPrefix() const = 0; + virtual const string getPropertyPrefix() const = 0; /** Return a list of available properties for this service. * * @return list of property names */ - virtual const std::vector availableProperties() const = 0; + virtual const std::vector getAvailableProperties() const = 0; }; diff --git a/src/messaging/session.cpp b/src/messaging/session.cpp index be1d8206..54f65c95 100644 --- a/src/messaging/session.cpp +++ b/src/messaging/session.cpp @@ -52,9 +52,9 @@ transport* session::getTransport(authenticator* auth) transport* session::getTransport(const string& protocol, authenticator* auth) { - service* sv = serviceFactory::getInstance()->create(*this, protocol, auth); + service* sv = serviceFactory::getInstance()->create(this, protocol, auth); - if (sv->type() != service::TYPE_TRANSPORT) + if (sv->getType() != service::TYPE_TRANSPORT) { delete (sv); throw exceptions::no_service_available(); @@ -72,9 +72,9 @@ store* session::getStore(authenticator* auth) store* session::getStore(const string& protocol, authenticator* auth) { - service* sv = serviceFactory::getInstance()->create(*this, protocol, auth); + service* sv = serviceFactory::getInstance()->create(this, protocol, auth); - if (sv->type() != service::TYPE_STORE) + if (sv->getType() != service::TYPE_STORE) { delete (sv); throw exceptions::no_service_available(); @@ -84,5 +84,17 @@ store* session::getStore(const string& protocol, authenticator* auth) } +const propertySet& session::getProperties() const +{ + return (m_props); +} + + +propertySet& session::getProperties() +{ + return (m_props); +} + + } // messaging } // vmime diff --git a/src/messaging/session.hpp b/src/messaging/session.hpp index 43bbe0b1..ad521fc3 100644 --- a/src/messaging/session.hpp +++ b/src/messaging/session.hpp @@ -94,11 +94,11 @@ public: /** Properties for the session and for the services. */ - const propertySet& properties() const { return (m_props); } + const propertySet& getProperties() const; /** Properties for the session and for the services. */ - propertySet& properties() { return (m_props); } + propertySet& getProperties(); private: diff --git a/src/messaging/simpleAuthenticator.cpp b/src/messaging/simpleAuthenticator.cpp index 557efd63..878e5aea 100644 --- a/src/messaging/simpleAuthenticator.cpp +++ b/src/messaging/simpleAuthenticator.cpp @@ -41,5 +41,29 @@ const authenticationInfos simpleAuthenticator::getAuthInfos() const } +const string& simpleAuthenticator::getUsername() const +{ + return (m_username); +} + + +void simpleAuthenticator::setUsername(const string& username) +{ + m_username = username; +} + + +const string& simpleAuthenticator::getPassword() const +{ + return (m_password); +} + + +void simpleAuthenticator::setPassword(const string& password) +{ + m_password = password; +} + + } // messaging } // vmime diff --git a/src/messaging/simpleAuthenticator.hpp b/src/messaging/simpleAuthenticator.hpp index 9d19f4c6..4fbbbf0a 100644 --- a/src/messaging/simpleAuthenticator.hpp +++ b/src/messaging/simpleAuthenticator.hpp @@ -37,11 +37,11 @@ public: public: - const string& username() const { return (m_username); } - string& username() { return (m_username); } + const string& getUsername() const; + void setUsername(const string& username); - const string& password() const { return (m_password); } - string& password() { return (m_password); } + const string& getPassword() const; + void setPassword(const string& password); private: diff --git a/src/messaging/store.hpp b/src/messaging/store.hpp index 687975d3..43890977 100644 --- a/src/messaging/store.hpp +++ b/src/messaging/store.hpp @@ -37,7 +37,7 @@ class store : public service { protected: - store(class session& sess, const serviceInfos& infos, class authenticator* auth) + store(session* sess, const serviceInfos& infos, authenticator* auth) : service(sess, infos, auth) { } public: @@ -64,7 +64,7 @@ public: virtual folder* getFolder(const folder::path& path) = 0; - const Type type() const { return (TYPE_STORE); } + const Type getType() const { return (TYPE_STORE); } }; diff --git a/src/messaging/transport.hpp b/src/messaging/transport.hpp index 588eb24b..bb3306c2 100644 --- a/src/messaging/transport.hpp +++ b/src/messaging/transport.hpp @@ -42,7 +42,7 @@ class transport : public service { protected: - transport(class session& sess, const serviceInfos& infos, class authenticator* auth) + transport(session* sess, const serviceInfos& infos, authenticator* auth) : service(sess, infos, auth) { } public: @@ -65,7 +65,7 @@ public: virtual void send(const mailbox& expeditor, const mailboxList& recipients, utility::inputStream& is, const utility::stream::size_type size, progressionListener* progress = NULL) = 0; - const Type type() const { return (TYPE_TRANSPORT); } + const Type getType() const { return (TYPE_TRANSPORT); } }; diff --git a/src/messaging/url.cpp b/src/messaging/url.cpp index cd38c656..9bedb150 100644 --- a/src/messaging/url.cpp +++ b/src/messaging/url.cpp @@ -131,7 +131,7 @@ void url::parse(const string& str) if (protoEnd == string::npos) throw exceptions::malformed_url("No protocol separator"); const string proto = - toLower(string(str.begin(), str.begin() + protoEnd)); + stringUtils::toLower(string(str.begin(), str.begin() + protoEnd)); // Username/password string::size_type slashPos = str.find('/', protoEnd + 3); @@ -222,5 +222,77 @@ void url::parse(const string& str) } +const string& url::getProtocol() const +{ + return (m_protocol); +} + + +void url::setProtocol(const string& protocol) +{ + m_protocol = protocol; +} + + +const string& url::getUsername() const +{ + return (m_username); +} + + +void url::setUsername(const string& username) +{ + m_username = username; +} + + +const string& url::getPassword() const +{ + return (m_password); +} + + +void url::setPassword(const string& password) +{ + m_password = password; +} + + +const string& url::getHost() const +{ + return (m_host); +} + + +void url::setHost(const string& host) +{ + m_host = host; +} + + +const port_t url::getPort() const +{ + return (m_port); +} + + +void url::setPort(const port_t port) +{ + m_port = port; +} + + +const string& url::getPath() const +{ + return (m_path); +} + + +void url::setPath(const string& path) +{ + m_path = path; +} + + } // messaging } // vmime diff --git a/src/messaging/url.hpp b/src/messaging/url.hpp index 8cef2d16..15c9d402 100644 --- a/src/messaging/url.hpp +++ b/src/messaging/url.hpp @@ -37,12 +37,16 @@ class url { public: - /** Means "port not specified" (use default port). - */ + /** Means "port not specified" (use default port). */ static const port_t UNSPECIFIED_PORT = static_cast (-1); + /** Standard name for FILE protocol (local file-system). */ static const string PROTOCOL_FILE; + + /** Standard name for HTTP protocol. */ static const string PROTOCOL_HTTP; + + /** Standard name for FTP protocol. */ static const string PROTOCOL_FTP; @@ -71,23 +75,82 @@ public: const string& path = "", const string& username = "", const string& password = ""); - const string& protocol() const { return (m_protocol); } - string& protocol() { return (m_protocol); } + /** Return the protocol of the URL (eg: "http"). + * + * @return protocol of the URL + */ + const string& getProtocol() const; - const string& username() const { return (m_username); } - string& username() { return (m_username); } + /** Set the protocol of the URL. + * + * @param protocol new protocol (eg: "http") + */ + void setProtocol(const string& protocol); - const string& password() const { return (m_password); } - string& password() { return (m_password); } + /** Return the username specified in the URL + * or empty if not specified. + * + * @return user name + */ + const string& getUsername() const; - const string& host() const { return (m_host); } - string& host() { return (m_host); } + /** Set the username of the URL. + * + * @param username user name + */ + void setUsername(const string& username); - const port_t port() const { return (m_port); } - port_t& port() { return (m_port); } + /** Return the password specified in the URL + * or empty if not specified. + * + * @return user password + */ + const string& getPassword() const; - const string& path() const { return (m_path); } - string& path() { return (m_path); } + /** Set the password of the URL. + * + * @param password user password + */ + void setPassword(const string& password); + + /** Return the host name of the URL (server name or IP address). + * + * @return host name + */ + const string& getHost() const; + + /** Set the host name of the URL. + * + * @param host server name or IP address + */ + void setHost(const string& host); + + /** Return the port of the URL, or url::UNSPECIFIED_PORT if + * the default port if used. + * + * @return server port + */ + const port_t getPort() const; + + /** Set the port of the URL. + * + * @param port server port or url::UNSPECIFIED_PORT to + * use the default port of the protocol + */ + void setPort(const port_t port); + + /** Return the path portion of the URL, + * or empty if not specified. + * + * @return path + */ + const string& getPath() const; + + /** Set the part portion of the URL. + * + * @param path path + */ + void setPath(const string& path); /** Build a string URL from this object. diff --git a/src/messaging/urlUtils.hpp b/src/messaging/urlUtils.hpp index 135d508e..c6296805 100644 --- a/src/messaging/urlUtils.hpp +++ b/src/messaging/urlUtils.hpp @@ -29,6 +29,9 @@ namespace vmime { namespace messaging { +/** Miscellaneous functions related to URLs. + */ + class urlUtils { public: diff --git a/src/options.cpp b/src/options.cpp index cd630a1d..8435f8f3 100644 --- a/src/options.cpp +++ b/src/options.cpp @@ -24,4 +24,36 @@ namespace vmime { +options::multipartOptions::multipartOptions() + : m_prologText("This is a multi-part message in MIME format. Your mail reader " \ + "does not understand MIME message format."), + m_epilogText("") +{ +} + + +const string& options::multipartOptions::getPrologText() const +{ + return (m_prologText); +} + + +void options::multipartOptions::setPrologText(const string& prologText) +{ + m_prologText = prologText; +} + + +const string& options::multipartOptions::getEpilogText() const +{ + return (m_epilogText); +} + + +void options::multipartOptions::setEpilogText(const string& epilogText) +{ + m_epilogText = epilogText; +} + + } // vmime diff --git a/src/options.hpp b/src/options.hpp index bfc2f243..a3b9c051 100644 --- a/src/options.hpp +++ b/src/options.hpp @@ -63,26 +63,22 @@ protected: */ class multipartOptions { - protected: + private: friend class options; - multipartOptions() - : m_prologText("This is a multi-part message in MIME format. Your mail reader does not understand MIME message format."), - m_epilogText("") - { - } + multipartOptions(); string m_prologText; string m_epilogText; public: - const string& prologText() const { return (m_prologText); } - string& prologText() { return (m_prologText); } + const string& getPrologText() const; + void setPrologText(const string& prologText); - const string& epilogText() const { return (m_epilogText); } - string& epilogText() { return (m_epilogText); } + const string& getEpilogText() const; + void setEpilogText(const string& epilogText); }; public: diff --git a/src/parameter.cpp b/src/parameter.cpp index 98111cb0..7c673703 100644 --- a/src/parameter.cpp +++ b/src/parameter.cpp @@ -34,9 +34,116 @@ parameter* parameter::clone() const } -void parameter::copyFrom(const parameter& param) +void parameter::copyFrom(const component& other) { + const parameter& param = dynamic_cast (other); + m_name = param.m_name; + + getValue().copyFrom(param.getValue()); +} + + +parameter& parameter::operator=(const parameter& other) +{ + copyFrom(other); + return (*this); +} + + +const string& parameter::getName() const +{ + return (m_name); +} + + +void parameter::parse(const string& buffer, const string::size_type position, + const string::size_type end, string::size_type* newPosition) +{ + getValue().parse(buffer, position, end, newPosition); +} + + +void parameter::generate(utility::outputStream& os, const string::size_type maxLineLength, + const string::size_type curLinePos, string::size_type* newLinePos) const +{ + string::size_type pos = curLinePos; + + if (pos + m_name.length() + 10 > maxLineLength) + { + os << NEW_LINE_SEQUENCE; + pos = NEW_LINE_SEQUENCE_LENGTH; + } + + os << m_name << "="; + pos += m_name.length() + 1; + + generateValue(os, maxLineLength, pos, newLinePos); +} + + +void parameter::generateValue(utility::outputStream& os, const string::size_type /* maxLineLength */, + const string::size_type curLinePos, string::size_type* newLinePos) const +{ + std::ostringstream valueStream; + utility::outputStreamAdapter valueStreamV(valueStream); + + // TODO: can we imagine having values that span on multiple lines? + getValue().generate(valueStreamV, lineLengthLimits::infinite, 0, NULL); + + const string value(valueStream.str()); + + 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()); + + if (quoted) + os << "\"" << ss.str() << "\""; + else + os << ss.str(); + + if (newLinePos) + *newLinePos = curLinePos + ss.str().length() + 2; } diff --git a/src/parameter.hpp b/src/parameter.hpp index 57f130ba..6c08722e 100644 --- a/src/parameter.hpp +++ b/src/parameter.hpp @@ -21,6 +21,7 @@ #define VMIME_PARAMETER_HPP_INCLUDED +#include "base.hpp" #include "component.hpp" @@ -30,22 +31,51 @@ namespace vmime class parameter : public component { - friend class parameterFactory; // for "parse()" + friend class parameterFactory; public: parameter* clone() const; + void copyFrom(const component& other); + parameter& operator=(const parameter& other); -protected: + /** Return the name of the parameter. + * + * @return name of the parameter + */ + const string& getName() const; + + /** Return the read-only value object attached to this field. + * + * @return read-only value object + */ + virtual const component& getValue() const = 0; + + /** Return the value object attached to this field. + * + * @return value object + */ + virtual component& getValue() = 0; + + /** Set the value of the parameter. + * + * @throw std::bad_cast_exception if the value type is + * incompatible with the parameter type + * @param value value object + */ + virtual void setValue(const component& value) = 0; + + 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; -public: - - virtual void copyFrom(const parameter& param); - - const string& name() const { return (m_name); } - string& name() { return (m_name); } + void generateValue(utility::outputStream& os, const string::size_type maxLineLength, const string::size_type curLinePos, string::size_type* newLinePos) const; }; diff --git a/src/parameterFactory.cpp b/src/parameterFactory.cpp index e67a8ee3..ae1d470d 100644 --- a/src/parameterFactory.cpp +++ b/src/parameterFactory.cpp @@ -20,9 +20,7 @@ #include "parameterFactory.hpp" #include "exception.hpp" -#include "textParameter.hpp" -#include "charsetParameter.hpp" -#include "dateParameter.hpp" +#include "standardParams.hpp" namespace vmime @@ -47,9 +45,9 @@ parameterFactory::~parameterFactory() parameter* parameterFactory::create (const string& name, const string& value) { - const string _name = toLower(name); + const string lcName = stringUtils::toLower(name); - NameMap::const_iterator pos = m_nameMap.find(_name); + NameMap::const_iterator pos = m_nameMap.find(lcName); parameter* param = NULL; if (pos != m_nameMap.end()) @@ -58,10 +56,10 @@ parameter* parameterFactory::create } else { - param = new textParameter; + param = registerer ::creator(); } - param->name() = _name; + param->m_name = name; if (value != NULL_STRING) param->parse(value); return (param); diff --git a/src/parameterFactory.hpp b/src/parameterFactory.hpp index 8bff7e33..3e58ff3f 100644 --- a/src/parameterFactory.hpp +++ b/src/parameterFactory.hpp @@ -23,6 +23,7 @@ #include "parameter.hpp" #include "utility/singleton.hpp" +#include "utility/stringUtils.hpp" namespace vmime @@ -60,7 +61,7 @@ public: template void registerName(const string& name) { - m_nameMap.insert(NameMap::value_type(toLower(name), ®isterer::creator)); + m_nameMap.insert(NameMap::value_type(stringUtils::toLower(name), ®isterer::creator)); } parameter* create(const string& name, const string& value = NULL_STRING); diff --git a/src/parameterizedHeaderField.cpp b/src/parameterizedHeaderField.cpp index ee00cd32..1487abd7 100644 --- a/src/parameterizedHeaderField.cpp +++ b/src/parameterizedHeaderField.cpp @@ -33,14 +33,14 @@ parameterizedHeaderField::parameterizedHeaderField() /* - This class handles field contents of the following form: - Field: VALUE; PARAM1="VALUE1"; PARAM2="VALUE2"... + This class handles field contents of the following form: + Field: VALUE; PARAM1="VALUE1"; PARAM2="VALUE2"... - eg. RFC-1521 + eg. RFC-1521 content := "Content-Type" ":" type "/" subtype *(";" parameter) - parameter := attribute "=" value + parameter := attribute "=" value attribute := token ; case-insensitive @@ -66,7 +66,9 @@ void parameterizedHeaderField::parse(const string& buffer, const string::size_ty while (p < pend && *p != ';') ++p; - parseValue(buffer, start, position + (p - pstart)); + getValue().parse(buffer, start, position + (p - pstart)); + + removeAllParameters(); // If there is one or more parameters following... if (p < pend) @@ -182,7 +184,7 @@ void parameterizedHeaderField::parse(const string& buffer, const string::size_ty if (attrStart != attrEnd && value.length()) { // Append this parameter to the list - parameters.m_params.push_back(parameterFactory::getInstance()-> + appendParameter(parameterFactory::getInstance()-> create(string(buffer.begin() + attrStart, buffer.begin() + attrEnd), value)); } @@ -206,22 +208,14 @@ void parameterizedHeaderField::generate(utility::outputStream& os, const string: // Parent header field headerField::generate(os, maxLineLength, pos, &pos); - // Value - const string value = generateValue(); - - encodeAndFoldText(os, text(value), maxLineLength - 1, - pos, &pos, encodeAndFoldFlags::none); - // Parameters for (std::vector ::const_iterator - it = parameters.m_params.begin() ; it != parameters.m_params.end() ; ++it) + it = m_params.begin() ; it != m_params.end() ; ++it) { - const parameter& param = **it; - os << "; "; pos += 2; - param.generate(os, maxLineLength, pos, &pos); + (*it)->generate(os, maxLineLength, pos, &pos); } if (newLinePos) @@ -229,107 +223,215 @@ void parameterizedHeaderField::generate(utility::outputStream& os, const string: } -void parameterizedHeaderField::copyFrom(const headerField& field) +void parameterizedHeaderField::copyFrom(const component& other) { - const parameterizedHeaderField& source = dynamic_cast(field); + headerField::copyFrom(other); - parameters.clear(); + const parameterizedHeaderField& source = dynamic_cast(other); - for (std::vector ::const_iterator i = source.parameters.m_params.begin() ; - i != source.parameters.m_params.end() ; ++i) + removeAllParameters(); + + for (std::vector ::const_iterator i = source.m_params.begin() ; + i != source.m_params.end() ; ++i) { - parameters.m_params.push_back((*i)->clone()); + appendParameter((*i)->clone()); } - - headerField::copyFrom(field); } - -////////////////////// -// Params container // -////////////////////// - - -parameterizedHeaderField::paramsContainer::~paramsContainer() +parameterizedHeaderField& parameterizedHeaderField::operator=(const parameterizedHeaderField& other) { - clear(); + copyFrom(other); + return (*this); } -parameter& parameterizedHeaderField::paramsContainer::find(const string& name) const +const bool parameterizedHeaderField::hasParameter(const string& paramName) const { - const string _name = toLower(name); + const string name = stringUtils::toLower(paramName); std::vector ::const_iterator pos = m_params.begin(); const std::vector ::const_iterator end = m_params.end(); - for ( ; pos != end && (*pos)->name() != _name ; ++pos); + for ( ; pos != end && stringUtils::toLower((*pos)->getName()) != name ; ++pos); + + return (pos != end); +} + + +parameter* parameterizedHeaderField::findParameter(const string& paramName) const +{ + const string name = stringUtils::toLower(paramName); + + // Find the first parameter that matches the specified name + std::vector ::const_iterator pos = m_params.begin(); + const std::vector ::const_iterator end = m_params.end(); + + for ( ; pos != end && stringUtils::toLower((*pos)->getName()) != name ; ++pos); // No parameter with this name can be found if (pos == end) { - throw exceptions::no_such_parameter(name); + throw exceptions::no_such_parameter(paramName); } // Else, return a reference to the existing parameter else { - return (**pos); + return (*pos); } } -parameter& parameterizedHeaderField::paramsContainer::get(const string& name) +parameter* parameterizedHeaderField::getParameter(const string& paramName) { - const string _name = toLower(name); + const string name = stringUtils::toLower(paramName); - std::vector ::iterator pos = m_params.begin(); - const std::vector ::iterator end = m_params.end(); + // Find the first parameter that matches the specified name + std::vector ::const_iterator pos = m_params.begin(); + const std::vector ::const_iterator end = m_params.end(); - for ( ; pos != end && (*pos)->name() != _name ; ++pos); + for ( ; pos != end && stringUtils::toLower((*pos)->getName()) != name ; ++pos); // If no parameter with this name can be found, create a new one if (pos == end) { - parameter* param = parameterFactory::getInstance()->create(_name); - m_params.push_back(param); + parameter* param = parameterFactory::getInstance()->create(paramName); + + try + { + appendParameter(param); + } + catch (std::exception&) + { + delete (param); + throw; + } // Return a reference to the new parameter - return (*param); + return (param); } // Else, return a reference to the existing parameter else { - return (**pos); + return (*pos); } } -// Parameter insertion -void parameterizedHeaderField::paramsContainer::append(const parameter& param) +void parameterizedHeaderField::appendParameter(parameter* param) { - m_params.push_back(param.clone()); + m_params.push_back(param); } -void parameterizedHeaderField::paramsContainer::insert(const iterator it, const parameter& param) +void parameterizedHeaderField::insertParameterBefore(parameter* beforeParam, parameter* param) { - m_params.insert(it.m_iterator, param.clone()); + const std::vector ::iterator it = std::find + (m_params.begin(), m_params.end(), beforeParam); + + if (it == m_params.end()) + throw exceptions::no_such_parameter(beforeParam->getName()); + + m_params.insert(it, param); } -// Parameter removing -void parameterizedHeaderField::paramsContainer::remove(const iterator it) +void parameterizedHeaderField::insertParameterBefore(const int pos, parameter* param) { - delete (*it.m_iterator); - m_params.erase(it.m_iterator); + m_params.insert(m_params.begin() + pos, param); } -void parameterizedHeaderField::paramsContainer::clear() +void parameterizedHeaderField::insertParameterAfter(parameter* afterParam, parameter* param) +{ + const std::vector ::iterator it = std::find + (m_params.begin(), m_params.end(), afterParam); + + if (it == m_params.end()) + throw exceptions::no_such_parameter(afterParam->getName()); + + m_params.insert(it + 1, param); +} + + +void parameterizedHeaderField::insertParameterAfter(const int pos, parameter* param) +{ + m_params.insert(m_params.begin() + pos + 1, param); +} + + +void parameterizedHeaderField::removeParameter(parameter* param) +{ + const std::vector ::iterator it = std::find + (m_params.begin(), m_params.end(), param); + + if (it == m_params.end()) + throw exceptions::no_such_parameter(param->getName()); + + m_params.erase(it); +} + + +void parameterizedHeaderField::removeParameter(const int pos) +{ + const std::vector ::iterator it = m_params.begin() + pos; + + delete (*it); + + m_params.erase(it); +} + + +void parameterizedHeaderField::removeAllParameters() { free_container(m_params); } +const int parameterizedHeaderField::getParameterCount() const +{ + return (m_params.size()); +} + + +const bool parameterizedHeaderField::isEmpty() const +{ + return (m_params.empty()); +} + + +parameter* parameterizedHeaderField::getParameterAt(const int pos) +{ + return (m_params[pos]); +} + + +const parameter* const parameterizedHeaderField::getParameterAt(const int pos) const +{ + return (m_params[pos]); +} + + +const std::vector parameterizedHeaderField::getParameterList() const +{ + std::vector list; + + list.reserve(m_params.size()); + + for (std::vector ::const_iterator it = m_params.begin() ; + it != m_params.end() ; ++it) + { + list.push_back(*it); + } + + return (list); +} + + +const std::vector parameterizedHeaderField::getParameterList() +{ + return (m_params); +} + + } // vmime diff --git a/src/parameterizedHeaderField.hpp b/src/parameterizedHeaderField.hpp index 949aceb4..980c78eb 100644 --- a/src/parameterizedHeaderField.hpp +++ b/src/parameterizedHeaderField.hpp @@ -32,7 +32,7 @@ namespace vmime { -class parameterizedHeaderField : public headerField +class parameterizedHeaderField : virtual public headerField { friend class headerFieldFactory::registerer ; @@ -42,154 +42,134 @@ protected: public: - void copyFrom(const headerField& field); + void copyFrom(const component& other); + parameterizedHeaderField& operator=(const parameterizedHeaderField& other); - // A sub-class for parameter manipulation - class paramsContainer - { - friend class parameterizedHeaderField; + /** Checks whether (at least) one parameter with this name exists. + * + * @return true if at least one parameter with the specified name + * exists, or false otherwise + */ + const bool hasParameter(const string& paramName) const; - protected: + /** Find the first parameter that matches the specified name. + * If no parameter is found, an exception is thrown. + * + * @throw exceptions::no_such_parameter if no parameter with this name exists + * @return first parameter with the specified name + */ + parameter* findParameter(const string& paramName) const; - ~paramsContainer(); + /** Find the first parameter that matches the specified name. + * If no parameter is found, one will be created and inserted into + * the parameter list. + * + * @return first parameter with the specified name or a new field + * if no parameter is found + */ + parameter* getParameter(const string& paramName); - public: + /** Add a parameter at the end of the list. + * + * @param param parameter to append + */ + void appendParameter(parameter* param); - // Find the first parameter with the specified name. If no parameter - // is found, an exception is thrown. - parameter& find(const string& name) const; + /** Insert a new parameter before the specified parameter. + * + * @param beforeParam parameter before which the new parameter will be inserted + * @param param parameter to insert + * @throw exceptions::no_such_parameter if the parameter is not in the list + */ + void insertParameterBefore(parameter* beforeParam, parameter* param); - // Find the first parameter with the specified name - parameter& get(const string& name); + /** Insert a new parameter before the specified position. + * + * @param pos position at which to insert the new parameter (0 to insert at + * the beginning of the list) + * @param param parameter to insert + */ + void insertParameterBefore(const int pos, parameter* param); - // Parameter iterator - class const_iterator; + /** Insert a new parameter after the specified parameter. + * + * @param afterParam parameter after which the new parameter will be inserted + * @param param parameter to insert + * @throw exceptions::no_such_parameter if the parameter is not in the list + */ + void insertParameterAfter(parameter* afterParam, parameter* param); - class iterator - { - friend class parameterizedHeaderField::paramsContainer::const_iterator; - friend class parameterizedHeaderField::paramsContainer; + /** Insert a new parameter after the specified position. + * + * @param pos position of the parameter before the new parameter + * @param param parameter to insert + */ + void insertParameterAfter(const int pos, parameter* param); - public: + /** Remove the specified parameter from the list. + * + * @param param parameter to remove + * @throw exceptions::no_such_parameter if the parameter is not in the list + */ + void removeParameter(parameter* param); - typedef std::vector ::iterator::difference_type difference_type; + /** Remove the parameter at the specified position. + * + * @param pos position of the parameter to remove + */ + void removeParameter(const int pos); - iterator(std::vector ::iterator it) : m_iterator(it) { } - iterator(const iterator& it) : m_iterator(it.m_iterator) { } + /** Remove all parameters from the list. + */ + void removeAllParameters(); - iterator& operator=(const iterator& it) { m_iterator = it.m_iterator; return (*this); } + /** Return the number of parameters in the list. + * + * @return number of parameters + */ + const int getParameterCount() const; - parameter& operator*() const { return (**m_iterator); } - parameter* operator->() const { return (*m_iterator); } + /** Tests whether the list of parameters is empty. + * + * @return true if there is no parameter, false otherwise + */ + const bool isEmpty() const; - iterator& operator++() { ++m_iterator; return (*this); } - iterator operator++(int) { iterator i(*this); ++m_iterator; return (i); } + /** Return the parameter at the specified position. + * + * @param pos position + * @return parameter at position 'pos' + */ + parameter* getParameterAt(const int pos); - iterator& operator--() { --m_iterator; return (*this); } - iterator operator--(int) { iterator i(*this); --m_iterator; return (i); } + /** Return the parameter at the specified position. + * + * @param pos position + * @return parameter at position 'pos' + */ + const parameter* const getParameterAt(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 parameter list. + * + * @return list of parameters + */ + const std::vector getParameterList() const; - iterator operator-(difference_type x) const { return iterator(m_iterator - x); } + /** Return the parameter list. + * + * @return list of parameters + */ + const std::vector getParameterList(); - parameter& operator[](difference_type n) const { return *(m_iterator[n]); } - - const bool operator==(const iterator& it) const { return (it.m_iterator == m_iterator); } - const bool operator!=(const iterator& it) const { return (!(*this == it)); } - - protected: - - std::vector ::iterator m_iterator; - }; - - class const_iterator - { - public: - - typedef std::vector ::const_iterator::difference_type difference_type; - - const_iterator(std::vector ::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 parameter& operator*() const { return (**m_iterator); } - const parameter* 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 parameter& 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 ::const_iterator m_iterator; - }; - - public: - - iterator begin() { return (m_params.begin()); } - iterator end() { return (m_params.end()); } - - const_iterator begin() const { return (const_iterator(m_params.begin())); } - const_iterator end() const { return (const_iterator(m_params.end())); } - - // Parameter insertion - void append(const parameter& param); - void insert(const iterator it, const parameter& param); - - // Parameter removing - void remove(const iterator it); - void clear(); - - // Parameter count - const size_t count() const { return (m_params.size()); } - const size_t size() const { return (m_params.size()); } - - parameter& front() { return (*m_params.front()); } - const parameter& front() const { return (*m_params.front()); } - parameter& back() { return (*m_params.back()); } - const parameter& back() const { return (*m_params.back()); } - - protected: - - std::vector m_params; - - } parameters; - - typedef paramsContainer::iterator iterator; - typedef paramsContainer::const_iterator const_iterator; - -protected: +private: std::vector m_params; -protected: - - virtual void parseValue(const string& buffer, const string::size_type position, const string::size_type end) = 0; - virtual const string generateValue() const = 0; - public: using headerField::parse; using headerField::generate; - // No need to override these (use "parseValue" and "generateValue" instead). - // For more information, see "defaultParameter.hpp". 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; }; diff --git a/src/parserHelpers.hpp b/src/parserHelpers.hpp index 41a9f13c..cfe853dd 100644 --- a/src/parserHelpers.hpp +++ b/src/parserHelpers.hpp @@ -22,6 +22,7 @@ #include "types.hpp" +#include "utility/stringUtils.hpp" #include diff --git a/src/plainTextPart.cpp b/src/plainTextPart.cpp index 141fb271..8a1bf994 100644 --- a/src/plainTextPart.cpp +++ b/src/plainTextPart.cpp @@ -26,7 +26,7 @@ namespace vmime { -const mediaType plainTextPart::type() const +const mediaType plainTextPart::getType() const { return (mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN)); } @@ -42,29 +42,29 @@ void plainTextPart::generateIn(bodyPart& /* message */, bodyPart& parent) const { // 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_text; + part->getBody()->setContents(m_text); } void plainTextPart::parse(const bodyPart& /* message */, const bodyPart& /* parent */, const bodyPart& textPart) { - m_text = textPart.body().contents(); + m_text = textPart.getBody()->getContents(); try { const contentTypeField& ctf = dynamic_cast - (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) { @@ -77,4 +77,28 @@ void plainTextPart::parse(const bodyPart& /* message */, } +const charset& plainTextPart::getCharset() const +{ + return (m_charset); +} + + +void plainTextPart::setCharset(const charset& ch) +{ + m_charset = ch; +} + + +const contentHandler& plainTextPart::getText() const +{ + return (m_text); +} + + +void plainTextPart::setText(const contentHandler& text) +{ + m_text = text; +} + + } // vmime diff --git a/src/plainTextPart.hpp b/src/plainTextPart.hpp index 324d2203..ae5425c6 100644 --- a/src/plainTextPart.hpp +++ b/src/plainTextPart.hpp @@ -28,22 +28,25 @@ namespace vmime { +/** Text part of type 'text/plain'. + */ + class plainTextPart : public textPart { public: - const mediaType type() const; + const mediaType getType() const; - const class charset& charset() const { return (m_charset); } - class charset& charset() { return (m_charset); } + const charset& getCharset() const; + void setCharset(const charset& ch); - const contentHandler& text() const { return (m_text); } - contentHandler& text() { return (m_text); } + const contentHandler& getText() const; + void setText(const contentHandler& text); -protected: +private: contentHandler m_text; - class charset m_charset; + charset m_charset; const int getPartCount() const; diff --git a/src/propertySet.cpp b/src/propertySet.cpp index 664a2b43..24ffee2c 100644 --- a/src/propertySet.cpp +++ b/src/propertySet.cpp @@ -44,13 +44,13 @@ propertySet::propertySet(const propertySet& set) propertySet::~propertySet() { - empty(); + removeAllProperties(); } propertySet& propertySet::operator=(const propertySet& set) { - empty(); + removeAllProperties(); for (std::list ::const_iterator it = set.m_props.begin() ; it != set.m_props.end() ; ++it) m_props.push_back(new property(**it)); @@ -59,19 +59,19 @@ propertySet& propertySet::operator=(const propertySet& set) } -void propertySet::set(const string& props) +void propertySet::setFromString(const string& props) { parse(props); } -void propertySet::empty() +void propertySet::removeAllProperties() { free_container(m_props); } -void propertySet::clear(const string& name) +void propertySet::removeProperty(const string& name) { std::list ::iterator it = std::find_if (m_props.begin(), m_props.end(), propFinder(name)); @@ -177,31 +177,138 @@ void propertySet::parse(const string& props) } -template <> -void propertySet::property::set(const string& value) +propertySet::property* propertySet::find(const string& name) const +{ + std::list ::const_iterator it = std::find_if + (m_props.begin(), m_props.end(), propFinder(name)); + + return (it != m_props.end() ? *it : NULL); +} + + +propertySet::property* propertySet::findOrCreate(const string& name) +{ + std::list ::const_iterator it = std::find_if + (m_props.begin(), m_props.end(), propFinder(name)); + + if (it != m_props.end()) + { + return (*it); + } + else + { + property* prop = new property(name, ""); + m_props.push_back(prop); + return (prop); + } +} + + +propertySet::propertyProxy propertySet::operator[](const string& name) +{ + return (propertyProxy(name, this)); +} + + +const propertySet::constPropertyProxy propertySet::operator[](const string& name) const +{ + return (constPropertyProxy(name, this)); +} + + +const bool propertySet::hasProperty(const string& name) const +{ + return (find(name) != NULL); +} + + +const std::vector propertySet::getPropertyList() const +{ + std::vector res; + + for (list_type::const_iterator it = m_props.begin() ; it != m_props.end() ; ++it) + res.push_back(*it); + + return (res); +} + + +const std::vector propertySet::getPropertyList() +{ + std::vector res; + + for (list_type::const_iterator it = m_props.begin() ; it != m_props.end() ; ++it) + res.push_back(*it); + + return (res); +} + + +// +// propertySet::property +// + +propertySet::property::property(const string& name, const string& value) + : m_name(name), m_value(value) +{ +} + + +propertySet::property::property(const string& name) + : m_name(name) +{ +} + + +propertySet::property::property(const property& prop) + : m_name(prop.m_name), m_value(prop.m_value) +{ +} + + +const string& propertySet::property::getName() const +{ + return (m_name); +} + + +const string& propertySet::property::getValue() const +{ + return (m_value); +} + + +void propertySet::property::setValue(const string& value) { m_value = value; } template <> -void propertySet::property::set(const bool& value) +void propertySet::property::setValue(const string& value) +{ + m_value = value; +} + + +template <> +void propertySet::property::setValue(const bool& value) { m_value = value ? "true" : "false"; } template <> -const string propertySet::property::get() const +const string propertySet::property::getValue() const { return (m_value); } template <> -const bool propertySet::property::get() const +const bool propertySet::property::getValue() const { - if (toLower(m_value) == "true") + if (stringUtils::toLower(m_value) == "true") return true; else { diff --git a/src/propertySet.hpp b/src/propertySet.hpp index eb0ee7d7..6cffa3ed 100644 --- a/src/propertySet.hpp +++ b/src/propertySet.hpp @@ -29,36 +29,67 @@ #include "base.hpp" #include "exception.hpp" +#include "utility/stringUtils.hpp" + namespace vmime { +/** Manage a list of (name,value) pairs. + */ + class propertySet { -private: +protected: class property { public: - property(const string& name, const string& value) : m_name(name), m_value(value) { } - property(const string& name) : m_name(name) { } - property(const property& prop) : m_name(prop.m_name), m_value(prop.m_value) { } + property(const string& name, const string& value); + property(const string& name); + property(const property& prop); - const string& name() const { return (m_name); } - const string& value() const { return (m_value); } + /** Return the name of the property. + * + * @return property name + */ + const string& getName() const; - template void set(const TYPE& value); - template const TYPE get() const; + /** Return the value of the property as a string. + * + * @return current value of the property + */ + const string& getValue() const; + + /** Set the value of the property as a string. + * + * @param value new value for property + */ + void setValue(const string& value); + + /** Set the value of the property as a generic type. + * + * @param value new value for property + */ + template void setValue(const TYPE& value); + + /** Get the value of the property as a generic type. + * + * @throw exceptions::invalid_property_type if the specified + * type is incompatible with the string value (cannot be + * converted using std::istringstream) + * @return current value of the property + */ + template const TYPE getValue() const; private: - string m_name; + const string m_name; string m_value; }; - class propertyProxy { public: @@ -71,25 +102,25 @@ private: template propertyProxy& operator=(const TYPE& value) { - m_set->set(m_name, value); + m_set->setProperty(m_name, value); return (*this); } template - void set(const TYPE& value) + void setValue(const TYPE& value) { - m_set->set(m_name, value); + m_set->setProperty(m_name, value); } template - const TYPE get() const + const TYPE getValue() const { - return (m_set->get (m_name)); + return (m_set->getProperty (m_name)); } operator string() const { - return (m_set->get (m_name)); + return (m_set->getProperty (m_name)); } private: @@ -108,14 +139,14 @@ private: } template - const TYPE get() const + const TYPE getValue() const { - return (m_set->get (m_name)); + return (m_set->getProperty (m_name)); } operator string() const { - return (m_set->get (m_name)); + return (m_set->getProperty (m_name)); } private: @@ -134,49 +165,91 @@ public: propertySet& operator=(const propertySet& set); - void set(const string& props); + /** Parse a string and extract one or more properties. + * The string format is: name[=value](;name[=value])*. + * + * @param props string representing a list of properties + */ + void setFromString(const string& props); - void empty(); + /** Remove all properties from the list. + */ + void removeAllProperties(); - void clear(const string& name); + /** Remove the specified property. + * + * @param name name of the property to remove + */ + void removeProperty(const string& name); + /** Test whether the specified property is set. + * + * @param name name of the property to test + * @return true if the property is set (has a value), + * false otherwise + */ + const bool hasProperty(const string& name) const; - const bool exists(const string& name) const - { - return (find(name) != NULL); - } - + /** Get the value of the specified property. + * + * @throw exceptions::no_such_property if the property does not exist + * @param name property name + * @return value of the specified property + */ template - const TYPE get(const string& name) const + const TYPE getProperty(const string& name) const { const property* const prop = find(name); if (!prop) throw exceptions::no_such_property(name); - return (prop->get ()); + return (prop->getValue ()); } + /** Get the value of the specified property. + * A default value can be returned if the property is not set. + * + * @param name property name + * @param defaultValue value to return if the specified property + * does not exist + * @return value of the specified property or default value + * if if does not exist + */ template - const TYPE get(const string& name, const TYPE defaultValue) const + const TYPE getProperty(const string& name, const TYPE defaultValue) const { const property* const prop = find(name); - return (prop ? prop->get () : defaultValue); + return (prop ? prop->getValue () : defaultValue); } + /** Change the value of the specified property or create + * a new property set to the specified a value. + * + * @param name property name + * @param value property value + */ template - void set(const string& name, const TYPE& value) + void setProperty(const string& name, const TYPE& value) { - findOrCreate(name)->set(value); + findOrCreate(name)->setValue(value); } - propertyProxy operator[](const string& name) - { - return (propertyProxy(name, this)); - } + /** Return a proxy object to access the specified property + * suitable for reading or writing. If the property does not + * exist and the value is changed, a new property will + * be created. + * + * @param name property name + * @return proxy object for the specified property + */ + propertyProxy operator[](const string& name); - const constPropertyProxy operator[](const string& name) const - { - return (constPropertyProxy(name, this)); - } + /** Return a proxy object to access the specified property + * suitable for reading only. + * + * @throw exceptions::no_such_property if the property does not exist + * @return read-only proxy object for the specified property + */ + const constPropertyProxy operator[](const string& name) const; private: @@ -187,11 +260,11 @@ private: { public: - propFinder(const string& name) : m_name(toLower(name)) { } + propFinder(const string& name) : m_name(stringUtils::toLower(name)) { } const bool operator()(property* const p) const { - return (toLower(p->name()) == m_name); + return (stringUtils::toLower(p->getName()) == m_name); } private: @@ -199,111 +272,31 @@ private: const std::string m_name; }; - property* find(const string& name) const - { - std::list ::const_iterator it = std::find_if - (m_props.begin(), m_props.end(), propFinder(name)); - - return (it != m_props.end() ? *it : NULL); - } - - property* findOrCreate(const string& name) - { - std::list ::const_iterator it = std::find_if - (m_props.begin(), m_props.end(), propFinder(name)); - - if (it != m_props.end()) - { - return (*it); - } - else - { - property* prop = new property(name, ""); - m_props.push_back(prop); - return (prop); - } - } + property* find(const string& name) const; + property* findOrCreate(const string& name); typedef std::list list_type; list_type m_props; public: - class iterator; + /** Return the property list. + * + * @return list of properties + */ + const std::vector getPropertyList() const; - class const_iterator - { - friend class propertySet; - - 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 property& operator*() const { return (**m_it); } - const property* operator->() const { return (*m_it); } - - 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 list_type::const_iterator it) : m_it(it) { } - - list_type::const_iterator m_it; - }; - - class iterator - { - friend class propertySet; - friend class propertySet::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); } - - property& operator*() const { return (**m_it); } - property* operator->() const { return (*m_it); } - - 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 list_type::iterator it) : m_it(it) { } - - list_type::iterator m_it; - }; - - iterator begin() { return iterator(m_props.begin()); } - iterator end() { return iterator(m_props.end()); } - - const_iterator begin() const { return const_iterator(m_props.begin()); } - const_iterator end() const { return const_iterator(m_props.end()); } + /** Return the property list. + * + * @return list of properties + */ + const std::vector getPropertyList(); }; template -void propertySet::property::set(const TYPE& value) +void propertySet::property::setValue(const TYPE& value) { std::ostringstream oss; oss << value; @@ -313,7 +306,7 @@ void propertySet::property::set(const TYPE& value) template -const TYPE propertySet::property::get() const +const TYPE propertySet::property::getValue() const { TYPE val = TYPE(); @@ -327,11 +320,11 @@ const TYPE propertySet::property::get() const } -template <> void propertySet::property::set(const string& value); -template <> void propertySet::property::set(const bool& value); +template <> void propertySet::property::setValue(const string& value); +template <> void propertySet::property::setValue(const bool& value); -template <> const string propertySet::property::get() const; -template <> const bool propertySet::property::get() const; +template <> const string propertySet::property::getValue() const; +template <> const bool propertySet::property::getValue() const; } // vmime diff --git a/src/relayField.cpp b/src/relay.cpp similarity index 70% rename from src/relayField.cpp rename to src/relay.cpp index b7959547..25f3aac7 100644 --- a/src/relayField.cpp +++ b/src/relay.cpp @@ -17,7 +17,7 @@ // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -#include "relayField.hpp" +#include "relay.hpp" #include "text.hpp" #include "parserHelpers.hpp" @@ -28,11 +28,18 @@ namespace vmime { -relayField::relayField() +relay::relay() { } +relay::relay(const relay& r) + : component() +{ + copyFrom(r); +} + + /* RFC #2822: @@ -46,7 +53,7 @@ relayField::relayField() ["for" addr-spec] ; initial form */ -void relayField::parse(const string& buffer, const string::size_type position, +void relay::parse(const string& buffer, const string::size_type position, const string::size_type end, string::size_type* newPosition) { const string::value_type* const pend = buffer.data() + end; @@ -108,32 +115,32 @@ void relayField::parse(const string& buffer, const string::size_type position, if (!inComment) { - if (isStringEqualNoCase(word, "from", 4)) + if (stringUtils::isStringEqualNoCase(word, "from", 4)) { newPart = Part_From; keyword = true; } - else if (isStringEqualNoCase(word, "by", 2)) + else if (stringUtils::isStringEqualNoCase(word, "by", 2)) { newPart = Part_By; keyword = true; } - else if (isStringEqualNoCase(word, "via", 2)) + else if (stringUtils::isStringEqualNoCase(word, "via", 2)) { newPart = Part_Via; keyword = true; } - else if (isStringEqualNoCase(word, "with", 2)) + else if (stringUtils::isStringEqualNoCase(word, "with", 2)) { newPart = Part_With; keyword = true; } - else if (isStringEqualNoCase(word, "id", 2)) + else if (stringUtils::isStringEqualNoCase(word, "id", 2)) { newPart = Part_Id; keyword = true; } - else if (isStringEqualNoCase(word, "for", 2)) + else if (stringUtils::isStringEqualNoCase(word, "for", 2)) { newPart = Part_For; keyword = true; @@ -185,7 +192,7 @@ void relayField::parse(const string& buffer, const string::size_type position, } -void relayField::generate(utility::outputStream& os, const string::size_type maxLineLength, +void relay::generate(utility::outputStream& os, const string::size_type maxLineLength, const string::size_type curLinePos, string::size_type* newLinePos) const { std::ostringstream oss; @@ -206,33 +213,122 @@ void relayField::generate(utility::outputStream& os, const string::size_type max oss << "; " << m_date.generate(); - string result(oss.str()); - - string::size_type pos = curLinePos; - - headerField::generate(os, maxLineLength, pos, &pos); - - encodeAndFoldText(os, text(result), maxLineLength, - pos, newLinePos, encodeAndFoldFlags::forceNoEncoding); + encodeAndFoldText(os, text(oss.str()), maxLineLength, + curLinePos, newLinePos, encodeAndFoldFlags::forceNoEncoding); } -void relayField::copyFrom(const headerField& field) +void relay::copyFrom(const component& other) { - const relayField& source = dynamic_cast(field); + const relay& r = dynamic_cast (other); - m_from = source.m_from; - m_via = source.m_via; - m_by = source.m_by; - m_id = source.m_id; - m_for = source.m_for; + m_from = r.m_from; + m_via = r.m_via; + m_by = r.m_by; + m_id = r.m_id; + m_for = r.m_for; - m_with.resize(source.m_with.size()); - std::copy(source.m_with.begin(), source.m_with.end(), m_with.begin()); + m_with.resize(r.m_with.size()); + std::copy(r.m_with.begin(), r.m_with.end(), m_with.begin()); - m_date = source.m_date; + m_date = r.m_date; +} - headerField::copyFrom(field); + +relay& relay::operator=(const relay& other) +{ + copyFrom(other); + return (*this); +} + + +relay* relay::clone() const +{ + return new relay(*this); +} + + +const string& relay::getFrom() const +{ + return (m_from); +} + + +void relay::setFrom(const string& from) +{ + m_from = from; +} + + +const string& relay::getVia() const +{ + return (m_via); +} + + +void relay::setVia(const string& via) +{ + m_via = via; +} + + +const string& relay::getBy() const +{ + return (m_by); +} + + +void relay::setBy(const string& by) +{ + m_by = by; +} + + +const string& relay::getId() const +{ + return (m_id); +} + + +void relay::setId(const string& id) +{ + m_id = id; +} + + +const string& relay::getFor() const +{ + return (m_for); +} + + +void relay::setFor(const string& for_) +{ + m_for = for_; +} + + +const datetime& relay::getDate() const +{ + return (m_date); +} + + +void relay::setDate(const datetime& date) +{ + m_date = date; +} + + +const std::vector & relay::getWithList() const +{ + return (m_with); +} + + +std::vector & relay::getWithList() +{ + return (m_with); } diff --git a/src/relayField.hpp b/src/relay.hpp similarity index 58% rename from src/relayField.hpp rename to src/relay.hpp index f24be873..8559bccd 100644 --- a/src/relayField.hpp +++ b/src/relay.hpp @@ -17,14 +17,13 @@ // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -#ifndef VMIME_RELAYFIELD_HPP_INCLUDED -#define VMIME_RELAYFIELD_HPP_INCLUDED +#ifndef VMIME_RELAY_HPP_INCLUDED +#define VMIME_RELAY_HPP_INCLUDED #include "base.hpp" #include "component.hpp" -#include "headerFieldFactory.hpp" #include "dateTime.hpp" @@ -32,40 +31,44 @@ namespace vmime { -class relayField : public headerField +/** Trace information about a relay (basic type). + */ + +class relay : public component { - friend class headerFieldFactory::registerer ; +public: -protected: - - relayField(); + relay(); + relay(const relay& r); public: - void copyFrom(const headerField& field); + relay* clone() const; + void copyFrom(const component& other); + relay& operator=(const relay& other); - const string& from() const { return (m_from); } - string& from() { return (m_from); } + const string& getFrom() const; + void setFrom(const string& from); - const string& via() const { return (m_via); } - string& via() { return (m_via); } + const string& getVia() const; + void setVia(const string& via); - const string& by() const { return (m_by); } - string& by() { return (m_by); } + const string& getBy() const; + void setBy(const string& by); - const string& id() const { return (m_id); } - string& id() { return (m_id); } + const string& getId() const; + void setId(const string& id); - const string& for_() const { return (m_for); } - string& for_() { return (m_for); } + const string& getFor() const; + void setFor(const string& for_); - const datetime& date() const { return (m_date); } - datetime& date() { return (m_date); } + const datetime& getDate() const; + void setDate(const datetime& date); - const std::vector & with() const { return (m_with); } - std::vector & with() { return (m_with); } + const std::vector & getWithList() const; + std::vector & getWithList(); -protected: +private: string m_from; string m_via; @@ -78,10 +81,9 @@ protected: public: - using headerField::parse; - using headerField::generate; + using component::parse; + using component::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; }; @@ -90,4 +92,4 @@ public: } // vmime -#endif // VMIME_RELAYFIELD_HPP_INCLUDED +#endif // VMIME_RELAY_HPP_INCLUDED diff --git a/src/standardFields.hpp b/src/standardFields.hpp new file mode 100644 index 00000000..f329069d --- /dev/null +++ b/src/standardFields.hpp @@ -0,0 +1,82 @@ +// +// VMime library (http://vmime.sourceforge.net) +// Copyright (C) 2002-2004 Vincent Richard +// +// 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_STANDARDFIELDS_HPP_INCLUDED +#define VMIME_STANDARDFIELDS_HPP_INCLUDED + + +#include "genericField.hpp" +#include "parameterizedHeaderField.hpp" +#include "headerFieldFactory.hpp" + +// Inclusion for field value types +#include "addressList.hpp" +#include "encoding.hpp" +#include "dateTime.hpp" +#include "text.hpp" +#include "messageId.hpp" +#include "relay.hpp" +#include "mailboxList.hpp" + + +namespace vmime +{ + + +#define DECLARE_STANDARD_FIELD(fieldClassName, valueTypeClassName) \ + class fieldClassName : public genericField { \ + friend class headerFieldFactory::registerer ; \ + protected: \ + fieldClassName() { } \ + fieldClassName(const fieldClassName&) \ + : headerField(), \ + genericField () { /* Not used */ } \ + } + +#define DECLARE_STANDARD_FIELD_PARAM(fieldClassName, valueTypeClassName) \ + class fieldClassName : public genericField , \ + public parameterizedHeaderField { \ + friend class headerFieldFactory::registerer ; \ + protected: \ + fieldClassName() { } \ + fieldClassName(const fieldClassName&) \ + : headerField(), \ + genericField (), \ + parameterizedHeaderField() { /* Not used */ } \ + } + + +DECLARE_STANDARD_FIELD(addressListField, addressList); +DECLARE_STANDARD_FIELD_PARAM(contentEncodingField, encoding); +DECLARE_STANDARD_FIELD(dateField, datetime); +DECLARE_STANDARD_FIELD(textField, text); +DECLARE_STANDARD_FIELD(messageIdField, messageId); +DECLARE_STANDARD_FIELD(defaultField, string); +DECLARE_STANDARD_FIELD(relayField, relay); +DECLARE_STANDARD_FIELD(mailboxListField, mailboxList); + + +#undef DECLARE_STANDARD_FIELD +#undef DECLARE_STANDARD_FIELD_PARAM + + +} // vmime + + +#endif // VMIME_STANDARDFIELDS_HPP_INCLUDED diff --git a/src/dateParameter.hpp b/src/standardParams.hpp similarity index 54% rename from src/dateParameter.hpp rename to src/standardParams.hpp index aa4ffd63..340f290b 100644 --- a/src/dateParameter.hpp +++ b/src/standardParams.hpp @@ -17,39 +17,40 @@ // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // -#ifndef VMIME_DATEPARAMETER_HPP_INCLUDED -#define VMIME_DATEPARAMETER_HPP_INCLUDED +#ifndef VMIME_STANDARDPARAMS_HPP_INCLUDED +#define VMIME_STANDARDPARAMS_HPP_INCLUDED -#include "defaultParameter.hpp" +#include "genericParameter.hpp" + +// Inclusion for field value types #include "dateTime.hpp" +#include "charset.hpp" namespace vmime { -class dateParameter : public defaultParameter -{ -protected: +#define DECLARE_STANDARD_PARAM(paramClassName, valueTypeClassName) \ + class paramClassName : public genericParameter { \ + friend class parameterFactory::registerer ; \ + protected: \ + paramClassName() { } \ + paramClassName(const paramClassName&) \ + : genericParameter () { /* Not used */ } \ + } - datetime m_value; -public: +DECLARE_STANDARD_PARAM(defaultParameter, string); +DECLARE_STANDARD_PARAM(dateParameter, datetime); +DECLARE_STANDARD_PARAM(charsetParameter, charset); - void copyFrom(const parameter& param); - const datetime& value() const { return (m_value); } - datetime& value() { return (m_value); } - -protected: - - void parseValue(const string& buffer, const string::size_type position, const string::size_type end); - const string generateValue() const; -}; +#undef DECLARE_STANDARD_PARAM } // vmime -#endif // VMIME_DATEPARAMETER_HPP_INCLUDED +#endif // VMIME_STANDARDPARAMS_HPP_INCLUDED diff --git a/src/text.cpp b/src/text.cpp index db993136..0969707c 100644 --- a/src/text.cpp +++ b/src/text.cpp @@ -30,32 +30,50 @@ text::text() text::text(const text& t) + : component() { - operator=(t); + copyFrom(t); } text::text(const string& t, const charset& ch) { - makeWordsFromText(t, ch, *this); + text::newFromString(t, ch, this); } text::text(const string& t) { - makeWordsFromText(t, charset::getLocaleCharset(), *this); + text::newFromString(t, charset::getLocaleCharset(), this); } text::text(const word& w) { - append(w); + appendWord(new word(w)); } text::~text() { - clear(); + removeAllWords(); +} + + +void text::parse(const string& buffer, const string::size_type position, + const string::size_type end, string::size_type* newPosition) +{ + decodeAndUnfoldText(buffer.begin() + position, buffer.begin() + end, *this); + + if (newPosition) + *newPosition = end; +} + + +void text::generate(utility::outputStream& os, const string::size_type maxLineLength, + const string::size_type curLinePos, string::size_type* newLinePos) const +{ + encodeAndFoldText(os, *this, maxLineLength, curLinePos, newLinePos, encodeAndFoldFlags::none); } @@ -66,9 +84,7 @@ const wstring text::getDecodedText() const wstring out; for (std::vector ::const_iterator i = m_words.begin() ; i != m_words.end() ; ++i) - { out += (*i)->getDecodedText(); - } return (out); } @@ -76,47 +92,34 @@ const wstring text::getDecodedText() const #endif -void text::append(const word& w) +void text::copyFrom(const component& other) { - m_words.push_back(new word(w)); -} + const text& t = dynamic_cast (other); - -void text::insert(const iterator it, const word& w) -{ - m_words.insert(it.m_iterator, new word(w)); -} - - -void text::clear() -{ - free_container(m_words); - - m_words.clear(); -} - - -void text::remove(const iterator it) -{ - delete (*it.m_iterator); - m_words.erase(it.m_iterator); -} - - -text& text::operator=(const text& t) -{ - clear(); + removeAllWords(); for (std::vector ::const_iterator i = t.m_words.begin() ; i != t.m_words.end() ; ++i) m_words.push_back(new word(**i)); +} + +text& text::operator=(const component& other) +{ + copyFrom(other); + return (*this); +} + + +text& text::operator=(const text& other) +{ + copyFrom(other); return (*this); } const bool text::operator==(const text& t) const { - if (size() == t.size()) + if (getWordCount() == t.getWordCount()) { bool equal = false; @@ -139,102 +142,177 @@ const bool text::operator!=(const text& t) const } -/** Return the text converted into the specified charset. - * The encoded-words are decoded and then converted in the - * destination charset. - * - * @param dest output charset - * @return text decoded in the specified charset - */ - const string text::getConvertedText(const charset& dest) const { string out; for (std::vector ::const_iterator i = m_words.begin() ; i != m_words.end() ; ++i) - { out += (*i)->getConvertedText(dest); + + return (out); +} + + +void text::appendWord(word* w) +{ + m_words.push_back(w); +} + + +void text::insertWordBefore(const int pos, word* w) +{ + m_words.insert(m_words.begin() + pos, w); +} + + +void text::insertWordAfter(const int pos, word* w) +{ + m_words.insert(m_words.begin() + pos + 1, w); +} + + +void text::removeWord(const int pos) +{ + const std::vector ::iterator it = m_words.begin() + pos; + + delete (*it); + + m_words.erase(it); +} + + +void text::removeAllWords() +{ + free_container(m_words); +} + + +const int text::getWordCount() const +{ + return (m_words.size()); +} + + +const bool text::isEmpty() const +{ + return (m_words.empty()); +} + + +word* text::getWordAt(const int pos) +{ + return (m_words[pos]); +} + + +const word* const text::getWordAt(const int pos) const +{ + return (m_words[pos]); +} + + +const std::vector text::getWordList() const +{ + std::vector list; + + list.reserve(m_words.size()); + + for (std::vector ::const_iterator it = m_words.begin() ; + it != m_words.end() ; ++it) + { + list.push_back(*it); + } + + return (list); +} + + +const std::vector text::getWordList() +{ + return (m_words); +} + + +text* text::clone() const +{ + return new text(*this); +} + + +text* text::newFromString(const string& in, const charset& ch, text* generateInExisting) +{ + 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 + + text* out = (generateInExisting != NULL) ? generateInExisting : new text(); + + out->removeAllWords(); + + for ( ; ; ) + { + if (p == end || isspace(*p)) + { + if (p != end) + ++p; + + if (is8bit) + { + if (count && prevIs8bit) + { + // No need to create a new encoded word, just append + // the current word to the previous one. + out->getWordAt(out->getWordCount() - 1)-> + getBuffer() += string(start, p); + } + else + { + out->appendWord(new word(string(start, p), ch)); + + prevIs8bit = true; + ++count; + } + } + else + { + if (count && !prevIs8bit) + { + out->getWordAt(out->getWordCount() - 1)-> + getBuffer() += string(start, p); + } + else + { + out->appendWord(new 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; + } } return (out); } -/** Check whether the list of encoded-words is empty. - * - * @return true if the list contains no encoded-word, false otherwise - */ - -const bool text::empty() const -{ - return (m_words.size() == 0); -} - - -/** Return the number of encoded-words in the list. - * - * @return number of encoded-words - */ - -const size_t text::count() const -{ - return (m_words.size()); -} - - -/** Return the number of encoded-words in the list. - * - * @return number of encoded-words - */ - -const size_t text::size() const -{ - return (m_words.size()); -} - - -/** Return the first encoded-word of the list. - * - * @return first encoded-word - */ - -word& text::front() -{ - return (*m_words.front()); -} - - -/** Return the first encoded-word of the list. - * - * @return first encoded-word - */ - -const word& text::front() const -{ - return (*m_words.front()); -} - - -/** Return the last encoded-word of the list. - * - * @return last encoded-word - */ - -word& text::back() -{ - return (*m_words.back()); -} - - -/** Return the last encoded-word of the list. - * - * @return last encoded-word - */ - -const word& text::back() const -{ - return (*m_words.back()); -} - - } // vmime diff --git a/src/text.hpp b/src/text.hpp index e6339ab9..437b74f0 100644 --- a/src/text.hpp +++ b/src/text.hpp @@ -29,11 +29,10 @@ namespace vmime { -/** A class representing a list of encoded-words, as defined - * in RFC-2047 (basic type). +/** List of encoded-words, as defined in RFC-2047 (basic type). */ -class text +class text : public component { public: @@ -46,125 +45,129 @@ public: public: - text& operator=(const text& t); - const bool operator==(const text& t) const; const bool operator!=(const text& t) const; - // Words iterator - class const_iterator; + text* clone() const; + void copyFrom(const component& other); + text& operator=(const component& other); + text& operator=(const text& other); - class iterator - { - friend class text::const_iterator; - friend class text; + /** Add a word at the end of the list. + * + * @param w word to append + */ + void appendWord(word* w); - public: + /** Insert a new word before the specified position. + * + * @param pos position at which to insert the new word (0 to insert at + * the beginning of the list) + * @param w word to insert + */ + void insertWordBefore(const int pos, word* w); - typedef std::vector ::iterator::difference_type difference_type; + /** Insert a new word after the specified position. + * + * @param pos position of the word before the new word + * @param w word to insert + */ + void insertWordAfter(const int pos, word* w); - iterator(std::vector ::iterator it) : m_iterator(it) { } - iterator(const iterator& it) : m_iterator(it.m_iterator) { } + /** Remove the word at the specified position. + * + * @param pos position of the word to remove + */ + void removeWord(const int pos); - iterator& operator=(const iterator& it) { m_iterator = it.m_iterator; return (*this); } + /** Remove all words from the list. + */ + void removeAllWords(); - word& operator*() const { return (**m_iterator); } - word* operator->() const { return (*m_iterator); } + /** Return the number of words in the list. + * + * @return number of words + */ + const int getWordCount() const; - iterator& operator++() { ++m_iterator; return (*this); } - iterator operator++(int) { iterator i(*this); ++m_iterator; return (i); } + /** Tests whether the list of words is empty. + * + * @return true if there is no word, false otherwise + */ + const bool isEmpty() const; - iterator& operator--() { --m_iterator; return (*this); } - iterator operator--(int) { iterator i(*this); --m_iterator; return (i); } + /** Return the word at the specified position. + * + * @param pos position + * @return word at position 'pos' + */ + word* getWordAt(const int pos); - iterator& operator+=(difference_type n) { m_iterator += n; return (*this); } - iterator& operator-=(difference_type n) { m_iterator -= n; return (*this); } + /** Return the word at the specified position. + * + * @param pos position + * @return word at position 'pos' + */ + const word* const getWordAt(const int pos) const; - iterator operator+(difference_type x) const { return iterator(m_iterator + x); } - iterator operator-(difference_type x) const { return iterator(m_iterator - x); } + /** Return the word list. + * + * @return list of words + */ + const std::vector getWordList() const; - word& operator[](difference_type n) const { return *(m_iterator[n]); } - - const bool operator==(const iterator& it) const { return (it.m_iterator == m_iterator); } - const bool operator!=(const iterator& it) const { return (!(*this == it)); } - - protected: - - std::vector ::iterator m_iterator; - }; - - class const_iterator - { - public: - - typedef std::vector ::const_iterator::difference_type difference_type; - - const_iterator(std::vector ::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 word& operator*() const { return (**m_iterator); } - const word* 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_iterator operator-(difference_type x) const { return const_iterator(m_iterator - x); } - - const word& 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 ::const_iterator m_iterator; - }; - - - iterator begin() { return (m_words.begin()); } - iterator end() { return (m_words.end()); } - - const_iterator begin() const { return (const_iterator(m_words.begin())); } - const_iterator end() const { return (const_iterator(m_words.end())); } - - const word& operator[](const std::vector ::size_type x) const { return (*m_words[x]); } - word& operator[](const std::vector ::size_type x) { return (*m_words[x]); } - - // Word manipulation - void append(const word& w); - void insert(const iterator it, const word& w); - - void clear(); - void remove(const iterator it); - - // Word count - const bool empty() const; - const size_t count() const; - const size_t size() const; - - word& front(); - const word& front() const; - word& back(); - const word& back() const; + /** Return the word list. + * + * @return list of words + */ + const std::vector getWordList(); // Decoding #if VMIME_WIDE_CHAR_SUPPORT const wstring getDecodedText() const; #endif + + /** Return the text converted into the specified charset. + * The encoded-words are decoded and then converted in the + * specified destination charset. + * + * @param dest output charset + * @return text decoded in the specified charset + */ const string getConvertedText(const charset& dest) const; -protected: + /** 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. + * + *

Eg: giving:

+ *
   <iso-8859-1> "Linux dans un t'el'ephone mobile"
+	  *    ("=?iso-8859-1?Q?Linux_dans_un_t=E9l=E9phone_mobile?=")
+	  * 

it will return:

+ *
   <: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")
+	  * 
+ * + * @param in input string + * @param ch input charset + * @param generateInExisting if not NULL, the resulting text will be generated + * in the specified object instead of a new created object (in this case, the + * function returns the same pointer). Can be used to avoid copying the + * resulting object into an existing object. + * @return new text object or existing object if generateInExisting != NULL + */ + static text* newFromString(const string& in, const charset& ch, text* generateInExisting = NULL); + + + using component::parse; + using component::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; + +private: std::vector m_words; }; diff --git a/src/textField.cpp b/src/textField.cpp deleted file mode 100644 index 0a316af9..00000000 --- a/src/textField.cpp +++ /dev/null @@ -1,69 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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 "textField.hpp" - - -namespace vmime -{ - - -textField::textField() -{ -} - - -void textField::parse(const string& buffer, const string::size_type position, - const string::size_type end, string::size_type* newPosition) -{ - decodeAndUnfoldText(buffer.begin() + position, buffer.begin() + end, m_text); - - if (newPosition) - *newPosition = end; -} - - -void textField::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, m_text, maxLineLength, pos, newLinePos, encodeAndFoldFlags::none); -} - - -void textField::copyFrom(const headerField& field) -{ - const textField& source = dynamic_cast(field); - m_text = source.m_text; - - headerField::copyFrom(field); -} - - -textField& textField::operator=(const text& value) -{ - m_text = value; - return (*this); -} - - -} // vmime diff --git a/src/textField.hpp b/src/textField.hpp deleted file mode 100644 index 1e672202..00000000 --- a/src/textField.hpp +++ /dev/null @@ -1,70 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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_TEXTFIELD_HPP_INCLUDED -#define VMIME_TEXTFIELD_HPP_INCLUDED - - -#include "base.hpp" -#include "component.hpp" - -#include "headerFieldFactory.hpp" -#include "text.hpp" - - -namespace vmime -{ - - -class textField : public headerField -{ - friend class headerFieldFactory::registerer ; - -protected: - - textField(); - -public: - - void copyFrom(const headerField& field); - - textField& operator=(const text& value); - - const text& value() const { return (m_text); } - text& value() { return (m_text); } - -protected: - - text 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_TEXTFIELD_HPP_INCLUDED diff --git a/src/textParameter.cpp b/src/textParameter.cpp deleted file mode 100644 index 402d8d1f..00000000 --- a/src/textParameter.cpp +++ /dev/null @@ -1,50 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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 "textParameter.hpp" -#include "parserHelpers.hpp" - - -namespace vmime -{ - - -void textParameter::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 textParameter::generateValue() const -{ - return (m_value); -} - - -void textParameter::copyFrom(const parameter& param) -{ - const textParameter& source = dynamic_cast(param); - m_value = source.m_value; - - defaultParameter::copyFrom(param); -} - - -} // vmime diff --git a/src/textParameter.hpp b/src/textParameter.hpp deleted file mode 100644 index a3332a84..00000000 --- a/src/textParameter.hpp +++ /dev/null @@ -1,54 +0,0 @@ -// -// VMime library (http://vmime.sourceforge.net) -// Copyright (C) 2002-2004 Vincent Richard -// -// 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_TEXTPARAMETER_HPP_INCLUDED -#define VMIME_TEXTPARAMETER_HPP_INCLUDED - - -#include "defaultParameter.hpp" - - -namespace vmime -{ - - -class textParameter : public defaultParameter -{ -protected: - - string m_value; - -public: - - void copyFrom(const parameter& param); - - const string& value() const { return (m_value); } - string& 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_TEXTPARAMETER_HPP_INCLUDED diff --git a/src/textPart.hpp b/src/textPart.hpp index ed07f0b7..412493d3 100644 --- a/src/textPart.hpp +++ b/src/textPart.hpp @@ -32,6 +32,9 @@ namespace vmime { +/** Generic text part. + */ + class textPart { friend class textPartFactory; @@ -42,14 +45,37 @@ public: virtual ~textPart() { } + /** Return the type of text part (eg: "text/html"). + * + * @return type of text part + */ + virtual const mediaType getType() const = 0; - virtual const mediaType type() const = 0; + /** Return the charset used to encode text in the + * text part. + * + * @return text charset + */ + virtual const charset& getCharset() const = 0; - virtual const class charset& charset() const = 0; - virtual class charset& charset() = 0; + /** Set the charset used to encode text in the + * text part. + * + * @param ch text charset + */ + virtual void setCharset(const charset& ch) = 0; - virtual const contentHandler& text() const = 0; - virtual contentHandler& text() = 0; + /** Return the text contained in the part. + * + * @return text of the part + */ + virtual const contentHandler& getText() const = 0; + + /** Set the text contained in the part. + * + * @param text text of the part + */ + virtual void setText(const contentHandler& text) = 0; protected: diff --git a/src/textPartFactory.hpp b/src/textPartFactory.hpp index 15969c93..d55d9dd5 100644 --- a/src/textPartFactory.hpp +++ b/src/textPartFactory.hpp @@ -61,7 +61,7 @@ public: template void registerType(const mediaType& type) { - m_nameMap.insert(NameMap::value_type(toLower(type.generate()), ®isterer::creator)); + m_nameMap.insert(NameMap::value_type(type.generate(), ®isterer::creator)); } textPart* create(const mediaType& type); diff --git a/src/typeAdapter.hpp b/src/typeAdapter.hpp new file mode 100644 index 00000000..1e67ab33 --- /dev/null +++ b/src/typeAdapter.hpp @@ -0,0 +1,119 @@ +// +// VMime library (http://vmime.sourceforge.net) +// Copyright (C) 2002-2004 Vincent Richard +// +// 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_TYPEADAPTER_HPP_INCLUDED +#define VMIME_TYPEADAPTER_HPP_INCLUDED + + +#include + +#include "component.hpp" + + +namespace vmime +{ + + +template +class typeAdapter : public component +{ +public: + + typeAdapter() + { + } + + typeAdapter(typeAdapter& a) + : m_value(a.m_value) + { + } + + typeAdapter(const TYPE& v) + : m_value(v) + { + } + + + typeAdapter* clone() const + { + return new typeAdapter(*this); + } + + + void copyFrom(const component& other) + { + m_value = dynamic_cast &>(other).m_value; + } + + + typeAdapter& operator=(const TYPE& v) + { + m_value = v; + return (*this); + } + + + typeAdapter& operator=(const component& other) + { + copyFrom(other); + return (*this); + } + + + operator TYPE() const + { + return (m_value); + } + + + void parse(const string& buffer, const string::size_type position, + const string::size_type end, string::size_type* newPosition = NULL) + { + std::istringstream iss(string(buffer.begin() + position, buffer.begin() + end)); + iss >> m_value; + + if (newPosition) + *newPosition = end; + } + + + void generate(utility::outputStream& os, + const string::size_type /* maxLineLength */ = lineLengthLimits::infinite, + const string::size_type curLinePos = 0, + string::size_type* newLinePos = NULL) const + { + std::ostringstream oss; + oss << m_value; + + os << oss.str(); + + if (newLinePos) + *newLinePos = curLinePos + oss.str().length(); + } + +private: + + TYPE m_value; +}; + + +} // vmime + + +#endif // VMIME_TYPEADAPTE_HPP_INCLUDED diff --git a/src/types.hpp b/src/types.hpp index fa37c6dc..7f20ce8a 100644 --- a/src/types.hpp +++ b/src/types.hpp @@ -21,8 +21,8 @@ #define VMIME_TYPES_HPP_INCLUDED -#include #include +#include #include "config.hpp" diff --git a/src/utility/path.cpp b/src/utility/path.cpp index 477f29dd..88ad00e5 100644 --- a/src/utility/path.cpp +++ b/src/utility/path.cpp @@ -86,11 +86,11 @@ path& path::operator/=(const component& c) } -path path::parent() const +path path::getParent() const { path p; - if (!empty()) + if (!isEmpty()) { p.m_list.resize(m_list.size() - 1); std::copy(m_list.begin(), m_list.end() - 1, p.m_list.begin()); @@ -130,7 +130,7 @@ const bool path::operator==(const path& p) const for ( ; equal && i != m_list.end() ; ++i, ++j) //equal = (*i == *j); - equal = ((*i).buffer() == (*j).buffer()); + equal = ((*i).getBuffer() == (*j).getBuffer()); return (equal); } @@ -142,25 +142,25 @@ const bool path::operator!=(const path& p) const } -const bool path::empty() const +const bool path::isEmpty() const { return (m_list.empty()); } -const path::component path::last() const +const path::component path::getLastComponent() const { - return (empty() ? component("") : m_list[m_list.size() - 1]); + return (isEmpty() ? component("") : m_list[m_list.size() - 1]); } -path::component& path::last() +path::component& path::getLastComponent() { return (m_list[m_list.size() - 1]); } -const int path::size() const +const int path::getSize() const { return (m_list.size()); } @@ -180,12 +180,12 @@ path::component& path::operator[](const int x) const bool path::isDirectParentOf(const path& p) const { - if (p.size() != size() + 1) + if (p.getSize() != getSize() + 1) return (false); bool equal = true; - for (int i = 0 ; equal && i < size() ; ++i) + for (list::size_type i = 0 ; equal && i < m_list.size() ; ++i) equal = (m_list[i] == p.m_list[i]); return (equal); diff --git a/src/utility/path.hpp b/src/utility/path.hpp index bc980889..8a05f1a2 100644 --- a/src/utility/path.hpp +++ b/src/utility/path.hpp @@ -55,7 +55,7 @@ public: path& operator/=(const component& c); // Return the parent path - path parent() const; + path getParent() const; // Assignment path& operator=(const path& p); @@ -69,25 +69,25 @@ public: * * @return true if the path is empty (no components = root) */ - const bool empty() const; + const bool isEmpty() const; /** Return the last component of this path (const version). * * @return last component */ - const component last() const; + const component getLastComponent() const; /** Return the last component of this path (non-const version). * * @return last component */ - component& last(); + component& getLastComponent(); /** Return the number of components in this path. * * @return number of components */ - const int size() const; + const int getSize() const; /** Return the specified component of the path (const version). * diff --git a/src/utility/random.cpp b/src/utility/random.cpp index 6896d83c..b2a935d8 100644 --- a/src/utility/random.cpp +++ b/src/utility/random.cpp @@ -30,7 +30,7 @@ namespace utility { unsigned int random::m_next(static_cast(::std::time(NULL))); -const unsigned int random::next() +const unsigned int random::getNext() { // Park and Miller's minimal standard generator: // xn+1 = (a * xn + b) mod c @@ -43,13 +43,13 @@ const unsigned int random::next() } -const unsigned int random::time() +const unsigned int random::getTime() { return (platformDependant::getHandler()->getUnixTime()); } -const unsigned int random::process() +const unsigned int random::getProcess() { return (platformDependant::getHandler()->getProcessId()); } diff --git a/src/utility/random.hpp b/src/utility/random.hpp index 0d9dd92a..70ae6716 100644 --- a/src/utility/random.hpp +++ b/src/utility/random.hpp @@ -25,6 +25,9 @@ namespace vmime { namespace utility { +/** Pseudo-random number generator. + */ + class random { public: @@ -33,21 +36,21 @@ public: * * @return random number */ - static const unsigned int next(); + static const unsigned int getNext(); /** Return the current time as a number (may be used to * build "random" strings). * * @return time as a number */ - static const unsigned int time(); + static const unsigned int getTime(); /** Return the current process number (may be user to * build "random" strings). * * @return process number */ - static const unsigned int process(); + static const unsigned int getProcess(); protected: diff --git a/src/utility/stringUtils.cpp b/src/utility/stringUtils.cpp new file mode 100644 index 00000000..937eb99d --- /dev/null +++ b/src/utility/stringUtils.cpp @@ -0,0 +1,122 @@ +// +// VMime library (http://vmime.sourceforge.net) +// Copyright (C) 2002-2004 Vincent Richard +// +// 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 "stringUtils.hpp" + + +namespace vmime +{ + + +const bool stringUtils::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); +} + + +const bool stringUtils::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); +} + + +const bool stringUtils::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(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); +} + + +const string stringUtils::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); +} + + +const string stringUtils::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)); +} + + +const string::size_type stringUtils::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); +} + + +} // vmime diff --git a/src/utility/stringUtils.hpp b/src/utility/stringUtils.hpp new file mode 100644 index 00000000..617874f0 --- /dev/null +++ b/src/utility/stringUtils.hpp @@ -0,0 +1,131 @@ +// +// VMime library (http://vmime.sourceforge.net) +// Copyright (C) 2002-2004 Vincent Richard +// +// 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_STRINGUTILS_HPP_INCLUDED +#define VMIME_STRINGUTILS_HPP_INCLUDED + + +#include "../types.hpp" +#include "../base.hpp" + +#include + + +namespace vmime +{ + + +/** Miscellaneous functions related to strings. + */ + +class stringUtils +{ +public: + + /** 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 + */ + static const bool isStringEqualNoCase(const string& s1, const char* s2, const string::size_type n); + + /** 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 + */ + static const bool isStringEqualNoCase(const string& s1, const string& s2); + + /** 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 + */ + static const bool isStringEqualNoCase(const string::const_iterator begin, const string::const_iterator end, const char* s, const string::size_type n); + + /** 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 + */ + static const string toLower(const string& str); + + /** 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 + */ + static const string trim(const string& str); + + /** 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 + */ + static const string::size_type countASCIIchars(const string::const_iterator begin, const string::const_iterator end); + + /** Convert the specified value to a string value. + * + * @param value to convert + * @return value converted from type 'TYPE' + */ + template + static const string toString(const TYPE& value) + { + std::ostringstream oss; + oss << value; + + return (oss.str()); + } + + /** Convert the specified string value to a value of + * the specified type. + * + * @param value value to convert + * @return value converted into type 'TYPE' + */ + template + static const TYPE fromString(const string& value) + { + TYPE ret; + + std::istringstream iss(value); + iss >> ret; + + return (ret); + } +}; + + +} // vmime + + +#endif // VMIME_STRINGUTILS_HPP_INCLUDED diff --git a/src/vmime b/src/vmime index 4953d8fd..e837093d 100644 --- a/src/vmime +++ b/src/vmime @@ -44,6 +44,7 @@ #include "addressList.hpp" #include "mediaType.hpp" #include "messageId.hpp" +#include "relay.hpp" // Message components #include "message.hpp" @@ -51,10 +52,8 @@ // Header fields #include "headerFieldFactory.hpp" #include "mailboxField.hpp" -#include "defaultField.hpp" -#include "addressListField.hpp" #include "parameterizedHeaderField.hpp" -#include "relayField.hpp" +#include "standardFields.hpp" // Encoders #include "encoderFactory.hpp" diff --git a/src/word.cpp b/src/word.cpp index 6578ec5f..6c213f5a 100644 --- a/src/word.cpp +++ b/src/word.cpp @@ -42,7 +42,7 @@ word::word(const string& buffer) // Defaults to locale charset } -word::word(const string& buffer, const class charset& charset) +word::word(const string& buffer, const charset& charset) : m_buffer(buffer), m_charset(charset) { } @@ -77,6 +77,13 @@ word& word::operator=(const string& s) } +void word::copyFrom(const word& w) +{ + m_buffer = w.m_buffer; + m_charset = w.m_charset; +} + + const bool word::operator==(const word& w) const { return (m_charset == w.m_charset && m_buffer == w.m_buffer); @@ -89,7 +96,7 @@ const bool word::operator!=(const word& w) const } -const string word::getConvertedText(const class charset& dest) const +const string word::getConvertedText(const charset& dest) const { string out; @@ -99,4 +106,40 @@ const string word::getConvertedText(const class charset& dest) const } +word* word::clone() const +{ + return new word(m_buffer, m_charset); +} + + +const charset& word::getCharset() const +{ + return (m_charset); +} + + +void word::setCharset(const charset& ch) +{ + m_charset = ch; +} + + +const string& word::getBuffer() const +{ + return (m_buffer); +} + + +string& word::getBuffer() +{ + return (m_buffer); +} + + +void word::setBuffer(const string& buffer) +{ + m_buffer = buffer; +} + + } // vmime diff --git a/src/word.hpp b/src/word.hpp index e9321942..22f791ca 100644 --- a/src/word.hpp +++ b/src/word.hpp @@ -39,13 +39,37 @@ public: word(); word(const word& w); word(const string& buffer); // Defaults to locale charset - word(const string& buffer, const class charset& charset); + word(const string& buffer, const charset& charset); - const string& buffer() const { return (m_buffer); } - string& buffer() { return (m_buffer); } + /** Return the raw data for this encoded word. + * + * @return raw data buffer + */ + const string& getBuffer() const; - const class charset& charset() const { return (m_charset); } - class charset& charset() { return (m_charset); } + /** Return the raw data for this encoded word. + * + * @return raw data buffer + */ + string& getBuffer(); + + /** Set the raw data for this encoded word. + * + * @param buffer raw data buffer + */ + void setBuffer(const string& buffer); + + /** Return the charset of this word. + * + * @return charset for this word + */ + const charset& getCharset() const; + + /** Set the charset of this word. + * + * @param ch charset of this word + */ + void setCharset(const charset& ch); word& operator=(const word& w); @@ -57,14 +81,32 @@ public: #if VMIME_WIDE_CHAR_SUPPORT const wstring getDecodedText() const; #endif - const string getConvertedText(const class charset& dest) const; -protected: + /** Return the contained text converted to the specified charset. + * + * @param dest output charset + * @return word converted to the specified charset + */ + const string getConvertedText(const charset& dest) const; + + /** Replace data in this word by data in other word. + * + * @param other other word to copy data from + */ + void copyFrom(const word& other); + + /** Clone this word. + * + * @return a copy of this word + */ + word* clone() const; + +private: // The "m_buffer" of this word holds the data, and this data is encoded // in the specified "m_charset". string m_buffer; - class charset m_charset; + charset m_charset; }; diff --git a/tests/charset/main.cpp b/tests/charset/main.cpp index 5bf3a647..b7a91495 100644 --- a/tests/charset/main.cpp +++ b/tests/charset/main.cpp @@ -33,8 +33,8 @@ int main(int argc, char* argv[]) const vmime::string from(argv[1]); const vmime::string to(argv[2]); - vmime::inputStreamAdapter in(std::cin); - vmime::outputStreamAdapter out(std::cout); + vmime::utility::inputStreamAdapter in(std::cin); + vmime::utility::outputStreamAdapter out(std::cout); vmime::charset::convert(in, out, from, to); } diff --git a/tests/encoding/main.cpp b/tests/encoding/main.cpp index 78664f8a..597ef248 100644 --- a/tests/encoding/main.cpp +++ b/tests/encoding/main.cpp @@ -35,10 +35,10 @@ int main(int argc, char* argv[]) vmime::encoder* p = vmime::encoderFactory::getInstance()->create(encoding); - p->properties()["maxlinelength"] = 76; + p->getProperties()["maxlinelength"] = 76; - vmime::inputStreamAdapter in(std::cin); - vmime::outputStreamAdapter out(std::cout); + vmime::utility::inputStreamAdapter in(std::cin); + vmime::utility::outputStreamAdapter out(std::cout); if (mode == "e") p->encode(in, out); diff --git a/tests/mailbox/main.cpp b/tests/mailbox/main.cpp index 9f1de6ac..cd59d900 100644 --- a/tests/mailbox/main.cpp +++ b/tests/mailbox/main.cpp @@ -32,14 +32,14 @@ std::ostream& operator<<(std::ostream& os, const vmime::text& txt) { os << "["; - for (int i = 0 ; i < txt.size() ; ++i) + for (int i = 0 ; i < txt.getWordCount() ; ++i) { - const vmime::word& w = txt[i]; + const vmime::word& w = *txt.getWordAt(i); if (i != 0) os << ","; - os << "[" << w.charset().name() << "," << w.buffer() << "]"; + os << "[" << w.getCharset().getName() << "," << w.getBuffer() << "]"; } os << "]"; @@ -50,7 +50,7 @@ std::ostream& operator<<(std::ostream& os, const vmime::text& txt) std::ostream& operator<<(std::ostream& os, const vmime::mailbox& mbox) { - std::cout << "MAILBOX[name=" << mbox.name() << ",email=" << mbox.email() << "]" << std::endl; + std::cout << "MAILBOX[name=" << mbox.getName() << ",email=" << mbox.getEmail() << "]" << std::endl; return (os); } @@ -58,11 +58,11 @@ std::ostream& operator<<(std::ostream& os, const vmime::mailbox& mbox) std::ostream& operator<<(std::ostream& os, const vmime::mailboxGroup& group) { - std::cout << "GROUP[name=" << group.name() << "]" << std::endl; + std::cout << "GROUP[name=" << group.getName() << "]" << std::endl; - for (int i = 0 ; i < group.size() ; ++i) + for (int i = 0 ; i < group.getMailboxCount() ; ++i) { - std::cout << "* " << group[i]; + std::cout << "* " << *group.getMailboxAt(i); } return (os); @@ -97,9 +97,9 @@ int main(int argc, char* argv[]) vmime::addressList list; list.parse(data.str()); - for (int i = 0 ; i < list.size() ; ++i) + for (int i = 0 ; i < list.getAddressCount() ; ++i) { - const vmime::address& addr = list[i]; + const vmime::address& addr = *list.getAddressAt(i); if (addr.isGroup()) { diff --git a/tests/parser/headerTest.cpp b/tests/parser/headerTest.cpp index 90905c3e..13a8f03e 100644 --- a/tests/parser/headerTest.cpp +++ b/tests/parser/headerTest.cpp @@ -21,125 +21,40 @@ namespace return (oss.str()); } - // has function tests - void testHas1(/*By type*/) - { - vmime::header hdr; - hdr.parse("From: x\r\nTo: y\r\nSubject: test\r\n"); - - bool res = hdr.fields.has(vmime::headerField::To); - - assert_eq("Value", true, res); - } - - void testHas2(/*By type*/) - { - vmime::header hdr; - hdr.parse("From: x\r\nTo: y\r\nTo: z\r\n"); - - bool res = hdr.fields.has(vmime::headerField::Subject); - - assert_eq("Value", false, res); - } - - void testHas3(/*By name*/) - { - vmime::header hdr; - hdr.parse("From: x\r\nTo: y\r\nTo: z\r\n"); - - bool res = hdr.fields.has("Z"); - - assert_eq("Value", false, res); - } - - void testHas4(/*By name*/) - { - vmime::header hdr; - hdr.parse("X: x\r\nTo: y\r\nTo: z\r\n"); - - bool res = hdr.fields.has("To"); - - assert_eq("Value", true, res); - } - - // find function tests - void testFind1(/*By type*/) - { - vmime::header hdr; - hdr.parse("From: a\r\nTo: b\r\nTo: c\r\nFrom: d\r\n"); - - vmime::headerField& res = hdr.fields.find(vmime::headerField::To); - - assert_eq("Value", "To: b", getFieldValue(res)); - } - - void testFind2(/*By name*/) - { - vmime::header hdr; - hdr.parse("A: a\r\nB: b\r\nC: c\r\nB: d\r\n"); - - vmime::headerField& res = hdr.fields.find("B"); - - assert_eq("Value", "B: b", getFieldValue(res)); - } - - // findAllByType function tests - void testFindAllByType1() - { - vmime::header hdr; - hdr.parse("To: a\r\nFrom: b\r\n"); - - std::vector res = hdr.fields.findAllByType(vmime::headerField::Subject); - - assert_eq("Count", (unsigned int) 0, res.size()); - } - - void testFindAllByType2() - { - vmime::header hdr; - hdr.parse("To: b\r\nTo : a\r\nFrom: c\r\n"); - - std::vector res = hdr.fields.findAllByType(vmime::headerField::To); - - assert_eq("Count", (unsigned int) 2, res.size()); - assert_eq("First value", "To: b", getFieldValue(*res[0])); - assert_eq("First value", "To: a", getFieldValue(*res[1])); - } - - // findAllByName function tests - void testFindAllByName1() + // getAllByName function tests + void testFindAllFields1() { vmime::header hdr; hdr.parse("A: a1\nC: c1\n"); - std::vector res = hdr.fields.findAllByName("B"); + std::vector res = hdr.findAllFields("B"); assert_eq("Count", (unsigned int) 0, res.size()); } - void testFindAllByName2() + void testFindAllFields2() { vmime::header hdr; hdr.parse("A: a1\nB: b1\nB: b2\nC: c1\n"); - std::vector res = hdr.fields.findAllByName("B"); + std::vector res = hdr.findAllFields("B"); assert_eq("Count", (unsigned int) 2, res.size()); - assert_eq("First value", "B: b1", getFieldValue(*res[0])); - assert_eq("Second value", "B: b2", getFieldValue(*res[1])); + assert_eq("First value", "B: b1", headerTest::getFieldValue(*res[0])); + assert_eq("Second value", "B: b2", headerTest::getFieldValue(*res[1])); } - void testFindAllByName3() + void testFindAllFields3() { vmime::header hdr; hdr.parse("A: a1\nB: b1\nB: b2\nC: c1\nC: c3\nC: c2\n"); - std::vector res = hdr.fields.findAllByName("C"); + std::vector res = hdr.findAllFields("C"); assert_eq("Count", (unsigned int) 3, res.size()); - assert_eq("First value", "C: c1", getFieldValue(*res[0])); - assert_eq("Second value", "C: c3", getFieldValue(*res[1])); - assert_eq("Second value", "C: c2", getFieldValue(*res[2])); + assert_eq("First value", "C: c1", headerTest::getFieldValue(*res[0])); + assert_eq("Second value", "C: c3", headerTest::getFieldValue(*res[1])); + assert_eq("Second value", "C: c2", headerTest::getFieldValue(*res[2])); } public: @@ -149,21 +64,9 @@ namespace // VMime initialization vmime::platformDependant::setHandler(); - add("Has", testcase(this, "Has1", &headerTest::testHas1)); - add("Has", testcase(this, "Has2", &headerTest::testHas2)); - add("Has", testcase(this, "Has3", &headerTest::testHas3)); - add("Has", testcase(this, "Has4", &headerTest::testHas4)); - - add("Find", testcase(this, "Find1", &headerTest::testFind1)); - add("Find", testcase(this, "Find2", &headerTest::testFind2)); - - add("FindAllByType", testcase(this, "FindAllByType1", &headerTest::testFindAllByType1)); - add("FindAllByType", testcase(this, "FindAllByType2", &headerTest::testFindAllByType2)); - - add("FindAllByName", testcase(this, "FindAllByName1", &headerTest::testFindAllByName1)); - add("FindAllByName", testcase(this, "FindAllByName2", &headerTest::testFindAllByName2)); - add("FindAllByName", testcase(this, "FindAllByName3", &headerTest::testFindAllByName3)); - + add("FindAllFields", testcase(this, "FindAllFields1", &headerTest::testFindAllFields1)); + add("FindAllFields", testcase(this, "FindAllFields2", &headerTest::testFindAllFields2)); + add("FindAllFields", testcase(this, "FindAllFields3", &headerTest::testFindAllFields3)); suite::main().add("vmime::header", this); }