changeset 16391:24bbd7e46bfe

Change the imgstore and by extension, then the buddy icon code to take over the references to icon data instead of calling g_memdup(). This eliminates g_memdup()ing and g_free()ing in ~50% of the callers. For the rest, it's no worse (they now do a g_memdup() instead of the core) and they may be able to be modified in the future to avoid that.
author Richard Laager <rlaager@wiktel.com>
date Wed, 25 Apr 2007 22:23:29 +0000
parents 4fc51a87ce42
children 6f197c81d478
files libpurple/buddyicon.c libpurple/buddyicon.h libpurple/imgstore.c libpurple/imgstore.h libpurple/protocols/jabber/buddy.c libpurple/protocols/jabber/presence.c libpurple/protocols/msn/msn.c libpurple/protocols/msn/slp.c libpurple/protocols/oscar/odc.c libpurple/protocols/oscar/oscar.c libpurple/protocols/qq/buddy_info.c libpurple/protocols/sametime/sametime.c libpurple/protocols/silc/buddy.c libpurple/protocols/silc/ops.c libpurple/protocols/yahoo/yahoo_picture.c libpurple/protocols/yahoo/yahoo_profile.c pidgin/gtkaccount.c pidgin/gtkimhtmltoolbar.c pidgin/gtkstatusbox.c pidgin/gtkutils.c
diffstat 20 files changed, 40 insertions(+), 39 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/buddyicon.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/buddyicon.c	Wed Apr 25 22:23:29 2007 +0000
@@ -236,7 +236,10 @@
 	{
 		file = purple_buddy_icon_data_calculate_filename(icon_data, icon_len);
 		if (file == NULL)
+		{
+			g_free(icon_data);
 			return NULL;
+		}
 	}
 	else
 		file = g_strdup(filename);
@@ -244,6 +247,7 @@
 	if ((img = g_hash_table_lookup(icon_data_cache, file)))
 	{
 		g_free(file);
+		g_free(icon_data);
 		return purple_imgstore_ref(img);
 	}
 
@@ -438,8 +442,11 @@
 	old_img = icon->img;
 	icon->img = NULL;
 
-	if (data != NULL && len > 0)
-		icon->img = purple_buddy_icon_data_new(data, len, NULL);
+	if (data != NULL)
+		if (len > 0)
+			icon->img = purple_buddy_icon_data_new(data, len, NULL);
+		else
+			g_free(data);
 
 	icon->checksum = g_strdup(checksum);
 
@@ -610,7 +617,6 @@
 				icon->img = NULL;
 				checksum = g_strdup(purple_blist_node_get_string((PurpleBlistNode*)b, "icon_checksum"));
 				purple_buddy_icon_set_data(icon, data, len, checksum);
-				g_free(data);
 			}
 			g_free(path);
 		}
@@ -658,7 +664,6 @@
 	{
 		g_free(path);
 		img = purple_buddy_icon_data_new(data, len, account_icon_file);
-		g_free(data);
 		g_hash_table_insert(pointer_icon_cache, account, img);
 		return img;
 	}
@@ -680,7 +685,6 @@
 	if (icon_data != NULL && icon_len > 0)
 	{
 		img = purple_buddy_icon_data_new(icon_data, icon_len, NULL);
-		g_free(icon_data);
 	}
 
 	old_icon = g_strdup(purple_account_get_string(account, "buddy_icon", NULL));
@@ -757,7 +761,6 @@
 	{
 		g_free(path);
 		img = purple_buddy_icon_data_new(data, len, custom_icon_file);
-		g_free(data);
 		g_hash_table_insert(pointer_icon_cache, contact, img);
 		return img;
 	}
