security/nss/lib/smime/cmsarray.c

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

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

mercurial