Fix up includes in section docs
[platform/upstream/glib.git] / gio / gmemoryinputstream.c
1 /* GIO - GLib Input, Output and Streaming Library
2  * 
3  * Copyright (C) 2006-2007 Red Hat, Inc.
4  *
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.
9  *
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.
14  *
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.
19  *
20  * Author: Christian Kellner <gicmo@gnome.org> 
21  */
22
23 #include <config.h>
24 #include "gmemoryinputstream.h"
25 #include "ginputstream.h"
26 #include "gseekable.h"
27 #include "string.h"
28 #include "gsimpleasyncresult.h"
29 #include "glibintl.h"
30
31 #include "gioalias.h"
32
33 /**
34  * SECTION:gmemoryinputstream
35  * @short_description: Streaming input operations on memory chunks
36  * @include: gio.h
37  * @see_also: #GMemoryOutputStream
38  *
39  * #GMemoryInputStream is a class for using arbitrary
40  * memory chunks as input for GIO streaming input operations.
41  *
42  */
43
44 struct _GMemoryInputStreamPrivate {
45   guint8 *buffer;      
46   gsize   pos;
47   gsize   len;
48   gboolean free_data;
49 };
50
51 static gssize   g_memory_input_stream_read         (GInputStream         *stream,
52                                                     void                 *buffer,
53                                                     gsize                 count,
54                                                     GCancellable         *cancellable,
55                                                     GError              **error);
56 static gssize   g_memory_input_stream_skip         (GInputStream         *stream,
57                                                     gsize                 count,
58                                                     GCancellable         *cancellable,
59                                                     GError              **error);
60 static gboolean g_memory_input_stream_close        (GInputStream         *stream,
61                                                     GCancellable         *cancellable,
62                                                     GError              **error);
63 static void     g_memory_input_stream_read_async   (GInputStream         *stream,
64                                                     void                 *buffer,
65                                                     gsize                 count,
66                                                     int                   io_priority,
67                                                     GCancellable         *cancellable,
68                                                     GAsyncReadyCallback   callback,
69                                                     gpointer              user_data);
70 static gssize   g_memory_input_stream_read_finish  (GInputStream         *stream,
71                                                     GAsyncResult         *result,
72                                                     GError              **error);
73 static void     g_memory_input_stream_skip_async   (GInputStream         *stream,
74                                                     gsize                 count,
75                                                     int                   io_priority,
76                                                     GCancellable         *cancellabl,
77                                                     GAsyncReadyCallback   callback,
78                                                     gpointer              datae);
79 static gssize   g_memory_input_stream_skip_finish  (GInputStream         *stream,
80                                                     GAsyncResult         *result,
81                                                     GError              **error);
82 static void     g_memory_input_stream_close_async  (GInputStream         *stream,
83                                                     int                   io_priority,
84                                                     GCancellable         *cancellabl,
85                                                     GAsyncReadyCallback   callback,
86                                                     gpointer              data);
87 static gboolean g_memory_input_stream_close_finish (GInputStream         *stream,
88                                                     GAsyncResult         *result,
89                                                     GError              **error);
90
91 static void     g_memory_input_stream_seekable_iface_init (GSeekableIface  *iface);
92 static goffset  g_memory_input_stream_tell                (GSeekable       *seekable);
93 static gboolean g_memory_input_stream_can_seek            (GSeekable       *seekable);
94 static gboolean g_memory_input_stream_seek                (GSeekable       *seekable,
95                                                            goffset          offset,
96                                                            GSeekType        type,
97                                                            GCancellable    *cancellable,
98                                                            GError         **error);
99 static gboolean g_memory_input_stream_can_truncate        (GSeekable       *seekable);
100 static gboolean g_memory_input_stream_truncate            (GSeekable       *seekable,
101                                                            goffset          offset,
102                                                            GCancellable    *cancellable,
103                                                            GError         **error);
104 static void     g_memory_input_stream_finalize            (GObject         *object);
105
106 G_DEFINE_TYPE_WITH_CODE (GMemoryInputStream, g_memory_input_stream, G_TYPE_INPUT_STREAM,
107                          G_IMPLEMENT_INTERFACE (G_TYPE_SEEKABLE,
108                                                 g_memory_input_stream_seekable_iface_init))
109
110
111 static void
112 g_memory_input_stream_class_init (GMemoryInputStreamClass *klass)
113 {
114   GObjectClass *object_class;
115   GInputStreamClass *istream_class;
116
117   g_type_class_add_private (klass, sizeof (GMemoryInputStreamPrivate));
118
119   object_class = G_OBJECT_CLASS (klass);
120   object_class->finalize     = g_memory_input_stream_finalize;
121   
122   istream_class = G_INPUT_STREAM_CLASS (klass);
123   istream_class->read_fn  = g_memory_input_stream_read;
124   istream_class->skip  = g_memory_input_stream_skip;
125   istream_class->close_fn = g_memory_input_stream_close;
126
127   istream_class->read_async  = g_memory_input_stream_read_async;
128   istream_class->read_finish  = g_memory_input_stream_read_finish;
129   istream_class->skip_async  = g_memory_input_stream_skip_async;
130   istream_class->skip_finish  = g_memory_input_stream_skip_finish;
131   istream_class->close_async = g_memory_input_stream_close_async;
132   istream_class->close_finish = g_memory_input_stream_close_finish;
133 }
134
135 static void
136 g_memory_input_stream_finalize (GObject *object)
137 {
138   GMemoryInputStream        *stream;
139
140   stream = G_MEMORY_INPUT_STREAM (object);
141
142   if (stream->priv->free_data)
143     g_free (stream->priv->buffer);
144
145   if (G_OBJECT_CLASS (g_memory_input_stream_parent_class)->finalize)
146     (*G_OBJECT_CLASS (g_memory_input_stream_parent_class)->finalize) (object);
147 }
148
149 static void
150 g_memory_input_stream_seekable_iface_init (GSeekableIface *iface)
151 {
152   iface->tell         = g_memory_input_stream_tell;
153   iface->can_seek     = g_memory_input_stream_can_seek;
154   iface->seek         = g_memory_input_stream_seek;
155   iface->can_truncate = g_memory_input_stream_can_truncate;
156   iface->truncate_fn  = g_memory_input_stream_truncate;
157 }
158
159 static void
160 g_memory_input_stream_init (GMemoryInputStream *stream)
161 {
162   stream->priv = G_TYPE_INSTANCE_GET_PRIVATE (stream,
163                                               G_TYPE_MEMORY_INPUT_STREAM,
164                                               GMemoryInputStreamPrivate);
165 }
166
167 /**
168  * g_memory_input_stream_set_free_data:
169  * @stream: a #GMemoryInputStream.
170  * @free_data: a #gboolean. If %TRUE, frees the data within @stream.
171  * 
172  * Sets if the data within the @stream should be freed when the stream 
173  * is freed. 
174  **/
175 void
176 g_memory_input_stream_set_free_data (GMemoryInputStream *stream,
177                                      gboolean            free_data)
178 {
179   g_return_if_fail (G_IS_MEMORY_INPUT_STREAM (stream));
180
181   stream->priv->free_data = free_data;
182 }
183
184 /**
185  * g_memory_input_stream_from_data:
186  * @data: input data.
187  * @len: length of the data.
188  *
189  * Creates a new #GMemoryInputStream with data in memory of a given size.
190  * 
191  * Returns: new #GInputStream read from @data of @len bytes.
192  **/
193 GInputStream *
194 g_memory_input_stream_from_data (const void *data, 
195                                  gssize      len)
196 {
197   GInputStream *stream;
198   GMemoryInputStream *memory_stream;
199
200   g_return_val_if_fail (data != NULL, NULL);
201
202   stream = g_object_new (G_TYPE_MEMORY_INPUT_STREAM, NULL);
203   memory_stream = G_MEMORY_INPUT_STREAM (stream);
204
205   if (len == -1)
206     len = strlen (data);
207   
208   memory_stream->priv->buffer = (guint8 *)data;
209   memory_stream->priv->len = len;
210
211   return stream;
212 }
213
214 static gssize
215 g_memory_input_stream_read (GInputStream  *stream,
216                             void          *buffer,
217                             gsize          count,
218                             GCancellable  *cancellable,
219                             GError       **error)
220 {
221   GMemoryInputStream *memory_stream;
222   GMemoryInputStreamPrivate * priv;
223
224   memory_stream = G_MEMORY_INPUT_STREAM (stream);
225   priv = memory_stream->priv;
226
227   count = MIN (count, priv->len - priv->pos);
228   memcpy (buffer, priv->buffer + priv->pos, count);
229   priv->pos += count;
230
231   return count;
232 }
233
234 /**
235  * g_memory_input_stream_get_data:
236  * @stream: a #GMemoryInputStream
237  * 
238  * Gets a pointer to the data within the #GMemoryInputStream.
239  *
240  * Returns: a pointer to the memory in the @stream.
241  **/
242 const void *
243 g_memory_input_stream_get_data (GMemoryInputStream *stream)
244 {
245   g_return_val_if_fail (G_IS_MEMORY_INPUT_STREAM (stream), NULL);
246
247   return stream->priv->buffer;
248 }
249
250 /**
251  * g_memory_input_stream_get_data_size:
252  * @stream: a #GMemoryInputStream
253  * 
254  * Gets the size of the data within the #GMemoryInputStream.
255  *
256  * Returns: a gsize with the size of the data in @stream.
257  **/
258 gsize
259 g_memory_input_stream_get_data_size (GMemoryInputStream *stream)
260 {
261   g_return_val_if_fail (G_IS_MEMORY_INPUT_STREAM (stream), -1);
262
263   return stream->priv->len;
264 }
265
266 static gssize
267 g_memory_input_stream_skip (GInputStream  *stream,
268                             gsize          count,
269                             GCancellable  *cancellable,
270                             GError       **error)
271 {
272   GMemoryInputStream *memory_stream;
273   GMemoryInputStreamPrivate *priv;
274
275   memory_stream = G_MEMORY_INPUT_STREAM (stream);
276   priv = memory_stream->priv;
277
278   count = MIN (count, priv->len - priv->pos);
279   priv->pos += count;
280
281   return count;
282  
283
284 }
285
286 static gboolean
287 g_memory_input_stream_close (GInputStream  *stream,
288                              GCancellable  *cancellable,
289                              GError       **error)
290 {
291   return TRUE;
292 }
293
294 static void
295 g_memory_input_stream_read_async (GInputStream        *stream,
296                                   void                *buffer,
297                                   gsize                count,
298                                   int                  io_priority,
299                                   GCancellable        *cancellable,
300                                   GAsyncReadyCallback  callback,
301                                   gpointer             user_data)
302 {
303   GSimpleAsyncResult *simple;
304   gssize nread;
305
306   nread =  g_memory_input_stream_read (stream,  buffer, count, cancellable, NULL);
307   simple = g_simple_async_result_new (G_OBJECT (stream),
308                                       callback,
309                                       user_data,
310                                       g_memory_input_stream_read_async);
311   g_simple_async_result_set_op_res_gssize (simple, nread);
312   g_simple_async_result_complete_in_idle (simple);
313   g_object_unref (simple);
314 }
315
316 static gssize
317 g_memory_input_stream_read_finish (GInputStream  *stream,
318                                    GAsyncResult  *result,
319                                    GError       **error)
320 {
321   GSimpleAsyncResult *simple;
322   gssize nread;
323
324   simple = G_SIMPLE_ASYNC_RESULT (result);
325   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_memory_input_stream_read_async);
326   
327   nread = g_simple_async_result_get_op_res_gssize (simple);
328   return nread;
329 }
330
331 static void
332 g_memory_input_stream_skip_async (GInputStream        *stream,
333                                   gsize                count,
334                                   int                  io_priority,
335                                   GCancellable        *cancellable,
336                                   GAsyncReadyCallback  callback,
337                                   gpointer             user_data)
338 {
339   GSimpleAsyncResult *simple;
340   gssize nskipped;
341
342   nskipped = g_memory_input_stream_skip (stream, count, cancellable, NULL);
343   simple = g_simple_async_result_new (G_OBJECT (stream),
344                                       callback,
345                                       user_data,
346                                       g_memory_input_stream_skip_async);
347   g_simple_async_result_set_op_res_gssize (simple, nskipped);
348   g_simple_async_result_complete_in_idle (simple);
349   g_object_unref (simple);
350 }
351
352 static gssize
353 g_memory_input_stream_skip_finish (GInputStream  *stream,
354                                    GAsyncResult  *result,
355                                    GError       **error)
356 {
357   GSimpleAsyncResult *simple;
358   gssize nskipped;
359
360   simple = G_SIMPLE_ASYNC_RESULT (result);
361   g_warn_if_fail (g_simple_async_result_get_source_tag (simple) == g_memory_input_stream_skip_async);
362   
363   nskipped = g_simple_async_result_get_op_res_gssize (simple);
364   return nskipped;
365 }
366
367 static void
368 g_memory_input_stream_close_async (GInputStream        *stream,
369                                    int                  io_priority,
370                                    GCancellable        *cancellable,
371                                    GAsyncReadyCallback  callback,
372                                    gpointer             user_data)
373 {
374   GSimpleAsyncResult *simple;
375   
376   simple = g_simple_async_result_new (G_OBJECT (stream),
377                                       callback,
378                                       user_data,
379                                       g_memory_input_stream_close_async);
380   g_simple_async_result_complete_in_idle (simple);
381   g_object_unref (simple);
382 }
383
384 static gboolean
385 g_memory_input_stream_close_finish (GInputStream  *stream,
386                                     GAsyncResult  *result,
387                                     GError       **error)
388 {
389   return TRUE;
390 }
391
392 static goffset
393 g_memory_input_stream_tell (GSeekable *seekable)
394 {
395   GMemoryInputStream *memory_stream;
396   GMemoryInputStreamPrivate * priv;
397
398   memory_stream = G_MEMORY_INPUT_STREAM (seekable);
399   priv = memory_stream->priv;
400
401   return priv->pos;
402 }
403
404 static
405 gboolean g_memory_input_stream_can_seek (GSeekable *seekable)
406 {
407   return TRUE;
408 }
409
410 static gboolean
411 g_memory_input_stream_seek (GSeekable     *seekable,
412                             goffset        offset,
413                             GSeekType      type,
414                             GCancellable  *cancellable,
415                             GError       **error)
416 {
417   GMemoryInputStream *memory_stream;
418   GMemoryInputStreamPrivate * priv;
419   goffset absolute;
420
421   memory_stream = G_MEMORY_INPUT_STREAM (seekable);
422   priv = memory_stream->priv;
423
424   switch (type) 
425     {
426     case G_SEEK_CUR:
427       absolute = priv->pos + offset;
428       break;
429
430     case G_SEEK_SET:
431       absolute = offset;
432       break;
433
434     case G_SEEK_END:
435       absolute = priv->len + offset;
436       break;
437   
438     default:
439       g_set_error (error,
440                    G_IO_ERROR,
441                    G_IO_ERROR_INVALID_ARGUMENT,
442                    "Invalid GSeekType supplied");
443
444       return FALSE;
445     }
446
447   if (absolute < 0 || absolute > priv->len)
448     {
449       g_set_error (error,
450                    G_IO_ERROR,
451                    G_IO_ERROR_INVALID_ARGUMENT,
452                    "Invalid seek request");
453       return FALSE;
454     }
455
456   priv->pos = absolute;
457
458   return TRUE;
459 }
460
461 static gboolean
462 g_memory_input_stream_can_truncate (GSeekable *seekable)
463 {
464   return FALSE;
465 }
466
467 static gboolean
468 g_memory_input_stream_truncate (GSeekable     *seekable,
469                                 goffset        offset,
470                                 GCancellable  *cancellable,
471                                 GError       **error)
472 {
473   g_set_error (error,
474                G_IO_ERROR,
475                G_IO_ERROR_NOT_SUPPORTED,
476                "Cannot seek on GMemoryInputStream");
477   return FALSE;
478 }
479
480 #define __G_MEMORY_INPUT_STREAM_C__
481 #include "gioaliasdef.c"