<commit_before>/*
 * channel.c - proxy for a Telepathy channel
 *
 * Copyright (C) 2007 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
 */

#include "telepathy-glib/channel.h"

#include <telepathy-glib/channel-iface.h>
#include <telepathy-glib/handle.h>
#include <telepathy-glib/interfaces.h>

#include "_gen/signals-marshal.h"

#define DEBUG_FLAG TP_DEBUG_CHANNEL
#include "debug-internal.h"

#include "_gen/tp-cli-channel-body.h"

/**
 * SECTION:channel
 * @title: TpChannel
 * @short_description: proxy object for a Telepathy channel
 * @see_also: #TpConnection
 *
 * #TpChannel objects provide convenient access to Telepathy channels.
 *
 * Since: 0.7.1
 */

/**
 * TpChannelClass:
 *
 * The class of a #TpChannel.
 */
struct _TpChannelClass {
    TpProxyClass parent_class;
    /*<private>*/
};

/**
 * TpChannel:
 *
 * A proxy object for a Telepathy channel.
 */
struct _TpChannel {
    TpProxy parent;
    /*<private>*/
    GQuark channel_type;
    TpHandleType handle_type;
    TpHandle handle;
};

enum
{
  PROP_CHANNEL_TYPE = 1,
  PROP_HANDLE_TYPE,
  PROP_HANDLE,
  N_PROPS
};

G_DEFINE_TYPE_WITH_CODE (TpChannel,
    tp_channel,
    TP_TYPE_PROXY,
    G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL));

enum {
    SIGNAL_CHANNEL_READY,
    N_SIGNALS
};

static guint signals[N_SIGNALS] = {0};

