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