| |
1 /* |
| |
2 * Gaim's oscar protocol plugin |
| |
3 * This file is the legal property of its developers. |
| |
4 * Please see the AUTHORS file distributed alongside this file. |
| |
5 * |
| |
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. |
| |
10 * |
| |
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. |
| |
15 * |
| |
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| |
19 */ |
| |
20 |
| |
21 /* |
| |
22 * This file contains all functions needed to use bstreams. |
| |
23 */ |
| |
24 |
| |
25 #include "oscar.h" |
| |
26 |
| |
27 int byte_stream_new(ByteStream *bs, guint32 len) |
| |
28 { |
| |
29 if (bs == NULL) |
| |
30 return -1; |
| |
31 |
| |
32 return byte_stream_init(bs, g_malloc(len), len); |
| |
33 } |
| |
34 |
| |
35 int byte_stream_init(ByteStream *bs, guint8 *data, int len) |
| |
36 { |
| |
37 |
| |
38 if (bs == NULL) |
| |
39 return -1; |
| |
40 |
| |
41 bs->data = data; |
| |
42 bs->len = len; |
| |
43 bs->offset = 0; |
| |
44 |
| |
45 return 0; |
| |
46 } |
| |
47 |
| |
48 int byte_stream_empty(ByteStream *bs) |
| |
49 { |
| |
50 return bs->len - bs->offset; |
| |
51 } |
| |
52 |
| |
53 int byte_stream_curpos(ByteStream *bs) |
| |
54 { |
| |
55 return bs->offset; |
| |
56 } |
| |
57 |
| |
58 int byte_stream_setpos(ByteStream *bs, unsigned int off) |
| |
59 { |
| |
60 |
| |
61 if (off > bs->len) |
| |
62 return -1; |
| |
63 |
| |
64 bs->offset = off; |
| |
65 |
| |
66 return off; |
| |
67 } |
| |
68 |
| |
69 void byte_stream_rewind(ByteStream *bs) |
| |
70 { |
| |
71 |
| |
72 byte_stream_setpos(bs, 0); |
| |
73 |
| |
74 return; |
| |
75 } |
| |
76 |
| |
77 /* |
| |
78 * N can be negative, which can be used for going backwards |
| |
79 * in a bstream. I'm not sure if libfaim actually does |
| |
80 * this anywhere... |
| |
81 */ |
| |
82 int byte_stream_advance(ByteStream *bs, int n) |
| |
83 { |
| |
84 |
| |
85 if ((byte_stream_curpos(bs) + n < 0) || (byte_stream_empty(bs) < n)) |
| |
86 return 0; /* XXX throw an exception */ |
| |
87 |
| |
88 bs->offset += n; |
| |
89 |
| |
90 return n; |
| |
91 } |
| |
92 |
| |
93 guint8 byte_stream_get8(ByteStream *bs) |
| |
94 { |
| |
95 |
| |
96 if (byte_stream_empty(bs) < 1) |
| |
97 return 0; /* XXX throw an exception */ |
| |
98 |
| |
99 bs->offset++; |
| |
100 |
| |
101 return aimutil_get8(bs->data + bs->offset - 1); |
| |
102 } |
| |
103 |
| |
104 guint16 byte_stream_get16(ByteStream *bs) |
| |
105 { |
| |
106 |
| |
107 if (byte_stream_empty(bs) < 2) |
| |
108 return 0; /* XXX throw an exception */ |
| |
109 |
| |
110 bs->offset += 2; |
| |
111 |
| |
112 return aimutil_get16(bs->data + bs->offset - 2); |
| |
113 } |
| |
114 |
| |
115 guint32 byte_stream_get32(ByteStream *bs) |
| |
116 { |
| |
117 |
| |
118 if (byte_stream_empty(bs) < 4) |
| |
119 return 0; /* XXX throw an exception */ |
| |
120 |
| |
121 bs->offset += 4; |
| |
122 |
| |
123 return aimutil_get32(bs->data + bs->offset - 4); |
| |
124 } |
| |
125 |
| |
126 guint8 byte_stream_getle8(ByteStream *bs) |
| |
127 { |
| |
128 |
| |
129 if (byte_stream_empty(bs) < 1) |
| |
130 return 0; /* XXX throw an exception */ |
| |
131 |
| |
132 bs->offset++; |
| |
133 |
| |
134 return aimutil_getle8(bs->data + bs->offset - 1); |
| |
135 } |
| |
136 |
| |
137 guint16 byte_stream_getle16(ByteStream *bs) |
| |
138 { |
| |
139 |
| |
140 if (byte_stream_empty(bs) < 2) |
| |
141 return 0; /* XXX throw an exception */ |
| |
142 |
| |
143 bs->offset += 2; |
| |
144 |
| |
145 return aimutil_getle16(bs->data + bs->offset - 2); |
| |
146 } |
| |
147 |
| |
148 guint32 byte_stream_getle32(ByteStream *bs) |
| |
149 { |
| |
150 |
| |
151 if (byte_stream_empty(bs) < 4) |
| |
152 return 0; /* XXX throw an exception */ |
| |
153 |
| |
154 bs->offset += 4; |
| |
155 |
| |
156 return aimutil_getle32(bs->data + bs->offset - 4); |
| |
157 } |
| |
158 |
| |
159 int byte_stream_getrawbuf(ByteStream *bs, guint8 *buf, int len) |
| |
160 { |
| |
161 |
| |
162 if (byte_stream_empty(bs) < len) |
| |
163 return 0; |
| |
164 |
| |
165 memcpy(buf, bs->data + bs->offset, len); |
| |
166 bs->offset += len; |
| |
167 |
| |
168 return len; |
| |
169 } |
| |
170 |
| |
171 guint8 *byte_stream_getraw(ByteStream *bs, int len) |
| |
172 { |
| |
173 guint8 *ob; |
| |
174 |
| |
175 ob = malloc(len); |
| |
176 |
| |
177 if (byte_stream_getrawbuf(bs, ob, len) < len) { |
| |
178 free(ob); |
| |
179 return NULL; |
| |
180 } |
| |
181 |
| |
182 return ob; |
| |
183 } |
| |
184 |
| |
185 char *byte_stream_getstr(ByteStream *bs, int len) |
| |
186 { |
| |
187 char *ob; |
| |
188 |
| |
189 ob = malloc(len + 1); |
| |
190 |
| |
191 if (byte_stream_getrawbuf(bs, (guint8 *)ob, len) < len) { |
| |
192 free(ob); |
| |
193 return NULL; |
| |
194 } |
| |
195 |
| |
196 ob[len] = '\0'; |
| |
197 |
| |
198 return ob; |
| |
199 } |
| |
200 |
| |
201 int byte_stream_put8(ByteStream *bs, guint8 v) |
| |
202 { |
| |
203 |
| |
204 if (byte_stream_empty(bs) < 1) |
| |
205 return 0; /* XXX throw an exception */ |
| |
206 |
| |
207 bs->offset += aimutil_put8(bs->data + bs->offset, v); |
| |
208 |
| |
209 return 1; |
| |
210 } |
| |
211 |
| |
212 int byte_stream_put16(ByteStream *bs, guint16 v) |
| |
213 { |
| |
214 |
| |
215 if (byte_stream_empty(bs) < 2) |
| |
216 return 0; /* XXX throw an exception */ |
| |
217 |
| |
218 bs->offset += aimutil_put16(bs->data + bs->offset, v); |
| |
219 |
| |
220 return 2; |
| |
221 } |
| |
222 |
| |
223 int byte_stream_put32(ByteStream *bs, guint32 v) |
| |
224 { |
| |
225 |
| |
226 if (byte_stream_empty(bs) < 4) |
| |
227 return 0; /* XXX throw an exception */ |
| |
228 |
| |
229 bs->offset += aimutil_put32(bs->data + bs->offset, v); |
| |
230 |
| |
231 return 1; |
| |
232 } |
| |
233 |
| |
234 int byte_stream_putle8(ByteStream *bs, guint8 v) |
| |
235 { |
| |
236 |
| |
237 if (byte_stream_empty(bs) < 1) |
| |
238 return 0; /* XXX throw an exception */ |
| |
239 |
| |
240 bs->offset += aimutil_putle8(bs->data + bs->offset, v); |
| |
241 |
| |
242 return 1; |
| |
243 } |
| |
244 |
| |
245 int byte_stream_putle16(ByteStream *bs, guint16 v) |
| |
246 { |
| |
247 |
| |
248 if (byte_stream_empty(bs) < 2) |
| |
249 return 0; /* XXX throw an exception */ |
| |
250 |
| |
251 bs->offset += aimutil_putle16(bs->data + bs->offset, v); |
| |
252 |
| |
253 return 2; |
| |
254 } |
| |
255 |
| |
256 int byte_stream_putle32(ByteStream *bs, guint32 v) |
| |
257 { |
| |
258 |
| |
259 if (byte_stream_empty(bs) < 4) |
| |
260 return 0; /* XXX throw an exception */ |
| |
261 |
| |
262 bs->offset += aimutil_putle32(bs->data + bs->offset, v); |
| |
263 |
| |
264 return 1; |
| |
265 } |
| |
266 |
| |
267 |
| |
268 int byte_stream_putraw(ByteStream *bs, const guint8 *v, int len) |
| |
269 { |
| |
270 |
| |
271 if (byte_stream_empty(bs) < len) |
| |
272 return 0; /* XXX throw an exception */ |
| |
273 |
| |
274 memcpy(bs->data + bs->offset, v, len); |
| |
275 bs->offset += len; |
| |
276 |
| |
277 return len; |
| |
278 } |
| |
279 |
| |
280 int byte_stream_putstr(ByteStream *bs, const char *str) |
| |
281 { |
| |
282 return byte_stream_putraw(bs, (guint8 *)str, strlen(str)); |
| |
283 } |
| |
284 |
| |
285 int byte_stream_putbs(ByteStream *bs, ByteStream *srcbs, int len) |
| |
286 { |
| |
287 |
| |
288 if (byte_stream_empty(srcbs) < len) |
| |
289 return 0; /* XXX throw exception (underrun) */ |
| |
290 |
| |
291 if (byte_stream_empty(bs) < len) |
| |
292 return 0; /* XXX throw exception (overflow) */ |
| |
293 |
| |
294 memcpy(bs->data + bs->offset, srcbs->data + srcbs->offset, len); |
| |
295 bs->offset += len; |
| |
296 srcbs->offset += len; |
| |
297 |
| |
298 return len; |
| |
299 } |