Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > DynArray
changeset 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 |
| files | DynArray.c DynArray.h |
| diffstat | 2 files changed, 158 insertions(+), 52 deletions(-) [+] |
line diff
1.1 --- a/DynArray.c Sun Sep 12 12:10:25 2010 -0700 1.2 +++ b/DynArray.c Sat Oct 30 22:12:32 2010 -0700 1.3 @@ -9,61 +9,137 @@ 1.4 #include <stdio.h> 1.5 #include <malloc.h> 1.6 1.7 +#include "DynArray.h" 1.8 1.9 1.10 -/*make a struct with the sizes and a pointer to the 1.11 - * array, but hide a reverse pointer at the front of the array that 1.12 - * points back to the vector struct -- that way, can pass around the 1.13 - * array when doing work on elements, but when need to increase size, 1.14 - * get pointer to vector struct and use that, which will change the 1.15 - * ptr to the array in the vector struc, and return the new pointer.. 1.16 - * so from the point of changing size on, have the correct array ptr, 1.17 - * and also all other places that initiate a sequence later will get 1.18 - * the array ptr from the vector struct at the sequence start.. 1.19 - */ 1.20 -bool8 1.21 -addToVect( Vector *vect, void *ptrToElem ) 1.22 - { int32 numPtrsInVect, sizeOfVect; 1.23 1.24 -/* 1.25 - numPtrsInVect = *(vect -1); //num ptrs is "hidden" in front 1.26 - sizeOfVect = *(vect -2); 1.27 -*/ 1.28 - numPtrsInVect = vect->numPtrsInArray; 1.29 - sizeOfVect = vect->sizeOfArray; 1.30 +DynArrayInfo * 1.31 +makeDynArrayInfoFrom( void ***addrOfPtrToArray, int32 sizeOfArray ) 1.32 + { DynArrayInfo *info; 1.33 1.34 - if( numPtrsInVect >= sizeOfVect ) return FALSE; 1.35 + info = malloc( sizeof(DynArrayInfo) ); 1.36 1.37 - vect->arrayOfPtrs[numPtrsInVect] = ptrToElem; 1.38 - vect->numPtrsInArray++; 1.39 + info->addrOfPtrToArray = addrOfPtrToArray; 1.40 + info->sizeOfArray = sizeOfArray; 1.41 + info->numInArray = 0; 1.42 } 1.43 1.44 -void ** 1.45 -increaseSizeOfVect( Vector *vect ) 1.46 - { int32 oldSizeOfArray, newSizeOfArray, i; 1.47 +DynArrayInfo * 1.48 +makeDynArrayOfSize( void ***addrOfPtrToArray, int32 sizeOfArray ) 1.49 + { DynArrayInfo *info; 1.50 + 1.51 + info = malloc( sizeof(DynArrayInfo) ); 1.52 + 1.53 + info->addrOfPtrToArray = addrOfPtrToArray; 1.54 + 1.55 + *(addrOfPtrToArray) = malloc( sizeOfArray * sizeof(void *) ); 1.56 + info->sizeOfArray = sizeOfArray; 1.57 + info->numInArray = 0; 1.58 + } 1.59 + 1.60 + 1.61 +/*A dynamic array is same as any other array, but add a DynArrayInfo next 1.62 + * to it. Accesses and updates of array indexes are done normally, it's 1.63 + * only when add a new element into array that use the extra info. 1.64 + * An add can cause the pointer to the normal array to change.. so must 1.65 + * be protected to single VP at a time. 1.66 + * 1.67 + *Only need to use this Fn when need a new index, higher than any previous 1.68 + */ 1.69 +int32 1.70 +addToDynArray( void *value, DynArrayInfo *info ) 1.71 + { int32 numInArray, sizeOfArray; 1.72 + void **array; 1.73 + 1.74 + numInArray = info->numInArray; 1.75 + sizeOfArray = info->sizeOfArray; 1.76 + 1.77 + if( numInArray >= sizeOfArray ) 1.78 + { 1.79 + increaseSizeOfDynArrayTo( info, sizeOfArray * 2 ); 1.80 + } 1.81 + 1.82 + array = *(info->addrOfPtrToArray); 1.83 + array[ numInArray ] = value; 1.84 + info->numInArray++; 1.85 + 1.86 + return numInArray; //pre-incr value is the index put value into 1.87 + } 1.88 + 1.89 + 1.90 +/*Use this when know how many things going to add in -- then can do this 1.91 + * once and use as normal array afterwards. If later add another chunk, 1.92 + * do this again. Note, this makes new size be just big enough to hold 1.93 + * highest index, so will do a linear number of copies if use only this. 1.94 + *To cut down on number of copies, can use the increaseSizeTo Fn to 1.95 + * exponentially increase size.. 1.96 + */ 1.97 +void 1.98 +makeHighestDynArrayIndexBe( DynArrayInfo *info, int32 highestIndex ) 1.99 + { 1.100 + if( info->sizeOfArray <= highestIndex ) 1.101 + { 1.102 + increaseSizeOfDynArrayTo( info, highestIndex + 1 ); 1.103 + } 1.104 + info->numInArray = highestIndex + 1; 1.105 + } 1.106 + 1.107 + 1.108 +/*Only use this if certain new size is bigger than current size 1.109 + */ 1.110 +void 1.111 +increaseSizeOfDynArrayTo( DynArrayInfo *info, int32 newSize ) 1.112 + { int32 oldSizeOfArray, i; 1.113 void **newArray, **oldArray; 1.114 1.115 - oldSizeOfArray = vect->sizeOfArray; 1.116 - newSizeOfArray = oldSizeOfArray * 2; 1.117 - oldArray = vect->arrayOfPtrs; 1.118 - newArray = malloc( (newSizeOfArray + 1) * sizeof(void *) ); 1.119 - *newArray = vect; 1.120 - newArray++; 1.121 + oldSizeOfArray = info->sizeOfArray; 1.122 + if( newSize <= oldSizeOfArray ) return; 1.123 + 1.124 + oldArray = *(info->addrOfPtrToArray); 1.125 + newArray = malloc( newSize * sizeof(void *) ); 1.126 + 1.127 for( i = 0; i < oldSizeOfArray; i++ ) 1.128 { 1.129 newArray[i] = oldArray[i]; 1.130 } 1.131 - vect->arrayOfPtrs = newArray; 1.132 - vect->sizeOfArray = newSizeOfArray; 1.133 + *(info->addrOfPtrToArray) = newArray; //change location of array-ptr 1.134 + info->sizeOfArray = newSize; 1.135 1.136 - free( oldArray -1 ); 1.137 - return newArray; 1.138 + free( oldArray ); 1.139 } 1.140 1.141 -/* 1.142 -bool8 1.143 -forAllInVectDo( ptrToFnTakesVectElemAsVoid* ) 1.144 + 1.145 +/* Frees the array, plus the info 1.146 + */ 1.147 +void 1.148 +freeDynArrayDeep( DynArrayInfo *info, FreeFnPtr freeFnPtr ) 1.149 { 1.150 - return success; 1.151 + forAllInDynArrayDo( info, freeFnPtr ); 1.152 + free( *(info->addrOfPtrToArray) ); 1.153 + free( info ); 1.154 } 1.155 -*/ 1.156 + 1.157 +/* Only frees the info 1.158 + */ 1.159 +void 1.160 +freeDynArrayFlat( DynArrayInfo *info ) 1.161 + { 1.162 + free( info ); 1.163 + } 1.164 + 1.165 + 1.166 +/*The function has a fixed prototype: takes a void * returns void 1.167 + * So, the function has to internally cast void * to whatever data struc.. 1.168 + */ 1.169 +void 1.170 +forAllInDynArrayDo( DynArrayInfo *info, DynArrayFnPtr fnPtr ) 1.171 + { int32 idx; 1.172 + void **array; 1.173 + 1.174 + array = *(info->addrOfPtrToArray); 1.175 + for( idx = 0; idx < info->numInArray; idx++ ) 1.176 + { 1.177 + (*fnPtr)(array[idx]); 1.178 + } 1.179 + } 1.180 +
2.1 --- a/DynArray.h Sun Sep 12 12:10:25 2010 -0700 2.2 +++ b/DynArray.h Sat Oct 30 22:12:32 2010 -0700 2.3 @@ -5,23 +5,53 @@ 2.4 * Created on May 14, 2010, 3:08 PM 2.5 */ 2.6 2.7 -#ifndef _VECTOR_H 2.8 -#define _VECTOR_H 2.9 +#ifndef _DYNARRAY_H 2.10 +#define _DYNARRAY_H 2.11 2.12 -//Doing one special cheat -- hiding a back-ptr in front of array 2.13 +#include "../VMS_primitive_data_types.h" 2.14 + 2.15 + 2.16 + //A dynamic array is same as any other array, but add a DynArrayInfo next 2.17 + // to it. Accesses and updates of array indexes are done normally, it's 2.18 + // only when add a new element into array that use the extra info. 2.19 + // An add can cause the pointer to the normal array to change.. so must 2.20 + // be protected to single VP at a time. 2.21 typedef struct 2.22 { 2.23 - void **arrayOfPtrs; 2.24 - int numPtrsInArray; 2.25 - int sizeOfArray; 2.26 + void ***addrOfPtrToArray; //addr of array of ptrs == triple * 2.27 + int32 numInArray; 2.28 + int32 sizeOfArray; 2.29 } 2.30 -Vector; 2.31 +DynArrayInfo; 2.32 2.33 -Vector *createVect ( int32 initialSizeOfArray ); 2.34 -Vector *increaseSizeOfVect( Vector *vect ); 2.35 -bool8 addToVect ( void *ptrToAdd, Vector *vect ); 2.36 -bool8 removeLastInVect ( Vector *vect ); 2.37 +DynArrayInfo * 2.38 +makeDynArrayInfoFrom( void ***addrOfPtrToArray, int32 sizeOfArray ); 2.39 2.40 +DynArrayInfo * 2.41 +makeDynArrayOfSize( void ***addrOfPtrToArray, int32 sizeOfArray ); 2.42 2.43 -#endif /* _VECTOR_H */ 2.44 +int32 2.45 +addToDynArray( void *value, DynArrayInfo *info ); 2.46 2.47 +void 2.48 +makeHighestDynArrayIndexBe( DynArrayInfo *info, int32 highestIndex ); 2.49 + 2.50 +void 2.51 +increaseSizeOfDynArrayTo( DynArrayInfo *info, int32 newSize ); 2.52 + 2.53 +typedef void (*FreeFnPtr) ( void * ); //fn has to cast void * to whatever 2.54 + 2.55 +void 2.56 +freeDynArrayDeep( DynArrayInfo *info, FreeFnPtr freeFnPtr ); 2.57 + 2.58 +void 2.59 +freeDynArrayFlat( DynArrayInfo *info ); 2.60 + 2.61 + 2.62 +typedef void (*DynArrayFnPtr) ( void * ); //fn has to cast void * 2.63 + 2.64 +void 2.65 +forAllInDynArrayDo( DynArrayInfo *info, DynArrayFnPtr fnPtr ); 2.66 + 2.67 +#endif /* _DYNARRAY_H */ 2.68 +
