Annotation of ChivanetAimPidgin/oscarprpl/src/c/bstream.c, revision 1.1
1.1 ! snw 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.
! 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 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, size_t 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, size_t len)
! 36: {
! 37: if (bs == NULL)
! 38: return -1;
! 39:
! 40: bs->data = data;
! 41: bs->len = len;
! 42: bs->offset = 0;
! 43:
! 44: return 0;
! 45: }
! 46:
! 47: void byte_stream_destroy(ByteStream *bs)
! 48: {
! 49: g_free(bs->data);
! 50: }
! 51:
! 52: size_t byte_stream_bytes_left(ByteStream *bs)
! 53: {
! 54: return bs->len - bs->offset;
! 55: }
! 56:
! 57: int byte_stream_curpos(ByteStream *bs)
! 58: {
! 59: return bs->offset;
! 60: }
! 61:
! 62: int byte_stream_setpos(ByteStream *bs, size_t off)
! 63: {
! 64: g_return_val_if_fail(off <= bs->len, -1);
! 65:
! 66: bs->offset = off;
! 67: return off;
! 68: }
! 69:
! 70: void byte_stream_rewind(ByteStream *bs)
! 71: {
! 72: byte_stream_setpos(bs, 0);
! 73: }
! 74:
! 75: /*
! 76: * N can be negative, which can be used for going backwards
! 77: * in a bstream.
! 78: */
! 79: int byte_stream_advance(ByteStream *bs, int n)
! 80: {
! 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);
! 83:
! 84: bs->offset += n;
! 85: return n;
! 86: }
! 87:
! 88: guint8 byte_stream_get8(ByteStream *bs)
! 89: {
! 90: g_return_val_if_fail(byte_stream_bytes_left(bs) >= 1, 0);
! 91:
! 92: bs->offset++;
! 93: return aimutil_get8(bs->data + bs->offset - 1);
! 94: }
! 95:
! 96: guint16 byte_stream_get16(ByteStream *bs)
! 97: {
! 98: g_return_val_if_fail(byte_stream_bytes_left(bs) >= 2, 0);
! 99:
! 100: bs->offset += 2;
! 101: return aimutil_get16(bs->data + bs->offset - 2);
! 102: }
! 103:
! 104: guint32 byte_stream_get32(ByteStream *bs)
! 105: {
! 106: g_return_val_if_fail(byte_stream_bytes_left(bs) >= 4, 0);
! 107:
! 108: bs->offset += 4;
! 109: return aimutil_get32(bs->data + bs->offset - 4);
! 110: }
! 111:
! 112: guint8 byte_stream_getle8(ByteStream *bs)
! 113: {
! 114: g_return_val_if_fail(byte_stream_bytes_left(bs) >= 1, 0);
! 115:
! 116: bs->offset++;
! 117: return aimutil_getle8(bs->data + bs->offset - 1);
! 118: }
! 119:
! 120: guint16 byte_stream_getle16(ByteStream *bs)
! 121: {
! 122: g_return_val_if_fail(byte_stream_bytes_left(bs) >= 2, 0);
! 123:
! 124: bs->offset += 2;
! 125: return aimutil_getle16(bs->data + bs->offset - 2);
! 126: }
! 127:
! 128: guint32 byte_stream_getle32(ByteStream *bs)
! 129: {
! 130: g_return_val_if_fail(byte_stream_bytes_left(bs) >= 4, 0);
! 131:
! 132: bs->offset += 4;
! 133: return aimutil_getle32(bs->data + bs->offset - 4);
! 134: }
! 135:
! 136: static void byte_stream_getrawbuf_nocheck(ByteStream *bs, guint8 *buf, size_t len)
! 137: {
! 138: memcpy(buf, bs->data + bs->offset, len);
! 139: bs->offset += len;
! 140: }
! 141:
! 142: int byte_stream_getrawbuf(ByteStream *bs, guint8 *buf, size_t len)
! 143: {
! 144: g_return_val_if_fail(byte_stream_bytes_left(bs) >= len, 0);
! 145:
! 146: byte_stream_getrawbuf_nocheck(bs, buf, len);
! 147: return len;
! 148: }
! 149:
! 150: guint8 *byte_stream_getraw(ByteStream *bs, size_t len)
! 151: {
! 152: guint8 *ob;
! 153:
! 154: g_return_val_if_fail(byte_stream_bytes_left(bs) >= len, NULL);
! 155:
! 156: ob = g_malloc(len);
! 157: byte_stream_getrawbuf_nocheck(bs, ob, len);
! 158: return ob;
! 159: }
! 160:
! 161: char *byte_stream_getstr(ByteStream *bs, size_t len)
! 162: {
! 163: char *ob;
! 164:
! 165: g_return_val_if_fail(byte_stream_bytes_left(bs) >= len, NULL);
! 166:
! 167: ob = g_malloc(len + 1);
! 168: byte_stream_getrawbuf_nocheck(bs, (guint8 *)ob, len);
! 169: ob[len] = '\0';
! 170: return ob;
! 171: }
! 172:
! 173: int byte_stream_put8(ByteStream *bs, guint8 v)
! 174: {
! 175: g_return_val_if_fail(byte_stream_bytes_left(bs) >= 1, 0);
! 176:
! 177: bs->offset += aimutil_put8(bs->data + bs->offset, v);
! 178: return 1;
! 179: }
! 180:
! 181: int byte_stream_put16(ByteStream *bs, guint16 v)
! 182: {
! 183: g_return_val_if_fail(byte_stream_bytes_left(bs) >= 2, 0);
! 184:
! 185: bs->offset += aimutil_put16(bs->data + bs->offset, v);
! 186: return 2;
! 187: }
! 188:
! 189: int byte_stream_put32(ByteStream *bs, guint32 v)
! 190: {
! 191: g_return_val_if_fail(byte_stream_bytes_left(bs) >= 4, 0);
! 192:
! 193: bs->offset += aimutil_put32(bs->data + bs->offset, v);
! 194: return 1;
! 195: }
! 196:
! 197: int byte_stream_putle8(ByteStream *bs, guint8 v)
! 198: {
! 199: g_return_val_if_fail(byte_stream_bytes_left(bs) >= 1, 0);
! 200:
! 201: bs->offset += aimutil_putle8(bs->data + bs->offset, v);
! 202: return 1;
! 203: }
! 204:
! 205: int byte_stream_putle16(ByteStream *bs, guint16 v)
! 206: {
! 207: g_return_val_if_fail(byte_stream_bytes_left(bs) >= 2, 0);
! 208:
! 209: bs->offset += aimutil_putle16(bs->data + bs->offset, v);
! 210: return 2;
! 211: }
! 212:
! 213: int byte_stream_putle32(ByteStream *bs, guint32 v)
! 214: {
! 215: g_return_val_if_fail(byte_stream_bytes_left(bs) >= 4, 0);
! 216:
! 217: bs->offset += aimutil_putle32(bs->data + bs->offset, v);
! 218: return 1;
! 219: }
! 220:
! 221:
! 222: int byte_stream_putraw(ByteStream *bs, const guint8 *v, size_t len)
! 223: {
! 224: g_return_val_if_fail(byte_stream_bytes_left(bs) >= len, 0);
! 225:
! 226: memcpy(bs->data + bs->offset, v, len);
! 227: bs->offset += len;
! 228: return len;
! 229: }
! 230:
! 231: int byte_stream_putstr(ByteStream *bs, const char *str)
! 232: {
! 233: return byte_stream_putraw(bs, (guint8 *)str, strlen(str));
! 234: }
! 235:
! 236: int byte_stream_putbs(ByteStream *bs, ByteStream *srcbs, size_t len)
! 237: {
! 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);
! 240:
! 241: memcpy(bs->data + bs->offset, srcbs->data + srcbs->offset, len);
! 242: bs->offset += len;
! 243: srcbs->offset += len;
! 244: return len;
! 245: }
! 246:
! 247: int byte_stream_putuid(ByteStream *bs, OscarData *od)
! 248: {
! 249: PurpleAccount *account;
! 250:
! 251: account = purple_connection_get_account(od->gc);
! 252:
! 253: return byte_stream_putle32(bs, atoi(purple_account_get_username(account)));
! 254: }
! 255:
! 256: void byte_stream_put_bart_asset(ByteStream *bs, guint16 type, ByteStream *data)
! 257: {
! 258: byte_stream_put16(bs, type);
! 259:
! 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 */
! 270: }
! 271: }
! 272:
! 273: void byte_stream_put_bart_asset_str(ByteStream *bs, guint16 type, const char *datastr)
! 274: {
! 275: ByteStream data;
! 276: size_t len = datastr != NULL ? strlen(datastr) : 0;
! 277:
! 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);
! 287: }
! 288: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>