diff options
-rw-r--r-- | camel/ChangeLog | 22 | ||||
-rw-r--r-- | camel/camel-service.c | 10 | ||||
-rw-r--r-- | camel/camel-service.h | 1 | ||||
-rw-r--r-- | camel/camel-session.c | 62 | ||||
-rw-r--r-- | camel/camel-session.h | 4 | ||||
-rw-r--r-- | camel/camel-store.c | 14 | ||||
-rw-r--r-- | camel/camel-url.c | 56 | ||||
-rw-r--r-- | camel/camel-url.h | 4 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-folder.c | 6 | ||||
-rw-r--r-- | camel/providers/mbox/camel-mbox-summary.c | 2 |
10 files changed, 163 insertions, 18 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index f13b2c7c3a..f270abcad2 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,25 @@ +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 diff --git a/camel/camel-service.c b/camel/camel-service.c index 885c166a05..52a7581e9f 100644 --- a/camel/camel-service.c +++ b/camel/camel-service.c @@ -67,6 +67,13 @@ camel_service_class_init (CamelServiceClass *camel_service_class) gtk_object_class->finalize = _finalize; } +static void +camel_service_init (void *o, void *k) +{ +/* CamelService *service = o;*/ + return; +} + GtkType camel_service_get_type (void) { @@ -79,7 +86,7 @@ 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, @@ -92,7 +99,6 @@ camel_service_get_type (void) return camel_service_type; } - static void _finalize (GtkObject *object) { diff --git a/camel/camel-service.h b/camel/camel-service.h index c2f4f12020..7ebd6aa0e8 100644 --- a/camel/camel-service.h +++ b/camel/camel-service.h @@ -51,7 +51,6 @@ struct _CamelService { gboolean connected; CamelURL *url; int url_flags; - }; diff --git a/camel/camel-session.c b/camel/camel-session.c index 55a466e404..17d7e60ee0 100644 --- a/camel/camel-session.c +++ b/camel/camel-session.c @@ -34,12 +34,43 @@ #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 @@ -53,7 +84,7 @@ camel_session_get_type (void) "CamelSession", sizeof (CamelSession), sizeof (CamelSessionClass), - (GtkClassInitFunc) NULL, + (GtkClassInitFunc) camel_session_class_init, (GtkObjectInitFunc) camel_session_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, @@ -157,6 +188,11 @@ camel_session_list_providers (CamelSession *session, gboolean load) 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, @@ -164,11 +200,23 @@ 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. */ @@ -196,8 +244,12 @@ camel_session_get_service (CamelSession *session, const char *url_string, 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; } diff --git a/camel/camel-session.h b/camel/camel-session.h index 81f8a3da85..e6a6b2ffc2 100644 --- a/camel/camel-session.h +++ b/camel/camel-session.h @@ -53,7 +53,9 @@ struct _CamelSession CamelAuthCallback authenticator; - GHashTable *providers, *modules; + GHashTable *providers, + *modules, + *service_cache; }; typedef struct { diff --git a/camel/camel-store.c b/camel/camel-store.c index 87384a61d4..b4eae9975e 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -90,7 +90,7 @@ camel_store_get_type (void) sizeof (CamelStore), sizeof (CamelStoreClass), (GtkClassInitFunc) camel_store_class_init, - (GtkObjectInitFunc) NULL, + (GtkObjectInitFunc) camel_store_init, /* reserved_1 */ NULL, /* reserved_2 */ NULL, (GtkClassInitFunc) NULL, @@ -166,7 +166,7 @@ cache_folder (CamelStore *store, const char *folder_name, CamelFolder *folder) 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)); @@ -175,6 +175,7 @@ cache_folder (CamelStore *store, const char *folder_name, CamelFolder *folder) static void uncache_folder (CamelStore *store, CamelFolder *folder) { + /* FIXME: free name index */ g_hash_table_remove (store->folders, camel_folder_get_full_name (folder)); } @@ -186,18 +187,25 @@ get_folder_internal (CamelStore *store, const char *folder_name, { 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; } diff --git a/camel/camel-url.c b/camel/camel-url.c index 96721bda24..c0707dcbb1 100644 --- a/camel/camel-url.c +++ b/camel/camel-url.c @@ -43,8 +43,7 @@ * * 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 @@ -292,3 +291,56 @@ camel_url_decode (char *part) } *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; +} diff --git a/camel/camel-url.h b/camel/camel-url.h index f2a4c645f5..bea1c439b2 100644 --- a/camel/camel-url.h +++ b/camel/camel-url.h @@ -57,6 +57,10 @@ char *camel_url_encode (char *part, gboolean escape_unsafe, 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 */ diff --git a/camel/providers/mbox/camel-mbox-folder.c b/camel/providers/mbox/camel-mbox-folder.c index de7a7764ba..c663824301 100644 --- a/camel/providers/mbox/camel-mbox-folder.c +++ b/camel/providers/mbox/camel-mbox-folder.c @@ -593,7 +593,7 @@ mbox_append_message (CamelFolder *folder, CamelMimeMessage *message, CamelExcept { 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; @@ -779,8 +779,8 @@ mbox_get_message_by_uid (CamelFolder *folder, const gchar *uid, CamelException * 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; } diff --git a/camel/providers/mbox/camel-mbox-summary.c b/camel/providers/mbox/camel-mbox-summary.c index a5cd61b596..e78bede490 100644 --- a/camel/providers/mbox/camel-mbox-summary.c +++ b/camel/providers/mbox/camel-mbox-summary.c @@ -683,7 +683,7 @@ camel_mbox_summary_expunge(CamelMboxSummary *mbs) goto error; } /* update from pos here? */ - /*info->frompos += offset;*/ + info->frompos += offset; } else { d(printf("Nothing to do for this message\n")); } |