]> git.evergreen-ils.org Git - OpenSRF.git/blob - src/libopensrf/osrf_list.c
Patch from Scott McKellar:
[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
111 int osrfListFind( const osrfList* list, void* addr ) {
112         if(!(list && addr)) return -1;
113         int index;
114         for( index = 0; index < list->size; index++ ) {
115                 if( list->arrlist[index] == addr ) 
116                         return index;
117         }
118         return -1;
119 }
120
121
122 unsigned int osrfListGetCount( const osrfList* list ) {
123         if(!list) return -1;
124         return list->size;
125 }
126
127
128 void* osrfListPop( osrfList* list ) {
129         if(!list) return NULL;
130         return osrfListRemove( list, list->size - 1 );
131 }
132
133
134 osrfListIterator* osrfNewListIterator( const osrfList* list ) {
135         if(!list) return NULL;
136         osrfListIterator* itr;
137         OSRF_MALLOC(itr, sizeof(osrfListIterator));
138         itr->list = list;
139         itr->current = 0;
140         return itr;
141 }
142
143 void* osrfListIteratorNext( osrfListIterator* itr ) {
144         if(!(itr && itr->list)) return NULL;
145         if(itr->current >= itr->list->size) return NULL;
146         return itr->list->arrlist[itr->current++];
147 }
148
149 void osrfListIteratorFree( osrfListIterator* itr ) {
150         if(!itr) return;
151         free(itr);
152 }
153
154
155 void osrfListIteratorReset( osrfListIterator* itr ) {
156         if(!itr) return;
157         itr->current = 0;
158 }
159
160
161 void osrfListVanillaFree( void* item ) {
162         free(item);
163 }
164
165 void osrfListSetDefaultFree( osrfList* list ) {
166         if(!list) return;
167         list->freeItem = osrfListVanillaFree;
168 }