security/nss/lib/smime/cmsarray.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

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

mercurial