[Pkg-e-commits] [SCM] Core abstraction layer for enlightenment DR 0.17 branch, upstream-vcs, updated. d6ccd8186518c58c26c1b20e1ea5de408340bb80

raster raster at alioth.debian.org
Mon Mar 10 15:24:36 UTC 2008


The following commit has been merged in the upstream-vcs branch:
commit b9b91317e564d4765b1d9f048aeb3bd654682b3d
Author: raster <raster>
Date:   Sun Mar 9 16:43:32 2008 +0000

    cedrics ecore_cn_url stuff for file downloads

diff --git a/configure.in b/configure.in
index c983ea4..6895c39 100644
--- a/configure.in
+++ b/configure.in
@@ -100,7 +100,6 @@ if test "x$want_curl" = "xyes"; then
   PKG_CHECK_MODULES(CURL, libcurl,
     [
       AC_DEFINE(HAVE_CURL, 1, [ Downloading with CURL ])
-      requirements_ecore_file="$requirements_ecore_file libcurl"
       requirements_ecore_con="$requirements_ecore_con libcurl"
       have_curl="yes"
     ],
@@ -721,6 +720,7 @@ if test "x$have_ecore_file" = "xyes"; then
     AC_DEFINE(HAVE_POLL, 1, [ File monitoring with polling ])
     have_poll="yes"
   fi
+  requirements_ecore_file="$requirements_ecore_file $requirements_ecore_con"
 fi
 
 dnl ecore_desktop
diff --git a/src/lib/ecore_con/Ecore_Con.h b/src/lib/ecore_con/Ecore_Con.h
index 01375f4..e977c84 100644
--- a/src/lib/ecore_con/Ecore_Con.h
+++ b/src/lib/ecore_con/Ecore_Con.h
@@ -149,8 +149,14 @@ extern "C" {
    struct _Ecore_Con_Event_Url_Progress
      {
 	Ecore_Con_Url    *url_con;
-	double            total;
-	double            now;
+	struct {
+	   double         total;
+	   double         now;
+	} down;
+	struct {
+	   double         total;
+	   double         now;
+	} up;
      };
 
    EAPI extern int ECORE_CON_EVENT_CLIENT_ADD;
@@ -161,8 +167,7 @@ extern "C" {
    EAPI extern int ECORE_CON_EVENT_SERVER_DATA;
    EAPI extern int ECORE_CON_EVENT_URL_DATA;
    EAPI extern int ECORE_CON_EVENT_URL_COMPLETE;
-   EAPI extern int ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD;
-   EAPI extern int ECORE_CON_EVENT_URL_PROGRESS_UPLOAD;
+   EAPI extern int ECORE_CON_EVENT_URL_PROGRESS;
    
    EAPI int               ecore_con_init(void);
    EAPI int               ecore_con_shutdown(void);
@@ -196,6 +201,8 @@ extern "C" {
    EAPI void              ecore_con_url_data_set(Ecore_Con_Url *url_con, void *data);
    EAPI void             *ecore_con_url_data_get(Ecore_Con_Url *url_con);
    EAPI int               ecore_con_url_url_set(Ecore_Con_Url *url_con, const char *url);
+   EAPI void		  ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd);
+   EAPI int		  ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con);
    EAPI int               ecore_con_url_send(Ecore_Con_Url *url_con, void *data, size_t length, char *content_type);
    EAPI void              ecore_con_url_time(Ecore_Con_Url *url_con, Ecore_Con_Url_Time condition, time_t tm);
 
diff --git a/src/lib/ecore_con/ecore_con_private.h b/src/lib/ecore_con/ecore_con_private.h
index 820771a..d5d9258 100644
--- a/src/lib/ecore_con/ecore_con_private.h
+++ b/src/lib/ecore_con/ecore_con_private.h
@@ -78,6 +78,11 @@ struct _Ecore_Con_Url
    void              *data;
 
    Ecore_Fd_Handler  *fd_handler;
+   int		      fd;
+   int		      flags;
+
+   int		      received;
+   int		      write_fd;
 
    unsigned char      active : 1;
 };
diff --git a/src/lib/ecore_con/ecore_con_url.c b/src/lib/ecore_con/ecore_con_url.c
index 5b67306..97077ce 100644
--- a/src/lib/ecore_con/ecore_con_url.c
+++ b/src/lib/ecore_con/ecore_con_url.c
@@ -40,6 +40,8 @@
 #include "Ecore_Con.h"
 #include "ecore_con_private.h"
 
+#include <errno.h>
+
 /**
  * @defgroup Ecore_Con_Url_Group Ecore URL Connection Functions
  *
@@ -50,8 +52,7 @@
 
 int ECORE_CON_EVENT_URL_DATA = 0;
 int ECORE_CON_EVENT_URL_COMPLETE = 0;
-int ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD = 0;
-int ECORE_CON_EVENT_URL_PROGRESS_UPLOAD = 0;
+int ECORE_CON_EVENT_URL_PROGRESS = 0;
 
 #ifdef HAVE_CURL
 static int _ecore_con_url_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
@@ -61,10 +62,11 @@ static int _ecore_con_url_progress_cb(void *clientp, double dltotal, double dlno
 static void _ecore_con_event_url_free(void *data __UNUSED__, void *ev);
 static int _ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match);
 
-static CURLM *curlm = NULL;
-static Ecore_List *_url_con_list = NULL;
-static fd_set _current_fd_set;
-static int init_count = 0;
+static Ecore_Idler	*_fd_idler_handler = NULL;
+static Ecore_List	*_url_con_list = NULL;
+static CURLM		*curlm = NULL;
+static fd_set		 _current_fd_set;
+static int		 init_count = 0;
 
 struct _Ecore_Con_Url_Event
 {
@@ -114,8 +116,7 @@ ecore_con_url_init(void)
      {
 	ECORE_CON_EVENT_URL_DATA = ecore_event_type_new();
 	ECORE_CON_EVENT_URL_COMPLETE = ecore_event_type_new();
-	ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD = ecore_event_type_new();
-	ECORE_CON_EVENT_URL_PROGRESS_UPLOAD = ecore_event_type_new();
+	ECORE_CON_EVENT_URL_PROGRESS = ecore_event_type_new();
      }
 
    if (!_url_con_list)
@@ -168,7 +169,7 @@ ecore_con_url_shutdown(void)
 	if (!ecore_list_empty_is(_url_con_list))
 	  {
 	     Ecore_Con_Url *url_con;
-	     while ((url_con = ecore_list_first_remove(_url_con_list)))
+	     while ((url_con = ecore_list_first(_url_con_list)))
 	       {
 		  ecore_con_url_destroy(url_con);
 	       }
@@ -230,6 +231,11 @@ ecore_con_url_new(const char *url)
    curl_easy_setopt(url_con->curl_easy, CURLOPT_TIMEOUT, 300);
    curl_easy_setopt(url_con->curl_easy, CURLOPT_FOLLOWLOCATION, 1);
 
+   curl_easy_setopt(url_con->curl_easy, CURLOPT_ENCODING, "gzip,deflate");
+
+   url_con->fd = -1;
+   url_con->write_fd = -1;
+
    return url_con;
 #else
    return NULL;
@@ -237,6 +243,15 @@ ecore_con_url_new(const char *url)
 #endif
 }
 
+static int
+_ecore_con_url_compare_cb(const void *data1, const void *data2)
+{
+   const void	*url_con1 = data1;
+   const void	*url_con2 = data2;
+
+   return (url_con1 == url_con2) ? 0 : 1;
+}
+
 /**
  * Frees the Ecore_Con_Url.
  * @return  FIXME: To be documented. 
@@ -255,11 +270,20 @@ ecore_con_url_destroy(Ecore_Con_Url *url_con)
 
    ECORE_MAGIC_SET(url_con, ECORE_MAGIC_NONE);
    if (url_con->fd_handler)
-     ecore_main_fd_handler_del(url_con->fd_handler);
+     {
+	ecore_main_fd_handler_del(url_con->fd_handler);
+	url_con->fd = -1;
+     }
    if (url_con->curl_easy)
      {
 	if (url_con->active)
-	  curl_multi_remove_handle(curlm, url_con->curl_easy);
+	  {
+	     if (ecore_list_find(_url_con_list, _ecore_con_url_compare_cb, url_con) == url_con)
+	       ecore_list_remove(_url_con_list);
+	     url_con->active = 0;
+
+	     curl_multi_remove_handle(curlm, url_con->curl_easy);
+	  }
 	curl_easy_cleanup(url_con->curl_easy);
      }
    curl_slist_free_all(url_con->headers);
@@ -376,6 +400,43 @@ ecore_con_url_time(Ecore_Con_Url *url_con, Ecore_Con_Url_Time condition, time_t
  * @return  FIXME: To be documented.
  * @ingroup Ecore_Con_Url_Group
  */
+EAPI void
+ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd)
+{
+#ifdef HAVE_CURL
+   if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+     {
+	ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_set");
+	return ;
+     }
+   url_con->write_fd = fd;
+#endif   
+}
+
+/**
+ * FIXME: To be documented.
+ * @return  FIXME: To be documented.
+ * @ingroup Ecore_Con_Url_Group
+ */
+EAPI int
+ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con)
+{
+#ifdef HAVE_CURL
+   if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
+     {
+	ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_received_bytes_get");
+	return -1;
+     }
+
+   return url_con->received;
+#endif   
+}
+
+/**
+ * FIXME: To be documented.
+ * @return  FIXME: To be documented.
+ * @ingroup Ecore_Con_Url_Group
+ */
 EAPI int
 ecore_con_url_send(Ecore_Con_Url *url_con, void *data, size_t length, char *content_type)
 {
@@ -440,6 +501,57 @@ ecore_con_url_send(Ecore_Con_Url *url_con, void *data, size_t length, char *cont
 }
 
 #ifdef HAVE_CURL
+static int
+_ecore_con_url_suspend_fd_handler(void)
+{
+   Ecore_Con_Url	*url_con;
+   int			 deleted = 0;
+
+   if (!_url_con_list)
+     return 0;
+
+   ecore_list_first_goto(_url_con_list);
+   while ((url_con = ecore_list_current(_url_con_list)))
+     {
+	if (url_con->active && url_con->fd_handler)
+	  {
+	     ecore_main_fd_handler_del(url_con->fd_handler);
+	     url_con->fd_handler = NULL;
+	     deleted++;
+	  }
+	ecore_list_next(_url_con_list);
+     }
+
+   return deleted;
+}
+
+static int
+_ecore_con_url_restart_fd_handler(void)
+{
+   Ecore_Con_Url	*url_con;
+   int			 activated = 0;
+
+   if (!_url_con_list)
+     return 0;
+
+   ecore_list_first_goto(_url_con_list);
+   while ((url_con = ecore_list_current(_url_con_list)))
+     {
+	if (url_con->fd_handler == NULL
+	    && url_con->fd != -1)
+	  {
+	     url_con->fd_handler = ecore_main_fd_handler_add(url_con->fd,
+							     url_con->flags,
+							     _ecore_con_url_fd_handler,
+							     NULL, NULL, NULL);
+	     activated++;
+	  }
+	ecore_list_next(_url_con_list);
+     }
+
+   return activated;
+}
+
 static size_t
 _ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp)
 {
@@ -448,15 +560,50 @@ _ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp)
    size_t real_size = size * nmemb;
 
    url_con = (Ecore_Con_Url *)userp;
