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 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 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 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 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 123 ESR_ReturnCode Int8ArrayList_RemoveAll(Int8ArrayList* self) 124 { 125 Int8ArrayListImpl* impl = (Int8ArrayListImpl*) self; 126 127 impl->virtualSize = 0; 128 return ESR_SUCCESS; 129 } 130 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 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 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 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 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 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 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