| /* This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| |
| /* |
| * item.c |
| * |
| * This contains some item-manipulation code. |
| */ |
| |
| #ifndef BASE_H |
| #include "base.h" |
| #endif /* BASE_H */ |
| |
| /* |
| * nssItem_Create |
| * |
| * -- fgmr comments -- |
| * |
| * The error may be one of the following values: |
| * NSS_ERROR_INVALID_ARENA |
| * NSS_ERROR_NO_MEMORY |
| * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD |
| * NSS_ERROR_INVALID_POINTER |
| * |
| * Return value: |
| * A pointer to an NSSItem upon success |
| * NULL upon failure |
| */ |
| |
| NSS_IMPLEMENT NSSItem * |
| nssItem_Create(NSSArena *arenaOpt, NSSItem *rvOpt, PRUint32 length, |
| const void *data) |
| { |
| NSSItem *rv = (NSSItem *)NULL; |
| |
| #ifdef DEBUG |
| if ((NSSArena *)NULL != arenaOpt) { |
| if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) { |
| return (NSSItem *)NULL; |
| } |
| } |
| |
| if ((const void *)NULL == data) { |
| if (length > 0) { |
| nss_SetError(NSS_ERROR_INVALID_POINTER); |
| return (NSSItem *)NULL; |
| } |
| } |
| #endif /* DEBUG */ |
| |
| if ((NSSItem *)NULL == rvOpt) { |
| rv = (NSSItem *)nss_ZNEW(arenaOpt, NSSItem); |
| if ((NSSItem *)NULL == rv) { |
| goto loser; |
| } |
| } else { |
| rv = rvOpt; |
| } |
| |
| rv->size = length; |
| rv->data = nss_ZAlloc(arenaOpt, length); |
| if ((void *)NULL == rv->data) { |
| goto loser; |
| } |
| |
| if (length > 0) { |
| (void)nsslibc_memcpy(rv->data, data, length); |
| } |
| |
| return rv; |
| |
| loser: |
| if (rv != rvOpt) { |
| nss_ZFreeIf(rv); |
| } |
| |
| return (NSSItem *)NULL; |
| } |
| |
| NSS_IMPLEMENT void |
| nssItem_Destroy(NSSItem *item) |
| { |
| nss_ClearErrorStack(); |
| |
| nss_ZFreeIf(item->data); |
| nss_ZFreeIf(item); |
| } |
| |
| /* |
| * nssItem_Duplicate |
| * |
| * -- fgmr comments -- |
| * |
| * The error may be one of the following values: |
| * NSS_ERROR_INVALID_ARENA |
| * NSS_ERROR_NO_MEMORY |
| * NSS_ERROR_ARENA_MARKED_BY_ANOTHER_THREAD |
| * NSS_ERROR_INVALID_ITEM |
| * |
| * Return value: |
| * A pointer to an NSSItem upon success |
| * NULL upon failure |
| */ |
| |
| NSS_IMPLEMENT NSSItem * |
| nssItem_Duplicate(NSSItem *obj, NSSArena *arenaOpt, NSSItem *rvOpt) |
| { |
| #ifdef DEBUG |
| if ((NSSArena *)NULL != arenaOpt) { |
| if (PR_SUCCESS != nssArena_verifyPointer(arenaOpt)) { |
| return (NSSItem *)NULL; |
| } |
| } |
| |
| if ((NSSItem *)NULL == obj) { |
| nss_SetError(NSS_ERROR_INVALID_ITEM); |
| return (NSSItem *)NULL; |
| } |
| #endif /* DEBUG */ |
| |
| return nssItem_Create(arenaOpt, rvOpt, obj->size, obj->data); |
| } |
| |
| #ifdef DEBUG |
| /* |
| * nssItem_verifyPointer |
| * |
| * -- fgmr comments -- |
| * |
| * The error may be one of the following values: |
| * NSS_ERROR_INVALID_ITEM |
| * |
| * Return value: |
| * PR_SUCCESS upon success |
| * PR_FAILURE upon failure |
| */ |
| |
| NSS_IMPLEMENT PRStatus |
| nssItem_verifyPointer(const NSSItem *item) |
| { |
| if (((const NSSItem *)NULL == item) || |
| (((void *)NULL == item->data) && (item->size > 0))) { |
| nss_SetError(NSS_ERROR_INVALID_ITEM); |
| return PR_FAILURE; |
| } |
| |
| return PR_SUCCESS; |
| } |
| #endif /* DEBUG */ |
| |
| /* |
| * nssItem_Equal |
| * |
| * -- fgmr comments -- |
| * |
| * The error may be one of the following values: |
| * NSS_ERROR_INVALID_ITEM |
| * |
| * Return value: |
| * PR_TRUE if the items are identical |
| * PR_FALSE if they aren't |
| * PR_FALSE upon error |
| */ |
| |
| NSS_IMPLEMENT PRBool |
| nssItem_Equal(const NSSItem *one, const NSSItem *two, PRStatus *statusOpt) |
| { |
| if ((PRStatus *)NULL != statusOpt) { |
| *statusOpt = PR_SUCCESS; |
| } |
| |
| if (((const NSSItem *)NULL == one) && ((const NSSItem *)NULL == two)) { |
| return PR_TRUE; |
| } |
| |
| if (((const NSSItem *)NULL == one) || ((const NSSItem *)NULL == two)) { |
| return PR_FALSE; |
| } |
| |
| if (one->size != two->size) { |
| return PR_FALSE; |
| } |
| |
| return nsslibc_memequal(one->data, two->data, one->size, statusOpt); |
| } |