<commit_before>/*
 * contacts-mixin.c - Source for TpContactsMixin
 * Copyright (C) 2008 Collabora Ltd.
 * Copyright (C) 2008 Nokia Corporation
 *   @author <NAME> <<EMAIL>>
 *
 * 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
 */

/**
 * SECTION:contacts-mixin
 * @title: TpContactsMixin
 * @short_description: a mixin implementation of the contacts connection
 * interface
 * @see_also: #TpSvcConnectionInterfaceContacts
 *
 * This mixin can be added to a #TpBaseConnection subclass to implement the
 * Contacts interface in a generic way.
 *
 * To use the contacts mixin, include a #TpContactsMixinClass somewhere in
 * your class structure and a #TpContactsMixin somewhere in your instance
 * structure, and call tp_contacts_mixin_class_init() from your class_init
 * function, tp_contacts_mixin_init() from your init function or constructor,
 * and tp_contacts_mixin_finalize() from your dispose or finalize function.
 *
 * To use the contacts mixin as the implementation of
 * #TpSvcConnectionInterfaceContacts, in the function you pass to
 * G_IMPLEMENT_INTERFACE, you should call tp_contacts_mixin_iface_init.
 * TpContactsMixin implements all of the D-Bus methods and properties in the
 * Contacts interface.
 *
 * To add interfaces with contact attributes to this interface use
 * tp_contacts_mixin_add_contact_attributes_iface:
 *
 * Since: 0.7.14
 *
 */

#include <telepathy-glib/contacts-mixin.h>

#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>

#include <telepathy-glib/base-connection.h>
#include <telepathy-glib/dbus.h>
#include <telepathy-glib/enums.h>
#include <telepathy-glib/errors.h>
#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/interfaces.h>

#define DEBUG_FLAG TP_DEBUG_CONNECTION

#include "debug-internal.h"

struct _TpContactsMixinPrivate
{
  /* String interface name -> FillContactAttributes func */
  GHashTable *interfaces;
};

enum {
  MIXIN_DP_CONTACT_ATTRIBUTE_INTERFACES,
  NUM_MIXIN_CONTACTS_DBUS_PROPERTIES
};

static TpDBusPropertiesMixinPropImpl known_contacts_props[] = {
  { "ContactAttributeInterfaces", NULL, NULL },
  { NULL }
};

static void
tp_presence_mixin_get_contacts_dbus_property (GObject *object,
                                              GQuark interface,
                                              GQuark name,
                                              GValue *value,
                                              gpointer unused
                                              G_GNUC_UNUSED)
{
  static GQuark q[NUM_MIXIN_CONTACTS_DBUS_PROPERTIES] = { 0, };
  TpContactsMixin *self = TP_CONTACTS_MIXIN (object);

  DEBUG ("called.");

  if (G_UNLIKELY (q[0] == 0))
    {
      q[MIXIN_DP_CONTACT_ATTRIBUTE_INTERFACES] =
        g_quark_from_static_string ("ContactAttributeInterfaces");
    }

  g_return_if_fail (object != NULL);

  if (name == q[MIXIN_DP_CONTACT_ATTRIBUTE_INTERFACES])
    {
      gchar **interfaces;
      GHashTableIter iter;
      gpointer key;
      int i = 0;

      g_assert (G_VALUE_HOLDS(value, G_TYPE_STRV));

      /* FIXME, cache this when connected ? */
      interfaces = g_malloc0(
        (g_hash_table_size (self->priv->interfaces) + 1) * sizeof (gchar *));

      g_hash_table_iter_init (&iter, self->priv->interfaces);
      while (g_hash_table_iter_next (&iter, &key, NULL))
          {
            interfaces[i] = g_strdup ((gchar *) key);
            i++;
          }
      g_value_take_boxed (value, interfaces);
    }
  else
    {
      g_assert_not_reached ();
    }
}


/**
 * tp_contacts_mixin_class_get_offset_quark:
 *
 * <!--no documentation beyond Returns: needed-->
 *
 * Returns: the quark used for storing mixin offset on a GObjectClass
 *
 * Since: 0.7.14
 *
 */
GQuark
tp_contacts_mixin_class_get_offset_quark ()
{
  static GQuark offset_quark = 0;

  if (G_UNLIKELY (offset_quark == 0))
    offset_quark = g_quark_from_static_string (
        "TpContactsMixinClassOffsetQuark");

  return offset_quark;
}

/**
 * tp_contacts_mixin_get_offset_quark:
 *
 * <!--no documentation beyond Returns: needed-->
 *
 * Returns: the quark used for storing mixin offset on a GObject
 *
 * Since: 0.7.14
 *
 */
