2 * MIO, an I/O abstraction layer replicating C file I/O API.
3 * Copyright (C) 2010 Colomban Wendling <ban@herbesfolles.org>
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program 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
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 /* Hack to force ANSI compliance by not using va_copy() even if present.
22 * This relies on the fact G_VA_COPY is maybe defined as va_copy in
23 * glibconfig.h, so we undef it, but gutils.h takes care of defining a
24 * compiler-specific implementation if not already defined.
25 * This needs to come before any other GLib inclusion. */
27 # include <glibconfig.h>
33 #include "mio-memory.c"
45 * @short_description: The MIO object
48 * The #MIO object replicates the C file I/O API with support of both standard
49 * file based operations and in-memory operations. Its goal is to ease the port
50 * of an application that uses C file I/O API to perform in-memory operations.
52 * A #MIO object is created using mio_new_file() or mio_new_memory(), depending
53 * on whether you want file or in-memory operations, and destroyed using
54 * mio_free(). There is also some other convenient API to create file-based
55 * #MIO objects for more complex cases, such as mio_new_file_full() and
58 * Once the #MIO object is created, you can perform standard I/O operations on
59 * it transparently without the need to care about the effective underlying
62 * The I/O API is almost exactly a replication of the standard C file I/O API
63 * with the significant difference that the first parameter is always the #MIO
70 * @filename: Filename to open, passed as-is to @open_func as the first argument
71 * @mode: Mode in which open the file, passed as-is to @open_func as the second
73 * @open_func: A function with the fopen() semantic to use to open the file
74 * @close_func: A function with the fclose() semantic to close the file when
75 * the #MIO object is destroyed, or %NULL not to close the #FILE
78 * Creates a new #MIO object working on a file, from a filename and an opening
79 * function. See also mio_new_file().
81 * This function is generally overkill and mio_new_file() should often be used
82 * instead, but it allows to specify a custom function to open a file, as well
83 * as a close function. The former is useful e.g. if you need to wrap fopen()
84 * for some reason (like filename encoding conversion for example), and the
85 * latter allows you both to match your custom open function and to choose
86 * whether the underlying #FILE object should or not be closed when mio_free()
87 * is called on the returned object.
89 * Free-function: mio_free()
91 * Returns: A new #MIO on success, or %NULL on failure.
94 mio_new_file_full (const gchar
*filename
,
96 MIOFOpenFunc open_func
,
97 MIOFCloseFunc close_func
)
101 /* we need to create the MIO object first, because we may not be able to close
102 * the opened file if the user passed NULL as the close function, which means
103 * that everything must succeed if we've opened the file successfully */
104 mio
= g_slice_alloc (sizeof *mio
);
106 FILE *fp
= open_func (filename
, mode
);
109 g_slice_free1 (sizeof *mio
, mio
);
112 mio
->type
= MIO_TYPE_FILE
;
113 mio
->impl
.file
.fp
= fp
;
114 mio
->impl
.file
.close_func
= close_func
;
115 /* function table filling */
116 FILE_SET_VTABLE (mio
);
125 * @filename: Filename to open, same as the fopen()'s first argument
126 * @mode: Mode in which open the file, fopen()'s second argument
128 * Creates a new #MIO object working on a file from a filename; wrapping
130 * This function simply calls mio_new_file_full() with the libc's fopen() and
131 * fclose() functions.
133 * Free-function: mio_free()
135 * Returns: A new #MIO on success, or %NULL on failure.
138 mio_new_file (const gchar
*filename
,
141 return mio_new_file_full (filename
, mode
, fopen
, fclose
);
146 * @fp: An opened #FILE object
147 * @close_func: (allow-none): Function used to close @fp when the #MIO object
148 * gets destroyed, or %NULL not to close the #FILE object
150 * Creates a new #MIO object working on a file, from an already opened #FILE
154 * <title>Typical use of this function</title>
156 * MIO *mio = mio_new_fp (fp, fclose);
160 * Free-function: mio_free()
162 * Returns: A new #MIO on success or %NULL on failure.
165 mio_new_fp (FILE *fp
,
166 MIOFCloseFunc close_func
)
170 mio
= g_slice_alloc (sizeof *mio
);
172 mio
->type
= MIO_TYPE_FILE
;
173 mio
->impl
.file
.fp
= fp
;
174 mio
->impl
.file
.close_func
= close_func
;
175 /* function table filling */
176 FILE_SET_VTABLE (mio
);
184 * @data: Initial data (may be %NULL)
185 * @size: Length of @data in bytes
186 * @realloc_func: A function with the realloc() semantic used to grow the
187 * buffer, or %NULL to disable buffer growing
188 * @free_func: A function with the free() semantic to destroy the data together
189 * with the object, or %NULL not to destroy the data
191 * Creates a new #MIO object working on memory.
193 * To allow the buffer to grow, you must provide a @realloc_func, otherwise
194 * trying to write after the end of the current data will fail.
196 * If you want the buffer to be freed together with the #MIO object, you must
197 * give a @free_func; otherwise the data will still live after #MIO object
201 * <title>Basic creation of a non-growable, freeable #MIO object</title>
203 * MIO *mio = mio_new_memory (data, size, NULL, g_free);
208 * <title>Basic creation of an empty growable and freeable #MIO object</title>
210 * MIO *mio = mio_new_memory (NULL, 0, g_try_realloc, g_free);
214 * Free-function: mio_free()
216 * Returns: A new #MIO on success, or %NULL on failure.
219 mio_new_memory (guchar
*data
,
221 MIOReallocFunc realloc_func
,
222 GDestroyNotify free_func
)
226 mio
= g_slice_alloc (sizeof *mio
);
228 mio
->type
= MIO_TYPE_MEMORY
;
229 mio
->impl
.mem
.buf
= data
;
230 mio
->impl
.mem
.ungetch
= EOF
;
231 mio
->impl
.mem
.pos
= 0;
232 mio
->impl
.mem
.size
= size
;
233 mio
->impl
.mem
.allocated_size
= size
;
234 mio
->impl
.mem
.realloc_func
= realloc_func
;
235 mio
->impl
.mem
.free_func
= free_func
;
236 mio
->impl
.mem
.eof
= FALSE
;
237 mio
->impl
.mem
.error
= FALSE
;
238 /* function table filling */
239 MEM_SET_VTABLE (mio
);
247 * @mio: A #MIO object
249 * Gets the underlying #FILE object associated with a #MIO file stream.
251 * <warning><para>The returned object may become invalid after a call to
252 * mio_free() if the stream was configured to close the file when
253 * destroyed.</para></warning>
255 * Returns: The underlying #FILE object of the given stream, or %NULL if the
256 * stream is not a file stream.
259 mio_file_get_fp (MIO
*mio
)
263 if (mio
->type
== MIO_TYPE_FILE
) {
264 fp
= mio
->impl
.file
.fp
;
271 * mio_memory_get_data:
272 * @mio: A #MIO object
273 * @size: (allow-none) (out): Return location for the length of the returned
276 * Gets the underlying memory buffer associated with a #MIO memory stream.
278 * <warning><para>The returned pointer and size may become invalid after a
279 * successful write on the stream or after a call to mio_free() if the stream
280 * was configured to free the memory when destroyed.</para></warning>
282 * Returns: The memory buffer of the given #MIO stream, or %NULL if the stream
283 * is not a memory stream.
286 mio_memory_get_data (MIO
*mio
,
291 if (mio
->type
== MIO_TYPE_MEMORY
) {
292 ptr
= mio
->impl
.mem
.buf
;
293 if (size
) *size
= mio
->impl
.mem
.size
;
301 * @mio: A #MIO object
303 * Destroys a #MIO object.
310 g_slice_free1 (sizeof *mio
, mio
);
316 * @mio: A #MIO object
317 * @ptr: Pointer to the memory to fill with the read data
318 * @size: Size of each block to read
319 * @nmemb: Number o blocks to read
321 * Reads raw data from a #MIO stream. This function behave the same as fread().
323 * Returns: The number of actually read blocks. If an error occurs or if the
324 * end of the stream is reached, the return value may be smaller than
325 * the requested block count, or even 0. This function doesn't
326 * distinguish between end-of-stream and an error, you should then use
327 * mio_eof() and mio_error() to determine which occurred.
335 return mio
->v_read (mio
, ptr
, size
, nmemb
);
340 * @mio: A #MIO object
341 * @ptr: Pointer to the memory to write on the stream
342 * @size: Size of each block to write
343 * @nmemb: Number of block to write
345 * Writes raw data to a #MIO stream. This function behaves the same as fwrite().
347 * Returns: The number of blocks actually written to the stream. This might be
348 * smaller than the requested count if a write error occurs.
356 return mio
->v_write (mio
, ptr
, size
, nmemb
);
361 * @mio: A #MIO object
362 * @c: The character to write
364 * Writes a character to a #MIO stream. This function behaves the same as
367 * Returns: The written wharacter, or %EOF on error.
373 return mio
->v_putc (mio
, c
);
378 * @mio: A #MIO object
379 * @s: The string to write
381 * Writes a string to a #MIO object. This function behaves the same as fputs().
383 * Returns: A non-negative integer on success or %EOF on failure.
389 return mio
->v_puts (mio
, s
);
394 * @mio: A #MIO object
395 * @format: A printf fomrat string
396 * @ap: The variadic argument list for the format
398 * Writes a formatted string into a #MIO stream. This function behaves the same
401 * Returns: The number of bytes written in the stream, or a negative value on
405 mio_vprintf (MIO
*mio
,
409 return mio
->v_vprintf (mio
, format
, ap
);
414 * @mio: A #MIO object
415 * @format: A print format string
416 * @...: Arguments of the format
418 * Writes a formatted string to a #MIO stream. This function behaves the same as
421 * Returns: The number of bytes written to the stream, or a negative value on
425 mio_printf (MIO
*mio
,
432 va_start (ap
, format
);
433 rv
= mio
->v_vprintf (mio
, format
, ap
);
441 * @mio: A #MIO object
443 * Gets the current character from a #MIO stream. This function behaves the same
446 * Returns: The read character as a #gint, or %EOF on error.
451 return mio
->v_getc (mio
);
456 * @mio: A #MIO object
457 * @ch: Character to put back in the stream
459 * Puts a character back in a #MIO stream. This function behaves the sames as
462 * <warning><para>It is only guaranteed that one character can be but back at a
463 * time, even if the implementation may allow more.</para></warning>
464 * <warning><para>Using this function while the stream cursor is at offset 0 is
465 * not guaranteed to function properly. As the C99 standard says, it is "an
466 * obsolescent feature".</para></warning>
468 * Returns: The character put back, or %EOF on error.
471 mio_ungetc (MIO
*mio
,
474 return mio
->v_ungetc (mio
, ch
);
479 * @mio: A #MIO object
480 * @s: A string to fill with the read data
481 * @size: The maximum number of bytes to read
483 * Reads a string from a #MIO stream, stopping after the first new-line
484 * character or at the end of the stream. This function behaves the same as
487 * Returns: @s on success, %NULL otherwise.
494 return mio
->v_gets (mio
, s
, size
);
499 * @mio: A #MIO object
501 * Clears the error and end-of-stream indicators of a #MIO stream. This function
502 * behaves the same as clearerr().
505 mio_clearerr (MIO
*mio
)
507 mio
->v_clearerr (mio
);
512 * @mio: A #MIO object
514 * Checks whether the end-of-stream indicator of a #MIO stream is set. This
515 * function behaves the same as feof().
517 * Returns: A non-null value if the stream reached its end, 0 otherwise.
522 return mio
->v_eof (mio
);
527 * @mio: A #MIO object
529 * Checks whether the error indicator of a #MIO stream is set. This function
530 * behaves the same as ferror().
532 * Returns: A non-null value if the stream have an error set, 0 otherwise.
537 return mio
->v_error (mio
);
542 * @mio: A #MIO object
543 * @offset: Offset of the new place, from @whence
544 * @whence: Move origin. SEEK_SET moves relative to the start of the stream,
545 * SEEK_CUR from the current position and SEEK_SET from the end of the
548 * Sets the curosr position on a #MIO stream. This functions behaves the same as
549 * fseek(). See also mio_tell() and mio_setpos().
551 * Returns: 0 on success, -1 otherwise, in which case errno should be set to
552 * indicate the error.
559 return mio
->v_seek (mio
, offset
, whence
);
564 * @mio: A #MIO object
566 * Gets the current cursor position of a #MIO stream. This function behaves the
569 * Returns: The current offset from the start of the stream, or -1 or error, in
570 * which case errno is set to indicate the error.
575 return mio
->v_tell (mio
);
580 * @mio: A #MIO object
582 * Resets the cursor position to 0, and also the end-of-stream and the error
583 * indicators of a #MIO stream.
584 * See also mio_seek() and mio_clearerr().
587 mio_rewind (MIO
*mio
)
594 * @mio: A #MIO stream
595 * @pos: (out): A #MIOPos object to fill-in
597 * Stores the current position (and maybe other informations about the stream
598 * state) of a #MIO stream in order to restore it later with mio_setpos(). This
599 * function behaves the same as fgetpos().
601 * Returns: 0 on success, -1 otherwise, in which case errno is set to indicate
605 mio_getpos (MIO
*mio
,
610 pos
->type
= mio
->type
;
611 rv
= mio
->v_getpos (mio
, pos
);
616 #endif /* MIO_DEBUG */
623 * @mio: A #MIO object
624 * @pos: (in): A #MIOPos object filled-in by a previous call of mio_getpos() on
627 * Restores the position and state indicators of a #MIO stream previously saved
630 * <warning><para>The #MIOPos object must have been initialized by a previous
631 * call to mio_getpos() on the same stream.</para></warning>
633 * Returns: 0 on success, -1 otherwise, in which case errno is set to indicate
637 mio_setpos (MIO
*mio
,
643 if (pos
->tag
!= mio
) {
644 g_critical ("mio_setpos((MIO*)%p, (MIOPos*)%p): "
645 "Given MIOPos was not set by a previous call to mio_getpos() "
646 "on the same MIO object, which means there is a bug in "
648 (void *)mio
, (void *)pos
);
652 #endif /* MIO_DEBUG */
653 rv
= mio
->v_setpos (mio
, pos
);