Author: omote.masahito
Date: Sat Apr 19 09:44:18 2008
New Revision: 5426

Modified:
  trunk/uim/curl.c

Log:
* uim/curl.c: Make it GC safe.
 - (uim_curl_fetch_simple_internal): New function.
 - (uim_curl_post_internal): New function.
 - (uim_curl_url_escape_internal): New function.
 - (uim_curl_url_unescape_internal): New function.
 - (uim_curl_perform): New function for delegate common code from
                       uim_curl_post and uim_curl_fetch_simple.


Modified: trunk/uim/curl.c
==============================================================================
--- trunk/uim/curl.c    (original)
+++ trunk/uim/curl.c    Sat Apr 19 09:44:18 2008
@@ -52,19 +52,32 @@
#define DPRINTFN(n,x)
#endif

-struct curl_memory_struct {
-  char *str;
-  size_t size;
-};
-
-static size_t uim_curl_write_func(void *, size_t, size_t, void *);
static uim_lisp uim_curl_fetch_simple(uim_lisp);
+static void *uim_curl_fetch_simple_internal(void *);
+
+struct uim_curl_post_args {
+  uim_lisp url;
+  uim_lisp post;
+};
static uim_lisp uim_curl_post(uim_lisp, uim_lisp);
+static void *uim_curl_post_internal(struct uim_curl_post_args *);
+
static uim_lisp uim_curl_url_escape(uim_lisp);
+static void *uim_curl_url_escape_internal(void *);
+
static uim_lisp uim_curl_url_unescape(uim_lisp);
+static void *uim_curl_url_unescape_internal(void *);
+
void uim_plugin_instance_init(void);
void uim_plugin_instance_quit(void);

+struct curl_memory_struct {
+  char *str;
+  size_t size;
+};
+static size_t uim_curl_write_func(void *, size_t, size_t, void *);
+static CURLcode uim_curl_perform(CURL *);
+
static size_t
uim_curl_write_func(void *ptr, size_t size, size_t nmemb, void *data)
{
@@ -72,9 +85,9 @@
  size_t realsize = size * nmemb;

  if(mem->str != NULL)
-    mem->str = realloc(mem->str, mem->size + realsize + 1);
+    mem->str = uim_realloc(mem->str, mem->size + realsize + 1);
  else
-    mem->str = malloc(realsize + 1);
+    mem->str = uim_malloc(realsize + 1);

  if(mem->str != NULL) {
    memcpy(&(mem->str[mem->size]), ptr, realsize);
@@ -88,13 +101,18 @@
static uim_lisp
uim_curl_fetch_simple(uim_lisp url_)
{
-  const char *url = REFER_C_STR(url_);
+  return 
(uim_lisp)uim_scm_call_with_gc_ready_stack((uim_gc_gate_func_ptr)uim_curl_fetch_simple_internal,
+                                                   (void *)url_);
+}
+
+static void *
+uim_curl_fetch_simple_internal(void *url_)
+{
+  const char *url = REFER_C_STR((uim_lisp)url_);
  CURL *curl;
  CURLcode res;
  struct curl_memory_struct chunk;
  uim_lisp fetched_str_;
-  char *ua;
-  char *referer;

  curl = curl_easy_init();

@@ -104,6 +122,26 @@
  memset(&chunk, 0, sizeof(struct curl_memory_struct));

  curl_easy_setopt(curl, CURLOPT_URL, url);
+  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, uim_curl_write_func);
+  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);
+
+  res = uim_curl_perform(curl);
+
+  fetched_str_ = (chunk.str != NULL) ? MAKE_STR(chunk.str) : uim_scm_f();
+
+  curl_easy_cleanup(curl);
+  curl_global_cleanup();
+  free(chunk.str);
+
+  return (void *)fetched_str_;
+}
+
+static CURLcode
+uim_curl_perform(CURL *curl)
+{
+  char *ua;
+  char *referer;
+  CURLcode res;

  ua = uim_scm_symbol_value_str("uim-curl-user-agent");
  referer = uim_scm_symbol_value_str("uim-curl-referer");
@@ -112,35 +150,38 @@
                   (ua != NULL) ? ua : "libcurl-agent/1.0");
  curl_easy_setopt(curl, CURLOPT_REFERER,
                   (referer != NULL) ? referer : "");
