+2000-05-30 Not Zed <NotZed@HelixCode.com>
+
+ * providers/mbox/camel-mbox-folder.c (mbox_append_message): Init
+ filter_from to NULL, for exception case.
+ (mbox_get_message_by_uid): Cast off_t to long int for diagnostics.
+
+ * camel-url.c (camel_url_hash): Hash funciton for using camel
+ url's as hash keys.
+ (camel_url_equal): equal function for same.
+
+ * camel-session.c (camel_session_finalise): Free cached services.
+ (camel_session_init): Init service cache.
+ (service_cache_remove): destroy callback to remove a service from
+ the cache.
+
+ * camel-store.c (get_folder_internal): Remove the extra ref of the
+ folder. That seems the right behaviour ...?
+ (camel_store_get_type): Doh, actually call store init, so the
+ cache works.
+ (cache_folder): strdup the folder name! no wonder it never found
+ it again.
+
2000-05-30 Jeffrey Stedfast <fejj@helixcode.com>
* providers/imap/camel-imap-folder.c: Implemented a few more
gtk_object_class->finalize = _finalize;
}
+static void
+camel_service_init (void *o, void *k)
+{
+/* CamelService *service = o;*/
+ return;
+}
+
GtkType
camel_service_get_type (void)
{
sizeof (CamelService),
sizeof (CamelServiceClass),
(GtkClassInitFunc) camel_service_class_init,
- (GtkObjectInitFunc) NULL,
+ (GtkObjectInitFunc) camel_service_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
return camel_service_type;
}
-
static void
_finalize (GtkObject *object)
{
gboolean connected;
CamelURL *url;
int url_flags;
-
};
#include "camel-url.h"
#include "hash-table-utils.h"
+static CamelObjectClass *parent_class;
+
static void
camel_session_init (CamelSession *session)
{
session->modules = camel_provider_init ();
- session->providers = g_hash_table_new (g_strcase_hash,
- g_strcase_equal);
+ session->providers =
+ g_hash_table_new (g_strcase_hash, g_strcase_equal);
+ session->service_cache =
+ g_hash_table_new (camel_url_hash, camel_url_equal);
+}
+
+static void
+hash_unref_service(void *key, void *value, void *data)
+{
+ gtk_object_unref((GtkObject *)value);
+}
+
+static void
+camel_session_finalise(GtkObject *o)
+{
+ CamelSession *session = (CamelSession *)o;
+
+ g_hash_table_foreach(session->service_cache, hash_unref_service, 0);
+ g_hash_table_destroy(session->service_cache);
+ g_hash_table_destroy(session->providers);
+
+ GTK_OBJECT_CLASS (parent_class)->finalize (o);
+}
+
+static void
+camel_session_class_init (CamelServiceClass *camel_service_class)
+{
+ GtkObjectClass *object_class = (GtkObjectClass *)camel_service_class;
+
+ parent_class = gtk_type_class (camel_object_get_type ());
+ object_class->finalize = camel_session_finalise;
}
GtkType
"CamelSession",
sizeof (CamelSession),
sizeof (CamelSessionClass),
- (GtkClassInitFunc) NULL,
+ (GtkClassInitFunc) camel_session_class_init,
(GtkObjectInitFunc) camel_session_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
return list;
}
+static void
+service_cache_remove(CamelService *service, CamelSession *session)
+{
+ g_hash_table_remove(session->service_cache, service->url);
+}
CamelService *
camel_session_get_service (CamelSession *session, const char *url_string,
{
CamelURL *url;
const CamelProvider *provider;
+ CamelService *service;
url = camel_url_new (url_string, ex);
if (!url)
return NULL;
+ /* lookup in cache first */
+ printf("looking up service in cache: %s\n", url_string);
+ service = g_hash_table_lookup(session->service_cache, url);
+ if (service != NULL) {
+ printf("found!!\n");
+ camel_url_free(url);
+ gtk_object_ref((GtkObject *)service);
+ return service;
+ }
+ printf("not found, creating service\n");
+
provider = g_hash_table_lookup (session->providers, url->protocol);
if (!provider) {
/* See if there's one we can load. */
return NULL;
}
- return camel_service_new (provider->object_types[type], session,
- url, ex);
+ service = camel_service_new (provider->object_types[type], session, url, ex);
+ if (service) {
+ g_hash_table_insert(session->service_cache, url, service);
+ gtk_signal_connect((GtkObject *)service, "destroy", service_cache_remove, session);
+ }
+ return service;
}
CamelAuthCallback authenticator;
- GHashTable *providers, *modules;
+ GHashTable *providers,
+ *modules,
+ *service_cache;
};
typedef struct {
sizeof (CamelStore),
sizeof (CamelStoreClass),
(GtkClassInitFunc) camel_store_class_init,
- (GtkObjectInitFunc) NULL,
+ (GtkObjectInitFunc) camel_store_init,
/* reserved_1 */ NULL,
/* reserved_2 */ NULL,
(GtkClassInitFunc) NULL,
g_warning ("Caching folder %s that already exists.",
folder_name);
}
- g_hash_table_insert (store->folders, (gpointer)folder_name, folder);
+ g_hash_table_insert (store->folders, (gpointer)g_strdup(folder_name), folder);
gtk_signal_connect_object (GTK_OBJECT (folder), "destroy",
GTK_SIGNAL_FUNC (CS_CLASS (store)->uncache_folder),
GTK_OBJECT (store));
static void
uncache_folder (CamelStore *store, CamelFolder *folder)
{
+ /* FIXME: free name index */
g_hash_table_remove (store->folders,
camel_folder_get_full_name (folder));
}
{
CamelFolder *folder = NULL;
+ printf("Getting folder %p '%s'\n", store, folder_name);
/* Try cache first. */
folder = CS_CLASS (store)->lookup_folder (store, folder_name);
+ if (folder) {
+ printf("Folder cached!\n");
+ } else {
+ printf("Folder not cached!\n");
+ }
+
if (!folder) {
folder = CS_CLASS (store)->get_folder (store, folder_name, ex);
if (!folder)
return NULL;
+ printf("storing folder in cache: %p '%s'\n", store, folder_name);
CS_CLASS (store)->cache_folder (store, folder_name, folder);
}
- gtk_object_ref (GTK_OBJECT (folder));
return folder;
}
*
* protocol://user;AUTH=mech:password@host:port/path
*
- * The protocol, followed by a ":" is required. If it is followed by
- * "//", there must be an "authority" containing at least a host,
+ * The protocol, followed by a ":" is required. If it is followed by * "//", there must be an "authority" containing at least a host,
* which ends at the end of the string or at the next "/". If there
* is an "@" in the authority, there must be a username before it,
* and the host comes after it. The authmech, password, and port are
}
*d = '\0';
}
+
+static void
+add_hash(guint *hash, char *s)
+{
+ if (s)
+ *hash ^= g_str_hash(s);
+}
+
+guint camel_url_hash (const void *v)
+{
+ const CamelURL *u = v;
+ guint hash = 0;
+
+ add_hash(&hash, u->protocol);
+ add_hash(&hash, u->user);
+ add_hash(&hash, u->authmech);
+ add_hash(&hash, u->passwd);
+ add_hash(&hash, u->host);
+ add_hash(&hash, u->path);
+ hash ^= u->port;
+ return hash;
+}
+
+static int
+check_equal(char *s1, char *s2)
+{
+ if (s1 == NULL) {
+ if (s2 == NULL)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ if (s2 == NULL) {
+ if (s1 == NULL)
+ return TRUE;
+ else
+ return FALSE;
+ }
+ return strcmp(s1, s2) == 0;
+}
+
+int camel_url_equal(const void *v, const void *v2)
+{
+ const CamelURL *u1 = v, *u2 = v2;
+
+ return check_equal(u1->protocol, u2->protocol)
+ && check_equal(u1->user, u2->user)
+ && check_equal(u1->authmech, u2->authmech)
+ && check_equal(u1->passwd, u2->passwd)
+ && check_equal(u1->host, u2->host)
+ && check_equal(u1->path, u2->path)
+ && u1->port == u2->port;
+}
char *escape_extra);
void camel_url_decode (char *part);
+/* for putting url's into hash tables */
+guint camel_url_hash (const void *v);
+int camel_url_equal(const void *v, const void *v2);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
{
CamelMboxFolder *mbox_folder = CAMEL_MBOX_FOLDER (folder);
CamelStream *output_stream = NULL, *filter_stream = NULL;
- CamelMimeFilter *filter_from;
+ CamelMimeFilter *filter_from = NULL;
struct stat st;
off_t seek = -1;
char *xev;
if (camel_mime_parser_tell_start_from(parser) != info->frompos) {
g_warning("Summary doesn't match the folder contents! eek!\n"
- " expecting offset %d got %d", info->frompos,
- camel_mime_parser_tell_start_from(parser));
+ " expecting offset %ld got %ld", (long int)info->frompos,
+ (long int)camel_mime_parser_tell_start_from(parser));
errno = EINVAL;
goto fail;
}