Blame gio/gfilteroutputstream.c

Packit ae235b
/* GIO - GLib Input, Output and Streaming Library
Packit ae235b
 * 
Packit ae235b
 * Copyright (C) 2006-2007 Red Hat, Inc.
Packit ae235b
 *
Packit ae235b
 * This library is free software; you can redistribute it and/or
Packit ae235b
 * modify it under the terms of the GNU Lesser General Public
Packit ae235b
 * License as published by the Free Software Foundation; either
Packit ae235b
 * version 2.1 of the License, or (at your option) any later version.
Packit ae235b
 *
Packit ae235b
 * This library is distributed in the hope that it will be useful,
Packit ae235b
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit ae235b
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit ae235b
 * Lesser General Public License for more details.
Packit ae235b
 *
Packit ae235b
 * You should have received a copy of the GNU Lesser General
Packit ae235b
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit ae235b
 *
Packit ae235b
 * Author: Christian Kellner <gicmo@gnome.org> 
Packit ae235b
 */
Packit ae235b
Packit ae235b
#include "config.h"
Packit ae235b
#include "gfilteroutputstream.h"
Packit ae235b
#include "goutputstream.h"
Packit ae235b
#include "glibintl.h"
Packit ae235b
Packit ae235b
Packit ae235b
/**
Packit ae235b
 * SECTION:gfilteroutputstream
Packit ae235b
 * @short_description: Filter Output Stream
Packit ae235b
 * @include: gio/gio.h
Packit ae235b
 *
Packit ae235b
 * Base class for output stream implementations that perform some
Packit ae235b
 * kind of filtering operation on a base stream. Typical examples
Packit ae235b
 * of filtering operations are character set conversion, compression
Packit ae235b
 * and byte order flipping.
Packit ae235b
 */
Packit ae235b
Packit ae235b
enum {
Packit ae235b
  PROP_0,
Packit ae235b
  PROP_BASE_STREAM,
Packit ae235b
  PROP_CLOSE_BASE
Packit ae235b
};
Packit ae235b
Packit ae235b
static void     g_filter_output_stream_set_property (GObject      *object,
Packit ae235b
                                                     guint         prop_id,
Packit ae235b
                                                     const GValue *value,
Packit ae235b
                                                     GParamSpec   *pspec);
Packit ae235b
Packit ae235b
static void     g_filter_output_stream_get_property (GObject    *object,
Packit ae235b
                                                     guint       prop_id,
Packit ae235b
                                                     GValue     *value,
Packit ae235b
                                                     GParamSpec *pspec);
Packit ae235b
static void     g_filter_output_stream_dispose      (GObject *object);
Packit ae235b
Packit ae235b
Packit ae235b
static gssize   g_filter_output_stream_write        (GOutputStream *stream,
Packit ae235b
                                                     const void    *buffer,
Packit ae235b
                                                     gsize          count,
Packit ae235b
                                                     GCancellable  *cancellable,
Packit ae235b
                                                     GError       **error);
Packit ae235b
static gboolean g_filter_output_stream_flush        (GOutputStream    *stream,
Packit ae235b
                                                     GCancellable  *cancellable,
Packit ae235b
                                                     GError          **error);
Packit ae235b
static gboolean g_filter_output_stream_close        (GOutputStream  *stream,
Packit ae235b
                                                     GCancellable   *cancellable,
Packit ae235b
                                                     GError        **error);
