Mercurial > pidgin.yaz
comparison libpurple/protocols/msn/slpmsg_part.c @ 31292:47b6eda87723
propagate from branch 'im.pidgin.pidgin' (head 07d0765c444a097af45c2650f54323afb900a07b)
to branch 'im.pidgin.soc.2010.msn-tlc' (head f3998422a4724ab424e4e2328f58fc0504856557)
author | masca@cpw.pidgin.im |
---|---|
date | Mon, 19 Jul 2010 21:11:32 +0000 |
parents | e358e16e527f |
children | 5ad928319db0 |
comparison
equal
deleted
inserted
replaced
30698:e874875a74a7 | 31292:47b6eda87723 |
---|---|
1 #include "internal.h" | |
2 #include "debug.h" | |
3 | |
4 #include "slpmsg.h" | |
5 #include "slpmsg_part.h" | |
6 | |
7 MsnSlpMessagePart *msn_slpmsgpart_new(MsnP2PHeader *header, MsnP2PFooter *footer) | |
8 { | |
9 MsnSlpMessagePart *part; | |
10 | |
11 part = g_new0(MsnSlpMessagePart, 1); | |
12 | |
13 if (header) | |
14 part->header = g_memdup(header, P2P_PACKET_HEADER_SIZE); | |
15 if (footer) | |
16 part->footer = g_memdup(footer, P2P_PACKET_FOOTER_SIZE); | |
17 | |
18 part->ack_cb = msn_slpmsgpart_ack; | |
19 part->nak_cb = msn_slpmsgpart_nak; | |
20 | |
21 return msn_slpmsgpart_ref(part); | |
22 } | |
23 | |
24 MsnSlpMessagePart *msn_slpmsgpart_new_from_data(const char *data, size_t data_len) | |
25 { | |
26 MsnSlpMessagePart *part; | |
27 MsnP2PHeader *header; | |
28 const char *tmp; | |
29 int body_len; | |
30 | |
31 tmp = data; | |
32 part = msn_slpmsgpart_new(NULL, NULL); | |
33 | |
34 if (data_len < sizeof(*header)) { | |
35 return NULL; | |
36 } | |
37 | |
38 /* Extract the binary SLP header */ | |
39 part->header = msn_p2p_header_from_wire((MsnP2PHeader*)tmp); | |
40 tmp += P2P_PACKET_HEADER_SIZE; | |
41 | |
42 /* Extract the body */ | |
43 body_len = data_len - P2P_PACKET_HEADER_SIZE - P2P_PACKET_FOOTER_SIZE; | |
44 /* msg->body_len = msg->msnslp_header.length; */ | |
45 | |
46 if (body_len > 0) { | |
47 part->size = body_len; | |
48 part->buffer = g_malloc(body_len); | |
49 memcpy(part->buffer, tmp, body_len); | |
50 tmp += body_len; | |
51 } | |
52 | |
53 /* Extract the footer */ | |
54 if (body_len >= 0) | |
55 part->footer = msn_p2p_footer_from_wire((MsnP2PFooter*)tmp); | |
56 | |
57 return part; | |
58 } | |
59 | |
60 void msn_slpmsgpart_destroy(MsnSlpMessagePart *part) | |
61 { | |
62 if (!part) | |
63 return; | |
64 | |
65 if (part->ref_count > 0) { | |
66 msn_slpmsgpart_unref(part); | |
67 | |
68 return; | |
69 } | |
70 | |
71 g_free(part->header); | |
72 g_free(part->footer); | |
73 | |
74 g_free(part); | |
75 | |
76 } | |
77 | |
78 MsnSlpMessagePart *msn_slpmsgpart_ref(MsnSlpMessagePart *part) | |
79 { | |
80 g_return_val_if_fail(part != NULL, NULL); | |
81 part->ref_count ++; | |
82 | |
83 if (purple_debug_is_verbose()) | |
84 purple_debug_info("msn", "part ref (%p)[%" G_GSIZE_FORMAT "]\n", part, part->ref_count); | |
85 | |
86 return part; | |
87 } | |
88 | |
89 MsnSlpMessagePart *msn_slpmsgpart_unref(MsnSlpMessagePart *part) | |
90 { | |
91 g_return_val_if_fail(part != NULL, NULL); | |
92 g_return_val_if_fail(part->ref_count > 0, NULL); | |
93 | |
94 part->ref_count--; | |
95 | |
96 if (purple_debug_is_verbose()) | |
97 purple_debug_info("msn", "part unref (%p)[%" G_GSIZE_FORMAT "]\n", part, part->ref_count); | |
98 | |
99 if (part->ref_count == 0) { | |
100 msn_slpmsgpart_destroy(part); | |
101 | |
102 return NULL; | |
103 } | |
104 | |
105 return part; | |
106 } | |
107 | |
108 void msn_slpmsgpart_set_bin_data(MsnSlpMessagePart *part, const void *data, size_t len) | |
109 { | |
110 g_return_if_fail(part != NULL); | |
111 | |
112 if (part->buffer != NULL) | |
113 g_free(part->buffer); | |
114 | |
115 if (data != NULL && len > 0) { | |
116 part->buffer = g_malloc(len + 1); | |
117 memcpy(part->buffer, data, len); | |
118 part->buffer[len] = '\0'; | |
119 part->size = len; | |
120 } else { | |
121 part->buffer = NULL; | |
122 part->size = 0; | |
123 } | |
124 | |
125 } | |
126 | |
127 char *msn_slpmsgpart_serialize(MsnSlpMessagePart *part, size_t *ret_size) | |
128 { | |
129 MsnP2PHeader *header; | |
130 MsnP2PFooter *footer; | |
131 char *base; | |
132 char *tmp; | |
133 size_t siz; | |
134 | |
135 base = g_malloc(P2P_PACKET_HEADER_SIZE + part->size + sizeof(MsnP2PFooter)); | |
136 tmp = base; | |
137 | |
138 header = msn_p2p_header_to_wire(part->header); | |
139 footer = msn_p2p_footer_to_wire(part->footer); | |
140 | |
141 siz = sizeof(MsnP2PHeader); | |
142 /* Copy header */ | |
143 memcpy(tmp, (char*)header, siz); | |
144 tmp += siz; | |
145 | |
146 /* Copy body */ | |
147 memcpy(tmp, part->buffer, part->size); | |
148 tmp += part->size; | |
149 | |
150 /* Copy footer */ | |
151 siz = sizeof(MsnP2PFooter); | |
152 memcpy(tmp, (char*)footer, siz); | |
153 tmp += siz; | |
154 | |
155 *ret_size = tmp - base; | |
156 | |
157 return base; | |
158 } | |
159 /* We have received the message ack */ | |
160 void | |
161 msn_slpmsgpart_ack(MsnSlpMessagePart *part, void *data) | |
162 { | |
163 MsnSlpMessage *slpmsg; | |
164 long long real_size; | |
165 | |
166 slpmsg = data; | |
167 | |
168 real_size = (slpmsg->flags == P2P_ACK) ? 0 : slpmsg->size; | |
169 | |
170 slpmsg->offset += part->header->length; | |
171 | |
172 slpmsg->parts = g_list_remove(slpmsg->parts, part); | |
173 | |
174 if (slpmsg->offset < real_size) | |
175 { | |
176 if (slpmsg->slpcall->xfer && purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED) | |
177 { | |
178 slpmsg->slpcall->xfer_msg = slpmsg; | |
179 purple_xfer_prpl_ready(slpmsg->slpcall->xfer); | |
180 } | |
181 else | |
182 msn_slplink_send_msgpart(slpmsg->slplink, slpmsg); | |
183 } | |
184 else | |
185 { | |
186 /* The whole message has been sent */ | |
187 if (slpmsg->flags == P2P_MSN_OBJ_DATA || | |
188 slpmsg->flags == (P2P_WML2009_COMP | P2P_MSN_OBJ_DATA) || | |
189 slpmsg->flags == P2P_FILE_DATA) | |
190 { | |
191 if (slpmsg->slpcall != NULL) | |
192 { | |
193 if (slpmsg->slpcall->cb) | |
194 slpmsg->slpcall->cb(slpmsg->slpcall, | |
195 NULL, 0); | |
196 } | |
197 } | |
198 } | |
199 } | |
200 | |
201 /* We have received the message nak. */ | |
202 void | |
203 msn_slpmsgpart_nak(MsnSlpMessagePart *part, void *data) | |
204 { | |
205 MsnSlpMessage *slpmsg; | |
206 | |
207 slpmsg = data; | |
208 | |
209 msn_slplink_send_msgpart(slpmsg->slplink, slpmsg); | |
210 | |
211 slpmsg->parts = g_list_remove(slpmsg->parts, part); | |
212 } |