1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright (C) 2006-2007 Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18 * Boston, MA 02111-1307, USA.
20 * Author: Christian Kellner <gicmo@gnome.org>
24 #include "gmemoryinputstream.h"
25 #include "ginputstream.h"
26 #include "gseekable.h"
28 #include "gsimpleasyncresult.h"
32 * SECTION:gmemoryinputstream
33 * @short_description: streaming input operations on memory chunks
34 * @see_also: #GMemoryOutputStream
36 * #GMemoryInputStream is a class for using arbitrary
37 * memory chunks as input for GIO streaming input operations.
41 struct _GMemoryInputStreamPrivate {
48 static gssize g_memory_input_stream_read (GInputStream *stream,
51 GCancellable *cancellable,
53 static gssize g_memory_input_stream_skip (GInputStream *stream,
55 GCancellable *cancellable,
57 static gboolean g_memory_input_stream_close (GInputStream *stream,
58 GCancellable *cancellable,
60 static void g_memory_input_stream_read_async (GInputStream *stream,
64 GCancellable *cancellable,
65 GAsyncReadyCallback callback,
67 static gssize g_memory_input_stream_read_finish (GInputStream *stream,
70 static void g_memory_input_stream_skip_async (GInputStream *stream,
73 GCancellable *cancellabl,
74 GAsyncReadyCallback callback,
76 static gssize g_memory_input_stream_skip_finish (GInputStream *stream,
79 static void g_memory_input_stream_close_async (GInputStream *stream,
81 GCancellable *cancellabl,
82 GAsyncReadyCallback callback,
84 static gboolean g_memory_input_stream_close_finish (GInputStream *stream,
88 static void g_memory_input_stream_seekable_iface_init (GSeekableIface *iface);
89 static goffset g_memory_input_stream_tell (GSeekable *seekable);
90 static gboolean g_memory_input_stream_can_seek (GSeekable *seekable);
91 static gboolean g_memory_input_stream_seek (GSeekable *seekable,
94 GCancellable *cancellable,
96 static gboolean g_memory_input_stream_can_truncate (GSeekable *seekable);
97 static gboolean g_memory_input_stream_truncate (GSeekable *seekable,
99 GCancellable *cancellable,
101 static void g_memory_input_stream_finalize (GObject *object);
103 G_DEFINE_TYPE_WITH_CODE (GMemoryInputStream, g_memory_input_stream, G_TYPE_INPUT_STREAM,
104 G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE,
105 g_memory_input_stream_seekable_iface_init))
109 g_memory_input_stream_class_init (GMemoryInputStreamClass *klass)
111 GObjectClass *object_class;
112 GInputStreamClass *istream_class;
114 g_type_class_add_private (klass, sizeof (GMemoryInputStreamPrivate));
116 object_class = G_OBJECT_CLASS (klass);
117 object_class->finalize = g_memory_input_stream_finalize;
119 istream_class = G_INPUT_STREAM_CLASS (klass);
120 istream_class->read = g_memory_input_stream_read;
121 istream_class->skip = g_memory_input_stream_skip;
122 istream_class->close = g_memory_input_stream_close;
124 istream_class->read_async = g_memory_input_stream_read_async;
125 istream_class->read_finish = g_memory_input_stream_read_finish;
126 istream_class->skip_async = g_memory_input_stream_skip_async;
127 istream_class->skip_finish = g_memory_input_stream_skip_finish;
128 istream_class->close_async = g_memory_input_stream_close_async;
129 istream_class->close_finish = g_memory_input_stream_close_finish;
133 g_memory_input_stream_finalize (GObject *object)
135 GMemoryInputStream *stream;
137 stream = G_MEMORY_INPUT_STREAM (object);
139 if (stream->priv->free_data)
140 g_free (stream->priv->buffer);
142 if (G_OBJECT_CLASS (g_memory_input_stream_parent_class)->finalize)
143 (*G_OBJECT_CLASS (g_memory_input_stream_parent_class)->finalize) (object);
147 g_memory_input_stream_seekable_iface_init (GSeekableIface *iface)
149 iface->tell = g_memory_input_stream_tell;
150 iface->can_seek = g_memory_input_stream_can_seek;
151 iface->seek = g_memory_input_stream_seek;
152 iface->can_truncate = g_memory_input_stream_can_truncate;
153 iface->truncate = g_memory_input_stream_truncate;
157 g_memory_input_stream_init (GMemoryInputStream *stream)
159 stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
160 G_TYPE_MEMORY_INPUT_STREAM,
161 GMemoryInputStreamPrivate);
165 * g_memory_input_stream_set_free_data:
171 g_memory_input_stream_set_free_data (GMemoryInputStream *stream,
174 g_return_if_fail (G_IS_MEMORY_INPUT_STREAM (stream));
176 stream->priv->free_data = free_data;
180 * g_memory_input_stream_from_data:
182 * @len: length of the data.
184 * Returns: new #GInputStream read from @data of @len bytes.
187 g_memory_input_stream_from_data (const void *data, gssize len)
189 GInputStream *stream;
190 GMemoryInputStream *memory_stream;
192 g_return_val_if_fail (data != NULL, NULL);
194 stream = g_object_new (G_TYPE_MEMORY_INPUT_STREAM, NULL);
195 memory_stream = G_MEMORY_INPUT_STREAM (stream);
200 memory_stream->priv->buffer = (guint8 *)data;
201 memory_stream->priv->len = len;
207 g_memory_input_stream_read (GInputStream *stream,
210 GCancellable *cancellable,
213 GMemoryInputStream *memory_stream;
214 GMemoryInputStreamPrivate * priv;
216 memory_stream = G_MEMORY_INPUT_STREAM (stream);
217 priv = memory_stream->priv;
219 count = MIN (count, priv->len - priv->pos);
220 memcpy (buffer, priv->buffer + priv->pos, count);
227 * g_memory_input_stream_get_data:
233 g_memory_input_stream_get_data (GMemoryInputStream *stream)
235 g_return_val_if_fail (G_IS_MEMORY_INPUT_STREAM (stream), NULL);
237 return stream->priv->buffer;
241 * g_memory_input_stream_get_data_size:
247 g_memory_input_stream_get_data_size (GMemoryInputStream *stream)
249 g_return_val_if_fail (G_IS_MEMORY_INPUT_STREAM (stream), -1);
251 return stream->priv->len;
255 g_memory_input_stream_skip (GInputStream *stream,
257 GCancellable *cancellable,
260 GMemoryInputStream *memory_stream;
261 GMemoryInputStreamPrivate *priv;
263 memory_stream = G_MEMORY_INPUT_STREAM (stream);
264 priv = memory_stream->priv;
266 count = MIN (count, priv->len - priv->pos);
275 g_memory_input_stream_close (GInputStream *stream,
276 GCancellable *cancellable,
283 g_memory_input_stream_read_async (GInputStream *stream,
287 GCancellable *cancellable,
288 GAsyncReadyCallback callback,
291 GSimpleAsyncResult *simple;
294 nread = g_memory_input_stream_read (stream, buffer, count, cancellable, NULL);
295 simple = g_simple_async_result_new (G_OBJECT (stream),
298 g_memory_input_stream_read_async);
299 g_simple_async_result_set_op_res_gssize (simple, nread);
300 g_simple_async_result_complete_in_idle (simple);
301 g_object_unref (simple);
305 g_memory_input_stream_read_finish (GInputStream *stream,
306 GAsyncResult *result,
309 GSimpleAsyncResult *simple;
312 simple = G_SIMPLE_ASYNC_RESULT (result);
313 g_assert (g_simple_async_result_get_source_tag (simple) == g_memory_input_stream_read_async);
315 nread = g_simple_async_result_get_op_res_gssize (simple);
320 g_memory_input_stream_skip_async (GInputStream *stream,
323 GCancellable *cancellable,
324 GAsyncReadyCallback callback,
327 GSimpleAsyncResult *simple;
330 nskipped = g_memory_input_stream_skip (stream, count, cancellable, NULL);
331 simple = g_simple_async_result_new (G_OBJECT (stream),
334 g_memory_input_stream_skip_async);
335 g_simple_async_result_set_op_res_gssize (simple, nskipped);
336 g_simple_async_result_complete_in_idle (simple);
337 g_object_unref (simple);
341 g_memory_input_stream_skip_finish (GInputStream *stream,
342 GAsyncResult *result,
345 GSimpleAsyncResult *simple;
348 simple = G_SIMPLE_ASYNC_RESULT (result);
349 g_assert (g_simple_async_result_get_source_tag (simple) == g_memory_input_stream_skip_async);
351 nskipped = g_simple_async_result_get_op_res_gssize (simple);
356 g_memory_input_stream_close_async (GInputStream *stream,
358 GCancellable *cancellable,
359 GAsyncReadyCallback callback,
362 GSimpleAsyncResult *simple;
364 simple = g_simple_async_result_new (G_OBJECT (stream),
367 g_memory_input_stream_close_async);
368 g_simple_async_result_complete_in_idle (simple);
369 g_object_unref (simple);
373 g_memory_input_stream_close_finish (GInputStream *stream,
374 GAsyncResult *result,
381 g_memory_input_stream_tell (GSeekable *seekable)
383 GMemoryInputStream *memory_stream;
384 GMemoryInputStreamPrivate * priv;
386 memory_stream = G_MEMORY_INPUT_STREAM (seekable);
387 priv = memory_stream->priv;
393 gboolean g_memory_input_stream_can_seek (GSeekable *seekable)
399 g_memory_input_stream_seek (GSeekable *seekable,
402 GCancellable *cancellable,
405 GMemoryInputStream *memory_stream;
406 GMemoryInputStreamPrivate * priv;
409 memory_stream = G_MEMORY_INPUT_STREAM (seekable);
410 priv = memory_stream->priv;
415 absolute = priv->pos + offset;
423 absolute = priv->len + offset;
429 G_IO_ERROR_INVALID_ARGUMENT,
430 "Invalid GSeekType supplied");
435 if (absolute < 0 || absolute > priv->len)
439 G_IO_ERROR_INVALID_ARGUMENT,
440 "Invalid seek request");
444 priv->pos = absolute;
450 g_memory_input_stream_can_truncate (GSeekable *seekable)
456 g_memory_input_stream_truncate (GSeekable *seekable,
458 GCancellable *cancellable,
463 G_IO_ERROR_NOT_SUPPORTED,
464 "Cannot seek on GMemoryInputStream");
468 /* vim: ts=2 sw=2 et */