Packit ae235b
Packit ae235b
typedef struct
Packit ae235b
{
Packit ae235b
  gboolean close_base;
Packit ae235b
} GFilterOutputStreamPrivate;
Packit ae235b
Packit ae235b
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GFilterOutputStream, g_filter_output_stream, G_TYPE_OUTPUT_STREAM)
Packit ae235b
Packit ae235b
static void
Packit ae235b
g_filter_output_stream_class_init (GFilterOutputStreamClass *klass)
Packit ae235b
{
Packit ae235b
  GObjectClass *object_class;
Packit ae235b
  GOutputStreamClass *ostream_class;
Packit ae235b
Packit ae235b
  object_class = G_OBJECT_CLASS (klass);
Packit ae235b
  object_class->get_property = g_filter_output_stream_get_property;
Packit ae235b
  object_class->set_property = g_filter_output_stream_set_property;
Packit ae235b
  object_class->dispose      = g_filter_output_stream_dispose;
Packit ae235b
    
Packit ae235b
  ostream_class = G_OUTPUT_STREAM_CLASS (klass);
Packit ae235b
  ostream_class->write_fn = g_filter_output_stream_write;
Packit ae235b
  ostream_class->flush = g_filter_output_stream_flush;
Packit ae235b
  ostream_class->close_fn = g_filter_output_stream_close;
Packit ae235b
Packit ae235b
  g_object_class_install_property (object_class,
Packit ae235b
                                   PROP_BASE_STREAM,
Packit ae235b
                                   g_param_spec_object ("base-stream",
Packit ae235b
                                                         P_("The Filter Base Stream"),
Packit ae235b
                                                         P_("The underlying base stream on which the io ops will be done."),
Packit ae235b
                                                         G_TYPE_OUTPUT_STREAM,
Packit ae235b
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | 
Packit ae235b
                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
Packit ae235b
Packit ae235b
  g_object_class_install_property (object_class,
Packit ae235b
                                   PROP_CLOSE_BASE,
Packit ae235b
                                   g_param_spec_boolean ("close-base-stream",
Packit ae235b
                                                         P_("Close Base Stream"),
Packit ae235b
                                                         P_("If the base stream should be closed when the filter stream is closed."),
Packit ae235b
                                                         TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
Packit ae235b
                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
g_filter_output_stream_set_property (GObject      *object,
Packit ae235b
                                     guint         prop_id,
Packit ae235b
                                     const GValue *value,
Packit ae235b
                                     GParamSpec   *pspec)
Packit ae235b
{
Packit ae235b
  GFilterOutputStream *filter_stream;
Packit ae235b
  GObject *obj;
Packit ae235b
Packit ae235b
  filter_stream = G_FILTER_OUTPUT_STREAM (object);
Packit ae235b
Packit ae235b
  switch (prop_id) 
Packit ae235b
    {
Packit ae235b
    case PROP_BASE_STREAM:
Packit ae235b
      obj = g_value_dup_object (value);
Packit ae235b
      filter_stream->base_stream = G_OUTPUT_STREAM (obj);
Packit ae235b
      break;
Packit ae235b
Packit ae235b
    case PROP_CLOSE_BASE:
Packit ae235b
      g_filter_output_stream_set_close_base_stream (filter_stream,
Packit ae235b
                                                    g_value_get_boolean (value));
Packit ae235b
      break;
Packit ae235b
Packit ae235b
    default:
Packit ae235b
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit ae235b
      break;
Packit ae235b
    }
Packit ae235b
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
g_filter_output_stream_get_property (GObject    *object,
Packit ae235b
                                     guint       prop_id,
Packit ae235b
                                     GValue     *value,
Packit ae235b
                                     GParamSpec *pspec)
Packit ae235b
{
Packit ae235b
  GFilterOutputStream *filter_stream;
Packit ae235b
  GFilterOutputStreamPrivate *priv;
Packit ae235b
Packit ae235b
  filter_stream = G_FILTER_OUTPUT_STREAM (object);
Packit ae235b
  priv = g_filter_output_stream_get_instance_private (filter_stream);
Packit ae235b
Packit ae235b
  switch (prop_id)
Packit ae235b
    {
Packit ae235b
    case PROP_BASE_STREAM:
Packit ae235b
      g_value_set_object (value, filter_stream->base_stream);
Packit ae235b
      break;
Packit ae235b
Packit ae235b
    case PROP_CLOSE_BASE:
Packit ae235b
      g_value_set_boolean (value, priv->close_base);
Packit ae235b
      break;
Packit ae235b
Packit ae235b
    default:
Packit ae235b
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit ae235b
      break;
Packit ae235b
    }
Packit ae235b
Packit ae235b
}
Packit ae235b
Packit ae235b
static void
Packit ae235b
g_filter_output_stream_dispose (GObject *object)
Packit ae235b
{
Packit ae235b
  GFilterOutputStream *stream;
Packit ae235b
Packit ae235b
  stream = G_FILTER_OUTPUT_STREAM (object);
Packit ae235b
Packit ae235b
  G_OBJECT_CLASS (g_filter_output_stream_parent_class)->dispose (object);
Packit ae235b
  
Packit ae235b
  if (stream->base_stream)
Packit ae235b
    {
Packit ae235b
      g_object_unref (stream->base_stream);
Packit ae235b
      stream->base_stream = NULL;
Packit ae235b
    }
Packit ae235b
}
Packit ae235b
Packit ae235b
Packit ae235b
static void
Packit ae235b
g_filter_output_stream_init (GFilterOutputStream *stream)
Packit ae235b
{
Packit ae235b
}
Packit ae235b
Packit ae235b
/**
Packit ae235b
 * g_filter_output_stream_get_base_stream:
Packit ae235b
 * @stream: a #GFilterOutputStream.
Packit ae235b
 * 
Packit ae235b
 * Gets the base stream for the filter stream.
Packit ae235b
 *
Packit ae235b
 * Returns: (transfer none): a #GOutputStream.
Packit ae235b
 **/
Packit ae235b
GOutputStream *
Packit ae235b
g_filter_output_stream_get_base_stream (GFilterOutputStream *stream)
Packit ae235b
{
Packit ae235b
  g_return_val_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream), NULL);
Packit ae235b
Packit ae235b
  return stream->base_stream;
Packit ae235b
}
Packit ae235b
Packit ae235b
/**
Packit ae235b
 * g_filter_output_stream_get_close_base_stream:
Packit ae235b
 * @stream: a #GFilterOutputStream.
Packit ae235b
 *
Packit ae235b
 * Returns whether the base stream will be closed when @stream is
Packit ae235b
 * closed.
Packit ae235b
 *
Packit ae235b
 * Returns: %TRUE if the base stream will be closed.
Packit ae235b
 **/
Packit ae235b
gboolean
Packit ae235b
g_filter_output_stream_get_close_base_stream (GFilterOutputStream *stream)
Packit ae235b
{
Packit ae235b
  GFilterOutputStreamPrivate *priv;
Packit ae235b
Packit ae235b
  g_return_val_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream), FALSE);
Packit ae235b
Packit ae235b
  priv = g_filter_output_stream_get_instance_private (stream);
Packit ae235b
Packit ae235b
  return priv->close_base;
Packit ae235b
}
Packit ae235b
Packit ae235b
/**
Packit ae235b
 * g_filter_output_stream_set_close_base_stream:
Packit ae235b
 * @stream: a #GFilterOutputStream.
Packit ae235b
 * @close_base: %TRUE to close the base stream.
Packit ae235b
 *
Packit ae235b
 * Sets whether the base stream will be closed when @stream is closed.
Packit ae235b
 **/
Packit ae235b
void
Packit ae235b
g_filter_output_stream_set_close_base_stream (GFilterOutputStream *stream,
Packit ae235b
                                              gboolean             close_base)
Packit ae235b
{
Packit ae235b
  GFilterOutputStreamPrivate *priv;
Packit ae235b
Packit ae235b
  g_return_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream));
Packit ae235b
Packit ae235b
  close_base = !!close_base;
Packit ae235b
Packit ae235b
  priv = g_filter_output_stream_get_instance_private (stream);
Packit ae235b
Packit ae235b
  if (priv->close_base != close_base)
Packit ae235b
    {
Packit ae235b
      priv->close_base = close_base;
Packit ae235b
      g_object_notify (G_OBJECT (stream), "close-base-stream");
Packit ae235b
    }
Packit ae235b
}
Packit ae235b
Packit ae235b
static gssize
Packit ae235b
g_filter_output_stream_write (GOutputStream  *stream,
Packit ae235b
                              const void     *buffer,
Packit ae235b
                              gsize           count,
Packit ae235b
                              GCancellable   *cancellable,
Packit ae235b
                              GError        **error)
