Annotation of ChivanetAimPidgin/oscarprpl/src/c/bstream.c, revision 1.1.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>