Home | History | Annotate | Download | only in src
      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