@@ -780,7 +783,6 @@
 	if (icon_data != NULL && icon_len > 0)
 	{
 		img = purple_buddy_icon_data_new(icon_data, icon_len, NULL);
-		g_free(icon_data);
 	}
 
 	old_icon = g_strdup(purple_blist_node_get_string((PurpleBlistNode *)contact,
--- a/libpurple/buddyicon.h	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/buddyicon.h	Wed Apr 25 22:23:29 2007 +0000
@@ -88,10 +88,11 @@
 void purple_buddy_icon_update(PurpleBuddyIcon *icon);
 
 /**
- * Sets the buddy icon's data that was received over the wire.
+ * Sets the buddy icon's data.
  *
  * @param icon The buddy icon.
- * @param data The buddy icon data received over the wire.
+ * @param data The buddy icon data, which the buddy icon code
+ *             takes ownership of and will free.
  * @param len  The length of the data in @a data.
  * @param checksum  A protocol checksum from the prpl or @c NULL.
  */
@@ -177,7 +178,8 @@
  *
  * @param account   The account the user is on.
  * @param username  The username of the user.
- * @param icon_data The icon data.
+ * @param icon_data The buddy icon data, which the buddy icon code
+ *                  takes ownership of and will free.
  * @param icon_len  The length of the icon data.
  * @param checksum  A protocol checksum from the prpl or @c NULL.
  *
--- a/libpurple/imgstore.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/imgstore.c	Wed Apr 25 22:23:29 2007 +0000
@@ -48,7 +48,7 @@
 };
 
 PurpleStoredImage *
-purple_imgstore_add(gconstpointer data, size_t size, const char *filename)
+purple_imgstore_add(gpointer data, size_t size, const char *filename)
 {
 	PurpleStoredImage *img;
 
@@ -56,7 +56,7 @@
 	g_return_val_if_fail(size > 0, 0);
 
 	img = g_new(PurpleStoredImage, 1);
-	img->data = g_memdup(data, size);
+	img->data = data;
 	img->size = size;
 	img->filename = g_strdup(filename);
 	img->refcount = 1;
@@ -66,7 +66,7 @@
 }
 
 int
-purple_imgstore_add_with_id(gconstpointer data, size_t size, const char *filename)
+purple_imgstore_add_with_id(gpointer data, size_t size, const char *filename)
 {
 	PurpleStoredImage *img = purple_imgstore_add(data, size, filename);
 	img->id = ++nextid;
--- a/libpurple/imgstore.h	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/imgstore.h	Wed Apr 25 22:23:29 2007 +0000
@@ -44,14 +44,16 @@
  * No ID is allocated when using this function.  If you need to reference the
  * image by an ID, use purple_imgstore_add_with_id() instead.
  *
- * @param data		Pointer to the image data.
+ * @param data		Pointer to the image data, which the imgstore will take
+ *                      ownership of and free as appropriate.  If you want a
+ *                      copy of the data, make it before calling this function.
  * @param size		Image data's size.
  * @param filename	Filename associated with image.
  *
  * @return The stored image.
  */
 PurpleStoredImage *
-purple_imgstore_add(gconstpointer data, size_t size, const char *filename);
+purple_imgstore_add(gpointer data, size_t size, const char *filename);
 
 /**
  * Add an image to the store, allocating an ID.
@@ -60,13 +62,15 @@
  * the image with purple_imgstore_unref_by_id() or purple_imgstore_unref()
  * for it to be freed.
  *
- * @param data		Pointer to the image data.
+ * @param data		Pointer to the image data, which the imgstore will take
+ *                      ownership of and free as appropriate.  If you want a
+ *                      copy of the data, make it before calling this function.
  * @param size		Image data's size.
  * @param filename	Filename associated with image.
 
  * @return ID for the image.
  */
-int purple_imgstore_add_with_id(gconstpointer data, size_t size, const char *filename);
+int purple_imgstore_add_with_id(gpointer data, size_t size, const char *filename);
 
 /**
  * Retrieve an image from the store. The caller does not own a
--- a/libpurple/protocols/jabber/buddy.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/protocols/jabber/buddy.c	Wed Apr 25 22:23:29 2007 +0000
@@ -955,7 +955,7 @@
 
 					data = purple_base64_decode(bintext, &size);
 
-					jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(purple_imgstore_add_with_id(data, size, "logo.png")));
+					jbi->vcard_imgids = g_slist_prepend(jbi->vcard_imgids, GINT_TO_POINTER(purple_imgstore_add_with_id(g_memdup(data, size), size, "logo.png")));
 					g_string_append_printf(info_text,
 							"<b>%s:</b> <img id='%d'><br/>",
 							photo ? _("Photo") : _("Logo"),
@@ -969,8 +969,6 @@
 
 					purple_buddy_icons_set_for_user(js->gc->account, bare_jid,
 							data, size, hash);
-
-					g_free(data);
 					g_free(bintext);
 				}
 			}
--- a/libpurple/protocols/jabber/presence.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/protocols/jabber/presence.c	Wed Apr 25 22:23:29 2007 +0000
@@ -233,8 +233,6 @@
 				snprintf(p, 3, "%02x", hashval[i]);
 
 			purple_buddy_icons_set_for_user(js->gc->account, from, data, size, hash);
-
-			g_free(data);
 			g_free(text);
 		}
 	}
--- a/libpurple/protocols/msn/msn.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/protocols/msn/msn.c	Wed Apr 25 22:23:29 2007 +0000
@@ -1869,7 +1869,7 @@
 		{
 			char buf[1024];
 			purple_debug_info("msn", "%s is %d bytes\n", photo_url_text, len);
-			id = purple_imgstore_add_with_id(url_text, len, NULL);
+			id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL);
 			g_snprintf(buf, sizeof(buf), "<img id=\"%d\"><br>", id);
 			purple_notify_user_info_prepend_pair(user_info, NULL, buf);
 		}
--- a/libpurple/protocols/msn/slp.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/protocols/msn/slp.c	Wed Apr 25 22:23:29 2007 +0000
@@ -997,7 +997,7 @@
 	account = slpcall->slplink->session->account;
 
 	purple_buddy_icons_set_for_user(account, slpcall->slplink->remote_user,
-								  (void *)data, size, info);
+								  g_memdup(data, size), size, info);
 
 #if 0
 	/* Free one window slot */
--- a/libpurple/protocols/oscar/odc.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/protocols/oscar/odc.c	Wed Apr 25 22:23:29 2007 +0000
@@ -353,7 +353,7 @@
 
 			if ((embedded_data != NULL) && (embedded_data->size == size))
 			{
-				imgid = purple_imgstore_add_with_id(embedded_data->data, size, src);
+				imgid = purple_imgstore_add_with_id(g_memdup(embedded_data->data, size), size, src);
 
 				/* Record the image number */
 				images = g_slist_append(images, GINT_TO_POINTER(imgid));
--- a/libpurple/protocols/oscar/oscar.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/protocols/oscar/oscar.c	Wed Apr 25 22:23:29 2007 +0000
@@ -2142,7 +2142,7 @@
 	else if (args->type & OSCAR_CAPABILITY_BUDDYICON)
 	{
 		purple_buddy_icons_set_for_user(account, userinfo->sn,
-									  args->info.icon.icon,
+									  g_memdup(args->info.icon.icon, args->info.icon.length),
 									  args->info.icon.length,
 									  NULL);
 	}
@@ -3242,7 +3242,7 @@
 	if ((iconlen > 0) && (iconlen != 90)) {
 		char *b16 = purple_base16_encode(iconcsum, iconcsumlen);
 		purple_buddy_icons_set_for_user(purple_connection_get_account(gc),
-									  sn, icon, iconlen, b16);
+									  sn, g_memdup(icon, iconlen), iconlen, b16);
 		g_free(b16);
 	}
 
--- a/libpurple/protocols/qq/buddy_info.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/protocols/qq/buddy_info.c	Wed Apr 25 22:23:29 2007 +0000
@@ -541,7 +541,6 @@
 	else
 	{
 		purple_buddy_icons_set_for_user(account, who, data, len, icon_num);
-		g_free(data);
 	}
 }
 
--- a/libpurple/protocols/sametime/sametime.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/protocols/sametime/sametime.c	Wed Apr 25 22:23:29 2007 +0000
@@ -2699,7 +2699,6 @@
 
       /* add image to the purple image store */
       img = purple_imgstore_add_with_id(d_dat, d_len, cid);
-      g_free(d_dat);
 
       /* map the cid to the image store identifier */
       g_hash_table_insert(img_by_cid, cid, GINT_TO_POINTER(img));
--- a/libpurple/protocols/silc/buddy.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/protocols/silc/buddy.c	Wed Apr 25 22:23:29 2007 +0000
@@ -987,7 +987,7 @@
 					SilcUInt32 data_len;
 					data = silc_mime_get_data(m, &data_len);
 					if (data)
-						purple_buddy_icons_set_for_user(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), (void *)data, data_len);
+						purple_buddy_icons_set_for_user(purple_buddy_get_account(r->b), purple_buddy_get_name(r->b), g_memdup(data, data_len), data_len);
 				}
 				silc_mime_free(m);
 			}
