Remove useless comparison
[pidgin-git.git] / libpurple / protocols / oscar / bstream.c
blobf933d186605ab789afa90f9cdb90c647f194ba8f
1 /*
2 * Purple's oscar protocol plugin
3 * This file is the legal property of its developers.
4 * Please see the AUTHORS file distributed alongside this file.
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
22 * This file contains all functions needed to use bstreams.
25 #include "oscar.h"
27 int byte_stream_new(ByteStream *bs, size_t len)
29 if (bs == NULL)
30 return -1;
32 return byte_stream_init(bs, g_malloc(len), len);
35 int byte_stream_init(ByteStream *bs, guint8 *data, size_t len)
37 if (bs == NULL)
38 return -1;
40 bs->data = data;
41 bs->len = len;
42 bs->offset = 0;
44 return 0;
47 void byte_stream_destroy(ByteStream *bs)
49 g_free(bs->data);
52 size_t byte_stream_bytes_left(ByteStream *bs)
54 return bs->len - bs->offset;
57 int byte_stream_curpos(ByteStream *bs)
59 return bs->offset;
62 int byte_stream_setpos(ByteStream *bs, size_t off)
64 g_return_val_if_fail(off <= bs->len, -1);
66 bs->offset = off;
67 return off;
70 void byte_stream_rewind(ByteStream *bs)
72 byte_stream_setpos(bs, 0);
76 * N can be negative, which can be used for going backwards
77 * in a bstream.
79 int byte_stream_advance(ByteStream *bs, int n)
81 g_return_val_if_fail(byte_stream_curpos(bs) + n >= 0, 0);
82 g_return_val_if_fail((gsize)n <= byte_stream_bytes_left(bs), 0);
84 bs->offset += n;
85 return n;
88 guint8 byte_stream_get8(ByteStream *bs)
90 g_return_val_if_fail(byte_stream_bytes_left(bs) >= 1, 0);
92 bs->offset++;
93 return aimutil_get8(bs->data + bs->offset - 1);
96 guint16 byte_stream_get16(ByteStream *bs)
98 g_return_val_if_fail(byte_stream_bytes_left(bs) >= 2, 0);
100 bs->offset += 2;
101 return aimutil_get16(bs->data + bs->offset - 2);
104 guint32 byte_stream_get32(ByteStream *bs)
106 g_return_val_if_fail(byte_stream_bytes_left(bs) >= 4, 0);
108 bs->offset += 4;
109 return aimutil_get32(bs->data + bs->offset - 4);
112 guint8 byte_stream_getle8(ByteStream *bs)
114 g_return_val_if_fail(byte_stream_bytes_left(bs) >= 1, 0);
116 bs->offset++;
117 return aimutil_getle8(bs->data + bs->offset - 1);
120 guint16 byte_stream_getle16(ByteStream *bs)
122 g_return_val_if_fail(byte_stream_bytes_left(bs) >= 2, 0);
124 bs->offset += 2;
125 return aimutil_getle16(bs->data + bs->offset - 2);
128 guint32 byte_stream_getle32(ByteStream *bs)
130 g_return_val_if_fail(byte_stream_bytes_left(bs) >= 4, 0);
132 bs->offset += 4;
133 return aimutil_getle32(bs->data + bs->offset - 4);
136 static void byte_stream_getrawbuf_nocheck(ByteStream *bs, guint8 *buf, size_t len)
138 memcpy(buf, bs->data + bs->offset, len);
139 bs->offset += len;
142 int byte_stream_getrawbuf(ByteStream *bs, guint8 *buf, size_t len)
144 g_return_val_if_fail(byte_stream_bytes_left(bs) >= len, 0);
146 byte_stream_getrawbuf_nocheck(bs, buf, len);
147 return len;
150 guint8 *byte_stream_getraw(ByteStream *bs, size_t len)
152 guint8 *ob;
154 g_return_val_if_fail(byte_stream_bytes_left(bs) >= len, NULL);
156 ob = g_malloc(len);
157 byte_stream_getrawbuf_nocheck(bs, ob, len);
158 return ob;
161 char *byte_stream_getstr(ByteStream *bs, size_t len)
163 char *ob;
165 g_return_val_if_fail(byte_stream_bytes_left(bs) >= len, NULL);
167 ob = g_malloc(len + 1);
168 byte_stream_getrawbuf_nocheck(bs, (guint8 *)ob, len);
169 ob[len] = '\0';
170 return ob;
173 int byte_stream_put8(ByteStream *bs, guint8 v)
175 g_return_val_if_fail(byte_stream_bytes_left(bs) >= 1, 0);
177 bs->offset += aimutil_put8(bs->data + bs->offset, v);
178 return 1;
181 int byte_stream_put16(ByteStream *bs, guint16 v)
183 g_return_val_if_fail(byte_stream_bytes_left(bs) >= 2, 0);
185 bs->offset += aimutil_put16(bs->data + bs->offset, v);
186 return 2;
189 int byte_stream_put32(ByteStream *bs, guint32 v)
191 g_return_val_if_fail(byte_stream_bytes_left(bs) >= 4, 0);
193 bs->offset += aimutil_put32(bs->data + bs->offset, v);
194 return 1;
197 int byte_stream_putle8(ByteStream *bs, guint8 v)
199 g_return_val_if_fail(byte_stream_bytes_left(bs) >= 1, 0);
201 bs->offset += aimutil_putle8(bs->data + bs->offset, v);
202 return 1;
205 int byte_stream_putle16(ByteStream *bs, guint16 v)
207 g_return_val_if_fail(byte_stream_bytes_left(bs) >= 2, 0);
209 bs->offset += aimutil_putle16(bs->data + bs->offset, v);
210 return 2;
213 int byte_stream_putle32(ByteStream *bs, guint32 v)
215 g_return_val_if_fail(byte_stream_bytes_left(bs) >= 4, 0);
217 bs->offset += aimutil_putle32(bs->data + bs->offset, v);
218 return 1;
222 int byte_stream_putraw(ByteStream *bs, const guint8 *v, size_t len)
224 g_return_val_if_fail(byte_stream_bytes_left(bs) >= len, 0);
226 memcpy(bs->data + bs->offset, v, len);
227 bs->offset += len;
228 return len;
231 int byte_stream_putstr(ByteStream *bs, const char *str)
233 return byte_stream_putraw(bs, (guint8 *)str, strlen(str));
236 int byte_stream_putbs(ByteStream *bs, ByteStream *srcbs, size_t len)
238 g_return_val_if_fail(byte_stream_bytes_left(srcbs) >= len, 0);
239 g_return_val_if_fail(byte_stream_bytes_left(bs) >= len, 0);
241 memcpy(bs->data + bs->offset, srcbs->data + srcbs->offset, len);
242 bs->offset += len;
243 srcbs->offset += len;
244 return len;
247 int byte_stream_putuid(ByteStream *bs, OscarData *od)
249 PurpleAccount *account;
251 account = purple_connection_get_account(od->gc);
253 return byte_stream_putle32(bs, atoi(purple_account_get_username(account)));
256 void byte_stream_put_bart_asset(ByteStream *bs, guint16 type, ByteStream *data)
258 byte_stream_put16(bs, type);
260 if (data != NULL && data->len > 0) {
261 /* Flags. 0x04 means "this asset has data attached to it" */
262 byte_stream_put8(bs, 0x04); /* Flags */
263 byte_stream_put8(bs, data->len); /* Length */
264 byte_stream_rewind(data);
265 byte_stream_putbs(bs, data, data->len); /* Data */
266 } else {
267 byte_stream_put8(bs, 0x00); /* No flags */
268 byte_stream_put8(bs, 0x00); /* Length */
269 /* No data */
273 void byte_stream_put_bart_asset_str(ByteStream *bs, guint16 type, const char *datastr)
275 ByteStream data;
276 size_t len = datastr != NULL ? strlen(datastr) : 0;
278 if (len > 0) {
279 byte_stream_new(&data, 2 + len + 2);
280 byte_stream_put16(&data, len); /* Length */
281 byte_stream_putstr(&data, datastr); /* String */
282 byte_stream_put16(&data, 0x0000); /* Unknown */
283 byte_stream_put_bart_asset(bs, type, &data);
284 byte_stream_destroy(&data);
285 } else {
286 byte_stream_put_bart_asset(bs, type, NULL);