<commit_before>/*
 * wocky-loopback-stream.c - Source for WockyLoopbackStream
 * Copyright (C) 2009-2011 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "wocky-loopback-connection.h"

enum {
  PROP_IO_INPUT_STREAM = 1,
  PROP_IO_OUTPUT_STREAM
};

static GType wocky_loopback_input_stream_get_type (void);
static GType wocky_loopback_output_stream_get_type (void);

struct _WockyLoopbackConnectionPrivate
{
  GInputStream *input;
  GOutputStream *output;
};

typedef struct
{
  GOutputStream parent;
  GAsyncQueue *queue;
  GError *write_error /* no, this is not a coding style violation */;
  gboolean dispose_has_run;
} WockyLoopbackOutputStream;

typedef struct
{
  GOutputStreamClass parent_class;
} WockyLoopbackOutputStreamClass;

typedef struct
{
  GInputStream parent;
  GAsyncQueue *queue;
  guint offset;
  GArray *out_array;
  GSimpleAsyncResult *read_result;
  GCancellable *read_cancellable;
  gulong read_cancellable_sig_id;
  void *buffer;
  gsize count;
  GError *read_error /* no, this is not a coding style violation */;
  gboolean dispose_has_run;
} WockyLoopbackInputStream;

typedef struct
{
  GOutputStreamClass parent_class;
} WockyLoopbackInputStreamClass;


G_DEFINE_TYPE (WockyLoopbackConnection, wocky_loopback_connection,
    G_TYPE_IO_STREAM);
G_DEFINE_TYPE (WockyLoopbackInputStream, wocky_loopback_input_stream,
  G_TYPE_INPUT_STREAM);
G_DEFINE_TYPE (WockyLoopbackOutputStream, wocky_loopback_output_stream,
  G_TYPE_OUTPUT_STREAM);

#define WOCKY_TYPE_LOOPBACK_INPUT_STREAM (wocky_loopback_input_stream_get_type ())
#define WOCKY_TYPE_LOOPBACK_OUTPUT_STREAM (wocky_loopback_output_stream_get_type ())

#define WOCKY_LOOPBACK_INPUT_STREAM(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
  WOCKY_TYPE_LOOPBACK_INPUT_STREAM,                                             \
  WockyLoopbackInputStream))

#define WOCKY_LOOPBACK_OUTPUT_STREAM(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
  WOCKY_TYPE_LOOPBACK_OUTPUT_STREAM,                                             \
  WockyLoopbackOutputStream))

static gboolean wocky_loopback_input_stream_try_read (WockyLoopbackInputStream *self);

static void
output_data_written_cb (GOutputStream *output,
    WockyLoopbackInputStream *input_stream)
{
  wocky_loopback_input_stream_try_read (input_stream);
}

/* connection */
static void
wocky_loopback_connection_init (WockyLoopbackConnection *self)
{
  WockyLoopbackConnectionPrivate *priv;

  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, WOCKY_TYPE_LOOPBACK_CONNECTION,
      WockyLoopbackConnectionPrivate);
  priv = self->priv;

  priv->output = g_object_new (WOCKY_TYPE_LOOPBACK_OUTPUT_STREAM, NULL);

  priv->input = g_object_new (WOCKY_TYPE_LOOPBACK_INPUT_STREAM, NULL);
  WOCKY_LOOPBACK_INPUT_STREAM (priv->input)->queue =
    g_async_queue_ref (
        WOCKY_LOOPBACK_OUTPUT_STREAM (priv->output)->queue);

  g_signal_connect (priv->output, "data-written",
      G_CALLBACK (output_data_written_cb), priv->input);
}

static void
wocky_loopback_connection_get_property (GObject *object,
    guint property_id,
    GValue *value,
    GParamSpec *pspec)
{
  WockyLoopbackConnection *self = WOCKY_LOOPBACK_CONNECTION (object);
  WockyLoopbackConnectionPrivate *priv = self->priv;

  switch (property_id)
    {
      case PROP_IO_INPUT_STREAM:
        g_value_set_object (value, priv->input);
        break;
      case PROP_IO_OUTPUT_STREAM:
        g_value_set_object (value, priv->output);
        break;
      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
        break;
    }
}

