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
This commit is contained in:
105
curl_default_function.e
Normal file
105
curl_default_function.e
Normal file
@@ -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
|
||||
@@ -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 <eiffel_curl.h>"
|
||||
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 <eiffel_curl.h>"
|
||||
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"
|
||||
|
||||
166
curl_function.e
Normal file
166
curl_function.e
Normal file
@@ -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 <eiffel_curl.h>"
|
||||
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 <eiffel_curl.h>"
|
||||
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 <eiffel_curl.h>"
|
||||
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
|
||||
62
curl_info_type.e
Normal file
62
curl_info_type.e
Normal file
@@ -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
|
||||
@@ -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 <eiffel_curl.h>]"
|
||||
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 <eiffel_curl.h>"
|
||||
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 <eiffel_curl.h>"
|
||||
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 <eiffel_curl.h>"
|
||||
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 <eiffel_curl.h>"
|
||||
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
|
||||
@@ -154,6 +154,36 @@ feature -- Enumerations.
|
||||
]"
|
||||
end
|
||||
|
||||
curlopt_progressfunction: INTEGER is
|
||||
-- Declared as CURLOPT_PROGRESSFUNCTION
|
||||
external
|
||||
"C inline use <curl/curl.h>"
|
||||
alias
|
||||
"[
|
||||
return CURLOPT_PROGRESSFUNCTION;
|
||||
]"
|
||||
end
|
||||
|
||||
curlopt_noprogress: INTEGER is
|
||||
-- Decalred as CURLOPT_NOPROGRESS
|
||||
external
|
||||
"C inline use <curl/curl.h>"
|
||||
alias
|
||||
"[
|
||||
return CURLOPT_NOPROGRESS;
|
||||
]"
|
||||
end
|
||||
|
||||
curlopt_progressdata: INTEGER is
|
||||
-- Decalred as CURLOPT_PROGRESSDATA
|
||||
external
|
||||
"C inline use <curl/curl.h>"
|
||||
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
|
||||
|
||||
50
curl_string.e
Normal file
50
curl_string.e
Normal file
@@ -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
|
||||
|
||||
@@ -9,119 +9,140 @@
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
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;
|
||||
};
|
||||
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 */
|
||||
);
|
||||
|
||||
static void dump(const char *text, FILE *stream, unsigned char *ptr, size_t size,bool nohex)
|
||||
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)
|
||||
{
|
||||
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<size; i+= width) {
|
||||
|
||||
fprintf(stream, "%04zx: ", i);
|
||||
|
||||
if(!nohex) {
|
||||
/* hex not disabled, show it */
|
||||
for(c = 0; c < width; c++)
|
||||
if(i+c < size)
|
||||
fprintf(stream, "%02x ", ptr[i+c]);
|
||||
else
|
||||
fputs(" ", stream);
|
||||
}
|
||||
|
||||
for(c = 0; (c < width) && (i+c < size); c++) {
|
||||
/* check for 0D0A; if found, skip past and start a new line of output */
|
||||
if (nohex && (i+c+1 < size) && ptr[i+c]==0x0D && ptr[i+c+1]==0x0A) {
|
||||
i+=(c+2-width);
|
||||
break;
|
||||
}
|
||||
fprintf(stream, "%c",
|
||||
(ptr[i+c]>=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);
|
||||
eiffel_function_object = (EIF_OBJECT) eif_adopt (a_address);
|
||||
}
|
||||
|
||||
static int curl_trace(CURL *handle, curl_infotype type, unsigned char *data, size_t size, void *userp)
|
||||
/* Release Eiffel CURL_FUNCTION object address */
|
||||
void c_release_object()
|
||||
{
|
||||
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;
|
||||
eif_wean (eiffel_function_object);
|
||||
}
|
||||
|
||||
static void *eiffel_realloc(void *ptr, size_t size)
|
||||
/* Set CURL_FUNCTOIN.progress_function address */
|
||||
void c_set_progress_function_address( EIF_POINTER a_address)
|
||||
{
|
||||
/* 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);
|
||||
eiffel_progress_function = (EIF_CURL_PROGRESS_PROC) a_address;
|
||||
}
|
||||
|
||||
static size_t WriteMemoryCallback(void *ptr, size_t size, size_t nmemb, void *data)
|
||||
/* Set CURL_FUNCTOIN.write_function address */
|
||||
void c_set_write_function_address( EIF_POINTER a_address)
|
||||
{
|
||||
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;
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user