-  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, uim_curl_write_func);
-  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

  res = curl_easy_perform(curl);
-  curl_easy_cleanup(curl);
-  curl_global_cleanup();
-
-  fetched_str_ = (chunk.str != NULL) ? MAKE_STR(chunk.str) : uim_scm_f();

  free(ua);
  free(referer);
-  free(chunk.str);

-  return fetched_str_;
+  return res;
}

static uim_lisp
uim_curl_post(uim_lisp url_, uim_lisp post_)
{
+  struct uim_curl_post_args args;
+
+  args.url = url_;
+  args.post = post_;
+  return 
(uim_lisp)uim_scm_call_with_gc_ready_stack((uim_gc_gate_func_ptr)uim_curl_post_internal,
+                                                   &args);
+}
+
+static void *
+uim_curl_post_internal(struct uim_curl_post_args *args)
+{
+  uim_lisp post_ = args->post;
  uim_lisp post_car_, post_cdr_;
  uim_lisp fetched_str_;
-  const char *url = REFER_C_STR(url_);
+  const char *url = REFER_C_STR(args->url);
  CURL *curl;
  CURLcode res;
  struct curl_memory_struct chunk;
  struct curl_httppost* post_first = NULL;
  struct curl_httppost* post_last = NULL;
-  char *ua;
-  char *referer;

  curl = curl_easy_init();

@@ -150,14 +191,6 @@
  memset(&chunk, 0, sizeof(struct curl_memory_struct));

  curl_easy_setopt(curl, CURLOPT_URL, url);
-
-  ua = uim_scm_symbol_value_str("uim-curl-user-agent");
-  referer = uim_scm_symbol_value_str("uim-curl-referer");
-
-  curl_easy_setopt(curl, CURLOPT_USERAGENT,
-                  (ua != NULL) ? ua : "libcurl-agent/1.0");
-  curl_easy_setopt(curl, CURLOPT_REFERER,
-                  (referer != NULL) ? referer : "");
  curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, uim_curl_write_func);
  curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&chunk);

@@ -178,26 +211,29 @@

  curl_easy_setopt(curl, CURLOPT_HTTPPOST, post_first);

-  res = curl_easy_perform(curl);
+  res = uim_curl_perform(curl);
+
+  fetched_str_ = (chunk.str != NULL) ? MAKE_STR(chunk.str) : uim_scm_f();

  curl_easy_cleanup(curl);
  curl_formfree(post_first);
  curl_global_cleanup();
-
-  fetched_str_ = (chunk.str != NULL) ? MAKE_STR(chunk.str) : uim_scm_f();
-
-  free(ua);
-  free(referer);
  free(chunk.str);

-  return fetched_str_;
+  return (void *)fetched_str_;
}

static uim_lisp
uim_curl_url_escape(uim_lisp url_)
{
+  return 
(uim_lisp)uim_scm_call_with_gc_ready_stack((uim_gc_gate_func_ptr)uim_curl_url_escape_internal,
+                                                   (void *)url_);
+}
+static void *
+uim_curl_url_escape_internal(void *url_)
+{
  uim_lisp escaped_url_;
-  const char *unescaped_url = REFER_C_STR(url_);
+  const char *unescaped_url = REFER_C_STR((uim_lisp)url_);
  char *escaped_url;
  CURL *curl;

@@ -213,14 +249,21 @@
  curl_easy_cleanup(curl);
  curl_global_cleanup();

-  return escaped_url_;
+  return (void *)escaped_url_;
}

static uim_lisp
uim_curl_url_unescape(uim_lisp url_)
{
+  return 
(uim_lisp)uim_scm_call_with_gc_ready_stack((uim_gc_gate_func_ptr)uim_curl_url_unescape_internal,
+                                                   (void *)url_);
+}
+
+static void *
+uim_curl_url_unescape_internal(void *url_)
+{
  uim_lisp unescaped_url_;
-  const char *escaped_url = REFER_C_STR(url_);
+  const char *escaped_url = REFER_C_STR((uim_lisp)url_);
  char *unescaped_url;
  int len; /* curl_easy_unescape uses int, not size_t */
  CURL *curl;
@@ -238,7 +281,7 @@
  curl_easy_cleanup(curl);
  curl_global_cleanup();

-  return unescaped_url_;
+  return (void *)unescaped_url_;
}

void uim_plugin_instance_init(void)

Reply via email to