aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2002-05-07 15:31:26 +0800
committerMichael Zucci <zucchi@src.gnome.org>2002-05-07 15:31:26 +0800
commit4655d888677e71962722ad86f255a27386e1e621 (patch)
treea72629c9b63c2b16ca71fc3b666735cfd14b6bef
parent1acd03710d50072259f91bae1a9e2395c6bdfac7 (diff)
downloadgsoc2013-evolution-4655d888677e71962722ad86f255a27386e1e621.tar
gsoc2013-evolution-4655d888677e71962722ad86f255a27386e1e621.tar.gz
gsoc2013-evolution-4655d888677e71962722ad86f255a27386e1e621.tar.bz2
gsoc2013-evolution-4655d888677e71962722ad86f255a27386e1e621.tar.lz
gsoc2013-evolution-4655d888677e71962722ad86f255a27386e1e621.tar.xz
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
-rw-r--r--camel/ChangeLog43
-rw-r--r--camel/Makefile.am2
-rw-r--r--camel/camel-arg.c124
-rw-r--r--camel/camel-arg.h109
-rw-r--r--camel/camel-block-file.c2
-rw-r--r--camel/camel-folder-search.c2
-rw-r--r--camel/camel-folder-search.h2
-rw-r--r--camel/camel-folder-summary.h2
-rw-r--r--camel/camel-folder.c12
-rw-r--r--camel/camel-html-parser.h2
-rw-r--r--camel/camel-index.c6
-rw-r--r--camel/camel-index.h6
-rw-r--r--camel/camel-mime-filter-basic.h2
-rw-r--r--camel/camel-mime-filter-bestenc.h2
-rw-r--r--camel/camel-mime-filter-charset.h2
-rw-r--r--camel/camel-mime-filter-from.h2
-rw-r--r--camel/camel-mime-filter-html.h2
-rw-r--r--camel/camel-mime-filter-index.h2
-rw-r--r--camel/camel-mime-parser.h2
-rw-r--r--camel/camel-news-address.h2
-rw-r--r--camel/camel-object.c1265
-rw-r--r--camel/camel-object.h213
-rw-r--r--camel/camel-partition-table.h4
-rw-r--r--camel/camel-remote-store.c2
-rw-r--r--camel/camel-store-summary.h2
-rw-r--r--camel/camel-store.c16
-rw-r--r--camel/camel-stream-filter.h2
-rw-r--r--camel/camel-stream-null.h2
-rw-r--r--camel/camel-text-index.h2
-rw-r--r--camel/camel-vee-folder.c2
-rw-r--r--camel/camel-vee-folder.h2
-rw-r--r--camel/camel-vee-store.c4
-rw-r--r--camel/camel-vee-store.h2
-rw-r--r--camel/camel.c3
-rw-r--r--camel/providers/imap/camel-imap-command.c33
-rw-r--r--camel/providers/imap/camel-imap-search.h2
-rw-r--r--camel/providers/imap/camel-imap-store.c2
-rw-r--r--camel/providers/imap/camel-imap-summary.c4
-rw-r--r--camel/providers/imap/camel-imap-summary.h2
-rw-r--r--camel/providers/imap/camel-imap-utils.c58
-rw-r--r--camel/providers/imap/camel-imap-utils.h1
-rw-r--r--camel/providers/local/camel-local-store.c4
-rw-r--r--camel/providers/local/camel-local-summary.h2
-rw-r--r--camel/providers/local/camel-mbox-summary.h2
-rw-r--r--camel/providers/local/camel-spool-summary.h2
-rw-r--r--camel/providers/nntp/camel-nntp-stream.h2
-rw-r--r--camel/providers/nntp/camel-nntp-summary.h2
-rw-r--r--camel/providers/pop3/camel-pop3-engine.h2
-rw-r--r--camel/providers/pop3/camel-pop3-stream.h2
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);