aboutsummaryrefslogtreecommitdiff
path: root/vmime-master/doc/book/basics.tex
diff options
context:
space:
mode:
Diffstat (limited to 'vmime-master/doc/book/basics.tex')
-rw-r--r--vmime-master/doc/book/basics.tex823
1 files changed, 823 insertions, 0 deletions
diff --git a/vmime-master/doc/book/basics.tex b/vmime-master/doc/book/basics.tex
new file mode 100644
index 0000000..94633ef
--- /dev/null
+++ b/vmime-master/doc/book/basics.tex
@@ -0,0 +1,823 @@
+\chapter{Basics}
+
+% ============================================================================
+\section{Reference counting}
+
+\subsection{Introduction} % --------------------------------------------------
+
+Since version 0.7.2cvs, VMime use smart pointers to simplify memory
+management. Smart pointers rely on
+RAII\footnote{Ressource Allocation is Initialisation} so that we do not need
+to bother with deleting an object (freeing memory) when it is not used
+anymore.
+
+There are two possibilities for owning a reference to an object. We can own a
+strong reference to an object: as long as we keep this reference, the object
+is not destroyed. Or we can own a weak reference to the object: the object can
+be destroyed if nobody owns a strong reference to it, in which case the weak
+reference becomes invalid.
+
+An object is destroyed as soon as the last strong reference to it is released.
+At the same tine, all weak references (if any) are automatically set to point
+to \vnull.
+
+In VMime, these two types of references are known as {\vcode vmime::shared\_ptr}
+and {\vcode vmime::weak\_ptr}, respectively.
+
+\vnote{since November 2013, we switched from an old, intrusive implementation
+of smart pointers to a more standard one: either Boost {\vcode shared\_ptr<>}
+implementation or standard C++ one if we are compiling in C++11. Here are the
+changes:
+
+{\vcode vmime::ref <>} is replaced with {\vcode vmime::shared\_ptr <>}
+
+{\vcode vmime::weak\_ref <>} is replaced with {\vcode vmime::weak\_ptr <>}
+
+{\vcode vmime::create <>} is replaced with {\vcode vmime::make\_shared <>}
+}
+
+\subsection{Instanciating reference-counted objects} % -----------------------
+
+In VMime, all objects that support reference counting inherit from the
+{\vcode vmime::object} class, which is responsible for
+incrementing/decrementing the counter and managing the object's life cycle.
+If you want to create a smart pointer to a new object instance, you should
+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 {
+
+public:
+
+ myObject(const vmime::string& name)
+ : m_name(name) {
+
+ }
+
+ void sayHello() {
+
+ std::cout << "Hello " << m_name << std::endl;
+ }
+
+private:
+
+ vmime::string m_name;
+};
+
+int main() {
+
+ vmime::shared_ptr <myObject> obj =
+ vmime::make_shared <myObject>("world");
+
+ obj->sayHello();
+
+ return 0;
+
+} // Here, 'obj' gets automatically destroyed
+\end{lstlisting}
+
+\subsection{Using smart pointers} % ------------------------------------------
+
+Smart pointers are copiable, assignable and comparable. You can use them like
+you would use normal ("raw") C++ pointers (eg. you can write
+\lstinline{!ptr, ptr != NULL, ptr->method(), *ptr}...).
+
+Type safety is also guaranteed, and you can type cast smart pointers using
+the {\vcode static\_cast()}, {\vcode dynamic\_cast()} and {\vcode const\_cast()}
+equivalents on {\vcode vmime::shared\_ptr} and {\vcode vmime::weak\_ptr} objects:
+
+\begin{lstlisting}[caption={Casting smart pointers}]
+class myBase : public vmime::object { }
+class myObject : public myBase { }
+
+vmime::shared_ptr <myObject> obj = vmime::make_shared <myObject>();
+
+// Implicit downcast
+vmime::shared_ptr <myBase> base = obj;
+
+// Explicit upcast
+vmime::shared_ptr <myObject> obj2 = vmime::dynamicCast <myObject>(base);
+\end{lstlisting}
+
+Weak references are used to resolve reference cycles (an object which refers
+directly or indirectly to itself). The following example illustrates a
+typical problem of reference counting:
+
+\begin{lstlisting}
+class parent : public vmime::object {
+
+public:
+
+ void createChild(vmime::shared_ptr <child> c) {
+
+ m_child = c;
+ }
+
+private:
+
+ vmime::shared_ptr <child> m_child;
+};
+
+class child : public vmime::object {
+
+public:
+
+ child(vmime::shared_ptr <parent> p)
+ : m_parent(p) {
+
+ }
+
+private:
+
+ vmime::shared_ptr <parent> m_parent;
+};
+
+int main() {
+
+ vmime::shared_ptr <parent> p = vmime::make_shared <parent>();
+ vmime::shared_ptr <child> c = vmime::make_shared <child>();
+
+ p->setChild(c);
+}
+\end{lstlisting}
+
+In this example, neither {\vcode p} nor {\vcode c} will be deleted when
+exiting {\vcode main()}. That's because {\vcode p} indirectly points to itself
+{\em via} {\vcode c}, and {\em vice versa}. The solution is to use a weak
+reference to the parent:
+
+\begin{lstlisting}
+vmime::weak_ptr <parent> m_parent;
+\end{lstlisting}
+
+The decision to make the parent or the child a weak reference is purely
+semantic, and it depends on the context and the relationships between the
+objects. Note that when the parent is deleted, the {\vcode m\_parent} member
+of the child points to \vnull.
+
+More information about reference counting can be found on
+Wikipedia\footnote{http://en.wikipedia.org/wiki/Reference\_counting}.
+
+% ============================================================================
+\section{Error handling}
+
+In VMime, error handling is exclusively based on exceptions, there is no error
+codes, or things like that.
+
+VMime code may throw exceptions in many different situations: an unexpected
+error occurred, an operation is not supported, etc. You should catch them if
+you want to report failures to the user. This is also useful when debugging
+your program.
+
+VMime exceptions support chaining: an exception can be encapsulated into
+another exception to hide implementation details. The function
+{\vcode exception::other()} returns the next exception in the chain,
+or \vnull.
+
+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) {
+
+ os << "* vmime::exceptions::" << e.name() << std::endl;
+ os << " what = " << e.what() << std::endl;
+
+ // Recursively print all encapsuled exceptions
+ if (e.other() != NULL) {
+ os << *e.other();
+ }
+
+ return os;
+}
+
+...
+
+try {
+
+ // ...some call to VMime...
+
+} catch (vmime::exception& e) {
+
+ std::cerr << e; // VMime exception
+
+} catch (std::exception& e) {
+
+ std::cerr << e.what(); // standard exception
+}
+\end{lstlisting}
+
+Read the source of {\vexample example6} if yo want to see a more complete
+example of using VMime exceptions (such as getting more detailed information
+by using specialized classes of {\vcode vmime::exception}).
+
+
+% ============================================================================
+\section{Basic objects}
+
+\subsection{The {\vcode component} class} % ----------------------------------
+
+In VMime, all the components of a message inherit from the same class
+{\vcode component}. This includes the message itself (classes {\vcode message}
+and {\vcode bodyPart}), the header, the header fields and the value of each
+header field, the body and all the parts in the message.
+
+The class component provide a common interface for parsing or generating all
+these components (methods {\vcode parse()} and {\vcode generate()}). It also
+provides additional functions to get some information about the parsing
+process or the structure (methods {\vcode getParsedOffset()},
+{\vcode getParsedLength()} and {\vcode getChildComponents()}).
+
+VMime also provides a set of classes corresponding to the basic types found
+in a message; for example a mailbox, a mailbox list, date/time information,
+media type, etc. They all inherit from {\vcode component} too.
+
+\subsection{Date and time} % -------------------------------------------------
+
+Date and time are used in several places in VMime, particularly in header
+fields (Date, Received, ...). VMime fully supports RFC-2822's date and time
+specification. The object {\vcode vmime::datetime} is used to manipulate date
+and time information, and to parse/generate it from/to RFC-2822 format.
+
+The following code snippet show various manners of using the
+{\vcode vmime::datetime} object:
+
+\begin{lstlisting}[caption={Using {\vcode vmime::datetime} object}]
+// Creating from string in RFC-2822 format
+vmime::datetime d1("Sat, 08 Oct 2005 14:07:52 +0200");
+
+// Creating from components
+vmime::datetime d2(
+ /* date */ 2005, vmime::datetime::OCTOBER, 8,
+ /* time */ 14, 7, 52,
+ /* zone */ vmime::datetime::GMT2
+);
+
+// Getting day of week
+const int dow = d2.getWeekDay(); // 'dow' should be datetime::SATURDAY
+\end{lstlisting}
+
+\subsection{Media type} % ----------------------------------------------------
+
+In MIME, the nature of the data contained in parts is identified using a
+media type. A general type (eg. \emph{image}) and a sub-type (eg. \emph{jpeg})
+are put together to form a media type (eg. \emph{image/jpeg}). This is also
+called the MIME type.
+
+There are a lot of media types officially registered, and vendor-specific
+types are possible (they start with ``x-'', eg.
+\emph{application/x-zip-compressed}).
+
+In VMime, the object {\vcode vmime::mediaType} represents a media type. There
+are also some constants for top-level types and sub-types in the
+{\vcode vmime::mediaTypes} namespace. For example, you can instanciate a new
+media type with:
+
+\begin{lstlisting}
+vmime::mediaType theType(
+ /* top-level type */ vmime::mediaTypes::IMAGE,
+ /* sub-type */ vmime::mediaTypes::IMAGE_JPEG
+);
+
+// theType.getType() is "image"
+// theType.getSubType() is "jpeg"
+// theType.generate() returns "image/jpeg"
+\end{lstlisting}
+
+For more information about media types, see
+RFC-2046\footnote{http://www.faqs.org/rfcs/rfc2046.html}.
+
+\subsection{Mailbox and mailbox groups} % ------------------------------------
+
+VMime provides several objects for working with mailboxes and addresses.
+
+The {\vcode vmime::address} class is an abstract type for representing an
+address: it can be either a mailbox (type {\vcode vmime::mailbox}) or a
+mailbox group (type {\vcode vmime::mailboxGroup}). A mailbox is composed of
+an email address (mandatory) and possibly a name. A mailbox group is simply
+a named list of mailboxes (see Figure \ref{uml_addr_mbox_mboxgroup}).
+
+\begin{lstlisting}[caption={Using mailboxes and mailbox groups}]
+vmime::shared_ptr <vmime::mailbox> mbox1 = vmime::make_shared <vmime::mailbox>
+ (/* name */ vmime::text("John Doe"), /* email */ "john.doe@acme.com");
+vmime::shared_ptr <vmime::mailbox> mbox2 = vmime::make_shared <vmime::mailbox>
+ (/* no name, email only */ "bill@acme.com");
+
+vmime::shared_ptr <vmime::mailboxGroup> grp = vmime::make_shared <vmime::mailboxGroup>();
+grp->appendMailbox(mbox1);
+grp->appendMailbox(mbox2);
+\end{lstlisting}
+
+\begin{figure}[ht!]
+ \center\includegraphics[width=0.7\textwidth]
+ {images/address-mailbox-mailboxgroup.png}\endcenter
+ \caption{Diagram for address-related classes}
+ \label{uml_addr_mbox_mboxgroup}
+\end{figure}
+
+
+% ============================================================================
+\section{Message, body parts and header}
+
+\subsection{Introduction to MIME messages} % ---------------------------------
+
+A MIME message is a recursive structure in which each part can contains one
+or more parts (or \emph{entities}). Each part is composed of a header and
+a body (actual contents). Figure \ref{uml_msg_body_header} shows how this
+model is implemented in VMime, and all classes that take part in it.
+
+\begin{figure}
+ \center\includegraphics[width=1.0\textwidth]
+ {images/message-body-header.png}\endcenter
+ \caption{Overall structure of MIME messages}
+ \label{uml_msg_body_header}
+\end{figure}
+
+
+\subsection{Header and header fields} % --------------------------------------
+
+\subsubsection{Standard header fields} % .....................................
+
+Header fields carry information about a message (or a part) and its contents.
+Each header field has a name and a value. All types that can be used as a
+field value inherit from the {\vcode headerFieldValue} class.
+
+You cannot instanciate header fields directly using their constructor.
+Instead, you should use the {\vcode headerFieldFactory} object. This ensures
+the right field type and value type is used for the specified field name.
+For more information about how to use header fields and the factory, see
+section \ref{msg-building-simple-message}.
+
+Some standard fields are officially registered and have their value type
+specified in a RFC. Table \ref{standard-fields} lists all the fields
+registered by default in VMime and the value type they contains.
+
+By default, all unregistered fields have a value of type {\vcode text}.
+
+\begin{table}[!ht]
+\begin{center}
+\noindent\begin{tabularx}{0.85\textwidth}{|X|X|}
+\hline
+ {\bf Field Name} &
+ {\bf Value Type} \\
+\hline
+\hline
+From & mailbox \\
+To & addressList \\
+Cc & addressList \\
+Bcc & addressList \\
+Sender & mailbox \\
+Date & datetime \\
+Received & relay \\
+Subject & text \\
+Reply-To & mailbox \\
+Delivered-To & mailbox \\
+Organization & text \\
+Return-Path & path \\
+Mime-Version & text \\
+Content-Type & mediaType \\
+Content-Transfer-Encoding & encoding \\
+Content-Description & text \\
+Content-Disposition & contentDisposition \\
+Content-Id & messageId \\
+Content-Location & text \\
+Message-Id & messageId \\
+In-Reply-To & messageIdSequence \\
+References & messageIdSequence \\
+Original-Message-Id & messageId \\
+Disposition & disposition \\
+Disposition-Notification-To & mailboxList \\
+\hline
+\end{tabularx}
+\end{center}
+\label{standard-fields}
+\caption{Standard fields and their types}
+\end{table}
+
+
+\subsubsection{Parameterized fields} % .......................................
+
+In addition to a value, some header fields can contain one or more
+\emph{name=value} couples which are called \emph{parameters}. For example,
+this is used in the \emph{Content-Type} field to give more information about
+the content:
+
+\begin{verbatim}
+ Content-Type: text/plain; charset="utf-8"
+\end{verbatim}
+
+Fields that support parameters inherit from the
+{\vcode parameterizedHeaderField} class which provides methods to deal with
+these parameters: {\vcode appendParameter()}, {\vcode getParameterAt()}...
+
+A parameter is identified by a name (eg. \emph{charset}) and associated to
+a value of type {\vcode vmime::text}. Parameters provide helper functions to
+convert automatically from basic types to text, and \emph{vice versa}. The
+following example illustrates it:
+
+\begin{lstlisting}[caption={Getting and setting parameter value in fields}]
+vmime::shared_ptr <vmime::parameterizedField> field =
+ header->findField <vmime::parameterizedField>("X-Field-That-Contains-Parameters");
+
+// Use setValue() to convert from a basic type to 'text'
+vmime::shared_ptr <vmime::parameter> prm = field->getParameter("my-date-param");
+prm->setValue(vmime::datetime::now());
+
+// Use getValueAs() to convert from 'text' to a basic type
+prm = field->getParameter("my-charset-param");
+const vmime::charset ch = prm->getValueAs <vmime::charset>();
+\end{lstlisting}
+
+Some fields provide easy access to their standard parameters (see
+Table \ref{standard-prm-fields}). This avoids finding the parameter and
+\emph{dynamic-casting} its value to the right type. The following code
+illustrates how to use it:
+
+\begin{lstlisting}
+vmime::shared_ptr <vmime::contentTypeField> field =
+ header->getField <vmime::contentTypeField>(vmime::fields::CONTENT_TYPE);
+
+// 1. First solution: the "hard" way
+vmime::shared_ptr <vmime::parameter> prm = field->findParameter("charset");
+const charset ch1 = prm->getValueAs <vmime::charset>();
+
+// 2. Second solution: the simple way
+const charset ch2 = field->getCharset();
+\end{lstlisting}
+
+\vnote{In both cases, an exception {\vcode no\_such\_parameter} can be
+thrown if the parameter does not exist, so be sure to catch it.}
+
+\begin{table}[ht!]
+\begin{center}
+\noindent\begin{tabularx}{0.85\textwidth}{|l|l|X|}
+\hline
+ {\bf Field Name} &
+ {\bf Field Type} &
+ {\bf Parameters} \\
+\hline
+\hline
+Content-Type & contentTypeField & boundary, charset, report-type \\
+\hline
+Content-Disposition & contentDispositionField & creation-date,
+modification-date, read-date, filename, size \\
+\hline
+\end{tabularx}
+\end{center}
+\label{standard-prm-fields}
+\caption{Standard parameterized fields}
+\end{table}
+
+
+
+% ============================================================================
+\section{Streams}
+
+\subsection{Streams and stream adapters} % -----------------------------------
+
+Streams permit reading or writing data whatever the underlying system is:
+a file on a hard disk, a socket connected to a remote service...
+
+There are two types of streams: input streams (from which you can read data)
+and output streams (in which you can write data). Some adapters are provided
+for compatibility and convenience, for example:
+
+\begin{itemize}
+\item {\vcode inputStreamAdapter} and {\vcode outputStreamAdapter}: allow
+to use standard C++ iostreams with VMime;
+\item {\vcode inputStreamStringAdapter} and
+{\vcode outputStreamStringAdapter}: use a {\vcode vmime::string} object to
+read/write data.
+\end{itemize}
+
+The following example shows two ways of writing the current date to the
+standard output, using stream adapters:
+
+\begin{lstlisting}[caption={Using stream adapters}]
+// Get current date and time
+const vmime::datetime date = vmime::datetime::now();
+
+// 1. Using outputStreamAdapter
+vmime::utility::outputStreamAdapter out(std::cout);
+
+std::cout << "Current date is: ";
+date.generate(out);
+std::cout << std::endl;
+
+// 2. Using outputStreamStringAdapter
+vmime::string dateStr;
+vmime::utility::outputStreamStringAdapter outStr(dateStr);
+
+date.generate(outStr);
+
+std::cout << "Current date is: " << dateStr << std::endl;
+\end{lstlisting}
+
+
+\subsection{Stream filters} % ------------------------------------------------
+
+Input and output streams can be filtered to perform inline conversions (for
+example, there is a filter to convert ``{\textbackslash}r{\textbackslash}n''
+sequences to ``{\textbackslash}n''). They inherit from
+{\vcode vmime::utility::filteredInputStream} or
+{\vcode vmime::utility::filteredOutputStream} and are used like adapters (some
+filters also accept parameters; read the documentation).
+
+The most useful filter in VMime (and probably the only one you will need) is
+the {\vcode charsetFilteredOutputStream}, which performs inline conversion
+of charsets. See \ref{section_charsets} to know how to use it.
+
+\vnote{After you have finished to use a filtered output stream, it is
+important to call {\vcode flush()} on it to flush the internal buffer.
+If {\vcode flush()} is not called, not all data may be written to the
+underlying stream.}
+
+
+% ============================================================================
+\section{Content handlers}
+
+\subsection{Introduction} % --------------------------------------------------
+
+Content handlers are an abstraction for data sources. They are currently used
+when some data need to be stored for later use (eg. body part contents,
+attachment data, ...). Data can be stored encoded or unencoded (for more
+information about encodings, see \ref{section_encodings}).
+
+\subsection{Extracting data from content handlers} % -------------------------
+
+You can extract data in a content handler using the {\vcode extract()} method
+(which automatically decodes data if encoded) or {\vcode extractRaw()} (which
+extracts data without perfoming any decoding).
+
+The following example shows how to extract the body text from a message, and
+writing it to the standard output with charset conversion:
+
+\begin{lstlisting}[caption={Using content handlers to extract body text from
+a message}]
+// Suppose we already have a message
+vmime::shared_ptr <vmime::message> msg;
+
+// Obtains a reference to the body contents
+vmime::shared_ptr <vmime::body> body = msg->getBody();
+vmime::shared_ptr <vmime::contentHandler> cts = body->getContents();
+
+vmime::utility::outputStreamAdapter out(std::cout);
+cts->extract(out);
+\end{lstlisting}
+
+\vnote{The body contents is extracted ``as is''. No charset conversion is
+performed. See \ref{section_charsets} to know more about conversion between
+charsets.}
+
+
+\subsection{Creating content handlers} % -------------------------------------
+
+When you are building a message, you may need to instanciate content handlers
+if you want to set the contents of a body part. The following code snippet
+shows how to set the body text of a part from a string:
+
+\begin{lstlisting}[caption={Setting the contents of a body part}]
+vmime::shared_ptr <vmime::bodyPart> part; // suppose we have a body part
+
+// Create a new content handler from a string
+vmime::shared_ptr <vmime::contentHandler> cth =
+ vmime::make_shared <vmime::stringContentHandler>("Put body contents here");
+
+// Set the contents
+part->getBody()->setContents(cth);
+\end{lstlisting}
+
+Content handlers are also used when creating attachments. The following
+example illustrates how to create an attachment from a file:
+
+\begin{lstlisting}[caption={Creating an attachment from a file}]
+// Create a stream from a file
+std::ifstream* fileStream = new std::ifstream();
+
+fileStream->open("/home/vincent/paris.jpg", std::ios::binary);
+
+if (!*fileStream) {
+ // handle error
+}
+
+vmime::shared_ptr <utility::stream> dataStream =
+ vmime::make_shared <vmime::utility::inputStreamPointerAdapter>(fileStream);
+
+ // NOTE: 'fileStream' will be automatically deleted
+ // when 'dataStream' is deleted
+
+// Create a new content handler
+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")
+);
+\end{lstlisting}
+
+You will see later that the {\vcode vmime::fileAttachment} class already
+encapsulates all the mechanics to create an attachment from a file.
+
+
+% ============================================================================
+\section{Character sets, charsets and conversions\label{section_charsets}}
+
+Quoting from RFC-2278: \emph{`` The term 'charset' is used to refer to a
+method of converting a sequence of octets into a sequence of characters.''}
+
+With the {\vcode vmime::charset} object, VMime supports conversion between
+charsets using the {\em iconv} library, which is available on almost all
+existing platforms. See {\vcode vmime::charset} and
+{\vcode vmime::charsetConverter} in the class documentation to know more
+about charset conversion.
+
+The following example shows how to convert data in one charset to another
+charset. The data is extracted from the body of a message and converted
+to UTF-8 charset:
+
+\begin{lstlisting}[caption={Extracting and converting body contents to a
+specified charset}]
+vmime::shared_ptr <vmime::message> msg; // we have a message
+
+// Obtain the content handler first
+vmime::shared_ptr <vmime::body> body = msg->getBody();
+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(),
+ /* dest charset */ vmime::charset("utf-8"),
+ /* dest stream */ out
+);
+
+cth->extract(fout);
+
+fout.flush(); // Very important!
+\end{lstlisting}
+
+
+% ============================================================================
+\section{Non-ASCII text in header fields}
+
+MIME standard defines methods\footnote{See RFC-2047: Message Header Extensions
+for Non-ASCII Text} for dealing with data which is not 7-bit only (ie. the
+ASCII character set), in particular in header fields. For example, the field
+``Subject:'' use this data type.
+
+VMime is fully compatible with RFC-2047 and provides two objects for
+manipulating 8-bit data: {\vcode vmime::text} and {\vcode vmime::word}. A word
+represents textual information encoded in a specified charset. A text is
+composed of one or more words.
+
+RFC-2047 describes the process of encoding 8-bit data into a 7-bit form;
+basically, it relies on Base64 and Quoted-Printable encoding. Hopefully, all
+the encoding/decoding process is done internally by VMime, so creating text
+objects is fairly simple:
+
+\begin{lstlisting}[caption={Creating \vcode{vmime::text} objects}]
+vmime::string inText = "Linux dans un téléphone mobile";
+vmime::charset inCharset = "utf-8";
+
+vmime::text outText;
+outText.createFromString(inText, inCharset);
+
+// 'outText' now contains 3 words:
+// . <us-ascii> "Linux dans un "
+// . <utf-8> "téléphone "
+// . <us-ascii> "mobile"
+
+vmime::shared_ptr <vmime::header> header = myMessage->getHeader();
+header->Subject()->setValue(outText);
+\end{lstlisting}
+
+In general, you will not need to decode RFC-2047-encoded data as the process
+is totally transparent in VMime. If you really have to, you can use the
+{\vcode vmime::text::decodeAndUnfold()} static method to create a text object
+from encoded data.
+
+For example, say you have the following encoded data:
+
+\begin{verbatim}
+ Linux dans un =?UTF-8?B?dMOpbMOpcGhvbmUgbW9iaWxl?=
+\end{verbatim}
+
+You can simply decode it using the following code:
+
+\begin{lstlisting}[caption={Decoding RFC-2047-encoded data}]
+vmime::string inData =
+ "Linux dans un =?UTF-8?B?dMOpbMOpcGhvbmUgbW9iaWxl?=";
+
+vmime::text outText;
+vmime::text::decodeAndUnfold(inData, &outText);
+\end{lstlisting}
+
+{\vcode vmime::text} also provides a function to convert all the words to
+another charset in a single call. The following example shows how to convert
+text stored in the Subject field of a message:
+
+\begin{lstlisting}[caption={Converting data in a {\vcode vmime::text} to a
+specified charset}]
+vmime::shared_ptr <vmime::message> msg; // we have a message
+
+vmime::text subject = msg->getHeader()->Subject()->getValue();
+
+const vmime::string subjectText =
+ subject.getConvertedText(vmime::charset("utf-8"));
+
+// 'subjectText' now contains the subject in UTF-8 encoding
+\end{lstlisting}
+
+
+% ============================================================================
+\section{Encodings\label{section_encodings}}
+
+\subsection{Introduction} % --------------------------------------------------
+
+The MIME standard defines a certain number of encodings to allow data
+to be safely transmitted from one peer to another. VMime provides
+data encoding and decoding using the {\vcode vmime::utility::encoder::encoder} object.
+
+You should not need to use encoders directly, as all encoding/decoding
+process is handled internally by the library, but it is good to know
+they exist and how they work.
+
+\subsection{Using encoders} % ------------------------------------------------
+
+You can create an instance of an encoder using the 'vmime::utility::encoder::encoderFactory'
+object, giving the encoding name ({\it base64}, {\it quoted-printable}, ...).
+The following example creates an instance of the Base64 encoder to encode
+some data:
+
+\begin{lstlisting}[caption={A simple example of using an encoder}]
+vmime::shared_ptr <vmime::utility::encoder::encoder> enc =
+ vmime::utility::encoder::encoderFactory::getInstance()->create("base64");
+
+vmime::string inString("Some data to encode");
+vmime::utility::inputStreamStringAdapter in(inString);
+
+vmime::string outString;
+vmime::utility::outputStreamStringAdapter out(outString);
+
+enc->encode(in, out);
+
+std::cout << "Encoded data is:" << outString << std::endl;
+\end{lstlisting}
+
+\subsection{Enumerating available encoders} % --------------------------------
+
+The behaviour of the encoders can be configured using properties. However,
+not all encoders support properties. The following example\footnote{This is
+an excerpt from {\vexample example6}} enumerates available encoders and the
+supported properties for each of them:
+
+\begin{lstlisting}[caption={Enumerating encoders and their properties}]
+vmime::shared_ptr <vmime::utility::encoder::encoderFactory> ef =
+ vmime::utility::encoder::encoderFactory::getInstance();
+
+std::cout << "Available encoders:" << std::endl;
+
+for (int i = 0 ; i < ef->getEncoderCount() ; ++i) {
+
+ // Output encoder name
+ vmime::shared_ptr <const vmime::utility::encoder::encoderFactory::registeredEncoder>
+ enc = ef->getEncoderAt(i);
+
+ std::cout << " * " << enc->getName() << std::endl;
+
+ // Create an instance of the encoder to get its properties
+ vmime::shared_ptr <vmime::utility::encoder::encoder> e = enc->create();
+
+ std::vector <vmime::string> props = e->getAvailableProperties();
+ std::vector <vmime::string>::const_iterator it;
+
+ for (it = props.begin() ; it != props.end() ; ++it) {
+ std::cout << " - " << *it << std::endl;
+ }
+\end{lstlisting}
+
+
+% ============================================================================
+\section{Progress listeners}
+
+Progress listeners are used with objects that can notify you about the state
+of progress when they are performing an operation.
+
+The {\vcode vmime::utility::progressListener} interface is rather simple:
+
+\begin{lstlisting}
+void start(const int predictedTotal);
+void progress(const int current, const int currentTotal);
+void stop(const int total);
+\end{lstlisting}
+
+{\vcode start()} and {\vcode stop()} are called at the beginning and the end
+of the operation, respectively. {\vcode progress()} is called each time the
+status of progress changes (eg. a chunk of data has been processed). There is
+no unit specified for the values passed in argument. It depends on the
+notifier: it can be bytes, percent, number of messages...