view DynArray.c @ 10:20f0996a8400

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