diff DynArray2.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
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/DynArray2.c	Fri Jul 19 12:27:43 2013 -0700
     1.3 @@ -0,0 +1,158 @@
     1.4 +/*
     1.5 + * Copyright 2010  OpenSourceCodeStewardshipFoundation
     1.6 + *
     1.7 + * Licensed under BSD
     1.8 + */
     1.9 +
    1.10 +
    1.11 +
    1.12 +#include <stdio.h>
    1.13 +#include <malloc.h>
    1.14 +
    1.15 +#include "DynArray.h"
    1.16 +
    1.17 +//== declarations
    1.18 +#define giveInfoFor( array )   &(((PrivDynArrayInfo*)array)[-1])
    1.19 +//==
    1.20 +
    1.21 +/*This updates the contents of the array variable, by side-effect.  There can
    1.22 + * only ever be one variable that holds a pointer to the dyn array, and all
    1.23 + * accesses must use that variable.  An add can cause the contents of that
    1.24 + * variable to change!  (Meaning the position of the array has moved)
    1.25 + */
    1.26 +void *
    1.27 +makePrivDynArray2( void ***addrOfArrayVar, int32 numElemsToAllocate, int32 sizeOfElem )
    1.28 + { PrivDynArrayInfo *info;
    1.29 +   int32 bytesInArray  = numElemsToAllocate * sizeOfElem;
    1.30 +   
    1.31 +   info = PR_int__malloc( sizeof(PrivDynArrayInfo) + bytesInArray );
    1.32 +   info->addrOfPtrToArray = addrOfArrayVar;
    1.33 +   info->sizeOfArray      = numElemsToAllocate;
    1.34 +   info->sizeOfElem       = sizeOfElem;
    1.35 +   info->numInArray       = 0;
    1.36 +   return &(info[1]); //skip over prolog -- info is prolog
    1.37 + }
    1.38 +
    1.39 +
    1.40 +/*A dynamic array is same as any other array, but add a DynArrayInfo next
    1.41 + * to it.  Accesses and updates of array indexes are done normally, it's
    1.42 + * only when add a new element into array that use the extra info.
    1.43 + * An add can cause the pointer to the normal array to change..  so must
    1.44 + * be protected to single VP at a time.
    1.45 + *
    1.46 + *Only need to use this Fn when need a new index, higher than any previous
    1.47 + */
    1.48 +int32
    1.49 +addToDynArray2( void *value, void **array )
    1.50 + { int32 numInArray, sizeOfArray;
    1.51 +   PrivDynArrayInfo *info = giveInfoFor(array); //go backward to prolog
    1.52 +   
    1.53 +   numInArray  = info->numInArray;
    1.54 +   sizeOfArray = info->sizeOfArray;
    1.55 +
    1.56 +   if( numInArray >= sizeOfArray )
    1.57 +    {
    1.58 +      array = increaseSizeOfDynArrayTo2( array, sizeOfArray * 2 );
    1.59 +      info  = giveInfoFor( array );
    1.60 +    }
    1.61 +
    1.62 +   array[ numInArray ] = value;
    1.63 +   info->numInArray++;
    1.64 +
    1.65 +   return numInArray; //index of last elem is one less than num in array
    1.66 + }
    1.67 +
    1.68 +
    1.69 +/*Sets num in array to exactly value give 
    1.70 + *Use this when know how many things going to add in -- then can do this
    1.71 + * once and use as normal array afterwards.  If later add another chunk,
    1.72 + * do this again.  Note, this makes new size be just big enough to hold
    1.73 + * highest index, so will do a linear number of copies if use only this.
    1.74 + *To cut down on number of copies, can use the increaseSizeTo Fn to
    1.75 + * exponentially increase size..
    1.76 + */
    1.77 +void
    1.78 +makeNumInArrayBe2( void **array, int32 numInArray )
    1.79 + { PrivDynArrayInfo *info = giveInfoFor( array );
    1.80 +   
    1.81 +   if( info->sizeOfArray <= numInArray )
    1.82 +    {
    1.83 +      array = increaseSizeOfDynArrayTo2( array, numInArray );
    1.84 +      info = giveInfoFor( array );
    1.85 +    }
    1.86 +   info->numInArray = numInArray; //num is highest index plus 1
    1.87 + }
    1.88 +
    1.89 +/*Allows highest index to remain higher than index give*/
    1.90 +void
    1.91 +makeHighestDynArrayIndexBeAtLeast2( void **array, int32 index)
    1.92 + { PrivDynArrayInfo *info = giveInfoFor( array );
    1.93 + 
    1.94 +   if( index < info->numInArray ) return; //num added diff than size
    1.95 +   else makeNumInArrayBe2( array, index );
    1.96 + }
    1.97 +
    1.98 +
    1.99 +/*Only use this if certain new size is bigger than current size
   1.100 + */
   1.101 +void **
   1.102 +increaseSizeOfDynArrayTo2( void **oldArray, int32 newSize )
   1.103 + { int32 oldsizeOfArray, i, numBytesToCopy;
   1.104 +   void **newArray;
   1.105 +   PrivDynArrayInfo  *oldInfo = giveInfoFor( oldArray );
   1.106 +   PrivDynArrayInfo  *newInfo;
   1.107 +
   1.108 +   oldsizeOfArray   = oldInfo->sizeOfArray;
   1.109 +   if( newSize <= oldsizeOfArray ) return;
   1.110 +
   1.111 +   newInfo = PR_int__malloc( newSize * oldInfo->sizeOfElem + sizeof(PrivDynArrayInfo) );
   1.112 +   newArray = &(newInfo[1]);
   1.113 +   
   1.114 +   numBytesToCopy = oldInfo->numInArray * oldInfo->sizeOfElem + sizeof(PrivDynArrayInfo);
   1.115 +   memcpy( newInfo, oldInfo, numBytesToCopy ); //copies info + array contents
   1.116 +   
   1.117 +   *(newInfo->addrOfPtrToArray) = newArray; //change contents of array var
   1.118 +   newInfo->sizeOfArray = newSize;
   1.119 +
   1.120 +   PR_int__free( oldInfo );
   1.121 +   
   1.122 +   return newArray;
   1.123 + }
   1.124 +
   1.125 +
   1.126 +/* Frees the array, plus the info
   1.127 + */
   1.128 +void
   1.129 +freeDynArrayDeep2( void *array, FreeFnPtr freeFnPtr )
   1.130 + { PrivDynArrayInfo  *info = giveInfoFor( array );
   1.131 + 
   1.132 +   forAllInDynArrayDo2( array, freeFnPtr );
   1.133 +   PR_int__free( info );
   1.134 + }
   1.135 +
   1.136 +/* Only frees the info
   1.137 + */
   1.138 +void
   1.139 +freeDynArrayFlat2( void *array )
   1.140 + { PrivDynArrayInfo  *info = giveInfoFor( array );
   1.141 + 
   1.142 +   PR_int__free( info );
   1.143 + }
   1.144 +
   1.145 +
   1.146 +/*The function has a fixed prototype: takes a void * returns void
   1.147 + * So, the function has to internally cast void * to whatever data struc..
   1.148 + */
   1.149 +void
   1.150 +forAllInDynArrayDo2( void *array, DynArrayFnPtr fnPtr )
   1.151 + { PrivDynArrayInfo  *info = giveInfoFor( array );
   1.152 +   int32 idx, sizeOfElem;
   1.153 +   void *addrOfElem;
   1.154 +   
   1.155 +   sizeOfElem = info->sizeOfElem;
   1.156 +   for( idx = 0; idx < info->numInArray; idx++ )
   1.157 +    { addrOfElem = ((int8 *)array) + idx * sizeOfElem;
   1.158 +      (*fnPtr)( addrOfElem );
   1.159 +    }
   1.160 + }
   1.161 +