1. Create a new osrfListExtract function, which removes an item
[OpenSRF.git] / src / libopensrf / osrf_list.c
1 #include <opensrf/osrf_list.h>
2
3 #define OSRF_LIST_DEFAULT_SIZE 48 /* most opensrf lists are small... */
4 #define OSRF_LIST_INC_SIZE 256
5 //#define OSRF_LIST_MAX_SIZE 10240
6
7 osrfList* osrfNewList() {
8         return osrfNewListSize( OSRF_LIST_DEFAULT_SIZE );
9 }
10
11 osrfList* osrfNewListSize( unsigned int size ) {
12         osrfList* list;
13         OSRF_MALLOC(list, sizeof(osrfList));
14         list->size = 0;
15         list->freeItem = NULL;
16     if( size <= 0 ) size = 16;
17         list->arrsize   = size;
18         OSRF_MALLOC( list->arrlist, list->arrsize * sizeof(void*) );
19
20         // Nullify all pointers in the array
21
22         int i;
23         for( i = 0; i < list->arrsize; ++i )
24                 list->arrlist[ i ] = NULL;
25         
26         return list;
27 }
28
29
30 int osrfListPush( osrfList* list, void* item ) {
31         if(!(list)) return -1;
32         osrfListSet( list, item, list->size );
33         return 0;
34 }
35
36 int osrfListPushFirst( osrfList* list, void* item ) {
37         if(!(list && item)) return -1;
38         int i;
39         for( i = 0; i < list->size; i++ ) 
40                 if(!list->arrlist[i]) break;
41         osrfListSet( list, item, i );
42         return list->size;
43 }
44
45 void* osrfListSet( osrfList* list, void* item, unsigned int position ) {
46         if(!list || position < 0) return NULL;
47
48         int newsize = list->arrsize;
49
50         while( position >= newsize ) 
51                 newsize += OSRF_LIST_INC_SIZE;
52
53         if( newsize > list->arrsize ) { /* expand the list if necessary */
54                 void** newarr;
55                 OSRF_MALLOC(newarr, newsize * sizeof(void*));
56
57                 // Copy the old pointers, and nullify the new ones
58                 
59                 int i;
60                 for( i = 0; i < list->arrsize; i++ )
61                         newarr[i] = list->arrlist[i];
62                 for( ; i < newsize; i++ )
63                         newarr[i] = NULL;
64                 free(list->arrlist);
65                 list->arrlist = newarr;
66                 list->arrsize = newsize;
67         }
68
69         void* olditem = osrfListRemove( list, position );
70         list->arrlist[position] = item;
71         if( list->size <= position ) list->size = position + 1;
72         return olditem;
73 }
74
75
76 void* osrfListGetIndex( const osrfList* list, unsigned int position ) {
77         if(!list || position >= list->size || position < 0) return NULL;
78         return list->arrlist[position];
79 }
80
81 void osrfListFree( osrfList* list ) {
82         if(!list) return;
83
84         if( list->freeItem ) {
85                 int i; void* val;
86                 for( i = 0; i < list->size; i++ ) {
87                         if( (val = list->arrlist[i]) ) 
88                                 list->freeItem(val);
89                 }
90         }
91
92         free(list->arrlist);
93         free(list);
94 }
95
96 void* osrfListRemove( osrfList* list, unsigned int position ) {
97         if(!list || position >= list->size || position < 0) return NULL;
98
99         void* olditem = list->arrlist[position];
100         list->arrlist[position] = NULL;
101         if( list->freeItem ) {
102                 list->freeItem(olditem);
103                 olditem = NULL;
104         }
105
106         if( position == list->size - 1 ) list->size--;
107         return olditem;
108 }
109
110 void* osrfListExtract( osrfList* list, unsigned int position ) {
111         if(!list || position >= list->size || position < 0) return NULL;
112
113         void* olditem = list->arrlist[position];
114         list->arrlist[position] = NULL;
115
116         if( position == list->size - 1 ) list->size--;
117         return olditem;
118 }
119
120
121 int osrfListFind( const osrfList* list, void* addr ) {
122         if(!(list && addr)) return -1;
123         int index;
124         for( index = 0; index < list->size; index++ ) {
125                 if( list->arrlist[index] == addr ) 
126                         return index;
127         }
128         return -1;
129 }
130
131
132 unsigned int osrfListGetCount( const osrfList* list ) {
133         if(!list) return -1;
134         return list->size;
135 }
136
137
138 void* osrfListPop( osrfList* list ) {
139         if(!list) return NULL;
140         return osrfListRemove( list, list->size - 1 );
141 }
142
143
144 osrfListIterator* osrfNewListIterator( const osrfList* list ) {
145         if(!list) return NULL;
146         osrfListIterator* itr;
147         OSRF_MALLOC(itr, sizeof(osrfListIterator));
148         itr->list = list;
149         itr->current = 0;
150         return itr;
151 }
152
153 void* osrfListIteratorNext( osrfListIterator* itr ) {
154         if(!(itr && itr->list)) return NULL;
155         if(itr->current >= itr->list->size) return NULL;
156         return itr->list->arrlist[itr->current++];
157 }
158
159 void osrfListIteratorFree( osrfListIterator* itr ) {
160         if(!itr) return;
161         free(itr);
162 }
163
164
165 void osrfListIteratorReset( osrfListIterator* itr ) {
166         if(!itr) return;
167         itr->current = 0;
168 }
169
170
171 void osrfListVanillaFree( void* item ) {
172         free(item);
173 }
174
175 void osrfListSetDefaultFree( osrfList* list ) {
176         if(!list) return;
177         list->freeItem = osrfListVanillaFree;
178 }