cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Feature freeze on May 21

From: Tim Tassonis <timtas_at_cubic.ch>
Date: Fri, 16 May 2008 10:18:54 +0200

Hi Daniel

Daniel Stenberg wrote:
> Hey
>
> On May 21st 2008, we stop adding new features and we only fix bugs
> during the following 14 days. If things go well we can then release
> 7.18.2 at around June 4th.
>
> If want anything included or fixed in the next release, raise your hand
> and speak up!
>

What do you think about a new option to store the response directly in a
char buffer, as I proposed earler? I posted a possible implementation
two days ago and attach it below, I would also rework it if you want
something changed. Or do you oppose the idea completely?

How about this:

This would go into the curl.h header:

struct curl_response_buffer {
     size_t size;
     char *data;
     char *curr;
};

size_t curl_buffer_response(void *b, size_t s, size_t n, void *userp);

#define curl_easy_set_response_buffer(x,y); \
   curl_easy_setopt(x, CURLOPT_WRITEFUNCTION, curl_buffer_response); \
   curl_easy_setopt(x, CURLOPT_WRITEDATA, &y);

And this function would go to the library somewhere:

size_t curl_buffer_response(void *buffer, size_t size, size_t num, void
*userp) {
     struct curl_response_buffer *crb = userp;
     int data_size;
     int new_size=0;
     data_size = size*num;
     char *new_data=NULL;
     if (crb->size == 0 ) {
         crb->data = (char *)malloc(data_size+1);
         crb->curr = crb->data;
     } else {
         new_size = crb->size+data_size+1;
         new_data = (char *)realloc(crb->data,new_size);
         if (new_data) {
             crb->data = new_data;
             crb->curr = crb->data;
             crb->curr += crb->size;
         } else {
             return 0;
         }
     }
     memcpy(crb->curr,buffer,data_size);
     crb->size += data_size;
     return data_size;
}

So, one could then easily do the following:
#include <curl/curl.h>

int main(int argc, char **argv)
{
     CURL * curl_handle = NULL;
     CURLcode curl_rc;
     int rc=0;
     struct curl_response_buffer my_resp;
     char * my_url = "http://curl.haxx.se";
     rc = curl_global_init(CURL_GLOBAL_ALL);
     if (rc != 0 ) {
         fprintf(stderr,"Curl global initialization failed\n");
         exit(rc);
     }
     curl_handle = curl_easy_init();
     if ( curl_handle == NULL ) {
         fprintf(stderr,"Curl library initialization failed\n");
         exit(1);
     }
     curl_easy_setopt(curl_handle, CURLOPT_URL, my_url);
     my_resp.size = 0;
     my_resp.data = NULL;
     curl_easy_set_response_buffer(curl_handle,my_resp);
     rc = curl_easy_perform(curl_handle);
     if ( ( rc == 0 ) && (my_resp.size > 0 ) ) {
         my_resp.data[my_resp.size] = '\0';
         printf("%s\n",my_resp.data);
         free(my_resp.data);
     } else {
         if (my_resp.data) free(my_resp.data);
         fprintf(stderr,"Error at %s: %s",my_url,curl_easy_strerror(rc));
     }
     curl_easy_cleanup(curl_handle);
     return rc;
}

Of course, function and structure names may not be very good and perhaps a
   curl_easy_init_response_buffer(curl_response_buffer *crb)
and a
   curl_easy_free_response_buffer(curl_response_buffer *crb)
would also be desirable.

Also, I made the decision to make the buffer one byte bigger than its
actual content, so one can add a \0 termination to it. This might not be
desirable, but it's quite convenient if the data is text. The function
itself does not null terminate and add the byte to the size, as the data
might well be binary.

Bye
Tim
im
Received on 2008-05-16