GObjectification - GSoC progress as of June 16, 2013
a at nevitus.org
Sun Jun 16 08:59:00 EDT 2013
As a part of Google Summer of Code 2013, I have been working on
GObjectification. It has been 4 days since I started working, and I
would like to share with the community of the changes I've been doing.
Since I'm still learning and getting used to libpurple, I have started
out with simpler entities. I hope to speed up as I keep learning. I
would appreciate feedback and comments on how things can be done
Most of what I've done so far has been similar to how it has been done
in the gobjectification branch. However, due to the many changes in
the API and code of libpurple since 2.10.0 (the version of pidgin that
the gobjectification branch is based on), simply merging the code
would have been a tedious and error-prone task. A shortlog of my
commits can be seen here:
As a general principle, all GObject-based objects will have their own
.c and .h file, and the file name will be a lower case space-less
representation of the object name without the 'purple' prefix. For
example, PurpleCircularBuffer can be found in circularbuffer.h.
To get my hands on this whole gobjectification of libpurple thing
people talk of, I started out with a simple entity - the circular
buffer, used in a number of prpls. Not a lot of changes in the API for
this, but some of the things to note are:
- PurpleCircBuffer is now PurpleCircularBuffer, which subclasses GObject.
- Appropriately, circbuffer .h and .c are now circularbuffer .h and .c
- purple_circ_buffer_* functions are now purple_circular_buffer_* methods.
- There is no longer a purple_circ_buffer_destroy(), use
PurpleCipher and PurpleHash
I worked on PurpleCipher, as a step to getting more used to libpurple
and its GObjectification, preparing for the more complicated entities
to come. Quite a few things have been changed in how a cipher is to be
Firstly, PurpleCipher has been split into PurpleCipher (cipher.h) and
PurpleHash (hash.h), making a distinction between ciphers (e.g. DES,
RC4) and hashes (e.g. MD5, SHA256). The semantics of both PurpleCipher
and PurpleHash are similar, except that some methods are specific to
a) Methods common to both PurpleHash and PurpleCipher are reset,
reset_state, append, digest, get_digest_size, get_block_size,
b) Methods specific to PurpleCipher are set_iv, encrypt, decrypt,
set_salt, set_key, get_key_size, set_batch_mode, get_batch_mode.
The ciphers that subclass PurpleHash are:
- PurpleMD4Hash (ciphers/md4hash.h)
- PurpleMD5Hash (ciphers/md5hash.h)
- PurpleSHA1Hash (ciphers/sha1hash.h)
- PurpleSHA256Hash (ciphers/sha256hash.h)
The ciphers that subclass PurpleCipher are:
- PurpleAESCipher (ciphers/aescipher.h)
- PurpleDESCipher (ciphers/descipher.h)
- PurpleDES3Cipher (ciphers/des3cipher.h)
- PurpleRC4Cipher (ciphers/rc4cipher.h)
- PurpleHMACCipher (ciphers/hmaccipher.h): Requires a PurpleHash* to
be passed to purple_hmac_cipher_new(hash_function)
- PurplePBKDF2Cipher (ciphers/pbkdf2cipher.h): Requires a PurpleHash*
to be passed to purple_pbkdf2_cipher_new(hash_function)
Now, let me make some basic things clear (I provide some examples
afterwards). Everything listed here about PurpleCipher also applies to
PurpleHash unless stated.
- PurpleCipherOps has been removed. It is no longer required as the
PurpleCipherClass structure for PurpleCipher is responsible for
implementing the operations.
- PurpleCipherContext has been removed. It is no longer required as
the GObject private structures (e.g. PurpleDESCipherPrivate) can hold
the private data of a particular instance of a cipher/hash.
- PurpleCipherCaps has been removed. I didn't really find any place in
the codebase where this was actually used. If you really want to know
if a cipher can do a particular operation, you can get a reference to
its PurpleCipherClass* and check if it implements a particular method
- PurpleCipherBatchMode is a GEnum. This enum is not required for PurpleHash.
- A get_name method has been added to every cipher and hash that
returns a const gchar* to the algorithm's name.
- purple_cipher_context_* functions are now just purple_cipher_*
functions, that take a PurpleCipher* argument instead of
- The init and destroy methods are removed. GObject init and
g_object_unref() are used for this purpose.
- The set_option, get_option methods are removed. Use g_object_set()
to set properties when necessary.
The purple_ciphers_* API has been removed. Earlier, a cipher was
registered in the cipher subsystem and a context was created for every
Now, users can directly instantiate cipher objects of whatever type
they wish (after including the specific cipher's header file).
A new GObject-based plugin API (also a part of this project) would
allow plugins to create their own ciphers subclassing PurpleCipher,
and register this type in the glib type system.
An example of using the HMAC cipher with the SHA1 hash (before
PurpleCipherContext *hmac = purple_cipher_context_new_by_name("hmac", NULL);
purple_cipher_context_set_option(hmac, "hash", "sha1");
purple_cipher_context_set_key(hmac, key, key_len);
purple_cipher_context_append(hmac, data, data_len);
purple_cipher_context_digest(hmac, output, sizeof(output));
An example of using the HMAC cipher with the SHA1 hash (after gobjectification):
PurpleHash *hash = purple_sha1_hash_new();
PurpleCipher *hmac = purple_hmac_cipher_new(hash);
purple_cipher_set_key(hmac, key, key_len);
purple_cipher_append(hmac, data, data_len);
purple_cipher_digest(hmac, output, sizeof(output));
Some other changes
- Entities in libpurple have reserved members such as void
(*purple_reserved)(void), to make it easier to add new API without
breaking the ABI for plugins compiled against older versions. Existing
GObjectified entities such as PurpleTheme, PurpleThemeManager,
PurpleThemeLoader, PurpleSoundTheme and PurpleSoundThemeLoader were
missing these padding members, so I added those to them.
- PurpleSmiley and PurpleMedia were already GObjects, but their
structures were hidden. I exposed them in the header file so these can
be subclassed. They do not have any methods that can be overridden
Please suggest any improvements I can do. I will keep informing you
all of my progress approximately every week. I hope for a GObjectified
pidgin by the end of summer! :D
More information about the Devel