It is my intention to make migrating code using one version of GMime to another as easy as I can and so for the most part, I will try not to break API/ABI compatability between versions, however this isn't always easy to do. This document is intended to help developers port their application(s) from one version of GMime to another. For each new major release, I will attempt to list the main things to watch out for when migrating to the new release from the prior version. Porting from GMime 2.4 to GMime 2.6 ----------------------------------- After releasing GMime 2.4, it was discovered that g_mime_stream_length() still returned ssize_t which, on 32bit systems, meant that the function was useless if the actual stream was larger than 2GB (which could happen if GMime was built with large file support). As I fixed this, I also found some API inconsistencies which I felt I might as well fix up since I had to break API/ABI compatibility with 2.4 anyway. Most notable in GMime 2.6 is the lack of GMimeSession which has been dropped in favor of a much simpler callback mechanism. GMimeCipherContexts constructors now take a password_request callback function rather than forcing you to subclass GMimeSession to get this functionality. Other API changes include: - GMimeBestEncoding has been renamed to GMimeEncodingConstraint - GMimeSignatureValidity has been dropped in favor of GMimeSignatureList which is simply a collection of signatures. - GMimeSigner has been replaced by GMimeSignature and GMimeCertificate which added a number of new fields and accessors making it much more complete. - GMimeCipherContext has been renamed to GMimeCryptoContext and the method names for this class have also been renamed in a similar fashion. - g_mime_crypto_context_encrypt() now takes a digest algorithm argument which is used when the 'sign' argument is TRUE. - g_mime_multipart_encrypted_encrypt() also now takes a digest algorithm argument which it passes along to g_mime_crypto_context_encrypt(). - g_mime_crypto_context_decrypt() now returns a GMimeDecryptResult which contains a list of signatures (if signed), a list of recipients that the stream had been encrypted to, and also the cipher and digest algorithms used. - g_mime_multipart_encrypted_decrypt() no longer caches the decrypted part and also now takes a GMimeSignatureList** output argument which it sets in place of having to call g_mime_multipart_encrypted_get_signature_validity() afterward. For convenience, GMime 2.6 source packages include a shell-script to aid in porting applications using GMime 2.4 to the 2.6 API. You can find this script under the tools/ directory, named `gmime-port-2-4-to-2-6.sh'. Porting from GMime 2.2 to GMime 2.4 ----------------------------------- GMime 2.4 has had a number of API changes since GMime 2.2. To start, ALL public APIs that used to use off_t in GMime 2.2 now use gint64 so that the API and ABI do not change based on whether or not large file support is enabled. In addition, all of the functions marked as deprecated in 2.0 and 2.2 were removed (usually they had equivalent functionality in a parent class). Many functions have also been renamed for better clarity and/or consistency. For convenience, GMime 2.4 source packages include a shell-script to aid in porting applications using GMime 2.2 (should work for most GMime 2.0 applications as well) to the 2.4 API. You can find this script under the tools/ directory, named `gmime-port-2-2-to-2-4.sh'. This script won't fix everything, but it should help quite a bit. Beyond that, a few methods have changed in other ways: - g_mime_cipher_context_sign() still returns int, but if the value isn't -1 (failure), then it will represent a GMimeCipherHash that it used for signing. This is useful, for example, when the requested hash was GMIME_CIPHER_HASH_DEFAULT. - g_mime_cipher_context_decrypt() now returns a GMimeSignatureValidty on success and NULL on failure. This is needed in case the encrypted stream was also signed. - g_mime_multipart_encrypted_encrypt() now takes a boolean 'sign' argument to allow the caller to request encrypting and signing in a single pass. Several structs have also been rewritten to subclass GObject like GMimeContentType and GMimeContentDisposition as well as InternetAddress and InternetAddressList. Not only have InternetAddress and InternetAddressList been ported to GObject, but they have also undergone other design changes. InternetAddress is now a base class for InternetAddressMailbox and InternetAddressGroup, meaning that InternetAddress no longer contains a union for group/addr fields. All functions that return a GObject have been changed to not add a ref to the object returned, meaning that it is no longer necessary to call g_object_unref() on MIME parts returned from functions like g_mime_message_get_mime_part() or g_mime_multipart_get_part(). This was done to be more consistent with the Gtk+ API. Porting from GMime 2.0 to GMime 2.2 ----------------------------------- Note: GMime 2.2 is both API and ABI compatible with GMime 2.0 meaning that any program written for GMime 2.0 will compile fine with GMime 2.2 and any program linked against GMime 2.0's libraries will also work with GMime 2.2's libraries. Most of the changes made between 2.0 and 2.2 were internal but there are a few API changes you should be aware of (as these interfaces will be deprecated in some future version, probably 3.0). - g_mime_utils_8bit_header_decode() has been split into 2 functions. We now have g_mime_utils_header_decode_text() and g_mime_utils_header_decode_phrase(). header_decode_text() no longer requires encoded-words to be rfc822 atoms. header_decode_phrase() is still strict in that encoded-words MUST be valid rfc822 atoms. - g_mime_utils_8bit_header_encode() has been renamed to g_mime_utils_header_encode_text() to be more clear as to what type of header this is supposed to encode. If you haven't guessed, this function is for encoding rfc822 'text' headers (such as Subject). - g_mime_utils_8bit_header_encode_phrase() has been renamed to g_mime_utils_header_encode_phrase() mostly for consistancy with the previous 2 changes. - g_mime_charset_name() has been renamed to g_mime_charset_iconv_name() for clarity. - g_mime_charset_locale_name() has been renamed to g_mime_locale_charset(). Hmmm, was this a bad rename? - g_mime_cipher_context_verify() no longer returns a GMimeCipherValidity, instead it returns a GMimeSignatureValidity which is far more useful. Never fear, you may still use the GMimeCipherValidity APIs for the time being - they work fine given a GMimeSignatureValidity structure. - g_mime_multipart_signed_verify() also now returns a GMimeSignatureValidity structure rather than a GMimeCipherValidity structure. See changes to g_mime_cipher_context_verify() for details. Porting from GMime 1.0 to GMime 2.0 ----------------------------------- The major change here is that I've dropped my own base object class and have replaced it with GObject from glib-2.0. This should be a pleasant change since you (the developer) will now be able to do many more things such as setting arbitrary data on all GMime objects. For additional information about GObject, please see the GObject Reference Manual at http://developer.gnome.org/doc/API/2.0/gobject/ - The first thing you need to know is that any function returning a non-const pointer to any object /must/ be unref'd when you are done with it. Since all objects in GMime now subclass GObject, you may safely use g_object_unref() (GMimeStream's may also be unref'd using g_mime_stream_unref(), but either way is fine). Don't forget that g_mime_part_get_content_object() returns a ref-counted GMimeDataWrapper object now, and so you /must/ unref it when you have finished using it. You must also remember to unref any GMimeDataWrapper object that you /set/ on a GMimePart using g_mime_part_set_content_object() as the GMimePart will now ref the content object that you set on it. - GMimeMultipart is a new class which is to be used for all multipart MIME parts rather than GMimePart (as in 1.0). There are also some subclasses of GMimeMultipart for other things. - g_mime_part_[g,s]et_boundary() have been removed (see above). You must now create a GMimeMultipart object and use g_mime_multipart_[g,s]et_boundary(). - g_mime_part_add_subpart() has been replaced with g_mime_multipart_add_part(). - g_mime_part_foreach() has been replaced with g_mime_multipart_foreach() and/or g_mime_message_foreach_part(). - g_mime_part_get_subpart_from_content_id() has been replaced with g_mime_multipart_get_subpart_from_content_id(). - Another new class is GMimeMessagePart which is to be used for all MIME parts containing an rfc822 message. All 1.0 GMimePart's representing message/rfc822 parts (as well as message/news parts?) need to be migrated over to be GMimeMessagePart objects. - GMimeMessagePartial is another class meant for handling the message/partial MIME type. All 1.0 GMimePart's holding data of this type should be replaced with GMimeMessagePartial objects. - g_mime_message_write_to_stream() and g_mime_part_write_to_stream() functions have been consolidated into a virtual method. Replace calls to these functions with g_mime_object_write_to_stream(). Note: while g_mime_part_write_to_stream() and g_mime_message_write_to_stream() still exist, it is suggested you migrate to g_mime_object_write_to_stream(). Same goes for g_mime_part_to_string() and g_mime_message_to_string(). - GMimeMessage's structure has changed a bit. You will not be able to do message->header, instead you want to do ((GMimeObject *) message)->header. - g_mime_message_set_message_id() now takes a message_id argument without the encapsulating <>'s (it now just takes the addr-spec portion of the msg-id). - GMimeFilterFrom has changed slightly, you will want to replace all calls to g_mime_filter_from_new () with g_mime_filter_from_new (GMIME_FILTER_FROM_MODE_DEFAULT) (GMIME_FILTER_FROM_MODE_DEFAULT is equivalent to (int) 0). - GMimeParser has had a number of API additions, but g_mime_parser_construct_part() and g_mime_parser_construct_message() still exist, however they no longer take a GMimeStream argument. Instead, they take a GMimeParser object. If you find more trouble spots when porting your code from one version of GMime to a later version, please feel free to send me additional notes to add to this porting document. -- fejj@gnome.org