Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > DynArray
comparison DynArray3.c @ 33:3ed337b6a04f
creating version of dyn array that keeps info in prolog instead of 2nd var
| author | Sean Halle <seanhalle@yahoo.com> |
|---|---|
| date | Fri, 19 Jul 2013 12:27:43 -0700 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| -1:000000000000 | 0:6aa41e153e08 |
|---|---|
| 1 /* | |
| 2 * Copyright 2010 OpenSourceCodeStewardshipFoundation | |
| 3 * | |
| 4 * Licensed under BSD | |
| 5 */ | |
| 6 | |
| 7 | |
| 8 | |
| 9 #include <stdio.h> | |
| 10 | |
| 11 #include "DynArray.h" | |
| 12 | |
| 13 //== declarations | |
| 14 void | |
| 15 increaseSizeOfDynArrayTo_Ext( PtrToPrivDynArray *info, int32 newSize ); | |
| 16 //== | |
| 17 | |
| 18 PtrToPrivDynArray * | |
| 19 makePrivDynArrayInfoFrom( void ***addrOfPtrToArray, int32 sizeOfArray ) | |
| 20 { PtrToPrivDynArray *info; | |
| 21 | |
| 22 info = PR_int__malloc( sizeof(PtrToPrivDynArray) ); | |
| 23 | |
| 24 info->addrOfPtrToArray = addrOfPtrToArray; | |
| 25 info->sizeOfArray = sizeOfArray; | |
| 26 info->numInArray = 0; | |
| 27 return info; | |
| 28 } | |
| 29 | |
| 30 PtrToPrivDynArray * | |
| 31 makePrivDynArrayOfSize( void ***addrOfPtrToArray, int32 sizeOfArray ) | |
| 32 { PtrToPrivDynArray *info; | |
| 33 | |
| 34 info = PR_int__malloc( sizeof(PtrToPrivDynArray) ); | |
| 35 | |
| 36 info->addrOfPtrToArray = addrOfPtrToArray; | |
| 37 | |
| 38 *(addrOfPtrToArray) = PR_int__malloc( sizeOfArray * sizeof(void *) ); | |
| 39 info->sizeOfArray = sizeOfArray; | |
| 40 info->numInArray = 0; | |
| 41 return info; | |
| 42 } | |
| 43 | |
| 44 PtrToPrivDynArray * | |
| 45 makePrivDynArrayOfSize_Ext( void ***addrOfPtrToArray, int32 sizeOfArray ) | |
| 46 { PtrToPrivDynArray *info; | |
| 47 | |
| 48 info = malloc( sizeof(PtrToPrivDynArray) ); | |
| 49 | |
| 50 info->addrOfPtrToArray = addrOfPtrToArray; | |
| 51 | |
| 52 *(addrOfPtrToArray) = malloc( sizeOfArray * sizeof(void *) ); | |
| 53 info->sizeOfArray = sizeOfArray; | |
| 54 info->numInArray = 0; | |
| 55 } | |
| 56 | |
| 57 | |
| 58 /*A dynamic array is same as any other array, but add a DynArrayInfo next | |
| 59 * to it. Accesses and updates of array indexes are done normally, it's | |
| 60 * only when add a new element into array that use the extra info. | |
| 61 * An add can cause the pointer to the normal array to change.. so must | |
| 62 * be protected to single VP at a time. | |
| 63 * | |
| 64 *Only need to use this Fn when need a new index, higher than any previous | |
| 65 */ | |
| 66 int32 | |
| 67 addToDynArray( void *value, PtrToPrivDynArray *info ) | |
| 68 { int32 numInArray, sizeOfArray; | |
| 69 void **array; | |
| 70 | |
| 71 numInArray = info->numInArray; | |
| 72 sizeOfArray = info->sizeOfArray; | |
| 73 | |
| 74 if( numInArray >= sizeOfArray ) | |
| 75 { | |
| 76 increaseSizeOfDynArrayTo( info, sizeOfArray * 2 ); | |
| 77 } | |
| 78 | |
| 79 array = *(info->addrOfPtrToArray); | |
| 80 array[ numInArray ] = value; | |
| 81 info->numInArray++; | |
| 82 | |
| 83 return numInArray; //pre-incr value is the index put value into | |
| 84 } | |
| 85 int32 | |
| 86 addToDynArray_Ext( void *value, PtrToPrivDynArray *ptrToArray ) | |
| 87 { int32 numInArray, sizeOfArray; | |
| 88 void **array; | |
| 89 | |
| 90 numInArray = ptrToArray->numInArray; | |
| 91 sizeOfArray = ptrToArray->sizeOfArray; | |
| 92 | |
| 93 if( numInArray >= sizeOfArray ) | |
| 94 { | |
| 95 increaseSizeOfDynArrayTo_Ext( ptrToArray, sizeOfArray * 2 ); | |
| 96 } | |
| 97 | |
| 98 array = *(ptrToArray->addrOfPtrToArray); | |
| 99 array[ numInArray ] = value; | |
| 100 ptrToArray->numInArray++; | |
| 101 | |
| 102 return numInArray; //pre-incr value is the index put value into | |
| 103 } | |
| 104 | |
| 105 | |
| 106 /*Use this when know how many things going to add in -- then can do this | |
| 107 * once and use as normal array afterwards. If later add another chunk, | |
| 108 * do this again. Note, this makes new size be just big enough to hold | |
| 109 * highest index, so will do a linear number of copies if use only this. | |
| 110 *To cut down on number of copies, can use the increaseSizeTo Fn to | |
| 111 * exponentially increase size.. | |
| 112 */ | |
| 113 void | |
| 114 makeHighestDynArrayIndexBe( PtrToPrivDynArray *info, int32 highestIndex ) | |
| 115 { | |
| 116 if( info->sizeOfArray <= highestIndex ) | |
| 117 { | |
| 118 increaseSizeOfDynArrayTo( info, highestIndex + 1 ); | |
| 119 } | |
| 120 info->numInArray = highestIndex + 1; | |
| 121 } | |
| 122 | |
| 123 void | |
| 124 makeHighestDynArrayIndexBeAtLeast(PtrToPrivDynArray *info, int32 index) | |
| 125 { | |
| 126 if( index < info->numInArray ) return; | |
| 127 else makeHighestDynArrayIndexBe( info, index ); | |
| 128 } | |
| 129 | |
| 130 | |
| 131 /*Only use this if certain new size is bigger than current size | |
| 132 */ | |
| 133 void | |
| 134 increaseSizeOfDynArrayTo( PtrToPrivDynArray *info, int32 newSize ) | |
| 135 { int32 oldSizeOfArray, i; | |
| 136 void **newArray, **oldArray; | |
| 137 | |
| 138 oldSizeOfArray = info->sizeOfArray; | |
| 139 if( newSize <= oldSizeOfArray ) return; | |
| 140 | |
| 141 oldArray = *(info->addrOfPtrToArray); | |
| 142 newArray = PR_int__malloc( newSize * sizeof(void *) ); | |
| 143 | |
| 144 for( i = 0; i < oldSizeOfArray; i++ ) | |
| 145 { | |
| 146 newArray[i] = oldArray[i]; | |
| 147 } | |
| 148 *(info->addrOfPtrToArray) = newArray; //change location of array-ptr | |
| 149 info->sizeOfArray = newSize; | |
| 150 | |
| 151 PR_int__free( oldArray ); | |
| 152 } | |
| 153 | |
| 154 /*Can't mix PR_int__malloc locations with external malloc locations -- so use | |
| 155 * this version inside PR, which will perform normal malloc in the core | |
| 156 * loop -- hopefully avoiding the annoying system-stack bugs.. | |
| 157 */ | |
| 158 void | |
| 159 increaseSizeOfDynArrayTo_Ext( PtrToPrivDynArray *info, int32 newSize ) | |
| 160 { int32 oldSizeOfArray, i; | |
| 161 void **newArray, **oldArray; | |
| 162 | |
| 163 oldSizeOfArray = info->sizeOfArray; | |
| 164 if( newSize <= oldSizeOfArray ) return; | |
| 165 | |
| 166 oldArray = *(info->addrOfPtrToArray); | |
| 167 newArray = malloc( newSize * sizeof(void *) ); | |
| 168 | |
| 169 for( i = 0; i < oldSizeOfArray; i++ ) | |
| 170 { | |
| 171 newArray[i] = oldArray[i]; | |
| 172 } | |
| 173 *(info->addrOfPtrToArray) = newArray; //change location of array-ptr | |
| 174 info->sizeOfArray = newSize; | |
| 175 | |
| 176 free( oldArray ); | |
| 177 } | |
| 178 | |
| 179 | |
| 180 /* Frees the array, plus the info | |
| 181 */ | |
| 182 void | |
| 183 freeDynArrayDeep( PtrToPrivDynArray *info, FreeFnPtr freeFnPtr ) | |
| 184 { | |
| 185 forAllInDynArrayDo( info, freeFnPtr ); | |
| 186 PR_int__free( *(info->addrOfPtrToArray) ); | |
| 187 PR_int__free( info ); | |
| 188 } | |
| 189 | |
| 190 /* Only frees the info | |
| 191 */ | |
| 192 void | |
| 193 freeDynArrayFlat( PtrToPrivDynArray *info ) | |
| 194 { | |
| 195 PR_int__free( info ); | |
| 196 } | |
| 197 | |
| 198 | |
| 199 /*The function has a fixed prototype: takes a void * returns void | |
| 200 * So, the function has to internally cast void * to whatever data struc.. | |
| 201 */ | |
| 202 void | |
| 203 forAllInDynArrayDo( PtrToPrivDynArray *info, DynArrayFnPtr fnPtr ) | |
| 204 { int32 idx; | |
| 205 void **array; | |
| 206 | |
| 207 array = *(info->addrOfPtrToArray); | |
| 208 for( idx = 0; idx < info->numInArray; idx++ ) | |
| 209 { | |
| 210 (*fnPtr)(array[idx]); | |
| 211 } | |
| 212 } | |
| 213 |
