annotate DynArray.c @ 32:958dcb7754ca

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