[libsocialweb] lsw-client: Implements contacts



commit e3a345ec08fffdfb456b8780ab5ad2aeb4e83b0f
Author: Alban Crequy <alban crequy collabora co uk>
Date:   Fri Mar 25 11:24:44 2011 +0000

    lsw-client: Implements contacts

 libsocialweb-client/Makefile.am              |    9 +-
 libsocialweb-client/kludge.xsl               |   25 ++
 libsocialweb-client/sw-client-contact-view.c |  510 ++++++++++++++++++++++++++
 libsocialweb-client/sw-client-contact-view.h |   68 ++++
 libsocialweb-client/sw-contact.c             |  118 ++++++
 libsocialweb-client/sw-contact.h             |   52 +++
 6 files changed, 778 insertions(+), 4 deletions(-)
---
diff --git a/libsocialweb-client/Makefile.am b/libsocialweb-client/Makefile.am
index b7952f3..ed19af4 100644
--- a/libsocialweb-client/Makefile.am
+++ b/libsocialweb-client/Makefile.am
@@ -8,14 +8,15 @@ libsocialweb_client_la_CFLAGS = -I$(top_srcdir) $(DBUS_GLIB_CFLAGS) $(GIO_CFLAGS
 libsocialweb_client_la_LIBADD = $(DBUS_GLIB_LIBS) $(GIO_LIBS) $(top_builddir)/interfaces/libsocialweb-bindings.la
 libsocialweb_client_la_LDFLAGS = -version-info $(LIBSOCIALWEB_CLIENT_CURRENT):$(LIBSOCIALWEB_CLIENT_REVISION):$(LIBSOCIALWEB_CLIENT_AGE)
 HANDWRITTED_H_SOURCES = sw-client.h \
-			      sw-item.h sw-client-service.h \
-			      sw-client-lastfm.h sw-client-item-view.h
+			      sw-item.h sw-contact.h sw-client-service.h \
+			      sw-client-lastfm.h \
+			      sw-client-item-view.h sw-client-contact-view.h
 libsocialweb_client_la_HEADERS = $(HANDWRITTED_H_SOURCES)
 nodist_libsocialweb_client_la_HEADERS =
 HANDWRITTED_C_SOURCES = sw-client.c \
-			      sw-item.c sw-client-service.c \
+			      sw-item.c sw-contact.c sw-client-service.c \
 			      sw-client-lastfm.c \
-			      sw-client-item-view.c
+			      sw-client-item-view.c sw-client-contact-view.c
 PRIVATE_H_SOURCES = sw-client-service-private.h
 libsocialweb_client_la_SOURCES = $(HANDWRITTED_C_SOURCES) \
 			      $(PRIVATE_H_SOURCES) \
diff --git a/libsocialweb-client/kludge.xsl b/libsocialweb-client/kludge.xsl
index 25a4025..565e25c 100644
--- a/libsocialweb-client/kludge.xsl
+++ b/libsocialweb-client/kludge.xsl
@@ -27,6 +27,22 @@
     </glib:signal>
   </xsl:template>
 
+  <xsl:template match="glib:signal[ name='contacts-added' or
+    @name='contacts-changed' or @name='contacts-removed']">
+    <glib:signal name="{ name}">
+      <return-value transfer-ownership="none">
+        <type name="none"/>
+      </return-value>
+      <parameters>
+        <parameter name="contacts" transfer-ownership="none">
+          <type name="GLib.List" c:type="GList*">
+            <type name="SocialWebClient.Contact" c:type="SwContact*"/>
+          </type>
+        </parameter>
+      </parameters>
+    </glib:signal>
+  </xsl:template>
+
   <xsl:template match="gi:record[ name='Item']/gi:field[ name='props']">
     <field name="props" writable="1">
       <type name="GLib.HashTable" c:type="GHashTable*">
@@ -36,4 +52,13 @@
     </field>
   </xsl:template>
 
