changeset 29350:99d1b433dba0

Keep CurrentMedia in a separate object outside of MsnUser that needs to be allocated if a user has media. This makes MsnUser smaller by the size of 3 pointers (apparently) for each buddy in your buddy list. In practice it looks like less than 1% of MSN users have media set, so this should save a little bit of memory.
author Mark Doliner <mark@kingant.net>
date Thu, 04 Feb 2010 00:15:41 +0000
parents 3de19f8f5c92
children 08296b862f98
files libpurple/protocols/msn/notification.c libpurple/protocols/msn/state.c libpurple/protocols/msn/state.h libpurple/protocols/msn/user.c libpurple/protocols/msn/user.h
diffstat 5 files changed, 44 insertions(+), 65 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/msn/notification.c	Wed Feb 03 22:48:03 2010 +0000
+++ b/libpurple/protocols/msn/notification.c	Thu Feb 04 00:15:41 2010 +0000
@@ -1613,7 +1613,7 @@
 	MsnUser *user;
 	const char *passport;
 	char *psm_str, *str;
-	CurrentMedia media = {CURRENT_MEDIA_UNKNOWN, NULL, NULL, NULL};
+	CurrentMedia *media = NULL;
 
 	session = cmdproc->session;
 	account = session->account;
@@ -1634,19 +1634,12 @@
 		g_free(psm_str);
 
 		str = msn_get_currentmedia(cmd->payload, len);
-		if (msn_parse_currentmedia(str, &media))
-			msn_user_set_currentmedia(user, &media);
-		else
-			msn_user_set_currentmedia(user, NULL);
-		g_free(media.title);
-		g_free(media.album);
-		g_free(media.artist);
+		media = msn_parse_currentmedia(str);
 		g_free(str);
-
 	} else {
 		msn_user_set_statusline(user, NULL);
-		msn_user_set_currentmedia(user, NULL);
 	}
+	msn_user_set_currentmedia(user, media);
 
 	msn_user_update(user);
 }
--- a/libpurple/protocols/msn/state.c	Wed Feb 03 22:48:03 2010 +0000
+++ b/libpurple/protocols/msn/state.c	Thu Feb 04 00:15:41 2010 +0000
@@ -86,17 +86,15 @@
 	return result;
 }
 
-/* parse CurrentMedia string */
-gboolean
-msn_parse_currentmedia(const char *cmedia, CurrentMedia *media)
+CurrentMedia *msn_parse_currentmedia(const char *cmedia)
 {
 	char **cmedia_array;
 	int strings = 0;
-	gboolean parsed = FALSE;
+	CurrentMedia *media = NULL;
 
-	if ((cmedia == NULL) || (*cmedia == '\0')) {
+	if (!cmedia || cmedia[0] == '\0') {
 		purple_debug_info("msn", "No currentmedia string\n");
-		return FALSE;
+		return NULL;
 	}
 
 	purple_debug_info("msn", "Parsing currentmedia string: \"%s\"\n", cmedia);
@@ -121,7 +119,7 @@
 #endif
 
 	if (strings >= 4 && !strcmp(cmedia_array[2], "1")) {
-		parsed = TRUE;
+		media = g_new(CurrentMedia, 1);
 
 		if (!strcmp(cmedia_array[1], "Music"))
 			media->type = CURRENT_MEDIA_MUSIC;
@@ -132,30 +130,14 @@
 		else
 			media->type = CURRENT_MEDIA_UNKNOWN;
 
-		g_free(media->title);
-		if (strings == 4) {
-			media->title = g_strdup(cmedia_array[3]);
-		} else {
-			media->title = g_strdup(cmedia_array[4]);
-		}
-
-		g_free(media->artist);
-		if (strings > 5)
-			media->artist = g_strdup(cmedia_array[5]);
-		else
-			media->artist = NULL;
-
-		g_free(media->album);
-		if (strings > 6)
-			media->album = g_strdup(cmedia_array[6]);
-		else
-			media->album = NULL;
-
+		media->title = g_strdup(cmedia_array[strings == 4 ? 3 : 4]);
+		media->artist = strings > 5 ? g_strdup(cmedia_array[5]) : NULL;
+		media->album = strings > 6 ? g_strdup(cmedia_array[6]) : NULL;
 	}
 
 	g_strfreev(cmedia_array);
 
-	return parsed;
+	return media;
 }
 
 /* get the CurrentMedia info from the XML string */
--- a/libpurple/protocols/msn/state.h	Wed Feb 03 22:48:03 2010 +0000
+++ b/libpurple/protocols/msn/state.h	Thu Feb 04 00:15:41 2010 +0000
@@ -61,8 +61,10 @@
 
 void msn_set_psm(MsnSession *session);
 
-/* Parse CurrentMedia string */
-gboolean msn_parse_currentmedia(const char *cmedia, CurrentMedia *media);
+/**
+ * Parse CurrentMedia string.
+ */
+CurrentMedia *msn_parse_currentmedia(const char *cmedia);
 
 /* Get the CurrentMedia info from the XML string */
 char * msn_get_currentmedia(char *xml_str,gsize len);
--- a/libpurple/protocols/msn/user.c	Wed Feb 03 22:48:03 2010 +0000
+++ b/libpurple/protocols/msn/user.c	Thu Feb 04 00:15:41 2010 +0000
@@ -70,9 +70,12 @@
 	g_free(user->phone.home);
 	g_free(user->phone.work);
 	g_free(user->phone.mobile);
-	g_free(user->media.artist);
-	g_free(user->media.title);
-	g_free(user->media.album);
+	if (user->media) {
+		g_free(user->media->artist);
+		g_free(user->media->title);
+		g_free(user->media->album);
+		g_free(user->media);
+	}
 	g_free(user->statusline);
 	g_free(user->invite_message);
 
@@ -107,24 +110,24 @@
 		purple_prpl_got_user_status_deactive(account, user->passport, "mobile");
 	}
 
