diff libpurple/protocols/jabber/si.c @ 27879:b2dd32ce7353

jabber: Migrate IBB to the new code added in the previous commit.
author Paul Aurich <paul@darkrain42.org>
date Wed, 12 Aug 2009 04:32:16 +0000
parents 6adbdd4b2963
children c585572e80dd 52cb819c6668
line wrap: on
line diff
--- a/libpurple/protocols/jabber/si.c	Wed Aug 12 04:31:17 2009 +0000
+++ b/libpurple/protocols/jabber/si.c	Wed Aug 12 04:32:16 2009 +0000
@@ -67,7 +67,7 @@
 
 	JabberIBBSession *ibb_session;
 	guint ibb_timeout_handle;
-	FILE *fp;
+	PurpleCircBuffer *ibb_buffer;
 } JabberSIXfer;
 
 /* some forward declarations */
@@ -1012,18 +1012,8 @@
 	if (size <= purple_xfer_get_bytes_remaining(xfer)) {
 		purple_debug_info("jabber", "about to write %" G_GSIZE_FORMAT " bytes from IBB stream\n",
 			size);
-		if(!fwrite(data, size, 1, jsx->fp)) {
-			purple_debug_error("jabber", "error writing to file\n");
-			purple_xfer_cancel_remote(xfer);
-			return;
-		}
-		purple_xfer_set_bytes_sent(xfer, purple_xfer_get_bytes_sent(xfer) + size);
-		purple_xfer_update_progress(xfer);
-
-		if (purple_xfer_get_bytes_remaining(xfer) == 0) {
-			purple_xfer_set_completed(xfer, TRUE);
-			purple_xfer_end(xfer);
-		}
+		purple_circ_buffer_append(jsx->ibb_buffer, data, size);
+		purple_xfer_prpl_ready(xfer);
 	} else {
 		/* trying to write past size of file transfers negotiated size,
 		  reject transfer to protect against malicious behaviour */
@@ -1034,6 +1024,25 @@
 
 }
 
+static gssize
+jabber_si_xfer_ibb_read(guchar **out_buffer, PurpleXfer *xfer)
+{
+	JabberSIXfer *jsx = xfer->data;
+	guchar *buffer;
+	gsize size;
+	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);
+		buffer += tmp;
+		purple_circ_buffer_mark_read(jsx->ibb_buffer, tmp);
+	}
+
+	return size;
+}
+
 static gboolean
 jabber_si_xfer_ibb_open_cb(JabberStream *js, const char *who, const char *id,
                            xmlnode *open)
@@ -1044,21 +1053,10 @@
 		JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
 		JabberIBBSession *sess =
 			jabber_ibb_session_create_from_xmlnode(js, who, id, open, xfer);
-		const char *filename;
 
 		jabber_si_bytestreams_ibb_timeout_remove(jsx);
 
 		if (sess) {
-			/* open the file to write to */
-			filename = purple_xfer_get_local_filename(xfer);
-			jsx->fp = g_fopen(filename, "wb");
-			if (jsx->fp == NULL) {
-				purple_debug_error("jabber", "failed to open file %s for writing: %s\n",
-					filename, g_strerror(errno));
-				purple_xfer_cancel_remote(xfer);
-				return FALSE;
-			}
-
 			/* setup callbacks here...*/
 			jabber_ibb_session_set_data_received_callback(sess,
 				jabber_si_xfer_ibb_recv_data_cb);
@@ -1068,6 +1066,11 @@
 				jabber_si_xfer_ibb_error_cb);
 
 			jsx->ibb_session = sess;
+			jsx->ibb_buffer =
+				purple_circ_buffer_new(jabber_ibb_session_get_block_size(sess));
+
+			/* set up read function */
+			purple_xfer_set_read_fnc(xfer, jabber_si_xfer_ibb_read);
 
 			/* start the transfer */
 			purple_xfer_start(xfer, -1, NULL, 0);
@@ -1086,32 +1089,17 @@
 	}
 }
 
-static void
-jabber_si_xfer_ibb_send_data(JabberIBBSession *sess)
+static gssize
+jabber_si_xfer_ibb_write(const guchar *buffer, size_t len, PurpleXfer *xfer)
 {
-	PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess);
 	JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
-	gsize remaining = purple_xfer_get_bytes_remaining(xfer);
-	gsize packet_size = remaining < jabber_ibb_session_get_block_size(sess) ?
-		remaining : jabber_ibb_session_get_block_size(sess);
-	gpointer data = g_malloc(packet_size);
-	int res;
+	JabberIBBSession *sess = jsx->ibb_session;
+	gsize packet_size = len < jabber_ibb_session_get_block_size(sess) ?
+		len : jabber_ibb_session_get_block_size(sess);
 
