Added features related with curlopt_readfunction (for setting and using read function), so users can read data from local machine and send the data to server.

Added curlopt_put and other constance to {CURL_OPT_CONSTATNS} which used by {CURL_EASY_EXTERNALS}

Contributed by Heiko Gering 

git-svn-id: https://svn.origo.ethz.ch/eiffelstudio/trunk/Src/library/cURL@77404 8089f293-4706-0410-a29e-feb5c42a2edf
This commit is contained in:
larryl
2009-02-27 13:02:12 +00:00
parent e880fbde14
commit caf6d8c528
6 changed files with 165 additions and 7 deletions

View File

@@ -35,6 +35,17 @@ typedef EIF_INTEGER (* EIF_CURL_WRITE_PROC) (
EIF_POINTER /* a_write_pointer */
);
typedef EIF_INTEGER (* EIF_CURL_READ_PROC) (
#ifndef EIF_IL_DLL
EIF_REFERENCE, /* 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_REFERENCE, /* CURL_FUNCTION Eiffel object */
@@ -55,6 +66,9 @@ static EIF_CURL_PROGRESS_PROC eiffel_progress_function = NULL;
static EIF_CURL_WRITE_PROC eiffel_write_function = NULL;
/* Address of Eiffel CURL_FUNCTION.write_function */
static EIF_CURL_READ_PROC eiffel_read_function = NULL;
/* Address of Eiffel CURL_FUNCTION.read_function */
static EIF_CURL_DEBUG_PROC eiffel_debug_function = NULL;
/* Address of Eiffel CURL_FUNCTION.debug_function */
@@ -86,6 +100,12 @@ void c_set_write_function_address( EIF_POINTER a_address)
eiffel_write_function = (EIF_CURL_WRITE_PROC) a_address;
}
/* Set CURL_FUNCTOIN.read_function address */
void c_set_read_function_address( EIF_POINTER a_address)
{
eiffel_read_function = (EIF_CURL_READ_PROC) a_address;
}
/* Set CURL_FUNCTOIN.debug_function address */
void c_set_debug_function_address (EIF_POINTER a_address)
{
@@ -110,6 +130,25 @@ size_t curl_write_function (void *ptr, size_t size, size_t nmemb, void *data)
}
}
/* Eiffel adapter function for CURLOPT_READFUNCTION
We need this function since Eiffel function call need first parameter is EIF_REFERENCE. */
size_t curl_read_function (void *ptr, size_t size, size_t nmemb, void *data)
{
if (eiffel_function_object) {
return (size_t) ((eiffel_read_function) (
#ifndef EIF_IL_DLL
(EIF_REFERENCE) eif_access (eiffel_function_object),
#endif
(EIF_POINTER) ptr,
(EIF_INTEGER) size,
(EIF_INTEGER) nmemb,
(EIF_POINTER) data));
} else {
return 0;
}
}
/* Eiffel adapter function for CURLOPT_PROGRESSFUNCTION
We need this function since Eiffel function call need first parameter is EIF_REFERENCE. */
size_t curl_progress_function (void * a_object_id, double a_dltotal, double a_dlnow, double a_ultotal, double a_ulnow)

View File

@@ -1,4 +1,4 @@
note
indexing
description: "[
Default implementation of CURL_FUNCTION.
]"
@@ -48,6 +48,11 @@ feature -- Command
end
end
read_function (a_data_pointer: POINTER; a_size, a_nmemb: INTEGER; a_object_id: POINTER): INTEGER
-- A callback readfunction
do
end
debug_function (a_curl_handle: POINTER; a_curl_infotype: INTEGER; a_char_pointer: POINTER; a_size: INTEGER; a_object_id: POINTER): INTEGER
-- Redefine
local

View File

@@ -1,4 +1,4 @@
note
indexing
description: "[
cURL easy externals.
For more informaton see:
@@ -95,6 +95,16 @@ feature -- Command
end
end
setopt_file (a_curl_handle: POINTER; a_opt: INTEGER; a_file: FILE)
-- Declared as curl_easy_setopt().
require
exists: a_curl_handle /= default_pointer
valid: a_opt = {CURL_OPT_CONSTANTS}.curlopt_readdata
readable: a_file /= void and then a_file.file_readable
do
setopt_void_star (a_curl_handle, a_opt, a_file.file_pointer)
end
perform (a_curl_handle: POINTER): INTEGER
-- Declared as curl_easy_perform().
-- Result is one value from {CURL_CODES}
@@ -170,6 +180,21 @@ feature -- Special setting
end
end
set_read_function (a_curl_handle: POINTER)
-- Set cURL read function
-- Set cURL read function with Eiffel default read function.
-- So we can use a c file pointer as parameter in {CURL_EASY_EXTERNALS}.setopt_file_pointer when the option is {CURL_OPT_CONSTANTS}.curlopt_readdata
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_read_function (l_api, a_curl_handle)
end
end
set_progress_function (a_curl_handle: POINTER)
-- Set cURL progress function for upload/download progress.
require

