diff --git a/curl_msg.e b/curl_msg.e new file mode 100644 index 00000000..3a318a81 --- /dev/null +++ b/curl_msg.e @@ -0,0 +1,51 @@ +note + description: "[ + C CURLMSG enum + ]" + date: "$Date$" + revision: "$Revision$" + +class + CURL_MSG + +feature -- Query + + curlmsg_done: INTEGER + -- Declared as CURLMSG_DONE. + -- This easy handle has completed. + -- 'result' contains the CURLcode of the transfer + external + "C inline use " + alias + "return CURLMSG_DONE;" + end + + curlmsg_none: INTEGER + -- Declared as CURLMSG_NONE. + -- First, not used + external + "C inline use " + alias + "return CURLMSG_NONE;" + end + + curlmsg_last: INTEGER + -- Declared as CURLMSG_LAST. + -- Last, not used + external + "C inline use " + alias + "return CURLMSG_LAST;" + end + +note + copyright: "Copyright (c) 1984-2012, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., 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_msg_struct.e b/curl_msg_struct.e new file mode 100644 index 00000000..b5e618a1 --- /dev/null +++ b/curl_msg_struct.e @@ -0,0 +1,83 @@ +note + description: "[ + + C Struct CURLMsg wrapper + Read multi stack informationals + + This class is used by {CURL_MSG_STRUCT}.info_read + + More info: + http://curl.haxx.se/libcurl/c/curl_multi_info_read.html + ]" + date: "$Date$" + revision: "$Revision$" + +class + CURL_MSG_STRUCT + +create + make + +feature {NONE} -- Initialization + + make (a_pointer: POINTER) + -- Creation method + -- Bind message structure to the address `a_pointer'". + require + not_default: a_pointer /= default_pointer + do + item := a_pointer + ensure + set: item = a_pointer + end + +feature -- Query + + curl_handle: POINTER + -- CURL easy_handle + -- The handle it concerns + do + Result := c_curl_handle (item) + end + + msg: INTEGER + -- What does this message mean? + -- It's one value from {CURLMSG} + do + Result := c_msg (item) + end + +feature {NONE} -- Implementation + + item: POINTER + -- C struct item + +feature {NONE} -- C externals + + c_curl_handle (a_item: POINTER): POINTER + -- cURL easy handle it concerns + external + "C inline use " + alias + "return (CURL *)((CURLMsg *)$a_item)->easy_handle;" + end + + c_msg (a_item: POINTER): INTEGER + -- Get msg + external + "C inline use " + alias + "return (CURLMSG)((CURLMsg *)$a_item)->msg;" + end + +;note + copyright: "Copyright (c) 1984-2012, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., 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_multi_codes.e b/curl_multi_codes.e new file mode 100644 index 00000000..44951a36 --- /dev/null +++ b/curl_multi_codes.e @@ -0,0 +1,48 @@ +note + description: "[ + The generic return code used by functions in the libcurl multi interface. + Also consider curl_multi_strerror(3). + ]" + date: "$Date$" + revision: "$Revision$" + +class + CURL_MULTI_CODES + +feature -- Query + + curlm_call_multi_perform: INTEGER = -1 + -- This is not really an error. It means you should call curl_multi_perform(3) again without doing select() or similar in between. + + curlm_ok: INTEGER = 0 + -- Things are fine. + + curlm_bad_handle: INTEGER = 1 + -- The passed-in handle is not a valid CURLM handle. + + curlm_bad_easy_handle: INTEGER = 2 + -- An easy handle was not good/valid. It could mean that it isn't an easy handle at all, or possibly that the handle already is in used by this or another multi handle. + + curlm_out_of_memory: INTEGER = 3 + -- You are doomed. + + curlm_internal_error: INTEGER = 4 + -- This can only be returned if libcurl bugs. Please report it to us! + + curlm_bad_socket: INTEGER = 5 + -- The passed-in socket is not a valid one that libcurl already knows about. (Added in 7.15.4) + + curlm_unknown_option: INTEGER = 6 + -- curl_multi_setopt() with unsupported option (Added in 7.15.4) + +note + copyright: "Copyright (c) 1984-2012, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., 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_multi_externals.e b/curl_multi_externals.e new file mode 100644 index 00000000..2ee944b0 --- /dev/null +++ b/curl_multi_externals.e @@ -0,0 +1,251 @@ +note + description: "[ + The multi interface offers several abilities that the easy interface doesn't. They are mainly: + 1. Enable a "pull" interface. The application that uses libcurl decides where and when to ask libcurl to get/send data. + 2. Enable multiple simultaneous transfers in the same thread without making it complicated for the application. + 3. Enable the application to wait for action on its own file descriptors and curl's file descriptors simultaneous easily. + + More info: http://curl.haxx.se/libcurl/c/libcurl-multi.html + ]" + date: "$Date$" + revision: "$Revision$" + +class + CURL_MULTI_EXTERNALS + +feature -- Command + + init + -- Create a multi handle. + -- If success, Result is a cURL multi hanlde just created. + -- This feature maybe failed in some cases: cannot find required DLL, etc. + -- Then the post condition would be violated. + require + dynamic_library_exists: is_dynamic_library_exists + local + l_api: POINTER + do + l_api := api_loader.api_pointer ("curl_multi_init") + if l_api /= default_pointer then + item := c_init (l_api) + end + end + + add_handle (a_easy_handle: POINTER) + -- Add an easy handle to a multi session. + require + dynamic_library_exists: is_dynamic_library_exists + is_multi_handle_exists: is_exists + local + l_api: POINTER + do + l_api := api_loader.api_pointer ("curl_multi_add_handle") + if l_api /= default_pointer then + c_add_handle (l_api, item, a_easy_handle) + end + end + + remove_handle (a_easy_handle: POINTER) + -- Remove an easy handle from a multi session. + require + dynamic_library_exists: is_dynamic_library_exists + is_multi_handle_exists: is_exists + local + l_api: POINTER + do + l_api := api_loader.api_pointer ("curl_multi_remove_handle") + if l_api /= default_pointer then + c_remove_handle (l_api, item, a_easy_handle) + end + end + + cleanup: INTEGER + -- Close down a multi session. + -- Result is one value from {CURL_MULTI_CODES}. + require + dynamic_library_exists: is_dynamic_library_exists + is_multi_handle_exists: is_exists + local + l_api: POINTER + do + l_api := api_loader.api_pointer ("curl_multi_cleanup") + if l_api /= default_pointer then + Result := c_cleanup (l_api, item) + end + end + + perform (a_running_handle: CELL [INTEGER]): INTEGER + -- Reads/writes available data from each easy handle. + -- Result is one value from {CURL_MULTI_CODES}. + require + dynamic_library_exists: is_dynamic_library_exists + is_multi_handle_exists: is_exists + local + l_api: POINTER + l_running_handle: INTEGER + do + l_api := api_loader.api_pointer ("curl_multi_perform") + if l_api /= default_pointer then + Result := c_perform (l_api, item, $l_running_handle) + a_running_handle.put (l_running_handle) + end + end + + info_read (a_msgs_in_queue: CELL [INTEGER]): POINTER + -- Read multi stack informationals. + -- The result is C struct CURLMsg {CURL_MSG_STRUCT}. + -- Repeated calls to this function will return a new struct each time, until a NULL + -- is returned as a signal that there is no more to get at this point. The integer + -- pointed to with msgs_in_queue will contain the number of remaining messages after + -- this function was called. + -- When you fetch a message using this function, it is removed from the internal queue + -- so calling this function again will not return the same message again. It will instead + -- return new messages at each new invoke until the queue is emptied. + require + dynamic_library_exists: is_dynamic_library_exists + is_multi_handle_exists: is_exists + local + l_api: POINTER + l_msgs_in_queue: INTEGER + do + l_api := api_loader.api_pointer ("curl_multi_info_read") + if l_api /= default_pointer then + Result := c_info_read (l_api, item, $l_msgs_in_queue) + a_msgs_in_queue.put (l_msgs_in_queue) + end + end + + is_dynamic_library_exists: BOOLEAN + -- Are required .dll/.so files available? + do + Result := api_loader.is_interface_usable + end + +-- Feature not yet wrapped/tested +-- curl_multi_assign +-- curl_multi_fdset +-- curl_multi_setopt +-- curl_multi_socket +-- curl_multi_socket_action +-- curl_multi_strerror +-- curl_multi_timeout + +feature -- Query + + is_exists: BOOLEAN + -- If C pointer exists? + do + Result := item /= default_pointer + end + +feature {NONE} -- Implementation + + item: POINTER + -- C pointer item for cURL multi + +feature {NONE} -- C externals + + c_init (a_api: POINTER): POINTER + -- Declared as curl_multi_init (). + require + exists: a_api /= default_pointer + external + "C inline use " + alias + "[ + return (FUNCTION_CAST(CURLM *, ()) $a_api)(); + ]" + end + + c_cleanup (a_api: POINTER; a_multi_handle: POINTER): INTEGER + -- Declared as curl_multi_cleanup (). + require + exists: a_api /= default_pointer + external + "C inline use " + alias + "[ + return (FUNCTION_CAST(CURLMcode, (CURLM *)) $a_api) + ((CURLM *)$a_multi_handle); + ]" + end + + c_add_handle (a_api: POINTER; a_multi_handle: POINTER; a_easy_handle: POINTER) + -- Declared as curl_multi_add_handle (). + require + exists: a_api /= default_pointer + external + "C inline use " + alias + "[ + (FUNCTION_CAST(void, (CURLM *, CURL *)) $a_api) + ((CURLM *) $a_multi_handle, + (CURL *) $a_easy_handle); + ]" + end + + c_remove_handle (a_api: POINTER; a_multi_handle: POINTER; a_easy_handle: POINTER) + -- Declared as curl_multi_remove_handle (). + require + exists: a_api /= default_pointer + external + "C inline use " + alias + "[ + (FUNCTION_CAST(void, (CURLM *, CURL *)) $a_api) + ((CURLM *) $a_multi_handle, + (CURL *) $a_easy_handle); + ]" + end + + c_perform (a_api: POINTER; a_multi_handle: POINTER; a_running_handles: TYPED_POINTER [INTEGER]): INTEGER + -- Declared as curl_multi_perform. + require + exists: a_api /= default_pointer + external + "C inline use " + alias + "[ + return (FUNCTION_CAST(CURLMcode, (CURLM *, int *)) $a_api) + ((CURLM *) $a_multi_handle, + (int *) $a_running_handles); + ]" + end + + c_info_read (a_api: POINTER; a_multi_handle: POINTER; a_msgs_in_queue: TYPED_POINTER [INTEGER]): POINTER + -- Declared as curl_multi_info_read. + require + exists: a_api /= default_pointer + external + "C inline use " + alias + "[ + return (FUNCTION_CAST(CURLMsg *, (CURLM *, int *)) $a_api) + ((CURLM *) $a_multi_handle, + (int *) $a_msgs_in_queue); + ]" + end + +feature {NONE} -- Implementation + + api_loader: DYNAMIC_MODULE + -- Module name. + local + l_utility: CURL_UTILITY + once + create l_utility + Result := l_utility.api_loader + end + + +note + copyright: "Copyright (c) 1984-2012, Eiffel Software and others" + license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" + source: "[ + Eiffel Software + 5949 Hollister Ave., 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 7adb0ea8..372e3f27 100644 --- a/curl_opt_constants.e +++ b/curl_opt_constants.e @@ -624,6 +624,17 @@ feature -- Connection "return CURLOPT_TIMEOUT" end + curlopt_connect_timeout: INTEGER + -- The number of seconds to wait while trying to connect. Use 0 to wait indefinitely. + -- Declared as CURLOPT_CONNECTTIMEOUT + external + "C inline use " + alias + "[ + return CURLOPT_CONNECTTIMEOUT + ]" + end + curlopt_timeout_ms: INTEGER -- Declared as CURLOPT_TIMEOUT_MS external @@ -1093,7 +1104,7 @@ feature -- Status report note library: "cURL: Library of reusable components for Eiffel." - copyright: "Copyright (c) 1984-2011, Eiffel Software and others" + copyright: "Copyright (c) 1984-2012, Eiffel Software and others" license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)" source: "[ Eiffel Software