--- a/libpurple/protocols/silc/ops.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/protocols/silc/ops.c	Wed Apr 25 22:23:29 2007 +0000
@@ -161,7 +161,7 @@
 		if (channel && !convo)
 			goto out;
 
-		imgid = purple_imgstore_add_with_id(data, data_len, "");
+		imgid = purple_imgstore_add_with_id(g_memdup(data, data_len), data_len, "");
 		if (imgid) {
 			cflags |= PURPLE_MESSAGE_IMAGES | PURPLE_MESSAGE_RECV;
 			g_snprintf(tmp, sizeof(tmp), "<IMG ID=\"%d\">", imgid);
--- a/libpurple/protocols/yahoo/yahoo_picture.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo_picture.c	Wed Apr 25 22:23:29 2007 +0000
@@ -60,7 +60,7 @@
 		purple_debug_error("yahoo", "Fetched an icon with length 0.  Strange.\n");
 	} else {
 		char *checksum = g_strdup_printf("%i", d->checksum);
-		purple_buddy_icons_set_for_user(purple_connection_get_account(d->gc), d->who, (void *)pic_data, len, checksum);
+		purple_buddy_icons_set_for_user(purple_connection_get_account(d->gc), d->who, g_memdup(pic_data, len), len, checksum);
 		g_free(checksum);
 	}
 
