gobjectification: 61b9fcfa: Converted PurpleCircBuffer to a GObject ...

grim at pidgin.im grim at pidgin.im
Mon Mar 21 03:23:03 EDT 2011


----------------------------------------------------------------------
Revision: 61b9fcfa675b77124b7e0a3d92f41b59aa2713a6
Parent:   c80ed0d532adbb826aa721a9f241b431c2640fab
Author:   grim at pidgin.im
Date:     03/21/11 03:16:00
Branch:   im.pidgin.gobjectification
URL: http://d.pidgin.im/viewmtn/revision/info/61b9fcfa675b77124b7e0a3d92f41b59aa2713a6

Changelog: 

Converted PurpleCircBuffer to a GObject and renamed it to PurpleCircularBuffer

Changes against parent c80ed0d532adbb826aa721a9f241b431c2640fab

  patched  libpurple/circbuffer.c
  patched  libpurple/circbuffer.h
  patched  libpurple/protocols/irc/irc.c
  patched  libpurple/protocols/irc/irc.h
  patched  libpurple/protocols/jabber/bosh.c
  patched  libpurple/protocols/jabber/jabber.c
  patched  libpurple/protocols/jabber/jabber.h
  patched  libpurple/protocols/jabber/si.c
  patched  libpurple/protocols/msn/httpconn.c
  patched  libpurple/protocols/msn/httpconn.h
  patched  libpurple/protocols/msn/servconn.c
  patched  libpurple/protocols/msn/servconn.h
  patched  libpurple/protocols/oscar/flap_connection.c
  patched  libpurple/protocols/oscar/oft.c
  patched  libpurple/protocols/oscar/oscar.h
  patched  libpurple/protocols/oscar/peer.c
  patched  libpurple/protocols/oscar/peer.h
  patched  libpurple/protocols/qq/qq.h
  patched  libpurple/protocols/qq/qq_network.c
  patched  libpurple/protocols/simple/simple.c
  patched  libpurple/protocols/simple/simple.h
  patched  libpurple/protocols/yahoo/libymsg.c
  patched  libpurple/protocols/yahoo/libymsg.h
  patched  libpurple/protocols/yahoo/yahoo_packet.c
  patched  libpurple/protocols/yahoo/ycht.c
  patched  libpurple/protocols/yahoo/ycht.h

