~prateek.karandikar/ubuntu/precise/pidgin/add_quicklist

« back to all changes in this revision

Viewing changes to libpurple/protocols/msn/slpmsg_part.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2010-12-02 16:45:52 UTC
  • mfrom: (2.3.14 sid)
  • Revision ID: james.westby@ubuntu.com-20101202164552-z64wykojzacbb546
Tags: 1:2.7.7-1ubuntu1
New upstream version, drop msn workaround

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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
        if (data_len < sizeof(*header)) {
 
32
                return NULL;
 
33
        }
 
34
 
 
35
        part = msn_slpmsgpart_new(NULL, NULL);
 
36
        tmp = data;
 
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)[%d]\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)[%d]\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
        g_free(part->buffer);
 
113
 
 
114
        if (data != NULL && len > 0) {
 
115
                part->buffer = g_malloc(len + 1);
 
116
                memcpy(part->buffer, data, len);
 
117
                part->buffer[len] = '\0';
 
118
                part->size = len;
 
119
        } else {
 
120
                part->buffer = NULL;
 
121
                part->size = 0;
 
122
        }
 
123
 
 
124
}
 
125
 
 
126
char *msn_slpmsgpart_serialize(MsnSlpMessagePart *part, size_t *ret_size)
 
127
{
 
128
        MsnP2PHeader *header;
 
129
        MsnP2PFooter *footer;
 
130
        char *base;
 
131
        char *tmp;
 
132
        size_t siz;
 
133
 
 
134
        base = g_malloc(P2P_PACKET_HEADER_SIZE + part->size + sizeof(MsnP2PFooter));
 
135
        tmp = base;
 
136
 
 
137
        header = msn_p2p_header_to_wire(part->header);
 
138
        footer = msn_p2p_footer_to_wire(part->footer);
 
139
 
 
140
        siz = sizeof(MsnP2PHeader);
 
141
        /* Copy header */
 
142
        memcpy(tmp, (char*)header, siz);
 
143
        tmp += siz;
 
144
 
 
145
        /* Copy body */
 
146
        memcpy(tmp, part->buffer, part->size);
 
147
        tmp += part->size;
 
148
 
 
149
        /* Copy footer */
 
150
        siz = sizeof(MsnP2PFooter);
 
151
        memcpy(tmp, (char*)footer, siz);
 
152
        tmp += siz;
 
153
 
 
154
        *ret_size = tmp - base;
 
155
 
 
156
        g_free(header);
 
157
        g_free(footer);
 
158
 
 
159
        return base;
 
160
}
 
161
/* We have received the message ack */
 
162
void
 
163
msn_slpmsgpart_ack(MsnSlpMessagePart *part, void *data)
 
164
{
 
165
        MsnSlpMessage *slpmsg;
 
166
        long long real_size;
 
167
 
 
168
        slpmsg = data;
 
169
 
 
170
        real_size = (slpmsg->header->flags == P2P_ACK) ? 0 : slpmsg->size;
 
171
 
 
172
        slpmsg->header->offset += part->header->length;
 
173
 
 
174
        slpmsg->parts = g_list_remove(slpmsg->parts, part);
 
175
 
 
176
        if (slpmsg->header->offset < real_size)
 
177
        {
 
178
                if (slpmsg->slpcall->xfer && purple_xfer_get_status(slpmsg->slpcall->xfer) == PURPLE_XFER_STATUS_STARTED)
 
179
                {
 
180
                        slpmsg->slpcall->xfer_msg = slpmsg;
 
181
                        purple_xfer_prpl_ready(slpmsg->slpcall->xfer);
 
182
                }
 
183
                else
 
184
                        msn_slplink_send_msgpart(slpmsg->slplink, slpmsg);
 
185
        }
 
186
        else
 
187
        {
 
188
                /* The whole message has been sent */
 
189
                if (msn_p2p_msg_is_data(slpmsg->header->flags))
 
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
}