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);
struct _Ecore_Con_Url Ecore_Con_Url
Used to provide legacy API/ABI compatibility with non-Eo applications.
Definition: Ecore_Con.h:323
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.