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