cpw.malu.xmpp.jingle_ft: 26442f03: Migrate the use of the IBB transport for...
malu at pidgin.im
malu at pidgin.im
Wed Aug 12 17:25:59 EDT 2009
-----------------------------------------------------------------
Revision: 26442f037db45ed1211149fde4ef6bb565fa3b36
Ancestor: 39c43c2879bd386b772e010eb23b15f7ed9307c2
Author: malu at pidgin.im
Date: 2009-08-12T21:19:27
Branch: im.pidgin.cpw.malu.xmpp.jingle_ft
URL: http://d.pidgin.im/viewmtn/revision/info/26442f037db45ed1211149fde4ef6bb565fa3b36
Modified files:
libpurple/protocols/jabber/jingle/file-transfer.c
ChangeLog:
Migrate the use of the IBB transport for FT to use the new xfer operations
instead of doing their own thing...
Set fd == -1 when starting xfer with IBB
-------------- next part --------------
============================================================
--- libpurple/protocols/jabber/jingle/file-transfer.c 7ac68bb79e7f6c92979d194dd2883ad8dad5b4e2
+++ libpurple/protocols/jabber/jingle/file-transfer.c 4f2b6c75250395df68c60b838f941678710bbfae
@@ -28,7 +28,7 @@ struct _JingleFTPrivate {
struct _JingleFTPrivate {
PurpleXfer *xfer;
- FILE *ibb_fp; /* used to read/write from/to IBB streams */
+ PurpleCircBuffer *ibb_buffer;
gboolean remote_failed_s5b;
};
@@ -116,8 +116,9 @@ jingle_file_transfer_finalize (GObject *
JingleFTPrivate *priv = JINGLE_FT_GET_PRIVATE(ft);
purple_debug_info("jingle-ft","jingle_file_transfer_finalize\n");
- if (priv->ibb_fp) {
- fclose(priv->ibb_fp);
+ if (priv->ibb_buffer) {
+ purple_circ_buffer_destroy(priv->ibb_buffer);
+ priv->ibb_buffer = NULL;
}
if (priv->xfer) {
@@ -246,33 +247,18 @@ jingle_file_transfer_ibb_end(JingleConte
g_object_unref(session); /* actually delete it */
}
-static void
-jingle_file_transfer_ibb_send_data(JingleContent *content)
+static gsize
+jingle_file_transfer_ibb_write(const guchar *buffer, gsize len, PurpleXfer *xfer)
{
- PurpleXfer *xfer = JINGLE_FT_GET_PRIVATE(JINGLE_FT(content))->xfer;
- FILE *fp = JINGLE_FT_GET_PRIVATE(JINGLE_FT(content))->ibb_fp;
- gsize remaining = purple_xfer_get_bytes_remaining(xfer);
+ JingleContent *content = (JingleContent *) xfer->data;
JingleTransport *transport = jingle_content_get_transport(content);
- gsize block_size = jingle_ibb_get_block_size(JINGLE_IBB(transport));
- gsize packet_size = remaining < block_size ? remaining : block_size;
- gpointer data = g_malloc(packet_size);
- int res;
+ gsize packet_size = len < jingle_ibb_get_block_size(JINGLE_IBB(transport)) ?
+ len : jingle_ibb_get_block_size(JINGLE_IBB(transport));
- purple_debug_info("jingle-ft",
- "IBB: about to read %" G_GSIZE_FORMAT " bytes from file %p\n",
- packet_size, fp);
- res = fread(data, packet_size, 1, fp);
-
- if (res == 1) {
- jingle_ibb_send_data(JINGLE_IBB(transport), data, packet_size);
- purple_xfer_set_bytes_sent(xfer,
- purple_xfer_get_bytes_sent(xfer) + packet_size);
- purple_xfer_update_progress(xfer);
- } else {
- jingle_file_transfer_cancel_local(content);
- }
- g_free(data);
+ jingle_ibb_send_data(JINGLE_IBB(transport), buffer, packet_size);
g_object_unref(transport);
+
+ return packet_size;
}
/* callback functions for IBB */
@@ -287,7 +273,7 @@ jingle_file_transfer_ibb_data_sent_callb
jingle_file_transfer_ibb_end(content);
} else {
/* send more... */
- jingle_file_transfer_ibb_send_data(content);
+ purple_xfer_prpl_ready(xfer);
}
}
@@ -297,24 +283,13 @@ jingle_file_transfer_ibb_data_recv_callb
{
JingleFT *ft = JINGLE_FT(content);
PurpleXfer *xfer = JINGLE_FT_GET_PRIVATE(ft)->xfer;
- FILE *fp = JINGLE_FT_GET_PRIVATE(ft)->ibb_fp;
if (size <= purple_xfer_get_bytes_remaining(xfer)) {
purple_debug_info("jingle-ft",
"about to write %" G_GSIZE_FORMAT " bytes from IBB stream\n",
size);
- if(!fwrite(data, size, 1, fp)) {
- purple_debug_error("jingle-ft", "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) {
- jingle_file_transfer_success(content);
- }
+ purple_circ_buffer_append(ft->priv->ibb_buffer, data, size);
+ purple_xfer_prpl_ready(xfer);
} else {
/* sending more than intended */
purple_debug_error("jingle-ft",
@@ -323,6 +298,26 @@ jingle_file_transfer_ibb_data_recv_callb
}
}
+static gsize
+jingle_file_transfer_ibb_read(guchar **out_buffer, PurpleXfer *xfer)
+{
+ JingleContent *content = (JingleContent *) xfer->data;
+ guchar *buffer;
+ gsize size;
+ gsize tmp;
+
+ size = JINGLE_FT(content)->priv->ibb_buffer->bufused;
+ *out_buffer = buffer = g_malloc(size);
+ while ((tmp =
+ purple_circ_buffer_get_max_read(JINGLE_FT(content)->priv->ibb_buffer))) {
+ memcpy(buffer, JINGLE_FT(content)->priv->ibb_buffer->outptr, tmp);
+ buffer += tmp;
+ purple_circ_buffer_mark_read(JINGLE_FT(content)->priv->ibb_buffer, tmp);
+ }
+
+ return size;
+}
+
static void
jingle_file_transfer_ibb_error_callback(JingleContent *content)
{
@@ -355,6 +350,9 @@ jingle_file_transfer_add_ibb_session_to_
jingle_file_transfer_ibb_data_sent_callback);
jingle_ibb_set_error_callback(JINGLE_IBB(transport),
jingle_file_transfer_ibb_error_callback);
+ JINGLE_FT(content)->priv->ibb_buffer =
+ purple_circ_buffer_new(jingle_ibb_get_block_size(
+ JINGLE_IBB(transport)));
} else {
purple_debug_error("jingle-ft",
"trying to setup an IBB session of a non-IBB transport\n");
@@ -550,7 +548,7 @@ jingle_file_transfer_xfer_init(PurpleXfe
jingle_file_transfer_s5b_connect_failed_callback, content);
/* start local listen on the S5B transport */
jingle_s5b_gather_candidates(session, JINGLE_S5B(transport));
- }
+ }
} else if (xfer->data) {
JingleContent *content = (JingleContent *) xfer->data;
JingleSession *session = jingle_content_get_session(content);
@@ -561,26 +559,13 @@ jingle_file_transfer_xfer_init(PurpleXfe
/* open file and prepare for IBB */
/* open file to write to */
JingleIBB *ibb = JINGLE_IBB(transport);
- const gchar *filename = purple_xfer_get_local_filename(xfer);
/* send a session-accept immediatly, since it's IBB */
jabber_iq_send(jingle_session_to_packet(session,
JINGLE_SESSION_ACCEPT));
- JINGLE_FT_GET_PRIVATE(JINGLE_FT(content))->ibb_fp =
- g_fopen(filename, "wb");
- if (JINGLE_FT_GET_PRIVATE(JINGLE_FT(content))->ibb_fp == NULL) {
- purple_debug_error("jabber",
- "failed to open file %s for writing: %s\n", filename,
- g_strerror(errno));
- purple_xfer_cancel_remote(xfer);
- jabber_iq_send(jingle_session_to_packet(session,
- JINGLE_SESSION_TERMINATE));
- g_object_unref(transport);
- g_object_unref(session);
- g_object_unref(session);
- return;
- }
+ JINGLE_FT(content)->priv->ibb_buffer =
+ purple_circ_buffer_new(jingle_ibb_get_block_size(ibb));
/* setup callbacks */
jingle_ibb_set_data_received_callback(ibb,
@@ -588,8 +573,11 @@ jingle_file_transfer_xfer_init(PurpleXfe
jingle_ibb_set_error_callback(ibb,
jingle_file_transfer_ibb_error_callback);
+ /* setup read function */
+ purple_xfer_set_read_fnc(xfer, jingle_file_transfer_ibb_read);
+
/* start the transfer */
- purple_xfer_start(xfer, 0, NULL, 0);
+ purple_xfer_start(xfer, -1, NULL, 0);
} else if (JINGLE_IS_S5B(transport)) {
jingle_s5b_set_connect_callback(JINGLE_S5B(transport),
jingle_file_transfer_s5b_connect_callback, content);
@@ -713,22 +701,13 @@ jingle_file_transfer_handle_action_inter
/* do stuff here, start the transfer, etc... */
if (JINGLE_IS_IBB(transport)) {
JingleFT *ft = JINGLE_FT(content);
- /* open the file for reading */
- JINGLE_FT_GET_PRIVATE(ft)->ibb_fp =
- g_fopen(purple_xfer_get_local_filename(xfer), "rb");
-
- if (JINGLE_FT_GET_PRIVATE(ft)->ibb_fp) {
- /* send first data */
- purple_xfer_start(xfer, 0, NULL, 0);
- purple_xfer_set_bytes_sent(xfer, 0);
- purple_xfer_update_progress(xfer);
- jingle_file_transfer_ibb_send_data(content);
- } else {
- purple_debug_error("jingle-ft",
- "failed to open file for reading\n");
- jingle_file_transfer_cancel_local(content);
- break;
- }
+
+ /* send first data */
+ purple_xfer_set_bytes_sent(xfer, 0);
+ purple_xfer_update_progress(xfer);
+ purple_xfer_set_write_fnc(xfer, jingle_file_transfer_ibb_write);
+ purple_xfer_start(xfer, -1, NULL, 0);
+ purple_xfer_prpl_ready(xfer);
} else if (JINGLE_IS_S5B(transport)) {
/* add the receiver's streamhost candidates (this must be done
here since parse is not called on the existing transport */
@@ -786,6 +765,11 @@ jingle_file_transfer_handle_action_inter
const gchar *filename =
purple_xfer_get_local_filename(xfer);
jingle_ibb_create_session(ibb, content, sid, who);
+ JINGLE_FT(content)->priv->ibb_buffer =
+ purple_circ_buffer_new(jingle_ibb_get_block_size(ibb));
+ purple_xfer_set_read_fnc(xfer,
+ jingle_file_transfer_ibb_read);
+ purple_xfer_prpl_ready(xfer);
} else if (JINGLE_IS_S5B(transport)) {
/* set S5B callbacks */
jingle_s5b_set_connect_callback(JINGLE_S5B(transport),
@@ -863,20 +847,17 @@ jingle_file_transfer_handle_action_inter
/* Note: the new tranport are automatically accepted from
pending before this is called */
/* open the file, etc... */
- JINGLE_FT_GET_PRIVATE(JINGLE_FT(content))->ibb_fp =
- g_fopen(purple_xfer_get_local_filename(xfer), "rb");
+ JINGLE_FT(content)->priv->ibb_buffer =
+ purple_circ_buffer_new(jingle_ibb_get_block_size(
+ JINGLE_IBB(transport)));
- if (JINGLE_FT_GET_PRIVATE(JINGLE_FT(content))->ibb_fp) {
- /* send first data */
- purple_xfer_start(xfer, 0, NULL, 0);
- purple_xfer_set_bytes_sent(xfer, 0);
- purple_xfer_update_progress(xfer);
- jingle_file_transfer_ibb_send_data(content);
- } else {
- purple_debug_error("jingle-ft",
- "failed to open file for reading\n");
- jingle_file_transfer_cancel_local(content);
- }
+ purple_xfer_set_write_fnc(xfer, jingle_file_transfer_ibb_write);
+
+ /* send first data */
+ purple_xfer_start(xfer, -1, NULL, 0);
+ purple_xfer_set_bytes_sent(xfer, 0);
+ purple_xfer_update_progress(xfer);
+ purple_xfer_prpl_ready(xfer);
}
g_object_unref(session);
@@ -903,22 +884,8 @@ jingle_file_transfer_handle_action_inter
/* immediatly accept the new transport */
jingle_content_accept_transport(content);
- /* open the file and setup the callbacks */
- JINGLE_FT_GET_PRIVATE(JINGLE_FT(content))->ibb_fp =
- g_fopen(filename, "wb");
- if (JINGLE_FT_GET_PRIVATE(JINGLE_FT(content))->ibb_fp == NULL) {
- purple_debug_error("jabber",
- "failed to open file %s for writing: %s\n", filename,
- g_strerror(errno));
- purple_xfer_cancel_remote(xfer);
- jabber_iq_send(jingle_session_to_packet(session,
- JINGLE_SESSION_TERMINATE));
- g_object_unref(new_transport);
- g_object_unref(session);
- g_object_unref(session);
- g_free(who);
- return;
- }
+ JINGLE_FT(content)->priv->ibb_buffer =
+ purple_circ_buffer_new(jingle_ibb_get_block_size(ibb));
/* setup callbacks */
jingle_ibb_set_data_received_callback(ibb,
@@ -927,8 +894,11 @@ jingle_file_transfer_handle_action_inter
jingle_file_transfer_ibb_error_callback);
/* start the transfer */
- purple_xfer_start(xfer, 0, NULL, 0);
+ purple_xfer_start(xfer, -1, NULL, 0);
+ /* set read function */
+ purple_xfer_set_read_fnc(xfer, jingle_file_transfer_ibb_read);
+
/* send transport-accept */
jabber_iq_send(jingle_session_to_packet(session,
JINGLE_TRANSPORT_ACCEPT));
More information about the Commits
mailing list