I refresh the concept of function pointer in C/C++, thanks
http://www.newty.de/fpt/fpt.html

As mentioned "Regarding their syntax, there are two different types of
function pointers: On the one hand there are pointers to
ordinary C functions or to static C++ member functions. On the other
hand there are pointers to non-static
C++ member functions. The basic difference is that all pointers to
non-static member functions need a hidden
argument: The this-pointer to an instance of the class. Always keep in
mind: These two types of function
pointers are incompatible with each other."

So HTTPDownload object or what my stuff instant the this-pointer like:

/* $Id: cgi.cpp 33 2007-11-26 08:54:30Z xiang.zhai $ */

#include "cgi.h"

CGI::CGI():
curlHandle(curl_easy_init()), data(NULL), length(0), allocatedLength(0)
{}

CGI::~CGI()
{
  curl_easy_cleanup(curlHandle);

  if (data)
  {
    free(data);
    data = NULL;
    allocatedLength = 0;
    length = 0;
  }
}

void
CGI::SetURL(char *url)
{
  curl_easy_setopt(curlHandle, CURLOPT_URL, url);
}

char *
CGI::GetData()
{
  return data;
}

size_t
CGI::WriteFunctor(void *ptr, size_t size, size_t nmemb, void *stream)
{
  int written = fwrite(ptr, size, nmemb, (FILE *) stream);

  return written;
}

bool
CGI::WriteContent(FILE *fp)
{
  curl_easy_setopt(curlHandle, CURLOPT_NOBODY, false);
  curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, fp);
  curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, WriteFunctor);

  if (this->Perform())
  {
    return true;
  }
  else
  {
    return false;
  }
}

bool
CGI::GetContent()
{
  curl_easy_setopt(curlHandle, CURLOPT_NOBODY, false);
  curl_easy_setopt(curlHandle, CURLOPT_WRITEDATA, this);
  curl_easy_setopt(curlHandle, CURLOPT_WRITEFUNCTION, CallbackFunctor);

  if (this->Perform())
  {
    return true;
  }
  else
  {
    return false;
  }
}

bool
CGI::GetHeader()
{
  curl_easy_setopt(curlHandle, CURLOPT_NOBODY, true);
  curl_easy_setopt(curlHandle, CURLOPT_HEADERDATA, this);
  curl_easy_setopt(curlHandle, CURLOPT_HEADERFUNCTION, CallbackFunctor);

  if (this->Perform())
  {
    return true;
  }
  else
  {
    return false;
  }
}

size_t
CGI::CallbackFunctor(void *ptr, size_t size, size_t nmemb, void *stream)
{
  CGI *handle = (CGI *) stream;
  size_t newDataSize = size * nmemb;

  if (handle->data == NULL)
  {
    assert(handle->allocatedLength == 0);
    handle->data = (char *) malloc(BUFFER_SIZE);
    handle->allocatedLength = BUFFER_SIZE;
    handle->length = 0;
  }

  while (handle->length + newDataSize + 1 > handle->allocatedLength)
  {
    assert(handle->allocatedLength > 0);
    handle->data = (char *) realloc(handle->data, handle->allocatedLength * 2);
    handle->allocatedLength *= 2;
  }

  memcpy(handle->data + handle->length, ptr, newDataSize);
  handle->length += newDataSize;

  return newDataSize;
}

bool CGI::SimplePerform()
{
  if (this->GetContent())
  {
    return true;
  }
  else
  {
    return false;
  }
}