static void
wocky_loopback_connection_dispose (GObject *object)
{
  WockyLoopbackConnection *self = WOCKY_LOOPBACK_CONNECTION (object);
  WockyLoopbackConnectionPrivate *priv = self->priv;

  g_object_unref (priv->input);
  g_object_unref (priv->output);

  if (G_OBJECT_CLASS (wocky_loopback_connection_parent_class)->dispose)
    G_OBJECT_CLASS (wocky_loopback_connection_parent_class)->dispose (object);
}

static GInputStream *
wocky_loopback_connection_get_input_stream (GIOStream *stream)
{
  return WOCKY_LOOPBACK_CONNECTION (stream)->priv->input;
}

static GOutputStream *
wocky_loopback_connection_get_output_stream (GIOStream *stream)
{
  return WOCKY_LOOPBACK_CONNECTION (stream)->priv->output;
}

static void
wocky_loopback_connection_class_init (
    WockyLoopbackConnectionClass *wocky_loopback_connection_class)
{
  GObjectClass *obj_class = G_OBJECT_CLASS (wocky_loopback_connection_class);
  GIOStreamClass *stream_class = G_IO_STREAM_CLASS (
      wocky_loopback_connection_class);

  g_type_class_add_private (wocky_loopback_connection_class,
      sizeof (WockyLoopbackConnectionPrivate));

  obj_class->dispose = wocky_loopback_connection_dispose;
  obj_class->get_property = wocky_loopback_connection_get_property;
<commit_msg>loopback-connection: dispose the in/out streams only after they've been closed<commit_after>/*
 * wocky-loopback-stream.c - Source for WockyLoopbackStream
 * Copyright (C) 2009-2011 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "wocky-loopback-connection.h"

enum {
  PROP_IO_INPUT_STREAM = 1,
  PROP_IO_OUTPUT_STREAM
};

static GType wocky_loopback_input_stream_get_type (void);
static GType wocky_loopback_output_stream_get_type (void);

struct _WockyLoopbackConnectionPrivate
{
  GInputStream *input;
  GOutputStream *output;
};

typedef struct
{
  GOutputStream parent;
  GAsyncQueue *queue;
  GError *write_error /* no, this is not a coding style violation */;
  gboolean dispose_has_run;
} WockyLoopbackOutputStream;

typedef struct
{
  GOutputStreamClass parent_class;
} WockyLoopbackOutputStreamClass;

typedef struct
{
  GInputStream parent;
  GAsyncQueue *queue;
  guint offset;
  GArray *out_array;
  GSimpleAsyncResult *read_result;
  GCancellable *read_cancellable;
  gulong read_cancellable_sig_id;
  void *buffer;
  gsize count;
  GError *read_error /* no, this is not a coding style violation */;
  gboolean dispose_has_run;
} WockyLoopbackInputStream;

typedef struct
{
  GOutputStreamClass parent_class;
} WockyLoopbackInputStreamClass;


G_DEFINE_TYPE (WockyLoopbackConnection, wocky_loopback_connection,
    G_TYPE_IO_STREAM);
G_DEFINE_TYPE (WockyLoopbackInputStream, wocky_loopback_input_stream,
  G_TYPE_INPUT_STREAM);
G_DEFINE_TYPE (WockyLoopbackOutputStream, wocky_loopback_output_stream,
  G_TYPE_OUTPUT_STREAM);

#define WOCKY_TYPE_LOOPBACK_INPUT_STREAM (wocky_loopback_input_stream_get_type ())
#define WOCKY_TYPE_LOOPBACK_OUTPUT_STREAM (wocky_loopback_output_stream_get_type ())

#define WOCKY_LOOPBACK_INPUT_STREAM(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
  WOCKY_TYPE_LOOPBACK_INPUT_STREAM,                                             \
  WockyLoopbackInputStream))

