annotate DynArray.c @ 9:bc91986481e1

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