Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
1 /* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 /*
6 * CMS array functions.
7 */
9 #include "cmslocal.h"
11 #include "secerr.h"
13 /*
14 * ARRAY FUNCTIONS
15 *
16 * In NSS, arrays are rather primitive arrays of pointers.
17 * Makes it easy to walk the array, but hard to count elements
18 * and manage the storage.
19 *
20 * This is a feeble attempt to encapsulate the functionality
21 * and get rid of hundreds of lines of similar code
22 */
24 /*
25 * NSS_CMSArray_Alloc - allocate an array in an arena
26 *
27 * This allocates space for the array of pointers
28 */
29 void **
30 NSS_CMSArray_Alloc(PLArenaPool *poolp, int n)
31 {
32 return (void **)PORT_ArenaZAlloc(poolp, n * sizeof(void *));
33 }
35 /*
36 * NSS_CMSArray_Add - add an element to the end of an array
37 *
38 * The array of pointers is either created (if array was empty before) or grown.
39 */
40 SECStatus
41 NSS_CMSArray_Add(PLArenaPool *poolp, void ***array, void *obj)
42 {
43 void **p;
44 int n;
45 void **dest;
47 PORT_Assert(array != NULL);
48 if (array == NULL)
49 return SECFailure;
51 if (*array == NULL) {
52 dest = (void **)PORT_ArenaAlloc(poolp, 2 * sizeof(void *));
53 n = 0;
54 } else {
55 n = 0; p = *array;
56 while (*p++)
57 n++;
58 dest = (void **)PORT_ArenaGrow (poolp,
59 *array,
60 (n + 1) * sizeof(void *),
61 (n + 2) * sizeof(void *));
62 }
64 if (dest == NULL)
65 return SECFailure;
67 dest[n] = obj;
68 dest[n+1] = NULL;
69 *array = dest;
70 return SECSuccess;
71 }
73 /*
74 * NSS_CMSArray_IsEmpty - check if array is empty
75 */
76 PRBool
77 NSS_CMSArray_IsEmpty(void **array)
78 {
79 return (array == NULL || array[0] == NULL);
80 }
82 /*
83 * NSS_CMSArray_Count - count number of elements in array
84 */
85 int
86 NSS_CMSArray_Count(void **array)
87 {
88 int n = 0;
90 if (array == NULL)
91 return 0;
93 while (*array++ != NULL)
94 n++;
96 return n;
97 }
99 /*
100 * NSS_CMSArray_Sort - sort an array in place
101 *
102 * If "secondary" or "tertiary are not NULL, it must be arrays with the same
103 * number of elements as "primary". The same reordering will get applied to it.
104 *
105 * "compare" is a function that returns
106 * < 0 when the first element is less than the second
107 * = 0 when the first element is equal to the second
108 * > 0 when the first element is greater than the second
109 * to acheive ascending ordering.
110 */
111 void
112 NSS_CMSArray_Sort(void **primary, int (*compare)(void *,void *), void **secondary, void **tertiary)
113 {
114 int n, i, limit, lastxchg;
115 void *tmp;
117 n = NSS_CMSArray_Count(primary);
119 PORT_Assert(secondary == NULL || NSS_CMSArray_Count(secondary) == n);
120 PORT_Assert(tertiary == NULL || NSS_CMSArray_Count(tertiary) == n);
122 if (n <= 1) /* ordering is fine */
123 return;
125 /* yes, ladies and gentlemen, it's BUBBLE SORT TIME! */
126 limit = n - 1;
127 while (1) {
128 lastxchg = 0;
129 for (i = 0; i < limit; i++) {
130 if ((*compare)(primary[i], primary[i+1]) > 0) {
131 /* exchange the neighbours */
132 tmp = primary[i+1];
133 primary[i+1] = primary[i];
134 primary[i] = tmp;
135 if (secondary) { /* secondary array? */
136 tmp = secondary[i+1]; /* exchange there as well */
137 secondary[i+1] = secondary[i];
138 secondary[i] = tmp;
139 }
140 if (tertiary) { /* tertiary array? */
141 tmp = tertiary[i+1]; /* exchange there as well */
142 tertiary[i+1] = tertiary[i];
143 tertiary[i] = tmp;
144 }
145 lastxchg = i+1; /* index of the last element bubbled up */
146 }
147 }
148 if (lastxchg == 0) /* no exchanges, so array is sorted */
149 break; /* we're done */
150 limit = lastxchg; /* array is sorted up to [limit] */
151 }
152 }
154 #if 0
156 /* array iterator stuff... not used */
158 typedef void **NSSCMSArrayIterator;
160 /* iterator */
161 NSSCMSArrayIterator
162 NSS_CMSArray_First(void **array)
163 {
164 if (array == NULL || array[0] == NULL)
165 return NULL;
166 return (NSSCMSArrayIterator)&(array[0]);
167 }
169 void *
170 NSS_CMSArray_Obj(NSSCMSArrayIterator iter)
171 {
172 void **p = (void **)iter;
174 return *iter; /* which is NULL if we are at the end of the array */
175 }
177 NSSCMSArrayIterator
178 NSS_CMSArray_Next(NSSCMSArrayIterator iter)
179 {
180 void **p = (void **)iter;
182 return (NSSCMSArrayIterator)(p + 1);
183 }
185 #endif