diff options
Diffstat (limited to 'doc/book/basics.tex')
-rw-r--r-- | doc/book/basics.tex | 110 |
1 files changed, 60 insertions, 50 deletions
diff --git a/doc/book/basics.tex b/doc/book/basics.tex index 9c129912..ac66959e 100644 --- a/doc/book/basics.tex +++ b/doc/book/basics.tex @@ -6,7 +6,7 @@ \subsection{Introduction} % -------------------------------------------------- Since version 0.7.2cvs, VMime use smart pointers to simplify memory -management. VMime's smart pointer implementation relies on +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. @@ -21,8 +21,20 @@ 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::ref} -and {\vcode vmime::weak\_ref}, respectively. +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} % ----------------------- @@ -30,7 +42,7 @@ 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::create} instead of the {\vcode new} +use the function {\vcode vmime::make\_shared} instead of the {\vcode new} operator. \begin{lstlisting}[caption={Smarts pointers and creating objects}] @@ -55,8 +67,8 @@ private: int main() { - vmime::ref <myObject> obj = - vmime::create <myObject>("world"); + vmime::shared_ptr <myObject> obj = + vmime::make_shared <myObject>("world"); obj->sayHello(); @@ -72,20 +84,20 @@ 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 staticCast()}, {\vcode dynamicCast()} and {\vcode constCast()} -equivalents on {\vcode vmime::ref} and {\vcode vmime::weak\_ref} objects: +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::ref <myObject> obj = vmime::create <myObject>(); +vmime::shared_ptr <myObject> obj = vmime::make_shared <myObject>(); // Implicit downcast -vmime::ref <myBase> base = obj; +vmime::shared_ptr <myBase> base = obj; // Explicit upcast -vmime::ref <myObject> obj2 = base.dynamicCast <myObject>(); +vmime::shared_ptr <myObject> obj2 = vmime::dynamicCast <myObject>(base); \end{lstlisting} Weak references are used to resolve reference cycles (an object which refers @@ -97,34 +109,34 @@ class parent : public vmime::object { public: - void createChild(vmime::ref <child> c) + void createChild(vmime::shared_ptr <child> c) { m_child = c; } private: - vmime::ref <child> m_child; + vmime::shared_ptr <child> m_child; }; class child : public vmime::object { public: - child(vmime::ref <parent> p) + child(vmime::shared_ptr <parent> p) : m_parent(p) { } private: - vmime::ref <parent> m_parent; + vmime::shared_ptr <parent> m_parent; }; int main() { - vmime::ref <parent> p = vmime::create <parent>(); - vmime::ref <child> c = vmime::create <child>(); + vmime::shared_ptr <parent> p = vmime::make_shared <parent>(); + vmime::shared_ptr <child> c = vmime::make_shared <child>(); p->setChild(c); } @@ -136,7 +148,7 @@ exiting {\vcode main()}. That's because {\vcode p} indirectly points to itself reference to the parent: \begin{lstlisting} -vmime::weak_ref <parent> m_parent; +vmime::weak_ptr <parent> m_parent; \end{lstlisting} The decision to make the parent or the child a weak reference is purely @@ -216,7 +228,7 @@ 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 +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. @@ -284,12 +296,12 @@ 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::ref <vmime::mailbox> mbox1 = vmime::create <vmime::mailbox> +vmime::shared_ptr <vmime::mailbox> mbox1 = vmime::make_shared <vmime::mailbox> (/* name */ vmime::text("John Doe"), /* email */ "[email protected]"); -vmime::ref <vmime::mailbox> mbox2 = vmime::create <vmime::mailbox> +vmime::shared_ptr <vmime::mailbox> mbox2 = vmime::make_shared <vmime::mailbox> (/* no name, email only */ "[email protected]"); -vmime::ref <vmime::mailboxGroup> grp = vmime::create <vmime::mailboxGroup>(); +vmime::shared_ptr <vmime::mailboxGroup> grp = vmime::make_shared <vmime::mailboxGroup>(); grp->appendMailbox(mbox1); grp->appendMailbox(mbox2); \end{lstlisting} @@ -402,12 +414,11 @@ 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::ref <vmime::parameterizedField> field = - header->findField("X-Field-That-Contains-Parameters") - .dynamicCast <vmime::parameterizedField>(); +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::ref <vmime::parameter> prm = field->getParameter("my-date-param"); +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 @@ -421,12 +432,11 @@ Table \ref{standard-prm-fields}). This avoids finding the parameter and illustrates how to use it: \begin{lstlisting} -vmime::ref <vmime::contentTypeField> field = - header->getField(vmime::fields::CONTENT_TYPE) - .dynamicCast <vmime::contentTypeField>(); +vmime::shared_ptr <vmime::contentTypeField> field = + header->getField <vmime::contentTypeField>(vmime::fields::CONTENT_TYPE); // 1. First solution: the "hard" way -vmime::ref <vmime::parameter> prm = field->findParameter("charset"); +vmime::shared_ptr <vmime::parameter> prm = field->findParameter("charset"); const charset ch1 = prm->getValueAs <vmime::charset>(); // 2. Second solution: the simple way @@ -541,11 +551,11 @@ 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::ref <vmime::message> msg; +vmime::shared_ptr <vmime::message> msg; // Obtains a reference to the body contents -vmime::ref <vmime::body> body = msg->getBody(); -vmime::ref <vmime::contentHandler> cts = body->getContents(); +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); @@ -563,11 +573,11 @@ 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::ref <vmime::bodyPart> part; // suppose we have a body part +vmime::shared_ptr <vmime::bodyPart> part; // suppose we have a body part // Create a new content handler from a string -vmime::ref <vmime::contentHandler> cth = - vmime::create <vmime::stringContentHandler>("Put body contents here"); +vmime::shared_ptr <vmime::contentHandler> cth = + vmime::make_shared <vmime::stringContentHandler>("Put body contents here"); // Set the contents part->getBody()->setContents(cth); @@ -585,18 +595,18 @@ fileStream->open("/home/vincent/paris.jpg", std::ios::binary); if (!*fileStream) // handle error -vmime::ref <utility::stream> dataStream = - vmime::create <vmime::utility::inputStreamPointerAdapter>(fileStream); +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::ref <contentHandler> data = - vmime::create <vmime::streamContentHandler>(dataStream, 0); +vmime::shared_ptr <contentHandler> data = + vmime::make_shared <vmime::streamContentHandler>(dataStream, 0); // Now create the attachment -ref <vmime::attachment> att = vmime::create <vmime::defaultAttachment> +ref <vmime::attachment> att = vmime::make_shared <vmime::defaultAttachment> ( /* attachment data */ data, /* content type */ vmime::mediaType("image/jpeg"), @@ -627,11 +637,11 @@ to UTF-8 charset: \begin{lstlisting}[caption={Extracting and converting body contents to a specified charset}] -vmime::ref <vmime::message> msg; // we have a message +vmime::shared_ptr <vmime::message> msg; // we have a message // Obtain the content handler first -vmime::ref <vmime::body> body = msg->getBody(); -vmime::ref <const vmime::contentHandler> cth = body->getContents(); +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); @@ -676,7 +686,7 @@ outText.createFromString(inText, inCharset); // . <utf-8> "t�l�phone " // . <us-ascii> "mobile" -vmime::ref <vmime::header> header = myMessage->getHeader(); +vmime::shared_ptr <vmime::header> header = myMessage->getHeader(); header->Subject()->setValue(outText); \end{lstlisting} @@ -707,7 +717,7 @@ text stored in the Subject field of a message: \begin{lstlisting}[caption={Converting data in a {\vcode vmime::text} to a specified charset}] -vmime::ref <vmime::message> msg; // we have a message +vmime::shared_ptr <vmime::message> msg; // we have a message vmime::text subject = msg->getHeader()->Subject()->getValue(); @@ -739,7 +749,7 @@ 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::ref <vmime::utility::encoder::encoder> enc = +vmime::shared_ptr <vmime::utility::encoder::encoder> enc = vmime::utility::encoder::encoderFactory::getInstance()->create("base64"); vmime::string inString("Some data to encode"); @@ -761,7 +771,7 @@ 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::utility::encoder::encoderFactory* ef = +vmime::shared_ptr <vmime::utility::encoder::encoderFactory> ef = vmime::utility::encoder::encoderFactory::getInstance(); std::cout << "Available encoders:" << std::endl; @@ -769,13 +779,13 @@ std::cout << "Available encoders:" << std::endl; for (int i = 0 ; i < ef->getEncoderCount() ; ++i) { // Output encoder name - vmime::ref <const vmime::utility::encoder::encoderFactory::registeredEncoder> + 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::ref <vmime::utility::encoder::encoder> e = enc->create(); + vmime::shared_ptr <vmime::utility::encoder::encoder> e = enc->create(); std::vector <vmime::string> props = e->getAvailableProperties(); std::vector <vmime::string>::const_iterator it; |