diff options
author | Not Zed <NotZed@Ximian.com> | 2002-05-07 15:31:26 +0800 |
---|---|---|
committer | Michael Zucci <zucchi@src.gnome.org> | 2002-05-07 15:31:26 +0800 |
commit | 4655d888677e71962722ad86f255a27386e1e621 (patch) | |
tree | a72629c9b63c2b16ca71fc3b666735cfd14b6bef | |
parent | 1acd03710d50072259f91bae1a9e2395c6bdfac7 (diff) | |
download | gsoc2013-evolution-4655d888677e71962722ad86f255a27386e1e621.tar.gz gsoc2013-evolution-4655d888677e71962722ad86f255a27386e1e621.tar.zst gsoc2013-evolution-4655d888677e71962722ad86f255a27386e1e621.zip |
Check for LOGIN xxxx as well if debug is on, so we dont print passwords to
2002-05-07 Not Zed <NotZed@Ximian.com>
* camel-remote-store.c (remote_send_string): Check for LOGIN xxxx
as well if debug is on, so we dont print passwords to evolution
logs.
* providers/imap/camel-imap-utils.c (imap_is_atom_char): This was
really broken. 1. isprint() is locale dependent, and 2. it looked
up an 8 bit value in a 7 bit table without truncating it. I've
removed the isprint() stuff and just put it directly into the
special table, which i've expanded to the right size too.
* providers/imap/*: Applied patch from Preston Elder
<prez@magick.tm> to make camel only use literals if it needs to
for simple strings. Changed slightly to use imap_is_atom() and
more consistent formatting.
providers/imap/camel-imap-utils.c (imap_is_atom): Chagned from
imap_needs_quoting().
** Merged in camel-object2 branch. Simpler camelobject
implementation + object args interface.
* camel.c (camel_init): Call camel_object_get_type() to make sure
camel_object_type is initialised.
* camel-object.h (CAMEL_OBJECT_TYPE): Changed to return global
camel_object_type pointer, not call camel_object_get_type.
svn path=/trunk/; revision=16701
49 files changed, 1119 insertions, 850 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog index 2e85fa9be6..4bd0a9329e 100644 --- a/camel/ChangeLog +++ b/camel/ChangeLog @@ -1,3 +1,31 @@ +2002-05-07 Not Zed <NotZed@Ximian.com> + + * camel-remote-store.c (remote_send_string): Check for LOGIN xxxx + as well if debug is on, so we dont print passwords to evolution + logs. + + * providers/imap/camel-imap-utils.c (imap_is_atom_char): This was + really broken. 1. isprint() is locale dependent, and 2. it looked + up an 8 bit value in a 7 bit table without truncating it. I've + removed the isprint() stuff and just put it directly into the + special table, which i've expanded to the right size too. + + * providers/imap/*: Applied patch from Preston Elder + <prez@magick.tm> to make camel only use literals if it needs to + for simple strings. Changed slightly to use imap_is_atom() and + more consistent formatting. + providers/imap/camel-imap-utils.c (imap_is_atom): Chagned from + imap_needs_quoting(). + + ** Merged in camel-object2 branch. Simpler camelobject + implementation + object args interface. + + * camel.c (camel_init): Call camel_object_get_type() to make sure + camel_object_type is initialised. + + * camel-object.h (CAMEL_OBJECT_TYPE): Changed to return global + camel_object_type pointer, not call camel_object_get_type. + 2002-05-06 Jeffrey Stedfast <fejj@ximian.com> * providers/pop3/camel-pop3-store.c (pop3_try_authenticate): If @@ -216,6 +244,21 @@ used the full names. (MONTH_CHARS): Same as above but for months. +2002-04-15 Not Zed <NotZed@Ximian.com> + + * *.c: Fix callers for api changes to camel-object, mainly + declare_event->add_event, and classfuncs->klass, and a couple + of missing #include <config.h>'s + + * camel-arg.[ch], Makefile.am: New support code for + camel_object_get/set arg. + + * *.h: Fixed all uses of get_type to return a CamelType rather + than a guint (now a pointer). + + * camel-object.[ch]: Major cleanup of object implementation. Also + added a get/set interface, and some debugging options. + 2002-04-11 Not Zed <NotZed@Ximian.com> * providers/local/camel-spool-summary.c (spool_summary_sync_full): diff --git a/camel/Makefile.am b/camel/Makefile.am index d38787c218..7937c7aa1c 100644 --- a/camel/Makefile.am +++ b/camel/Makefile.am @@ -20,6 +20,7 @@ INCLUDES = -I.. -I$(srcdir)/.. \ libcamel_la_SOURCES = \ broken-date-parser.c \ camel-address.c \ + camel-arg.c \ camel-block-file.c \ camel-cipher-context.c \ camel-cms-context.c \ @@ -115,6 +116,7 @@ libcamel_la_SOURCES = \ libcamelinclude_HEADERS = \ broken-date-parser.h \ camel-address.h \ + camel-arg.h \ camel-block-file.h \ camel-charset-map.h \ camel-cipher-context.h \ diff --git a/camel/camel-arg.c b/camel/camel-arg.c new file mode 100644 index 0000000000..bc6ececd2e --- /dev/null +++ b/camel/camel-arg.c @@ -0,0 +1,124 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * + * + * Author: + * Michael Zucchi <notzed@ximian.com> + * + * Copyright 2002 Ximian, Inc. (www.ximian.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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 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 + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include "camel-arg.h" + +int camel_argv_build(CamelArgV *tv) +{ + register guint32 tag; + register int i; + register CamelArg *a; + int more = TRUE; + + for (i=0;i<CAMEL_ARGV_MAX;i++) { + a = &tv->argv[i]; + + if ( (tag = va_arg(tv->ap, guint32)) == 0) { + more = FALSE; + break; + } + + a->tag = tag; + + switch((tag & CAMEL_ARG_TYPE)) { + case CAMEL_ARG_OBJ: + a->ca_object = va_arg(tv->ap, void *); + break; + case CAMEL_ARG_INT: + a->ca_int = va_arg(tv->ap, int); + break; + case CAMEL_ARG_DBL: + a->ca_double = va_arg(tv->ap, double); + break; + case CAMEL_ARG_STR: + a->ca_str = va_arg(tv->ap, char *); + break; + case CAMEL_ARG_PTR: + a->ca_ptr = va_arg(tv->ap, void *); + break; + default: + printf("Error, unknown type, truncating result\n"); + more = FALSE; + goto fail; + } + + } +fail: + tv->argc = i; + + return more; +} + +int camel_arggetv_build(CamelArgGetV *tv) +{ + register guint32 tag; + register int i; + register CamelArgGet *a; + int more = TRUE; + + for (i=0;i<CAMEL_ARGV_MAX;i++) { + a = &tv->argv[i]; + + if ( (tag = va_arg(tv->ap, guint32)) == 0) { + more = FALSE; + break; + } + + a->tag = tag; + + switch((tag & CAMEL_ARG_TYPE)) { + case CAMEL_ARG_OBJ: + a->ca_object = va_arg(tv->ap, void **); + *a->ca_object = NULL; + break; + case CAMEL_ARG_INT: + a->ca_int = va_arg(tv->ap, int *); + *a->ca_int = 0; + break; + case CAMEL_ARG_DBL: + a->ca_double = va_arg(tv->ap, double *); + *a->ca_double = 0.0; + break; + case CAMEL_ARG_STR: + a->ca_str = va_arg(tv->ap, char **); + *a->ca_str = NULL; + break; + case CAMEL_ARG_PTR: + a->ca_ptr = va_arg(tv->ap, void **); + *a->ca_ptr = NULL; + break; + default: + printf("Error, unknown type, truncating result\n"); + more = FALSE; + goto fail; + } + + } +fail: + tv->argc = i; + + return more; +} diff --git a/camel/camel-arg.h b/camel/camel-arg.h new file mode 100644 index 0000000000..7846018149 --- /dev/null +++ b/camel/camel-arg.h @@ -0,0 +1,109 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * + * Author: + * Michael Zucchi <notzed@ximian.com> + * + * Copyright 2002 Ximian, Inc. (www.ximian.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of version 2 of the GNU General Public + * License as published by the Free Software Foundation. + * + * 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 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 CAMEL_ARG_H +#define CAMEL_ARG_H 1 + +#ifdef __cplusplus +extern "C" { +#pragma } +#endif /* __cplusplus } */ + +#include <glib.h> +#include <stdarg.h> + +enum camel_arg_t { + CAMEL_ARG_END = 0, + CAMEL_ARG_IGNORE = 1, /* override/ignore an arg in-place */ + + CAMEL_ARG_FIRST = 1024, /* 1024 args reserved for arg system */ + + CAMEL_ARG_TYPE = 0xf0000000, /* type field for tags */ + CAMEL_ARG_TAG = 0x0fffffff, /* tag field for args */ + + CAMEL_ARG_OBJ = 0x00000000, /* object */ + CAMEL_ARG_INT = 0x10000000, /* int */ + CAMEL_ARG_DBL = 0x20000000, /* double */ + CAMEL_ARG_STR = 0x30000000, /* c string */ + CAMEL_ARG_PTR = 0x40000000, /* ptr */ +}; + +typedef struct _CamelArg CamelArg; +typedef struct _CamelArgV CamelArgV; + +typedef struct _CamelArgGet CamelArgGet; +typedef struct _CamelArgGetV CamelArgGetV; + +struct _CamelArg { + guint32 tag; + union { + void *ca_object; + int ca_int; + double ca_double; + char *ca_str; + void *ca_ptr; + } u; +}; +struct _CamelArgGet { + guint32 tag; + union { + void **ca_object; + int *ca_int; + double *ca_double; + char **ca_str; + void **ca_ptr; + } u; +}; +#define ca_object u.ca_object +#define ca_int u.ca_int +#define ca_double u.ca_double +#define ca_str u.ca_str +#define ca_ptr u.ca_ptr + +/* maximum no of args processed at any one time, not the max of all args */ +#define CAMEL_ARGV_MAX (20) + +struct _CamelArgV { + va_list ap; + int argc; + CamelArg argv[CAMEL_ARGV_MAX]; +}; + +struct _CamelArgGetV { + va_list ap; + int argc; + CamelArgGet argv[CAMEL_ARGV_MAX]; +}; + +#define camel_argv_start(tv, last) (va_start((tv)->ap, last)) +#define camel_argv_end(tv) (va_end((tv)->ap)) +int camel_argv_build(CamelArgV *tv); +int camel_arggetv_build(CamelArgGetV *tv); + +/* set an arg ignored */ +#define camel_argv_ignore(tv, i) ((tv)->argv[i].tag = ((tv)->argv[i].tag & CAMEL_ARG_TYPE) | CAMEL_ARG_IGNORE) + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* CAMEL_ARG_H */ diff --git a/camel/camel-block-file.c b/camel/camel-block-file.c index be30ad6f17..1ec1f74061 100644 --- a/camel/camel-block-file.c +++ b/camel/camel-block-file.c @@ -83,7 +83,7 @@ static EDList block_file_active_list = E_DLIST_INITIALISER(block_file_active_lis static int block_file_count = 0; static int block_file_threshhold = 10; -#define CBF_CLASS(o) ((CamelBlockFileClass *)(((CamelObject *)o)->classfuncs)) +#define CBF_CLASS(o) ((CamelBlockFileClass *)(((CamelObject *)o)->klass)) static int sync_nolock(CamelBlockFile *bs); static int sync_block_nolock(CamelBlockFile *bs, CamelBlock *bl); diff --git a/camel/camel-folder-search.c b/camel/camel-folder-search.c index d9702706f9..92b73e6f59 100644 --- a/camel/camel-folder-search.c +++ b/camel/camel-folder-search.c @@ -213,7 +213,7 @@ camel_folder_search_construct (CamelFolderSearch *search) /* c is sure messy sometimes */ func = *((void **)(((char *)klass)+builtins[i].offset)); if (func == NULL && builtins[i].flags&1) { - g_warning("Search class doesn't implement '%s' method: %s", builtins[i].name, camel_type_to_name(CAMEL_OBJECT_GET_CLASS(search)->s.type)); + g_warning("Search class doesn't implement '%s' method: %s", builtins[i].name, camel_type_to_name(CAMEL_OBJECT_GET_CLASS(search))); func = (void *)search_dummy; } if (func != NULL) { diff --git a/camel/camel-folder-search.h b/camel/camel-folder-search.h index 3f29567aed..701178b0b4 100644 --- a/camel/camel-folder-search.h +++ b/camel/camel-folder-search.h @@ -112,7 +112,7 @@ struct _CamelFolderSearchClass { ESExpResult * (*uid)(struct _ESExp *f, int argc, struct _ESExpResult **argv, CamelFolderSearch *s); }; -guint camel_folder_search_get_type (void); +CamelType camel_folder_search_get_type (void); CamelFolderSearch *camel_folder_search_new (void); void camel_folder_search_construct (CamelFolderSearch *search); diff --git a/camel/camel-folder-summary.h b/camel/camel-folder-summary.h index 3ba03480d6..e94ffe2cfa 100644 --- a/camel/camel-folder-summary.h +++ b/camel/camel-folder-summary.h @@ -209,7 +209,7 @@ struct _CamelFolderSummaryClass { char *(*next_uid_string)(CamelFolderSummary *); }; -guint camel_folder_summary_get_type (void); +CamelType camel_folder_summary_get_type (void); CamelFolderSummary *camel_folder_summary_new (void); void camel_folder_summary_set_filename(CamelFolderSummary *, const char *); diff --git a/camel/camel-folder.c b/camel/camel-folder.c index b29a845fb2..e4edebf257 100644 --- a/camel/camel-folder.c +++ b/camel/camel-folder.c @@ -45,7 +45,7 @@ static CamelObjectClass *parent_class = NULL; /* Returns the class for a CamelFolder */ -#define CF_CLASS(so) ((CamelFolderClass *)((CamelObject *)(so))->classfuncs) +#define CF_CLASS(so) ((CamelFolderClass *)((CamelObject *)(so))->klass) static void camel_folder_finalize (CamelObject *object); @@ -156,12 +156,10 @@ camel_folder_class_init (CamelFolderClass *camel_folder_class) camel_folder_class->is_frozen = is_frozen; /* virtual method overload */ - camel_object_class_declare_event (camel_object_class, - "folder_changed", folder_changed); - camel_object_class_declare_event (camel_object_class, - "message_changed", message_changed); - camel_object_class_declare_event (camel_object_class, "deleted", NULL); - camel_object_class_declare_event (camel_object_class, "renamed", NULL); + camel_object_class_add_event(camel_object_class, "folder_changed", folder_changed); + camel_object_class_add_event(camel_object_class, "message_changed", message_changed); + camel_object_class_add_event(camel_object_class, "deleted", NULL); + camel_object_class_add_event(camel_object_class, "renamed", NULL); } static void diff --git a/camel/camel-html-parser.h b/camel/camel-html-parser.h index 973ce29fe5..2e68e3bdff 100644 --- a/camel/camel-html-parser.h +++ b/camel/camel-html-parser.h @@ -65,7 +65,7 @@ struct _CamelHTMLParserClass { CamelObjectClass parent_class; }; -guint camel_html_parser_get_type (void); +CamelType camel_html_parser_get_type (void); CamelHTMLParser *camel_html_parser_new (void); void camel_html_parser_set_data(CamelHTMLParser *hp, const char *start, int len, int last); diff --git a/camel/camel-index.c b/camel/camel-index.c index cb8ebd120b..eb476b41fc 100644 --- a/camel/camel-index.c +++ b/camel/camel-index.c @@ -46,7 +46,7 @@ struct _CamelIndexPrivate { #define _PRIVATE(o) (((CamelIndex *)(o))->priv) -#define CI_CLASS(o) ((CamelIndexClass *)(((CamelObject *)o)->classfuncs)) +#define CI_CLASS(o) ((CamelIndexClass *)(((CamelObject *)o)->klass)) /* ********************************************************************** */ /* CamelIndex */ @@ -203,7 +203,7 @@ camel_index_names(CamelIndex *idx) static CamelObjectClass *camel_index_name_parent; -#define CIN_CLASS(o) ((CamelIndexNameClass *)(((CamelObject *)o)->classfuncs)) +#define CIN_CLASS(o) ((CamelIndexNameClass *)(((CamelObject *)o)->klass)) static void camel_index_name_class_init(CamelIndexNameClass *klass) @@ -278,7 +278,7 @@ camel_index_name_add_buffer(CamelIndexName *idn, const char *buffer, size_t len) static CamelObjectClass *camel_index_cursor_parent; -#define CIC_CLASS(o) ((CamelIndexCursorClass *)(((CamelObject *)o)->classfuncs)) +#define CIC_CLASS(o) ((CamelIndexCursorClass *)(((CamelObject *)o)->klass)) static void camel_index_cursor_class_init(CamelIndexCursorClass *klass) diff --git a/camel/camel-index.h b/camel/camel-index.h index eba57a43b0..81b84c3d38 100644 --- a/camel/camel-index.h +++ b/camel/camel-index.h @@ -64,7 +64,7 @@ struct _CamelIndexCursorClass { void (*reset) (CamelIndexCursor *idc); }; -guint camel_index_cursor_get_type(void); +CamelType camel_index_cursor_get_type(void); CamelIndexCursor *camel_index_cursor_new(CamelIndex *idx, const char *name); @@ -94,7 +94,7 @@ struct _CamelIndexNameClass { size_t (*add_buffer)(CamelIndexName *name, const char *buffer, size_t len); }; -guint camel_index_name_get_type (void); +CamelType camel_index_name_get_type (void); CamelIndexName *camel_index_name_new(CamelIndex *idx, const char *name); @@ -135,7 +135,7 @@ struct _CamelIndexClass { CamelIndexCursor * (*names)(CamelIndex *idx); }; -guint camel_index_get_type (void); +CamelType camel_index_get_type (void); CamelIndex *camel_index_new(const char *path, int flags); void camel_index_construct(CamelIndex *, const char *path, int flags); diff --git a/camel/camel-mime-filter-basic.h b/camel/camel-mime-filter-basic.h index 196f0bdb09..d07edee107 100644 --- a/camel/camel-mime-filter-basic.h +++ b/camel/camel-mime-filter-basic.h @@ -60,7 +60,7 @@ struct _CamelMimeFilterBasicClass { CamelMimeFilterClass parent_class; }; -guint camel_mime_filter_basic_get_type (void); +CamelType camel_mime_filter_basic_get_type (void); CamelMimeFilterBasic *camel_mime_filter_basic_new (void); CamelMimeFilterBasic *camel_mime_filter_basic_new_type (CamelMimeFilterBasicType type); diff --git a/camel/camel-mime-filter-bestenc.h b/camel/camel-mime-filter-bestenc.h index 8950a95a0a..3d2e79fa55 100644 --- a/camel/camel-mime-filter-bestenc.h +++ b/camel/camel-mime-filter-bestenc.h @@ -83,7 +83,7 @@ struct _CamelMimeFilterBestencClass { CamelMimeFilterClass parent_class; }; -guint camel_mime_filter_bestenc_get_type (void); +CamelType camel_mime_filter_bestenc_get_type (void); CamelMimeFilterBestenc *camel_mime_filter_bestenc_new (unsigned int flags); diff --git a/camel/camel-mime-filter-charset.h b/camel/camel-mime-filter-charset.h index 80cf7d6213..ddc3025eb0 100644 --- a/camel/camel-mime-filter-charset.h +++ b/camel/camel-mime-filter-charset.h @@ -50,7 +50,7 @@ struct _CamelMimeFilterCharsetClass { CamelMimeFilterClass parent_class; }; -guint camel_mime_filter_charset_get_type (void); +CamelType camel_mime_filter_charset_get_type (void); CamelMimeFilterCharset *camel_mime_filter_charset_new (void); CamelMimeFilterCharset *camel_mime_filter_charset_new_convert (const char *from_charset, const char *to_charset); diff --git a/camel/camel-mime-filter-from.h b/camel/camel-mime-filter-from.h index 2176dfcda4..cbc2e70a94 100644 --- a/camel/camel-mime-filter-from.h +++ b/camel/camel-mime-filter-from.h @@ -49,7 +49,7 @@ struct _CamelMimeFilterFromClass { CamelMimeFilterClass parent_class; }; -guint camel_mime_filter_from_get_type (void); +CamelType camel_mime_filter_from_get_type (void); CamelMimeFilterFrom *camel_mime_filter_from_new (void); #ifdef __cplusplus diff --git a/camel/camel-mime-filter-html.h b/camel/camel-mime-filter-html.h index f572e3b06d..bb9b6aaa4e 100644 --- a/camel/camel-mime-filter-html.h +++ b/camel/camel-mime-filter-html.h @@ -47,7 +47,7 @@ struct _CamelMimeFilterHTMLClass { CamelMimeFilterClass parent_class; }; -guint camel_mime_filter_html_get_type (void); +CamelType camel_mime_filter_html_get_type (void); CamelMimeFilterHTML *camel_mime_filter_html_new (void); #ifdef __cplusplus diff --git a/camel/camel-mime-filter-index.h b/camel/camel-mime-filter-index.h index fa1f49e830..3bb1bd532c 100644 --- a/camel/camel-mime-filter-index.h +++ b/camel/camel-mime-filter-index.h @@ -49,7 +49,7 @@ struct _CamelMimeFilterIndexClass { CamelMimeFilterClass parent_class; }; -guint camel_mime_filter_index_get_type (void); +CamelType camel_mime_filter_index_get_type (void); CamelMimeFilterIndex *camel_mime_filter_index_new (void); CamelMimeFilterIndex *camel_mime_filter_index_new_index(struct _CamelIndex *); diff --git a/camel/camel-mime-parser.h b/camel/camel-mime-parser.h index 81c2e0d8c8..7f784a1065 100644 --- a/camel/camel-mime-parser.h +++ b/camel/camel-mime-parser.h @@ -80,7 +80,7 @@ struct _CamelMimeParserClass { void (*content)(CamelMimeParser *); }; -guint camel_mime_parser_get_type (void); +CamelType camel_mime_parser_get_type (void); CamelMimeParser *camel_mime_parser_new (void); /* quick-fix for parser not erroring, we can find out if it had an error afterwards */ diff --git a/camel/camel-news-address.h b/camel/camel-news-address.h index 444dfb4580..ca1505e9a6 100644 --- a/camel/camel-news-address.h +++ b/camel/camel-news-address.h @@ -46,7 +46,7 @@ struct _CamelNewsAddressClass { CamelAddressClass parent_class; }; -guint camel_news_address_get_type (void); +CamelType camel_news_address_get_type (void); CamelNewsAddress *camel_news_address_new (void); #ifdef __cplusplus diff --git a/camel/camel-object.c b/camel/camel-object.c index b10edf82a4..cb21b58f0d 100644 --- a/camel/camel-object.c +++ b/camel/camel-object.c @@ -1,9 +1,8 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ -/* camel-object.c: Base class for Camel */ - -/* +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- * + * * Author: * Dan Winship <danw@ximian.com> + * Michael Zucchi <notzed@ximian.com> * * Copyright 2000 Ximian, Inc. (www.ximian.com) * @@ -26,47 +25,25 @@ #include <config.h> #endif +#include <stdio.h> #include <string.h> #include "camel-object.h" +#include <e-util/e-memory.h> + #ifdef ENABLE_THREADS #include <pthread.h> #include <e-util/e-msgport.h> #endif /* I just mashed the keyboard for these... */ -#define CAMEL_OBJECT_MAGIC_VALUE 0x77A344EF -#define CAMEL_OBJECT_CLASS_MAGIC_VALUE 0xEE26A990 -#define CAMEL_OBJECT_FINALIZED_VALUE 0x84AC3656 -#define CAMEL_OBJECT_CLASS_FINALIZED_VALUE 0x7621ABCD - -#define DEFAULT_PREALLOCS 8 - -#define BAST_CASTARD 1 /* Define to return NULL when casts fail */ - -#define NULL_PREP_VALUE ((gpointer)make_global_classfuncs) /* See camel_object_class_declare_event */ +#define CAMEL_OBJECT_MAGIC 0x77A344ED +#define CAMEL_OBJECT_CLASS_MAGIC 0xEE26A997 +#define CAMEL_OBJECT_FINALISED_MAGIC 0x84AC365F +#define CAMEL_OBJECT_CLASS_FINALISED_MAGIC 0x7621ABCD /* ** Quickie type system ************************************************* */ -typedef struct _CamelTypeInfo -{ - CamelType self; - CamelType parent; - const gchar *name; - - size_t instance_size; - GMemChunk *instance_chunk; - CamelObjectInitFunc instance_init; - CamelObjectFinalizeFunc instance_finalize; - GList *free_instances; - - size_t classfuncs_size; - CamelObjectClassInitFunc class_init; - CamelObjectClassFinalizeFunc class_finalize; - CamelObjectClass *global_classfuncs; -} -CamelTypeInfo; - /* A 'locked' hooklist, that is only allocated on demand */ typedef struct _CamelHookList { EMutex *lock; @@ -90,642 +67,536 @@ typedef struct _CamelHookPair { struct _CamelHookPair *next; /* next MUST be the first member */ - unsigned int flags; /* removed, etc */ + unsigned int id:30; + unsigned int flags:2; /* removed, etc */ const char *name; /* points to the key field in the classes preplist, static memory */ - CamelObjectEventHookFunc func; + union { + CamelObjectEventHookFunc event; + CamelObjectEventPrepFunc prep; + } func; void *data; } CamelHookPair; -/* ************************************************************************ */ +/* ********************************************************************** */ -static void camel_type_lock_up (void); -static void camel_type_lock_down (void); +static void camel_object_free_hooks(CamelObject *o); -static void obj_init (CamelObject * obj); -static void obj_finalize (CamelObject * obj); -static void obj_class_init (CamelObjectClass * class); -static void obj_class_finalize (CamelObjectClass * class); +/* ********************************************************************** */ -static gboolean shared_is_of_type (CamelObjectShared * sh, CamelType ctype, - gboolean is_obj); -static void make_global_classfuncs (CamelTypeInfo * type_info); +static pthread_mutex_t chunks_lock = PTHREAD_MUTEX_INITIALIZER; -static void camel_object_free_hooks(CamelObject *o); +static EMemChunk *pair_chunks; +static EMemChunk *hook_chunks; +static unsigned int pair_id = 1; -/* ************************************************************************ */ +static EMutex *type_lock; -G_LOCK_DEFINE_STATIC (type_system); -G_LOCK_DEFINE_STATIC (type_system_level); -static GPrivate *type_system_locklevel = NULL; +static GHashTable *type_table; +static EMemChunk *type_chunks; -G_LOCK_DEFINE_STATIC (refcount); +CamelType camel_object_type; -static gboolean type_system_initialized = FALSE; -static GHashTable *ctype_to_typeinfo = NULL; -static GHashTable *name_to_typeinfo = NULL; -static const CamelType camel_object_type = 1; -static CamelType cur_max_type = CAMEL_INVALID_TYPE; +#ifdef ENABLE_THREADS +#define P_LOCK(l) (pthread_mutex_lock(&l)) +#define P_UNLOCK(l) (pthread_mutex_unlock(&l)) +#define E_LOCK(l) (e_mutex_lock(l)) +#define E_UNLOCK(l) (e_mutex_unlock(l)) +#define CLASS_LOCK(k) (g_mutex_lock((((CamelObjectClass *)k)->lock))) +#define CLASS_UNLOCK(k) (g_mutex_unlock((((CamelObjectClass *)k)->lock))) +#else +#define P_LOCK(l) +#define P_UNLOCK(l) +#define E_LOCK(l) +#define E_UNLOCK(l) +#define CLASS_LOCK(k) +#define CLASS_UNLOCK(k) +#endif -/* ************************************************************************ */ +static struct _CamelHookPair * +pair_alloc(void) +{ + CamelHookPair *pair; -#define LOCK_VAL (GPOINTER_TO_INT (g_private_get (type_system_locklevel))) -#define LOCK_SET( val ) g_private_set (type_system_locklevel, GINT_TO_POINTER (val)) + P_LOCK(chunks_lock); + pair = e_memchunk_alloc(pair_chunks); + pair->id = pair_id++; + if (pair_id == 0) + pair_id = 1; + P_UNLOCK(chunks_lock); + + return pair; +} static void -camel_type_lock_up (void) +pair_free(CamelHookPair *pair) { - G_LOCK (type_system_level); + g_assert(pair_chunks != NULL); - if (type_system_locklevel == NULL) - type_system_locklevel = g_private_new (GINT_TO_POINTER (0)); + P_LOCK(chunks_lock); + e_memchunk_free(pair_chunks, pair); + P_UNLOCK(chunks_lock); +} - if (LOCK_VAL == 0) { - G_UNLOCK (type_system_level); - G_LOCK (type_system); - G_LOCK (type_system_level); - } +static struct _CamelHookList * +hooks_alloc(void) +{ + CamelHookList *hooks; - LOCK_SET (LOCK_VAL + 1); + P_LOCK(chunks_lock); + hooks = e_memchunk_alloc(hook_chunks); + P_UNLOCK(chunks_lock); - G_UNLOCK (type_system_level); + return hooks; } static void -camel_type_lock_down (void) +hooks_free(CamelHookList *hooks) { - G_LOCK (type_system_level); + g_assert(hook_chunks != NULL); - if (type_system_locklevel == NULL) { - g_warning - ("camel_type_lock_down: lock down before a lock up?"); - type_system_locklevel = g_private_new (GINT_TO_POINTER (0)); - G_UNLOCK (type_system_level); - return; - } - - LOCK_SET (LOCK_VAL - 1); - - if (LOCK_VAL == 0) - G_UNLOCK (type_system); - - G_UNLOCK (type_system_level); + P_LOCK(chunks_lock); + e_memchunk_free(hook_chunks, hooks); + P_UNLOCK(chunks_lock); } +/* not checked locked, who cares, only required for people that want to redefine root objects */ void -camel_type_init (void) +camel_type_init(void) { - CamelTypeInfo *obj_info; + static int init = FALSE; - camel_type_lock_up (); - - if (type_system_initialized) { - g_warning ("camel_type_init: type system already initialized."); - camel_type_lock_down (); + if (init) return; - } - type_system_initialized = TRUE; - ctype_to_typeinfo = g_hash_table_new (g_direct_hash, g_direct_equal); - name_to_typeinfo = g_hash_table_new (g_str_hash, g_str_equal); - - obj_info = g_new (CamelTypeInfo, 1); - obj_info->self = camel_object_type; - obj_info->parent = CAMEL_INVALID_TYPE; - obj_info->name = "CamelObject"; - - obj_info->instance_size = sizeof (CamelObject); - obj_info->instance_chunk = - g_mem_chunk_create (CamelObject, DEFAULT_PREALLOCS, - G_ALLOC_ONLY); - obj_info->instance_init = obj_init; - obj_info->instance_finalize = obj_finalize; - obj_info->free_instances = NULL; - - obj_info->classfuncs_size = sizeof (CamelObjectClass); - obj_info->class_init = obj_class_init; - obj_info->class_finalize = obj_class_finalize; - - g_hash_table_insert (ctype_to_typeinfo, - GINT_TO_POINTER (CAMEL_INVALID_TYPE), NULL); - g_hash_table_insert (ctype_to_typeinfo, - GINT_TO_POINTER (camel_object_type), obj_info); - g_hash_table_insert (name_to_typeinfo, (gpointer) obj_info->name, obj_info); - - /* Sigh. Ugly */ - make_global_classfuncs (obj_info); - - cur_max_type = camel_object_type; - - camel_type_lock_down (); + init = TRUE; + pair_chunks = e_memchunk_new(16, sizeof(CamelHookPair)); + hook_chunks = e_memchunk_new(16, sizeof(CamelHookList)); + type_lock = e_mutex_new(E_MUTEX_REC); + type_chunks = e_memchunk_new(32, sizeof(CamelType)); + type_table = g_hash_table_new(NULL, NULL); } -CamelType -camel_type_register (CamelType parent, const gchar * name, - size_t instance_size, size_t classfuncs_size, - CamelObjectClassInitFunc class_init, - CamelObjectClassFinalizeFunc class_finalize, - CamelObjectInitFunc instance_init, - CamelObjectFinalizeFunc instance_finalize) -{ - CamelTypeInfo *parent_info; - CamelTypeInfo *obj_info; - gchar *chunkname; - - g_return_val_if_fail (parent != CAMEL_INVALID_TYPE, - CAMEL_INVALID_TYPE); - g_return_val_if_fail (name, CAMEL_INVALID_TYPE); - g_return_val_if_fail (instance_size, CAMEL_INVALID_TYPE); - g_return_val_if_fail (classfuncs_size, CAMEL_INVALID_TYPE); - - camel_type_lock_up (); - - if (type_system_initialized == FALSE) { - G_UNLOCK (type_system); - camel_type_init (); - G_LOCK (type_system); - } - - obj_info = g_hash_table_lookup (name_to_typeinfo, name); - if (obj_info != NULL) { - /* looks like we've already registered this type... */ - camel_type_lock_down (); - return obj_info->self; - } - - parent_info = - g_hash_table_lookup (ctype_to_typeinfo, - GINT_TO_POINTER (parent)); - - if (parent_info == NULL) { - g_warning - ("camel_type_register: no such parent type %d of class `%s'", - parent, name); - camel_type_lock_down (); - return CAMEL_INVALID_TYPE; - } - - if (parent_info->instance_size > instance_size) { - g_warning - ("camel_type_register: instance of class `%s' would be smaller than parent `%s'", - name, parent_info->name); - camel_type_lock_down (); - return CAMEL_INVALID_TYPE; - } - - if (parent_info->classfuncs_size > classfuncs_size) { - g_warning - ("camel_type_register: classfuncs of class `%s' would be smaller than parent `%s'", - name, parent_info->name); - camel_type_lock_down (); - return CAMEL_INVALID_TYPE; - } +/* ************************************************************************ */ - cur_max_type++; - - obj_info = g_new (CamelTypeInfo, 1); - obj_info->self = cur_max_type; - obj_info->parent = parent; - obj_info->name = name; - - obj_info->instance_size = instance_size; - chunkname = - g_strdup_printf ("chunk for instances of Camel type `%s'", - name); - obj_info->instance_chunk = - g_mem_chunk_new (chunkname, instance_size, - instance_size * DEFAULT_PREALLOCS, - G_ALLOC_ONLY); - g_free (chunkname); - obj_info->instance_init = instance_init; - obj_info->instance_finalize = instance_finalize; - obj_info->free_instances = NULL; - - obj_info->classfuncs_size = classfuncs_size; - obj_info->class_init = class_init; - obj_info->class_finalize = class_finalize; - - g_hash_table_insert (ctype_to_typeinfo, - GINT_TO_POINTER (obj_info->self), obj_info); - g_hash_table_insert (name_to_typeinfo, (gpointer) obj_info->name, obj_info); - - /* Sigh. Ugly. */ - make_global_classfuncs (obj_info); - - camel_type_lock_down (); - return obj_info->self; +/* Should this return the object to the caller? */ +static void +cobject_init (CamelObject *o, CamelObjectClass *klass) +{ + o->klass = klass; + o->magic = CAMEL_OBJECT_MAGIC; + o->ref_count = 1; + o->flags = 0; } -CamelObjectClass * -camel_type_get_global_classfuncs (CamelType type) +static void +cobject_finalise(CamelObject *o) { - CamelTypeInfo *type_info; - - g_return_val_if_fail (type != CAMEL_INVALID_TYPE, NULL); - - camel_type_lock_up (); - type_info = - g_hash_table_lookup (ctype_to_typeinfo, - GINT_TO_POINTER (type)); - camel_type_lock_down (); + g_assert(o->ref_count == 0); - g_return_val_if_fail (type_info != NULL, NULL); + camel_object_free_hooks(o); - return type_info->global_classfuncs; + o->magic = CAMEL_OBJECT_FINALISED_MAGIC; + o->klass = NULL; } -const gchar * -camel_type_to_name (CamelType type) +static int +cobject_getv(CamelObject *o, CamelException *ex, CamelArgGetV *args) { - CamelTypeInfo *type_info; - - g_return_val_if_fail (type != CAMEL_INVALID_TYPE, - "(the invalid type)"); - - camel_type_lock_up (); - type_info = - g_hash_table_lookup (ctype_to_typeinfo, - GINT_TO_POINTER (type)); - camel_type_lock_down (); - - g_return_val_if_fail (type_info != NULL, - "(a bad type parameter was specified)"); - - return type_info->name; + /* could have flags or stuff here? */ + return 0; } -/* ** The CamelObject ***************************************************** */ - -static void -obj_init (CamelObject * obj) +static int +cobject_setv(CamelObject *o, CamelException *ex, CamelArgV *args) { - obj->s.magic = CAMEL_OBJECT_MAGIC_VALUE; - obj->ref_count = 1; - obj->hooks = NULL; - obj->in_event = 0; - obj->destroying = 0; + /* could have flags or stuff here? */ + return 0; } static void -obj_finalize (CamelObject * obj) +cobject_class_init(CamelObjectClass *klass) { - g_return_if_fail (obj->s.magic == CAMEL_OBJECT_MAGIC_VALUE); - g_return_if_fail (obj->ref_count == 0); - g_return_if_fail (obj->in_event == 0); + klass->magic = CAMEL_OBJECT_CLASS_MAGIC; - obj->s.magic = CAMEL_OBJECT_FINALIZED_VALUE; + klass->getv = cobject_getv; + klass->setv = cobject_setv; - camel_object_free_hooks(obj); + camel_object_class_add_event(klass, "finalize", NULL); } static void -obj_class_init (CamelObjectClass * class) +cobject_class_finalise(CamelObjectClass * klass) { - class->s.magic = CAMEL_OBJECT_CLASS_MAGIC_VALUE; + klass->magic = CAMEL_OBJECT_CLASS_FINALISED_MAGIC; - camel_object_class_declare_event (class, "finalize", NULL); -} - -static void -obj_class_finalize (CamelObjectClass * class) -{ - g_return_if_fail (class->s.magic == CAMEL_OBJECT_CLASS_MAGIC_VALUE); - - class->s.magic = CAMEL_OBJECT_CLASS_FINALIZED_VALUE; - - if (class->event_to_preplist) { - /* FIXME: This leaks the preplist slist entries */ - g_hash_table_foreach (class->event_to_preplist, - (GHFunc) g_free, NULL); - g_hash_table_destroy (class->event_to_preplist); - class->event_to_preplist = NULL; - } + g_free(klass); } CamelType camel_object_get_type (void) { - if (type_system_initialized == FALSE) - camel_type_init (); + if (camel_object_type == CAMEL_INVALID_TYPE) { + camel_type_init(); + + camel_object_type = camel_type_register(NULL, "CamelObject", /*, 0, 0*/ + sizeof(CamelObject), sizeof(CamelObjectClass), + cobject_class_init, cobject_class_finalise, + cobject_init, cobject_finalise); + } return camel_object_type; } -CamelObject * -camel_object_new (CamelType type) +static void +camel_type_class_init(CamelObjectClass *klass, CamelObjectClass *type) { - CamelTypeInfo *type_info; - GSList *parents = NULL; - GSList *head = NULL; - CamelObject *instance; - - g_return_val_if_fail (type != CAMEL_INVALID_TYPE, NULL); + if (type->parent) + camel_type_class_init(klass, type->parent); - /* Look up the type */ - - camel_type_lock_up (); + if (type->klass_init) + type->klass_init(klass); +} - type_info = - g_hash_table_lookup (ctype_to_typeinfo, - GINT_TO_POINTER (type)); +CamelType +camel_type_register (CamelType parent, const char * name, + /*unsigned int ver, unsigned int rev,*/ + size_t object_size, size_t klass_size, + CamelObjectClassInitFunc class_init, + CamelObjectClassFinalizeFunc class_finalise, + CamelObjectInitFunc object_init, + CamelObjectFinalizeFunc object_finalise) +{ + CamelObjectClass *klass; + /*int offset; + size_t size;*/ - if (type_info == NULL) { - g_warning - ("camel_object_new: trying to create object of invalid type %d", - type); - camel_type_lock_down (); + if (parent != NULL && parent->magic != CAMEL_OBJECT_CLASS_MAGIC) { + g_warning("camel_type_register: invalid junk parent class for '%s'", name); return NULL; } - /* Grab an instance out of the freed ones if possible, alloc otherwise */ - - if (type_info->free_instances) { - GList *first; + E_LOCK(type_lock); - first = g_list_first (type_info->free_instances); - instance = first->data; - type_info->free_instances = - g_list_remove_link (type_info->free_instances, first); - g_list_free_1 (first); - memset (instance, 0, type_info->instance_size); - } else { - instance = g_mem_chunk_alloc0 (type_info->instance_chunk); + /* Have to check creation, it might've happened in another thread before we got here */ + klass = g_hash_table_lookup(type_table, name); + if (klass != NULL) { + if (klass->klass_size != klass_size || klass->object_size != object_size + || klass->klass_init != class_init || klass->klass_finalise != class_finalise + || klass->init != object_init || klass->finalise != object_finalise) { + g_warning("camel_type_register: Trying to re-register class '%s'", name); + klass = NULL; + } + E_UNLOCK(type_lock); + return klass; } - /* Init the instance and classfuncs a bit */ - - instance->s.type = type; - instance->classfuncs = type_info->global_classfuncs; + /* this is for objects with no parent as part of their struct ('interfaces'?) */ + /*offset = parent?parent->klass_size:0; + offset = (offset + 3) & (~3); - /* Loop through the parents in simplest -> most complex order, initing the class and instance. + size = offset + klass_size; - * When parent = CAMEL_INVALID_TYPE and we're at the end of the line, _lookup returns NULL - * because we inserted it as corresponding to CAMEL_INVALID_TYPE. Clever, eh? - */ + klass = g_malloc0(size); - while (type_info) { - parents = g_slist_prepend (parents, type_info); - type_info = - g_hash_table_lookup (ctype_to_typeinfo, - GINT_TO_POINTER (type_info-> - parent)); - } + klass->klass_size = size; + klass->klass_data = offset; - head = parents; + offset = parent?parent->object_size:0; + offset = (offset + 3) & (~3); - for (; parents && parents->data; parents = parents->next) { - CamelTypeInfo *thisinfo; + klass->object_size = offset + object_size; + klass->object_data = offset;*/ - thisinfo = parents->data; - if (thisinfo->instance_init) - (thisinfo->instance_init) (instance); + if (parent + && klass_size < parent->klass_size) { + g_warning("camel_type_register: '%s' has smaller class size than parent '%s'", name, parent->name); + E_UNLOCK(type_lock); + return NULL; } - g_slist_free (head); + klass = g_malloc0(klass_size); + klass->klass_size = klass_size; + klass->object_size = object_size; +#ifdef ENABLE_THREADS + klass->lock = g_mutex_new(); +#endif + klass->instance_chunks = e_memchunk_new(8, object_size); - camel_type_lock_down (); - return instance; -} + klass->parent = parent; + if (parent) { + klass->next = parent->child; + parent->child = klass; + } + klass->name = name; -#ifdef camel_object_ref -#undef camel_object_ref -#endif + /*klass->version = ver; + klass->revision = rev;*/ -void -camel_object_ref (CamelObject * obj) -{ - g_return_if_fail (CAMEL_IS_OBJECT (obj)); + klass->klass_init = class_init; + klass->klass_finalise = class_finalise; - G_LOCK (refcount); - obj->ref_count++; - G_UNLOCK (refcount); -} + klass->init = object_init; + klass->finalise = object_finalise; -#ifdef camel_object_unref -#undef camel_object_unref -#endif + /* setup before class init, incase class init func uses the type or looks it up ? */ + g_hash_table_insert(type_table, (void *)name, klass); -void -camel_object_unref (CamelObject * obj) -{ - CamelTypeInfo *type_info; - CamelTypeInfo *iter; - GSList *parents = NULL; - GSList *head = NULL; + camel_type_class_init(klass, klass); - g_return_if_fail (CAMEL_IS_OBJECT (obj)); + E_UNLOCK(type_lock); - G_LOCK (refcount); - obj->ref_count--; + return klass; +} - if (obj->ref_count > 0) { - G_UNLOCK (refcount); - return; - } +static void +camel_object_init(CamelObject *o, CamelObjectClass *klass, CamelType type) +{ + if (type->parent) + camel_object_init(o, klass, type->parent); - G_UNLOCK (refcount); + if (type->init) + type->init(o, klass); +} - /* If the object already had its last unref, do not begin the - * destruction process again. This can happen if, for example, - * the object sends an event in its finalize handler (vfolders - * do this). - */ +CamelObject * +camel_object_new(CamelType type) +{ + CamelObject *o; - if (obj->destroying) - return; - - obj->destroying = 1; + if (type == NULL) + return NULL; - /* Send the finalize event */ + if (type->magic != CAMEL_OBJECT_CLASS_MAGIC) + return NULL; - camel_object_trigger_event (obj, "finalize", NULL); + CLASS_LOCK(type); + o = e_memchunk_alloc0(type->instance_chunks); - /* Destroy it! hahaha! */ +#ifdef CAMEL_OBJECT_TRACK_INSTANCES + if (type->instances) + type->instances->prev = o; + o->next = type->instances; + o->prev = NULL; + type->instances = o; +#endif - camel_type_lock_up (); + CLASS_UNLOCK(type); + camel_object_init(o, type, type); - type_info = - g_hash_table_lookup (ctype_to_typeinfo, - GINT_TO_POINTER (obj->s.type)); + return o; +} - if (type_info == NULL) { - g_warning - ("camel_object_unref: seemingly valid object has a bad type %d", - obj->s.type); - camel_type_lock_down (); - return; - } +void +camel_object_ref(CamelObject *o) +{ + CLASS_LOCK(o->klass); + o->ref_count++; + CLASS_UNLOCK(o->klass); +} - /* Loop through the parents in most complex -> simplest order, finalizing the class - * and instance. - * - * When parent = CAMEL_INVALID_TYPE and we're at the end of the line, _lookup returns NULL - * because we inserted it as corresponding to CAMEL_INVALID_TYPE. Clever, eh? - * - * Use iter to preserve type_info for free_{instance,classfunc}s - */ - - iter = type_info; - - while (iter) { - parents = g_slist_prepend (parents, iter); - iter = - g_hash_table_lookup (ctype_to_typeinfo, - GINT_TO_POINTER (iter->parent)); +void +camel_object_unref(CamelObject *o) +{ + register CamelObjectClass *klass = o->klass, *k; + + CLASS_LOCK(klass); + o->ref_count--; + if (o->ref_count > 0 + || (o->flags & CAMEL_OBJECT_DESTROY)) { + CLASS_UNLOCK(klass); + return; } - /* ok, done with the type stuff, and our data pointers - * won't go bad. */ - camel_type_lock_down (); + o->flags |= CAMEL_OBJECT_DESTROY; - parents = g_slist_reverse (parents); - head = parents; + CLASS_UNLOCK(klass); - for (; parents && parents->data; parents = parents->next) { - CamelTypeInfo *thisinfo; + camel_object_trigger_event(o, "finalize", NULL); - thisinfo = parents->data; - if (thisinfo->instance_finalize) - (thisinfo->instance_finalize) (obj); + k = klass; + while (k) { + if (k->finalise) + k->finalise(o); + k = k->parent; } - g_slist_free (head); + o->magic = CAMEL_OBJECT_FINALISED_MAGIC; - /* Sanity check */ + CLASS_LOCK(klass); +#ifdef CAMEL_OBJECT_TRACK_INSTANCES + if (o->prev) + o->prev->next = o->next; + else + klass->instances = o->next; + if (o->next) + o->next->prev = o->prev; +#endif + e_memchunk_free(klass->instance_chunks, o); + CLASS_UNLOCK(klass); +} - if (obj->ref_count != 0) - g_warning ("camel_object_unref: destroyed object %s at %p somehow got" - " referenced in destruction chain.", - camel_type_to_name (obj->s.type), - obj); +const char * +camel_type_to_name (CamelType type) +{ + if (type == NULL) + return "(NULL class)"; - /* A little bit of cleaning up. + if (type->magic == CAMEL_OBJECT_CLASS_MAGIC) + return type->name; - * Don't erase the type, so we can peek at it if a finalized object - * is check_cast'ed somewhere. Fill it with gunk to help detect - * other invalid ref's of it. - */ + return "(Junk class)"; +} - memset (obj, 0xEB, type_info->instance_size); - obj->s.type = type_info->self; - obj->s.magic = CAMEL_OBJECT_FINALIZED_VALUE; +CamelType camel_name_to_type(const char *name) +{ + /* TODO: Load a class off disk (!) */ - /* Tuck away the pointer for use in a new object */ + return g_hash_table_lookup(type_table, name); +} - camel_type_lock_up (); +static char * +desc_data(CamelObject *o, int ok) +{ + char *what; + + if (o == NULL) + what = g_strdup("NULL OBJECT"); + else if (o->magic == ok) + what = NULL; + else if (o->magic == CAMEL_OBJECT_MAGIC) + what = g_strdup_printf("CLASS '%s'", ((CamelObjectClass *)o)->name); + else if (o->magic == CAMEL_OBJECT_CLASS_MAGIC) + what = g_strdup_printf("CLASS '%s'", ((CamelObjectClass *)o)->name); + else if (o->magic == CAMEL_OBJECT_FINALISED_MAGIC) + what = g_strdup_printf("finalised OBJECT"); + else if (o->magic == CAMEL_OBJECT_CLASS_FINALISED_MAGIC) + what = g_strdup_printf("finalised CLASS"); + else + what = g_strdup_printf("junk data"); + + return what; +} - type_info->free_instances = - g_list_prepend (type_info->free_instances, obj); +static gboolean +check_magic(void *o, CamelType ctype, int isob) +{ + char *what, *to; + + what = desc_data(o, isob?CAMEL_OBJECT_MAGIC:CAMEL_OBJECT_CLASS_MAGIC); + to = desc_data((CamelObject *)ctype, CAMEL_OBJECT_CLASS_MAGIC); + + if (what || to) { + if (what == NULL) { + if (isob) + what = g_strdup_printf("OBJECT '%s'", ((CamelObject *)o)->klass->name); + else + what = g_strdup_printf("OBJECT '%s'", ((CamelObjectClass *)o)->name); + } + if (to == NULL) + to = g_strdup_printf("OBJECT '%s'", ctype->name); + g_warning("Trying to check %s is %s", what, to); + g_free(what); + g_free(to); - camel_type_lock_down (); + return FALSE; + } + + return TRUE; } gboolean -camel_object_is_of_type (CamelObject * obj, CamelType ctype) +camel_object_is (CamelObject *o, CamelType ctype) { - return shared_is_of_type ((CamelObjectShared *) obj, ctype, TRUE); + CamelObjectClass *k; + + g_return_val_if_fail(check_magic(o, ctype, TRUE), FALSE); + + k = o->klass; + while (k) { + if (k == ctype) + return TRUE; + k = k->parent; + } + + return FALSE; } gboolean -camel_object_class_is_of_type (CamelObjectClass * class, CamelType ctype) +camel_object_class_is (CamelObjectClass *k, CamelType ctype) { - return shared_is_of_type ((CamelObjectShared *) class, ctype, FALSE); -} + g_return_val_if_fail(check_magic(k, ctype, FALSE), FALSE); -#ifdef BAST_CASTARD -#define ERRVAL NULL -#else -#define ERRVAL obj -#endif + while (k) { + if (k == ctype) + return TRUE; + k = k->parent; + } + + return FALSE; +} CamelObject * -camel_object_check_cast (CamelObject * obj, CamelType ctype) +camel_object_cast(CamelObject *o, CamelType ctype) { - if (shared_is_of_type ((CamelObjectShared *) obj, ctype, TRUE)) - return obj; - return ERRVAL; + CamelObjectClass *k; + + g_return_val_if_fail(check_magic(o, ctype, TRUE), NULL); + + k = o->klass; + while (k) { + if (k == ctype) + return o; + k = k->parent; + } + + g_warning("Object %p (class '%s') doesn't have '%s' in its heirachy", o, o->klass->name, ctype->name); + + return NULL; } CamelObjectClass * -camel_object_class_check_cast (CamelObjectClass * class, CamelType ctype) +camel_object_class_cast(CamelObjectClass *k, CamelType ctype) { - if (shared_is_of_type ((CamelObjectShared *) class, ctype, FALSE)) - return class; - return ERRVAL; -} + CamelObjectClass *r = k; -#undef ERRVAL + g_return_val_if_fail(check_magic(k, ctype, FALSE), NULL); -gchar * -camel_object_describe (CamelObject * obj) -{ - if (obj == NULL) - return g_strdup ("a NULL pointer"); - - if (obj->s.magic == CAMEL_OBJECT_MAGIC_VALUE) { - return g_strdup_printf ("an instance of `%s' at %p", - camel_type_to_name (obj->s.type), - obj); - } else if (obj->s.magic == CAMEL_OBJECT_FINALIZED_VALUE) { - return g_strdup_printf ("a finalized instance of `%s' at %p", - camel_type_to_name (obj->s.type), - obj); - } else if (obj->s.magic == CAMEL_OBJECT_CLASS_MAGIC_VALUE) { - return g_strdup_printf ("the classfuncs of `%s' at %p", - camel_type_to_name (obj->s.type), - obj); - } else if (obj->s.magic == CAMEL_OBJECT_CLASS_FINALIZED_VALUE) { - return - g_strdup_printf - ("the finalized classfuncs of `%s' at %p", - camel_type_to_name (obj->s.type), obj); + while (k) { + if (k == ctype) + return r; + k = k->parent; } - return g_strdup ("not a CamelObject"); + g_warning("Class '%s' doesn't have '%s' in its heirarchy", k->name, ctype->name); + + return NULL; } -/* This is likely to be called in the class_init callback, - * and the type will likely be somewhat uninitialized. - * Is this a problem? We'll see.... - */ void -camel_object_class_declare_event (CamelObjectClass * class, - const gchar * name, - CamelObjectEventPrepFunc prep) +camel_object_class_add_event(CamelObjectClass *klass, const char *name, CamelObjectEventPrepFunc prep) { - g_return_if_fail (CAMEL_IS_OBJECT_CLASS (class)); + CamelHookPair *pair; + g_return_if_fail (name); - if (class->event_to_preplist == NULL) - class->event_to_preplist = - g_hash_table_new (g_str_hash, g_str_equal); - else if (g_hash_table_lookup (class->event_to_preplist, name) != NULL) { - g_warning - ("camel_object_class_declare_event: event `%s' already declared for `%s'", - name, camel_type_to_name (class->s.type)); - return; + pair = klass->hooks; + while (pair) { + if (strcmp(pair->name, name) == 0) { + g_warning("camel_object_class_add_event: `%s' is already declared for '%s'\n", + name, klass->name); + return; + } + pair = pair->next; } - /* AIEEEEEEEEEEEEEEEEEEEEEE - - * I feel so naughty. Since it's valid to declare an event and not - * provide a hook, it should be valid to insert a NULL value into - * the table. However, then our lookup in trigger_event would be - * ambiguous, not telling us whether the event is undefined or whether - * it merely has no hook. - * - * So we create an 'NULL prep' value that != NULL... specifically, it - * equals the address of one of our static functions , because that - * can't possibly be your hook. - * - * Just don't forget to check for the 'evil value' and it'll work, - * I promise. - */ - - if (prep == NULL) - prep = NULL_PREP_VALUE; - - g_hash_table_insert (class->event_to_preplist, g_strdup (name), prep); + pair = pair_alloc(); + pair->name = name; + pair->func.prep = prep; + pair->flags = 0; + + pair->next = klass->hooks; + klass->hooks = pair; } /* free hook data */ @@ -734,18 +605,17 @@ static void camel_object_free_hooks(CamelObject *o) CamelHookPair *pair, *next; if (o->hooks) { - g_assert(o->hooks->depth == 0); g_assert((o->hooks->flags & CAMEL_HOOK_PAIR_REMOVED) == 0); pair = o->hooks->list; while (pair) { next = pair->next; - g_free(pair); + pair_free(pair); pair = next; } e_mutex_destroy(o->hooks->lock); - g_free(o->hooks); + hooks_free(o->hooks); o->hooks = NULL; } } @@ -765,7 +635,7 @@ static CamelHookList *camel_object_get_hooks(CamelObject *o) pthread_mutex_lock(&lock); #endif if (o->hooks == NULL) { - hooks = g_malloc(sizeof(*o->hooks)); + hooks = hooks_alloc(); #ifdef ENABLE_THREADS hooks->lock = e_mutex_new(E_MUTEX_REC); #endif @@ -793,34 +663,37 @@ static CamelHookList *camel_object_get_hooks(CamelObject *o) #define camel_object_unget_hooks(o) #endif -void -camel_object_hook_event (CamelObject * obj, const char * name, - CamelObjectEventHookFunc func, void *data) +unsigned int +camel_object_hook_event(CamelObject * obj, const char * name, CamelObjectEventHookFunc func, void *data) { - CamelHookPair *pair; - const char *prepname; - CamelObjectEventPrepFunc prep; + CamelHookPair *pair, *hook; CamelHookList *hooks; + int id; - g_return_if_fail (CAMEL_IS_OBJECT (obj)); - g_return_if_fail (name != NULL); - g_return_if_fail (func != NULL); + g_return_val_if_fail (CAMEL_IS_OBJECT (obj), 0); + g_return_val_if_fail (name != NULL, 0); + g_return_val_if_fail (func != NULL, 0); - /* first, does this event exist? */ - if (obj->classfuncs->event_to_preplist == NULL - || !g_hash_table_lookup_extended(obj->classfuncs->event_to_preplist, name, - (void **)&prepname, (void **)&prep)) { - g_warning("camel_object_hook_event: trying to hook event `%s' in class `%s' with no defined events.", - name, camel_type_to_name (obj->s.type)); - return; + hook = obj->klass->hooks; + while (hook) { + if (strcmp(hook->name, name) == 0) + goto setup; + hook = hook->next; } + g_warning("camel_object_hook_event: trying to hook event `%s' in class `%s' with no defined events.", + name, obj->klass->name); + + return 0; + +setup: /* setup hook pair */ - pair = g_malloc(sizeof(*pair)); - pair->name = prepname; /* effectively static! */ - pair->func = func; + pair = pair_alloc(); + pair->name = hook->name; /* effectively static! */ + pair->func.event = func; pair->data = data; pair->flags = 0; + id = pair->id; /* get the hook list object, locked, link in new event hook, unlock */ hooks = camel_object_get_hooks(obj); @@ -828,33 +701,65 @@ camel_object_hook_event (CamelObject * obj, const char * name, hooks->list = pair; hooks->list_length++; camel_object_unget_hooks(obj); + + return id; } void -camel_object_unhook_event (CamelObject * obj, const char * name, - CamelObjectEventHookFunc func, void *data) +camel_object_remove_event(CamelObject * obj, unsigned int id) { - char *prepname; - CamelObjectEventPrepFunc prep; CamelHookList *hooks; CamelHookPair *pair, *parent; g_return_if_fail (CAMEL_IS_OBJECT (obj)); - g_return_if_fail (name != NULL); - g_return_if_fail (func != NULL); + g_return_if_fail (id != 0); if (obj->hooks == NULL) { - g_warning("camel_object_unhook_event: trying to unhook `%s` from an instance of `%s' with no hooks", - name, camel_type_to_name(obj->s.type)); + g_warning("camel_object_unhook_event: trying to unhook `%d` from an instance of `%s' with no hooks", + id, obj->klass->name); return; } - /* get event name static pointer */ - if (obj->classfuncs->event_to_preplist == NULL - || !g_hash_table_lookup_extended(obj->classfuncs->event_to_preplist, name, - (void **)&prepname, (void **)&prep)) { - g_warning("camel_object_hook_event: trying to hook event `%s' in class `%s' with no defined events.", - name, camel_type_to_name (obj->s.type)); + /* scan hooks for this event, remove it, or flag it if we're busy */ + hooks = camel_object_get_hooks(obj); + parent = (CamelHookPair *)&hooks->list; + pair = parent->next; + while (pair) { + if (pair->id == id + && (pair->flags & CAMEL_HOOK_PAIR_REMOVED) == 0) { + if (hooks->depth > 0) { + pair->flags |= CAMEL_HOOK_PAIR_REMOVED; + hooks->flags |= CAMEL_HOOK_PAIR_REMOVED; + } else { + parent->next = pair->next; + pair_free(pair); + hooks->list_length--; + } + camel_object_unget_hooks(obj); + return; + } + parent = pair; + pair = pair->next; + } + camel_object_unget_hooks(obj); + + g_warning("camel_object_unhook_event: cannot find hook id %d in instance of `%s'", + id, obj->klass->name); +} + +void +camel_object_unhook_event(CamelObject * obj, const char * name, CamelObjectEventHookFunc func, void *data) +{ + CamelHookList *hooks; + CamelHookPair *pair, *parent; + + g_return_if_fail (CAMEL_IS_OBJECT (obj)); + g_return_if_fail (name != NULL); + g_return_if_fail (func != NULL); + + if (obj->hooks == NULL) { + g_warning("camel_object_unhook_event: trying to unhook `%s` from an instance of `%s' with no hooks", + name, obj->klass->name); return; } @@ -863,16 +768,16 @@ camel_object_unhook_event (CamelObject * obj, const char * name, parent = (CamelHookPair *)&hooks->list; pair = parent->next; while (pair) { - if (pair->name == prepname - && pair->func == func + if (pair->func.event == func && pair->data == data + && strcmp(pair->name, name) == 0 && (pair->flags & CAMEL_HOOK_PAIR_REMOVED) == 0) { if (hooks->depth > 0) { pair->flags |= CAMEL_HOOK_PAIR_REMOVED; hooks->flags |= CAMEL_HOOK_PAIR_REMOVED; } else { parent->next = pair->next; - g_free(pair); + pair_free(pair); hooks->list_length--; } camel_object_unget_hooks(obj); @@ -884,32 +789,35 @@ camel_object_unhook_event (CamelObject * obj, const char * name, camel_object_unget_hooks(obj); g_warning("camel_object_unhook_event: cannot find hook/data pair %p/%p in an instance of `%s' attached to `%s'", - func, data, camel_type_to_name (obj->s.type), name); + func, data, obj->klass->name, name); } void camel_object_trigger_event (CamelObject * obj, const char * name, void *event_data) { - CamelObjectEventPrepFunc prep; - const char *prepname; CamelHookList *hooks; - CamelHookPair *pair, **pairs, *parent; + CamelHookPair *pair, **pairs, *parent, *hook; int i, size; + const char *prepname; g_return_if_fail (CAMEL_IS_OBJECT (obj)); g_return_if_fail (name); - /* get event name static pointer/prep func */ - if (obj->classfuncs->event_to_preplist == NULL - || !g_hash_table_lookup_extended(obj->classfuncs->event_to_preplist, name, - (void **)&prepname, (void **)&prep)) { - g_warning("camel_object_hook_event: trying to hook event `%s' in class `%s' with no defined events.", - name, camel_type_to_name (obj->s.type)); - return; + hook = obj->klass->hooks; + while (hook) { + if (strcmp(hook->name, name) == 0) + goto trigger; + hook = hook->next; } + g_warning("camel_object_trigger_event: trying to trigger unknown event `%s' in class `%s'", + name, obj->klass->name); + + return; + +trigger: /* try prep function, if false, then quit */ - if (prep != NULL_PREP_VALUE && !prep(obj, event_data)) + if (hook->func.prep != NULL && !hook->func.prep(obj, event_data)) return; /* also, no hooks, dont bother going further */ @@ -919,13 +827,14 @@ camel_object_trigger_event (CamelObject * obj, const char * name, void *event_da /* lock the object for hook emission */ camel_object_ref(obj); hooks = camel_object_get_hooks(obj); - + if (hooks->list) { /* first, copy the items in the list, and say we're in an event */ hooks->depth++; pair = hooks->list; size = 0; pairs = alloca(sizeof(pairs[0]) * hooks->list_length); + prepname = hook->name; while (pair) { if (pair->name == prepname) pairs[size++] = pair; @@ -936,7 +845,7 @@ camel_object_trigger_event (CamelObject * obj, const char * name, void *event_da for (i=0;i<size;i++) { pair = pairs[i]; if ((pair->flags & CAMEL_HOOK_PAIR_REMOVED) == 0) - (pair->func) (obj, event_data, pair->data); + (pair->func.event) (obj, event_data, pair->data); } hooks->depth--; @@ -947,7 +856,7 @@ camel_object_trigger_event (CamelObject * obj, const char * name, void *event_da while (pair) { if (pair->flags & CAMEL_HOOK_PAIR_REMOVED) { parent->next = pair->next; - g_free(pair); + pair_free(pair); hooks->list_length--; } else { parent = pair; @@ -962,154 +871,114 @@ camel_object_trigger_event (CamelObject * obj, const char * name, void *event_da camel_object_unref(obj); } -/* ** Static helpers ****************************************************** */ - -static gboolean -shared_is_of_type (CamelObjectShared * sh, CamelType ctype, gboolean is_obj) +/* get/set arg methods */ +int camel_object_set(CamelObject *o, CamelException *ex, ...) { - CamelTypeInfo *type_info; - gchar *targtype; + CamelArgV args; + CamelObjectClass *klass = o->klass; + int ret = 0; - if (is_obj) - targtype = "instance"; - else - targtype = "classdata"; + g_return_val_if_fail(CAMEL_IS_OBJECT(o), -1); - if (ctype == CAMEL_INVALID_TYPE) { - g_warning - ("shared_is_of_type: trying to cast to CAMEL_INVALID_TYPE"); - return FALSE; - } + camel_argv_start(&args, ex); - if (sh == NULL) { - g_warning - ("shared_is_of_type: trying to cast NULL to %s of `%s'", - targtype, camel_type_to_name (ctype)); - return FALSE; - } + while (camel_argv_build(&args) && ret == 0) + ret = klass->setv(o, ex, &args); + if (ret == 0) + ret = klass->setv(o, ex, &args); - if (sh->magic == CAMEL_OBJECT_FINALIZED_VALUE) { - g_warning - ("shared_is_of_type: trying to cast finalized instance " - "of `%s' into %s of `%s'", - camel_type_to_name (sh->type), targtype, - camel_type_to_name (ctype)); - return FALSE; - } + camel_argv_end(&args); - if (sh->magic == CAMEL_OBJECT_CLASS_FINALIZED_VALUE) { - g_warning - ("shared_is_of_type: trying to cast finalized classdata " - "of `%s' into %s of `%s'", - camel_type_to_name (sh->type), targtype, - camel_type_to_name (ctype)); - return FALSE; - } + return ret; +} - if (is_obj) { - if (sh->magic == CAMEL_OBJECT_CLASS_MAGIC_VALUE) { - g_warning - ("shared_is_of_type: trying to cast classdata " - "of `%s' into instance of `%s'", - camel_type_to_name (sh->type), - camel_type_to_name (ctype)); - return FALSE; - } +int camel_object_setv(CamelObject *o, CamelException *ex, CamelArgV *args) +{ + g_return_val_if_fail(CAMEL_IS_OBJECT(o), -1); - if (sh->magic != CAMEL_OBJECT_MAGIC_VALUE) { - g_warning - ("shared_is_of_type: trying to cast junk data " - "into instance of `%s'", - camel_type_to_name (ctype)); - return FALSE; - } - } else { - if (sh->magic == CAMEL_OBJECT_MAGIC_VALUE) { - g_warning - ("shared_is_of_type: trying to cast instance " - "of `%s' into classdata of `%s'", - camel_type_to_name (sh->type), - camel_type_to_name (ctype)); - return FALSE; - } + return o->klass->setv(o, ex, args); +} - if (sh->magic != CAMEL_OBJECT_CLASS_MAGIC_VALUE) { - g_warning - ("shared_is_of_type: trying to cast junk data " - "into classdata of `%s'", - camel_type_to_name (ctype)); - return FALSE; - } - } +int camel_object_get(CamelObject *o, CamelException *ex, ...) +{ + CamelArgGetV args; + CamelObjectClass *klass = o->klass; + int ret = 0; - camel_type_lock_up (); + g_return_val_if_fail(CAMEL_IS_OBJECT(o), -1); - type_info = - g_hash_table_lookup (ctype_to_typeinfo, - GINT_TO_POINTER (sh->type)); + camel_argv_start(&args, ex); - if (type_info == NULL) { - g_warning ("shared_is_of_type: seemingly valid %s has " - "bad type %d.", targtype, sh->type); - camel_type_lock_down (); - return FALSE; - } + while (camel_arggetv_build(&args) && ret == 0) + ret = klass->getv(o, ex, &args); + if (ret == 0) + ret = klass->getv(o, ex, &args); - while (type_info) { - if (type_info->self == ctype) { - camel_type_lock_down (); - return TRUE; - } + camel_argv_end(&args); - type_info = - g_hash_table_lookup (ctype_to_typeinfo, - GINT_TO_POINTER (type_info-> - parent)); - } + return ret; +} - /* this isn't an error, e.g. CAMEL_IS_FOLDER(folder), its upto the - caller to handle the false case */ - /*g_warning - ("shared_is_of_type: %s of `%s' (@%p) is not also %s of `%s'", - targtype, camel_type_to_name (sh->type), sh, targtype, - camel_type_to_name (ctype));*/ +int camel_object_getv(CamelObject *o, CamelException *ex, CamelArgGetV *args) +{ + CamelObjectClass *klass = o->klass; - camel_type_lock_down (); - return FALSE; + g_return_val_if_fail(CAMEL_IS_OBJECT(o), -1); + + return klass->getv(o, ex, args); } static void -make_global_classfuncs (CamelTypeInfo * type_info) +object_class_dump_tree_rec(CamelType root, int depth) { - CamelObjectClass *funcs; - GSList *parents; - GSList *head; - - g_assert (type_info); - - funcs = g_malloc0 (type_info->classfuncs_size); - funcs->s.type = type_info->self; + char *p; +#ifdef CAMEL_OBJECT_TRACK_INSTANCES + struct _CamelObject *o; +#endif - type_info->global_classfuncs = funcs; + p = alloca(depth*2+1); + memset(p, ' ', depth*2); + p[depth*2] = 0; - parents = NULL; - while (type_info) { - parents = g_slist_prepend (parents, type_info); - type_info = - g_hash_table_lookup (ctype_to_typeinfo, - GINT_TO_POINTER (type_info-> - parent)); - } + while (root) { + CLASS_LOCK(root); + printf("%sClass: %s\n", p, root->name); + /*printf("%sVersion: %u.%u\n", p, root->version, root->revision);*/ + if (root->hooks) { + CamelHookPair *pair = root->hooks; - head = parents; + while (pair) { + printf("%s event '%s' prep %p\n", p, pair->name, pair->func.prep); + pair = pair->next; + } + } +#ifdef CAMEL_OBJECT_TRACK_INSTANCES + o = root->instances; + while (o) { + printf("%s instance %p [%d]\n", p, o, o->ref_count); + /* todo: should lock hooks while it scans them */ + if (o->hooks) { + CamelHookPair *pair = o->hooks->list; + + while (pair) { + printf("%s hook '%s' func %p data %p\n", p, pair->name, pair->func.event, pair->data); + pair = pair->next; + } + } + o = o->next; + } +#endif + CLASS_UNLOCK(root); - for (; parents && parents->data; parents = parents->next) { - CamelTypeInfo *thisinfo; + if (root->child) + object_class_dump_tree_rec(root->child, depth+1); - thisinfo = parents->data; - if (thisinfo->class_init) - (thisinfo->class_init) (funcs); + root = root->next; } +} - g_slist_free (head); +void +camel_object_class_dump_tree(CamelType root) +{ + object_class_dump_tree_rec(root, 0); } diff --git a/camel/camel-object.h b/camel/camel-object.h index 27e30a7728..0578db77a8 100644 --- a/camel/camel-object.h +++ b/camel/camel-object.h @@ -4,6 +4,7 @@ /* * Author: * Dan Winship <danw@ximian.com> + * Michael Zucchi <notzed@ximian.com> * * Copyright 2000 Ximian, Inc. (www.ximian.com) * @@ -32,89 +33,152 @@ extern "C" { #include <stdlib.h> /* size_t */ #include <glib.h> +#include <stdarg.h> +#include <camel/camel-arg.h> +#include <camel/camel-types.h> /* this is a @##$@#SF stupid header */ + +/* this crap shouldn't be here */ #include <libgnome/gnome-defs.h> #include <libgnome/gnome-i18n.h> -#include <camel/camel-types.h> + +#ifdef ENABLE_THREADS +#include <pthread.h> +#endif + +/* turn on so that camel_object_class_dump_tree() dumps object instances as well */ +/*#define CAMEL_OBJECT_TRACK_INSTANCES*/ + +typedef struct _CamelObjectClass *CamelType; #ifdef G_DISABLE_CHECKS #define CAMEL_CHECK_CAST( obj, ctype, ptype ) ((ptype *) obj) -#define CAMEL_CHECK_CLASS_CAST( klass, ctype, ptype ) ((ptype *) klass) -#define CAMEL_CHECK_TYPE( obj, ctype ) (TRUE) -#define CAMEL_CHECK_CLASS_TYPE( klass, ctype ) (TRUE) +#define CAMEL_CHECK_CLASS_CAST( class, ctype, ptype ) ((ptype *) class) #else -#define CAMEL_CHECK_CAST( obj, ctype, ptype ) ((ptype *) camel_object_check_cast( (CamelObject *)(obj), (CamelType)(ctype) )) -#define CAMEL_CHECK_CLASS_CAST( klass, ctype, ptype ) ((ptype *) camel_object_class_check_cast( (CamelObjectClass *)(klass), (CamelType)(ctype) )) -#define CAMEL_CHECK_TYPE( obj, ctype ) (camel_object_is_of_type( (CamelObject *)(obj), (CamelType)(ctype) )) -#define CAMEL_CHECK_CLASS_TYPE( klass, ctype ) (camel_object_class_is_of_type( (CamelObjectClass *)(klass), (CamelType)(ctype) )) +#define CAMEL_CHECK_CAST( obj, ctype, ptype ) ((ptype *) camel_object_cast( (CamelObject *)(obj), (CamelType)(ctype) )) +#define CAMEL_CHECK_CLASS_CAST( class, ctype, ptype ) ((ptype *) camel_object_class_cast( (CamelObjectClass *)(class), (CamelType)(ctype) )) #endif +#define CAMEL_CHECK_TYPE( obj, ctype ) (camel_object_is( (CamelObject *)(obj), (CamelType)(ctype) )) +#define CAMEL_CHECK_CLASS_TYPE( class, ctype ) (camel_object_class_is( (CamelObjectClass *)(class), (CamelType)(ctype) )) -#define CAMEL_INVALID_TYPE ((CamelType)0) +extern CamelType camel_object_type; -#define CAMEL_OBJECT_TYPE (camel_object_get_type ()) +#define CAMEL_OBJECT_TYPE (camel_object_type) -#define CAMEL_OBJECT(obj) (CAMEL_CHECK_CAST((obj), CAMEL_OBJECT_TYPE, CamelObject)) -#define CAMEL_OBJECT_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), CAMEL_OBJECT_TYPE, CamelObjectClass)) -#define CAMEL_IS_OBJECT(o) (CAMEL_CHECK_TYPE((o), CAMEL_OBJECT_TYPE)) -#define CAMEL_IS_OBJECT_CLASS(k) (CAMEL_CHECK_CLASS_TYPE((k), CAMEL_OBJECT_TYPE)) +/* we can't check casts till we've got the type, use the global type variable because its cheaper */ +#define CAMEL_OBJECT(obj) (CAMEL_CHECK_CAST((obj), camel_object_type, CamelObject)) +#define CAMEL_OBJECT_CLASS(k) (CAMEL_CHECK_CLASS_CAST ((k), camel_object_type, CamelObjectClass)) +#define CAMEL_IS_OBJECT(o) (CAMEL_CHECK_TYPE((o), camel_object_type)) +#define CAMEL_IS_OBJECT_CLASS(k) (CAMEL_CHECK_CLASS_TYPE((k), camel_object_type)) -#define CAMEL_OBJECT_GET_CLASS(o) ((CamelObjectClass *)(CAMEL_OBJECT(o))->classfuncs) -#define CAMEL_OBJECT_GET_TYPE(o) ((CamelType)(CAMEL_OBJECT(o))->s.type) +#define CAMEL_OBJECT_GET_CLASS(o) ((CamelObjectClass *)(CAMEL_OBJECT(o))->klass) +#define CAMEL_OBJECT_GET_TYPE(o) ((CamelType)(CAMEL_OBJECT(o))->klass) -typedef guint32 CamelType; +typedef struct _CamelObjectClass CamelObjectClass; +typedef struct _CamelObject CamelObject; +typedef unsigned int CamelObjectHookID; -typedef struct _CamelObjectShared -{ - guint32 magic; - CamelType type; -} -CamelObjectShared; +typedef void (*CamelObjectClassInitFunc) (CamelObjectClass *); +typedef void (*CamelObjectClassFinalizeFunc) (CamelObjectClass *); +typedef void (*CamelObjectInitFunc) (CamelObject *, CamelObjectClass *); +typedef void (*CamelObjectFinalizeFunc) (CamelObject *); -typedef struct _CamelObjectClass -{ - CamelObjectShared s; - - GHashTable *event_to_preplist; -} -CamelObjectClass; +typedef gboolean (*CamelObjectEventPrepFunc) (CamelObject *, gpointer); +typedef void (*CamelObjectEventHookFunc) (CamelObject *, gpointer, gpointer); -typedef struct _CamelObject -{ - CamelObjectShared s; - CamelObjectClass *classfuncs; +#define CAMEL_INVALID_TYPE (NULL) + +enum _CamelObjectFlags { + CAMEL_OBJECT_DESTROY = (1<<0), +}; + +/* TODO: create a simpleobject which has no events on it, or an interface for events */ +struct _CamelObject { + struct _CamelObjectClass *klass; + + guint32 magic; /* only really needed for debugging ... */ + + /* current hooks on this object */ struct _CamelHookList *hooks; - guint32 ref_count:30; - guint32 in_event:1; - guint32 destroying:1; -} -CamelObject; -typedef void (*CamelObjectClassInitFunc) (CamelObjectClass *); -typedef void (*CamelObjectClassFinalizeFunc) (CamelObjectClass *); -typedef void (*CamelObjectInitFunc) (CamelObject *); -typedef void (*CamelObjectFinalizeFunc) (CamelObject *); + guint32 ref_count:24; + guint32 flags:8; -typedef gboolean (*CamelObjectEventPrepFunc) (CamelObject *, - gpointer); -typedef void (*CamelObjectEventHookFunc) (CamelObject *, gpointer, - gpointer); +#ifdef CAMEL_OBJECT_TRACK_INSTANCES + struct _CamelObject *next, *prev; +#endif +}; -/* The type system .... it's pretty simple..... */ +struct _CamelObjectClass +{ + struct _CamelObjectClass *parent; + + guint32 magic; /* in same spot for validation */ + + struct _CamelObjectClass *next, *child; /* maintain heirarchy, just for kicks */ + + const char *name; + + void *lock; /* lock when used in threading, else just pads struct */ + + /*unsigned short version, revision;*/ + + /* if the object's bigger than 64K, it could use redesigning */ + unsigned short object_size/*, object_data*/; + unsigned short klass_size/*, klass_data*/; + + /* available hooks for this class */ + struct _CamelHookPair *hooks; + + /* memchunks for this type */ + struct _EMemChunk *instance_chunks; +#ifdef CAMEL_OBJECT_TRACK_INSTANCES + struct _CamelObject *instances; +#endif + /* init class */ + void (*klass_init)(struct _CamelObjectClass *); + void (*klass_finalise)(struct _CamelObjectClass *); + + /* init/finalise object */ + void (*init)(struct _CamelObject *, struct _CamelObjectClass *); + void (*finalise)(struct _CamelObject *); + + /* get/set interface */ + int (*setv)(struct _CamelObject *, struct _CamelException *ex, CamelArgV *args); + int (*getv)(struct _CamelObject *, struct _CamelException *ex, CamelArgGetV *args); +}; + +/* The type system .... it's pretty simple..... */ void camel_type_init (void); -CamelType camel_type_register (CamelType parent, const gchar * name, - size_t instance_size, - size_t classfuncs_size, - CamelObjectClassInitFunc class_init, - CamelObjectClassFinalizeFunc - class_finalize, - CamelObjectInitFunc instance_init, - CamelObjectFinalizeFunc - instance_finalize); -CamelObjectClass *camel_type_get_global_classfuncs (CamelType type); -const gchar *camel_type_to_name (CamelType type); +CamelType camel_type_register(CamelType parent, const char * name, /*unsigned int ver, unsigned int rev,*/ + size_t instance_size, + size_t classfuncs_size, + CamelObjectClassInitFunc class_init, + CamelObjectClassFinalizeFunc class_finalize, + CamelObjectInitFunc instance_init, + CamelObjectFinalizeFunc instance_finalize); + +/* deprecated interface */ +#define camel_type_get_global_classfuncs(x) ((CamelObjectClass *)(x)) + +/* object class methods (types == classes now) */ +const char *camel_type_to_name (CamelType type); +CamelType camel_name_to_type(const char *name); +void camel_object_class_add_event (CamelObjectClass *class, const char * name, CamelObjectEventPrepFunc prep); + +void camel_object_class_dump_tree(CamelType root); + +/* casting */ +CamelObject *camel_object_cast(CamelObject * obj, CamelType ctype); +gboolean camel_object_is(CamelObject * obj, CamelType ctype); + +CamelObjectClass *camel_object_class_cast (CamelObjectClass *k, CamelType ctype); +gboolean camel_object_class_is (CamelObjectClass * class, CamelType ctype); CamelType camel_object_get_type (void); + CamelObject *camel_object_new (CamelType type); +CamelObject *camel_object_new_name (const char *name); void camel_object_ref (CamelObject *obj); void camel_object_unref (CamelObject *obj); @@ -124,26 +188,17 @@ void camel_object_unref (CamelObject *obj); #define camel_object_unref(o) (printf("%s (%s:%d):unref (%p)\n", __FUNCTION__, __FILE__, __LINE__, o), camel_object_unref (o)) #endif -CamelObject *camel_object_check_cast (CamelObject *obj, - CamelType ctype); -CamelObjectClass *camel_object_class_check_cast (CamelObjectClass *klass, - CamelType ctype); -gboolean camel_object_is_of_type (CamelObject *obj, CamelType ctype); -gboolean camel_object_class_is_of_type (CamelObjectClass *klass, - CamelType ctype); -gchar *camel_object_describe (CamelObject *obj); -void camel_object_class_declare_event (CamelObjectClass *klass, - const char *name, - CamelObjectEventPrepFunc prep); -void camel_object_hook_event (CamelObject *obj, const char * name, - CamelObjectEventHookFunc hook, - gpointer user_data); -void camel_object_unhook_event (CamelObject *obj, const char * name, - CamelObjectEventHookFunc hook, - gpointer user_data); -void camel_object_trigger_event (CamelObject *obj, - const char *name, - gpointer event_data); +/* hooks */ +CamelObjectHookID camel_object_hook_event(CamelObject *obj, const char *name, CamelObjectEventHookFunc hook, void *data); +void camel_object_remove_event(CamelObject *obj, CamelObjectHookID id); +void camel_object_unhook_event(CamelObject *obj, const char *name, CamelObjectEventHookFunc hook, void *data); +void camel_object_trigger_event(CamelObject *obj, const char *name, void *event_data); + +/* get/set methods */ +int camel_object_set(CamelObject *obj, struct _CamelException *ex, ...); +int camel_object_setv(CamelObject *obj, struct _CamelException *ex, CamelArgV *); +int camel_object_get(CamelObject *obj, struct _CamelException *ex, ...); +int camel_object_getv(CamelObject *obj, struct _CamelException *ex, CamelArgGetV *); #ifdef __cplusplus } diff --git a/camel/camel-partition-table.h b/camel/camel-partition-table.h index 0b87390835..3433da3cf1 100644 --- a/camel/camel-partition-table.h +++ b/camel/camel-partition-table.h @@ -39,7 +39,7 @@ typedef struct _CamelPartitionMap CamelPartitionMap; typedef struct _CamelPartitionMapBlock CamelPartitionMapBlock; typedef struct _CamelPartitionTable CamelPartitionTable; -typedef struct _CamelPartitionTable CamelPartitionTableClass; +typedef struct _CamelPartitionTableClass CamelPartitionTableClass; struct _CamelPartitionKey { camel_hash_t hashid; @@ -97,7 +97,7 @@ typedef struct _CamelKeyBlock CamelKeyBlock; typedef struct _CamelKeyRootBlock CamelKeyRootBlock; typedef struct _CamelKeyTable CamelKeyTable; -typedef struct _CamelKeyTable CamelKeyTableClass; +typedef struct _CamelKeyTableClass CamelKeyTableClass; struct _CamelKeyRootBlock { camel_block_t first; diff --git a/camel/camel-remote-store.c b/camel/camel-remote-store.c index 5f56b66fd4..76fdc642d6 100644 --- a/camel/camel-remote-store.c +++ b/camel/camel-remote-store.c @@ -338,6 +338,8 @@ remote_send_string (CamelRemoteStore *store, CamelException *ex, char *fmt, va_l fprintf (stderr, "sending : ------ LOGIN \"xxxx\" \"xxxx\"\n"); else if (strstr (cmdbuf, "LOGIN {")) fprintf (stderr, "sending : ------ LOGIN {N+} ....\n"); + else if (strstr (cmdbuf, "LOGIN ")) + fprintf (stderr, "sending : ------ LOGIN xxxx xxxx\n"); else fprintf (stderr, "sending : %s", cmdbuf); } diff --git a/camel/camel-store-summary.h b/camel/camel-store-summary.h index 6f11f1276c..a26d2fa84c 100644 --- a/camel/camel-store-summary.h +++ b/camel/camel-store-summary.h @@ -118,7 +118,7 @@ struct _CamelStoreSummaryClass { void (*folder_info_set_string)(CamelStoreSummary *, CamelFolderInfo *, int, const char *); }; -guint camel_store_summary_get_type (void); +CamelType camel_store_summary_get_type (void); CamelStoreSummary *camel_store_summary_new (void); void camel_store_summary_set_filename(CamelStoreSummary *, const char *); diff --git a/camel/camel-store.c b/camel/camel-store.c index d230ef3777..6764ac0af6 100644 --- a/camel/camel-store.c +++ b/camel/camel-store.c @@ -44,7 +44,7 @@ static CamelServiceClass *parent_class = NULL; /* Returns the class for a CamelStore */ -#define CS_CLASS(so) ((CamelStoreClass *)((CamelObject *)(so))->classfuncs) +#define CS_CLASS(so) ((CamelStoreClass *)((CamelObject *)(so))->klass) static CamelFolder *get_folder (CamelStore *store, const char *folder_name, guint32 flags, CamelException *ex); @@ -103,11 +103,11 @@ camel_store_class_init (CamelStoreClass *camel_store_class) /* virtual method overload */ camel_service_class->construct = construct; - camel_object_class_declare_event(camel_object_class, "folder_created", NULL); - camel_object_class_declare_event(camel_object_class, "folder_deleted", NULL); - camel_object_class_declare_event(camel_object_class, "folder_renamed", NULL); - camel_object_class_declare_event(camel_object_class, "folder_subscribed", NULL); - camel_object_class_declare_event(camel_object_class, "folder_unsubscribed", NULL); + camel_object_class_add_event(camel_object_class, "folder_created", NULL); + camel_object_class_add_event(camel_object_class, "folder_deleted", NULL); + camel_object_class_add_event(camel_object_class, "folder_renamed", NULL); + camel_object_class_add_event(camel_object_class, "folder_subscribed", NULL); + camel_object_class_add_event(camel_object_class, "folder_unsubscribed", NULL); } static void @@ -474,10 +474,10 @@ camel_store_rename_folder (CamelStore *store, const char *old_name, const char * flags |= CAMEL_STORE_FOLDER_INFO_SUBSCRIBED; reninfo.old_base = (char *)old_name; - reninfo.new = ((CamelStoreClass *)((CamelObject *)store)->classfuncs)->get_folder_info(store, new_name, flags, ex); + reninfo.new = ((CamelStoreClass *)((CamelObject *)store)->klass)->get_folder_info(store, new_name, flags, ex); if (reninfo.new != NULL) { camel_object_trigger_event(CAMEL_OBJECT(store), "folder_renamed", &reninfo); - ((CamelStoreClass *)((CamelObject *)store)->classfuncs)->free_folder_info(store, reninfo.new); + ((CamelStoreClass *)((CamelObject *)store)->klass)->free_folder_info(store, reninfo.new); } } else { /* Failed, just unlock our folders for re-use */ diff --git a/camel/camel-stream-filter.h b/camel/camel-stream-filter.h index ae50e016c3..3d265e8b4c 100644 --- a/camel/camel-stream-filter.h +++ b/camel/camel-stream-filter.h @@ -49,7 +49,7 @@ struct _CamelStreamFilterClass { CamelStreamClass parent_class; }; -guint camel_stream_filter_get_type (void); +CamelType camel_stream_filter_get_type (void); CamelStreamFilter *camel_stream_filter_new_with_stream (CamelStream *stream); diff --git a/camel/camel-stream-null.h b/camel/camel-stream-null.h index f2e1c26ccc..be11da7741 100644 --- a/camel/camel-stream-null.h +++ b/camel/camel-stream-null.h @@ -46,7 +46,7 @@ struct _CamelStreamNullClass { CamelStreamClass parent_class; }; -guint camel_stream_null_get_type (void); +CamelType camel_stream_null_get_type (void); CamelStream *camel_stream_null_new (void); diff --git a/camel/camel-text-index.h b/camel/camel-text-index.h index 1982321502..de2a5252ec 100644 --- a/camel/camel-text-index.h +++ b/camel/camel-text-index.h @@ -97,7 +97,7 @@ struct _CamelTextIndexClass { CamelIndexClass parent_class; }; -guint camel_text_index_get_type (void); +CamelType camel_text_index_get_type (void); CamelTextIndex *camel_text_index_new(const char *path, int flags); /* static utility functions */ diff --git a/camel/camel-vee-folder.c b/camel/camel-vee-folder.c index ab5bcf3c18..7ccaae72ab 100644 --- a/camel/camel-vee-folder.c +++ b/camel/camel-vee-folder.c @@ -570,7 +570,7 @@ vee_sync(CamelFolder *folder, gboolean expunge, CamelException *ex) static void vee_expunge (CamelFolder *folder, CamelException *ex) { - ((CamelFolderClass *)((CamelObject *)folder)->classfuncs)->sync(folder, TRUE, ex); + ((CamelFolderClass *)((CamelObject *)folder)->klass)->sync(folder, TRUE, ex); } static CamelMimeMessage * diff --git a/camel/camel-vee-folder.h b/camel/camel-vee-folder.h index c461d80a7e..8d6770b4bc 100644 --- a/camel/camel-vee-folder.h +++ b/camel/camel-vee-folder.h @@ -64,7 +64,7 @@ struct _CamelVeeFolderClass { #define CAMEL_UNMATCHED_NAME "UNMATCHED" -guint camel_vee_folder_get_type (void); +CamelType camel_vee_folder_get_type (void); CamelFolder *camel_vee_folder_new (CamelStore *parent_store, const char *name, guint32 flags); void camel_vee_folder_construct (CamelVeeFolder *vf, CamelStore *parent_store, const char *name, guint32 flags); diff --git a/camel/camel-vee-store.c b/camel/camel-vee-store.c index 6fe9e31339..e8fa1054e1 100644 --- a/camel/camel-vee-store.c +++ b/camel/camel-vee-store.c @@ -18,6 +18,10 @@ * Boston, MA 02111-1307, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include "camel-exception.h" #include "camel-vee-store.h" #include "camel-vee-folder.h" diff --git a/camel/camel-vee-store.h b/camel/camel-vee-store.h index 974bca5bd3..b7309c33c5 100644 --- a/camel/camel-vee-store.h +++ b/camel/camel-vee-store.h @@ -51,7 +51,7 @@ struct _CamelVeeStoreClass { CamelStoreClass parent_class; }; -guint camel_vee_store_get_type (void); +CamelType camel_vee_store_get_type (void); CamelVeeStore *camel_vee_store_new (void); #ifdef __cplusplus diff --git a/camel/camel.c b/camel/camel.c index 2bdc67b1a3..25807b5aac 100644 --- a/camel/camel.c +++ b/camel/camel.c @@ -64,6 +64,9 @@ camel_init (const char *configdir, gboolean nss_init) if (getenv ("CAMEL_VERBOSE_DEBUG")) camel_verbose_debug = TRUE; + /* initialise global camel_object_type */ + camel_object_get_type(); + camel_mime_utils_init(); #ifdef HAVE_NSS diff --git a/camel/providers/imap/camel-imap-command.c b/camel/providers/imap/camel-imap-command.c index 6a2382b3c8..f8ea456439 100644 --- a/camel/providers/imap/camel-imap-command.c +++ b/camel/providers/imap/camel-imap-command.c @@ -696,10 +696,14 @@ imap_command_strdup_vprintf (CamelImapStore *store, const char *fmt, arglen += strlen (store->namespace) + 1; } g_ptr_array_add (args, string); - if (store->capabilities & IMAP_CAPABILITY_LITERALPLUS) - len += arglen + 15; - else - len += arglen * 2; + if (imap_is_atom(string)) { + len += arglen; + } else { + if (store->capabilities & IMAP_CAPABILITY_LITERALPLUS) + len += arglen + 15; + else + len += arglen * 2; + } start = p + 1; break; @@ -750,16 +754,21 @@ imap_command_strdup_vprintf (CamelImapStore *store, const char *fmt, string = imap_mailbox_encode (mailbox, strlen (mailbox)); g_free (mailbox); } - - if (store->capabilities & IMAP_CAPABILITY_LITERALPLUS) { - op += sprintf (op, "{%d+}\r\n%s", - strlen (string), string); + + if (imap_is_atom(string)) { + op += sprintf(op, "%s", string); } else { - char *quoted = imap_quote_string (string); - - op += sprintf (op, "%s", quoted); - g_free (quoted); + if (store->capabilities & IMAP_CAPABILITY_LITERALPLUS) { + op += sprintf (op, "{%d+}\r\n%s", + strlen (string), string); + } else { + char *quoted = imap_quote_string (string); + + op += sprintf (op, "%s", quoted); + g_free (quoted); + } } + if (*p == 'F') g_free (string); break; diff --git a/camel/providers/imap/camel-imap-search.h b/camel/providers/imap/camel-imap-search.h index 9d1694c2c9..7664c4c2ed 100644 --- a/camel/providers/imap/camel-imap-search.h +++ b/camel/providers/imap/camel-imap-search.h @@ -56,7 +56,7 @@ struct _CamelImapSearchClass { }; -guint camel_imap_search_get_type (void); +CamelType camel_imap_search_get_type (void); CamelFolderSearch *camel_imap_search_new (const char *cachedir); #endif /* ! _CAMEL_IMAP_SEARCH_H */ diff --git a/camel/providers/imap/camel-imap-store.c b/camel/providers/imap/camel-imap-store.c index ce87174486..316ab6980e 100644 --- a/camel/providers/imap/camel-imap-store.c +++ b/camel/providers/imap/camel-imap-store.c @@ -1184,7 +1184,7 @@ rename_folder (CamelStore *store, const char *old_name, const char *new_name, Ca flags = CAMEL_STORE_FOLDER_INFO_FAST | CAMEL_STORE_FOLDER_INFO_RECURSIVE | (store->flags & CAMEL_STORE_SUBSCRIPTIONS ? CAMEL_STORE_FOLDER_INFO_SUBSCRIBED : 0); - fi = ((CamelStoreClass *)((CamelObject *)store)->classfuncs)->get_folder_info (store, old_name, flags, ex); + fi = ((CamelStoreClass *)((CamelObject *)store)->klass)->get_folder_info (store, old_name, flags, ex); if (fi && store->flags & CAMEL_STORE_SUBSCRIPTIONS) unsubscribe_folders (store, fi); diff --git a/camel/providers/imap/camel-imap-summary.c b/camel/providers/imap/camel-imap-summary.c index b6c048f299..f64cc00c19 100644 --- a/camel/providers/imap/camel-imap-summary.c +++ b/camel/providers/imap/camel-imap-summary.c @@ -21,6 +21,10 @@ * Boston, MA 02111-1307, USA. */ +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + #include <sys/stat.h> #include <sys/uio.h> #include <unistd.h> diff --git a/camel/providers/imap/camel-imap-summary.h b/camel/providers/imap/camel-imap-summary.h index 14f5dd2433..3b203f639b 100644 --- a/camel/providers/imap/camel-imap-summary.h +++ b/camel/providers/imap/camel-imap-summary.h @@ -63,7 +63,7 @@ struct _CamelImapSummaryClass { }; -guint camel_imap_summary_get_type (void); +CamelType camel_imap_summary_get_type (void); CamelFolderSummary *camel_imap_summary_new (const char *filename); void camel_imap_summary_add_offline (CamelFolderSummary *summary, diff --git a/camel/providers/imap/camel-imap-utils.c b/camel/providers/imap/camel-imap-utils.c index 91d2efb702..7ee7ff807d 100644 --- a/camel/providers/imap/camel-imap-utils.c +++ b/camel/providers/imap/camel-imap-utils.c @@ -271,17 +271,63 @@ imap_parse_flag_list (char **flag_list_p) return flags; } -static char imap_atom_specials[128] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, +/* + From rfc2060 + +ATOM_CHAR ::= <any CHAR except atom_specials> + +atom_specials ::= "(" / ")" / "{" / SPACE / CTL / list_wildcards / + quoted_specials + +CHAR ::= <any 7-bit US-ASCII character except NUL, + 0x01 - 0x7f> + +CTL ::= <any ASCII control character and DEL, + 0x00 - 0x1f, 0x7f> + +SPACE ::= <ASCII SP, space, 0x20> + +list_wildcards ::= "%" / "*" + +quoted_specials ::= <"> / "\" +*/ + +static unsigned char imap_atom_specials[256] = { +/* 00 */0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 10 */0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, +/* 20 */0, 1, 0, 1, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, +/* 30 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* 40 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* 50 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, +/* 60 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, +/* 70 */1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, }; -#define imap_is_atom_char(ch) (isprint (ch) && !imap_atom_specials[ch]) + +#define imap_is_atom_char(c) ((imap_atom_specials[(c)&0xff] & 0x01) != 0) + +gboolean +imap_is_atom(const char *in) +{ + register unsigned char c; + register const char *p = in; + + while ((c = (unsigned char)*p)) { + if (!imap_is_atom_char(c)) + return FALSE; + p++; + } + + /* check for empty string */ + return p!=in; +} /** * imap_parse_string_generic: diff --git a/camel/providers/imap/camel-imap-utils.h b/camel/providers/imap/camel-imap-utils.h index 924b71c119..7078e12335 100644 --- a/camel/providers/imap/camel-imap-utils.h +++ b/camel/providers/imap/camel-imap-utils.h @@ -63,6 +63,7 @@ char *imap_parse_string_generic (char **str_p, size_t *len, int type); void imap_parse_body (char **body_p, CamelFolder *folder, CamelMessageContentInfo *ci); +gboolean imap_is_atom (const char *in); char *imap_quote_string (const char *str); void imap_skip_list (char **str_p); diff --git a/camel/providers/local/camel-local-store.c b/camel/providers/local/camel-local-store.c index 6a51046814..a0d3708346 100644 --- a/camel/providers/local/camel-local-store.c +++ b/camel/providers/local/camel-local-store.c @@ -242,10 +242,10 @@ create_folder(CamelStore *store, const char *parent_name, const char *folder_nam name = g_strdup_printf("%s/%s", parent_name, folder_name); - folder = ((CamelStoreClass *)((CamelObject *)store)->classfuncs)->get_folder(store, name, CAMEL_STORE_FOLDER_CREATE, ex); + folder = ((CamelStoreClass *)((CamelObject *)store)->klass)->get_folder(store, name, CAMEL_STORE_FOLDER_CREATE, ex); if (folder) { camel_object_unref((CamelObject *)folder); - info = ((CamelStoreClass *)((CamelObject *)store)->classfuncs)->get_folder_info(store, name, 0, ex); + info = ((CamelStoreClass *)((CamelObject *)store)->klass)->get_folder_info(store, name, 0, ex); /* get_folder(CREATE) will emit a folder_created event for us */ /*if (info) diff --git a/camel/providers/local/camel-local-summary.h b/camel/providers/local/camel-local-summary.h index 4a4db952d2..d1153fa8c6 100644 --- a/camel/providers/local/camel-local-summary.h +++ b/camel/providers/local/camel-local-summary.h @@ -62,7 +62,7 @@ struct _CamelLocalSummaryClass { int (*decode_x_evolution)(CamelLocalSummary *cls, const char *xev, CamelMessageInfo *info); }; -guint camel_local_summary_get_type (void); +CamelType camel_local_summary_get_type (void); void camel_local_summary_construct (CamelLocalSummary *new, const char *filename, const char *local_name, CamelIndex *index); /* load/check the summary */ diff --git a/camel/providers/local/camel-mbox-summary.h b/camel/providers/local/camel-mbox-summary.h index ec4d015489..6c61da21e5 100644 --- a/camel/providers/local/camel-mbox-summary.h +++ b/camel/providers/local/camel-mbox-summary.h @@ -52,7 +52,7 @@ struct _CamelMboxSummaryClass { CamelLocalSummaryClass parent_class; }; -guint camel_mbox_summary_get_type (void); +CamelType camel_mbox_summary_get_type (void); CamelMboxSummary *camel_mbox_summary_new (const char *filename, const char *mbox_name, CamelIndex *index); /* generate a From line from headers */ diff --git a/camel/providers/local/camel-spool-summary.h b/camel/providers/local/camel-spool-summary.h index 5b20e1dfbe..77fa6bdb3e 100644 --- a/camel/providers/local/camel-spool-summary.h +++ b/camel/providers/local/camel-spool-summary.h @@ -67,7 +67,7 @@ struct _CamelSpoolSummaryClass { int (*decode_x_evolution)(CamelSpoolSummary *cls, const char *xev, CamelMessageInfo *info); }; -guint camel_spool_summary_get_type (void); +CamelType camel_spool_summary_get_type (void); void camel_spool_summary_construct (CamelSpoolSummary *new, const char *filename, const char *spool_name, CamelIndex *index); /* create the summary, in-memory only */ diff --git a/camel/providers/nntp/camel-nntp-stream.h b/camel/providers/nntp/camel-nntp-stream.h index e7b732beff..eef217cef2 100644 --- a/camel/providers/nntp/camel-nntp-stream.h +++ b/camel/providers/nntp/camel-nntp-stream.h @@ -52,7 +52,7 @@ struct _CamelNNTPStreamClass { CamelStreamClass parent_class; }; -guint camel_nntp_stream_get_type (void); +CamelType camel_nntp_stream_get_type (void); CamelStream *camel_nntp_stream_new (CamelStream *source); diff --git a/camel/providers/nntp/camel-nntp-summary.h b/camel/providers/nntp/camel-nntp-summary.h index b82283452e..82070cdc31 100644 --- a/camel/providers/nntp/camel-nntp-summary.h +++ b/camel/providers/nntp/camel-nntp-summary.h @@ -47,7 +47,7 @@ struct _CamelNNTPSummaryClass { CamelFolderSummaryClass parent_class; }; -guint camel_nntp_summary_get_type (void); +CamelType camel_nntp_summary_get_type (void); CamelNNTPSummary *camel_nntp_summary_new(struct _CamelNNTPFolder *folder); int camel_nntp_summary_check(CamelNNTPSummary *cns, CamelFolderChangeInfo *, CamelException *ex); diff --git a/camel/providers/pop3/camel-pop3-engine.h b/camel/providers/pop3/camel-pop3-engine.h index 6b1f0cee1e..caf6ca1d2a 100644 --- a/camel/providers/pop3/camel-pop3-engine.h +++ b/camel/providers/pop3/camel-pop3-engine.h @@ -112,7 +112,7 @@ struct _CamelPOP3EngineClass { CamelObjectClass parent_class; }; -guint camel_pop3_engine_get_type (void); +CamelType camel_pop3_engine_get_type (void); CamelPOP3Engine *camel_pop3_engine_new (CamelStream *source); diff --git a/camel/providers/pop3/camel-pop3-stream.h b/camel/providers/pop3/camel-pop3-stream.h index 2baf48d21d..2a4ebc01f2 100644 --- a/camel/providers/pop3/camel-pop3-stream.h +++ b/camel/providers/pop3/camel-pop3-stream.h @@ -55,7 +55,7 @@ struct _CamelPOP3StreamClass { CamelStreamClass parent_class; }; -guint camel_pop3_stream_get_type (void); +CamelType camel_pop3_stream_get_type (void); CamelStream *camel_pop3_stream_new (CamelStream *source); |