view DynArray.c @ 8:015aab562ace

Nov 14 vers -- Fixed bug in make() where didn't return the info
author Me
date Sun, 14 Nov 2010 11:12:40 -0800
parents f4b108f21041
children bc91986481e1
line source
1 /*
2 * Copyright 2010 OpenSourceCodeStewardshipFoundation
3 *
4 * Licensed under BSD
5 */
9 #include <stdio.h>
11 #include "DynArray.h"
15 PrivDynArrayInfo *
16 makePrivDynArrayInfoFrom( void ***addrOfPtrToArray, int32 sizeOfArray )
17 { PrivDynArrayInfo *info;
19 info = VMS__malloc( sizeof(PrivDynArrayInfo) );
21 info->addrOfPtrToArray = addrOfPtrToArray;
22 info->sizeOfArray = sizeOfArray;
23 info->numInArray = 0;
24 return info;
25 }
27 PrivDynArrayInfo *
28 makePrivDynArrayOfSize( void ***addrOfPtrToArray, int32 sizeOfArray )
29 { PrivDynArrayInfo *info;
31 info = VMS__malloc( sizeof(PrivDynArrayInfo) );
33 info->addrOfPtrToArray = addrOfPtrToArray;
35 *(addrOfPtrToArray) = VMS__malloc( sizeOfArray * sizeof(void *) );
36 info->sizeOfArray = sizeOfArray;
37 info->numInArray = 0;
38 return info;
39 }
42 /*A dynamic array is same as any other array, but add a DynArrayInfo next
43 * to it. Accesses and updates of array indexes are done normally, it's
44 * only when add a new element into array that use the extra info.
45 * An add can cause the pointer to the normal array to change.. so must
46 * be protected to single VP at a time.
47 *
48 *Only need to use this Fn when need a new index, higher than any previous
49 */
50 int32
51 addToDynArray( void *value, PrivDynArrayInfo *info )
52 { int32 numInArray, sizeOfArray;
53 void **array;
55 numInArray = info->numInArray;
56 sizeOfArray = info->sizeOfArray;
58 if( numInArray >= sizeOfArray )
59 {
60 increaseSizeOfDynArrayTo( info, sizeOfArray * 2 );
61 }
63 array = *(info->addrOfPtrToArray);
64 array[ numInArray ] = value;
65 info->numInArray++;
67 return numInArray; //pre-incr value is the index put value into
68 }
69 int32
70 VMS_ext__addToDynArray( void *value, PrivDynArrayInfo *info )
71 { int32 numInArray, sizeOfArray;
72 void **array;
74 numInArray = info->numInArray;
75 sizeOfArray = info->sizeOfArray;
77 if( numInArray >= sizeOfArray )
78 {
79 VMS_ext__increaseSizeOfDynArrayTo( info, sizeOfArray * 2 );
80 }
82 array = *(info->addrOfPtrToArray);
83 array[ numInArray ] = value;
84 info->numInArray++;
86 return numInArray; //pre-incr value is the index put value into
87 }
90 /*Use this when know how many things going to add in -- then can do this
91 * once and use as normal array afterwards. If later add another chunk,
92 * do this again. Note, this makes new size be just big enough to hold
93 * highest index, so will do a linear number of copies if use only this.
94 *To cut down on number of copies, can use the increaseSizeTo Fn to
95 * exponentially increase size..
96 */
97 void
98 makeHighestDynArrayIndexBe( PrivDynArrayInfo *info, int32 highestIndex )
99 {
100 if( info->sizeOfArray <= highestIndex )
101 {
102 increaseSizeOfDynArrayTo( info, highestIndex + 1 );
103 }
104 info->numInArray = highestIndex + 1;
105 }
108 /*Only use this if certain new size is bigger than current size
109 */
110 void
111 increaseSizeOfDynArrayTo( PrivDynArrayInfo *info, int32 newSize )
112 { int32 oldSizeOfArray, i;
113 void **newArray, **oldArray;
115 oldSizeOfArray = info->sizeOfArray;
116 if( newSize <= oldSizeOfArray ) return;
118 oldArray = *(info->addrOfPtrToArray);
119 newArray = VMS__malloc( newSize * sizeof(void *) );
121 for( i = 0; i < oldSizeOfArray; i++ )
122 {
123 newArray[i] = oldArray[i];
124 }
125 *(info->addrOfPtrToArray) = newArray; //change location of array-ptr
126 info->sizeOfArray = newSize;
128 VMS__free( oldArray );
129 }
131 /*Can't mix VMS__malloc locations with external malloc locations -- so use
132 * this version inside VMS, which will perform normal malloc in the core
133 * loop -- hopefully avoiding the annoying system-stack bugs..
134 */
135 void
136 VMS_ext__increaseSizeOfDynArrayTo( PrivDynArrayInfo *info, int32 newSize )
137 { int32 oldSizeOfArray, i;
138 void **newArray, **oldArray;
140 oldSizeOfArray = info->sizeOfArray;
141 if( newSize <= oldSizeOfArray ) return;
143 oldArray = *(info->addrOfPtrToArray);
144 newArray = VMS__malloc_in_ext( newSize * sizeof(void *) );
146 for( i = 0; i < oldSizeOfArray; i++ )
147 {
148 newArray[i] = oldArray[i];
149 }
150 *(info->addrOfPtrToArray) = newArray; //change location of array-ptr
151 info->sizeOfArray = newSize;
153 VMS__free( oldArray );
154 }
157 /* Frees the array, plus the info
158 */
159 void
160 freeDynArrayDeep( PrivDynArrayInfo *info, FreeFnPtr freeFnPtr )
161 {
162 forAllInDynArrayDo( info, freeFnPtr );
163 VMS__free( *(info->addrOfPtrToArray) );
164 VMS__free( info );
165 }
167 /* Only frees the info
168 */
169 void
170 freeDynArrayFlat( PrivDynArrayInfo *info )
171 {
172 VMS__free( info );
173 }
176 /*The function has a fixed prototype: takes a void * returns void
177 * So, the function has to internally cast void * to whatever data struc..
178 */
179 void
180 forAllInDynArrayDo( PrivDynArrayInfo *info, DynArrayFnPtr fnPtr )
181 { int32 idx;
182 void **array;
184 array = *(info->addrOfPtrToArray);
185 for( idx = 0; idx < info->numInArray; idx++ )
186 {
187 (*fnPtr)(array[idx]);
188 }
189 }