Mercurial > feed
diff src/c/feed.c @ 0:ad85b8813e8a
Fetched a URL
author | Adam Chlipala <adam@chlipala.net> |
---|---|
date | Tue, 11 Jan 2011 10:31:48 -0500 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/c/feed.c Tue Jan 11 10:31:48 2011 -0500 @@ -0,0 +1,78 @@ +#include <ctype.h> +#include <string.h> +#include <stdlib.h> + +#include <curl/curl.h> + +#include <feed.h> + +#define BUF_INIT 1024 +#define BUF_MAX 1073741824 + +uw_unit uw_FeedFfi_init(uw_context ctx) { + curl_global_init(CURL_GLOBAL_ALL); + + return uw_unit_v; +} + +static CURL *curl(uw_context ctx) { + CURL *r; + + if (!(r = uw_get_global(ctx, "curl"))) { + r = curl_easy_init(); + if (r) + uw_set_global(ctx, "curl", r, curl_easy_cleanup); + } + + return r; +} + +static void free_buffer(void *data) { + uw_buffer *buf = data; + + uw_buffer_free(buf); + free(buf); +} + +static uw_buffer *curl_buffer(uw_context ctx) { + uw_buffer *r; + + if (!(r = uw_get_global(ctx, "curl_buffer"))) { + r = malloc(sizeof(uw_buffer)); + if (r) { + uw_buffer_init(BUF_MAX, r, BUF_INIT); + uw_set_global(ctx, "curl_buffer", r, free_buffer); + } + } + + return r; +} + +static size_t write_data(void *buffer, size_t size, size_t nmemb, void *userp) { + uw_buffer *out = userp; + + uw_buffer_append(out, buffer, size * nmemb); + + return size * nmemb; +} + +uw_Basis_string uw_FeedFfi_fetch(uw_context ctx, uw_Basis_string url) { + CURL *c = curl(ctx); + uw_buffer *b = curl_buffer(ctx); + CURLcode code; + + uw_buffer_reset(b); + + curl_easy_setopt(c, CURLOPT_URL, url); + curl_easy_setopt(c, CURLOPT_WRITEFUNCTION, write_data); + curl_easy_setopt(c, CURLOPT_WRITEDATA, b); + + code = curl_easy_perform(c); + + if (code) + uw_error(ctx, FATAL, "Error fetching URL %s", url); + else { + uw_buffer_append(b, "", 1); + return uw_strdup(ctx, b->start); + } +}