-   e = malloc(sizeof(Ecore_Con_Event_Url_Data) + sizeof(unsigned char) * (real_size - 1));
-   if (e)
+
+   if (!url_con) return -1;
+   if (!ECORE_MAGIC_CHECK(url_con, ECORE_MAGIC_CON_URL))
      {
-	e->url_con = url_con;
-	e->size = real_size;
-	memcpy(e->data, buffer, real_size);
-	ecore_event_add(ECORE_CON_EVENT_URL_DATA, e,
-			_ecore_con_event_url_free, NULL);
+	ECORE_MAGIC_FAIL(url_con, ECORE_MAGIC_CON_URL, "ecore_con_url_data_cb");
+	return -1;
+     }
+
+   url_con->received += real_size;
+
+   if (url_con->write_fd < 0)
+     {
+	e = malloc(sizeof(Ecore_Con_Event_Url_Data) + sizeof(unsigned char) * (real_size - 1));
+	if (e)
+	  {
+	     e->url_con = url_con;
+	     e->size = real_size;
+	     memcpy(e->data, buffer, real_size);
+	     ecore_event_add(ECORE_CON_EVENT_URL_DATA, e,
+			     _ecore_con_event_url_free, NULL);
+	  }
+     }
+   else
+     {
+	ssize_t	count = 0;
+	size_t	total_size = real_size;
+	size_t	offset = 0;
+
+	while (total_size > 0)
+	  {
+	     count = write(url_con->write_fd, (char*) buffer + offset, total_size);
+	     if (count < 0)
+	       {
+		  if (errno != EAGAIN && errno != EINTR)
+		    return -1;
+	       }
+	     else
+	       {
+		  total_size -= count;
+		  offset += count;
+	       }
+	  }
      }