GQuark
tp_contacts_mixin_get_offset_quark ()
{
  static GQuark offset_quark = 0;

  if (G_UNLIKELY (offset_quark == 0))
    offset_quark = g_quark_from_static_string ("TpContactsMixinOffsetQuark");

  return offset_quark;
}


/**
 * tp_contacts_mixin_class_init:
 * @obj_cls: The class of the implementation that uses this mixin
 * @offset: The byte offset of the TpContactsMixinClass within the class
 *          structure
 *
 * Initialize the contacts mixin. Should be called from the implementation's
 * class_init function like so:
 *
 * <informalexample><programlisting>
 * tp_contacts_mixin_class_init ((GObjectClass *) klass,
 *                          G_STRUCT_OFFSET (SomeObjectClass, contacts_mixin));
 * </programlisting></informalexample>
 *
 * Since: 0.7.14
 *
 */

void
tp_contacts_mixin_class_init (GObjectClass *obj_cls, glong offset)
{
  TpContactsMixinClass *mixin_cls;

  g_assert (G_IS_OBJECT_CLASS (obj_cls));

  g_type_set_qdata (G_OBJECT_CLASS_TYPE (obj_cls),
      TP_CONTACTS_MIXIN_CLASS_OFFSET_QUARK,
      GINT_TO_POINTER (offset));

  mixin_cls = TP_CONTACTS_MIXIN_CLASS (obj_cls);

  tp_dbus_properties_mixin_implement_interface (obj_cls,
      TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACTS,
      tp_presence_mixin_get_contacts_dbus_property,
      NULL, known_contacts_props);
}


/**
 * tp_contacts_mixin_init:
 * @obj: An instance of the implementation that uses this mixin
 * @offset: The byte offset of the TpContactsMixin within the object structure
 *
 * Initialize the contacts mixin. Should be called from the implementation's
 * instance init function like so:
 *
 * <informalexample><programlisting>
 * tp_contacts_mixin_init ((GObject *) self,
 *                     G_STRUCT_OFFSET (SomeObject, contacts_mixin));
 * </programlisting></informalexample>
 *
 * Since: 0.7.14
 *
 */
