Coverage Report

Created: 2018-09-25 14:53

/src/mozilla-central/security/nss/lib/smime/cmsarray.c
Line
Count
Source (jump to first uncovered line)
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/. */
4
5
/*
6
 * CMS array functions.
7
 */
8
9
#include "cmslocal.h"
10
11
#include "secerr.h"
12
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
 */
23
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
0
{
32
0
    return (void **)PORT_ArenaZAlloc(poolp, n * sizeof(void *));
33
0
}
34
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
0
{
43
0
    void **p;
44
0
    int n;
45
0
    void **dest;
46
0
47
0
    PORT_Assert(array != NULL);
48
0
    if (array == NULL)
49
0
        return SECFailure;
50
0
51
0
    if (*array == NULL) {
52
0
        dest = (void **)PORT_ArenaAlloc(poolp, 2 * sizeof(void *));
53
0
        n = 0;
54
0
    } else {
55
0
        n = 0;
56
0
        p = *array;
57
0
        while (*p++)
58
0
            n++;
59
0
        dest = (void **)PORT_ArenaGrow(poolp,
60
0
                                       *array,
61
0
                                       (n + 1) * sizeof(void *),
62
0
                                       (n + 2) * sizeof(void *));
63
0
    }
64
0
65
0
    if (dest == NULL)
66
0
        return SECFailure;
67
0
68
0
    dest[n] = obj;
69
0
    dest[n + 1] = NULL;
70
0
    *array = dest;
71
0
    return SECSuccess;
72
0
}
73
74
/*
75
 * NSS_CMSArray_IsEmpty - check if array is empty
76
 */
77
PRBool
78
NSS_CMSArray_IsEmpty(void **array)
79
0
{
80
0
    return (array == NULL || array[0] == NULL);
81
0
}
82
83
/*
84
 * NSS_CMSArray_Count - count number of elements in array
85
 */
86
int
87
NSS_CMSArray_Count(void **array)
88
0
{
89
0
    int n = 0;
90
0
91
0
    if (array == NULL)
92
0
        return 0;
93
0
94
0
    while (*array++ != NULL)
95
0
        n++;
96
0
97
0
    return n;
98
0
}
99
100
/*
101
 * NSS_CMSArray_Sort - sort an array in place
102
 *
103
 * If "secondary" or "tertiary are not NULL, it must be arrays with the same
104
 *  number of elements as "primary". The same reordering will get applied to it.
105
 *
106
 * "compare" is a function that returns
107
 *  < 0 when the first element is less than the second
108
 *  = 0 when the first element is equal to the second
109
 *  > 0 when the first element is greater than the second
110
 * to acheive ascending ordering.
111
 */
112
void
113
NSS_CMSArray_Sort(void **primary, int (*compare)(void *, void *), void **secondary, void **tertiary)
114
0
{
115
0
    int n, i, limit, lastxchg;
116
0
    void *tmp;
117
0
118
0
    n = NSS_CMSArray_Count(primary);
119
0
120
0
    PORT_Assert(secondary == NULL || NSS_CMSArray_Count(secondary) == n);
121
0
    PORT_Assert(tertiary == NULL || NSS_CMSArray_Count(tertiary) == n);
122
0
123
0
    if (n <= 1) /* ordering is fine */
124
0
        return;
125
0
126
0
    /* yes, ladies and gentlemen, it's BUBBLE SORT TIME! */
127
0
    limit = n - 1;
128
0
    while (1) {
129
0
        lastxchg = 0;
130
0
        for (i = 0; i < limit; i++) {
131
0
            if ((*compare)(primary[i], primary[i + 1]) > 0) {
132
0
                /* exchange the neighbours */
133
0
                tmp = primary[i + 1];
134
0
                primary[i + 1] = primary[i];
135
0
                primary[i] = tmp;
136
0
                if (secondary) {            /* secondary array? */
137
0
                    tmp = secondary[i + 1]; /* exchange there as well */
138
0
                    secondary[i + 1] = secondary[i];
139
0
                    secondary[i] = tmp;
140
0
                }
141
0
                if (tertiary) {            /* tertiary array? */
142
0
                    tmp = tertiary[i + 1]; /* exchange there as well */
143
0
                    tertiary[i + 1] = tertiary[i];
144
0
                    tertiary[i] = tmp;
145
0
                }
146
0
                lastxchg = i + 1; /* index of the last element bubbled up */
147
0
            }
148
0
        }
149
0
        if (lastxchg == 0) /* no exchanges, so array is sorted */
150
0
            break;         /* we're done */
151
0
        limit = lastxchg;  /* array is sorted up to [limit] */
152
0
    }
153
0
}
154
155
#if 0
156
157
/* array iterator stuff... not used */
158
159
typedef void **NSSCMSArrayIterator;
160
161
/* iterator */
162
NSSCMSArrayIterator
163
NSS_CMSArray_First(void **array)
164
{
165
    if (array == NULL || array[0] == NULL)
166
    return NULL;
167
    return (NSSCMSArrayIterator)&(array[0]);
168
}
169
170
void *
171
NSS_CMSArray_Obj(NSSCMSArrayIterator iter)
172
{
173
    void **p = (void **)iter;
174
175
    return *iter;   /* which is NULL if we are at the end of the array */
176
}
177
178
NSSCMSArrayIterator
179
NSS_CMSArray_Next(NSSCMSArrayIterator iter)
180
{
181
    void **p = (void **)iter;
182
183
    return (NSSCMSArrayIterator)(p + 1);
184
}
185
186
#endif