+
    return real_size;
 }
 
@@ -479,12 +626,21 @@ _ecore_con_url_data_cb(void *buffer, size_t size, size_t nmemb, void *userp)
 static int
 _ecore_con_url_progress_cb(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
 {
-   Ecore_Con_Url *url_con;
+   Ecore_Con_Event_Url_Progress	*e;
+   Ecore_Con_Url		*url_con;
 
    url_con = clientp;
 
-   ECORE_CON_URL_TRANSMISSION(Download, ECORE_CON_EVENT_URL_PROGRESS_DOWNLOAD, url_con, dltotal, dlnow);
-   ECORE_CON_URL_TRANSMISSION(Upload, ECORE_CON_EVENT_URL_PROGRESS_UPLOAD, url_con, ultotal, ulnow);
+   e = calloc(1, sizeof(Ecore_Con_Event_Url_Progress));
+   if (e)
+     {
+	e->url_con = url_con;
+	e->down.total = dltotal;
+	e->down.now = dlnow;
+	e->up.total = ultotal;
+	e->up.now = ulnow;
+	ecore_event_add(ECORE_CON_EVENT_URL_PROGRESS, e, _ecore_con_event_url_free, NULL);
+     }
 
    return 0;
 }
@@ -493,6 +649,7 @@ static int
 _ecore_con_url_perform(Ecore_Con_Url *url_con)
 {
    fd_set read_set, write_set, exc_set;
+   double start;
    int fd_max;
    int fd;
    int flags;
@@ -501,8 +658,10 @@ _ecore_con_url_perform(Ecore_Con_Url *url_con)
 
    ecore_list_append(_url_con_list, url_con);
 
+   start = ecore_time_get();
    url_con->active = 1;
    curl_multi_add_handle(curlm, url_con->curl_easy);
+   /* This one can't be stopped, or the download never start. */
    while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM);
 
    completed_immediately =  _ecore_con_url_process_completed_jobs(url_con);
@@ -527,9 +686,12 @@ _ecore_con_url_perform(Ecore_Con_Url *url_con)
 		  if (flags)
 		    {
 		       FD_SET(fd, &_current_fd_set);
+		       url_con->fd = fd;
+		       url_con->flags = flags;
 		       url_con->fd_handler = ecore_main_fd_handler_add(fd, flags,
 								       _ecore_con_url_fd_handler,
 								       NULL, NULL, NULL);
+		       break;
 		    }
 	       }
 	  }
