File:  [Coherent Logic Development] / ChivanetAimPidgin / oscarprpl / src / c / bstream.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Mon Jan 27 19:48:25 2025 UTC (6 months ago) by snw
Branches: MAIN, CoherentLogicDevelopment
CVS tags: test-tag, start, HEAD
Pidgin AIM Plugin for ChivaNet

    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>