Code style and clarity.
This commit is contained in:
parent
71a0fa4b26
commit
b55bdc9c0b
94
HACKING
94
HACKING
@ -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.
|
||||
|
||||
|
@ -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}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
131
doc/book/msg.tex
131
doc/book/msg.tex
@ -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
|
||||
|
144
doc/book/net.tex
144
doc/book/net.tex
@ -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}
|
||||
|
@ -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>();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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>();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
@ -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()));
|
||||
}
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
@ -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("?") {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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];
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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> >();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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> >();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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 {
|
||||
|
||||
|
||||
//
|
||||
|
@ -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
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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')
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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),
|
||||
®isterer <headerField, T>::creator));
|
||||
void registerField(const string& name) {
|
||||
|
||||
m_nameMap.insert(
|
||||
NameMap::value_type(
|
||||
utility::stringUtils::toLower(name),
|
||||
®isterer <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 = ®isterer <headerFieldValue, T>::creator;
|
||||
vi.checkTypeFunc = ®isterer <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.
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 <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
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
|
@ -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> >();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user