diff options
Diffstat (limited to 'security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c')
-rwxr-xr-x | security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c | 1473 |
1 files changed, 0 insertions, 1473 deletions
diff --git a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c b/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c deleted file mode 100755 index 846977b37..000000000 --- a/security/nss/lib/libpkix/pkix_pl_nss/system/pkix_pl_object.c +++ /dev/null @@ -1,1473 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the PKIX-C library. - * - * The Initial Developer of the Original Code is - * Sun Microsystems, Inc. - * Portions created by the Initial Developer are - * Copyright 2004-2007 Sun Microsystems, Inc. All Rights Reserved. - * - * Contributor(s): - * Sun Microsystems, Inc. - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * 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_AtomicIncrement(&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_AtomicIncrement(&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_AtomicDecrement(&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_AtomicDecrement(&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); -} |