From 6df7363a2aafacf4f2d01aedf5738cbe81083f51 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alexis=20Laferri=C3=A8re?= Date: Sat, 6 Jun 2015 16:28:05 -0400 Subject: [PATCH] lib/curl: update and clean up the callback system MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexis Laferrière --- lib/curl/curl.nit | 12 ++--- lib/curl/curl_c.nit | 145 ++++++++++++++++++++++++--------------------------- 2 files changed, 75 insertions(+), 82 deletions(-) diff --git a/lib/curl/curl.nit b/lib/curl/curl.nit index dbfc157..027fd95 100644 --- a/lib/curl/curl.nit +++ b/lib/curl/curl.nit @@ -108,10 +108,10 @@ class CurlHTTPRequest if not err.is_ok then return answer_failure(err.to_i, err.to_s) # Callbacks - err = self.curl.prim_curl.register_callback(callback_receiver, new CURLCallbackType.header) + err = self.curl.prim_curl.register_callback_header(callback_receiver) if not err.is_ok then return answer_failure(err.to_i, err.to_s) - err = self.curl.prim_curl.register_callback(callback_receiver, new CURLCallbackType.body) + err = self.curl.prim_curl.register_callback_body(callback_receiver) if not err.is_ok then return answer_failure(err.to_i, err.to_s) # HTTP Header @@ -153,10 +153,10 @@ class CurlHTTPRequest err = self.curl.prim_curl.easy_setopt(new CURLOption.url, url) if not err.is_ok then return answer_failure(err.to_i, err.to_s) - err = self.curl.prim_curl.register_callback(callback_receiver, new CURLCallbackType.header) + err = self.curl.prim_curl.register_callback_header(callback_receiver) if not err.is_ok then return answer_failure(err.to_i, err.to_s) - err = self.curl.prim_curl.register_callback(callback_receiver, new CURLCallbackType.stream) + err = self.curl.prim_curl.register_callback_stream(callback_receiver) if not err.is_ok then return answer_failure(err.to_i, err.to_s) var opt_name @@ -317,7 +317,7 @@ class CurlMailRequest content = add_conventional_space(content) content = add_pair_to_content(content, "", self.body) content = add_conventional_space(content) - err = self.curl.prim_curl.register_callback(self, once new CURLCallbackType.read) + err = self.curl.prim_curl.register_callback_read(self) if not err.is_ok then return answer_failure(err.to_i, err.to_s) err = self.curl.prim_curl.register_read_datas_callback(self, content) if not err.is_ok then return answer_failure(err.to_i, err.to_s) @@ -398,7 +398,7 @@ class CurlFileResponseSuccess private var i_file: nullable OFile = null # Receive bytes stream from request due to stream callback registering - redef fun stream_callback(buffer, size, count) + redef fun stream_callback(buffer) do self.i_file.write(buffer, size, count) end diff --git a/lib/curl/curl_c.nit b/lib/curl/curl_c.nit index 7d28842..d16c69b 100644 --- a/lib/curl/curl_c.nit +++ b/lib/curl/curl_c.nit @@ -20,18 +20,6 @@ module curl_c is pkgconfig("libcurl") in "C header" `{ #include - typedef enum { - CURLcallbackTypeHeader, - CURLcallbackTypeBody, - CURLcallbackTypeStream, - CURLcallbackTypeRead, - } CURLcallbackType; - - typedef struct { - CCurlCallbacks delegate; - CURLcallbackType type; - } CURLCallbackDatas; - typedef struct { char *data; int len; @@ -44,26 +32,6 @@ in "C body" `{ #include #include - // Callbacks method for Header, Body, Stream. - size_t nit_curl_callback_func(void *buffer, size_t size, size_t count, CURLCallbackDatas *datas){ - if(datas->type == CURLcallbackTypeHeader){ - char *line_c = (char*)buffer; - String line_o = NativeString_to_s_with_copy(line_c); - CCurlCallbacks_header_callback(datas->delegate, line_o); - } - else if(datas->type == CURLcallbackTypeBody){ - char *line_c = (char*)buffer; - String line_o = NativeString_to_s_with_copy(line_c); - CCurlCallbacks_body_callback(datas->delegate, line_o); - } - else if(datas->type == CURLcallbackTypeStream){ - char *line_c = (char*)buffer; - String line_o = NativeString_to_s(line_c); - CCurlCallbacks_stream_callback(datas->delegate, line_o, size, count); - } - return count; - } - // Callback method to read datas from buffer. size_t nit_curl_callback_read_func(void *buffer, size_t size, size_t count, CURLCallbackReadDatas *datas){ int len = datas->len - datas->pos; @@ -74,6 +42,30 @@ in "C body" `{ } `} +redef extern class NativeString + private fun native_callback_header(size, count: Int, target: CCurlCallbacks): Int + do + target.header_callback to_s_with_length(size*count) + + # FIXME we probably should return a value from the user + return count + end + + private fun native_callback_body(size, count: Int, target: CCurlCallbacks): Int + do + target.body_callback to_s_with_length(size*count) + + return count + end + + private fun native_callback_stream(size, count: Int, target: CCurlCallbacks): Int + do + target.stream_callback to_s_with_length(size*count) + + return count + end +end + # CURL Extern Type, reproduce CURL low level behaviors extern class CCurl `{ CURL * `} # Constructor, CURL low level initializer @@ -186,15 +178,6 @@ extern class CCurl `{ CURL * `} return ce; `} - # Register delegate to get callbacks about the CURL transfer performed - fun register_callback(delegate: CCurlCallbacks, cbtype: CURLCallbackType): CURLCode - do - if once [new CURLCallbackType.header, new CURLCallbackType.body, new CURLCallbackType.stream, new CURLCallbackType.read].has(cbtype) then - return i_register_callback(delegate, cbtype) - end - return once new CURLCode.unknown_option - end - # Register delegate to read datas from given buffer fun register_read_datas_callback(delegate: CCurlCallbacks, datas: String): CURLCode do @@ -212,33 +195,53 @@ extern class CCurl `{ CURL * `} return curl_easy_setopt( self, CURLOPT_READDATA, d); `} - # Internal method used to configure callbacks in terms of given type - private fun i_register_callback(delegate: CCurlCallbacks, cbtype: CURLCallbackType):CURLCode is extern import CCurlCallbacks.native_header_callback, CCurlCallbacks.native_body_callback, CCurlCallbacks.native_stream_callback `{ - CURLCallbackDatas *d = malloc(sizeof(CURLCallbackDatas)); + # Register `delegate` to get callbacks about the CURL transfer + fun register_callback_header(delegate: CCurlCallbacks): CURLCode + import NativeString.native_callback_header `{ + CURLcode e; + CCurlCallbacks_incr_ref(delegate); // FIXME deallocated these when download completes? + + e = curl_easy_setopt(self, CURLOPT_HEADERFUNCTION, (curl_write_callback)&NativeString_native_callback_header); + if(e != CURLE_OK) return e; + + e = curl_easy_setopt(self, CURLOPT_WRITEHEADER, delegate); + return e; + `} + + # Register `delegate` to get callbacks about the CURL transfer + fun register_callback_body(delegate: CCurlCallbacks): CURLCode + import NativeString.native_callback_body `{ + CURLcode e; CCurlCallbacks_incr_ref(delegate); - d->type = cbtype; - d->delegate = delegate; + + e = curl_easy_setopt(self, CURLOPT_WRITEFUNCTION, (curl_write_callback)&NativeString_native_callback_body); + if(e != CURLE_OK) return e; + + e = curl_easy_setopt(self, CURLOPT_WRITEDATA, delegate); + return e; + `} + + # Register `delegate` to get callbacks about the CURL transfer + fun register_callback_stream(delegate: CCurlCallbacks): CURLCode + import NativeString.native_callback_stream `{ CURLcode e; - switch(cbtype){ - case CURLcallbackTypeHeader: - e = curl_easy_setopt( self, CURLOPT_HEADERFUNCTION, (curl_write_callback)&nit_curl_callback_func); - if(e != CURLE_OK) return e; - e = curl_easy_setopt( self, CURLOPT_WRITEHEADER, d); - break; - case CURLcallbackTypeBody: - case CURLcallbackTypeStream: - e = curl_easy_setopt( self, CURLOPT_WRITEFUNCTION, (curl_write_callback)&nit_curl_callback_func); - if(e != CURLE_OK) return e; - e = curl_easy_setopt( self, CURLOPT_WRITEDATA, d); - break; - case CURLcallbackTypeRead: - e = curl_easy_setopt( self, CURLOPT_READFUNCTION, (curl_write_callback)&nit_curl_callback_read_func); - default: - break; - } + CCurlCallbacks_incr_ref(delegate); + + e = curl_easy_setopt(self, CURLOPT_WRITEFUNCTION, (curl_write_callback)&NativeString_native_callback_stream); + if(e != CURLE_OK) return e; + + e = curl_easy_setopt(self, CURLOPT_WRITEDATA, delegate); return e; `} + # Register `delegate` to get callbacks about the CURL transfer + fun register_callback_read(delegate: CCurlCallbacks): CURLCode + import NativeString.native_callback_stream `{ + CCurlCallbacks_incr_ref(delegate); + + return curl_easy_setopt(self, CURLOPT_READFUNCTION, (curl_write_callback)&nit_curl_callback_read_func); + `} + # Convert given string to URL encoded string fun escape(url: String): String import String.to_cstring, NativeString.to_s_with_copy `{ char *orig_url, *encoded_url = NULL; @@ -276,19 +279,9 @@ end # Interface for internal information callbacks methods interface CCurlCallbacks - fun header_callback(line: String) is abstract - fun body_callback(line: String) is abstract - fun stream_callback(buffer: String, size: Int, count: Int) is abstract -end - -# Extern Type to reproduce Enum of available Callback type -extern class CURLCallbackType `{ CURLcallbackType `} - new header `{ return CURLcallbackTypeHeader; `} - new body `{ return CURLcallbackTypeBody; `} - new stream `{ return CURLcallbackTypeStream; `} - new read `{ return CURLcallbackTypeRead; `} - - fun to_i: Int `{ return self; `} + fun header_callback(buffer: String) do end + fun body_callback(buffer: String) do end + fun stream_callback(buffer: String) do end end # CURL Code binding and helpers -- 1.7.9.5