aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNot Zed <NotZed@Ximian.com>2004-11-04 13:34:05 +0800
committerMichael Zucci <zucchi@src.gnome.org>2004-11-04 13:34:05 +0800
commit0b736de5187a40f7e2c1414387cc8251e8d5ac9a (patch)
tree7daaedce122b86bda5dc333808c705e67e40c0f6
parent584ff682e56b90d2a20dc77250ab691a525a2873 (diff)
downloadgsoc2013-evolution-0b736de5187a40f7e2c1414387cc8251e8d5ac9a.tar
gsoc2013-evolution-0b736de5187a40f7e2c1414387cc8251e8d5ac9a.tar.gz
gsoc2013-evolution-0b736de5187a40f7e2c1414387cc8251e8d5ac9a.tar.bz2
gsoc2013-evolution-0b736de5187a40f7e2c1414387cc8251e8d5ac9a.tar.lz
gsoc2013-evolution-0b736de5187a40f7e2c1414387cc8251e8d5ac9a.tar.xz
gsoc2013-evolution-0b736de5187a40f7e2c1414387cc8251e8d5ac9a.tar.zst
gsoc2013-evolution-0b736de5187a40f7e2c1414387cc8251e8d5ac9a.zip
check interfaces for events too. (camel_object_trigger_event): check
2004-11-02 Not Zed <NotZed@Ximian.com> * camel-object.c (camel_object_hook_event): check interfaces for events too. (camel_object_trigger_event): check interfaces for events too. (camel_object_class_add_event): more checks for interfaces vs normal object classes. (camel_object_class_add_interface): add an interface to a class. (camel_object_get_interface): query for interfaces on an object. (camel_object_get_type): register the interface type. svn path=/trunk/; revision=27834
-rw-r--r--camel/ChangeLog11
-rw-r--r--camel/camel-object.c331
-rw-r--r--camel/camel-object.h23
-rw-r--r--camel/camel-store.c55
-rw-r--r--camel/camel-store.h15
5 files changed, 397 insertions, 38 deletions
diff --git a/camel/ChangeLog b/camel/ChangeLog
index 61e4fb639d..fa375342d8 100644
--- a/camel/ChangeLog
+++ b/camel/ChangeLog
@@ -1,3 +1,14 @@
+2004-11-02 Not Zed <NotZed@Ximian.com>
+
+ * camel-object.c (camel_object_hook_event): check interfaces for
+ events too.
+ (camel_object_trigger_event): check interfaces for events too.
+ (camel_object_class_add_event): more checks for interfaces vs
+ normal object classes.
+ (camel_object_class_add_interface): add an interface to a class.
+ (camel_object_get_interface): query for interfaces on an object.
+ (camel_object_get_type): register the interface type.
+
2004-11-02 Jeffrey Stedfast <fejj@novell.com>
* providers/imap4/camel-imap4-store.c (imap4_folder_utf7_name):
diff --git a/camel/camel-object.c b/camel/camel-object.c
index a866ae95a2..3cdcd1b3fc 100644
--- a/camel/camel-object.c
+++ b/camel/camel-object.c
@@ -43,8 +43,10 @@
/* I just mashed the keyboard for these... */
#define CAMEL_OBJECT_MAGIC 0x77A344ED
#define CAMEL_OBJECT_CLASS_MAGIC 0xEE26A997
+#define CAMEL_INTERFACE_MAGIC 0xBCE137A7
#define CAMEL_OBJECT_FINALISED_MAGIC 0x84AC365F
#define CAMEL_OBJECT_CLASS_FINALISED_MAGIC 0x7621ABCD
+#define CAMEL_INTERFACE_FINALISED_MAGIC 0x7CB2FE71
/* ** Quickie type system ************************************************* */
@@ -113,6 +115,9 @@ static CamelHookPair *co_metadata_pair(CamelObject *obj, int create);
static const char *meta_name = "object:meta";
#define CAMEL_OBJECT_STATE_FILE_MAGIC "CLMD"
+/* interface stuff */
+static const char *interface_name = "object:interface";
+
/* ********************************************************************** */
static CamelHookList *camel_object_get_hooks(CamelObject *o);
@@ -135,7 +140,9 @@ static EMutex *type_lock;
static GHashTable *type_table;
static EMemChunk *type_chunks;
+/* fundamental types are accessed via global */
CamelType camel_object_type;
+CamelType camel_interface_type;
#define P_LOCK(l) (pthread_mutex_lock(&l))
#define P_UNLOCK(l) (pthread_mutex_unlock(&l))
@@ -144,7 +151,6 @@ CamelType camel_object_type;
#define CLASS_LOCK(k) (g_mutex_lock((((CamelObjectClass *)k)->lock)))
#define CLASS_UNLOCK(k) (g_mutex_unlock((((CamelObjectClass *)k)->lock)))
-
static struct _CamelHookPair *
pair_alloc(void)
{
@@ -211,6 +217,8 @@ camel_type_init(void)
/* ************************************************************************ */
+/* CamelObject base methods */
+
/* Should this return the object to the caller? */
static void
cobject_init(CamelObject *o, CamelObjectClass *klass)
@@ -610,6 +618,59 @@ cobject_class_finalise(CamelObjectClass * klass)
g_free(klass);
}
+
+/* CamelInterface base methods */
+
+static void
+cinterface_init(CamelObject *o, CamelObjectClass *klass)
+{
+ g_error("Cannot instantiate interfaces, trying to instantiate '%s'", klass->name);
+ abort();
+}
+
+static int
+cinterface_getv(CamelObject *o, CamelException *ex, CamelArgGetV *args)
+{
+ return 0;
+}
+
+static int
+cinterface_setv(CamelObject *o, CamelException *ex, CamelArgV *args)
+{
+ return 0;
+}
+
+static void
+cinterface_free(CamelObject *o, guint32 tag, void *value)
+{
+ /* NOOP */
+}
+
+static void
+cinterface_class_init(CamelObjectClass *klass)
+{
+ klass->magic = CAMEL_INTERFACE_MAGIC;
+
+ /* just setup dummy callbacks, properties could be part of the interface but we support none */
+ klass->getv = cinterface_getv;
+ klass->setv = cinterface_setv;
+ klass->free = cinterface_free;
+
+ /* TODO: ok, these are cruft hanging around an interface, but it saves having to define two different class bases */
+ klass->meta_get = NULL;
+ klass->meta_set = NULL;
+ klass->state_read = NULL;
+ klass->state_write = NULL;
+}
+
+static void
+cinterface_class_finalise(CamelObjectClass * klass)
+{
+ klass->magic = CAMEL_INTERFACE_FINALISED_MAGIC;
+ g_free(klass);
+}
+
+/* this function must be called for any other in the object system */
CamelType
camel_object_get_type(void)
{
@@ -620,6 +681,12 @@ camel_object_get_type(void)
sizeof(CamelObject), sizeof(CamelObjectClass),
cobject_class_init, cobject_class_finalise,
cobject_init, cobject_finalise);
+
+ camel_interface_type = camel_type_register(NULL, "CamelInterface",
+ 0, sizeof(CamelInterface),
+ cinterface_class_init, cinterface_class_finalise,
+ cinterface_init, NULL);
+
}
return camel_object_type;
@@ -635,24 +702,19 @@ camel_type_class_init(CamelObjectClass *klass, CamelObjectClass *type)
type->klass_init(klass);
}
-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)
+static CamelType
+co_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 (parent != NULL && parent->magic != CAMEL_OBJECT_CLASS_MAGIC) {
- g_warning("camel_type_register: invalid junk parent class for '%s'", name);
- return NULL;
- }
-
E_LOCK(type_lock);
/* Have to check creation, it might've happened in another thread before we got here */
@@ -724,6 +786,37 @@ camel_type_register(CamelType parent, const char * name,
return klass;
}
+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)
+{
+ if (parent != NULL && parent->magic != CAMEL_OBJECT_CLASS_MAGIC) {
+ g_warning("camel_type_register: invalid junk parent class for '%s'", name);
+ return NULL;
+ }
+
+ return co_type_register(parent, name, object_size, klass_size, class_init, class_finalise, object_init, object_finalise);
+}
+
+CamelType
+camel_interface_register(CamelType parent, const char *name,
+ size_t class_size,
+ CamelObjectClassInitFunc class_init,
+ CamelObjectClassFinalizeFunc class_finalise)
+{
+ if (parent != NULL && parent->magic != CAMEL_INTERFACE_MAGIC) {
+ g_warning("camel_interface_register: invalid junk parent class for '%s'", name);
+ return NULL;
+ }
+
+ return camel_type_register(parent, name, 0, class_size, class_init, class_finalise, NULL, NULL);
+}
+
static void
camel_object_init(CamelObject *o, CamelObjectClass *klass, CamelType type)
{
@@ -852,6 +945,9 @@ camel_type_to_name(CamelType type)
if (type->magic == CAMEL_OBJECT_CLASS_MAGIC)
return type->name;
+ if (type->magic == CAMEL_INTERFACE_MAGIC)
+ return type->name;
+
return "(Junk class)";
}
@@ -875,10 +971,14 @@ desc_data(CamelObject *o, guint32 ok)
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_INTERFACE_MAGIC)
+ what = g_strdup_printf("INTERFACE '%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 if (o->magic == CAMEL_INTERFACE_FINALISED_MAGIC)
+ what = g_strdup_printf("finalised INTERFACE");
else
what = g_strdup_printf("junk data");
@@ -948,6 +1048,20 @@ camel_object_class_is(CamelObjectClass *k, CamelType ctype)
return FALSE;
}
+gboolean
+camel_interface_is(CamelObjectClass *k, CamelType ctype)
+{
+ g_return_val_if_fail(check_magic(k, ctype, CAMEL_INTERFACE_MAGIC), FALSE);
+
+ while (k) {
+ if (k == ctype)
+ return TRUE;
+ k = k->parent;
+ }
+
+ return FALSE;
+}
+
CamelObject *
camel_object_cast(CamelObject *o, CamelType ctype)
{
@@ -985,6 +1099,55 @@ camel_object_class_cast(CamelObjectClass *k, CamelType ctype)
return NULL;
}
+CamelObjectClass *
+camel_interface_cast(CamelObjectClass *k, CamelType ctype)
+{
+ CamelObjectClass *r = k;
+
+ g_return_val_if_fail(check_magic(k, ctype, CAMEL_INTERFACE_MAGIC), NULL);
+
+ while (k) {
+ if (k == ctype)
+ return r;
+ k = k->parent;
+ }
+
+ g_warning("Interface '%s' doesn't have '%s' in its hierarchy", r->name, ctype->name);
+
+ return NULL;
+}
+
+static CamelHookPair *
+co_find_pair(CamelObjectClass *klass, const char *name)
+{
+ CamelHookPair *hook;
+
+ hook = klass->hooks;
+ while (hook) {
+ if (strcmp(hook->name, name) == 0)
+ return hook;
+ hook = hook->next;
+ }
+
+ return NULL;
+}
+
+static CamelHookPair *
+co_find_pair_ptr(CamelObjectClass *klass, const char *name)
+{
+ CamelHookPair *hook;
+
+ hook = klass->hooks;
+ while (hook) {
+ if (hook->name == name)
+ return hook;
+ hook = hook->next;
+ }
+
+ return NULL;
+}
+
+/* class functions */
void
camel_object_class_add_event(CamelObjectClass *klass, const char *name, CamelObjectEventPrepFunc prep)
{
@@ -992,14 +1155,17 @@ camel_object_class_add_event(CamelObjectClass *klass, const char *name, CamelObj
g_return_if_fail (name);
- 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;
+ pair = co_find_pair(klass, name);
+ if (pair) {
+ g_warning("camel_object_class_add_event: `%s' is already declared for '%s'",
+ name, klass->name);
+ return;
+ }
+
+ if (klass->magic == CAMEL_INTERFACE_MAGIC && prep != NULL) {
+ g_warning("camel_object_class_add_event: `%s', CamelInterface '%s' may not have an event prep function - ignored",
+ name, klass->name);
+ prep = NULL;
}
pair = pair_alloc();
@@ -1011,6 +1177,50 @@ camel_object_class_add_event(CamelObjectClass *klass, const char *name, CamelObj
klass->hooks = pair;
}
+void
+camel_object_class_add_interface(CamelObjectClass *klass, CamelType itype)
+{
+ CamelHookPair *pair;
+ CamelType iscan;
+ GPtrArray *interfaces;
+ int i;
+
+ if (!camel_interface_is(itype, camel_interface_type)) {
+ g_warning("Cannot add an interface not derived from CamelInterface on class '%s'", klass->name);
+ return;
+ }
+
+ if (camel_object_class_is(klass, camel_interface_type)) {
+ g_warning("Cannot add an interface onto a class derived from CamelInterface");
+ return;
+ }
+
+ /* we store it on the class hooks so we don't have to add any extra space to the class */
+ pair = co_find_pair_ptr(klass, interface_name);
+ if (pair == NULL) {
+ pair = pair_alloc();
+ pair->data = g_ptr_array_new();
+ pair->next = klass->hooks;
+ klass->hooks = pair;
+ }
+
+ /* We just check that this type isn't added/derived anywhere else */
+ interfaces = pair->data;
+ iscan = itype;
+ while (iscan && iscan != camel_interface_type) {
+ for (i=0;i<interfaces->len;i++) {
+ if (camel_interface_is((CamelType)interfaces->pdata[i], iscan)) {
+ g_warning("Cannot add an interface twice '%s' on class '%s'\n", itype->name, klass->name);
+ return;
+ }
+ }
+ iscan = iscan->parent;
+ }
+
+ if (iscan == camel_interface_type)
+ g_ptr_array_add(interfaces, itype);
+}
+
/* free hook data */
static void
camel_object_free_hooks(CamelObject *o)
@@ -1079,18 +1289,27 @@ camel_object_hook_event(void *vo, const char * name, CamelObjectEventHookFunc fu
g_return_val_if_fail(name != NULL, 0);
g_return_val_if_fail(func != NULL, 0);
- hook = obj->klass->hooks;
- while (hook) {
- if (strcmp(hook->name, name) == 0)
- goto setup;
- hook = hook->next;
- }
+ hook = co_find_pair(obj->klass, name);
- g_warning("camel_object_hook_event: trying to hook event `%s' in class `%s' with no defined events.",
- name, obj->klass->name);
+ /* Check all interfaces on this object for events defined on them */
+ if (hook == NULL) {
+ pair = co_find_pair_ptr(obj->klass, interface_name);
+ if (pair) {
+ GPtrArray *interfaces = pair->data;
+ int i;
- return 0;
+ for (i=0;i<interfaces->len;i++) {
+ hook = co_find_pair(interfaces->pdata[i], name);
+ if (hook)
+ goto setup;
+ }
+ }
+
+ 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 = pair_alloc();
@@ -1217,11 +1436,24 @@ camel_object_trigger_event(void *vo, const char * name, void *event_data)
g_return_if_fail (CAMEL_IS_OBJECT (obj));
g_return_if_fail (name);
- hook = obj->klass->hooks;
- while (hook) {
- if (strcmp(hook->name, name) == 0)
- goto trigger;
- hook = hook->next;
+ hook = co_find_pair(obj->klass, name);
+ if (hook)
+ goto trigger;
+
+ if (obj->hooks == NULL)
+ return;
+
+ /* interface events can't have prep functions */
+ pair = co_find_pair_ptr(obj->klass, interface_name);
+ if (pair) {
+ GPtrArray *interfaces = pair->data;
+ int i;
+
+ for (i=0;i<interfaces->len;i++) {
+ hook = co_find_pair(interfaces->pdata[i], name);
+ if (hook)
+ goto trigger_interface;
+ }
}
g_warning("camel_object_trigger_event: trying to trigger unknown event `%s' in class `%s'",
@@ -1237,7 +1469,7 @@ trigger:
/* also, no hooks, dont bother going further */
if (obj->hooks == NULL)
return;
-
+trigger_interface:
/* lock the object for hook emission */
camel_object_ref(obj);
hooks = camel_object_get_hooks(obj);
@@ -1285,6 +1517,31 @@ trigger:
camel_object_unref(obj);
}
+void *
+camel_object_get_interface(void *vo, CamelType itype)
+{
+ CamelObject *obj = vo;
+ CamelHookPair *pair;
+
+ g_return_val_if_fail(CAMEL_IS_OBJECT (obj), NULL);
+ g_return_val_if_fail(camel_interface_is(itype, camel_interface_type), NULL);
+
+ pair = co_find_pair_ptr(obj->klass, interface_name);
+ if (pair) {
+ GPtrArray *interfaces = pair->data;
+ int i;
+
+ for (i=0;i<interfaces->len;i++) {
+ if (camel_interface_is((CamelType)interfaces->pdata[i], itype))
+ return (CamelType)interfaces->pdata[i];
+ }
+ }
+
+ g_warning("Object %p class %s doesn't contain interface %s\n", vo, obj->klass->name, itype->name);
+
+ return NULL;
+}
+
/* get/set arg methods */
int camel_object_set(void *vo, CamelException *ex, ...)
{
diff --git a/camel/camel-object.h b/camel/camel-object.h
index 9ee9c45345..a1afdd71ca 100644
--- a/camel/camel-object.h
+++ b/camel/camel-object.h
@@ -72,6 +72,10 @@ typedef struct _CamelObject CamelObject;
typedef unsigned int CamelObjectHookID;
typedef struct _CamelObjectMeta CamelObjectMeta;
+extern CamelType camel_interface_type;
+#define CAMEL_INTERFACE_TYPE (camel_interface_type)
+typedef struct _CamelInterface CamelInterface;
+
typedef void (*CamelObjectClassInitFunc) (CamelObjectClass *);
typedef void (*CamelObjectClassFinalizeFunc) (CamelObjectClass *);
typedef void (*CamelObjectInitFunc) (CamelObject *, CamelObjectClass *);
@@ -165,6 +169,8 @@ struct _CamelObjectClass
void (*init)(struct _CamelObject *, struct _CamelObjectClass *);
void (*finalise)(struct _CamelObject *);
+ /* root-class fields follow, type system above */
+
/* get/set interface */
int (*setv)(struct _CamelObject *, struct _CamelException *ex, CamelArgV *args);
int (*getv)(struct _CamelObject *, struct _CamelException *ex, CamelArgGetV *args);
@@ -180,6 +186,11 @@ struct _CamelObjectClass
int (*state_write)(struct _CamelObject *, FILE *fp);
};
+/* an interface is just a class with no instance data */
+struct _CamelInterface {
+ struct _CamelObjectClass type;
+};
+
/* The type system .... it's pretty simple..... */
void camel_type_init (void);
CamelType camel_type_register(CamelType parent, const char * name, /*unsigned int ver, unsigned int rev,*/
@@ -190,6 +201,11 @@ CamelType camel_type_register(CamelType parent, const char * name, /*unsigned in
CamelObjectInitFunc instance_init,
CamelObjectFinalizeFunc instance_finalize);
+CamelType camel_interface_register(CamelType parent, const char *name,
+ size_t classfuncs_size,
+ CamelObjectClassInitFunc class_init,
+ CamelObjectClassFinalizeFunc class_finalize);
+
/* deprecated interface */
#define camel_type_get_global_classfuncs(x) ((CamelObjectClass *)(x))
@@ -197,6 +213,7 @@ CamelType camel_type_register(CamelType parent, const char * name, /*unsigned in
const char *camel_type_to_name (CamelType type);
CamelType camel_name_to_type (const char *name);
void camel_object_class_add_event (CamelObjectClass *klass, const char *name, CamelObjectEventPrepFunc prep);
+void camel_object_class_add_interface(CamelObjectClass *klass, CamelType itype);
void camel_object_class_dump_tree (CamelType root);
@@ -207,6 +224,9 @@ gboolean camel_object_is(CamelObject *obj, CamelType ctype);
CamelObjectClass *camel_object_class_cast (CamelObjectClass *klass, CamelType ctype);
gboolean camel_object_class_is (CamelObjectClass *klass, CamelType ctype);
+CamelObjectClass *camel_interface_cast(CamelObjectClass *klass, CamelType ctype);
+gboolean camel_interface_is(CamelObjectClass *k, CamelType ctype);
+
CamelType camel_object_get_type (void);
CamelObject *camel_object_new (CamelType type);
@@ -226,6 +246,9 @@ void camel_object_remove_event(void *obj, CamelObjectHookID id);
void camel_object_unhook_event(void *obj, const char *name, CamelObjectEventHookFunc hook, void *data);
void camel_object_trigger_event(void *obj, const char *name, void *event_data);
+/* interfaces */
+void *camel_object_get_interface(void *vo, CamelType itype);
+
/* get/set methods */
int camel_object_set(void *obj, struct _CamelException *ex, ...);
int camel_object_setv(void *obj, struct _CamelException *ex, CamelArgV *);
diff --git a/camel/camel-store.c b/camel/camel-store.c
index 4075170eb8..3ae83bdbca 100644
--- a/camel/camel-store.c
+++ b/camel/camel-store.c
@@ -1204,3 +1204,58 @@ camel_store_folder_uri_equal (CamelStore *store, const char *uri0, const char *u
return equal;
}
+
+/* subscriptions interface */
+
+static void
+cis_interface_init (CamelISubscribe *cis)
+{
+ camel_object_class_add_event((CamelType)cis, "subscribed", NULL);
+ camel_object_class_add_event((CamelType)cis, "unsubscribed", NULL);
+}
+
+CamelType camel_isubscribe_get_type (void)
+{
+ static CamelType camel_isubscribe_type = CAMEL_INVALID_TYPE;
+
+ if (camel_isubscribe_type == CAMEL_INVALID_TYPE) {
+ camel_isubscribe_type = camel_interface_register (CAMEL_INTERFACE_TYPE, "CamelISubscribe",
+ sizeof (CamelISubscribe),
+ (CamelObjectClassInitFunc) cis_interface_init,
+ NULL);
+ }
+
+ return camel_isubscribe_type;
+}
+
+gboolean camel_isubscribe_subscribed(CamelStore *store, const char *name)
+{
+ CamelISubscribe *iface = camel_object_get_interface(store, camel_isubscribe_get_type());
+
+ if (iface && iface->subscribed)
+ return iface->subscribed(store, name);
+
+ g_warning("Trying to invoke unimplemented subscribed method on a store");
+ return FALSE;
+}
+
+void camel_isubscribe_subscribe(CamelStore *store, const char *folder_name, CamelException *ex)
+{
+ CamelISubscribe *iface = camel_object_get_interface(store, camel_isubscribe_get_type());
+
+ if (iface && iface->subscribe)
+ return iface->subscribe(store, folder_name, ex);
+
+ g_warning("Trying to invoke unimplemented subscribe method on a store");
+}
+
+void camel_isubscribe_unsubscribe(CamelStore *store, const char *folder_name, CamelException *ex)
+{
+ CamelISubscribe *iface = camel_object_get_interface(store, camel_isubscribe_get_type());
+
+ if (iface && iface->unsubscribe)
+ return iface->unsubscribe(store, folder_name, ex);
+
+ g_warning("Trying to invoke unimplemented unsubscribe method on a store");
+}
+
diff --git a/camel/camel-store.h b/camel/camel-store.h
index adffedfa31..3a7676340d 100644
--- a/camel/camel-store.h
+++ b/camel/camel-store.h
@@ -164,7 +164,6 @@ typedef struct {
CamelException *ex);
} CamelStoreClass;
-
/* Standard Camel function */
CamelType camel_store_get_type (void);
@@ -231,6 +230,20 @@ int camel_store_folder_uri_equal (CamelStore *store,
const char *uri0,
const char *uri1);
+typedef struct _CamelISubscribe CamelISubscribe;
+struct _CamelISubscribe {
+ CamelInterface iface;
+
+ gboolean (*subscribed)(CamelStore *store, const char *folder_name);
+ void (*subscribe)(CamelStore *store, const char *folder_name, CamelException *ex);
+ void (*unsubscribe)(CamelStore *store, const char *folder_name, CamelException *ex);
+};
+
+CamelType camel_isubscribe_get_type (void);
+gboolean camel_isubscribe_subscribed(CamelStore *store, const char *name);
+void camel_isubscribe_subscribe(CamelStore *store, const char *folder_name, CamelException *ex);
+void camel_isubscribe_unsubscribe(CamelStore *store, const char *folder_name, CamelException *ex);
+
#ifdef __cplusplus
}
#endif /* __cplusplus */