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