1. Replaced the innards of an osrfStringArray to include an
[OpenSRF.git] / src / libopensrf / string_array.c
1 #include <opensrf/string_array.h>
2
3 osrfStringArray* osrfNewStringArray(int size) {
4         if(size > STRING_ARRAY_MAX_SIZE)
5                 osrfLogError( OSRF_LOG_MARK, "osrfNewStringArray size is too large");
6
7         osrfStringArray* arr;
8         OSRF_MALLOC(arr, sizeof(osrfStringArray));
9         arr->size = 0;
10
11         // Initialize list
12         arr->list.size = 0;
13         arr->list.freeItem = NULL;
14         if( size <= 0 )
15                 arr->list.arrsize = 16;
16         else
17                 arr->list.arrsize = size;
18         OSRF_MALLOC( arr->list.arrlist, arr->list.arrsize * sizeof(void*) );
19
20         // Nullify all pointers in the array
21
22         int i;
23         for( i = 0; i < arr->list.arrsize; ++i )
24                 arr->list.arrlist[ i ] = NULL;
25
26         osrfListSetDefaultFree(&arr->list);
27         return arr;
28 }
29
30 void osrfStringArrayAdd( osrfStringArray* arr, const char* string ) {
31         if(arr == NULL || string == NULL ) return;
32         if( arr->list.size > STRING_ARRAY_MAX_SIZE )
33                 osrfLogError( OSRF_LOG_MARK, "osrfStringArrayAdd size is too large" );
34     osrfListPush(&arr->list, strdup(string));
35     arr->size = arr->list.size;
36 }
37
38 char* osrfStringArrayGetString( osrfStringArray* arr, int index ) {
39     if(!arr) return NULL;
40         return OSRF_LIST_GET_INDEX(&arr->list, index);
41 }
42
43 void osrfStringArrayFree(osrfStringArray* arr) {
44
45         // This function is a sleazy hack designed to avoid the
46         // need to duplicate the code in osrfListFree().  It
47         // works because:
48         //
49         // 1. The osrfList is the first member of an
50         //    osrfStringArray.  C guarantees that a pointer
51         //    to the one is also a pointer to the other.
52         //
53         // 2. The rest of the osrfStringArray owns no memory
54         //    and requires no special attention when freeing.
55         //
56         // If these facts ever cease to be true, we'll have to
57         // revisit this function.
58         
59         osrfListFree( (osrfList*) arr );
60 }
61
62 int osrfStringArrayContains(
63         const osrfStringArray* arr, const char* string ) {
64         if(!(arr && string)) return 0;
65         int i;
66         for( i = 0; i < arr->size; i++ ) {
67         char* str = OSRF_LIST_GET_INDEX(&arr->list, i);
68                 if(str && !strcmp(str, string)) 
69             return 1;
70         }
71
72         return 0;
73 }
74
75 void osrfStringArrayRemove( osrfStringArray* arr, const char* tstr ) {
76         if(!(arr && tstr)) return;
77         int i;
78     char* str;
79
80         for( i = 0; i < arr->size; i++ ) {
81         /* find and remove the string */
82         str = OSRF_LIST_GET_INDEX(&arr->list, i);
83                 if(str && !strcmp(str, tstr)) {
84             osrfListRemove(&arr->list, i);
85                         break;
86                 }
87         }
88
89     /* disable automatic item freeing on delete and shift
90      * items up in the array to fill in the gap
91      */
92     arr->list.freeItem = NULL;
93         for( ; i < arr->size - 1; i++ ) 
94         osrfListSet(&arr->list, OSRF_LIST_GET_INDEX(&arr->list, i+1), i);
95
96     /* remove the last item since it was shifted up */
97     osrfListRemove(&arr->list, i);
98
99     /* re-enable automatic item freeing in delete */
100     osrfListSetDefaultFree(&arr->list);
101         arr->size--;
102 }