--- a/libpurple/protocols/yahoo/yahoo_profile.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/libpurple/protocols/yahoo/yahoo_profile.c	Wed Apr 25 22:23:29 2007 +0000
@@ -1022,7 +1022,7 @@
 					photo_url_text, url_text);
 		} else {
 			purple_debug_info("yahoo", "%s is %d bytes\n", photo_url_text, len);
-			id = purple_imgstore_add_with_id(url_text, len, NULL);
+			id = purple_imgstore_add_with_id(g_memdup(url_text, len), len, NULL);
 			
 			tmp = g_strdup_printf("<img id=\"%d\"><br>", id);
 			purple_notify_user_info_add_pair(user_info, NULL, tmp);
--- a/pidgin/gtkaccount.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/pidgin/gtkaccount.c	Wed Apr 25 22:23:29 2007 +0000
@@ -199,9 +199,11 @@
 	GdkPixbuf *pixbuf = NULL;
 
 	purple_imgstore_unref(dialog->icon_img);
-	if (data != NULL && len > 0)
-		dialog->icon_img = purple_imgstore_add(data, len, new_icon_path);
-	g_free(data);
+	if (data != NULL)
+		if (len > 0)
+			dialog->icon_img = purple_imgstore_add(data, len, new_icon_path);
+		else
+			g_free(data);
 
 	if (dialog->icon_img != NULL) {
 		GdkPixbufLoader *loader = gdk_pixbuf_loader_new();
--- a/pidgin/gtkimhtmltoolbar.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/pidgin/gtkimhtmltoolbar.c	Wed Apr 25 22:23:29 2007 +0000
@@ -481,7 +481,6 @@
 	name = strrchr(filename, G_DIR_SEPARATOR) + 1;
 
 	id = purple_imgstore_add_with_id(filedata, size, name);
-	g_free(filedata);
 
 	if (id == 0) {
 		buf = g_strdup_printf(_("Failed to store image: %s\n"), filename);
--- a/pidgin/gtkstatusbox.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/pidgin/gtkstatusbox.c	Wed Apr 25 22:23:29 2007 +0000
@@ -401,7 +401,6 @@
 			if (g_file_get_contents(filename, &contents, &size, NULL))
 			{
 				img = purple_imgstore_add(contents, size, filename);
-				g_free(contents);
 			}
 		}
 
--- a/pidgin/gtkutils.c	Wed Apr 25 21:48:56 2007 +0000
+++ b/pidgin/gtkutils.c	Wed Apr 25 22:23:29 2007 +0000
@@ -1351,7 +1351,6 @@
 			return;
 		}
 		id = purple_imgstore_add_with_id(filedata, size, data->filename);
-		g_free(filedata);
 
 		gtk_text_buffer_get_iter_at_mark(GTK_IMHTML(gtkconv->entry)->text_buffer, &iter,
 						 gtk_text_buffer_get_insert(GTK_IMHTML(gtkconv->entry)->text_buffer));