From 179ac3a128532824cb68b6a99ae9363f2e3b4134 Mon Sep 17 00:00:00 2001 From: larryl Date: Thu, 8 Nov 2007 07:09:16 +0000 Subject: [PATCH] Improved cURL wrapper library. We can write functions from curl_easy_setopt in pure Eiffel now. Before we have to implement the functions in C. git-svn-id: https://svn.origo.ethz.ch/eiffelstudio/trunk/Src/library/cURL@71081 8089f293-4706-0410-a29e-feb5c42a2edf --- curl_default_function.e | 105 ++++++++++++++++ curl_easy_externals.e | 89 +++++++------- curl_function.e | 166 +++++++++++++++++++++++++ curl_info_type.e | 62 ++++++++++ curl_memory_struct.e | 192 ----------------------------- curl_opt_constants.e | 35 +++++- curl_string.e | 50 ++++++++ spec/include/eiffel_curl.h | 243 ++++++++++++++++++++----------------- 8 files changed, 591 insertions(+), 351 deletions(-) create mode 100644 curl_default_function.e create mode 100644 curl_function.e create mode 100644 curl_info_type.e delete mode 100644 curl_memory_struct.e create mode 100644 curl_string.e diff --git a/curl_default_function.e b/curl_default_function.e new file mode 100644 index 00000000..b8ddb07c --- /dev/null +++ b/curl_default_function.e @@ -0,0 +1,105 @@ +indexing + description: "[ + Default implementation of CURL_FUNCTION. + ]" + status: "See notice at end of class." + legal: "See notice at end of class." + date: "$Date$" + revision: "$Revision$" + +class + CURL_DEFAULT_FUNCTION + +inherit + CURL_FUNCTION + +create + make + +feature {NONE} -- Initialization + + make is + -- Creation method + do + set_object_and_function_address + end + +feature -- Command + + progress_function (a_object_id: POINTER; a_download_total, a_download_now, a_upload_total, a_upload_now: REAL_64): INTEGER is + -- Redefine + do + end + + write_function (a_data_pointer: POINTER; a_size, a_nmemb: INTEGER; a_object_id: POINTER): INTEGER is + -- Redefine + local + l_c_string: C_STRING + l_string: STRING + l_identified: IDENTIFIED + do + Result := a_size * a_nmemb + create l_c_string.share_from_pointer_and_count (a_data_pointer, Result) + + create l_identified + l_string ?= l_identified.id_object (a_object_id.to_integer_32) + check not_void: l_string /= Void end + l_string.append (l_c_string.string) + end + + debug_function (a_curl_handle: POINTER; a_curl_infotype: INTEGER; a_char_pointer: POINTER; a_size: INTEGER; a_object_id: POINTER): INTEGER is + -- Redefine + local + l_c_string: C_STRING + do + inspect + a_curl_infotype + when {CURL_INFO_TYPE}.curlinfo_data_in then + dump ("<= Recv data", a_char_pointer, a_size) + when {CURL_INFO_TYPE}.curlinfo_data_out then + dump ("=> Send data", a_char_pointer, a_size) + when {CURL_INFO_TYPE}.curlinfo_header_in then + dump ("<= Recv header", a_char_pointer, a_size) + when {CURL_INFO_TYPE}.curlinfo_header_out then + dump ("=> Send header", a_char_pointer, a_size) + when {CURL_INFO_TYPE}.curlinfo_ssl_data_in then + dump ("<= Recv SSL data", a_char_pointer, a_size) + when {CURL_INFO_TYPE}.curlinfo_ssl_data_out then + dump ("=> Send SSL data", a_char_pointer, a_size) + when {CURL_INFO_TYPE}.curlinfo_text then + create l_c_string.make_by_pointer_and_count (a_char_pointer, a_size) + print ("%N== Info: " + l_c_string.string) + else + check type_unknow: False end + end + end + +feature {NONE} -- Implementation + + dump (a_text: STRING; a_char_pointer: POINTER; a_size: INTEGER) is + -- Dump debug information + require + not_void: a_text /= Void + exists: a_char_pointer /= default_pointer + non_negative: a_size >= 0 + local + l_c_string: C_STRING + do + print ("%N" + a_text) + create l_c_string.share_from_pointer_and_count (a_char_pointer, a_size) + print ("%N" + l_c_string.string) + end + +indexing + library: "cURL: Library of reusable components for Eiffel." + copyright: "Copyright (c) 1984-2006, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 356 Storke Road, Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" + +end diff --git a/curl_easy_externals.e b/curl_easy_externals.e index bd1a9805..42932207 100644 --- a/curl_easy_externals.e +++ b/curl_easy_externals.e @@ -54,18 +54,18 @@ feature -- Command setopt_void_star (a_curl_handle, a_opt, a_form.item) end - setopt_memory_struct (a_curl_handle: POINTER; a_opt: INTEGER; a_memory_struct: CURL_MEMORY_STRUCT) is + setopt_curl_string (a_curl_handle: POINTER; a_opt: INTEGER; a_curl_string: CURL_STRING) is -- Declared as curl_easy_setopt(). require exists: a_curl_handle /= default_pointer valid: (create {CURL_OPT_CONSTANTS}).is_valid (a_opt) - not_void: a_memory_struct /= Void + not_void: a_curl_string /= Void local l_api: POINTER do l_api := api_loader.safe_load_api (module_name, "curl_easy_setopt") if l_api /= default_pointer then - c_setopt (l_api, a_curl_handle, a_opt, a_memory_struct.item) + c_setopt_int (l_api, a_curl_handle, a_opt, a_curl_string.object_id) end end @@ -113,6 +113,26 @@ feature -- Command feature -- Special setting + set_curl_function (a_curl_function: CURL_FUNCTION) is + -- Set `curl_function' with `a_curl_function' + do + internal_curl_function := a_curl_function + ensure + set: a_curl_function /= Void implies curl_function = a_curl_function + end + + curl_function: CURL_FUNCTION is + -- cURL functions in curl_easy_setopt. + do + Result := internal_curl_function + if Result = Void then + create {CURL_DEFAULT_FUNCTION} Result.make + internal_curl_function := Result + end + ensure + not_void: Result /= Void + end + set_write_function (a_curl_handle: POINTER) is -- Set cURL write function require @@ -122,7 +142,20 @@ feature -- Special setting do l_api := api_loader.safe_load_api (module_name, "curl_easy_setopt") if l_api /= default_pointer then - c_set_write_function (l_api, a_curl_handle) + curl_function.c_set_write_function (l_api, a_curl_handle) + end + end + + set_progress_function (a_curl_handle: POINTER) is + -- Set cURL progress function for upload/download progress. + require + exists: a_curl_handle /= default_pointer + local + l_api: POINTER + do + l_api := api_loader.safe_load_api (module_name, "curl_easy_setopt") + if l_api /= default_pointer then + curl_function.c_set_progress_function (l_api, a_curl_handle) end end @@ -135,12 +168,15 @@ feature -- Special setting do l_api := api_loader.safe_load_api (module_name, "curl_easy_setopt") if l_api /= default_pointer then - c_debug_function (l_api, a_curl_handle) + curl_function.c_set_debug_function (l_api, a_curl_handle) end end feature {NONE} -- Implementation + internal_curl_function: CURL_FUNCTION + -- cURL functions. + api_loader: API_LOADER is -- API dynamic loader once @@ -232,7 +268,7 @@ feature {NONE} -- C externals ]" end - c_setopt (a_api: POINTER; a_curl_handle: POINTER; a_opt: INTEGER; a_data:POINTER) is + c_setopt (a_api: POINTER; a_curl_handle: POINTER; a_opt: INTEGER; a_data: POINTER) is -- C implementation of `setopt_void_star'. -- Declared as curl_easy_setopt (). require @@ -252,47 +288,6 @@ feature {NONE} -- C externals ]" end - c_set_write_function (a_setopt_api: POINTER; a_curl_handle: POINTER) is - -- Setting CURLOPT_WRITEFUNCTION option of `a_curl_handle'. - -- We need this function since cURL need a static c function pointer as value. - require - exists: a_setopt_api /= default_pointer - external - "C inline use " - alias - "[ - { - (FUNCTION_CAST(void, (CURL *, CURLoption, ...)) $a_setopt_api) - ((CURL *) $a_curl_handle, - (CURLoption)CURLOPT_WRITEFUNCTION, - WriteMemoryCallback); - } - ]" - end - - c_debug_function (a_setopt_api: POINTER; a_curl_handle: POINTER) is - -- Setting CURLOPT_DEBUGFUNCTION option of `a_curl_handle'. - -- We need this function since cURL need a static c function pointer as value. - require - exists: a_curl_handle /= default_pointer - external - "C inline use " - alias - "[ - { - (FUNCTION_CAST(void, (CURL *, CURLoption, ...)) $a_setopt_api) - ((CURL *) $a_curl_handle, - (CURLoption)CURLOPT_DEBUGFUNCTION, - curl_trace); - - (FUNCTION_CAST(void, (CURL *, CURLoption, ...)) $a_setopt_api) - ((CURL *) $a_curl_handle, - (CURLoption)CURLOPT_VERBOSE, - TRUE); - } - ]" - end - indexing library: "cURL: Library of reusable components for Eiffel." copyright: "Copyright (c) 1984-2006, Eiffel Software and others" diff --git a/curl_function.e b/curl_function.e new file mode 100644 index 00000000..055de7cc --- /dev/null +++ b/curl_function.e @@ -0,0 +1,166 @@ +indexing + description: "[ + cURL curl_easy_setopt callback functions' Eiffel wrappers. + We need this class since cURL need a c function pointer as value but + Eiffel function need frist parameter of any funciton call is object address. + Client programmers can inherit this class to fit their needs. + ]" + status: "See notice at end of class." + legal: "See notice at end of class." + date: "$Date$" + revision: "$Revision$" + +deferred class + CURL_FUNCTION + +inherit + DISPOSABLE + +feature -- Interactive with C + + set_object_and_function_address is + -- Set object and function addresses. + -- Call this feature before call `c_set_progress_function', `c_set_debug_function' and `c_set_write_function'. + do + c_set_object (Current) + c_set_progress_function_address ($progress_function) + c_set_write_function_address ($write_function) + c_set_debug_function_address ($debug_function) + end + + c_set_progress_function (a_setopt_api: POINTER; a_curl_handle: POINTER) is + -- Setting CURLOPT_PROGRESSFUNCTION option of `a_curl_handle'. + -- We need this function since cURL need a c function pointer as value. + require + exists: a_setopt_api /= default_pointer + external + "C inline use " + alias + "[ + { + (FUNCTION_CAST(void, (CURL *, CURLoption, ...)) $a_setopt_api) + ((CURL *) $a_curl_handle, + (CURLoption)CURLOPT_PROGRESSFUNCTION, + curl_progress_function); + } + ]" + end + + c_set_debug_function (a_setopt_api: POINTER; a_curl_handle: POINTER) is + -- Setting CURLOPT_DEBUGFUNCTION option of `a_curl_handle'. + -- We need this function since cURL need a c function pointer as value. + require + exists: a_curl_handle /= default_pointer + external + "C inline use " + alias + "[ + { + (FUNCTION_CAST(void, (CURL *, CURLoption, ...)) $a_setopt_api) + ((CURL *) $a_curl_handle, + (CURLoption)CURLOPT_DEBUGFUNCTION, + curl_debug_function); + + } + ]" + end + + c_set_write_function (a_setopt_api: POINTER; a_curl_handle: POINTER) is + -- Setting CURLOPT_WRITEFUNCTION option of `a_curl_handle'. + -- We need this function since cURL need a c function pointer as value. + require + exists: a_setopt_api /= default_pointer + external + "C inline use " + alias + "[ + { + (FUNCTION_CAST(void, (CURL *, CURLoption, ...)) $a_setopt_api) + ((CURL *) $a_curl_handle, + (CURLoption)CURLOPT_WRITEFUNCTION, + curl_write_function); + } + ]" + end + +feature -- cURL curl_easy_setopt functions + + progress_function (a_object_id: POINTER; a_download_total, a_download_now, a_upload_total, a_upload_now: REAL_64): INTEGER is + -- Function correspond to {CURL_OPT_CONSTANTS}.curlopt_progressfunction + -- Note, pass a {IDENTIFIED}.object_id as `a_object_id' value is helpful since we can't directly pass an Eiffel Object address which + -- may changed during GC. + deferred + end + + write_function (a_data_pointer: POINTER; a_size, a_nmemb: INTEGER; a_object_id: POINTER): INTEGER is + -- Function correspond to {CURL_OPT_CONSTANTS}.curlopt_writefunction + -- Note, pass a {IDENTIFIED}.object_id as `a_object_id' value is helpful since we can't directly pass an Eiffel Object address which + -- may changed during GC. + deferred + end + + debug_function (a_curl_handle: POINTER; a_curl_infotype: INTEGER; a_char_pointer: POINTER; a_size: INTEGER; a_object_id: POINTER): INTEGER is + -- Function correspond to {CURL_OPT_CONSTANTS}.curlopt_debugfunction + -- Note, pass a {IDENTIFIED}.object_id as `a_object_id' value is helpful since we can't directly pass an Eiffel Object address which + -- may changed during GC. + require + vaild: (create {CURL_INFO_TYPE}).is_valid (a_curl_infotype) + deferred + end + +feature {NONE} -- Externals + + c_set_object (a_object: like Current) is + -- Set Current object address. + external + "C macro signature (EIF_OBJECT) use %"eiffel_curl.h%"" + end + + c_release_object is + -- Release Current pointer in C + external + "C [macro %"eiffel_curl.h%"]" + end + + c_set_progress_function_address (a_address: POINTER) is + -- Set progress function address. + external + "C [macro %"eiffel_curl.h%"]" + end + + c_set_write_function_address (a_address: POINTER) is + -- Set write function address. + external + "C [macro %"eiffel_curl.h%"]" + end + + c_set_debug_function_address (a_address: POINTER) is + -- Set write function address. + external + "C [macro %"eiffel_curl.h%"]" + end + +feature {NONE} -- Implementation + + dispose is + -- Wean `Current' + local + default_object: like Current + do + c_release_object + c_set_object (default_object) + end + +indexing + library: "cURL: Library of reusable components for Eiffel." + copyright: "Copyright (c) 1984-2006, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 356 Storke Road, Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" + +end diff --git a/curl_info_type.e b/curl_info_type.e new file mode 100644 index 00000000..5300bc29 --- /dev/null +++ b/curl_info_type.e @@ -0,0 +1,62 @@ +indexing + description: "[ + cURL library info type constants. + ]" + status: "See notice at end of class." + legal: "See notice at end of class." + date: "$Date$" + revision: "$Revision$" + +class + CURL_INFO_TYPE + +feature -- Enumeration + + curlinfo_text: INTEGER is 0 + -- Declared as CURLINFO_TEXT + + curlinfo_header_in: INTEGER is 1 + -- Declared as CURLINFO_HEADER_IN + + curlinfo_header_out: INTEGER is 2 + -- Declared as CURLINFO_HEADER_OUT + + curlinfo_data_in: INTEGER is 3 + -- Declared as CURLINFO_DATA_IN + + curlinfo_data_out: INTEGER is 4 + -- Declared as CURLINFO_DATA_OUT + + curlinfo_ssl_data_in: INTEGER is 5 + -- Declared as CURLINFO_SSL_DATA_IN + + curlinfo_ssl_data_out: INTEGER is 6 + -- Declared as CURLINFO_SSL_DATA_OUT + +feature -- Contract support + + is_valid (a_type: INTEGER): BOOLEAN is + -- If `a_type' valid? + do + Result := a_type = curlinfo_data_in or + a_type = curlinfo_data_out or + a_type = curlinfo_header_in or + a_type = curlinfo_header_out or + a_type = curlinfo_ssl_data_in or + a_type = curlinfo_ssl_data_out or + a_type = curlinfo_text + end + +indexing + library: "cURL: Library of reusable components for Eiffel." + copyright: "Copyright (c) 1984-2006, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 356 Storke Road, Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" + +end diff --git a/curl_memory_struct.e b/curl_memory_struct.e deleted file mode 100644 index 601c50bb..00000000 --- a/curl_memory_struct.e +++ /dev/null @@ -1,192 +0,0 @@ -indexing - description: "[ - When libcURL write data which get from remote web site, - this memory stuct will be used by Eiffel language to store the data. - For more informaton see: - http://curl.haxx.se/libcurl/c/curl_easy_setopt.html#CURLOPTWRITEDATA - ]" - status: "See notice at end of class." - legal: "See notice at end of class." - date: "$Date$" - revision: "$Revision$" - -class - CURL_MEMORY_STRUCT - -inherit - DISPOSABLE - -create - make - -feature {NONE} -- Intialization - - make is - -- Creation method. - do - item := item.memory_alloc (struct_size) - set_size (0) - set_memory_chunk (default_pointer) - end - -feature -- Query - - item: POINTER - -- Managed pointer. - - size: INTEGER is - -- String size. - do - if item /= default_pointer then - Result := c_size (item) - end - end - - memory_chunk: POINTER is - -- Memory chunk access pointer - do - if item /= default_pointer then - Result := c_memory_chunck (item) - end - end - - string: STRING_GENERAL is - -- Covert to Eiffel String. - -- Maybe void if not exists. - local - l_c_string: C_STRING - l_mem: POINTER - l_size: INTEGER - do - l_mem := c_memory_chunck (item) - l_size := size - if l_mem /= default_pointer and then l_size > 0 then - create l_c_string.share_from_pointer_and_count (l_mem, l_size) - Result := l_c_string.string - end - end - - struct_size: INTEGER is - -- Size of C Structure. - do - Result := c_size_of_memory_struct - ensure - nonnegative: Result >= 0 - end - -feature -- Command - - set_size (a_size: INTEGER) is - -- Set `size' to `a_size' - require - nonnegative: a_size >= 0 - do - c_set_size (item, a_size) - ensure - set: size = a_size - end - - set_memory_chunk (a_ptr: POINTER) is - -- Set `memory_chunk' to `a_ptr'. - do - c_set_memory_chunk (item, a_ptr) - ensure - set: memory_chunk = a_ptr - end - - dispose is - -- Clean up. - local - l_mem: POINTER - do - if item /= default_pointer then - l_mem := c_memory_chunck (item) - if l_mem /= default_pointer then - l_mem.memory_free - end - item.memory_free - item := default_pointer - end - ensure then - cleared: item = default_pointer - end - -feature {NONE} -- C externals - - c_size_of_memory_struct: INTEGER is - -- CURL memory struct struct size. - external - "C [macro ]" - alias - "sizeof (struct cURLMemoryStruct)" - end - - c_size (a_item: POINTER): INTEGER is - -- `a_item''s size - require - exists: a_item /= default_pointer - external - "C inline use " - alias - "[ - ((struct cURLMemoryStruct *)$a_item)->size - ]" - end - - c_set_size (a_item: POINTER; a_size: INTEGER) is - -- Set `a_item''s size to `a_size'. - require - exists: a_item /=default_pointer - external - "C inline use " - alias - "[ - { - ((struct cURLMemoryStruct *)$a_item)->size = $a_size; - } - ]" - ensure - set: c_size (a_item) = a_size - end - - c_memory_chunck (a_item: POINTER): POINTER is - -- `a_item''s memory pointer. - require - exists: a_item /= default_pointer - external - "C inline use " - alias - "[ - ((struct cURLMemoryStruct *)$a_item)->memory - ]" - end - - c_set_memory_chunk (a_item: POINTER; a_ptr: POINTER) is - -- Set `a_item''s memory to `a_ptr'. - require - exists: a_item /= default_pointer - external - "C inline use " - alias - "[ - { - ((struct cURLMemoryStruct *)$a_item)->memory = $a_ptr; - } - ]" - ensure - set: c_memory_chunck (a_item) = a_ptr - end - -indexing - library: "cURL: Library of reusable components for Eiffel." - copyright: "Copyright (c) 1984-2006, Eiffel Software and others" - license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" - source: "[ - Eiffel Software - 356 Storke Road, Goleta, CA 93117 USA - Telephone 805-685-1006, Fax 805-685-6869 - Website http://www.eiffel.com - Customer support http://support.eiffel.com - ]" - -end diff --git a/curl_opt_constants.e b/curl_opt_constants.e index c12171ed..c748e999 100644 --- a/curl_opt_constants.e +++ b/curl_opt_constants.e @@ -154,6 +154,36 @@ feature -- Enumerations. ]" end + curlopt_progressfunction: INTEGER is + -- Declared as CURLOPT_PROGRESSFUNCTION + external + "C inline use " + alias + "[ + return CURLOPT_PROGRESSFUNCTION; + ]" + end + + curlopt_noprogress: INTEGER is + -- Decalred as CURLOPT_NOPROGRESS + external + "C inline use " + alias + "[ + return CURLOPT_NOPROGRESS; + ]" + end + + curlopt_progressdata: INTEGER is + -- Decalred as CURLOPT_PROGRESSDATA + external + "C inline use " + alias + "[ + return CURLOPT_PROGRESSDATA; + ]" + end + is_valid (a_integer: INTEGER): BOOLEAN is -- If `a_integer' value vaild? do @@ -170,7 +200,10 @@ feature -- Enumerations. a_integer = curlopt_verbose or a_integer = curlopt_writedata or a_integer = curlopt_writeheader or - a_integer = curlopt_writefunction + a_integer = curlopt_writefunction or + a_integer = curlopt_progressfunction or + a_integer = curlopt_progressdata or + a_integer = curlopt_noprogress end indexing diff --git a/curl_string.e b/curl_string.e new file mode 100644 index 00000000..ce055282 --- /dev/null +++ b/curl_string.e @@ -0,0 +1,50 @@ +indexing + description: "[ + String used by cURL wrapper library. + Only added features from IDENTIFIED. + ]" + status: "See notice at end of class." + legal: "See notice at end of class." + date: "$Date$" + revision: "$Revision$" + +class + CURL_STRING + +inherit + STRING + select + is_equal, + copy, + out + end + + IDENTIFIED + rename + is_equal as identified_is_equal, + copy as identified_copy, + out as identified_out + end + +create + make, + make_empty, + make_filled, + make_from_string, + make_from_c, + make_from_cil + +indexing + library: "cURL: Library of reusable components for Eiffel." + copyright: "Copyright (c) 1984-2006, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 356 Storke Road, Goleta, CA 93117 USA + Telephone 805-685-1006, Fax 805-685-6869 + Website http://www.eiffel.com + Customer support http://support.eiffel.com + ]" + +end + diff --git a/spec/include/eiffel_curl.h b/spec/include/eiffel_curl.h index 1cf3ec45..fa48272d 100644 --- a/spec/include/eiffel_curl.h +++ b/spec/include/eiffel_curl.h @@ -9,119 +9,140 @@ #include -typedef char bool; -#define TRUE 1 +#include "eif_main.h" + +#ifdef EIF_THREADS +#include "eif_threads.h" +#endif #ifndef eiffel_curl #define eiffel_curl -struct cURLMemoryStruct { - char *memory; - size_t size; -}; - -static void dump(const char *text, FILE *stream, unsigned char *ptr, size_t size,bool nohex) -{ - size_t i; - size_t c; - - unsigned int width=0x10; - - if(nohex) - /* without the hex output, we can fit more on screen */ - width = 0x400; - - fprintf(stream, "%s, %zd bytes (0x%zx)\n", text, size, size); - - for(i=0; i=0x20) && (ptr[i+c]<0x80)?ptr[i+c]:'.'); - /* check again for 0D0A, to avoid an extra \n if it's at width */ - if (nohex && (i+c+2 < size) && ptr[i+c+1]==0x0D && ptr[i+c+2]==0x0A) { - i+=(c+3-width); - break; - } - } - fputc('\n', stream); /* newline */ - } - fflush(stream); -} - -static int curl_trace(CURL *handle, curl_infotype type, unsigned char *data, size_t size, void *userp) -{ - const char *text; - - (void)handle; /* prevent compiler warning */ - - switch (type) { - case CURLINFO_TEXT: - fprintf(stderr, "== Info: %s", data); - default: /* in case a new one is introduced to shock us */ - return 0; - - case CURLINFO_HEADER_OUT: - text = "=> Send header"; - break; - case CURLINFO_DATA_OUT: - text = "=> Send data"; - break; - case CURLINFO_HEADER_IN: - text = "<= Recv header"; - - break; - case CURLINFO_DATA_IN: - text = "<= Recv data"; - break; - } - - dump(text, stderr, data, size, TRUE); - return 0; -} - -static void *eiffel_realloc(void *ptr, size_t size) -{ - /* There might be a realloc() out there that doesn't like reallocing - NULL pointers, so we take care of it here */ - if(ptr) - return realloc(ptr, size); - else - return malloc(size); -} - -static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data) -{ - size_t realsize = size * nmemb; - size_t totalsize; - - struct cURLMemoryStruct *mem = (struct cURLMemoryStruct *)data; - - mem->memory = (char *)eiffel_realloc(mem->memory, mem->size + realsize + 1); - - if (mem->memory) { - memcpy(&(mem->memory[mem->size]), ptr, realsize); - mem->size += realsize; - mem->memory[mem->size] = 0; - } - - return realsize; -} - +typedef EIF_INTEGER (* EIF_CURL_PROGRESS_PROC) ( +#ifndef EIF_IL_DLL + EIF_OBJECT, /* CURL_FUNCTION Eiffel object */ #endif + EIF_POINTER, /* a_user_pointer */ + EIF_REAL_64, /* a_dltotal */ + EIF_REAL_64, /* a_dlnow */ + EIF_REAL_64, /* a_ultotal */ + EIF_REAL_64 /* a_ulnow */ + ); + +typedef EIF_INTEGER (* EIF_CURL_WRITE_PROC) ( +#ifndef EIF_IL_DLL + EIF_OBJECT, /* CURL_FUNCTION Eiffel object */ +#endif + EIF_POINTER, /* a_data_pointer */ + EIF_INTEGER, /* a_size */ + EIF_INTEGER, /* a_nmemb */ + EIF_POINTER /* a_write_pointer */ + ); + +typedef EIF_INTEGER (* EIF_CURL_DEBUG_PROC) ( +#ifndef EIF_IL_DLL + EIF_OBJECT, /* CURL_FUNCTION Eiffel object */ +#endif + EIF_POINTER, /* a_curl_handle */ + EIF_INTEGER, /* a_curl_infotype */ + EIF_POINTER /* a_char_pointer */ + EIF_INTEGER, /* a_size */ + EIF_POINTER /* a_user_pointer */ + ); + +EIF_OBJECT eiffel_function_object = NULL; + /* Address of Eiffel object CURL_FUNCTION */ + +EIF_CURL_PROGRESS_PROC eiffel_progress_function = NULL; + /* Address of Eiffel CURL_FUNCTION.progress_function */ + +EIF_CURL_WRITE_PROC eiffel_write_function = NULL; + /* Address of Eiffel CURL_FUNCTION.write_function */ + +EIF_CURL_DEBUG_PROC eiffel_debug_function = NULL; + /* Address of Eiffel CURL_FUNCTION.debug_function */ + +/* Set Eiffel CURL_FUNCTION object address */ +void c_set_object(EIF_OBJECT a_address) +{ + eiffel_function_object = (EIF_OBJECT) eif_adopt (a_address); +} + +/* Release Eiffel CURL_FUNCTION object address */ +void c_release_object() +{ + eif_wean (eiffel_function_object); +} + +/* Set CURL_FUNCTOIN.progress_function address */ +void c_set_progress_function_address( EIF_POINTER a_address) +{ + eiffel_progress_function = (EIF_CURL_PROGRESS_PROC) a_address; +} + +/* Set CURL_FUNCTOIN.write_function address */ +void c_set_write_function_address( EIF_POINTER a_address) +{ + eiffel_write_function = (EIF_CURL_WRITE_PROC) a_address; +} + +/* Set CURL_FUNCTOIN.debug_function address */ +void c_set_debug_function_address (EIF_POINTER a_address) +{ + eiffel_debug_function = (EIF_CURL_DEBUG_PROC) a_address; +} + +/* Eiffel adapter function for CURLOPT_WRITEFUNCTION + We need this function since Eiffel function call need first parameter is EIF_OBJECT. */ +size_t curl_write_function (void *ptr, size_t size, size_t nmemb, void *data) +{ + if (eiffel_function_object) { + return (size_t) ((eiffel_write_function) ( +#ifndef EIF_IL_DLL + (EIF_OBJECT) eif_access (eiffel_function_object), +#endif + (EIF_POINTER) ptr, + (EIF_INTEGER) size, + (EIF_INTEGER) nmemb, + (EIF_POINTER) data)); + } else { + } +} + +/* Eiffel adapter function for CURLOPT_PROGRESSFUNCTION + We need this function since Eiffel function call need first parameter is EIF_OBJECT. */ +size_t curl_progress_function (void * a_object_id, double a_dltotal, double a_dlnow, double a_ultotal, double a_ulnow) + { + if (eiffel_function_object) { + return (size_t) ((eiffel_progress_function) ( +#ifndef EIF_IL_DLL + (EIF_OBJECT) eif_access (eiffel_function_object), +#endif + (EIF_POINTER) a_object_id, + (EIF_REAL_64) a_dltotal, + (EIF_REAL_64) a_dlnow, + (EIF_REAL_64) a_ultotal, + (EIF_REAL_64) a_ulnow)); + } else { + } + } + +/* Eiffel adapter function for CURLOPT_DEBUGFUNCTION + We need this function since Eiffel function call need first parameter is EIF_OBJECT. */ +size_t curl_debug_function (CURL * a_curl_handle, curl_infotype a_curl_infotype, unsigned char * a_char_pointer, size_t a_size, void * a_object_id) + { + if (eiffel_function_object) { + return (size_t) ((eiffel_debug_function) ( +#ifndef EIF_IL_DLL + (EIF_OBJECT) eif_access (eiffel_function_object), +#endif + (EIF_POINTER) a_curl_handle, + (EIF_INTEGER) a_curl_infotype, + (EIF_POINTER) a_char_pointer, + (EIF_INTEGER) a_size, + (EIF_POINTER) a_object_id)); + } else { + } + } + +#endif