| 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 #include <malloc.h>
|
|
seanhalle@33
|
11
|
|
seanhalle@33
|
12 #include "DynArray.h"
|
|
seanhalle@33
|
13
|
|
seanhalle@33
|
14 //== declarations
|
|
seanhalle@33
|
15 #define giveInfoFor( array ) &(((PrivDynArrayInfo*)array)[-1])
|
|
seanhalle@33
|
16 //==
|
|
seanhalle@33
|
17
|
|
seanhalle@33
|
18 /*This updates the contents of the array variable, by side-effect. There can
|
|
seanhalle@33
|
19 * only ever be one variable that holds a pointer to the dyn array, and all
|
|
seanhalle@33
|
20 * accesses must use that variable. An add can cause the contents of that
|
|
seanhalle@33
|
21 * variable to change! (Meaning the position of the array has moved)
|
|
seanhalle@33
|
22 */
|
|
seanhalle@33
|
23 void *
|
|
seanhalle@33
|
24 makePrivDynArray2( void ***addrOfArrayVar, int32 numElemsToAllocate, int32 sizeOfElem )
|
|
seanhalle@33
|
25 { PrivDynArrayInfo *info;
|
|
seanhalle@33
|
26 int32 bytesInArray = numElemsToAllocate * sizeOfElem;
|
|
seanhalle@33
|
27
|
|
seanhalle@33
|
28 info = PR_int__malloc( sizeof(PrivDynArrayInfo) + bytesInArray );
|
|
seanhalle@33
|
29 info->addrOfPtrToArray = addrOfArrayVar;
|
|
seanhalle@33
|
30 info->sizeOfArray = numElemsToAllocate;
|
|
seanhalle@33
|
31 info->sizeOfElem = sizeOfElem;
|
|
seanhalle@33
|
32 info->numInArray = 0;
|
|
seanhalle@33
|
33 return &(info[1]); //skip over prolog -- info is prolog
|
|
seanhalle@33
|
34 }
|
|
seanhalle@33
|
35
|
|
seanhalle@33
|
36
|
|
seanhalle@33
|
37 /*A dynamic array is same as any other array, but add a DynArrayInfo next
|
|
seanhalle@33
|
38 * to it. Accesses and updates of array indexes are done normally, it's
|
|
seanhalle@33
|
39 * only when add a new element into array that use the extra info.
|
|
seanhalle@33
|
40 * An add can cause the pointer to the normal array to change.. so must
|
|
seanhalle@33
|
41 * be protected to single VP at a time.
|
|
seanhalle@33
|
42 *
|
|
seanhalle@33
|
43 *Only need to use this Fn when need a new index, higher than any previous
|
|
seanhalle@33
|
44 */
|
|
seanhalle@33
|
45 int32
|
|
seanhalle@33
|
46 addToDynArray2( void *value, void **array )
|
|
seanhalle@33
|
47 { int32 numInArray, sizeOfArray;
|
|
seanhalle@33
|
48 PrivDynArrayInfo *info = giveInfoFor(array); //go backward to prolog
|
|
seanhalle@33
|
49
|
|
seanhalle@33
|
50 numInArray = info->numInArray;
|
|
seanhalle@33
|
51 sizeOfArray = info->sizeOfArray;
|
|
seanhalle@33
|
52
|
|
seanhalle@33
|
53 if( numInArray >= sizeOfArray )
|
|
seanhalle@33
|
54 {
|
|
seanhalle@33
|
55 array = increaseSizeOfDynArrayTo2( array, sizeOfArray * 2 );
|
|
seanhalle@33
|
56 info = giveInfoFor( array );
|
|
seanhalle@33
|
57 }
|
|
seanhalle@33
|
58
|
|
seanhalle@33
|
59 array[ numInArray ] = value;
|
|
seanhalle@33
|
60 info->numInArray++;
|
|
seanhalle@33
|
61
|
|
seanhalle@33
|
62 return numInArray; //index of last elem is one less than num in array
|
|
seanhalle@33
|
63 }
|
|
seanhalle@33
|
64
|
|
seanhalle@33
|
65
|
|
seanhalle@33
|
66 /*Sets num in array to exactly value give
|
|
seanhalle@33
|
67 *Use this when know how many things going to add in -- then can do this
|
|
seanhalle@33
|
68 * once and use as normal array afterwards. If later add another chunk,
|
|
seanhalle@33
|
69 * do this again. Note, this makes new size be just big enough to hold
|
|
seanhalle@33
|
70 * highest index, so will do a linear number of copies if use only this.
|
|
seanhalle@33
|
71 *To cut down on number of copies, can use the increaseSizeTo Fn to
|
|
seanhalle@33
|
72 * exponentially increase size..
|
|
seanhalle@33
|
73 */
|
|
seanhalle@33
|
74 void
|
|
seanhalle@33
|
75 makeNumInArrayBe2( void **array, int32 numInArray )
|
|
seanhalle@33
|
76 { PrivDynArrayInfo *info = giveInfoFor( array );
|
|
seanhalle@33
|
77
|
|
seanhalle@33
|
78 if( info->sizeOfArray <= numInArray )
|
|
seanhalle@33
|
79 {
|
|
seanhalle@33
|
80 array = increaseSizeOfDynArrayTo2( array, numInArray );
|
|
seanhalle@33
|
81 info = giveInfoFor( array );
|
|
seanhalle@33
|
82 }
|
|
seanhalle@33
|
83 info->numInArray = numInArray; //num is highest index plus 1
|
|
seanhalle@33
|
84 }
|
|
seanhalle@33
|
85
|
|
seanhalle@33
|
86 /*Allows highest index to remain higher than index give*/
|
|
seanhalle@33
|
87 void
|
|
seanhalle@33
|
88 makeHighestDynArrayIndexBeAtLeast2( void **array, int32 index)
|
|
seanhalle@33
|
89 { PrivDynArrayInfo *info = giveInfoFor( array );
|
|
seanhalle@33
|
90
|
|
seanhalle@33
|
91 if( index < info->numInArray ) return; //num added diff than size
|
|
seanhalle@33
|
92 else makeNumInArrayBe2( array, index );
|
|
seanhalle@33
|
93 }
|
|
seanhalle@33
|
94
|
|
seanhalle@33
|
95
|
|
seanhalle@33
|
96 /*Only use this if certain new size is bigger than current size
|
|
seanhalle@33
|
97 */
|
|
seanhalle@33
|
98 void **
|
|
seanhalle@33
|
99 increaseSizeOfDynArrayTo2( void **oldArray, int32 newSize )
|
|
seanhalle@33
|
100 { int32 oldsizeOfArray, i, numBytesToCopy;
|
|
seanhalle@33
|
101 void **newArray;
|
|
seanhalle@33
|
102 PrivDynArrayInfo *oldInfo = giveInfoFor( oldArray );
|
|
seanhalle@33
|
103 PrivDynArrayInfo *newInfo;
|
|
seanhalle@33
|
104
|
|
seanhalle@33
|
105 oldsizeOfArray = oldInfo->sizeOfArray;
|
|
seanhalle@33
|
106 if( newSize <= oldsizeOfArray ) return;
|
|
seanhalle@33
|
107
|
|
seanhalle@33
|
108 newInfo = PR_int__malloc( newSize * oldInfo->sizeOfElem + sizeof(PrivDynArrayInfo) );
|
|
seanhalle@33
|
109 newArray = &(newInfo[1]);
|
|
seanhalle@33
|
110
|
|
seanhalle@33
|
111 numBytesToCopy = oldInfo->numInArray * oldInfo->sizeOfElem + sizeof(PrivDynArrayInfo);
|
|
seanhalle@33
|
112 memcpy( newInfo, oldInfo, numBytesToCopy ); //copies info + array contents
|
|
seanhalle@33
|
113
|
|
seanhalle@33
|
114 *(newInfo->addrOfPtrToArray) = newArray; //change contents of array var
|
|
seanhalle@33
|
115 newInfo->sizeOfArray = newSize;
|
|
seanhalle@33
|
116
|
|
seanhalle@33
|
117 PR_int__free( oldInfo );
|
|
seanhalle@33
|
118
|
|
seanhalle@33
|
119 return newArray;
|
|
seanhalle@33
|
120 }
|
|
seanhalle@33
|
121
|
|
seanhalle@33
|
122
|
|
seanhalle@33
|
123 /* Frees the array, plus the info
|
|
seanhalle@33
|
124 */
|
|
seanhalle@33
|
125 void
|
|
seanhalle@33
|
126 freeDynArrayDeep2( void *array, FreeFnPtr freeFnPtr )
|
|
seanhalle@33
|
127 { PrivDynArrayInfo *info = giveInfoFor( array );
|
|
seanhalle@33
|
128
|
|
seanhalle@33
|
129 forAllInDynArrayDo2( array, freeFnPtr );
|
|
seanhalle@33
|
130 PR_int__free( info );
|
|
seanhalle@33
|
131 }
|
|
seanhalle@33
|
132
|
|
seanhalle@33
|
133 /* Only frees the info
|
|
seanhalle@33
|
134 */
|
|
seanhalle@33
|
135 void
|
|
seanhalle@33
|
136 freeDynArrayFlat2( void *array )
|
|
seanhalle@33
|
137 { PrivDynArrayInfo *info = giveInfoFor( array );
|
|
seanhalle@33
|
138
|
|
seanhalle@33
|
139 PR_int__free( info );
|
|
seanhalle@33
|
140 }
|
|
seanhalle@33
|
141
|
|
seanhalle@33
|
142
|
|
seanhalle@33
|
143 /*The function has a fixed prototype: takes a void * returns void
|
|
seanhalle@33
|
144 * So, the function has to internally cast void * to whatever data struc..
|
|
seanhalle@33
|
145 */
|
|
seanhalle@33
|
146 void
|
|
seanhalle@33
|
147 forAllInDynArrayDo2( void *array, DynArrayFnPtr fnPtr )
|
|
seanhalle@33
|
148 { PrivDynArrayInfo *info = giveInfoFor( array );
|
|
seanhalle@33
|
149 int32 idx, sizeOfElem;
|
|
seanhalle@33
|
150 void *addrOfElem;
|
|
seanhalle@33
|
151
|
|
seanhalle@33
|
152 sizeOfElem = info->sizeOfElem;
|
|
seanhalle@33
|
153 for( idx = 0; idx < info->numInArray; idx++ )
|
|
seanhalle@33
|
154 { addrOfElem = ((int8 *)array) + idx * sizeOfElem;
|
|
seanhalle@33
|
155 (*fnPtr)( addrOfElem );
|
|
seanhalle@33
|
156 }
|
|
seanhalle@33
|
157 }
|
|
seanhalle@33
|
158
|