void
tp_contacts_mixin_init (GObject *obj, gsize offset)
{
  TpContactsMixin *mixin;
<commit_msg>Remove unused lookup of contacts mixin class.<commit_after>/*
 * contacts-mixin.c - Source for TpContactsMixin
 * Copyright (C) 2008 Collabora Ltd.
 * Copyright (C) 2008 Nokia Corporation
 *   @author <NAME> <<EMAIL>>
 *
 * 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
 */

/**
 * SECTION:contacts-mixin
 * @title: TpContactsMixin
 * @short_description: a mixin implementation of the contacts connection
 * interface
 * @see_also: #TpSvcConnectionInterfaceContacts
 *
 * This mixin can be added to a #TpBaseConnection subclass to implement the
 * Contacts interface in a generic way.
 *
 * To use the contacts mixin, include a #TpContactsMixinClass somewhere in
 * your class structure and a #TpContactsMixin somewhere in your instance
 * structure, and call tp_contacts_mixin_class_init() from your class_init
 * function, tp_contacts_mixin_init() from your init function or constructor,
 * and tp_contacts_mixin_finalize() from your dispose or finalize function.
 *
 * To use the contacts mixin as the implementation of
 * #TpSvcConnectionInterfaceContacts, in the function you pass to
 * G_IMPLEMENT_INTERFACE, you should call tp_contacts_mixin_iface_init.
 * TpContactsMixin implements all of the D-Bus methods and properties in the
 * Contacts interface.
 *
 * To add interfaces with contact attributes to this interface use
 * tp_contacts_mixin_add_contact_attributes_iface:
 *
 * Since: 0.7.14
 *
 */

#include <telepathy-glib/contacts-mixin.h>

#include <dbus/dbus-glib-lowlevel.h>
#include <dbus/dbus-glib.h>

#include <telepathy-glib/base-connection.h>
#include <telepathy-glib/dbus.h>
#include <telepathy-glib/enums.h>
#include <telepathy-glib/errors.h>
#include <telepathy-glib/gtypes.h>
#include <telepathy-glib/interfaces.h>

#define DEBUG_FLAG TP_DEBUG_CONNECTION

#include "debug-internal.h"

struct _TpContactsMixinPrivate
{
  /* String interface name -> FillContactAttributes func */
  GHashTable *interfaces;
};

enum {
  MIXIN_DP_CONTACT_ATTRIBUTE_INTERFACES,
  NUM_MIXIN_CONTACTS_DBUS_PROPERTIES
};

static TpDBusPropertiesMixinPropImpl known_contacts_props[] = {
  { "ContactAttributeInterfaces", NULL, NULL },
  { NULL }
};

static void
tp_presence_mixin_get_contacts_dbus_property (GObject *object,
                                              GQuark interface,
                                              GQuark name,
                                              GValue *value,
                                              gpointer unused
                                              G_GNUC_UNUSED)
{
  static GQuark q[NUM_MIXIN_CONTACTS_DBUS_PROPERTIES] = { 0, };
  TpContactsMixin *self = TP_CONTACTS_MIXIN (object);

  DEBUG ("called.");

  if (G_UNLIKELY (q[0] == 0))
    {
      q[MIXIN_DP_CONTACT_ATTRIBUTE_INTERFACES] =
        g_quark_from_static_string ("ContactAttributeInterfaces");
    }

  g_return_if_fail (object != NULL);

  if (name == q[MIXIN_DP_CONTACT_ATTRIBUTE_INTERFACES])
    {
      gchar **interfaces;
      GHashTableIter iter;
      gpointer key;
      int i = 0;

      g_assert (G_VALUE_HOLDS(value, G_TYPE_STRV));

      /* FIXME, cache this when connected ? */
      interfaces = g_malloc0(
        (g_hash_table_size (self->priv->interfaces) + 1) * sizeof (gchar *));

      g_hash_table_iter_init (&iter, self->priv->interfaces);
      while (g_hash_table_iter_next (&iter, &key, NULL))
          {
            interfaces[i] = g_strdup ((gchar *) key);
            i++;
          }
      g_value_take_boxed (value, interfaces);
    }
  else
    {
      g_assert_not_reached ();
    }
}


/**
 * tp_contacts_mixin_class_get_offset_quark:
 *
 * <!--no documentation beyond Returns: needed-->
 *
 * Returns: the quark used for storing mixin offset on a GObjectClass
 *
 * Since: 0.7.14
 *
 */
GQuark
tp_contacts_mixin_class_get_offset_quark ()
{
  static GQuark offset_quark = 0;

  if (G_UNLIKELY (offset_quark == 0))
    offset_quark = g_quark_from_static_string (
        "TpContactsMixinClassOffsetQuark");

  return offset_quark;
}

/**
 * tp_contacts_mixin_get_offset_quark:
 *
 * <!--no documentation beyond Returns: needed-->
 *
 * Returns: the quark used for storing mixin offset on a GObject
 *
 * Since: 0.7.14
 *
 */
GQuark
tp_contacts_mixin_get_offset_quark ()
{
  static GQuark offset_quark = 0;

  if (G_UNLIKELY (offset_quark == 0))
    offset_quark = g_quark_from_static_string ("TpContactsMixinOffsetQuark");

  return offset_quark;
}


/**
 * tp_contacts_mixin_class_init:
 * @obj_cls: The class of the implementation that uses this mixin
 * @offset: The byte offset of the TpContactsMixinClass within the class
 *          structure
 *
 * Initialize the contacts mixin. Should be called from the implementation's
 * class_init function like so:
 *
 * <informalexample><programlisting>
 * tp_contacts_mixin_class_init ((GObjectClass *) klass,
 *                          G_STRUCT_OFFSET (SomeObjectClass, contacts_mixin));
 * </programlisting></informalexample>
 *
 * Since: 0.7.14
 *
 */

void
tp_contacts_mixin_class_init (GObjectClass *obj_cls, glong offset)
{
  g_assert (G_IS_OBJECT_CLASS (obj_cls));

  g_type_set_qdata (G_OBJECT_CLASS_TYPE (obj_cls),
      TP_CONTACTS_MIXIN_CLASS_OFFSET_QUARK,
      GINT_TO_POINTER (offset));

  tp_dbus_properties_mixin_implement_interface (obj_cls,
      TP_IFACE_QUARK_CONNECTION_INTERFACE_CONTACTS,
      tp_presence_mixin_get_contacts_dbus_property,
      NULL, known_contacts_props);
}


/**
 * tp_contacts_mixin_init:
 * @obj: An instance of the implementation that uses this mixin
 * @offset: The byte offset of the TpContactsMixin within the object structure
 *
 * Initialize the contacts mixin. Should be called from the implementation's
 * instance init function like so:
 *
 * <informalexample><programlisting>
 * tp_contacts_mixin_init ((GObject *) self,
 *                     G_STRUCT_OFFSET (SomeObject, contacts_mixin));
 * </programlisting></informalexample>
 *
 * Since: 0.7.14
 *
 */
void
tp_contacts_mixin_init (GObject *obj, gsize offset)
{
  TpContactsMixin *mixin;

{'fraction_non_alphanumeric': 0.08659134829790396, 'fraction_numerical': 0.0075813884346662705, 'mean_word_length': 3.493987975951904, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 20, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6864982', 'n_tokens_mistral': 4470, 'n_tokens_neox': 4271, 'n_words': 1145}