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 g_return_val_if_fail(bs
!= NULL
, 0);
55 g_return_val_if_fail(bs
->len
>= bs
->offset
, 0);
57 return bs
->len
- bs
->offset
;
60 int byte_stream_curpos(ByteStream
*bs
)
65 int byte_stream_setpos(ByteStream
*bs
, size_t off
)
67 g_return_val_if_fail(off
<= bs
->len
, -1);
73 void byte_stream_rewind(ByteStream
*bs
)
75 byte_stream_setpos(bs
, 0);
79 * N can be negative, which can be used for going backwards
82 int byte_stream_advance(ByteStream
*bs
, int n
)
84 g_return_val_if_fail(byte_stream_curpos(bs
) + n
>= 0, 0);
85 g_return_val_if_fail((gsize
)n
<= byte_stream_bytes_left(bs
), 0);
91 guint8
byte_stream_get8(ByteStream
*bs
)
93 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= 1, 0);
96 return aimutil_get8(bs
->data
+ bs
->offset
- 1);
99 guint16
byte_stream_get16(ByteStream
*bs
)
101 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= 2, 0);
104 return aimutil_get16(bs
->data
+ bs
->offset
- 2);
107 guint32
byte_stream_get32(ByteStream
*bs
)
109 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= 4, 0);
112 return aimutil_get32(bs
->data
+ bs
->offset
- 4);
115 guint8
byte_stream_getle8(ByteStream
*bs
)
117 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= 1, 0);
120 return aimutil_getle8(bs
->data
+ bs
->offset
- 1);
123 guint16
byte_stream_getle16(ByteStream
*bs
)
125 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= 2, 0);
128 return aimutil_getle16(bs
->data
+ bs
->offset
- 2);
131 guint32
byte_stream_getle32(ByteStream
*bs
)
133 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= 4, 0);
136 return aimutil_getle32(bs
->data
+ bs
->offset
- 4);
139 static void byte_stream_getrawbuf_nocheck(ByteStream
*bs
, guint8
*buf
, size_t len
)
141 memcpy(buf
, bs
->data
+ bs
->offset
, len
);
145 int byte_stream_getrawbuf(ByteStream
*bs
, guint8
*buf
, size_t len
)
147 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= len
, 0);
149 byte_stream_getrawbuf_nocheck(bs
, buf
, len
);
153 guint8
*byte_stream_getraw(ByteStream
*bs
, size_t len
)
157 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= len
, NULL
);
160 byte_stream_getrawbuf_nocheck(bs
, ob
, len
);
164 char *byte_stream_getstr(ByteStream
*bs
, size_t len
)
168 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= len
, NULL
);
170 ob
= g_malloc(len
+ 1);
171 byte_stream_getrawbuf_nocheck(bs
, (guint8
*)ob
, len
);
176 int byte_stream_put8(ByteStream
*bs
, guint8 v
)
178 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= 1, 0);
180 bs
->offset
+= aimutil_put8(bs
->data
+ bs
->offset
, v
);
184 int byte_stream_put16(ByteStream
*bs
, guint16 v
)
186 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= 2, 0);
188 bs
->offset
+= aimutil_put16(bs
->data
+ bs
->offset
, v
);
192 int byte_stream_put32(ByteStream
*bs
, guint32 v
)
194 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= 4, 0);
196 bs
->offset
+= aimutil_put32(bs
->data
+ bs
->offset
, v
);
200 int byte_stream_putle8(ByteStream
*bs
, guint8 v
)
202 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= 1, 0);
204 bs
->offset
+= aimutil_putle8(bs
->data
+ bs
->offset
, v
);
208 int byte_stream_putle16(ByteStream
*bs
, guint16 v
)
210 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= 2, 0);
212 bs
->offset
+= aimutil_putle16(bs
->data
+ bs
->offset
, v
);
216 int byte_stream_putle32(ByteStream
*bs
, guint32 v
)
218 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= 4, 0);
220 bs
->offset
+= aimutil_putle32(bs
->data
+ bs
->offset
, v
);
225 int byte_stream_putraw(ByteStream
*bs
, const guint8
*v
, size_t len
)
227 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= len
, 0);
229 memcpy(bs
->data
+ bs
->offset
, v
, len
);
234 int byte_stream_putstr(ByteStream
*bs
, const char *str
)
236 return byte_stream_putraw(bs
, (guint8
*)str
, strlen(str
));
239 int byte_stream_putbs(ByteStream
*bs
, ByteStream
*srcbs
, size_t len
)
241 g_return_val_if_fail(byte_stream_bytes_left(srcbs
) >= len
, 0);
242 g_return_val_if_fail(byte_stream_bytes_left(bs
) >= len
, 0);
244 memcpy(bs
->data
+ bs
->offset
, srcbs
->data
+ srcbs
->offset
, len
);
246 srcbs
->offset
+= len
;
250 int byte_stream_putuid(ByteStream
*bs
, OscarData
*od
)
252 PurpleAccount
*account
;
254 account
= purple_connection_get_account(od
->gc
);
256 return byte_stream_putle32(bs
, atoi(purple_account_get_username(account
)));
259 void byte_stream_put_bart_asset(ByteStream
*bs
, guint16 type
, ByteStream
*data
)
261 byte_stream_put16(bs
, type
);
263 if (data
!= NULL
&& data
->len
> 0) {
264 /* Flags. 0x04 means "this asset has data attached to it" */
265 byte_stream_put8(bs
, 0x04); /* Flags */
266 byte_stream_put8(bs
, data
->len
); /* Length */
267 byte_stream_rewind(data
);
268 byte_stream_putbs(bs
, data
, data
->len
); /* Data */
270 byte_stream_put8(bs
, 0x00); /* No flags */
271 byte_stream_put8(bs
, 0x00); /* Length */
276 void byte_stream_put_bart_asset_str(ByteStream
*bs
, guint16 type
, const char *datastr
)
279 size_t len
= datastr
!= NULL
? strlen(datastr
) : 0;
282 byte_stream_new(&data
, 2 + len
+ 2);
283 byte_stream_put16(&data
, len
); /* Length */
284 byte_stream_putstr(&data
, datastr
); /* String */
285 byte_stream_put16(&data
, 0x0000); /* Unknown */
286 byte_stream_put_bart_asset(bs
, type
, &data
);
287 byte_stream_destroy(&data
);
289 byte_stream_put_bart_asset(bs
, type
, NULL
);