@@ -538,6 +700,7 @@ _ecore_con_url_perform(Ecore_Con_Url *url_con)
 	     /* Failed to set up an fd_handler */
 	     curl_multi_remove_handle(curlm, url_con->curl_easy);
 	     url_con->active = 0;
+	     url_con->fd = -1;
 	     return 0;
 	  }
      }
@@ -546,14 +709,41 @@ _ecore_con_url_perform(Ecore_Con_Url *url_con)
 }
 
 static int
+_ecore_con_url_idler_handler(void *data)
+{
+   double	start;
+   int		done = 1;
+   int		still_running;
+
+   start = ecore_time_get();
+   while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM)
+     /* make this 1/20th of a second to keep interactivity high */
+     if ((ecore_time_get() - start) > 0.2)
+       {
+	  done = 0;
+	  break;
+       }
+
+   _ecore_con_url_process_completed_jobs(NULL);
+
+   if (done)
+     {
+	_ecore_con_url_restart_fd_handler();
+	_fd_idler_handler = NULL;
+	return 0;
+     }
+
+   return 1;
+}
+
+static int
 _ecore_con_url_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
 {
-   int still_running;
+   _ecore_con_url_suspend_fd_handler();
 
-   /* FIXME: Can this run for a long time? Maybe limit how long it can run */
-   while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM);
+   if (_fd_idler_handler == NULL)
+     _fd_idler_handler = ecore_idler_add(_ecore_con_url_idler_handler, NULL);
 
-   _ecore_con_url_process_completed_jobs(NULL);
    return 1;
 }
 
