changeset 30796:e545b2b6f66a

Introduce SlpMessagePart, It will replace MsnMessage in every Slp related code so MsnMessage just get used where it makes sense, in the Switchboard.
author masca@cpw.pidgin.im
date Wed, 16 Jun 2010 21:25:11 +0000
parents 22f26c372797
children efe9b0338606
files libpurple/protocols/msn/Makefile.am libpurple/protocols/msn/Makefile.mingw libpurple/protocols/msn/slpmsg_part.c libpurple/protocols/msn/slpmsg_part.h
diffstat 4 files changed, 208 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/protocols/msn/Makefile.am	Tue Jun 15 21:21:24 2010 +0000
+++ b/libpurple/protocols/msn/Makefile.am	Wed Jun 16 21:25:11 2010 +0000
@@ -50,6 +50,8 @@
 	slplink.h \
 	slpmsg.c \
 	slpmsg.h \
+	slpmsg_part.c \
+	slpmsg_part.h \
 	soap.c \
 	soap.h \
 	state.c \
--- a/libpurple/protocols/msn/Makefile.mingw	Tue Jun 15 21:21:24 2010 +0000
+++ b/libpurple/protocols/msn/Makefile.mingw	Wed Jun 16 21:25:11 2010 +0000
@@ -60,6 +60,7 @@
 			slpcall.c \
 			slplink.c \
 			slpmsg.c \
+			slpmsg_part.c \
 			soap.c\
 			state.c \
 			sbconn.c \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/msn/slpmsg_part.c	Wed Jun 16 21:25:11 2010 +0000
