gfilteroutputstream.c 10 KB
Newer Older
1 2 3 4 5 6 7
/* GIO - GLib Input, Output and Streaming Library
 * 
 * Copyright (C) 2006-2007 Red Hat, Inc.
 *
 * 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
8
 * version 2.1 of the License, or (at your option) any later version.
9 10 11 12 13 14 15
 *
 * 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
16
 * Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
17 18 19 20
 *
 * Author: Christian Kellner <gicmo@gnome.org> 
 */

21
#include "config.h"
22 23 24 25
#include "gfilteroutputstream.h"
#include "goutputstream.h"
#include "glibintl.h"

26

27 28 29
/**
 * SECTION:gfilteroutputstream
 * @short_description: Filter Output Stream
Matthias Clasen's avatar
Matthias Clasen committed
30
 * @include: gio/gio.h
31
 *
32 33 34 35 36
 * Base class for output stream implementations that perform some
 * kind of filtering operation on a base stream. Typical examples
 * of filtering operations are character set conversion, compression
 * and byte order flipping.
 */
37

38 39
enum {
  PROP_0,
40 41
  PROP_BASE_STREAM,
  PROP_CLOSE_BASE
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
};

static void     g_filter_output_stream_set_property (GObject      *object,
                                                     guint         prop_id,
                                                     const GValue *value,
                                                     GParamSpec   *pspec);

static void     g_filter_output_stream_get_property (GObject    *object,
                                                     guint       prop_id,
                                                     GValue     *value,
                                                     GParamSpec *pspec);
static void     g_filter_output_stream_dispose      (GObject *object);


static gssize   g_filter_output_stream_write        (GOutputStream *stream,
                                                     const void    *buffer,
                                                     gsize          count,
                                                     GCancellable  *cancellable,
                                                     GError       **error);
static gboolean g_filter_output_stream_flush        (GOutputStream    *stream,
                                                     GCancellable  *cancellable,
                                                     GError          **error);
static gboolean g_filter_output_stream_close        (GOutputStream  *stream,
                                                     GCancellable   *cancellable,
                                                     GError        **error);

68 69 70 71
typedef struct
{
  gboolean close_base;
} GFilterOutputStreamPrivate;
72

73 74
G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GFilterOutputStream, g_filter_output_stream, G_TYPE_OUTPUT_STREAM)

75 76 77 78 79 80 81 82 83 84 85 86
static void
g_filter_output_stream_class_init (GFilterOutputStreamClass *klass)
{
  GObjectClass *object_class;
  GOutputStreamClass *ostream_class;

  object_class = G_OBJECT_CLASS (klass);
  object_class->get_property = g_filter_output_stream_get_property;
  object_class->set_property = g_filter_output_stream_set_property;
  object_class->dispose      = g_filter_output_stream_dispose;
    
  ostream_class = G_OUTPUT_STREAM_CLASS (klass);
87
  ostream_class->write_fn = g_filter_output_stream_write;
88
  ostream_class->flush = g_filter_output_stream_flush;
89
  ostream_class->close_fn = g_filter_output_stream_close;
90 91 92 93 94

  g_object_class_install_property (object_class,
                                   PROP_BASE_STREAM,
                                   g_param_spec_object ("base-stream",
                                                         P_("The Filter Base Stream"),
95
                                                         P_("The underlying base stream on which the io ops will be done."),
96 97 98 99
                                                         G_TYPE_OUTPUT_STREAM,
                                                         G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | 
                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));

100 101 102 103
  g_object_class_install_property (object_class,
                                   PROP_CLOSE_BASE,
                                   g_param_spec_boolean ("close-base-stream",
                                                         P_("Close Base Stream"),
104
                                                         P_("If the base stream should be closed when the filter stream is closed."),
105 106
                                                         TRUE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
                                                         G_PARAM_STATIC_NAME|G_PARAM_STATIC_NICK|G_PARAM_STATIC_BLURB));
107 108 109
}

static void
Matthias Clasen's avatar
Matthias Clasen committed
110 111 112 113
g_filter_output_stream_set_property (GObject      *object,
                                     guint         prop_id,
                                     const GValue *value,
                                     GParamSpec   *pspec)
114 115 116 117 118 119 120 121 122 123 124 125 126
{
  GFilterOutputStream *filter_stream;
  GObject *obj;

  filter_stream = G_FILTER_OUTPUT_STREAM (object);

  switch (prop_id) 
    {
    case PROP_BASE_STREAM:
      obj = g_value_dup_object (value);
      filter_stream->base_stream = G_OUTPUT_STREAM (obj);
      break;

127 128 129 130 131
    case PROP_CLOSE_BASE:
      g_filter_output_stream_set_close_base_stream (filter_stream,
                                                    g_value_get_boolean (value));
      break;

132 133 134 135 136 137 138 139 140 141 142 143 144 145
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }

}

