mark PurpleImageClass as private
[pidgin-git.git] / libpurple / protocols / novell / nmfield.c
bloba94a45913ad65d6aee5468400695c36c123b5765
1 /*
2 * nmfield.c
4 * Copyright (c) 2004 Novell, Inc. All Rights Reserved.
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
21 #include <string.h>
22 #include <stdio.h>
23 #include "nmfield.h"
25 /* Free a field value and tag */
26 static void _free_field(NMField * field);
28 /* Free a field value */
29 static void _free_field_value(NMField * field);
31 /* Make a deep copy of the field */
32 static void _copy_field(NMField * dest, NMField * src);
34 /* Make a deep copy of the field's value */
35 static void _copy_field_value(NMField * dest, NMField * src);
37 /* Create a string from a value -- for debugging */
38 static char *_value_to_string(NMField * field);
40 static NMField *
41 _add_blank_field(NMField *fields, guint32 count)
43 guint32 new_len;
45 if (fields == NULL) {
46 fields = g_new0(NMField, 10);
47 fields->len = 10;
48 } else {
49 if (fields->len < count + 2) {
50 new_len = count + 10;
51 fields = g_realloc(fields, new_len * sizeof(NMField));
52 fields->len = new_len;
55 return fields;
58 NMField *
59 nm_field_add_number(NMField * fields, const char *tag, guint32 size, guint8 method,
60 guint8 flags, guint32 value, guint8 type)
62 guint32 count;
63 NMField *field;
65 count = nm_count_fields(fields);
66 fields = _add_blank_field(fields, count);
68 field = &(fields[count]);
69 field->tag = g_strdup(tag);
70 field->size = size;
71 field->method = method;
72 field->flags = flags;
73 field->value = value;
74 field->type = type;
76 /* Null terminate the field array */
77 field = &((fields)[count + 1]);
78 field->tag = NULL;
79 field->value = 0;
80 field->ptr_value = NULL;
82 return fields;
85 NMField *
86 nm_field_add_pointer(NMField * fields, const char *tag, guint32 size, guint8 method,
87 guint8 flags, gpointer value, guint8 type)
89 guint32 count;
90 NMField *field = NULL;
92 count = nm_count_fields(fields);
93 fields = _add_blank_field(fields, count);
95 field = &(fields[count]);
96 field->tag = g_strdup(tag);
97 field->size = size;
98 field->method = method;
99 field->flags = flags;
100 field->ptr_value = value;
101 field->type = type;
103 /* Null terminate the field array */
104 field = &((fields)[count + 1]);
105 field->tag = NULL;
106 field->value = 0;
107 field->ptr_value = NULL;
109 return fields;
112 guint32
113 nm_count_fields(NMField * fields)
115 guint32 count = 0;
117 if (fields) {
118 while (fields->tag != NULL) {
119 count++;
120 fields++;
124 return count;
127 void
128 nm_free_fields(NMField ** fields)
130 NMField *field = NULL;
132 if ((fields == NULL) || (*fields == NULL))
133 return;
135 field = *fields;
137 while (field->tag != NULL) {
138 _free_field(field);
139 field++;
142 g_free(*fields);
143 *fields = NULL;
147 static void
148 _free_field(NMField * field)
150 if (field == NULL)
151 return;
153 _free_field_value(field);
154 g_free(field->tag);
157 static void
158 _free_field_value(NMField * field)
160 if (field == NULL)
161 return;
163 switch (field->type) {
164 case NMFIELD_TYPE_BINARY:
165 case NMFIELD_TYPE_UTF8:
166 case NMFIELD_TYPE_DN:
167 g_free(field->ptr_value);
168 break;
170 case NMFIELD_TYPE_ARRAY:
171 case NMFIELD_TYPE_MV:
172 nm_free_fields((NMField **)&field->ptr_value);
173 break;
175 default:
176 break;
179 field->size = 0;
180 field->ptr_value = NULL;
183 NMField *
184 nm_locate_field(char *tag, NMField * fields)
186 NMField *ret_fields = NULL;
188 if ((fields == NULL) || (tag == NULL)) {
189 return NULL;
192 while (fields->tag != NULL) {
193 if (g_ascii_strcasecmp(fields->tag, tag) == 0) {
194 ret_fields = fields;
195 break;
197 fields++;
200 return ret_fields;
203 NMField *
204 nm_copy_field_array(NMField * src)
206 NMField *ptr = NULL;
207 NMField *dest = NULL;
208 int count;
210 if (src != NULL) {
211 count = nm_count_fields(src) + 1;
212 dest = g_new0(NMField, count);
213 dest->len = count;
214 ptr = dest;
215 while (src->tag != NULL) {
216 _copy_field(ptr, src);
217 ptr++;
218 src++;
222 return dest;
225 static void
226 _copy_field(NMField * dest, NMField * src)
228 dest->type = src->type;
229 dest->flags = src->flags;
230 dest->method = src->method;
231 dest->tag = g_strdup(src->tag);
232 _copy_field_value(dest, src);
235 static void
236 _copy_field_value(NMField * dest, NMField * src)
238 dest->type = src->type;
239 switch (dest->type) {
240 case NMFIELD_TYPE_UTF8:
241 case NMFIELD_TYPE_DN:
242 if (src->size == 0 && src->ptr_value != NULL) {
243 src->size = strlen((char *) src->ptr_value) + 1;
245 /* fall through */
246 case NMFIELD_TYPE_BINARY:
247 if (src->size != 0 && src->ptr_value != NULL) {
248 dest->ptr_value = g_new0(char, src->size);
249 memcpy(dest->ptr_value, src->ptr_value, src->size);
251 break;
253 case NMFIELD_TYPE_ARRAY:
254 case NMFIELD_TYPE_MV:
255 dest->ptr_value = nm_copy_field_array((NMField *)src->ptr_value);
256 break;
258 default:
259 /* numeric value */
260 dest->value = src->value;
261 break;
264 dest->size = src->size;
267 void
268 nm_remove_field(NMField * field)
270 NMField *tmp;
271 guint32 len;
273 if ((field != NULL) && (field->tag != NULL)) {
274 _free_field(field);
276 /* Move fields down */
277 tmp = field + 1;
278 while (1) {
279 /* Don't overwrite the size of the array */
280 len = field->len;
282 *field = *tmp;
284 field->len = len;
286 if (tmp->tag == NULL)
287 break;
289 field++;
290 tmp++;
295 void
296 nm_print_fields(NMField * fields)
298 char *str = NULL;
299 NMField *field = fields;
301 if (fields == NULL)
302 return;
304 while (field->tag != NULL) {
305 if (field->type == NMFIELD_TYPE_ARRAY || field->type == NMFIELD_TYPE_MV) {
306 printf("Subarray START: %s Method = %d\n", field->tag, field->method);
307 nm_print_fields((NMField *) field->ptr_value);
308 printf("Subarray END: %s\n", field->tag);
309 } else {
310 str = _value_to_string(field);
311 printf("Tag=%s;Value=%s\n", field->tag, str);
312 g_free(str);
313 str = NULL;
315 field++;
320 static char *
321 _value_to_string(NMField * field)
323 char *value = NULL;
325 if (field == NULL)
326 return NULL;
328 /* This is a single value attribute */
329 if (((field->type == NMFIELD_TYPE_UTF8) ||
330 (field->type == NMFIELD_TYPE_DN)) && (field->ptr_value != NULL)) {
331 value = g_strdup((const char *) field->ptr_value);
332 } else if (field->type == NMFIELD_TYPE_BINARY && field->ptr_value != NULL) {
333 value = g_new0(char, field->size);
334 memcpy(value, (const char *) field->ptr_value, field->size);
335 } else if (field->type == NMFIELD_TYPE_BOOL) {
336 if (field->value) {
337 value = g_strdup(NM_FIELD_TRUE);
338 } else {
339 value = g_strdup(NM_FIELD_FALSE);
341 } else {
342 /* assume it is a number */
343 switch (field->type) {
344 case NMFIELD_TYPE_BYTE:
345 case NMFIELD_TYPE_WORD:
346 case NMFIELD_TYPE_DWORD:
347 value = g_strdup_printf("%ld", (long) field->value);
348 break;
350 case NMFIELD_TYPE_UBYTE:
351 case NMFIELD_TYPE_UWORD:
352 case NMFIELD_TYPE_UDWORD:
353 value = g_strdup_printf("%lu", (unsigned long) field->value);
354 break;
358 if (value == NULL)
359 value = g_strdup("NULL");
361 return value;