Blame gio/gfilterinputstream.c

Packit Service d3d246
/* GIO - GLib Input, Output and Streaming Library
Packit Service d3d246
 * 
Packit Service d3d246
 * Copyright (C) 2006-2007 Red Hat, Inc.
Packit Service d3d246
 *
Packit Service d3d246
 * This library is free software; you can redistribute it and/or
Packit Service d3d246
 * modify it under the terms of the GNU Lesser General Public
Packit Service d3d246
 * License as published by the Free Software Foundation; either
Packit Service d3d246
 * version 2.1 of the License, or (at your option) any later version.
Packit Service d3d246
 *
Packit Service d3d246
 * This library is distributed in the hope that it will be useful,
Packit Service d3d246
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service d3d246
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service d3d246
 * Lesser General Public License for more details.
Packit Service d3d246
 *
Packit Service d3d246
 * You should have received a copy of the GNU Lesser General
Packit Service d3d246
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
Packit Service d3d246
 *
Packit Service d3d246
 * Author: Christian Kellner <gicmo@gnome.org> 
Packit Service d3d246
 */
Packit Service d3d246
Packit Service d3d246
#include "config.h"
Packit Service d3d246
#include "gfilterinputstream.h"
Packit Service d3d246
#include "ginputstream.h"
Packit Service d3d246
#include "glibintl.h"
Packit Service d3d246
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * SECTION:gfilterinputstream
Packit Service d3d246
 * @short_description: Filter Input Stream
Packit Service d3d246
 * @include: gio/gio.h
Packit Service d3d246
 *
Packit Service d3d246
 * Base class for input stream implementations that perform some
Packit Service d3d246
 * kind of filtering operation on a base stream. Typical examples
Packit Service d3d246
 * of filtering operations are character set conversion, compression
Packit Service d3d246
 * and byte order flipping.
Packit Service d3d246
 **/
Packit Service d3d246
Packit Service d3d246
enum {
Packit Service d3d246
  PROP_0,
Packit Service d3d246
  PROP_BASE_STREAM,
Packit Service d3d246
  PROP_CLOSE_BASE
Packit Service d3d246
};
Packit Service d3d246
Packit Service d3d246
static void     g_filter_input_stream_set_property (GObject      *object,
Packit Service d3d246
                                                    guint         prop_id,
Packit Service d3d246
                                                    const GValue *value,
Packit Service d3d246
                                                    GParamSpec   *pspec);
Packit Service d3d246
Packit Service d3d246
static void     g_filter_input_stream_get_property (GObject      *object,
Packit Service d3d246
                                                    guint         prop_id,
Packit Service d3d246
                                                    GValue       *value,
Packit Service d3d246
                                                    GParamSpec   *pspec);
Packit Service d3d246
static void     g_filter_input_stream_finalize     (GObject *object);
Packit Service d3d246
Packit Service d3d246
Packit Service d3d246
static gssize   g_filter_input_stream_read         (GInputStream         *stream,
Packit Service d3d246
                                                    void                 *buffer,
Packit Service d3d246
                                                    gsize                 count,
Packit Service d3d246
                                                    GCancellable         *cancellable,
Packit Service d3d246
                                                    GError              **error);
Packit Service d3d246
static gssize   g_filter_input_stream_skip         (GInputStream         *stream,
Packit Service d3d246
                                                    gsize                 count,
Packit Service d3d246
                                                    GCancellable         *cancellable,
Packit Service d3d246
                                                    GError              **error);
Packit Service d3d246
static gboolean g_filter_input_stream_close        (GInputStream         *stream,
Packit Service d3d246
                                                    GCancellable         *cancellable,
Packit Service d3d246
                                                    GError              **error);
