Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > DynArray
comparison DynArray.c @ 4:f35e64d7a42b
Working version used for probes in Master Env
| author | Me |
|---|---|
| date | Sat, 30 Oct 2010 22:12:32 -0700 |
| parents | 8473c52c6f0e |
| children | 2915fb26c9e2 601709e9f2a4 |
comparison
equal
deleted
inserted
replaced
| 1:9040f3edda48 | 2:a8b72852155d |
|---|---|
| 7 | 7 |
| 8 | 8 |
| 9 #include <stdio.h> | 9 #include <stdio.h> |
| 10 #include <malloc.h> | 10 #include <malloc.h> |
| 11 | 11 |
| 12 #include "DynArray.h" | |
| 12 | 13 |
| 13 | 14 |
| 14 /*make a struct with the sizes and a pointer to the | |
| 15 * array, but hide a reverse pointer at the front of the array that | |
| 16 * points back to the vector struct -- that way, can pass around the | |
| 17 * array when doing work on elements, but when need to increase size, | |
| 18 * get pointer to vector struct and use that, which will change the | |
| 19 * ptr to the array in the vector struc, and return the new pointer.. | |
| 20 * so from the point of changing size on, have the correct array ptr, | |
| 21 * and also all other places that initiate a sequence later will get | |
| 22 * the array ptr from the vector struct at the sequence start.. | |
| 23 */ | |
| 24 bool8 | |
| 25 addToVect( Vector *vect, void *ptrToElem ) | |
| 26 { int32 numPtrsInVect, sizeOfVect; | |
| 27 | 15 |
| 28 /* | 16 DynArrayInfo * |
| 29 numPtrsInVect = *(vect -1); //num ptrs is "hidden" in front | 17 makeDynArrayInfoFrom( void ***addrOfPtrToArray, int32 sizeOfArray ) |
| 30 sizeOfVect = *(vect -2); | 18 { DynArrayInfo *info; |
| 31 */ | |
| 32 numPtrsInVect = vect->numPtrsInArray; | |
| 33 sizeOfVect = vect->sizeOfArray; | |
| 34 | 19 |
| 35 if( numPtrsInVect >= sizeOfVect ) return FALSE; | 20 info = malloc( sizeof(DynArrayInfo) ); |
| 36 | 21 |
| 37 vect->arrayOfPtrs[numPtrsInVect] = ptrToElem; | 22 info->addrOfPtrToArray = addrOfPtrToArray; |
| 38 vect->numPtrsInArray++; | 23 info->sizeOfArray = sizeOfArray; |
| 24 info->numInArray = 0; | |
| 39 } | 25 } |
| 40 | 26 |
| 41 void ** | 27 DynArrayInfo * |
| 42 increaseSizeOfVect( Vector *vect ) | 28 makeDynArrayOfSize( void ***addrOfPtrToArray, int32 sizeOfArray ) |
| 43 { int32 oldSizeOfArray, newSizeOfArray, i; | 29 { DynArrayInfo *info; |
| 30 | |
| 31 info = malloc( sizeof(DynArrayInfo) ); | |
| 32 | |
| 33 info->addrOfPtrToArray = addrOfPtrToArray; | |
| 34 | |
| 35 *(addrOfPtrToArray) = malloc( sizeOfArray * sizeof(void *) ); | |
| 36 info->sizeOfArray = sizeOfArray; | |
| 37 info->numInArray = 0; | |
| 38 } | |
| 39 | |
| 40 | |
| 41 /*A dynamic array is same as any other array, but add a DynArrayInfo next | |
| 42 * to it. Accesses and updates of array indexes are done normally, it's | |
| 43 * only when add a new element into array that use the extra info. | |
| 44 * An add can cause the pointer to the normal array to change.. so must | |
| 45 * be protected to single VP at a time. | |
| 46 * | |
| 47 *Only need to use this Fn when need a new index, higher than any previous | |
| 48 */ | |
| 49 int32 | |
| 50 addToDynArray( void *value, DynArrayInfo *info ) | |
| 51 { int32 numInArray, sizeOfArray; | |
| 52 void **array; | |
| 53 | |
| 54 numInArray = info->numInArray; | |
| 55 sizeOfArray = info->sizeOfArray; | |
| 56 | |
| 57 if( numInArray >= sizeOfArray ) | |
| 58 { | |
| 59 increaseSizeOfDynArrayTo( info, sizeOfArray * 2 ); | |
| 60 } | |
| 61 | |
| 62 array = *(info->addrOfPtrToArray); | |
| 63 array[ numInArray ] = value; | |
| 64 info->numInArray++; | |
| 65 | |
| 66 return numInArray; //pre-incr value is the index put value into | |
| 67 } | |
| 68 | |
| 69 | |
| 70 /*Use this when know how many things going to add in -- then can do this | |
| 71 * once and use as normal array afterwards. If later add another chunk, | |
| 72 * do this again. Note, this makes new size be just big enough to hold | |
| 73 * highest index, so will do a linear number of copies if use only this. | |
| 74 *To cut down on number of copies, can use the increaseSizeTo Fn to | |
| 75 * exponentially increase size.. | |
| 76 */ | |
| 77 void | |
| 78 makeHighestDynArrayIndexBe( DynArrayInfo *info, int32 highestIndex ) | |
| 79 { | |
| 80 if( info->sizeOfArray <= highestIndex ) | |
| 81 { | |
| 82 increaseSizeOfDynArrayTo( info, highestIndex + 1 ); | |
| 83 } | |
| 84 info->numInArray = highestIndex + 1; | |
| 85 } | |
| 86 | |
| 87 | |
| 88 /*Only use this if certain new size is bigger than current size | |
| 89 */ | |
| 90 void | |
| 91 increaseSizeOfDynArrayTo( DynArrayInfo *info, int32 newSize ) | |
| 92 { int32 oldSizeOfArray, i; | |
| 44 void **newArray, **oldArray; | 93 void **newArray, **oldArray; |
| 45 | 94 |
| 46 oldSizeOfArray = vect->sizeOfArray; | 95 oldSizeOfArray = info->sizeOfArray; |
| 47 newSizeOfArray = oldSizeOfArray * 2; | 96 if( newSize <= oldSizeOfArray ) return; |
| 48 oldArray = vect->arrayOfPtrs; | 97 |
| 49 newArray = malloc( (newSizeOfArray + 1) * sizeof(void *) ); | 98 oldArray = *(info->addrOfPtrToArray); |
| 50 *newArray = vect; | 99 newArray = malloc( newSize * sizeof(void *) ); |
| 51 newArray++; | 100 |
| 52 for( i = 0; i < oldSizeOfArray; i++ ) | 101 for( i = 0; i < oldSizeOfArray; i++ ) |
| 53 { | 102 { |
| 54 newArray[i] = oldArray[i]; | 103 newArray[i] = oldArray[i]; |
| 55 } | 104 } |
| 56 vect->arrayOfPtrs = newArray; | 105 *(info->addrOfPtrToArray) = newArray; //change location of array-ptr |
| 57 vect->sizeOfArray = newSizeOfArray; | 106 info->sizeOfArray = newSize; |
| 58 | 107 |
| 59 free( oldArray -1 ); | 108 free( oldArray ); |
| 60 return newArray; | |
| 61 } | 109 } |
| 62 | 110 |
| 63 /* | 111 |
| 64 bool8 | 112 /* Frees the array, plus the info |
| 65 forAllInVectDo( ptrToFnTakesVectElemAsVoid* ) | 113 */ |
| 114 void | |
| 115 freeDynArrayDeep( DynArrayInfo *info, FreeFnPtr freeFnPtr ) | |
| 66 { | 116 { |
| 67 return success; | 117 forAllInDynArrayDo( info, freeFnPtr ); |
| 118 free( *(info->addrOfPtrToArray) ); | |
| 119 free( info ); | |
| 68 } | 120 } |
| 69 */ | 121 |
| 122 /* Only frees the info | |
| 123 */ | |
| 124 void | |
| 125 freeDynArrayFlat( DynArrayInfo *info ) | |
| 126 { | |
| 127 free( info ); | |
| 128 } | |
| 129 | |
| 130 | |
| 131 /*The function has a fixed prototype: takes a void * returns void | |
| 132 * So, the function has to internally cast void * to whatever data struc.. | |
| 133 */ | |
| 134 void | |
| 135 forAllInDynArrayDo( DynArrayInfo *info, DynArrayFnPtr fnPtr ) | |
| 136 { int32 idx; | |
| 137 void **array; | |
| 138 | |
| 139 array = *(info->addrOfPtrToArray); | |
| 140 for( idx = 0; idx < info->numInArray; idx++ ) | |
| 141 { | |
| 142 (*fnPtr)(array[idx]); | |
| 143 } | |
| 144 } | |
| 145 |