-	purple_debug_info("jabber", "IBB: about to read %" G_GSIZE_FORMAT " bytes from file %p\n",
-		packet_size, jsx->fp);
-	res = fread(data, packet_size, 1, jsx->fp);
+	jabber_ibb_session_send_data(sess, buffer, packet_size);
 
-	if (res == 1) {
-		jabber_ibb_session_send_data(sess, data, packet_size);
-		purple_xfer_set_bytes_sent(xfer,
-			purple_xfer_get_bytes_sent(xfer) + packet_size);
-		purple_xfer_update_progress(xfer);
-	} else {
-		purple_debug_error("jabber",
-			"jabber_si_xfer_ibb_send_data: error reading from file\n");
-		purple_xfer_cancel_local(xfer);
-	}
-	g_free(data);
+	return packet_size;
 }
 
 static void
@@ -1127,7 +1115,7 @@
 		purple_xfer_end(xfer);
 	} else {
 		/* send more... */
-		jabber_si_xfer_ibb_send_data(sess);
+		purple_xfer_prpl_ready(xfer);
 	}
 }
 
@@ -1135,28 +1123,13 @@
 jabber_si_xfer_ibb_opened_cb(JabberIBBSession *sess)
 {
 	PurpleXfer *xfer = (PurpleXfer *) jabber_ibb_session_get_user_data(sess);
-	JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
 	JabberStream *js = jabber_ibb_session_get_js(sess);
 	PurpleConnection *gc = js->gc;
 	PurpleAccount *account = purple_connection_get_account(gc);
 
 	if (jabber_ibb_session_get_state(sess) == JABBER_IBB_SESSION_OPENED) {
-		const char *filename = purple_xfer_get_local_filename(xfer);
-		jsx->fp = g_fopen(filename, "rb");
-		if (jsx->fp == NULL) {
-			purple_debug_error("jabber", "Failed to open file %s for reading: %s\n",
-				filename, g_strerror(errno));
-			purple_xfer_error(purple_xfer_get_type(xfer), account,
-				jabber_ibb_session_get_who(sess),
-				_("Failed to open the file"));
-			purple_xfer_cancel_local(xfer);
-			return;
-		}
-
 		purple_xfer_start(xfer, -1, NULL, 0);
-		purple_xfer_set_bytes_sent(xfer, 0);
-		purple_xfer_update_progress(xfer);
-		jabber_si_xfer_ibb_send_data(sess);
+		purple_xfer_prpl_ready(xfer);
 	} else {
 		/* error */
 		purple_xfer_error(purple_xfer_get_type(xfer), account,
@@ -1171,8 +1144,6 @@
 {
 	JabberSIXfer *jsx = (JabberSIXfer *) xfer->data;
 
-	purple_xfer_ref(xfer);
-
 	jsx->ibb_session = jabber_ibb_session_create(js, jsx->stream_id,
 		purple_xfer_get_remote_user(xfer), xfer);
 
@@ -1187,6 +1158,11 @@
 		jabber_ibb_session_set_error_callback(jsx->ibb_session,
 			jabber_si_xfer_ibb_error_cb);
 
+		purple_xfer_set_write_fnc(xfer, jabber_si_xfer_ibb_write);
+
+		jsx->ibb_buffer =
+			purple_circ_buffer_new(jabber_ibb_session_get_block_size(jsx->ibb_session));
+
 		/* open the IBB session */
 		jabber_ibb_session_open(jsx->ibb_session);
 
@@ -1342,10 +1318,8 @@
 			jabber_ibb_session_destroy(jsx->ibb_session);
 		}
 
-		if (jsx->fp) {
-			purple_debug_info("jabber",
-				"jabber_si_xfer_free: closing file for IBB transfer\n");
-			fclose(jsx->fp);
+		if (jsx->ibb_buffer) {
+			purple_circ_buffer_destroy(jsx->ibb_buffer);
 		}
 
 		purple_debug_info("jabber", "jabber_si_xfer_free(): freeing jsx %p\n", jsx);
@@ -1356,7 +1330,6 @@
 		g_free(jsx->rxqueue);
 		g_free(jsx);
 		xfer->data = NULL;
-
 	}
 }
 
@@ -1632,7 +1605,6 @@
 		jsx->local_streamhost_fd = -1;
 
 		jsx->ibb_session = NULL;
-		jsx->fp = NULL;
 
 		purple_xfer_set_init_fnc(xfer, jabber_si_xfer_init);
 		purple_xfer_set_cancel_send_fnc(xfer, jabber_si_xfer_cancel_send);