static void
g_filter_output_stream_get_property (GObject    *object,
                                     guint       prop_id,
                                     GValue     *value,
                                     GParamSpec *pspec)
{
  GFilterOutputStream *filter_stream;
146
  GFilterOutputStreamPrivate *priv;
147 148

  filter_stream = G_FILTER_OUTPUT_STREAM (object);
149
  priv = g_filter_output_stream_get_instance_private (filter_stream);
150 151 152 153 154 155 156

  switch (prop_id)
    {
    case PROP_BASE_STREAM:
      g_value_set_object (value, filter_stream->base_stream);
      break;

157
    case PROP_CLOSE_BASE:
158
      g_value_set_boolean (value, priv->close_base);
159 160
      break;

161 162 163 164 165 166 167 168 169 170
    default:
      G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
      break;
    }

}

static void
g_filter_output_stream_dispose (GObject *object)
{
Matthias Clasen's avatar
Matthias Clasen committed
171
  GFilterOutputStream *stream;
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189

  stream = G_FILTER_OUTPUT_STREAM (object);

  G_OBJECT_CLASS (g_filter_output_stream_parent_class)->dispose (object);
  
  if (stream->base_stream)
    {
      g_object_unref (stream->base_stream);
      stream->base_stream = NULL;
    }
}


static void
g_filter_output_stream_init (GFilterOutputStream *stream)
{
}

Matthias Clasen's avatar
Matthias Clasen committed
190 191 192 193 194 195
/**
 * g_filter_output_stream_get_base_stream:
 * @stream: a #GFilterOutputStream.
 * 
 * Gets the base stream for the filter stream.
 *
196
 * Returns: (transfer none): a #GOutputStream.
Matthias Clasen's avatar
Matthias Clasen committed
197
 **/
198 199 200 201 202 203 204 205
GOutputStream *
g_filter_output_stream_get_base_stream (GFilterOutputStream *stream)
{
  g_return_val_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream), NULL);

  return stream->base_stream;
}

206 207 208 209 210 211 212
/**
 * g_filter_output_stream_get_close_base_stream:
 * @stream: a #GFilterOutputStream.
 *
 * Returns whether the base stream will be closed when @stream is
 * closed.
 *
213
 * Returns: %TRUE if the base stream will be closed.
214 215 216 217
 **/
gboolean
g_filter_output_stream_get_close_base_stream (GFilterOutputStream *stream)
{
218 219
  GFilterOutputStreamPrivate *priv;

220 221
  g_return_val_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream), FALSE);

222
  priv = g_filter_output_stream_get_instance_private (stream);
223 224

  return priv->close_base;
225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243
}

/**
 * g_filter_output_stream_set_close_base_stream:
 * @stream: a #GFilterOutputStream.
 * @close_base: %TRUE to close the base stream.
 *
 * Sets whether the base stream will be closed when @stream is closed.
 **/
void
g_filter_output_stream_set_close_base_stream (GFilterOutputStream *stream,
                                              gboolean             close_base)
{
  GFilterOutputStreamPrivate *priv;

  g_return_if_fail (G_IS_FILTER_OUTPUT_STREAM (stream));

  close_base = !!close_base;

244
  priv = g_filter_output_stream_get_instance_private (stream);
245 246 247 248 249 250 251 252

  if (priv->close_base != close_base)
    {
      priv->close_base = close_base;
      g_object_notify (G_OBJECT (stream), "close-base-stream");
    }
}

253
static gssize
Matthias Clasen's avatar
Matthias Clasen committed
254 255 256 257 258
g_filter_output_stream_write (GOutputStream  *stream,
                              const void     *buffer,
                              gsize           count,
                              GCancellable   *cancellable,
                              GError        **error)
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274
{
  GFilterOutputStream *filter_stream;
  gssize nwritten;

  filter_stream = G_FILTER_OUTPUT_STREAM (stream);

  nwritten = g_output_stream_write (filter_stream->base_stream,
                                    buffer,
                                    count,
                                    cancellable,
                                    error);

  return nwritten;
}

static gboolean
Matthias Clasen's avatar
Matthias Clasen committed
275 276 277
g_filter_output_stream_flush (GOutputStream  *stream,
                              GCancellable   *cancellable,
                              GError        **error)
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295
{
  GFilterOutputStream *filter_stream;
  gboolean res;

  filter_stream = G_FILTER_OUTPUT_STREAM (stream);

  res = g_output_stream_flush (filter_stream->base_stream,
                               cancellable,
                               error);

  return res;
}

static gboolean
g_filter_output_stream_close (GOutputStream  *stream,
                              GCancellable   *cancellable,
                              GError        **error)
{
296
  GFilterOutputStream *filter_stream = G_FILTER_OUTPUT_STREAM (stream);
297
  GFilterOutputStreamPrivate *priv = g_filter_output_stream_get_instance_private (filter_stream);
298
  gboolean res = TRUE;
299

300
  if (priv->close_base)
301 302 303 304 305
    {
      res = g_output_stream_close (filter_stream->base_stream,
                                   cancellable,
                                   error);
    }
306 307 308

  return res;
}