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.
27 int byte_stream_new(ByteStream
*bs
, size_t len
)
32 return byte_stream_init(bs
, g_malloc(len
), len
);
35 int byte_stream_init(ByteStream
*bs
, guint8
*data
, size_t len
)
47 void byte_stream_destroy(ByteStream
*bs
)
52 size_t byte_stream_bytes_left(ByteStream
*bs
)
54 return bs
->len
- bs
->offset
;
57 int byte_stream_curpos(ByteStream
*bs
)
62 int byte_stream_setpos(ByteStream
*bs
, size_t off
)
64 g_return_val_if_fail(off
<= bs
->len
, -1);
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
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);
88 guint8
byte_stream_get8(ByteStream
*bs
)
90 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= 1, 0);
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);
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);
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);
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);
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);
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
);
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
);
150 guint8
*byte_stream_getraw(ByteStream
*bs
, size_t len
)
154 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= len
, NULL
);
157 byte_stream_getrawbuf_nocheck(bs
, ob
, len
);
161 char *byte_stream_getstr(ByteStream
*bs
, size_t len
)
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
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
);
243 srcbs
->offset
+= 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 */
267 byte_stream_put8(bs
, 0x00); /* No flags */
268 byte_stream_put8(bs
, 0x00); /* Length */
273 void byte_stream_put_bart_asset_str(ByteStream
*bs
, guint16 type
, const char *datastr
)
276 size_t len
= datastr
!= NULL
? strlen(datastr
) : 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
);
286 byte_stream_put_bart_asset(bs
, type
, NULL
);