@@ -580,11 +770,12 @@ _ecore_con_url_process_completed_jobs(Ecore_Con_Url *url_con_to_match)
 		  if (url_con_to_match && (url_con == url_con_to_match)) {
 		       job_matched = 1;
 		  }
-		  if (url_con->fd_handler)
+		  if (url_con->fd != -1)
 		    {
-		       FD_CLR(ecore_main_fd_handler_fd_get(url_con->fd_handler),
-			      &_current_fd_set);
-		       ecore_main_fd_handler_del(url_con->fd_handler);
+		       FD_CLR(url_con->fd, &_current_fd_set);
+		       if (url_con->fd_handler)
+			 ecore_main_fd_handler_del(url_con->fd_handler);
+		       url_con->fd = -1;
 		       url_con->fd_handler = NULL;
 		    }
 		  ecore_list_remove(_url_con_list);
diff --git a/src/lib/ecore_file/Makefile.am b/src/lib/ecore_file/Makefile.am
index 3e52f50..05e1ee3 100644
--- a/src/lib/ecore_file/Makefile.am
+++ b/src/lib/ecore_file/Makefile.am
@@ -2,6 +2,7 @@ MAINTAINERCLEANFILES = Makefile.in
 
 AM_CPPFLAGS = \
 -I$(top_srcdir)/src/lib/ecore \
+-I$(top_srcdir)/src/lib/ecore_con \
 -I$(top_builddir)/src/lib/ecore \
 @CURL_CFLAGS@
 
@@ -21,7 +22,8 @@ ecore_file_download.c
 
 libecore_file_la_LIBADD = \
 $(top_builddir)/src/lib/ecore/libecore.la \
- at CURL_LIBS@ @ecore_file_win32_lib@ @winsock_libs@
+$(top_builddir)/src/lib/ecore_con/libecore_con.la \
+ at ecore_file_win32_lib@ @winsock_libs@
 
 libecore_file_la_LDFLAGS = @create_shared_lib@ -version-info @version_info@
 
diff --git a/src/lib/ecore_file/ecore_file_download.c b/src/lib/ecore_file/ecore_file_download.c
index 85ede05..bda540f 100644
--- a/src/lib/ecore_file/ecore_file_download.c
+++ b/src/lib/ecore_file/ecore_file_download.c
@@ -1,111 +1,98 @@
 /*
  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
  */
+#include "Ecore_Con.h"
 #include "ecore_file_private.h"
 
-static int init = 0;
-
-#ifdef HAVE_CURL
-#include <curl/curl.h>
-
-typedef struct _Ecore_File_Download_Job Ecore_File_Download_Job;
+#define ECORE_MAGIC_FILE_DOWNLOAD_JOB	0xf7427cb8
 
+typedef struct _Ecore_File_Download_Job		Ecore_File_Download_Job;
 struct _Ecore_File_Download_Job
 {
-   Ecore_Fd_Handler *fd_handler;
-   CURL *curl;
-   void (*completion_cb)(void *data, const char *file, int status);
-   int (*progress_cb)(void *data, const char *file, long int dltotal, long int dlnow, long int ultotal, long int ulnow);
-   void *data;
-   FILE *file;
-   char *dst;
+   ECORE_MAGIC;
+
+   Ecore_Con_Url	*url_con;
+   FILE			*file;
+
+   char			*dst;
+
+   void	(*completion_cb)(void *data, const char *file, int status);
+
+   int	(*progress_cb)  (void *data, const char *file,
+			 long int dltotal, long int dlnow,
+			 long int ultotal, long int ulnow);
 };
 
+#ifdef HAVE_CURL
 Ecore_File_Download_Job *_ecore_file_download_curl(const char *url, const char *dst,
 						   void (*completion_cb)(void *data, const char *file, int status),
 						   int (*progress_cb)(void *data, const char *file, long int dltotal, long int dlnow, long int ultotal, long int ulnow),
 						   void *data);
 static int _ecore_file_download_curl_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
 
-static CURLM *curlm;
-static Ecore_List *_job_list;
-static fd_set _current_fd_set;
+static void _ecore_file_download_abort(Ecore_File_Download_Job *job);
+
+static int _ecore_file_download_url_complete_cb(void *data, int type, void *event);
+static int _ecore_file_download_url_progress_cb(void *data, int type, void *event);
 #endif
 
