+#define HTTP_CURL_CALLBACK_DATA(from, type, var) \
+ http_curl_callback_ctx *__CTX = (http_curl_callback_ctx *) (from); \
+ TSRMLS_FETCH_FROM_CTX(__CTX->tsrm_ctx); \
+ type (var) = (type) (__CTX->data)
+
+#define http_curl_callback_data(data) _http_curl_callback_data((data) TSRMLS_CC)
+static http_curl_callback_ctx *_http_curl_callback_data(void *data TSRMLS_DC);
+
+
+#if HTTP_CURL_USE_ZEND_MM
+static void http_curl_free(void *p) { efree(p); }
+static char *http_curl_strdup(const char *p) { return estrdup(p); }
+static void *http_curl_malloc(size_t s) { return emalloc(s); }
+static void *http_curl_realloc(void *p, size_t s) { return erealloc(p, s); }
+static void *http_curl_calloc(size_t n, size_t s) { return ecalloc(n, s); }
+#endif
+
+/* {{{ STATUS http_request_global_init() */
+STATUS _http_request_global_init(void)
+{
+#if HTTP_CURL_USE_ZEND_MM
+ if (CURLE_OK != curl_global_init_mem(CURL_GLOBAL_ALL,
+ http_curl_malloc,
+ http_curl_free,
+ http_curl_realloc,
+ http_curl_strdup,
+ http_curl_calloc)) {
+ return FAILURE;
+ }
+#else
+ if (CURLE_OK != curl_global_init(CURL_GLOBAL_ALL)) {
+ return FAILURE;
+ }
+#endif
+ return SUCCESS;
+}
+/* }}} */
+
+/* {{{ void *http_request_data_copy(int, void *) */
+void *_http_request_data_copy(int type, void *data TSRMLS_DC)
+{
+ switch (type)
+ {
+ case COPY_STRING:
+ {
+ char *new_str = estrdup(data);
+ //fprintf(stderr, "COPY STRING: %p (%s)\n", new_str, new_str);
+ zend_llist_add_element(&HTTP_G(request).copies.strings, &new_str);
+ return new_str;
+ }
+
+ case COPY_SLIST:
+ {
+ zend_llist_add_element(&HTTP_G(request).copies.slists, &data);
+ return data;
+ }
+
+ case COPY_CONTEXT:
+ {
+ zend_llist_add_element(&HTTP_G(request).copies.contexts, &data);
+ return data;
+ }
+
+ default:
+ {
+ return data;
+ }
+ }
+}
+/* }}} */
+
+/* {{{ void http_request_data_free_string(char **) */
+void _http_request_data_free_string(void *string)
+{
+ //fprintf(stderr, "FREE STRING %p (%s)\n", *((char **)string), *((char **)string));
+ efree(*((char **)string));
+}
+/* }}} */
+
+/* {{{ void http_request_data_free_slist(struct curl_slist **) */
+void _http_request_data_free_slist(void *list)
+{
+ curl_slist_free_all(*((struct curl_slist **) list));
+}
+/* }}} */
+
+/* {{{ _http_request_data_free_context(http_curl_callback_ctx **) */
+void _http_request_data_free_context(void *context)
+{
+ efree(*((http_curl_callback_ctx **) context));
+}
+/* }}} */
+
+/* {{{ http_request_body *http_request_body_new() */
+PHP_HTTP_API http_request_body *_http_request_body_new(TSRMLS_D)
+{
+ http_request_body *body = ecalloc(1, sizeof(http_request_body));
+ return body;
+}
+/* }}} */