⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tlv.c

📁 oscar message protocol stack
💻 C
📖 第 1 页 / 共 2 页
字号:
/** * Add a four byte integer to a TLV chain. * * @param list Destination chain. * @param type TLV type to add. * @param value Value to add. * @return The size of the value added. */faim_internal int aim_tlvlist_add_32(aim_tlvlist_t **list, const fu16_t type, const fu32_t value){	fu8_t v32[4];	aimutil_put32(v32, value);	return aim_tlvlist_add_raw(list, type, 4, v32);}/** * Adds a block of capability blocks to a TLV chain. The bitfield * passed in should be a bitwise %OR of any of the %AIM_CAPS constants: * *     %AIM_CAPS_BUDDYICON   Supports Buddy Icons *     %AIM_CAPS_TALK        Supports Voice Chat *     %AIM_CAPS_IMIMAGE     Supports DirectIM/IMImage *     %AIM_CAPS_CHAT        Supports Chat *     %AIM_CAPS_GETFILE     Supports Get File functions *     %AIM_CAPS_SENDFILE    Supports Send File functions * * @param list Destination chain * @param type TLV type to add * @param caps Bitfield of capability flags to send * @return The size of the value added. */faim_internal int aim_tlvlist_add_caps(aim_tlvlist_t **list, const fu16_t type, const fu32_t caps){	fu8_t buf[16*16]; /* XXX icky fixed length buffer */	aim_bstream_t bs;	if (!caps)		return 0; /* nothing there anyway */	aim_bstream_init(&bs, buf, sizeof(buf));	aim_putcap(&bs, caps);	return aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf);}/** * Adds the given userinfo struct to a TLV chain. * * @param list Destination chain. * @param type TLV type to add. * @return The size of the value added. */faim_internal int aim_tlvlist_add_userinfo(aim_tlvlist_t **list, fu16_t type, aim_userinfo_t *userinfo){	fu8_t buf[1024]; /* bleh */	aim_bstream_t bs;	aim_bstream_init(&bs, buf, sizeof(buf));	aim_putuserinfo(&bs, userinfo);	return aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf);}/** * Adds the given chatroom info to a TLV chain. * * @param list Destination chain. * @param type TLV type to add. * @param roomname The name of the chat. * @param instance The instance. * @return The size of the value added. */faim_internal int aim_tlvlist_add_chatroom(aim_tlvlist_t **list, fu16_t type, fu16_t exchange, const char *roomname, fu16_t instance){	fu8_t *buf;	int len;	aim_bstream_t bs;	len = 2 + 1 + strlen(roomname) + 2;		if (!(buf = malloc(len)))		return 0;	aim_bstream_init(&bs, buf, len);	aimbs_put16(&bs, exchange);	aimbs_put8(&bs, strlen(roomname));	aimbs_putraw(&bs, roomname, strlen(roomname));	aimbs_put16(&bs, instance);	len = aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf);	free(buf);	return len;}/** * Adds a TLV with a zero length to a TLV chain. * * @param list Destination chain. * @param type TLV type to add. * @return The size of the value added. */faim_internal int aim_tlvlist_add_noval(aim_tlvlist_t **list, const fu16_t type){	return aim_tlvlist_add_raw(list, type, 0, NULL);}/* * Note that the inner TLV chain will not be modifiable as a tlvchain once * it is written using this.  Or rather, it can be, but updates won't be * made to this. * * XXX should probably support sublists for real. *  * This is so neat. * * @param list Destination chain. * @param type TLV type to add. * @param t1 The TLV chain you want to write. * @return The number of bytes written to the destination TLV chain. *         0 is returned if there was an error or if the destination *         TLV chain has length 0. */faim_internal int aim_tlvlist_add_frozentlvlist(aim_tlvlist_t **list, fu16_t type, aim_tlvlist_t **tl){	fu8_t *buf;	int buflen;	aim_bstream_t bs;	buflen = aim_tlvlist_size(tl);	if (buflen <= 0)		return 0;	if (!(buf = malloc(buflen)))		return 0;	aim_bstream_init(&bs, buf, buflen);	aim_tlvlist_write(&bs, tl);	aim_tlvlist_add_raw(list, type, aim_bstream_curpos(&bs), buf);	free(buf);	return buflen;}/** * Substitute a TLV of a given type with a new TLV of the same type.  If  * you attempt to replace a TLV that does not exist, this function will  * just add a new TLV as if you called aim_tlvlist_add_raw(). * * @param list Desination chain (%NULL pointer if empty). * @param type TLV type. * @param length Length of string to add (not including %NULL). * @param value String to add. * @return The length of the TLV. */faim_internal int aim_tlvlist_replace_raw(aim_tlvlist_t **list, const fu16_t type, const fu16_t length, const fu8_t *value){	aim_tlvlist_t *cur;	if (list == NULL)		return 0;	for (cur = *list; ((cur != NULL) && (cur->tlv->type != type)); cur = cur->next);	if (cur == NULL)		return aim_tlvlist_add_raw(list, type, length, value);	free(cur->tlv->value);	cur->tlv->length = length;	if (cur->tlv->length > 0) {		cur->tlv->value = (fu8_t *)malloc(cur->tlv->length);		memcpy(cur->tlv->value, value, cur->tlv->length);	} else		cur->tlv->value = NULL;	return cur->tlv->length;}/** * Substitute a TLV of a given type with a new TLV of the same type.  If  * you attempt to replace a TLV that does not exist, this function will  * just add a new TLV as if you called aim_tlvlist_add_raw(). * * @param list Desination chain (%NULL pointer if empty). * @param type TLV type. * @return The length of the TLV. */faim_internal int aim_tlvlist_replace_noval(aim_tlvlist_t **list, const fu16_t type){	return aim_tlvlist_replace_raw(list, type, 0, NULL);}/** * Substitute a TLV of a given type with a new TLV of the same type.  If  * you attempt to replace a TLV that does not exist, this function will  * just add a new TLV as if you called aim_tlvlist_add_raw(). * * @param list Desination chain (%NULL pointer if empty). * @param type TLV type. * @param value 8 bit value to add. * @return The length of the TLV. */faim_internal int aim_tlvlist_replace_8(aim_tlvlist_t **list, const fu16_t type, const fu8_t value){	fu8_t v8[1];	aimutil_put8(v8, value);	return aim_tlvlist_replace_raw(list, type, 1, v8);}/** * Substitute a TLV of a given type with a new TLV of the same type.  If  * you attempt to replace a TLV that does not exist, this function will  * just add a new TLV as if you called aim_tlvlist_add_raw(). * * @param list Desination chain (%NULL pointer if empty). * @param type TLV type. * @param value 32 bit value to add. * @return The length of the TLV. */faim_internal int aim_tlvlist_replace_32(aim_tlvlist_t **list, const fu16_t type, const fu32_t value){	fu8_t v32[4];	aimutil_put32(v32, value);	return aim_tlvlist_replace_raw(list, type, 4, v32);}/** * Remove a TLV of a given type.  If you attempt to remove a TLV that  * does not exist, nothing happens. * * @param list Desination chain (%NULL pointer if empty). * @param type TLV type. */faim_internal void aim_tlvlist_remove(aim_tlvlist_t **list, const fu16_t type){	aim_tlvlist_t *del;	if (!list || !(*list))		return;	/* Remove the item from the list */	if ((*list)->tlv->type == type) {		del = *list;		*list = (*list)->next;	} else {		aim_tlvlist_t *cur;		for (cur=*list; (cur->next && (cur->next->tlv->type!=type)); cur=cur->next);		if (!cur->next)			return;		del = cur->next;		cur->next = del->next;	}	/* Free the removed item */	free(del->tlv->value);	free(del->tlv);	free(del);}/** * Write a TLV chain into a data buffer. * * Copies a TLV chain into a raw data buffer, writing only the number * of bytes specified. This operation does not free the chain;  * aim_tlvlist_free() must still be called to free up the memory used * by the chain structures. * * XXX clean this up, make better use of bstreams  * * @param bs Input bstream * @param list Source TLV chain * @return Return 0 if the destination bstream is too small. */faim_internal int aim_tlvlist_write(aim_bstream_t *bs, aim_tlvlist_t **list){	int goodbuflen;	aim_tlvlist_t *cur;	/* do an initial run to test total length */	goodbuflen = aim_tlvlist_size(list);	if (goodbuflen > aim_bstream_empty(bs))		return 0; /* not enough buffer */	/* do the real write-out */	for (cur = *list; cur; cur = cur->next) {		aimbs_put16(bs, cur->tlv->type);		aimbs_put16(bs, cur->tlv->length);		if (cur->tlv->length)			aimbs_putraw(bs, cur->tlv->value, cur->tlv->length);	}	return 1; /* XXX this is a nonsensical return */}/** * Grab the Nth TLV of type type in the TLV list list. * * Returns a pointer to an aim_tlv_t of the specified type;  * %NULL on error.  The @nth parameter is specified starting at %1. * In most cases, there will be no more than one TLV of any type * in a chain. * * @param list Source chain. * @param type Requested TLV type. * @param nth Index of TLV of type to get. * @return The TLV you were looking for, or NULL if one could not be found. */faim_internal aim_tlv_t *aim_tlv_gettlv(aim_tlvlist_t *list, const fu16_t type, const int nth){	aim_tlvlist_t *cur;	int i;	for (cur = list, i = 0; cur; cur = cur->next) {		if (cur && cur->tlv) {			if (cur->tlv->type == type)				i++;			if (i >= nth)				return cur->tlv;		}	}	return NULL;}/** * Get the length of the data of the nth TLV in the given TLV chain. * * @param list Source chain. * @param type Requested TLV type. * @param nth Index of TLV of type to get. * @return The length of the data in this TLV, or -1 if the TLV could not be *         found.  Unless -1 is returned, this value will be 2 bytes. */faim_internal int aim_tlv_getlength(aim_tlvlist_t *list, const fu16_t type, const int nth){	aim_tlvlist_t *cur;	int i;	for (cur = list, i = 0; cur; cur = cur->next) {		if (cur && cur->tlv) {			if (cur->tlv->type == type)				i++;			if (i >= nth)				return cur->tlv->length;		}	}	return -1;}/** * Retrieve the data from the nth TLV in the given TLV chain as a string. * * @param list Source TLV chain. * @param type TLV type to search for. * @param nth Index of TLV to return. * @return The value of the TLV you were looking for, or NULL if one could  *         not be found.  This is a dynamic buffer and must be freed by the  *         caller. */faim_internal char *aim_tlv_getstr(aim_tlvlist_t *list, const fu16_t type, const int nth){	aim_tlv_t *tlv;	char *newstr;	if (!(tlv = aim_tlv_gettlv(list, type, nth)))		return NULL;	newstr = (char *) malloc(tlv->length + 1);	memcpy(newstr, tlv->value, tlv->length);	newstr[tlv->length] = '\0';	return newstr;}/** * Retrieve the data from the nth TLV in the given TLV chain as an 8bit  * integer. * * @param list Source TLV chain. * @param type TLV type to search for. * @param nth Index of TLV to return. * @return The value the TLV you were looking for, or 0 if one could  *         not be found. */faim_internal fu8_t aim_tlv_get8(aim_tlvlist_t *list, const fu16_t type, const int nth){	aim_tlv_t *tlv;	if (!(tlv = aim_tlv_gettlv(list, type, nth)))		return 0; /* erm */	return aimutil_get8(tlv->value);}/** * Retrieve the data from the nth TLV in the given TLV chain as a 16bit  * integer. * * @param list Source TLV chain. * @param type TLV type to search for. * @param nth Index of TLV to return. * @return The value the TLV you were looking for, or 0 if one could  *         not be found. */faim_internal fu16_t aim_tlv_get16(aim_tlvlist_t *list, const fu16_t type, const int nth){	aim_tlv_t *tlv;	if (!(tlv = aim_tlv_gettlv(list, type, nth)))		return 0; /* erm */	return aimutil_get16(tlv->value);}/** * Retrieve the data from the nth TLV in the given TLV chain as a 32bit  * integer. * * @param list Source TLV chain. * @param type TLV type to search for. * @param nth Index of TLV to return. * @return The value the TLV you were looking for, or 0 if one could  *         not be found. */faim_internal fu32_t aim_tlv_get32(aim_tlvlist_t *list, const fu16_t type, const int nth){	aim_tlv_t *tlv;	if (!(tlv = aim_tlv_gettlv(list, type, nth)))		return 0; /* erm */	return aimutil_get32(tlv->value);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -