1 /*---------------------------------------------------------------------------*
2 * Int8ArrayListImpl.c *
3 * *
4 * Copyright 2007, 2008 Nuance Communciations, Inc. *
5 * *
6 * Licensed under the Apache License, Version 2.0 (the 'License'); *
7 * you may not use this file except in compliance with the License. *
8 * *
9 * You may obtain a copy of the License at *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, software *
13 * distributed under the License is distributed on an 'AS IS' BASIS, *
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15 * See the License for the specific language governing permissions and *
16 * limitations under the License. *
17 * *
18 *---------------------------------------------------------------------------*/
19
20 #include "Int8ArrayList.h"
21 #include "Int8ArrayListImpl.h"
22 #include "pmemory.h"
23 #include "passert.h"
24
25 #define MTAG NULL
26 #define INITIAL_SIZE 32
27
28
Int8ArrayListCreate(Int8ArrayList ** self)29 ESR_ReturnCode Int8ArrayListCreate(Int8ArrayList** self)
30 {
31 Int8ArrayListImpl* impl;
32
33 if (self == NULL)
34 return ESR_INVALID_ARGUMENT;
35 impl = NEW(Int8ArrayListImpl, MTAG);
36 if (impl == NULL)
37 return ESR_OUT_OF_MEMORY;
38 impl->Interface.add = &Int8ArrayList_Add;
39 impl->Interface.contains = &Int8ArrayList_Contains;
40 impl->Interface.destroy = &Int8ArrayList_Destroy;
41 impl->Interface.get = &Int8ArrayList_Get;
42 impl->Interface.getSize = &Int8ArrayList_GetSize;
43 impl->Interface.remove = &Int8ArrayList_Remove;
44 impl->Interface.removeAll = &Int8ArrayList_RemoveAll;
45 impl->Interface.set = &Int8ArrayList_Set;
46 impl->Interface.toStaticArray = &Int8ArrayList_ToStaticArray;
47 impl->Interface.clone = &Int8ArrayList_Clone;
48 impl->contents = MALLOC((INITIAL_SIZE + 1) * sizeof(asr_int8_t), MTAG);
49 if (impl->contents == NULL)
50 {
51 FREE(impl);
52 return ESR_OUT_OF_MEMORY;
53 }
54 impl->actualSize = INITIAL_SIZE;
55 impl->virtualSize = 0;
56 *self = (Int8ArrayList*) impl;
57 return ESR_SUCCESS;
58 }
59
Int8ArrayListImport(asr_int8_t * value,Int8ArrayList ** self)60 ESR_ReturnCode Int8ArrayListImport(asr_int8_t* value, Int8ArrayList** self)
61 {
62 ESR_ReturnCode rc;
63 Int8ArrayListImpl* impl;
64
65 if (self == NULL)
66 return ESR_INVALID_ARGUMENT;
67 CHK(rc, Int8ArrayListCreate(self));
68 impl = (Int8ArrayListImpl*) self;
69 impl->contents = value;
70 return ESR_SUCCESS;
71 CLEANUP:
72 return rc;
73 }
74
Int8ArrayList_Add(Int8ArrayList * self,const asr_int8_t element)75 ESR_ReturnCode Int8ArrayList_Add(Int8ArrayList* self, const asr_int8_t element)
76 {
77 Int8ArrayListImpl* impl = (Int8ArrayListImpl*) self;
78
79 if (impl->virtualSize >= impl->actualSize)
80 {
81 /* enlarge buffer */
82 asr_int8_t* temp = REALLOC(impl->contents, (impl->actualSize * 2 + 1) * sizeof(asr_int8_t));
83 if (temp == NULL)
84 return ESR_OUT_OF_MEMORY;
85 impl->contents = temp;
86 impl->actualSize *= 2;
87 }
88 impl->contents[impl->virtualSize] = element;
89 ++impl->virtualSize;
90 return ESR_SUCCESS;
91 }
92
Int8ArrayList_Remove(Int8ArrayList * self,const asr_int8_t element)93 ESR_ReturnCode Int8ArrayList_Remove(Int8ArrayList* self, const asr_int8_t element)
94 {
95 Int8ArrayListImpl* impl = (Int8ArrayListImpl*) self;
96 asr_int8_t* contents = impl->contents; /* cache pointer */
97 size_t virtualSize = impl->virtualSize; /* cache value */
98 size_t i;
99
100 for (i = 0; i < virtualSize; ++i)
101 {
102 if (contents[i] == element)
103 {
104 --virtualSize;
105 break;
106 }
107 }
108 /* shift remaining elements back */
109 for (; i < virtualSize; ++i)
110 contents[i] = contents[i+1];
111
112 impl->virtualSize = virtualSize; /* flush cache */
113 if (virtualSize <= impl->actualSize / 4)
114 {
115 /* shrink buffer */
116 impl->contents = REALLOC(contents, (impl->actualSize / 2 + 1) * sizeof(asr_int8_t));
117 passert(impl->contents != NULL); /* should never fail */
118 impl->actualSize /= 2;
119 }
120 return ESR_SUCCESS;
121 }
122
Int8ArrayList_RemoveAll(Int8ArrayList * self)123 ESR_ReturnCode Int8ArrayList_RemoveAll(Int8ArrayList* self)
124 {
125 Int8ArrayListImpl* impl = (Int8ArrayListImpl*) self;
126
127 impl->virtualSize = 0;
128 return ESR_SUCCESS;
129 }
130
Int8ArrayList_Contains(Int8ArrayList * self,const asr_int8_t element,ESR_BOOL * exists)131 ESR_ReturnCode Int8ArrayList_Contains(Int8ArrayList* self, const asr_int8_t element, ESR_BOOL* exists)
132 {
133 Int8ArrayListImpl* impl = (Int8ArrayListImpl*) self;
134 size_t i;
135 size_t virtualSize = impl->virtualSize; /* cache value */
136 asr_int8_t* contents = impl->contents; /* cache value */
137
138 for (i = 0; i < virtualSize; ++i)
139 {
140 if (contents[i] == element)
141 {
142 *exists = ESR_TRUE;
143 return ESR_SUCCESS;
144 }
145 }
146 *exists = ESR_FALSE;
147 return ESR_SUCCESS;
148 }
149
Int8ArrayList_Get(Int8ArrayList * self,size_t index,asr_int8_t * element)150 ESR_ReturnCode Int8ArrayList_Get(Int8ArrayList* self, size_t index, asr_int8_t* element)
151 {
152 Int8ArrayListImpl* impl = (Int8ArrayListImpl*) self;
153
154 passert(index >= 0 && index <= impl->virtualSize);
155 *element = impl->contents[index];
156 return ESR_SUCCESS;
157 }
158
Int8ArrayList_Set(Int8ArrayList * self,size_t index,const asr_int8_t element)159 ESR_ReturnCode Int8ArrayList_Set(Int8ArrayList* self, size_t index, const asr_int8_t element)
160 {
161 Int8ArrayListImpl* impl = (Int8ArrayListImpl*) self;
162
163 passert(index >= 0 && index <= impl->virtualSize);
164 impl->contents[index] = element;
165 return ESR_SUCCESS;
166 }
167
Int8ArrayList_GetSize(Int8ArrayList * self,size_t * size)168 ESR_ReturnCode Int8ArrayList_GetSize(Int8ArrayList* self, size_t* size)
169 {
170 Int8ArrayListImpl* impl = (Int8ArrayListImpl*) self;
171
172 *size = impl->virtualSize;
173 return ESR_SUCCESS;
174 }
175
Int8ArrayList_ToStaticArray(Int8ArrayList * self,asr_int8_t ** newArray)176 ESR_ReturnCode Int8ArrayList_ToStaticArray(Int8ArrayList* self, asr_int8_t** newArray)
177 {
178 Int8ArrayListImpl* impl = (Int8ArrayListImpl*) self;
179
180 *newArray = impl->contents;
181 impl->contents = NULL; /* prevent free() from deallocating buffer */
182 return Int8ArrayList_Destroy(self);
183 }
184
Int8ArrayList_Clone(Int8ArrayList * self,Int8ArrayList * clone)185 ESR_ReturnCode Int8ArrayList_Clone(Int8ArrayList* self, Int8ArrayList* clone)
186 {
187 size_t size, i;
188 asr_int8_t element;
189 ESR_ReturnCode rc;
190
191 CHK(rc, clone->removeAll(clone));
192 CHK(rc, self->getSize(self, &size));
193 for (i = 0; i < size; ++i)
194 {
195 CHK(rc, self->get(self, i, &element));
196 CHK(rc, clone->add(clone, element));
197 }
198 return ESR_SUCCESS;
199 CLEANUP:
200 return rc;
201 }
202
Int8ArrayList_Destroy(Int8ArrayList * self)203 ESR_ReturnCode Int8ArrayList_Destroy(Int8ArrayList* self)
204 {
205 Int8ArrayListImpl* impl = (Int8ArrayListImpl*) self;
206
207 FREE(impl->contents);
208 FREE(impl);
209 return ESR_SUCCESS;
210 }
211