/* * Copyright (c) 2001-2002 Apple Inc. All rights reserved. * * @APPLE_LICENSE_HEADER_START@ * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in * compliance with the License. Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ /* * Modification History * * November 13, 2001 Dieter Siegmund * - created */ #include #include #include #include #include #include "KeyValue.h" typedef struct KeyValue_s KeyValue; struct KeyValue_s { char * key; char * value; }; struct KeyValueList_s { KeyValue * elements; int count; char * str; }; void KeyValueList_print(KeyValueList * list) { int i; if (list == NULL) { return; } for (i = 0; i < list->count; i++) { printf("%2d. %10s=%-10s\n", i, list->elements[i].key, list->elements[i].value); } return; } char * KeyValueList_find(KeyValueList * list, char * key, int * where) { int i; int start = 0; if (where) { if (*where > 0) { start = *where; } } for (i = start; i < list->count; i++) { if (strcmp(list->elements[i].key, key) == 0) { if (where) { *where = i; } return (list->elements[i].value); } } return (NULL); } void KeyValueList_free(KeyValueList * * list_p) { KeyValueList * list = *list_p; if (list) { void * chunk; if (list->str) { free(list->str); list->str = NULL; } /* Note: "list" is part of the same malloc chunk as "list->elements" */ chunk = list->elements; if (chunk) { list->elements = NULL; free(chunk); } *list_p = NULL; } return; } KeyValueList * KeyValueList_create(void * buf, int buflen) { int count = 0; KeyValue * elements = NULL; size_t n; KeyValueList * ret = NULL; char * scan; int size = 4; char * str = NULL; str = malloc(buflen + 1); if (str == NULL) { goto failed; } bcopy(buf, str, buflen); str[buflen] = '\0'; elements = malloc(sizeof(*elements) * size + sizeof(*ret)); if (elements == NULL) { goto failed; } for (scan = str; *scan != '\0'; scan++) { size_t nval; char * start = scan; n = strcspn(scan, ","); if (n == 0) { continue; } scan[n] = '\0'; scan += n; nval = strcspn(start, "="); if (nval == 0) { continue; } if (count == size) { size *= 2; elements = realloc(elements, sizeof(*elements) * size + sizeof(*ret)); if (elements == NULL) { goto failed; } } elements[count].key = start; if (start[nval] == '\0') { elements[count].value = start + nval; } else { start[nval] = '\0'; elements[count].value = start + nval + 1; } count++; } if (count == 0) { goto failed; } if (count != size) { elements = realloc(elements, sizeof(*elements) * count + sizeof(*ret)); if (elements == NULL) goto failed; } ret = (KeyValueList *)(elements + count); ret->elements = elements; ret->count = count; ret->str = str; return (ret); failed: if (elements) { free(elements); } if (str) { free(str); } return (NULL); } #ifdef TEST_KEYVALUE int main(int argc, char * argv[]) { char * tests[] = { "this=that,this=,other=,,=nothing,", "this=that", ",this=that", "one=1,two=2,three=3,four=4,five=5,six=6,seven=7", "networkid=Microsoft.com,networkid=exchange.Microsoft.com,foo=bar", "testing", "networkid=Microsoft.com,networkid=exchange.Microsoft.com,foo=bar", "", NULL, }; KeyValueList * list; char * * scan = tests; for (scan = tests; *scan; scan++) { printf("Input '%s'\n", *scan); list = KeyValueList_create(*scan, strlen(*scan)); if (list) { KeyValueList_print(list); } printf("\n"); KeyValueList_free(&list); } exit(0); return (0); } #endif /* TEST_KEYVALUE */