diff options
author | Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> | 2009-12-15 15:37:33 -0200 |
---|---|---|
committer | Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> | 2009-12-15 15:37:33 -0200 |
commit | d9bbcf4244376b8976f2a12e525c4813232be581 (patch) | |
tree | c976c799c179e6b73647d1670da0d71ca036542a /src | |
parent | 436431fa929cea024a97421cb3029a565d17d313 (diff) | |
download | telepathy-logger-d9bbcf4244376b8976f2a12e525c4813232be581.tar.gz |
Code clean-up complete - working TPL
Diffstat (limited to 'src')
-rwxr-xr-x | src/compile.sh | 2 | ||||
-rw-r--r-- | src/test.c | 21 | ||||
-rw-r--r-- | src/tpl-channel.c | 185 | ||||
-rw-r--r-- | src/tpl-contact.c | 239 | ||||
-rw-r--r-- | src/tpl-headless-logger-init.c | 22 | ||||
-rw-r--r-- | src/tpl-log-entry-text.c | 183 | ||||
-rw-r--r-- | src/tpl-log-manager.c | 1 | ||||
-rw-r--r-- | src/tpl-log-manager.xsl (renamed from src/empathy-log-manager.xsl) | 0 | ||||
-rw-r--r-- | src/tpl-log-store-empathy.c | 36 | ||||
-rw-r--r-- | src/tpl-observer.c | 144 | ||||
-rw-r--r-- | src/tpl-text-channel-context.c | 156 | ||||
-rw-r--r-- | src/tpl-time.c | 6 | ||||
-rw-r--r-- | src/tpl-utils.c | 21 |
13 files changed, 797 insertions, 219 deletions
diff --git a/src/compile.sh b/src/compile.sh index 358577b..67efd01 100755 --- a/src/compile.sh +++ b/src/compile.sh @@ -2,7 +2,7 @@ PACKAGE_NAME="TpLogger" CC=${CC:-gcc} -CCOPTS="-D__USE_POSIX -DPACKAGE_NAME=\"${PACKAGE_NAME}\" --std=c99 -g -I../include -Wall -Werror" # -pedantic" +CCOPTS="-D_POSIX_SOURCE -DPACKAGE_NAME=\"${PACKAGE_NAME}\" --std=c99 -g -I../include -Wall -Werror" # -pedantic" PKGS="telepathy-glib libxml-2.0" MODULES="tpl-observer.c tpl-headless-logger-init.c tpl-channel.c tpl-text-channel-context.c @@ -1,3 +1,24 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + #include <glib.h> #include <tpl-observer.h> diff --git a/src/tpl-channel.c b/src/tpl-channel.c index 7216d10..9373ea9 100644 --- a/src/tpl-channel.c +++ b/src/tpl-channel.c @@ -1,32 +1,88 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + #include <glib.h> #include <tpl-observer.h> #include <tpl-channel.h> +#include <tpl-text-channel-context.h> G_DEFINE_TYPE (TplChannel, tpl_channel, G_TYPE_OBJECT) +static void tpl_channel_dispose (GObject *obj); +static void tpl_channel_finalize (GObject *obj); + +static void tpl_channel_class_init (TplChannelClass* klass) +{ + GObjectClass* object_class = G_OBJECT_CLASS (klass); + + object_class->dispose = tpl_channel_dispose; + object_class->finalize = tpl_channel_finalize; +} + + +static void tpl_channel_init (TplChannel* self) +{ + /* Init TplChannel's members to zero/NULL */ +#define TPL_SET_NULL(x) tpl_channel_set_##x(self, NULL) + TPL_SET_NULL(channel); + TPL_SET_NULL(channel_path); + TPL_SET_NULL(channel_type); + TPL_SET_NULL(channel_properties); + TPL_SET_NULL(account); + TPL_SET_NULL(account_path); + TPL_SET_NULL(connection); + TPL_SET_NULL(connection_path); + TPL_SET_NULL(observer); +#undef TPL_SET_NULL +} static void tpl_channel_dispose (GObject* obj) { TplChannel *self = TPL_CHANNEL(obj); + g_debug("TplChannel dispose start\n"); + tpl_object_unref_if_not_null (self->channel); self->channel = NULL; - tpl_object_unref_if_not_null (self->channel_properties); + + if(self->channel_properties != NULL) + g_hash_table_unref (self->channel_properties); self->channel_properties = NULL; + tpl_object_unref_if_not_null (self->account); self->account = NULL; + tpl_object_unref_if_not_null (self->connection); self->connection = NULL; + tpl_object_unref_if_not_null (self->observer); self->observer = NULL; G_OBJECT_CLASS (tpl_channel_parent_class)->dispose (obj); + g_debug("TplChannel dispose end\n"); } static void tpl_channel_finalize (GObject* obj) { TplChannel *self = TPL_CHANNEL(obj); - g_free ((gchar*) self->channel_path); g_free ((gchar*) self->channel_type); g_free ((gchar*) self->account_path); @@ -34,35 +90,15 @@ static void tpl_channel_finalize (GObject* obj) G_OBJECT_CLASS (tpl_channel_parent_class)->finalize (obj); - g_debug("TplChannel instnace finalized\n"); + g_debug("TplChannel instance finalized\n"); } -static void tpl_channel_class_init(TplChannelClass* klass) { - GObjectClass* object_class = G_OBJECT_CLASS (klass); - - object_class->dispose = tpl_channel_dispose; - object_class->finalize = tpl_channel_finalize; -} - - -static void tpl_channel_init(TplChannel* self) { - /* Init TplChannel's members to zero/NULL */ -#define TPL_SET_NULL(x) tpl_channel_set_##x(self, NULL) - TPL_SET_NULL(channel); - TPL_SET_NULL(channel_path); - TPL_SET_NULL(channel_type); - TPL_SET_NULL(channel_properties); - TPL_SET_NULL(account); - TPL_SET_NULL(account_path); - TPL_SET_NULL(connection); - TPL_SET_NULL(connection_path); - TPL_SET_NULL(observer); -#undef TPL_SET_NULL -} TplChannel* tpl_channel_new(TpSvcClientObserver* observer) { + g_return_val_if_fail(TP_IS_SVC_CLIENT_OBSERVER(observer), NULL); + TplChannel *ret = g_object_new(TPL_TYPE_CHANNEL,NULL); tpl_channel_set_observer(ret, observer); return ret; @@ -70,46 +106,55 @@ TplChannel* tpl_channel_new(TpSvcClientObserver* observer) TpSvcClientObserver* tpl_channel_get_observer(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->observer; } TpAccount *tpl_channel_get_account(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->account; } const gchar *tpl_channel_get_account_path(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->account_path; } TpConnection *tpl_channel_get_connection(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->connection; } const gchar *tpl_channel_get_connection_path(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->connection_path; } TpChannel *tpl_channel_get_channel(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->channel; } const gchar *tpl_channel_get_channel_path(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->channel_path; } const gchar *tpl_channel_get_channel_type(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->channel_type; } GHashTable *tpl_channel_get_channel_properties(TplChannel *self) { + g_return_val_if_fail(TPL_IS_CHANNEL(self), NULL); return self->channel_properties; } @@ -118,6 +163,9 @@ GHashTable *tpl_channel_get_channel_properties(TplChannel *self) void tpl_channel_set_observer(TplChannel *self, TpSvcClientObserver *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + g_return_if_fail(TP_IS_SVC_CLIENT_OBSERVER(data)||data==NULL); + tpl_object_unref_if_not_null(self->observer); self->observer = data; tpl_object_ref_if_not_null(data); @@ -125,6 +173,9 @@ void tpl_channel_set_observer(TplChannel *self, void tpl_channel_set_account(TplChannel *self, TpAccount *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + g_return_if_fail(TP_IS_ACCOUNT(data)||data==NULL); + tpl_object_unref_if_not_null(self->account); self->account = data; tpl_object_ref_if_not_null(data); @@ -132,12 +183,18 @@ void tpl_channel_set_account(TplChannel *self, TpAccount *data) void tpl_channel_set_account_path(TplChannel *self, const gchar *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + // TODO check validity of data + g_free ((gchar*) self->account_path); - self->account_path = data; + self->account_path = g_strdup (data); } void tpl_channel_set_connection(TplChannel *self, TpConnection *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + g_return_if_fail(TP_IS_CONNECTION(data)||data==NULL); + tpl_object_unref_if_not_null(self->connection); self->connection = data; tpl_object_ref_if_not_null(data); @@ -145,31 +202,105 @@ void tpl_channel_set_connection(TplChannel *self, TpConnection *data) void tpl_channel_set_connection_path(TplChannel *self, const gchar *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + // TODO check validity of data + g_free((gchar*) self->connection_path); self->connection_path = g_strdup (data); } void tpl_channel_set_channel(TplChannel *self, TpChannel *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + g_return_if_fail(TP_IS_CHANNEL(data)||data==NULL); + tpl_object_unref_if_not_null(self->channel); self->channel = data; tpl_object_ref_if_not_null(data); } void tpl_channel_set_channel_path(TplChannel *self, const gchar *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + // TODO check validity of data + g_free((gchar*) self->channel_path); self->channel_path = g_strdup (data); } void tpl_channel_set_channel_type(TplChannel *self, const gchar *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + // TODO check validity of data + g_free((gchar*) self->channel_type); self->channel_type = g_strdup (data); } void tpl_channel_set_channel_properties(TplChannel *self, GHashTable *data) { + g_return_if_fail(TPL_IS_CHANNEL(self)); + // TODO check validity of data + if (self->channel_properties != NULL) g_hash_table_unref(self->channel_properties); self->channel_properties = data; - g_hash_table_ref(data); + if (data!=NULL) + g_hash_table_ref(data); +} + + +gboolean +tpl_channel_register_to_observer(TplChannel *self) +{ + TplObserver *obs = TPL_OBSERVER(tpl_channel_get_observer(self)); + GHashTable *glob_map = tpl_observer_get_channel_map(obs); + gchar *key; + + g_return_val_if_fail( TPL_IS_CHANNEL(self), FALSE); + g_return_val_if_fail( glob_map != NULL, FALSE); + + key = g_strdup (tpl_channel_get_channel_path (self)); + + if (g_hash_table_lookup(glob_map, key) != NULL) { + g_error("Channel path found, replacing %s\n", key); + g_hash_table_remove(glob_map, key); + } else { + g_debug("Channel path not found, registering %s\n", key); + } + + // Instantiate and delegate channel handling to the right object + if (0==g_strcmp0 (TP_IFACE_CHAN_TEXT, + tpl_channel_get_channel_type(self))) { + // when removed, automatically frees the Key and unrefs + // its Value + TplTextChannel *chan_text = tpl_text_channel_new(self); + g_hash_table_insert(glob_map, key, chan_text); + } else { + g_warning("%s: channel type not handled by this logger", + tpl_channel_get_channel_type(self)); + } + + g_object_unref(self); + + return TRUE; +} + +gboolean +tpl_channel_unregister_from_observer(TplChannel *self) +{ + TplObserver *obs = TPL_OBSERVER(tpl_channel_get_observer(self)); + GHashTable *glob_map = tpl_observer_get_channel_map(obs); + const gchar *key; + + g_assert (TPL_IS_CHANNEL(self)); + g_assert (glob_map != NULL); + g_return_val_if_fail (TPL_IS_CHANNEL(self), FALSE); + g_return_val_if_fail (glob_map != NULL, FALSE); + + key = tpl_channel_get_channel_path (self); + g_debug ("Unregistering channel path %s\n", key); + + // this will destroy the associated value object: at this point + // the hash table reference should be the only one for the + // value's object + return g_hash_table_remove(glob_map, key); } diff --git a/src/tpl-contact.c b/src/tpl-contact.c index 162e47b..4870526 100644 --- a/src/tpl-contact.c +++ b/src/tpl-contact.c @@ -1,72 +1,215 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + +#include <telepathy-glib/account.h> + #include <tpl-contact.h> #include <tpl-utils.h> G_DEFINE_TYPE (TplContact, tpl_contact, G_TYPE_OBJECT) -static void tpl_contact_class_init(TplContactClass* klass) { - //GObjectClass* gobject_class = G_OBJECT_CLASS (klass); +static void tpl_contact_finalize(GObject *obj); +static void tpl_contact_dispose(GObject *obj); + +static void tpl_contact_class_init(TplContactClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->finalize = tpl_contact_finalize; + object_class->dispose = tpl_contact_dispose; } -static void tpl_contact_init(TplContact* self) { +static void tpl_contact_init(TplContact *self) +{ +#define SET_NULL(member) self->member = NULL + SET_NULL(contact); + SET_NULL(alias); + SET_NULL(identifier); + SET_NULL(presence_status); + SET_NULL(presence_message); +#undef SET_NULL } -/* retrieved contact and set TplContact ready */ +static void tpl_contact_finalize(GObject *obj) +{ + TplContact *self = TPL_CONTACT(obj); + + g_free ((gchar*) self->alias); + self->alias = NULL; + g_free ((gchar*) self->identifier); + self->identifier = NULL; + g_free ((gchar*) self->presence_status); + self->presence_status = NULL; + g_free ((gchar*) self->presence_message); + self->presence_message = NULL; -TplContact *tpl_contact_from_tp_contact(TpContact *contact) + G_OBJECT_CLASS (tpl_contact_parent_class)->finalize (obj); + g_debug("TplContact finalized\n"); +} +static void tpl_contact_dispose(GObject *obj) +{ + TplContact *self = TPL_CONTACT(obj); + + tpl_object_unref_if_not_null(self->contact); + self->contact = NULL; + + G_OBJECT_CLASS (tpl_contact_parent_class)->dispose (obj); + g_debug("TplContact disposed\n"); +} + + + +TplContact *tpl_contact_from_tp_contact (TpContact *contact) { TplContact *ret; - const gchar *id, *alias; - const gchar *pres_msg, *pres_status; - - ret = tpl_contact_new(); - id = tp_contact_get_identifier(contact); - alias = tp_contact_get_alias(contact); - pres_status = tp_contact_get_presence_status(contact); - pres_msg = tp_contact_get_presence_message (contact); - -#define CONTACT_ENTRY_SET(x,y) tpl_contact_set_##x(ret,y) - CONTACT_ENTRY_SET(contact, contact); - CONTACT_ENTRY_SET(alias, alias); - CONTACT_ENTRY_SET(identifier, id); - CONTACT_ENTRY_SET(presence_status, pres_status); - CONTACT_ENTRY_SET(presence_message, pres_msg ); + const gchar *identifier, *alias; + const gchar *presence_message, *presence_status; + + ret = tpl_contact_new (); + identifier = tp_contact_get_identifier (contact); + alias = tp_contact_get_alias (contact); + presence_status = tp_contact_get_presence_status (contact); + presence_message = tp_contact_get_presence_message (contact); + +#define CONTACT_ENTRY_SET(x) tpl_contact_set_##x(ret, x) + CONTACT_ENTRY_SET(contact); + CONTACT_ENTRY_SET(alias); + CONTACT_ENTRY_SET(identifier); + CONTACT_ENTRY_SET(presence_status); + CONTACT_ENTRY_SET(presence_message); #undef CONTACT_ENTRY_SET return ret; } -TplContact *tpl_contact_new() { +TplContact *tpl_contact_new(void) +{ return g_object_new(TPL_TYPE_CONTACT, NULL); } -#define ADD_GET(x,y) y tpl_contact_get_##x(TplContact *self) { \ - return self->x; } - ADD_GET(contact, TpContact *); - ADD_GET(alias, const gchar *); - ADD_GET(identifier, const gchar *); - ADD_GET(presence_status, const gchar *); - ADD_GET(presence_message, const gchar *); - ADD_GET(contact_type, TplContactType); - ADD_GET(account, TpAccount *); -#undef ADD_GET - -#define ADD_SET_PTR(member,y) void tpl_contact_set_##member(TplContact *self, y data) { \ - tpl_object_unref_if_not_null(self->member) ; \ - self->member = data; \ - tpl_object_ref_if_not_null(data); } - ADD_SET_PTR(contact, TpContact *); - ADD_SET_PTR(account, TpAccount *); -#undef ADD_SET_PTR -#define ADD_SET_STR(member, Type) \ - void tpl_contact_set_##member(TplContact *self, Type data) \ - { g_free( (gchar*) self->member); self->member = g_strdup (data); } - ADD_SET_STR(alias, const gchar *); - ADD_SET_STR(identifier, const gchar *); - ADD_SET_STR(presence_status, const gchar *); - ADD_SET_STR(presence_message, const gchar *); -#undef ADD_SET_STR +TpContact *tpl_contact_get_contact(TplContact *self) +{ + return self->contact; +} + +const gchar *tpl_contact_get_alias(TplContact *self) +{ + return self->alias; +} + +const gchar *tpl_contact_get_identifier(TplContact *self) +{ + return self->identifier; +} + +const gchar *tpl_contact_get_presence_status(TplContact *self) +{ + return self->presence_status; +} + +const gchar *tpl_contact_get_presence_message(TplContact *self) +{ + return self->presence_message; +} + +TplContactType tpl_contact_get_contact_type(TplContact *self) +{ + return self->contact_type; +} + +TpAccount *tpl_contact_get_account(TplContact *self) +{ + return self->account; +} + + +void tpl_contact_set_contact(TplContact *self, TpContact *data) +{ + g_assert(TPL_IS_CONTACT(self)); + g_assert(TP_IS_CONTACT(data)||data==NULL); + g_return_if_fail(TPL_IS_CONTACT(self)); + g_return_if_fail(TP_IS_CONTACT(data)||data==NULL); + + tpl_object_unref_if_not_null(self->contact); + self->contact = data; + tpl_object_ref_if_not_null(data); +} + +void tpl_contact_set_account(TplContact *self, TpAccount *data) +{ + g_assert(TPL_IS_CONTACT(self)); + g_assert(TP_IS_ACCOUNT(data)||data==NULL); + g_return_if_fail(TPL_IS_CONTACT(self)); + g_return_if_fail(TP_IS_ACCOUNT(data)||data==NULL); + + tpl_object_unref_if_not_null(self->account); + self->account = data; + tpl_object_ref_if_not_null(data); +} + +void tpl_contact_set_alias(TplContact *self, const gchar *data) +{ + g_assert(TPL_IS_CONTACT(self)); + g_return_if_fail(TPL_IS_CONTACT(self)); + // TODO check data validity + + g_free( (gchar*) self->alias); + self->alias = g_strdup (data); +} + +void tpl_contact_set_identifier(TplContact *self, const gchar *data) +{ + g_assert(TPL_IS_CONTACT(self)); + g_return_if_fail(TPL_IS_CONTACT(self)); + // TODO check data validity + + g_free( (gchar*) self->identifier); + self->identifier = g_strdup (data); +} + +void tpl_contact_set_presence_status(TplContact *self, const gchar *data) +{ + g_assert(TPL_IS_CONTACT(self)); + g_return_if_fail(TPL_IS_CONTACT(self)); + // TODO check data validity + + g_free( (gchar*) self->presence_status); + self->presence_status = g_strdup (data); +} + +void tpl_contact_set_presence_message(TplContact *self, const gchar *data) +{ + g_assert(TPL_IS_CONTACT(self)); + g_return_if_fail(TPL_IS_CONTACT(self)); + // TODO check data validity + + g_free( (gchar*) self->presence_message); + self->presence_message = g_strdup (data); +} + void tpl_contact_set_contact_type(TplContact *self, TplContactType data) { - self->contact_type = data; + g_assert(TPL_IS_CONTACT(self)); + g_return_if_fail(TPL_IS_CONTACT(self)); + // TODO check data validity + + self->contact_type = data; } diff --git a/src/tpl-headless-logger-init.c b/src/tpl-headless-logger-init.c index e82deaf..e522508 100644 --- a/src/tpl-headless-logger-init.c +++ b/src/tpl-headless-logger-init.c @@ -1,3 +1,25 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + + #include <telepathy-glib/account-manager.h> #include <telepathy-glib/channel-dispatch-operation.h> #include <telepathy-glib/connection-manager.h> diff --git a/src/tpl-log-entry-text.c b/src/tpl-log-entry-text.c index 0b67143..a2f05cf 100644 --- a/src/tpl-log-entry-text.c +++ b/src/tpl-log-entry-text.c @@ -1,26 +1,93 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + +#include <tpl-log-entry-text.h> #include <tpl-channel.h> #include <tpl-contact.h> -#include <tpl-log-entry-text.h> #include <tpl-utils.h> G_DEFINE_TYPE (TplLogEntryText, tpl_log_entry_text, G_TYPE_OBJECT) +static void tpl_log_entry_text_finalize (GObject *obj); +static void tpl_log_entry_text_dispose (GObject *obj); + static void tpl_log_entry_text_class_init(TplLogEntryTextClass* klass) { - //GObjectClass* gobject_class = G_OBJECT_CLASS (klass); + GObjectClass* object_class = G_OBJECT_CLASS (klass); + object_class->finalize = tpl_log_entry_text_finalize; + object_class->dispose = tpl_log_entry_text_dispose; } static void tpl_log_entry_text_init(TplLogEntryText* self) { #define TPL_SET_NULL(x) tpl_log_entry_text_set_##x(self, NULL) TPL_SET_NULL(tpl_text_channel); + TPL_SET_NULL(sender); + TPL_SET_NULL(receiver); + TPL_SET_NULL(message); + TPL_SET_NULL(chat_id); #undef TPL_SET_NULL } +static void +tpl_log_entry_text_dispose (GObject *obj) +{ + TplLogEntryText *self = TPL_LOG_ENTRY_TEXT(obj); + g_debug("TplLogEntryText: disposing\n"); + + tpl_object_unref_if_not_null (self->tpl_text); + self->tpl_text = NULL; + tpl_object_unref_if_not_null (self->sender); + self->sender = NULL; + tpl_object_unref_if_not_null (self->receiver); + self->receiver = NULL; + + G_OBJECT_CLASS (tpl_log_entry_text_parent_class)->finalize (obj); + + g_debug("TplLogEntryText: disposed\n"); +} + + + +static void +tpl_log_entry_text_finalize (GObject *obj) +{ + TplLogEntryText *self = TPL_LOG_ENTRY_TEXT(obj); + + g_debug("TplLogEntryText: finalizing\n"); + + g_free ((gchar*) self->message); + self->message = NULL; + g_free ((gchar*) self->chat_id); + self->chat_id = NULL; + + G_OBJECT_CLASS (tpl_log_entry_text_parent_class)->dispose (obj); + + g_debug("TplLogEntryText: finalized\n"); +} + + TplLogEntryText *tpl_log_entry_text_new(void) { - TplLogEntryText *ret = g_object_new(TPL_TYPE_LOG_ENTRY_TEXT, NULL); - return ret; + return g_object_new(TPL_TYPE_LOG_ENTRY_TEXT, NULL); } @@ -45,25 +112,28 @@ tpl_log_entry_text_message_type_from_str (const gchar *type_str) } -const gchar *tpl_log_entry_text_message_type_to_str (TpChannelTextMessageType msg_type) +const gchar * +tpl_log_entry_text_message_type_to_str (TpChannelTextMessageType msg_type) { - switch (msg_type) - { - case TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION: - return "action"; - case TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE: - return "notice"; - case TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY: - return "auto-reply"; - default: - return "normal"; - } + switch (msg_type) + { + case TP_CHANNEL_TEXT_MESSAGE_TYPE_ACTION: + return "action"; + case TP_CHANNEL_TEXT_MESSAGE_TYPE_NOTICE: + return "notice"; + case TP_CHANNEL_TEXT_MESSAGE_TYPE_AUTO_REPLY: + return "auto-reply"; + default: + return "normal"; + } } TplChannel * tpl_log_entry_text_get_tpl_channel (TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), NULL); + return tpl_text_channel_get_tpl_channel ( tpl_log_entry_text_get_tpl_text_channel (self)); } @@ -71,91 +141,150 @@ tpl_log_entry_text_get_tpl_channel (TplLogEntryText *self) TplTextChannel * tpl_log_entry_text_get_tpl_text_channel(TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), NULL); return self->tpl_text; } -TplContact *tpl_log_entry_text_get_sender (TplLogEntryText *self) +TplContact * +tpl_log_entry_text_get_sender (TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), NULL); return self->sender; } -TplContact *tpl_log_entry_text_get_receiver (TplLogEntryText *self) + +TplContact * +tpl_log_entry_text_get_receiver (TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), NULL); return self->receiver; } -const gchar *tpl_log_entry_text_get_message (TplLogEntryText *self) + +const gchar * +tpl_log_entry_text_get_message (TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), NULL); return self->message; } + TpChannelTextMessageType tpl_log_entry_text_get_message_type (TplLogEntryText *self) { return self->message_type; } + TplLogEntryTextSignalType tpl_log_entry_text_get_signal_type (TplLogEntryText *self) { return self->signal_type; } -TplLogEntryTextDirection tpl_log_entry_text_get_direction (TplLogEntryText *self) + +TplLogEntryTextDirection +tpl_log_entry_text_get_direction (TplLogEntryText *self) { return self->direction; } -time_t tpl_log_entry_text_get_timestamp (TplLogEntryText *self) + +time_t +tpl_log_entry_text_get_timestamp (TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), -1); return self->timestamp; } -guint tpl_log_entry_text_get_message_id (TplLogEntryText *self) + +guint +tpl_log_entry_text_get_message_id (TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), 0); return self->message_id; } -const gchar *tpl_log_entry_text_get_chat_id (TplLogEntryText *self) + +const gchar * +tpl_log_entry_text_get_chat_id (TplLogEntryText *self) { + g_return_val_if_fail(TPL_IS_LOG_ENTRY_TEXT(self), NULL); return self->chat_id; } -void tpl_log_entry_text_set_tpl_text_channel(TplLogEntryText *self, TplTextChannel *data) +void +tpl_log_entry_text_set_tpl_text_channel(TplLogEntryText *self, + TplTextChannel *data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + g_return_if_fail(TPL_IS_TEXT_CHANNEL(data)||data==NULL); + tpl_object_unref_if_not_null(self->tpl_text); self->tpl_text = data; tpl_object_ref_if_not_null(data); } -void tpl_log_entry_text_set_sender (TplLogEntryText *self, TplContact *data) +void +tpl_log_entry_text_set_sender (TplLogEntryText *self, TplContact *data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + g_return_if_fail(TPL_IS_CONTACT(data)||data==NULL); + + tpl_object_unref_if_not_null(self->sender); self->sender = data; + tpl_object_ref_if_not_null(data); } -void tpl_log_entry_text_set_receiver (TplLogEntryText *self, TplContact *data) + +void +tpl_log_entry_text_set_receiver (TplLogEntryText *self, TplContact *data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + g_return_if_fail(TPL_IS_CONTACT(data)||data==NULL); + + tpl_object_unref_if_not_null(self->receiver); self->receiver = data; + tpl_object_ref_if_not_null(data); } -void tpl_log_entry_text_set_message (TplLogEntryText *self, const gchar *data) + +void +tpl_log_entry_text_set_message (TplLogEntryText *self, + const gchar *data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + + g_free((gchar*) self->message); self->message = g_strdup (data); } void tpl_log_entry_text_set_message_type (TplLogEntryText *self, TpChannelTextMessageType data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + self->message_type = data; } void tpl_log_entry_text_set_signal_type (TplLogEntryText *self, TplLogEntryTextSignalType data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + self->signal_type = data; } void tpl_log_entry_text_set_direction (TplLogEntryText *self, TplLogEntryTextDirection data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + self->direction = data; } void tpl_log_entry_text_set_timestamp (TplLogEntryText *self, time_t data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + self->timestamp = data; } void tpl_log_entry_text_set_message_id (TplLogEntryText *self, guint data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + self->message_id = data; } void tpl_log_entry_text_set_chat_id (TplLogEntryText *self, const gchar *data) { + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(self)); + + g_free((gchar*) self->chat_id); self->chat_id = g_strdup (data); } diff --git a/src/tpl-log-manager.c b/src/tpl-log-manager.c index d4f946f..7f47b67 100644 --- a/src/tpl-log-manager.c +++ b/src/tpl-log-manager.c @@ -150,6 +150,7 @@ tpl_log_manager_add_message (TplLogManager *manager, { out = tpl_log_store_add_message (TPL_LOG_STORE (l->data), chat_id, chatroom, message, error); + g_message("YEAH\n"); found = TRUE; break; } diff --git a/src/empathy-log-manager.xsl b/src/tpl-log-manager.xsl index a934f3a..a934f3a 100644 --- a/src/empathy-log-manager.xsl +++ b/src/tpl-log-manager.xsl diff --git a/src/tpl-log-store-empathy.c b/src/tpl-log-store-empathy.c index 9d739c9..4137a33 100644 --- a/src/tpl-log-store-empathy.c +++ b/src/tpl-log-store-empathy.c @@ -82,12 +82,30 @@ G_DEFINE_TYPE_WITH_CODE (TplLogStoreEmpathy, tpl_log_store_empathy, log_store_iface_init)); static void +log_store_empathy_dispose (GObject *object) +{ + TplLogStoreEmpathy *self = TPL_LOG_STORE_EMPATHY (object); + TplLogStoreEmpathyPriv *priv = GET_PRIV (self); + + // FIXME See TP-bug #25569, when dispose a non prepared TP_AM, it + // might segfault. + // To avoid it, a *klduge*, a reference in the TplObserver to + // the TplLogManager is kept, so that until TplObserver is instanced, + // there will always be a TpLogManager reference and it won't be + // diposed, not executing the follwoing unref (which caused the bug) + if (priv->account_manager != NULL) { + g_object_unref (priv->account_manager); + priv->account_manager = NULL; + } +} + + +static void log_store_empathy_finalize (GObject *object) { TplLogStoreEmpathy *self = TPL_LOG_STORE_EMPATHY (object); TplLogStoreEmpathyPriv *priv = GET_PRIV (self); - g_object_unref (priv->account_manager); g_free (priv->basedir); g_free (priv->name); } @@ -98,6 +116,7 @@ tpl_log_store_empathy_class_init (TplLogStoreEmpathyClass *klass) GObjectClass *object_class = G_OBJECT_CLASS (klass); object_class->finalize = log_store_empathy_finalize; + object_class->dispose = log_store_empathy_dispose; g_type_class_add_private (object_class, sizeof (TplLogStoreEmpathyPriv)); } @@ -123,7 +142,6 @@ static gchar * log_store_account_to_dirname (TpAccount *account) { const gchar *name; - name = tp_proxy_get_object_path (account); if (g_str_has_prefix (name, TP_ACCOUNT_OBJECT_PATH_BASE)) name += strlen (TP_ACCOUNT_OBJECT_PATH_BASE); @@ -249,7 +267,8 @@ static gboolean _log_store_empathy_write_to_store ( TplLogStore *self, return TRUE; } -static gboolean _log_store_empathy_add_message_status_changed ( +static gboolean +_log_store_empathy_add_message_status_changed ( TplLogStore *self, const gchar *chat_id, gboolean chatroom, @@ -311,10 +330,10 @@ static gboolean _log_store_empathy_add_message_status_changed ( static gboolean _log_store_empathy_add_message_chat (TplLogStore *self, - const gchar *chat_id, - gboolean chatroom, - TplLogEntryText *message, - GError **error) + const gchar *chat_id, + gboolean chatroom, + TplLogEntryText *message, + GError **error) { gboolean ret; TpAccount *account; @@ -374,8 +393,7 @@ _log_store_empathy_add_message_chat (TplLogStore *self, g_free (entry); //g_free (avatar_token); - - return TRUE; + return ret; } diff --git a/src/tpl-observer.c b/src/tpl-observer.c index ea9a0a5..c94d51c 100644 --- a/src/tpl-observer.c +++ b/src/tpl-observer.c @@ -1,3 +1,26 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + +#include <glib.h> + #include <telepathy-glib/interfaces.h> #include <telepathy-glib/channel.h> #include <telepathy-glib/gtypes.h> @@ -8,8 +31,13 @@ #include <tpl-observer.h> #include <tpl-channel.h> #include <tpl-text-channel-context.h> +#include <tpl-log-manager.h> + +// TODO move to a member of TplObserver +static TplLogManager *logmanager = NULL; -static GHashTable *glob_map = NULL; +static void tpl_observer_finalize (GObject *obj); +static void tpl_observer_dispose (GObject *obj); static void observer_iface_init (gpointer, gpointer); @@ -22,6 +50,7 @@ G_DEFINE_TYPE_WITH_CODE (TplObserver, tpl_observer, G_TYPE_OBJECT, observer_iface_init); ); +static TplObserver * observer_singleton = NULL; static const char *client_interfaces[] = { TP_IFACE_CLIENT_OBSERVER, NULL @@ -68,7 +97,6 @@ _get_ready_tp_channel(TpConnection *connection, _observe_channel_when_ready_cb, tpl_chan); } - static void tpl_observer_observe_channels (TpSvcClientObserver *self, const char *account, @@ -190,11 +218,36 @@ tpl_observer_get_property (GObject *self, } } +/* Singleton Constructor */ +static GObject * +tpl_observer_constructor (GType type, guint n_props, + GObjectConstructParam *props) +{ + GObject *retval; + + if (observer_singleton) { + retval = g_object_ref (observer_singleton); + } else { + retval = G_OBJECT_CLASS (tpl_observer_parent_class)->constructor + (type, n_props, props); + + observer_singleton = TPL_OBSERVER (retval); + g_object_add_weak_pointer (retval, (gpointer *) &observer_singleton); + } + + return retval; +} + + static void tpl_observer_class_init (TplObserverClass *klass) { GObjectClass *object_class = G_OBJECT_CLASS (klass); + object_class->constructor = tpl_observer_constructor; + object_class->finalize = tpl_observer_finalize; + object_class->dispose = tpl_observer_dispose; + /* D-Bus properties are exposed as GObject properties through the * TpDBusPropertiesMixin */ /* properties on the Client interface */ @@ -255,10 +308,9 @@ static gboolean tpl_str_are_eq(gconstpointer data, gconstpointer data2) static void tpl_observer_init (TplObserver *self) { - //self->chan_map = g_hash_table_new_full (g_str_hash, g_strcmp0, - // g_free, g_object_unref); - glob_map = g_hash_table_new_full (g_str_hash, tpl_str_are_eq, + self->channel_map = g_hash_table_new_full (g_str_hash, tpl_str_are_eq, g_free, g_object_unref); + logmanager = tpl_log_manager_dup_singleton (); } static void @@ -272,57 +324,61 @@ observer_iface_init (gpointer g_iface, gpointer iface_data) #undef IMPLEMENT } -TplObserver *tpl_observer_new (void) +static void +tpl_observer_dispose (GObject *obj) { - return g_object_new (TYPE_TPL_OBSERVER, NULL); + TplObserver *self = TPL_OBSERVER(obj); + + g_debug("TplObserver: disposing\n"); + + if (self->channel_map != NULL) { + g_object_unref(self->channel_map); + self->channel_map = NULL; + } + if (logmanager != NULL) { + g_object_unref(logmanager); + logmanager = NULL; + } + + G_OBJECT_CLASS (tpl_observer_parent_class)->dispose (obj); + + g_debug("TplObserver: disposed\n"); } -gboolean -tpl_channel_register_to_observer(TplChannel *self) +static void +tpl_observer_finalize (GObject *obj) { - g_return_val_if_fail( self != NULL, FALSE); - g_assert(glob_map != NULL); + //TplObserver *self = TPL_OBSERVER(obj); - //TplObserver *obs = tpl_channel_get_observer(self); - gchar *key; + g_debug("TplObserver: finalizing\n"); - key = g_strdup (tpl_channel_get_channel_path (self)); - - if (g_hash_table_lookup(glob_map, key) != NULL) { - g_error("Channel path found, replacing %s\n", key); - g_hash_table_remove(glob_map, key); - } else { - g_message("Channel path not found, registering %s\n", key); - } - - // Instantiate and delegate channel handling to the right object - if (0==g_strcmp0 (TP_IFACE_CHAN_TEXT, - tpl_channel_get_channel_type(self))) { - // when removed, automatically frees the Key and unrefs - // its Value - g_hash_table_insert(glob_map, key, - tpl_text_channel_new(self)); - } else { - g_warning("%s: channel type not handled by this logger", - tpl_channel_get_channel_type(self)); - } + G_OBJECT_CLASS (tpl_observer_parent_class)->finalize (obj); - g_object_unref(self); + g_debug("TplObserver: finalized\n"); +} - return TRUE; +TplObserver * +tpl_observer_new (void) +{ + return g_object_new (TYPE_TPL_OBSERVER, NULL); } -gboolean -tpl_channel_unregister_from_observer(TplChannel *self) +GHashTable * +tpl_observer_get_channel_map(TplObserver *self) { - //TplObserver *obs = tpl_channel_get_observer(self); - const gchar *key; + g_return_val_if_fail(TPL_IS_OBSERVER(self), NULL); - g_return_val_if_fail( self != NULL, FALSE); - - key = tpl_channel_get_channel_path (self); - g_message ("Unregistering channel path %s\n", key); + return self->channel_map; +} - return g_hash_table_remove(glob_map, key); +void +tpl_observer_set_channel_map (TplObserver *self, GHashTable *data) +{ + g_return_if_fail(TPL_IS_OBSERVER(self)); + //TODO check data validity + + tpl_object_unref_if_not_null(self->channel_map); + self->channel_map = data; + tpl_object_ref_if_not_null(data); } diff --git a/src/tpl-text-channel-context.c b/src/tpl-text-channel-context.c index f87bce8..e13413e 100644 --- a/src/tpl-text-channel-context.c +++ b/src/tpl-text-channel-context.c @@ -1,3 +1,24 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + /* * This object acts as a Text Channel context, handling a automaton to * set up all the needed information before connect to Text iface @@ -34,12 +55,14 @@ _channel_on_closed_cb (TpChannel *proxy, { TplTextChannel *tpl_text = TPL_TEXT_CHANNEL(user_data); TplChannel *tpl_chan = tpl_text_channel_get_tpl_channel(tpl_text); - gboolean is_unreg; + gchar* chan_path; + + chan_path = g_strdup (tpl_channel_get_channel_path(tpl_chan)); + + if (!tpl_channel_unregister_from_observer(tpl_chan)) + g_warning("Channel %s couldn't be unregistered correctly (BUG?)\n", chan_path); - is_unreg = tpl_channel_unregister_from_observer(tpl_chan); - g_debug("%s has been unregistered? %d\n", - tpl_channel_get_channel_path(tpl_chan), is_unreg); - g_object_unref(tpl_text); + g_free(chan_path); } static void @@ -47,7 +70,7 @@ _channel_on_lost_message_cb (TpChannel *proxy, gpointer user_data, GObject *weak_object) { - g_debug("LOST MESSAGE"); + g_debug("lost message signal catched"); // log that the system lost a message } @@ -80,7 +103,10 @@ _channel_on_sent_signal_cb (TpChannel *proxy, TplContact *tpl_contact_receiver; TplLogEntryText *log; TplLogManager *logmanager; - const gchar *chat_id; + gchar *chat_id; + + g_assert(TPL_IS_TEXT_CHANNEL(tpl_text)); + g_return_if_fail(TPL_IS_TEXT_CHANNEL(tpl_text)); /* Initialize data for TplContact */ me = tpl_text_channel_get_my_contact(tpl_text); @@ -120,12 +146,10 @@ _channel_on_sent_signal_cb (TpChannel *proxy, chat_id = g_strdup (tpl_text_channel_get_chatroom_id( tpl_text)); - g_message("CHATID(%d):%s\n", - tpl_text_channel_is_chatroom(tpl_text), chat_id); + tpl_log_entry_text_set_chat_id(log, chat_id); logmanager = tpl_log_manager_dup_singleton(); - tpl_log_manager_add_message(logmanager, - chat_id, + tpl_log_manager_add_message(logmanager, chat_id, tpl_text_channel_is_chatroom(tpl_text), log, &error); if(error!=NULL) @@ -135,36 +159,42 @@ _channel_on_sent_signal_cb (TpChannel *proxy, g_error_free(error); } + g_object_unref(tpl_contact_receiver); + g_object_unref(tpl_contact_sender); + g_object_unref(logmanager); + g_object_unref(log); + g_free(chat_id); } - - static void _channel_on_received_signal_with_contact_cb(TpConnection *connection, - guint n_contacts, - TpContact * const *contacts, - guint n_failed, - const TpHandle *failed, - const GError *error, - gpointer user_data, - GObject *weak_object) + guint n_contacts, + TpContact * const *contacts, + guint n_failed, + const TpHandle *failed, + const GError *error, + gpointer user_data, + GObject *weak_object) { TplLogEntryText *log = TPL_LOG_ENTRY_TEXT(user_data); + TplTextChannel *tpl_text = tpl_log_entry_text_get_tpl_text_channel(log); GError *e = NULL; TplLogManager *logmanager; - TplTextChannel *tpl_text; - TpContact *remote; TplContact *tpl_contact_sender; - const gchar *chat_id; + TpContact *remote; + gchar *chat_id; + + g_assert(TPL_IS_LOG_ENTRY_TEXT(log)); + g_return_if_fail(TPL_IS_LOG_ENTRY_TEXT(log)); if(error!=NULL) { - g_error("LogStore: %s", error->message); - // TODO cleanup + g_error("Retrieving remote contact information: %s\n", error->message); + g_error("Not able to log the received message: %s\n", + tpl_log_entry_text_get_message(log)); return; } - tpl_text = tpl_log_entry_text_get_tpl_text_channel(log); remote = tpl_text_channel_get_remote_contact(tpl_text); tpl_contact_sender = tpl_contact_from_tp_contact(remote); @@ -178,7 +208,6 @@ _channel_on_received_signal_with_contact_cb(TpConnection *connection, tpl_log_entry_text_get_message(log)); /* Initialize LogStore and store the message */ - // TODO use the log-manager if (!tpl_text_channel_is_chatroom(tpl_text)) chat_id = g_strdup (tpl_contact_get_identifier( @@ -187,13 +216,12 @@ _channel_on_received_signal_with_contact_cb(TpConnection *connection, chat_id = g_strdup (tpl_text_channel_get_chatroom_id( tpl_text)); - g_message("RECV: CHATID(%d):%s = %s\n", - tpl_text_channel_is_chatroom(tpl_text), chat_id, - tpl_contact_get_identifier(tpl_contact_sender)); + tpl_log_entry_text_set_chat_id(log, chat_id); logmanager = tpl_log_manager_dup_singleton(); + g_assert(TPL_IS_LOG_ENTRY_TEXT(log)); tpl_log_manager_add_message(logmanager, - chat_id, + tpl_log_entry_text_get_chat_id(log), tpl_text_channel_is_chatroom (tpl_text), log, &e); if(e!=NULL) @@ -202,6 +230,10 @@ _channel_on_received_signal_with_contact_cb(TpConnection *connection, g_clear_error(&e); g_error_free(e); } + + g_object_unref(tpl_contact_sender); + g_object_unref(logmanager); + g_free(chat_id); } static void @@ -243,7 +275,9 @@ _channel_on_received_signal_cb (TpChannel *proxy, 1, &arg_Sender, TP_CONTACT_FEATURES_LEN, features, _channel_on_received_signal_with_contact_cb, - log, NULL, NULL); + log, g_object_unref, NULL); + + g_object_unref(tpl_contact_receiver); } /* End of Signal's Callbacks */ @@ -274,7 +308,6 @@ _tpl_text_channel_pendingproc_connect_signals(TplTextChannel* self) channel = tpl_channel_get_channel( tpl_text_channel_get_tpl_channel (self) ); - //TODO handle data destruction tp_cli_channel_type_text_connect_to_received( channel, _channel_on_received_signal_cb, self, NULL, NULL, &error); @@ -285,7 +318,6 @@ _tpl_text_channel_pendingproc_connect_signals(TplTextChannel* self) error = NULL; } - //TODO handle data destruction tp_cli_channel_type_text_connect_to_sent( channel, _channel_on_sent_signal_cb, self, NULL, NULL, &error); @@ -296,7 +328,6 @@ _tpl_text_channel_pendingproc_connect_signals(TplTextChannel* self) error = NULL; } - //TODO handle data destruction tp_cli_channel_type_text_connect_to_send_error( channel, _channel_on_send_error_cb, self, NULL, NULL, &error); @@ -307,7 +338,6 @@ _tpl_text_channel_pendingproc_connect_signals(TplTextChannel* self) error = NULL; } - //TODO handle data destruction tp_cli_channel_type_text_connect_to_lost_message( channel, _channel_on_lost_message_cb, self, NULL, NULL, &error); @@ -328,14 +358,8 @@ _tpl_text_channel_pendingproc_connect_signals(TplTextChannel* self) error = NULL; } - - - // TODO connect to TpContacts' notify::presence-type - context_continue(self); - - g_debug("CONNECT!\n"); } static void @@ -371,16 +395,13 @@ _tpl_text_channel_pendingproc_get_chatroom_id(TplTextChannel *ctx) NULL); g_array_append_val(handles, room_handle); - - g_debug("HANDLE ROOM: %d\n", - g_array_index(handles, TpHandle, 0)); - tpl_text_channel_set_chatroom(ctx, TRUE); - //TODO unref tpl_text tp_cli_connection_call_inspect_handles(connection, -1, TP_HANDLE_TYPE_ROOM, handles, _tpl_text_channel_get_chatroom_cb, ctx, NULL, NULL); + + g_array_unref(handles); } @@ -406,11 +427,15 @@ _tpl_text_channel_get_contact_cb(TpConnection *connection, g_assert_cmpuint(tpl_text->selector, <=, TP_CONTACT_REMOTE); if (n_failed > 0) { - g_error("error resolving self handle for connection %s\n", + g_error("error resolving self handle for connection %s.\n" + "Aborting channel %s observation\n", tpl_channel_get_connection_path( + tpl_text_channel_get_tpl_channel(tpl_text)), + tpl_channel_get_channel_path( tpl_text_channel_get_tpl_channel(tpl_text)) ); - context_continue(tpl_text); + tpl_channel_unregister_from_observer( + tpl_text_channel_get_tpl_channel(tpl_text)); return; } @@ -424,8 +449,16 @@ _tpl_text_channel_get_contact_cb(TpConnection *connection, *contacts); break; default: - g_error("retrieving TpContacts: passing invalid value for selector: %d", tpl_text->selector); - context_continue(tpl_text); + g_error("retrieving TpContacts: passing invalid value " + "for selector: %d\n" + "Aborting channel %s observation\n", + tpl_text->selector, + tpl_channel_get_channel_path( + tpl_text_channel_get_tpl_channel(tpl_text)) + + ); + tpl_channel_unregister_from_observer( + tpl_text_channel_get_tpl_channel(tpl_text)); return; } @@ -436,9 +469,9 @@ _tpl_text_channel_get_contact_cb(TpConnection *connection, static void _tpl_text_channel_pendingproc_get_remote_contact(TplTextChannel *ctx) { + TplChannel *tpl_chan = tpl_text_channel_get_tpl_channel(ctx); TpHandleType remote_handle_type; TpHandle remote_handle; - TplChannel *tpl_chan = tpl_text_channel_get_tpl_channel(ctx); remote_handle = tp_channel_get_handle( tpl_channel_get_channel (tpl_chan), @@ -478,26 +511,32 @@ static void tpl_text_channel_dispose(GObject *obj) { TplTextChannel *self = TPL_TEXT_CHANNEL(obj); + g_debug("TplTextChannel: disposing\n"); + tpl_object_unref_if_not_null(self->tpl_channel); self->tpl_channel = NULL; tpl_object_unref_if_not_null(self->my_contact); self->my_contact = NULL; tpl_object_unref_if_not_null(self->remote_contact); self->remote_contact = NULL; - g_queue_free(self->chain); self->chain = NULL; G_OBJECT_CLASS (tpl_text_channel_parent_class)->dispose (obj); + + g_debug("TplTextChannel: disposed\n"); } static void tpl_text_channel_finalize(GObject *obj) { TplTextChannel *self = TPL_TEXT_CHANNEL(obj); - + + g_debug("TplTextChannel: finalizing\n"); + g_free ((gchar*) self->chatroom_id); G_OBJECT_CLASS (tpl_text_channel_parent_class)->finalize (obj); + g_debug("TplTextChannel: finalized\n"); } static void @@ -512,12 +551,11 @@ tpl_text_channel_class_init(TplTextChannelClass* klass) { static void tpl_text_channel_init(TplTextChannel* self) { /* Init TplTextChannel's members to zero/NULL */ -#define TPL_SET_NULL(x) tpl_text_channel_set_##x(self, NULL) - TPL_SET_NULL(tpl_channel); - TPL_SET_NULL(my_contact); - TPL_SET_NULL(remote_contact); - TPL_SET_NULL(chatroom_id); #undef TPL_SET_NULL + tpl_text_channel_set_tpl_channel(self, NULL); + tpl_text_channel_set_my_contact(self, NULL); + tpl_text_channel_set_remote_contact(self, NULL); + tpl_text_channel_set_chatroom_id(self, NULL); tpl_text_channel_set_chatroom(self, FALSE); } diff --git a/src/tpl-time.c b/src/tpl-time.c index e35c6c8..a9ab267 100644 --- a/src/tpl-time.c +++ b/src/tpl-time.c @@ -45,8 +45,7 @@ tpl_time_get_local_time (struct tm *tm) tz = g_getenv ("TZ"); g_setenv ("TZ", "", TRUE); - //TODO reenable - //tzset (); + tzset (); t = mktime (tm); @@ -56,8 +55,7 @@ tpl_time_get_local_time (struct tm *tm) g_unsetenv ("TZ"); } - //TODO reenable - //tzset (); + tzset (); return t; } diff --git a/src/tpl-utils.c b/src/tpl-utils.c index a34ad8c..9572991 100644 --- a/src/tpl-utils.c +++ b/src/tpl-utils.c @@ -1,3 +1,24 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2009 Collabora Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Cosimo Alfarano <cosimo.alfarano@collabora.co.uk> + */ + #include <tpl-utils.h> void tpl_object_unref_if_not_null(void* data) { |