view DynArray.c @ 5:2915fb26c9e2

Changed malloc and free to VMS__malloc and VMS__free
author Me
date Sun, 31 Oct 2010 20:26:32 -0700
parents f35e64d7a42b
children f4b108f21041
line source
1 /*
2 * Copyright 2010 OpenSourceCodeStewardshipFoundation
3 *
4 * Licensed under BSD
5 */
9 #include <stdio.h>
11 #include "DynArray.h"
15 DynArrayInfo *
16 makeDynArrayInfoFrom( void ***addrOfPtrToArray, int32 sizeOfArray )
17 { DynArrayInfo *info;
19 info = VMS__malloc( sizeof(DynArrayInfo) );
21 info->addrOfPtrToArray = addrOfPtrToArray;
22 info->sizeOfArray = sizeOfArray;
23 info->numInArray = 0;
24 }
26 DynArrayInfo *
27 makeDynArrayOfSize( void ***addrOfPtrToArray, int32 sizeOfArray )
28 { DynArrayInfo *info;
30 info = VMS__malloc( sizeof(DynArrayInfo) );
32 info->addrOfPtrToArray = addrOfPtrToArray;
34 *(addrOfPtrToArray) = VMS__malloc( sizeOfArray * sizeof(void *) );
35 info->sizeOfArray = sizeOfArray;
36 info->numInArray = 0;
37 }
40 /*A dynamic array is same as any other array, but add a DynArrayInfo next
41 * to it. Accesses and updates of array indexes are done normally, it's
42 * only when add a new element into array that use the extra info.
43 * An add can cause the pointer to the normal array to change.. so must
44 * be protected to single VP at a time.
45 *
46 *Only need to use this Fn when need a new index, higher than any previous
47 */
48 int32
49 addToDynArray( void *value, DynArrayInfo *info )
50 { int32 numInArray, sizeOfArray;
51 void **array;
53 numInArray = info->numInArray;
54 sizeOfArray = info->sizeOfArray;
56 if( numInArray >= sizeOfArray )
57 {
58 increaseSizeOfDynArrayTo( info, sizeOfArray * 2 );
59 }
61 array = *(info->addrOfPtrToArray);
62 array[ numInArray ] = value;
63 info->numInArray++;
65 return numInArray; //pre-incr value is the index put value into
66 }
67 int32
68 VMS_ext__addToDynArray( void *value, DynArrayInfo *info )
69 { int32 numInArray, sizeOfArray;
70 void **array;
72 numInArray = info->numInArray;
73 sizeOfArray = info->sizeOfArray;
75 if( numInArray >= sizeOfArray )
76 {
77 VMS_ext__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 }
88 /*Use this when know how many things going to add in -- then can do this
89 * once and use as normal array afterwards. If later add another chunk,
90 * do this again. Note, this makes new size be just big enough to hold
91 * highest index, so will do a linear number of copies if use only this.
92 *To cut down on number of copies, can use the increaseSizeTo Fn to
93 * exponentially increase size..
94 */
95 void
96 makeHighestDynArrayIndexBe( DynArrayInfo *info, int32 highestIndex )
97 {
98 if( info->sizeOfArray <= highestIndex )
99 {
100 increaseSizeOfDynArrayTo( info, highestIndex + 1 );
101 }
102 info->numInArray = highestIndex + 1;
103 }
106 /*Only use this if certain new size is bigger than current size
107 */
108 void
109 increaseSizeOfDynArrayTo( DynArrayInfo *info, int32 newSize )
110 { int32 oldSizeOfArray, i;
111 void **newArray, **oldArray;
113 oldSizeOfArray = info->sizeOfArray;
114 if( newSize <= oldSizeOfArray ) return;
116 oldArray = *(info->addrOfPtrToArray);
117 newArray = VMS__malloc( newSize * sizeof(void *) );
119 for( i = 0; i < oldSizeOfArray; i++ )
120 {
121 newArray[i] = oldArray[i];
122 }
123 *(info->addrOfPtrToArray) = newArray; //change location of array-ptr
124 info->sizeOfArray = newSize;
126 VMS__free( oldArray );
127 }
129 /*Can't mix VMS__malloc locations with external malloc locations -- so use
130 * this version inside VMS, which will perform normal malloc in the core
131 * loop -- hopefully avoiding the annoying system-stack bugs..
132 */
133 void
134 VMS_ext__increaseSizeOfDynArrayTo( DynArrayInfo *info, int32 newSize )
135 { int32 oldSizeOfArray, i;
136 void **newArray, **oldArray;
138 oldSizeOfArray = info->sizeOfArray;
139 if( newSize <= oldSizeOfArray ) return;
141 oldArray = *(info->addrOfPtrToArray);
142 newArray = VMS__malloc_in_ext( newSize * sizeof(void *) );
144 for( i = 0; i < oldSizeOfArray; i++ )
145 {
146 newArray[i] = oldArray[i];
147 }
148 *(info->addrOfPtrToArray) = newArray; //change location of array-ptr
149 info->sizeOfArray = newSize;
151 VMS__free( oldArray );
152 }
155 /* Frees the array, plus the info
156 */
157 void
158 freeDynArrayDeep( DynArrayInfo *info, FreeFnPtr freeFnPtr )
159 {
160 forAllInDynArrayDo( info, freeFnPtr );
161 VMS__free( *(info->addrOfPtrToArray) );
162 VMS__free( info );
163 }
165 /* Only frees the info
166 */
167 void
168 freeDynArrayFlat( DynArrayInfo *info )
169 {
170 VMS__free( info );
171 }
174 /*The function has a fixed prototype: takes a void * returns void
175 * So, the function has to internally cast void * to whatever data struc..
176 */
177 void
178 forAllInDynArrayDo( DynArrayInfo *info, DynArrayFnPtr fnPtr )
179 { int32 idx;
180 void **array;
182 array = *(info->addrOfPtrToArray);
183 for( idx = 0; idx < info->numInArray; idx++ )
184 {
185 (*fnPtr)(array[idx]);
186 }
187 }