Mercurial > pidgin
annotate src/protocols/novell/nmfield.c @ 10462:f7b32dd67bdf
[gaim-migrate @ 11735]
Fix for bug 1027454: Blank "Unable to open socket" window if locale is not UTF-8
committer: Tailor Script <tailor@pidgin.im>
| author | Stu Tomlinson <stu@nosnilmot.com> |
|---|---|
| date | Fri, 31 Dec 2004 15:34:18 +0000 |
| parents | 6663ad2386d9 |
| children |
| rev | line source |
|---|---|
| 8675 | 1 /* |
| 2 * nmfield.c | |
| 3 * | |
| 8933 | 4 * Copyright (c) 2004 Novell, Inc. All Rights Reserved. |
| 5 * | |
| 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. | |
| 8675 | 9 * |
| 8933 | 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. | |
|
8684
046dd8ef2920
[gaim-migrate @ 9437]
Christian Hammond <chipx86@chipx86.com>
parents:
8675
diff
changeset
|
14 * |
| 8933 | 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
| 8675 | 18 * |
| 19 */ | |
| 20 | |
| 21 #include <string.h> | |
| 22 #include <stdio.h> | |
| 23 #include "nmfield.h" | |
| 24 | |
| 25 /* Free a field value and tag */ | |
| 26 static void _free_field(NMField * field); | |
| 27 | |
| 28 /* Free a field value */ | |
| 29 static void _free_field_value(NMField * field); | |
| 30 | |
| 31 /* Make a deep copy of the field */ | |
| 32 static void _copy_field(NMField * dest, NMField * src); | |
| 33 | |
| 34 /* Make a deep copy of the field's value */ | |
| 35 static void _copy_field_value(NMField * dest, NMField * src); | |
| 36 | |
| 37 /* Create a string from a value -- for debugging */ | |
| 38 static char *_value_to_string(NMField * field); | |
| 39 | |
| 8933 | 40 static NMField * |
| 41 _add_blank_field(NMField *fields, guint32 count) | |
| 8675 | 42 { |
| 8933 | 43 guint32 new_len; |
| 8675 | 44 |
| 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; | |
| 53 } | |
| 54 } | |
| 8933 | 55 return fields; |
| 56 } | |
| 57 | |
| 58 NMField * | |
| 59 nm_field_add_number(NMField * fields, const char *tag, guint32 size, guint8 method, | |
| 60 guint8 flags, guint32 value, guint8 type) | |
| 61 { | |
| 62 guint32 count; | |
| 63 NMField *field; | |
| 64 | |
| 65 count = nm_count_fields(fields); | |
| 66 fields = _add_blank_field(fields, count); | |
| 8675 | 67 |
| 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; | |
| 75 | |
| 76 /* Null terminate the field array */ | |
| 77 field = &((fields)[count + 1]); | |
| 78 field->tag = NULL; | |
| 79 field->value = 0; | |
| 8933 | 80 field->ptr_value = NULL; |
| 81 | |
| 82 return fields; | |
| 83 } | |
| 84 | |
| 85 NMField * | |
| 86 nm_field_add_pointer(NMField * fields, const char *tag, guint32 size, guint8 method, | |
| 87 guint8 flags, gpointer value, guint8 type) | |
| 88 { | |
| 89 guint32 count; | |
| 90 NMField *field = NULL; | |
| 91 | |
| 92 count = nm_count_fields(fields); | |
| 93 fields = _add_blank_field(fields, count); | |
| 94 | |
| 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; | |
| 102 | |
| 103 /* Null terminate the field array */ | |
| 104 field = &((fields)[count + 1]); | |
| 105 field->tag = NULL; | |
| 106 field->value = 0; | |
| 107 field->ptr_value = NULL; | |
| 8675 | 108 |
| 109 return fields; | |
| 110 } | |
| 111 | |
| 112 guint32 | |
| 113 nm_count_fields(NMField * fields) | |
| 114 { | |
| 115 guint32 count = 0; | |
| 116 | |
| 117 if (fields) { | |
| 118 while (fields->tag != NULL) { | |
| 119 count++; | |
| 120 fields++; | |
| 121 } | |
| 122 } | |
| 123 | |
| 124 return count; | |
| 125 } | |
| 126 | |
| 127 void | |
| 128 nm_free_fields(NMField ** fields) | |
| 129 { | |
| 130 NMField *field = NULL; | |
| 131 | |
| 132 if ((fields == NULL) || (*fields == NULL)) | |
| 133 return; | |
| 134 | |
| 135 field = *fields; | |
| 136 | |
| 137 while (field->tag != NULL) { | |
| 138 _free_field(field); | |
| 139 field++; | |
| 140 } | |
| 141 | |
| 142 g_free(*fields); | |
| 143 *fields = NULL; | |
| 144 } | |
| 145 | |
| 146 | |
| 147 static void | |
| 148 _free_field(NMField * field) | |
| 149 { | |
| 150 if (field == NULL) | |
| 151 return; | |
| 152 | |
| 153 _free_field_value(field); | |
| 154 g_free(field->tag); | |
| 155 } | |
| 156 | |
| 157 static void | |
| 158 _free_field_value(NMField * field) | |
| 159 { | |
| 160 if (field == NULL) | |
| 161 return; | |
| 162 | |
| 163 switch (field->type) { | |
| 8933 | 164 case NMFIELD_TYPE_BINARY: |
| 165 case NMFIELD_TYPE_UTF8: | |
| 166 case NMFIELD_TYPE_DN: | |
| 167 if (field->ptr_value != NULL) { | |
| 168 g_free(field->ptr_value); | |
| 169 } | |
| 170 break; | |
| 8675 | 171 |
| 8933 | 172 case NMFIELD_TYPE_ARRAY: |
| 173 case NMFIELD_TYPE_MV: | |
| 174 nm_free_fields((NMField **)&field->ptr_value); | |
| 175 break; | |
| 8675 | 176 |
| 8933 | 177 default: |
| 178 break; | |
| 8675 | 179 } |
| 180 | |
| 181 field->size = 0; | |
| 8933 | 182 field->ptr_value = NULL; |
| 8675 | 183 } |
| 184 | |
| 185 NMField * | |
| 186 nm_locate_field(char *tag, NMField * fields) | |
| 187 { | |
| 188 NMField *ret_fields = NULL; | |
| 189 | |
| 190 if ((fields == NULL) || (tag == NULL)) { | |
| 191 return NULL; | |
| 192 } | |
| 193 | |
| 194 while (fields->tag != NULL) { | |
| 195 if (g_ascii_strcasecmp(fields->tag, tag) == 0) { | |
| 196 ret_fields = fields; | |
| 197 break; | |
| 198 } | |
| 199 fields++; | |
| 200 } | |
| 201 | |
| 202 return ret_fields; | |
| 203 } | |
| 204 | |
| 205 NMField * | |
| 206 nm_copy_field_array(NMField * src) | |
| 207 { | |
| 208 NMField *ptr = NULL; | |
| 209 NMField *dest = NULL; | |
| 210 int count; | |
| 211 | |
| 212 if (src != NULL) { | |
| 213 count = nm_count_fields(src) + 1; | |
| 214 dest = g_new0(NMField, count); | |
| 215 dest->len = count; | |
| 216 ptr = dest; | |
| 217 while (src->tag != NULL) { | |
| 218 _copy_field(ptr, src); | |
| 219 ptr++; | |
| 220 src++; | |
| 221 } | |
| 222 } | |
| 223 | |
| 224 return dest; | |
| 225 } | |
| 226 | |
| 227 static void | |
| 228 _copy_field(NMField * dest, NMField * src) | |
| 229 { | |
| 230 dest->type = src->type; | |
| 231 dest->flags = src->flags; | |
| 232 dest->method = src->method; | |
| 233 dest->tag = g_strdup(src->tag); | |
| 234 _copy_field_value(dest, src); | |
| 235 } | |
| 236 | |
| 237 static void | |
| 238 _copy_field_value(NMField * dest, NMField * src) | |
| 239 { | |
| 240 dest->type = src->type; | |
| 241 switch (dest->type) { | |
| 8933 | 242 case NMFIELD_TYPE_UTF8: |
| 243 case NMFIELD_TYPE_DN: | |
| 244 if (src->size == 0 && src->ptr_value != NULL) { | |
| 245 src->size = strlen((char *) src->ptr_value) + 1; | |
| 246 } | |
| 247 /* fall through */ | |
| 248 case NMFIELD_TYPE_BINARY: | |
| 249 if (src->size != 0 && src->ptr_value != NULL) { | |
| 250 dest->ptr_value = g_new0(char, src->size); | |
| 251 memcpy(dest->ptr_value, src->ptr_value, src->size); | |
| 252 } | |
| 253 break; | |
| 8675 | 254 |
| 8933 | 255 case NMFIELD_TYPE_ARRAY: |
| 256 case NMFIELD_TYPE_MV: | |
| 257 dest->ptr_value = nm_copy_field_array((NMField *)src->ptr_value); | |
| 258 break; | |
| 8675 | 259 |
| 8933 | 260 default: |
| 261 /* numeric value */ | |
| 262 dest->value = src->value; | |
| 263 break; | |
| 8675 | 264 } |
| 265 | |
| 266 dest->size = src->size; | |
| 267 } | |
| 268 | |
| 269 void | |
| 270 nm_remove_field(NMField * field) | |
| 271 { | |
| 272 NMField *tmp; | |
| 273 guint32 len; | |
| 274 | |
| 275 if ((field != NULL) && (field->tag != NULL)) { | |
| 276 _free_field(field); | |
| 277 | |
| 278 /* Move fields down */ | |
| 279 tmp = field + 1; | |
| 280 while (1) { | |
| 281 /* Don't overwrite the size of the array */ | |
| 282 len = field->len; | |
| 283 | |
| 284 *field = *tmp; | |
| 285 | |
| 286 field->len = len; | |
| 287 | |
| 288 if (tmp->tag == NULL) | |
| 289 break; | |
| 290 | |
| 291 field++; | |
| 292 tmp++; | |
| 293 } | |
| 294 } | |
| 295 } | |
| 296 | |
| 297 void | |
| 298 nm_print_fields(NMField * fields) | |
| 299 { | |
| 300 char *str = NULL; | |
| 301 NMField *field = fields; | |
| 302 | |
| 303 if (fields == NULL) | |
| 304 return; | |
| 305 | |
| 306 while (field->tag != NULL) { | |
| 307 if (field->type == NMFIELD_TYPE_ARRAY || field->type == NMFIELD_TYPE_MV) { | |
| 308 printf("Subarray START: %s Method = %d\n", field->tag, field->method); | |
| 8933 | 309 nm_print_fields((NMField *) field->ptr_value); |
| 8675 | 310 printf("Subarray END: %s\n", field->tag); |
| 311 } else { | |
| 312 str = _value_to_string(field); | |
| 313 printf("Tag=%s;Value=%s\n", field->tag, str); | |
| 314 g_free(str); | |
| 315 str = NULL; | |
| 316 } | |
| 317 field++; | |
| 318 } | |
| 319 | |
| 320 } | |
| 321 | |
| 322 static char * | |
| 323 _value_to_string(NMField * field) | |
| 324 { | |
| 325 char *value = NULL; | |
| 326 | |
| 327 if (field == NULL) | |
| 328 return NULL; | |
| 329 | |
| 330 /* This is a single value attribute */ | |
| 331 if (((field->type == NMFIELD_TYPE_UTF8) || | |
| 8933 | 332 (field->type == NMFIELD_TYPE_DN)) && (field->ptr_value != NULL)) { |
| 333 value = g_strdup((const char *) field->ptr_value); | |
| 334 } else if (field->type == NMFIELD_TYPE_BINARY && field->ptr_value != NULL) { | |
| 8675 | 335 value = g_new0(char, field->size); |
| 8933 | 336 memcpy(value, (const char *) field->ptr_value, field->size); |
| 8675 | 337 } else if (field->type == NMFIELD_TYPE_BOOL) { |
| 338 if (field->value) { | |
| 339 value = g_strdup(NM_FIELD_TRUE); | |
| 340 } else { | |
| 341 value = g_strdup(NM_FIELD_FALSE); | |
| 342 } | |
| 343 } else { | |
| 344 /* assume it is a number */ | |
| 345 value = g_new0(char, 20); | |
| 346 | |
| 347 switch (field->type) { | |
| 348 case NMFIELD_TYPE_BYTE: | |
| 349 case NMFIELD_TYPE_WORD: | |
| 350 case NMFIELD_TYPE_DWORD: | |
| 351 value = g_strdup_printf("%ld", (long) field->value); | |
| 352 break; | |
| 353 | |
| 354 case NMFIELD_TYPE_UBYTE: | |
| 355 case NMFIELD_TYPE_UWORD: | |
| 356 case NMFIELD_TYPE_UDWORD: | |
| 357 value = g_strdup_printf("%lu", (unsigned long) field->value); | |
| 358 break; | |
| 359 } | |
| 360 } | |
| 361 | |
| 362 if (value == NULL) | |
| 363 value = g_strdup("NULL"); | |
| 364 | |
| 365 return value; | |
| 366 } |