bool
CGI::Perform()
{
  // Set timout
  curl_easy_setopt(curlHandle, CURLOPT_TIMEOUT, TIMEOUT);
  curl_easy_setopt(curlHandle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
  curl_easy_setopt(curlHandle, CURLOPT_USERPWD, "archermind:123456");

  if (curl_easy_perform(curlHandle) == CURLE_OK)
  {
    return true;
  }
  else
  {
    return false;
  }
}

The header file:
/* $Id: cgi.h 33 2007-11-26 08:54:30Z xiang.zhai $ */

#ifndef _CGI_H
#define _CGI_H

#include <cassert>
#include <string>
#include <curl/curl.h>

#define TIMEOUT 10
#define BUFFER_SIZE 1024 * 1024

class CGI
{
  public:
    CGI();
    ~CGI();
                
    void SetURL(char *url);
    bool SimplePerform();
    bool GetHeader();
    bool GetContent();
    bool WriteContent(FILE *fp);
    char *GetData();
                
  private:
    bool Perform();
    static size_t CallbackFunctor(void *ptr, size_t size, size_t
nmemb, void *stream);
    static size_t WriteFunctor(void *ptr, size_t size, size_t nmemb,
void *stream);
                
    CURL *curlHandle;
    char *data;
    unsigned int length;
    unsigned int allocatedLength;
};

#endif // _CGI_H

2007/11/24, sirtoozee <[EMAIL PROTECTED]>:
> Hi Jean:
>
> I Google a way to new this object in the static functor via
> http://www.gamedev.net/community/forums/topic.asp?topic_id=305990,
> RichardS pasted the HTTPDownloader class source code, he re-new the
> HTTPDownloader object in his httpFetch static functor.
>
> Thanks Jean again ^_^
>
> sirtoozee
>
> 2007/11/23, Jean-Philippe Barrette-LaPierre <[EMAIL PROTECTED]>:
> >
> > On 22-Nov-07, at 9:15 PM, sirtoozee wrote:
> >
> > > Hi curlpp geek:
> > >
> > > I read the source code of the example05.cpp(Function functor for
> > > WriteFunction example), the callback WriteMemoryCallback must be
> > > declared static, otherwise it won't link...
> > >
> > > So it acts like a class member use a static function pointer only
> > > based on curl but not curlpp, such as
> >
> > Well, you can use expample06.cpp for home made functors, or just use
> > the more versatile boost functor (which in fact uses home made
> > functors),
> > which is demonstrated in expample18.cpp
> >
> > All of these examples are in the latest release.
> >
> > >
> > > static size_t
> > > WriteFunction(char *ptr, size_t size, size_t nmemb, std::string
> > > *stream)
> > > {
> > >  if (stream == NULL)
> > >  {
> > >    return 0;
> > >  }
> > >
> > >  stream->append(ptr, size * nmemb);
> > >  cout << ptr << endl;
> > >
> > >  return size * nmemb;
> > > }
> > >
> > > void *
> > > CGI::Print()
> > > {
> > >  curl_easy_setopt(this->curl, CURLOPT_WRITEDATA, &this->buffer);
> > >  curl_easy_setopt(this->curl, CURLOPT_WRITEFUNCTION, WriteFunction);
> > >
> > >  return NULL;
> > > }
> > >
> > > When I even know the callback functor can not use a member function
> > > pointer, I still modified the example05.cpp to see whether it work or
> > > not, such as:
> > >
> > > size_t
> > > Callback::WriteMemoryCallback(char* ptr, size_t size, size_t nmemb)
> > > {
> > >  size_t realsize = size * nmemb;
> > >
> > >  this->m_pBuffer = (char*) this->Realloc(this->m_pBuffer,
> > > this->m_Size + realsize);
> > >
> > >  if (this->m_pBuffer == NULL) {
> > >    realsize = 0;
> > >  }
> > >
> > >  memcpy(&(this->m_pBuffer[this->m_Size]), ptr, realsize);
> > >  this->m_Size += realsize;
> > >
> > >  return realsize;
> > > };
> > >
> > > void Callback::print()
> > > {
> > >  cURLpp::Types::WriteFunctionFunctor functor(this-
> > > >*WriteMemoryCallback);
> > >  cURLpp::Options::WriteFunction *test = new
> > > cURLpp::Options::WriteFunction(functor);
> > >  this->request.setOpt(test);
> > >  this->request.perform();
> > >
> > >  std::cout << "Content: " << std::endl << this->m_pBuffer <<
> > > std::endl;
> > > }
> > >
> > > And yes '((Callback*)this)->Callback::WriteMemoryCallback' cannot be
> > > used as a member pointer, since it is of type '<unresolved overloaded
> > > function type>'
> > >
> > > So the C++ wrapper of curl still can not make callback functor to use
> > > the member function pointer, right?
> > >
> > > sirtoozee
> > >
> > > --
> > > An individual human existence should be like a river - small at first,
> > > narrowly contained within its banks, and rushing passionately past
> > > boulders and over waterfalls. Gradually the river grows wider, the
> > > banks recede, the waters flow more quietly, and in the end, without
> > > any visible break, they become merged in the sea, and painlessly lose
> > > their individual being.
> > > _______________________________________________
> > > cURLpp mailing list
> > > [email protected]
> > > http://www.rrette.com/mailman/listinfo/curlpp
> >
> > _______________________________________________
> > cURLpp mailing list
> > [email protected]
> > http://www.rrette.com/mailman/listinfo/curlpp
> >
>
>
> --
> An individual human existence should be like a river - small at first,
> narrowly contained within its banks, and rushing passionately past
> boulders and over waterfalls. Gradually the river grows wider, the
> banks recede, the waters flow more quietly, and in the end, without
> any visible break, they become merged in the sea, and painlessly lose
> their individual being.
>


-- 
An individual human existence should be like a river - small at first,
narrowly contained within its banks, and rushing passionately past
boulders and over waterfalls. Gradually the river grows wider, the
banks recede, the waters flow more quietly, and in the end, without
any visible break, they become merged in the sea, and painlessly lose
their individual being.
_______________________________________________
cURLpp mailing list
[email protected]
http://www.rrette.com/mailman/listinfo/curlpp

Reply via email to