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