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