GObjectification - GSoC progress as of June 16, 2013 (resent with readable formatting)

Ankit Vani a at nevitus.org
Sun Jun 16 09:11:03 EDT 2013


Hi everyone

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 better. :)

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:
http://hg.pidgin.im/soc/2013/ankitkv/gobjectification/shortlog

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.


PurpleCircularBuffer
--------------------
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 g_object_unref()
  instead.


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 used.

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 PurpleCipher.
 a) Methods common to both PurpleHash and PurpleCipher are reset, reset_state,
    append, digest, get_digest_size, get_block_size, get_name.
 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
  (see cipher.c).
- 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 PurpleCipherContext*.
- 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 use.
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
gobjectification):

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));
purple_cipher_context_destroy(hmac);

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));
g_object_unref(hmac);
g_object_unref(hash);


Some other changes
------------------
- Entities in libpurple have reserved members such as
  void (*purple_reserved[4])(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 yet.


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

Ankit Vani



More information about the Devel mailing list