Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > DynArray
view DynArray.c @ 35:59eaf81a9cc7
updated headers (fixed circular includes) and PR_int__malloc into PR__malloc
| author | Sean Halle <seanhalle@yahoo.com> |
|---|---|
| date | Tue, 23 Jul 2013 07:41:03 -0700 |
| parents | 958dcb7754ca |
| children | 82b36ebdc648 |
line source
1 /*
2 * Copyright 2010 OpenSourceCodeStewardshipFoundation
3 *
4 * Licensed under BSD
5 */
9 #include <stdio.h>
10 #include <malloc.h>
12 #include "DynArray.h"
13 #include "PR__common_includes/Services_offered_by_PR/Memory_Handling/vmalloc__wrapper_library.h"
15 //== declarations
16 void
17 increaseSizeOfDynArrayTo_Ext( PrivDynArrayInfo *info, int32 newSize );
18 //==
20 PrivDynArrayInfo *
21 makePrivDynArrayInfoFrom( void ***addrOfPtrToArray, int32 sizeOfArray )
22 { PrivDynArrayInfo *info;
24 info = PR__malloc( sizeof(PrivDynArrayInfo) );
26 info->addrOfPtrToArray = addrOfPtrToArray;
27 info->sizeOfArray = sizeOfArray;
28 info->numInArray = 0;
29 return info;
30 }
32 PrivDynArrayInfo *
33 makePrivDynArrayOfSize( void ***addrOfPtrToArray, int32 sizeOfArray )
34 { PrivDynArrayInfo *info;
36 info = PR__malloc( sizeof(PrivDynArrayInfo) );
38 info->addrOfPtrToArray = addrOfPtrToArray;
40 *(addrOfPtrToArray) = PR__malloc( sizeOfArray * sizeof(void *) );
41 info->sizeOfArray = sizeOfArray;
42 info->numInArray = 0;
43 return info;
44 }
46 PrivDynArrayInfo *
47 makePrivDynArrayOfSize_Ext( void ***addrOfPtrToArray, int32 sizeOfArray )
48 { PrivDynArrayInfo *info;
50 info = (PrivDynArrayInfo*) malloc( sizeof(PrivDynArrayInfo) );
52 info->addrOfPtrToArray = addrOfPtrToArray;
54 *(addrOfPtrToArray) = malloc( sizeOfArray * sizeof(void *) );
55 info->sizeOfArray = sizeOfArray;
56 info->numInArray = 0;
57 }
60 /*A dynamic array is same as any other array, but add a DynArrayInfo next
61 * to it. Accesses and updates of array indexes are done normally, it's
62 * only when add a new element into array that use the extra info.
63 * An add can cause the pointer to the normal array to change.. so must
64 * be protected to single VP at a time.
65 *
66 *Only need to use this Fn when need a new index, higher than any previous
67 */
68 int32
69 addToDynArray( void *value, PrivDynArrayInfo *info )
70 { int32 numInArray, sizeOfArray;
71 void **array;
73 numInArray = info->numInArray;
74 sizeOfArray = info->sizeOfArray;
76 if( numInArray >= sizeOfArray )
77 {
78 increaseSizeOfDynArrayTo( info, sizeOfArray * 2 );
79 }
81 array = *(info->addrOfPtrToArray);
82 array[ numInArray ] = value;
83 info->numInArray++;
85 return numInArray; //pre-incr value is the index put value into
86 }
87 int32
88 addToDynArray_Ext( void *value, PrivDynArrayInfo *info )
89 { int32 numInArray, sizeOfArray;
90 void **array;
92 numInArray = info->numInArray;
93 sizeOfArray = info->sizeOfArray;
95 if( numInArray >= sizeOfArray )
96 {
97 increaseSizeOfDynArrayTo_Ext( info, sizeOfArray * 2 );
98 }
100 array = *(info->addrOfPtrToArray);
101 array[ numInArray ] = value;
102 info->numInArray++;
104 return numInArray; //pre-incr value is the index put value into
105 }
108 /*Use this when know how many things going to add in -- then can do this
109 * once and use as normal array afterwards. If later add another chunk,
110 * do this again. Note, this makes new size be just big enough to hold
111 * highest index, so will do a linear number of copies if use only this.
112 *To cut down on number of copies, can use the increaseSizeTo Fn to
113 * exponentially increase size..
114 */
115 void
116 makeHighestDynArrayIndexBe( PrivDynArrayInfo *info, int32 highestIndex )
117 {
118 if( info->sizeOfArray <= highestIndex )
119 {
120 increaseSizeOfDynArrayTo( info, highestIndex + 1 );
121 }
122 info->numInArray = highestIndex + 1;
123 }
125 void
126 makeHighestDynArrayIndexBeAtLeast(PrivDynArrayInfo *info, int32 index)
127 {
128 if( index < info->numInArray ) return;
129 else makeHighestDynArrayIndexBe( info, index );
130 }
133 /*Only use this if certain new size is bigger than current size
134 */
135 void
136 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 = PR__malloc( 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 PR__free( oldArray );
154 }
156 /*Can't mix PR__malloc locations with external malloc locations -- so use
157 * this version inside PR, which will perform normal malloc in the core
158 * loop -- hopefully avoiding the annoying system-stack bugs..
159 */
160 void
161 increaseSizeOfDynArrayTo_Ext( PrivDynArrayInfo *info, int32 newSize )
162 { int32 oldsizeOfArray, i;
163 void **newArray, **oldArray;
165 oldsizeOfArray = info->sizeOfArray;
166 if( newSize <= oldsizeOfArray ) return;
168 oldArray = *(info->addrOfPtrToArray);
169 newArray = malloc( newSize * sizeof(void *) );
171 for( i = 0; i < oldsizeOfArray; i++ )
172 {
173 newArray[i] = oldArray[i];
174 }
175 *(info->addrOfPtrToArray) = newArray; //change location of array-ptr
176 info->sizeOfArray = newSize;
178 free( oldArray );
179 }
182 /* Frees the array, plus the info
183 */
184 void
185 freeDynArrayDeep( PrivDynArrayInfo *info, FreeFnPtr freeFnPtr )
186 {
187 forAllInDynArrayDo( info, freeFnPtr );
188 PR__free( *(info->addrOfPtrToArray) );
189 PR__free( info );
190 }
192 /* Only frees the info
193 */
194 void
195 freeDynArrayFlat( PrivDynArrayInfo *info )
196 {
197 PR__free( info );
198 }
201 /*The function has a fixed prototype: takes a void * returns void
202 * So, the function has to internally cast void * to whatever data struc..
203 */
204 void
205 forAllInDynArrayDo( PrivDynArrayInfo *info, DynArrayFnPtr fnPtr )
206 { int32 idx;
207 void **array;
209 array = *(info->addrOfPtrToArray);
210 for( idx = 0; idx < info->numInArray; idx++ )
211 {
212 (*fnPtr)(array[idx]);
213 }
214 }
