OLD | NEW |
| (Empty) |
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 * Support routines for SECItemArray data structure. | |
7 */ | |
8 | |
9 #include "nssutil.h" | |
10 #include "seccomon.h" | |
11 #include "secitem.h" | |
12 #include "secerr.h" | |
13 #include "secport.h" | |
14 | |
15 #define NSSUTIL_VERSION_NUM \ | |
16 (NSSUTIL_VMAJOR * 10000 + NSSUTIL_VMINOR * 100 + NSSUTIL_VPATCH) | |
17 #if NSSUTIL_VERSION_NUM < 31500 | |
18 // Added in NSS 3.15. | |
19 typedef struct SECItemArrayStr SECItemArray; | |
20 | |
21 struct SECItemArrayStr { | |
22 SECItem *items; | |
23 unsigned int len; | |
24 }; | |
25 #endif | |
26 | |
27 SECItemArray * | |
28 SECITEM_AllocArray(PLArenaPool *arena, SECItemArray *array, unsigned int len) | |
29 { | |
30 SECItemArray *result = NULL; | |
31 void *mark = NULL; | |
32 | |
33 if (arena != NULL) { | |
34 mark = PORT_ArenaMark(arena); | |
35 } | |
36 | |
37 if (array == NULL) { | |
38 if (arena != NULL) { | |
39 result = PORT_ArenaZAlloc(arena, sizeof(SECItemArray)); | |
40 } else { | |
41 result = PORT_ZAlloc(sizeof(SECItemArray)); | |
42 } | |
43 if (result == NULL) { | |
44 goto loser; | |
45 } | |
46 } else { | |
47 PORT_Assert(array->items == NULL); | |
48 result = array; | |
49 } | |
50 | |
51 result->len = len; | |
52 if (len) { | |
53 if (arena != NULL) { | |
54 result->items = PORT_ArenaZNewArray(arena, SECItem, len); | |
55 } else { | |
56 result->items = PORT_ZNewArray(SECItem, len); | |
57 } | |
58 if (result->items == NULL) { | |
59 goto loser; | |
60 } | |
61 } else { | |
62 result->items = NULL; | |
63 } | |
64 | |
65 if (mark) { | |
66 PORT_ArenaUnmark(arena, mark); | |
67 } | |
68 return(result); | |
69 | |
70 loser: | |
71 if ( arena != NULL ) { | |
72 if (mark) { | |
73 PORT_ArenaRelease(arena, mark); | |
74 } | |
75 if (array != NULL) { | |
76 array->items = NULL; | |
77 array->len = 0; | |
78 } | |
79 } else { | |
80 if (result != NULL && array == NULL) { | |
81 PORT_Free(result); | |
82 } | |
83 /* | |
84 * If array is not NULL, the above has set array->data and | |
85 * array->len to 0. | |
86 */ | |
87 } | |
88 return(NULL); | |
89 } | |
90 | |
91 static void | |
92 secitem_FreeArray(SECItemArray *array, PRBool zero_items, PRBool freeit) | |
93 { | |
94 unsigned int i; | |
95 | |
96 if (!array || !array->len || !array->items) | |
97 return; | |
98 | |
99 for (i=0; i<array->len; ++i) { | |
100 SECItem *item = &array->items[i]; | |
101 | |
102 if (item->data) { | |
103 if (zero_items) { | |
104 SECITEM_ZfreeItem(item, PR_FALSE); | |
105 } else { | |
106 SECITEM_FreeItem(item, PR_FALSE); | |
107 } | |
108 } | |
109 } | |
110 PORT_Free(array->items); | |
111 array->items = NULL; | |
112 array->len = 0; | |
113 | |
114 if (freeit) | |
115 PORT_Free(array); | |
116 } | |
117 | |
118 void SECITEM_FreeArray(SECItemArray *array, PRBool freeit) | |
119 { | |
120 secitem_FreeArray(array, PR_FALSE, freeit); | |
121 } | |
122 | |
123 void SECITEM_ZfreeArray(SECItemArray *array, PRBool freeit) | |
124 { | |
125 secitem_FreeArray(array, PR_TRUE, freeit); | |
126 } | |
127 | |
128 SECItemArray * | |
129 SECITEM_DupArray(PLArenaPool *arena, const SECItemArray *from) | |
130 { | |
131 SECItemArray *result; | |
132 unsigned int i; | |
133 | |
134 if (!from || !from->items || !from->len) | |
135 return NULL; | |
136 | |
137 result = SECITEM_AllocArray(arena, NULL, from->len); | |
138 if (!result) | |
139 return NULL; | |
140 | |
141 for (i=0; i<from->len; ++i) { | |
142 SECStatus rv = SECITEM_CopyItem(arena, | |
143 &result->items[i], &from->items[i]); | |
144 if (rv != SECSuccess) { | |
145 SECITEM_ZfreeArray(result, PR_TRUE); | |
146 return NULL; | |
147 } | |
148 } | |
149 | |
150 return result; | |
151 } | |
OLD | NEW |