-int
+static int			 init = 0;
+static Ecore_Event_Handler	*_url_complete_handler = NULL;
+static Ecore_Event_Handler	*_url_progress_download = NULL;
+static Ecore_List		*_job_list;
+
+EAPI int
 ecore_file_download_init(void)
 {
-   if (++init != 1) return init;
+   ecore_con_url_init();
 
+   if (init++ == 0)
+     {
 #ifdef HAVE_CURL
-   FD_ZERO(&_current_fd_set);
-   _job_list = ecore_list_new();
-   if (!_job_list) return --init;
-
-   if (curl_global_init(CURL_GLOBAL_NOTHING)) return 0;
-
-   curlm = curl_multi_init();
-   if (!curlm)
+	_url_complete_handler = ecore_event_handler_add(ECORE_CON_EVENT_URL_COMPLETE, _ecore_file_download_url_complete_cb, NULL);
+	_url_progress_download = ecore_event_handler_add(ECORE_CON_EVENT_URL_PROGRESS, _ecore_file_download_url_progress_cb, NULL);
+#endif	
+     }
+   if (!_job_list)
      {
-	ecore_list_destroy(_job_list);
-	_job_list = NULL;
-	return --init;
+	_job_list = ecore_list_new();
+	if (!_job_list) return 0;
      }
-#endif
-   return init;
+
+   return 1;
 }
 
-int
+EAPI int
 ecore_file_download_shutdown(void)
 {
-   if (--init != 0) return init;
-#ifdef HAVE_CURL
-   Ecore_File_Download_Job *job;
-
-   if (!ecore_list_empty_is(_job_list))
+   if (--init == 0)
      {
-	ecore_list_first_goto(_job_list);
-	while ((job = ecore_list_next(_job_list)))
-	  {
-	     ecore_main_fd_handler_del(job->fd_handler);
-	     curl_multi_remove_handle(curlm, job->curl);
-	     curl_easy_cleanup(job->curl);
-	     fclose(job->file);
-	     free(job->dst);
-	     free(job);
-	  }
+	ecore_event_handler_del(_url_complete_handler);
+	ecore_event_handler_del(_url_progress_download);
+	_url_complete_handler = NULL;
+	_url_progress_download = NULL;
+
+	ecore_list_destroy(_job_list);
      }
-   ecore_list_destroy(_job_list);
-   curl_multi_cleanup(curlm);
-   curl_global_cleanup();
-#endif
-   return init;
+
+   return ecore_con_url_shutdown();
 }
 
-void
+EAPI void
 ecore_file_download_abort_all(void)
 {
-#ifdef HAVE_CURL
-   Ecore_File_Download_Job *job;
-
-   if (!_job_list)
-     return;
-
-   ecore_list_first_goto(_job_list);
-   while ((job = ecore_list_next(_job_list)))
+   if (!ecore_list_empty_is(_job_list))
      {
-	ecore_main_fd_handler_del(job->fd_handler);
-	curl_multi_remove_handle(curlm, job->curl);
-	curl_easy_cleanup(job->curl);
-	fclose(job->file);
-	free(job->dst);
-	free(job);
+	Ecore_File_Download_Job *job;
+
+	while ((job = ecore_list_first_remove(_job_list)))
+	  {
+	     _ecore_file_download_abort(job);
+	  }
      }
    ecore_list_clear(_job_list);
-#endif
 }
 
-
 /**
  * Download @p url to the given @p dst
  * @param  url The complete url to download
@@ -192,200 +179,108 @@ ecore_file_download_protocol_available(const char *protocol)
 }
 
 #ifdef HAVE_CURL
-/* this reports the downloads progress. if we return 0, then download
- * continues, if we return anything else, then the download stops */
 static int
-_ecore_file_download_curl_progress_func(void *clientp, double dltotal, double dlnow, double ultotal, double ulnow)
+_ecore_file_download_url_compare_job(const void *data1, const void *data2)
 {
-   Ecore_File_Download_Job *job;
+   const Ecore_File_Download_Job	*job = data1;
+   const Ecore_Con_Url			*url = data2;
+
+   if (job->url_con == url) return 0;
+   return -1;
+}
+
+static int
+_ecore_file_download_url_complete_cb(void *data, int type, void *event)
+{
+   Ecore_Con_Event_Url_Complete	*ev = event;
+   Ecore_File_Download_Job	*job;
+
+   job = ecore_list_find(_job_list, _ecore_file_download_url_compare_job, ev->url_con);
+   if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB)) return 1;
 