Packit ae235b
{
Packit ae235b
  GFilterOutputStream *filter_stream;
Packit ae235b
  gssize nwritten;
Packit ae235b
Packit ae235b
  filter_stream = G_FILTER_OUTPUT_STREAM (stream);
Packit ae235b
Packit ae235b
  nwritten = g_output_stream_write (filter_stream->base_stream,
Packit ae235b
                                    buffer,
Packit ae235b
                                    count,
Packit ae235b
                                    cancellable,
Packit ae235b
                                    error);
Packit ae235b
Packit ae235b
  return nwritten;
Packit ae235b
}
Packit ae235b
Packit ae235b
static gboolean
Packit ae235b
g_filter_output_stream_flush (GOutputStream  *stream,
Packit ae235b
                              GCancellable   *cancellable,
Packit ae235b
                              GError        **error)
Packit ae235b
{
Packit ae235b
  GFilterOutputStream *filter_stream;
Packit ae235b
  gboolean res;
Packit ae235b
Packit ae235b
  filter_stream = G_FILTER_OUTPUT_STREAM (stream);
Packit ae235b
Packit ae235b
  res = g_output_stream_flush (filter_stream->base_stream,
Packit ae235b
                               cancellable,
Packit ae235b
                               error);
Packit ae235b
Packit ae235b
  return res;
Packit ae235b
}
Packit ae235b
Packit ae235b
static gboolean
Packit ae235b
g_filter_output_stream_close (GOutputStream  *stream,
Packit ae235b
                              GCancellable   *cancellable,
Packit ae235b
                              GError        **error)
Packit ae235b
{
Packit ae235b
  GFilterOutputStream *filter_stream = G_FILTER_OUTPUT_STREAM (stream);
Packit ae235b
  GFilterOutputStreamPrivate *priv = g_filter_output_stream_get_instance_private (filter_stream);
Packit ae235b
  gboolean res = TRUE;
Packit ae235b
Packit ae235b
  if (priv->close_base)
Packit ae235b
    {
Packit ae235b
      res = g_output_stream_close (filter_stream->base_stream,
Packit ae235b
                                   cancellable,
Packit ae235b
                                   error);
Packit ae235b
    }
Packit ae235b
Packit ae235b
  return res;
Packit ae235b
}