Mercurial > cgi-bin > hgwebdir.cgi > VMS > C_Libraries > DynArray
view DynArray.c @ 18:ef65bdf3ce16
updated for VMS name chgs from VMS__malloc to VMS_int__malloc
| author | Me@portablequad |
|---|---|
| date | Sun, 12 Feb 2012 01:46:42 -0800 |
| parents | 62b3a4793b6e |
| children | 3e8e1a2a10f5 |
line source
1 /*
2 * Copyright 2010 OpenSourceCodeStewardshipFoundation
3 *
4 * Licensed under BSD
5 */
9 #include <stdio.h>
11 #include "DynArray.h"
13 //== declarations
14 void
15 increaseSizeOfDynArrayTo_Ext( PrivDynArrayInfo *info, int32 newSize );
16 //==
18 PrivDynArrayInfo *
19 makePrivDynArrayInfoFrom( void ***addrOfPtrToArray, int32 sizeOfArray )
20 { PrivDynArrayInfo *info;
22 info = VMS_int__malloc( sizeof(PrivDynArrayInfo) );
24 info->addrOfPtrToArray = addrOfPtrToArray;
25 info->sizeOfArray = sizeOfArray;
26 info->numInArray = 0;
27 return info;
28 }
30 PrivDynArrayInfo *
31 makePrivDynArrayOfSize( void ***addrOfPtrToArray, int32 sizeOfArray )
32 { PrivDynArrayInfo *info;
34 info = VMS_int__malloc( sizeof(PrivDynArrayInfo) );
36 info->addrOfPtrToArray = addrOfPtrToArray;
38 *(addrOfPtrToArray) = VMS_int__malloc( sizeOfArray * sizeof(void *) );
39 info->sizeOfArray = sizeOfArray;
40 info->numInArray = 0;
41 return info;
42 }
44 PrivDynArrayInfo *
45 makePrivDynArrayOfSize_Ext( void ***addrOfPtrToArray, int32 sizeOfArray )
46 { PrivDynArrayInfo *info;
48 info = malloc( sizeof(PrivDynArrayInfo) );
50 info->addrOfPtrToArray = addrOfPtrToArray;
52 *(addrOfPtrToArray) = malloc( sizeOfArray * sizeof(void *) );
53 info->sizeOfArray = sizeOfArray;
54 info->numInArray = 0;
55 }
58 /*A dynamic array is same as any other array, but add a DynArrayInfo next
59 * to it. Accesses and updates of array indexes are done normally, it's
60 * only when add a new element into array that use the extra info.
61 * An add can cause the pointer to the normal array to change.. so must
62 * be protected to single VP at a time.
63 *
64 *Only need to use this Fn when need a new index, higher than any previous
65 */
66 int32
67 addToDynArray( void *value, PrivDynArrayInfo *info )
68 { int32 numInArray, sizeOfArray;
69 void **array;
71 numInArray = info->numInArray;
72 sizeOfArray = info->sizeOfArray;
74 if( numInArray >= sizeOfArray )
75 {
76 increaseSizeOfDynArrayTo( info, sizeOfArray * 2 );
77 }
79 array = *(info->addrOfPtrToArray);
80 array[ numInArray ] = value;
81 info->numInArray++;
83 return numInArray; //pre-incr value is the index put value into
84 }
85 int32
86 addToDynArray_Ext( void *value, PrivDynArrayInfo *info )
87 { int32 numInArray, sizeOfArray;
88 void **array;
90 numInArray = info->numInArray;
91 sizeOfArray = info->sizeOfArray;
93 if( numInArray >= sizeOfArray )
94 {
95 increaseSizeOfDynArrayTo_Ext( info, sizeOfArray * 2 );
96 }
98 array = *(info->addrOfPtrToArray);
99 array[ numInArray ] = value;
100 info->numInArray++;
102 return numInArray; //pre-incr value is the index put value into
103 }
106 /*Use this when know how many things going to add in -- then can do this
107 * once and use as normal array afterwards. If later add another chunk,
108 * do this again. Note, this makes new size be just big enough to hold
109 * highest index, so will do a linear number of copies if use only this.
110 *To cut down on number of copies, can use the increaseSizeTo Fn to
111 * exponentially increase size..
112 */
113 void
114 makeHighestDynArrayIndexBe( PrivDynArrayInfo *info, int32 highestIndex )
115 {
116 if( info->sizeOfArray <= highestIndex )
117 {
118 increaseSizeOfDynArrayTo( info, highestIndex + 1 );
119 }
120 info->numInArray = highestIndex + 1;
121 }
123 void
124 makeHighestDynArrayIndexBeAtLeast(PrivDynArrayInfo *info, int32 index)
125 {
126 if( index < info->numInArray ) return;
127 else makeHighestDynArrayIndexBe( info, index );
128 }
131 /*Only use this if certain new size is bigger than current size
132 */
133 void
134 increaseSizeOfDynArrayTo( PrivDynArrayInfo *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_int__malloc( 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_int__free( oldArray );
152 }
154 /*Can't mix VMS__malloc locations with external malloc locations -- so use
155 * this version inside VMS, which will perform normal malloc in the core
156 * loop -- hopefully avoiding the annoying system-stack bugs..
157 */
158 void
159 increaseSizeOfDynArrayTo_Ext( PrivDynArrayInfo *info, int32 newSize )
160 { int32 oldSizeOfArray, i;
161 void **newArray, **oldArray;
163 oldSizeOfArray = info->sizeOfArray;
164 if( newSize <= oldSizeOfArray ) return;
166 oldArray = *(info->addrOfPtrToArray);
167 newArray = malloc( newSize * sizeof(void *) );
169 for( i = 0; i < oldSizeOfArray; i++ )
170 {
171 newArray[i] = oldArray[i];
172 }
173 *(info->addrOfPtrToArray) = newArray; //change location of array-ptr
174 info->sizeOfArray = newSize;
176 free( oldArray );
177 }
180 /* Frees the array, plus the info
181 */
182 void
183 freeDynArrayDeep( PrivDynArrayInfo *info, FreeFnPtr freeFnPtr )
184 {
185 forAllInDynArrayDo( info, freeFnPtr );
186 VMS_int__free( *(info->addrOfPtrToArray) );
187 VMS_int__free( info );
188 }
190 /* Only frees the info
191 */
192 void
193 freeDynArrayFlat( PrivDynArrayInfo *info )
194 {
195 VMS_int__free( info );
196 }
199 /*The function has a fixed prototype: takes a void * returns void
200 * So, the function has to internally cast void * to whatever data struc..
201 */
202 void
203 forAllInDynArrayDo( PrivDynArrayInfo *info, DynArrayFnPtr fnPtr )
204 { int32 idx;
205 void **array;
207 array = *(info->addrOfPtrToArray);
208 for( idx = 0; idx < info->numInArray; idx++ )
209 {
210 (*fnPtr)(array[idx]);
211 }
212 }
