Code style and clarity.

This commit is contained in:
Vincent Richard 2018-09-05 23:54:48 +02:00
parent 71a0fa4b26
commit b55bdc9c0b
529 changed files with 25689 additions and 21810 deletions

94
HACKING
View File

@ -80,73 +80,91 @@ width to its preferred settings (eg. 4 or 8 spaces).
2.2. Brace position
-------------------
Open braces should always be at the beginning of the line after the statement
that begins the block. Contents of the brace should be indented by 1 tab.
Open braces should always be at the end of the line of the statement that
begins the block. Contents of the brace should be indented by 1 tab.
if (expr) {
if (expr)
{
do_something();
do_another_thing();
}
else
{
} else {
do_something_else();
}
In a function, the opening brace must always be followed by an empty line:
void header::appendField(const shared_ptr <headerField>& field) {
m_fields.push_back(field);
}
A function with few arguments:
bool header::hasField(const string& fieldName) const {
...
}
A function with more arguments:
void header::parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
...
}
2.3. "switch" statement
-----------------------
switch (expr)
{
case 0:
switch (expr) {
something;
break;
case 0:
case 1:
something;
break;
something_else;
break;
case 1:
case 2:
{
int var = 42;
another_thing;
break;
}
something_else;
break;
case 2: {
int var = 42;
another_thing;
break;
}
}
2.4. Single instruction
-----------------------
Omit braces around simple single-statement body:
Don't omit braces around simple single-statement body:
if (...)
if (...) {
something;
}
and not:
if (...)
{
something;
}
Except when body spans over multiple lines:
if (...)
{
something_too_long_for(
a_single_line);
}
2.5. Line length
----------------
Each line of text should not exceed 80 characters.
If possible, each line of text should not exceed 100 characters, except if
manual line wrapping breaks code clarity.
Exception: if a comment line contains an example command or a literal URL
longer than 100 characters, that line may be longer than 100 characters
@ -290,8 +308,8 @@ Where ever possible, place comments above the code instead of beside it.
Comments can be placed at the end of a line when one or more spaces follow.
Tabs should NOT be used to indent at the end of a line:
class myClass
{
class myClass {
private:
int m_member1; // first member
@ -322,8 +340,8 @@ the purpose of the functions/classes and the meaning of the parameters.
* No more than one class per file (except for inner classes).
* Put the inclusion for the class's header file as the first inclusion in
the implementation file.
* Put the #include for the class's header file first in the implementation
file.
* Put the copyright header at the top of each file.

View File

@ -46,17 +46,17 @@ use the function {\vcode vmime::make\_shared} instead of the {\vcode new}
operator.
\begin{lstlisting}[caption={Smarts pointers and creating objects}]
class myObject : public vmime::object
{
class myObject : public vmime::object {
public:
myObject(const vmime::string& name)
: m_name(name)
{
: m_name(name) {
}
void sayHello()
{
void sayHello() {
std::cout << "Hello " << m_name << std::endl;
}
@ -65,8 +65,8 @@ private:
vmime::string m_name;
};
int main()
{
int main() {
vmime::shared_ptr <myObject> obj =
vmime::make_shared <myObject>("world");
@ -105,12 +105,12 @@ directly or indirectly to itself). The following example illustrates a
typical problem of reference counting:
\begin{lstlisting}
class parent : public vmime::object
{
class parent : public vmime::object {
public:
void createChild(vmime::shared_ptr <child> c)
{
void createChild(vmime::shared_ptr <child> c) {
m_child = c;
}
@ -119,13 +119,13 @@ private:
vmime::shared_ptr <child> m_child;
};
class child : public vmime::object
{
class child : public vmime::object {
public:
child(vmime::shared_ptr <parent> p)
: m_parent(p)
{
: m_parent(p) {
}
private:
@ -133,8 +133,8 @@ private:
vmime::shared_ptr <parent> m_parent;
};
int main()
{
int main() {
vmime::shared_ptr <parent> p = vmime::make_shared <parent>();
vmime::shared_ptr <child> c = vmime::make_shared <child>();
@ -179,30 +179,31 @@ Following is an example code for catching VMime exceptions and writing error
messages to the console:
\begin{lstlisting}[caption={Catching VMime exceptions}]
std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
{
std::ostream& operator<<(std::ostream& os, const vmime::exception& e) {
os << "* vmime::exceptions::" << e.name() << std::endl;
os << " what = " << e.what() << std::endl;
// Recursively print all encapsuled exceptions
if (e.other() != NULL)
if (e.other() != NULL) {
os << *e.other();
}
return os;
}
...
try
{
try {
// ...some call to VMime...
}
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cerr << e; // VMime exception
}
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cerr << e.what(); // standard exception
}
\end{lstlisting}
@ -250,7 +251,8 @@ vmime::datetime d1("Sat, 08 Oct 2005 14:07:52 +0200");
vmime::datetime d2(
/* date */ 2005, vmime::datetime::OCTOBER, 8,
/* time */ 14, 7, 52,
/* zone */ vmime::datetime::GMT2);
/* zone */ vmime::datetime::GMT2
);
// Getting day of week
const int dow = d2.getWeekDay(); // 'dow' should be datetime::SATURDAY
@ -275,7 +277,8 @@ media type with:
\begin{lstlisting}
vmime::mediaType theType(
/* top-level type */ vmime::mediaTypes::IMAGE,
/* sub-type */ vmime::mediaTypes::IMAGE_JPEG);
/* sub-type */ vmime::mediaTypes::IMAGE_JPEG
);
// theType.getType() is "image"
// theType.getSubType() is "jpeg"
@ -594,8 +597,9 @@ std::ifstream* fileStream = new std::ifstream();
fileStream->open("/home/vincent/paris.jpg", std::ios::binary);
if (!*fileStream)
if (!*fileStream) {
// handle error
}
vmime::shared_ptr <utility::stream> dataStream =
vmime::make_shared <vmime::utility::inputStreamPointerAdapter>(fileStream);
@ -608,13 +612,12 @@ vmime::shared_ptr <contentHandler> data =
vmime::make_shared <vmime::streamContentHandler>(dataStream, 0);
// Now create the attachment
ref <vmime::attachment> att = vmime::make_shared <vmime::defaultAttachment>
(
/* attachment data */ data,
/* content type */ vmime::mediaType("image/jpeg"),
/* description */ vmime::text("Holiday photo"),
/* filename */ vmime::word("paris.jpg")
);
ref <vmime::attachment> att = vmime::make_shared <vmime::defaultAttachment>(
/* attachment data */ data,
/* content type */ vmime::mediaType("image/jpeg"),
/* description */ vmime::text("Holiday photo"),
/* filename */ vmime::word("paris.jpg")
);
\end{lstlisting}
You will see later that the {\vcode vmime::fileAttachment} class already
@ -647,10 +650,11 @@ vmime::shared_ptr <const vmime::contentHandler> cth = body->getContents();
// Then, extract and convert the contents
vmime::utility::outputStreamAdapter out(std::cout);
vmime::utility::charsetFilteredOutputStream fout
(/* source charset */ body->getCharset(),
vmime::utility::charsetFilteredOutputStream fout(
/* source charset */ body->getCharset(),
/* dest charset */ vmime::charset("utf-8"),
/* dest stream */ out);
/* dest stream */ out
);
cth->extract(fout);
@ -778,8 +782,8 @@ vmime::shared_ptr <vmime::utility::encoder::encoderFactory> ef =
std::cout << "Available encoders:" << std::endl;
for (int i = 0 ; i < ef->getEncoderCount() ; ++i)
{
for (int i = 0 ; i < ef->getEncoderCount() ; ++i) {
// Output encoder name
vmime::shared_ptr <const vmime::utility::encoder::encoderFactory::registeredEncoder>
enc = ef->getEncoderAt(i);
@ -792,8 +796,9 @@ for (int i = 0 ; i < ef->getEncoderCount() ; ++i)
std::vector <vmime::string> props = e->getAvailableProperties();
std::vector <vmime::string>::const_iterator it;
for (it = props.begin() ; it != props.end() ; ++it)
for (it = props.begin() ; it != props.end() ; ++it) {
std::cout << " - " << *it << std::endl;
}
\end{lstlisting}

View File

@ -55,7 +55,7 @@ General Public License\footnote{See Appendix \ref{appendix_license} and
\url{http://www.gnu.org/copyleft/gpl.html}} (GPL) version 3:
\begin{verbatim}
Copyright (C) 2002-2013 Vincent Richard
Copyright (C) 2002 Vincent Richard
VMime library is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@ -79,7 +79,7 @@ GNU Free Documentation
License\footnote{See \url{http://www.gnu.org/copyleft/fdl.html}} (FDL):
\begin{verbatim}
Copyright (C) 2004-2013 Vincent Richard
Copyright (C) 2004 Vincent Richard
Permission is granted to copy, distribute and/or modify
this document under the terms of the GNU Free Documentation

View File

@ -94,8 +94,8 @@ vmime::messageParser mp(msg);
std::cout << "Message has " << mp.getAttachmentCount()
<< " attachment(s)" << std::endl;
for (int i = 0 ; i < mp.getAttachmentCount() ; ++i)
{
for (int i = 0 ; i < mp.getAttachmentCount() ; ++i) {
vmime::shared_ptr <const vmime::attachment> att = mp.getAttachmentAt(i);
std::cout << " - " << att->getType().generate() << std::endl;
}
@ -104,13 +104,13 @@ for (int i = 0 ; i < mp.getAttachmentCount() ; ++i)
std::cout << "Message has " << mp.getTextPartCount()
<< " text part(s)" << std::endl;
for (int i = 0 ; i < mp.getTextPartCount() ; ++i)
{
for (int i = 0 ; i < mp.getTextPartCount() ; ++i) {
vmime::shared_ptr <const vmime::textPart> tp = mp.getTextPartAt(i);
// text/html
if (tp->getType().getSubType() == vmime::mediaTypes::TEXT_HTML)
{
if (tp->getType().getSubType() == vmime::mediaTypes::TEXT_HTML) {
vmime::shared_ptr <const vmime::htmlTextPart> htp =
vmime::dynamicCast <const vmime::htmlTextPart>(tp);
@ -118,18 +118,18 @@ for (int i = 0 ; i < mp.getTextPartCount() ; ++i)
// Plain text is in tp->getPlainText()
// Enumerate embedded objects
for (int j = 0 ; j < htp->getObjectCount() ; ++j)
{
for (int j = 0 ; j < htp->getObjectCount() ; ++j) {
vmime::shared_ptr <const vmime::htmlTextPart::embeddedObject> obj =
htp->getObjectAt(j);
// Identifier (Content-Id or Content-Location) is obj->getId()
// Object data is in obj->getData()
}
}
// text/plain or anything else
else
{
} else {
// Text is in tp->getText()
}
}
@ -172,8 +172,7 @@ hdr->appendField(subjectField);
vmime::shared_ptr <vmime::headerField> fromField =
hfFactory->create(vmime::fields::FROM);
fromField->setValue
(vmime::make_shared <vmime::mailbox>("me@vmime.org"));
fromField->setValue(vmime::make_shared <vmime::mailbox>("me@vmime.org"));
hdr->appendField(fromField);
// Append a 'To:' field
@ -190,8 +189,11 @@ toField->setValue(recipients);
hdr->appendField(toField);
// Set the body contents
bdy->setContents(vmime::make_shared <vmime::stringContentHandler>
("This is the text of your message..."));
bdy->setContents(
vmime::make_shared <vmime::stringContentHandler>(
"This is the text of your message..."
)
);
// Output raw message data to standard output
vmime::utility::outputStreamAdapter out(std::cout);
@ -207,19 +209,23 @@ previous example, using the {\vcode vmime::messageBuilder} object:
\begin{lstlisting}[caption={Building a simple message
using {\vcode vmime::messageBuilder}}]
try
{
try {
vmime::messageBuilder mb;
// Fill in some header fields and message body
mb.setSubject(vmime::text("Message subject"));
mb.setExpeditor(vmime::mailbox("me@vmime.org"));
mb.getRecipients().appendAddress
(vmime::make_shared <vmime::mailbox>("you@vmime.org"));
mb.getRecipients().appendAddress(
vmime::make_shared <vmime::mailbox>("you@vmime.org")
);
mb.getTextPart()->setCharset(vmime::charsets::ISO8859_15);
mb.getTextPart()->setText(vmime::make_shared <vmime::stringContentHandler>
("This is the text of your message..."));
mb.getTextPart()->setText(
vmime::make_shared <vmime::stringContentHandler>(
"This is the text of your message..."
)
);
// Message construction
vmime::shared_ptr <vmime::message> msg = mb.construct();
@ -227,15 +233,15 @@ try
// Output raw message data to standard output
vmime::utility::outputStreamAdapter out(std::cout);
msg->generate(out);
}
// VMime exception
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cerr << "vmime::exception: " << e.what() << std::endl;
}
// Standard exception
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cerr << "std::exception: " << e.what() << std::endl;
}
\end{lstlisting}
@ -250,17 +256,17 @@ previous example to attach a file to the message:
{\vcode vmime::messageBuilder}}]
// Create an attachment
vmime::shared_ptr <vmime::fileAttachment> att =
vmime::make_shared <vmime::fileAttachment>
(
/* full path to file */ "/home/vincent/paris.jpg",
/* content type */ vmime::mediaType("image/jpeg),
/* description */ vmime::text("My holidays in Paris")
vmime::make_shared <vmime::fileAttachment>(
/* full path to file */ "/home/vincent/paris.jpg",
/* content type */ vmime::mediaType("image/jpeg),
/* description */ vmime::text("My holidays in Paris")
);
// You can also set some infos about the file
att->getFileInfo().setFilename("paris.jpg");
att->getFileInfo().setCreationDate
(vmime::datetime("30 Apr 2003 14:30:00 +0200"));
att->getFileInfo().setCreationDate(
vmime::datetime("30 Apr 2003 14:30:00 +0200")
);
// Add this attachment to the message
mb.appendAttachment(att);
@ -283,14 +289,19 @@ using the {\vcode vmime::messageBuilder}}]
// Fill in some header fields
mb.setSubject(vmime::text("An HTML message"));
mb.setExpeditor(vmime::mailbox("me@vmime.org"));
mb.getRecipients().appendAddress
(vmime::make_shared <vmime::mailbox>("you@vmime.org"));
mb.getRecipients().appendAddress(
vmime::make_shared <vmime::mailbox>("you@vmime.org")
);
// Set the content-type to "text/html": a text part factory must be
// available for the type you are using. The following code will make
// the message builder construct the two text parts.
mb.constructTextPart(vmime::mediaType
(vmime::mediaTypes::TEXT, vmime::mediaTypes::TEXT_HTML));
mb.constructTextPart(
vmime::mediaType(
vmime::mediaTypes::TEXT,
vmime::mediaTypes::TEXT_HTML
)
);
// Set contents of the text parts; the message is available in two formats:
// HTML and plain text. The HTML format also includes an embedded image.
@ -306,12 +317,18 @@ const vmime::string id = textPart->addObject("<...image data...>",
// -- Set the text
textPart->setCharset(vmime::charsets::ISO8859_15);
textPart->setText(vmime::make_shared <vmime::stringContentHandler>
("This is the <b>HTML text</b>, and the image:<br/>"
"<img src=\"") + id + vmime::string("\"/>"));
textPart->setText(
vmime::make_shared <vmime::stringContentHandler>(
"This is the <b>HTML text</b>, and the image:<br/>"
"<img src=\"") + id + vmime::string("\"/>"
)
);
textPart->setPlainText(vmime::make_shared <vmime::stringContentHandler>
("This is the plain text."));
textPart->setPlainText(
vmime::make_shared <vmime::stringContentHandler>(
"This is the plain text."
)
);
\end{lstlisting}
This will create a message having the following structure:
@ -336,11 +353,18 @@ vmime::shared_ptr <vmime::utility::file> imageFile =
fs->create(fs->stringToPath("/path/to/image.jpg"));
vmime::shared_ptr <vmime::contentHandler> imageCts =
vmime::make_shared <vmime::streamContentHandler>
(imageFile->getFileReader()->getInputStream(), imageFile->getLength());
vmime::make_shared <vmime::streamContentHandler>(
imageFile->getFileReader()->getInputStream(),
imageFile->getLength()
);
const vmime::string cid = textPart.addObject(imageCts,
vmime::mediaType(vmime::mediaTypes::IMAGE, vmime::mediaTypes::IMAGE_JPEG));
const vmime::string cid = textPart.addObject(
imageCts,
vmime::mediaType(
vmime::mediaTypes::IMAGE,
vmime::mediaTypes::IMAGE_JPEG
)
);
\end{lstlisting}
@ -361,8 +385,8 @@ extract its contents to the standard output:
\begin{lstlisting}[caption={Testing if a body part is an attachment}]
vmime::shared_ptr <vmime::bodyPart> part; // suppose we have a body part
if (vmime::attachmentHelper::isBodyPartAnAttachment(part))
{
if (vmime::attachmentHelper::isBodyPartAnAttachment(part)) {
// The body part contains an attachment, get it
vmime::shared_ptr <const vmime::attachment> attach =
attachmentHelper::getBodyPartAttachment(part);
@ -394,11 +418,10 @@ vmime::shared_ptr <vmime::message> msg; // suppose we have a message
// Create an attachment
vmime::shared_ptr <vmime::fileAttachment> att =
vmime::make_shared <vmime::fileAttachment>
(
/* full path to file */ "/home/vincent/paris.jpg",
/* content type */ vmime::mediaType("image/jpeg),
/* description */ vmime::text("My holidays in Paris")
vmime::make_shared <vmime::fileAttachment>(
/* full path to file */ "/home/vincent/paris.jpg",
/* content type */ vmime::mediaType("image/jpeg),
/* description */ vmime::text("My holidays in Paris")
);
// Attach it to the message

View File

@ -300,10 +300,10 @@ The following example shows how to use a custom authenticator to request
the user to enter her/his credentials:
\begin{lstlisting}[caption={A simple interactive authenticator}]
class myAuthenticator : public vmime::security::defaultAuthenticator
{
const string getUsername() const
{
class myAuthenticator : public vmime::security::defaultAuthenticator {
const string getUsername() const {
std::cout << "Enter your username: " << std::endl;
vmime::string res;
@ -312,8 +312,8 @@ class myAuthenticator : public vmime::security::defaultAuthenticator
return res;
}
const string getPassword() const
{
const string getPassword() const {
std::cout << "Enter your password: " << std::endl;
vmime::string res;
@ -331,9 +331,10 @@ This is how to use it:
vmime::shared_ptr <vmime::net::session> sess = vmime::net::session::create();
// Next, initialize a service which will use our authenticator
vmime::shared_ptr <vmime::net::store> st =
sess->getStore(vmime::utility::url("imap://imap.example.com"),
/* use our authenticator */ vmime::make_shared <myAuthenticator>());
vmime::shared_ptr <vmime::net::store> st = sess->getStore(
vmime::utility::url("imap://imap.example.com"),
/* use our authenticator */ vmime::make_shared <myAuthenticator>()
);
\end{lstlisting}
\vnote{An authenticator object should be used with one and only one service
@ -354,14 +355,15 @@ use the SASL-specific methods {\vcode getAcceptableMechanisms()} and
implementation of an SASL authenticator.
\begin{lstlisting}[caption={A simple SASL authenticator}]
class mySASLAuthenticator : public vmime::security::sasl::defaultSASLAuthenticator
{
class mySASLAuthenticator : public vmime::security::sasl::defaultSASLAuthenticator {
typedef vmime::security::sasl::SASLMechanism mechanism; // save us typing
const std::vector <vmime::shared_ptr <mechanism> > getAcceptableMechanisms
(const std::vector <vmime::shared_ptr <mechanism> >& available,
const vmime::shared_ptr <mechanism>& suggested) const
{
const std::vector <vmime::shared_ptr <mechanism> > getAcceptableMechanisms(
const std::vector <vmime::shared_ptr <mechanism> >& available,
const vmime::shared_ptr <mechanism>& suggested
) const {
// Here, you can sort the SASL mechanisms in the order they will be
// tried. If no SASL mechanism is acceptable (ie. for example, not
// enough secure), you can return an empty list.
@ -372,8 +374,8 @@ class mySASLAuthenticator : public vmime::security::sasl::defaultSASLAuthenticat
getAcceptableMechanisms(available, suggested);
}
void setSASLMechanism(const vmime::shared_ptr <mechanism>& mech)
{
void setSASLMechanism(const vmime::shared_ptr <mechanism>& mech) {
// This is called when the authentication process is going to
// try the specified mechanism.
//
@ -435,7 +437,8 @@ tr->send(
/* expeditor */ from,
/* recipient(s) */ to,
/* data */ is,
/* total length */ msgData.length());
/* total length */ msgData.length()
);
// We have finished using the service
tr->disconnect();
@ -556,22 +559,26 @@ std::vector <ref <vmime::net::message> > allMessages =
folder->getMessages(vmime::net::messageSet::byNumber(1, -1));
// -1 is a special value to mean "the number of the last message in the folder"
folder->fetchMessages(allMessages,
folder->fetchMessages(
allMessages,
vmime::net::fetchAttributes::FLAGS |
vmime::net::fetchAttributes::ENVELOPE);
vmime::net::fetchAttributes::ENVELOPE
);
for (unsigned int i = 0 ; i < allMessages.size() ; ++i) {
for (unsigned int i = 0 ; i < allMessages.size() ; ++i)
{
vmime::shared_ptr <vmime::net::message> msg = allMessages[i];
const int flags = msg->getFlags();
std::cout << "Message " << i << ":" << std::endl;
if (flags & vmime::net::message::FLAG_SEEN)
if (flags & vmime::net::message::FLAG_SEEN) {
std::cout << " - is read" << std::endl;
if (flags & vmime::net::message::FLAG_DELETED)
}
if (flags & vmime::net::message::FLAG_DELETED) {
std::cout << " - is deleted" << std::endl;
}
vmime::shared_ptr <const vmime::header> hdr = msg->getHeader();
@ -698,8 +705,8 @@ running.
An interface called {\vcode timeoutHandler} is provided:
\begin{lstlisting}
class timeoutHandler : public object
{
class timeoutHandler : public object {
/** Called to test if the time limit has been reached.
*
* @return true if the timeout delay is elapsed
@ -738,27 +745,27 @@ is thrown.
The following example shows how to implement a simple timeout handler:
\begin{lstlisting}[caption={Implementing a simple timeout handler}]
class myTimeoutHandler : public vmime::net::timeoutHandler
{
class myTimeoutHandler : public vmime::net::timeoutHandler {
public:
myTimeoutHandler()
{
myTimeoutHandler() {
m_startTime = time(NULL);
}
const bool isTimeOut()
{
return (time(NULL) >= m_startTime + 30); // 30 seconds timeout
const bool isTimeOut() {
return time(NULL) >= m_startTime + 30; // 30 seconds timeout
}
void resetTimeOut()
{
void resetTimeOut() {
m_startTime = time(NULL);
}
const bool handleTimeOut()
{
const bool handleTimeOut() {
std::cout << "Operation timed out." << std::endl;
<< "Press [Y] to continue, or [N] to "
<< "cancel the operation." << std::endl;
@ -766,7 +773,7 @@ public:
std::string response;
std::cin >> response;
return (response == "y" || response == "Y");
return response == "y" || response == "Y";
}
private:
@ -781,12 +788,12 @@ is required because the service can use several connections to the server
simultaneously, and each connection needs its own timeout handler.
\begin{lstlisting}
class myTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory
{
class myTimeoutHandlerFactory : public vmime::net::timeoutHandlerFactory {
public:
ref <timeoutHandler> create()
{
ref <timeoutHandler> create() {
return vmime::make_shared <myTimeoutHandler>();
}
};
@ -918,13 +925,12 @@ First, we need some code to load existing X.509 certificates:
\begin{lstlisting}[caption={Reading a X.509 certificate from a file}]
vmime::shared_ptr <vmime::security::cert::X509Certificate>
loadX509CertificateFromFile(const std::string& path)
{
loadX509CertificateFromFile(const std::string& path) {
std::ifstream certFile;
certFile.open(path.c_str(), std::ios::in | std::ios::binary);
if (!certFile)
{
if (!certFile) {
// ...handle error...
}
@ -978,12 +984,12 @@ use this in a production application as this is obviously a serious security
issue):
\begin{lstlisting}[caption={A custom certificate verifier}]
class myCertVerifier : public vmime::security::cert::certificateVerifier
{
class myCertVerifier : public vmime::security::cert::certificateVerifier {
public:
void verify(const vmime::shared_ptr <certificateChain>& certs)
{
void verify(const vmime::shared_ptr <certificateChain>& certs) {
// Obtain the subject's certificate
vmime::shared_ptr <vmime::security::cert::certificate> cert = chain->getAt(0);
@ -996,8 +1002,9 @@ public:
std::string answer;
std::getline(std::cin, answer);
if (answer.length() != 0 && (answer[0] == 'Y' || answer[0] == 'y'))
if (answer.length() != 0 && (answer[0] == 'Y' || answer[0] == 'y')) {
return; // OK, we trust the certificate
}
// Don't trust this certificate
throw vmime::security::cert::certificateException();
@ -1092,25 +1099,26 @@ First, you have to create your own tracer, which must implement the
simply logs to the standard output:
\begin{lstlisting}[caption={A simple tracer}]
class myTracer : public vmime::net::tracer
{
class myTracer : public vmime::net::tracer {
public:
myTracer(const vmime::string& proto, const int connectionId)
: m_proto(proto), m_connectionId(connectionId)
{
: m_proto(proto),
m_connectionId(connectionId) {
}
// Called by VMime to trace what is sent on the socket
void traceSend(const vmime::string& line)
{
void traceSend(const vmime::string& line) {
std::cout << "[" << m_proto << ":" << m_connectionId
<< "] C: " << line << std::endl;
}
// Called by VMime to trace what is received from the socket
void traceReceive(const vmime::string& line)
{
void traceReceive(const vmime::string& line) {
std::cout << "[" < < m_proto << ":" << m_connectionId
<< "] S: " << line << std::endl;
}
@ -1125,16 +1133,18 @@ private:
Also create a factory class, used to instanciate your tracer objects:
\begin{lstlisting}
class myTracerFactory : public vmime::net::tracerFactory
{
class myTracerFactory : public vmime::net::tracerFactory {
public:
vmime::shared_ptr <vmime::net::tracer> create
(const vmime::shared_ptr <vmime::net::service>& serv,
const int connectionId)
{
return vmime::make_shared <myTracer>
(serv->getProtocolName(), connectionId);
vmime::shared_ptr <vmime::net::tracer> create(
const vmime::shared_ptr <vmime::net::service>& serv,
const int connectionId
) {
return vmime::make_shared <myTracer>(
serv->getProtocolName(), connectionId
);
}
};
\end{lstlisting}

View File

@ -82,8 +82,8 @@ So, if your platform is POSIX, your program should look like this:
#include <vmime/vmime.hpp>
#include <vmime/platforms/posix/posixHandler.hpp>
int main()
{
int main() {
vmime::platform::
setHandler <vmime::platforms::posix::posixHandler>();

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -39,23 +39,20 @@
#include "vmime/platforms/posix/posixHandler.hpp"
int main()
{
int main() {
std::cout << std::endl;
// Set the global C and C++ locale to the user-configured locale.
// The locale should use UTF-8 encoding for these tests to run successfully.
try
{
try {
std::locale::global(std::locale(""));
}
catch (std::exception &)
{
} catch (std::exception &) {
std::setlocale(LC_ALL, "");
}
try
{
try {
vmime::messageBuilder mb;
// Fill in the basic fields
@ -74,9 +71,12 @@ int main()
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
// Message body
mb.getTextPart()->setText(vmime::make_shared <vmime::stringContentHandler>(
"I'm writing this short text to test message construction " \
"using the vmime::messageBuilder component."));
mb.getTextPart()->setText(
vmime::make_shared <vmime::stringContentHandler>(
"I'm writing this short text to test message construction " \
"using the vmime::messageBuilder component."
)
);
// Construction
vmime::shared_ptr <vmime::message> msg = mb.construct();
@ -87,20 +87,21 @@ int main()
vmime::utility::outputStreamAdapter out(std::cout);
msg->generate(out);
}
// VMime exception
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cout << "vmime::exception: " << e.what() << std::endl;
throw;
}
// Standard exception
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cout << "std::exception: " << e.what() << std::endl;
//throw;
throw;
}
std::cout << std::endl;
}
return 0;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -39,23 +39,20 @@
#include "vmime/platforms/posix/posixHandler.hpp"
int main()
{
int main() {
std::cout << std::endl;
// Set the global C and C++ locale to the user-configured locale.
// The locale should use UTF-8 encoding for these tests to run successfully.
try
{
try {
std::locale::global(std::locale(""));
}
catch (std::exception &)
{
} catch (std::exception &) {
std::setlocale(LC_ALL, "");
}
try
{
try {
vmime::messageBuilder mb;
// Fill in the basic fields
@ -74,17 +71,20 @@ int main()
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
// Message body
mb.getTextPart()->setText(vmime::make_shared <vmime::stringContentHandler>(
"I'm writing this short text to test message construction " \
"with attachment, using the vmime::messageBuilder component."));
mb.getTextPart()->setText(
vmime::make_shared <vmime::stringContentHandler>(
"I'm writing this short text to test message construction " \
"with attachment, using the vmime::messageBuilder component."
)
);
// Adding an attachment
vmime::shared_ptr <vmime::fileAttachment> a = vmime::make_shared <vmime::fileAttachment>
(
__FILE__, // full path to file
vmime::mediaType("application/octet-stream"), // content type
vmime::text("My first attachment") // description
);
vmime::shared_ptr <vmime::fileAttachment> a =
vmime::make_shared <vmime::fileAttachment>(
__FILE__, // full path to file
vmime::mediaType("application/octet-stream"), // content type
vmime::text("My first attachment") // description
);
a->getFileInfo().setFilename("example2.cpp");
a->getFileInfo().setCreationDate(vmime::datetime("30 Apr 2003 14:30:00 +0200"));
@ -101,20 +101,21 @@ int main()
std::cout << "==================" << std::endl;
std::cout << std::endl;
std::cout << dataToSend << std::endl;
}
// VMime exception
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cout << "vmime::exception: " << e.what() << std::endl;
throw;
}
// Standard exception
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cout << "std::exception: " << e.what() << std::endl;
throw;
}
std::cout << std::endl;
}
return 0;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -39,23 +39,20 @@
#include "vmime/platforms/posix/posixHandler.hpp"
int main()
{
int main() {
std::cout << std::endl;
// Set the global C and C++ locale to the user-configured locale.
// The locale should use UTF-8 encoding for these tests to run successfully.
try
{
try {
std::locale::global(std::locale(""));
}
catch (std::exception &)
{
} catch (std::exception &) {
std::setlocale(LC_ALL, "");
}
try
{
try {
vmime::messageBuilder mb;
// Fill in the basic fields
@ -74,12 +71,17 @@ int main()
mb.setSubject(vmime::text("My first message generated with vmime::messageBuilder"));
// Set the content-type to "text/html"
mb.constructTextPart(vmime::mediaType
(vmime::mediaTypes::TEXT, vmime::mediaTypes::TEXT_HTML));
mb.constructTextPart(
vmime::mediaType(
vmime::mediaTypes::TEXT,
vmime::mediaTypes::TEXT_HTML
)
);
// 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 = *vmime::dynamicCast <vmime::htmlTextPart>(mb.getTextPart());
vmime::htmlTextPart& textPart =
*vmime::dynamicCast <vmime::htmlTextPart>(mb.getTextPart());
// -- embed an image (the returned "CID" (content identifier) is used to reference
// -- the image into HTML content).
@ -93,18 +95,33 @@ int main()
imageFile->getFileReader();
vmime::shared_ptr <vmime::contentHandler> imageCts =
vmime::make_shared <vmime::streamContentHandler>
(fileReader->getInputStream(), imageFile->getLength());
vmime::make_shared <vmime::streamContentHandler>(
fileReader->getInputStream(),
imageFile->getLength()
);
vmime::shared_ptr <const vmime::htmlTextPart::embeddedObject> obj = textPart.addObject
(imageCts, vmime::mediaType(vmime::mediaTypes::IMAGE, vmime::mediaTypes::IMAGE_JPEG));
vmime::shared_ptr <const vmime::htmlTextPart::embeddedObject> obj =
textPart.addObject(
imageCts,
vmime::mediaType(
vmime::mediaTypes::IMAGE,
vmime::mediaTypes::IMAGE_JPEG
)
);
// -- message text
textPart.setText(vmime::make_shared <vmime::stringContentHandler>
(vmime::string("This is the <b>HTML text</b>.<br/>"
"<img src=\"") + obj->getReferenceId() + vmime::string("\"/>")));
textPart.setPlainText(vmime::make_shared <vmime::stringContentHandler>
("This is the plain text (without HTML formatting)."));
textPart.setText(
vmime::make_shared <vmime::stringContentHandler>(
vmime::string("This is the <b>HTML text</b>.<br/>"
"<img src=\"") + obj->getReferenceId() + vmime::string("\"/>")
)
);
textPart.setPlainText(
vmime::make_shared <vmime::stringContentHandler>(
"This is the plain text (without HTML formatting)."
)
);
// Construction
vmime::shared_ptr <vmime::message> msg = mb.construct();
@ -116,20 +133,21 @@ int main()
std::cout << "==================" << std::endl;
std::cout << std::endl;
std::cout << dataToSend << std::endl;
}
// VMime exception
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cout << "vmime::exception: " << e.what() << std::endl;
throw;
}
// Standard exception
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cout << "std::exception: " << e.what() << std::endl;
throw;
}
std::cout << std::endl;
}
return 0;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -39,71 +39,70 @@
#include "vmime/platforms/posix/posixHandler.hpp"
int main()
{
int main() {
std::cout << std::endl;
// Set the global C and C++ locale to the user-configured locale.
// The locale should use UTF-8 encoding for these tests to run successfully.
try
{
try {
std::locale::global(std::locale(""));
}
catch (std::exception &)
{
} catch (std::exception &) {
std::setlocale(LC_ALL, "");
}
try
{
try {
vmime::messageParser mp("<...MIME message content...>");
// Enumerate text parts
for (size_t i = 0 ; i < mp.getTextPartCount() ; ++i)
{
for (size_t i = 0 ; i < mp.getTextPartCount() ; ++i) {
const vmime::textPart& part = *mp.getTextPartAt(i);
// Output content-type of the part
std::cout << part.getType().generate() << std::endl;
// text/html
if (part.getType().getSubType() == vmime::mediaTypes::TEXT_HTML)
{
if (part.getType().getSubType() == vmime::mediaTypes::TEXT_HTML) {
const vmime::htmlTextPart& hp = dynamic_cast<const vmime::htmlTextPart&>(part);
// HTML text is in "hp.getText()"
// Corresponding plain text is in "hp.getPlainText()"
// Enumerate embedded objects (eg. images)
for (size_t j = 0 ; j < hp.getObjectCount() ; ++j)
{
for (size_t j = 0 ; j < hp.getObjectCount() ; ++j) {
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
else
{
} else {
const vmime::textPart& tp = dynamic_cast<const vmime::textPart&>(part);
// Text is in "tp.getText()"
}
}
}
// VMime exception
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cout << "vmime::exception: " << e.what() << std::endl;
throw;
}
// Standard exception
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cout << "std::exception: " << e.what() << std::endl;
throw;
}
std::cout << std::endl;
return 0;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -39,28 +39,25 @@
#include "vmime/platforms/posix/posixHandler.hpp"
int main()
{
int main() {
std::cout << std::endl;
// Set the global C and C++ locale to the user-configured locale.
// The locale should use UTF-8 encoding for these tests to run successfully.
try
{
try {
std::locale::global(std::locale(""));
}
catch (std::exception &)
{
} catch (std::exception &) {
std::setlocale(LC_ALL, "");
}
try
{
try {
vmime::messageParser mp("<...MIME message content...>");
// Enumerate attachments
for (size_t i = 0 ; i < mp.getAttachmentCount() ; ++i)
{
for (size_t i = 0 ; i < mp.getAttachmentCount() ; ++i) {
const vmime::attachment& att = *mp.getAttachmentAt(i);
// Media type (content type) is in "att.getType()"
@ -68,19 +65,21 @@ int main()
// Description is in "att.getDescription()"
// Data is in "att.getData()"
}
}
// VMime exception
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cout << "vmime::exception: " << e.what() << std::endl;
throw;
}
// Standard exception
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cout << "std::exception: " << e.what() << std::endl;
throw;
}
std::cout << std::endl;
return 0;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -46,22 +46,23 @@ static vmime::shared_ptr <vmime::net::session> g_session = vmime::net::session::
* @param type service type (vmime::net::service::TYPE_STORE or
* vmime::net::service::TYPE_TRANSPORT)
*/
static const std::string findAvailableProtocols(const vmime::net::service::Type type)
{
static const std::string findAvailableProtocols(const vmime::net::service::Type type) {
vmime::shared_ptr <vmime::net::serviceFactory> sf =
vmime::net::serviceFactory::getInstance();
std::ostringstream res;
size_t count = 0;
for (size_t i = 0 ; i < sf->getServiceCount() ; ++i)
{
for (size_t i = 0 ; i < sf->getServiceCount() ; ++i) {
const vmime::net::serviceFactory::registeredService& serv = *sf->getServiceAt(i);
if (serv.getType() == type)
{
if (count != 0)
if (serv.getType() == type) {
if (count != 0) {
res << ", ";
}
res << serv.getName();
++count;
@ -73,14 +74,14 @@ static const std::string findAvailableProtocols(const vmime::net::service::Type
// Exception helper
static std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
{
static std::ostream& operator<<(std::ostream& os, const vmime::exception& e) {
os << "* vmime::exceptions::" << e.name() << std::endl;
os << " what = " << e.what() << std::endl;
// More information for special exceptions
if (dynamic_cast <const vmime::exceptions::command_error*>(&e))
{
if (dynamic_cast <const vmime::exceptions::command_error*>(&e)) {
const vmime::exceptions::command_error& cee =
dynamic_cast <const vmime::exceptions::command_error&>(e);
@ -88,32 +89,32 @@ static std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
os << " response = " << cee.response() << std::endl;
}
if (dynamic_cast <const vmime::exceptions::invalid_response*>(&e))
{
if (dynamic_cast <const vmime::exceptions::invalid_response*>(&e)) {
const vmime::exceptions::invalid_response& ir =
dynamic_cast <const vmime::exceptions::invalid_response&>(e);
os << " response = " << ir.response() << std::endl;
}
if (dynamic_cast <const vmime::exceptions::connection_greeting_error*>(&e))
{
if (dynamic_cast <const vmime::exceptions::connection_greeting_error*>(&e)) {
const vmime::exceptions::connection_greeting_error& cgee =
dynamic_cast <const vmime::exceptions::connection_greeting_error&>(e);
os << " response = " << cgee.response() << std::endl;
}
if (dynamic_cast <const vmime::exceptions::authentication_error*>(&e))
{
if (dynamic_cast <const vmime::exceptions::authentication_error*>(&e)) {
const vmime::exceptions::authentication_error& aee =
dynamic_cast <const vmime::exceptions::authentication_error&>(e);
os << " response = " << aee.response() << std::endl;
}
if (dynamic_cast <const vmime::exceptions::filesystem_exception*>(&e))
{
if (dynamic_cast <const vmime::exceptions::filesystem_exception*>(&e)) {
const vmime::exceptions::filesystem_exception& fse =
dynamic_cast <const vmime::exceptions::filesystem_exception&>(e);
@ -121,8 +122,9 @@ static std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
getFileSystemFactory()->pathToString(fse.path()) << std::endl;
}
if (e.other() != NULL)
if (e.other()) {
os << *e.other();
}
return os;
}
@ -133,35 +135,40 @@ static std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
* @param s structure object
* @param level current depth
*/
static void printStructure(vmime::shared_ptr <const vmime::net::messageStructure> s, const int level = 0)
{
for (size_t i = 0 ; i < s->getPartCount() ; ++i)
{
static void printStructure(
vmime::shared_ptr <const vmime::net::messageStructure> s,
const int level = 0
) {
for (size_t i = 0 ; i < s->getPartCount() ; ++i) {
vmime::shared_ptr <const vmime::net::messagePart> part = s->getPartAt(i);
for (int j = 0 ; j < level * 2 ; ++j)
for (int j = 0 ; j < level * 2 ; ++j) {
std::cout << " ";
}
std::cout << (part->getNumber() + 1) << ". "
<< part->getType().generate()
<< " [" << part->getSize() << " byte(s)]"
<< std::endl;
std::cout
<< (part->getNumber() + 1) << ". "
<< part->getType().generate()
<< " [" << part->getSize() << " byte(s)]"
<< std::endl;
printStructure(part->getStructure(), level + 1);
}
}
static const vmime::string getFolderPathString(vmime::shared_ptr <vmime::net::folder> f)
{
static const vmime::string getFolderPathString(vmime::shared_ptr <vmime::net::folder> f) {
const vmime::string n = f->getName().getBuffer();
if (n.empty()) // root folder
{
if (n.empty()) { // root folder
return "/";
}
else
{
} else {
vmime::shared_ptr <vmime::net::folder> p = f->getParent();
return getFolderPathString(p) + n + "/";
}
@ -172,38 +179,43 @@ static const vmime::string getFolderPathString(vmime::shared_ptr <vmime::net::fo
*
* @param folder current folder
*/
static void printFolders(vmime::shared_ptr <vmime::net::folder> folder, const int level = 0)
{
for (int j = 0 ; j < level * 2 ; ++j)
static void printFolders(vmime::shared_ptr <vmime::net::folder> folder, const int level = 0) {
for (int j = 0 ; j < level * 2 ; ++j) {
std::cout << " ";
}
const vmime::net::folderAttributes attr = folder->getAttributes();
std::ostringstream attrStr;
if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ALL)
if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ALL) {
attrStr << " \\use:All";
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ARCHIVE)
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_ARCHIVE) {
attrStr << " \\use:Archive";
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_DRAFTS)
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_DRAFTS) {
attrStr << " \\use:Drafts";
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_FLAGGED)
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_FLAGGED) {
attrStr << " \\use:Flagged";
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_JUNK)
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_JUNK) {
attrStr << " \\use:Junk";
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_SENT)
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_SENT) {
attrStr << " \\use:Sent";
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_TRASH)
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_TRASH) {
attrStr << " \\use:Trash";
else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_IMPORTANT)
} else if (attr.getSpecialUse() == vmime::net::folderAttributes::SPECIALUSE_IMPORTANT) {
attrStr << " \\use:Important";
}
if (attr.getFlags() & vmime::net::folderAttributes::FLAG_HAS_CHILDREN)
if (attr.getFlags() & vmime::net::folderAttributes::FLAG_HAS_CHILDREN) {
attrStr << " \\flag:HasChildren";
if (attr.getFlags() & vmime::net::folderAttributes::FLAG_NO_OPEN)
}
if (attr.getFlags() & vmime::net::folderAttributes::FLAG_NO_OPEN) {
attrStr << " \\flag:NoOpen";
}
for (size_t i = 0, n = attr.getUserFlags().size() ; i < n ; ++i)
for (size_t i = 0, n = attr.getUserFlags().size() ; i < n ; ++i) {
attrStr << " \\" << attr.getUserFlags()[i];
}
std::cout << getFolderPathString(folder);
std::cout << " " << attrStr.str();
@ -211,8 +223,9 @@ static void printFolders(vmime::shared_ptr <vmime::net::folder> folder, const in
std::vector <vmime::shared_ptr <vmime::net::folder> > subFolders = folder->getFolders(false);
for (unsigned int i = 0 ; i < subFolders.size() ; ++i)
for (unsigned int i = 0 ; i < subFolders.size() ; ++i) {
printFolders(subFolders[i], level + 1);
}
}
@ -220,12 +233,13 @@ static void printFolders(vmime::shared_ptr <vmime::net::folder> folder, const in
*
* @param choices menu choices
*/
static unsigned int printMenu(const std::vector <std::string>& choices)
{
static unsigned int printMenu(const std::vector <std::string>& choices) {
std::cout << std::endl;
for (unsigned int i = 0 ; i < choices.size() ; ++i)
for (unsigned int i = 0 ; i < choices.size() ; ++i) {
std::cout << " " << (i + 1) << ". " << choices[i] << std::endl;
}
std::cout << std::endl;
std::cout << " Your choice? [1-" << choices.size() << "] ";
@ -241,19 +255,20 @@ static unsigned int printMenu(const std::vector <std::string>& choices)
std::cout << std::endl;
if (choice < 1 || choice > choices.size())
if (choice < 1 || choice > choices.size()) {
return 0;
else
} else {
return choice;
}
}
/** Send a message interactively.
*/
static void sendMessage()
{
try
{
static void sendMessage() {
try {
// Request user to enter an URL
std::cout << "Enter an URL to connect to transport service." << std::endl;
std::cout << "Available protocols: " << findAvailableProtocols(vmime::net::service::TYPE_TRANSPORT) << std::endl;
@ -268,10 +283,11 @@ static void sendMessage()
vmime::shared_ptr <vmime::net::transport> tr;
if (url.getUsername().empty() || url.getPassword().empty())
if (url.getUsername().empty() || url.getPassword().empty()) {
tr = g_session->getTransport(url, vmime::make_shared <interactiveAuthenticator>());
else
} else {
tr = g_session->getTransport(url);
}
#if VMIME_HAVE_TLS_SUPPORT
@ -283,15 +299,17 @@ static void sendMessage()
// Set the object responsible for verifying certificates, in the
// case a secured connection is used (TLS/SSL)
tr->setCertificateVerifier
(vmime::make_shared <interactiveCertificateVerifier>());
tr->setCertificateVerifier(
vmime::make_shared <interactiveCertificateVerifier>()
);
#endif // VMIME_HAVE_TLS_SUPPORT
// You can also set some properties (see example7 to know the properties
// available for each service). For example, for SMTP:
if (!url.getUsername().empty() || !url.getPassword().empty())
if (!url.getUsername().empty() || !url.getPassword().empty()) {
tr->setProperty("options.need-authentication", true);
}
// Trace communication between client and server
vmime::shared_ptr <std::ostringstream> traceStream = vmime::make_shared <std::ostringstream>();
@ -307,8 +325,8 @@ static void sendMessage()
vmime::mailbox from(fromString);
vmime::mailboxList to;
for (bool cont = true ; cont ; )
{
for (bool cont = true ; cont ; ) {
std::cout << "Enter email of the recipient (empty to stop): ";
std::cout.flush();
@ -317,23 +335,25 @@ static void sendMessage()
cont = (toString.size() != 0);
if (cont)
if (cont) {
to.appendMailbox(vmime::make_shared <vmime::mailbox>(toString));
}
}
std::cout << "Enter message data, including headers (end with '.' on a single line):" << std::endl;
std::ostringstream data;
for (bool cont = true ; cont ; )
{
for (bool cont = true ; cont ; ) {
std::string line;
std::getline(std::cin, line);
if (line == ".")
if (line == ".") {
cont = false;
else
} else {
data << line << "\r\n";
}
}
// Connect to server
@ -357,15 +377,15 @@ static void sendMessage()
std::cout << traceStream->str();
tr->disconnect();
}
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cerr << std::endl;
std::cerr << e << std::endl;
throw;
}
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cerr << std::endl;
std::cerr << "std::exception: " << e.what() << std::endl;
throw;
@ -375,10 +395,10 @@ static void sendMessage()
/** Connect to a message store interactively.
*/
static void connectStore()
{
try
{
static void connectStore() {
try {
// Request user to enter an URL
std::cout << "Enter an URL to connect to store service." << std::endl;
std::cout << "Available protocols: " << findAvailableProtocols(vmime::net::service::TYPE_STORE) << std::endl;
@ -396,10 +416,11 @@ static void connectStore()
// session properties "auth.username" and "auth.password".
vmime::shared_ptr <vmime::net::store> st;
if (url.getUsername().empty() || url.getPassword().empty())
if (url.getUsername().empty() || url.getPassword().empty()) {
st = g_session->getStore(url, vmime::make_shared <interactiveAuthenticator>());
else
} else {
st = g_session->getStore(url);
}
#if VMIME_HAVE_TLS_SUPPORT
@ -411,8 +432,9 @@ static void connectStore()
// Set the object responsible for verifying certificates, in the
// case a secured connection is used (TLS/SSL)
st->setCertificateVerifier
(vmime::make_shared <interactiveCertificateVerifier>());
st->setCertificateVerifier(
vmime::make_shared <interactiveCertificateVerifier>()
);
#endif // VMIME_HAVE_TLS_SUPPORT
@ -441,13 +463,13 @@ static void connectStore()
std::cout << std::endl;
std::cout << count << " message(s) in your inbox" << std::endl;
for (bool cont = true ; cont ; )
{
for (bool cont = true ; cont ; ) {
typedef std::map <vmime::size_t, vmime::shared_ptr <vmime::net::message> > MessageList;
MessageList msgList;
try
{
try {
std::vector <std::string> choices;
choices.push_back("Show message flags");
@ -470,8 +492,8 @@ static void connectStore()
vmime::shared_ptr <vmime::net::message> msg;
if (choice == 1 || choice == 2 || choice == 3 || choice == 4 ||
choice == 5 || choice == 6 || choice == 11)
{
choice == 5 || choice == 6 || choice == 11) {
std::cout << "Enter message number: ";
std::cout.flush();
@ -483,20 +505,20 @@ static void connectStore()
vmime::size_t num = 0;
iss >> num;
if (num < 1 || num > f->getMessageCount())
{
if (num < 1 || num > f->getMessageCount()) {
std::cerr << "Invalid message number." << std::endl;
continue;
}
MessageList::iterator it = msgList.find(num);
if (it != msgList.end())
{
if (it != msgList.end()) {
msg = (*it).second;
}
else
{
} else {
msg = f->getMessage(num);
msgList.insert(MessageList::value_type(num, msg));
}
@ -504,25 +526,31 @@ static void connectStore()
std::cout << std::endl;
}
switch (choice)
{
switch (choice) {
// Show message flags
case 1:
f->fetchMessage(msg, vmime::net::fetchAttributes::FLAGS);
if (msg->getFlags() & vmime::net::message::FLAG_SEEN)
if (msg->getFlags() & vmime::net::message::FLAG_SEEN) {
std::cout << "FLAG_SEEN" << std::endl;
if (msg->getFlags() & vmime::net::message::FLAG_RECENT)
}
if (msg->getFlags() & vmime::net::message::FLAG_RECENT) {
std::cout << "FLAG_RECENT" << std::endl;
if (msg->getFlags() & vmime::net::message::FLAG_REPLIED)
}
if (msg->getFlags() & vmime::net::message::FLAG_REPLIED) {
std::cout << "FLAG_REPLIED" << std::endl;
if (msg->getFlags() & vmime::net::message::FLAG_DELETED)
}
if (msg->getFlags() & vmime::net::message::FLAG_DELETED) {
std::cout << "FLAG_DELETED" << std::endl;
if (msg->getFlags() & vmime::net::message::FLAG_MARKED)
}
if (msg->getFlags() & vmime::net::message::FLAG_MARKED) {
std::cout << "FLAG_MARKED" << std::endl;
if (msg->getFlags() & vmime::net::message::FLAG_PASSED)
}
if (msg->getFlags() & vmime::net::message::FLAG_PASSED) {
std::cout << "FLAG_PASSED" << std::endl;
}
break;
@ -541,8 +569,8 @@ static void connectStore()
break;
// Show message envelope
case 4:
{
case 4: {
vmime::net::fetchAttributes attr(vmime::net::fetchAttributes::ENVELOPE);
// If you also want to fetch "Received: " fields:
@ -555,37 +583,38 @@ static void connectStore()
break;
}
// Extract whole message
case 5:
{
case 5: {
vmime::utility::outputStreamAdapter out(std::cout);
msg->extract(out);
break;
}
// Extract attachments
case 6:
{
case 6: {
vmime::shared_ptr <vmime::message> parsedMsg = msg->getParsedMessage();
std::vector <vmime::shared_ptr <const vmime::attachment> > attchs =
vmime::attachmentHelper::findAttachmentsInMessage(parsedMsg);
if (attchs.size() > 0)
{
if (attchs.size() > 0) {
std::cout << attchs.size() << " attachments found." << std::endl;
for (std::vector <vmime::shared_ptr <const vmime::attachment> >::iterator
it = attchs.begin() ; it != attchs.end() ; ++it)
{
it = attchs.begin() ; it != attchs.end() ; ++it) {
vmime::shared_ptr <const vmime::attachment> att = *it;
// Get attachment size
vmime::size_t size = 0;
if (att->getData()->isEncoded())
if (att->getData()->isEncoded()) {
size = att->getData()->getEncoding().getEncoder()->getDecodedSize(att->getData()->getLength());
else
} else {
size = att->getData()->getLength();
}
std::cout << "Found attachment '" << att->getName().getBuffer() << "'"
<< ", size is " << size << " bytes:" << std::endl;
@ -618,17 +647,17 @@ static void connectStore()
att->getData()->extract(*output.get());
*/
}
}
else
{
} else {
std::cout << "No attachments found." << std::endl;
}
break;
}
// Status
case 7:
{
case 7: {
vmime::size_t count, unseen;
f->status(count, unseen);
@ -636,17 +665,16 @@ static void connectStore()
break;
}
// List folders
case 8:
{
vmime::shared_ptr <vmime::net::folder>
root = st->getRootFolder();
case 8: {
vmime::shared_ptr <vmime::net::folder> root = st->getRootFolder();
printFolders(root);
break;
}
// Change folder
case 9:
{
case 9: {
std::cout << "Enter folder path (eg. /root/subfolder):" << std::endl;
std::cout.flush();
@ -655,19 +683,21 @@ static void connectStore()
vmime::shared_ptr <vmime::net::folder> newFolder = st->getRootFolder();
for (std::string::size_type s = 0, p = 0 ; ; s = p + 1)
{
for (std::string::size_type s = 0, p = 0 ; ; s = p + 1) {
p = path.find_first_of('/', s);
const std::string x = (p == std::string::npos)
? std::string(path.begin() + s, path.end())
: std::string(path.begin() + s, path.begin() + p);
if (!x.empty())
if (!x.empty()) {
newFolder = newFolder->getFolder(vmime::utility::path::component(x));
}
if (p == std::string::npos)
if (p == std::string::npos) {
break;
}
}
newFolder->open(vmime::net::folder::MODE_READ_WRITE);
@ -683,8 +713,8 @@ static void connectStore()
break;
}
// Add message
case 10:
{
case 10: {
vmime::messageBuilder mb;
mb.setExpeditor(vmime::mailbox("me@somewhere.com"));
@ -694,32 +724,35 @@ static void connectStore()
mb.setRecipients(to);
mb.setSubject(vmime::text("Test message from VMime example6"));
mb.getTextPart()->setText(vmime::make_shared <vmime::stringContentHandler>(
"Body of test message from VMime example6."));
mb.getTextPart()->setText(
vmime::make_shared <vmime::stringContentHandler>(
"Body of test message from VMime example6."
)
);
vmime::shared_ptr <vmime::message> msg = mb.construct();
vmime::net::messageSet set = f->addMessage(msg);
if (set.isEmpty())
{
if (set.isEmpty()) {
std::cout << "Message has successfully been added, "
<< "but its UID/number is not known." << std::endl;
}
else
{
} else {
const vmime::net::messageRange& range = set.getRangeAt(0);
if (set.isUIDSet())
{
if (set.isUIDSet()) {
const vmime::net::message::uid uid =
dynamic_cast <const vmime::net::UIDMessageRange&>(range).getFirst();
std::cout << "Message has successfully been added, "
<< "its UID is '" << uid << "'." << std::endl;
}
else
{
} else {
const vmime::size_t number =
dynamic_cast <const vmime::net::numberMessageRange&>(range).getFirst();
@ -731,30 +764,30 @@ static void connectStore()
break;
}
// Copy message
case 11:
{
case 11: {
vmime::net::messageSet set = f->copyMessages(f->getFullPath(),
vmime::net::messageSet::byNumber(msg->getNumber()));
if (set.isEmpty())
{
if (set.isEmpty()) {
std::cout << "Message has successfully been copied, "
<< "but its UID/number is not known." << std::endl;
}
else
{
} else {
const vmime::net::messageRange& range = set.getRangeAt(0);
if (set.isUIDSet())
{
if (set.isUIDSet()) {
const vmime::net::message::uid uid =
dynamic_cast <const vmime::net::UIDMessageRange&>(range).getFirst();
std::cout << "Message has successfully been copied, "
<< "its UID is '" << uid << "'." << std::endl;
}
else
{
} else {
const vmime::size_t number =
dynamic_cast <const vmime::net::numberMessageRange&>(range).getFirst();
@ -808,35 +841,37 @@ static void connectStore()
{
vmime::shared_ptr <vmime::net::folder> g = st->getFolder(vmime::net::folder::path("TEMP"));
if (!g->exists())
if (!g->exists()) {
g->create(vmime::net::folder::TYPE_CONTAINS_MESSAGES);
}
f->copyMessages(g->getFullPath());
}
*/
}
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cerr << std::endl;
std::cerr << e << std::endl;
}
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cerr << std::endl;
std::cerr << "std::exception: " << e.what() << std::endl;
}
} // for(cont)
st->disconnect();
}
catch (vmime::exception& e)
{
} catch (vmime::exception& e) {
std::cerr << std::endl;
std::cerr << e << std::endl;
throw;
}
catch (std::exception& e)
{
} catch (std::exception& e) {
std::cerr << std::endl;
std::cerr << "std::exception: " << e.what() << std::endl;
throw;
@ -848,16 +883,16 @@ static void connectStore()
*
* @return true to quit the program, false to continue
*/
static bool menu()
{
static bool menu() {
std::vector <std::string> items;
items.push_back("Connect to a message store");
items.push_back("Send a message");
items.push_back("Quit");
switch (printMenu(items))
{
switch (printMenu(items)) {
// Connect to store
case 1:
@ -883,25 +918,21 @@ static bool menu()
}
int main()
{
int main() {
// Set the global C and C++ locale to the user-configured locale.
// The locale should use UTF-8 encoding for these tests to run successfully.
try
{
try {
std::locale::global(std::locale(""));
}
catch (std::exception &)
{
} catch (std::exception &) {
std::setlocale(LC_ALL, "");
}
for (bool quit = false ; !quit ; )
{
for (bool quit = false ; !quit ; ) {
// Loop on main menu
quit = menu();
}
return 0;
}

View File

@ -3,20 +3,23 @@
#if VMIME_HAVE_SASL_SUPPORT
// SASL authentication handler
class interactiveAuthenticator : public vmime::security::sasl::defaultSASLAuthenticator
{
const std::vector <vmime::shared_ptr <vmime::security::sasl::SASLMechanism> > getAcceptableMechanisms
(const std::vector <vmime::shared_ptr <vmime::security::sasl::SASLMechanism> >& available,
const vmime::shared_ptr <vmime::security::sasl::SASLMechanism>& suggested) const
{
class interactiveAuthenticator : public vmime::security::sasl::defaultSASLAuthenticator {
const std::vector <vmime::shared_ptr <vmime::security::sasl::SASLMechanism> >
getAcceptableMechanisms(
const std::vector <vmime::shared_ptr <vmime::security::sasl::SASLMechanism> >& available,
const vmime::shared_ptr <vmime::security::sasl::SASLMechanism>& suggested
) const {
std::cout << std::endl << "Available SASL mechanisms:" << std::endl;
for (unsigned int i = 0 ; i < available.size() ; ++i)
{
for (unsigned int i = 0 ; i < available.size() ; ++i) {
std::cout << " " << available[i]->getName();
if (suggested && available[i]->getName() == suggested->getName())
if (suggested && available[i]->getName() == suggested->getName()) {
std::cout << "(suggested)";
}
}
std::cout << std::endl << std::endl;
@ -24,31 +27,33 @@ class interactiveAuthenticator : public vmime::security::sasl::defaultSASLAuthen
return defaultSASLAuthenticator::getAcceptableMechanisms(available, suggested);
}
void setSASLMechanism(const vmime::shared_ptr <vmime::security::sasl::SASLMechanism>& mech)
{
void setSASLMechanism(const vmime::shared_ptr <vmime::security::sasl::SASLMechanism>& mech) {
std::cout << "Trying '" << mech->getName() << "' authentication mechanism" << std::endl;
defaultSASLAuthenticator::setSASLMechanism(mech);
}
const vmime::string getUsername() const
{
if (m_username.empty())
const vmime::string getUsername() const {
if (m_username.empty()) {
m_username = getUserInput("Username");
}
return m_username;
}
const vmime::string getPassword() const
{
if (m_password.empty())
const vmime::string getPassword() const {
if (m_password.empty()) {
m_password = getUserInput("Password");
}
return m_password;
}
static const vmime::string getUserInput(const std::string& prompt)
{
static const vmime::string getUserInput(const std::string& prompt) {
std::cout << prompt << ": ";
std::cout.flush();
@ -67,26 +72,28 @@ private:
#else // !VMIME_HAVE_SASL_SUPPORT
// Simple authentication handler
class interactiveAuthenticator : public vmime::security::defaultAuthenticator
{
const vmime::string getUsername() const
{
if (m_username.empty())
class interactiveAuthenticator : public vmime::security::defaultAuthenticator {
const vmime::string getUsername() const {
if (m_username.empty()) {
m_username = getUserInput("Username");
}
return m_username;
}
const vmime::string getPassword() const
{
if (m_password.empty())
const vmime::string getPassword() const {
if (m_password.empty()) {
m_password = getUserInput("Password");
}
return m_password;
}
static const vmime::string getUserInput(const std::string& prompt)
{
static const vmime::string getUserInput(const std::string& prompt) {
std::cout << prompt << ": ";
std::cout.flush();
@ -103,4 +110,3 @@ private:
};
#endif // VMIME_HAVE_SASL_SUPPORT

View File

@ -3,20 +3,23 @@
#if VMIME_HAVE_TLS_SUPPORT
// Certificate verifier (TLS/SSL)
class interactiveCertificateVerifier : public vmime::security::cert::defaultCertificateVerifier
{
class interactiveCertificateVerifier : public vmime::security::cert::defaultCertificateVerifier {
public:
void verify(const vmime::shared_ptr <vmime::security::cert::certificateChain>& chain, const vmime::string& hostname)
{
try
{
void verify(
const vmime::shared_ptr <vmime::security::cert::certificateChain>& chain,
const vmime::string& hostname
) {
try {
setX509TrustedCerts(m_trustedCerts);
defaultCertificateVerifier::verify(chain, hostname);
}
catch (vmime::security::cert::certificateException&)
{
} catch (vmime::security::cert::certificateException&) {
// Obtain subject's certificate
vmime::shared_ptr <vmime::security::cert::certificate> cert = chain->getAt(0);
@ -29,13 +32,14 @@ public:
std::getline(std::cin, answer);
if (answer.length() != 0 &&
(answer[0] == 'Y' || answer[0] == 'y'))
{
(answer[0] == 'Y' || answer[0] == 'y')) {
// Accept it, and remember user's choice for later
if (cert->getType() == "X.509")
{
m_trustedCerts.push_back(vmime::dynamicCast
<vmime::security::cert::X509Certificate>(cert));
if (cert->getType() == "X.509") {
m_trustedCerts.push_back(
vmime::dynamicCast <vmime::security::cert::X509Certificate>(cert)
);
setX509TrustedCerts(m_trustedCerts);
defaultCertificateVerifier::verify(chain, hostname);
@ -44,8 +48,7 @@ public:
return;
}
throw vmime::security::cert::certificateException
("User did not accept the certificate.");
throw vmime::security::cert::certificateException("User did not accept the certificate.");
}
}
@ -59,4 +62,3 @@ std::vector <vmime::shared_ptr <vmime::security::cert::X509Certificate> >
interactiveCertificateVerifier::m_trustedCerts;
#endif // VMIME_HAVE_TLS_SUPPORT

View File

@ -5,17 +5,17 @@
* Used to stop the current operation after too much time, or if the user
* requested cancellation.
*/
class timeoutHandler : public vmime::net::timeoutHandler
{
class timeoutHandler : public vmime::net::timeoutHandler {
public:
timeoutHandler()
: m_start(time(NULL))
{
: m_start(time(NULL)) {
}
bool isTimeOut()
{
bool isTimeOut() {
// This is a cancellation point: return true if you want to cancel
// the current operation. If you return true, handleTimeOut() will
// be called just after this, and before actually cancelling the
@ -25,15 +25,15 @@ public:
return (time(NULL) - m_start) >= 10; // seconds
}
void resetTimeOut()
{
void resetTimeOut() {
// Called at the beginning of an operation (eg. connecting,
// a read() or a write() on a socket...)
m_start = time(NULL);
}
bool handleTimeOut()
{
bool handleTimeOut() {
// If isTimeOut() returned true, this function will be called. This
// allows you to interact with the user, ie. display a prompt to
// know whether he wants to cancel the operation.
@ -49,13 +49,12 @@ private:
};
class timeoutHandlerFactory : public vmime::net::timeoutHandlerFactory
{
class timeoutHandlerFactory : public vmime::net::timeoutHandlerFactory {
public:
vmime::shared_ptr <vmime::net::timeoutHandler> create()
{
vmime::shared_ptr <vmime::net::timeoutHandler> create() {
return vmime::make_shared <timeoutHandler>();
}
};

View File

@ -1,25 +1,29 @@
/** Tracer used to demonstrate logging communication between client and server.
*/
class myTracer : public vmime::net::tracer {
class myTracer : public vmime::net::tracer
{
public:
myTracer(const vmime::shared_ptr <std::ostringstream>& stream,
const vmime::shared_ptr <vmime::net::service>& serv, const int connectionId)
: m_stream(stream), m_service(serv), m_connectionId(connectionId)
{
myTracer(
const vmime::shared_ptr <std::ostringstream>& stream,
const vmime::shared_ptr <vmime::net::service>& serv,
const int connectionId
)
: m_stream(stream),
m_service(serv),
m_connectionId(connectionId) {
}
void traceSend(const vmime::string& line)
{
void traceSend(const vmime::string& line) {
*m_stream << "[" << m_service->getProtocolName() << ":" << m_connectionId
<< "] C: " << line << std::endl;
}
void traceReceive(const vmime::string& line)
{
void traceReceive(const vmime::string& line) {
*m_stream << "[" << m_service->getProtocolName() << ":" << m_connectionId
<< "] S: " << line << std::endl;
}
@ -31,18 +35,21 @@ private:
const int m_connectionId;
};
class myTracerFactory : public vmime::net::tracerFactory
{
class myTracerFactory : public vmime::net::tracerFactory {
public:
myTracerFactory(const vmime::shared_ptr <std::ostringstream>& stream)
: m_stream(stream)
{
: m_stream(stream) {
}
vmime::shared_ptr <vmime::net::tracer> create
(const vmime::shared_ptr <vmime::net::service>& serv, const int connectionId)
{
vmime::shared_ptr <vmime::net::tracer> create(
const vmime::shared_ptr <vmime::net::service>& serv,
const int connectionId
) {
return vmime::make_shared <myTracer>(m_stream, serv, connectionId);
}
@ -50,4 +57,3 @@ private:
vmime::shared_ptr <std::ostringstream> m_stream;
};

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -39,16 +39,16 @@
#include "vmime/platforms/posix/posixHandler.hpp"
int main()
{
int main() {
// Enumerate encoders
vmime::shared_ptr <vmime::utility::encoder::encoderFactory> ef =
vmime::utility::encoder::encoderFactory::getInstance();
std::cout << "Available encoders:" << std::endl;
for (size_t i = 0 ; i < ef->getEncoderCount() ; ++i)
{
for (size_t i = 0 ; i < ef->getEncoderCount() ; ++i) {
vmime::shared_ptr <const vmime::utility::encoder::encoderFactory::registeredEncoder>
enc = ef->getEncoderAt(i);
@ -59,8 +59,9 @@ int main()
std::vector <vmime::string> props = e->getAvailableProperties();
for (std::vector <vmime::string>::const_iterator it = props.begin() ; it != props.end() ; ++it)
for (std::vector <vmime::string>::const_iterator it = props.begin() ; it != props.end() ; ++it) {
std::cout << " - " << *it << std::endl;
}
}
std::cout << std::endl;
@ -71,8 +72,8 @@ int main()
std::cout << "Available messaging services:" << std::endl;
for (size_t i = 0 ; i < sf->getServiceCount() ; ++i)
{
for (size_t i = 0 ; i < sf->getServiceCount() ; ++i) {
const vmime::net::serviceFactory::registeredService& serv = *sf->getServiceAt(i);
std::cout << " * " << serv.getName() << std::endl;
@ -81,28 +82,29 @@ int main()
serv.getInfos().getAvailableProperties();
for (std::vector <vmime::net::serviceInfos::property>::const_iterator it = props.begin() ;
it != props.end() ; ++it)
{
it != props.end() ; ++it) {
const vmime::net::serviceInfos::property& p = *it;
const vmime::string name = serv.getInfos().getPropertyPrefix() + p.getName();
vmime::string type;
switch (p.getType())
{
case vmime::net::serviceInfos::property::TYPE_INTEGER: type = "TYPE_INTEGER"; break;
case vmime::net::serviceInfos::property::TYPE_STRING: type = "TYPE_STRING"; break;
case vmime::net::serviceInfos::property::TYPE_BOOLEAN: type = "TYPE_BOOLEAN"; break;
default: type = "(unknown)"; break;
switch (p.getType()) {
case vmime::net::serviceInfos::property::TYPE_INTEGER: type = "TYPE_INTEGER"; break;
case vmime::net::serviceInfos::property::TYPE_STRING: type = "TYPE_STRING"; break;
case vmime::net::serviceInfos::property::TYPE_BOOLEAN: type = "TYPE_BOOLEAN"; break;
default: type = "(unknown)"; break;
}
vmime::string flags;
if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_REQUIRED)
if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_REQUIRED) {
flags += " FLAG_REQUIRED";
if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_HIDDEN)
}
if (p.getFlags() & vmime::net::serviceInfos::property::FLAG_HIDDEN) {
flags += " FLAG_HIDDEN";
}
std::cout << " - " << serv.getInfos().getPropertyPrefix() + p.getName();
std::cout << " (type=" << type << ", flags=" << flags;
@ -111,5 +113,6 @@ int main()
}
std::cout << std::endl;
}
return 0;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -53,8 +53,12 @@ vmime::shared_ptr <vmime::message> currentMessage;
void insertRowInModel(GtkTreeStore* model, vmime::shared_ptr <vmime::component> comp, GtkTreeIter* parent = NULL)
{
void insertRowInModel(
GtkTreeStore* model,
vmime::shared_ptr <vmime::component> comp,
GtkTreeIter* parent = NULL
) {
GtkTreeIter iter;
gtk_tree_store_append(model, &iter, parent);
@ -62,15 +66,14 @@ void insertRowInModel(GtkTreeStore* model, vmime::shared_ptr <vmime::component>
const std::vector <vmime::shared_ptr <vmime::component> > children = comp->getChildComponents();
for (int i = 0 ; i < children.size() ; ++i)
{
for (int i = 0 ; i < children.size() ; ++i) {
insertRowInModel(model, children[i], &iter);
}
}
void updateTreeView()
{
void updateTreeView() {
GtkTreeStore* model = GTK_TREE_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(treeView)));
g_object_ref(model);
@ -85,8 +88,8 @@ void updateTreeView()
}
static void treeViewSelChanged(GtkTreeView* treeView, gpointer userData)
{
static void treeViewSelChanged(GtkTreeView* treeView, gpointer userData) {
GtkTreePath* path = NULL;
GtkTreeViewColumn* col = NULL;
@ -112,19 +115,18 @@ static void treeViewSelChanged(GtkTreeView* treeView, gpointer userData)
}
static void destroy(GtkWidget* widget, gpointer data)
{
static void destroy(GtkWidget* widget, gpointer data) {
gtk_main_quit();
}
void openFile(const std::string& filename)
{
void openFile(const std::string& filename) {
std::ifstream file;
file.open(filename.c_str(), std::ios::in | std::ios::binary);
if (!file)
{
if (!file) {
std::cerr << "Can't open file '" << filename << "'." << std::endl;
return;
}
@ -132,12 +134,10 @@ void openFile(const std::string& filename)
vmime::string data;
char buffer[16384];
do
{
do {
file.read(buffer, sizeof(buffer));
data += vmime::string(buffer, file.gcount());
}
while (file.gcount());
} while (file.gcount());
vmime::shared_ptr <vmime::message> msg = vmime::make_shared <vmime::message>();
msg->parse(data);
@ -147,13 +147,13 @@ void openFile(const std::string& filename)
char* convData = g_convert_with_fallback(data.c_str(), data.length(),
"UTF-8", "ISO-8859-1", "?", NULL, NULL, NULL);
if (convData == NULL)
{
if (!convData) {
gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)),
"GLib UTF-8 conversion error.", -1);
}
else
{
} else {
gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(textArea)),
convData, strlen(convData));
@ -164,16 +164,19 @@ void openFile(const std::string& filename)
}
static void onFileOpen()
{
GtkWidget* dlg = gtk_file_chooser_dialog_new
("Open Message File", GTK_WINDOW(window), GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL);
static void onFileOpen() {
GtkWidget* dlg = gtk_file_chooser_dialog_new(
"Open Message File",
GTK_WINDOW(window),
GTK_FILE_CHOOSER_ACTION_OPEN,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
NULL
);
if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_ACCEPT) {
if (gtk_dialog_run(GTK_DIALOG(dlg)) == GTK_RESPONSE_ACCEPT)
{
char* filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dlg));
openFile(filename);
@ -187,8 +190,7 @@ static void onFileOpen()
// UI definitions
static const GtkActionEntry uiActions[] =
{
static const GtkActionEntry uiActions[] = {
{ "FileMenu", NULL, "_File" },
{ "FileOpen", GTK_STOCK_OPEN, "_Open...", "<control>O", NULL, G_CALLBACK(onFileOpen) },
{ "FileExit", GTK_STOCK_QUIT, "_Exit", "<control>Q", NULL, G_CALLBACK(gtk_main_quit) }
@ -205,8 +207,8 @@ static const char* uiDefinition =
"</ui>";
int main(int argc, char* argv[])
{
int main(int argc, char* argv[]) {
// VMime initialization
vmime::platform::setHandler<vmime::platforms::posix::posixHandler>();
@ -290,5 +292,3 @@ int main(int argc, char* argv[])
return 0;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -29,12 +29,11 @@
#include "vmime/parserHelpers.hpp"
namespace vmime
{
namespace vmime {
address::address()
{
address::address() {
}
@ -66,10 +65,15 @@ address-list = (address *("," address)) / obs-addr-list
*/
shared_ptr <address> address::parseNext
(const parsingContext& ctx, const string& buffer, const size_t position,
const size_t end, size_t* newPosition, bool *isLastAddressOfGroup)
{
shared_ptr <address> address::parseNext(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition,
bool *isLastAddressOfGroup
) {
bool escaped = false;
bool quoted = false;
bool quotedRFC2047 = false;
@ -78,135 +82,151 @@ shared_ptr <address> address::parseNext
bool stop = false;
int commentLevel = 0;
if (isLastAddressOfGroup)
if (isLastAddressOfGroup) {
*isLastAddressOfGroup = false;
}
size_t pos = position;
while (pos < end && parserHelpers::isSpace(buffer[pos]))
while (pos < end && parserHelpers::isSpace(buffer[pos])) {
++pos;
}
const size_t start = pos;
while (!stop && pos < end)
{
if (escaped)
{
while (!stop && pos < end) {
if (escaped) {
escaped = false;
}
else
{
switch (buffer[pos])
{
case '\\':
escaped = true;
break;
case '"':
quoted = !quoted;
break;
case '<':
inRouteAddr = true;
break;
case '>':
inRouteAddr = false;
break;
case '(':
} else {
++commentLevel;
break;
switch (buffer[pos]) {
case ')':
case '\\':
if (commentLevel > 0)
--commentLevel;
escaped = true;
break;
break;
case '"':
case '=':
quoted = !quoted;
break;
if (commentLevel == 0 && !quoted && !quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '?')
{
++pos;
quotedRFC2047 = true;
}
case '<':
break;
inRouteAddr = true;
break;
case '?':
case '>':
if (commentLevel == 0 && quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '=')
{
++pos;
quotedRFC2047 = false;
}
inRouteAddr = false;
break;
break;
case '(':
default:
{
if (commentLevel == 0 && !quoted && !quotedRFC2047 && !inRouteAddr)
{
switch (buffer[pos])
{
case ';':
++commentLevel;
break;
if (isGroup)
{
if (pos + 1 < end && buffer[pos + 1] == ',')
++pos;
}
case ')':
if (isLastAddressOfGroup)
*isLastAddressOfGroup = true;
stop = true;
break;
case ':':
isGroup = true;
break;
case ',':
if (!isGroup) stop = true;
break;
if (commentLevel > 0) {
--commentLevel;
}
}
break;
}
break;
case '=':
if (commentLevel == 0 && !quoted && !quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '?') {
++pos;
quotedRFC2047 = true;
}
break;
case '?':
if (commentLevel == 0 && quotedRFC2047 && pos + 1 < end && buffer[pos + 1] == '=') {
++pos;
quotedRFC2047 = false;
}
break;
default:
{
if (commentLevel == 0 && !quoted && !quotedRFC2047 && !inRouteAddr) {
switch (buffer[pos]) {
case ';':
if (isGroup) {
if (pos + 1 < end && buffer[pos + 1] == ',') {
++pos;
}
}
if (isLastAddressOfGroup) {
*isLastAddressOfGroup = true;
}
stop = true;
break;
case ':':
isGroup = true;
break;
case ',':
if (!isGroup) {
stop = true;
}
break;
}
}
break;
}
}
}
if (!stop)
if (!stop) {
++pos;
}
}
if (newPosition)
{
if (pos == end)
if (newPosition) {
if (pos == end) {
*newPosition = end;
else
} else {
*newPosition = pos + 1; // ',' or ';'
}
}
// Parse extracted address (mailbox or group)
if (pos != start)
{
if (pos != start) {
shared_ptr <address> parsedAddress;
if (isGroup)
if (isGroup) {
parsedAddress = make_shared <mailboxGroup>();
else
} else {
parsedAddress = make_shared <mailbox>();
}
parsedAddress->parse(ctx, buffer, start, pos, NULL);
parsedAddress->setParsedBounds(start, pos);
return (parsedAddress);
return parsedAddress;
}
return null;

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -29,8 +29,7 @@
#include "vmime/headerFieldValue.hpp"
namespace vmime
{
namespace vmime {
/** Abstract class representing a mailbox or a group of mailboxes.
@ -38,9 +37,8 @@ namespace vmime
* This class define a common behaviour for the mailbox
* and mailboxGroup classes.
*/
class VMIME_EXPORT address : public headerFieldValue {
class VMIME_EXPORT address : public headerFieldValue
{
protected:
address();
@ -74,10 +72,14 @@ public:
* of a group (end delimiter was found), or false otherwise (may be set to NULL)
* @return a new address object, or null if no more address is available in the input buffer
*/
static shared_ptr <address> parseNext
(const parsingContext& ctx, const string& buffer,
const size_t position, const size_t end,
size_t* newPosition, bool *isLastAddressOfGroup);
static shared_ptr <address> parseNext(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition,
bool *isLastAddressOfGroup
);
};

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -28,181 +28,204 @@
#include "vmime/mailboxGroup.hpp"
namespace vmime
{
namespace vmime {
addressList::addressList()
{
addressList::addressList() {
}
addressList::addressList(const addressList& addrList)
: headerFieldValue()
{
: headerFieldValue() {
copyFrom(addrList);
}
addressList::~addressList()
{
addressList::~addressList() {
removeAllAddresses();
}
void addressList::parseImpl
(const parsingContext& ctx, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void addressList::parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
removeAllAddresses();
size_t pos = position;
while (pos < end)
{
while (pos < end) {
shared_ptr <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, NULL);
if (parsedAddress != NULL)
if (parsedAddress) {
m_list.push_back(parsedAddress);
}
}
setParsedBounds(position, end);
if (newPosition)
if (newPosition) {
*newPosition = end;
}
}
void addressList::generateImpl
(const generationContext& ctx, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
void addressList::generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
size_t pos = curLinePos;
generationContext tmpCtx(ctx);
tmpCtx.setMaxLineLength(tmpCtx.getMaxLineLength() - 2);
if (!m_list.empty())
{
for (std::vector <shared_ptr <address> >::const_iterator i = m_list.begin() ; ; )
{
if (!m_list.empty()) {
for (std::vector <shared_ptr <address> >::const_iterator i = m_list.begin() ; ; ) {
(*i)->generate(ctx, os, pos, &pos);
if (++i == m_list.end())
if (++i == m_list.end()) {
break;
}
os << ", ";
pos += 2;
}
}
if (newLinePos)
if (newLinePos) {
*newLinePos = pos;
}
}
void addressList::copyFrom(const component& other)
{
void addressList::copyFrom(const component& other) {
const addressList& addrList = dynamic_cast <const addressList&>(other);
removeAllAddresses();
for (std::vector <shared_ptr <address> >::const_iterator it = addrList.m_list.begin() ;
it != addrList.m_list.end() ; ++it)
{
it != addrList.m_list.end() ; ++it) {
m_list.push_back(vmime::clone(*it));
}
}
addressList& addressList::operator=(const addressList& other)
{
addressList& addressList::operator=(const addressList& other) {
copyFrom(other);
return (*this);
return *this;
}
addressList& addressList::operator=(const mailboxList& other)
{
addressList& addressList::operator=(const mailboxList& other) {
removeAllAddresses();
for (size_t i = 0 ; i < other.getMailboxCount() ; ++i)
for (size_t i = 0 ; i < other.getMailboxCount() ; ++i) {
m_list.push_back(dynamicCast <address>(other.getMailboxAt(i)->clone()));
}
return (*this);
return *this;
}
shared_ptr <component> addressList::clone() const
{
shared_ptr <component> addressList::clone() const {
return make_shared <addressList>(*this);
}
void addressList::appendAddress(const shared_ptr <address> &addr)
{
void addressList::appendAddress(const shared_ptr <address> &addr) {
m_list.push_back(addr);
}
void addressList::insertAddressBefore(const shared_ptr <address>& beforeAddress, const shared_ptr <address>& addr)
{
const std::vector <shared_ptr <address> >::iterator it = std::find
(m_list.begin(), m_list.end(), beforeAddress);
void addressList::insertAddressBefore(const shared_ptr <address>& beforeAddress, const shared_ptr <address>& addr) {
if (it == m_list.end())
const std::vector <shared_ptr <address> >::iterator it = std::find(
m_list.begin(), m_list.end(), beforeAddress
);
if (it == m_list.end()) {
throw std::out_of_range("Invalid position");
}
m_list.insert(it, addr);
}
void addressList::insertAddressBefore(const size_t pos, const shared_ptr <address>& addr)
{
if (pos >= m_list.size())
void addressList::insertAddressBefore(const size_t pos, const shared_ptr <address>& addr) {
if (pos >= m_list.size()) {
throw std::out_of_range("Invalid position");
}
m_list.insert(m_list.begin() + pos, addr);
}
void addressList::insertAddressAfter(const shared_ptr <address>& afterAddress, const shared_ptr <address>& addr)
{
const std::vector <shared_ptr <address> >::iterator it = std::find
(m_list.begin(), m_list.end(), afterAddress);
void addressList::insertAddressAfter(
const shared_ptr <address>& afterAddress,
const shared_ptr <address>& addr
) {
if (it == m_list.end())
const std::vector <shared_ptr <address> >::iterator it = std::find(
m_list.begin(), m_list.end(), afterAddress
);
if (it == m_list.end()) {
throw std::out_of_range("Invalid position");
}
m_list.insert(it + 1, addr);
}
void addressList::insertAddressAfter(const size_t pos, const shared_ptr <address>& addr)
{
if (pos >= m_list.size())
void addressList::insertAddressAfter(const size_t pos, const shared_ptr <address>& addr) {
if (pos >= m_list.size()) {
throw std::out_of_range("Invalid position");
}
m_list.insert(m_list.begin() + pos + 1, addr);
}
void addressList::removeAddress(const shared_ptr <address>& addr)
{
const std::vector <shared_ptr <address> >::iterator it = std::find
(m_list.begin(), m_list.end(), addr);
void addressList::removeAddress(const shared_ptr <address>& addr) {
if (it == m_list.end())
const std::vector <shared_ptr <address> >::iterator it = std::find(
m_list.begin(), m_list.end(), addr
);
if (it == m_list.end()) {
throw std::out_of_range("Invalid position");
}
m_list.erase(it);
}
void addressList::removeAddress(const size_t pos)
{
if (pos >= m_list.size())
void addressList::removeAddress(const size_t pos) {
if (pos >= m_list.size()) {
throw std::out_of_range("Invalid position");
}
const std::vector <shared_ptr <address> >::iterator it = m_list.begin() + pos;
@ -210,90 +233,90 @@ void addressList::removeAddress(const size_t pos)
}
void addressList::removeAllAddresses()
{
void addressList::removeAllAddresses() {
m_list.clear();
}
size_t addressList::getAddressCount() const
{
return (m_list.size());
size_t addressList::getAddressCount() const {
return m_list.size();
}
bool addressList::isEmpty() const
{
return (m_list.empty());
bool addressList::isEmpty() const {
return m_list.empty();
}
shared_ptr <address> addressList::getAddressAt(const size_t pos)
{
return (m_list[pos]);
shared_ptr <address> addressList::getAddressAt(const size_t pos) {
return m_list[pos];
}
const shared_ptr <const address> addressList::getAddressAt(const size_t pos) const
{
return (m_list[pos]);
const shared_ptr <const address> addressList::getAddressAt(const size_t pos) const {
return m_list[pos];
}
const std::vector <shared_ptr <const address> > addressList::getAddressList() const
{
const std::vector <shared_ptr <const address> > addressList::getAddressList() const {
std::vector <shared_ptr <const address> > list;
list.reserve(m_list.size());
for (std::vector <shared_ptr <address> >::const_iterator it = m_list.begin() ;
it != m_list.end() ; ++it)
{
it != m_list.end() ; ++it) {
list.push_back(*it);
}
return (list);
return list;
}
const std::vector <shared_ptr <address> > addressList::getAddressList()
{
return (m_list);
const std::vector <shared_ptr <address> > addressList::getAddressList() {
return m_list;
}
const std::vector <shared_ptr <component> > addressList::getChildComponents()
{
const std::vector <shared_ptr <component> > addressList::getChildComponents() {
std::vector <shared_ptr <component> > list;
copy_vector(m_list, list);
return (list);
return list;
}
shared_ptr <mailboxList> addressList::toMailboxList() const
{
shared_ptr <mailboxList> addressList::toMailboxList() const {
shared_ptr <mailboxList> res = make_shared <mailboxList>();
for (std::vector <shared_ptr <address> >::const_iterator it = m_list.begin() ;
it != m_list.end() ; ++it)
{
it != m_list.end() ; ++it) {
shared_ptr <const address> addr = *it;
if (addr->isGroup())
{
if (addr->isGroup()) {
const std::vector <shared_ptr <const mailbox> > mailboxes =
dynamicCast <const mailboxGroup>(addr)->getMailboxList();
for (std::vector <shared_ptr <const mailbox> >::const_iterator jt = mailboxes.begin() ;
jt != mailboxes.end() ; ++jt)
{
jt != mailboxes.end() ; ++jt) {
res->appendMailbox(vmime::clone(*jt));
}
}
else
{
} else {
res->appendMailbox(dynamicCast <mailbox>(addr->clone()));
}
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -31,8 +31,7 @@
#include "vmime/address.hpp"
namespace vmime
{
namespace vmime {
class mailboxList;
@ -40,9 +39,8 @@ class mailboxList;
/** A list of addresses.
*/
class VMIME_EXPORT addressList : public headerFieldValue {
class VMIME_EXPORT addressList : public headerFieldValue
{
public:
addressList();
@ -71,7 +69,10 @@ public:
* @param addr address to insert
* @throw std::out_of_range if the address is not in the list
*/
void insertAddressBefore(const shared_ptr <address>& beforeAddress, const shared_ptr <address>& addr);
void insertAddressBefore(
const shared_ptr <address>& beforeAddress,
const shared_ptr <address>& addr
);
/** Insert a new address before the specified position.
*
@ -88,7 +89,10 @@ public:
* @param addr address to insert
* @throw std::out_of_range if the address is not in the list
*/
void insertAddressAfter(const shared_ptr <address>& afterAddress, const shared_ptr <address>& addr);
void insertAddressAfter(
const shared_ptr <address>& afterAddress,
const shared_ptr <address>& addr
);
/** Insert a new address after the specified position.
*
@ -171,18 +175,20 @@ private:
protected:
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -34,15 +34,13 @@
#include "vmime/encoding.hpp"
namespace vmime
{
namespace vmime {
/** Base class for all types of attachment.
*/
class VMIME_EXPORT attachment : public object {
class VMIME_EXPORT attachment : public object
{
friend class messageBuilder;
friend class messageParser;
friend class attachmentHelper;

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -33,36 +33,39 @@
#include <iterator>
namespace vmime
{
namespace vmime {
// static
bool attachmentHelper::isBodyPartAnAttachment
(const shared_ptr <const bodyPart>& part, const unsigned int options)
{
bool attachmentHelper::isBodyPartAnAttachment(
const shared_ptr <const bodyPart>& part,
const unsigned int options
) {
// First, try with "Content-Disposition" field.
// If not present, we will try with "Content-Type" field.
shared_ptr <const contentDispositionField> cdf =
part->getHeader()->findField <contentDispositionField>(fields::CONTENT_DISPOSITION);
if (cdf)
{
if (cdf) {
const contentDisposition disp = *cdf->getValue <contentDisposition>();
if (disp.getName() != contentDispositionTypes::INLINE)
if (disp.getName() != contentDispositionTypes::INLINE) {
return true;
}
if ((options & INLINE_OBJECTS) == 0) {
if ((options & INLINE_OBJECTS) == 0)
{
// If the Content-Disposition is 'inline' and there is no
// Content-Id or Content-Location field, it may be an attachment
if (!part->getHeader()->hasField(vmime::fields::CONTENT_ID) &&
!part->getHeader()->hasField(vmime::fields::CONTENT_LOCATION))
{
!part->getHeader()->hasField(vmime::fields::CONTENT_LOCATION)) {
// If this is the root part, it might not be an attachment
if (part->getParentPart() == NULL)
if (!part->getParentPart()) {
return false;
}
return true;
}
@ -78,40 +81,46 @@ bool attachmentHelper::isBodyPartAnAttachment
shared_ptr <const contentTypeField> ctf =
part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
if (ctf)
{
if (ctf) {
type = *ctf->getValue <mediaType>();
if (ctf->hasParameter("name"))
if (ctf->hasParameter("name")) {
hasContentTypeName = true;
}
else
{
}
} else {
// If this is the root part and no Content-Type field is present,
// then this may not be a MIME message, so do not assume it is
// an attachment
if (part->getParentPart() == NULL)
if (!part->getParentPart()) {
return false;
}
// No "Content-type" field: assume "application/octet-stream".
type = mediaType(mediaTypes::APPLICATION,
mediaTypes::APPLICATION_OCTET_STREAM);
type = mediaType(
mediaTypes::APPLICATION,
mediaTypes::APPLICATION_OCTET_STREAM
);
}
if (type.getType() != mediaTypes::TEXT &&
type.getType() != mediaTypes::MULTIPART)
{
type.getType() != mediaTypes::MULTIPART) {
// Compatibility with (obsolete) RFC-1341: if there is a "name" parameter
// on the "Content-Type" field, then we assume it is an attachment
if (hasContentTypeName)
if (hasContentTypeName) {
return true;
}
if ((options & INLINE_OBJECTS) == 0) {
if ((options & INLINE_OBJECTS) == 0)
{
// If a "Content-Id" field is present, it might be an
// embedded object (MHTML messages)
if (part->getHeader()->hasField(vmime::fields::CONTENT_ID))
if (part->getHeader()->hasField(vmime::fields::CONTENT_ID)) {
return false;
}
}
return true;
@ -122,35 +131,40 @@ bool attachmentHelper::isBodyPartAnAttachment
// static
shared_ptr <const attachment> attachmentHelper::getBodyPartAttachment
(const shared_ptr <const bodyPart>& part, const unsigned int options)
{
if (!isBodyPartAnAttachment(part, options))
shared_ptr <const attachment> attachmentHelper::getBodyPartAttachment(
const shared_ptr <const bodyPart>& part,
const unsigned int options
) {
if (!isBodyPartAnAttachment(part, options)) {
return null;
}
mediaType type;
shared_ptr <const contentTypeField> ctf =
part->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
if (ctf)
{
if (ctf) {
type = *ctf->getValue <mediaType>();
}
else
{
} else {
// No "Content-type" field: assume "application/octet-stream".
type = mediaType(mediaTypes::APPLICATION,
mediaTypes::APPLICATION_OCTET_STREAM);
type = mediaType(
mediaTypes::APPLICATION,
mediaTypes::APPLICATION_OCTET_STREAM
);
}
if (type.getType() == mediaTypes::MESSAGE &&
type.getSubType() == mediaTypes::MESSAGE_RFC822)
{
type.getSubType() == mediaTypes::MESSAGE_RFC822) {
return make_shared <generatedMessageAttachment>(part);
}
else
{
} else {
return make_shared <bodyPartAttachment>(part);
}
}
@ -158,32 +172,36 @@ shared_ptr <const attachment> attachmentHelper::getBodyPartAttachment
// static
const std::vector <shared_ptr <const attachment> >
attachmentHelper::findAttachmentsInMessage
(const shared_ptr <const message>& msg, const unsigned int options)
{
attachmentHelper::findAttachmentsInMessage(
const shared_ptr <const message>& msg,
const unsigned int options
) {
return findAttachmentsInBodyPart(msg, options);
}
// static
const std::vector <shared_ptr <const attachment> >
attachmentHelper::findAttachmentsInBodyPart
(const shared_ptr <const bodyPart>& part, const unsigned int options)
{
attachmentHelper::findAttachmentsInBodyPart(
const shared_ptr <const bodyPart>& part,
const unsigned int options
) {
std::vector <shared_ptr <const attachment> > atts;
// Test this part
if (isBodyPartAnAttachment(part, options))
{
if (isBodyPartAnAttachment(part, options)) {
atts.push_back(getBodyPartAttachment(part, options));
}
// Find in sub-parts
else
{
} else {
shared_ptr <const body> bdy = part->getBody();
for (size_t i = 0 ; i < bdy->getPartCount() ; ++i)
{
for (size_t i = 0 ; i < bdy->getPartCount() ; ++i) {
std::vector <shared_ptr <const attachment> > partAtts =
findAttachmentsInBodyPart(bdy->getPartAt(i), options);
@ -196,35 +214,39 @@ const std::vector <shared_ptr <const attachment> >
// static
void attachmentHelper::addAttachment(const shared_ptr <message>& msg, const shared_ptr <attachment>& att)
{
void attachmentHelper::addAttachment(const shared_ptr <message>& msg, const shared_ptr <attachment>& att) {
// We simply search for a "multipart/mixed" part. If no one exists,
// create it in the root part. This (very simple) algorithm should
// work in the most cases.
vmime::mediaType mpMixed(vmime::mediaTypes::MULTIPART,
vmime::mediaTypes::MULTIPART_MIXED);
vmime::mediaType mpMixed(
vmime::mediaTypes::MULTIPART,
vmime::mediaTypes::MULTIPART_MIXED
);
shared_ptr <bodyPart> part = findBodyPart(msg, mpMixed);
if (part == NULL) // create it
{
if (msg->getBody()->getPartCount() != 0)
{
if (!part) { // create it
if (msg->getBody()->getPartCount() != 0) {
// Create a new container part for the parts that were in
// the root part of the message
shared_ptr <bodyPart> container = make_shared <bodyPart>();
if (msg->getHeader()->hasField(fields::CONTENT_TYPE))
{
container->getHeader()->ContentType()->setValue
(msg->getHeader()->ContentType()->getValue());
if (msg->getHeader()->hasField(fields::CONTENT_TYPE)) {
container->getHeader()->ContentType()->setValue(
msg->getHeader()->ContentType()->getValue()
);
}
if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING))
{
container->getHeader()->ContentTransferEncoding()->setValue
(msg->getHeader()->ContentTransferEncoding()->getValue());
if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING)) {
container->getHeader()->ContentTransferEncoding()->setValue(
msg->getHeader()->ContentTransferEncoding()->getValue()
);
}
// Move parts from the root part to this new part
@ -233,28 +255,31 @@ void attachmentHelper::addAttachment(const shared_ptr <message>& msg, const shar
msg->getBody()->removeAllParts();
for (unsigned int i = 0 ; i < partList.size() ; ++i)
for (unsigned int i = 0 ; i < partList.size() ; ++i) {
container->getBody()->appendPart(partList[i]);
}
msg->getBody()->appendPart(container);
}
else
{
} else {
// The message is a simple (RFC-822) message, and do not
// contains any MIME part. Move the contents from the
// root to a new child part.
shared_ptr <bodyPart> child = make_shared <bodyPart>();
if (msg->getHeader()->hasField(fields::CONTENT_TYPE))
{
child->getHeader()->ContentType()->setValue
(msg->getHeader()->ContentType()->getValue());
if (msg->getHeader()->hasField(fields::CONTENT_TYPE)) {
child->getHeader()->ContentType()->setValue(
msg->getHeader()->ContentType()->getValue()
);
}
if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING))
{
child->getHeader()->ContentTransferEncoding()->setValue
(msg->getHeader()->ContentTransferEncoding()->getValue());
if (msg->getHeader()->hasField(fields::CONTENT_TRANSFER_ENCODING)) {
child->getHeader()->ContentTransferEncoding()->setValue(
msg->getHeader()->ContentTransferEncoding()->getValue()
);
}
child->getBody()->setContents(msg->getBody()->getContents());
@ -278,22 +303,25 @@ void attachmentHelper::addAttachment(const shared_ptr <message>& msg, const shar
// static
shared_ptr <bodyPart> attachmentHelper::findBodyPart
(const shared_ptr <bodyPart>& part, const mediaType& type)
{
if (part->getBody()->getContentType() == type)
shared_ptr <bodyPart> attachmentHelper::findBodyPart(
const shared_ptr <bodyPart>& part,
const mediaType& type
) {
if (part->getBody()->getContentType() == type) {
return part;
}
// Try in sub-parts
shared_ptr <body> bdy = part->getBody();
for (size_t i = 0 ; i < bdy->getPartCount() ; ++i)
{
shared_ptr <bodyPart> found =
findBodyPart(bdy->getPartAt(i), type);
for (size_t i = 0 ; i < bdy->getPartCount() ; ++i) {
if (found != NULL)
shared_ptr <bodyPart> found = findBodyPart(bdy->getPartAt(i), type);
if (found) {
return found;
}
}
return null;
@ -301,12 +329,11 @@ shared_ptr <bodyPart> attachmentHelper::findBodyPart
// static
void attachmentHelper::addAttachment(const shared_ptr <message>& msg, const shared_ptr <message>& amsg)
{
void attachmentHelper::addAttachment(const shared_ptr <message>& msg, const shared_ptr <message>& amsg) {
shared_ptr <attachment> att = make_shared <parsedMessageAttachment>(amsg);
addAttachment(msg, att);
}
} // vmime

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -31,14 +31,13 @@
#include "vmime/message.hpp"
namespace vmime
{
namespace vmime {
/** Retrieve attachment information from message parts.
*/
class VMIME_EXPORT attachmentHelper
{
class VMIME_EXPORT attachmentHelper {
public:
/** Options for use with the following functions:
@ -46,8 +45,7 @@ public:
* getBodyPartAttachment,
* and isBodyPartAnAttachment.
*/
enum FindOptions
{
enum FindOptions {
INLINE_OBJECTS = (1 << 0) /**< Recognize and return inline objects. The aim is to
consider MHTML objects (parts with a "Content-Id" or
a "Content-Location", such as inline images) as attachments. */
@ -59,7 +57,10 @@ public:
* @param options search options (see FindOptions)
* @return true if the part is an attachment, false otherwise
*/
static bool isBodyPartAnAttachment(const shared_ptr <const bodyPart>& part, const unsigned int options = 0);
static bool isBodyPartAnAttachment(
const shared_ptr <const bodyPart>& part,
const unsigned int options = 0
);
/** Return attachment information in the specified body part.
* If the specified body part does not contain attachment
@ -69,8 +70,10 @@ public:
* @param options search options (see FindOptions)
* @return attachment found in the part, or NULL
*/
static shared_ptr <const attachment>
getBodyPartAttachment(const shared_ptr <const bodyPart>& part, const unsigned int options = 0);
static shared_ptr <const attachment> getBodyPartAttachment(
const shared_ptr <const bodyPart>& part,
const unsigned int options = 0
);
/** Find all attachments contained in the specified part
* and all its children parts.
@ -81,7 +84,10 @@ public:
* @return a list of attachments found
*/
static const std::vector <shared_ptr <const attachment> >
findAttachmentsInBodyPart(const shared_ptr <const bodyPart>& part, const unsigned int options = 0);
findAttachmentsInBodyPart(
const shared_ptr <const bodyPart>& part,
const unsigned int options = 0
);
/** Find all attachments contained in the specified message.
* This is simply a recursive call to getBodyPartAttachment().
@ -91,26 +97,37 @@ public:
* @return a list of attachments found
*/
static const std::vector <shared_ptr <const attachment> >
findAttachmentsInMessage(const shared_ptr <const message>& msg, const unsigned int options = 0);
findAttachmentsInMessage(
const shared_ptr <const message>& msg,
const unsigned int options = 0
);
/** Add an attachment to the specified message.
*
* @param msg message into which to add the attachment
* @param att attachment to add
*/
static void addAttachment(const shared_ptr <message>& msg, const shared_ptr <attachment>& att);
static void addAttachment(
const shared_ptr <message>& msg,
const shared_ptr <attachment>& att
);
/** Add a message attachment to the specified message.
*
* @param msg message into which to add the attachment
* @param amsg message to attach
*/
static void addAttachment(const shared_ptr <message>& msg, const shared_ptr <message>& amsg);
static void addAttachment(
const shared_ptr <message>& msg,
const shared_ptr <message>& amsg
);
protected:
static shared_ptr <bodyPart> findBodyPart
(const shared_ptr <bodyPart>& part, const mediaType& type);
static shared_ptr <bodyPart> findBodyPart(
const shared_ptr <bodyPart>& part,
const mediaType& type
);
};
@ -118,4 +135,3 @@ protected:
#endif // VMIME_ATTACHMENTHELPER_HPP_INCLUDED

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -48,8 +48,7 @@
#endif
namespace vmime
{
namespace vmime {
/** "Null" (empty) string.
@ -108,8 +107,8 @@ nullPtrType null;
// Line length limits
namespace lineLengthLimits
{
namespace lineLengthLimits {
const size_t infinite = std::numeric_limits <size_t>::max();
}
@ -134,12 +133,10 @@ const size_t npos = std::numeric_limits <size_t>::max();
// constructor, for example).
//
class initializer
{
public:
struct initializer {
initializer() {
initializer()
{
parsingContext::getDefaultContext();
generationContext::getDefaultContext();

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -37,8 +37,8 @@
#include "vmime/constants.hpp"
namespace vmime
{
namespace vmime {
class text;
class word;
class charset;
@ -53,9 +53,9 @@ namespace vmime
#ifndef VMIME_BUILDING_DOC
// Null pointer
struct nullPtrType
{
template<typename T>
struct nullPtrType {
template <typename T>
operator shared_ptr <T>() { return shared_ptr <T>(); }
};
@ -78,47 +78,48 @@ namespace vmime
//
template <typename T, size_t N>
inline T const* cbegin(T const (&array)[N])
{
return (array);
inline T const* cbegin(T const (&array)[N]) {
return array;
}
template <typename T, size_t N>
inline T const* cend(T const (&array)[N])
{
return (array + N);
inline T const* cend(T const (&array)[N]) {
return array + N;
}
template <typename T, size_t N>
inline T* begin(T (&array)[N])
{
return (array);
inline T* begin(T (&array)[N]) {
return array;
}
template <typename T, size_t N>
inline T* end(T (&array)[N])
{
return (array + N);
inline T* end(T (&array)[N]) {
return array + N;
}
template <typename T, size_t N>
inline size_t count(T const (&/* array */)[N])
{
return (N);
inline size_t count(T const (&/* array */)[N]) {
return N;
}
// Copy one vector to another, with type conversion
template <class T1, class T2>
void copy_vector(const T1& v1, T2& v2)
{
void copy_vector(const T1& v1, T2& v2) {
const typename T1::size_type count = v1.size();
v2.resize(count);
for (typename T1::size_type i = 0 ; i < count ; ++i)
for (typename T1::size_type i = 0 ; i < count ; ++i) {
v2[i] = v1[i];
}
}
@ -154,12 +155,11 @@ namespace vmime
character limit) for the sake of robustness.
*/
namespace lineLengthLimits
{
namespace lineLengthLimits {
extern VMIME_EXPORT const size_t infinite;
enum
{
enum {
max = 998,
convenient = 78
};
@ -192,8 +192,8 @@ namespace vmime
* This is an alias for dynamic_pointer_cast <T>(obj->clone()).
*/
template <class T>
shared_ptr <T> clone(const shared_ptr <T>& obj)
{
shared_ptr <T> clone(const shared_ptr <T>& obj) {
return dynamic_pointer_cast <T>(obj->clone());
}
@ -201,8 +201,8 @@ namespace vmime
* This is an alias for dynamic_pointer_cast <T>(obj->clone()).
*/
template <class T>
shared_ptr <T> clone(const shared_ptr <const T>& obj)
{
shared_ptr <T> clone(const shared_ptr <const T>& obj) {
return dynamic_pointer_cast <T>(obj->clone());
}
@ -210,8 +210,8 @@ namespace vmime
* This is an alias for dynamic_pointer_cast <T>(obj.clone()).
*/
template <class T>
shared_ptr <T> clone(const T& obj)
{
shared_ptr <T> clone(const T& obj) {
return dynamic_pointer_cast <T>(obj.clone());
}
@ -220,24 +220,24 @@ namespace vmime
* type Type, and DerivedType is derived from Type.
*/
template <class X, class Y>
shared_ptr <X> dynamicCast(const shared_ptr <Y>& obj)
{
shared_ptr <X> dynamicCast(const shared_ptr <Y>& obj) {
return dynamic_pointer_cast <X, Y>(obj);
}
/** Const cast helper.
*/
template <class X, class Y>
shared_ptr <X> constCast(const shared_ptr <Y>& obj)
{
shared_ptr <X> constCast(const shared_ptr <Y>& obj) {
return const_pointer_cast <X, Y>(obj);
}
/** Inherit from this class to indicate the subclass is not copyable,
* ie. you want to prohibit copy construction and copy assignment.
*/
class VMIME_EXPORT noncopyable
{
class VMIME_EXPORT noncopyable {
protected:
noncopyable() { }

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -37,8 +37,7 @@
#include "vmime/contentHandler.hpp"
namespace vmime
{
namespace vmime {
class bodyPart;
@ -46,9 +45,8 @@ class bodyPart;
/** Body section of a MIME part.
*/
class VMIME_EXPORT body : public component {
class VMIME_EXPORT body : public component
{
friend class bodyPart;
public:
@ -68,7 +66,10 @@ public:
* @param part part to insert
* @throw exceptions::no_such_part if the part is not in the list
*/
void insertPartBefore(const shared_ptr <bodyPart>& beforePart, const shared_ptr <bodyPart>& part);
void insertPartBefore(
const shared_ptr <bodyPart>& beforePart,
const shared_ptr <bodyPart>& part
);
/** Insert a new part before the specified position.
*
@ -84,7 +85,10 @@ public:
* @param part part to insert
* @throw exceptions::no_such_part if the part is not in the list
*/
void insertPartAfter(const shared_ptr <bodyPart>& afterPart, const shared_ptr <bodyPart>& part);
void insertPartAfter(
const shared_ptr <bodyPart>& afterPart,
const shared_ptr <bodyPart>& part
);
/** Insert a new part after the specified position.
*
@ -189,7 +193,10 @@ public:
* @param contents new body contents
* @param type type of contents
*/
void setContents(const shared_ptr <const contentHandler>& contents, const mediaType& type);
void setContents(
const shared_ptr <const contentHandler>& contents,
const mediaType& type
);
/** Set the body contents, type and charset.
*
@ -197,7 +204,11 @@ public:
* @param type type of contents
* @param chset charset of contents
*/
void setContents(const shared_ptr <const contentHandler>& contents, const mediaType& type, const charset& chset);
void setContents(
const shared_ptr <const contentHandler>& contents,
const mediaType& type,
const charset& chset
);
/** Set the body contents, type, charset and encoding.
*
@ -206,8 +217,12 @@ public:
* @param chset charset of contents
* @param enc contents encoding
*/
void setContents(const shared_ptr <const contentHandler>& contents, const mediaType& type,
const charset& chset, const encoding& enc);
void setContents(
const shared_ptr <const contentHandler>& contents,
const mediaType& type,
const charset& chset,
const encoding& enc
);
/** Set the MIME type and charset of contents.
* If a charset is defined, it will not be modified.
@ -317,24 +332,30 @@ protected:
* before the CRLF or "--" which follows)
* @return the position of the boundary string, or npos if not found
*/
size_t findNextBoundaryPosition
(const shared_ptr <utility::parserInputStreamAdapter>& parser, const string& boundary,
const size_t position, const size_t end,
size_t* boundaryStart, size_t* boundaryEnd);
size_t findNextBoundaryPosition(
const shared_ptr <utility::parserInputStreamAdapter>& parser,
const string& boundary,
const size_t position,
const size_t end,
size_t* boundaryStart,
size_t* boundaryEnd
);
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
const shared_ptr <utility::parserInputStreamAdapter>& parser,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parseImpl(
const parsingContext& ctx,
const shared_ptr <utility::parserInputStreamAdapter>& parser,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -24,23 +24,26 @@
#include "vmime/bodyPart.hpp"
namespace vmime
{
namespace vmime {
bodyPart::bodyPart()
: m_header(make_shared <header>()),
m_body(make_shared <body>()),
m_parent()
{
m_parent() {
m_body->setParentPart(this);
}
void bodyPart::parseImpl
(const parsingContext& ctx, const shared_ptr <utility::parserInputStreamAdapter>& parser,
const size_t position, const size_t end, size_t* newPosition)
{
void bodyPart::parseImpl(
const parsingContext& ctx,
const shared_ptr <utility::parserInputStreamAdapter>& parser,
const size_t position,
const size_t end,
size_t* newPosition
) {
// Parse the headers
size_t pos = position;
m_header->parse(ctx, parser, pos, end, &pos);
@ -50,34 +53,39 @@ void bodyPart::parseImpl
setParsedBounds(position, end);
if (newPosition)
if (newPosition) {
*newPosition = end;
}
}
void bodyPart::generateImpl
(const generationContext& ctx, utility::outputStream& os,
const size_t /* curLinePos */, size_t* newLinePos) const
{
void bodyPart::generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t /* curLinePos */,
size_t* newLinePos
) const {
m_header->generate(ctx, os);
os << CRLF;
m_body->generate(ctx, os);
if (newLinePos)
if (newLinePos) {
*newLinePos = 0;
}
}
size_t bodyPart::getGeneratedSize(const generationContext& ctx)
{
size_t bodyPart::getGeneratedSize(const generationContext& ctx) {
return m_header->getGeneratedSize(ctx) + 2 /* CRLF */ + m_body->getGeneratedSize(ctx);
}
shared_ptr <component> bodyPart::clone() const
{
shared_ptr <component> bodyPart::clone() const {
shared_ptr <bodyPart> p = make_shared <bodyPart>();
p->m_parent = NULL;
@ -85,12 +93,12 @@ shared_ptr <component> bodyPart::clone() const
p->m_header->copyFrom(*m_header);
p->m_body->copyFrom(*m_body);
return (p);
return p;
}
void bodyPart::copyFrom(const component& other)
{
void bodyPart::copyFrom(const component& other) {
const bodyPart& bp = dynamic_cast <const bodyPart&>(other);
m_header->copyFrom(*(bp.m_header));
@ -98,70 +106,71 @@ void bodyPart::copyFrom(const component& other)
}
bodyPart& bodyPart::operator=(const bodyPart& other)
{
bodyPart& bodyPart::operator=(const bodyPart& other) {
copyFrom(other);
return (*this);
return *this;
}
const shared_ptr <const header> bodyPart::getHeader() const
{
return (m_header);
const shared_ptr <const header> bodyPart::getHeader() const {
return m_header;
}
shared_ptr <header> bodyPart::getHeader()
{
return (m_header);
shared_ptr <header> bodyPart::getHeader() {
return m_header;
}
void bodyPart::setHeader(const shared_ptr <header>& h)
{
void bodyPart::setHeader(const shared_ptr <header>& h) {
m_header = h;
}
const shared_ptr <const body> bodyPart::getBody() const
{
return (m_body);
const shared_ptr <const body> bodyPart::getBody() const {
return m_body;
}
shared_ptr <body> bodyPart::getBody()
{
return (m_body);
shared_ptr <body> bodyPart::getBody() {
return m_body;
}
void bodyPart::setBody(const shared_ptr <body>& b)
{
void bodyPart::setBody(const shared_ptr <body>& b) {
bodyPart* oldPart = b->m_part;
m_body = b;
m_body->setParentPart(this);
// A body is associated to one and only one part
if (oldPart != NULL)
if (oldPart) {
oldPart->setBody(make_shared <body>());
}
}
bodyPart* bodyPart::getParentPart()
{
bodyPart* bodyPart::getParentPart() {
return m_parent;
}
const bodyPart* bodyPart::getParentPart() const
{
const bodyPart* bodyPart::getParentPart() const {
return m_parent;
}
shared_ptr <bodyPart> bodyPart::createChildPart()
{
shared_ptr <bodyPart> bodyPart::createChildPart() {
shared_ptr <bodyPart> part = make_shared <bodyPart>();
part->m_parent = this;
@ -169,22 +178,21 @@ shared_ptr <bodyPart> bodyPart::createChildPart()
}
void bodyPart::importChildPart(const shared_ptr <bodyPart>& part)
{
void bodyPart::importChildPart(const shared_ptr <bodyPart>& part) {
part->m_parent = this;
}
const std::vector <shared_ptr <component> > bodyPart::getChildComponents()
{
const std::vector <shared_ptr <component> > bodyPart::getChildComponents() {
std::vector <shared_ptr <component> > list;
list.push_back(m_header);
list.push_back(m_body);
return (list);
return list;
}
} // vmime

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -32,15 +32,13 @@
#include "vmime/body.hpp"
namespace vmime
{
namespace vmime {
/** A MIME part.
*/
class VMIME_EXPORT bodyPart : public component {
class VMIME_EXPORT bodyPart : public component
{
friend class body;
public:
@ -134,18 +132,20 @@ protected:
void importChildPart(const shared_ptr <bodyPart>& part);
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
const shared_ptr <utility::parserInputStreamAdapter>& parser,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parseImpl(
const parsingContext& ctx,
const shared_ptr <utility::parserInputStreamAdapter>& parser,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -24,55 +24,57 @@
#include "vmime/bodyPartAttachment.hpp"
namespace vmime
{
namespace vmime {
bodyPartAttachment::bodyPartAttachment(const shared_ptr <const bodyPart>& part)
: m_part(part)
{
: m_part(part) {
}
const mediaType bodyPartAttachment::getType() const
{
const mediaType bodyPartAttachment::getType() const {
shared_ptr <const contentTypeField> ctf = getContentType();
if (ctf)
{
if (ctf) {
return *ctf->getValue <mediaType>();
}
else
{
} else {
// No "Content-type" field: assume "application/octet-stream".
return mediaType(mediaTypes::APPLICATION,
mediaTypes::APPLICATION_OCTET_STREAM);
return mediaType(
mediaTypes::APPLICATION,
mediaTypes::APPLICATION_OCTET_STREAM
);
}
}
const word bodyPartAttachment::getName() const
{
const word bodyPartAttachment::getName() const {
word name;
// Try the 'filename' parameter of 'Content-Disposition' field
shared_ptr <const contentDispositionField> cdf = getContentDisposition();
if (cdf && cdf->hasFilename())
{
if (cdf && cdf->hasFilename()) {
name = cdf->getFilename();
}
// Try the 'name' parameter of 'Content-Type' field
else
{
} else {
shared_ptr <const contentTypeField> ctf = getContentType();
if (ctf)
{
if (ctf) {
shared_ptr <const parameter> prm = ctf->findParameter("name");
if (prm != NULL)
if (prm) {
name = prm->getValue();
}
}
}
@ -80,19 +82,19 @@ const word bodyPartAttachment::getName() const
}
const text bodyPartAttachment::getDescription() const
{
const text bodyPartAttachment::getDescription() const {
text description;
shared_ptr <const headerField> cd =
getHeader()->findField(fields::CONTENT_DESCRIPTION);
if (cd)
{
if (cd) {
description = *cd->getValue <text>();
}
else
{
} else {
// No description available.
}
@ -100,47 +102,46 @@ const text bodyPartAttachment::getDescription() const
}
const encoding bodyPartAttachment::getEncoding() const
{
const encoding bodyPartAttachment::getEncoding() const {
return m_part->getBody()->getEncoding();
}
const shared_ptr <const contentHandler> bodyPartAttachment::getData() const
{
const shared_ptr <const contentHandler> bodyPartAttachment::getData() const {
return m_part->getBody()->getContents();
}
shared_ptr <const object> bodyPartAttachment::getPart() const
{
shared_ptr <const object> bodyPartAttachment::getPart() const {
return m_part;
}
shared_ptr <const header> bodyPartAttachment::getHeader() const
{
shared_ptr <const header> bodyPartAttachment::getHeader() const {
return m_part->getHeader();
}
shared_ptr <const contentDispositionField> bodyPartAttachment::getContentDisposition() const
{
shared_ptr <const contentDispositionField> bodyPartAttachment::getContentDisposition() const {
return getHeader()->findField <contentDispositionField>(fields::CONTENT_DISPOSITION);
}
shared_ptr <const contentTypeField> bodyPartAttachment::getContentType() const
{
shared_ptr <const contentTypeField> bodyPartAttachment::getContentType() const {
return getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
}
void bodyPartAttachment::generateIn(const shared_ptr <bodyPart>& /* parent */) const
{
void bodyPartAttachment::generateIn(const shared_ptr <bodyPart>& /* parent */) const {
// Not used
}
} // vmime

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -34,14 +34,13 @@
#include "vmime/contentTypeField.hpp"
namespace vmime
{
namespace vmime {
/** An attachment related to a local body part.
*/
class VMIME_EXPORT bodyPartAttachment : public attachment
{
class VMIME_EXPORT bodyPartAttachment : public attachment {
public:
bodyPartAttachment(const shared_ptr <const bodyPart>& part);
@ -75,4 +74,3 @@ private:
#endif // VMIME_BODYPARTATTACHMENT_HPP_INCLUDED

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -32,74 +32,93 @@
namespace vmime
{
namespace vmime {
charset::charset()
: m_name(charsets::US_ASCII)
{
: m_name(charsets::US_ASCII) {
}
charset::charset(const string& name)
: m_name(name)
{
: m_name(name) {
// If we receive this rfc-1642 valid MIME charset, convert it to something usefull for iconv
if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7"))
if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7")) {
m_name = "utf-7";
}
}
charset::charset(const char* name)
: m_name(name)
{
: m_name(name) {
}
void charset::parseImpl
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
m_name = utility::stringUtils::trim
(string(buffer.begin() + position, buffer.begin() + end));
void charset::parseImpl(
const parsingContext& /* ctx */,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
m_name = utility::stringUtils::trim(
string(buffer.begin() + position, buffer.begin() + end)
);
// If we parsed this rfc-1642 valid MIME charset, convert it to something usefull for iconv
if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7"))
if (utility::stringUtils::isStringEqualNoCase(m_name, "unicode-1-1-utf-7")) {
m_name = "utf-7";
}
setParsedBounds(position, end);
if (newPosition)
if (newPosition) {
*newPosition = end;
}
}
void charset::generateImpl
(const generationContext& /* ctx */, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
void charset::generateImpl(
const generationContext& /* ctx */,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
os << m_name;
if (newLinePos)
if (newLinePos) {
*newLinePos = curLinePos + m_name.length();
}
}
void charset::convert(utility::inputStream& in, utility::outputStream& out,
const charset& source, const charset& dest,
const charsetConverterOptions& opts)
{
void charset::convert(
utility::inputStream& in,
utility::outputStream& out,
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
) {
shared_ptr <charsetConverter> conv = charsetConverter::create(source, dest, opts);
conv->convert(in, out);
}
void charset::convert(const string& in, string& out, const charset& source, const charset& dest,
const charsetConverterOptions& opts)
{
if (source == dest)
{
void charset::convert(
const string& in,
string& out,
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
) {
if (source == dest) {
out = in;
return;
}
@ -109,27 +128,26 @@ void charset::convert(const string& in, string& out, const charset& source, cons
}
bool charset::isValidText
(const string& text, string::size_type* firstInvalidByte) const
{
bool charset::isValidText(const string& text, string::size_type* firstInvalidByte) const {
charsetConverterOptions opts;
opts.silentlyReplaceInvalidSequences = false;
charsetConverter::status st;
try
{
try {
std::string out;
// Try converting to UTF-8
shared_ptr <charsetConverter> conv = charsetConverter::create(*this, vmime::charset("utf-8"), opts);
conv->convert(text, out, &st);
}
catch (exceptions::illegal_byte_sequence_for_charset& e)
{
} catch (exceptions::illegal_byte_sequence_for_charset& e) {
// An illegal byte sequence was found in the input buffer
if (firstInvalidByte)
{
if (firstInvalidByte) {
if (st.inputBytesRead < text.length())
*firstInvalidByte = st.inputBytesRead;
else
@ -139,77 +157,79 @@ bool charset::isValidText
return false;
}
if (firstInvalidByte)
if (firstInvalidByte) {
*firstInvalidByte = text.length();
}
return true;
}
const charset charset::getLocalCharset()
{
return (platform::getHandler()->getLocalCharset());
const charset charset::getLocalCharset() {
return platform::getHandler()->getLocalCharset();
}
charset& charset::operator=(const charset& other)
{
charset& charset::operator=(const charset& other) {
copyFrom(other);
return (*this);
return *this;
}
bool charset::operator==(const charset& value) const
{
return (utility::stringUtils::isStringEqualNoCase(m_name, value.m_name));
bool charset::operator==(const charset& value) const {
return utility::stringUtils::isStringEqualNoCase(m_name, value.m_name);
}
bool charset::operator!=(const charset& value) const
{
bool charset::operator!=(const charset& value) const {
return !(*this == value);
}
shared_ptr <component> charset::clone() const
{
shared_ptr <component> charset::clone() const {
return make_shared <charset>(m_name);
}
const string& charset::getName() const
{
return (m_name);
const string& charset::getName() const {
return m_name;
}
void charset::copyFrom(const component& other)
{
void charset::copyFrom(const component& other) {
m_name = dynamic_cast <const charset&>(other).m_name;
}
const std::vector <shared_ptr <component> > charset::getChildComponents()
{
const std::vector <shared_ptr <component> > charset::getChildComponents() {
return std::vector <shared_ptr <component> >();
}
// Explicitly force encoding for some charsets
struct CharsetEncodingEntry
{
struct CharsetEncodingEntry {
CharsetEncodingEntry(const string& charset_, const string& encoding_)
: charset(charset_), encoding(encoding_)
{
: charset(charset_), encoding(encoding_) {
}
const string charset;
const string encoding;
};
CharsetEncodingEntry g_charsetEncodingMap[] =
{
CharsetEncodingEntry g_charsetEncodingMap[] = {
// Use QP encoding for ISO-8859-x charsets
CharsetEncodingEntry("iso-8859", encodingTypes::QUOTED_PRINTABLE),
CharsetEncodingEntry("iso8859", encodingTypes::QUOTED_PRINTABLE),
@ -226,15 +246,16 @@ CharsetEncodingEntry g_charsetEncodingMap[] =
};
bool charset::getRecommendedEncoding(encoding& enc) const
{
bool charset::getRecommendedEncoding(encoding& enc) const {
// Special treatment for some charsets
const string cset = utility::stringUtils::toLower(getName());
for (unsigned int i = 0 ; i < (sizeof(g_charsetEncodingMap) / sizeof(g_charsetEncodingMap[0])) - 1 ; ++i)
{
if (cset.find(g_charsetEncodingMap[i].charset) != string::npos)
{
for (unsigned int i = 0 ;
i < (sizeof(g_charsetEncodingMap) / sizeof(g_charsetEncodingMap[0])) - 1 ;
++i) {
if (cset.find(g_charsetEncodingMap[i].charset) != string::npos) {
enc = g_charsetEncodingMap[i].encoding;
return true;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -32,8 +32,7 @@
#include "vmime/component.hpp"
namespace vmime
{
namespace vmime {
class encoding; // forward reference
@ -41,9 +40,8 @@ class encoding; // forward reference
/** Charset description (basic type).
*/
class VMIME_EXPORT charset : public component {
class VMIME_EXPORT charset : public component
{
public:
charset();
@ -102,9 +100,13 @@ public:
* @throws exceptions::charset_conv_error if an unexpected error occurred
* during the conversion
*/
static void convert(const string& in, string& out,
const charset& source, const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions());
static void convert(
const string& in,
string& out,
const charset& source,
const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions()
);
/** Convert the contents of an input stream in a specified charset
* to another charset and write the result to an output stream.
@ -121,9 +123,13 @@ public:
* @throws exceptions::charset_conv_error if an unexpected error occurred
* during the conversion
*/
static void convert(utility::inputStream& in, utility::outputStream& out,
const charset& source, const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions());
static void convert(
utility::inputStream& in,
utility::outputStream& out,
const charset& source,
const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions()
);
/** Checks whether the specified text is valid in this charset.
*
@ -147,18 +153,20 @@ private:
protected:
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -26,25 +26,26 @@
#include "vmime/charsetConverter_idna.hpp"
namespace vmime
{
namespace vmime {
// static
shared_ptr <charsetConverter> charsetConverter::create
(const charset& source, const charset& dest,
const charsetConverterOptions& opts)
{
if (source == "idna" || dest == "idna")
shared_ptr <charsetConverter> charsetConverter::create(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
) {
if (source == "idna" || dest == "idna") {
return make_shared <charsetConverter_idna>(source, dest, opts);
else
} else {
return createGenericConverter(source, dest, opts);
}
}
charsetConverter::status::status()
: inputBytesRead(0), outputBytesWritten(0)
{
: inputBytesRead(0), outputBytesWritten(0) {
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -33,12 +33,10 @@
#include "vmime/utility/filteredStream.hpp"
namespace vmime
{
namespace vmime {
namespace utility
{
namespace utility {
/** A filtered output stream which applies a charset conversion
@ -52,9 +50,8 @@ namespace utility
* 'silentlyReplaceInvalidSequences' flag is set to false in
* the charsetConverterOptions.
*/
class VMIME_EXPORT charsetFilteredOutputStream : public filteredOutputStream {
class VMIME_EXPORT charsetFilteredOutputStream : public filteredOutputStream
{
};
@ -63,15 +60,14 @@ class VMIME_EXPORT charsetFilteredOutputStream : public filteredOutputStream
/** Convert between charsets.
*/
class VMIME_EXPORT charsetConverter : public object {
class VMIME_EXPORT charsetConverter : public object
{
public:
/** Holds information about a conversion.
*/
struct status
{
struct status {
status();
@ -91,9 +87,11 @@ public:
* @param dest output charset
* @param opts conversion options
*/
static shared_ptr <charsetConverter> create
(const charset& source, const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions());
static shared_ptr <charsetConverter> create(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions()
);
/** Convert a string buffer from one charset to another
* charset (in-memory conversion)
@ -128,7 +126,11 @@ public:
* @throws exceptions::charset_conv_error if an unexpected error occurred
* during the conversion
*/
virtual void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL) = 0;
virtual void convert(
utility::inputStream& in,
utility::outputStream& out,
status* st = NULL
) = 0;
/** Returns a filtered output stream which applies a charset
* conversion to input bytes. Please note that it may not be
@ -138,15 +140,19 @@ public:
* @param opts conversion options
* @return a filtered output stream, or NULL if not supported
*/
virtual shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream
(utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions()) = 0;
virtual shared_ptr <utility::charsetFilteredOutputStream>
getFilteredOutputStream(
utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions()
) = 0;
private:
static shared_ptr <charsetConverter> createGenericConverter
(const charset& source, const charset& dest,
const charsetConverterOptions& opts);
static shared_ptr <charsetConverter> createGenericConverter(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
);
};

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -24,14 +24,13 @@
#include "vmime/charsetConverterOptions.hpp"
namespace vmime
{
namespace vmime {
charsetConverterOptions::charsetConverterOptions()
: silentlyReplaceInvalidSequences(true),
invalidSequence("?")
{
invalidSequence("?") {
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -28,15 +28,13 @@
#include "vmime/base.hpp"
namespace vmime
{
namespace vmime {
/** Options for charset conversion.
*/
class VMIME_EXPORT charsetConverterOptions : public object {
class VMIME_EXPORT charsetConverterOptions : public object
{
public:
charsetConverterOptions();

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -34,8 +34,8 @@
#include "vmime/utility/outputStreamStringAdapter.hpp"
extern "C"
{
extern "C" {
#ifndef VMIME_BUILDING_DOC
#include <iconv.h>
@ -45,8 +45,8 @@ extern "C"
// second parameter may or may not be 'const'). This relies on the compiler
// for choosing the right type.
class ICONV_IN_TYPE
{
class ICONV_IN_TYPE {
public:
ICONV_IN_TYPE(const char** ptr) : m_ptr(ptr) { }
@ -62,8 +62,8 @@ extern "C"
const char** m_ptr;
};
class ICONV_OUT_TYPE
{
class ICONV_OUT_TYPE {
public:
ICONV_OUT_TYPE(char** ptr) : m_ptr(ptr) { }
@ -85,9 +85,12 @@ extern "C"
// Output replacement char when an invalid sequence is encountered
template <typename OUTPUT_CLASS, typename ICONV_DESC>
void outputInvalidChar(OUTPUT_CLASS& out, ICONV_DESC cd,
const vmime::charsetConverterOptions& opts = vmime::charsetConverterOptions())
{
void outputInvalidChar(
OUTPUT_CLASS& out,
ICONV_DESC cd,
const vmime::charsetConverterOptions& opts = vmime::charsetConverterOptions()
) {
const char* invalidCharIn = opts.invalidSequence.c_str();
vmime::size_t invalidCharInLen = opts.invalidSequence.length();
@ -96,36 +99,43 @@ void outputInvalidChar(OUTPUT_CLASS& out, ICONV_DESC cd,
vmime::size_t invalidCharOutLen = 16;
if (iconv(cd, ICONV_IN_TYPE(&invalidCharIn), &invalidCharInLen,
ICONV_OUT_TYPE(&invalidCharOutPtr), &invalidCharOutLen) != static_cast <size_t>(-1))
{
ICONV_OUT_TYPE(&invalidCharOutPtr), &invalidCharOutLen) != static_cast <size_t>(-1)) {
out.write(invalidCharOutBuffer, 16 - invalidCharOutLen);
}
}
namespace vmime
{
namespace vmime {
// static
shared_ptr <charsetConverter> charsetConverter::createGenericConverter
(const charset& source, const charset& dest,
const charsetConverterOptions& opts)
{
shared_ptr <charsetConverter> charsetConverter::createGenericConverter(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
) {
return make_shared <charsetConverter_iconv>(source, dest, opts);
}
charsetConverter_iconv::charsetConverter_iconv
(const charset& source, const charset& dest, const charsetConverterOptions& opts)
: m_desc(NULL), m_source(source), m_dest(dest), m_options(opts)
{
charsetConverter_iconv::charsetConverter_iconv(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
)
: m_desc(NULL),
m_source(source),
m_dest(dest),
m_options(opts) {
// Get an iconv descriptor
const iconv_t cd = iconv_open(dest.getName().c_str(), source.getName().c_str());
if (cd != reinterpret_cast <iconv_t>(-1))
{
if (cd != reinterpret_cast <iconv_t>(-1)) {
iconv_t* p = new iconv_t;
*p= cd;
@ -134,10 +144,10 @@ charsetConverter_iconv::charsetConverter_iconv
}
charsetConverter_iconv::~charsetConverter_iconv()
{
if (m_desc != NULL)
{
charsetConverter_iconv::~charsetConverter_iconv() {
if (m_desc) {
// Close iconv handle
iconv_close(*static_cast <iconv_t*>(m_desc));
@ -147,14 +157,19 @@ charsetConverter_iconv::~charsetConverter_iconv()
}
void charsetConverter_iconv::convert
(utility::inputStream& in, utility::outputStream& out, status* st)
{
if (st)
new (st) status();
void charsetConverter_iconv::convert(
utility::inputStream& in,
utility::outputStream& out,
status* st
) {
if (m_desc == NULL)
if (st) {
new (st) status();
}
if (!m_desc) {
throw exceptions::charset_conv_error("Cannot initialize converter.");
}
const iconv_t cd = *static_cast <iconv_t*>(m_desc);
@ -165,8 +180,8 @@ void charsetConverter_iconv::convert
bool prevIsInvalid = false;
bool breakAfterNext = false;
while (true)
{
while (true) {
// Fullfill the buffer
size_t inLength = static_cast <size_t>(in.read(inBuffer + inPos, sizeof(inBuffer) - inPos) + inPos);
size_t outLength = sizeof(outBuffer);
@ -177,23 +192,23 @@ void charsetConverter_iconv::convert
// Convert input bytes
if (iconv(cd, ICONV_IN_TYPE(&inPtr), ptrLength,
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1))
{
if (st && inPtr)
{
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1)) {
if (st && inPtr) {
st->inputBytesRead += (inPtr - inBuffer);
st->outputBytesWritten += (outPtr - outBuffer);
}
// Illegal input sequence or input sequence has no equivalent
// sequence in the destination charset.
if (prevIsInvalid)
{
if (prevIsInvalid) {
// Write successfully converted bytes
out.write(outBuffer, sizeof(outBuffer) - outLength);
if (!m_options.silentlyReplaceInvalidSequences)
if (!m_options.silentlyReplaceInvalidSequences) {
throw exceptions::illegal_byte_sequence_for_charset();
}
// Output a special character to indicate we don't known how to
// convert the sequence at this position
@ -202,9 +217,9 @@ void charsetConverter_iconv::convert
// Skip a byte and leave unconverted bytes in the input buffer
std::copy(const_cast <byte_t*>(inPtr + 1), inBuffer + sizeof(inBuffer), inBuffer);
inPos = inLength - 1;
}
else
{
} else {
// Write successfully converted bytes
out.write(outBuffer, sizeof(outBuffer) - outLength);
@ -212,17 +227,17 @@ void charsetConverter_iconv::convert
std::copy(const_cast <byte_t*>(inPtr), inBuffer + sizeof(inBuffer), inBuffer);
inPos = inLength;
if (errno != E2BIG)
if (errno != E2BIG) {
prevIsInvalid = true;
}
}
}
else
{
} else {
// Write successfully converted bytes
out.write(outBuffer, sizeof(outBuffer) - outLength);
if (st && inPtr)
{
if (st && inPtr) {
st->inputBytesRead += (inPtr - inBuffer);
st->outputBytesWritten += (outPtr - outBuffer);
}
@ -231,20 +246,23 @@ void charsetConverter_iconv::convert
prevIsInvalid = false;
}
if (breakAfterNext)
if (breakAfterNext) {
break;
}
// Check for end of data, loop again to flush stateful data from iconv
if (in.eof() && inPos == 0)
if (in.eof() && inPos == 0) {
breakAfterNext = true;
}
}
}
void charsetConverter_iconv::convert(const string& in, string& out, status* st)
{
if (st)
void charsetConverter_iconv::convert(const string& in, string& out, status* st) {
if (st) {
new (st) status();
}
out.clear();
@ -258,9 +276,11 @@ void charsetConverter_iconv::convert(const string& in, string& out, status* st)
shared_ptr <utility::charsetFilteredOutputStream>
charsetConverter_iconv::getFilteredOutputStream
(utility::outputStream& os, const charsetConverterOptions& opts)
{
charsetConverter_iconv::getFilteredOutputStream(
utility::outputStream& os,
const charsetConverterOptions& opts
) {
return make_shared <utility::charsetFilteredOutputStream_iconv>(m_source, m_dest, &os, opts);
}
@ -271,17 +291,23 @@ shared_ptr <utility::charsetFilteredOutputStream>
namespace utility {
charsetFilteredOutputStream_iconv::charsetFilteredOutputStream_iconv
(const charset& source, const charset& dest, outputStream* os,
const charsetConverterOptions& opts)
: m_desc(NULL), m_sourceCharset(source), m_destCharset(dest),
m_stream(*os), m_unconvCount(0), m_options(opts)
{
charsetFilteredOutputStream_iconv::charsetFilteredOutputStream_iconv(
const charset& source,
const charset& dest, outputStream* os,
const charsetConverterOptions& opts
)
: m_desc(NULL),
m_sourceCharset(source),
m_destCharset(dest),
m_stream(*os),
m_unconvCount(0),
m_options(opts) {
// Get an iconv descriptor
const iconv_t cd = iconv_open(dest.getName().c_str(), source.getName().c_str());
if (cd != reinterpret_cast <iconv_t>(-1))
{
if (cd != reinterpret_cast <iconv_t>(-1)) {
iconv_t* p = new iconv_t;
*p= cd;
@ -290,10 +316,10 @@ charsetFilteredOutputStream_iconv::charsetFilteredOutputStream_iconv
}
charsetFilteredOutputStream_iconv::~charsetFilteredOutputStream_iconv()
{
if (m_desc != NULL)
{
charsetFilteredOutputStream_iconv::~charsetFilteredOutputStream_iconv() {
if (m_desc) {
// Close iconv handle
iconv_close(*static_cast <iconv_t*>(m_desc));
@ -303,17 +329,20 @@ charsetFilteredOutputStream_iconv::~charsetFilteredOutputStream_iconv()
}
outputStream& charsetFilteredOutputStream_iconv::getNextOutputStream()
{
outputStream& charsetFilteredOutputStream_iconv::getNextOutputStream() {
return m_stream;
}
void charsetFilteredOutputStream_iconv::writeImpl
(const byte_t* const data, const size_t count)
{
if (m_desc == NULL)
void charsetFilteredOutputStream_iconv::writeImpl(
const byte_t* const data,
const size_t count
) {
if (!m_desc) {
throw exceptions::charset_conv_error("Cannot initialize converter.");
}
const iconv_t cd = *static_cast <iconv_t*>(m_desc);
@ -322,23 +351,26 @@ void charsetFilteredOutputStream_iconv::writeImpl
// If there is some unconverted bytes left, add more data from this
// chunk to see if it can now be converted.
while (m_unconvCount != 0 || curDataLen != 0)
{
if (m_unconvCount != 0)
{
while (m_unconvCount != 0 || curDataLen != 0) {
if (m_unconvCount != 0) {
// Check if an incomplete input sequence is larger than the
// input buffer size: should not happen except if something
// in the input sequence is invalid. If so, output a special
// character and skip one byte in the invalid sequence.
if (m_unconvCount >= sizeof(m_unconvBuffer))
{
if (!m_options.silentlyReplaceInvalidSequences)
if (m_unconvCount >= sizeof(m_unconvBuffer)) {
if (!m_options.silentlyReplaceInvalidSequences) {
throw exceptions::illegal_byte_sequence_for_charset();
}
outputInvalidChar(m_stream, cd);
std::copy(m_unconvBuffer + 1,
m_unconvBuffer + m_unconvCount, m_unconvBuffer);
std::copy(
m_unconvBuffer + 1,
m_unconvBuffer + m_unconvCount, m_unconvBuffer
);
m_unconvCount--;
}
@ -365,16 +397,18 @@ void charsetFilteredOutputStream_iconv::writeImpl
const size_t inLength0 = inLength;
if (iconv(cd, ICONV_IN_TYPE(&inPtr), &inLength,
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1))
{
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1)) {
const size_t inputConverted = inLength0 - inLength;
// Write successfully converted bytes
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
// Shift unconverted bytes
std::copy(m_unconvBuffer + inputConverted,
m_unconvBuffer + m_unconvCount, m_unconvBuffer);
std::copy(
m_unconvBuffer + inputConverted,
m_unconvBuffer + m_unconvCount, m_unconvBuffer
);
m_unconvCount -= inputConverted;
@ -388,8 +422,9 @@ void charsetFilteredOutputStream_iconv::writeImpl
m_unconvCount = 0;
}
if (curDataLen == 0)
if (curDataLen == 0) {
return; // no more data
}
// Now, convert the current data buffer
const byte_t* inPtr = curData;
@ -400,8 +435,8 @@ void charsetFilteredOutputStream_iconv::writeImpl
const size_t inLength0 = inLength;
if (iconv(cd, ICONV_IN_TYPE(&inPtr), &inLength,
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1))
{
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1)) {
// Write successfully converted bytes
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
@ -412,17 +447,17 @@ void charsetFilteredOutputStream_iconv::writeImpl
// Put one byte byte into the unconverted buffer so
// that the next iteration fill it
if (curDataLen != 0)
{
if (curDataLen != 0) {
m_unconvCount = 1;
m_unconvBuffer[0] = *curData;
curData++;
curDataLen--;
}
}
else
{
} else {
// Write successfully converted bytes
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
@ -433,18 +468,19 @@ void charsetFilteredOutputStream_iconv::writeImpl
}
void charsetFilteredOutputStream_iconv::flush()
{
if (m_desc == NULL)
void charsetFilteredOutputStream_iconv::flush() {
if (!m_desc) {
throw exceptions::charset_conv_error("Cannot initialize converter.");
}
const iconv_t cd = *static_cast <iconv_t*>(m_desc);
size_t offset = 0;
// Process unconverted bytes
while (m_unconvCount != 0)
{
while (m_unconvCount != 0) {
// Try a conversion
const byte_t* inPtr = m_unconvBuffer + offset;
size_t inLength = m_unconvCount;
@ -453,32 +489,34 @@ void charsetFilteredOutputStream_iconv::flush()
const size_t inLength0 = inLength;
if (iconv(cd, ICONV_IN_TYPE(&inPtr), &inLength, ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1))
{
if (iconv(cd, ICONV_IN_TYPE(&inPtr), &inLength,
ICONV_OUT_TYPE(&outPtr), &outLength) == static_cast <size_t>(-1)) {
const size_t inputConverted = inLength0 - inLength;
// Skip a "blocking" character
if (inputConverted == 0)
{
if (!m_options.silentlyReplaceInvalidSequences)
if (inputConverted == 0) {
if (!m_options.silentlyReplaceInvalidSequences) {
throw exceptions::illegal_byte_sequence_for_charset();
}
outputInvalidChar(m_stream, cd);
offset++;
m_unconvCount--;
}
else
{
} else {
// Write successfully converted bytes
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);
offset += inputConverted;
m_unconvCount -= inputConverted;
}
}
else
{
} else {
// Write successfully converted bytes
m_stream.write(m_outputBuffer, sizeof(m_outputBuffer) - outLength);

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -34,15 +34,13 @@
#include "vmime/charsetConverter.hpp"
namespace vmime
{
namespace vmime {
/** A generic charset converter which uses iconv library.
*/
class charsetConverter_iconv : public charsetConverter {
class charsetConverter_iconv : public charsetConverter
{
public:
/** Construct and initialize an iconv charset converter.
@ -51,17 +49,21 @@ public:
* @param dest output charset
* @param opts conversion options
*/
charsetConverter_iconv(const charset& source, const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions());
charsetConverter_iconv(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions()
);
~charsetConverter_iconv();
void convert(const string& in, string& out, status* st = NULL);
void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL);
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream
(utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions());
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(
utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions()
);
private:
@ -77,8 +79,8 @@ private:
namespace utility {
class charsetFilteredOutputStream_iconv : public charsetFilteredOutputStream
{
class charsetFilteredOutputStream_iconv : public charsetFilteredOutputStream {
public:
/** Construct a new filter for the specified output stream.
@ -88,9 +90,11 @@ public:
* @param os stream into which write filtered data
* @param opts conversion options
*/
charsetFilteredOutputStream_iconv
(const charset& source, const charset& dest, outputStream* os,
const charsetConverterOptions& opts = charsetConverterOptions());
charsetFilteredOutputStream_iconv(
const charset& source,
const charset& dest, outputStream* os,
const charsetConverterOptions& opts = charsetConverterOptions()
);
~charsetFilteredOutputStream_iconv();

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -34,8 +34,8 @@
#include "vmime/utility/outputStreamStringAdapter.hpp"
extern "C"
{
extern "C" {
#ifndef VMIME_BUILDING_DOC
#include <unicode/ucnv.h>
@ -48,59 +48,75 @@ extern "C"
#include <unicode/unistr.h>
namespace vmime
{
namespace vmime {
// static
shared_ptr <charsetConverter> charsetConverter::createGenericConverter
(const charset& source, const charset& dest,
const charsetConverterOptions& opts)
{
shared_ptr <charsetConverter> charsetConverter::createGenericConverter(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
) {
return make_shared <charsetConverter_icu>(source, dest, opts);
}
charsetConverter_icu::charsetConverter_icu
(const charset& source, const charset& dest, const charsetConverterOptions& opts)
: m_from(NULL), m_to(NULL), m_source(source), m_dest(dest), m_options(opts)
{
charsetConverter_icu::charsetConverter_icu(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
)
: m_from(NULL),
m_to(NULL),
m_source(source),
m_dest(dest),
m_options(opts) {
UErrorCode err = U_ZERO_ERROR;
m_from = ucnv_open(source.getName().c_str(), &err);
if (!U_SUCCESS(err))
{
throw exceptions::charset_conv_error
("Cannot initialize ICU converter for source charset '" + source.getName() + "' (error code: " + u_errorName(err) + ".");
if (!U_SUCCESS(err)) {
throw exceptions::charset_conv_error(
"Cannot initialize ICU converter for source charset '" + source.getName()
+ "' (error code: " + u_errorName(err) + "."
);
}
m_to = ucnv_open(dest.getName().c_str(), &err);
if (!U_SUCCESS(err))
{
throw exceptions::charset_conv_error
("Cannot initialize ICU converter for destination charset '" + dest.getName() + "' (error code: " + u_errorName(err) + ".");
if (!U_SUCCESS(err)) {
throw exceptions::charset_conv_error(
"Cannot initialize ICU converter for destination charset '" + dest.getName()
+ "' (error code: " + u_errorName(err) + "."
);
}
}
charsetConverter_icu::~charsetConverter_icu()
{
charsetConverter_icu::~charsetConverter_icu() {
if (m_from) ucnv_close(m_from);
if (m_to) ucnv_close(m_to);
}
void charsetConverter_icu::convert
(utility::inputStream& in, utility::outputStream& out, status* st)
{
void charsetConverter_icu::convert(
utility::inputStream& in,
utility::outputStream& out,
status* st
) {
UErrorCode err = U_ZERO_ERROR;
ucnv_reset(m_from);
ucnv_reset(m_to);
if (st)
if (st) {
new (st) status();
}
// From buffers
byte_t cpInBuffer[16]; // stream data put here
@ -113,34 +129,39 @@ void charsetConverter_icu::convert
std::vector <char> cpOutBuffer(cpOutBufferSz);
// Tell ICU what to do when encountering an illegal byte sequence
if (m_options.silentlyReplaceInvalidSequences)
{
if (m_options.silentlyReplaceInvalidSequences) {
// Set replacement chars for when converting from Unicode to codepage
icu::UnicodeString substString(m_options.invalidSequence.c_str());
ucnv_setSubstString(m_to, substString.getTerminatedBuffer(), -1, &err);
if (U_FAILURE(err))
if (U_FAILURE(err)) {
throw exceptions::charset_conv_error("[ICU] Error when setting substitution string.");
}
else
{
}
} else {
// Tell ICU top stop (and return an error) on illegal byte sequences
ucnv_setToUCallBack
(m_from, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err);
ucnv_setToUCallBack(
m_from, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err
);
if (U_FAILURE(err))
if (U_FAILURE(err)) {
throw exceptions::charset_conv_error("[ICU] Error when setting ToU callback.");
}
ucnv_setFromUCallBack
(m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err);
ucnv_setFromUCallBack(
m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err
);
if (U_FAILURE(err))
if (U_FAILURE(err)) {
throw exceptions::charset_conv_error("[ICU] Error when setting FromU callback.");
}
}
// Input data available
while (!in.eof())
{
while (!in.eof()) {
// Read input data into buffer
size_t inLength = in.read(cpInBuffer, sizeof(cpInBuffer));
@ -153,30 +174,36 @@ void charsetConverter_icu::convert
UErrorCode toErr;
// Loop until all source has been processed
do
{
do {
// Set up target pointers
UChar* target = &uOutBuffer[0];
UChar* targetLimit = &target[0] + outSize;
toErr = U_ZERO_ERROR;
ucnv_toUnicode(m_from, &target, targetLimit,
&source, sourceLimit, NULL, flush, &toErr);
if (st)
ucnv_toUnicode(
m_from, &target, targetLimit,
&source, sourceLimit, NULL, flush, &toErr
);
if (st) {
st->inputBytesRead += (source - reinterpret_cast <const char*>(&cpInBuffer[0]));
}
if (toErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(toErr)) {
if (toErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(toErr))
{
if (toErr == U_INVALID_CHAR_FOUND ||
toErr == U_TRUNCATED_CHAR_FOUND ||
toErr == U_ILLEGAL_CHAR_FOUND)
{
toErr == U_ILLEGAL_CHAR_FOUND) {
// Error will be thrown later (*)
}
else
{
throw exceptions::charset_conv_error("[ICU] Error converting to Unicode from " + m_source.getName());
} else {
throw exceptions::charset_conv_error(
"[ICU] Error converting to Unicode from " + m_source.getName()
);
}
}
@ -187,19 +214,21 @@ void charsetConverter_icu::convert
UErrorCode fromErr;
// Loop until converted chars are fully written
do
{
do {
char* cpTarget = &cpOutBuffer[0];
const char* cpTargetLimit = &cpOutBuffer[0] + cpOutBufferSz;
fromErr = U_ZERO_ERROR;
// Write converted bytes (Unicode) to destination codepage
ucnv_fromUnicode(m_to, &cpTarget, cpTargetLimit,
&uSource, uSourceLimit, NULL, flush, &fromErr);
ucnv_fromUnicode(
m_to, &cpTarget, cpTargetLimit,
&uSource, uSourceLimit, NULL, flush, &fromErr
);
if (st) {
if (st)
{
// Decrement input bytes count by the number of input bytes in error
char errBytes[16];
int8_t errBytesLen = sizeof(errBytes);
@ -214,22 +243,24 @@ void charsetConverter_icu::convert
// (*) If an error occurred while converting from input charset, throw it now
if (toErr == U_INVALID_CHAR_FOUND ||
toErr == U_TRUNCATED_CHAR_FOUND ||
toErr == U_ILLEGAL_CHAR_FOUND)
{
toErr == U_ILLEGAL_CHAR_FOUND) {
throw exceptions::illegal_byte_sequence_for_charset();
}
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr))
{
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr)) {
if (fromErr == U_INVALID_CHAR_FOUND ||
fromErr == U_TRUNCATED_CHAR_FOUND ||
fromErr == U_ILLEGAL_CHAR_FOUND)
{
fromErr == U_ILLEGAL_CHAR_FOUND) {
throw exceptions::illegal_byte_sequence_for_charset();
}
else
{
throw exceptions::charset_conv_error("[ICU] Error converting from Unicode to " + m_dest.getName());
} else {
throw exceptions::charset_conv_error(
"[ICU] Error converting from Unicode to " + m_dest.getName()
);
}
}
@ -243,10 +274,11 @@ void charsetConverter_icu::convert
}
void charsetConverter_icu::convert(const string& in, string& out, status* st)
{
if (st)
void charsetConverter_icu::convert(const string& in, string& out, status* st) {
if (st) {
new (st) status();
}
out.clear();
@ -260,9 +292,11 @@ void charsetConverter_icu::convert(const string& in, string& out, status* st)
shared_ptr <utility::charsetFilteredOutputStream>
charsetConverter_icu::getFilteredOutputStream
(utility::outputStream& os, const charsetConverterOptions& opts)
{
charsetConverter_icu::getFilteredOutputStream(
utility::outputStream& os,
const charsetConverterOptions& opts
) {
return make_shared <utility::charsetFilteredOutputStream_icu>(m_source, m_dest, &os, opts);
}
@ -273,75 +307,94 @@ shared_ptr <utility::charsetFilteredOutputStream>
namespace utility {
charsetFilteredOutputStream_icu::charsetFilteredOutputStream_icu
(const charset& source, const charset& dest, outputStream* os,
const charsetConverterOptions& opts)
: m_from(NULL), m_to(NULL), m_sourceCharset(source),
m_destCharset(dest), m_stream(*os), m_options(opts)
{
charsetFilteredOutputStream_icu::charsetFilteredOutputStream_icu(
const charset& source,
const charset& dest,
outputStream* os,
const charsetConverterOptions& opts
)
: m_from(NULL),
m_to(NULL),
m_sourceCharset(source),
m_destCharset(dest),
m_stream(*os),
m_options(opts) {
UErrorCode err = U_ZERO_ERROR;
m_from = ucnv_open(source.getName().c_str(), &err);
if (!U_SUCCESS(err))
{
throw exceptions::charset_conv_error
("Cannot initialize ICU converter for source charset '" + source.getName() + "' (error code: " + u_errorName(err) + ".");
if (!U_SUCCESS(err)) {
throw exceptions::charset_conv_error(
"Cannot initialize ICU converter for source charset '" + source.getName()
+ "' (error code: " + u_errorName(err) + "."
);
}
m_to = ucnv_open(dest.getName().c_str(), &err);
if (!U_SUCCESS(err))
{
throw exceptions::charset_conv_error
("Cannot initialize ICU converter for destination charset '" + dest.getName() + "' (error code: " + u_errorName(err) + ".");
if (!U_SUCCESS(err)) {
throw exceptions::charset_conv_error(
"Cannot initialize ICU converter for destination charset '" + dest.getName()
+ "' (error code: " + u_errorName(err) + "."
);
}
// Tell ICU what to do when encountering an illegal byte sequence
if (m_options.silentlyReplaceInvalidSequences)
{
if (m_options.silentlyReplaceInvalidSequences) {
// Set replacement chars for when converting from Unicode to codepage
icu::UnicodeString substString(m_options.invalidSequence.c_str());
ucnv_setSubstString(m_to, substString.getTerminatedBuffer(), -1, &err);
if (U_FAILURE(err))
if (U_FAILURE(err)) {
throw exceptions::charset_conv_error("[ICU] Error when setting substitution string.");
}
else
{
}
} else {
// Tell ICU top stop (and return an error) on illegal byte sequences
ucnv_setToUCallBack
(m_to, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err);
ucnv_setToUCallBack(
m_to, UCNV_TO_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err
);
if (U_FAILURE(err))
if (U_FAILURE(err)) {
throw exceptions::charset_conv_error("[ICU] Error when setting ToU callback.");
}
ucnv_setFromUCallBack
(m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err);
ucnv_setFromUCallBack(
m_to, UCNV_FROM_U_CALLBACK_STOP, UCNV_SUB_STOP_ON_ILLEGAL, NULL, NULL, &err
);
if (U_FAILURE(err))
if (U_FAILURE(err)) {
throw exceptions::charset_conv_error("[ICU] Error when setting FromU callback.");
}
}
}
charsetFilteredOutputStream_icu::~charsetFilteredOutputStream_icu()
{
charsetFilteredOutputStream_icu::~charsetFilteredOutputStream_icu() {
if (m_from) ucnv_close(m_from);
if (m_to) ucnv_close(m_to);
}
outputStream& charsetFilteredOutputStream_icu::getNextOutputStream()
{
outputStream& charsetFilteredOutputStream_icu::getNextOutputStream() {
return m_stream;
}
void charsetFilteredOutputStream_icu::writeImpl
(const byte_t* const data, const size_t count)
{
if (m_from == NULL || m_to == NULL)
void charsetFilteredOutputStream_icu::writeImpl(
const byte_t* const data,
const size_t count
) {
if (!m_from || !m_to) {
throw exceptions::charset_conv_error("Cannot initialize converters.");
}
// Allocate buffer for Unicode chars
const size_t uniSize = ucnv_getMinCharSize(m_from) * count * sizeof(UChar);
@ -353,29 +406,32 @@ void charsetFilteredOutputStream_icu::writeImpl
const char* uniSource = reinterpret_cast <const char*>(data);
const char* uniSourceLimit = uniSource + count;
do
{
do {
// Convert from source charset to Unicode
UChar* uniTarget = &uniBuffer[0];
UChar* uniTargetLimit = &uniBuffer[0] + uniSize;
toErr = U_ZERO_ERROR;
ucnv_toUnicode(m_from, &uniTarget, uniTargetLimit,
&uniSource, uniSourceLimit, NULL, /* flush */ FALSE, &toErr);
ucnv_toUnicode(
m_from, &uniTarget, uniTargetLimit,
&uniSource, uniSourceLimit, NULL, /* flush */ FALSE, &toErr
);
if (U_FAILURE(toErr) && toErr != U_BUFFER_OVERFLOW_ERROR) {
if (U_FAILURE(toErr) && toErr != U_BUFFER_OVERFLOW_ERROR)
{
if (toErr == U_INVALID_CHAR_FOUND ||
toErr == U_TRUNCATED_CHAR_FOUND ||
toErr == U_ILLEGAL_CHAR_FOUND)
{
toErr == U_ILLEGAL_CHAR_FOUND) {
throw exceptions::illegal_byte_sequence_for_charset();
}
else
{
throw exceptions::charset_conv_error
("[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'.");
} else {
throw exceptions::charset_conv_error(
"[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'."
);
}
}
@ -391,28 +447,31 @@ void charsetFilteredOutputStream_icu::writeImpl
const UChar* cpSource = &uniBuffer[0];
const UChar* cpSourceLimit = &uniBuffer[0] + uniLength;
do
{
do {
char* cpTarget = &cpBuffer[0];
char* cpTargetLimit = &cpBuffer[0] + cpSize;
fromErr = U_ZERO_ERROR;
ucnv_fromUnicode(m_to, &cpTarget, cpTargetLimit,
&cpSource, cpSourceLimit, NULL, /* flush */ FALSE, &fromErr);
ucnv_fromUnicode(
m_to, &cpTarget, cpTargetLimit,
&cpSource, cpSourceLimit, NULL, /* flush */ FALSE, &fromErr
);
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr)) {
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr))
{
if (fromErr == U_INVALID_CHAR_FOUND ||
fromErr == U_TRUNCATED_CHAR_FOUND ||
fromErr == U_ILLEGAL_CHAR_FOUND)
{
fromErr == U_ILLEGAL_CHAR_FOUND) {
throw exceptions::illegal_byte_sequence_for_charset();
}
else
{
throw exceptions::charset_conv_error
("[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'.");
} else {
throw exceptions::charset_conv_error(
"[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'."
);
}
}
@ -427,10 +486,11 @@ void charsetFilteredOutputStream_icu::writeImpl
}
void charsetFilteredOutputStream_icu::flush()
{
if (m_from == NULL || m_to == NULL)
void charsetFilteredOutputStream_icu::flush() {
if (!m_from || !m_to) {
throw exceptions::charset_conv_error("Cannot initialize converters.");
}
// Allocate buffer for Unicode chars
const size_t uniSize = ucnv_getMinCharSize(m_from) * 1024 * sizeof(UChar);
@ -442,21 +502,24 @@ void charsetFilteredOutputStream_icu::flush()
const char* uniSource = 0;
const char* uniSourceLimit = 0;
do
{
do {
// Convert from source charset to Unicode
UChar* uniTarget = &uniBuffer[0];
UChar* uniTargetLimit = &uniBuffer[0] + uniSize;
toErr = U_ZERO_ERROR;
ucnv_toUnicode(m_from, &uniTarget, uniTargetLimit,
&uniSource, uniSourceLimit, NULL, /* flush */ TRUE, &toErr);
ucnv_toUnicode(
m_from, &uniTarget, uniTargetLimit,
&uniSource, uniSourceLimit, NULL, /* flush */ TRUE, &toErr
);
if (U_FAILURE(toErr) && toErr != U_BUFFER_OVERFLOW_ERROR)
{
throw exceptions::charset_conv_error
("[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'.");
if (U_FAILURE(toErr) && toErr != U_BUFFER_OVERFLOW_ERROR) {
throw exceptions::charset_conv_error(
"[ICU] Error converting to Unicode from '" + m_sourceCharset.getName() + "'."
);
}
const size_t uniLength = uniTarget - &uniBuffer[0];
@ -471,20 +534,23 @@ void charsetFilteredOutputStream_icu::flush()
const UChar* cpSource = &uniBuffer[0];
const UChar* cpSourceLimit = &uniBuffer[0] + uniLength;
do
{
do {
char* cpTarget = &cpBuffer[0];
char* cpTargetLimit = &cpBuffer[0] + cpSize;
fromErr = U_ZERO_ERROR;
ucnv_fromUnicode(m_to, &cpTarget, cpTargetLimit,
&cpSource, cpSourceLimit, NULL, /* flush */ TRUE, &fromErr);
ucnv_fromUnicode(
m_to, &cpTarget, cpTargetLimit,
&cpSource, cpSourceLimit, NULL, /* flush */ TRUE, &fromErr
);
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr))
{
throw exceptions::charset_conv_error
("[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'.");
if (fromErr != U_BUFFER_OVERFLOW_ERROR && U_FAILURE(fromErr)) {
throw exceptions::charset_conv_error(
"[ICU] Error converting from Unicode to '" + m_destCharset.getName() + "'."
);
}
const size_t cpLength = cpTarget - &cpBuffer[0];

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -37,15 +37,13 @@
struct UConverter;
namespace vmime
{
namespace vmime {
/** A generic charset converter which uses ICU library.
*/
class charsetConverter_icu : public charsetConverter {
class charsetConverter_icu : public charsetConverter
{
public:
/** Construct and initialize an ICU charset converter.
@ -54,17 +52,21 @@ public:
* @param dest output charset
* @param opts conversion options
*/
charsetConverter_icu(const charset& source, const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions());
charsetConverter_icu(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions()
);
~charsetConverter_icu();
void convert(const string& in, string& out, status* st = NULL);
void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL);
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream
(utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions());
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(
utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions()
);
private:
@ -81,8 +83,8 @@ private:
namespace utility {
class charsetFilteredOutputStream_icu : public charsetFilteredOutputStream
{
class charsetFilteredOutputStream_icu : public charsetFilteredOutputStream {
public:
/** Construct a new filter for the specified output stream.
@ -92,9 +94,12 @@ public:
* @param os stream into which write filtered data
* @param opts conversion options
*/
charsetFilteredOutputStream_icu
(const charset& source, const charset& dest, outputStream* os,
const charsetConverterOptions& opts = charsetConverterOptions());
charsetFilteredOutputStream_icu(
const charset& source,
const charset& dest,
outputStream* os,
const charsetConverterOptions& opts = charsetConverterOptions()
);
~charsetFilteredOutputStream_icu();

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -30,8 +30,7 @@
#include "vmime/utility/outputStreamStringAdapter.hpp"
extern "C"
{
extern "C" {
#include "contrib/punycode/punycode.h"
#include "contrib/punycode/punycode.c"
@ -41,26 +40,31 @@ extern "C"
#include "contrib/utf8/utf8.h"
namespace vmime
{
namespace vmime {
charsetConverter_idna::charsetConverter_idna
(const charset& source, const charset& dest, const charsetConverterOptions& opts)
: m_source(source), m_dest(dest), m_options(opts)
{
charsetConverter_idna::charsetConverter_idna(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
)
: m_source(source),
m_dest(dest),
m_options(opts) {
}
charsetConverter_idna::~charsetConverter_idna()
{
charsetConverter_idna::~charsetConverter_idna() {
}
void charsetConverter_idna::convert(utility::inputStream& in, utility::outputStream& out, status* st)
{
if (st)
void charsetConverter_idna::convert(utility::inputStream& in, utility::outputStream& out, status* st) {
if (st) {
new (st) status();
}
// IDNA should be used for short strings, so it does not matter if we
// do not work directly on the stream
@ -75,19 +79,19 @@ void charsetConverter_idna::convert(utility::inputStream& in, utility::outputStr
}
void charsetConverter_idna::convert(const string& in, string& out, status* st)
{
if (st)
void charsetConverter_idna::convert(const string& in, string& out, status* st) {
if (st) {
new (st) status();
}
out.clear();
if (m_dest == "idna")
{
if (utility::stringUtils::is7bit(in))
{
if (st)
{
if (m_dest == "idna") {
if (utility::stringUtils::is7bit(in)) {
if (st) {
st->inputBytesRead = in.length();
st->outputBytesWritten = in.length();
}
@ -106,41 +110,42 @@ void charsetConverter_idna::convert(const string& in, string& out, status* st)
std::vector <punycode_uint> unichars;
unichars.reserve(inUTF8.length());
while (ch < end)
{
while (ch < end) {
const utf8::uint32_t uc = utf8::unchecked::next(ch);
unichars.push_back(uc);
}
if (st)
if (st) {
st->inputBytesRead = in.length();
}
punycode_uint inputLen = static_cast <punycode_uint>(unichars.size());
std::vector <char> output(inUTF8.length() * 2);
punycode_uint outputLen = static_cast <punycode_uint>(output.size());
const punycode_status status = punycode_encode
(inputLen, &unichars[0], /* case_flags */ NULL, &outputLen, &output[0]);
const punycode_status status = punycode_encode(
inputLen, &unichars[0], /* case_flags */ NULL, &outputLen, &output[0]
);
if (status == punycode_success) {
if (status == punycode_success)
{
out = string("xn--") + string(output.begin(), output.begin() + outputLen);
if (st)
if (st) {
st->outputBytesWritten = out.length();
}
else
{
}
} else {
// TODO
}
}
else if (m_source == "idna")
{
if (in.length() < 5 || in.substr(0, 4) != "xn--")
{
if (st)
{
} else if (m_source == "idna") {
if (in.length() < 5 || in.substr(0, 4) != "xn--") {
if (st) {
st->inputBytesRead = in.length();
st->outputBytesWritten = in.length();
}
@ -155,31 +160,34 @@ void charsetConverter_idna::convert(const string& in, string& out, status* st)
std::vector <punycode_uint> output(in.length() - 4);
punycode_uint outputLen = static_cast <punycode_uint>(output.size());
const punycode_status status = punycode_decode
(inputLen, &in[4], &outputLen, &output[0], /* case_flags */ NULL);
const punycode_status status = punycode_decode(
inputLen, &in[4], &outputLen, &output[0], /* case_flags */ NULL
);
if (st)
if (st) {
st->inputBytesRead = in.length();
}
if (status == punycode_success) {
if (status == punycode_success)
{
std::vector <char> outUTF8Bytes(outputLen * 4);
char* p = &outUTF8Bytes[0];
for (std::vector <punycode_uint>::const_iterator it = output.begin() ;
it != output.begin() + outputLen ; ++it)
{
it != output.begin() + outputLen ; ++it) {
p = utf8::unchecked::append(*it, p);
}
string outUTF8(&outUTF8Bytes[0], p);
charset::convert(outUTF8, out, vmime::charsets::UTF_8, m_dest);
if (st)
if (st) {
st->outputBytesWritten = out.length();
}
else
{
}
} else {
// TODO
}
}
@ -187,9 +195,12 @@ void charsetConverter_idna::convert(const string& in, string& out, status* st)
shared_ptr <utility::charsetFilteredOutputStream>
charsetConverter_idna::getFilteredOutputStream
(utility::outputStream& /* os */, const charsetConverterOptions& /* opts */)
{
charsetConverter_idna::getFilteredOutputStream(
utility::outputStream& /* os */,
const charsetConverterOptions& /* opts */
) {
// Not supported
return null;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -28,15 +28,13 @@
#include "vmime/charsetConverter.hpp"
namespace vmime
{
namespace vmime {
/** A charset converter which can convert to and from Punycode (for IDNA).
*/
class charsetConverter_idna : public charsetConverter {
class charsetConverter_idna : public charsetConverter
{
public:
/** Construct and initialize an IDNA charset converter.
@ -45,17 +43,21 @@ public:
* @param dest output charset
* @param opts conversion options
*/
charsetConverter_idna(const charset& source, const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions());
charsetConverter_idna(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions()
);
~charsetConverter_idna();
void convert(const string& in, string& out, status* st = NULL);
void convert(utility::inputStream& in, utility::outputStream& out, status* st = NULL);
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream
(utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions());
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(
utility::outputStream& os,
const charsetConverterOptions& opts = charsetConverterOptions()
);
private:

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -49,37 +49,46 @@
#define CP_UNICODE 1200
namespace vmime
{
namespace vmime {
// static
shared_ptr <charsetConverter> charsetConverter::createGenericConverter
(const charset& source, const charset& dest,
const charsetConverterOptions& opts)
{
shared_ptr <charsetConverter> charsetConverter::createGenericConverter(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
) {
return make_shared <charsetConverter_win>(source, dest, opts);
}
charsetConverter_win::charsetConverter_win
(const charset& source, const charset& dest, const charsetConverterOptions& opts)
: m_source(source), m_dest(dest), m_options(opts)
{
charsetConverter_win::charsetConverter_win(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts
)
: m_source(source),
m_dest(dest),
m_options(opts) {
}
void charsetConverter_win::convert
(utility::inputStream& in, utility::outputStream& out, status* st)
{
if (st)
void charsetConverter_win::convert(
utility::inputStream& in,
utility::outputStream& out,
status* st
) {
if (st) {
new (st) status();
}
byte_t buffer[32768];
string inStr, outStr;
while (!in.eof())
{
while (!in.eof()) {
const size_t len = in.read(buffer, sizeof(buffer));
utility::stringUtils::appendBytesToString(inStr, buffer, len);
}
@ -90,10 +99,11 @@ void charsetConverter_win::convert
}
void charsetConverter_win::convert(const string& in, string& out, status* st)
{
if (st)
void charsetConverter_win::convert(const string& in, string& out, status* st) {
if (st) {
new (st) status();
}
const int sourceCodePage = getCodePage(m_source.getName().c_str());
const int destCodePage = getCodePage(m_dest.getName().c_str());
@ -103,69 +113,77 @@ void charsetConverter_win::convert(const string& in, string& out, status* st)
const WCHAR* unicodePtr = NULL;
size_t unicodeLen = 0;
if (sourceCodePage == CP_UNICODE)
{
if (sourceCodePage == CP_UNICODE) {
unicodePtr = reinterpret_cast <const WCHAR*>(in.c_str());
unicodeLen = in.length() / 2;
}
else
{
const size_t bufferSize = MultiByteToWideChar
(sourceCodePage, 0, in.c_str(), static_cast <int>(in.length()),
NULL, 0) * sizeof(WCHAR); // in wide characters
} else {
const size_t bufferSize = MultiByteToWideChar(
sourceCodePage, 0, in.c_str(), static_cast <int>(in.length()), NULL, 0
) * sizeof(WCHAR); // in wide characters
unicodeBuffer.resize(bufferSize);
DWORD flags = 0;
if (!m_options.silentlyReplaceInvalidSequences)
if (!m_options.silentlyReplaceInvalidSequences) {
flags |= MB_ERR_INVALID_CHARS;
}
unicodePtr = reinterpret_cast <const WCHAR*>(&unicodeBuffer[0]);
unicodeLen = MultiByteToWideChar
(sourceCodePage, 0, in.c_str(), static_cast <int>(in.length()),
reinterpret_cast <WCHAR*>(&unicodeBuffer[0]), static_cast <int>(bufferSize));
unicodeLen = MultiByteToWideChar(
sourceCodePage, 0, in.c_str(), static_cast <int>(in.length()),
reinterpret_cast <WCHAR*>(&unicodeBuffer[0]), static_cast <int>(bufferSize)
);
if (unicodeLen == 0) {
if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) {
if (unicodeLen == 0)
{
if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION)
{
throw exceptions::illegal_byte_sequence_for_charset();
}
else
{
throw exceptions::charset_conv_error("MultiByteToWideChar() failed when converting to Unicode from " + m_source.getName());
} else {
throw exceptions::charset_conv_error(
"MultiByteToWideChar() failed when converting to Unicode from " + m_source.getName()
);
}
}
}
// Convert from Unicode to destination charset
if (destCodePage == CP_UNICODE)
{
if (destCodePage == CP_UNICODE) {
out.assign(reinterpret_cast <const char*>(unicodePtr), unicodeLen * 2);
}
else
{
const size_t bufferSize = WideCharToMultiByte
(destCodePage, 0, unicodePtr, static_cast <int>(unicodeLen),
NULL, 0, 0, NULL); // in multibyte characters
} else {
const size_t bufferSize = WideCharToMultiByte(
destCodePage, 0, unicodePtr, static_cast <int>(unicodeLen),
NULL, 0, 0, NULL
); // in multibyte characters
std::vector <char> buffer;
buffer.resize(bufferSize);
const size_t len = WideCharToMultiByte
(destCodePage, 0, unicodePtr, static_cast <int>(unicodeLen),
&buffer[0], static_cast <int>(bufferSize), 0, NULL);
const size_t len = WideCharToMultiByte(
destCodePage, 0, unicodePtr, static_cast <int>(unicodeLen),
&buffer[0], static_cast <int>(bufferSize), 0, NULL
);
if (len == 0) {
if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION) {
if (len == 0)
{
if (GetLastError() == ERROR_NO_UNICODE_TRANSLATION)
{
throw exceptions::illegal_byte_sequence_for_charset();
}
else
{
throw exceptions::charset_conv_error("WideCharToMultiByte() failed when converting from Unicode to " + m_source.getName());
} else {
throw exceptions::charset_conv_error(
"WideCharToMultiByte() failed when converting from Unicode to " + m_source.getName()
);
}
}
@ -175,15 +193,16 @@ void charsetConverter_win::convert(const string& in, string& out, status* st)
// static
int charsetConverter_win::getCodePage(const char* name)
{
if (_stricmp(name, charsets::UTF_16) == 0) // wchar_t is UTF-16 on Windows
int charsetConverter_win::getCodePage(const char* name) {
if (_stricmp(name, charsets::UTF_16) == 0) { // wchar_t is UTF-16 on Windows
return CP_UNICODE;
}
// "cp1252" --> return 1252
if ((name[0] == 'c' || name[0] == 'C') &&
(name[1] == 'p' || name[1] == 'P'))
{
(name[1] == 'p' || name[1] == 'P')) {
return atoi(name + 2);
}
@ -192,9 +211,11 @@ int charsetConverter_win::getCodePage(const char* name)
shared_ptr <utility::charsetFilteredOutputStream>
charsetConverter_win::getFilteredOutputStream
(utility::outputStream& /* os */, const charsetConverterOptions& /* opts */)
{
charsetConverter_win::getFilteredOutputStream(
utility::outputStream& /* os */,
const charsetConverterOptions& /* opts */
) {
// TODO: implement me!
return null;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -34,8 +34,7 @@
#include "vmime/charsetConverter.hpp"
namespace vmime
{
namespace vmime {
/** A generic charset converter which uses Windows MultiByteToWideChar
@ -49,9 +48,8 @@ namespace vmime
*
* Also, "status" is not supported by this converter for the same reason.
*/
class charsetConverter_win : public charsetConverter {
class charsetConverter_win : public charsetConverter
{
public:
/** Construct and initialize a Windows charset converter.
@ -60,14 +58,19 @@ public:
* @param dest output charset
* @param opts conversion options
*/
charsetConverter_win(const charset& source, const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions());
charsetConverter_win(
const charset& source,
const charset& dest,
const charsetConverterOptions& opts = charsetConverterOptions()
);
void convert(const string& in, string& out, status* st);
void convert(utility::inputStream& in, utility::outputStream& out, status* st);
shared_ptr <utility::charsetFilteredOutputStream>
getFilteredOutputStream(utility::outputStream& os, const charsetConverterOptions& opts);
shared_ptr <utility::charsetFilteredOutputStream> getFilteredOutputStream(
utility::outputStream& os,
const charsetConverterOptions& opts
);
private:

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -31,48 +31,54 @@
#include <sstream>
namespace vmime
{
namespace vmime {
component::component()
: m_parsedOffset(0), m_parsedLength(0)
{
: m_parsedOffset(0), m_parsedLength(0) {
}
component::~component()
{
component::~component() {
}
void component::parse
(const shared_ptr <utility::inputStream>& inputStream, const size_t length)
{
void component::parse(
const shared_ptr <utility::inputStream>& inputStream,
const size_t length
) {
parse(inputStream, 0, length, NULL);
}
void component::parse
(const shared_ptr <utility::inputStream>& inputStream, const size_t position,
const size_t end, size_t* newPosition)
{
void component::parse(
const shared_ptr <utility::inputStream>& inputStream,
const size_t position,
const size_t end,
size_t* newPosition) {
parse(parsingContext::getDefaultContext(), inputStream, position, end, newPosition);
}
void component::parse
(const parsingContext& ctx,
const shared_ptr <utility::inputStream>& inputStream, const size_t position,
const size_t end, size_t* newPosition)
{
void component::parse(
const parsingContext& ctx,
const shared_ptr <utility::inputStream>& inputStream,
const size_t position,
const size_t end,
size_t* newPosition
) {
m_parsedOffset = m_parsedLength = 0;
shared_ptr <utility::seekableInputStream> seekableStream =
dynamicCast <utility::seekableInputStream>(inputStream);
if (seekableStream == NULL || end == 0)
{
if (!seekableStream || end == 0) {
// Read the whole stream into a buffer
std::ostringstream oss;
utility::outputStreamAdapter ossAdapter(oss);
@ -81,9 +87,9 @@ void component::parse
const string buffer = oss.str();
parseImpl(ctx, buffer, 0, buffer.length(), NULL);
}
else
{
} else {
shared_ptr <utility::parserInputStreamAdapter> parser =
make_shared <utility::parserInputStreamAdapter>(seekableStream);
@ -92,79 +98,95 @@ void component::parse
}
void component::parse(const string& buffer)
{
void component::parse(const string& buffer) {
m_parsedOffset = m_parsedLength = 0;
parseImpl(parsingContext::getDefaultContext(), buffer, 0, buffer.length(), NULL);
}
void component::parse(const parsingContext& ctx, const string& buffer)
{
void component::parse(const parsingContext& ctx, const string& buffer) {
m_parsedOffset = m_parsedLength = 0;
parseImpl(ctx, buffer, 0, buffer.length(), NULL);
}
void component::parse
(const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void component::parse(
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
m_parsedOffset = m_parsedLength = 0;
parseImpl(parsingContext::getDefaultContext(), buffer, position, end, newPosition);
}
void component::parse
(const parsingContext& ctx,
const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void component::parse(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end, size_t* newPosition
) {
m_parsedOffset = m_parsedLength = 0;
parseImpl(ctx, buffer, position, end, newPosition);
}
void component::offsetParsedBounds(const size_t offset)
{
void component::offsetParsedBounds(const size_t offset) {
// Offset parsed bounds of this component
if (m_parsedLength != 0)
if (m_parsedLength != 0) {
m_parsedOffset += offset;
}
// Offset parsed bounds of our children
std::vector <shared_ptr <component> > children = getChildComponents();
for (size_t i = 0, n = children.size() ; i < n ; ++i)
for (size_t i = 0, n = children.size() ; i < n ; ++i) {
children[i]->offsetParsedBounds(offset);
}
}
void component::parseImpl
(const parsingContext& ctx, const shared_ptr <utility::parserInputStreamAdapter>& parser,
const size_t position, const size_t end, size_t* newPosition)
{
void component::parseImpl(
const parsingContext& ctx,
const shared_ptr <utility::parserInputStreamAdapter>& parser,
const size_t position,
const size_t end,
size_t* newPosition
) {
// This is the default implementation for parsing from an input stream:
// actually, we extract the substring and use the "parse from string" implementation
const string buffer = parser->extract(position, end);
parseImpl(ctx, buffer, 0, buffer.length(), newPosition);
// Recursivey offset parsed bounds on children
if (position != 0)
if (position != 0) {
offsetParsedBounds(position);
}
if (newPosition != NULL)
if (newPosition) {
*newPosition += position;
}
}
void component::parseImpl
(const parsingContext& ctx, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void component::parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition) {
// This is the default implementation for parsing from a string:
// actually, we encapsulate the string buffer in an input stream, then use
// the "parse from input stream" implementation
@ -178,9 +200,11 @@ void component::parseImpl
}
const string component::generate
(const size_t maxLineLength, const size_t curLinePos) const
{
const string component::generate(
const size_t maxLineLength,
const size_t curLinePos
) const {
std::ostringstream oss;
utility::outputStreamAdapter adapter(oss);
@ -189,56 +213,63 @@ const string component::generate
generateImpl(ctx, adapter, curLinePos, NULL);
return (oss.str());
return oss.str();
}
void component::generate
(utility::outputStream& os, const size_t curLinePos, size_t* newLinePos) const
{
generateImpl(generationContext::getDefaultContext(),
os, curLinePos, newLinePos);
void component::generate(
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
generateImpl(generationContext::getDefaultContext(), os, curLinePos, newLinePos);
}
void component::generate
(const generationContext& ctx, utility::outputStream& outputStream,
const size_t curLinePos, size_t* newLinePos) const
{
void component::generate(
const generationContext& ctx,
utility::outputStream& outputStream,
const size_t curLinePos,
size_t* newLinePos
) const {
generateImpl(ctx, outputStream, curLinePos, newLinePos);
}
size_t component::getParsedOffset() const
{
return (m_parsedOffset);
size_t component::getParsedOffset() const {
return m_parsedOffset;
}
size_t component::getParsedLength() const
{
return (m_parsedLength);
size_t component::getParsedLength() const {
return m_parsedLength;
}
void component::setParsedBounds(const size_t start, const size_t end)
{
void component::setParsedBounds(const size_t start, const size_t end) {
m_parsedOffset = start;
m_parsedLength = end - start;
}
size_t component::getGeneratedSize(const generationContext& ctx)
{
size_t component::getGeneratedSize(const generationContext& ctx) {
std::vector <shared_ptr <component> > children = getChildComponents();
size_t totalSize = 0;
for (std::vector <shared_ptr <component> >::iterator it = children.begin() ; it != children.end() ; ++it)
for (std::vector <shared_ptr <component> >::iterator it = children.begin() ;
it != children.end() ; ++it) {
totalSize += (*it)->getGeneratedSize(ctx);
}
return totalSize;
}
} // vmime

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -34,16 +34,14 @@
#include "vmime/parsingContext.hpp"
namespace vmime
{
namespace vmime {
/** This abstract class is the base class for all the components of a message.
* It defines methods for parsing and generating a component.
*/
class VMIME_EXPORT component : public object {
class VMIME_EXPORT component : public object
{
public:
component();
@ -80,11 +78,12 @@ public:
* @param end end position in the input buffer
* @param newPosition will receive the new position in the input buffer
*/
void parse
(const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parse(
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
/** Parse RFC-822/MIME data for this component.
*
@ -94,12 +93,13 @@ public:
* @param end end position in the input buffer
* @param newPosition will receive the new position in the input buffer
*/
void parse
(const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parse(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
/** Parse RFC-822/MIME data for this component. If stream is not seekable,
* or if end position is not specified, entire contents of the stream will
@ -111,11 +111,12 @@ public:
* @param end end position in the input stream
* @param newPosition will receive the new position in the input stream
*/
void parse
(const shared_ptr <utility::inputStream>& inputStream,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parse(
const shared_ptr <utility::inputStream>& inputStream,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
/** Parse RFC-822/MIME data for this component. If stream is not seekable,
* or if end position is not specified, entire contents of the stream will
@ -127,12 +128,13 @@ public:
* @param end end position in the input stream
* @param newPosition will receive the new position in the input stream
*/
void parse
(const parsingContext& ctx,
const shared_ptr <utility::inputStream>& inputStream,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parse(
const parsingContext& ctx,
const shared_ptr <utility::inputStream>& inputStream,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
/** Generate RFC-2822/MIME data for this component.
*
@ -142,9 +144,10 @@ public:
* @param curLinePos length of the current line in the output buffer
* @return generated data
*/
virtual const string generate
(const size_t maxLineLength = lineLengthLimits::infinite,
const size_t curLinePos = 0) const;
virtual const string generate(
const size_t maxLineLength = lineLengthLimits::infinite,
const size_t curLinePos = 0
) const;
/** Generate RFC-2822/MIME data for this component, using the default generation context.
*
@ -152,10 +155,11 @@ public:
* @param curLinePos length of the current line in the output buffer
* @param newLinePos will receive the new line position (length of the last line written)
*/
virtual void generate
(utility::outputStream& outputStream,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
virtual void generate(
utility::outputStream& outputStream,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
/** Generate RFC-2822/MIME data for this component, using the default generation context.
*
@ -164,11 +168,12 @@ public:
* @param curLinePos length of the current line in the output buffer
* @param newLinePos will receive the new line position (length of the last line written)
*/
virtual void generate
(const generationContext& ctx,
utility::outputStream& outputStream,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
virtual void generate(
const generationContext& ctx,
utility::outputStream& outputStream,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
/** Clone this component.
*
@ -222,25 +227,28 @@ protected:
void setParsedBounds(const size_t start, const size_t end);
// AT LEAST ONE of these parseImpl() functions MUST be implemented in derived class
virtual void parseImpl
(const parsingContext& ctx,
const shared_ptr <utility::parserInputStreamAdapter>& parser,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
virtual void parseImpl(
const parsingContext& ctx,
const shared_ptr <utility::parserInputStreamAdapter>& parser,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
virtual void parseImpl
(const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
virtual void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
virtual void generateImpl
(const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const = 0;
virtual void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const = 0;
private:

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -24,13 +24,12 @@
#include "vmime/constants.hpp"
namespace vmime
{
namespace vmime {
// Media Types
namespace mediaTypes
{
namespace mediaTypes {
// Types
const char* const TEXT = "text";
const char* const MULTIPART = "multipart";
@ -72,8 +71,8 @@ namespace mediaTypes
// Encoding types
namespace encodingTypes
{
namespace encodingTypes {
const char* const SEVEN_BIT = "7bit";
const char* const EIGHT_BIT = "8bit";
const char* const BASE64 = "base64";
@ -84,16 +83,16 @@ namespace encodingTypes
// Content disposition types
namespace contentDispositionTypes
{
namespace contentDispositionTypes {
const char* const INLINE = "inline";
const char* const ATTACHMENT = "attachment";
}
// Charsets
namespace charsets
{
namespace charsets {
const char* const ISO8859_1 = "iso-8859-1";
const char* const ISO8859_2 = "iso-8859-2";
const char* const ISO8859_3 = "iso-8859-3";
@ -159,8 +158,8 @@ namespace charsets
// Fields
namespace fields
{
namespace fields {
const char* const RECEIVED = "Received";
const char* const FROM = "From";
const char* const SENDER = "Sender";
@ -204,32 +203,32 @@ namespace fields
// Constants for disposition action modes (RFC-3978).
namespace dispositionActionModes
{
namespace dispositionActionModes {
const char* const MANUAL = "manual";
const char* const AUTOMATIC = "automatic";
}
// Constants for disposition sending modes (RFC-3798).
namespace dispositionSendingModes
{
namespace dispositionSendingModes {
const char* const SENT_MANUALLY = "MDN-sent-manually";
const char* const SENT_AUTOMATICALLY ="MDN-sent-automatically";
}
// Constants for disposition types (RFC-3798).
namespace dispositionTypes
{
namespace dispositionTypes {
const char* const DISPLAYED = "displayed";
const char* const DELETED = "deleted";
}
// Constants for disposition modifiers (RFC-3798).
namespace dispositionModifiers
{
namespace dispositionModifiers {
const char* const ERROR = "error";
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free SOFTWARE; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -37,11 +37,11 @@
#endif
namespace vmime
{
namespace vmime {
/** Constants for media types. */
namespace mediaTypes
{
namespace mediaTypes {
// Types
extern VMIME_EXPORT const char* const TEXT;
extern VMIME_EXPORT const char* const MULTIPART;
@ -83,8 +83,8 @@ namespace vmime
/** Constants for encoding types. */
namespace encodingTypes
{
namespace encodingTypes {
extern VMIME_EXPORT const char* const SEVEN_BIT;
extern VMIME_EXPORT const char* const EIGHT_BIT;
extern VMIME_EXPORT const char* const BASE64;
@ -95,16 +95,16 @@ namespace vmime
/** Constants for content disposition types (RFC-2183). */
namespace contentDispositionTypes
{
namespace contentDispositionTypes {
extern VMIME_EXPORT const char* const INLINE;
extern VMIME_EXPORT const char* const ATTACHMENT;
}
/** Constants for charsets. */
namespace charsets
{
namespace charsets {
extern VMIME_EXPORT const char* const ISO8859_1;
extern VMIME_EXPORT const char* const ISO8859_2;
extern VMIME_EXPORT const char* const ISO8859_3;
@ -169,8 +169,8 @@ namespace vmime
}
/** Constants for standard field names. */
namespace fields
{
namespace fields {
extern VMIME_EXPORT const char* const RECEIVED;
extern VMIME_EXPORT const char* const FROM;
extern VMIME_EXPORT const char* const SENDER;
@ -213,8 +213,8 @@ namespace vmime
}
/** Constants for disposition action modes (RFC-3978). */
namespace dispositionActionModes
{
namespace dispositionActionModes {
/** User implicitely displayed or deleted the message (filter or
* any other automatic action). */
extern VMIME_EXPORT const char* const AUTOMATIC;
@ -224,8 +224,8 @@ namespace vmime
}
/** Constants for disposition sending modes (RFC-3798). */
namespace dispositionSendingModes
{
namespace dispositionSendingModes {
/** The MDN was sent because the MUA had previously been configured
* to do so automatically. */
extern VMIME_EXPORT const char* const SENT_AUTOMATICALLY;
@ -235,8 +235,8 @@ namespace vmime
}
/** Constants for disposition types (RFC-3798). */
namespace dispositionTypes
{
namespace dispositionTypes {
/** Message has been displayed to the user. */
extern VMIME_EXPORT const char* const DISPLAYED;
/** Message has been deleted without being displayed. */
@ -246,8 +246,8 @@ namespace vmime
}
/** Constants for disposition modifiers (RFC-3798). */
namespace dispositionModifiers
{
namespace dispositionModifiers {
extern VMIME_EXPORT const char* const ERROR;
}
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -25,107 +25,118 @@
#include "vmime/utility/stringUtils.hpp"
namespace vmime
{
namespace vmime {
contentDisposition::contentDisposition()
: m_name(contentDispositionTypes::INLINE)
{
: m_name(contentDispositionTypes::INLINE) {
}
contentDisposition::contentDisposition(const string& name)
: m_name(utility::stringUtils::toLower(name))
{
: m_name(utility::stringUtils::toLower(name)) {
}
contentDisposition::contentDisposition(const contentDisposition& type)
: headerFieldValue(), m_name(type.m_name)
{
: headerFieldValue(), m_name(type.m_name) {
}
void contentDisposition::parseImpl
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
m_name = utility::stringUtils::trim(utility::stringUtils::toLower
(string(buffer.begin() + position, buffer.begin() + end)));
void contentDisposition::parseImpl(
const parsingContext& /* ctx */,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
m_name = utility::stringUtils::trim(
utility::stringUtils::toLower(
string(buffer.begin() + position, buffer.begin() + end)
)
);
setParsedBounds(position, end);
if (newPosition)
if (newPosition) {
*newPosition = end;
}
}
void contentDisposition::generateImpl
(const generationContext& /* ctx */, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
void contentDisposition::generateImpl(
const generationContext& /* ctx */,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
os << m_name;
if (newLinePos)
if (newLinePos) {
*newLinePos = curLinePos + m_name.length();
}
}
contentDisposition& contentDisposition::operator=(const string& name)
{
contentDisposition& contentDisposition::operator=(const string& name) {
m_name = utility::stringUtils::toLower(name);
return (*this);
return *this;
}
bool contentDisposition::operator==(const contentDisposition& value) const
{
return (utility::stringUtils::toLower(m_name) == value.m_name);
bool contentDisposition::operator==(const contentDisposition& value) const {
return utility::stringUtils::toLower(m_name) == value.m_name;
}
bool contentDisposition::operator!=(const contentDisposition& value) const
{
bool contentDisposition::operator!=(const contentDisposition& value) const {
return !(*this == value);
}
shared_ptr <component> contentDisposition::clone() const
{
shared_ptr <component> contentDisposition::clone() const {
return make_shared <contentDisposition>(*this);
}
void contentDisposition::copyFrom(const component& other)
{
void contentDisposition::copyFrom(const component& other) {
const contentDisposition& d = dynamic_cast <const contentDisposition&>(other);
m_name = d.m_name;
}
contentDisposition& contentDisposition::operator=(const contentDisposition& other)
{
contentDisposition& contentDisposition::operator=(const contentDisposition& other) {
copyFrom(other);
return (*this);
return *this;
}
const string& contentDisposition::getName() const
{
return (m_name);
const string& contentDisposition::getName() const {
return m_name;
}
void contentDisposition::setName(const string& name)
{
void contentDisposition::setName(const string& name) {
m_name = name;
}
const std::vector <shared_ptr <component> > contentDisposition::getChildComponents()
{
const std::vector <shared_ptr <component> > contentDisposition::getChildComponents() {
return std::vector <shared_ptr <component> >();
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -29,15 +29,13 @@
#include "vmime/headerFieldValue.hpp"
namespace vmime
{
namespace vmime {
/** Content disposition (basic type).
*/
class VMIME_EXPORT contentDisposition : public headerFieldValue {
class VMIME_EXPORT contentDisposition : public headerFieldValue
{
public:
contentDisposition();
@ -78,18 +76,20 @@ private:
protected:
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -25,132 +25,136 @@
#include "vmime/exception.hpp"
namespace vmime
{
namespace vmime {
contentDispositionField::contentDispositionField()
{
contentDispositionField::contentDispositionField() {
}
contentDispositionField::contentDispositionField(contentDispositionField&)
: parameterizedHeaderField()
{
: parameterizedHeaderField() {
}
bool contentDispositionField::hasCreationDate() const
{
bool contentDispositionField::hasCreationDate() const {
return hasParameter("creation-date");
}
const datetime contentDispositionField::getCreationDate() const
{
const datetime contentDispositionField::getCreationDate() const {
shared_ptr <parameter> param = findParameter("creation-date");
if (param)
if (param) {
return param->getValueAs <datetime>();
else
} else {
return datetime::now();
}
}
void contentDispositionField::setCreationDate(const datetime& creationDate)
{
void contentDispositionField::setCreationDate(const datetime& creationDate) {
getParameter("creation-date")->setValue(creationDate);
}
bool contentDispositionField::hasModificationDate() const
{
bool contentDispositionField::hasModificationDate() const {
return hasParameter("modification-date");
}
const datetime contentDispositionField::getModificationDate() const
{
const datetime contentDispositionField::getModificationDate() const {
shared_ptr <parameter> param = findParameter("modification-date");
if (param)
if (param) {
return param->getValueAs <datetime>();
else
} else {
return datetime::now();
}
}
void contentDispositionField::setModificationDate(const datetime& modificationDate)
{
void contentDispositionField::setModificationDate(const datetime& modificationDate) {
getParameter("modification-date")->setValue(modificationDate);
}
bool contentDispositionField::hasReadDate() const
{
bool contentDispositionField::hasReadDate() const {
return hasParameter("read-date");
}
const datetime contentDispositionField::getReadDate() const
{
const datetime contentDispositionField::getReadDate() const {
shared_ptr <parameter> param = findParameter("read-date");
if (param)
if (param) {
return param->getValueAs <datetime>();
else
} else {
return datetime::now();
}
}
void contentDispositionField::setReadDate(const datetime& readDate)
{
void contentDispositionField::setReadDate(const datetime& readDate) {
getParameter("read-date")->setValue(readDate);
}
bool contentDispositionField::hasFilename() const
{
bool contentDispositionField::hasFilename() const {
return hasParameter("filename");
}
const word contentDispositionField::getFilename() const
{
const word contentDispositionField::getFilename() const {
shared_ptr <parameter> param = findParameter("filename");
if (param)
if (param) {
return param->getValue();
else
} else {
return word();
}
}
void contentDispositionField::setFilename(const word& filename)
{
void contentDispositionField::setFilename(const word& filename) {
getParameter("filename")->setValue(filename);
}
bool contentDispositionField::hasSize() const
{
bool contentDispositionField::hasSize() const {
return hasParameter("size");
}
const string contentDispositionField::getSize() const
{
const string contentDispositionField::getSize() const {
shared_ptr <parameter> param = findParameter("size");
if (param)
if (param) {
return param->getValue().getBuffer();
else
} else {
return "";
}
}
void contentDispositionField::setSize(const string& size)
{
void contentDispositionField::setSize(const string& size) {
getParameter("size")->setValue(word(size, vmime::charsets::US_ASCII));
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -32,15 +32,13 @@
#include "vmime/word.hpp"
namespace vmime
{
namespace vmime {
/** Describes presentation information, as per RFC-2183.
*/
class VMIME_EXPORT contentDispositionField : public parameterizedHeaderField {
class VMIME_EXPORT contentDispositionField : public parameterizedHeaderField
{
friend class headerFieldFactory;
protected:

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -24,16 +24,15 @@
#include "vmime/contentHandler.hpp"
namespace vmime
{
namespace vmime {
// No encoding = "binary" encoding
const encoding contentHandler::NO_ENCODING(encodingTypes::BINARY);
contentHandler::~contentHandler()
{
contentHandler::~contentHandler() {
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -34,12 +34,11 @@
#include "vmime/mediaType.hpp"
namespace vmime
{
namespace vmime {
class VMIME_EXPORT contentHandler : public object
{
class VMIME_EXPORT contentHandler : public object {
public:
/** Used to specify that enclosed data is not encoded. */
@ -63,7 +62,11 @@ public:
* @param enc encoding for output
* @param maxLineLength maximum line length for output
*/
virtual void generate(utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength = lineLengthLimits::infinite) const = 0;
virtual void generate(
utility::outputStream& os,
const vmime::encoding& enc,
const size_t maxLineLength = lineLengthLimits::infinite
) const = 0;
/** Extract the contents into the specified stream. If needed, data
* will be decoded before being written into the stream.
@ -74,7 +77,10 @@ public:
* @param progress progress listener, or NULL if you do not
* want to receive progress notifications
*/
virtual void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const = 0;
virtual void extract(
utility::outputStream& os,
utility::progressListener* progress = NULL
) const = 0;
/** Extract the contents into the specified stream, without
* decoding it. It may be useful in case the encoding is not
@ -84,7 +90,10 @@ public:
* @param progress progress listener, or NULL if you do not
* want to receive progress notifications
*/
virtual void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const = 0;
virtual void extractRaw(
utility::outputStream& os,
utility::progressListener* progress = NULL
) const = 0;
/** Returns the actual length of data. WARNING: this can return 0 if no
* length was specified when setting data of this object, or if the

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -25,89 +25,90 @@
#include "vmime/exception.hpp"
namespace vmime
{
namespace vmime {
contentTypeField::contentTypeField()
{
contentTypeField::contentTypeField() {
}
contentTypeField::contentTypeField(contentTypeField&)
: parameterizedHeaderField()
{
: parameterizedHeaderField() {
}
bool contentTypeField::hasBoundary() const
{
bool contentTypeField::hasBoundary() const {
return hasParameter("boundary");
}
const string contentTypeField::getBoundary() const
{
const string contentTypeField::getBoundary() const {
shared_ptr <parameter> param = findParameter("boundary");
if (param)
if (param) {
return param->getValue().getBuffer();
else
} else {
return "";
}
}
void contentTypeField::setBoundary(const string& boundary)
{
void contentTypeField::setBoundary(const string& boundary) {
getParameter("boundary")->setValue(word(boundary, vmime::charsets::US_ASCII));
}
bool contentTypeField::hasCharset() const
{
bool contentTypeField::hasCharset() const {
return hasParameter("charset");
}
const charset contentTypeField::getCharset() const
{
const charset contentTypeField::getCharset() const {
shared_ptr <parameter> param = findParameter("charset");
if (param)
if (param) {
return param->getValueAs <charset>();
else
} else {
return charset();
}
}
void contentTypeField::setCharset(const charset& ch)
{
void contentTypeField::setCharset(const charset& ch) {
getParameter("charset")->setValue(ch);
}
bool contentTypeField::hasReportType() const
{
bool contentTypeField::hasReportType() const {
return hasParameter("report-type");
}
const string contentTypeField::getReportType() const
{
const string contentTypeField::getReportType() const {
shared_ptr <parameter> param = findParameter("report-type");
if (param)
if (param) {
return param->getValue().getBuffer();
else
} else {
return "";
}
}
void contentTypeField::setReportType(const string& reportType)
{
void contentTypeField::setReportType(const string& reportType) {
getParameter("report-type")->setValue(word(reportType, vmime::charsets::US_ASCII));
}
} // vmime

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -31,12 +31,11 @@
#include "vmime/charset.hpp"
namespace vmime
{
namespace vmime {
class VMIME_EXPORT contentTypeField : public parameterizedHeaderField
{
class VMIME_EXPORT contentTypeField : public parameterizedHeaderField {
friend class headerFieldFactory;
protected:

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -24,61 +24,60 @@
#include "vmime/context.hpp"
namespace vmime
{
namespace vmime {
context::context()
: m_internationalizedEmail(false)
{
: m_internationalizedEmail(false) {
}
context::context(const context& ctx)
: object(),
m_internationalizedEmail(ctx.m_internationalizedEmail)
{
m_internationalizedEmail(ctx.m_internationalizedEmail) {
}
context::~context()
{
context::~context() {
}
bool context::getInternationalizedEmailSupport() const
{
bool context::getInternationalizedEmailSupport() const {
return m_internationalizedEmail;
}
void context::setInternationalizedEmailSupport(const bool support)
{
void context::setInternationalizedEmailSupport(const bool support) {
m_internationalizedEmail = support;
}
const charsetConverterOptions& context::getCharsetConversionOptions() const
{
const charsetConverterOptions& context::getCharsetConversionOptions() const {
return m_charsetConvOptions;
}
void context::setCharsetConversionOptions(const charsetConverterOptions& opts)
{
void context::setCharsetConversionOptions(const charsetConverterOptions& opts) {
m_charsetConvOptions = opts;
}
context& context::operator=(const context& ctx)
{
context& context::operator=(const context& ctx) {
copyFrom(ctx);
return *this;
}
void context::copyFrom(const context& ctx)
{
void context::copyFrom(const context& ctx) {
m_internationalizedEmail = ctx.m_internationalizedEmail;
m_charsetConvOptions = ctx.m_charsetConvOptions;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -29,15 +29,13 @@
#include "vmime/charsetConverterOptions.hpp"
namespace vmime
{
namespace vmime {
/** Holds configuration parameters used either for parsing or generating messages.
*/
class VMIME_EXPORT context : public object {
class VMIME_EXPORT context : public object
{
public:
virtual ~context();
@ -74,8 +72,8 @@ public:
/** Switches between contexts temporarily.
*/
template <typename CTX_CLASS>
class switcher
{
class switcher {
public:
/** Switches to the specified context.
@ -85,15 +83,15 @@ public:
* @param newCtx new context
*/
switcher(CTX_CLASS& newCtx)
: m_oldCtxData(CTX_CLASS::getDefaultContext()), m_newCtx(&newCtx)
{
: m_oldCtxData(CTX_CLASS::getDefaultContext()), m_newCtx(&newCtx) {
CTX_CLASS::getDefaultContext().copyFrom(newCtx);
}
/** Restores back saved context.
*/
~switcher()
{
~switcher() {
CTX_CLASS::getDefaultContext().copyFrom(m_oldCtxData);
}

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -31,21 +31,31 @@
#include <ctime>
namespace vmime
{
namespace vmime {
/** Date and time (basic type).
*/
class VMIME_EXPORT datetime : public headerFieldValue {
class VMIME_EXPORT datetime : public headerFieldValue
{
public:
// Constructors
datetime();
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 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);
datetime(const time_t t, const int zone = GMT);
@ -54,8 +64,8 @@ public:
~datetime();
// Some time zones (in minutes)
enum TimeZones
{
enum TimeZones {
GMT_12 = -720, // GMT-12h
GMT_11 = -660, // GMT-11h
GMT_10 = -600, // GMT-10h
@ -124,8 +134,8 @@ public:
};
// Months list
enum Months
{
enum Months {
// Long
JANUARY = 1,
FEBRUARY = 2,
@ -155,8 +165,8 @@ public:
};
// Days of week list
enum DaysOfWeek
{
enum DaysOfWeek {
// Long
SUNDAY = 0,
MONDAY = 1,
@ -242,18 +252,20 @@ public:
protected:
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -28,57 +28,75 @@
#include "vmime/encoding.hpp"
namespace vmime
{
namespace vmime {
defaultAttachment::defaultAttachment()
{
defaultAttachment::defaultAttachment() {
}
defaultAttachment::defaultAttachment(const shared_ptr <const contentHandler>& data,
const encoding& enc, const mediaType& type, const text& desc, const word& name)
: m_type(type), m_desc(desc), m_data(data), m_encoding(enc), m_name(name)
{
defaultAttachment::defaultAttachment(
const shared_ptr <const contentHandler>& data,
const encoding& enc,
const mediaType& type,
const text& desc,
const word& name
)
: m_type(type),
m_desc(desc),
m_data(data),
m_encoding(enc),
m_name(name) {
}
defaultAttachment::defaultAttachment(const shared_ptr <const contentHandler>& data,
const mediaType& type, const text& desc, const word& name)
: m_type(type), m_desc(desc), m_data(data),
m_encoding(encoding::decide(data)), m_name(name)
{
defaultAttachment::defaultAttachment(
const shared_ptr <const contentHandler>& data,
const mediaType& type,
const text& desc,
const word& name
)
: m_type(type),
m_desc(desc),
m_data(data),
m_encoding(encoding::decide(data)),
m_name(name) {
}
defaultAttachment::defaultAttachment(const defaultAttachment& attach)
: attachment(), m_type(attach.m_type), m_desc(attach.m_desc),
: attachment(),
m_type(attach.m_type),
m_desc(attach.m_desc),
m_data(vmime::clone(attach.m_data)),
m_encoding(attach.m_encoding), m_name(attach.m_name)
{
m_encoding(attach.m_encoding),
m_name(attach.m_name) {
}
defaultAttachment::~defaultAttachment()
{
defaultAttachment::~defaultAttachment() {
}
defaultAttachment& defaultAttachment::operator=(const defaultAttachment& attach)
{
defaultAttachment& defaultAttachment::operator=(const defaultAttachment& attach) {
m_type = attach.m_type;
m_desc = attach.m_desc;
m_name = attach.m_name;
m_data = vmime::clone(attach.m_data);
m_encoding = attach.m_encoding;
return (*this);
return *this;
}
void defaultAttachment::generateIn(const shared_ptr <bodyPart>& parent) const
{
void defaultAttachment::generateIn(const shared_ptr <bodyPart>& parent) const {
// Create and append a new part for this attachment
shared_ptr <bodyPart> part = make_shared <bodyPart>();
parent->getBody()->appendPart(part);
@ -87,8 +105,8 @@ void defaultAttachment::generateIn(const shared_ptr <bodyPart>& parent) const
}
void defaultAttachment::generatePart(const shared_ptr <bodyPart>& part) const
{
void defaultAttachment::generatePart(const shared_ptr <bodyPart>& part) const {
// Set header fields
part->getHeader()->ContentType()->setValue(m_type);
if (!m_desc.isEmpty()) part->getHeader()->ContentDescription()->setValue(m_desc);
@ -101,44 +119,44 @@ void defaultAttachment::generatePart(const shared_ptr <bodyPart>& part) const
}
const mediaType defaultAttachment::getType() const
{
const mediaType defaultAttachment::getType() const {
return m_type;
}
const text defaultAttachment::getDescription() const
{
const text defaultAttachment::getDescription() const {
return m_desc;
}
const word defaultAttachment::getName() const
{
const word defaultAttachment::getName() const {
return m_name;
}
const shared_ptr <const contentHandler> defaultAttachment::getData() const
{
const shared_ptr <const contentHandler> defaultAttachment::getData() const {
return m_data;
}
const encoding defaultAttachment::getEncoding() const
{
const encoding defaultAttachment::getEncoding() const {
return m_encoding;
}
shared_ptr <const object> defaultAttachment::getPart() const
{
shared_ptr <const object> defaultAttachment::getPart() const {
return null;
}
shared_ptr <const header> defaultAttachment::getHeader() const
{
shared_ptr <const header> defaultAttachment::getHeader() const {
return null;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -29,15 +29,13 @@
#include "vmime/encoding.hpp"
namespace vmime
{
namespace vmime {
/** Default implementation for attachments.
*/
class VMIME_EXPORT defaultAttachment : public attachment {
class VMIME_EXPORT defaultAttachment : public attachment
{
protected:
// For use in derived classes.
@ -45,8 +43,21 @@ protected:
public:
defaultAttachment(const shared_ptr <const contentHandler>& data, const encoding& enc, const mediaType& type, const text& desc = NULL_TEXT, const word& name = NULL_WORD);
defaultAttachment(const shared_ptr <const contentHandler>& data, const mediaType& type, const text& desc = NULL_TEXT, const word& name = NULL_WORD);
defaultAttachment(
const shared_ptr <const contentHandler>& data,
const encoding& enc,
const mediaType& type,
const text& desc = NULL_TEXT,
const word& name = NULL_WORD
);
defaultAttachment(
const shared_ptr <const contentHandler>& data,
const mediaType& type,
const text& desc = NULL_TEXT,
const word& name = NULL_WORD
);
defaultAttachment(const defaultAttachment& attach);
~defaultAttachment();

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -27,25 +27,30 @@
#include "vmime/utility/stringUtils.hpp"
namespace vmime
{
namespace vmime {
disposition::disposition()
{
disposition::disposition() {
}
disposition::disposition(const string& actionMode, const string& sendingMode,
const string& type, const string& modifier)
: m_actionMode(actionMode), m_sendingMode(sendingMode), m_type(type)
{
disposition::disposition(
const string& actionMode,
const string& sendingMode,
const string& type,
const string& modifier
)
: m_actionMode(actionMode),
m_sendingMode(sendingMode),
m_type(type) {
m_modifiers.push_back(modifier);
}
shared_ptr <component> disposition::clone() const
{
shared_ptr <component> disposition::clone() const {
shared_ptr <disposition> disp = make_shared <disposition>();
disp->m_actionMode = m_actionMode;
@ -55,12 +60,12 @@ shared_ptr <component> disposition::clone() const
std::copy(m_modifiers.begin(), m_modifiers.end(), disp->m_modifiers.begin());
return (disp);
return disp;
}
void disposition::copyFrom(const component& other)
{
void disposition::copyFrom(const component& other) {
const disposition& disp = dynamic_cast <const disposition&>(other);
m_actionMode = disp.m_actionMode;
@ -72,71 +77,71 @@ void disposition::copyFrom(const component& other)
}
disposition& disposition::operator=(const disposition& other)
{
disposition& disposition::operator=(const disposition& other) {
copyFrom(other);
return (*this);
return *this;
}
const std::vector <shared_ptr <component> > disposition::getChildComponents()
{
const std::vector <shared_ptr <component> > disposition::getChildComponents() {
return std::vector <shared_ptr <component> >();
}
void disposition::setActionMode(const string& mode)
{
void disposition::setActionMode(const string& mode) {
m_actionMode = mode;
}
const string& disposition::getActionMode() const
{
return (m_actionMode);
const string& disposition::getActionMode() const {
return m_actionMode;
}
void disposition::setSendingMode(const string& mode)
{
void disposition::setSendingMode(const string& mode) {
m_sendingMode = mode;
}
const string& disposition::getSendingMode() const
{
return (m_sendingMode);
const string& disposition::getSendingMode() const {
return m_sendingMode;
}
void disposition::setType(const string& type)
{
void disposition::setType(const string& type) {
m_type = type;
}
const string& disposition::getType() const
{
return (m_type);
const string& disposition::getType() const {
return m_type;
}
void disposition::addModifier(const string& modifier)
{
if (!hasModifier(modifier))
void disposition::addModifier(const string& modifier) {
if (!hasModifier(modifier)) {
m_modifiers.push_back(utility::stringUtils::toLower(modifier));
}
}
void disposition::removeModifier(const string& modifier)
{
void disposition::removeModifier(const string& modifier) {
const string modifierLC = utility::stringUtils::toLower(modifier);
for (std::vector <string>::iterator it = m_modifiers.begin() ;
it != m_modifiers.end() ; ++it)
{
if (*it == modifierLC)
{
it != m_modifiers.end() ; ++it) {
if (*it == modifierLC) {
m_modifiers.erase(it);
break;
}
@ -144,37 +149,42 @@ void disposition::removeModifier(const string& modifier)
}
void disposition::removeAllModifiers()
{
void disposition::removeAllModifiers() {
m_modifiers.clear();
}
bool disposition::hasModifier(const string& modifier) const
{
bool disposition::hasModifier(const string& modifier) const {
const string modifierLC = utility::stringUtils::toLower(modifier);
for (std::vector <string>::const_iterator it = m_modifiers.begin() ;
it != m_modifiers.end() ; ++it)
{
if (*it == modifierLC)
return (true);
it != m_modifiers.end() ; ++it) {
if (*it == modifierLC) {
return true;
}
}
return (false);
return false;
}
const std::vector <string> disposition::getModifierList() const
{
return (m_modifiers);
const std::vector <string> disposition::getModifierList() const {
return m_modifiers;
}
void disposition::parseImpl
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void disposition::parseImpl(
const parsingContext& /* ctx */,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
// disposition-mode ";" disposition-type
// [ "/" disposition-modifier *( "," disposition-modifier ) ]
//
@ -182,105 +192,116 @@ void disposition::parseImpl
size_t pos = position;
while (pos < end && parserHelpers::isSpace(buffer[pos]))
while (pos < end && parserHelpers::isSpace(buffer[pos])) {
++pos;
}
// -- disposition-mode
const size_t modeStart = pos;
size_t modeEnd = pos;
while (pos < end && buffer[pos] != ';')
{
while (pos < end && buffer[pos] != ';') {
++modeEnd;
++pos;
}
while (modeEnd > modeStart && parserHelpers::isSpace(buffer[modeEnd - 1]))
while (modeEnd > modeStart && parserHelpers::isSpace(buffer[modeEnd - 1])) {
--modeEnd;
}
const string mode = string(buffer.begin() + modeStart, buffer.begin() + modeEnd);
const size_t slash = mode.find('/');
if (slash != string::npos)
{
if (slash != string::npos) {
m_actionMode = string(mode.begin(), mode.begin() + slash);
m_sendingMode = string(mode.begin() + slash + 1, mode.end());
}
else
{
} else {
m_actionMode = mode;
m_sendingMode.clear();
}
if (pos < end)
{
if (pos < end) {
// Skip ';'
++pos;
}
while (pos < end && parserHelpers::isSpace(buffer[pos]))
while (pos < end && parserHelpers::isSpace(buffer[pos])) {
++pos;
}
// -- disposition-type
const size_t typeStart = pos;
size_t typeEnd = pos;
while (pos < end && buffer[pos] != '/')
{
while (pos < end && buffer[pos] != '/') {
++typeEnd;
++pos;
}
while (typeEnd > typeStart && parserHelpers::isSpace(buffer[typeEnd - 1]))
while (typeEnd > typeStart && parserHelpers::isSpace(buffer[typeEnd - 1])) {
--typeEnd;
}
m_type = string(buffer.begin() + typeStart, buffer.begin() + typeEnd);
m_modifiers.clear();
if (pos < end) // modifiers follow
{
if (pos < end) { // modifiers follow
// Skip '/'
++pos;
while (pos < end)
{
while (pos < end && parserHelpers::isSpace(buffer[pos]))
while (pos < end) {
while (pos < end && parserHelpers::isSpace(buffer[pos])) {
++pos;
}
const size_t modifierStart = pos;
size_t modifierEnd = pos;
while (pos < end && buffer[pos] != ',')
{
while (pos < end && buffer[pos] != ',') {
++modifierEnd;
++pos;
}
while (modifierEnd > modifierStart && parserHelpers::isSpace(buffer[modifierEnd - 1]))
while (modifierEnd > modifierStart && parserHelpers::isSpace(buffer[modifierEnd - 1])) {
--modifierEnd;
}
if (modifierEnd > modifierStart)
{
m_modifiers.push_back(string(buffer.begin() + modifierStart,
buffer.begin() + modifierEnd));
if (modifierEnd > modifierStart) {
m_modifiers.push_back(
string(
buffer.begin() + modifierStart,
buffer.begin() + modifierEnd
)
);
}
// Skip ','
if (pos < end)
if (pos < end) {
++pos;
}
}
}
if (newPosition)
if (newPosition) {
*newPosition = pos;
}
}
void disposition::generateImpl
(const generationContext& ctx, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
void disposition::generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
size_t pos = curLinePos;
const string actionMode = (m_actionMode.empty() ? "automatic-action" : m_actionMode);
@ -289,8 +310,7 @@ void disposition::generateImpl
os << actionMode << "/" << sendingMode << ";";
pos += actionMode.length() + 1 + sendingMode.length() + 1;
if (pos > ctx.getMaxLineLength())
{
if (pos > ctx.getMaxLineLength()) {
os << NEW_LINE_SEQUENCE;
pos = NEW_LINE_SEQUENCE_LENGTH;
}
@ -300,18 +320,19 @@ void disposition::generateImpl
os << type;
pos += type.length();
if (m_modifiers.size() >= 1)
{
for (std::vector <string>::size_type i = 0, n = 0 ; i < m_modifiers.size() ; ++i)
{
if (m_modifiers.size() >= 1) {
for (std::vector <string>::size_type i = 0, n = 0 ; i < m_modifiers.size() ; ++i) {
const string mod = utility::stringUtils::trim(m_modifiers[i]);
if (!mod.empty())
{
if (n == 0)
if (!mod.empty()) {
if (n == 0) {
os << "/";
else
} else {
os << ",";
}
os << mod;
pos += 1 + mod.length();
@ -321,8 +342,9 @@ void disposition::generateImpl
}
}
if (newLinePos)
if (newLinePos) {
*newLinePos = pos;
}
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -31,19 +31,22 @@
#include <vector>
namespace vmime
{
namespace vmime {
/** Disposition - from RFC-3798 (basic type).
*/
class VMIME_EXPORT disposition : public headerFieldValue {
class VMIME_EXPORT disposition : public headerFieldValue
{
public:
disposition();
disposition(const string& actionMode, const string& sendingMode, const string& type, const string& modifier);
disposition(
const string& actionMode,
const string& sendingMode,
const string& type,
const string& modifier
);
shared_ptr <component> clone() const;
@ -137,18 +140,20 @@ private:
protected:
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
};
@ -156,4 +161,3 @@ protected:
#endif // VMIME_DISPOSITION_HPP_INCLUDED

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -31,8 +31,7 @@
#include "vmime/utility/stringUtils.hpp"
namespace vmime
{
namespace vmime {
/** Decode an IDNA-encoded domain name ("xn--5rtw95l.xn--wgv71a")
@ -41,48 +40,52 @@ namespace vmime
* @param idnaDomain domain name encoded with IDNA
* @return decoded domain name in UTF-8
*/
static const string domainNameFromIDNA(const string& idnaDomain)
{
static const string domainNameFromIDNA(const string& idnaDomain) {
std::ostringstream domainName;
size_t p = 0;
for (size_t n = idnaDomain.find('.', p) ;
(n = idnaDomain.find('.', p)) != string::npos ; p = n + 1)
{
(n = idnaDomain.find('.', p)) != string::npos ; p = n + 1) {
const string encodedPart(idnaDomain.begin() + p, idnaDomain.begin() + n);
if (encodedPart.length() > 4 &&
encodedPart[0] == 'x' && encodedPart[1] == 'n' &&
encodedPart[2] == '-' && encodedPart[3] == '-')
{
encodedPart[2] == '-' && encodedPart[3] == '-') {
string decodedPart;
charset::convert(encodedPart, decodedPart,
vmime::charsets::IDNA, vmime::charsets::UTF_8);
charset::convert(
encodedPart, decodedPart,
vmime::charsets::IDNA, vmime::charsets::UTF_8
);
domainName << decodedPart << '.';
}
else
{
} else {
domainName << encodedPart << '.'; // not encoded
}
}
if (p < idnaDomain.length())
{
if (p < idnaDomain.length()) {
const string encodedPart(idnaDomain.begin() + p, idnaDomain.end());
if (encodedPart.length() > 4 &&
encodedPart[0] == 'x' && encodedPart[1] == 'n' &&
encodedPart[2] == '-' && encodedPart[3] == '-')
{
encodedPart[2] == '-' && encodedPart[3] == '-') {
string decodedPart;
charset::convert(encodedPart, decodedPart,
vmime::charsets::IDNA, vmime::charsets::UTF_8);
charset::convert(
encodedPart, decodedPart,
vmime::charsets::IDNA, vmime::charsets::UTF_8
);
domainName << decodedPart;
}
else
{
} else {
domainName << encodedPart; // not encoded
}
}
@ -97,26 +100,30 @@ static const string domainNameFromIDNA(const string& idnaDomain)
* @param domainName domain name in UTF-8
* @return domain name encoded with IDNA
*/
static const string domainNameToIDNA(const string& domainName)
{
static const string domainNameToIDNA(const string& domainName) {
std::ostringstream idnaDomain;
size_t p = 0;
for (size_t n = domainName.find('.', p) ;
(n = domainName.find('.', p)) != string::npos ; p = n + 1)
{
(n = domainName.find('.', p)) != string::npos ; p = n + 1) {
string idnaPart;
charset::convert(string(domainName.begin() + p, domainName.begin() + n),
idnaPart, vmime::charsets::UTF_8, vmime::charsets::IDNA);
charset::convert(
string(domainName.begin() + p, domainName.begin() + n), idnaPart,
vmime::charsets::UTF_8, vmime::charsets::IDNA
);
idnaDomain << idnaPart << '.';
}
if (p < domainName.length())
{
if (p < domainName.length()) {
string idnaPart;
charset::convert(string(domainName.begin() + p, domainName.end()),
idnaPart, vmime::charsets::UTF_8, vmime::charsets::IDNA);
charset::convert(
string(domainName.begin() + p, domainName.end()), idnaPart,
vmime::charsets::UTF_8, vmime::charsets::IDNA
);
idnaDomain << idnaPart;
}
@ -127,52 +134,60 @@ static const string domainNameToIDNA(const string& domainName)
emailAddress::emailAddress()
{
emailAddress::emailAddress() {
}
emailAddress::emailAddress(const emailAddress& eml)
: component(), m_localName(eml.m_localName), m_domainName(eml.m_domainName)
{
: component(),
m_localName(eml.m_localName),
m_domainName(eml.m_domainName) {
}
emailAddress::emailAddress(const string& email)
{
emailAddress::emailAddress(const string& email) {
parse(email);
}
emailAddress::emailAddress(const char* email)
{
emailAddress::emailAddress(const char* email) {
parse(email);
}
emailAddress::emailAddress(const string& localName, const string& domainName)
: component(), m_localName(word(localName, vmime::charsets::UTF_8)),
m_domainName(word(domainName, vmime::charsets::UTF_8))
{
: component(),
m_localName(word(localName, vmime::charsets::UTF_8)),
m_domainName(word(domainName, vmime::charsets::UTF_8)) {
}
emailAddress::emailAddress(const word& localName, const word& domainName)
: component(), m_localName(localName), m_domainName(domainName)
{
: component(),
m_localName(localName),
m_domainName(domainName) {
}
void emailAddress::parseImpl
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void emailAddress::parseImpl(
const parsingContext& /* ctx */,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
const char* const pend = buffer.data() + end;
const char* const pstart = buffer.data() + position;
const char* p = pstart;
enum ParserStates
{
enum ParserStates {
State_Before,
State_LocalPartStart,
State_LocalPartMiddle,
@ -199,361 +214,367 @@ void emailAddress::parseImpl
int commentLevel = 0;
bool localPartIsRFC2047 = false;
while (p < pend && !stop)
{
while (p < pend && !stop) {
const char c = *p;
if ((localPart.str().length() + domainPart.str().length()) >= 256)
{
if ((localPart.str().length() + domainPart.str().length()) >= 256) {
state = State_Error;
break;
}
switch (state)
{
case State_Before:
switch (state) {
if (parserHelpers::isSpace(c))
++p;
else
state = State_LocalPartStart;
case State_Before:
break;
case State_LocalPartStart:
if (c == '"')
{
state = State_LocalPartQuoted;
++p;
}
else if (c == '=')
{
state = State_LocalPartRFC2047Start;
++p;
}
else if (c == '(')
{
state = State_LocalPartComment;
++commentLevel;
++p;
}
else
{
state = State_LocalPartMiddle;
localPart << c;
++p;
}
break;
case State_LocalPartComment:
if (escapeNext)
{
escapeNext = false;
++p;
}
else if (c == '\\')
{
escapeNext = true;
++p;
}
else if (c == '(')
{
++commentLevel;
++p;
}
else if (c == ')')
{
if (--commentLevel == 0)
{
// End of comment
state = State_LocalPartMiddle;
if (parserHelpers::isSpace(c)) {
++p;
} else {
state = State_LocalPartStart;
}
++p;
}
else
{
// Comment continues
++p;
}
break;
break;
case State_LocalPartStart:
case State_LocalPartQuoted:
if (c == '"') {
if (escapeNext)
{
escapeNext = false;
state = State_LocalPartQuoted;
++p;
if (c == '"' || c == '\\')
{
} else if (c == '=') {
state = State_LocalPartRFC2047Start;
++p;
} else if (c == '(') {
state = State_LocalPartComment;
++commentLevel;
++p;
} else {
state = State_LocalPartMiddle;
localPart << c;
++p;
}
else
{
// This char cannot be escaped
state = State_Error;
break;
case State_LocalPartComment:
if (escapeNext) {
escapeNext = false;
++p;
} else if (c == '\\') {
escapeNext = true;
++p;
} else if (c == '(') {
++commentLevel;
++p;
} else if (c == ')') {
if (--commentLevel == 0) {
// End of comment
state = State_LocalPartMiddle;
}
++p;
} else {
// Comment continues
++p;
}
}
else if (c == '"')
{
// End of quoted string
state = State_LocalPartMiddle;
++p;
}
else if (c == '\\')
{
escapeNext = true;
++p;
}
else
{
localPart << c;
++p;
}
break;
break;
case State_LocalPartRFC2047Start:
case State_LocalPartQuoted:
if (c == '?')
{
state = State_LocalPartRFC2047Middle;
localPart << "=?";
localPartIsRFC2047 = true;
++p;
}
else
{
state = State_LocalPartMiddle;
localPart << '=';
localPart << c;
++p;
}
if (escapeNext) {
break;
escapeNext = false;
case State_LocalPartMiddle:
if (c == '"' || c == '\\') {
if (c == '.')
{
prevIsDot = true;
localPart << c;
++p;
}
else if (c == '"' && prevIsDot)
{
prevIsDot = false;
state = State_LocalPartQuoted;
++p;
}
else if (c == '(')
{
// By allowing comments anywhere in the local part,
// we are more permissive than RFC-2822
state = State_LocalPartComment;
++commentLevel;
++p;
}
else if (c == '@')
{
atFound = true;
state = State_DomainPartStart;
++p;
}
else if (parserHelpers::isSpace(c))
{
// Allow not specifying domain part
state = State_End;
}
else
{
prevIsDot = false;
localPart << c;
++p;
}
localPart << c;
++p;
break;
} else {
case State_LocalPartRFC2047Middle:
// This char cannot be escaped
state = State_Error;
}
if (c == '?')
{
state = State_LocalPartRFC2047MiddleQM;
++p;
}
else
{
localPart << c;
++p;
}
} else if (c == '"') {
break;
// End of quoted string
state = State_LocalPartMiddle;
++p;
case State_LocalPartRFC2047MiddleQM:
} else if (c == '\\') {
if (c == '=')
{
// End of RFC-2047 encoded word
state = State_LocalPartRFC2047End;
localPart << "?=";
++p;
}
else
{
state = State_LocalPartRFC2047Middle;
localPart << '?';
localPart << c;
++p;
}
escapeNext = true;
++p;
break;
} else {
case State_LocalPartRFC2047End:
localPart << c;
++p;
}
if (c == '@')
{
atFound = true;
state = State_DomainPartStart;
++p;
}
else
{
state = State_End;
}
break;
break;
case State_LocalPartRFC2047Start:
case State_DomainPartStart:
if (c == '?') {
if (c == '(')
{
state = State_DomainPartComment;
++commentLevel;
++p;
}
else
{
state = State_DomainPartMiddle;
domainPart << c;
++p;
}
state = State_LocalPartRFC2047Middle;
localPart << "=?";
localPartIsRFC2047 = true;
++p;
break;
} else {
case State_DomainPartMiddle:
state = State_LocalPartMiddle;
localPart << '=';
localPart << c;
++p;
}
if (parserHelpers::isSpace(c))
{
state = State_End;
}
else if (c == '(')
{
// By allowing comments anywhere in the domain part,
// we are more permissive than RFC-2822
state = State_DomainPartComment;
++commentLevel;
++p;
}
else
{
domainPart << c;
++p;
}
break;
break;
case State_LocalPartMiddle:
case State_DomainPartComment:
if (c == '.') {
prevIsDot = true;
localPart << c;
++p;
} else if (c == '"' && prevIsDot) {
prevIsDot = false;
state = State_LocalPartQuoted;
++p;
} else if (c == '(') {
// By allowing comments anywhere in the local part,
// we are more permissive than RFC-2822
state = State_LocalPartComment;
++commentLevel;
++p;
} else if (c == '@') {
atFound = true;
state = State_DomainPartStart;
++p;
} else if (parserHelpers::isSpace(c)) {
// Allow not specifying domain part
state = State_End;
} else {
prevIsDot = false;
localPart << c;
++p;
}
break;
case State_LocalPartRFC2047Middle:
if (c == '?') {
state = State_LocalPartRFC2047MiddleQM;
++p;
} else {
localPart << c;
++p;
}
break;
case State_LocalPartRFC2047MiddleQM:
if (c == '=') {
// End of RFC-2047 encoded word
state = State_LocalPartRFC2047End;
localPart << "?=";
++p;
} else {
state = State_LocalPartRFC2047Middle;
localPart << '?';
localPart << c;
++p;
}
break;
case State_LocalPartRFC2047End:
if (c == '@') {
atFound = true;
state = State_DomainPartStart;
++p;
} else {
state = State_End;
}
break;
case State_DomainPartStart:
if (c == '(') {
state = State_DomainPartComment;
++commentLevel;
++p;
} else {
if (escapeNext)
{
escapeNext = false;
++p;
}
else if (c == '\\')
{
escapeNext = true;
++p;
}
else if (c == '(')
{
++commentLevel;
++p;
}
else if (c == ')')
{
if (--commentLevel == 0)
{
// End of comment
state = State_DomainPartMiddle;
domainPart << c;
++p;
}
++p;
}
else
{
// Comment continues
++p;
}
break;
break;
case State_DomainPartMiddle:
case State_End:
case State_Error:
if (parserHelpers::isSpace(c)) {
stop = true;
break;
state = State_End;
} else if (c == '(') {
// By allowing comments anywhere in the domain part,
// we are more permissive than RFC-2822
state = State_DomainPartComment;
++commentLevel;
++p;
} else {
domainPart << c;
++p;
}
break;
case State_DomainPartComment:
if (escapeNext) {
escapeNext = false;
++p;
} else if (c == '\\') {
escapeNext = true;
++p;
} else if (c == '(') {
++commentLevel;
++p;
} else if (c == ')') {
if (--commentLevel == 0) {
// End of comment
state = State_DomainPartMiddle;
}
++p;
} else {
// Comment continues
++p;
}
break;
case State_End:
case State_Error:
stop = true;
break;
}
}
if (p == pend && state != State_Error)
{
if (state == State_DomainPartMiddle)
if (p == pend && state != State_Error) {
if (state == State_DomainPartMiddle) {
state = State_End;
else if (state == State_LocalPartMiddle)
} else if (state == State_LocalPartMiddle) {
state = State_End; // allow not specifying domain part
}
}
if (state != State_End)
{
if (state != State_End) {
m_localName = word("invalid", vmime::charsets::UTF_8);
m_domainName = word("invalid", vmime::charsets::UTF_8);
}
else
{
// If the domain part is missing, use local host name
if (domainPart.str().empty() && !atFound)
domainPart << platform::getHandler()->getHostName();
if (localPartIsRFC2047)
} else {
// If the domain part is missing, use local host name
if (domainPart.str().empty() && !atFound) {
domainPart << platform::getHandler()->getHostName();
}
if (localPartIsRFC2047) {
m_localName.parse(localPart.str());
else
} else {
m_localName = word(localPart.str(), vmime::charsets::UTF_8);
}
m_domainName = word(domainNameFromIDNA(domainPart.str()), vmime::charsets::UTF_8);
}
setParsedBounds(position, p - pend);
if (newPosition)
if (newPosition) {
*newPosition = p - pend;
}
}
void emailAddress::generateImpl
(const generationContext& ctx, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
void emailAddress::generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
string localPart, domainPart;
if (ctx.getInternationalizedEmailSupport() &&
(!utility::stringUtils::is7bit(m_localName.getBuffer()) ||
!utility::stringUtils::is7bit(m_domainName.getBuffer())))
{
!utility::stringUtils::is7bit(m_domainName.getBuffer()))) {
// Local part
string localPartUTF8(m_localName.getConvertedText(vmime::charsets::UTF_8));
word localPartWord(localPartUTF8, vmime::charsets::UTF_8);
@ -563,9 +584,9 @@ void emailAddress::generateImpl
// Domain part
domainPart = m_domainName.getConvertedText(vmime::charsets::UTF_8);
}
else
{
} else {
// Local part
vmime::utility::outputStreamStringAdapter os(localPart);
m_localName.generate(ctx, os, 0, NULL, text::QUOTE_IF_NEEDED, NULL);
@ -578,8 +599,8 @@ void emailAddress::generateImpl
<< "@"
<< domainPart;
if (newLinePos)
{
if (newLinePos) {
*newLinePos = curLinePos
+ localPart.length()
+ 1 // @
@ -588,21 +609,21 @@ void emailAddress::generateImpl
}
bool emailAddress::operator==(const class emailAddress& eml) const
{
return (m_localName == eml.m_localName &&
m_domainName == eml.m_domainName);
bool emailAddress::operator==(const class emailAddress& eml) const {
return m_localName == eml.m_localName &&
m_domainName == eml.m_domainName;
}
bool emailAddress::operator!=(const class emailAddress& eml) const
{
bool emailAddress::operator!=(const class emailAddress& eml) const {
return !(*this == eml);
}
void emailAddress::copyFrom(const component& other)
{
void emailAddress::copyFrom(const component& other) {
const emailAddress& source = dynamic_cast <const emailAddress&>(other);
m_localName = source.m_localName;
@ -610,57 +631,57 @@ void emailAddress::copyFrom(const component& other)
}
emailAddress& emailAddress::operator=(const emailAddress& other)
{
emailAddress& emailAddress::operator=(const emailAddress& other) {
copyFrom(other);
return (*this);
return *this;
}
shared_ptr <component>emailAddress::clone() const
{
shared_ptr <component>emailAddress::clone() const {
return make_shared <emailAddress>(*this);
}
const word& emailAddress::getLocalName() const
{
const word& emailAddress::getLocalName() const {
return m_localName;
}
void emailAddress::setLocalName(const word& localName)
{
void emailAddress::setLocalName(const word& localName) {
m_localName = localName;
}
const word& emailAddress::getDomainName() const
{
const word& emailAddress::getDomainName() const {
return m_domainName;
}
void emailAddress::setDomainName(const word& domainName)
{
void emailAddress::setDomainName(const word& domainName) {
m_domainName = domainName;
}
const std::vector <shared_ptr <component> > emailAddress::getChildComponents()
{
const std::vector <shared_ptr <component> > emailAddress::getChildComponents() {
return std::vector <shared_ptr <component> >();
}
bool emailAddress::isEmpty() const
{
bool emailAddress::isEmpty() const {
return m_localName.isEmpty();
}
const string emailAddress::toString() const
{
const string emailAddress::toString() const {
std::ostringstream oss;
utility::outputStreamAdapter adapter(oss);
@ -673,8 +694,8 @@ const string emailAddress::toString() const
}
const text emailAddress::toText() const
{
const text emailAddress::toText() const {
text txt;
txt.appendWord(make_shared <vmime::word>(m_localName));
txt.appendWord(make_shared <vmime::word>("@", vmime::charsets::US_ASCII));

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -29,15 +29,13 @@
#include "vmime/text.hpp"
namespace vmime
{
namespace vmime {
/** An email address: local name and domain name (basic type).
*/
class VMIME_EXPORT emailAddress : public component {
class VMIME_EXPORT emailAddress : public component
{
public:
emailAddress();
@ -114,18 +112,20 @@ public:
using component::generate;
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -24,92 +24,101 @@
#include "vmime/emptyContentHandler.hpp"
namespace vmime
{
namespace vmime {
emptyContentHandler::emptyContentHandler()
{
emptyContentHandler::emptyContentHandler() {
}
shared_ptr <contentHandler> emptyContentHandler::clone() const
{
shared_ptr <contentHandler> emptyContentHandler::clone() const {
return make_shared <emptyContentHandler>();
}
void emptyContentHandler::generate(utility::outputStream& /* os */, const vmime::encoding& /* enc */,
const size_t /* maxLineLength */) const
{
void emptyContentHandler::generate(
utility::outputStream& /* os */,
const vmime::encoding& /* enc */,
const size_t /* maxLineLength */
) const {
// Nothing to do.
}
void emptyContentHandler::extract(utility::outputStream& /* os */,
void emptyContentHandler::extract(
utility::outputStream& /* os */,
utility::progressListener* progress) const
{
if (progress)
if (progress) {
progress->start(0);
}
// Nothing to do.
if (progress)
if (progress) {
progress->stop(0);
}
}
void emptyContentHandler::extractRaw(utility::outputStream& /* os */,
utility::progressListener* progress) const
{
if (progress)
void emptyContentHandler::extractRaw(
utility::outputStream& /* os */,
utility::progressListener* progress
) const {
if (progress) {
progress->start(0);
}
// Nothing to do.
if (progress)
if (progress) {
progress->stop(0);
}
}
size_t emptyContentHandler::getLength() const
{
return (0);
size_t emptyContentHandler::getLength() const {
return 0;
}
bool emptyContentHandler::isEmpty() const
{
return (true);
}
bool emptyContentHandler::isEmpty() const {
bool emptyContentHandler::isEncoded() const
{
return (false);
}
const vmime::encoding& emptyContentHandler::getEncoding() const
{
return (NO_ENCODING);
}
bool emptyContentHandler::isBuffered() const
{
return true;
}
void emptyContentHandler::setContentTypeHint(const mediaType& type)
{
bool emptyContentHandler::isEncoded() const {
return false;
}
const vmime::encoding& emptyContentHandler::getEncoding() const {
return NO_ENCODING;
}
bool emptyContentHandler::isBuffered() const {
return true;
}
void emptyContentHandler::setContentTypeHint(const mediaType& type) {
m_contentType = type;
}
const mediaType emptyContentHandler::getContentTypeHint() const
{
const mediaType emptyContentHandler::getContentTypeHint() const {
return m_contentType;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -28,22 +28,32 @@
#include "vmime/contentHandler.hpp"
namespace vmime
{
namespace vmime {
class VMIME_EXPORT emptyContentHandler : public contentHandler
{
class VMIME_EXPORT emptyContentHandler : public contentHandler {
public:
emptyContentHandler();
shared_ptr <contentHandler> clone() const;
void generate(utility::outputStream& os, const vmime::encoding& enc, const size_t maxLineLength = lineLengthLimits::infinite) const;
void generate(
utility::outputStream& os,
const vmime::encoding& enc,
const size_t maxLineLength = lineLengthLimits::infinite
) const;
void extract(utility::outputStream& os, utility::progressListener* progress = NULL) const;
void extractRaw(utility::outputStream& os, utility::progressListener* progress = NULL) const;
void extract(
utility::outputStream& os,
utility::progressListener* progress = NULL
) const;
void extractRaw(
utility::outputStream& os,
utility::progressListener* progress = NULL
) const;
size_t getLength() const;

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -30,118 +30,140 @@
#include <algorithm>
namespace vmime
{
namespace vmime {
encoding::encoding()
: m_name(encodingTypes::SEVEN_BIT),
m_usage(USAGE_UNKNOWN)
{
m_usage(USAGE_UNKNOWN) {
}
encoding::encoding(const string& name)
: m_name(utility::stringUtils::toLower(name)),
m_usage(USAGE_UNKNOWN)
{
m_usage(USAGE_UNKNOWN) {
}
encoding::encoding(const string& name, const EncodingUsage usage)
: m_name(utility::stringUtils::toLower(name)),
m_usage(usage)
{
m_usage(usage) {
}
encoding::encoding(const encoding& enc)
: headerFieldValue(), m_name(enc.m_name), m_usage(enc.m_usage)
{
: headerFieldValue(),
m_name(enc.m_name),
m_usage(enc.m_usage) {
}
void encoding::parseImpl
(const parsingContext& /* ctx */, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void encoding::parseImpl(
const parsingContext& /* ctx */,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
m_usage = USAGE_UNKNOWN;
m_name = utility::stringUtils::toLower(utility::stringUtils::trim
(utility::stringUtils::unquote(utility::stringUtils::trim
(string(buffer.begin() + position, buffer.begin() + end)))));
m_name = utility::stringUtils::toLower(
utility::stringUtils::trim(
utility::stringUtils::unquote(
utility::stringUtils::trim(
string(buffer.begin() + position, buffer.begin() + end)
)
)
)
);
if (m_name.empty())
if (m_name.empty()) {
m_name = encodingTypes::SEVEN_BIT; // assume default "7-bit"
}
setParsedBounds(position, end);
if (newPosition)
if (newPosition) {
*newPosition = end;
}
}
void encoding::generateImpl
(const generationContext& /* ctx */, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
void encoding::generateImpl(
const generationContext& /* ctx */,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
os << m_name;
if (newLinePos)
if (newLinePos) {
*newLinePos = curLinePos + m_name.length();
}
}
shared_ptr <utility::encoder::encoder> encoding::getEncoder() const
{
shared_ptr <utility::encoder::encoder> encoding::getEncoder() const {
shared_ptr <utility::encoder::encoder> encoder =
utility::encoder::encoderFactory::getInstance()->create(generate());
// FIXME: this should not be here (move me into QP encoder instead?)
if (m_usage == USAGE_TEXT && m_name == encodingTypes::QUOTED_PRINTABLE)
if (m_usage == USAGE_TEXT && m_name == encodingTypes::QUOTED_PRINTABLE) {
encoder->getProperties()["text"] = true;
}
return encoder;
}
encoding& encoding::operator=(const encoding& other)
{
encoding& encoding::operator=(const encoding& other) {
copyFrom(other);
return (*this);
}
encoding& encoding::operator=(const string& name)
{
encoding& encoding::operator=(const string& name) {
m_name = utility::stringUtils::toLower(name);
m_usage = USAGE_UNKNOWN;
return (*this);
return *this;
}
bool encoding::operator==(const encoding& value) const
{
return (utility::stringUtils::toLower(m_name) == value.m_name);
bool encoding::operator==(const encoding& value) const {
return utility::stringUtils::toLower(m_name) == value.m_name;
}
bool encoding::operator!=(const encoding& value) const
{
bool encoding::operator!=(const encoding& value) const {
return !(*this == value);
}
const encoding encoding::decideImpl
(const string::const_iterator begin, const string::const_iterator end)
{
const encoding encoding::decideImpl(
const string::const_iterator begin,
const string::const_iterator end
) {
const string::difference_type length = end - begin;
const string::difference_type count = std::count_if
(begin, end, std::bind2nd(std::less<unsigned char>(), 127));
const string::difference_type count = std::count_if(
begin, end,
std::bind2nd(std::less<unsigned char>(), 127)
);
// All is in 7-bit US-ASCII --> 7-bit (or Quoted-Printable...)
if (length == count)
{
if (length == count) {
// Now, we check if there is any line with more than
// "lineLengthLimits::convenient" characters (7-bit requires that)
string::const_iterator p = begin;
@ -149,49 +171,51 @@ const encoding encoding::decideImpl
const size_t maxLen = lineLengthLimits::convenient;
size_t len = 0;
for ( ; p != end && len <= maxLen ; )
{
if (*p == '\n')
{
for ( ; p != end && len <= maxLen ; ) {
if (*p == '\n') {
len = 0;
++p;
// May or may not need to be encoded, we don't take
// any risk (avoid problems with SMTP)
if (p != end && *p == '.')
if (p != end && *p == '.') {
len = maxLen + 1;
}
else
{
}
} else {
++len;
++p;
}
}
if (len > maxLen)
return (encoding(encodingTypes::QUOTED_PRINTABLE));
else
return (encoding(encodingTypes::SEVEN_BIT));
}
if (len > maxLen) {
return encoding(encodingTypes::QUOTED_PRINTABLE);
} else {
return encoding(encodingTypes::SEVEN_BIT);
}
// Less than 20% non US-ASCII --> Quoted-Printable
else if ((length - count) <= length / 5)
{
return (encoding(encodingTypes::QUOTED_PRINTABLE));
}
} else if ((length - count) <= length / 5) {
return encoding(encodingTypes::QUOTED_PRINTABLE);
// Otherwise --> Base64
else
{
return (encoding(encodingTypes::BASE64));
} else {
return encoding(encodingTypes::BASE64);
}
}
bool encoding::shouldReencode() const
{
bool encoding::shouldReencode() const {
if (m_name == encodingTypes::BASE64 ||
m_name == encodingTypes::QUOTED_PRINTABLE ||
m_name == encodingTypes::UUENCODE)
{
m_name == encodingTypes::UUENCODE) {
return false;
}
@ -199,18 +223,21 @@ bool encoding::shouldReencode() const
}
const encoding encoding::decide
(const shared_ptr <const contentHandler>& data, const EncodingUsage usage)
{
const encoding encoding::decide(
const shared_ptr <const contentHandler>& data,
const EncodingUsage usage
) {
// Do not re-encode data if it is already encoded
if (data->isEncoded() && !data->getEncoding().shouldReencode())
if (data->isEncoded() && !data->getEncoding().shouldReencode()) {
return data->getEncoding();
}
encoding enc;
if (usage == USAGE_TEXT && data->isBuffered() &&
data->getLength() > 0 && data->getLength() < 32768)
{
data->getLength() > 0 && data->getLength() < 32768) {
// Extract data into temporary buffer
string buffer;
utility::outputStreamStringAdapter os(buffer);
@ -219,9 +246,9 @@ const encoding encoding::decide
os.flush();
enc = decideImpl(buffer.begin(), buffer.end());
}
else
{
} else {
enc = encoding(encodingTypes::BASE64);
}
@ -231,19 +258,23 @@ const encoding encoding::decide
}
const encoding encoding::decide(const shared_ptr <const contentHandler>& data,
const charset& chset, const EncodingUsage usage)
{
// Do not re-encode data if it is already encoded
if (data->isEncoded() && !data->getEncoding().shouldReencode())
return data->getEncoding();
const encoding encoding::decide(
const shared_ptr <const contentHandler>& data,
const charset& chset,
const EncodingUsage usage
) {
// Do not re-encode data if it is already encoded
if (data->isEncoded() && !data->getEncoding().shouldReencode()) {
return data->getEncoding();
}
if (usage == USAGE_TEXT) {
if (usage == USAGE_TEXT)
{
encoding recEncoding;
if (chset.getRecommendedEncoding(recEncoding))
{
if (chset.getRecommendedEncoding(recEncoding)) {
recEncoding.setUsage(usage);
return recEncoding;
}
@ -253,46 +284,46 @@ const encoding encoding::decide(const shared_ptr <const contentHandler>& data,
}
shared_ptr <component> encoding::clone() const
{
shared_ptr <component> encoding::clone() const {
return make_shared <encoding>(*this);
}
void encoding::copyFrom(const component& other)
{
void encoding::copyFrom(const component& other) {
const encoding& e = dynamic_cast <const encoding&>(other);
m_name = e.m_name;
}
const string& encoding::getName() const
{
return (m_name);
const string& encoding::getName() const {
return m_name;
}
void encoding::setName(const string& name)
{
void encoding::setName(const string& name) {
m_name = name;
}
encoding::EncodingUsage encoding::getUsage() const
{
encoding::EncodingUsage encoding::getUsage() const {
return m_usage;
}
void encoding::setUsage(const EncodingUsage usage)
{
void encoding::setUsage(const EncodingUsage usage) {
m_usage = usage;
}
const std::vector <shared_ptr <component> > encoding::getChildComponents()
{
const std::vector <shared_ptr <component> > encoding::getChildComponents() {
return std::vector <shared_ptr <component> >();
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -31,8 +31,7 @@
#include "vmime/utility/encoder/encoder.hpp"
namespace vmime
{
namespace vmime {
class contentHandler;
@ -40,13 +39,12 @@ class contentHandler;
/** Content encoding (basic type).
*/
class VMIME_EXPORT encoding : public headerFieldValue {
class VMIME_EXPORT encoding : public headerFieldValue
{
public:
enum EncodingUsage
{
enum EncodingUsage {
USAGE_UNKNOWN,
USAGE_TEXT, /**< Use for body text. */
USAGE_BINARY_DATA /**< Use for attachment, image... */
@ -99,7 +97,10 @@ public:
* @param usage context of use of data
* @return suitable encoding for specified data
*/
static const encoding decide(const shared_ptr <const contentHandler>& data, const EncodingUsage usage = USAGE_BINARY_DATA);
static const encoding decide(
const shared_ptr <const contentHandler>& data,
const EncodingUsage usage = USAGE_BINARY_DATA
);
/** Decide which encoding to use based on the specified data and charset.
*
@ -108,7 +109,11 @@ public:
* @param usage context of use of data
* @return suitable encoding for specified data and charset
*/
static const encoding decide(const shared_ptr <const contentHandler>& data, const charset& chset, const EncodingUsage usage = USAGE_BINARY_DATA);
static const encoding decide(
const shared_ptr <const contentHandler>& data,
const charset& chset,
const EncodingUsage usage = USAGE_BINARY_DATA
);
shared_ptr <component> clone() const;
@ -144,23 +149,28 @@ private:
* @param end end iterator in buffer
* @return suitable encoding for specified data
*/
static const encoding decideImpl(const string::const_iterator begin, const string::const_iterator end);
static const encoding decideImpl(
const string::const_iterator begin,
const string::const_iterator end
);
protected:
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -35,31 +35,31 @@ const exception exception::NO_EXCEPTION;
exception::exception()
: std::runtime_error(""), m_other(NULL)
{
: std::runtime_error(""), m_other(NULL) {
}
exception::exception(const string& what, const exception& other)
: std::runtime_error(what), m_other(&other != &NO_EXCEPTION ? other.clone() : NULL)
{
: std::runtime_error(what), m_other(&other != &NO_EXCEPTION ? other.clone() : NULL) {
}
exception::exception(const exception& e)
: std::runtime_error(e.what()), m_other(e.m_other == NULL ? NULL : e.m_other->clone())
{
: std::runtime_error(e.what()), m_other(e.m_other == NULL ? NULL : e.m_other->clone()) {
}
exception::~exception() throw()
{
delete (m_other);
exception::~exception() throw() {
delete m_other;
}
void exception::chainException(const exception& other)
{
void exception::chainException(const exception& other) {
exception* e = other.clone();
delete m_other;
@ -67,27 +67,26 @@ void exception::chainException(const exception& other)
}
const exception* exception::other() const throw()
{
return (m_other);
const exception* exception::other() const throw() {
return m_other;
}
const char* exception::name() const throw()
{
const char* exception::name() const throw() {
return "exception";
}
exception* exception::clone() const
{
exception* exception::clone() const {
return new exception(*this);
}
namespace exceptions
{
namespace exceptions {
//

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -32,15 +32,13 @@
#include "vmime/utility/path.hpp"
namespace vmime
{
namespace vmime {
/** Base class for VMime exceptions.
*/
class VMIME_EXPORT exception : public std::runtime_error {
class VMIME_EXPORT exception : public std::runtime_error
{
private:
exception* m_other;
@ -87,13 +85,11 @@ protected:
/** List of all VMime exceptions. */
namespace exceptions
{
namespace exceptions {
class VMIME_EXPORT bad_field_value_type : public vmime::exception
{
class VMIME_EXPORT bad_field_value_type : public vmime::exception {
public:
bad_field_value_type(const string& fieldName, const exception& other = NO_EXCEPTION);
@ -104,8 +100,8 @@ public:
};
class VMIME_EXPORT charset_conv_error : public vmime::exception
{
class VMIME_EXPORT charset_conv_error : public vmime::exception {
public:
charset_conv_error(const string& what = "", const exception& other = NO_EXCEPTION);
@ -116,8 +112,8 @@ public:
};
class VMIME_EXPORT illegal_byte_sequence_for_charset : public vmime::exception
{
class VMIME_EXPORT illegal_byte_sequence_for_charset : public vmime::exception {
public:
illegal_byte_sequence_for_charset(const string& what = "", const exception& other = NO_EXCEPTION);
@ -130,9 +126,8 @@ public:
/** No encoder has been found for the specified encoding name.
*/
class VMIME_EXPORT no_encoder_available : public vmime::exception {
class VMIME_EXPORT no_encoder_available : public vmime::exception
{
public:
no_encoder_available(const string& name, const exception& other = NO_EXCEPTION);
@ -145,9 +140,8 @@ public:
/** No algorithm has been found for the specified name.
*/
class VMIME_EXPORT no_digest_algorithm_available : public vmime::exception {
class VMIME_EXPORT no_digest_algorithm_available : public vmime::exception
{
public:
no_digest_algorithm_available(const string& name, const exception& other = NO_EXCEPTION);
@ -158,8 +152,8 @@ public:
};
class VMIME_EXPORT no_such_field : public vmime::exception
{
class VMIME_EXPORT no_such_field : public vmime::exception {
public:
no_such_field(const exception& other = NO_EXCEPTION);
@ -170,8 +164,8 @@ public:
};
class VMIME_EXPORT no_such_part : public vmime::exception
{
class VMIME_EXPORT no_such_part : public vmime::exception {
public:
no_such_part(const exception& other = NO_EXCEPTION);
@ -182,8 +176,8 @@ public:
};
class VMIME_EXPORT no_such_message_id : public vmime::exception
{
class VMIME_EXPORT no_such_message_id : public vmime::exception {
public:
no_such_message_id(const exception& other = NO_EXCEPTION);
@ -194,8 +188,8 @@ public:
};
class VMIME_EXPORT open_file_error : public vmime::exception
{
class VMIME_EXPORT open_file_error : public vmime::exception {
public:
open_file_error(const exception& other = NO_EXCEPTION);
@ -206,8 +200,8 @@ public:
};
class VMIME_EXPORT no_factory_available : public vmime::exception
{
class VMIME_EXPORT no_factory_available : public vmime::exception {
public:
no_factory_available(const exception& other = NO_EXCEPTION);
@ -218,8 +212,8 @@ public:
};
class VMIME_EXPORT no_platform_handler : public vmime::exception
{
class VMIME_EXPORT no_platform_handler : public vmime::exception {
public:
no_platform_handler(const exception& other = NO_EXCEPTION);
@ -232,9 +226,8 @@ public:
/** No expeditor specified.
*/
class VMIME_EXPORT no_expeditor : public vmime::exception {
class VMIME_EXPORT no_expeditor : public vmime::exception
{
public:
no_expeditor(const exception& other = NO_EXCEPTION);
@ -247,9 +240,8 @@ public:
/** No recipient specified.
*/
class VMIME_EXPORT no_recipient : public vmime::exception {
class VMIME_EXPORT no_recipient : public vmime::exception
{
public:
no_recipient(const exception& other = NO_EXCEPTION);
@ -262,9 +254,8 @@ public:
/** There is no property with that name in the set.
*/
class VMIME_EXPORT no_such_property : public vmime::exception {
class VMIME_EXPORT no_such_property : public vmime::exception
{
public:
no_such_property(const string& name, const exception& other = NO_EXCEPTION);
@ -277,9 +268,8 @@ public:
/** Bad type specified when reading property.
*/
class VMIME_EXPORT invalid_property_type : public vmime::exception {
class VMIME_EXPORT invalid_property_type : public vmime::exception
{
public:
invalid_property_type(const exception& other = NO_EXCEPTION);
@ -292,9 +282,8 @@ public:
/** Bad argument was passed to the function.
*/
class VMIME_EXPORT invalid_argument : public vmime::exception {
class VMIME_EXPORT invalid_argument : public vmime::exception
{
public:
invalid_argument(const exception& other = NO_EXCEPTION);
@ -307,9 +296,8 @@ public:
/** Underlying operating system error.
*/
class VMIME_EXPORT system_error : public vmime::exception {
class VMIME_EXPORT system_error : public vmime::exception
{
public:
system_error(const string& what, const exception& other = NO_EXCEPTION);
@ -322,9 +310,8 @@ public:
/** The URL is malformed.
*/
class VMIME_EXPORT malformed_url : public vmime::exception {
class VMIME_EXPORT malformed_url : public vmime::exception
{
public:
malformed_url(const string& error, const exception& other = NO_EXCEPTION);
@ -341,9 +328,8 @@ public:
/** Base class for exceptions thrown by the networking module.
*/
class VMIME_EXPORT net_exception : public vmime::exception {
class VMIME_EXPORT net_exception : public vmime::exception
{
public:
net_exception(const string& what, const exception& other = NO_EXCEPTION);
@ -362,9 +348,8 @@ typedef net_exception messaging_exception;
/** Socket error.
*/
class VMIME_EXPORT socket_exception : public net_exception {
class VMIME_EXPORT socket_exception : public net_exception
{
public:
socket_exception(const string& what = "", const exception& other = NO_EXCEPTION);
@ -379,9 +364,8 @@ public:
/** Socket not connected: you are trying to write to/read from a socket which
* is not connected to a peer.
*/
class VMIME_EXPORT socket_not_connected_exception : public socket_exception {
class VMIME_EXPORT socket_not_connected_exception : public socket_exception
{
public:
socket_not_connected_exception(const string& what = "", const exception& other = NO_EXCEPTION);
@ -396,9 +380,8 @@ public:
/** Error while connecting to the server: this may be a DNS resolution error
* or a connection error (for example, time-out while connecting).
*/
class VMIME_EXPORT connection_error : public socket_exception {
class VMIME_EXPORT connection_error : public socket_exception
{
public:
connection_error(const string& what = "", const exception& other = NO_EXCEPTION);
@ -411,9 +394,8 @@ public:
/** Server did not initiated the connection correctly.
*/
class VMIME_EXPORT connection_greeting_error : public net_exception {
class VMIME_EXPORT connection_greeting_error : public net_exception
{
public:
connection_greeting_error(const string& response, const exception& other = NO_EXCEPTION);
@ -433,9 +415,8 @@ private:
/** Error while giving credentials to the server (wrong username
* or password, or wrong authentication method).
*/
class VMIME_EXPORT authentication_error : public net_exception {
class VMIME_EXPORT authentication_error : public net_exception
{
public:
authentication_error(const string& response, const exception& other = NO_EXCEPTION);
@ -454,9 +435,8 @@ private:
/** Option not supported.
*/
class VMIME_EXPORT unsupported_option : public net_exception {
class VMIME_EXPORT unsupported_option : public net_exception
{
public:
unsupported_option(const exception& other = NO_EXCEPTION);
@ -470,9 +450,8 @@ public:
/** The current state of the object does not permit to execute the
* operation (for example, you try to close a folder which is not open).
*/
class VMIME_EXPORT illegal_state : public net_exception {
class VMIME_EXPORT illegal_state : public net_exception
{
public:
illegal_state(const string& state, const exception& other = NO_EXCEPTION);
@ -485,9 +464,8 @@ public:
/** Folder not found (does not exist).
*/
class VMIME_EXPORT folder_not_found : public net_exception {
class VMIME_EXPORT folder_not_found : public net_exception
{
public:
folder_not_found(const exception& other = NO_EXCEPTION);
@ -500,9 +478,8 @@ public:
/** Folder is already open in the same session.
*/
class VMIME_EXPORT folder_already_open : public net_exception {
class VMIME_EXPORT folder_already_open : public net_exception
{
public:
folder_already_open(const exception& other = NO_EXCEPTION);
@ -515,9 +492,8 @@ public:
/** Message not found (does not exist).
*/
class VMIME_EXPORT message_not_found : public net_exception {
class VMIME_EXPORT message_not_found : public net_exception
{
public:
message_not_found(const exception& other = NO_EXCEPTION);
@ -530,9 +506,8 @@ public:
/** Operation not supported by the underlying protocol.
*/
class VMIME_EXPORT operation_not_supported : public net_exception {
class VMIME_EXPORT operation_not_supported : public net_exception
{
public:
operation_not_supported(const exception& other = NO_EXCEPTION);
@ -545,9 +520,8 @@ public:
/** The operation timed out (time-out delay is elapsed).
*/
class VMIME_EXPORT operation_timed_out : public net_exception {
class VMIME_EXPORT operation_timed_out : public net_exception
{
public:
operation_timed_out(const exception& other = NO_EXCEPTION);
@ -560,9 +534,8 @@ public:
/** The operation has been cancelled.
*/
class VMIME_EXPORT operation_cancelled : public net_exception {
class VMIME_EXPORT operation_cancelled : public net_exception
{
public:
operation_cancelled(const exception& other = NO_EXCEPTION);
@ -576,9 +549,8 @@ public:
/** Must call fetchMessage() or fetchHeader() before accessing
* the requested object.
*/
class VMIME_EXPORT unfetched_object : public net_exception {
class VMIME_EXPORT unfetched_object : public net_exception
{
public:
unfetched_object(const exception& other = NO_EXCEPTION);
@ -591,9 +563,8 @@ public:
/** The service is not currently connected.
*/
class VMIME_EXPORT not_connected : public net_exception {
class VMIME_EXPORT not_connected : public net_exception
{
public:
not_connected(const exception& other = NO_EXCEPTION);
@ -606,9 +577,8 @@ public:
/** The service is already connected (must disconnect before).
*/
class VMIME_EXPORT already_connected : public net_exception {
class VMIME_EXPORT already_connected : public net_exception
{
public:
already_connected(const exception& other = NO_EXCEPTION);
@ -621,9 +591,8 @@ public:
/** Illegal operation: cannot run this operation on the object.
*/
class VMIME_EXPORT illegal_operation : public net_exception {
class VMIME_EXPORT illegal_operation : public net_exception
{
public:
illegal_operation(const string& msg = "", const exception& other = NO_EXCEPTION);
@ -636,12 +605,17 @@ public:
/** Command error: operation failed (this is specific to the underlying protocol).
*/
class VMIME_EXPORT command_error : public net_exception {
class VMIME_EXPORT command_error : public net_exception
{
public:
command_error(const string& command, const string& response, const string& desc = "", const exception& other = NO_EXCEPTION);
command_error(
const string& command,
const string& response,
const string& desc = "",
const exception& other = NO_EXCEPTION
);
~command_error() throw();
/** Return the name of the command which have thrown the exception.
@ -670,12 +644,16 @@ private:
/** The server returned an invalid response.
*/
class VMIME_EXPORT invalid_response : public net_exception {
class VMIME_EXPORT invalid_response : public net_exception
{
public:
invalid_response(const string& command, const string& response, const exception& other = NO_EXCEPTION);
invalid_response(
const string& command,
const string& response,
const exception& other = NO_EXCEPTION
);
~invalid_response() throw();
/** Return the name of the command which have thrown the exception.
@ -704,9 +682,8 @@ private:
/** Partial fetch is not supported by the underlying protocol.
*/
class VMIME_EXPORT partial_fetch_not_supported : public net_exception {
class VMIME_EXPORT partial_fetch_not_supported : public net_exception
{
public:
partial_fetch_not_supported(const exception& other = NO_EXCEPTION);
@ -719,9 +696,8 @@ public:
/** Folder name is invalid.
*/
class VMIME_EXPORT invalid_folder_name : public net_exception {
class VMIME_EXPORT invalid_folder_name : public net_exception
{
public:
invalid_folder_name(const string& error = "", const exception& other = NO_EXCEPTION);
@ -740,12 +716,16 @@ public:
/** Base class for exceptions thrown by the filesystem features.
*/
class VMIME_EXPORT filesystem_exception : public vmime::exception {
class VMIME_EXPORT filesystem_exception : public vmime::exception
{
public:
filesystem_exception(const string& what, const utility::path& path, const exception& other = NO_EXCEPTION);
filesystem_exception(
const string& what,
const utility::path& path,
const exception& other = NO_EXCEPTION
);
~filesystem_exception() throw();
/** Return the full path of the file have thrown the exception.
@ -765,9 +745,8 @@ private:
/** File is not a directory.
*/
class VMIME_EXPORT not_a_directory : public filesystem_exception {
class VMIME_EXPORT not_a_directory : public filesystem_exception
{
public:
not_a_directory(const utility::path& path, const exception& other = NO_EXCEPTION);
@ -780,9 +759,8 @@ public:
/** File not found.
*/
class VMIME_EXPORT file_not_found : public filesystem_exception {
class VMIME_EXPORT file_not_found : public filesystem_exception
{
public:
file_not_found(const utility::path& path, const exception& other = NO_EXCEPTION);
@ -798,9 +776,8 @@ public:
/** Authentication exception.
*/
class VMIME_EXPORT authentication_exception : public vmime::exception {
class VMIME_EXPORT authentication_exception : public vmime::exception
{
public:
authentication_exception(const string& what, const exception& other = NO_EXCEPTION);
@ -813,9 +790,8 @@ public:
/** The requested information cannot be provided.
*/
class VMIME_EXPORT no_auth_information : public authentication_exception {
class VMIME_EXPORT no_auth_information : public authentication_exception
{
public:
no_auth_information(const exception& other = NO_EXCEPTION);
@ -831,9 +807,8 @@ public:
/** Base class for exceptions thrown by SASL module.
*/
class VMIME_EXPORT sasl_exception : public authentication_exception {
class VMIME_EXPORT sasl_exception : public authentication_exception
{
public:
sasl_exception(const string& what, const exception& other = NO_EXCEPTION);
@ -846,9 +821,8 @@ public:
/** No mechanism is registered with the specified name.
*/
class VMIME_EXPORT no_such_mechanism : public sasl_exception {
class VMIME_EXPORT no_such_mechanism : public sasl_exception
{
public:
no_such_mechanism(const string& name, const exception& other = NO_EXCEPTION);
@ -867,9 +841,8 @@ public:
/** Base class for exceptions thrown by TLS module.
*/
class VMIME_EXPORT tls_exception : public vmime::exception {
class VMIME_EXPORT tls_exception : public vmime::exception
{
public:
tls_exception(const string& what, const exception& other = NO_EXCEPTION);
@ -883,7 +856,6 @@ public:
#endif // VMIME_HAVE_TLS_SUPPORT
} // exceptions

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -42,12 +42,14 @@
#include "vmime/utility/file.hpp"
namespace vmime
{
namespace vmime {
fileAttachment::fileAttachment(const string& filepath, const mediaType& type)
{
fileAttachment::fileAttachment(
const string& filepath,
const mediaType& type
) {
m_type = type;
setData(filepath);
@ -56,8 +58,12 @@ fileAttachment::fileAttachment(const string& filepath, const mediaType& type)
}
fileAttachment::fileAttachment(const string& filepath, const mediaType& type, const text& desc)
{
fileAttachment::fileAttachment(
const string& filepath,
const mediaType& type,
const text& desc
) {
m_type = type;
m_desc = desc;
@ -67,9 +73,13 @@ fileAttachment::fileAttachment(const string& filepath, const mediaType& type, co
}
fileAttachment::fileAttachment(const string& filepath, const mediaType& type,
const text& desc, const encoding& enc)
{
fileAttachment::fileAttachment(
const string& filepath,
const mediaType& type,
const text& desc,
const encoding& enc
) {
m_type = type;
m_desc = desc;
@ -79,10 +89,14 @@ fileAttachment::fileAttachment(const string& filepath, const mediaType& type,
}
fileAttachment::fileAttachment(const shared_ptr <contentHandler>& cts, const word& filename, const mediaType& type)
{
if (!filename.isEmpty())
fileAttachment::fileAttachment(
const shared_ptr <contentHandler>& cts,
const word& filename,
const mediaType& type) {
if (!filename.isEmpty()) {
m_fileInfo.setFilename(filename);
}
m_type = type;
@ -92,11 +106,16 @@ fileAttachment::fileAttachment(const shared_ptr <contentHandler>& cts, const wor
}
fileAttachment::fileAttachment(const shared_ptr <contentHandler>& cts, const word& filename,
const mediaType& type, const text& desc)
{
if (!filename.isEmpty())
fileAttachment::fileAttachment(
const shared_ptr <contentHandler>& cts,
const word& filename,
const mediaType& type,
const text& desc
) {
if (!filename.isEmpty()) {
m_fileInfo.setFilename(filename);
}
m_type = type;
m_desc = desc;
@ -107,11 +126,17 @@ fileAttachment::fileAttachment(const shared_ptr <contentHandler>& cts, const wor
}
fileAttachment::fileAttachment(const shared_ptr <contentHandler>& cts, const word& filename,
const mediaType& type, const text& desc, const encoding& enc)
{
if (!filename.isEmpty())
fileAttachment::fileAttachment(
const shared_ptr <contentHandler>& cts,
const word& filename,
const mediaType& type,
const text& desc,
const encoding& enc
) {
if (!filename.isEmpty()) {
m_fileInfo.setFilename(filename);
}
m_type = type;
m_desc = desc;
@ -121,34 +146,36 @@ fileAttachment::fileAttachment(const shared_ptr <contentHandler>& cts, const wor
}
void fileAttachment::setData(const string& filepath)
{
void fileAttachment::setData(const string& filepath) {
shared_ptr <utility::fileSystemFactory> fsf = platform::getHandler()->getFileSystemFactory();
utility::file::path path = fsf->stringToPath(filepath);
shared_ptr <utility::file> file = fsf->create(path);
if (!file->isFile())
if (!file->isFile()) {
throw exceptions::open_file_error();
}
m_data = make_shared <streamContentHandler>
(file->getFileReader()->getInputStream(), file->getLength());
m_data = make_shared <streamContentHandler>(
file->getFileReader()->getInputStream(), file->getLength()
);
m_fileInfo.setFilename(path.getLastComponent());
m_fileInfo.setSize(file->getLength());
}
void fileAttachment::setData(const shared_ptr <contentHandler>& cts)
{
void fileAttachment::setData(const shared_ptr <contentHandler>& cts) {
m_data = cts;
m_fileInfo.setSize(cts->getLength());
}
void fileAttachment::generatePart(const shared_ptr <bodyPart>& part) const
{
void fileAttachment::generatePart(const shared_ptr <bodyPart>& part) const {
defaultAttachment::generatePart(part);
shared_ptr <contentDispositionField> cdf =
@ -162,14 +189,14 @@ void fileAttachment::generatePart(const shared_ptr <bodyPart>& part) const
}
const fileAttachment::fileInfo& fileAttachment::getFileInfo() const
{
const fileAttachment::fileInfo& fileAttachment::getFileInfo() const {
return m_fileInfo;
}
fileAttachment::fileInfo& fileAttachment::getFileInfo()
{
fileAttachment::fileInfo& fileAttachment::getFileInfo() {
return m_fileInfo;
}
@ -180,39 +207,43 @@ fileAttachment::fileInfo& fileAttachment::getFileInfo()
//
fileAttachment::fileInfo::fileInfo()
: m_filename(NULL), m_size(NULL), m_creationDate(NULL), m_modifDate(NULL), m_readDate(NULL)
{
: m_filename(NULL),
m_size(NULL),
m_creationDate(NULL),
m_modifDate(NULL),
m_readDate(NULL) {
}
fileAttachment::fileInfo::~fileInfo()
{
delete (m_filename);
delete (m_size);
delete (m_creationDate);
delete (m_modifDate);
delete (m_readDate);
delete m_filename;
delete m_size;
delete m_creationDate;
delete m_modifDate;
delete m_readDate;
}
bool fileAttachment::fileInfo::hasFilename() const { return (m_filename != NULL); }
const word& fileAttachment::fileInfo::getFilename() const { return (*m_filename); }
bool fileAttachment::fileInfo::hasFilename() const { return m_filename; }
const word& fileAttachment::fileInfo::getFilename() const { return *m_filename; }
void fileAttachment::fileInfo::setFilename(const string& name) { if (m_filename) { *m_filename = name; } else { m_filename = new word(name); } }
void fileAttachment::fileInfo::setFilename(const word& name) { if (m_filename) { *m_filename = name; } else { m_filename = new word(name); } }
bool fileAttachment::fileInfo::hasCreationDate() const { return (m_creationDate != NULL); }
const datetime& fileAttachment::fileInfo::getCreationDate() const { return (*m_creationDate); }
bool fileAttachment::fileInfo::hasCreationDate() const { return m_creationDate; }
const datetime& fileAttachment::fileInfo::getCreationDate() const { return *m_creationDate; }
void fileAttachment::fileInfo::setCreationDate(const datetime& date) { if (m_creationDate) { *m_creationDate = date; } else { m_creationDate = new datetime(date); } }
bool fileAttachment::fileInfo::hasModificationDate() const { return (m_modifDate != NULL); }
const datetime& fileAttachment::fileInfo::getModificationDate() const { return (*m_modifDate); }
bool fileAttachment::fileInfo::hasModificationDate() const { return m_modifDate; }
const datetime& fileAttachment::fileInfo::getModificationDate() const { return *m_modifDate; }
void fileAttachment::fileInfo::setModificationDate(const datetime& date) { if (m_modifDate) { *m_modifDate = date; } else { m_modifDate = new datetime(date); } }
bool fileAttachment::fileInfo::hasReadDate() const { return (m_readDate != NULL); }
const datetime& fileAttachment::fileInfo::getReadDate() const { return (*m_readDate); }
bool fileAttachment::fileInfo::hasReadDate() const { return m_readDate; }
const datetime& fileAttachment::fileInfo::getReadDate() const { return *m_readDate; }
void fileAttachment::fileInfo::setReadDate(const datetime& date) { if (m_readDate) { *m_readDate = date; } else { m_readDate = new datetime(date); } }
bool fileAttachment::fileInfo::hasSize() const { return (m_size != NULL); }
size_t fileAttachment::fileInfo::getSize() const { return (*m_size); }
bool fileAttachment::fileInfo::hasSize() const { return m_size; }
size_t fileAttachment::fileInfo::getSize() const { return *m_size; }
void fileAttachment::fileInfo::setSize(const size_t size) { if (m_size) { *m_size = size; } else { m_size = new size_t(size); } }
@ -220,4 +251,3 @@ void fileAttachment::fileInfo::setSize(const size_t size) { if (m_size) { *m_siz
#endif // VMIME_HAVE_FILESYSTEM_FEATURES

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -37,29 +37,58 @@
#include "vmime/utility/stream.hpp"
namespace vmime
{
namespace vmime {
/** Attachment of type 'file'.
*/
class VMIME_EXPORT fileAttachment : public defaultAttachment {
class VMIME_EXPORT fileAttachment : public defaultAttachment
{
public:
fileAttachment(const string& filepath, const mediaType& type);
fileAttachment(const string& filepath, const mediaType& type, const text& desc);
fileAttachment(const string& filepath, const mediaType& type, const text& desc, const encoding& enc);
fileAttachment(
const string& filepath,
const mediaType& type
);
fileAttachment(const shared_ptr <contentHandler>& cts, const word& filename, const mediaType& type);
fileAttachment(const shared_ptr <contentHandler>& cts, const word& filename, const mediaType& type, const text& desc);
fileAttachment(const shared_ptr <contentHandler>& cts, const word& filename, const mediaType& type, const text& desc, const encoding& enc);
fileAttachment(
const string& filepath,
const mediaType& type,
const text& desc
);
fileAttachment(
const string& filepath,
const mediaType& type,
const text& desc,
const encoding& enc
);
fileAttachment(
const shared_ptr <contentHandler>& cts,
const word& filename,
const mediaType& type
);
fileAttachment(
const shared_ptr <contentHandler>& cts,
const word& filename,
const mediaType& type,
const text& desc
);
fileAttachment(
const shared_ptr <contentHandler>& cts,
const word& filename,
const mediaType& type,
const text& desc,
const encoding& enc
);
/** Stores information about a file attachment.
*/
class VMIME_EXPORT fileInfo
{
class VMIME_EXPORT fileInfo {
public:
fileInfo();

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -30,57 +30,61 @@
#include "vmime/fileContentHandler.hpp"
namespace vmime
{
namespace vmime {
fileContentHandler::fileContentHandler()
: streamContentHandler()
{
: streamContentHandler() {
}
fileContentHandler::fileContentHandler
(const shared_ptr <utility::file>& file, const vmime::encoding& enc)
{
fileContentHandler::fileContentHandler(
const shared_ptr <utility::file>& file,
const vmime::encoding& enc
) {
setData(file, enc);
}
fileContentHandler::~fileContentHandler()
{
fileContentHandler::~fileContentHandler() {
}
fileContentHandler::fileContentHandler(const fileContentHandler& cts)
: streamContentHandler()
{
: streamContentHandler() {
setData(cts.m_file, cts.m_encoding);
}
fileContentHandler& fileContentHandler::operator=(const fileContentHandler& cts)
{
fileContentHandler& fileContentHandler::operator=(const fileContentHandler& cts) {
setData(cts.m_file, cts.m_encoding);
return *this;
}
shared_ptr <contentHandler> fileContentHandler::clone() const
{
shared_ptr <contentHandler> fileContentHandler::clone() const {
return make_shared <fileContentHandler>(*this);
}
void fileContentHandler::setData
(const shared_ptr <utility::file>& file, const vmime::encoding& enc)
{
void fileContentHandler::setData(
const shared_ptr <utility::file>& file,
const vmime::encoding& enc
) {
m_file = file;
m_encoding = enc;
streamContentHandler::setData
(file->getFileReader()->getInputStream(), file->getLength(), enc);
streamContentHandler::setData(
file->getFileReader()->getInputStream(), file->getLength(), enc
);
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -35,15 +35,13 @@
#include "vmime/utility/file.hpp"
namespace vmime
{
namespace vmime {
/** A content handler which obtains its data from a file.
*/
class VMIME_EXPORT fileContentHandler : public streamContentHandler {
class VMIME_EXPORT fileContentHandler : public streamContentHandler
{
public:
/** Creates a new empty content handler. No data can be extracted until
@ -61,9 +59,10 @@ public:
*
* @return a reference to a new content handler
*/
fileContentHandler
(const shared_ptr <utility::file>& file,
const vmime::encoding& enc = NO_ENCODING);
fileContentHandler(
const shared_ptr <utility::file>& file,
const vmime::encoding& enc = NO_ENCODING
);
~fileContentHandler();
@ -78,9 +77,10 @@ public:
* @param enc set to anything other than NO_ENCODING if the data contained
* in the file is already encoded with the specified encoding
*/
void setData
(const shared_ptr <utility::file>& file,
const vmime::encoding& enc = NO_ENCODING);
void setData(
const shared_ptr <utility::file>& file,
const vmime::encoding& enc = NO_ENCODING
);
private:

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -26,62 +26,63 @@
#include "vmime/utility/outputStreamAdapter.hpp"
namespace vmime
{
namespace vmime {
generatedMessageAttachment::generatedMessageAttachment(const shared_ptr <const bodyPart>& part)
: m_bpa(make_shared <bodyPartAttachment>(part))
{
generatedMessageAttachment::generatedMessageAttachment(
const shared_ptr <const bodyPart>& part
)
: m_bpa(make_shared <bodyPartAttachment>(part)) {
}
const mediaType generatedMessageAttachment::getType() const
{
const mediaType generatedMessageAttachment::getType() const {
return mediaType(mediaTypes::MESSAGE, mediaTypes::MESSAGE_RFC822);
}
const text generatedMessageAttachment::getDescription() const
{
const text generatedMessageAttachment::getDescription() const {
return m_bpa->getDescription();
}
const word generatedMessageAttachment::getName() const
{
const word generatedMessageAttachment::getName() const {
return m_bpa->getName();
}
const shared_ptr <const contentHandler> generatedMessageAttachment::getData() const
{
const shared_ptr <const contentHandler> generatedMessageAttachment::getData() const {
return m_bpa->getData();
}
const encoding generatedMessageAttachment::getEncoding() const
{
const encoding generatedMessageAttachment::getEncoding() const {
return m_bpa->getEncoding();
}
shared_ptr <const object> generatedMessageAttachment::getPart() const
{
shared_ptr <const object> generatedMessageAttachment::getPart() const {
return m_bpa->getPart();
}
shared_ptr <const header> generatedMessageAttachment::getHeader() const
{
shared_ptr <const header> generatedMessageAttachment::getHeader() const {
return m_bpa->getHeader();
}
shared_ptr <message> generatedMessageAttachment::getMessage() const
{
if (m_msg == NULL)
{
shared_ptr <message> generatedMessageAttachment::getMessage() const {
if (!m_msg) {
// Extract data
std::ostringstream oss;
utility::outputStreamAdapter os(oss);
@ -97,8 +98,8 @@ shared_ptr <message> generatedMessageAttachment::getMessage() const
}
void generatedMessageAttachment::generateIn(const shared_ptr <bodyPart>& /* parent */) const
{
void generatedMessageAttachment::generateIn(const shared_ptr <bodyPart>& /* parent */) const {
// Not used (see 'parsedMessageAttachment')
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -32,14 +32,13 @@
#include "vmime/bodyPartAttachment.hpp"
namespace vmime
{
namespace vmime {
/** A message attachment that can be extracted from a message.
*/
class VMIME_EXPORT generatedMessageAttachment : public messageAttachment
{
class VMIME_EXPORT generatedMessageAttachment : public messageAttachment {
public:
generatedMessageAttachment(const shared_ptr <const bodyPart>& part);
@ -76,4 +75,3 @@ private:
#endif // VMIME_GENERATEDMESSAGEATTACHMENT_HPP_INCLUDED

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -24,8 +24,7 @@
#include "vmime/generationContext.hpp"
namespace vmime
{
namespace vmime {
generationContext::generationContext()
@ -34,8 +33,8 @@ generationContext::generationContext()
"does not understand MIME message format."),
m_epilogText(""),
m_wrapMessageId(true),
m_paramValueMode(PARAMETER_VALUE_RFC2231_ONLY)
{
m_paramValueMode(PARAMETER_VALUE_RFC2231_ONLY) {
}
@ -45,86 +44,89 @@ generationContext::generationContext(const generationContext& ctx)
m_prologText(ctx.m_prologText),
m_epilogText(ctx.m_epilogText),
m_wrapMessageId(ctx.m_wrapMessageId),
m_paramValueMode(ctx.m_paramValueMode)
{
m_paramValueMode(ctx.m_paramValueMode) {
}
generationContext& generationContext::getDefaultContext()
{
generationContext& generationContext::getDefaultContext() {
static generationContext ctx;
return ctx;
}
size_t generationContext::getMaxLineLength() const
{
size_t generationContext::getMaxLineLength() const {
return m_maxLineLength;
}
void generationContext::setMaxLineLength(const size_t maxLineLength)
{
void generationContext::setMaxLineLength(const size_t maxLineLength) {
m_maxLineLength = maxLineLength;
}
const string generationContext::getPrologText() const
{
const string generationContext::getPrologText() const {
return m_prologText;
}
void generationContext::setPrologText(const string& prologText)
{
void generationContext::setPrologText(const string& prologText) {
m_prologText = prologText;
}
const string generationContext::getEpilogText() const
{
const string generationContext::getEpilogText() const {
return m_epilogText;
}
void generationContext::setEpilogText(const string& epilogText)
{
void generationContext::setEpilogText(const string& epilogText) {
m_epilogText = epilogText;
}
bool generationContext::getWrapMessageId() const
{
bool generationContext::getWrapMessageId() const {
return m_wrapMessageId;
}
void generationContext::setWrapMessageId(const bool& wrapMessageId)
{
void generationContext::setWrapMessageId(const bool& wrapMessageId) {
m_wrapMessageId = wrapMessageId;
}
void generationContext::setEncodedParameterValueMode(const EncodedParameterValueModes mode)
{
void generationContext::setEncodedParameterValueMode(const EncodedParameterValueModes mode) {
m_paramValueMode = mode;
}
generationContext::EncodedParameterValueModes
generationContext::getEncodedParameterValueMode() const
{
generationContext::getEncodedParameterValueMode() const {
return m_paramValueMode;
}
generationContext& generationContext::operator=(const generationContext& ctx)
{
generationContext& generationContext::operator=(const generationContext& ctx) {
copyFrom(ctx);
return *this;
}
void generationContext::copyFrom(const generationContext& ctx)
{
void generationContext::copyFrom(const generationContext& ctx) {
context::copyFrom(ctx);
m_maxLineLength = ctx.m_maxLineLength;

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -28,15 +28,13 @@
#include "vmime/context.hpp"
namespace vmime
{
namespace vmime {
/** Holds configuration parameters used for generating messages.
*/
class VMIME_EXPORT generationContext : public context {
class VMIME_EXPORT generationContext : public context
{
public:
generationContext();
@ -103,8 +101,8 @@ public:
/** Modes available for generating values in parameterized header fields.
*/
enum EncodedParameterValueModes
{
enum EncodedParameterValueModes {
PARAMETER_VALUE_NO_ENCODING, /**< Only generate 7-bit (ASCII-only) values,
even if the value contains non-ASCII chars or
if folding is needed. */

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -28,17 +28,16 @@
#include <iterator>
namespace vmime
{
namespace vmime {
header::header()
{
header::header() {
}
header::~header()
{
header::~header() {
removeAllFields();
}
@ -62,70 +61,79 @@ field-body-contents =
specials tokens, or else consisting of texts>
*/
void header::parseImpl
(const parsingContext& ctx, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void header::parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
size_t pos = position;
removeAllFields();
while (pos < end)
{
while (pos < end) {
shared_ptr <headerField> field = headerField::parseNext(ctx, buffer, pos, end, &pos);
if (field == NULL) break;
if (!field) break;
m_fields.push_back(field);
}
setParsedBounds(position, pos);
if (newPosition)
if (newPosition) {
*newPosition = pos;
}
}
void header::generateImpl
(const generationContext& ctx, utility::outputStream& os,
const size_t /* curLinePos */, size_t* newLinePos) const
{
void header::generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t /* curLinePos */,
size_t* newLinePos
) const {
// Generate the fields
for (std::vector <shared_ptr <headerField> >::const_iterator it = m_fields.begin() ;
it != m_fields.end() ; ++it)
{
it != m_fields.end() ; ++it) {
(*it)->generate(ctx, os);
os << CRLF;
}
if (newLinePos)
if (newLinePos) {
*newLinePos = 0;
}
}
size_t header::getGeneratedSize(const generationContext& ctx)
{
size_t header::getGeneratedSize(const generationContext& ctx) {
return component::getGeneratedSize(ctx) + 2 * m_fields.size() /* CRLF */;
}
shared_ptr <component> header::clone() const
{
shared_ptr <component> header::clone() const {
shared_ptr <header> hdr = make_shared <header>();
hdr->m_fields.reserve(m_fields.size());
for (std::vector <shared_ptr <headerField> >::const_iterator it = m_fields.begin() ;
it != m_fields.end() ; ++it)
{
it != m_fields.end() ; ++it) {
hdr->m_fields.push_back(vmime::clone(*it));
}
return (hdr);
return hdr;
}
void header::copyFrom(const component& other)
{
void header::copyFrom(const component& other) {
const header& h = dynamic_cast <const header&>(other);
std::vector <shared_ptr <headerField> > fields;
@ -133,8 +141,8 @@ void header::copyFrom(const component& other)
fields.reserve(h.m_fields.size());
for (std::vector <shared_ptr <headerField> >::const_iterator it = h.m_fields.begin() ;
it != h.m_fields.end() ; ++it)
{
it != h.m_fields.end() ; ++it) {
fields.push_back(vmime::clone(*it));
}
@ -145,217 +153,238 @@ void header::copyFrom(const component& other)
}
header& header::operator=(const header& other)
{
header& header::operator=(const header& other) {
copyFrom(other);
return (*this);
return *this;
}
bool header::hasField(const string& fieldName) const
{
bool header::hasField(const string& fieldName) const {
std::vector <shared_ptr <headerField> >::const_iterator pos =
std::find_if(m_fields.begin(), m_fields.end(),
fieldHasName(utility::stringUtils::toLower(fieldName)));
std::find_if(
m_fields.begin(), m_fields.end(),
fieldHasName(utility::stringUtils::toLower(fieldName))
);
return (pos != m_fields.end());
return pos != m_fields.end();
}
shared_ptr <headerField> header::findField(const string& fieldName) const
{
shared_ptr <headerField> header::findField(const string& fieldName) const {
// Find the first field that matches the specified name
std::vector <shared_ptr <headerField> >::const_iterator pos =
std::find_if(m_fields.begin(), m_fields.end(),
fieldHasName(utility::stringUtils::toLower(fieldName)));
std::find_if(
m_fields.begin(), m_fields.end(),
fieldHasName(utility::stringUtils::toLower(fieldName))
);
// No field with this name can be found
if (pos == m_fields.end())
if (pos == m_fields.end()) {
return null;
}
// Else, return a reference to the existing field
return (*pos);
return *pos;
}
std::vector <shared_ptr <headerField> > header::findAllFields(const string& fieldName)
{
std::vector <shared_ptr <headerField> > header::findAllFields(const string& fieldName) {
std::vector <shared_ptr <headerField> > result;
std::back_insert_iterator <std::vector <shared_ptr <headerField> > > back(result);
std::remove_copy_if(m_fields.begin(), m_fields.end(), back,
fieldHasNotName(utility::stringUtils::toLower(fieldName)));
std::remove_copy_if(
m_fields.begin(), m_fields.end(), back,
fieldHasNotName(utility::stringUtils::toLower(fieldName))
);
return result;
}
shared_ptr <headerField> header::getField(const string& fieldName)
{
shared_ptr <headerField> header::getField(const string& fieldName) {
const string name = utility::stringUtils::toLower(fieldName);
// Find the first field that matches the specified name
std::vector <shared_ptr <headerField> >::const_iterator pos = m_fields.begin();
const std::vector <shared_ptr <headerField> >::const_iterator end = m_fields.end();
while (pos != end && utility::stringUtils::toLower((*pos)->getName()) != name)
while (pos != end && utility::stringUtils::toLower((*pos)->getName()) != name) {
++pos;
}
// If no field with this name can be found, create a new one
if (pos == end)
{
if (pos == end) {
shared_ptr <headerField> field = headerFieldFactory::getInstance()->create(fieldName);
appendField(field);
// Return a reference to the new field
return (field);
}
// Else, return a reference to the existing field
else
{
return (*pos);
} else {
return *pos;
}
}
void header::appendField(const shared_ptr <headerField>& field)
{
void header::appendField(const shared_ptr <headerField>& field) {
m_fields.push_back(field);
}
void header::insertFieldBefore(const shared_ptr <headerField>& beforeField, const shared_ptr <headerField>& field)
{
const std::vector <shared_ptr <headerField> >::iterator it = std::find
(m_fields.begin(), m_fields.end(), beforeField);
void header::insertFieldBefore(
const shared_ptr <headerField>& beforeField,
const shared_ptr <headerField>& field
) {
if (it == m_fields.end())
const std::vector <shared_ptr <headerField> >::iterator it =
std::find(m_fields.begin(), m_fields.end(), beforeField);
if (it == m_fields.end()) {
throw exceptions::no_such_field();
}
m_fields.insert(it, field);
}
void header::insertFieldBefore(const size_t pos, const shared_ptr <headerField>& field)
{
void header::insertFieldBefore(const size_t pos, const shared_ptr <headerField>& field) {
m_fields.insert(m_fields.begin() + pos, field);
}
void header::insertFieldAfter(const shared_ptr <headerField>& afterField, const shared_ptr <headerField>& field)
{
const std::vector <shared_ptr <headerField> >::iterator it = std::find
(m_fields.begin(), m_fields.end(), afterField);
void header::insertFieldAfter(
const shared_ptr <headerField>& afterField,
const shared_ptr <headerField>& field
) {
if (it == m_fields.end())
const std::vector <shared_ptr <headerField> >::iterator it =
std::find(m_fields.begin(), m_fields.end(), afterField);
if (it == m_fields.end()) {
throw exceptions::no_such_field();
}
m_fields.insert(it + 1, field);
}
void header::insertFieldAfter(const size_t pos, const shared_ptr <headerField>& field)
{
void header::insertFieldAfter(const size_t pos, const shared_ptr <headerField>& field) {
m_fields.insert(m_fields.begin() + pos + 1, field);
}
void header::removeField(const shared_ptr <headerField>& field)
{
const std::vector <shared_ptr <headerField> >::iterator it = std::find
(m_fields.begin(), m_fields.end(), field);
void header::removeField(const shared_ptr <headerField>& field) {
if (it == m_fields.end())
const std::vector <shared_ptr <headerField> >::iterator it =
std::find(m_fields.begin(), m_fields.end(), field);
if (it == m_fields.end()) {
throw exceptions::no_such_field();
}
m_fields.erase(it);
}
void header::removeField(const size_t pos)
{
void header::removeField(const size_t pos) {
const std::vector <shared_ptr <headerField> >::iterator it = m_fields.begin() + pos;
m_fields.erase(it);
}
void header::replaceField(const shared_ptr <headerField>& field, const shared_ptr <headerField>& newField)
{
void header::replaceField(
const shared_ptr <headerField>& field,
const shared_ptr <headerField>& newField
) {
insertFieldBefore(field, newField);
removeField(field);
}
void header::removeAllFields()
{
void header::removeAllFields() {
m_fields.clear();
}
void header::removeAllFields(const string& fieldName)
{
void header::removeAllFields(const string& fieldName) {
std::vector <shared_ptr <headerField> > fields = findAllFields(fieldName);
for (unsigned int i = 0 ; i < fields.size() ; ++i)
for (unsigned int i = 0 ; i < fields.size() ; ++i) {
removeField(fields[i]);
}
}
size_t header::getFieldCount() const
{
return (m_fields.size());
size_t header::getFieldCount() const {
return m_fields.size();
}
bool header::isEmpty() const
{
return (m_fields.empty());
bool header::isEmpty() const {
return m_fields.empty();
}
const shared_ptr <headerField> header::getFieldAt(const size_t pos)
{
return (m_fields[pos]);
const shared_ptr <headerField> header::getFieldAt(const size_t pos) {
return m_fields[pos];
}
const shared_ptr <const headerField> header::getFieldAt(const size_t pos) const
{
return (m_fields[pos]);
const shared_ptr <const headerField> header::getFieldAt(const size_t pos) const {
return m_fields[pos];
}
const std::vector <shared_ptr <const headerField> > header::getFieldList() const
{
const std::vector <shared_ptr <const headerField> > header::getFieldList() const {
std::vector <shared_ptr <const headerField> > list;
list.reserve(m_fields.size());
for (std::vector <shared_ptr <headerField> >::const_iterator it = m_fields.begin() ;
it != m_fields.end() ; ++it)
{
it != m_fields.end() ; ++it) {
list.push_back(*it);
}
return (list);
return list;
}
const std::vector <shared_ptr <headerField> > header::getFieldList()
{
return (m_fields);
const std::vector <shared_ptr <headerField> > header::getFieldList() {
return m_fields;
}
const std::vector <shared_ptr <component> > header::getChildComponents()
{
const std::vector <shared_ptr <component> > header::getChildComponents() {
std::vector <shared_ptr <component> > list;
copy_vector(m_fields, list);
return (list);
return list;
}
@ -364,23 +393,23 @@ const std::vector <shared_ptr <component> > header::getChildComponents()
header::fieldHasName::fieldHasName(const string& name)
: m_name(name)
{
: m_name(name) {
}
bool header::fieldHasName::operator() (const shared_ptr <const headerField>& field)
{
bool header::fieldHasName::operator() (const shared_ptr <const headerField>& field) {
return utility::stringUtils::toLower(field->getName()) == m_name;
}
header::fieldHasNotName::fieldHasNotName(const string& name)
: m_name(name)
{
: m_name(name) {
}
bool header::fieldHasNotName::operator() (const shared_ptr <const headerField>& field)
{
bool header::fieldHasNotName::operator() (const shared_ptr <const headerField>& field) {
return utility::stringUtils::toLower(field->getName()) != m_name;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -33,8 +33,7 @@
#include "vmime/headerFieldFactory.hpp"
namespace vmime
{
namespace vmime {
class bodyPart;
@ -42,9 +41,8 @@ class bodyPart;
/** Header section of a MIME part.
*/
class VMIME_EXPORT header : public component {
class VMIME_EXPORT header : public component
{
friend class bodyPart;
friend class body;
friend class message;
@ -120,8 +118,8 @@ public:
* with this name was found
*/
template <typename T>
shared_ptr <T> findField(const string& fieldName) const
{
shared_ptr <T> findField(const string& fieldName) const {
return dynamicCast <T>(findField(fieldName));
}
@ -137,14 +135,15 @@ public:
* specified type
*/
template <typename T>
shared_ptr <T> findFieldValue(const string& fieldName) const
{
shared_ptr <T> findFieldValue(const string& fieldName) const {
shared_ptr <headerField> field = findField(fieldName);
if (field)
if (field) {
return dynamicCast <T>(field->getValue());
else
} else {
return null;
}
}
/** Find all fields that match the specified name.
@ -176,8 +175,8 @@ public:
* if no field is found
*/
template <typename T>
shared_ptr <T> getField(const string& fieldName)
{
shared_ptr <T> getField(const string& fieldName) {
return dynamicCast <T>(getField(fieldName));
}
@ -193,7 +192,10 @@ public:
* @param field field to insert
* @throw exceptions::no_such_field if the field is not in the list
*/
void insertFieldBefore(const shared_ptr <headerField>& beforeField, const shared_ptr <headerField>& field);
void insertFieldBefore(
const shared_ptr <headerField>& beforeField,
const shared_ptr <headerField>& field
);
/** Insert a new field before the specified position.
*
@ -201,7 +203,10 @@ public:
* the beginning of the list)
* @param field field to insert
*/
void insertFieldBefore(const size_t pos, const shared_ptr <headerField>& field);
void insertFieldBefore(
const size_t pos,
const shared_ptr <headerField>& field
);
/** Insert a new field after the specified field.
*
@ -209,14 +214,20 @@ public:
* @param field field to insert
* @throw exceptions::no_such_field if the field is not in the list
*/
void insertFieldAfter(const shared_ptr <headerField>& afterField, const shared_ptr <headerField>& field);
void insertFieldAfter(
const shared_ptr <headerField>& afterField,
const shared_ptr <headerField>& field
);
/** 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 size_t pos, const shared_ptr <headerField>& field);
void insertFieldAfter(
const size_t pos,
const shared_ptr <headerField>& field
);
/** Remove the specified field from the list.
*
@ -237,7 +248,10 @@ public:
* @param newField field to replace with
* @throw exceptions::no_such_field if the field is not in the list
*/
void replaceField(const shared_ptr <headerField>& field, const shared_ptr <headerField>& newField);
void replaceField(
const shared_ptr <headerField>& field,
const shared_ptr <headerField>& newField
);
/** Remove all fields from the list.
*/
@ -298,8 +312,8 @@ private:
std::vector <shared_ptr <headerField> > m_fields;
class fieldHasName
{
class fieldHasName {
public:
fieldHasName(const string& name);
@ -310,8 +324,8 @@ private:
string m_name;
};
class fieldHasNotName
{
class fieldHasNotName {
public:
fieldHasNotName(const string& name);
@ -325,18 +339,20 @@ private:
protected:
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -29,130 +29,147 @@
#include "vmime/exception.hpp"
namespace vmime
{
namespace vmime {
headerField::headerField()
: m_name("X-Undefined")
{
: m_name("X-Undefined") {
}
headerField::headerField(const string& fieldName)
: m_name(fieldName)
{
: m_name(fieldName) {
}
headerField::~headerField()
{
headerField::~headerField() {
}
shared_ptr <component> headerField::clone() const
{
shared_ptr <component> headerField::clone() const {
shared_ptr <headerField> field = headerFieldFactory::getInstance()->create(m_name);
field->copyFrom(*this);
return (field);
return field;
}
void headerField::copyFrom(const component& other)
{
void headerField::copyFrom(const component& other) {
const headerField& hf = dynamic_cast <const headerField&>(other);
m_value->copyFrom(*hf.m_value);
}
headerField& headerField::operator=(const headerField& other)
{
headerField& headerField::operator=(const headerField& other) {
copyFrom(other);
return (*this);
return *this;
}
shared_ptr <headerField> headerField::parseNext
(const parsingContext& ctx, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
shared_ptr <headerField> headerField::parseNext(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
size_t pos = position;
while (pos < end)
{
while (pos < end) {
char_t c = buffer[pos];
// Check for end of headers (empty line): although RFC-822 recommends
// to use CRLF for header/body separator (see 4.1 SYNTAX), here, we
// also check for LF for compatibility with broken implementations...
if (c == '\n')
{
if (newPosition)
if (c == '\n') {
if (newPosition) {
*newPosition = pos + 1; // LF: illegal
}
return null;
}
else if (c == '\r' && pos + 1 < end && buffer[pos + 1] == '\n')
{
if (newPosition)
} else if (c == '\r' && pos + 1 < end && buffer[pos + 1] == '\n') {
if (newPosition) {
*newPosition = pos + 2; // CR+LF
}
return null;
}
// This line may be a field description
if (!parserHelpers::isSpace(c))
{
if (!parserHelpers::isSpace(c)) {
const size_t nameStart = pos; // remember the start position of the line
while (pos < end && (buffer[pos] != ':' && !parserHelpers::isSpace(buffer[pos])))
while (pos < end && (buffer[pos] != ':' && !parserHelpers::isSpace(buffer[pos]))) {
++pos;
}
const size_t nameEnd = pos;
while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t'))
while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t')) {
++pos;
}
if (buffer[pos] != ':') {
if (buffer[pos] != ':')
{
switch (ctx.getHeaderParseErrorRecoveryMethod()) {
case vmime::headerParseRecoveryMethod::SKIP_LINE:
// Humm...does not seem to be a valid header line.
// Skip this error and advance to the next line
pos = nameStart;
while (pos < end && buffer[pos] != '\n')
while (pos < end && buffer[pos] != '\n') {
++pos;
}
if (pos < end && buffer[pos] == '\n')
if (pos < end && buffer[pos] == '\n') {
++pos;
}
break;
// case vmime::headerParseRecoveryMethod::APPEND_TO_PREVIOUS_LINE:
//
// // TODO Implement this...
// break;
case vmime::headerParseRecoveryMethod::ASSUME_END_OF_HEADERS:
return null;
break;
}
}
else
{
} else {
// Extract the field name
const string name(buffer.begin() + nameStart,
buffer.begin() + nameEnd);
const string name(
buffer.begin() + nameStart,
buffer.begin() + nameEnd
);
// Skip ':' character
while (pos < end && buffer[pos] == ':')
while (pos < end && buffer[pos] == ':') {
++pos;
}
// Skip spaces between ':' and the field contents
while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t'))
while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t')) {
++pos;
}
const size_t contentsStart = pos;
size_t contentsEnd = 0;
@ -160,19 +177,20 @@ shared_ptr <headerField> headerField::parseNext
bool firstLine = true;
// Parse field value, taking care of line folding (value on multiple lines)
for (size_t eol = 0 ; parserHelpers::findEOL(buffer, pos, end, &eol) ; pos = eol)
{
for (size_t eol = 0 ; parserHelpers::findEOL(buffer, pos, end, &eol) ; pos = eol) {
// If the line does not start with a folding indicator (SPACE or TAB),
// and this is not the first line, then stop parsing lines
if (!firstLine && !(buffer[pos] == ' ' || buffer[pos] == '\t'))
if (!firstLine && !(buffer[pos] == ' ' || buffer[pos] == '\t')) {
break;
}
contentsEnd = eol;
firstLine = false;
}
if (pos == end && contentsEnd == 0)
{
if (pos == end && contentsEnd == 0) {
// End of data, and no CRLF was found at the end
contentsEnd = end;
}
@ -180,8 +198,8 @@ shared_ptr <headerField> headerField::parseNext
// Strip spaces from end of header lines
while (contentsEnd > contentsStart &&
(buffer[contentsEnd - 1] == ' ' || buffer[contentsEnd - 1] == '\t' ||
buffer[contentsEnd - 1] == '\r' || buffer[contentsEnd - 1] == '\n'))
{
buffer[contentsEnd - 1] == '\r' || buffer[contentsEnd - 1] == '\n')) {
contentsEnd--;
}
@ -191,145 +209,164 @@ shared_ptr <headerField> headerField::parseNext
field->parse(ctx, buffer, contentsStart, contentsEnd, NULL);
field->setParsedBounds(nameStart, pos);
if (newPosition)
if (newPosition) {
*newPosition = pos;
}
return (field);
return field;
}
}
else
{
} else {
// If the line contains only space characters, we assume it is
// the end of the headers.
while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t'))
while (pos < end && (buffer[pos] == ' ' || buffer[pos] == '\t')) {
++pos;
}
if (pos < end && buffer[pos] == '\n')
{
if (newPosition)
if (pos < end && buffer[pos] == '\n') {
if (newPosition) {
*newPosition = pos + 1; // LF: illegal
}
return null;
}
else if (pos + 1 < end && buffer[pos] == '\r' && buffer[pos + 1] == '\n')
{
if (newPosition)
} else if (pos + 1 < end && buffer[pos] == '\r' && buffer[pos + 1] == '\n') {
if (newPosition) {
*newPosition = pos + 2; // CR+LF
}
return null;
}
// Skip this error and advance to the next line
while (pos < end && buffer[pos] != '\n')
while (pos < end && buffer[pos] != '\n') {
++pos;
}
if (buffer[pos] == '\n')
if (buffer[pos] == '\n') {
++pos;
}
}
}
if (newPosition)
if (newPosition) {
*newPosition = pos;
}
return null;
}
void headerField::parseImpl
(const parsingContext& ctx, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void headerField::parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
m_value->parse(ctx, buffer, position, end, newPosition);
}
void headerField::generateImpl
(const generationContext& ctx, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
void headerField::generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
os << m_name + ": ";
m_value->generate(ctx, os, curLinePos + m_name.length() + 2, newLinePos);
}
size_t headerField::getGeneratedSize(const generationContext& ctx)
{
size_t headerField::getGeneratedSize(const generationContext& ctx) {
return m_name.length() + 2 /* ": " */ + m_value->getGeneratedSize(ctx);
}
const string headerField::getName() const
{
const string headerField::getName() const {
return m_name;
}
void headerField::setName(const string& name)
{
void headerField::setName(const string& name) {
m_name = name;
}
bool headerField::isCustom() const
{
return (m_name.length() > 2 && m_name[0] == 'X' && m_name[1] == '-');
bool headerField::isCustom() const {
return m_name.length() > 2 && m_name[0] == 'X' && m_name[1] == '-';
}
const std::vector <shared_ptr <component> > headerField::getChildComponents()
{
const std::vector <shared_ptr <component> > headerField::getChildComponents() {
std::vector <shared_ptr <component> > list;
if (m_value)
if (m_value) {
list.push_back(m_value);
}
return (list);
return list;
}
shared_ptr <const headerFieldValue> headerField::getValue() const
{
shared_ptr <const headerFieldValue> headerField::getValue() const {
return m_value;
}
shared_ptr <headerFieldValue> headerField::getValue()
{
shared_ptr <headerFieldValue> headerField::getValue() {
return m_value;
}
void headerField::setValue(const shared_ptr <headerFieldValue>& value)
{
if (!headerFieldFactory::getInstance()->isValueTypeValid(*this, *value))
void headerField::setValue(const shared_ptr <headerFieldValue>& value) {
if (!headerFieldFactory::getInstance()->isValueTypeValid(*this, *value)) {
throw exceptions::bad_field_value_type(getName());
}
if (value != NULL)
if (value != NULL) {
m_value = value;
}
}
void headerField::setValueConst(const shared_ptr <const headerFieldValue>& value)
{
if (!headerFieldFactory::getInstance()->isValueTypeValid(*this, *value))
void headerField::setValueConst(const shared_ptr <const headerFieldValue>& value) {
if (!headerFieldFactory::getInstance()->isValueTypeValid(*this, *value)) {
throw exceptions::bad_field_value_type(getName());
}
m_value = vmime::clone(value);
}
void headerField::setValue(const headerFieldValue& value)
{
if (!headerFieldFactory::getInstance()->isValueTypeValid(*this, value))
void headerField::setValue(const headerFieldValue& value) {
if (!headerFieldFactory::getInstance()->isValueTypeValid(*this, value)) {
throw exceptions::bad_field_value_type(getName());
}
m_value = vmime::clone(value);
}
void headerField::setValue(const string& value)
{
void headerField::setValue(const string& value) {
parse(value);
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -30,15 +30,13 @@
#include "vmime/headerFieldValue.hpp"
namespace vmime
{
namespace vmime {
/** Base class for header fields.
*/
class VMIME_EXPORT headerField : public component {
class VMIME_EXPORT headerField : public component
{
friend class headerFieldFactory;
friend class header;
@ -90,8 +88,8 @@ public:
* @return value object
*/
template <typename T>
shared_ptr <const T> getValue() const
{
shared_ptr <const T> getValue() const {
return dynamicCast <const T>(m_value);
}
@ -107,8 +105,8 @@ public:
* @return value object
*/
template <typename T>
shared_ptr <T> getValue()
{
shared_ptr <T> getValue() {
return dynamicCast <T>(m_value);
}
@ -154,29 +152,32 @@ public:
* @return parsed header field, or NULL if no more header field can be parsed
* in the input buffer
*/
static shared_ptr <headerField> parseNext
(const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
static shared_ptr <headerField> parseNext(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
size_t getGeneratedSize(const generationContext& ctx);
protected:
void parseImpl
(const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
string m_name;

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -38,12 +38,11 @@
#include "vmime/mailboxField.hpp"
namespace vmime
{
namespace vmime {
headerFieldFactory::headerFieldFactory()
{
headerFieldFactory::headerFieldFactory() {
// Register parameterized fields
registerField <contentTypeField>(vmime::fields::CONTENT_TYPE);
registerField <parameterizedHeaderField>(vmime::fields::CONTENT_TRANSFER_ENCODING);
@ -85,67 +84,75 @@ headerFieldFactory::headerFieldFactory()
}
headerFieldFactory::~headerFieldFactory()
{
headerFieldFactory::~headerFieldFactory() {
}
shared_ptr <headerFieldFactory> headerFieldFactory::getInstance()
{
shared_ptr <headerFieldFactory> headerFieldFactory::getInstance() {
static headerFieldFactory instance;
return shared_ptr <headerFieldFactory>(&instance, noop_shared_ptr_deleter <headerFieldFactory>());
}
shared_ptr <headerField> headerFieldFactory::create
(const string& name, const string& body)
{
shared_ptr <headerField> headerFieldFactory::create(
const string& name,
const string& body
) {
NameMap::const_iterator pos = m_nameMap.find(utility::stringUtils::toLower(name));
shared_ptr <headerField> field;
if (pos != m_nameMap.end())
if (pos != m_nameMap.end()) {
field = ((*pos).second)();
else
} else {
field = registerer <headerField, headerField>::creator();
}
field->setName(name);
field->setValue(createValue(name));
if (body != NULL_STRING)
if (body != NULL_STRING) {
field->parse(body);
}
return field;
}
shared_ptr <headerFieldValue> headerFieldFactory::createValue(const string& fieldName)
{
ValueMap::const_iterator pos = m_valueMap.find
(utility::stringUtils::toLower(fieldName));
shared_ptr <headerFieldValue> headerFieldFactory::createValue(const string& fieldName) {
ValueMap::const_iterator pos = m_valueMap.find(
utility::stringUtils::toLower(fieldName)
);
shared_ptr <headerFieldValue> value;
if (pos != m_valueMap.end())
if (pos != m_valueMap.end()) {
value = ((*pos).second.allocFunc)();
else
} else {
value = registerer <headerFieldValue, text>::creator();
}
return value;
}
bool headerFieldFactory::isValueTypeValid
(const headerField& field, const headerFieldValue& value) const
{
bool headerFieldFactory::isValueTypeValid(
const headerField& field,
const headerFieldValue& value
) const {
ValueMap::const_iterator pos = m_valueMap.find
(utility::stringUtils::toLower(field.getName()));
if (pos != m_valueMap.end())
if (pos != m_valueMap.end()) {
return ((*pos).second.checkTypeFunc)(value);
}
return true; // No info on this field
}
} // vmime

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -29,15 +29,13 @@
#include "vmime/utility/stringUtils.hpp"
namespace vmime
{
namespace vmime {
/** Creates header field and header field value objects.
*/
class VMIME_EXPORT headerFieldFactory {
class VMIME_EXPORT headerFieldFactory
{
protected:
headerFieldFactory();
@ -49,8 +47,8 @@ protected:
NameMap m_nameMap;
struct ValueInfo
{
struct ValueInfo {
typedef shared_ptr <headerFieldValue> (*ValueAllocFunc)(void);
typedef bool (*ValueTypeCheckFunc)(const object&);
@ -67,24 +65,26 @@ public:
static shared_ptr <headerFieldFactory> getInstance();
#ifndef VMIME_BUILDING_DOC
// TYPE must inherit from BASE_TYPE
template <class BASE_TYPE, class TYPE>
class registerer
{
class registerer {
public:
static bool checkType(const object& obj)
{
static bool checkType(const object& obj) {
const TYPE* typedObj = dynamic_cast <const TYPE*>(&obj);
return typedObj != NULL;
}
static shared_ptr <BASE_TYPE> creator()
{
static shared_ptr <BASE_TYPE> creator() {
// Allocate a new object
return shared_ptr <BASE_TYPE>(new TYPE());
}
};
#endif // VMIME_BUILDING_DOC
@ -94,11 +94,14 @@ public:
* @param name field name (eg. "X-MyField")
*/
template <class T>
void registerField(const string& name)
{
m_nameMap.insert(NameMap::value_type
(utility::stringUtils::toLower(name),
&registerer <headerField, T>::creator));
void registerField(const string& name) {
m_nameMap.insert(
NameMap::value_type(
utility::stringUtils::toLower(name),
&registerer <headerField, T>::creator
)
);
}
/** Register a field value type.
@ -107,14 +110,18 @@ public:
* @param name field name
*/
template <class T>
void registerFieldValue(const string& name)
{
void registerFieldValue(const string& name) {
ValueInfo vi;
vi.allocFunc = &registerer <headerFieldValue, T>::creator;
vi.checkTypeFunc = &registerer <headerField, T>::checkType;
m_valueMap.insert(ValueMap::value_type
(utility::stringUtils::toLower(name), vi));
m_valueMap.insert(
ValueMap::value_type(
utility::stringUtils::toLower(name),
vi
)
);
}
/** Create a new field object for the specified field name.

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -26,12 +26,11 @@
#include "vmime/utility/outputStreamAdapter.hpp"
namespace vmime
{
namespace vmime {
size_t headerFieldValue::getGeneratedSize(const generationContext& ctx)
{
size_t headerFieldValue::getGeneratedSize(const generationContext& ctx) {
std::ostringstream oss;
utility::outputStreamAdapter osa(oss);

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -29,16 +29,14 @@
#include "vmime/component.hpp"
namespace vmime
{
namespace vmime {
/** Base class for all classes that can be used as a value
* for a header field.
*/
class VMIME_EXPORT headerFieldValue : public component {
class VMIME_EXPORT headerFieldValue : public component
{
public:
size_t getGeneratedSize(const generationContext& ctx);
@ -49,4 +47,3 @@ public:
#endif // VMIME_HEADERFIELDVALUE_HPP_INCLUDED

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -34,47 +34,52 @@
#include "vmime/utility/outputStreamAdapter.hpp"
namespace vmime
{
namespace vmime {
htmlTextPart::htmlTextPart()
: m_plainText(make_shared <emptyContentHandler>()),
m_text(make_shared <emptyContentHandler>())
{
m_text(make_shared <emptyContentHandler>()) {
}
htmlTextPart::~htmlTextPart()
{
htmlTextPart::~htmlTextPart() {
}
const mediaType htmlTextPart::getType() const
{
const mediaType htmlTextPart::getType() const {
return mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML);
}
size_t htmlTextPart::getPartCount() const
{
return (m_plainText->isEmpty() ? 1 : 2);
size_t htmlTextPart::getPartCount() const {
return m_plainText->isEmpty() ? 1 : 2;
}
void htmlTextPart::generateIn(const shared_ptr <bodyPart>& /* message */, const shared_ptr <bodyPart>& parent) const
{
void htmlTextPart::generateIn(
const shared_ptr <bodyPart>& /* message */,
const shared_ptr <bodyPart>& parent
) const {
// Plain text
if (!m_plainText->isEmpty())
{
if (!m_plainText->isEmpty()) {
// -- Create a new part
shared_ptr <bodyPart> part = make_shared <bodyPart>();
parent->getBody()->appendPart(part);
// -- Set contents
part->getBody()->setContents(m_plainText,
mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN), m_charset,
encoding::decide(m_plainText, m_charset, encoding::USAGE_TEXT));
part->getBody()->setContents(
m_plainText,
mediaType(mediaTypes::TEXT, mediaTypes::TEXT_PLAIN),
m_charset,
encoding::decide(m_plainText, m_charset, encoding::USAGE_TEXT)
);
}
// HTML text
@ -82,27 +87,31 @@ void htmlTextPart::generateIn(const shared_ptr <bodyPart>& /* message */, const
shared_ptr <bodyPart> htmlPart = make_shared <bodyPart>();
// -- Set contents
htmlPart->getBody()->setContents(m_text,
mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML), m_charset,
encoding::decide(m_text, m_charset, encoding::USAGE_TEXT));
htmlPart->getBody()->setContents(
m_text,
mediaType(mediaTypes::TEXT, mediaTypes::TEXT_HTML),
m_charset,
encoding::decide(m_text, m_charset, encoding::USAGE_TEXT)
);
// Handle the case we have embedded objects
if (!m_objects.empty())
{
if (!m_objects.empty()) {
// Create a "multipart/related" body part
shared_ptr <bodyPart> relPart = make_shared <bodyPart>();
parent->getBody()->appendPart(relPart);
relPart->getHeader()->ContentType()->
setValue(mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_RELATED));
relPart->getHeader()->ContentType()->setValue(
mediaType(mediaTypes::MULTIPART, mediaTypes::MULTIPART_RELATED)
);
// Add the HTML part into this part
relPart->getBody()->appendPart(htmlPart);
// Also add objects into this part
for (std::vector <shared_ptr <embeddedObject> >::const_iterator it = m_objects.begin() ;
it != m_objects.end() ; ++it)
{
it != m_objects.end() ; ++it) {
shared_ptr <bodyPart> objPart = make_shared <bodyPart>();
relPart->getBody()->appendPart(objPart);
@ -112,8 +121,8 @@ void htmlTextPart::generateIn(const shared_ptr <bodyPart>& /* message */, const
(id[0] == 'c' || id[0] == 'C') &&
(id[1] == 'i' || id[1] == 'I') &&
(id[2] == 'd' || id[2] == 'D') &&
id[3] == ':')
{
id[3] == ':') {
id = id.substr(4);
}
@ -125,38 +134,46 @@ void htmlTextPart::generateIn(const shared_ptr <bodyPart>& /* message */, const
objPart->getBody()->setContents((*it)->getData()->clone());
}
}
else
{
} else {
// Add the HTML part into the parent part
parent->getBody()->appendPart(htmlPart);
}
}
void htmlTextPart::findEmbeddedParts(const bodyPart& part,
std::vector <shared_ptr <const bodyPart> >& cidParts, std::vector <shared_ptr <const bodyPart> >& locParts)
{
for (size_t i = 0 ; i < part.getBody()->getPartCount() ; ++i)
{
void htmlTextPart::findEmbeddedParts(
const bodyPart& part,
std::vector <shared_ptr <const bodyPart> >& cidParts,
std::vector <shared_ptr <const bodyPart> >& locParts
) {
for (size_t i = 0 ; i < part.getBody()->getPartCount() ; ++i) {
shared_ptr <const bodyPart> p = part.getBody()->getPartAt(i);
// For a part to be an embedded object, it must have either a
// Content-Id field or a Content-Location field.
if (p->getHeader()->hasField(fields::CONTENT_ID))
if (p->getHeader()->hasField(fields::CONTENT_ID)) {
cidParts.push_back(p);
}
if (p->getHeader()->hasField(fields::CONTENT_LOCATION))
if (p->getHeader()->hasField(fields::CONTENT_LOCATION)) {
locParts.push_back(p);
}
findEmbeddedParts(*p, cidParts, locParts);
}
}
void htmlTextPart::addEmbeddedObject(const bodyPart& part, const string& id,
const embeddedObject::ReferenceType refType)
{
void htmlTextPart::addEmbeddedObject(
const bodyPart& part,
const string& id,
const embeddedObject::ReferenceType refType
) {
// The object may already exists. This can happen if an object is
// identified by both a Content-Id and a Content-Location. In this
// case, there will be two embedded objects with two different IDs
@ -167,23 +184,33 @@ void htmlTextPart::addEmbeddedObject(const bodyPart& part, const string& id,
shared_ptr <const headerField> ctf =
part.getHeader()->findField(fields::CONTENT_TYPE);
if (ctf)
{
if (ctf) {
type = *ctf->getValue <mediaType>();
}
else
{
} else {
// No "Content-type" field: assume "application/octet-stream".
}
m_objects.push_back(make_shared <embeddedObject>
(vmime::clone(part.getBody()->getContents()),
part.getBody()->getEncoding(), id, type, refType));
m_objects.push_back(
make_shared <embeddedObject>(
vmime::clone(part.getBody()->getContents()),
part.getBody()->getEncoding(),
id,
type,
refType
)
);
}
void htmlTextPart::parse(const shared_ptr <const bodyPart>& message, const shared_ptr <const bodyPart>& parent, const shared_ptr <const bodyPart>& textPart)
{
void htmlTextPart::parse(
const shared_ptr <const bodyPart>& message,
const shared_ptr <const bodyPart>& parent,
const shared_ptr <const bodyPart>& textPart
) {
// Search for possible embedded objects in the _whole_ message.
std::vector <shared_ptr <const bodyPart> > cidParts;
std::vector <shared_ptr <const bodyPart> > locParts;
@ -204,39 +231,42 @@ void htmlTextPart::parse(const shared_ptr <const bodyPart>& message, const share
shared_ptr <const contentTypeField> ctf =
textPart->getHeader()->findField <contentTypeField>(fields::CONTENT_TYPE);
if (ctf && ctf->hasCharset())
if (ctf && ctf->hasCharset()) {
m_charset = ctf->getCharset();
else
} else {
m_charset = charset();
}
// Extract embedded objects. The algorithm is quite simple: for each previously
// found inline part, we check if its CID/Location is contained in the HTML text.
for (std::vector <shared_ptr <const bodyPart> >::const_iterator p = cidParts.begin() ; p != cidParts.end() ; ++p)
{
for (std::vector <shared_ptr <const bodyPart> >::const_iterator p = cidParts.begin() ;
p != cidParts.end() ; ++p) {
const shared_ptr <const headerField> midField =
(*p)->getHeader()->findField(fields::CONTENT_ID);
const messageId mid = *midField->getValue <messageId>();
if (data.find("CID:" + mid.getId()) != string::npos ||
data.find("cid:" + mid.getId()) != string::npos)
{
data.find("cid:" + mid.getId()) != string::npos) {
// This part is referenced in the HTML text.
// Add it to the embedded object list.
addEmbeddedObject(**p, mid.getId(), embeddedObject::REFERENCED_BY_ID);
}
}
for (std::vector <shared_ptr <const bodyPart> >::const_iterator p = locParts.begin() ; p != locParts.end() ; ++p)
{
for (std::vector <shared_ptr <const bodyPart> >::const_iterator p = locParts.begin() ;
p != locParts.end() ; ++p) {
const shared_ptr <const headerField> locField =
(*p)->getHeader()->findField(fields::CONTENT_LOCATION);
const text loc = *locField->getValue <text>();
const string locStr = loc.getWholeBuffer();
if (data.find(locStr) != string::npos)
{
if (data.find(locStr) != string::npos) {
// This part is referenced in the HTML text.
// Add it to the embedded object list.
addEmbeddedObject(**p, locStr, embeddedObject::REFERENCED_BY_LOCATION);
@ -244,65 +274,68 @@ void htmlTextPart::parse(const shared_ptr <const bodyPart>& message, const share
}
// Extract plain text, if any.
if (!findPlainTextPart(*message, *parent, *textPart))
{
if (!findPlainTextPart(*message, *parent, *textPart)) {
m_plainText = make_shared <emptyContentHandler>();
}
}
bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& parent, const bodyPart& textPart)
{
bool htmlTextPart::findPlainTextPart(
const bodyPart& part,
const bodyPart& parent,
const bodyPart& textPart
) {
// We search for the nearest "multipart/alternative" part.
const shared_ptr <const headerField> ctf =
part.getHeader()->findField(fields::CONTENT_TYPE);
if (ctf)
{
if (ctf) {
const mediaType type = *ctf->getValue <mediaType>();
if (type.getType() == mediaTypes::MULTIPART &&
type.getSubType() == mediaTypes::MULTIPART_ALTERNATIVE)
{
type.getSubType() == mediaTypes::MULTIPART_ALTERNATIVE) {
shared_ptr <const bodyPart> foundPart;
for (size_t i = 0 ; i < part.getBody()->getPartCount() ; ++i)
{
for (size_t i = 0 ; i < part.getBody()->getPartCount() ; ++i) {
const shared_ptr <const bodyPart> p = part.getBody()->getPartAt(i);
if (p.get() == &parent || // if "text/html" is in "multipart/related"
p.get() == &textPart) // if not...
{
p.get() == &textPart) { // if not...
foundPart = p;
}
}
if (foundPart)
{
if (foundPart) {
bool found = false;
// Now, search for the alternative plain text part
for (size_t i = 0 ; !found && i < part.getBody()->getPartCount() ; ++i)
{
for (size_t i = 0 ; !found && i < part.getBody()->getPartCount() ; ++i) {
const shared_ptr <const bodyPart> p = part.getBody()->getPartAt(i);
const shared_ptr <const headerField> ctf =
p->getHeader()->findField(fields::CONTENT_TYPE);
if (ctf)
{
if (ctf) {
const mediaType type = *ctf->getValue <mediaType>();
if (type.getType() == mediaTypes::TEXT &&
type.getSubType() == mediaTypes::TEXT_PLAIN)
{
type.getSubType() == mediaTypes::TEXT_PLAIN) {
m_plainText = p->getBody()->getContents()->clone();
found = true;
}
}
else
{
} else {
// No "Content-type" field.
}
}
@ -313,16 +346,16 @@ bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& paren
return found;
}
}
}
else
{
} else {
// No "Content-type" field.
}
bool found = false;
for (size_t i = 0 ; !found && i < part.getBody()->getPartCount() ; ++i)
{
for (size_t i = 0 ; !found && i < part.getBody()->getPartCount() ; ++i) {
found = findPlainTextPart(*part.getBody()->getPartAt(i), parent, textPart);
}
@ -330,50 +363,50 @@ bool htmlTextPart::findPlainTextPart(const bodyPart& part, const bodyPart& paren
}
const charset& htmlTextPart::getCharset() const
{
const charset& htmlTextPart::getCharset() const {
return m_charset;
}
void htmlTextPart::setCharset(const charset& ch)
{
void htmlTextPart::setCharset(const charset& ch) {
m_charset = ch;
}
shared_ptr <const contentHandler> htmlTextPart::getPlainText() const
{
shared_ptr <const contentHandler> htmlTextPart::getPlainText() const {
return m_plainText;
}
void htmlTextPart::setPlainText(const shared_ptr <contentHandler>& plainText)
{
void htmlTextPart::setPlainText(const shared_ptr <contentHandler>& plainText) {
m_plainText = plainText->clone();
}
const shared_ptr <const contentHandler> htmlTextPart::getText() const
{
const shared_ptr <const contentHandler> htmlTextPart::getText() const {
return m_text;
}
void htmlTextPart::setText(const shared_ptr <contentHandler>& text)
{
void htmlTextPart::setText(const shared_ptr <contentHandler>& text) {
m_text = text->clone();
}
size_t htmlTextPart::getObjectCount() const
{
size_t htmlTextPart::getObjectCount() const {
return m_objects.size();
}
shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::getObjectAt(const size_t pos) const
{
shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::getObjectAt(const size_t pos) const {
return m_objects[pos];
}
@ -381,36 +414,42 @@ shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::getObjectAt(const
shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::findObject(const string& id) const
{
for (std::vector <shared_ptr <embeddedObject> >::const_iterator o = m_objects.begin() ;
o != m_objects.end() ; ++o)
{
if ((*o)->matchesId(id))
o != m_objects.end() ; ++o) {
if ((*o)->matchesId(id)) {
return *o;
}
}
return null;
}
bool htmlTextPart::hasObject(const string& id) const
{
bool htmlTextPart::hasObject(const string& id) const {
for (std::vector <shared_ptr <embeddedObject> >::const_iterator o = m_objects.begin() ;
o != m_objects.end() ; ++o)
{
if ((*o)->matchesId(id))
o != m_objects.end() ; ++o) {
if ((*o)->matchesId(id)) {
return true;
}
}
return false;
}
shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::addObject
(const shared_ptr <contentHandler>& data, const vmime::encoding& enc, const mediaType& type)
{
shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::addObject(
const shared_ptr <contentHandler>& data,
const vmime::encoding& enc,
const mediaType& type
) {
const messageId mid(messageId::generateId());
shared_ptr <embeddedObject> obj = make_shared <embeddedObject>
(data, enc, mid.getId(), type, embeddedObject::REFERENCED_BY_ID);
shared_ptr <embeddedObject> obj = make_shared <embeddedObject>(
data, enc, mid.getId(), type, embeddedObject::REFERENCED_BY_ID
);
m_objects.push_back(obj);
@ -418,16 +457,20 @@ shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::addObject
}
shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::addObject
(const shared_ptr <contentHandler>& data, const mediaType& type)
{
shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::addObject(
const shared_ptr <contentHandler>& data,
const mediaType& type
) {
return addObject(data, encoding::decide(data), type);
}
shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::addObject
(const string& data, const mediaType& type)
{
shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::addObject(
const string& data,
const mediaType& type
) {
shared_ptr <stringContentHandler> cts = make_shared <stringContentHandler>(data);
return addObject(cts, encoding::decide(cts), type);
}
@ -438,76 +481,85 @@ shared_ptr <const htmlTextPart::embeddedObject> htmlTextPart::addObject
// htmlTextPart::embeddedObject
//
htmlTextPart::embeddedObject::embeddedObject
(const shared_ptr <contentHandler>& data, const encoding& enc,
const string& id, const mediaType& type, const ReferenceType refType)
htmlTextPart::embeddedObject::embeddedObject(
const shared_ptr <contentHandler>& data,
const encoding& enc,
const string& id,
const mediaType& type,
const ReferenceType refType
)
: m_data(vmime::clone(data)),
m_encoding(enc), m_id(id), m_type(type), m_refType(refType)
{
m_encoding(enc),
m_id(id),
m_type(type),
m_refType(refType) {
}
shared_ptr <const contentHandler> htmlTextPart::embeddedObject::getData() const
{
shared_ptr <const contentHandler> htmlTextPart::embeddedObject::getData() const {
return m_data;
}
const vmime::encoding htmlTextPart::embeddedObject::getEncoding() const
{
const vmime::encoding htmlTextPart::embeddedObject::getEncoding() const {
return m_encoding;
}
const string htmlTextPart::embeddedObject::getId() const
{
const string htmlTextPart::embeddedObject::getId() const {
return m_id;
}
const string htmlTextPart::embeddedObject::getReferenceId() const
{
if (m_refType == REFERENCED_BY_ID)
const string htmlTextPart::embeddedObject::getReferenceId() const {
if (m_refType == REFERENCED_BY_ID) {
return string("cid:") + m_id;
else
} else {
return m_id;
}
}
const mediaType htmlTextPart::embeddedObject::getType() const
{
const mediaType htmlTextPart::embeddedObject::getType() const {
return m_type;
}
htmlTextPart::embeddedObject::ReferenceType htmlTextPart::embeddedObject::getReferenceType() const
{
htmlTextPart::embeddedObject::ReferenceType htmlTextPart::embeddedObject::getReferenceType() const {
return m_refType;
}
bool htmlTextPart::embeddedObject::matchesId(const string& id) const
{
if (m_refType == REFERENCED_BY_ID)
bool htmlTextPart::embeddedObject::matchesId(const string& id) const {
if (m_refType == REFERENCED_BY_ID) {
return m_id == cleanId(id);
else
} else {
return m_id == id;
}
}
// static
const string htmlTextPart::embeddedObject::cleanId(const string& id)
{
const string htmlTextPart::embeddedObject::cleanId(const string& id) {
if (id.length() >= 4 &&
(id[0] == 'c' || id[0] == 'C') &&
(id[1] == 'i' || id[1] == 'I') &&
(id[2] == 'd' || id[2] == 'D') &&
id[3] == ':')
{
id[3] == ':') {
return id.substr(4);
}
else
{
} else {
return id;
}
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -32,15 +32,13 @@
#include "vmime/contentHandler.hpp"
namespace vmime
{
namespace vmime {
/** Text part of type 'text/html'.
*/
class VMIME_EXPORT htmlTextPart : public textPart {
class VMIME_EXPORT htmlTextPart : public textPart
{
public:
htmlTextPart();
@ -59,13 +57,11 @@ public:
/** Embedded object (eg: image for &lt;IMG> tag).
*/
class VMIME_EXPORT embeddedObject : public object
{
class VMIME_EXPORT embeddedObject : public object {
public:
/** The ways embedded objects can be referenced. */
enum ReferenceType
{
enum ReferenceType {
REFERENCED_BY_ID, /**< Referenced by Content-Id. */
REFERENCED_BY_LOCATION /**< Referenced by Content-Location. */
};
@ -79,9 +75,13 @@ public:
* @param refType reference type
* @return a reference to a new embedded object
*/
embeddedObject(const shared_ptr <contentHandler>& data, const encoding& enc,
const string& id, const mediaType& type,
const ReferenceType refType);
embeddedObject(
const shared_ptr <contentHandler>& data,
const encoding& enc,
const string& id,
const mediaType& type,
const ReferenceType refType
);
/** Return data stored in this embedded object.
*
@ -185,7 +185,10 @@ public:
* @return an unique object identifier used to identify the new
* object among all other embedded objects
*/
shared_ptr <const embeddedObject> addObject(const string& data, const mediaType& type);
shared_ptr <const embeddedObject> addObject(
const string& data,
const mediaType& type
);
/** Embed an object and returns a string which identifies it.
* The returned identifier is suitable for use in the 'src' attribute
@ -196,7 +199,10 @@ public:
* @return an unique object identifier used to identify the new
* object among all other embedded objects
*/
shared_ptr <const embeddedObject> addObject(const shared_ptr <contentHandler>& data, const mediaType& type);
shared_ptr <const embeddedObject> addObject(
const shared_ptr <contentHandler>& data,
const mediaType& type
);
/** Embed an object and returns a string which identifies it.
* The returned identifier is suitable for use in the 'src' attribute
@ -208,13 +214,25 @@ public:
* @return an unique object identifier used to identify the new
* object among all other embedded objects
*/
shared_ptr <const embeddedObject> addObject(const shared_ptr <contentHandler>& data, const encoding& enc, const mediaType& type);
shared_ptr <const embeddedObject> addObject(
const shared_ptr <contentHandler>& data,
const encoding& enc,
const mediaType& type
);
size_t getPartCount() const;
void generateIn(const shared_ptr <bodyPart>& message, const shared_ptr <bodyPart>& parent) const;
void parse(const shared_ptr <const bodyPart>& message, const shared_ptr <const bodyPart>& parent, const shared_ptr <const bodyPart>& textPart);
void generateIn(
const shared_ptr <bodyPart>& message,
const shared_ptr <bodyPart>& parent
) const;
void parse(
const shared_ptr <const bodyPart>& message,
const shared_ptr <const bodyPart>& parent,
const shared_ptr <const bodyPart>& textPart
);
private:
@ -224,10 +242,23 @@ private:
std::vector <shared_ptr <embeddedObject> > m_objects;
void findEmbeddedParts(const bodyPart& part, std::vector <shared_ptr <const bodyPart> >& cidParts, std::vector <shared_ptr <const bodyPart> >& locParts);
void addEmbeddedObject(const bodyPart& part, const string& id, const embeddedObject::ReferenceType refType);
void findEmbeddedParts(
const bodyPart& part,
std::vector <shared_ptr <const bodyPart> >& cidParts,
std::vector <shared_ptr <const bodyPart> >& locParts
);
bool findPlainTextPart(const bodyPart& part, const bodyPart& parent, const bodyPart& textPart);
void addEmbeddedObject(
const bodyPart& part,
const string& id,
const embeddedObject::ReferenceType refType
);
bool findPlainTextPart(
const bodyPart& part,
const bodyPart& parent,
const bodyPart& textPart
);
};

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -26,30 +26,32 @@
#include "vmime/utility/outputStreamStringAdapter.hpp"
namespace vmime
{
namespace vmime {
mailbox::mailbox()
{
mailbox::mailbox() {
}
mailbox::mailbox(const mailbox& mbox)
: address(), m_name(mbox.m_name), m_email(mbox.m_email)
{
: address(),
m_name(mbox.m_name),
m_email(mbox.m_email) {
}
mailbox::mailbox(const emailAddress& email)
: m_email(email)
{
: m_email(email) {
}
mailbox::mailbox(const text& name, const emailAddress& email)
: m_name(name), m_email(email)
{
: m_name(name),
m_email(email) {
}
@ -66,10 +68,14 @@ angle-addr = [CFWS] "<" addr-spec ">" [CFWS] / obs-angle-addr
*/
void mailbox::parseImpl
(const parsingContext& ctx, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void mailbox::parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
const char* const pend = buffer.data() + end;
const char* const pstart = buffer.data() + position;
const char* p = pstart;
@ -78,8 +84,7 @@ void mailbox::parseImpl
while (p < pend && parserHelpers::isSpace(*p)) ++p;
// Current state for parsing machine
enum States
{
enum States {
State_None,
State_Name,
State_Address
@ -92,96 +97,98 @@ void mailbox::parseImpl
string address;
bool hadBrackets = false;
while (p < pend)
{
if (state == State_Name)
{
if (*p == '<')
{
while (p < pend) {
if (state == State_Name) {
if (*p == '<') {
state = State_Address;
continue;
}
if (*p == '"') // Quoted string
{
if (*p == '"') { // Quoted string
++p;
bool escaped = false;
while (p < pend)
{
if (escaped)
{
while (p < pend) {
if (escaped) {
name += *p;
escaped = false;
}
else if (*p == '\\')
{
} else if (*p == '\\') {
escaped = true;
}
else
{
if (*p == '"')
{
} else {
if (*p == '"') {
++p;
break;
}
else
{
} else {
name += *p;
}
}
++p;
}
}
else
{
} else {
bool escaped = false;
int comment = 0;
while (p < pend)
{
if (escaped)
{
while (p < pend) {
if (escaped) {
if (!comment) name += *p;
escaped = false;
}
else if (comment)
{
if (*p == '\\')
} else if (comment) {
if (*p == '\\') {
escaped = true;
else if (*p == '(')
} else if (*p == '(') {
++comment;
else if (*p == ')')
} else if (*p == ')') {
--comment;
}
else if (*p == '\\')
{
}
} else if (*p == '\\') {
escaped = true;
}
else if (*p == '(')
{
} else if (*p == '(') {
++comment;
}
else if (*p == '<')
{
} else if (*p == '<') {
// Erase any space between display name and <address>
string::iterator q = name.end();
while (q != name.begin() && parserHelpers::isSpace(*(q - 1)))
while (q != name.begin() && parserHelpers::isSpace(*(q - 1))) {
--q;
}
name.erase(q, name.end());
break;
}
else if (/* parserHelpers::isSpace(*p) || */ *p == '@')
{
} else if (/* parserHelpers::isSpace(*p) || */ *p == '@') {
break;
}
else
{
} else {
name += *p;
}
@ -189,8 +196,8 @@ void mailbox::parseImpl
}
}
if (p < pend && *p == '@')
{
if (p < pend && *p == '@') {
// (*) Actually, we were parsing the local-part of an address
// and not a display name...
address = name;
@ -199,92 +206,94 @@ void mailbox::parseImpl
bool escaped = false;
int comment = 0;
while (p < pend)
{
if (escaped)
{
while (p < pend) {
if (escaped) {
if (!comment) address += *p;
escaped = false;
}
else if (comment)
{
if (*p == '\\')
} else if (comment) {
if (*p == '\\') {
escaped = true;
else if (*p == '(')
} else if (*p == '(') {
++comment;
else if (*p == ')')
} else if (*p == ')') {
--comment;
}
else if (*p == '\\')
{
}
} else if (*p == '\\') {
escaped = true;
}
else if (*p == '(')
{
} else if (*p == '(') {
++comment;
}
else if (parserHelpers::isSpace(*p))
{
} else if (parserHelpers::isSpace(*p)) {
break;
}
else
{
} else {
address += *p;
}
++p;
}
}
else
{
} else {
while (p < pend && parserHelpers::isSpace(*p)) ++p;
state = State_None;
}
}
else if (state == State_Address)
{
} else if (state == State_Address) {
bool escaped = false;
int comment = 0;
while (p < pend)
{
if (escaped)
{
while (p < pend) {
if (escaped) {
if (!comment) address += *p;
escaped = false;
}
else if (comment)
{
if (*p == '\\')
} else if (comment) {
if (*p == '\\') {
escaped = true;
else if (*p == '(')
} else if (*p == '(') {
++comment;
else if (*p == ')')
} else if (*p == ')') {
--comment;
}
else if (*p == '(')
{
}
} else if (*p == '(') {
++comment;
}
else if (*p == '\\')
{
} else if (*p == '\\') {
escaped = true;
}
else if (*p == '<')
{
} else if (*p == '<') {
// If we found a '<' here, it means that the address
// starts _only_ here...and the stuff we have parsed
// before belongs actually to the display name!
name += address;
address.clear();
}
else if (*p == '>')
{
} else if (*p == '>') {
hadBrackets = true;
break;
}
else if (!parserHelpers::isSpace(*p))
{
} else if (!parserHelpers::isSpace(*p)) {
address += *p;
}
@ -292,54 +301,56 @@ void mailbox::parseImpl
}
break;
}
else
{
} else {
while (p < pend && parserHelpers::isSpace(*p)) ++p;
if (p < pend)
{
//if (*p == '<')
state = State_Address;
if (p < pend) {
state = State_Address;
}
}
}
// Swap name and address when no address was found
// (email address is mandatory, whereas name is optional).
if (address.empty() && !name.empty() && !hadBrackets)
{
if (address.empty() && !name.empty() && !hadBrackets) {
m_name.removeAllWords();
m_email.parse(ctx, name);
}
else
{
} else {
text::decodeAndUnfold(ctx, name, &m_name);
m_email.parse(ctx, address);
}
setParsedBounds(position, position + (p - pstart));
if (newPosition)
if (newPosition) {
*newPosition = position + (p - pstart);
}
}
void mailbox::generateImpl
(const generationContext& ctx, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
void mailbox::generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
string generatedEmail;
utility::outputStreamStringAdapter generatedEmailStream(generatedEmail);
m_email.generate(ctx, generatedEmailStream, 0, NULL);
if (m_name.isEmpty())
{
if (m_name.isEmpty()) {
size_t pos = curLinePos;
// No display name is specified, only email address.
if (curLinePos + generatedEmail.length() > ctx.getMaxLineLength())
{
if (curLinePos + generatedEmail.length() > ctx.getMaxLineLength()) {
os << NEW_LINE_SEQUENCE;
pos = NEW_LINE_SEQUENCE.length();
}
@ -347,11 +358,12 @@ void mailbox::generateImpl
os << generatedEmail;
pos += generatedEmail.length();
if (newLinePos)
if (newLinePos) {
*newLinePos = pos;
}
else
{
}
} else {
// We have to encode the name:
// - if it contains characters in a charset different from "US-ASCII",
// - and/or if it contains one or more of these special chars:
@ -361,50 +373,52 @@ void mailbox::generateImpl
// and/or contain the special chars.
bool forceEncode = false;
for (size_t w = 0 ; !forceEncode && w != m_name.getWordCount() ; ++w)
{
if (m_name.getWordAt(w)->getCharset() == charset(charsets::US_ASCII))
{
for (size_t w = 0 ; !forceEncode && w != m_name.getWordCount() ; ++w) {
if (m_name.getWordAt(w)->getCharset() == charset(charsets::US_ASCII)) {
const string& buffer = m_name.getWordAt(w)->getBuffer();
for (string::const_iterator c = buffer.begin() ;
!forceEncode && c != buffer.end() ; ++c)
{
switch (*c)
{
case '\r':
case '\n':
case '\t':
case ';':
case ',':
case '<': case '>':
case '(': case ')':
case '@':
case '/':
case '?':
case '.':
case '=':
case ':':
case '"':
!forceEncode && c != buffer.end() ; ++c) {
forceEncode = true;
break;
switch (*c) {
case '\r':
case '\n':
case '\t':
case ';':
case ',':
case '<': case '>':
case '(': case ')':
case '@':
case '/':
case '?':
case '.':
case '=':
case ':':
case '"':
forceEncode = true;
break;
}
}
}
else
{
} else {
forceEncode = true;
}
}
size_t pos = curLinePos;
m_name.encodeAndFold(ctx, os, pos, &pos,
text::QUOTE_IF_POSSIBLE | (forceEncode ? text::FORCE_ENCODING : 0));
m_name.encodeAndFold(
ctx, os, pos, &pos,
text::QUOTE_IF_POSSIBLE | (forceEncode ? text::FORCE_ENCODING : 0)
);
if (pos + generatedEmail.length() + 3 > ctx.getMaxLineLength()) {
if (pos + generatedEmail.length() + 3 > ctx.getMaxLineLength())
{
os << NEW_LINE_SEQUENCE;
pos = NEW_LINE_SEQUENCE.length();
}
@ -412,26 +426,27 @@ void mailbox::generateImpl
os << " <" << generatedEmail << ">";
pos += 2 + generatedEmail.length() + 1;
if (newLinePos)
if (newLinePos) {
*newLinePos = pos;
}
}
}
bool mailbox::operator==(const class mailbox& mailbox) const
{
return (m_name == mailbox.m_name && m_email == mailbox.m_email);
bool mailbox::operator==(const class mailbox& mailbox) const {
return m_name == mailbox.m_name && m_email == mailbox.m_email;
}
bool mailbox::operator!=(const class mailbox& mailbox) const
{
bool mailbox::operator!=(const class mailbox& mailbox) const {
return !(*this == mailbox);
}
void mailbox::copyFrom(const component& other)
{
void mailbox::copyFrom(const component& other) {
const mailbox& source = dynamic_cast <const mailbox&>(other);
m_name = source.m_name;
@ -439,64 +454,64 @@ void mailbox::copyFrom(const component& other)
}
mailbox& mailbox::operator=(const mailbox& other)
{
mailbox& mailbox::operator=(const mailbox& other) {
copyFrom(other);
return (*this);
return *this;
}
shared_ptr <component>mailbox::clone() const
{
shared_ptr <component>mailbox::clone() const {
return make_shared <mailbox>(*this);
}
bool mailbox::isEmpty() const
{
bool mailbox::isEmpty() const {
return m_email.isEmpty();
}
void mailbox::clear()
{
void mailbox::clear() {
m_name.removeAllWords();
m_email = emailAddress();
}
bool mailbox::isGroup() const
{
return (false);
bool mailbox::isGroup() const {
return false;
}
const text& mailbox::getName() const
{
return (m_name);
const text& mailbox::getName() const {
return m_name;
}
void mailbox::setName(const text& name)
{
void mailbox::setName(const text& name) {
m_name = name;
}
const emailAddress& mailbox::getEmail() const
{
return (m_email);
const emailAddress& mailbox::getEmail() const {
return m_email;
}
void mailbox::setEmail(const emailAddress& email)
{
void mailbox::setEmail(const emailAddress& email) {
m_email = email;
}
const std::vector <shared_ptr <component> > mailbox::getChildComponents()
{
const std::vector <shared_ptr <component> > mailbox::getChildComponents() {
return std::vector <shared_ptr <component> >();
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -30,15 +30,13 @@
#include "vmime/text.hpp"
namespace vmime
{
namespace vmime {
/** A mailbox: full name + email (basic type).
*/
class VMIME_EXPORT mailbox : public address {
class VMIME_EXPORT mailbox : public address
{
friend class mailboxGroup;
friend class mailboxField;
@ -102,18 +100,20 @@ public:
using address::generate;
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
};

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -28,45 +28,51 @@
#ifndef VMIME_BUILDING_DOC
namespace vmime
{
namespace vmime {
mailboxField::mailboxField()
{
mailboxField::mailboxField() {
}
mailboxField::mailboxField(const mailboxField&)
: headerField()
{
: headerField() {
}
void mailboxField::parse
(const parsingContext& ctx, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void mailboxField::parse(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
shared_ptr <mailbox> mbox = make_shared <mailbox>();
// Here, we cannot simply call "m_mailbox.parse()" because it
// may have more than one address specified (even if this field
// should contain only one). We are never too much careful...
shared_ptr <address> parsedAddress = address::parseNext(ctx, buffer, position, end, newPosition, NULL);
shared_ptr <address> parsedAddress = address::parseNext(
ctx, buffer, position, end, newPosition, NULL
);
if (parsedAddress) {
if (parsedAddress->isGroup()) {
if (parsedAddress)
{
if (parsedAddress->isGroup())
{
// If it is a group of mailboxes, take the first
// mailbox of the group
shared_ptr <mailboxGroup> group = dynamicCast <mailboxGroup>(parsedAddress);
if (!group->isEmpty())
if (!group->isEmpty()) {
mbox = group->getMailboxAt(0);
}
else
{
}
} else {
// Parse only if it is a mailbox
mbox = dynamicCast <mailbox>(parsedAddress);
}
@ -78,8 +84,9 @@ void mailboxField::parse
setParsedBounds(position, end);
if (newPosition)
if (newPosition) {
*newPosition = end;
}
}
@ -87,4 +94,3 @@ void mailboxField::parse
#endif // VMIME_BUILDING_DOC

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -33,16 +33,14 @@
#ifndef VMIME_BUILDING_DOC
namespace vmime
{
namespace vmime {
/** Work-around for malformed header fields that are of type 'mailbox'
* and contains multiple addresses.
*/
class VMIME_EXPORT mailboxField : public headerField {
class VMIME_EXPORT mailboxField : public headerField
{
friend class headerFieldFactory;
protected:
@ -52,9 +50,13 @@ protected:
public:
void parse(const parsingContext& ctx, const string& buffer,
const size_t position, const size_t end,
size_t * newPosition = NULL);
void parse(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t * newPosition = NULL
);
};
@ -65,4 +67,3 @@ public:
#endif // VMIME_MAILBOXFIELD_HPP_INCLUDED

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -26,79 +26,83 @@
#include "vmime/exception.hpp"
namespace vmime
{
namespace vmime {
mailboxGroup::mailboxGroup()
{
mailboxGroup::mailboxGroup() {
}
mailboxGroup::mailboxGroup(const mailboxGroup& mboxGroup)
: address()
{
: address() {
copyFrom(mboxGroup);
}
mailboxGroup::mailboxGroup(const text& name)
: m_name(name)
{
: m_name(name) {
}
mailboxGroup::~mailboxGroup()
{
mailboxGroup::~mailboxGroup() {
removeAllMailboxes();
}
void mailboxGroup::parseImpl
(const parsingContext& ctx, const string& buffer, const size_t position,
const size_t end, size_t* newPosition)
{
void mailboxGroup::parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition
) {
const char* const pend = buffer.data() + end;
const char* const pstart = buffer.data() + position;
const char* p = pstart;
while (p < pend && parserHelpers::isSpace(*p))
while (p < pend && parserHelpers::isSpace(*p)) {
++p;
}
string name;
while (p < pend && *p != ':')
{
while (p < pend && *p != ':') {
name += *p;
++p;
}
if (p < pend && *p == ':')
if (p < pend && *p == ':') {
++p;
}
size_t pos = position + (p - pstart);
bool isLastAddressOfGroup = false;
while (pos < end && !isLastAddressOfGroup)
{
shared_ptr <address> parsedAddress = address::parseNext(ctx, buffer, pos, end, &pos, &isLastAddressOfGroup);
while (pos < end && !isLastAddressOfGroup) {
shared_ptr <address> parsedAddress =
address::parseNext(ctx, buffer, pos, end, &pos, &isLastAddressOfGroup);
if (parsedAddress) {
if (parsedAddress->isGroup()) {
if (parsedAddress)
{
if (parsedAddress->isGroup())
{
shared_ptr <mailboxGroup> group = dynamicCast <mailboxGroup>(parsedAddress);
// Sub-groups are not allowed in mailbox groups: so, we add all
// the contents of the sub-group into this group...
for (size_t i = 0 ; i < group->getMailboxCount() ; ++i)
{
for (size_t i = 0 ; i < group->getMailboxCount() ; ++i) {
m_list.push_back(vmime::clone(group->getMailboxAt(i)));
}
}
else
{
} else {
m_list.push_back(dynamicCast <mailbox>(parsedAddress));
}
}
@ -108,15 +112,19 @@ void mailboxGroup::parseImpl
setParsedBounds(position, end);
if (newPosition)
if (newPosition) {
*newPosition = end;
}
}
void mailboxGroup::generateImpl
(const generationContext& ctx, utility::outputStream& os,
const size_t curLinePos, size_t* newLinePos) const
{
void mailboxGroup::generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos,
size_t* newLinePos
) const {
// We have to encode the name:
// - if it contains characters in a charset different from "US-ASCII",
// - and/or if it contains one or more of these special chars:
@ -126,32 +134,32 @@ void mailboxGroup::generateImpl
// and/or contain the special chars.
bool forceEncode = false;
for (size_t w = 0 ; !forceEncode && w < m_name.getWordCount() ; ++w)
{
if (m_name.getWordAt(w)->getCharset() == charset(charsets::US_ASCII))
{
for (size_t w = 0 ; !forceEncode && w < m_name.getWordCount() ; ++w) {
if (m_name.getWordAt(w)->getCharset() == charset(charsets::US_ASCII)) {
const string& buffer = m_name.getWordAt(w)->getBuffer();
for (string::const_iterator c = buffer.begin() ;
!forceEncode && c != buffer.end() ; ++c)
{
switch (*c)
{
case ' ':
case '\t':
case ';':
case ',':
case '<': case '>':
case '(': case ')':
case '@':
case '/':
case '?':
case '.':
case '=':
case ':':
!forceEncode && c != buffer.end() ; ++c) {
forceEncode = true;
break;
switch (*c) {
case ' ':
case '\t':
case ';':
case ',':
case '<': case '>':
case '(': case ')':
case '@':
case '/':
case '?':
case '.':
case '=':
case ':':
forceEncode = true;
break;
}
}
}
@ -162,22 +170,24 @@ void mailboxGroup::generateImpl
generationContext tmpCtx(ctx);
tmpCtx.setMaxLineLength(ctx.getMaxLineLength() - 2);
m_name.encodeAndFold(ctx, os, pos, &pos,
forceEncode ? text::FORCE_ENCODING : 0);
m_name.encodeAndFold(
ctx, os, pos, &pos,
forceEncode ? text::FORCE_ENCODING : 0
);
os << ":";
++pos;
for (std::vector <shared_ptr <mailbox> >::const_iterator it = m_list.begin() ;
it != m_list.end() ; ++it)
{
if (it != m_list.begin())
{
it != m_list.end() ; ++it) {
if (it != m_list.begin()) {
os << ", ";
pos += 2;
}
else
{
} else {
os << " ";
++pos;
}
@ -188,13 +198,14 @@ void mailboxGroup::generateImpl
os << ";";
pos++;
if (newLinePos)
if (newLinePos) {
*newLinePos = pos;
}
}
void mailboxGroup::copyFrom(const component& other)
{
void mailboxGroup::copyFrom(const component& other) {
const mailboxGroup& source = dynamic_cast <const mailboxGroup&>(other);
m_name = source.m_name;
@ -202,114 +213,132 @@ void mailboxGroup::copyFrom(const component& other)
removeAllMailboxes();
for (std::vector <shared_ptr <mailbox> >::const_iterator it = source.m_list.begin() ;
it != source.m_list.end() ; ++it)
{
it != source.m_list.end() ; ++it) {
m_list.push_back(vmime::clone(*it));
}
}
shared_ptr <component> mailboxGroup::clone() const
{
shared_ptr <component> mailboxGroup::clone() const {
return make_shared <mailboxGroup>(*this);
}
mailboxGroup& mailboxGroup::operator=(const component& other)
{
mailboxGroup& mailboxGroup::operator=(const component& other) {
copyFrom(other);
return (*this);
return *this;
}
const text& mailboxGroup::getName() const
{
return (m_name);
const text& mailboxGroup::getName() const {
return m_name;
}
void mailboxGroup::setName(const text& name)
{
void mailboxGroup::setName(const text& name) {
m_name = name;
}
bool mailboxGroup::isGroup() const
{
return (true);
bool mailboxGroup::isGroup() const {
return true;
}
bool mailboxGroup::isEmpty() const
{
return (m_list.empty());
bool mailboxGroup::isEmpty() const {
return m_list.empty();
}
void mailboxGroup::appendMailbox(const shared_ptr <mailbox>& mbox)
{
void mailboxGroup::appendMailbox(const shared_ptr <mailbox>& mbox) {
m_list.push_back(mbox);
}
void mailboxGroup::insertMailboxBefore(const shared_ptr <mailbox>& beforeMailbox, const shared_ptr <mailbox>& mbox)
{
const std::vector <shared_ptr <mailbox> >::iterator it = std::find
(m_list.begin(), m_list.end(), beforeMailbox);
void mailboxGroup::insertMailboxBefore(
const shared_ptr <mailbox>& beforeMailbox,
const shared_ptr <mailbox>& mbox
) {
if (it == m_list.end())
const std::vector <shared_ptr <mailbox> >::iterator it =
std::find(m_list.begin(), m_list.end(), beforeMailbox);
if (it == m_list.end()) {
throw std::out_of_range("Invalid position");
}
m_list.insert(it, mbox);
}
void mailboxGroup::insertMailboxBefore(const size_t pos, const shared_ptr <mailbox>& mbox)
{
if (pos >= m_list.size())
void mailboxGroup::insertMailboxBefore(
const size_t pos,
const shared_ptr <mailbox>& mbox
) {
if (pos >= m_list.size()) {
throw std::out_of_range("Invalid position");
}
m_list.insert(m_list.begin() + pos, mbox);
}
void mailboxGroup::insertMailboxAfter(const shared_ptr <mailbox>& afterMailbox, const shared_ptr <mailbox>& mbox)
{
const std::vector <shared_ptr <mailbox> >::iterator it = std::find
(m_list.begin(), m_list.end(), afterMailbox);
void mailboxGroup::insertMailboxAfter(
const shared_ptr <mailbox>& afterMailbox,
const shared_ptr <mailbox>& mbox
) {
if (it == m_list.end())
const std::vector <shared_ptr <mailbox> >::iterator it =
std::find(m_list.begin(), m_list.end(), afterMailbox);
if (it == m_list.end()) {
throw std::out_of_range("Invalid position");
}
m_list.insert(it + 1, mbox);
}
void mailboxGroup::insertMailboxAfter(const size_t pos, const shared_ptr <mailbox>& mbox)
{
if (pos >= m_list.size())
void mailboxGroup::insertMailboxAfter(
const size_t pos,
const shared_ptr <mailbox>& mbox
) {
if (pos >= m_list.size()) {
throw std::out_of_range("Invalid position");
}
m_list.insert(m_list.begin() + pos + 1, mbox);
}
void mailboxGroup::removeMailbox(const shared_ptr <mailbox>& mbox)
{
const std::vector <shared_ptr <mailbox> >::iterator it = std::find
(m_list.begin(), m_list.end(), mbox);
void mailboxGroup::removeMailbox(const shared_ptr <mailbox>& mbox) {
if (it == m_list.end())
const std::vector <shared_ptr <mailbox> >::iterator it =
std::find(m_list.begin(), m_list.end(), mbox);
if (it == m_list.end()) {
throw std::out_of_range("Invalid position");
}
m_list.erase(it);
}
void mailboxGroup::removeMailbox(const size_t pos)
{
if (pos >= m_list.size())
void mailboxGroup::removeMailbox(const size_t pos) {
if (pos >= m_list.size()) {
throw std::out_of_range("Invalid position");
}
const std::vector <shared_ptr <mailbox> >::iterator it = m_list.begin() + pos;
@ -317,59 +346,59 @@ void mailboxGroup::removeMailbox(const size_t pos)
}
void mailboxGroup::removeAllMailboxes()
{
void mailboxGroup::removeAllMailboxes() {
m_list.clear();
}
size_t mailboxGroup::getMailboxCount() const
{
return (m_list.size());
size_t mailboxGroup::getMailboxCount() const {
return m_list.size();
}
shared_ptr <mailbox> mailboxGroup::getMailboxAt(const size_t pos)
{
return (m_list[pos]);
shared_ptr <mailbox> mailboxGroup::getMailboxAt(const size_t pos) {
return m_list[pos];
}
const shared_ptr <const mailbox> mailboxGroup::getMailboxAt(const size_t pos) const
{
return (m_list[pos]);
const shared_ptr <const mailbox> mailboxGroup::getMailboxAt(const size_t pos) const {
return m_list[pos];
}
const std::vector <shared_ptr <const mailbox> > mailboxGroup::getMailboxList() const
{
const std::vector <shared_ptr <const mailbox> > mailboxGroup::getMailboxList() const {
std::vector <shared_ptr <const mailbox> > list;
list.reserve(m_list.size());
for (std::vector <shared_ptr <mailbox> >::const_iterator it = m_list.begin() ;
it != m_list.end() ; ++it)
{
it != m_list.end() ; ++it) {
list.push_back(*it);
}
return (list);
return list;
}
const std::vector <shared_ptr <mailbox> > mailboxGroup::getMailboxList()
{
return (m_list);
const std::vector <shared_ptr <mailbox> > mailboxGroup::getMailboxList() {
return m_list;
}
const std::vector <shared_ptr <component> > mailboxGroup::getChildComponents()
{
const std::vector <shared_ptr <component> > mailboxGroup::getChildComponents() {
std::vector <shared_ptr <component> > list;
copy_vector(m_list, list);
return (list);
return list;
}

View File

@ -1,6 +1,6 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2013 Vincent Richard <vincent@vmime.org>
// Copyright (C) 2002 Vincent Richard <vincent@vmime.org>
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -30,15 +30,13 @@
#include "vmime/text.hpp"
namespace vmime
{
namespace vmime {
/** A group of mailboxes (basic type).
*/
class VMIME_EXPORT mailboxGroup : public address {
class VMIME_EXPORT mailboxGroup : public address
{
public:
mailboxGroup();
@ -78,7 +76,10 @@ public:
* @param mbox mailbox to insert
* @throw std::out_of_range if the mailbox is not in the list
*/
void insertMailboxBefore(const shared_ptr <mailbox>& beforeMailbox, const shared_ptr <mailbox>& mbox);
void insertMailboxBefore(
const shared_ptr <mailbox>& beforeMailbox,
const shared_ptr <mailbox>& mbox
);
/** Insert a new mailbox before the specified position.
*
@ -87,7 +88,10 @@ public:
* @param mbox mailbox to insert
* @throw std::out_of_range if the position is out of range
*/
void insertMailboxBefore(const size_t pos, const shared_ptr <mailbox>& mbox);
void insertMailboxBefore(
const size_t pos,
const shared_ptr <mailbox>& mbox
);
/** Insert a new mailbox after the specified mailbox.
*
@ -95,7 +99,10 @@ public:
* @param mbox mailbox to insert
* @throw std::out_of_range if the mailbox is not in the list
*/
void insertMailboxAfter(const shared_ptr <mailbox>& afterMailbox, const shared_ptr <mailbox>& mbox);
void insertMailboxAfter(
const shared_ptr <mailbox>& afterMailbox,
const shared_ptr <mailbox>& mbox
);
/** Insert a new mailbox after the specified position.
*
@ -103,7 +110,10 @@ public:
* @param mbox mailbox to insert
* @throw std::out_of_range if the position is out of range
*/
void insertMailboxAfter(const size_t pos, const shared_ptr <mailbox>& mbox);
void insertMailboxAfter(
const size_t pos,
const shared_ptr <mailbox>& mbox
);
/** Remove the specified mailbox from the list.
*
@ -173,18 +183,20 @@ private:
protected:
// Component parsing & assembling
void parseImpl
(const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL);
void parseImpl(
const parsingContext& ctx,
const string& buffer,
const size_t position,
const size_t end,
size_t* newPosition = NULL
);
void generateImpl
(const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL) const;
void generateImpl(
const generationContext& ctx,
utility::outputStream& os,
const size_t curLinePos = 0,
size_t* newLinePos = NULL
) const;
};

Some files were not shown because too many files have changed in this diff Show More