diff libpurple/protocols/myspace/message.c @ 17964:6d1d86ab6a59

In MsimMessage, add support for MSIM_TYPE_LIST - pipe-separated lists.
author Jeffrey Connelly <jaconnel@calpoly.edu>
date Sun, 22 Jul 2007 04:12:12 +0000
parents c109b7f1c739
children a2298513db8b
line wrap: on
line diff
--- a/libpurple/protocols/myspace/message.c	Sat Jul 21 07:53:22 2007 +0000
+++ b/libpurple/protocols/myspace/message.c	Sun Jul 22 04:12:12 2007 +0000
@@ -62,6 +62,7 @@
 	gchar *key, *value;
 	MsimMessageType type;
 	GString *gs;
+    GList *gl;
 	MsimMessage *msg;
 
 	/* Begin with an empty message. */
@@ -103,6 +104,13 @@
 				msg = msim_msg_append(msg, key, type, gs);
 				break;
 
+            case MSIM_TYPE_LIST:
+                gl = va_arg(argp, GList *);
+
+                g_return_val_if_fail(gl != NULL, FALSE);
+
+                msg = msim_msg_append(msg, key, type, gl);
+
 			default:
 				purple_debug_info("msim", "msim_send: unknown type %d\n", type);
 				break;
@@ -113,6 +121,55 @@
 	return msg;
 }
 
+/** Perform a deep copy on a GList * of gchar * strings. Free with msim_msg_list_free(). */
+GList *
+msim_msg_list_copy(GList *old)
+{
+    GList *new_list;
+
+    new_list = NULL;
+
+    /* Deep copy (g_list_copy is shallow). Copy each string. */
+    for (; old != NULL; old = g_list_next(old))
+    {
+        new_list = g_list_append(new_list, g_strdup(old->data));
+    }
+
+    return new_list;
+}
+
+/** Free a GList * of gchar * strings. */
+void
+msim_msg_list_free(GList *l)
+{
+
+    for (; l != NULL; l = g_list_next(l))
+    {
+        g_free((gchar *)(l->data));
+    }
+    g_list_free(l);
+}
+
+/** Parse a |-separated string into a new GList. Free with msim_msg_list_free(). */
+GList *
+msim_msg_list_parse(const gchar *raw)
+{
+    gchar **array;
+    GList *list;
+    guint i;
+
+    array = g_strsplit(raw, "|", 0);
+    list = NULL;
+    
+    for (i = 0; array[i] != NULL; ++i)
+    {
+        list = g_list_append(list, g_strdup(array[i]));
+    }
+
+    g_strfreev(array);
+
+    return list;
+}
 
 /** Clone an individual element.
  *
@@ -141,6 +198,10 @@
 			new_data = g_strdup((gchar *)elem->data);
 			break;
 
+        case MSIM_TYPE_LIST:
+            new_data = (gpointer)msim_msg_list_copy((GList *)(elem->data));
+            break;
+
 		case MSIM_TYPE_BINARY:
 			{
 				GString *gs;
@@ -216,7 +277,7 @@
 			break;
 			
 		case MSIM_TYPE_LIST:
-			/* TODO: free list */
+            g_list_free((GList *)elem->data);
 			break;
 
 		default:
@@ -237,6 +298,8 @@
 		return;
 	}
 
+    msim_msg_dump("msim_msg_free: freeing %s", msg);
+
 	g_list_foreach(msg, msim_msg_free_element, NULL);
 	g_list_free(msg);
 }
@@ -334,7 +397,7 @@
  *
  * * MSIM_TYPE_DICTIONARY: TODO
  *
- * * MSIM_TYPE_LIST: TODO
+ * * MSIM_TYPE_LIST: GList * of gchar *. Again, everything will be freed.
  *
  * */
 MsimMessage *
@@ -449,8 +512,23 @@
 			break;
 			
 		case MSIM_TYPE_LIST:
-			/* TODO: provide human-readable output of list. */
-			string = g_strdup_printf("%s(list): TODO", elem->name);
+            {
+                GString *gs;
+                GList *gl;
+                guint i;
+
+                gs = g_string_new("");
+                g_string_append_printf(gs, "%s(list): \n", elem->name);
+
+                i = 0;
+                for (gl = (GList *)elem->data; gl != NULL; gl = g_list_next(gl))
+                {
+                    g_string_append_printf(gs, " %d. %s\n", i, (gchar *)(gl->data));
+                    ++i;
+                }
+                
+                string = gs->str;
+            }
 			break;
 
 		default:
@@ -528,8 +606,20 @@
 			return NULL;
 			
 		case MSIM_TYPE_LIST:
-			/* TODO: pack using a|b|c|d|... */
-			return NULL;
+			/* Pack using a|b|c|d|... */
+            {
+                GString *gs;
+                GList *gl;
+
+                gs = g_string_new("");
+
+                for (gl = (GList *)elem->data; gl != NULL; gl = g_list_next(gl))
+                {
+                    g_string_append_printf(gs, "%s|", (gchar*)(gl->data));
+                }
+                
+                return gs->str;
+            }
 
 		default:
 			purple_debug_info("msim", "field %s, unknown type %d\n", elem->name, elem->type);
@@ -845,6 +935,31 @@
 	}
 }
 
+/** Return an element as a new list. Caller frees with msim_msg_list_free(). */
+GList *
+msim_msg_get_list(MsimMessage *msg, const gchar *name)
+{
+    MsimMessageElement *elem;
+
+    elem = msim_msg_get(msg, name);
+    if (!elem)
+        return NULL;
+
+    switch (elem->type)
+    {
+        case MSIM_TYPE_LIST:
+            return msim_msg_list_copy((GList *)(elem->data));
+
+        case MSIM_TYPE_RAW:
+            return msim_msg_list_parse((gchar *)(elem->data));
+
+        default:
+            purple_debug_info("msim_msg_get_list", "type %d unknown, name %s\n",
+                    elem->type, name);
+            return NULL;
+    }
+}
+
 /** Return the data of an element of a given name, as an integer.
  *
  * @param name Name of element.