From 66b1ca3cbae357abb95b4a31bba1d93072762c97 Mon Sep 17 00:00:00 2001 From: scottmk Date: Mon, 12 Jan 2009 05:35:10 +0000 Subject: [PATCH] 1. Replaced the innards of an osrfStringArray to include an osrfList instead of a pointer to an osrfList. This change eliminates a layer of malloc and free when creating and destroying an osrfStringArray. It also eliminates a layer of indirection when performing other operations. 2. Eliminated the prototype for string_array_get_total_size(), since no such function exists. 3. Added the const qualifier to various function parameters. git-svn-id: svn://svn.open-ils.org/OpenSRF/trunk@1617 9efc2488-bf62-4759-914b-345cdb29e865 --- include/opensrf/string_array.h | 29 ++++++------- src/libopensrf/string_array.c | 76 +++++++++++++++++++++++----------- 2 files changed, 64 insertions(+), 41 deletions(-) diff --git a/include/opensrf/string_array.h b/include/opensrf/string_array.h index 0df884d..89d9f32 100644 --- a/include/opensrf/string_array.h +++ b/include/opensrf/string_array.h @@ -13,31 +13,26 @@ extern "C" { #define STRING_ARRAY_MAX_SIZE 4096 -#define OSRF_STRING_ARRAY_FREE(arr)\ - if(arr) {osrfListFree(arr->list); free(arr);} - +#define OSRF_STRING_ARRAY_FREE(arr) osrfListFree( (osrfList*) (arr) ) -struct string_array_struct { - osrfList* list; - int size; -}; -typedef struct string_array_struct osrfStringArray; +typedef struct { + osrfList list; + int size; // redundant with osrfList.size +} osrfStringArray; -osrfStringArray* osrfNewStringArray(int size); +osrfStringArray* osrfNewStringArray( int size ); -void osrfStringArrayAdd(osrfStringArray*, char* str); +void osrfStringArrayAdd( osrfStringArray*, const char* str ); -char* osrfStringArrayGetString(osrfStringArray* arr, int index); +char* osrfStringArrayGetString( osrfStringArray* arr, int index ); /* returns true if this array contains the given string */ -int osrfStringArrayContains( osrfStringArray* arr, char* string ); +int osrfStringArrayContains( + const osrfStringArray* arr, const char* string ); -void osrfStringArrayFree(osrfStringArray*); +void osrfStringArrayFree( osrfStringArray* ); -/* total size of all included strings */ -int string_array_get_total_size(osrfStringArray* arr); - -void osrfStringArrayRemove( osrfStringArray* arr, char* str); +void osrfStringArrayRemove( osrfStringArray* arr, const char* str ); #ifdef __cplusplus } diff --git a/src/libopensrf/string_array.c b/src/libopensrf/string_array.c index af3262d..d44491d 100644 --- a/src/libopensrf/string_array.c +++ b/src/libopensrf/string_array.c @@ -5,36 +5,66 @@ osrfStringArray* osrfNewStringArray(int size) { osrfLogError( OSRF_LOG_MARK, "osrfNewStringArray size is too large"); osrfStringArray* arr; - OSRF_MALLOC( arr, sizeof(osrfStringArray)); - arr->list = osrfNewListSize(size); - osrfListSetDefaultFree(arr->list); + OSRF_MALLOC(arr, sizeof(osrfStringArray)); arr->size = 0; + + // Initialize list + arr->list.size = 0; + arr->list.freeItem = NULL; + if( size <= 0 ) + arr->list.arrsize = 16; + else + arr->list.arrsize = size; + OSRF_MALLOC( arr->list.arrlist, arr->list.arrsize * sizeof(void*) ); + + // Nullify all pointers in the array + + int i; + for( i = 0; i < arr->list.arrsize; ++i ) + arr->list.arrlist[ i ] = NULL; + + osrfListSetDefaultFree(&arr->list); return arr; } - -void osrfStringArrayAdd(osrfStringArray* arr, char* str) { - if(arr == NULL || str == NULL ) return; - if( arr->size > STRING_ARRAY_MAX_SIZE ) - osrfLogError( OSRF_LOG_MARK, "osrfStringArrayAdd size is too large"); - osrfListPush(arr->list, strdup(str)); - arr->size = arr->list->size; +void osrfStringArrayAdd( osrfStringArray* arr, const char* string ) { + if(arr == NULL || string == NULL ) return; + if( arr->list.size > STRING_ARRAY_MAX_SIZE ) + osrfLogError( OSRF_LOG_MARK, "osrfStringArrayAdd size is too large" ); + osrfListPush(&arr->list, strdup(string)); + arr->size = arr->list.size; } -char* osrfStringArrayGetString(osrfStringArray* arr, int index) { +char* osrfStringArrayGetString( osrfStringArray* arr, int index ) { if(!arr) return NULL; - return OSRF_LIST_GET_INDEX(arr->list, index); + return OSRF_LIST_GET_INDEX(&arr->list, index); } void osrfStringArrayFree(osrfStringArray* arr) { - OSRF_STRING_ARRAY_FREE(arr); + + // This function is a sleazy hack designed to avoid the + // need to duplicate the code in osrfListFree(). It + // works because: + // + // 1. The osrfList is the first member of an + // osrfStringArray. C guarantees that a pointer + // to the one is also a pointer to the other. + // + // 2. The rest of the osrfStringArray owns no memory + // and requires no special attention when freeing. + // + // If these facts ever cease to be true, we'll have to + // revisit this function. + + osrfListFree( (osrfList*) arr ); } -int osrfStringArrayContains( osrfStringArray* arr, char* string ) { +int osrfStringArrayContains( + const osrfStringArray* arr, const char* string ) { if(!(arr && string)) return 0; int i; for( i = 0; i < arr->size; i++ ) { - char* str = OSRF_LIST_GET_INDEX(arr->list, i); + char* str = OSRF_LIST_GET_INDEX(&arr->list, i); if(str && !strcmp(str, string)) return 1; } @@ -42,16 +72,16 @@ int osrfStringArrayContains( osrfStringArray* arr, char* string ) { return 0; } -void osrfStringArrayRemove( osrfStringArray* arr, char* tstr) { +void osrfStringArrayRemove( osrfStringArray* arr, const char* tstr ) { if(!(arr && tstr)) return; int i; char* str; for( i = 0; i < arr->size; i++ ) { /* find and remove the string */ - str = OSRF_LIST_GET_INDEX(arr->list, i); + str = OSRF_LIST_GET_INDEX(&arr->list, i); if(str && !strcmp(str, tstr)) { - osrfListRemove(arr->list, i); + osrfListRemove(&arr->list, i); break; } } @@ -59,16 +89,14 @@ void osrfStringArrayRemove( osrfStringArray* arr, char* tstr) { /* disable automatic item freeing on delete and shift * items up in the array to fill in the gap */ - arr->list->freeItem = NULL; + arr->list.freeItem = NULL; for( ; i < arr->size - 1; i++ ) - osrfListSet(arr->list, OSRF_LIST_GET_INDEX(arr->list, i+1) , i); + osrfListSet(&arr->list, OSRF_LIST_GET_INDEX(&arr->list, i+1), i); /* remove the last item since it was shifted up */ - osrfListRemove(arr->list, i); + osrfListRemove(&arr->list, i); /* re-enable automatic item freeing in delete */ - osrfListSetDefaultFree(arr->list); + osrfListSetDefaultFree(&arr->list); arr->size--; } - - -- 2.43.2