Packit Service d3d246
Packit Service d3d246
typedef struct
Packit Service d3d246
{
Packit Service d3d246
  gboolean close_base;
Packit Service d3d246
} GFilterInputStreamPrivate;
Packit Service d3d246
Packit Service d3d246
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GFilterInputStream, g_filter_input_stream, G_TYPE_INPUT_STREAM)
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
g_filter_input_stream_class_init (GFilterInputStreamClass *klass)
Packit Service d3d246
{
Packit Service d3d246
  GObjectClass *object_class;
Packit Service d3d246
  GInputStreamClass *istream_class;
Packit Service d3d246
Packit Service d3d246
  object_class = G_OBJECT_CLASS (klass);
Packit Service d3d246
  object_class->get_property = g_filter_input_stream_get_property;
Packit Service d3d246
  object_class->set_property = g_filter_input_stream_set_property;
Packit Service d3d246
  object_class->finalize     = g_filter_input_stream_finalize;
Packit Service d3d246
Packit Service d3d246
  istream_class = G_INPUT_STREAM_CLASS (klass);
Packit Service d3d246
  istream_class->read_fn  = g_filter_input_stream_read;
Packit Service d3d246
  istream_class->skip  = g_filter_input_stream_skip;
Packit Service d3d246
  istream_class->close_fn = g_filter_input_stream_close;
Packit Service d3d246
Packit Service d3d246
  g_object_class_install_property (object_class,
Packit Service d3d246
                                   PROP_BASE_STREAM,
Packit Service d3d246
                                   g_param_spec_object ("base-stream",
Packit Service d3d246
                                                         P_("The Filter Base Stream"),
Packit Service d3d246
                                                         P_("The underlying base stream on which the io ops will be done."),
Packit Service d3d246
                                                         G_TYPE_INPUT_STREAM,
Packit Service d3d246
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | 
Packit Service d3d246
                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
Packit Service d3d246
Packit Service d3d246
  g_object_class_install_property (object_class,
Packit Service d3d246
                                   PROP_CLOSE_BASE,
Packit Service d3d246
                                   g_param_spec_boolean ("close-base-stream",
Packit Service d3d246
                                                         P_("Close Base Stream"),
Packit Service d3d246
                                                         P_("If the base stream should be closed when the filter stream is closed."),
Packit Service d3d246
                                                         TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT |
Packit Service d3d246
                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
g_filter_input_stream_set_property (GObject         *object,
Packit Service d3d246
                                    guint            prop_id,
Packit Service d3d246
                                    const GValue    *value,
Packit Service d3d246
                                    GParamSpec      *pspec)
Packit Service d3d246
{
Packit Service d3d246
  GFilterInputStream *filter_stream;
Packit Service d3d246
  GObject *obj;
Packit Service d3d246
Packit Service d3d246
  filter_stream = G_FILTER_INPUT_STREAM (object);
Packit Service d3d246
Packit Service d3d246
  switch (prop_id) 
Packit Service d3d246
    {
Packit Service d3d246
    case PROP_BASE_STREAM:
Packit Service d3d246
      obj = g_value_dup_object (value);
Packit Service d3d246
      filter_stream->base_stream = G_INPUT_STREAM (obj); 
Packit Service d3d246
      break;
Packit Service d3d246
Packit Service d3d246
    case PROP_CLOSE_BASE:
Packit Service d3d246
      g_filter_input_stream_set_close_base_stream (filter_stream,
Packit Service d3d246
                                                   g_value_get_boolean (value));
Packit Service d3d246
      break;
Packit Service d3d246
Packit Service d3d246
    default:
Packit Service d3d246
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit Service d3d246
      break;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
g_filter_input_stream_get_property (GObject    *object,
Packit Service d3d246
                                    guint       prop_id,
Packit Service d3d246
                                    GValue     *value,
Packit Service d3d246
                                    GParamSpec *pspec)
Packit Service d3d246
{
Packit Service d3d246
  GFilterInputStream *filter_stream;
Packit Service d3d246
  GFilterInputStreamPrivate *priv;
Packit Service d3d246
Packit Service d3d246
  filter_stream = G_FILTER_INPUT_STREAM (object);
Packit Service d3d246
  priv = g_filter_input_stream_get_instance_private (filter_stream);
Packit Service d3d246
Packit Service d3d246
  switch (prop_id)
Packit Service d3d246
    {
Packit Service d3d246
    case PROP_BASE_STREAM:
Packit Service d3d246
      g_value_set_object (value, filter_stream->base_stream);
Packit Service d3d246
      break;
Packit Service d3d246
Packit Service d3d246
    case PROP_CLOSE_BASE:
Packit Service d3d246
      g_value_set_boolean (value, priv->close_base);
Packit Service d3d246
      break;
Packit Service d3d246
Packit Service d3d246
    default:
Packit Service d3d246
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
Packit Service d3d246
      break;
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
g_filter_input_stream_finalize (GObject *object)
Packit Service d3d246
{
Packit Service d3d246
  GFilterInputStream *stream;
Packit Service d3d246
Packit Service d3d246
  stream = G_FILTER_INPUT_STREAM (object);
Packit Service d3d246
Packit Service d3d246
  g_object_unref (stream->base_stream);
Packit Service d3d246
Packit Service d3d246
  G_OBJECT_CLASS (g_filter_input_stream_parent_class)->finalize (object);
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static void
Packit Service d3d246
g_filter_input_stream_init (GFilterInputStream *stream)
Packit Service d3d246
{
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * g_filter_input_stream_get_base_stream:
Packit Service d3d246
 * @stream: a #GFilterInputStream.
Packit Service d3d246
 * 
Packit Service d3d246
 * Gets the base stream for the filter stream.
Packit Service d3d246
 *
Packit Service d3d246
 * Returns: (transfer none): a #GInputStream.
Packit Service d3d246
 **/
Packit Service d3d246
GInputStream *
Packit Service d3d246
g_filter_input_stream_get_base_stream (GFilterInputStream *stream)
Packit Service d3d246
{
Packit Service d3d246
  g_return_val_if_fail (G_IS_FILTER_INPUT_STREAM (stream), NULL);
Packit Service d3d246
Packit Service d3d246
  return stream->base_stream;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * g_filter_input_stream_get_close_base_stream:
Packit Service d3d246
 * @stream: a #GFilterInputStream.
Packit Service d3d246
 *
Packit Service d3d246
 * Returns whether the base stream will be closed when @stream is
Packit Service d3d246
 * closed.
Packit Service d3d246
 *
Packit Service d3d246
 * Returns: %TRUE if the base stream will be closed.
Packit Service d3d246
 **/
Packit Service d3d246
gboolean
Packit Service d3d246
g_filter_input_stream_get_close_base_stream (GFilterInputStream *stream)
Packit Service d3d246
{
Packit Service d3d246
  GFilterInputStreamPrivate *priv;
Packit Service d3d246
Packit Service d3d246
  g_return_val_if_fail (G_IS_FILTER_INPUT_STREAM (stream), FALSE);
Packit Service d3d246
Packit Service d3d246
  priv = g_filter_input_stream_get_instance_private (stream);
Packit Service d3d246
Packit Service d3d246
  return priv->close_base;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
/**
Packit Service d3d246
 * g_filter_input_stream_set_close_base_stream:
Packit Service d3d246
 * @stream: a #GFilterInputStream.
Packit Service d3d246
 * @close_base: %TRUE to close the base stream.
Packit Service d3d246
 *
Packit Service d3d246
 * Sets whether the base stream will be closed when @stream is closed.
Packit Service d3d246
 **/
Packit Service d3d246
void
Packit Service d3d246
g_filter_input_stream_set_close_base_stream (GFilterInputStream *stream,
Packit Service d3d246
                                             gboolean            close_base)
Packit Service d3d246
{
Packit Service d3d246
  GFilterInputStreamPrivate *priv;
Packit Service d3d246
Packit Service d3d246
  g_return_if_fail (G_IS_FILTER_INPUT_STREAM (stream));
Packit Service d3d246
Packit Service d3d246
  close_base = !!close_base;
Packit Service d3d246
 
Packit Service d3d246
  priv = g_filter_input_stream_get_instance_private (stream);
Packit Service d3d246
Packit Service d3d246
  if (priv->close_base != close_base)
Packit Service d3d246
    {
Packit Service d3d246
      priv->close_base = close_base;
Packit Service d3d246
      g_object_notify (G_OBJECT (stream), "close-base-stream");
Packit Service d3d246
    }
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static gssize
Packit Service d3d246
g_filter_input_stream_read (GInputStream  *stream,
Packit Service d3d246
                            void          *buffer,
Packit Service d3d246
                            gsize          count,
Packit Service d3d246
                            GCancellable  *cancellable,
Packit Service d3d246
                            GError       **error)
Packit Service d3d246
{
Packit Service d3d246
  GFilterInputStream *filter_stream;
Packit Service d3d246
  GInputStream       *base_stream;
Packit Service d3d246
  gssize              nread;
Packit Service d3d246
Packit Service d3d246
  filter_stream = G_FILTER_INPUT_STREAM (stream);
Packit Service d3d246
  base_stream = filter_stream->base_stream;
Packit Service d3d246
Packit Service d3d246
  nread = g_input_stream_read (base_stream,
Packit Service d3d246
                               buffer,
Packit Service d3d246
                               count,
Packit Service d3d246
                               cancellable,
Packit Service d3d246
                               error);
Packit Service d3d246
Packit Service d3d246
  return nread;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static gssize
Packit Service d3d246
g_filter_input_stream_skip (GInputStream  *stream,
Packit Service d3d246
                            gsize          count,
Packit Service d3d246
                            GCancellable  *cancellable,
Packit Service d3d246
                            GError       **error)
Packit Service d3d246
{
Packit Service d3d246
  GFilterInputStream *filter_stream;
Packit Service d3d246
  GInputStream       *base_stream;
Packit Service d3d246
  gssize              nskipped;
Packit Service d3d246
Packit Service d3d246
  filter_stream = G_FILTER_INPUT_STREAM (stream);
Packit Service d3d246
  base_stream = filter_stream->base_stream;
Packit Service d3d246
Packit Service d3d246
  nskipped = g_input_stream_skip (base_stream,
Packit Service d3d246
                                  count,
Packit Service d3d246
                                  cancellable,
Packit Service d3d246
                                  error);
Packit Service d3d246
  return nskipped;
Packit Service d3d246
}
Packit Service d3d246
Packit Service d3d246
static gboolean
Packit Service d3d246
g_filter_input_stream_close (GInputStream  *stream,
Packit Service d3d246
                             GCancellable  *cancellable,
Packit Service d3d246
                             GError       **error)
Packit Service d3d246
{
Packit Service d3d246
  GFilterInputStream *filter_stream = G_FILTER_INPUT_STREAM (stream);
Packit Service d3d246
  GFilterInputStreamPrivate *priv = g_filter_input_stream_get_instance_private (filter_stream);
Packit Service d3d246
  gboolean res = TRUE;
Packit Service d3d246
Packit Service d3d246
  if (priv->close_base)
Packit Service d3d246
    {
Packit Service d3d246
      res = g_input_stream_close (filter_stream->base_stream,
Packit Service d3d246
                                  cancellable,
Packit Service d3d246
                                  error);
Packit Service d3d246
    }
Packit Service d3d246
Packit Service d3d246
  return res;
Packit Service d3d246
}