@@ -0,0 +1,171 @@
+#include "internal.h"
+
+#include "slpmsg.h"
+#include "slpmsg_part.h"
+
+MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PHeader *header, MsnP2PFooter *footer)
+{
+	MsnSlpMessagePart *part;
+
+	part = g_new0(MsnSlpMessagePart, 1);
+
+	if (header)
+		part->header = g_memdup(header, P2P_PACKET_HEADER_SIZE);
+	if (footer)
+		part->footer = g_memdup(footer, P2P_PACKET_FOOTER_SIZE);
+
+	part->ack_cb = msn_slpmsgpart_ack;
+	part->nack_cb = msn_slpmsgpart_nak;
+
+	return part;
+}
+
+MsnSlpMessagePart *msn_slpmsgpart_new_from_data(const char *data, size_t data_len)
+{
+	MsnSlpMessagePart *part;
+	MsnP2PHeader *header;
+	const char *tmp;
+	int body_len;
+
+	tmp = data;
+	part = msn_slpmsgpart_new(NULL, NULL);
+
+	if (data_len < sizeof(*header)) {
+		return NULL;
+	}
+
+	/* Extract the binary SLP header */
+	part->header = msn_p2p_header_from_wire((MsnP2PHeader*)tmp);
+
+	/* Extract the body */
+	body_len = data_len - (tmp - data);
+	/* msg->body_len = msg->msnslp_header.length; */
+
+	if (body_len > 0) {
+		part->size = body_len;
+		part->buffer = g_malloc(body_len);
+		memcpy(part->buffer, tmp, body_len);
+		tmp += body_len;
+	}
+
+	/* Extract the footer */
+	if (body_len >= 0) 
+		part->footer = msn_p2p_footer_from_wire((MsnP2PFooter*)tmp);
+
+	return part;
+}
+
+void msn_slpmsgpart_destroy(MsnSlpMessagePart *part)
+{
+	g_free(part->header);
+	g_free(part->footer);
+
+	g_free(part);
+
+}
+
+void msn_slpmsgpart_set_bin_data(MsnSlpMessagePart *part, const void *data, size_t len)
+{
+	g_return_if_fail(part != NULL);
+
+	if (part->buffer != NULL)
+		g_free(part->buffer);
+
+	if (data != NULL && len > 0) {
+		part->buffer = g_malloc(len + 1);
+		memcpy(part->buffer, data, len);
+		part->buffer[len] = '\0';
+		part->size = len;
+	} else {
+		part->buffer = NULL;
+		part->size = 0;
+	}
+
+}
+
+char *msn_slpmsgpart_serialize(MsnSlpMessagePart *part, size_t *ret_size)
+{
+	MsnP2PHeader *header;
+	MsnP2PFooter *footer;
+	char *base;
+	char *tmp;
+	size_t siz;
+
+	base = g_malloc(P2P_PACKET_HEADER_SIZE + part->size + sizeof(MsnP2PFooter));
+	tmp = base;
+
+	header = msn_p2p_header_to_wire(part->header);
+	footer = msn_p2p_footer_to_wire(part->footer);
+
+	siz = sizeof(MsnP2PHeader);
+	/* Copy header */
+	memcpy(tmp, (char*)header, siz);
+	tmp += siz;
+
+	/* Copy body */
+	memcpy(tmp, part->buffer, part->size);
+	tmp += part->size;
+
+	/* Copy footer */
+	siz = sizeof(MsnP2PFooter);
+	memcpy(tmp, (char*)footer, siz);
+	tmp += siz;
+
+	*ret_size = tmp - base;
+
+	return base;
+}
+/* We have received the message ack */
+void
+msn_slpmsgpart_ack(MsnSlpMessagePart *part, void *data)
+{
+	MsnSlpMessage *slpmsg;
+	long long real_size;
+
+	slpmsg = data;
+
+	real_size = (slpmsg->flags == P2P_ACK) ? 0 : slpmsg->size;
+
+	slpmsg->offset += part->header->length;
+
+	slpmsg->parts = g_list_remove(slpmsg->parts, part);
+
+	if (slpmsg->offset < real_size)
+	{
+		if (slpmsg->slpcall->xfer && purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED)
+		{
+			slpmsg->slpcall->xfer_msg = slpmsg;
+			purple_xfer_prpl_ready(slpmsg->slpcall->xfer);
+		}
+		else
+			msn_slplink_send_msgpart(slpmsg->slplink, slpmsg);
+	}
+	else
+	{
+		/* The whole message has been sent */
+		if (slpmsg->flags == P2P_MSN_OBJ_DATA ||
+	        slpmsg->flags == (P2P_WML2009_COMP | P2P_MSN_OBJ_DATA) ||
+	        slpmsg->flags == P2P_FILE_DATA) 
+		{
+			if (slpmsg->slpcall != NULL)
+			{
+				if (slpmsg->slpcall->cb)
+					slpmsg->slpcall->cb(slpmsg->slpcall,
+						NULL, 0);
+			}
+		}
+	}
+}
+
+/* We have received the message nak. */
+void
+msn_slpmsgpart_nak(MsnSlpMessagePart *part, void *data)
+{
+	MsnSlpMessage *slpmsg;
+
+	slpmsg = data;
+
+	msn_slplink_send_msgpart(slpmsg->slplink, slpmsg);
+
+	slpmsg->parts = g_list_remove(slpmsg->parts, part);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/msn/slpmsg_part.h	Wed Jun 16 21:25:11 2010 +0000
@@ -0,0 +1,34 @@
+#ifndef MSN_SLPMSG_PART_H
+#define MSN_SLPMSG_PART_H
+
+#include "p2p.h"
+
+typedef struct _MsnSlpMessagePart MsnSlpMessagePart;
+typedef void (*MsnSlpPartCb)(MsnSlpMessagePart *part, void *data);
+
+struct _MsnSlpMessagePart
+{
+	MsnP2PHeader *header;
+	MsnP2PFooter *footer;
+
+	MsnSlpPartCb ack_cb;
+	MsnSlpPartCb nack_cb;
+
+	guchar *buffer;
+	size_t size;
+};
+
+MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PHeader *header, MsnP2PFooter *footer);
+
+MsnSlpMessagePart *msn_slpmsgpart_new_from_data(const char *data, size_t data_len);
+
+void msn_slpmsgpart_destroy(MsnSlpMessagePart *part);
+
+void msn_slpmsgpart_set_bin_data(MsnSlpMessagePart *part, const void *data, size_t len);
+
+char *msn_slpmsgpart_serialize(MsnSlpMessagePart *part, size_t *ret_size);
+
+void msn_slpmsgpart_ack(MsnSlpMessagePart *part, void *data);
+
+void msn_slpmsgpart_nak(MsnSlpMessagePart *part, void *data);
+#endif /* MSN_SLPMSG_PART_H */