Me@11: /* Me@11: * Copyright 2010 OpenSourceCodeStewardshipFoundation Me@11: * Me@11: * Licensed under BSD Me@11: */ Me@11: Me@11: Me@11: Me@11: #include Me@11: #include Me@11: Me@11: #include "DynArray.h" Me@11: Me@11: Me@11: Me@11: DynArrayInfo * Me@11: makeDynArrayInfoFrom( void ***addrOfPtrToArray, int32 sizeOfArray ) Me@11: { DynArrayInfo *info; Me@11: Me@11: info = malloc( sizeof(DynArrayInfo) ); Me@11: Me@11: info->addrOfPtrToArray = addrOfPtrToArray; Me@11: info->sizeOfArray = sizeOfArray; Me@11: info->numInArray = 0; Me@11: } Me@11: Me@11: DynArrayInfo * Me@11: makeDynArrayOfSize( void ***addrOfPtrToArray, int32 sizeOfArray ) Me@11: { DynArrayInfo *info; Me@11: Me@11: info = malloc( sizeof(DynArrayInfo) ); Me@11: Me@11: info->addrOfPtrToArray = addrOfPtrToArray; Me@11: Me@11: *(addrOfPtrToArray) = malloc( sizeOfArray * sizeof(void *) ); Me@11: info->sizeOfArray = sizeOfArray; Me@11: info->numInArray = 0; Me@11: } Me@11: Me@11: Me@11: /*A dynamic array is same as any other array, but add a DynArrayInfo next Me@11: * to it. Accesses and updates of array indexes are done normally, it's Me@11: * only when add a new element into array that use the extra info. Me@11: * An add can cause the pointer to the normal array to change.. so must Me@11: * be protected to single VP at a time. Me@11: * Me@11: *Only need to use this Fn when need a new index, higher than any previous Me@11: */ Me@11: int32 Me@11: addToDynArray( void *value, DynArrayInfo *info ) Me@11: { int32 numInArray, sizeOfArray; Me@11: void **array; Me@11: Me@11: numInArray = info->numInArray; Me@11: sizeOfArray = info->sizeOfArray; Me@11: Me@11: if( numInArray >= sizeOfArray ) Me@11: { Me@11: increaseSizeOfDynArrayTo( info, sizeOfArray * 2 ); Me@11: } Me@11: Me@11: array = *(info->addrOfPtrToArray); Me@11: array[ numInArray ] = value; Me@11: info->numInArray++; Me@11: Me@11: return numInArray; //pre-incr value is the index put value into Me@11: } Me@11: Me@11: Me@11: /*Use this when know how many things going to add in -- then can do this Me@11: * once and use as normal array afterwards. If later add another chunk, Me@11: * do this again. Note, this makes new size be just big enough to hold Me@11: * highest index, so will do a linear number of copies if use only this. Me@11: *To cut down on number of copies, can use the increaseSizeTo Fn to Me@11: * exponentially increase size.. Me@11: */ Me@11: void Me@11: makeHighestDynArrayIndexBe( DynArrayInfo *info, int32 highestIndex ) Me@11: { Me@11: if( info->sizeOfArray <= highestIndex ) Me@11: { Me@11: increaseSizeOfDynArrayTo( info, highestIndex + 1 ); Me@11: } Me@11: info->numInArray = highestIndex + 1; Me@11: } Me@11: Me@11: Me@11: /*Only use this if certain new size is bigger than current size Me@11: */ Me@11: void Me@11: increaseSizeOfDynArrayTo( DynArrayInfo *info, int32 newSize ) Me@11: { int32 oldSizeOfArray, i; Me@11: void **newArray, **oldArray; Me@11: Me@11: oldSizeOfArray = info->sizeOfArray; Me@11: if( newSize <= oldSizeOfArray ) return; Me@11: Me@11: oldArray = *(info->addrOfPtrToArray); Me@11: newArray = malloc( newSize * sizeof(void *) ); Me@11: Me@11: for( i = 0; i < oldSizeOfArray; i++ ) Me@11: { Me@11: newArray[i] = oldArray[i]; Me@11: } Me@11: *(info->addrOfPtrToArray) = newArray; //change location of array-ptr Me@11: info->sizeOfArray = newSize; Me@11: Me@11: free( oldArray ); Me@11: } Me@11: Me@11: Me@11: /* Frees the array, plus the info Me@11: */ Me@11: void Me@11: freeDynArrayDeep( DynArrayInfo *info, FreeFnPtr freeFnPtr ) Me@11: { Me@11: forAllInDynArrayDo( info, freeFnPtr ); Me@11: free( *(info->addrOfPtrToArray) ); Me@11: free( info ); Me@11: } Me@11: Me@11: /* Only frees the info Me@11: */ Me@11: void Me@11: freeDynArrayFlat( DynArrayInfo *info ) Me@11: { Me@11: free( info ); Me@11: } Me@11: Me@11: Me@11: /*The function has a fixed prototype: takes a void * returns void Me@11: * So, the function has to internally cast void * to whatever data struc.. Me@11: */ Me@11: void Me@11: forAllInDynArrayDo( DynArrayInfo *info, DynArrayFnPtr fnPtr ) Me@11: { int32 idx; Me@11: void **array; Me@11: Me@11: array = *(info->addrOfPtrToArray); Me@11: for( idx = 0; idx < info->numInArray; idx++ ) Me@11: { Me@11: (*fnPtr)(array[idx]); Me@11: } Me@11: } Me@11: