GTK: Fix auto-completion popup sizing on some themes
[geany-mirror.git] / tagmanager / mio / mio.c
blob8bf5512064295c860ec5caa1cf402c3fb8a85372
1 /*
2 * MIO, an I/O abstraction layer replicating C file I/O API.
3 * Copyright (C) 2010 Colomban Wendling <ban@herbesfolles.org>
4 *
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.
9 *
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. */
26 #ifdef MIO_FORCE_ANSI
27 # include <glibconfig.h>
28 # undef G_VA_COPY
29 #endif
31 #include "mio.h"
32 #include "mio-file.c"
33 #include "mio-memory.c"
35 #include <glib.h>
36 #include <stdarg.h>
37 #include <stdio.h>
38 #include <string.h>
39 #include <errno.h>
43 /**
44 * SECTION:mio
45 * @short_description: The MIO object
46 * @include: mio/mio.h
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
56 * mio_new_fp().
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
60 * operations.
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
64 * object to work on.
68 /**
69 * mio_new_file_full:
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
72 * argument
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
76 * object
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.
93 MIO *
94 mio_new_file_full (const gchar *filename,
95 const gchar *mode,
96 MIOFOpenFunc open_func,
97 MIOFCloseFunc close_func)
99 MIO *mio;
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);
105 if (mio) {
106 FILE *fp = open_func (filename, mode);
108 if (! fp) {
109 g_slice_free1 (sizeof *mio, mio);
110 mio = NULL;
111 } else {
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);
120 return mio;
124 * mio_new_file:
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
129 * fopen().
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.
137 MIO *
138 mio_new_file (const gchar *filename,
139 const gchar *mode)
141 return mio_new_file_full (filename, mode, fopen, fclose);
145 * mio_new_fp:
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
151 * object.
153 * <example>
154 * <title>Typical use of this function</title>
155 * <programlisting>
156 * MIO *mio = mio_new_fp (fp, fclose);
157 * </programlisting>
158 * </example>
160 * Free-function: mio_free()
162 * Returns: A new #MIO on success or %NULL on failure.
164 MIO *
165 mio_new_fp (FILE *fp,
166 MIOFCloseFunc close_func)
168 MIO *mio;
170 mio = g_slice_alloc (sizeof *mio);
171 if (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);
179 return mio;
183 * mio_new_memory:
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
198 * termination.
200 * <example>
201 * <title>Basic creation of a non-growable, freeable #MIO object</title>
202 * <programlisting>
203 * MIO *mio = mio_new_memory (data, size, NULL, g_free);
204 * </programlisting>
205 * </example>
207 * <example>
208 * <title>Basic creation of an empty growable and freeable #MIO object</title>
209 * <programlisting>
210 * MIO *mio = mio_new_memory (NULL, 0, g_try_realloc, g_free);
211 * </programlisting>
212 * </example>
214 * Free-function: mio_free()
216 * Returns: A new #MIO on success, or %NULL on failure.
218 MIO *
219 mio_new_memory (guchar *data,
220 gsize size,
221 MIOReallocFunc realloc_func,
222 GDestroyNotify free_func)
224 MIO *mio;
226 mio = g_slice_alloc (sizeof *mio);
227 if (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);
242 return mio;
246 * mio_file_get_fp:
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.
258 FILE *
259 mio_file_get_fp (MIO *mio)
261 FILE *fp = NULL;
263 if (mio->type == MIO_TYPE_FILE) {
264 fp = mio->impl.file.fp;
267 return fp;
271 * mio_memory_get_data:
272 * @mio: A #MIO object
273 * @size: (allow-none) (out): Return location for the length of the returned
274 * memory, or %NULL
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.
285 guchar *
286 mio_memory_get_data (MIO *mio,
287 gsize *size)
289 guchar *ptr = NULL;
291 if (mio->type == MIO_TYPE_MEMORY) {
292 ptr = mio->impl.mem.buf;
293 if (size) *size = mio->impl.mem.size;
296 return ptr;
300 * mio_free:
301 * @mio: A #MIO object
303 * Destroys a #MIO object.
305 void
306 mio_free (MIO *mio)
308 if (mio) {
309 mio->v_free (mio);
310 g_slice_free1 (sizeof *mio, mio);
315 * mio_read:
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.
329 gsize
330 mio_read (MIO *mio,
331 void *ptr,
332 gsize size,
333 gsize nmemb)
335 return mio->v_read (mio, ptr, size, nmemb);
339 * mio_write:
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.
350 gsize
351 mio_write (MIO *mio,
352 const void *ptr,
353 gsize size,
354 gsize nmemb)
356 return mio->v_write (mio, ptr, size, nmemb);
360 * mio_putc:
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
365 * fputc().
367 * Returns: The written wharacter, or %EOF on error.
369 gint
370 mio_putc (MIO *mio,
371 gint c)
373 return mio->v_putc (mio, c);
377 * mio_puts:
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.
385 gint
386 mio_puts (MIO *mio,
387 const gchar *s)
389 return mio->v_puts (mio, s);
393 * mio_vprintf:
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
399 * as vfprintf().
401 * Returns: The number of bytes written in the stream, or a negative value on
402 * failure.
404 gint
405 mio_vprintf (MIO *mio,
406 const gchar *format,
407 va_list ap)
409 return mio->v_vprintf (mio, format, ap);
413 * mio_printf:
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
419 * fprintf().
421 * Returns: The number of bytes written to the stream, or a negative value on
422 * failure.
424 gint
425 mio_printf (MIO *mio,
426 const gchar *format,
427 ...)
429 gint rv;
430 va_list ap;
432 va_start (ap, format);
433 rv = mio->v_vprintf (mio, format, ap);
434 va_end (ap);
436 return rv;
440 * mio_getc:
441 * @mio: A #MIO object
443 * Gets the current character from a #MIO stream. This function behaves the same
444 * as fgetc().
446 * Returns: The read character as a #gint, or %EOF on error.
448 gint
449 mio_getc (MIO *mio)
451 return mio->v_getc (mio);
455 * mio_ungetc:
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
460 * ungetc().
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.
470 gint
471 mio_ungetc (MIO *mio,
472 gint ch)
474 return mio->v_ungetc (mio, ch);
478 * mio_gets:
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
485 * fgets().
487 * Returns: @s on success, %NULL otherwise.
489 gchar *
490 mio_gets (MIO *mio,
491 gchar *s,
492 gsize size)
494 return mio->v_gets (mio, s, size);
498 * mio_clearerr:
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().
504 void
505 mio_clearerr (MIO *mio)
507 mio->v_clearerr (mio);
511 * mio_eof:
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.
519 gint
520 mio_eof (MIO *mio)
522 return mio->v_eof (mio);
526 * mio_error:
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.
534 gint
535 mio_error (MIO *mio)
537 return mio->v_error (mio);
541 * mio_seek:
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
546 * stream.
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.
554 gint
555 mio_seek (MIO *mio,
556 glong offset,
557 gint whence)
559 return mio->v_seek (mio, offset, whence);
563 * mio_tell:
564 * @mio: A #MIO object
566 * Gets the current cursor position of a #MIO stream. This function behaves the
567 * same as ftell().
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.
572 glong
573 mio_tell (MIO *mio)
575 return mio->v_tell (mio);
579 * mio_rewind:
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().
586 void
587 mio_rewind (MIO *mio)
589 mio->v_rewind (mio);
593 * mio_getpos:
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
602 * the error.
604 gint
605 mio_getpos (MIO *mio,
606 MIOPos *pos)
608 gint rv = -1;
610 pos->type = mio->type;
611 rv = mio->v_getpos (mio, pos);
612 #ifdef MIO_DEBUG
613 if (rv != -1) {
614 pos->tag = mio;
616 #endif /* MIO_DEBUG */
618 return rv;
622 * mio_setpos:
623 * @mio: A #MIO object
624 * @pos: (in): A #MIOPos object filled-in by a previous call of mio_getpos() on
625 * the same stream
627 * Restores the position and state indicators of a #MIO stream previously saved
628 * by mio_getpos().
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
634 * the error.
636 gint
637 mio_setpos (MIO *mio,
638 MIOPos *pos)
640 gint rv = -1;
642 #ifdef MIO_DEBUG
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 "
647 "someone's code.",
648 (void *)mio, (void *)pos);
649 errno = EINVAL;
650 return -1;
652 #endif /* MIO_DEBUG */
653 rv = mio->v_setpos (mio, pos);
655 return rv;