Ecore_Con_Url - downloading a file

This is a simple example that shows how to download a file using Ecore_Con_Url.

The full source code for this example can be found at ecore_con_url_download_example.c.

First we are setting some callbacks for events that will be sent when data arrives in our connection (the data is the content of the file being downloaded), and when the download is completed. The _url_progress_cb and _url_complete_cb are these callbacks:

struct _request
{
long size;
};
static Eina_Bool
_url_progress_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event_info)
{
Ecore_Con_Event_Url_Progress *url_progress = event_info;
float percent;
if (url_progress->down.total > 0)
{
struct _request *req = ecore_con_url_data_get(url_progress->url_con);
req->size = url_progress->down.now;
percent = (url_progress->down.now / url_progress->down.total) * 100;
printf("Total of download complete: %0.1f (%0.0f)%%\n",
percent, url_progress->down.now);
}
printf("status: %d\n", ecore_con_url_status_code_get(url_progress->url_con));
return EINA_TRUE;
}
static Eina_Bool
_url_complete_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void *event_info)
{
Ecore_Con_Event_Url_Complete *url_complete = event_info;
struct _request *req = ecore_con_url_data_get(url_complete->url_con);
int nbytes = ecore_con_url_received_bytes_get(url_complete->url_con);
printf("\n");
printf("download completed with status code: %d\n", url_complete->status);
printf("Total size of downloaded file: %ld bytes\n", req->size);
printf("Total size of downloaded file: %d bytes "
"(from received_bytes_get)\n", nbytes);
ECORE_CON_API int ecore_con_url_received_bytes_get(Ecore_Con_Url *url_con)
Retrieves the number of bytes received.
Definition ecore_con_url.c:1279
ECORE_CON_API int ecore_con_url_status_code_get(Ecore_Con_Url *url_con)
Gets the returned HTTP STATUS code.
Definition ecore_con_url.c:1286
ECORE_CON_API void * ecore_con_url_data_get(Ecore_Con_Url *url_con)
Retrieves data associated with a Ecore_Con_Url connection object.
Definition ecore_con_url.c:830
void ecore_main_loop_quit(void)
Quits the main loop once all the events currently on the queue have been processed.
Definition ecore_main.c:1321
#define EINA_TRUE
boolean value TRUE (numerical value 1)
Definition eina_types.h:539
unsigned char Eina_Bool
Type to mimic a boolean.
Definition eina_types.h:527
#define EINA_UNUSED
Used to indicate that a function parameter is purposely unused.
Definition eina_types.h:339
Used as the data param for the ECORE_CON_EVENT_URL_COMPLETE event.
Definition Ecore_Con.h:586
Ecore_Con_Url * url_con
a pointer to the connection object
Definition Ecore_Con.h:587
int status
HTTP status code of the operation (200, 404, 401, etc.)
Definition Ecore_Con.h:588
Used as the data param for the ECORE_CON_EVENT_URL_PROGRESS event.
Definition Ecore_Con.h:597
Ecore_Con_Url * url_con
a pointer to the connection object
Definition Ecore_Con.h:598
double now
current size of the downloading data (in bytes)
Definition Ecore_Con.h:602
double total
total size of the downloading data (in bytes)
Definition Ecore_Con.h:601
struct _Ecore_Con_Event_Url_Progress::@27 down
download info
return EINA_TRUE;
}

Notice that we also declared a struct that will hold how many bytes were downloaded through this object. It will be set in the main function using ecore_con_url_data_set().

In the next step, on the main function, we open a file where we are going to save the content being downloaded:

int
main(int argc, const char *argv[])
{
Ecore_Con_Url *ec_url = NULL;
struct _request *req;
int fd;
const char *filename = "downloadedfile.dat";
if (argc < 2)
{
printf("need one parameter: <url>\n");
return -1;
}
fd = open(filename, O_CREAT | O_BINARY | O_WRONLY | O_TRUNC, 0644);
if (fd == -1)
{
printf("error: could not open file for writing: \"%s\"\n",
filename);
return -1;
}

With the file successfully open, let's create our Ecore_Con_Url object. For this, we initialize the libraries and create the object:

ec_url = ecore_con_url_new(argv[1]);
if (!ec_url)
{
printf("error when creating ecore con url object.\n");
goto end;
}
ECORE_CON_API int ecore_con_init(void)
Initializes the Ecore_Con library.
Definition ecore_con.c:68
ECORE_CON_API Ecore_Con_Url * ecore_con_url_new(const char *url)
Creates and initializes a new Ecore_Con_Url connection object.
Definition ecore_con_url.c:782
ECORE_CON_API int ecore_con_url_init(void)
Initializes the Ecore_Con_Url library.
Definition ecore_con_url.c:45
EAPI int ecore_init(void)
Sets up connections, signal handlers, sockets etc.
Definition ecore.c:230

Then we allocate and set the data struct to the connection object, and set a file descriptor from our previously open file to it. We also add the event handlers (callbacks) to the events that will be emitted on data being received and download complete:

req = malloc(sizeof(*req));
req->size = 0;
ecore_con_url_data_set(ec_url, req);
ecore_con_url_fd_set(ec_url, fd);
ECORE_CON_API int ECORE_CON_EVENT_URL_PROGRESS
A URL object has made progress in its transfer.
Definition ecore_con_url.c:31
ECORE_CON_API int ECORE_CON_EVENT_URL_COMPLETE
A URL object has completed its transfer to and from the server and can be reused.
Definition ecore_con_url.c:30
ECORE_CON_API void ecore_con_url_fd_set(Ecore_Con_Url *url_con, int fd)
Sets up a file for receiving response data.
Definition ecore_con_url.c:1138
ECORE_CON_API void ecore_con_url_data_set(Ecore_Con_Url *url_con, void *data)
Associates data with a connection object.
Definition ecore_con_url.c:837
Ecore_Event_Handler * ecore_event_handler_add(int type, Ecore_Event_Handler_Cb func, const void *data)
Adds an event handler.
Definition ecore_events.c:13

Finally we start our request, and run the main loop:

if (!ecore_con_url_get(ec_url))
{
printf("could not realize request.\n");
goto free_ec_url;
}
free_ec_url:
free(req);
end:
close(fd);
return 0;
ECORE_CON_API int ecore_con_shutdown(void)
Shuts down the Ecore_Con library.
Definition ecore_con.c:133
ECORE_CON_API void ecore_con_url_free(Ecore_Con_Url *url_con)
Destroys an Ecore_Con_Url connection object.
Definition ecore_con_url.c:819
ECORE_CON_API int ecore_con_url_shutdown(void)
Shuts down the Ecore_Con_Url library.
Definition ecore_con_url.c:68
ECORE_CON_API Eina_Bool ecore_con_url_get(Ecore_Con_Url *url_con)
Sends a get request.
Definition ecore_con_url.c:862
EAPI int ecore_shutdown(void)
Shuts down connections, signal handlers sockets etc.
Definition ecore.c:371
void ecore_main_loop_begin(void)
Runs the application main loop.
Definition ecore_main.c:1311
}

The rest of this code was just freeing resources, with some labels to be used for error handling.