| Index: mozilla/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c
|
| ===================================================================
|
| --- mozilla/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c (revision 191424)
|
| +++ mozilla/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c (working copy)
|
| @@ -1,1440 +0,0 @@
|
| -/* 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/. */
|
| -/*
|
| - * pkix_pl_object.c
|
| - *
|
| - * Object Construction, Destruction and Callback Functions
|
| - *
|
| - */
|
| -
|
| -#include "pkix_pl_object.h"
|
| -
|
| -#ifdef PKIX_USER_OBJECT_TYPE
|
| -/* --Class-Table-Initializers------------------------------------ */
|
| -
|
| -/*
|
| - * Create storage space for 20 Class Table buckets.
|
| - * These are only for user-defined types. System types are registered
|
| - * separately by PKIX_PL_Initialize.
|
| - */
|
| -
|
| -static pkix_pl_HT_Elem*
|
| -pkix_Raw_ClassTable_Buckets[] = {
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
|
| - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
|
| -};
|
| -
|
| -/*
|
| - * Allocate static memory for a ClassTable.
|
| - * XXX This assumes the bucket pointer will fit into a PKIX_UInt32
|
| - */
|
| -static pkix_pl_PrimHashTable pkix_Raw_ClassTable = {
|
| - (void *)pkix_Raw_ClassTable_Buckets, /* Buckets */
|
| - 20 /* Number of Buckets */
|
| -};
|
| -static pkix_pl_PrimHashTable * classTable = &pkix_Raw_ClassTable;
|
| -#endif /* PKIX_USER_OBJECT_TYPE */
|
| -
|
| -/* --Private-Functions-------------------------------------------- */
|
| -
|
| -/*
|
| - * FUNCTION: pkix_pl_Object_GetHeader
|
| - * DESCRIPTION:
|
| - *
|
| - * Shifts Object pointed to by "object" by the sizeof(PKIX_PL_Object) and
|
| - * stores the value at "pObjectHeader".
|
| - *
|
| - * PARAMETERS:
|
| - * "object"
|
| - * Address of Object to shift. Must be non-NULL.
|
| - * "pObjectHeader"
|
| - * Address where object pointer will be stored. Must be non-NULL.
|
| - * "plContext"
|
| - * Platform-specific context pointer.
|
| - * THREAD SAFETY:
|
| - * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
| - * RETURNS:
|
| - * Returns NULL if the function succeeds.
|
| - * Returns a Fatal Error if the function fails in an unrecoverable way.
|
| - */
|
| -static PKIX_Error *
|
| -pkix_pl_Object_GetHeader(
|
| - PKIX_PL_Object *object,
|
| - PKIX_PL_Object **pObjectHeader,
|
| - void *plContext)
|
| -{
|
| - PKIX_PL_Object *header = NULL;
|
| - PKIX_UInt32 objType;
|
| -
|
| - PKIX_ENTER(OBJECT, "pkix_pl_Object_GetHeader");
|
| - PKIX_NULLCHECK_TWO(object, pObjectHeader);
|
| -
|
| - PKIX_OBJECT_DEBUG("\tShifting object pointer).\n");
|
| -
|
| - /* The header is sizeof(PKIX_PL_Object) before the object pointer */
|
| - header = (PKIX_PL_Object *)((char *)object - sizeof(PKIX_PL_Object));
|
| -
|
| - objType = header->type;
|
| -
|
| - if (objType >= PKIX_NUMTYPES) { /* if this is a user-defined type */
|
| -#ifdef PKIX_USER_OBJECT_TYPE
|
| - pkix_ClassTable_Entry *ctEntry = NULL;
|
| -
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
|
| - PR_Lock(classTableLock);
|
| -
|
| - PKIX_CHECK(pkix_pl_PrimHashTable_Lookup
|
| - (classTable,
|
| - (void *)&objType,
|
| - objType,
|
| - NULL,
|
| - (void **)&ctEntry,
|
| - plContext),
|
| - PKIX_ERRORGETTINGCLASSTABLEENTRY);
|
| -
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
|
| - PR_Unlock(classTableLock);
|
| -
|
| - if (ctEntry == NULL) {
|
| - PKIX_ERROR_FATAL(PKIX_UNKNOWNOBJECTTYPE);
|
| - }
|
| -#else
|
| - PORT_Assert(objType < PKIX_NUMTYPES);
|
| - pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
|
| - pkixErrorClass = PKIX_FATAL_ERROR;
|
| - goto cleanup;
|
| -#endif /* PKIX_USER_OBJECT_TYPE */
|
| - }
|
| -
|
| -#ifdef PKIX_OBJECT_LEAK_TEST
|
| - PORT_Assert(header && header->magicHeader == PKIX_MAGIC_HEADER);
|
| -#endif /* PKIX_OBJECT_LEAK_TEST */
|
| -
|
| - if ((header == NULL)||
|
| - (header->magicHeader != PKIX_MAGIC_HEADER)) {
|
| - PKIX_ERROR_ALLOC_ERROR();
|
| - }
|
| -
|
| - *pObjectHeader = header;
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/*
|
| - * FUNCTION: pkix_Destroy_Object
|
| - * DESCRIPTION:
|
| - *
|
| - * Destroys and deallocates Object pointed to by "object". The caller is
|
| - * assumed to hold the Object's lock, which is acquired in
|
| - * PKIX_PL_Object_DecRef().
|
| - *
|
| - * PARAMETERS:
|
| - * "object"
|
| - * Address of Object to destroy. Must be non-NULL.
|
| - * "plContext"
|
| - * Platform-specific context pointer.
|
| - * THREAD SAFETY:
|
| - * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
| - * RETURNS:
|
| - * Returns NULL if the function succeeds.
|
| - * Returns a Fatal Error if the function fails in an unrecoverable way.
|
| - */
|
| -static PKIX_Error *
|
| -pkix_pl_Object_Destroy(
|
| - PKIX_PL_Object *object,
|
| - void *plContext)
|
| -{
|
| - PKIX_PL_Object *objectHeader = NULL;
|
| -
|
| - PKIX_ENTER(OBJECT, "pkix_pl_Object_Destroy");
|
| - PKIX_NULLCHECK_ONE(object);
|
| -
|
| -#ifdef PKIX_OBJECT_LEAK_TEST
|
| - PKIX_CHECK_FATAL(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
|
| - PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
|
| -#else
|
| - PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
|
| - PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
|
| -#endif /* PKIX_OBJECT_LEAK_TEST */
|
| -
|
| - /* Attempt to delete an object still being used */
|
| - if (objectHeader->references != 0) {
|
| - PKIX_ERROR_FATAL(PKIX_OBJECTSTILLREFERENCED);
|
| - }
|
| -
|
| - PKIX_DECREF(objectHeader->stringRep);
|
| -
|
| - /* Destroy this object's lock */
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_DestroyLock).\n");
|
| - PR_DestroyLock(objectHeader->lock);
|
| - objectHeader->lock = NULL;
|
| - object = NULL;
|
| -
|
| - objectHeader->magicHeader = PKIX_MAGIC_HEADER_DESTROYED;
|
| -
|
| -#ifdef PKIX_OBJECT_LEAK_TEST
|
| - memset(objectHeader, 0xbf, systemClasses[PKIX_OBJECT_TYPE].typeObjectSize);
|
| -#endif
|
| -
|
| - PKIX_FREE(objectHeader);
|
| -
|
| -cleanup:
|
| -#ifdef PKIX_OBJECT_LEAK_TEST
|
| -fatal:
|
| -#endif
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/* --Default-Callbacks-------------------------------------------- */
|
| -
|
| -/*
|
| - * FUNCTION: pkix_pl_Object_Equals_Default
|
| - * DESCRIPTION:
|
| - *
|
| - * Default Object_Equals callback: Compares the address of the Object pointed
|
| - * to by "firstObject" with the address of the Object pointed to by
|
| - * "secondObject" and stores the Boolean result at "pResult".
|
| - *
|
| - * PARAMETERS:
|
| - * "firstObject"
|
| - * Address of first Object to compare. Must be non-NULL.
|
| - * "secondObject"
|
| - * Address of second Object to compare. Must be non-NULL.
|
| - * "pResult"
|
| - * Address where Boolean result will be stored. Must be non-NULL.
|
| - * "plContext"
|
| - * Platform-specific context pointer.
|
| - * THREAD SAFETY:
|
| - * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
| - * RETURNS:
|
| - * Returns NULL if the function succeeds.
|
| - * Returns a Fatal Error if the function fails in an unrecoverable way.
|
| - */
|
| -static PKIX_Error *
|
| -pkix_pl_Object_Equals_Default(
|
| - PKIX_PL_Object *firstObject,
|
| - PKIX_PL_Object *secondObject,
|
| - PKIX_Boolean *pResult,
|
| - void *plContext)
|
| -{
|
| - PKIX_ENTER(OBJECT, "pkix_pl_Object_Equals_Default");
|
| - PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
|
| -
|
| - /* Just compare pointer values */
|
| - *pResult = (firstObject == secondObject)?PKIX_TRUE:PKIX_FALSE;
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/*
|
| - * FUNCTION: pkix_pl_Object_ToString_Default
|
| - * DESCRIPTION:
|
| - *
|
| - * Default Object_ToString callback: Creates a string consisting of the
|
| - * typename and address of the Object pointed to by "object" and stores
|
| - * the result at "pString". The format for the string is
|
| - * "TypeName@Address: <address>", where the default typename is "Object".
|
| - *
|
| - * PARAMETERS:
|
| - * "object"
|
| - * Address of Object to convert to a string. Must be non-NULL.
|
| - * "pString"
|
| - * Address where object pointer will be stored. Must be non-NULL.
|
| - * "plContext"
|
| - * Platform-specific context pointer.
|
| - * THREAD SAFETY:
|
| - * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
| - * RETURNS:
|
| - * Returns NULL if the function succeeds.
|
| - * Returns an Object Error if the function fails in a non-fatal way.
|
| - * Returns a Fatal Error if the function fails in an unrecoverable way.
|
| - */
|
| -static PKIX_Error *
|
| -pkix_pl_Object_ToString_Default(
|
| - PKIX_PL_Object *object,
|
| - PKIX_PL_String **pString,
|
| - void *plContext)
|
| -{
|
| - PKIX_PL_String *formatString = NULL;
|
| - PKIX_PL_String *descString = NULL;
|
| - char *format = "%s@Address: %x";
|
| - char *description = NULL;
|
| - PKIX_UInt32 objType;
|
| -
|
| - PKIX_ENTER(OBJECT, "pkix_pl_Object_ToString_Default");
|
| - PKIX_NULLCHECK_TWO(object, pString);
|
| -
|
| - PKIX_CHECK(PKIX_PL_Object_GetType(object, &objType, plContext),
|
| - PKIX_OBJECTGETTYPEFAILED);
|
| -
|
| - if (objType >= PKIX_NUMTYPES){
|
| -#ifdef PKIX_USER_OBJECT_TYPE
|
| - pkix_ClassTable_Entry *ctEntry = NULL;
|
| -
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
|
| - PR_Lock(classTableLock);
|
| - pkixErrorResult = pkix_pl_PrimHashTable_Lookup
|
| - (classTable,
|
| - (void *)&objType,
|
| - objType,
|
| - NULL,
|
| - (void **)&ctEntry,
|
| - plContext);
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
|
| - PR_Unlock(classTableLock);
|
| - if (pkixErrorResult){
|
| - PKIX_ERROR_FATAL(PKIX_ERRORGETTINGCLASSTABLEENTRY);
|
| - }
|
| -
|
| - if (ctEntry == NULL){
|
| - PKIX_ERROR_FATAL(PKIX_UNDEFINEDCLASSTABLEENTRY);
|
| - } else {
|
| - description = ctEntry->description;
|
| - if (description == NULL) {
|
| - description = "User Type Object";
|
| - }
|
| - }
|
| -#else
|
| - PORT_Assert (0);
|
| - pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
|
| - pkixErrorClass = PKIX_FATAL_ERROR;
|
| - goto cleanup;
|
| -#endif /* PKIX_USER_OBJECT_TYPE */
|
| - } else {
|
| - description = systemClasses[objType].description;
|
| - }
|
| - PKIX_CHECK(PKIX_PL_String_Create
|
| - (PKIX_ESCASCII,
|
| - (void *)format,
|
| - 0,
|
| - &formatString,
|
| - plContext),
|
| - PKIX_STRINGCREATEFAILED);
|
| -
|
| - PKIX_CHECK(PKIX_PL_String_Create
|
| - (PKIX_ESCASCII,
|
| - (void *)description,
|
| - 0,
|
| - &descString,
|
| - plContext),
|
| - PKIX_STRINGCREATEFAILED);
|
| -
|
| - PKIX_CHECK(PKIX_PL_Sprintf
|
| - (pString,
|
| - plContext,
|
| - formatString,
|
| - descString,
|
| - object),
|
| - PKIX_SPRINTFFAILED);
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_DECREF(formatString);
|
| - PKIX_DECREF(descString);
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/*
|
| - * FUNCTION: pkix_pl_Object_Hashcode_Default
|
| - * DESCRIPTION:
|
| - *
|
| - * Default Object_Hashcode callback. Creates the a hashcode value using the
|
| - * address of the Object pointed to by "object" and stores the result at
|
| - * "pValue".
|
| - *
|
| - * XXX This isn't great since addresses are not uniformly distributed.
|
| - *
|
| - * PARAMETERS:
|
| - * "object"
|
| - * Address of Object to compute hashcode for. Must be non-NULL.
|
| - * "pValue"
|
| - * Address where PKIX_UInt32 will be stored. Must be non-NULL.
|
| - * "plContext"
|
| - * Platform-specific context pointer.
|
| - * THREAD SAFETY:
|
| - * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
| - * RETURNS:
|
| - * Returns NULL if the function succeeds.
|
| - * Returns a Fatal Error if the function fails in an unrecoverable way.
|
| - */
|
| -static PKIX_Error *
|
| -pkix_pl_Object_Hashcode_Default(
|
| - PKIX_PL_Object *object,
|
| - PKIX_UInt32 *pValue,
|
| - void *plContext)
|
| -{
|
| - PKIX_ENTER(OBJECT, "pkix_pl_Object_Hashcode_Default");
|
| - PKIX_NULLCHECK_TWO(object, pValue);
|
| -
|
| - *pValue = (PKIX_UInt32)object;
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/*
|
| - * FUNCTION: pkix_pl_Object_RetrieveEqualsCallback
|
| - * DESCRIPTION:
|
| - *
|
| - * Retrieves Equals callback function of Object pointed to by "object and
|
| - * stores it at "pEqualsCallback". If the object's type is one of the system
|
| - * types, its callback function is retrieved from the systemClasses array;
|
| - * otherwise, its callback function is retrieve from the classTable hash
|
| - * table where user-defined types are stored.
|
| - *
|
| - * PARAMETERS:
|
| - * "object"
|
| - * Address of Object whose equals callback is desired. Must be non-NULL.
|
| - * "pEqualsCallback"
|
| - * Address where EqualsCallback function pointer will be stored.
|
| - * Must be non-NULL.
|
| - * "plContext"
|
| - * Platform-specific context pointer.
|
| - * THREAD SAFETY:
|
| - * Thread Safe (see Thread Safety Definitions in Programmer's Guide)
|
| - * RETURNS:
|
| - * Returns NULL if the function succeeds.
|
| - * Returns an Object Error if the function fails in a non-fatal way.
|
| - * Returns a Fatal Error if the function fails in an unrecoverable way.
|
| - */
|
| -PKIX_Error *
|
| -pkix_pl_Object_RetrieveEqualsCallback(
|
| - PKIX_PL_Object *object,
|
| - PKIX_PL_EqualsCallback *pEqualsCallback,
|
| - void *plContext)
|
| -{
|
| - PKIX_PL_Object *objectHeader = NULL;
|
| - PKIX_PL_EqualsCallback func = NULL;
|
| - pkix_ClassTable_Entry entry;
|
| - PKIX_UInt32 objType;
|
| -
|
| - PKIX_ENTER(OBJECT, "pkix_pl_Object_RetrieveEqualsCallback");
|
| - PKIX_NULLCHECK_TWO(object, pEqualsCallback);
|
| -
|
| - PKIX_CHECK(pkix_pl_Object_GetHeader
|
| - (object, &objectHeader, plContext),
|
| - PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
|
| -
|
| - objType = objectHeader->type;
|
| -
|
| - if (objType >= PKIX_NUMTYPES){
|
| -#ifdef PKIX_USER_OBJECT_TYPE
|
| - pkix_ClassTable_Entry *ctEntry = NULL;
|
| -
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
|
| - PR_Lock(classTableLock);
|
| - pkixErrorResult = pkix_pl_PrimHashTable_Lookup
|
| - (classTable,
|
| - (void *)&objType,
|
| - objType,
|
| - NULL,
|
| - (void **)&ctEntry,
|
| - plContext);
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
|
| - PR_Unlock(classTableLock);
|
| - if (pkixErrorResult){
|
| - PKIX_ERROR(PKIX_ERRORGETTINGCLASSTABLEENTRY);
|
| - }
|
| -
|
| - if ((ctEntry == NULL) || (ctEntry->equalsFunction == NULL)) {
|
| - PKIX_ERROR(PKIX_UNDEFINEDEQUALSCALLBACK);
|
| - } else {
|
| - *pEqualsCallback = ctEntry->equalsFunction;
|
| - }
|
| -#else
|
| - PORT_Assert (0);
|
| - pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
|
| - pkixErrorClass = PKIX_FATAL_ERROR;
|
| - goto cleanup;
|
| -#endif /* PKIX_USER_OBJECT_TYPE */
|
| - } else {
|
| - entry = systemClasses[objType];
|
| - func = entry.equalsFunction;
|
| - if (func == NULL){
|
| - func = pkix_pl_Object_Equals_Default;
|
| - }
|
| - *pEqualsCallback = func;
|
| - }
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/*
|
| - * FUNCTION: pkix_pl_Object_RegisterSelf
|
| - * DESCRIPTION:
|
| - * Registers PKIX_OBJECT_TYPE and its related functions with systemClasses[]
|
| - * THREAD SAFETY:
|
| - * Not Thread Safe - for performance and complexity reasons
|
| - *
|
| - * Since this function is only called by PKIX_PL_Initialize, which should
|
| - * only be called once, it is acceptable that this function is not
|
| - * thread-safe.
|
| - *
|
| - * PKIX_PL_Object should have all function pointes to be to NULL: they
|
| - * work as proxy function to a real objects.
|
| - *
|
| - */
|
| -PKIX_Error *
|
| -pkix_pl_Object_RegisterSelf(void *plContext)
|
| -{
|
| - pkix_ClassTable_Entry entry;
|
| -
|
| - PKIX_ENTER(ERROR, "pkix_pl_Object_RegisterSelf");
|
| -
|
| - entry.description = "Object";
|
| - entry.objCounter = 0;
|
| - entry.typeObjectSize = sizeof(PKIX_PL_Object);
|
| - entry.destructor = NULL;
|
| - entry.equalsFunction = NULL;
|
| - entry.hashcodeFunction = NULL;
|
| - entry.toStringFunction = NULL;
|
| - entry.comparator = NULL;
|
| - entry.duplicateFunction = NULL;
|
| -
|
| - systemClasses[PKIX_OBJECT_TYPE] = entry;
|
| -
|
| - PKIX_RETURN(ERROR);
|
| -}
|
| -
|
| -/* --Public-Functions------------------------------------------------------- */
|
| -
|
| -/*
|
| - * FUNCTION: PKIX_PL_Object_Alloc (see comments in pkix_pl_system.h)
|
| - */
|
| -PKIX_Error *
|
| -PKIX_PL_Object_Alloc(
|
| - PKIX_TYPENUM objType,
|
| - PKIX_UInt32 size,
|
| - PKIX_PL_Object **pObject,
|
| - void *plContext)
|
| -{
|
| - PKIX_PL_Object *object = NULL;
|
| - pkix_ClassTable_Entry *ctEntry = NULL;
|
| -
|
| - PKIX_ENTER(OBJECT, "PKIX_PL_Object_Alloc");
|
| - PKIX_NULLCHECK_ONE(pObject);
|
| -
|
| - /*
|
| - * We need to ensure that user-defined types have been registered.
|
| - * All system types have already been registered by PKIX_PL_Initialize.
|
| - */
|
| -
|
| - if (objType >= PKIX_NUMTYPES) { /* i.e. if this is a user-defined type */
|
| -#ifdef PKIX_USER_OBJECT_TYPE
|
| - PKIX_Boolean typeRegistered;
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
|
| - PR_Lock(classTableLock);
|
| - pkixErrorResult = pkix_pl_PrimHashTable_Lookup
|
| - (classTable,
|
| - (void *)&objType,
|
| - objType,
|
| - NULL,
|
| - (void **)&ctEntry,
|
| - plContext);
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
|
| - PR_Unlock(classTableLock);
|
| - if (pkixErrorResult){
|
| - PKIX_ERROR_FATAL(PKIX_COULDNOTLOOKUPINHASHTABLE);
|
| - }
|
| -
|
| - typeRegistered = (ctEntry != NULL);
|
| -
|
| - if (!typeRegistered) {
|
| - PKIX_ERROR_FATAL(PKIX_UNKNOWNTYPEARGUMENT);
|
| - }
|
| -#else
|
| - PORT_Assert (0);
|
| - pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
|
| - pkixErrorClass = PKIX_FATAL_ERROR;
|
| - goto cleanup;
|
| -#endif /* PKIX_USER_OBJECT_TYPE */
|
| - } else {
|
| - ctEntry = &systemClasses[objType];
|
| - }
|
| -
|
| - PORT_Assert(size == ctEntry->typeObjectSize);
|
| -
|
| - /* Allocate space for the object header and the requested size */
|
| -#ifdef PKIX_OBJECT_LEAK_TEST
|
| - PKIX_CHECK(PKIX_PL_Calloc
|
| - (1,
|
| - ((PKIX_UInt32)sizeof (PKIX_PL_Object))+size,
|
| - (void **)&object,
|
| - plContext),
|
| - PKIX_MALLOCFAILED);
|
| -#else
|
| - PKIX_CHECK(PKIX_PL_Malloc
|
| - (((PKIX_UInt32)sizeof (PKIX_PL_Object))+size,
|
| - (void **)&object,
|
| - plContext),
|
| - PKIX_MALLOCFAILED);
|
| -#endif /* PKIX_OBJECT_LEAK_TEST */
|
| -
|
| - /* Initialize all object fields */
|
| - object->magicHeader = PKIX_MAGIC_HEADER;
|
| - object->type = objType;
|
| - object->references = 1; /* Default to a single reference */
|
| - object->stringRep = NULL;
|
| - object->hashcode = 0;
|
| - object->hashcodeCached = 0;
|
| -
|
| - /* Cannot use PKIX_PL_Mutex because it depends on Object */
|
| - /* Using NSPR Locks instead */
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_NewLock).\n");
|
| - object->lock = PR_NewLock();
|
| - if (object->lock == NULL) {
|
| - PKIX_ERROR_ALLOC_ERROR();
|
| - }
|
| -
|
| - PKIX_OBJECT_DEBUG("\tShifting object pointer).\n");
|
| -
|
| -
|
| - /* Return a pointer to the user data. Need to offset by object size */
|
| - *pObject = object + 1;
|
| - object = NULL;
|
| -
|
| - /* Atomically increment object counter */
|
| - PR_ATOMIC_INCREMENT(&ctEntry->objCounter);
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_FREE(object);
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/*
|
| - * FUNCTION: PKIX_PL_Object_IsTypeRegistered (see comments in pkix_pl_system.h)
|
| - */
|
| -PKIX_Error *
|
| -PKIX_PL_Object_IsTypeRegistered(
|
| - PKIX_UInt32 objType,
|
| - PKIX_Boolean *pBool,
|
| - void *plContext)
|
| -{
|
| -#ifdef PKIX_USER_OBJECT_TYPE
|
| - pkix_ClassTable_Entry *ctEntry = NULL;
|
| -#endif
|
| -
|
| - PKIX_ENTER(OBJECT, "PKIX_PL_Object_IsTypeRegistered");
|
| - PKIX_NULLCHECK_ONE(pBool);
|
| -
|
| - /* first, we handle the system types */
|
| - if (objType < PKIX_NUMTYPES) {
|
| - *pBool = PKIX_TRUE;
|
| - goto cleanup;
|
| - }
|
| -
|
| -#ifndef PKIX_USER_OBJECT_TYPE
|
| - PORT_Assert (0);
|
| - pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
|
| - pkixErrorClass = PKIX_FATAL_ERROR;
|
| -#else
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
|
| - PR_Lock(classTableLock);
|
| - pkixErrorResult = pkix_pl_PrimHashTable_Lookup
|
| - (classTable,
|
| - (void *)&objType,
|
| - objType,
|
| - NULL,
|
| - (void **)&ctEntry,
|
| - plContext);
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
|
| - PR_Unlock(classTableLock);
|
| -
|
| - if (pkixErrorResult){
|
| - PKIX_ERROR_FATAL(PKIX_COULDNOTLOOKUPINHASHTABLE);
|
| - }
|
| -
|
| - *pBool = (ctEntry != NULL);
|
| -#endif /* PKIX_USER_OBJECT_TYPE */
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -#ifdef PKIX_USER_OBJECT_TYPE
|
| -/*
|
| - * FUNCTION: PKIX_PL_Object_RegisterType (see comments in pkix_pl_system.h)
|
| - */
|
| -PKIX_Error *
|
| -PKIX_PL_Object_RegisterType(
|
| - PKIX_UInt32 objType,
|
| - char *description,
|
| - PKIX_PL_DestructorCallback destructor,
|
| - PKIX_PL_EqualsCallback equalsFunction,
|
| - PKIX_PL_HashcodeCallback hashcodeFunction,
|
| - PKIX_PL_ToStringCallback toStringFunction,
|
| - PKIX_PL_ComparatorCallback comparator,
|
| - PKIX_PL_DuplicateCallback duplicateFunction,
|
| - void *plContext)
|
| -{
|
| - pkix_ClassTable_Entry *ctEntry = NULL;
|
| - pkix_pl_Integer *key = NULL;
|
| -
|
| - PKIX_ENTER(OBJECT, "PKIX_PL_Object_RegisterType");
|
| -
|
| - /*
|
| - * System types are registered on startup by PKIX_PL_Initialize.
|
| - * These can not be overwritten.
|
| - */
|
| -
|
| - if (objType < PKIX_NUMTYPES) { /* if this is a system type */
|
| - PKIX_ERROR(PKIX_CANTREREGISTERSYSTEMTYPE);
|
| - }
|
| -
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
|
| - PR_Lock(classTableLock);
|
| - PKIX_CHECK(pkix_pl_PrimHashTable_Lookup
|
| - (classTable,
|
| - (void *)&objType,
|
| - objType,
|
| - NULL,
|
| - (void **)&ctEntry,
|
| - plContext),
|
| - PKIX_PRIMHASHTABLELOOKUPFAILED);
|
| -
|
| - /* If the type is already registered, throw an error */
|
| - if (ctEntry) {
|
| - PKIX_ERROR(PKIX_TYPEALREADYREGISTERED);
|
| - }
|
| -
|
| - PKIX_CHECK(PKIX_PL_Malloc
|
| - (((PKIX_UInt32)sizeof (pkix_ClassTable_Entry)),
|
| - (void **)&ctEntry,
|
| - plContext),
|
| - PKIX_MALLOCFAILED);
|
| -
|
| - /* Set Default Values if none specified */
|
| -
|
| - if (description == NULL){
|
| - description = "Object";
|
| - }
|
| -
|
| - if (equalsFunction == NULL) {
|
| - equalsFunction = pkix_pl_Object_Equals_Default;
|
| - }
|
| -
|
| - if (toStringFunction == NULL) {
|
| - toStringFunction = pkix_pl_Object_ToString_Default;
|
| - }
|
| -
|
| - if (hashcodeFunction == NULL) {
|
| - hashcodeFunction = pkix_pl_Object_Hashcode_Default;
|
| - }
|
| -
|
| - ctEntry->destructor = destructor;
|
| - ctEntry->equalsFunction = equalsFunction;
|
| - ctEntry->toStringFunction = toStringFunction;
|
| - ctEntry->hashcodeFunction = hashcodeFunction;
|
| - ctEntry->comparator = comparator;
|
| - ctEntry->duplicateFunction = duplicateFunction;
|
| - ctEntry->description = description;
|
| -
|
| - PKIX_CHECK(PKIX_PL_Malloc
|
| - (((PKIX_UInt32)sizeof (pkix_pl_Integer)),
|
| - (void **)&key,
|
| - plContext),
|
| - PKIX_COULDNOTMALLOCNEWKEY);
|
| -
|
| - key->ht_int = objType;
|
| -
|
| - PKIX_CHECK(pkix_pl_PrimHashTable_Add
|
| - (classTable,
|
| - (void *)key,
|
| - (void *)ctEntry,
|
| - objType,
|
| - NULL,
|
| - plContext),
|
| - PKIX_PRIMHASHTABLEADDFAILED);
|
| -
|
| -cleanup:
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
|
| - PR_Unlock(classTableLock);
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -#endif /* PKIX_USER_OBJECT_TYPE */
|
| -
|
| -/*
|
| - * FUNCTION: PKIX_PL_Object_IncRef (see comments in pkix_pl_system.h)
|
| - */
|
| -PKIX_Error *
|
| -PKIX_PL_Object_IncRef(
|
| - PKIX_PL_Object *object,
|
| - void *plContext)
|
| -{
|
| - PKIX_PL_Object *objectHeader = NULL;
|
| - PKIX_PL_NssContext *context = NULL;
|
| - PKIX_Int32 refCount = 0;
|
| -
|
| - PKIX_ENTER(OBJECT, "PKIX_PL_Object_IncRef");
|
| - PKIX_NULLCHECK_ONE(object);
|
| -
|
| - if (plContext){
|
| - /*
|
| - * PKIX_PL_NssContext is not a complete PKIX Type, it doesn't
|
| - * have a header therefore we cannot verify its type before
|
| - * casting.
|
| - */
|
| - context = (PKIX_PL_NssContext *) plContext;
|
| - if (context->arena != NULL) {
|
| - goto cleanup;
|
| - }
|
| - }
|
| -
|
| - if (object == (PKIX_PL_Object*)PKIX_ALLOC_ERROR()) {
|
| - goto cleanup;
|
| - }
|
| -
|
| - /* Shift pointer from user data to object header */
|
| - PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
|
| - PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
|
| -
|
| - /* This object should never have zero references */
|
| - refCount = PR_ATOMIC_INCREMENT(&objectHeader->references);
|
| -
|
| - if (refCount <= 1) {
|
| - PKIX_THROW(FATAL, PKIX_OBJECTWITHNONPOSITIVEREFERENCES);
|
| - }
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/*
|
| - * FUNCTION: PKIX_PL_Object_DecRef (see comments in pkix_pl_system.h)
|
| - */
|
| -PKIX_Error *
|
| -PKIX_PL_Object_DecRef(
|
| - PKIX_PL_Object *object,
|
| - void *plContext)
|
| -{
|
| - PKIX_Int32 refCount = 0;
|
| - PKIX_PL_Object *objectHeader = NULL;
|
| - PKIX_PL_NssContext *context = NULL;
|
| -
|
| - PKIX_ENTER(OBJECT, "PKIX_PL_Object_DecRef");
|
| - PKIX_NULLCHECK_ONE(object);
|
| -
|
| - if (plContext){
|
| - /*
|
| - * PKIX_PL_NssContext is not a complete PKIX Type, it doesn't
|
| - * have a header therefore we cannot verify its type before
|
| - * casting.
|
| - */
|
| - context = (PKIX_PL_NssContext *) plContext;
|
| - if (context->arena != NULL) {
|
| - goto cleanup;
|
| - }
|
| - }
|
| -
|
| - if (object == (PKIX_PL_Object*)PKIX_ALLOC_ERROR()) {
|
| - goto cleanup;
|
| - }
|
| -
|
| - /* Shift pointer from user data to object header */
|
| - PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
|
| - PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
|
| -
|
| - refCount = PR_ATOMIC_DECREMENT(&objectHeader->references);
|
| -
|
| - if (refCount == 0) {
|
| - PKIX_PL_DestructorCallback destructor = NULL;
|
| - pkix_ClassTable_Entry *ctEntry = NULL;
|
| - PKIX_UInt32 objType = objectHeader->type;
|
| -
|
| - /* first, special handling for system types */
|
| - if (objType >= PKIX_NUMTYPES){
|
| -#ifdef PKIX_USER_OBJECT_TYPE
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
|
| - PR_Lock(classTableLock);
|
| - pkixErrorResult = pkix_pl_PrimHashTable_Lookup
|
| - (classTable,
|
| - (void *)&objType,
|
| - objType,
|
| - NULL,
|
| - (void **)&ctEntry,
|
| - plContext);
|
| - PKIX_OBJECT_DEBUG
|
| - ("\tCalling PR_Unlock).\n");
|
| - PR_Unlock(classTableLock);
|
| - if (pkixErrorResult){
|
| - PKIX_ERROR_FATAL
|
| - (PKIX_ERRORINGETTINGDESTRUCTOR);
|
| - }
|
| -
|
| - if (ctEntry != NULL){
|
| - destructor = ctEntry->destructor;
|
| - }
|
| -#else
|
| - PORT_Assert (0);
|
| - pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
|
| - pkixErrorClass = PKIX_FATAL_ERROR;
|
| - goto cleanup;
|
| -#endif /* PKIX_USER_OBJECT_TYPE */
|
| - } else {
|
| - ctEntry = &systemClasses[objType];
|
| - destructor = ctEntry->destructor;
|
| - }
|
| -
|
| - if (destructor != NULL){
|
| - /* Call destructor on user data if necessary */
|
| - pkixErrorResult = destructor(object, plContext);
|
| - if (pkixErrorResult) {
|
| - pkixErrorClass = PKIX_FATAL_ERROR;
|
| - PKIX_DoAddError(stdVarsPtr, pkixErrorResult, plContext);
|
| - pkixErrorResult = NULL;
|
| - }
|
| - }
|
| -
|
| - /* Atomically decrement object counter */
|
| - PR_ATOMIC_DECREMENT(&ctEntry->objCounter);
|
| -
|
| - /* pkix_pl_Object_Destroy assumes the lock is held */
|
| - /* It will call unlock and destroy the object */
|
| - pkixErrorResult = pkix_pl_Object_Destroy(object, plContext);
|
| - goto cleanup;
|
| - }
|
| -
|
| - if (refCount < 0) {
|
| - PKIX_ERROR_ALLOC_ERROR();
|
| - }
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -
|
| -
|
| -/*
|
| - * FUNCTION: PKIX_PL_Object_Equals (see comments in pkix_pl_system.h)
|
| - */
|
| -PKIX_Error *
|
| -PKIX_PL_Object_Equals(
|
| - PKIX_PL_Object *firstObject,
|
| - PKIX_PL_Object *secondObject,
|
| - PKIX_Boolean *pResult,
|
| - void *plContext)
|
| -{
|
| - PKIX_PL_Object *firstObjectHeader = NULL;
|
| - PKIX_PL_Object *secondObjectHeader = NULL;
|
| - PKIX_PL_EqualsCallback func = NULL;
|
| - pkix_ClassTable_Entry entry;
|
| - PKIX_UInt32 objType;
|
| -
|
| - PKIX_ENTER(OBJECT, "PKIX_PL_Object_Equals");
|
| - PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
|
| -
|
| - PKIX_CHECK(pkix_pl_Object_GetHeader
|
| - (firstObject, &firstObjectHeader, plContext),
|
| - PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
|
| -
|
| - PKIX_CHECK(pkix_pl_Object_GetHeader
|
| - (secondObject, &secondObjectHeader, plContext),
|
| - PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
|
| -
|
| - /* if hashcodes are cached but not equal, objects can't be equal */
|
| - if (firstObjectHeader->hashcodeCached &&
|
| - secondObjectHeader->hashcodeCached){
|
| - if (firstObjectHeader->hashcode !=
|
| - secondObjectHeader->hashcode){
|
| - *pResult = PKIX_FALSE;
|
| - goto cleanup;
|
| - }
|
| - }
|
| -
|
| - objType = firstObjectHeader->type;
|
| -
|
| - if (objType >= PKIX_NUMTYPES) {
|
| -#ifdef PKIX_USER_OBJECT_TYPE
|
| - pkix_ClassTable_Entry *ctEntry = NULL;
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
|
| - PR_Lock(classTableLock);
|
| - pkixErrorResult = pkix_pl_PrimHashTable_Lookup
|
| - (classTable,
|
| - (void *)&firstObjectHeader->type,
|
| - firstObjectHeader->type,
|
| - NULL,
|
| - (void **)&ctEntry,
|
| - plContext);
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
|
| - PR_Unlock(classTableLock);
|
| -
|
| - if (pkixErrorResult){
|
| - PKIX_ERROR_FATAL(PKIX_ERRORGETTINGCLASSTABLEENTRY);
|
| - }
|
| -
|
| - if ((ctEntry == NULL) || (ctEntry->equalsFunction == NULL)) {
|
| - PKIX_ERROR_FATAL(PKIX_UNDEFINEDCALLBACK);
|
| - } else {
|
| - func = ctEntry->equalsFunction;
|
| - }
|
| -#else
|
| - PORT_Assert (0);
|
| - pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
|
| - pkixErrorClass = PKIX_FATAL_ERROR;
|
| - goto cleanup;
|
| -#endif /* PKIX_USER_OBJECT_TYPE */
|
| - } else {
|
| - entry = systemClasses[objType];
|
| - func = entry.equalsFunction;
|
| - if (func == NULL){
|
| - func = pkix_pl_Object_Equals_Default;
|
| - }
|
| - }
|
| -
|
| - PKIX_CHECK(func(firstObject, secondObject, pResult, plContext),
|
| - PKIX_OBJECTSPECIFICFUNCTIONFAILED);
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/*
|
| - * FUNCTION: PKIX_PL_Object_Duplicate (see comments in pkix_pl_system.h)
|
| - */
|
| -PKIX_Error *
|
| -PKIX_PL_Object_Duplicate(
|
| - PKIX_PL_Object *firstObject,
|
| - PKIX_PL_Object **pNewObject,
|
| - void *plContext)
|
| -{
|
| - PKIX_PL_Object *firstObjectHeader = NULL;
|
| - PKIX_PL_DuplicateCallback func = NULL;
|
| - pkix_ClassTable_Entry entry;
|
| - PKIX_UInt32 objType;
|
| -
|
| - PKIX_ENTER(OBJECT, "PKIX_PL_Object_Duplicate");
|
| - PKIX_NULLCHECK_TWO(firstObject, pNewObject);
|
| -
|
| - PKIX_CHECK(pkix_pl_Object_GetHeader
|
| - (firstObject, &firstObjectHeader, plContext),
|
| - PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
|
| -
|
| - objType = firstObjectHeader->type;
|
| -
|
| - if (objType >= PKIX_NUMTYPES) {
|
| -#ifdef PKIX_USER_OBJECT_TYPE
|
| - pkix_ClassTable_Entry *ctEntry = NULL;
|
| -
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
|
| - PR_Lock(classTableLock);
|
| - pkixErrorResult = pkix_pl_PrimHashTable_Lookup
|
| - (classTable,
|
| - (void *)&objType,
|
| - objType,
|
| - NULL,
|
| - (void **)&ctEntry,
|
| - plContext);
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
|
| - PR_Unlock(classTableLock);
|
| -
|
| - if (pkixErrorResult){
|
| - PKIX_ERROR_FATAL(PKIX_ERRORGETTINGCLASSTABLEENTRY);
|
| - }
|
| -
|
| - if ((ctEntry == NULL) || (ctEntry->duplicateFunction == NULL)) {
|
| - PKIX_ERROR_FATAL(PKIX_UNDEFINEDCALLBACK);
|
| - } else {
|
| - func = ctEntry->duplicateFunction;
|
| - }
|
| -#else
|
| - PORT_Assert (0);
|
| - pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
|
| - pkixErrorClass = PKIX_FATAL_ERROR;
|
| - goto cleanup;
|
| -#endif /* PKIX_USER_OBJECT_TYPE */
|
| - } else {
|
| - entry = systemClasses[objType];
|
| - func = entry.duplicateFunction;
|
| - if (!func){
|
| - PKIX_ERROR_FATAL(PKIX_UNDEFINEDDUPLICATEFUNCTION);
|
| - }
|
| - }
|
| -
|
| - PKIX_CHECK(func(firstObject, pNewObject, plContext),
|
| - PKIX_OBJECTSPECIFICFUNCTIONFAILED);
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/*
|
| - * FUNCTION: PKIX_PL_Object_Hashcode (see comments in pkix_pl_system.h)
|
| - */
|
| -PKIX_Error *
|
| -PKIX_PL_Object_Hashcode(
|
| - PKIX_PL_Object *object,
|
| - PKIX_UInt32 *pValue,
|
| - void *plContext)
|
| -{
|
| - PKIX_PL_Object *objectHeader = NULL;
|
| - PKIX_PL_HashcodeCallback func = NULL;
|
| - pkix_ClassTable_Entry entry;
|
| - PKIX_UInt32 objectHash;
|
| -
|
| - PKIX_ENTER(OBJECT, "PKIX_PL_Object_Hashcode");
|
| - PKIX_NULLCHECK_TWO(object, pValue);
|
| -
|
| - /* Shift pointer from user data to object header */
|
| - PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
|
| - PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
|
| -
|
| - /* if we don't have a cached copy from before, we create one */
|
| - if (!objectHeader->hashcodeCached){
|
| -
|
| - PKIX_UInt32 objType = objectHeader->type;
|
| -
|
| - /* first, special handling for system types */
|
| - if (objType >= PKIX_NUMTYPES){
|
| -#ifdef PKIX_USER_OBJECT_TYPE
|
| - pkix_ClassTable_Entry *ctEntry = NULL;
|
| -
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
|
| - PR_Lock(classTableLock);
|
| - pkixErrorResult = pkix_pl_PrimHashTable_Lookup
|
| - (classTable,
|
| - (void *)&objType,
|
| - objType,
|
| - NULL,
|
| - (void **)&ctEntry,
|
| - plContext);
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
|
| - PR_Unlock(classTableLock);
|
| -
|
| - if (pkixErrorResult){
|
| - PKIX_ERROR_FATAL
|
| - (PKIX_ERRORGETTINGCLASSTABLEENTRY);
|
| - }
|
| -
|
| - if ((ctEntry == NULL) ||
|
| - (ctEntry->hashcodeFunction == NULL)) {
|
| - PKIX_ERROR_FATAL(PKIX_UNDEFINEDCALLBACK);
|
| - }
|
| -
|
| - func = ctEntry->hashcodeFunction;
|
| -#else
|
| - PORT_Assert (0);
|
| - pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
|
| - pkixErrorClass = PKIX_FATAL_ERROR;
|
| - goto cleanup;
|
| -#endif /* PKIX_USER_OBJECT_TYPE */
|
| - } else {
|
| - entry = systemClasses[objType];
|
| - func = entry.hashcodeFunction;
|
| - if (func == NULL){
|
| - func = pkix_pl_Object_Hashcode_Default;
|
| - }
|
| - }
|
| -
|
| - PKIX_CHECK(func(object, &objectHash, plContext),
|
| - PKIX_OBJECTSPECIFICFUNCTIONFAILED);
|
| -
|
| - if (!objectHeader->hashcodeCached){
|
| -
|
| - PKIX_CHECK(pkix_LockObject(object, plContext),
|
| - PKIX_ERRORLOCKINGOBJECT);
|
| -
|
| - if (!objectHeader->hashcodeCached){
|
| - /* save cached copy in case we need it again */
|
| - objectHeader->hashcode = objectHash;
|
| - objectHeader->hashcodeCached = PKIX_TRUE;
|
| - }
|
| -
|
| - PKIX_CHECK(pkix_UnlockObject(object, plContext),
|
| - PKIX_ERRORUNLOCKINGOBJECT);
|
| - }
|
| - }
|
| -
|
| - *pValue = objectHeader->hashcode;
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/*
|
| - * FUNCTION: PKIX_PL_Object_ToString (see comments in pkix_pl_system.h)
|
| - */
|
| -PKIX_Error *
|
| -PKIX_PL_Object_ToString(
|
| - PKIX_PL_Object *object,
|
| - PKIX_PL_String **pString,
|
| - void *plContext)
|
| -{
|
| - PKIX_PL_Object *objectHeader = NULL;
|
| - PKIX_PL_ToStringCallback func = NULL;
|
| - pkix_ClassTable_Entry entry;
|
| - PKIX_PL_String *objectString = NULL;
|
| -
|
| - PKIX_ENTER(OBJECT, "PKIX_PL_Object_ToString");
|
| - PKIX_NULLCHECK_TWO(object, pString);
|
| -
|
| - /* Shift pointer from user data to object header */
|
| - PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
|
| - PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
|
| -
|
| - /* if we don't have a cached copy from before, we create one */
|
| - if (!objectHeader->stringRep){
|
| -
|
| - PKIX_UInt32 objType = objectHeader->type;
|
| -
|
| - if (objType >= PKIX_NUMTYPES){
|
| -#ifdef PKIX_USER_OBJECT_TYPE
|
| - pkix_ClassTable_Entry *ctEntry = NULL;
|
| -
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
|
| - PR_Lock(classTableLock);
|
| - pkixErrorResult = pkix_pl_PrimHashTable_Lookup
|
| - (classTable,
|
| - (void *)&objType,
|
| - objType,
|
| - NULL,
|
| - (void **)&ctEntry,
|
| - plContext);
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
|
| - PR_Unlock(classTableLock);
|
| - if (pkixErrorResult){
|
| - PKIX_ERROR_FATAL
|
| - (PKIX_ERRORGETTINGCLASSTABLEENTRY);
|
| - }
|
| -
|
| - if ((ctEntry == NULL) ||
|
| - (ctEntry->toStringFunction == NULL)) {
|
| - PKIX_ERROR_FATAL(PKIX_UNDEFINEDCALLBACK);
|
| - }
|
| -
|
| - func = ctEntry->toStringFunction;
|
| -#else
|
| - PORT_Assert (0);
|
| - pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
|
| - pkixErrorClass = PKIX_FATAL_ERROR;
|
| - goto cleanup;
|
| -#endif /* PKIX_USER_OBJECT_TYPE */
|
| - } else {
|
| - entry = systemClasses[objType];
|
| - func = entry.toStringFunction;
|
| - if (func == NULL){
|
| - func = pkix_pl_Object_ToString_Default;
|
| - }
|
| - }
|
| -
|
| - PKIX_CHECK(func(object, &objectString, plContext),
|
| - PKIX_OBJECTSPECIFICFUNCTIONFAILED);
|
| -
|
| - if (!objectHeader->stringRep){
|
| -
|
| - PKIX_CHECK(pkix_LockObject(object, plContext),
|
| - PKIX_ERRORLOCKINGOBJECT);
|
| -
|
| - if (!objectHeader->stringRep){
|
| - /* save a cached copy */
|
| - objectHeader->stringRep = objectString;
|
| - objectString = NULL;
|
| - }
|
| -
|
| - PKIX_CHECK(pkix_UnlockObject(object, plContext),
|
| - PKIX_ERRORUNLOCKINGOBJECT);
|
| - }
|
| - }
|
| -
|
| -
|
| - *pString = objectHeader->stringRep;
|
| - objectHeader->stringRep = NULL;
|
| -
|
| -cleanup:
|
| - if (objectHeader) {
|
| - PKIX_DECREF(objectHeader->stringRep);
|
| - }
|
| - PKIX_DECREF(objectString);
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/*
|
| - * FUNCTION: PKIX_PL_Object_InvalidateCache (see comments in pkix_pl_system.h)
|
| - */
|
| -PKIX_Error *
|
| -PKIX_PL_Object_InvalidateCache(
|
| - PKIX_PL_Object *object,
|
| - void *plContext)
|
| -{
|
| - PKIX_PL_Object *objectHeader = NULL;
|
| -
|
| - PKIX_ENTER(OBJECT, "PKIX_PL_Object_InvalidateCache");
|
| - PKIX_NULLCHECK_ONE(object);
|
| -
|
| - /* Shift pointer from user data to object header */
|
| - PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
|
| - PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
|
| -
|
| - PKIX_CHECK(pkix_LockObject(object, plContext),
|
| - PKIX_ERRORLOCKINGOBJECT);
|
| -
|
| - /* invalidate hashcode */
|
| - objectHeader->hashcode = 0;
|
| - objectHeader->hashcodeCached = PKIX_FALSE;
|
| -
|
| - PKIX_DECREF(objectHeader->stringRep);
|
| -
|
| - PKIX_CHECK(pkix_UnlockObject(object, plContext),
|
| - PKIX_ERRORUNLOCKINGOBJECT);
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/*
|
| - * FUNCTION: PKIX_PL_Object_Compare (see comments in pkix_pl_system.h)
|
| - */
|
| -PKIX_Error *
|
| -PKIX_PL_Object_Compare(
|
| - PKIX_PL_Object *firstObject,
|
| - PKIX_PL_Object *secondObject,
|
| - PKIX_Int32 *pResult,
|
| - void *plContext)
|
| -{
|
| - PKIX_PL_Object *firstObjectHeader = NULL;
|
| - PKIX_PL_Object *secondObjectHeader = NULL;
|
| - PKIX_PL_ComparatorCallback func = NULL;
|
| - pkix_ClassTable_Entry entry;
|
| - PKIX_UInt32 objType;
|
| -
|
| - PKIX_ENTER(OBJECT, "PKIX_PL_Object_Compare");
|
| - PKIX_NULLCHECK_THREE(firstObject, secondObject, pResult);
|
| -
|
| - /* Shift pointer from user data to object header */
|
| - PKIX_CHECK(pkix_pl_Object_GetHeader
|
| - (firstObject, &firstObjectHeader, plContext),
|
| - PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
|
| -
|
| - /* Shift pointer from user data to object header */
|
| - PKIX_CHECK(pkix_pl_Object_GetHeader
|
| - (secondObject, &secondObjectHeader, plContext),
|
| - PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
|
| -
|
| - objType = firstObjectHeader->type;
|
| -
|
| - if (objType >= PKIX_NUMTYPES){
|
| -#ifdef PKIX_USER_OBJECT_TYPE
|
| - pkix_ClassTable_Entry *ctEntry = NULL;
|
| -
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Lock).\n");
|
| - PR_Lock(classTableLock);
|
| - pkixErrorResult = pkix_pl_PrimHashTable_Lookup
|
| - (classTable,
|
| - (void *)&objType,
|
| - objType,
|
| - NULL,
|
| - (void **)&ctEntry,
|
| - plContext);
|
| - PKIX_OBJECT_DEBUG("\tCalling PR_Unlock).\n");
|
| - PR_Unlock(classTableLock);
|
| - if (pkixErrorResult){
|
| - PKIX_ERROR_FATAL(PKIX_ERRORGETTINGCLASSTABLEENTRY);
|
| - }
|
| -
|
| - if ((ctEntry == NULL) || (ctEntry->comparator == NULL)) {
|
| - PKIX_ERROR_FATAL(PKIX_UNDEFINEDCOMPARATOR);
|
| - }
|
| -
|
| - func = ctEntry->comparator;
|
| -#else
|
| - PORT_Assert (0);
|
| - pkixErrorCode = PKIX_UNKNOWNOBJECTTYPE;
|
| - pkixErrorClass = PKIX_FATAL_ERROR;
|
| - goto cleanup;
|
| -#endif /* PKIX_USER_OBJECT_TYPE */
|
| - } else {
|
| - /* special handling for system types */
|
| - entry = systemClasses[objType];
|
| - func = entry.comparator;
|
| - if (!func){
|
| - PKIX_ERROR(PKIX_UNDEFINEDCOMPARATOR);
|
| - }
|
| - }
|
| -
|
| - PKIX_CHECK(func(firstObject, secondObject, pResult, plContext),
|
| - PKIX_OBJECTSPECIFICFUNCTIONFAILED);
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/*
|
| - * FUNCTION: PKIX_PL_Object_Lock (see comments in pkix_pl_system.h)
|
| - */
|
| -PKIX_Error *
|
| -PKIX_PL_Object_Lock(
|
| - PKIX_PL_Object *object,
|
| - void *plContext)
|
| -{
|
| - PKIX_ENTER(OBJECT, "PKIX_PL_Object_Lock");
|
| - PKIX_NULLCHECK_ONE(object);
|
| -
|
| - PKIX_CHECK(pkix_LockObject(object, plContext),
|
| - PKIX_LOCKOBJECTFAILED);
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -/*
|
| - * FUNCTION: PKIX_PL_Object_Unlock (see comments in pkix_pl_system.h)
|
| - */
|
| -PKIX_Error *
|
| -PKIX_PL_Object_Unlock(
|
| - PKIX_PL_Object *object,
|
| - void *plContext)
|
| -{
|
| - PKIX_ENTER(OBJECT, "PKIX_PL_Object_Unlock");
|
| - PKIX_NULLCHECK_ONE(object);
|
| -
|
| - PKIX_CHECK(pkix_UnlockObject(object, plContext),
|
| - PKIX_UNLOCKOBJECTFAILED);
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
| -
|
| -
|
| -/*
|
| - * FUNCTION: PKIX_PL_Object_GetType (see comments in pkix_pl_system.h)
|
| - */
|
| -PKIX_Error *
|
| -PKIX_PL_Object_GetType(
|
| - PKIX_PL_Object *object,
|
| - PKIX_UInt32 *pType,
|
| - void *plContext)
|
| -{
|
| - PKIX_PL_Object *objectHeader = NULL;
|
| -
|
| - PKIX_ENTER(OBJECT, "PKIX_PL_Object_GetType");
|
| - PKIX_NULLCHECK_TWO(object, pType);
|
| -
|
| - /* Shift pointer from user data to object header */
|
| - PKIX_CHECK(pkix_pl_Object_GetHeader(object, &objectHeader, plContext),
|
| - PKIX_RECEIVEDCORRUPTEDOBJECTARGUMENT);
|
| -
|
| - *pType = objectHeader->type;
|
| -
|
| -cleanup:
|
| -
|
| - PKIX_RETURN(OBJECT);
|
| -}
|
|
|