-   job = clientp;
+   ecore_list_remove(_job_list);
+
+   if (job->completion_cb)
+     job->completion_cb(ecore_con_url_data_get(job->url_con), job->dst, !ev->status);
+
+   _ecore_file_download_abort(job);
+
+   return 0;
+}
+
+static int
+_ecore_file_download_url_progress_cb(void *data, int type, void *event)
+{
+/* this reports the downloads progress. if we return 0, then download
+ * continues, if we return anything else, then the download stops */
+   Ecore_Con_Event_Url_Progress	*ev = event;
+   Ecore_File_Download_Job	*job;
+
+   job = ecore_list_find(_job_list, _ecore_file_download_url_compare_job, ev->url_con);
+   if (!ECORE_MAGIC_CHECK(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB)) return 1;
+
+   if (job->progress_cb)
+     if (job->progress_cb(ecore_con_url_data_get(job->url_con), job->dst,
+			  (long int) ev->down.total, (long int) ev->down.now,
+			  (long int) ev->up.total, (long int) ev->up.now) != 0)
+       {
+	  ecore_list_remove(_job_list);
+	  _ecore_file_download_abort(job);
+       }
 
-   if(job->progress_cb)
-     return job->progress_cb(job->data, job->dst, (long int)dltotal, (long int)dlnow, (long int)ultotal, (long int)ulnow);
    return 0;
 }
 
+static void
+_ecore_file_download_abort(Ecore_File_Download_Job *job)
+{
+   ecore_con_url_destroy(job->url_con);
+   fclose(job->file);
+   free(job->dst);
+   free(job);
+}
+
 Ecore_File_Download_Job *
 _ecore_file_download_curl(const char *url, const char *dst,
 			  void (*completion_cb)(void *data, const char *file,
 						int status),
 			  int (*progress_cb)(void *data, const char *file,
 					     long int dltotal, long int dlnow,
-					     long int ultotal,
-					     long int ulnow),
+					     long int ultotal, long int ulnow),
 			  void *data)
 {
-   CURLMsg *curlmsg;
-   fd_set read_set, write_set, exc_set;
-   int fd_max;
-   int fd;
-   int flags;
-   int n_remaining, still_running;
    Ecore_File_Download_Job *job;
-   double start = 0.0;
 
    job = calloc(1, sizeof(Ecore_File_Download_Job));
    if (!job) return NULL;
 
+   ECORE_MAGIC_SET(job, ECORE_MAGIC_FILE_DOWNLOAD_JOB);
+
    job->file = fopen(dst, "wb");
    if (!job->file)
      {
 	free(job);
 	return NULL;
      }
-   job->curl = curl_easy_init();
-   if (!job->curl)
+   job->url_con = ecore_con_url_new(url);
+   if (!job->url_con)
      {
 	fclose(job->file);
 	free(job);
 	return NULL;
      }
 
-   curl_easy_setopt(job->curl, CURLOPT_URL, url);
-   curl_easy_setopt(job->curl, CURLOPT_WRITEDATA, job->file);
-   curl_easy_setopt(job->curl, CURLOPT_FOLLOWLOCATION, TRUE);
-   
-   if (progress_cb)
-     {
-	curl_easy_setopt(job->curl, CURLOPT_NOPROGRESS, FALSE);
-	curl_easy_setopt(job->curl, CURLOPT_PROGRESSDATA, job);
-	curl_easy_setopt(job->curl, CURLOPT_PROGRESSFUNCTION, _ecore_file_download_curl_progress_func);
-     }
+   ecore_con_url_fd_set(job->url_con, fileno(job->file));
+   ecore_con_url_data_set(job->url_con, data);
+
+   job->dst = strdup(dst);
 
-   job->data = data;
    job->completion_cb = completion_cb;
    job->progress_cb = progress_cb;
-   job->dst = strdup(dst);
    ecore_list_append(_job_list, job);
 
-   curl_multi_add_handle(curlm, job->curl);
-   start = ecore_time_get();
-   while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM)
-     {
-	/* make this 1/100th of a second to keep interactivity high. really
-	 * though this needs to somehow get the fd from curl and use an fd handler
-	 * and thus select
-	 */
-	if ((ecore_time_get() - start) > 0.01) break;
-     }
-
-   /* check for completed jobs */
-   while ((curlmsg = curl_multi_info_read(curlm, &n_remaining)) != NULL)
-     {
-	Ecore_File_Download_Job *current;
-
-	if (curlmsg->msg != CURLMSG_DONE) continue;
-
-	/* find the job which is done */
-	ecore_list_first_goto(_job_list);
-	while ((current = ecore_list_current(_job_list)))
-	  {
-	     if (curlmsg->easy_handle == current->curl)
-	       {
-		  /* We have a match -- delete the job */
-		  if (current == job)
-		    job = NULL;
-		  if (current->fd_handler)
-		    {
-		       FD_CLR(ecore_main_fd_handler_fd_get(current->fd_handler),
-			      &_current_fd_set);
-		       ecore_main_fd_handler_del(current->fd_handler);
-		    }
-		  ecore_list_remove(_job_list);
-		  curl_multi_remove_handle(curlm, current->curl);
-		  curl_easy_cleanup(current->curl);
-		  fclose(current->file);
-		  if (current->completion_cb)
-		    current->completion_cb(current->data, current->dst,
-					   curlmsg->data.result);
-		  free(current->dst);
-		  free(current);
-		  break;
-	       }
-	     ecore_list_next(_job_list);
-	  }
-     }
-
-   if (job)
-     {
-	FD_ZERO(&read_set);
-	FD_ZERO(&write_set);
-	FD_ZERO(&exc_set);
-
-	/* Stupid curl, why can't I get the fd to the current added job? */
-	curl_multi_fdset(curlm, &read_set, &write_set, &exc_set, &fd_max);
-	for (fd = 0; fd <= fd_max; fd++)
-	  {
-	     if (!FD_ISSET(fd, &_current_fd_set))
-	       {
-		  flags = 0;
-		  if (FD_ISSET(fd, &read_set)) flags |= ECORE_FD_READ;
-		  if (FD_ISSET(fd, &write_set)) flags |= ECORE_FD_WRITE;
-		  if (FD_ISSET(fd, &exc_set)) flags |= ECORE_FD_ERROR;
-		  if (flags)
-		    {
-		       FD_SET(fd, &_current_fd_set);
-		       job->fd_handler = ecore_main_fd_handler_add(fd, flags,
-								   _ecore_file_download_curl_fd_handler,
-								   NULL, NULL, NULL);
-		    }
-	       }
-	  }
-	if (!job->fd_handler)
-	  {
-	     curl_easy_cleanup(job->curl);
-	     fclose(job->file);
-	     free(job);
-	     job = NULL;
-	  }
-     }
+   ecore_con_url_send(job->url_con, NULL, 0, NULL);
 
    return job;
 }