+  <xsl:template match="gi:record[ name='Contact']/gi:field[ name='props']">
+    <field name="props" writable="1">
+      <type name="GLib.HashTable" c:type="GHashTable*">
+        <type name="utf8"/>
+        <type name="utf8"/>
+      </type>
+    </field>
+  </xsl:template>
+
 </xsl:stylesheet>
diff --git a/libsocialweb-client/sw-client-contact-view.c b/libsocialweb-client/sw-client-contact-view.c
new file mode 100644
index 0000000..8df2da2
--- /dev/null
+++ b/libsocialweb-client/sw-client-contact-view.c
@@ -0,0 +1,510 @@
+/*
+ * libsocialweb - social data store
+ * Copyright (C) 2008 - 2009 Intel Corporation.
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <dbus/dbus-glib.h>
+#include <dbus/dbus-glib-lowlevel.h>
+
+#include "sw-client-contact-view.h"
+
+#include <interfaces/sw-contact-view-bindings.h>
+#include <interfaces/sw-marshals.h>
+
+G_DEFINE_TYPE (SwClientContactView, sw_client_contact_view, G_TYPE_OBJECT)
+
+#define GET_PRIVATE(o) \
+  (G_TYPE_INSTANCE_GET_PRIVATE ((o), SW_TYPE_CLIENT_CONTACT_VIEW, SwClientContactViewPrivate))
+
+typedef struct _SwClientContactViewPrivate SwClientContactViewPrivate;
+
+struct _SwClientContactViewPrivate {
+    gchar *object_path;
+    DBusGConnection *connection;
+    DBusGProxy *proxy;
+    GHashTable *uuid_to_contacts;
+};
+
+enum
+{
+  PROP_0,
+  PROP_OBJECT_PATH
+};
+
+enum
+{
+  CONTACTS_ADDED_SIGNAL,
+  CONTACTS_CHANGED_SIGNAL,
+  CONTACTS_REMOVED_SIGNAL,
+
+  LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+#define SW_SERVICE_NAME "com.meego.libsocialweb"
+#define SW_SERVICE_CONTACT_VIEW_INTERFACE "com.meego.libsocialweb.ContactView"
+
+static void
+sw_client_contact_view_get_property (GObject *object, guint property_id,
+                              GValue *value, GParamSpec *pspec)
+{
+  SwClientContactViewPrivate *priv = GET_PRIVATE (object);
+
+  switch (property_id) {
+    case PROP_OBJECT_PATH:
+      g_value_set_string (value, priv->object_path);
+      break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+  }
+}
+
+static void
+sw_client_contact_view_set_property (GObject *object, guint property_id,
+                              const GValue *value, GParamSpec *pspec)
+{
+  SwClientContactViewPrivate *priv = GET_PRIVATE (object);
+
+  switch (property_id) {
+    case PROP_OBJECT_PATH:
+      priv->object_path = g_value_dup_string (value);
+      break;
+  default:
+    G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+  }
+}
+
+static void
+sw_client_contact_view_dispose (GObject *object)
+{
+  SwClientContactViewPrivate *priv = GET_PRIVATE (object);
+
+  if (priv->connection)
+  {
+    dbus_g_connection_unref (priv->connection);
+    priv->connection = NULL;
+  }
+
+  if (priv->proxy)
+  {
+    g_object_unref (priv->proxy);
+    priv->proxy = NULL;
+  }
+
+  if (priv->uuid_to_contacts)
+  {
+    g_hash_table_unref (priv->uuid_to_contacts);
+    priv->uuid_to_contacts = NULL;
+  }
+
+  G_OBJECT_CLASS (sw_client_contact_view_parent_class)->dispose (object);
+}
+
+static void
+sw_client_contact_view_finalize (GObject *object)
+{
+  SwClientContactViewPrivate *priv = GET_PRIVATE (object);
+
+  g_free (priv->object_path);
+
+  G_OBJECT_CLASS (sw_client_contact_view_parent_class)->finalize (object);
+}
+
+static void
+_sw_contact_update_from_value_array (SwContact      *contact,
+                                  GValueArray *varray)
+{
+  if (contact->service)
+  {
+    g_free (contact->service);
+    contact->service = NULL;
+  }
+
+  contact->service = g_value_dup_string (g_value_array_get_nth (varray, 0));
+
+  if (contact->uuid)
+  {
+    g_free (contact->uuid);
+    contact->uuid = NULL;
+  }
+
+  contact->uuid = g_value_dup_string (g_value_array_get_nth (varray, 1));
+
+  contact->date.tv_sec = g_value_get_int64 (g_value_array_get_nth (varray, 2));
+
+  if (contact->props)
+  {
+    g_hash_table_unref (contact->props);
+    contact->props = NULL;
+  }
+
+  contact->props = g_value_dup_boxed (g_value_array_get_nth (varray, 3));
+}
+
+static SwContact *
+_sw_contact_from_value_array (GValueArray *varray)
+{
+  SwContact *contact;
+
+  contact = sw_contact_new ();
+  _sw_contact_update_from_value_array (contact, varray);
+
+  return contact;
+}
+
+static void
+_proxy_contacts_added_cb (DBusGProxy *proxy,
+                          GPtrArray  *contacts,
+                          gpointer    userdata)
+{
+  SwClientContactView *view = SW_CLIENT_CONTACT_VIEW (userdata);
+  SwClientContactViewPrivate *priv = GET_PRIVATE (view);
+  gint i = 0;
+  GList *contacts_list = NULL;
+
+  for (i = 0; i < contacts->len; i++)
+  {
+    GValueArray *varray = (GValueArray *)g_ptr_array_index (contacts, i);
+    SwContact *contact;
+
+    /* First reference dropped when list freed */
+    contact = _sw_contact_from_value_array (varray);
+
+    g_hash_table_insert (priv->uuid_to_contacts,
+                         g_strdup (contact->uuid),
+                         sw_contact_ref (contact));
+
+    contacts_list = g_list_append (contacts_list, contact);
+  }
+
+  /* If handler wants a ref then it should ref it up */
+  g_signal_emit (view, signals[CONTACTS_ADDED_SIGNAL], 0, contacts_list);
+
+  g_list_foreach (contacts_list, (GFunc)sw_contact_unref, NULL);
+  g_list_free (contacts_list);
+}
+
+static void
+_proxy_contacts_changed_cb (DBusGProxy *proxy,
+                            GPtrArray  *contacts,
+                            gpointer    userdata)
+{
+  SwClientContactView *view = SW_CLIENT_CONTACT_VIEW (userdata);
+  SwClientContactViewPrivate *priv = GET_PRIVATE (view);
+  gint i = 0;
+  GList *contacts_list = NULL;
+
+  for (i = 0; i < contacts->len; i++)
+  {
+    GValueArray *varray = (GValueArray *)g_ptr_array_index (contacts, i);
+    SwContact *contact;
+    const gchar *uid;
+
+    uid = g_value_get_string (g_value_array_get_nth (varray, 1));
+
+    contact = g_hash_table_lookup (priv->uuid_to_contacts,
+                                uid);
+
+    if (contact)
+    {
+      _sw_contact_update_from_value_array (contact, varray);
+      contacts_list = g_list_append (contacts_list, sw_contact_ref (contact));
+    } else {
+      g_critical (G_STRLOC ": Contact changed before added: %s", uid);
+    }
+  }
+
+  /* If handler wants a ref then it should ref it up */
+  g_signal_emit (view, signals[CONTACTS_CHANGED_SIGNAL], 0, contacts_list);
+
+  g_list_foreach (contacts_list, (GFunc)sw_contact_unref, NULL);
+  g_list_free (contacts_list);
+}
+
+static void
+_proxy_contacts_removed_cb (DBusGProxy *proxy,
+                            GPtrArray  *contacts,
+                            gpointer    userdata)
+{
+  SwClientContactView *view = SW_CLIENT_CONTACT_VIEW (userdata);
+  SwClientContactViewPrivate *priv = GET_PRIVATE (view);
+  gint i = 0;
+  GList *contacts_list = NULL;
+
+  for (i = 0; i < contacts->len; i++)
+  {
+    GValueArray *varray = (GValueArray *)g_ptr_array_index (contacts, i);
+    const gchar *uid;
+    SwContact *contact;
+
+    uid = g_value_get_string (g_value_array_get_nth (varray, 1));
+
+    contact = g_hash_table_lookup (priv->uuid_to_contacts,
+                                uid);
+
+    if (contact)
+    {
+      /* Must ref up because g_hash_table_remove drops ref */
+      contacts_list = g_list_append (contacts_list, sw_contact_ref (contact));
+      g_hash_table_remove (priv->uuid_to_contacts, uid);
+    }
+  }
+
+  /* If handler wants a ref then it should ref it up */
+  g_signal_emit (view, signals[CONTACTS_REMOVED_SIGNAL], 0, contacts_list);
+
+  g_list_foreach (contacts_list, (GFunc)sw_contact_unref, NULL);
+  g_list_free (contacts_list);
+}
+
+static GType
+_sw_contacts_get_container_type (void)
+{
+ return dbus_g_type_get_collection ("GPtrArray",
+     dbus_g_type_get_struct ("GValueArray",
+         G_TYPE_STRING,
+         G_TYPE_STRING,
+         G_TYPE_INT64,
+         dbus_g_type_get_map ("GHashTable",
+             G_TYPE_STRING, G_TYPE_STRV),
+         G_TYPE_INVALID));
+}
+
+static GType
+_sw_contacts_removed_get_container_type (void)
+{
+  return dbus_g_type_get_collection ("GPtrArray",
+      dbus_g_type_get_struct ("GValueArray",
+          G_TYPE_STRING,
+          G_TYPE_STRV,
+          G_TYPE_INVALID));
+}
+
+static void
+sw_client_contact_view_constructed (GObject *object)
+{
+  SwClientContactViewPrivate *priv = GET_PRIVATE (object);
+  GError *error = NULL;
+  DBusConnection *conn;
+
+  priv->connection = dbus_g_bus_get (DBUS_BUS_STARTER, &error);
+
+  if (!priv->connection)
+  {
+    g_critical (G_STRLOC ": Error getting DBUS connection: %s",
+                error->message);
+    g_clear_error (&error);
+    return;
+  }
+
+  conn = dbus_g_connection_get_connection (priv->connection);
+
+  priv->proxy = dbus_g_proxy_new_for_name_owner (priv->connection,
+                                                 SW_SERVICE_NAME,
+                                                 priv->object_path,
+                                                 SW_SERVICE_CONTACT_VIEW_INTERFACE,
+                                                 &error);
+
+  if (!priv->proxy)
+  {
+    g_critical (G_STRLOC ": Error setting up proxy for remote object: %s",
+                error->message);
+    g_clear_error (&error);
+    return;
+  }
+
+  dbus_g_proxy_add_signal (priv->proxy,
+                           "ContactsAdded",
+                           _sw_contacts_get_container_type (),
+                           NULL);
+  dbus_g_proxy_connect_signal (priv->proxy,
+                               "ContactsAdded",
+                               (GCallback)_proxy_contacts_added_cb,
+                               object,
+                               NULL);
+
+  dbus_g_proxy_add_signal (priv->proxy,
+                           "ContactsChanged",
+                           _sw_contacts_get_container_type (),
+                           NULL);
+  dbus_g_proxy_connect_signal (priv->proxy,
+                               "ContactsChanged",
+                               (GCallback)_proxy_contacts_changed_cb,
+                               object,
+                               NULL);
+
+  dbus_g_proxy_add_signal (priv->proxy,
+                           "ContactsRemoved",
+                           _sw_contacts_removed_get_container_type (),
+                           NULL);
+  dbus_g_proxy_connect_signal (priv->proxy,
+                               "ContactsRemoved",
+                               (GCallback)_proxy_contacts_removed_cb,
+                               object,
+                               NULL);
+
+}
+
+static void
+sw_client_contact_view_class_init (SwClientContactViewClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GParamSpec *pspec;
+
+  g_type_class_add_private (klass, sizeof (SwClientContactViewPrivate));
+
+  object_class->get_property = sw_client_contact_view_get_property;
+  object_class->set_property = sw_client_contact_view_set_property;
+  object_class->dispose = sw_client_contact_view_dispose;
+  object_class->finalize = sw_client_contact_view_finalize;
+  object_class->constructed = sw_client_contact_view_constructed;
+
+  pspec = g_param_spec_string ("object-path",
+                               "Object path",
+                               "DBUS path to the contact_view's object",
+                               NULL,
+                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY);
+  g_object_class_install_property (object_class, PROP_OBJECT_PATH, pspec);
+
+  /**
+   * SwClientContactView::contacts-added:
+   * @self:
+   * @contacts: (type GLib.List) (element-type Sw.Contact):
+   */
+  signals[CONTACTS_ADDED_SIGNAL] =
+    g_signal_new ("contacts-added",
+                  SW_TYPE_CLIENT_CONTACT_VIEW,
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (SwClientContactViewClass, contacts_added),
+                  NULL,
+                  NULL,
+                  sw_marshal_VOID__POINTER,
+                  G_TYPE_NONE,
+                  1,
+                  G_TYPE_POINTER);
+
+  /**
+   * SwClientContactView::contacts-removed:
+   * @self:
+   * @contacts: (type GLib.List) (element-type Sw.Contact):
+   */
+  signals[CONTACTS_REMOVED_SIGNAL] =
+    g_signal_new ("contacts-removed",
+                  SW_TYPE_CLIENT_CONTACT_VIEW,
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (SwClientContactViewClass, contacts_removed),
+                  NULL,
+                  NULL,
+                  sw_marshal_VOID__POINTER,
+                  G_TYPE_NONE,
+                  1,
+                  G_TYPE_POINTER);
+
+  /**
+   * SwClientContactView::contacts-changed:
+   * @self:
+   * @contacts: (type GLib.List) (element-type Sw.Contact):
+   */
+  signals[CONTACTS_CHANGED_SIGNAL] =
+    g_signal_new ("contacts-changed",
+                  SW_TYPE_CLIENT_CONTACT_VIEW,
+                  G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (SwClientContactViewClass, contacts_changed),
+                  NULL,
+                  NULL,
+                  sw_marshal_VOID__POINTER,
+                  G_TYPE_NONE,
+                  1,
+                  G_TYPE_POINTER);
+
+}
+
+static void
+sw_client_contact_view_init (SwClientContactView *self)
+{
+  SwClientContactViewPrivate *priv = GET_PRIVATE (self);
+
+
+  priv->uuid_to_contacts = g_hash_table_new_full (g_str_hash,
+                                               g_str_equal,
+                                               g_free,
+                                               (GDestroyNotify)sw_contact_unref);
+}
+
+SwClientContactView *
+_sw_client_contact_view_new_for_path (const gchar *contact_view_path)
+{
+  return g_object_new (SW_TYPE_CLIENT_CONTACT_VIEW,
+                       "object-path", contact_view_path,
+                       NULL);
+}
+
+/* This is to avoid multiple almost identical callbacks */
+static void
+_sw_client_contact_view_generic_cb (DBusGProxy *proxy,
+                                 GError     *error,
+                                 gpointer    userdata)
+{
+  if (error)
+  {
+    g_warning (G_STRLOC ": Error when calling %s: %s",
+               (const gchar *)userdata,
+               error->message);
+    g_error_free (error);
+  }
+}
+
+void
+sw_client_contact_view_start (SwClientContactView *contact_view)
+{
+  SwClientContactViewPrivate *priv = GET_PRIVATE (contact_view);
+
+  com_meego_libsocialweb_ContactView_start_async (priv->proxy,
+                                               _sw_client_contact_view_generic_cb,
+                                               (gpointer)G_STRFUNC);
+}
+
+void
+sw_client_contact_view_refresh (SwClientContactView *contact_view)
+{
+  SwClientContactViewPrivate *priv = GET_PRIVATE (contact_view);
+
+  com_meego_libsocialweb_ContactView_refresh_async (priv->proxy,
+                                                 _sw_client_contact_view_generic_cb,
+                                                 (gpointer)G_STRFUNC);
+}
+
+void
+sw_client_contact_view_stop (SwClientContactView *contact_view)
+{
+  SwClientContactViewPrivate *priv = GET_PRIVATE (contact_view);
+
+  com_meego_libsocialweb_ContactView_stop_async (priv->proxy,
+                                              _sw_client_contact_view_generic_cb,
+                                              (gpointer)G_STRFUNC);
+}
+
+void
+sw_client_contact_view_close (SwClientContactView *contact_view)
+{
+  SwClientContactViewPrivate *priv = GET_PRIVATE (contact_view);
+
+  com_meego_libsocialweb_ContactView_close_async (priv->proxy,
+                                              _sw_client_contact_view_generic_cb,
+                                              (gpointer)G_STRFUNC);
+}
diff --git a/libsocialweb-client/sw-client-contact-view.h b/libsocialweb-client/sw-client-contact-view.h
new file mode 100644
index 0000000..389bd16
--- /dev/null
+++ b/libsocialweb-client/sw-client-contact-view.h
@@ -0,0 +1,68 @@
+/*
+ * libsocialweb - social data store
+ * Copyright (C) 2008 - 2009 Intel Corporation.
+ * Copyright (C) 2011 Collabora Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _SW_CLIENT_CONTACT_VIEW
+#define _SW_CLIENT_CONTACT_VIEW
+
+#include <glib-object.h>
+
+#include <libsocialweb-client/sw-contact.h>
+
+G_BEGIN_DECLS
+
+#define SW_TYPE_CLIENT_CONTACT_VIEW sw_client_contact_view_get_type()
+
+#define SW_CLIENT_CONTACT_VIEW(obj) \
+  (G_TYPE_CHECK_INSTANCE_CAST ((obj), SW_TYPE_CLIENT_CONTACT_VIEW, SwClientContactView))
+
+#define SW_CLIENT_CONTACT_VIEW_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_CAST ((klass), SW_TYPE_CLIENT_CONTACT_VIEW, SwClientContactViewClass))
+
+#define SW_IS_CLIENT_CONTACT_VIEW(obj) \
+  (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SW_TYPE_CLIENT_CONTACT_VIEW))
+
+#define SW_IS_CLIENT_CONTACT_VIEW_CLASS(klass) \
+  (G_TYPE_CHECK_CLASS_TYPE ((klass), SW_TYPE_CLIENT_CONTACT_VIEW))
+
+#define SW_CLIENT_CONTACT_VIEW_GET_CLASS(obj) \
+  (G_TYPE_INSTANCE_GET_CLASS ((obj), SW_TYPE_CLIENT_CONTACT_VIEW, SwClientContactViewClass))
+
+typedef struct {
+  GObject parent;
+} SwClientContactView;
+
+typedef struct {
+  GObjectClass parent_class;
+  void (*contacts_added)(SwClientContactView *contact_view, GList *contacts);
+  void (*contacts_removed)(SwClientContactView *contact_view, GList *contacts);
+  void (*contacts_changed)(SwClientContactView *contact_view, GList *contacts);
+} SwClientContactViewClass;
+
+GType sw_client_contact_view_get_type (void);
+
+SwClientContactView *_sw_client_contact_view_new_for_path (const gchar *contact_view_path);
+void sw_client_contact_view_start (SwClientContactView *contact_view);
+void sw_client_contact_view_refresh (SwClientContactView *contact_view);
+void sw_client_contact_view_stop (SwClientContactView *contact_view);
+void sw_client_contact_view_close (SwClientContactView *contact_view);
+
+G_END_DECLS
+
+#endif /* _SW_CLIENT_CONTACT_VIEW */
+
diff --git a/libsocialweb-client/sw-contact.c b/libsocialweb-client/sw-contact.c
new file mode 100644
index 0000000..efefb37
--- /dev/null
+++ b/libsocialweb-client/sw-contact.c
@@ -0,0 +1,118 @@
+/*
+ * libsocialweb - social data store
+ * Copyright (C) 2008 - 2009 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include "sw-contact.h"
+
+/**
+ * SwContact:
+ * @refcount:
+ * @service:
+ * @uuid:
+ * @date:
+ * @props: (element-type gchar* gchar*):
+ */
+
+SwContact *
+sw_contact_new (void)
+{
+  SwContact *contact;
+
+  contact = g_slice_new0 (SwContact);
+  contact->refcount = 1;
+
+  return contact;
+}
+
+void
+sw_contact_free (SwContact *contact)
+{
+  g_free (contact->service);
+  g_free (contact->uuid);
+
+  if (contact->props)
+    g_hash_table_unref (contact->props);
+
+  g_slice_free (SwContact, contact);
+}
+
+SwContact *
+sw_contact_ref (SwContact *contact)
+{
+  g_atomic_int_inc (&(contact->refcount));
+  return contact;
+}
+
+void
+sw_contact_unref (SwContact *contact)
+{
+  if (g_atomic_int_dec_and_test (&(contact->refcount)))
+  {
+    sw_contact_free (contact);
+  }
+}
+
+GType
+sw_contact_get_type (void)
+{
+  static GType type = 0;
+
+  if (G_UNLIKELY (type == 0))
+  {
+    type = g_boxed_type_register_static ("SwContact",
+                                         (GBoxedCopyFunc)sw_contact_ref,
+                                         (GBoxedFreeFunc)sw_contact_unref);
+  }
+
+  return type;
+}
+
+gboolean
+sw_contact_is_from_cache (SwContact *contact)
+{
+  return g_hash_table_lookup (contact->props, "cached") != NULL;
+}
+
+gboolean
+sw_contact_has_key (SwContact  *contact,
+                     const gchar *key)
+{
+  return (g_hash_table_lookup (contact->props, key) != NULL);
+}
+
+const gchar *
+sw_contact_get_value (SwContact  *contact,
+                       const gchar *key)
+{
+  GStrv str_array = g_hash_table_lookup (contact->props, key);
+  return str_array ? str_array[0] : NULL;
+}
+
+/**
+ * sw_contact_get_value_all: 
+ *
+ * @contact: :
+ * @key: :
+ *
+ * Returns: (transfer none) (array zero-terminated=1) (element-type char*): 
+ */
+const GStrv
+sw_contact_get_value_all (SwContact  *contact,
+                       const gchar *key)
+{
+  return g_hash_table_lookup (contact->props, key);
+}
diff --git a/libsocialweb-client/sw-contact.h b/libsocialweb-client/sw-contact.h
new file mode 100644
index 0000000..86e15c4
--- /dev/null
+++ b/libsocialweb-client/sw-contact.h
@@ -0,0 +1,52 @@
+/*
+ * libsocialweb - social data store
+ * Copyright (C) 2008 - 2009 Intel Corporation.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU Lesser General Public License,
+ * version 2.1, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope 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 program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _SW_CONTACT
+#define _SW_CONTACT
+
+#define SW_TYPE_CONTACT (sw_contact_get_type())
+
+#include <glib-object.h>
+
+G_BEGIN_DECLS
+
+typedef struct {
+  volatile gint refcount;
+  gchar *service;
+  gchar *uuid;
+  GTimeVal date;
+  GHashTable *props;
+} SwContact;
+
+void sw_contact_unref (SwContact *contact);
+SwContact *sw_contact_ref (SwContact *contact);
+void sw_contact_free (SwContact *contact);
+SwContact *sw_contact_new (void);
+
+gboolean sw_contact_is_from_cache (SwContact *contact);
+gboolean sw_contact_has_key (SwContact  *contact,
+                              const gchar *key);
+const gchar *sw_contact_get_value (SwContact  *contact,
+                                    const gchar *key);
+const GStrv sw_contact_get_value_all (SwContact  *contact,
+                                    const gchar *key);
+
+GType sw_contact_get_type (void);
+
+G_END_DECLS
+#endif



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]