OLD | NEW |
1 /* This Source Code Form is subject to the terms of the Mozilla Public | 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 | 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/. */ | 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
4 | 4 |
5 #ifndef BUILTINS_H | 5 #ifndef BUILTINS_H |
6 #include "builtins.h" | 6 #include "builtins.h" |
7 #endif /* BUILTINS_H */ | 7 #endif /* BUILTINS_H */ |
8 | 8 |
9 /* | 9 /* |
10 * builtins/find.c | 10 * builtins/find.c |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
176 NSSCKFWSession *fwSession, | 176 NSSCKFWSession *fwSession, |
177 CK_ATTRIBUTE_PTR pTemplate, | 177 CK_ATTRIBUTE_PTR pTemplate, |
178 CK_ULONG ulAttributeCount, | 178 CK_ULONG ulAttributeCount, |
179 CK_RV *pError | 179 CK_RV *pError |
180 ) | 180 ) |
181 { | 181 { |
182 /* This could be made more efficient. I'm rather rushed. */ | 182 /* This could be made more efficient. I'm rather rushed. */ |
183 NSSArena *arena; | 183 NSSArena *arena; |
184 NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL; | 184 NSSCKMDFindObjects *rv = (NSSCKMDFindObjects *)NULL; |
185 struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL; | 185 struct builtinsFOStr *fo = (struct builtinsFOStr *)NULL; |
186 builtinsInternalObject **temp = (builtinsInternalObject **)NULL; | 186 |
| 187 /* |
| 188 * 99% of the time we get 0 or 1 matches. So we start with a small |
| 189 * stack-allocated array to hold the matches and switch to a heap-allocated |
| 190 * array later if the number of matches exceeds STACK_BUF_LENGTH. |
| 191 */ |
| 192 #define STACK_BUF_LENGTH 1 |
| 193 builtinsInternalObject *stackTemp[STACK_BUF_LENGTH]; |
| 194 builtinsInternalObject **temp = stackTemp; |
| 195 PRBool tempIsHeapAllocated = PR_FALSE; |
187 PRUint32 i; | 196 PRUint32 i; |
188 | 197 |
189 arena = NSSArena_Create(); | 198 arena = NSSArena_Create(); |
190 if( (NSSArena *)NULL == arena ) { | 199 if( (NSSArena *)NULL == arena ) { |
191 goto loser; | 200 goto loser; |
192 } | 201 } |
193 | 202 |
194 rv = nss_ZNEW(arena, NSSCKMDFindObjects); | 203 rv = nss_ZNEW(arena, NSSCKMDFindObjects); |
195 if( (NSSCKMDFindObjects *)NULL == rv ) { | 204 if( (NSSCKMDFindObjects *)NULL == rv ) { |
196 *pError = CKR_HOST_MEMORY; | 205 *pError = CKR_HOST_MEMORY; |
197 goto loser; | 206 goto loser; |
198 } | 207 } |
199 | 208 |
200 fo = nss_ZNEW(arena, struct builtinsFOStr); | 209 fo = nss_ZNEW(arena, struct builtinsFOStr); |
201 if( (struct builtinsFOStr *)NULL == fo ) { | 210 if( (struct builtinsFOStr *)NULL == fo ) { |
202 *pError = CKR_HOST_MEMORY; | 211 *pError = CKR_HOST_MEMORY; |
203 goto loser; | 212 goto loser; |
204 } | 213 } |
205 | 214 |
206 fo->arena = arena; | 215 fo->arena = arena; |
207 /* fo->n and fo->i are already zero */ | 216 /* fo->n and fo->i are already zero */ |
208 | 217 |
209 rv->etc = (void *)fo; | 218 rv->etc = (void *)fo; |
210 rv->Final = builtins_mdFindObjects_Final; | 219 rv->Final = builtins_mdFindObjects_Final; |
211 rv->Next = builtins_mdFindObjects_Next; | 220 rv->Next = builtins_mdFindObjects_Next; |
212 rv->null = (void *)NULL; | 221 rv->null = (void *)NULL; |
213 | 222 |
214 temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *, | |
215 nss_builtins_nObjects); | |
216 if( (builtinsInternalObject **)NULL == temp ) { | |
217 *pError = CKR_HOST_MEMORY; | |
218 goto loser; | |
219 } | |
220 | |
221 for( i = 0; i < nss_builtins_nObjects; i++ ) { | 223 for( i = 0; i < nss_builtins_nObjects; i++ ) { |
222 builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i]; | 224 builtinsInternalObject *o = (builtinsInternalObject *)&nss_builtins_data[i]; |
223 | 225 |
224 if( CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o) ) { | 226 if( CK_TRUE == builtins_match(pTemplate, ulAttributeCount, o) ) { |
| 227 if( fo->n == STACK_BUF_LENGTH ) { |
| 228 /* Switch from the small stack array to a heap-allocated array large |
| 229 * enough to handle matches in all remaining cases. */ |
| 230 temp = nss_ZNEWARRAY((NSSArena *)NULL, builtinsInternalObject *, |
| 231 fo->n + nss_builtins_nObjects - i); |
| 232 if( (builtinsInternalObject **)NULL == temp ) { |
| 233 *pError = CKR_HOST_MEMORY; |
| 234 goto loser; |
| 235 } |
| 236 tempIsHeapAllocated = PR_TRUE; |
| 237 (void)nsslibc_memcpy(temp, stackTemp, |
| 238 sizeof(builtinsInternalObject *) * fo->n); |
| 239 } |
| 240 |
225 temp[ fo->n ] = o; | 241 temp[ fo->n ] = o; |
226 fo->n++; | 242 fo->n++; |
227 } | 243 } |
228 } | 244 } |
229 | 245 |
230 fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n); | 246 fo->objs = nss_ZNEWARRAY(arena, builtinsInternalObject *, fo->n); |
231 if( (builtinsInternalObject **)NULL == fo->objs ) { | 247 if( (builtinsInternalObject **)NULL == fo->objs ) { |
232 *pError = CKR_HOST_MEMORY; | 248 *pError = CKR_HOST_MEMORY; |
233 goto loser; | 249 goto loser; |
234 } | 250 } |
235 | 251 |
236 (void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n)
; | 252 (void)nsslibc_memcpy(fo->objs, temp, sizeof(builtinsInternalObject *) * fo->n)
; |
237 nss_ZFreeIf(temp); | 253 if (tempIsHeapAllocated) { |
238 temp = (builtinsInternalObject **)NULL; | 254 nss_ZFreeIf(temp); |
| 255 temp = (builtinsInternalObject **)NULL; |
| 256 } |
239 | 257 |
240 return rv; | 258 return rv; |
241 | 259 |
242 loser: | 260 loser: |
243 nss_ZFreeIf(temp); | 261 if (tempIsHeapAllocated) { |
| 262 nss_ZFreeIf(temp); |
| 263 } |
244 nss_ZFreeIf(fo); | 264 nss_ZFreeIf(fo); |
245 nss_ZFreeIf(rv); | 265 nss_ZFreeIf(rv); |
246 if ((NSSArena *)NULL != arena) { | 266 if ((NSSArena *)NULL != arena) { |
247 NSSArena_Destroy(arena); | 267 NSSArena_Destroy(arena); |
248 } | 268 } |
249 return (NSSCKMDFindObjects *)NULL; | 269 return (NSSCKMDFindObjects *)NULL; |
250 } | 270 } |
251 | 271 |
OLD | NEW |