static void
tp_channel_get_property (GObject *object,
                         guint property_id,
                         GValue *value,
                         GParamSpec *pspec)
{
  TpChannel *self = TP_CHANNEL (object);

  switch (property_id)
    {
    case PROP_CHANNEL_TYPE:
      g_value_set_static_string (value,
          g_quark_to_string (self->channel_type));
      break;
    case PROP_HANDLE_TYPE:
      g_value_set_uint (value, self->handle_type);
      break;
    case PROP_HANDLE:
      g_value_set_uint (value, self->handle);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

static void
tp_channel_set_property (GObject *object,
                         guint property_id,
                         const GValue *value,
                         GParamSpec *pspec)
{
  TpChannel *self = TP_CHANNEL (object);

  switch (property_id)
    {
    case PROP_CHANNEL_TYPE:
      /* can only be set in constructor */
      g_assert (self->channel_type == 0);
      self->channel_type = g_quark_from_string (g_value_get_string (value));
      break;
    case PROP_HANDLE_TYPE:
      self->handle_type = g_value_get_uint (value);
      break;
    case PROP_HANDLE:
      self->handle = g_value_get_uint (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

static void
tp_channel_got_interfaces_cb (TpProxy *proxy,
                              const gchar **interfaces,
                              const GError *error,
                              gpointer unused)
{
  TpChannel *self = TP_CHANNEL (proxy);

  if (error == NULL)
    {
      DEBUG ("%p: Introspected interfaces", self);
      if (interfaces != NULL)
        {
          const gchar **iter;

          for (iter = interfaces; *iter != NULL; iter++)
            {
              DEBUG ("\t- %s", *iter);

              if (tp_dbus_check_valid_interface_name (*iter, NULL))
                {
                  tp_proxy_add_interface_by_id ((TpProxy *) self,
                      g_quark_from_string (*iter));
                }
              else
                {
                  DEBUG ("\t\tInterface %s not valid", *iter);
                }
            }
        }

      DEBUG ("%p: emitting channel-ready", self);
      g_signal_emit (self, signals[SIGNAL_CHANNEL_READY], 0,
          g_quark_to_string (self->channel_type), self->handle_type,
          self->handle, interfaces);
    }
  else
    {
      DEBUG ("%p: GetInterfaces() failed", self);
      tp_proxy_invalidated ((TpProxy *) self, error);
    }
}

static void
tp_channel_got_channel_type_cb (TpProxy *proxy,
                                const gchar *channel_type,
                                const GError *error,
                                gpointer unused)
{
  TpChannel *self = TP_CHANNEL (proxy);

  if (error == NULL)
    {
      DEBUG ("%p: Introspected channel type %s", self, channel_type);
      self->channel_type = g_quark_from_string (channel_type);
    }
  else
    {
      DEBUG ("%p: GetChannelType() failed, will self-destruct", self);
      tp_proxy_invalidated ((TpProxy *) self, error);
      return;
    }

  g_assert (self->channel_type != 0);
  tp_proxy_add_interface_by_id ((TpProxy *) self, self->channel_type);

  tp_cli_channel_call_get_interfaces (self, -1,
      tp_channel_got_interfaces_cb, NULL, NULL, NULL);
}

static void
tp_channel_got_handle_cb (TpProxy *proxy,
                          guint handle_type,
                          guint handle,
                          const GError *error,
                          gpointer unused)
{
  TpChannel *self = TP_CHANNEL (proxy);

  if (error == NULL)
    {
      DEBUG ("%p: Introspected handle #%d of type %d", self, handle,
          handle_type);
      self->handle_type = handle_type;<commit_msg>Invalidate TpChannel objects if their channel type is invalid<commit_after>/*
 * channel.c - proxy for a Telepathy channel
 *
 * Copyright (C) 2007 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
 */

#include "telepathy-glib/channel.h"

#include <telepathy-glib/channel-iface.h>
#include <telepathy-glib/handle.h>
#include <telepathy-glib/interfaces.h>

#include "_gen/signals-marshal.h"

#define DEBUG_FLAG TP_DEBUG_CHANNEL
#include "debug-internal.h"

#include "_gen/tp-cli-channel-body.h"

/**
 * SECTION:channel
 * @title: TpChannel
 * @short_description: proxy object for a Telepathy channel
 * @see_also: #TpConnection
 *
 * #TpChannel objects provide convenient access to Telepathy channels.
 *
 * Since: 0.7.1
 */

/**
 * TpChannelClass:
 *
 * The class of a #TpChannel.
 */
struct _TpChannelClass {
    TpProxyClass parent_class;
    /*<private>*/
};

/**
 * TpChannel:
 *
 * A proxy object for a Telepathy channel.
 */
struct _TpChannel {
    TpProxy parent;
    /*<private>*/
    GQuark channel_type;
    TpHandleType handle_type;
    TpHandle handle;
};

enum
{
  PROP_CHANNEL_TYPE = 1,
  PROP_HANDLE_TYPE,
  PROP_HANDLE,
  N_PROPS
};

G_DEFINE_TYPE_WITH_CODE (TpChannel,
    tp_channel,
    TP_TYPE_PROXY,
    G_IMPLEMENT_INTERFACE (TP_TYPE_CHANNEL_IFACE, NULL));

enum {
    SIGNAL_CHANNEL_READY,
    N_SIGNALS
};

static guint signals[N_SIGNALS] = {0};

static void
tp_channel_get_property (GObject *object,
                         guint property_id,
                         GValue *value,
                         GParamSpec *pspec)
{
  TpChannel *self = TP_CHANNEL (object);

  switch (property_id)
    {
    case PROP_CHANNEL_TYPE:
      g_value_set_static_string (value,
          g_quark_to_string (self->channel_type));
      break;
    case PROP_HANDLE_TYPE:
      g_value_set_uint (value, self->handle_type);
      break;
    case PROP_HANDLE:
      g_value_set_uint (value, self->handle);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

static void
tp_channel_set_property (GObject *object,
                         guint property_id,
                         const GValue *value,
                         GParamSpec *pspec)
{
  TpChannel *self = TP_CHANNEL (object);

  switch (property_id)
    {
    case PROP_CHANNEL_TYPE:
      /* can only be set in constructor */
      g_assert (self->channel_type == 0);
      self->channel_type = g_quark_from_string (g_value_get_string (value));
      break;
    case PROP_HANDLE_TYPE:
      self->handle_type = g_value_get_uint (value);
      break;
    case PROP_HANDLE:
      self->handle = g_value_get_uint (value);
      break;
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
      break;
  }
}

static void
tp_channel_got_interfaces_cb (TpProxy *proxy,
                              const gchar **interfaces,
                              const GError *error,
                              gpointer unused)
{
  TpChannel *self = TP_CHANNEL (proxy);

  if (error == NULL)
    {
      DEBUG ("%p: Introspected interfaces", self);
      if (interfaces != NULL)
        {
          const gchar **iter;

          for (iter = interfaces; *iter != NULL; iter++)
            {
              DEBUG ("\t- %s", *iter);

              if (tp_dbus_check_valid_interface_name (*iter, NULL))
                {
                  tp_proxy_add_interface_by_id ((TpProxy *) self,
                      g_quark_from_string (*iter));
                }
              else
                {
                  DEBUG ("\t\tInterface %s not valid", *iter);
                }
            }
        }

      DEBUG ("%p: emitting channel-ready", self);
      g_signal_emit (self, signals[SIGNAL_CHANNEL_READY], 0,
          g_quark_to_string (self->channel_type), self->handle_type,
          self->handle, interfaces);
    }
  else
    {
      DEBUG ("%p: GetInterfaces() failed", self);
      tp_proxy_invalidated ((TpProxy *) self, error);
    }
}

static void
tp_channel_got_channel_type_cb (TpProxy *proxy,
                                const gchar *channel_type,
                                const GError *error,
                                gpointer unused)
{
  TpChannel *self = TP_CHANNEL (proxy);

  if (error == NULL)
    {
      DEBUG ("%p: Introspected channel type %s", self, channel_type);
      GError *err2 = NULL;

      if (tp_dbus_check_valid_interface_name (channel_type, &err2))
        {
          self->channel_type = g_quark_from_string (channel_type);
        }
      else
        {
          DEBUG ("\t\tChannel type %s not valid: %s", *iter, err2->message);
          tp_proxy_invalidated ((TpProxy *) self, err2);
          return;
        }
    }
  else
    {
      DEBUG ("%p: GetChannelType() failed, will self-destruct", self);
      tp_proxy_invalidated ((TpProxy *) self, error);
      return;
    }

  g_assert (self->channel_type != 0);
  tp_proxy_add_interface_by_id ((TpProxy *) self, self->channel_type);

  tp_cli_channel_call_get_interfaces (self, -1,
      tp_channel_got_interfaces_cb, NULL, NULL, NULL);
}

static void
tp_channel_got_handle_cb (TpProxy *proxy,
                          guint handle_type,
                          guint handle,
                          const GError *error,
                          gpointer unused)
{
  TpChannel *self = TP_CHANNEL (proxy);

  if (error == NULL)
    {
      DEBUG ("%p: Introspected handle #%d of type %d", self, handle,
          handle_type);
      self->handle_type = handle_type;
{'fraction_non_alphanumeric': 0.09585769579181422, 'fraction_numerical': 0.004611710450465289, 'mean_word_length': 2.2848255342169326, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 42, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '206371', 'n_tokens_mistral': 3851, 'n_tokens_neox': 3665, 'n_words': 997}