diff libpurple/protocols/novell/nmfield.c @ 15373:5fe8042783c1

Rename gtk/ and libgaim/ to pidgin/ and libpurple/
author Sean Egan <seanegan@gmail.com>
date Sat, 20 Jan 2007 02:32:10 +0000
parents
children 44b4e8bd759b
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/libpurple/protocols/novell/nmfield.c	Sat Jan 20 02:32:10 2007 +0000
@@ -0,0 +1,366 @@
+/*
+ * nmfield.c
+ *
+ * Copyright (c) 2004 Novell, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA	02111-1307	USA
+ *
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include "nmfield.h"
+
+/* Free a field value and tag */
+static void _free_field(NMField * field);
+
+/* Free a field value */
+static void _free_field_value(NMField * field);
+
+/* Make a deep copy of the field */
+static void _copy_field(NMField * dest, NMField * src);
+
+/* Make a deep copy of the field's value */
+static void _copy_field_value(NMField * dest, NMField * src);
+
+/* Create a string from a value -- for debugging */
+static char *_value_to_string(NMField * field);
+
+static NMField *
+_add_blank_field(NMField *fields, guint32 count)
+{
+	guint32 new_len;
+
+	if (fields == NULL) {
+		fields = g_new0(NMField, 10);
+		fields->len = 10;
+	} else {
+		if (fields->len < count + 2) {
+			new_len = count + 10;
+			fields = g_realloc(fields, new_len * sizeof(NMField));
+			fields->len = new_len;
+		}
+	}
+	return fields;
+}
+
+NMField *
+nm_field_add_number(NMField * fields, const char *tag, guint32 size, guint8 method,
+					guint8 flags, guint32 value, guint8 type)
+{
+	guint32 count;
+	NMField *field;
+
+	count = nm_count_fields(fields);
+	fields = _add_blank_field(fields, count);
+
+	field = &(fields[count]);
+	field->tag = g_strdup(tag);
+	field->size = size;
+	field->method = method;
+	field->flags = flags;
+	field->value = value;
+	field->type = type;
+
+	/* Null terminate the field array */
+	field = &((fields)[count + 1]);
+	field->tag = NULL;
+	field->value = 0;
+	field->ptr_value = NULL;
+
+	return fields;
+}
+
+NMField *
+nm_field_add_pointer(NMField * fields, const char *tag, guint32 size, guint8 method,
+					 guint8 flags, gpointer value, guint8 type)
+{
+	guint32 count;
+	NMField *field = NULL;
+
+	count = nm_count_fields(fields);
+	fields = _add_blank_field(fields, count);
+
+	field = &(fields[count]);
+	field->tag = g_strdup(tag);
+	field->size = size;
+	field->method = method;
+	field->flags = flags;
+	field->ptr_value = value;
+	field->type = type;
+
+	/* Null terminate the field array */
+	field = &((fields)[count + 1]);
+	field->tag = NULL;
+	field->value = 0;
+	field->ptr_value = NULL;
+
+	return fields;
+}
+
+guint32
+nm_count_fields(NMField * fields)
+{
+	guint32 count = 0;
+
+	if (fields) {
+		while (fields->tag != NULL) {
+			count++;
+			fields++;
+		}
+	}
+
+	return count;
+}
+
+void
+nm_free_fields(NMField ** fields)
+{
+	NMField *field = NULL;
+
+	if ((fields == NULL) || (*fields == NULL))
+		return;
+
+	field = *fields;
+
+	while (field->tag != NULL) {
+		_free_field(field);
+		field++;
+	}
+
+	g_free(*fields);
+	*fields = NULL;
+}
+
+
+static void
+_free_field(NMField * field)
+{
+	if (field == NULL)
+		return;
+
+	_free_field_value(field);
+	g_free(field->tag);
+}
+
+static void
+_free_field_value(NMField * field)
+{
+	if (field == NULL)
+		return;
+
+	switch (field->type) {
+		case NMFIELD_TYPE_BINARY:
+		case NMFIELD_TYPE_UTF8:
+		case NMFIELD_TYPE_DN:
+			if (field->ptr_value != NULL) {
+				g_free(field->ptr_value);
+			}
+			break;
+
+		case NMFIELD_TYPE_ARRAY:
+		case NMFIELD_TYPE_MV:
+			nm_free_fields((NMField **)&field->ptr_value);
+			break;
+
+		default:
+			break;
+	}
+
+	field->size = 0;
+	field->ptr_value = NULL;
+}
+
+NMField *
+nm_locate_field(char *tag, NMField * fields)
+{
+	NMField *ret_fields = NULL;
+
+	if ((fields == NULL) || (tag == NULL)) {
+		return NULL;
+	}
+
+	while (fields->tag != NULL) {
+		if (g_ascii_strcasecmp(fields->tag, tag) == 0) {
+			ret_fields = fields;
+			break;
+		}
+		fields++;
+	}
+
+	return ret_fields;
+}
+
+NMField *
+nm_copy_field_array(NMField * src)
+{
+	NMField *ptr = NULL;
+	NMField *dest = NULL;
+	int count;
+
+	if (src != NULL) {
+		count = nm_count_fields(src) + 1;
+		dest = g_new0(NMField, count);
+		dest->len = count;
+		ptr = dest;
+		while (src->tag != NULL) {
+			_copy_field(ptr, src);
+			ptr++;
+			src++;
+		}
+	}
+
+	return dest;
+}
+
+static void
+_copy_field(NMField * dest, NMField * src)
+{
+	dest->type = src->type;
+	dest->flags = src->flags;
+	dest->method = src->method;
+	dest->tag = g_strdup(src->tag);
+	_copy_field_value(dest, src);
+}
+
+static void
+_copy_field_value(NMField * dest, NMField * src)
+{
+	dest->type = src->type;
+	switch (dest->type) {
+		case NMFIELD_TYPE_UTF8:
+		case NMFIELD_TYPE_DN:
+			if (src->size == 0 && src->ptr_value != NULL) {
+				src->size = strlen((char *) src->ptr_value) + 1;
+			}
+			/* fall through */
+		case NMFIELD_TYPE_BINARY:
+			if (src->size != 0 && src->ptr_value != NULL) {
+				dest->ptr_value = g_new0(char, src->size);
+				memcpy(dest->ptr_value, src->ptr_value, src->size);
+			}
+			break;
+
+		case NMFIELD_TYPE_ARRAY:
+		case NMFIELD_TYPE_MV:
+			dest->ptr_value = nm_copy_field_array((NMField *)src->ptr_value);
+			break;
+
+		default:
+			/* numeric value */
+			dest->value = src->value;
+			break;
+	}
+
+	dest->size = src->size;
+}
+
+void
+nm_remove_field(NMField * field)
+{
+	NMField *tmp;
+	guint32 len;
+
+	if ((field != NULL) && (field->tag != NULL)) {
+		_free_field(field);
+
+		/* Move fields down */
+		tmp = field + 1;
+		while (1) {
+			/* Don't overwrite the size of the array */
+			len = field->len;
+
+			*field = *tmp;
+
+			field->len = len;
+
+			if (tmp->tag == NULL)
+				break;
+
+			field++;
+			tmp++;
+		}
+	}
+}
+
+void
+nm_print_fields(NMField * fields)
+{
+	char *str = NULL;
+	NMField *field = fields;
+
+	if (fields == NULL)
+		return;
+
+	while (field->tag != NULL) {
+		if (field->type == NMFIELD_TYPE_ARRAY || field->type == NMFIELD_TYPE_MV) {
+			printf("Subarray START: %s Method = %d\n", field->tag, field->method);
+			nm_print_fields((NMField *) field->ptr_value);
+			printf("Subarray END: %s\n", field->tag);
+		} else {
+			str = _value_to_string(field);
+			printf("Tag=%s;Value=%s\n", field->tag, str);
+			g_free(str);
+			str = NULL;
+		}
+		field++;
+	}
+
+}
+
+static char *
+_value_to_string(NMField * field)
+{
+	char *value = NULL;
+
+	if (field == NULL)
+		return NULL;
+
+	/* This is a single value attribute */
+	if (((field->type == NMFIELD_TYPE_UTF8) ||
+		 (field->type == NMFIELD_TYPE_DN)) && (field->ptr_value != NULL)) {
+		value = g_strdup((const char *) field->ptr_value);
+	} else if (field->type == NMFIELD_TYPE_BINARY && field->ptr_value != NULL) {
+		value = g_new0(char, field->size);
+		memcpy(value, (const char *) field->ptr_value, field->size);
+	} else if (field->type == NMFIELD_TYPE_BOOL) {
+		if (field->value) {
+			value = g_strdup(NM_FIELD_TRUE);
+		} else {
+			value = g_strdup(NM_FIELD_FALSE);
+		}
+	} else {
+		/* assume it is a number */
+		value = g_new0(char, 20);
+
+		switch (field->type) {
+		case NMFIELD_TYPE_BYTE:
+		case NMFIELD_TYPE_WORD:
+		case NMFIELD_TYPE_DWORD:
+			value = g_strdup_printf("%ld", (long) field->value);
+			break;
+
+		case NMFIELD_TYPE_UBYTE:
+		case NMFIELD_TYPE_UWORD:
+		case NMFIELD_TYPE_UDWORD:
+			value = g_strdup_printf("%lu", (unsigned long) field->value);
+			break;
+		}
+	}
+
+	if (value == NULL)
+		value = g_strdup("NULL");
+
+	return value;
+}