-------------- next part --------------
============================================================
--- libpurple/protocols/irc/irc.c	d2d30ed597eb55f5e6620395b9697bd5bda1811f
+++ libpurple/protocols/irc/irc.c	813b053f41d35870f94814c9ab82887acb5a74b8
@@ -109,8 +109,9 @@ irc_send_cb(gpointer data, gint source, 
 {
 	struct irc_conn *irc = data;
 	int ret, writelen;
+	const gchar *buffer = NULL;
 
-	writelen = purple_circ_buffer_get_max_read(irc->outbuf);
+	writelen = purple_circular_buffer_get_max_read(irc->outbuf);
 
 	if (writelen == 0) {
 		purple_input_remove(irc->writeh);
@@ -118,8 +119,10 @@ irc_send_cb(gpointer data, gint source, 
 		return;
 	}
 
-	ret = do_send(irc, irc->outbuf->outptr, writelen);
+	buffer = purple_circular_buffer_get_output(irc->outbuf);
 
+	ret = do_send(irc, buffer, writelen);
+
 	if (ret < 0 && errno == EAGAIN)
 		return;
 	else if (ret <= 0) {
@@ -132,7 +135,7 @@ irc_send_cb(gpointer data, gint source, 
 		return;
 	}
 
-	purple_circ_buffer_mark_read(irc->outbuf, ret);
+	purple_circular_buffer_mark_read(irc->outbuf, ret);
 
 #if 0
 	/* We *could* try to write more if we wrote it all */
@@ -178,7 +181,7 @@ int irc_send(struct irc_conn *irc, const
 			irc->writeh = purple_input_add(
 				irc->gsc ? irc->gsc->fd : irc->fd,
 				PURPLE_INPUT_WRITE, irc_send_cb, irc);
-		purple_circ_buffer_append(irc->outbuf, tosend + ret,
+		purple_circular_buffer_append(irc->outbuf, tosend + ret,
 			buflen - ret);
 	}
 	g_free(tosend);
@@ -359,7 +362,7 @@ static void irc_login(PurpleAccount *acc
 	purple_object_set_protocol_data(PURPLE_OBJECT(gc),irc = g_new0(struct irc_conn, 1));
 	irc->fd = -1;
 	irc->account = account;
-	irc->outbuf = purple_circ_buffer_new(512);
+	irc->outbuf = purple_circular_buffer_new(512);
 
 	userparts = g_strsplit(username, "@", 2);
 	purple_connection_set_display_name(gc, userparts[0]);
@@ -552,7 +555,7 @@ static void irc_close(PurpleConnection *
 	if (irc->writeh)
 		purple_input_remove(irc->writeh);
 
-	purple_circ_buffer_destroy(irc->outbuf);
+	g_object_unref(G_OBJECT(irc->outbuf));
 
 	g_free(irc->mode_chars);
 	g_free(irc->reqnick);
============================================================
--- libpurple/protocols/jabber/jabber.c	6d388ff1e0983b3d39f24967bc8d054aec9d5515
+++ libpurple/protocols/jabber/jabber.c	56773f0db5edbbc8425757fdbc29dbd13371a87b
@@ -391,16 +391,19 @@ static void jabber_send_cb(gpointer data
 static void jabber_send_cb(gpointer data, gint source, PurpleInputCondition cond)
 {
 	JabberStream *js = data;
+	const gchar *output = NULL;
 	int ret, writelen;
-	writelen = purple_circ_buffer_get_max_read(js->write_buffer);
 
+	writelen = purple_circular_buffer_get_max_read(js->write_buffer);
+	output = purple_circular_buffer_get_output(js->write_buffer);
+
 	if (writelen == 0) {
 		purple_input_remove(js->writeh);
 		js->writeh = 0;
 		return;
 	}
 
-	ret = jabber_do_send(js, js->write_buffer->outptr, writelen);
+	ret = jabber_do_send(js, output, writelen);
 
 	if (ret < 0 && errno == EAGAIN)
 		return;
@@ -413,7 +416,7 @@ static void jabber_send_cb(gpointer data
 		return;
 	}
 
-	purple_circ_buffer_mark_read(js->write_buffer, ret);
+	purple_circular_buffer_mark_read(js->write_buffer, ret);
 }
 
 static gboolean do_jabber_send_raw(JabberStream *js, const char *data, int len)
@@ -456,7 +459,7 @@ static gboolean do_jabber_send_raw(Jabbe
 			js->writeh = purple_input_add(
 				js->gsc ? js->gsc->fd : js->fd,
 				PURPLE_INPUT_WRITE, jabber_send_cb, js);
-		purple_circ_buffer_append(js->write_buffer,
+		purple_circular_buffer_append(js->write_buffer,
 			data + ret, len - ret);
 	}
 
@@ -976,7 +979,7 @@ jabber_stream_new(PurpleAccount *account
 	js->chats = g_hash_table_new_full(g_str_hash, g_str_equal,
 			g_free, (GDestroyNotify)jabber_chat_free);
 	js->next_id = g_random_int();
-	js->write_buffer = purple_circ_buffer_new(512);
+	js->write_buffer = purple_circular_buffer_new(512);
 	js->old_length = 0;
 	js->keepalive_timeout = 0;
 	js->max_inactivity = DEFAULT_INACTIVITY_TIME;
@@ -1657,7 +1660,7 @@ void jabber_close(PurpleConnection *gc)
 	g_free(js->caps_hash);
 
 	if (js->write_buffer)
-		purple_circ_buffer_destroy(js->write_buffer);
+		g_object_unref(G_OBJECT(js->write_buffer));
 	if(js->writeh)
 		purple_input_remove(js->writeh);
 	if (js->auth_mech && js->auth_mech->dispose)
============================================================
--- libpurple/protocols/jabber/jabber.h	8093864e192c0e6f0cc8f19f0bb91a7a19ea77c2
+++ libpurple/protocols/jabber/jabber.h	c09e7dc51939cfdd757c523879bd9a12e0c92ee9
@@ -189,7 +189,7 @@ struct _JabberStream
 
 	GSList *pending_buddy_info_requests;
 
-	PurpleCircBuffer *write_buffer;
+	PurpleCircularBuffer *write_buffer;
 	guint writeh;
 
 	gboolean reinit;
============================================================
--- libpurple/protocols/yahoo/libymsg.c	9b76dcf47278173c26e6da729b63f0cbc4be22c0
+++ libpurple/protocols/yahoo/libymsg.c	fee1585dc5583d7a71f92496032098de44039a90
@@ -3681,7 +3681,7 @@ void yahoo_login(PurpleAccount *account)
 	yd->fd = -1;
 	yd->txhandler = 0;
 	/* TODO: Is there a good grow size for the buffer? */
-	yd->txbuf = purple_circ_buffer_new(0);
+	yd->txbuf = purple_circular_buffer_new(0);
 	yd->friends = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, yahoo_friend_free);
 	yd->imvironments = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
 	yd->xfer_peer_idstring_map = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL);
@@ -3773,7 +3773,7 @@ void yahoo_close(PurpleConnection *gc) {
 	if (yd->txhandler)
 		purple_input_remove(yd->txhandler);
 
-	purple_circ_buffer_destroy(yd->txbuf);
+	g_object_unref(G_OBJECT(yd->txbuf));
 
 	if (yd->fd >= 0)
 		close(yd->fd);
============================================================
--- libpurple/protocols/msn/servconn.c	c34d814fd12818e4c567b075e1ec2cd0c69bc243
+++ libpurple/protocols/msn/servconn.c	371fe75d0b1f2c6a77a697a33deb54ac44c67167
@@ -53,7 +53,7 @@ msn_servconn_new(MsnSession *session, Ms
 
 	servconn->num = session->servconns_count++;
 
-	servconn->tx_buf = purple_circ_buffer_new(MSN_BUF_LEN);
+	servconn->tx_buf = purple_circular_buffer_new(MSN_BUF_LEN);
 	servconn->tx_handler = 0;
 	servconn->timeout_sec = 0;
 	servconn->timeout_handle = 0;
@@ -84,7 +84,7 @@ msn_servconn_destroy(MsnServConn *servco
 
 	g_free(servconn->host);
 
-	purple_circ_buffer_destroy(servconn->tx_buf);
+	g_object_unref(G_OBJECT(servconn->tx_buf));
 	if (servconn->tx_handler > 0)
 		purple_input_remove(servconn->tx_handler);
 	if (servconn->timeout_handle > 0)
@@ -334,8 +334,10 @@ servconn_write_cb(gpointer data, gint so
 	MsnServConn *servconn = data;
 	gssize ret;
 	int writelen;
+	const gchar *output = NULL;
 
-	writelen = purple_circ_buffer_get_max_read(servconn->tx_buf);
+	writelen = purple_circular_buffer_get_max_read(servconn->tx_buf);
+	output = purple_circular_buffer_get_output(servconn->tx_buf);
 
 	if (writelen == 0) {
 		purple_input_remove(servconn->tx_handler);
@@ -343,7 +345,7 @@ servconn_write_cb(gpointer data, gint so
 		return;
 	}
 
-	ret = write(servconn->fd, servconn->tx_buf->outptr, writelen);
+	ret = write(servconn->fd, output, writelen);
 
 	if (ret < 0 && errno == EAGAIN)
 		return;
@@ -352,7 +354,7 @@ servconn_write_cb(gpointer data, gint so
 		return;
 	}
 
-	purple_circ_buffer_mark_read(servconn->tx_buf, ret);
+	purple_circular_buffer_mark_read(servconn->tx_buf, ret);
 	servconn_timeout_renew(servconn);
 }
 
@@ -394,7 +396,7 @@ msn_servconn_write(MsnServConn *servconn
 				servconn->tx_handler = purple_input_add(
 					servconn->fd, PURPLE_INPUT_WRITE,
 					servconn_write_cb, servconn);
-			purple_circ_buffer_append(servconn->tx_buf, buf + ret,
+			purple_circular_buffer_append(servconn->tx_buf, buf + ret,
 				len - ret);
 		}
 	}
============================================================
--- libpurple/protocols/msn/servconn.h	9c071ff49d6ee47c7cb6a0df0caf24dc283c4e2b
+++ libpurple/protocols/msn/servconn.h	046a5b232e930ebe887d03490514f98485b863d6
@@ -85,7 +85,7 @@ struct _MsnServConn
 						  It's only set when we've received a command that
 						  has a payload. */
 
-	PurpleCircBuffer *tx_buf;
+	PurpleCircularBuffer *tx_buf;
 	guint tx_handler;
 	guint timeout_sec;
 	guint timeout_handle;
============================================================
--- libpurple/protocols/irc/irc.h	7e52fe9ba8caa9d1f5a4055123b287b54ef3f599
+++ libpurple/protocols/irc/irc.h	45f85971ef47ea5bb3b018cd9acb45aac62b0112
@@ -85,7 +85,7 @@ struct irc_conn {
 
 	gboolean quitting;
 
-	PurpleCircBuffer *outbuf;
+	PurpleCircularBuffer *outbuf;
 	guint writeh;
 
 	time_t recv_time;
============================================================
--- libpurple/protocols/yahoo/libymsg.h	27cfffcdca15f0b87ff58f9e2b624a0c203fd27c
+++ libpurple/protocols/yahoo/libymsg.h	750170ce91b1dc8fc02842954d1a473669678300
@@ -190,7 +190,7 @@ typedef struct {
 	int fd;
 	guchar *rxqueue;
 	int rxlen;
-	PurpleCircBuffer *txbuf;
+	PurpleCircularBuffer *txbuf;
 	guint txhandler;
 	GHashTable *friends;
 
============================================================
--- libpurple/protocols/jabber/si.c	60aa148508dbd9ff8cf0cb6cd7866b02eae0c14b
+++ libpurple/protocols/jabber/si.c	a83ea8eede2cd2d5e7c455fbe9898bc2cd83abb5
@@ -71,7 +71,7 @@ typedef struct _JabberSIXfer {
 
 	JabberIBBSession *ibb_session;
 	guint ibb_timeout_handle;
-	PurpleCircBuffer *ibb_buffer;
+	PurpleCircularBuffer *ibb_buffer;
 } JabberSIXfer;
 
 /* some forward declarations */
@@ -1012,7 +1012,7 @@ jabber_si_xfer_ibb_recv_data_cb(JabberIB
 	if (size <= purple_xfer_get_bytes_remaining(xfer)) {
 		purple_debug_info("jabber", "about to write %" G_GSIZE_FORMAT " bytes from IBB stream\n",
 			size);
-		purple_circ_buffer_append(jsx->ibb_buffer, data, size);
+		purple_circular_buffer_append(jsx->ibb_buffer, data, size);
 		purple_xfer_prpl_ready(xfer);
 	} else {
 		/* trying to write past size of file transfers negotiated size,
@@ -1029,15 +1029,15 @@ jabber_si_xfer_ibb_read(guchar **out_buf
 {
 	JabberSIXfer *jsx = xfer->data;
 	guchar *buffer;
-	gsize size;
+	gsize size = purple_circular_buffer_get_used(jsx->ibb_buffer);
 	gsize tmp;
 
-	size = jsx->ibb_buffer->bufused;
 	*out_buffer = buffer = g_malloc(size);
-	while ((tmp = purple_circ_buffer_get_max_read(jsx->ibb_buffer))) {
-		memcpy(buffer, jsx->ibb_buffer->outptr, tmp);
+	while ((tmp = purple_circular_buffer_get_max_read(jsx->ibb_buffer))) {
+		const gchar *output = purple_circular_buffer_get_output(jsx->ibb_buffer);
+		memcpy(buffer, output, tmp);
 		buffer += tmp;
-		purple_circ_buffer_mark_read(jsx->ibb_buffer, tmp);
+		purple_circular_buffer_mark_read(jsx->ibb_buffer, tmp);
 	}
 
 	return size;
@@ -1070,7 +1070,7 @@ jabber_si_xfer_ibb_open_cb(JabberStream 
 			 clients interpreting the block-size attribute as that
 			 (see also remark in ibb.c) */
 			jsx->ibb_buffer =
-				purple_circ_buffer_new(jabber_ibb_session_get_block_size(sess));
+				purple_circular_buffer_new(jabber_ibb_session_get_block_size(sess));
 
 			/* set up read function */
 			purple_xfer_set_read_fnc(xfer, jabber_si_xfer_ibb_read);
@@ -1158,7 +1158,7 @@ jabber_si_xfer_ibb_send_init(JabberStrea
 		purple_xfer_set_write_fnc(xfer, jabber_si_xfer_ibb_write);
 
 		jsx->ibb_buffer =
-			purple_circ_buffer_new(jabber_ibb_session_get_max_data_size(jsx->ibb_session));
+			purple_circular_buffer_new(jabber_ibb_session_get_max_data_size(jsx->ibb_session));
 
 		/* open the IBB session */
 		jabber_ibb_session_open(jsx->ibb_session);
@@ -1336,7 +1336,7 @@ static void jabber_si_xfer_free(PurpleXf
 		}
 
 		if (jsx->ibb_buffer) {
-			purple_circ_buffer_destroy(jsx->ibb_buffer);
+			g_object_unref(G_OBJECT(jsx->ibb_buffer));
 		}
 
 		purple_debug_info("jabber", "jabber_si_xfer_free(): freeing jsx %p\n", jsx);
============================================================
--- libpurple/protocols/yahoo/ycht.c	faed785ea11fa6b9a99263bf9524c1fa7862b1d1
+++ libpurple/protocols/yahoo/ycht.c	ee77b8d2b1ded6c7a162a582181efa8408495175
@@ -267,8 +267,9 @@ static void ycht_packet_send_write_cb(gp
 {
 	YchtConn *ycht = data;
 	int ret, writelen;
+	const gchar *output = NULL;
 
-	writelen = purple_circ_buffer_get_max_read(ycht->txbuf);
+	writelen = purple_circular_buffer_get_max_read(ycht->txbuf);
 
 	if (writelen == 0) {
 		purple_input_remove(ycht->tx_handler);
@@ -276,8 +277,10 @@ static void ycht_packet_send_write_cb(gp
 		return;
 	}
 
-	ret = write(ycht->fd, ycht->txbuf->outptr, writelen);
+	output = purple_circular_buffer_get_output(ycht->txbuf);
 
+	ret = write(ycht->fd, output, writelen);
+
 	if (ret < 0 && errno == EAGAIN)
 		return;
 	else if (ret <= 0) {
@@ -292,7 +295,7 @@ static void ycht_packet_send_write_cb(gp
 		return;
 	}
 
-	purple_circ_buffer_mark_read(ycht->txbuf, ret);
+	purple_circular_buffer_mark_read(ycht->txbuf, ret);
 
 }
 
@@ -345,7 +348,7 @@ static void ycht_packet_send(YchtConn *y
 			ycht->tx_handler = purple_input_add(ycht->fd,
 				PURPLE_INPUT_WRITE, ycht_packet_send_write_cb,
 				ycht);
-		purple_circ_buffer_append(ycht->txbuf, buf + written,
+		purple_circular_buffer_append(ycht->txbuf, buf + written,
 			len - written);
 	}
 
@@ -444,7 +447,7 @@ void ycht_connection_close(YchtConn *ych
 	if (ycht->tx_handler)
 		purple_input_remove(ycht->tx_handler);
 
-	purple_circ_buffer_destroy(ycht->txbuf);
+	g_object_unref(G_OBJECT(ycht->txbuf));
 
 	g_free(ycht->rxqueue);
 
============================================================
--- libpurple/protocols/yahoo/ycht.h	4edc3ddcb9c2ac5090d8e87ab53a9dc9b0086a37
+++ libpurple/protocols/yahoo/ycht.h	2dd554b1203b8ff5d7155c40504e31f5bcc45c39
@@ -73,7 +73,7 @@ typedef struct _YchtConn {
 	gboolean changing_rooms;
 	guchar *rxqueue;
 	guint rxlen;
-	PurpleCircBuffer *txbuf;
+	PurpleCircularBuffer *txbuf;
 	guint tx_handler;
 } YchtConn;
 
============================================================
--- libpurple/protocols/yahoo/yahoo_packet.c	28dbeb27d2900b9e6801791e9c666c5df9fdda8f
+++ libpurple/protocols/yahoo/yahoo_packet.c	fb7caadf53662857448231bba0e155a80c16f59d
@@ -287,8 +287,9 @@ yahoo_packet_send_can_write(gpointer dat
 {
 	YahooData *yd = data;
 	int ret, writelen;
+	const gchar *output = NULL;
 
-	writelen = purple_circ_buffer_get_max_read(yd->txbuf);
+	writelen = purple_circular_buffer_get_max_read(yd->txbuf);
 
 	if (writelen == 0) {
 		purple_input_remove(yd->txhandler);
@@ -296,8 +297,10 @@ yahoo_packet_send_can_write(gpointer dat
 		return;
 	}
 
-	ret = write(yd->fd, yd->txbuf->outptr, writelen);
+	output = purple_circular_buffer_get_output(yd->txbuf);
 
+	ret = write(yd->fd, output, writelen);
+
 	if (ret < 0 && errno == EAGAIN)
 		return;
 	else if (ret < 0) {
@@ -307,7 +310,7 @@ yahoo_packet_send_can_write(gpointer dat
 		return;
 	}
 
-	purple_circ_buffer_mark_read(yd->txbuf, ret);
+	purple_circular_buffer_mark_read(yd->txbuf, ret);
 }
 
 
@@ -374,7 +377,7 @@ int yahoo_packet_send(struct yahoo_packe
 		if (yd->txhandler == 0)
 			yd->txhandler = purple_input_add(yd->fd, PURPLE_INPUT_WRITE,
 				yahoo_packet_send_can_write, yd);
-		purple_circ_buffer_append(yd->txbuf, data + ret, len - ret);
+		purple_circular_buffer_append(yd->txbuf, data + ret, len - ret);
 	}
 
 	g_free(data);
============================================================
--- libpurple/protocols/msn/httpconn.c	d0fbfbe984f9ee05e66b097956147d5f02b74285
+++ libpurple/protocols/msn/httpconn.c	cf8da190074d10e31048ce5ecc755770ada3a164
@@ -351,9 +351,11 @@ httpconn_write_cb(gpointer data, gint so
 	MsnHttpConn *httpconn;
 	gssize ret;
 	int writelen;
+	const gchar *output = NULL;
 
 	httpconn = data;
-	writelen = purple_circ_buffer_get_max_read(httpconn->tx_buf);
+	writelen = purple_circular_buffer_get_max_read(httpconn->tx_buf);
+	output = purple_circular_buffer_get_output(httpconn->tx_buf);
 
 	if (writelen == 0)
 	{
@@ -362,7 +364,7 @@ httpconn_write_cb(gpointer data, gint so
 		return;
 	}
 
-	ret = write(httpconn->fd, httpconn->tx_buf->outptr, writelen);
+	ret = write(httpconn->fd, output, writelen);
 	if (ret <= 0)
 	{
 		if ((errno == EAGAIN) || (errno == EWOULDBLOCK))
@@ -374,7 +376,7 @@ httpconn_write_cb(gpointer data, gint so
 		return;
 	}
 
-	purple_circ_buffer_mark_read(httpconn->tx_buf, ret);
+	purple_circular_buffer_mark_read(httpconn->tx_buf, ret);
 
 	/* TODO: I don't think these 2 lines are needed.  Remove them? */
 	if (ret == writelen)
@@ -407,7 +409,7 @@ write_raw(MsnHttpConn *httpconn, const c
 		if (httpconn->tx_handler == 0 && httpconn->fd)
 			httpconn->tx_handler = purple_input_add(httpconn->fd,
 				PURPLE_INPUT_WRITE, httpconn_write_cb, httpconn);
-		purple_circ_buffer_append(httpconn->tx_buf, data + res,
+		purple_circular_buffer_append(httpconn->tx_buf, data + res,
 			data_len - res);
 	}
 
@@ -610,7 +612,7 @@ msn_httpconn_new(MsnServConn *servconn)
 
 	httpconn->servconn = servconn;
 
-	httpconn->tx_buf = purple_circ_buffer_new(MSN_BUF_LEN);
+	httpconn->tx_buf = purple_circular_buffer_new(MSN_BUF_LEN);
 	httpconn->tx_handler = 0;
 
 	httpconn->fd = -1;
@@ -645,7 +647,7 @@ msn_httpconn_destroy(MsnHttpConn *httpco
 		g_free(queue_data);
 	}
 
-	purple_circ_buffer_destroy(httpconn->tx_buf);
+	g_object_unref(G_OBJECT(httpconn->tx_buf));
 	if (httpconn->tx_handler > 0)
 		purple_input_remove(httpconn->tx_handler);
 
============================================================
--- libpurple/protocols/msn/httpconn.h	bab2b06c03d57a4ddb7c5b096567797d272629af
+++ libpurple/protocols/msn/httpconn.h	fcce8a94fb10b618ee49bd0759074c9fa3b007a7
@@ -61,7 +61,7 @@ struct _MsnHttpConn
 	char *rx_buf; /**< The receive buffer. */
 	int rx_len; /**< The receive buffer length. */
 
-	PurpleCircBuffer *tx_buf;
+	PurpleCircularBuffer *tx_buf;
 	guint tx_handler;
 };
 
============================================================
--- libpurple/protocols/simple/simple.c	51189f58219b9a9cd5ab6c6e978c81aa470c3c86
+++ libpurple/protocols/simple/simple.c	84bb10853c893f02a24bbf233af9360d6f69ef44
@@ -415,8 +415,9 @@ static void simple_canwrite_cb(gpointer 
 	struct simple_account_data *sip = purple_object_get_protocol_data(PURPLE_OBJECT(gc));
 	gsize max_write;
 	gssize written;
+	const gchar *output = NULL;
 
-	max_write = purple_circ_buffer_get_max_read(sip->txbuf);
+	max_write = purple_circular_buffer_get_max_read(sip->txbuf);
 
 	if(max_write == 0) {
 		purple_input_remove(sip->tx_handler);
@@ -424,8 +425,10 @@ static void simple_canwrite_cb(gpointer 
 		return;
 	}
 
-	written = write(sip->fd, sip->txbuf->outptr, max_write);
+	output = purple_circular_buffer_get_output(sip->txbuf);
 
+	written = write(sip->fd, output, max_write);
+
 	if(written < 0 && errno == EAGAIN)
 		written = 0;
 	else if (written <= 0) {
@@ -438,7 +441,7 @@ static void simple_canwrite_cb(gpointer 
 		return;
 	}
 
-	purple_circ_buffer_mark_read(sip->txbuf, written);
+	purple_circular_buffer_mark_read(sip->txbuf, written);
 }
 
 static void simple_input_cb(gpointer data, gint source, PurpleInputCondition cond);
@@ -464,7 +467,7 @@ static void send_later_cb(gpointer data,
 	simple_canwrite_cb(gc, sip->fd, PURPLE_INPUT_WRITE);
 
 	/* If there is more to write now, we need to register a handler */
-	if(sip->txbuf->bufused > 0)
+	if(purple_circular_buffer_get_used(sip->txbuf) > 0)
 		sip->tx_handler = purple_input_add(sip->fd, PURPLE_INPUT_WRITE,
 			simple_canwrite_cb, gc);
 
@@ -484,10 +487,10 @@ static void sendlater(PurpleConnection *
 		sip->connecting = TRUE;
 	}
 
-	if(purple_circ_buffer_get_max_read(sip->txbuf) > 0)
-		purple_circ_buffer_append(sip->txbuf, "\r\n", 2);
+	if(purple_circular_buffer_get_max_read(sip->txbuf) > 0)
+		purple_circular_buffer_append(sip->txbuf, "\r\n", 2);
 
-	purple_circ_buffer_append(sip->txbuf, buf, strlen(buf));
+	purple_circular_buffer_append(sip->txbuf, buf, strlen(buf));
 }
 
 static void sendout_pkt(PurpleConnection *gc, const char *buf) {
@@ -528,10 +531,10 @@ static void sendout_pkt(PurpleConnection
 
 			/* XXX: is it OK to do this? You might get part of a request sent
 			   with part of another. */
-			if(sip->txbuf->bufused > 0)
-				purple_circ_buffer_append(sip->txbuf, "\r\n", 2);
+			if(purple_circular_buffer_get_used(sip->txbuf) > 0)
+				purple_circular_buffer_append(sip->txbuf, "\r\n", 2);
 
-			purple_circ_buffer_append(sip->txbuf, buf + ret,
+			purple_circular_buffer_append(sip->txbuf, buf + ret,
 				writelen - ret);
 		}
 	}
@@ -1931,7 +1934,7 @@ static void simple_login(PurpleAccount *
 	sip->udp = purple_account_get_bool(account, "udp", FALSE);
 	/* TODO: is there a good default grow size? */
 	if(!sip->udp)
-		sip->txbuf = purple_circ_buffer_new(0);
+		sip->txbuf = purple_circular_buffer_new(0);
 
 	userserver = g_strsplit(username, "@", 2);
 	if (userserver[1] == NULL || userserver[1][0] == '\0') {
@@ -2027,7 +2030,7 @@ static void simple_close(PurpleConnectio
 		transactions_remove(sip, sip->transactions->data);
 	g_free(sip->publish_etag);
 	if (sip->txbuf)
-		purple_circ_buffer_destroy(sip->txbuf);
+		g_object_unref(G_OBJECT(sip->txbuf));
 	g_free(sip->realhostname);
 
 	g_free(sip);
============================================================
--- libpurple/protocols/simple/simple.h	34020a4532ec9464d6c82babc885e557f13bfd88
+++ libpurple/protocols/simple/simple.h	541ce133847a3b0cf4a04572f613538a18524a87
@@ -101,7 +101,7 @@ struct simple_account_data {
 	guint resendtimeout;
 	gboolean connecting;
 	PurpleAccount *account;
-	PurpleCircBuffer *txbuf;
+	PurpleCircularBuffer *txbuf;
 	guint tx_handler;
 	gchar *regcallid;
 	GSList *transactions;
============================================================
--- libpurple/circbuffer.c	b32995d2823f39bf7136c85dcacd246246bbde11
+++ libpurple/circbuffer.c	0f0033b374215374714e384b3a96b132d805779d
@@ -27,127 +27,357 @@
 
 #define DEFAULT_BUF_SIZE 256
 
-PurpleCircBuffer *
-purple_circ_buffer_new(gsize growsize) {
-	PurpleCircBuffer *buf = g_new0(PurpleCircBuffer, 1);
-	buf->growsize = growsize ? growsize : DEFAULT_BUF_SIZE;
-	return buf;
-}
+#define PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(obj) \
+	(G_TYPE_INSTANCE_GET_PRIVATE((obj), PURPLE_TYPE_CIRCULAR_BUFFER, PurpleCircularBufferPrivate))
 
-void purple_circ_buffer_destroy(PurpleCircBuffer *buf) {
-	g_return_if_fail(buf != NULL);
+/******************************************************************************
+ * Structs
+ *****************************************************************************/
+typedef struct {
+	gchar *buffer;
+	gsize growsize;
+	gsize buflen;
+	gsize bufused;
+	gchar *input;
+	gchar *output;
+} PurpleCircularBufferPrivate;
 
-	g_free(buf->buffer);
-	g_free(buf);
-}
+/******************************************************************************
+ * Enums
+ *****************************************************************************/
+enum {
+	PROP_ZERO,
+	PROP_BUFFER,
+	PROP_GROW_SIZE,
+	PROP_BUFFER_LEN,
+	PROP_BUFFER_USED,
+	PROP_IN_POINTER,
+	PROP_OUTPUT,
+	PROP_LAST,
+};
 
-static void grow_circ_buffer(PurpleCircBuffer *buf, gsize len) {
-	int in_offset = 0, out_offset = 0;
-	int start_buflen;
+/******************************************************************************
+ * Globals
+ *****************************************************************************/
+static GObjectClass *parent_class = NULL;
 
-	g_return_if_fail(buf != NULL);
+/******************************************************************************
+ * Circular Buffer Implementation
+ *****************************************************************************/
+static void
+purple_circular_buffer_real_grow(PurpleCircularBuffer *buffer, gsize len) {
+	PurpleCircularBufferPrivate *priv = NULL;
+	gint in_offset = 0, out_offset = 0;
+	gint start_buflen;
 
-	start_buflen = buf->buflen;
+	priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
 
-	while ((buf->buflen - buf->bufused) < len)
-		buf->buflen += buf->growsize;
+	start_buflen = priv->buflen;
 
-	if (buf->inptr != NULL) {
-		in_offset = buf->inptr - buf->buffer;
-		out_offset = buf->outptr - buf->buffer;
+	while((priv->buflen - priv->bufused) < len)
+		priv->buflen += priv->growsize;
+
+	if(priv->input != NULL) {
+		in_offset = priv->input - priv->buffer;
+		out_offset = priv->output - priv->buffer;
 	}
-	buf->buffer = g_realloc(buf->buffer, buf->buflen);
 
+	priv->buffer = g_realloc(priv->buffer, priv->buflen);
+
 	/* adjust the fill and remove pointer locations */
-	if (buf->inptr == NULL) {
-		buf->inptr = buf->outptr = buf->buffer;
+	if(priv->input == NULL) {
+		priv->input = priv->output = priv->buffer;
 	} else {
-		buf->inptr = buf->buffer + in_offset;
-		buf->outptr = buf->buffer + out_offset;
+		priv->input = priv->buffer + in_offset;
+		priv->output = priv->buffer + out_offset;
 	}
 
 	/* If the fill pointer is wrapped to before the remove
 	 * pointer, we need to shift the data */
-	if (in_offset < out_offset
-			|| (in_offset == out_offset && buf->bufused > 0)) {
-		int shift_n = MIN(buf->buflen - start_buflen,
-			in_offset);
-		memcpy(buf->buffer + start_buflen, buf->buffer,
-			shift_n);
+	if(in_offset < out_offset
+			|| (in_offset == out_offset && priv->bufused > 0))
+	{
+		gint shift_n = MIN(priv->buflen - start_buflen, in_offset);
+		memcpy(priv->buffer + start_buflen, priv->buffer, shift_n);
 
-		/* If we couldn't fit the wrapped read buffer
-		 * at the end */
+		/* If we couldn't fit the wrapped read buffer at the end */
 		if (shift_n < in_offset) {
-			memmove(buf->buffer,
-				buf->buffer + shift_n,
-				in_offset - shift_n);
-			buf->inptr = buf->buffer +
-				(in_offset - shift_n);
+			memmove(priv->buffer, priv->buffer + shift_n, in_offset - shift_n);
+			priv->input = priv->buffer + (in_offset - shift_n);
 		} else {
-			buf->inptr = buf->buffer +
-				start_buflen + in_offset;
+			priv->input = priv->buffer + start_buflen + in_offset;
 		}
 	}
 }
 
-void purple_circ_buffer_append(PurpleCircBuffer *buf, gconstpointer src, gsize len) {
+static void
+purple_circular_buffer_real_append(PurpleCircularBuffer *buffer,
+                                   gconstpointer src, gsize len)
+{
+	PurpleCircularBufferPrivate *priv = NULL;
+	gint len_stored;
 
-	int len_stored;
+	priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
 
-	g_return_if_fail(buf != NULL);
-
 	/* Grow the buffer, if necessary */
-	if ((buf->buflen - buf->bufused) < len)
-		grow_circ_buffer(buf, len);
+	if((priv->buflen - priv->bufused) < len)
+		purple_circular_buffer_grow(buffer, len);
 
 	/* If there is not enough room to copy all of src before hitting
 	 * the end of the buffer then we will need to do two copies.
-	 * One copy from inptr to the end of the buffer, and the
+	 * One copy from input to the end of the buffer, and the
 	 * second copy from the start of the buffer to the end of src. */
-	if (buf->inptr >= buf->outptr)
-		len_stored = MIN(len, buf->buflen
-			- (buf->inptr - buf->buffer));
+	if(priv->input >= priv->output)
+		len_stored = MIN(len, priv->buflen - (priv->input - priv->buffer));
 	else
 		len_stored = len;
 
-	if (len_stored > 0)
-		memcpy(buf->inptr, src, len_stored);
+	if(len_stored > 0)
+		memcpy(priv->input, src, len_stored);
 
-	if (len_stored < len) {
-		memcpy(buf->buffer, (char*)src + len_stored, len - len_stored);
-		buf->inptr = buf->buffer + (len - len_stored);
+	if(len_stored < len) {
+		memcpy(priv->buffer, (char*)src + len_stored, len - len_stored);
+		priv->input = priv->buffer + (len - len_stored);
 	} else {
-		buf->inptr += len_stored;
+		priv->input += len_stored;
 	}
 
-	buf->bufused += len;
+	priv->bufused += len;
 }
 
-gsize purple_circ_buffer_get_max_read(const PurpleCircBuffer *buf) {
+static gsize
+purple_circular_buffer_real_max_read_size(const PurpleCircularBuffer *buffer) {
+	PurpleCircularBufferPrivate *priv = NULL;
 	gsize max_read;
 
-	g_return_val_if_fail(buf != NULL, 0);
+	priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
 
-	if (buf->bufused == 0)
+	if(priv->bufused == 0)
 		max_read = 0;
-	else if ((buf->outptr - buf->inptr) >= 0)
-		max_read = buf->buflen - (buf->outptr - buf->buffer);
+	else if((priv->output - priv->input) >= 0)
+		max_read = priv->buflen - (priv->output - priv->buffer);
 	else
-		max_read = buf->inptr - buf->outptr;
+		max_read = priv->input - priv->output;
 
 	return max_read;
 }
 
-gboolean purple_circ_buffer_mark_read(PurpleCircBuffer *buf, gsize len) {
-	g_return_val_if_fail(buf != NULL, FALSE);
-	g_return_val_if_fail(purple_circ_buffer_get_max_read(buf) >= len, FALSE);
+static gboolean
+purple_circular_buffer_real_mark_read(PurpleCircularBuffer *buffer,
+                                      gsize len)
+{
+	PurpleCircularBufferPrivate *priv = NULL;
 
-	buf->outptr += len;
-	buf->bufused -= len;
+	g_return_val_if_fail(purple_circular_buffer_get_max_read(buffer) >= len, FALSE);
+
+	priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+	priv->output += len;
+	priv->bufused -= len;
+
 	/* wrap to the start if we're at the end */
-	if ((buf->outptr - buf->buffer) == buf->buflen)
-		buf->outptr = buf->buffer;
+	if((priv->output - priv->buffer) == priv->buflen)
+		priv->output = priv->buffer;
 
 	return TRUE;
 }
 
+/******************************************************************************
+ * Object Stuff
+ *****************************************************************************/
+static void
+purple_circular_buffer_finalize(GObject *obj) {
+	PurpleCircularBufferPrivate *priv =
+		PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(obj);
+
+	g_free(priv->buffer);
+
+	G_OBJECT_CLASS(parent_class)->finalize(obj);
+}
+
+static void
+purple_circular_buffer_get_property(GObject *obj, guint param_id,
+                                    GValue *value, GParamSpec *pspec)
+{
+	PurpleCircularBuffer *buffer = PURPLE_CIRCULAR_BUFFER(obj);
+
+	switch(param_id) {
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+			break;
+	}
+}
+
+static void
+purple_circular_buffer_set_property(GObject *obj, guint param_id,
+                                    const GValue *value, GParamSpec *pspec)
+{
+	PurpleCircularBuffer *buffer = PURPLE_CIRCULAR_BUFFER(obj);
+
+	switch(param_id) {
+		default:
+			G_OBJECT_WARN_INVALID_PROPERTY_ID(obj, param_id, pspec);
+			break;
+	}
+}
+
+static void
+purple_circular_buffer_class_init(PurpleCircularBufferClass *klass) {
+	GObjectClass *obj_class = G_OBJECT_CLASS(klass);
+	PurpleCircularBufferClass *buffer_class = PURPLE_CIRCULAR_BUFFER_CLASS(klass);
+
+	parent_class = g_type_class_peek_parent(klass);
+
+	obj_class->finalize = purple_circular_buffer_finalize;
+	obj_class->get_property = purple_circular_buffer_get_property;
+	obj_class->set_property = purple_circular_buffer_set_property;
+
+	buffer_class->grow = purple_circular_buffer_real_grow;
+	buffer_class->append = purple_circular_buffer_real_append;
+	buffer_class->max_read_size = purple_circular_buffer_real_max_read_size;
+	buffer_class->mark_read = purple_circular_buffer_real_mark_read;
+}
+
+/******************************************************************************
+ * API
+ *****************************************************************************/
+GType
+purple_circular_buffer_get_type(void) {
+	static GType type = 0;
+
+	if(G_UNLIKELY(type == 0)) {
+		static const GTypeInfo info = {
+			.class_size = sizeof(PurpleCircularBufferClass),
+			.class_init = (GClassInitFunc)purple_circular_buffer_class_init,
+			.instance_size = sizeof(PurpleCircularBuffer),
+		};
+
+		type = g_type_register_static(G_TYPE_OBJECT,
+		                              "PurpleCircularBuffer",
+		                              &info, 0);
+	}
+
+	return type;
+}
+
+PurpleCircularBuffer *
+purple_circular_buffer_new(gsize growsize) {
+	return g_object_new(PURPLE_TYPE_CIRCULAR_BUFFER,
+	                    "grow-size", growsize ? growsize : DEFAULT_BUF_SIZE,
+	                    NULL);
+}
+
+void
+purple_circular_buffer_grow(PurpleCircularBuffer *buffer, gsize len) {
+	PurpleCircularBufferClass *klass = NULL;
+
+	g_return_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer));
+
+	klass = PURPLE_CIRCULAR_BUFFER_GET_CLASS(buffer);
+	if(klass && klass->grow)
+		klass->grow(buffer, len);
+}
+
+void
+purple_circular_buffer_append(PurpleCircularBuffer *buffer, gconstpointer src,
+                              gsize len)
+{
+	PurpleCircularBufferClass *klass = NULL;
+
+	g_return_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer));
+	g_return_if_fail(src != NULL);
+
+	klass = PURPLE_CIRCULAR_BUFFER_GET_CLASS(buffer);
+	if(klass && klass->append)
+		klass->append(buffer, src, len);
+}
+
+gsize
+purple_circular_buffer_get_max_read(const PurpleCircularBuffer *buffer) {
+	PurpleCircularBufferClass *klass = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer), 0);
+
+	klass = PURPLE_CIRCULAR_BUFFER_GET_CLASS(buffer);
+	if(klass && klass->max_read_size)
+		return klass->max_read_size(buffer);
+
+	return 0;
+}
+
+gboolean
+purple_circular_buffer_mark_read(PurpleCircularBuffer *buffer, gsize len) {
+	PurpleCircularBufferClass *klass = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer), FALSE);
+
+	klass = PURPLE_CIRCULAR_BUFFER_CLASS(buffer);
+	if(klass && klass->mark_read)
+		return klass->mark_read(buffer, len);
+
+	return FALSE;
+}
+
+gsize
+purple_circular_buffer_get_used(const PurpleCircularBuffer *buffer) {
+	PurpleCircularBufferPrivate *priv = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer), 0);
+
+	priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+	return priv->bufused;
+}
+
+const gchar *
+purple_circular_buffer_get_input(const PurpleCircularBuffer *buffer) {
+	PurpleCircularBufferPrivate *priv = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer), NULL);
+
+	priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+	return priv->input;
+}
+
+const gchar *
+purple_circular_buffer_get_output(const PurpleCircularBuffer *buffer) {
+	PurpleCircularBufferPrivate *priv = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer), NULL);
+
+	priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+	return priv->output;
+}
+
+const gchar *
+purple_circular_buffer_get_buffer(const PurpleCircularBuffer *buffer) {
+	PurpleCircularBufferPrivate *priv = NULL;
+
+	g_return_val_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer), NULL);
+
+	priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+	return priv->buffer;
+}
+
+void
+purple_circular_buffer_reset(PurpleCircularBuffer *buffer) {
+	PurpleCircularBufferPrivate *priv = NULL;
+	GObject *obj = NULL;
+
+	g_return_if_fail(PURPLE_IS_CIRCULAR_BUFFER(buffer));
+
+	priv = PURPLE_CIRCULAR_BUFFER_GET_PRIVATE(buffer);
+
+	priv->input = priv->buffer;
+	priv->output = priv->buffer;
+
+	obj = G_OBJECT(buffer);
+	g_object_freeze_notify(obj);
+	g_object_notify(obj, "input");
+	g_object_notify(obj, "output");
+	g_object_thaw_notify(obj);
+}
+
============================================================
--- libpurple/circbuffer.h	423fc024a802905912c62da588be2273fa94fb89
+++ libpurple/circbuffer.h	50871314da7f13cd0876394ffb6b169065f2947f
@@ -21,39 +21,48 @@
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111-1301  USA
  */
-#ifndef _CIRCBUFFER_H
-#define _CIRCBUFFER_H
+#ifndef PURPLE_CIRCULAR_BUFFER_H
+#define PURPLE_CIRCULAR_BUFFER_H
 
 #include <glib.h>
+#include <glib-object.h>
 
-#ifdef __cplusplus
-extern "C" {
-#endif
+#define PURPLE_TYPE_CIRCULAR_BUFFER            (purple_circular_buffer_get_type())
+#define PURPLE_CIRCULAR_BUFFER(obj)            (G_TYPE_CHECK_INSTANCE_CAST((obj), PURPLE_TYPE_CIRCULAR_BUFFER, PurpleCircularBuffer))
+#define PURPLE_CIRCULAR_BUFFER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST((klass), PURPLE_TYPE_CIRCULAR_BUFFER, PurpleCircularBufferClass))
+#define PURPLE_IS_CIRCULAR_BUFFER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE((obj), PURPLE_TYPE_CIRCULAR_BUFFER))
+#define PURPLE_IS_CIRCULAR_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), PURPLE_TYPE_CIRCULAR_BUFFER))
+#define PURPLE_CIRCULAR_BUFFER_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS((obj), PURPLE_TYPE_CIRCULAR_BUFFER, PurpleCircularBufferClass))
 
-typedef struct _PurpleCircBuffer {
+typedef struct _PurpleCircularBuffer           PurpleCircularBuffer;
+typedef struct _PurpleCircularBufferClass      PurpleCircularBufferClass;
 
-	/** A pointer to the starting address of our chunk of memory. */
-	gchar *buffer;
+struct _PurpleCircularBuffer {
+	GObject parent;
 
-	/** The incremental amount to increase this buffer by when
-	 *  the buffer is not big enough to hold incoming data, in bytes. */
-	gsize growsize;
+	void (*purple_reserved1)(void);
+	void (*purple_reserved2)(void);
+	void (*purple_reserved3)(void);
+	void (*purple_reserved4)(void);
+};
 
-	/** The length of this buffer, in bytes. */
-	gsize buflen;
+struct _PurpleCircularBufferClass {
+	GObjectClass parent;
 
-	/** The number of bytes of this buffer that contain unread data. */
-	gsize bufused;
+	void (*grow)(PurpleCircularBuffer *buffer, gsize len);
+	void (*append)(PurpleCircularBuffer *buffer, gconstpointer src, gsize len);
+	gsize (*max_read_size)(const PurpleCircularBuffer *buffer);
+	gboolean (*mark_read)(PurpleCircularBuffer *buffer, gsize len);
 
-	/** A pointer to the next byte where new incoming data is
-	 *  buffered to. */
-	gchar *inptr;
+	void (*purple_reserved1)(void);
+	void (*purple_reserved2)(void);
+	void (*purple_reserved3)(void);
+	void (*purple_reserved4)(void);
+};
 
-	/** A pointer to the next byte of buffered data that should be
-	 *  read by the consumer. */
-	gchar *outptr;
+G_BEGIN_DECLS
 
-} PurpleCircBuffer;
+GType purple_circular_buffer_get_type(void);
 
 /**
  * Creates a new circular buffer.  This will not allocate any memory for the
@@ -66,17 +75,9 @@ typedef struct _PurpleCircBuffer {
  * @return The new PurpleCircBuffer. This should be freed with
  *         purple_circ_buffer_destroy when you are done with it
  */
-PurpleCircBuffer *purple_circ_buffer_new(gsize growsize);
+PurpleCircularBuffer *purple_circular_buffer_new(gsize growsize);
 
 /**
- * Dispose of the PurpleCircBuffer and free any memory used by it (including any
- * memory used by the internal buffer).
- *
- * @param buf The PurpleCircBuffer to free
- */
-void purple_circ_buffer_destroy(PurpleCircBuffer *buf);
-
-/**
  * Append data to the PurpleCircBuffer.  This will grow the internal
  * buffer to fit the added data, if needed.
  *
@@ -84,7 +85,7 @@ void purple_circ_buffer_destroy(PurpleCi
  * @param src pointer to the data to copy into the buffer
  * @param len number of bytes to copy into the buffer
  */
-void purple_circ_buffer_append(PurpleCircBuffer *buf, gconstpointer src, gsize len);
+void purple_circular_buffer_append(PurpleCircularBuffer *buf, gconstpointer src, gsize len);
 
 /**
  * Determine the maximum number of contiguous bytes that can be read from the
@@ -98,7 +99,7 @@ void purple_circ_buffer_append(PurpleCir
  *
  * @return the number of bytes that can be read from the PurpleCircBuffer
  */
-gsize purple_circ_buffer_get_max_read(const PurpleCircBuffer *buf);
+gsize purple_circular_buffer_get_max_read(const PurpleCircularBuffer *buf);
 
 /**
  * Mark the number of bytes that have been read from the buffer.
@@ -109,10 +110,16 @@ gsize purple_circ_buffer_get_max_read(co
  * @return TRUE if we successfully marked the bytes as having been read, FALSE
  *         otherwise.
  */
-gboolean purple_circ_buffer_mark_read(PurpleCircBuffer *buf, gsize len);
+gboolean purple_circular_buffer_mark_read(PurpleCircularBuffer *buf, gsize len);
 
-#ifdef __cplusplus
-}
-#endif
+void purple_circular_buffer_grow(PurpleCircularBuffer *buffer, gsize len);
+gsize purple_circular_buffer_get_used(const PurpleCircularBuffer *buffer);
+const gchar *purple_circular_buffer_get_input(const PurpleCircularBuffer *buffer);
+const gchar *purple_circular_buffer_get_output(const PurpleCircularBuffer *buffer);
+const gchar *purple_circular_buffer_get_buffer(const PurpleCircularBuffer *buffer);
+void purple_circular_buffer_reset(PurpleCircularBuffer *buffer);
 
-#endif /* _CIRCBUFFER_H */
+G_END_DECLS
+
+#endif /* PURPLE_CIRCULAR_BUFFER_H */
+
============================================================
--- libpurple/protocols/oscar/oscar.h	f74ac44d93d0eabd4750dad9f6e61b351cccc340
+++ libpurple/protocols/oscar/oscar.h	6cb5d9bc6265a314f76823861cd71587ab9d6098
@@ -277,7 +277,7 @@ struct _FlapConnection
 	guint8 header[6];
 	gssize header_received;
 	FlapFrame buffer_incoming;
-	PurpleCircBuffer *buffer_outgoing;
+	PurpleCircularBuffer *buffer_outgoing;
 	guint watcher_incoming;
 	guint watcher_outgoing;
 
============================================================
--- libpurple/protocols/oscar/peer.c	815bc7a8ebfe86c526229a62531dabb0b62e4d0e
+++ libpurple/protocols/oscar/peer.c	5a68908a9f1cc7d1a91e45ef61f94acfd52a97c0
@@ -115,7 +115,7 @@ peer_connection_new(OscarData *od, guint
 	conn->od = od;
 	conn->type = type;
 	conn->bn = g_strdup(bn);
-	conn->buffer_outgoing = purple_circ_buffer_new(0);
+	conn->buffer_outgoing = purple_circular_buffer_new(0);
 	conn->listenerfd = -1;
 	conn->fd = -1;
 	conn->lastactivity = time(NULL);
@@ -189,8 +189,8 @@ peer_connection_close(PeerConnection *co
 	conn->buffer_incoming.len = 0;
 	conn->buffer_incoming.offset = 0;
 
-	purple_circ_buffer_destroy(conn->buffer_outgoing);
-	conn->buffer_outgoing = purple_circ_buffer_new(0);
+	g_object_unref(G_OBJECT(conn->buffer_outgoing));
+	conn->buffer_outgoing = purple_circular_buffer_new(0);
 
 	conn->flags &= ~PEER_CONNECTION_FLAG_IS_INCOMING;
 }
@@ -234,7 +234,7 @@ peer_connection_destroy_cb(gpointer data
 	g_free(conn->clientip);
 	g_free(conn->verifiedip);
 	g_free(conn->xferdata.name);
-	purple_circ_buffer_destroy(conn->buffer_outgoing);
+	g_object_unref(G_OBJECT(conn->buffer_outgoing));
 
 	conn->od->peer_connections = g_slist_remove(conn->od->peer_connections, conn);
 
@@ -408,9 +408,10 @@ send_cb(gpointer data, gint source, Purp
 	PeerConnection *conn;
 	gsize writelen;
 	gssize wrotelen;
+	const gchar *output = NULL;
 
 	conn = data;
-	writelen = purple_circ_buffer_get_max_read(conn->buffer_outgoing);
+	writelen = purple_circular_buffer_get_max_read(conn->buffer_outgoing);
 
 	if (writelen == 0)
 	{
@@ -433,12 +434,13 @@ send_cb(gpointer data, gint source, Purp
 		 * file transfer.  Somebody should teach those guys how to
 		 * write good TCP code.
 		 */
-		conn->buffer_outgoing->inptr = conn->buffer_outgoing->buffer;
-		conn->buffer_outgoing->outptr = conn->buffer_outgoing->buffer;
+		purple_circular_buffer_reset(conn->buffer_outgoing);
 		return;
 	}
 
-	wrotelen = send(conn->fd, conn->buffer_outgoing->outptr, writelen, 0);
+	output = purple_circular_buffer_get_output(conn->buffer_outgoing);
+
+	wrotelen = send(conn->fd, output, writelen, 0);
 	if (wrotelen <= 0)
 	{
 		if (wrotelen < 0 && ((errno == EAGAIN) || (errno == EWOULDBLOCK)))
@@ -465,7 +467,7 @@ send_cb(gpointer data, gint source, Purp
 		return;
 	}
 
-	purple_circ_buffer_mark_read(conn->buffer_outgoing, wrotelen);
+	purple_circular_buffer_mark_read(conn->buffer_outgoing, wrotelen);
 	conn->lastactivity = time(NULL);
 }
 
@@ -478,7 +480,7 @@ peer_connection_send(PeerConnection *con
 peer_connection_send(PeerConnection *conn, ByteStream *bs)
 {
 	/* Add everything to our outgoing buffer */
-	purple_circ_buffer_append(conn->buffer_outgoing, bs->data, bs->len);
+	purple_circular_buffer_append(conn->buffer_outgoing, bs->data, bs->len);
 
 	/* If we haven't already started writing stuff, then start the cycle */
 	if ((conn->watcher_outgoing == 0) && (conn->fd >= 0))
============================================================
--- libpurple/protocols/oscar/peer.h	997991488f63d8f6fbfd9405f936fc02da2bd1e5
+++ libpurple/protocols/oscar/peer.h	6efd44918b7bc4103c8ce070a9ad303c776837d9
@@ -184,7 +184,7 @@ struct _PeerConnection
 	guint8 proxy_header[12];
 	gssize proxy_header_received;
 	ByteStream buffer_incoming;
-	PurpleCircBuffer *buffer_outgoing;
+	PurpleCircularBuffer *buffer_outgoing;
 	guint watcher_incoming;
 	guint watcher_outgoing;
 
============================================================
--- libpurple/protocols/oscar/flap_connection.c	a7b65f688d6a4e80e7a1fac687b95f4ca6fc14c1
+++ libpurple/protocols/oscar/flap_connection.c	6184ceaa003670d60ba24a2ebbbb36659d874086
@@ -336,7 +336,7 @@ flap_connection_new(OscarData *od, int t
 
 	conn = g_new0(FlapConnection, 1);
 	conn->od = od;
-	conn->buffer_outgoing = purple_circ_buffer_new(0);
+	conn->buffer_outgoing = purple_circular_buffer_new(0);
 	conn->fd = -1;
 	conn->subtype = -1;
 	conn->type = type;
@@ -410,7 +410,7 @@ flap_connection_close(OscarData *od, Fla
 	g_free(conn->buffer_incoming.data.data);
 	conn->buffer_incoming.data.data = NULL;
 
-	purple_circ_buffer_destroy(conn->buffer_outgoing);
+	g_object_unref(G_OBJECT(conn->buffer_outgoing));
 	conn->buffer_outgoing = NULL;
 }
 
@@ -1020,9 +1020,11 @@ send_cb(gpointer data, gint source, Purp
 {
 	FlapConnection *conn;
 	int writelen, ret;
+	const gchar *output = NULL;
 
 	conn = data;
-	writelen = purple_circ_buffer_get_max_read(conn->buffer_outgoing);
+	writelen = purple_circular_buffer_get_max_read(conn->buffer_outgoing);
+	output = purple_circular_buffer_get_output(conn->buffer_outgoing);
 
 	if (writelen == 0)
 	{
@@ -1032,10 +1034,9 @@ send_cb(gpointer data, gint source, Purp
 	}
 
 	if (conn->gsc)
-		ret = purple_ssl_write(conn->gsc, conn->buffer_outgoing->outptr,
-				writelen);
+		ret = purple_ssl_write(conn->gsc, output, writelen);
 	else
-		ret = send(conn->fd, conn->buffer_outgoing->outptr, writelen, 0);
+		ret = send(conn->fd, output, writelen, 0);
 	if (ret <= 0)
 	{
 		if (ret < 0 && (errno == EAGAIN || errno == EWOULDBLOCK))
@@ -1057,7 +1058,7 @@ send_cb(gpointer data, gint source, Purp
 		return;
 	}
 
-	purple_circ_buffer_mark_read(conn->buffer_outgoing, ret);
+	purple_circular_buffer_mark_read(conn->buffer_outgoing, ret);
 }
 
 static void
@@ -1074,7 +1075,7 @@ flap_connection_send_byte_stream(ByteStr
 		return;
 
 	/* Add everything to our outgoing buffer */
-	purple_circ_buffer_append(conn->buffer_outgoing, bs->data, count);
+	purple_circular_buffer_append(conn->buffer_outgoing, bs->data, count);
 
 	/* If we haven't already started writing stuff, then start the cycle */
 	if (conn->watcher_outgoing == 0)
============================================================
--- libpurple/protocols/oscar/oft.c	db359a6d029fbd11a74eb0e68bfb1c0732ce6514
+++ libpurple/protocols/oscar/oft.c	758d3b1aead758f0a7626262b67a870a089b7b3c
@@ -360,7 +360,7 @@ start_transfer_when_done_sending_data(gp
 
 	conn = data;
 
-	if (purple_circ_buffer_get_max_read(conn->buffer_outgoing) == 0)
+	if (purple_circular_buffer_get_max_read(conn->buffer_outgoing) == 0)
 	{
 		conn->sending_data_timer = 0;
 		conn->xfer->fd = conn->fd;
@@ -385,7 +385,7 @@ destroy_connection_when_done_sending_dat
 
 	conn = data;
 
-	if (purple_circ_buffer_get_max_read(conn->buffer_outgoing) == 0)
+	if (purple_circular_buffer_get_max_read(conn->buffer_outgoing) == 0)
 	{
 		conn->sending_data_timer = 0;
 		peer_connection_destroy(conn, conn->disconnect_reason, NULL);
============================================================
--- libpurple/protocols/qq/qq.h	5528688ea51f10d31ad0751ba7f39d53c1d8dd6b
+++ libpurple/protocols/qq/qq.h	78c25f39441b7e30d97189d92876b0dae2f91b7d
@@ -110,7 +110,7 @@ struct _qq_connection {
 
 	/* tcp related */
 	int can_write_handler; 	/* use in tcp_send_out */
-	PurpleCircBuffer *tcp_txbuf;
+	PurpleCircularBuffer *tcp_txbuf;
 	guint8 *tcp_rxqueue;
 	int tcp_rxlen;
 };
============================================================
--- libpurple/protocols/qq/qq_network.c	b893411d796216d8045686a2b43a478560b0bc4a
+++ libpurple/protocols/qq/qq_network.c	a7d21815e8b2df8f13c0e78636285881bbb9f116
@@ -80,7 +80,7 @@ static void connection_remove(qq_data *q
 	if(conn->can_write_handler > 0)	purple_input_remove(conn->can_write_handler);
 
 	if (conn->fd >= 0)	close(conn->fd);
-	if(conn->tcp_txbuf != NULL) 	purple_circ_buffer_destroy(conn->tcp_txbuf);
+	if(conn->tcp_txbuf != NULL) 	g_object_unref(G_OBJECT(conn->tcp_txbuf));
 	if (conn->tcp_rxqueue != NULL)	g_free(conn->tcp_rxqueue);
 
 	g_free(conn);
@@ -564,6 +564,7 @@ static void tcp_can_write(gpointer data,
 	qq_data *qd;
 	qq_connection *conn;
 	int ret, writelen;
+	const gchar *output = NULL;
 
 	qd = gc ? (qq_data *) purple_object_get_protocol_data(PURPLE_OBJECT(gc)) : NULL;
 	g_return_if_fail(gc != NULL && qd != NULL);
@@ -571,14 +572,16 @@ static void tcp_can_write(gpointer data,
 	conn = connection_find(qd, source);
 	g_return_if_fail(conn != NULL);
 
-	writelen = purple_circ_buffer_get_max_read(conn->tcp_txbuf);
+	writelen = purple_circular_buffer_get_max_read(conn->tcp_txbuf);
 	if (writelen == 0) {
 		purple_input_remove(conn->can_write_handler);
 		conn->can_write_handler = 0;
 		return;
 	}
 
-	ret = write(source, conn->tcp_txbuf->outptr, writelen);
+	output = purple_circular_buffer_get_output(conn->tcp_txbuf);
+
+	ret = write(source, output, writelen);
 	purple_debug_info("TCP_CAN_WRITE", "total %d bytes is sent %d\n", writelen, ret);
 
 	if (ret < 0 && errno == EAGAIN)
@@ -593,7 +596,7 @@ static void tcp_can_write(gpointer data,
 		return;
 	}
 
-	purple_circ_buffer_mark_read(conn->tcp_txbuf, ret);
+	purple_circular_buffer_mark_read(conn->tcp_txbuf, ret);
 }
 
 static gint tcp_send_out(PurpleConnection *gc, guint8 *data, gint data_len)
@@ -647,9 +650,9 @@ static gint tcp_send_out(PurpleConnectio
 			conn->can_write_handler = purple_input_add(qd->fd, PURPLE_INPUT_WRITE, tcp_can_write, gc);
 		}
 		if (conn->tcp_txbuf == NULL) {
-			conn->tcp_txbuf = purple_circ_buffer_new(4096);
+			conn->tcp_txbuf = purple_circular_buffer_new(4096);
 		}
-		purple_circ_buffer_append(conn->tcp_txbuf, data + ret, data_len - ret);
+		purple_circular_buffer_append(conn->tcp_txbuf, data + ret, data_len - ret);
 	}
 	return ret;
 }
============================================================
--- libpurple/protocols/jabber/bosh.c	aba09d70f35fd3b356aab58afd373c7836bee987
+++ libpurple/protocols/jabber/bosh.c	4b0c43bc9436168ea866ec008136ad88e3b89b99
@@ -55,7 +55,7 @@ struct _PurpleBOSHConnection {
 	JabberStream *js;
 	PurpleHTTPConnection *connections[NUM_HTTP_CONNECTIONS];
 
-	PurpleCircBuffer *pending;
+	PurpleCircularBuffer *pending;
 	PurpleBOSHConnectionConnectFunction connect_cb;
 	PurpleBOSHConnectionReceiveFunction receive_cb;
 
@@ -90,7 +90,7 @@ struct _PurpleHTTPConnection {
 	PurpleBOSHConnection *bosh;
 	PurpleSslConnection *psc;
 
-	PurpleCircBuffer *write_buf;
+	PurpleCircularBuffer *write_buf;
 	GString *read_buf;
 
 	gsize handled_len;
@@ -168,7 +168,7 @@ jabber_bosh_http_connection_init(PurpleB
 	conn->fd = -1;
 	conn->state = HTTP_CONN_OFFLINE;
 
-	conn->write_buf = purple_circ_buffer_new(0 /* default grow size */);
+	conn->write_buf = purple_circular_buffer_new(0 /* default grow size */);
 
 	return conn;
 }
@@ -180,7 +180,7 @@ jabber_bosh_http_connection_destroy(Purp
 		g_string_free(conn->read_buf, TRUE);
 
 	if (conn->write_buf)
-		purple_circ_buffer_destroy(conn->write_buf);
+		g_object_unref(G_OBJECT(conn->write_buf));
 	if (conn->readh)
 		purple_input_remove(conn->readh);
 	if (conn->writeh)
@@ -238,7 +238,7 @@ jabber_bosh_connection_init(JabberStream
 	conn->rid = ((guint64)g_random_int() << 32) | g_random_int();
 	conn->rid &= 0xFFFFFFFFFFFFFLL;
 
-	conn->pending = purple_circ_buffer_new(0 /* default grow size */);
+	conn->pending = purple_circular_buffer_new(0 /* default grow size */);
 
 	conn->state = BOSH_CONN_OFFLINE;
 	if (purple_strcasestr(url, "https://") != NULL)
@@ -262,7 +262,7 @@ jabber_bosh_connection_destroy(PurpleBOS
 	if (conn->send_timer)
 		purple_timeout_remove(conn->send_timer);
 
-	purple_circ_buffer_destroy(conn->pending);
+	g_object_unref(G_OBJECT(conn->pending));
 
 	for (i = 0; i < NUM_HTTP_CONNECTIONS; ++i) {
 		if (conn->connections[i])
@@ -350,12 +350,15 @@ jabber_bosh_connection_send(PurpleBOSHCo
 		 */
 		if (data) {
 			int len = data ? strlen(data) : 0;
-			purple_circ_buffer_append(conn->pending, data, len);
+			purple_circular_buffer_append(conn->pending, data, len);
 		}
 
-		if (purple_debug_is_verbose())
+		if (purple_debug_is_verbose()) {
+			gsize bufused = purple_circular_buffer_get_used(conn->pending);
 			purple_debug_misc("jabber", "bosh: %p has %" G_GSIZE_FORMAT " bytes in "
-			                  "the buffer.\n", conn, conn->pending->bufused);
+			                  "the buffer.\n", conn, bufused);
+		}
+
 		if (conn->send_timer == 0)
 			conn->send_timer = purple_timeout_add_seconds(BUFFER_SEND_IN_SECS,
 					send_timer_cb, conn);
@@ -410,9 +413,10 @@ jabber_bosh_connection_send(PurpleBOSHCo
 
 		packet = g_string_append_c(packet, '>');
 
-		while ((read_amt = purple_circ_buffer_get_max_read(conn->pending)) > 0) {
-			packet = g_string_append_len(packet, conn->pending->outptr, read_amt);
-			purple_circ_buffer_mark_read(conn->pending, read_amt);
+		while ((read_amt = purple_circular_buffer_get_max_read(conn->pending)) > 0) {
+			const gchar *output = purple_circular_buffer_get_output(conn->pending);
+			packet = g_string_append_len(packet, output, read_amt);
+			purple_circular_buffer_mark_read(conn->pending, read_amt);
 		}
 
 		if (data)
@@ -685,7 +689,7 @@ connection_common_established_cb(PurpleH
 		jabber_bosh_connection_send(conn->bosh, PACKET_NORMAL, NULL);
 	else if (conn->bosh->state == BOSH_CONN_ONLINE) {
 		purple_debug_info("jabber", "BOSH session already exists. Trying to reuse it.\n");
-		if (conn->bosh->requests == 0 || conn->bosh->pending->bufused > 0) {
+		if (conn->bosh->requests == 0 || purple_circular_buffer_get_used(conn->bosh->pending) > 0) {
 			/* Send the pending data */
 			jabber_bosh_connection_send(conn->bosh, PACKET_FLUSH, NULL);
 		}
@@ -840,7 +844,9 @@ jabber_bosh_http_connection_process(Purp
 	}
 
 	if (conn->bosh->state == BOSH_CONN_ONLINE &&
-			(conn->bosh->requests == 0 || conn->bosh->pending->bufused > 0)) {
+			(conn->bosh->requests == 0 ||
+			purple_circular_buffer_get_used(conn->bosh->pending) > 0))
+	{
 		purple_debug_misc("jabber", "BOSH: Sending an empty request\n");
 		jabber_bosh_connection_send(conn->bosh, PACKET_NORMAL, NULL);
 	}
@@ -1009,8 +1015,9 @@ http_connection_send_cb(gpointer data, g
 http_connection_send_cb(gpointer data, gint source, PurpleInputCondition cond)
 {
 	PurpleHTTPConnection *conn = data;
+	const gchar *output = NULL;
 	int ret;
-	int writelen = purple_circ_buffer_get_max_read(conn->write_buf);
+	int writelen = purple_circular_buffer_get_max_read(conn->write_buf);
 
 	if (writelen == 0) {
 		purple_input_remove(conn->writeh);
@@ -1018,7 +1025,8 @@ http_connection_send_cb(gpointer data, g
 		return;
 	}
 
-	ret = http_connection_do_send(conn, conn->write_buf->outptr, writelen);
+	output = purple_circular_buffer_get_output(conn->write_buf);
+	ret = http_connection_do_send(conn, output, writelen);
 
 	if (ret < 0 && errno == EAGAIN)
 		return;
@@ -1037,7 +1045,7 @@ http_connection_send_cb(gpointer data, g
 		return;
 	}
 
-	purple_circ_buffer_mark_read(conn->write_buf, ret);
+	purple_circular_buffer_mark_read(conn->write_buf, ret);
 }
 
 static void
@@ -1097,7 +1105,7 @@ http_connection_send_request(PurpleHTTPC
 		if (conn->writeh == 0)
 			conn->writeh = purple_input_add(conn->psc ? conn->psc->fd : conn->fd,
 					PURPLE_INPUT_WRITE, http_connection_send_cb, conn);
-		purple_circ_buffer_append(conn->write_buf, data + ret, len - ret);
+		purple_circular_buffer_append(conn->write_buf, data + ret, len - ret);
 	}
 }
 


More information about the Commits mailing list