1 | /* Copyright 2009, UCAR/Unidata and OPeNDAP, Inc. |
---|
2 | See the COPYRIGHT file for more information. */ |
---|
3 | |
---|
4 | #include "config.h" |
---|
5 | |
---|
6 | #include <stdlib.h> |
---|
7 | #include <stdio.h> |
---|
8 | #include <string.h> |
---|
9 | |
---|
10 | #include "oclist.h" |
---|
11 | |
---|
12 | static ocelem ocDATANULL = (ocelem)0; |
---|
13 | /*static int ocinitialized=0;*/ |
---|
14 | |
---|
15 | int oclistnull(ocelem e) {return e == ocDATANULL;} |
---|
16 | |
---|
17 | #ifndef TRUE |
---|
18 | #define TRUE 1 |
---|
19 | #endif |
---|
20 | #ifndef FALSE |
---|
21 | #define FALSE 0 |
---|
22 | #endif |
---|
23 | |
---|
24 | #define DEFAULTALLOC 16 |
---|
25 | #define ALLOCINCR 16 |
---|
26 | |
---|
27 | OClist* oclistnewn(int prealloc) |
---|
28 | { |
---|
29 | OClist* l; |
---|
30 | /* |
---|
31 | if(!ocinitialized) { |
---|
32 | memset((void*)&ocDATANULL,0,sizeof(ocelem)); |
---|
33 | ocinitialized = 1; |
---|
34 | } |
---|
35 | */ |
---|
36 | if(prealloc < 0) prealloc = 0; |
---|
37 | l = (OClist*)malloc(sizeof(OClist)); |
---|
38 | if(l) { |
---|
39 | l->alloc=prealloc; |
---|
40 | l->length=prealloc; |
---|
41 | l->content=(prealloc==0?NULL:(ocelem*)calloc(prealloc,sizeof(ocelem))); |
---|
42 | if(l == NULL) {free(l);return 0;} |
---|
43 | } |
---|
44 | return l; |
---|
45 | } |
---|
46 | |
---|
47 | int |
---|
48 | oclistfree(OClist* l) |
---|
49 | { |
---|
50 | if(l) { |
---|
51 | l->alloc = 0; |
---|
52 | if(l->content != NULL) {free(l->content); l->content = NULL;} |
---|
53 | free(l); |
---|
54 | } |
---|
55 | return TRUE; |
---|
56 | } |
---|
57 | |
---|
58 | int |
---|
59 | oclistsetalloc(OClist* l, unsigned int sz) |
---|
60 | { |
---|
61 | ocelem* newcontent; |
---|
62 | if(l == NULL) return FALSE; |
---|
63 | if(sz <= 0) {sz = (l->length?2*l->length:DEFAULTALLOC);} |
---|
64 | if(l->alloc >= sz) {return TRUE;} |
---|
65 | newcontent=(ocelem*)calloc(sz,sizeof(ocelem)); |
---|
66 | if(l->alloc > 0 && l->length > 0 && l->content != NULL) { |
---|
67 | memcpy((void*)newcontent,(void*)l->content,sizeof(ocelem)*l->length); |
---|
68 | free(l->content); |
---|
69 | } |
---|
70 | l->content=newcontent; |
---|
71 | l->alloc=sz; |
---|
72 | return TRUE; |
---|
73 | } |
---|
74 | |
---|
75 | int |
---|
76 | oclistsetlength(OClist* l, unsigned int sz) |
---|
77 | { |
---|
78 | if(l == NULL) return FALSE; |
---|
79 | if(sz > l->alloc && !oclistsetalloc(l,sz)) return FALSE; |
---|
80 | l->length = sz; |
---|
81 | return TRUE; |
---|
82 | } |
---|
83 | |
---|
84 | ocelem |
---|
85 | oclistget(OClist* l, unsigned int index) |
---|
86 | { |
---|
87 | if(l == NULL || l->length == 0) return ocDATANULL; |
---|
88 | if(index >= l->length) return ocDATANULL; |
---|
89 | return l->content[index]; |
---|
90 | } |
---|
91 | |
---|
92 | int |
---|
93 | oclistset(OClist* l, unsigned int index, ocelem elem) |
---|
94 | { |
---|
95 | if(l == NULL) return FALSE; |
---|
96 | if(index >= l->length) return FALSE; |
---|
97 | l->content[index] = elem; |
---|
98 | return TRUE; |
---|
99 | } |
---|
100 | |
---|
101 | /* Insert at position i of l; will push up elements i..|seq|. */ |
---|
102 | int |
---|
103 | oclistinsert(OClist* l, unsigned int index, ocelem elem) |
---|
104 | { |
---|
105 | unsigned int i; |
---|
106 | if(l == NULL) return FALSE; |
---|
107 | if(index > l->length) return FALSE; |
---|
108 | oclistsetalloc(l,0); |
---|
109 | for(i=l->length;i>index;i--) l->content[i] = l->content[i-1]; |
---|
110 | l->content[index] = elem; |
---|
111 | l->length++; |
---|
112 | return TRUE; |
---|
113 | } |
---|
114 | |
---|
115 | int |
---|
116 | oclistpush(OClist* l, ocelem elem) |
---|
117 | { |
---|
118 | if(l == NULL) return FALSE; |
---|
119 | if(l->length >= l->alloc) oclistsetalloc(l,0); |
---|
120 | l->content[l->length] = elem; |
---|
121 | l->length++; |
---|
122 | return TRUE; |
---|
123 | } |
---|
124 | |
---|
125 | ocelem |
---|
126 | oclistpop(OClist* l) |
---|
127 | { |
---|
128 | if(l == NULL || l->length == 0) return ocDATANULL; |
---|
129 | l->length--; |
---|
130 | return l->content[l->length]; |
---|
131 | } |
---|
132 | |
---|
133 | ocelem |
---|
134 | oclisttop(OClist* l) |
---|
135 | { |
---|
136 | if(l == NULL || l->length == 0) return ocDATANULL; |
---|
137 | return l->content[l->length - 1]; |
---|
138 | } |
---|
139 | |
---|
140 | ocelem |
---|
141 | oclistremove(OClist* l, unsigned int i) |
---|
142 | { |
---|
143 | unsigned int len; |
---|
144 | ocelem elem; |
---|
145 | if(l == NULL || (len=l->length) == 0) return ocDATANULL; |
---|
146 | if(i >= len) return ocDATANULL; |
---|
147 | elem = l->content[i]; |
---|
148 | for(i++;i<len;i++) l->content[i-1] = l->content[i]; |
---|
149 | l->length--; |
---|
150 | return elem; |
---|
151 | } |
---|
152 | |
---|
153 | /* Duplicate and return the content (null terminate) */ |
---|
154 | ocelem* |
---|
155 | oclistdup(OClist* l) |
---|
156 | { |
---|
157 | ocelem* result = (ocelem*)malloc(sizeof(ocelem)*(l->length+1)); |
---|
158 | memcpy((void*)result,(void*)l->content,sizeof(ocelem)*l->length); |
---|
159 | result[l->length] = (ocelem)0; |
---|
160 | return result; |
---|
161 | } |
---|
162 | |
---|
163 | int |
---|
164 | oclistcontains(OClist* list, ocelem elem) |
---|
165 | { |
---|
166 | unsigned int i; |
---|
167 | for(i=0;i<oclistlength(list);i++) { |
---|
168 | if(elem == oclistget(list,i)) return 1; |
---|
169 | } |
---|
170 | return 0; |
---|
171 | } |
---|