cURL
Haxx ad
libcurl

curl's project page on SourceForge.net

Sponsors:
Haxx

cURL > Mailing List > Monthly Index > Single Mail

curlpp mailing list Archives

[cURLpp] cURLpp::OptionSetter partial template specialization

From: Jean-Philippe Barrette-LaPierre <jpb>
Date: Thu Mar 24 10:59:33 2005

 I started to work on the "How to enhance cURLpp" section of the guide. This
is the very first draft, it means that the sentences might not make sense,
and that it will have many spelling errors. Feel free to send comments, in
fact, I NEED comments!

hehe.

I need to add an introduction, but it starts like this:

------------------------------------------------
Let's enumerate the classes used in cURLpp:

- cURLpp::CurlHandle: This class is the wrapper on the CURL structure. Member
function are the easy interface functions (setopt, perform)

- template< T > class cURLpp::Option: This is a class that links a CURLOPT_OPT
to a value of Type T. An URL option, for example, would be like this:
 cURLpp::Option< char * > myURL(CURLOPT_URL, "http://rrette.com");

- cURLpp::OptionList: This class is a list of cURLpp::Option. This class is a
container that allow cURLpp::Option of different value Type. This class keeps
its own value of the cURLpp::Option passed in argument.

- cURLpp::Easy: This class is a cURLpp::OptionList, but that contains a
cURLpp::CurlHandle. Each option set will be forwarded to the CurlHandle with
the OptionSetter< U, V>::setOpt function (U being the value Type and V the
CURLOPT_*). It have a perform function too, that will be forwared to the
CurlHandle.

- cURLpp::OptionSetter: Now the big part. The best way to explain is to make
an example. First, let's take a look on the CURLOPT_URL option

http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTURL

In the first line, it says this:

The parameter should be a char * to a zero terminated string. The string must
remain present until curl no longer needs it, as it doesn't copy the string.

Let's say that we don't like the way it behaves. Let's say that we want it to
copy the string, so we don't have to bother if we change the string or not.
We could provide a specialization for cURLpp::OptionSetter that would change
the way curl_easy_setopt behaves. Usually the function
cURLpp::OptionSetter::setOpt is defined like this:

template<
   typename OptionValueType,
   cURL::CURLoption optionType >
void
cURLpp::OptionSetter<
   OptionValueType,
   optionType >::setOpt(cURLpp::CurlHandle *handle, ParamType value)
{
   handle->option(optionType, value);
};

I need to mention that the handle->option function call is just a wrapper
around the curl_easy_setopt function. Now let's specialize it in order to
behaves the way we decided it (Note: this code would lead to a memory leak
and it doesn't check for allocation errors, but this is just an example)

template< >
void cURLpp::OptionSetter< char *, cURL::CURLOPT_URL >::setOpt(
   cURLpp::CurlHandle *handle, char *url)
{
   char *urlCopy = malloc(strlen(url) + 1);
   strcpy(urlCopy, url);
   handle->option(optionType, urlCopy);
}

Now that we have specialized for this specific situation, each time we do
this:

  cURLpp::Option< char * > myURL(CURLOPT_URL, "http://rrette.com");
  //handle is a cURLpp::Easy object.
  handle.setOpt(myURL);

we will no longer need to be sure that the URL passed in argument must not be
modified.

Let's say now that we don't like to "play" with char *. Let's say you are a
std::string lover. How can I make cURLpp to handle an option with std::string
as a value type? First, let never forget that an libcurl's option that needs
a "char *" value type as argument still need a "char *", so as the
CurlHandle::option function. We would do a partial template specialization on
OptionSetter like this:

template< cURL::CURLoption optionType >
void cURLpp::OptionSetter<
   std::string,
   optionType >::setOpt(cURLpp::CurlHandle *handle, ParamType value)
{
 handle->option(optionType, value.c_str());
};

Now, we can do this:

cURLpp::Option< std::string > myURL(CURLOPT_URL,
     std::string("http://rrette.com"));
  //handle is a cURLpp::Easy object.
  handle.setOpt(myURL);

We can now use std::string on every option that needs a "char *". You might
asked yourself: "But the std::string::c_str() value will only be valid until
the std::string is itself. So, is it really a good way to do it?"

First, let's remember this: the cURLpp::Easy class is a cURLpp::OptionList
class. cURLpp::OptionList keeps its own value of the Option, so if the Option
contains a std::string object, the std::string will be valid as long as the
cURLpp::Easy is. In fact, even if we set a Option value for the CURLOPT_URL,
the new value will be set and the old one will be deleted, as the
std::string. So, by specializing the OptionSetter, you get a memory safe
Option (which isn't the case for the "char *" specialization.)
--------------------------

So, is it clear? If not, which part isn't?

I'll add a part for the new CurlHandleSetter later (introduced in the 0.5.1
version, still need to add it the the HEAD branch).

-- 
Jean-Philippe Barrette-LaPierre
Maintener of cURLpp (http://rrette.com/curlpp)
Received on 2005-03-24

These mail archives are generated by hypermail.

donate! Page updated November 12, 2010.
web site info

File upload with ASP.NET