# HG changeset patch # User Jeffrey Connelly # Date 1179644937 0 # Node ID a2e9890a57e09c37ce386c78f52dd68fa841a882 # Parent 37e3d6378b08a6754e68ddae44b06a6a891dc144 Implement msim_pack(), msim_sendh(), msim_send(). msim_pack() converts a hash table to a protocol message string. msim_sendh() sends a protocol message using msim_send_raw, after converting the hash table to a string using msim_pack(). msim_send() accepts variable arguments and converts them to a hash table, then sends using msim_sendh(). These are part of the TODO item "Generic protocol message sending function, that handles packing of messages", but functions haven't been updated to use msim_send() instead of msim_send_raw() yet. diff -r 37e3d6378b08 -r a2e9890a57e0 libpurple/protocols/myspace/myspace.c --- a/libpurple/protocols/myspace/myspace.c Sun May 13 19:53:34 2007 +0000 +++ b/libpurple/protocols/myspace/myspace.c Sun May 20 07:08:57 2007 +0000 @@ -35,6 +35,7 @@ #include #include /* for EAGAIN */ +#include #include @@ -381,11 +382,12 @@ static gboolean msim_send_raw(MsimSession *session, const gchar *msg) { int total_bytes_sent, total_bytes; + + purple_debug_info("msim", "msim_send: writing <%s>\n", msg); g_return_val_if_fail(MSIM_SESSION_VALID(session), FALSE); g_return_val_if_fail(msg != NULL, FALSE); - purple_debug_info("msim", "msim_send: writing <%s>\n", msg); /* Loop until all data is sent, or a failure occurs. */ total_bytes_sent = 0; @@ -410,14 +412,127 @@ } /** - * Send a message to the server. + * Pack a key=value item into a part of a protocol messge. + */ +static void msim_pack_each(gpointer key, gpointer value, gpointer user_data) +{ + gchar ***items; /* wow, a pointer to a pointer to a pointer */ + gchar *item; + gchar *escaped_key, *escaped_value; + + items = user_data; + + escaped_key = msim_escape((gchar *)key); + escaped_value = msim_escape((gchar *)value); + + item = g_strdup_printf("%s\\%s", escaped_key, escaped_value); + + g_free(escaped_key); + g_free(escaped_value); + + **items = item; + ++(*items); +} + +/** + * Pack a hash table of a protocol of a message into a string suitable + * for sending. + * + * @return The packed string; caller must g_free() when no longer needed. + */ +static gchar *msim_pack(GHashTable *table) +{ + gchar **items, **items_tmp; + gchar *raw; + guint i; + + items = (gchar **)g_new0(gchar *, g_hash_table_size(table)); + + items_tmp = items; + g_hash_table_foreach(table, (GHFunc)msim_pack_each, &items_tmp); + + /* Join each item of the message. */ + raw = g_strjoinv("\\", items); + + /* Free each item, then the array itself. */ + for (i = 0; i < g_hash_table_size(table); ++i) + { + g_free(items[i]); + } + g_free(items); + + return raw; +} + +/** + * Send a message to the server, by a hash table. * * @param session - * @param ... A sequence of gchar* key/value pairs, terminated with NULL + * @param table A hash table of the message to send. */ +static gboolean msim_sendh(MsimSession *session, GHashTable *table) +{ + gchar *raw_msg; + gboolean success; + + raw_msg = msim_pack(table); + success = msim_send_raw(session, raw_msg); + + g_free(raw_msg); + + return success; +} + +/** + * + * Send a message to the server, whose contents is specified using + * variable arguments. + * + * @param session + * @param ... A sequence of gchar* key/value pairs, terminated with NULL. The strings will be copied. + * + * This function exists for coding convenience: a message can be created + * and sent in one line of code. Internally it calls msim_sendh(). + */ + static gboolean msim_send(MsimSession *session, ...) { - /* TODO: implement this */ + va_list argp; + GHashTable *table; + gchar *key, *value; + gboolean success; + + table = g_hash_table_new_full((GHashFunc)g_str_hash, + (GEqualFunc)g_str_equal, g_free, g_free); + + /* Parse key, value pairs until NULL. */ + va_start(argp, session); + do + { + key = va_arg(argp, gchar *); + if (!key) + { + break; + } + + value = va_arg(argp, gchar *); + if (!value) + { + purple_debug_info("msim", "msim_send: no value for key '%s', ignoring\n", key); + break; + } + + g_hash_table_insert(table, g_strdup(key), g_strdup(value)); + } while(key && value); + + /* Actually send the message. */ + success = msim_sendh(session, table); + + /* Cleanup. */ + va_end(argp); + g_hash_table_destroy(table); + + return success; } /** diff -r 37e3d6378b08 -r a2e9890a57e0 libpurple/protocols/myspace/myspace.h --- a/libpurple/protocols/myspace/myspace.h Sun May 13 19:53:34 2007 +0000 +++ b/libpurple/protocols/myspace/myspace.h Sun May 20 07:08:57 2007 +0000 @@ -113,11 +113,13 @@ static gchar *msim_unescape(const gchar *msg); static gchar *msim_escape(const gchar *msg); static gchar *str_replace(const gchar* str, const gchar *old, const gchar *new); -static GHashTable* msim_parse(gchar* msg); -static GHashTable *msim_parse_body(const gchar *body_str); +static GHashTable *msim_parse(gchar* msg); +static GHashTable* msim_parse_body(const gchar *body_str); static void print_hash_item(gpointer key, gpointer value, gpointer user_data); static gboolean msim_send_raw(MsimSession *session, const gchar *msg); +static gchar *msim_pack(GHashTable *table); +static gboolean msim_sendh(MsimSession *session, GHashTable *table); static gboolean msim_send(MsimSession *session, ...); static void msim_login(PurpleAccount *acct);