[cairo-commit] roadster/src Makefile.am, 1.19, 1.20 downloader.c,
NONE, 1.1 downloader.h, NONE, 1.1 main.c, 1.27, 1.28
Ian McIntosh
commit at pdx.freedesktop.org
Fri Sep 30 16:25:00 PDT 2005
Committed by: ian
Update of /cvs/cairo/roadster/src
In directory gabe:/tmp/cvs-serv30511/src
Modified Files:
Makefile.am main.c
Added Files:
downloader.c downloader.h
Log Message:
* src/downloader.c: Added. This provides an easy interface to asyncronous file downloads.
Index: Makefile.am
===================================================================
RCS file: /cvs/cairo/roadster/src/Makefile.am,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -d -r1.19 -r1.20
--- Makefile.am 24 Sep 2005 05:25:24 -0000 1.19
+++ Makefile.am 30 Sep 2005 23:24:58 -0000 1.20
@@ -20,6 +20,7 @@
roadster_SOURCES = \
main.c\
db.c\
+ downloader.c\
gui.c\
mainwindow.c\
gotowindow.c\
--- NEW FILE: downloader.c ---
/***************************************************************************
* downloader.c
*
* Copyright 2005 Ian McIntosh
* ian_mcintosh at linuxadvocate.org
****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
/*
Purpose: A general purpose, easy to use, asyncronous downloader.
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <libgnomevfs/gnome-vfs.h>
#include <gnome.h>
#include "downloader.h"
#define TEMP_FILE_TEMPLATE ("roadster_download_XXXXXX") // format of temp files
typedef struct {
gchar* pszRemoteFilePath;
gchar* pszLocalFilePath; // will be NULL until file moves into 'active' list
gint nBytesDownloaded; // a count
downloader_t* pDownloader; // a handy pointer to the parent
GnomeVFSAsyncHandle* pGnomeVFSHandle;
DownloaderCallbackFileResult pCallbackFileResult; // called when file succeeds or fails
} download_t;
//
// prototypes
//
static gboolean _downloader_begin_download(download_t* pDownload);
static void _downloader_move_pending_to_active(downloader_t* pDownloader);
//
// functions
//
void downloader_init(void)
{
// nothing
}
downloader_t* downloader_new(gint nMaxConcurrentActive)
{
downloader_t* pNew = g_new0(downloader_t, 1);
pNew->pActiveArray = g_ptr_array_new();
pNew->pPendingArray = g_ptr_array_new();
pNew->nMaxConcurrentActive = nMaxConcurrentActive;
return pNew;
}
void downloader_add_uri(downloader_t* pDownloader, const gchar* pszRemoteFilePath, DownloaderCallbackFileResult pCallbackFileResult)
{
g_assert(pDownloader != NULL);
g_assert(pszRemoteFilePath != NULL);
g_assert(pCallbackFileResult != NULL);
download_t* pNewDownload = g_new0(download_t, 1);
pNewDownload->pszRemoteFilePath = g_strdup(pszRemoteFilePath);
pNewDownload->pCallbackFileResult = pCallbackFileResult;
pNewDownload->pDownloader = pDownloader;
g_ptr_array_add(pDownloader->pPendingArray, pNewDownload);
_downloader_move_pending_to_active(pDownloader);
}
// Check to see if we can add any pending files to active list
static void _downloader_move_pending_to_active(downloader_t* pDownloader)
{
if((pDownloader->pActiveArray->len < pDownloader->nMaxConcurrentActive) && (pDownloader->pPendingArray->len > 0)) {
// time to promote one from pending
download_t* pNext = g_ptr_array_index(pDownloader->pPendingArray, 0);
if(_downloader_begin_download(pNext)) {
g_ptr_array_remove(pDownloader->pPendingArray, pNext);
g_ptr_array_add(pDownloader->pActiveArray, pNext);
}
}
}
// static void _downloader_gnome_vfs_close_callback(GnomeVFSAsyncHandle *_unused, GnomeVFSResult __unused, gpointer ___unused)
// {
// //g_print("downloader: a file has been closed\n");
// }
static void _downloader_download_free(downloader_t* pDownloader, download_t* pDownload)
{
// Empty struct
g_free(pDownload->pszRemoteFilePath);
g_free(pDownload->pszLocalFilePath);
if(pDownload->pGnomeVFSHandle != NULL) {
// XXX: do we need to close this?
// gnome_vfs_async_close(pDownload->pGnomeVFSHandle, _downloader_gnome_vfs_close_callback, NULL);
}
// XXX: store a 'state' so we know which array it's in?
g_ptr_array_remove_fast(pDownloader->pActiveArray, pDownload);
g_ptr_array_remove(pDownloader->pPendingArray, pDownload);
// Free struct
g_free(pDownload);
}
static gint _downloader_gnome_vfs_progress_callback(GnomeVFSAsyncHandle *pHandle, GnomeVFSXferProgressInfo *pInfo, download_t* pDownload)
{
g_assert(pHandle != NULL);
g_assert(pInfo != NULL);
g_assert(pDownload != NULL);
pDownload->nBytesDownloaded = pInfo->bytes_copied;
if(pInfo->phase == GNOME_VFS_XFER_PHASE_COMPLETED) {
g_print("downloader: downloaded '%s' to '%s' (%d bytes)\n", pDownload->pszRemoteFilePath, pDownload->pszLocalFilePath, pDownload->nBytesDownloaded);
// Call user-supplied callback
pDownload->pCallbackFileResult(pDownload->pszRemoteFilePath, DOWNLOADER_RESULT_SUCCESS, pDownload->pszLocalFilePath);
// callback shouldn't leave the file in the temp directory
if(g_file_test(pDownload->pszLocalFilePath, G_FILE_TEST_EXISTS)) {
g_warning("downloader: callback failed to move/delete local file '%s' (from remote '%s')\n", pDownload->pszLocalFilePath, pDownload->pszRemoteFilePath);
}
downloader_t* pDownloader = pDownload->pDownloader;
_downloader_download_free(pDownloader, pDownload);
//
_downloader_move_pending_to_active(pDownloader);
}
// XXX: what other statuses messages do we care about? (failed?)
}
static gboolean _downloader_begin_download(download_t* pDownload)
{
g_assert(pDownload != NULL);
//g_print("downloader: beginning download of %s\n", pDownload->pszRemoteFilePath);
g_assert(pDownload->pszLocalFilePath == NULL);
gint nHandle = g_file_open_tmp(TEMP_FILE_TEMPLATE, &(pDownload->pszLocalFilePath), NULL);
if(nHandle == -1) {
g_warning("downloader: failed to create a temporary file\n");
return FALSE;
}
g_assert(pDownload->pszLocalFilePath != NULL);
close(nHandle); // we don't use the file here. gnome-vfs overwrites it.
//g_print("downloader: using temp file '%s'\n", pDownload->pszLocalFilePath);
GnomeVFSURI* pSrcURI = gnome_vfs_uri_new(pDownload->pszRemoteFilePath);
GList* pSrcList = g_list_prepend(pSrcList, pSrcURI);
GnomeVFSURI* pDestURI = gnome_vfs_uri_new(pDownload->pszLocalFilePath);
GList* pDestList = g_list_prepend(pDestList, pDestURI);
GnomeVFSResult res = gnome_vfs_async_xfer(&(pDownload->pGnomeVFSHandle),
pSrcList, pDestList,
GNOME_VFS_XFER_DEFAULT,
GNOME_VFS_XFER_ERROR_MODE_ABORT,
GNOME_VFS_XFER_OVERWRITE_MODE_REPLACE, // overwrite the tmp file we just made.
GNOME_VFS_PRIORITY_MIN,
(GnomeVFSAsyncXferProgressCallback)_downloader_gnome_vfs_progress_callback,
(gpointer)pDownload, // callback userdata
NULL,
NULL);
gnome_vfs_uri_unref(pSrcURI);
gnome_vfs_uri_unref(pDestURI);
g_list_free(pSrcList);
g_list_free(pDestList);
if(res != GNOME_VFS_OK) {
// return the download_t to a 'pending' state
g_free(pDownload->pszLocalFilePath); pDownload->pszLocalFilePath = NULL;
g_assert(pDownload->pGnomeVFSHandle == NULL);
return FALSE;
}
g_assert(pDownload->pGnomeVFSHandle != NULL);
return TRUE;
}
--- NEW FILE: downloader.h ---
/***************************************************************************
* downloader.h
*
* Copyright 2005 Ian McIntosh
* ian_mcintosh at linuxadvocate.org
****************************************************************************/
/*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
#ifndef _DOWNLOADER_H_
#define _DOWNLOADER_H_
#include <libgnomevfs/gnome-vfs.h>
#include <gtk/gtk.h>
typedef enum { DOWNLOADER_RESULT_FAILURE=0, DOWNLOADER_RESULT_SUCCESS } EDownloaderFileResult;
typedef void (*DownloaderCallbackFileResult)(const gchar* pszRemotePath, EDownloaderFileResult eDownloaderResult, const gchar* pszLocalPath);
typedef struct {
GPtrArray* pPendingArray;
GPtrArray* pActiveArray;
gint nMaxConcurrentActive;
} downloader_t;
// public API
void downloader_init(void);
downloader_t* downloader_new(gint nMaxConcurrentActive);
void downloader_add_uri(downloader_t* pDownloader, const gchar* pszRemoteFilePath, DownloaderCallbackFileResult pCallbackFileResult);
#endif
Index: main.c
===================================================================
RCS file: /cvs/cairo/roadster/src/main.c,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- main.c 30 Sep 2005 05:09:51 -0000 1.27
+++ main.c 30 Sep 2005 23:24:58 -0000 1.28
@@ -37,6 +37,8 @@
#include "locationset.h"
#include "location.h"
#include "search.h"
+#include "search.h"
+#include "downloader.h"
static gboolean main_init(void);
static void main_deinit(void);
@@ -126,7 +128,6 @@
#endif
}
-
gboolean main_init(void)
{
#ifdef USE_GNOME_VFS
@@ -196,6 +197,7 @@
g_print("initialization complete\n");
+ downloader_init();
return TRUE;
}
More information about the cairo-commit
mailing list