View File

@@ -1,4 +1,4 @@
note
indexing
description: "[
cURL curl_easy_setopt callback functions' Eiffel wrappers.
We need this class since cURL need a c function pointer as value but
@@ -20,11 +20,12 @@ feature -- Interactive with C
set_object_and_function_address
-- Set object and function addresses.
-- Call this feature before call `c_set_progress_function', `c_set_debug_function' and `c_set_write_function'.
-- Call this feature before call `c_set_progress_function', `c_set_debug_function' and `c_set_write_function, c_set_read_function'.
do
c_set_object ($Current)
c_set_progress_function_address ($progress_function)
c_set_write_function_address ($write_function)
c_set_read_function_address ($read_function)
c_set_debug_function_address ($debug_function)
end
@@ -83,6 +84,24 @@ feature -- Interactive with C
]"
end
c_set_read_function (a_setopt_api: POINTER; a_curl_handle: POINTER)
-- Setting CURLOPT_READFUNCTION 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 <eiffel_curl.h>"
alias
"[
{
(FUNCTION_CAST(void, (CURL *, CURLoption, ...)) $a_setopt_api)
((CURL *) $a_curl_handle,
(CURLoption)CURLOPT_READFUNCTION,
curl_read_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
@@ -99,6 +118,13 @@ feature -- cURL curl_easy_setopt functions
deferred
end
read_function (a_data_pointer: POINTER; a_size, a_nmemb: INTEGER; a_object_id: POINTER): INTEGER
-- Function correspond to {CURL_OPT_CONSTANTS}.curlopt_readfunction
-- 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
-- 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
@@ -134,6 +160,12 @@ feature {NONE} -- Externals
"C use %"eiffel_curl.h%""
end
c_set_read_function_address (a_address: POINTER)
-- Set read function address.
external
"C use %"eiffel_curl.h%""
end
c_set_debug_function_address (a_address: POINTER)
-- Set write function address.
external

View File

@@ -216,8 +216,58 @@ feature -- Enumerations.
]"
end
curlopt_readfunction: INTEGER
-- Declared as CURLOPT_READFUNCTION.
external
"C inline use <curl/curl.h>"
alias
"[
return CURLOPT_READFUNCTION;
]"
end
curlopt_upload: INTEGER
-- Declared as CURLOPT_UPLOAD.
external
"C inline use <curl/curl.h>"
alias
"[
return CURLOPT_UPLOAD;
]"
end
curlopt_put: INTEGER
-- Declared as CURLOPT_PUT.
external
"C inline use <curl/curl.h>"
alias
"[
return CURLOPT_PUT;
]"
end
curlopt_readdata: INTEGER
-- Declared as CURLOPT_READDATA.
external
"C inline use <curl/curl.h>"
alias
"[
return CURLOPT_READDATA;
]"
end
curlopt_infilesize_large: INTEGER
-- Declared as CURLOPT_INFILESIZE_LARGE.
external
"C inline use <curl/curl.h>"
alias
"[
return CURLOPT_INFILESIZE_LARGE;
]"
end
is_valid (a_integer: INTEGER): BOOLEAN
-- If `a_integer' value vaild?
-- If `a_integer' value valid?
do
Result := a_integer = curlopt_cookie or
a_integer = curlopt_cookiefile or
@@ -238,7 +288,12 @@ feature -- Enumerations.
a_integer = curlopt_progressdata or
a_integer = curlopt_noprogress or
a_integer = curlopt_referer or
a_integer = curlopt_httpget
a_integer = curlopt_httpget or
a_integer = curlopt_readfunction or
a_integer = curlopt_upload or
a_integer = curlopt_put or
a_integer = curlopt_readdata or
a_integer = curlopt_infilesize_large
end
note

View File

@@ -32,9 +32,11 @@ extern "C" {
extern void c_set_object(EIF_REFERENCE a_address);
extern void c_release_object(void);
extern void c_set_progress_function_address( EIF_POINTER a_address);
extern void c_set_read_function_address( EIF_POINTER a_address);
extern void c_set_write_function_address( EIF_POINTER a_address);
extern void c_set_debug_function_address (EIF_POINTER a_address);
extern size_t curl_write_function (void *ptr, size_t size, size_t nmemb, void *data);
extern size_t curl_read_function (void *ptr, size_t size, size_t nmemb, void *data);
extern size_t curl_progress_function (void * a_object_id, double a_dltotal, double a_dlnow, double a_ultotal, double a_ulnow);
extern 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);