#define WOCKY_LOOPBACK_OUTPUT_STREAM(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
  WOCKY_TYPE_LOOPBACK_OUTPUT_STREAM,                                             \
  WockyLoopbackOutputStream))

static gboolean wocky_loopback_input_stream_try_read (WockyLoopbackInputStream *self);

static void
output_data_written_cb (GOutputStream *output,
    WockyLoopbackInputStream *input_stream)
{
  wocky_loopback_input_stream_try_read (input_stream);
}

/* connection */
static void
wocky_loopback_connection_init (WockyLoopbackConnection *self)
{
  WockyLoopbackConnectionPrivate *priv;

  self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, WOCKY_TYPE_LOOPBACK_CONNECTION,
      WockyLoopbackConnectionPrivate);
  priv = self->priv;

  priv->output = g_object_new (WOCKY_TYPE_LOOPBACK_OUTPUT_STREAM, NULL);

  priv->input = g_object_new (WOCKY_TYPE_LOOPBACK_INPUT_STREAM, NULL);
  WOCKY_LOOPBACK_INPUT_STREAM (priv->input)->queue =
    g_async_queue_ref (
        WOCKY_LOOPBACK_OUTPUT_STREAM (priv->output)->queue);

  g_signal_connect (priv->output, "data-written",
      G_CALLBACK (output_data_written_cb), priv->input);
}

static void
wocky_loopback_connection_get_property (GObject *object,
    guint property_id,
    GValue *value,
    GParamSpec *pspec)
{
  WockyLoopbackConnection *self = WOCKY_LOOPBACK_CONNECTION (object);
  WockyLoopbackConnectionPrivate *priv = self->priv;

  switch (property_id)
    {
      case PROP_IO_INPUT_STREAM:
        g_value_set_object (value, priv->input);
        break;
      case PROP_IO_OUTPUT_STREAM:
        g_value_set_object (value, priv->output);
        break;
      default:
        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
        break;
    }
}

static void
wocky_loopback_connection_dispose (GObject *object)
{
  WockyLoopbackConnection *self = WOCKY_LOOPBACK_CONNECTION (object);
  WockyLoopbackConnectionPrivate *priv = self->priv;

  if (G_OBJECT_CLASS (wocky_loopback_connection_parent_class)->dispose)
    G_OBJECT_CLASS (wocky_loopback_connection_parent_class)->dispose (object);

  g_object_unref (priv->input);
  g_object_unref (priv->output);
}

static GInputStream *
wocky_loopback_connection_get_input_stream (GIOStream *stream)
{
  return WOCKY_LOOPBACK_CONNECTION (stream)->priv->input;
}

static GOutputStream *
wocky_loopback_connection_get_output_stream (GIOStream *stream)
{
  return WOCKY_LOOPBACK_CONNECTION (stream)->priv->output;
}

static void
wocky_loopback_connection_class_init (
    WockyLoopbackConnectionClass *wocky_loopback_connection_class)
{
  GObjectClass *obj_class = G_OBJECT_CLASS (wocky_loopback_connection_class);
  GIOStreamClass *stream_class = G_IO_STREAM_CLASS (
      wocky_loopback_connection_class);

  g_type_class_add_private (wocky_loopback_connection_class,
      sizeof (WockyLoopbackConnectionPrivate));

  obj_class->dispose = wocky_loopback_connection_dispose;
  obj_class->get_property = wocky_loopback_connection_get_property;

{'fraction_non_alphanumeric': 0.07299009547604177, 'fraction_numerical': 0.003926117605068261, 'mean_word_length': 5.199115044247788, 'pattern_counts': {'":': 0, '<': 9, '<?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': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7038577', 'n_tokens_mistral': 3787, 'n_tokens_neox': 3672, 'n_words': 787}