-	if (!offline && user->media.type != CURRENT_MEDIA_UNKNOWN) {
-		if (user->media.type == CURRENT_MEDIA_MUSIC) {
+	if (!offline && user->media && user->media->type != CURRENT_MEDIA_UNKNOWN) {
+		if (user->media->type == CURRENT_MEDIA_MUSIC) {
 			purple_prpl_got_user_status(account, user->passport, "tune",
-			                            PURPLE_TUNE_ARTIST, user->media.artist,
-			                            PURPLE_TUNE_ALBUM, user->media.album,
-			                            PURPLE_TUNE_TITLE, user->media.title,
+			                            PURPLE_TUNE_ARTIST, user->media->artist,
+			                            PURPLE_TUNE_ALBUM, user->media->album,
+			                            PURPLE_TUNE_TITLE, user->media->title,
 			                            NULL);
-		} else if (user->media.type == CURRENT_MEDIA_GAMES) {
+		} else if (user->media->type == CURRENT_MEDIA_GAMES) {
 			purple_prpl_got_user_status(account, user->passport, "tune",
-			                            "game", user->media.title,
+			                            "game", user->media->title,
 			                            NULL);
-		} else if (user->media.type == CURRENT_MEDIA_OFFICE) {
+		} else if (user->media->type == CURRENT_MEDIA_OFFICE) {
 			purple_prpl_got_user_status(account, user->passport, "tune",
-			                            "office", user->media.title,
+			                            "office", user->media->title,
 			                            NULL);
 		} else {
 			purple_debug_warning("msn", "Got CurrentMedia with unknown type %d.\n",
-			                     user->media.type);
+			                     user->media->type);
 		}
 	} else {
 		purple_prpl_got_user_status_deactive(account, user->passport, "tune");
@@ -205,18 +208,16 @@
 }
 
 void
-msn_user_set_currentmedia(MsnUser *user, const CurrentMedia *media)
+msn_user_set_currentmedia(MsnUser *user, CurrentMedia *media)
 {
-	g_return_if_fail(user != NULL);
+	if (user->media) {
+		g_free(user->media->title);
+		g_free(user->media->album);
+		g_free(user->media->artist);
+		g_free(user->media);
+	}
 
-	g_free(user->media.title);
-	g_free(user->media.album);
-	g_free(user->media.artist);
-
-	user->media.type   = media ? media->type : CURRENT_MEDIA_UNKNOWN;
-	user->media.title  = media ? g_strdup(media->title) : NULL;
-	user->media.artist = media ? g_strdup(media->artist) : NULL;
-	user->media.album  = media ? g_strdup(media->album) : NULL;
+	user->media = media;
 }
 
 void
--- a/libpurple/protocols/msn/user.h	Wed Feb 03 22:48:03 2010 +0000
+++ b/libpurple/protocols/msn/user.h	Thu Feb 04 00:15:41 2010 +0000
@@ -75,7 +75,7 @@
 
 	const char *status;     /**< The state of the user.         */
 	char *statusline;       /**< The state of the user.         */
-	CurrentMedia media;     /**< Current media of the user.     */
+	CurrentMedia *media;    /**< Current media of the user.     */
 
 	gboolean idle;          /**< The idle state of the user.    */
 
@@ -158,9 +158,10 @@
   *  Sets the current media of user.
   *
   *  @param user   The user.
-  *  @param cmedia Current media.
+  *  @param cmedia Current media.  This function takes ownership of this
+  *         object and its contents.
   */
-void msn_user_set_currentmedia(MsnUser *user, const CurrentMedia *cmedia);
+void msn_user_set_currentmedia(MsnUser *user, CurrentMedia *cmedia);
 
 /**
  * Sets the new state of user.