-
-static int
-_ecore_file_download_curl_fd_handler(void *data __UNUSED__, Ecore_Fd_Handler *fd_handler __UNUSED__)
-{
-   Ecore_File_Download_Job *job;
-   CURLMsg *curlmsg;
-   int n_remaining, still_running;
-   double start = 0.0;
-
-   start = ecore_time_get();
-   while (curl_multi_perform(curlm, &still_running) == CURLM_CALL_MULTI_PERFORM)
-     {
-	if ((ecore_time_get() - start) > 0.2) break;
-     }
-
-   /* Loop jobs and check if any are done */
-   while ((curlmsg = curl_multi_info_read(curlm, &n_remaining)) != NULL)
-     {
-	if (curlmsg->msg != CURLMSG_DONE) continue;
-
-	/* find the job which is done */
-	ecore_list_first_goto(_job_list);
-	while ((job = ecore_list_current(_job_list)))
-	  {
-	     if (curlmsg->easy_handle == job->curl)
-	       {
-		  /* We have a match -- delete the job */
-		  FD_CLR(ecore_main_fd_handler_fd_get(job->fd_handler),
-			&_current_fd_set);
-		  ecore_list_remove(_job_list);
-		  ecore_main_fd_handler_del(job->fd_handler);
-		  curl_multi_remove_handle(curlm, job->curl);
-		  curl_easy_cleanup(job->curl);
-		  fclose(job->file);
-		  if (job->completion_cb)
-		    job->completion_cb(job->data, job->dst, !curlmsg->data.result);
-		  free(job->dst);
-		  free(job);
-		  break;
-	       }
-	     ecore_list_next(_job_list);
-	  }
-     }
-   return 1;
-}
 #endif

-- 
Core abstraction layer for enlightenment DR 0.17



More information about the Pkg-e-commits mailing list