1\chapter{Basics}
2
3% ============================================================================
4\section{Reference counting}
5
6\subsection{Introduction} % --------------------------------------------------
7
8Since version 0.7.2cvs, VMime use smart pointers to simplify memory
9management. Smart pointers rely on
10RAII\footnote{Ressource Allocation is Initialisation} so that we do not need
11to bother with deleting an object (freeing memory) when it is not used
12anymore.
13
14There are two possibilities for owning a reference to an object. We can own a
15strong reference to an object: as long as we keep this reference, the object
16is not destroyed. Or we can own a weak reference to the object: the object can
17be destroyed if nobody owns a strong reference to it, in which case the weak
18reference becomes invalid.
19
20An object is destroyed as soon as the last strong reference to it is released.
21At the same tine, all weak references (if any) are automatically set to point
22to \vnull.
23
24In VMime, these two types of references are known as {\vcode vmime::shared\_ptr}
25and {\vcode vmime::weak\_ptr}, respectively.
26
27\vnote{since November 2013, we switched from an old, intrusive implementation
28of smart pointers to a more standard one: either Boost {\vcode shared\_ptr<>}
29implementation or standard C++ one if we are compiling in C++11. Here are the
30changes:
31
32{\vcode vmime::ref <>} is replaced with {\vcode vmime::shared\_ptr <>}
33
34{\vcode vmime::weak\_ref <>} is replaced with {\vcode vmime::weak\_ptr <>}
35
36{\vcode vmime::create <>} is replaced with {\vcode vmime::make\_shared <>}
37}
38
39\subsection{Instanciating reference-counted objects} % -----------------------
40
41In VMime, all objects that support reference counting inherit from the
42{\vcode vmime::object} class, which is responsible for
43incrementing/decrementing the counter and managing the object's life cycle.
44If you want to create a smart pointer to a new object instance, you should
45use the function {\vcode vmime::make\_shared} instead of the {\vcode new}
46operator.
47
48\begin{lstlisting}[caption={Smarts pointers and creating objects}]
49class myObject : public vmime::object
50{
51public:
52
53   myObject(const vmime::string& name)
54      : m_name(name)
55   {
56   }
57
58   void sayHello()
59   {
60      std::cout << "Hello " << m_name << std::endl;
61   }
62
63private:
64
65   vmime::string m_name;
66};
67
68int main()
69{
70   vmime::shared_ptr <myObject> obj =
71      vmime::make_shared <myObject>("world");
72
73   obj->sayHello();
74
75   return 0;
76
77} // Here, 'obj' gets automatically destroyed
78\end{lstlisting}
79
80\subsection{Using smart pointers} % ------------------------------------------
81
82Smart pointers are copiable, assignable and comparable. You can use them like
83you would use normal ("raw") C++ pointers (eg. you can write
84\lstinline{!ptr, ptr != NULL, ptr->method(), *ptr}...).
85
86Type safety is also guaranteed, and you can type cast smart pointers using
87the {\vcode static\_cast()}, {\vcode dynamic\_cast()} and {\vcode const\_cast()}
88equivalents on {\vcode vmime::shared\_ptr} and {\vcode vmime::weak\_ptr} objects:
89
90\begin{lstlisting}[caption={Casting smart pointers}]
91class myBase : public vmime::object { }
92class myObject : public myBase { }
93
94vmime::shared_ptr <myObject> obj = vmime::make_shared <myObject>();
95
96// Implicit downcast
97vmime::shared_ptr <myBase> base = obj;
98
99// Explicit upcast
100vmime::shared_ptr <myObject> obj2 = vmime::dynamicCast <myObject>(base);
101\end{lstlisting}
102
103Weak references are used to resolve reference cycles (an object which refers
104directly or indirectly to itself). The following example illustrates a
105typical problem of reference counting:
106
107\begin{lstlisting}
108class parent : public vmime::object
109{
110public:
111
112   void createChild(vmime::shared_ptr <child> c)
113   {
114      m_child = c;
115   }
116
117private:
118
119   vmime::shared_ptr <child> m_child;
120};
121
122class child : public vmime::object
123{
124public:
125
126   child(vmime::shared_ptr <parent> p)
127      : m_parent(p)
128   {
129   }
130
131private:
132
133   vmime::shared_ptr <parent> m_parent;
134};
135
136int main()
137{
138   vmime::shared_ptr <parent> p = vmime::make_shared <parent>();
139   vmime::shared_ptr <child> c = vmime::make_shared <child>();
140
141   p->setChild(c);
142}
143\end{lstlisting}
144
145In this example, neither {\vcode p} nor {\vcode c} will be deleted when
146exiting {\vcode main()}. That's because {\vcode p} indirectly points to itself
147{\em via} {\vcode c}, and {\em vice versa}. The solution is to use a weak
148reference to the parent:
149
150\begin{lstlisting}
151vmime::weak_ptr <parent> m_parent;
152\end{lstlisting}
153
154The decision to make the parent or the child a weak reference is purely
155semantic, and it depends on the context and the relationships between the
156objects. Note that when the parent is deleted, the {\vcode m\_parent} member
157of the child points to \vnull.
158
159More information about reference counting can be found on
160Wikipedia\footnote{http://en.wikipedia.org/wiki/Reference\_counting}.
161
162% ============================================================================
163\section{Error handling}
164
165In VMime, error handling is exclusively based on exceptions, there is no error
166codes, or things like that.
167
168VMime code may throw exceptions in many different situations: an unexpected
169error occured, an operation is not supported, etc. You should catch them if
170you want to report failures to the user. This is also useful when debugging
171your program.
172
173VMime exceptions support chaining: an exception can be encapsulated into
174another exception to hide implementation details. The function
175{\vcode exception::other()} returns the next exception in the chain,
176or \vnull.
177
178Following is an example code for catching VMime exceptions and writing error
179messages to the console:
180
181\begin{lstlisting}[caption={Catching VMime exceptions}]
182std::ostream& operator<<(std::ostream& os, const vmime::exception& e)
183{
184   os << "* vmime::exceptions::" << e.name() << std::endl;
185   os << "    what = " << e.what() << std::endl;
186
187   // Recursively print all encapsuled exceptions
188   if (e.other() != NULL)
189      os << *e.other();
190
191   return os;
192}
193
194...
195
196try
197{
198   // ...some call to VMime...
199}
200catch (vmime::exception& e)
201{
202   std::cerr << e;         // VMime exception
203}
204catch (std::exception& e)
205{
206   std::cerr << e.what();  // standard exception
207}
208\end{lstlisting}
209
210Read the source of {\vexample example6} if yo want to see a more complete
211example of using VMime exceptions (such as getting more detailed information
212by using specialized classes of {\vcode vmime::exception}).
213
214
215% ============================================================================
216\section{Basic objects}
217
218\subsection{The {\vcode component} class} % ----------------------------------
219
220In VMime, all the components of a message inherit from the same class
221{\vcode component}. This includes the message itself (classes {\vcode message}
222and {\vcode bodyPart}), the header, the header fields and the value of each
223header field, the body and all the parts in the message.
224
225The class component provide a common interface for parsing or generating all
226these components (methods {\vcode parse()} and {\vcode generate()}). It also
227provides additional functions to get some information about the parsing
228process or the structure (methods {\vcode getParsedOffset()},
229{\vcode getParsedLength()} and {\vcode getChildComponents()}).
230
231VMime also provides a set of classes corresponding to the basic types found
232in a message; for example a mailbox, a mailbox list, date/time information,
233media type, etc. They all inherit from {\vcode component} too.
234
235\subsection{Date and time} % -------------------------------------------------
236
237Date and time are used in several places in VMime, particularly in header
238fields (Date, Received, ...). VMime fully supports RFC-2822's date and time
239specification. The object {\vcode vmime::datetime} is used to manipulate date
240and time information, and to parse/generate it from/to RFC-2822 format.
241
242The following code snippet show various manners of using the
243{\vcode vmime::datetime} object:
244
245\begin{lstlisting}[caption={Using {\vcode vmime::datetime} object}]
246// Creating from string in RFC-2822 format
247vmime::datetime d1("Sat, 08 Oct 2005 14:07:52 +0200");
248
249// Creating from components
250vmime::datetime d2(
251   /* date */ 2005, vmime::datetime::OCTOBER, 8,
252   /* time */ 14, 7, 52,
253   /* zone */ vmime::datetime::GMT2);
254
255// Getting day of week
256const int dow = d2.getWeekDay();  // 'dow' should be datetime::SATURDAY
257\end{lstlisting}
258
259\subsection{Media type} % ----------------------------------------------------
260
261In MIME, the nature of the data contained in parts is identified using a
262media type. A general type (eg. \emph{image}) and a sub-type (eg. \emph{jpeg})
263are put together to form a media type (eg. \emph{image/jpeg}). This is also
264called the MIME type.
265
266There are a lot of media types officially registered, and vendor-specific
267types are possible (they start with ``x-'', eg.
268\emph{application/x-zip-compressed}).
269
270In VMime, the object {\vcode vmime::mediaType} represents a media type. There
271are also some constants for top-level types and sub-types in the
272{\vcode vmime::mediaTypes} namespace. For example, you can instanciate a new
273media type with:
274
275\begin{lstlisting}
276vmime::mediaType theType(
277   /* top-level type */ vmime::mediaTypes::IMAGE,
278   /* sub-type */       vmime::mediaTypes::IMAGE_JPEG);
279
280// theType.getType() is "image"
281// theType.getSubType() is "jpeg"
282// theType.generate() returns "image/jpeg"
283\end{lstlisting}
284
285For more information about media types, see
286RFC-2046\footnote{http://www.faqs.org/rfcs/rfc2046.html}.
287
288\subsection{Mailbox and mailbox groups} % ------------------------------------
289
290VMime provides several objects for working with mailboxes and addresses.
291
292The {\vcode vmime::address} class is an abstract type for representing an
293address: it can be either a mailbox (type {\vcode vmime::mailbox}) or a
294mailbox group (type {\vcode vmime::mailboxGroup}). A mailbox is composed of
295an email address (mandatory) and possibly a name. A mailbox group is simply
296a named list of mailboxes (see Figure \ref{uml_addr_mbox_mboxgroup}).
297
298\begin{lstlisting}[caption={Using mailboxes and mailbox groups}]
299vmime::shared_ptr <vmime::mailbox> mbox1 = vmime::make_shared <vmime::mailbox>
300    (/* name */ vmime::text("John Doe"), /* email */ "john.doe@acme.com");
301vmime::shared_ptr <vmime::mailbox> mbox2 = vmime::make_shared <vmime::mailbox>
302    (/* no name, email only */ "bill@acme.com");
303
304vmime::shared_ptr <vmime::mailboxGroup> grp = vmime::make_shared <vmime::mailboxGroup>();
305grp->appendMailbox(mbox1);
306grp->appendMailbox(mbox2);
307\end{lstlisting}
308
309\begin{figure}[ht!]
310	\center\includegraphics[width=0.7\textwidth]
311		{images/address-mailbox-mailboxgroup.png}\endcenter
312	\caption{Diagram for address-related classes}
313	\label{uml_addr_mbox_mboxgroup}
314\end{figure}
315
316
317% ============================================================================
318\section{Message, body parts and header}
319
320\subsection{Introduction to MIME messages} % ---------------------------------
321
322A MIME message is a recursive structure in which each part can contains one
323or more parts (or \emph{entities}). Each part is composed of a header and
324a body (actual contents). Figure \ref{uml_msg_body_header} shows how this
325model is implemented in VMime, and all classes that take part in it.
326
327\begin{figure}
328	\center\includegraphics[width=1.0\textwidth]
329		{images/message-body-header.png}\endcenter
330	\caption{Overall structure of MIME messages}
331	\label{uml_msg_body_header}
332\end{figure}
333
334
335\subsection{Header and header fields} % --------------------------------------
336
337\subsubsection{Standard header fields} % .....................................
338
339Header fields carry information about a message (or a part) and its contents.
340Each header field has a name and a value. All types that can be used as a
341field value inherit from the {\vcode headerFieldValue} class.
342
343You cannot instanciate header fields directly using their constructor.
344Instead, you should use the {\vcode headerFieldFactory} object. This ensures
345the right field type and value type is used for the specified field name.
346For more information about how to use header fields and the factory, see
347section \ref{msg-building-simple-message}.
348
349Some standard fields are officially registered and have their value type
350specified in a RFC. Table \ref{standard-fields} lists all the fields
351registered by default in VMime and the value type they contains.
352
353By default, all unregistered fields have a value of type {\vcode text}.
354
355\begin{table}[!ht]
356\begin{center}
357\noindent\begin{tabularx}{0.85\textwidth}{|X|X|}
358\hline
359	{\bf Field Name} &
360	{\bf Value Type} \\
361\hline
362\hline
363From & mailbox \\
364To & addressList \\
365Cc & addressList \\
366Bcc & addressList \\
367Sender & mailbox \\
368Date & datetime \\
369Received & relay \\
370Subject & text \\
371Reply-To & mailbox \\
372Delivered-To & mailbox \\
373Organization & text \\
374Return-Path & path \\
375Mime-Version & text \\
376Content-Type & mediaType \\
377Content-Transfer-Encoding & encoding \\
378Content-Description & text \\
379Content-Disposition & contentDisposition \\
380Content-Id & messageId \\
381Content-Location & text \\
382Message-Id & messageId \\
383In-Reply-To & messageIdSequence \\
384References & messageIdSequence \\
385Original-Message-Id & messageId \\
386Disposition & disposition \\
387Disposition-Notification-To & mailboxList \\
388\hline
389\end{tabularx}
390\end{center}
391\label{standard-fields}
392\caption{Standard fields and their types}
393\end{table}
394
395
396\subsubsection{Parameterized fields} % .......................................
397
398In addition to a value, some header fields can contain one or more
399\emph{name=value} couples which are called \emph{parameters}. For example,
400this is used in the \emph{Content-Type} field to give more information about
401the content:
402
403\begin{verbatim}
404   Content-Type: text/plain; charset="utf-8"
405\end{verbatim}
406
407Fields that support parameters inherit from the
408{\vcode parameterizedHeaderField} class which provides methods to deal with
409these parameters: {\vcode appendParameter()}, {\vcode getParameterAt()}...
410
411A parameter is identified by a name (eg. \emph{charset}) and associated to
412a value of type {\vcode vmime::text}. Parameters provide helper functions to
413convert automatically from basic types to text, and \emph{vice versa}. The
414following example illustrates it:
415
416\begin{lstlisting}[caption={Getting and setting parameter value in fields}]
417vmime::shared_ptr <vmime::parameterizedField> field =
418   header->findField <vmime::parameterizedField>("X-Field-That-Contains-Parameters");
419
420// Use setValue() to convert from a basic type to 'text'
421vmime::shared_ptr <vmime::parameter> prm = field->getParameter("my-date-param");
422prm->setValue(vmime::datetime::now());
423
424// Use getValueAs() to convert from 'text' to a basic type
425prm = field->getParameter("my-charset-param");
426const vmime::charset ch = prm->getValueAs <vmime::charset>();
427\end{lstlisting}
428
429Some fields provide easy access to their standard parameters (see
430Table \ref{standard-prm-fields}). This avoids finding the parameter and
431\emph{dynamic-casting} its value to the right type. The following code
432illustrates how to use it:
433
434\begin{lstlisting}
435vmime::shared_ptr <vmime::contentTypeField> field =
436   header->getField <vmime::contentTypeField>(vmime::fields::CONTENT_TYPE);
437
438// 1. First solution: the "hard" way
439vmime::shared_ptr <vmime::parameter> prm = field->findParameter("charset");
440const charset ch1 = prm->getValueAs <vmime::charset>();
441
442// 2. Second solution: the simple way
443const charset ch2 = field->getCharset();
444\end{lstlisting}
445
446\vnote{In both cases, an exception {\vcode no\_such\_parameter} can be
447thrown if the parameter does not exist, so be sure to catch it.}
448
449\begin{table}[ht!]
450\begin{center}
451\noindent\begin{tabularx}{0.85\textwidth}{|l|l|X|}
452\hline
453	{\bf Field Name} &
454	{\bf Field Type} &
455	{\bf Parameters} \\
456\hline
457\hline
458Content-Type & contentTypeField & boundary, charset, report-type  \\
459\hline
460Content-Disposition & contentDispositionField & creation-date,
461modification-date, read-date, filename, size \\
462\hline
463\end{tabularx}
464\end{center}
465\label{standard-prm-fields}
466\caption{Standard parameterized fields}
467\end{table}
468
469
470
471% ============================================================================
472\section{Streams}
473
474\subsection{Streams and stream adapters} % -----------------------------------
475
476Streams permit reading or writing data whatever the underlying system is:
477a file on a hard disk, a socket connected to a remote service...
478
479There are two types of streams: input streams (from which you can read data)
480and output streams (in which you can write data). Some adapters are provided
481for compatibility and convenience, for example:
482
483\begin{itemize}
484\item {\vcode inputStreamAdapter} and {\vcode outputStreamAdapter}: allow
485to use standard C++ iostreams with VMime;
486\item {\vcode inputStreamStringAdapter} and
487{\vcode outputStreamStringAdapter}: use a {\vcode vmime::string} object to
488read/write data.
489\end{itemize}
490
491The following example shows two ways of writing the current date to the
492standard output, using stream adapters:
493
494\begin{lstlisting}[caption={Using stream adapters}]
495// Get current date and time
496const vmime::datetime date = vmime::datetime::now();
497
498// 1. Using outputStreamAdapter
499vmime::utility::outputStreamAdapter out(std::cout);
500
501std::cout << "Current date is: ";
502date.generate(out);
503std::cout << std::endl;
504
505// 2. Using outputStreamStringAdapter
506vmime::string dateStr;
507vmime::utility::outputStreamStringAdapter outStr(dateStr);
508
509date.generate(outStr);
510
511std::cout << "Current date is: " << dateStr << std::endl;
512\end{lstlisting}
513
514
515\subsection{Stream filters} % ------------------------------------------------
516
517Input and output streams can be filtered to perform inline conversions (for
518example, there is a filter to convert ``{\textbackslash}r{\textbackslash}n''
519sequences to ``{\textbackslash}n''). They inherit from
520{\vcode vmime::utility::filteredInputStream} or
521{\vcode vmime::utility::filteredOutputStream} and are used like adapters (some
522filters also accept parameters; read the documentation).
523
524The most useful filter in VMime (and probably the only one you will need) is
525the {\vcode charsetFilteredOutputStream}, which performs inline conversion
526of charsets. See \ref{section_charsets} to know how to use it.
527
528\vnote{After you have finished to use a filtered output stream, it is
529important to call {\vcode flush()} on it to flush the internal buffer.
530If {\vcode flush()} is not called, not all data may be written to the
531underlying stream.}
532
533
534% ============================================================================
535\section{Content handlers}
536
537\subsection{Introduction} % --------------------------------------------------
538
539Content handlers are an abstraction for data sources. They are currently used
540when some data need to be stored for later use (eg. body part contents,
541attachment data, ...). Data can be stored encoded or unencoded (for more
542information about encodings, see \ref{section_encodings}).
543
544\subsection{Extracting data from content handlers} % -------------------------
545
546You can extract data in a content handler using the {\vcode extract()} method
547(which automatically decodes data if encoded) or {\vcode extractRaw()} (which
548extracts data without perfoming any decoding).
549
550The following example shows how to extract the body text from a message, and
551writing it to the standard output with charset conversion:
552
553\begin{lstlisting}[caption={Using content handlers to extract body text from
554a message}]
555// Suppose we already have a message
556vmime::shared_ptr <vmime::message> msg;
557
558// Obtains a reference to the body contents
559vmime::shared_ptr <vmime::body> body = msg->getBody();
560vmime::shared_ptr <vmime::contentHandler> cts = body->getContents();
561
562vmime::utility::outputStreamAdapter out(std::cout);
563cts->extract(out);
564\end{lstlisting}
565
566\vnote{The body contents is extracted ``as is''. No charset conversion is
567performed. See \ref{section_charsets} to know more about conversion between
568charsets.}
569
570
571\subsection{Creating content handlers} % -------------------------------------
572
573When you are building a message, you may need to instanciate content handlers
574if you want to set the contents of a body part. The following code snippet
575shows how to set the body text of a part from a string:
576
577\begin{lstlisting}[caption={Setting the contents of a body part}]
578vmime::shared_ptr <vmime::bodyPart> part;  // suppose we have a body part
579
580// Create a new content handler from a string
581vmime::shared_ptr <vmime::contentHandler> cth =
582   vmime::make_shared <vmime::stringContentHandler>("Put body contents here");
583
584// Set the contents
585part->getBody()->setContents(cth);
586\end{lstlisting}
587
588Content handlers are also used when creating attachments. The following
589example illustrates how to create an attachment from a file:
590
591\begin{lstlisting}[caption={Creating an attachment from a file}]
592// Create a stream from a file
593std::ifstream* fileStream = new std::ifstream();
594
595fileStream->open("/home/vincent/paris.jpg", std::ios::binary);
596
597if (!*fileStream)
598   // handle error
599
600vmime::shared_ptr <utility::stream> dataStream =
601   vmime::make_shared <vmime::utility::inputStreamPointerAdapter>(fileStream);
602
603   // NOTE: 'fileStream' will be automatically deleted
604   // when 'dataStream' is deleted
605
606// Create a new content handler
607vmime::shared_ptr <contentHandler> data =
608   vmime::make_shared <vmime::streamContentHandler>(dataStream, 0);
609
610// Now create the attachment
611ref <vmime::attachment> att = vmime::make_shared <vmime::defaultAttachment>
612   (
613   	/* attachment data */ data,
614	/* content type */    vmime::mediaType("image/jpeg"),
615	/* description */     vmime::text("Holiday photo"),
616	/* filename */        vmime::word("paris.jpg")
617   );
618\end{lstlisting}
619
620You will see later that the {\vcode vmime::fileAttachment} class already
621encapsulates all the mechanics to create an attachment from a file.
622
623
624% ============================================================================
625\section{Character sets, charsets and conversions\label{section_charsets}}
626
627Quoting from RFC-2278: \emph{`` The term 'charset' is used to refer to a
628method of converting a sequence of octets into a sequence of characters.''}
629
630With the {\vcode vmime::charset} object, VMime supports conversion between
631charsets using the {\em iconv} library, which is available on almost all
632existing platforms. See {\vcode vmime::charset} and
633{\vcode vmime::charsetConverter} in the class documentation to know more
634about charset conversion.
635
636The following example shows how to convert data in one charset to another
637charset. The data is extracted from the body of a message and converted
638to UTF-8 charset:
639
640\begin{lstlisting}[caption={Extracting and converting body contents to a
641specified charset}]
642vmime::shared_ptr <vmime::message> msg;  // we have a message
643
644// Obtain the content handler first
645vmime::shared_ptr <vmime::body> body = msg->getBody();
646vmime::shared_ptr <const vmime::contentHandler> cth = body->getContents();
647
648// Then, extract and convert the contents
649vmime::utility::outputStreamAdapter out(std::cout);
650vmime::utility::charsetFilteredOutputStream fout
651   (/* source charset */ body->getCharset(),
652    /* dest charset */   vmime::charset("utf-8"),
653    /* dest stream */    out);
654
655cth->extract(fout);
656
657fout.flush();  // Very important!
658\end{lstlisting}
659
660
661% ============================================================================
662\section{Non-ASCII text in header fields}
663
664MIME standard defines methods\footnote{See RFC-2047: Message Header Extensions
665for Non-ASCII Text} for dealing with data which is not 7-bit only (ie. the
666ASCII character set), in particular in header fields. For example, the field
667``Subject:'' use this data type.
668
669VMime is fully compatible with RFC-2047 and provides two objects for
670manipulating 8-bit data: {\vcode vmime::text} and {\vcode vmime::word}. A word
671represents textual information encoded in a specified charset. A text is
672composed of one or more words.
673
674RFC-2047 describes the process of encoding 8-bit data into a 7-bit form;
675basically, it relies on Base64 and Quoted-Printable encoding. Hopefully, all
676the encoding/decoding process is done internally by VMime, so creating text
677objects is fairly simple:
678
679\begin{lstlisting}[caption={Creating \vcode{vmime::text} objects}]
680vmime::string inText = "Linux dans un téléphone mobile";
681vmime::charset inCharset = "utf-8";
682
683vmime::text outText;
684outText.createFromString(inText, inCharset);
685
686// 'outText' now contains 3 words:
687//    . <us-ascii>   "Linux dans un "
688//    . <utf-8>      "téléphone "
689//    . <us-ascii>   "mobile"
690
691vmime::shared_ptr <vmime::header> header = myMessage->getHeader();
692header->Subject()->setValue(outText);
693\end{lstlisting}
694
695In general, you will not need to decode RFC-2047-encoded data as the process
696is totally transparent in VMime. If you really have to, you can use the
697{\vcode vmime::text::decodeAndUnfold()} static method to create a text object
698from encoded data.
699
700For example, say you have the following encoded data:
701
702\begin{verbatim}
703   Linux dans un =?UTF-8?B?dMOpbMOpcGhvbmUgbW9iaWxl?=
704\end{verbatim}
705
706You can simply decode it using the following code:
707
708\begin{lstlisting}[caption={Decoding RFC-2047-encoded data}]
709vmime::string inData =
710    "Linux dans un =?UTF-8?B?dMOpbMOpcGhvbmUgbW9iaWxl?=";
711
712vmime::text outText;
713vmime::text::decodeAndUnfold(inData, &outText);
714\end{lstlisting}
715
716{\vcode vmime::text} also provides a function to convert all the words to
717another charset in a single call. The following example shows how to convert
718text stored in the Subject field of a message:
719
720\begin{lstlisting}[caption={Converting data in a {\vcode vmime::text} to a
721specified charset}]
722vmime::shared_ptr <vmime::message> msg;  // we have a message
723
724vmime::text subject = msg->getHeader()->Subject()->getValue();
725
726const vmime::string subjectText =
727   subject.getConvertedText(vmime::charset("utf-8"));
728
729// 'subjectText' now contains the subject in UTF-8 encoding
730\end{lstlisting}
731
732
733% ============================================================================
734\section{Encodings\label{section_encodings}}
735
736\subsection{Introduction} % --------------------------------------------------
737
738The MIME standard defines a certain number of encodings to allow data
739to be safely transmitted from one peer to another. VMime provides
740data encoding and decoding using the {\vcode vmime::utility::encoder::encoder} object.
741
742You should not need to use encoders directly, as all encoding/decoding
743process is handled internally by the library, but it is good to know
744they exist and how they work.
745
746\subsection{Using encoders} % ------------------------------------------------
747
748You can create an instance of an encoder using the 'vmime::utility::encoder::encoderFactory'
749object, giving the encoding name ({\it base64}, {\it quoted-printable}, ...).
750The following example creates an instance of the Base64 encoder to encode
751some data:
752
753\begin{lstlisting}[caption={A simple example of using an encoder}]
754vmime::shared_ptr <vmime::utility::encoder::encoder> enc =
755    vmime::utility::encoder::encoderFactory::getInstance()->create("base64");
756
757vmime::string inString("Some data to encode");
758vmime::utility::inputStreamStringAdapter in(inString);
759
760vmime::string outString;
761vmime::utility::outputStreamStringAdapter out(outString);
762
763enc->encode(in, out);
764
765std::cout << "Encoded data is:"  << outString << std::endl;
766\end{lstlisting}
767
768\subsection{Enumerating available encoders} % --------------------------------
769
770The behaviour of the encoders can be configured using properties. However,
771not all encoders support properties. The following example\footnote{This is
772an excerpt from {\vexample example6}} enumerates available encoders and the
773supported properties for each of them:
774
775\begin{lstlisting}[caption={Enumerating encoders and their properties}]
776vmime::shared_ptr <vmime::utility::encoder::encoderFactory> ef =
777   vmime::utility::encoder::encoderFactory::getInstance();
778
779std::cout << "Available encoders:" << std::endl;
780
781for (int i = 0 ; i < ef->getEncoderCount() ; ++i)
782{
783   // Output encoder name
784   vmime::shared_ptr <const vmime::utility::encoder::encoderFactory::registeredEncoder>
785      enc = ef->getEncoderAt(i);
786
787   std::cout << "  * " << enc->getName() << std::endl;
788
789   // Create an instance of the encoder to get its properties
790   vmime::shared_ptr <vmime::utility::encoder::encoder> e = enc->create();
791
792   std::vector <vmime::string> props = e->getAvailableProperties();
793   std::vector <vmime::string>::const_iterator it;
794
795   for (it = props.begin() ; it != props.end() ; ++it)
796      std::cout << "      - " << *it << std::endl;
797\end{lstlisting}
798
799
800% ============================================================================
801\section{Progress listeners}
802
803Progress listeners are used with objects that can notify you about the state
804of progress when they are performing an operation.
805
806The {\vcode vmime::utility::progressListener} interface is rather simple:
807
808\begin{lstlisting}
809void start(const int predictedTotal);
810void progress(const int current, const int currentTotal);
811void stop(const int total);
812\end{lstlisting}
813
814{\vcode start()} and {\vcode stop()} are called at the beginning and the end
815of the operation, respectively. {\vcode progress()} is called each time the
816status of progress changes (eg. a chunk of data has been processed). There is
817no unit specified for the values passed in argument. It depends on the
818notifier: it can be bytes, percent, number of messages...
819