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