GMime 2.0 tutorial | ||
---|---|---|
<<< Previous | Getting Down to the Basics | Next >>> |
Before we get too deep into using GMime, it is important to understand how to use the underlying I/O classes since GMime is so very heavily dependant upon them.
If you've looked at the API at all already, you will have probably noticed that the stream functions work very much like those of the standard low-level Unix I/O functions (those that use file descriptors) but with a few extras taken from the higher-level Standard C I/O API.
Lets take a moment to regres back to our early days of programming where we learned how to write "Hello World!" on the console:
#include <stdio.h> int main (int argc, char **argv) { fprintf (stdout, "Hello World!\n"); fflush (stdout); return 0; } |
Everyone should recognize what that program does. The above program, rewritten to use GMime's stream classes would look something like this:
#include <stdio.h> #include <gmime/gmime.h> int main (int argc, char **argv) { GMimeStream *stream; /* initialize GMime */ g_mime_init (0); /* create a stream around stdout */ stream = g_mime_stream_file_new (stdout); /* 'printf' */ g_mime_stream_printf (stream, "Hello World!\n"); /* flush stdout */ g_mime_stream_flush (stream); /* free/close the stream */ g_object_unref (stream); return 0; } |
Hopefully, the only thing that may be new to you in either of the above examples is the flushing of the stream after writing to it. Most likely, in both examples, it is an unneeded call, however it is there for completenss and you should probably get into the habbit of flushing a stream after you've finished writing to it. Like fflush(), g_mime_stream_flush() will flush any write-buffers that the previous write-calls may have left.
The first function called in the second example is g_mime_init with a value of 0. If you haven't guessed, g_mime_init initializes the GMime library. It takes a single bit-mask argument specifying which options to enable. Currently there is only one optional bit-flag, GMIME_INIT_FLAG_UTF8 which is the default anyway, so a value of 0 is used here. The UTF-8 flag only exists for historical reasons.
The only other line that should need explaining might be:
stream = g_mime_stream_file_new (stdout); |
This line creates a new object of type GMimeStreamFile which takes a FILE* argument. Once the GMimeStreamFile is created, it takes ownership of the FILE* so be careful if you want to be able to ever use that FILE* handle again later in your program or if you do not wish for it to be closed when the GMimeStreamFile is closed later.
One way of working around this is to do something like the following example:
#include <stdio.h> #include <unistd.h> #include <gmime/gmime.h> int main (int argc, char **argv) { GMimeStream *stream; /* initialize GMime */ g_mime_init (0); /* create a stream around stdout */ stream = g_mime_stream_fs_new (dup (fileno (stdout))); /* 'printf' */ g_mime_stream_printf (stream, "Hello World!\n"); /* flush stdout */ g_mime_stream_flush (stream); /* free/close the stream */ g_object_unref (stream); return 0; } |
Here we have made a duplicate copy of stdout to give to g_mime_stream_fs_new(). GMimeStreamFs is the second type of stream meant for basic I/O, but instead of using a FILE* handle, it instead uses an integer file descriptor. The fileno() function returns the integer file descriptor for a given FILE* handle. The dup() function makes a duplicate of the file descriptor passed to it. More information can be read about these 2 functions by using man on your local Unix system or by reading the Reference Manual for your libc.
New in GMime 2.2 are some functions to tell GMimeStreamFile, GMimeStreamFs and GMimeStreamMem that they are not the owners of the backend storage and so when they are destroyed, they should not close the file or free the memory buffer (respectively). These functions are:
|
Next, lets examine some of the other stream functions.
g_mime_stream_eos (stream); |
This function is useful for finding out if the End-Of-Stream has been reached. This is similar in functionality to Standard C's feof() function.
g_mime_stream_reset (stream); |
This function will reset the state of a stream. Usually this only means 'rewinding' to the beginning of the file. For more complex streams, such as GMimeStreamFilter, however, this will also reset the state of all the the filters that have been attached to it (more on this later).
g_mime_stream_length (stream); |
This function will return the length of the stream if known, or -1 otherwise. For the most part, this function should be avoided unless you absolutely need to know the stream length and there is no other way to get it. The reason to avoid using it is that it may be inaccurate if any filters are to be applied as well as possibly being slow depending on the underlying storage device.
g_mime_stream_substream (stream, start, end); |
This last function will return a substream of the original stream, where the beginning of the new substream is the start offset and the end is the end offset. These start and end offsets MUST be within the bounds of the original stream. Substreams can be useful if you want to only allow reading and writing to a subsection of the original stream.
<<< Previous | Home | Next >>> |
Getting Down to the Basics | Up | Stream Class Overview |