⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pgpkeyiter.c

📁 PGP8.0源码 请认真阅读您的文件包然后写出其具体功能
💻 C
📖 第 1 页 / 共 2 页
字号:
/*____________________________________________________________________________
        Copyright (C) 2002 PGP Corporation
        All rights reserved.

        PGP Key Iteration functions

        $Id: pgpKeyIter.c,v 1.28 2002/08/06 20:11:00 dallen Exp $
____________________________________________________________________________*/

#include "pgpConfig.h"

#include "pgpKeyPriv.h"
#include "pgpSigSpec.h"
#include "pgpContext.h"



	PGPError 
PGPNewKeyIter (
	PGPKeyListRef	keys,
	PGPKeyIterRef *	outRef)
{
	PGPKeyIter * newIter = NULL;
	PGPError	err	= kPGPError_NoErr;
	PGPContextRef	context	= PGPPeekKeyListContext( keys );

	PGPValidatePtr( outRef );
	*outRef	= NULL;
	PGPValidateKeyList( keys );

	pgpEnterPGPErrorFunction();

	newIter = (PGPKeyIter *)pgpContextMemAlloc(
		context, sizeof (PGPKeyIter), kPGPMemoryMgrFlags_Clear );
	if ( IsntNull( newIter ) )
	{
		newIter->magic	= kPGPKeyIterMagic;
	    newIter->nextIterInList = keys->firstIterInList;
		newIter->prevIterInList = NULL;
		if (newIter->nextIterInList)
		    newIter->nextIterInList->prevIterInList = newIter;
		keys->firstIterInList = newIter;
		PGPIncKeyListRefCount(keys);
		newIter->keyList = keys;
		newIter->keySet = NULL;
		newIter->isKeyList = TRUE;

		newIter->keyIndex = -1;
		newIter->level = -1;
		newIter->currentObject = NULL;
		
		*outRef	= newIter;
	}
	else
	{
		err	= kPGPError_OutOfMemory;
	}
	
	pgpAssertErrWithPtr( err, *outRef );
	return( err );
}

	PGPError 
PGPNewKeyIterFromKeySet (
	PGPKeySetRef	keyset,
	PGPKeyIterRef *	outRef)
{
	PGPKeyIter * newIter = NULL;
	PGPError	err	= kPGPError_NoErr;
	PGPContextRef	context	= PGPPeekKeySetContext( keyset );

	PGPValidatePtr( outRef );
	*outRef	= NULL;
	PGPValidateKeySet( keyset );

	pgpEnterPGPErrorFunction();

	newIter = (PGPKeyIter *)pgpContextMemAlloc(
		context, sizeof (PGPKeyIter), kPGPMemoryMgrFlags_Clear );
	if ( IsntNull( newIter ) )
	{
		newIter->magic	= kPGPKeyIterMagic;
	    newIter->nextIterInList = NULL;
		newIter->prevIterInList = NULL;
		PGPIncKeySetRefCount(keyset);
		newIter->keyList = NULL;
		newIter->keySet = keyset;
		newIter->isKeyList = FALSE;

		newIter->keyIndex = -1;
		newIter->level = -1;
		newIter->currentObject = NULL;
		
		*outRef	= newIter;
	}
	else
	{
		err	= kPGPError_OutOfMemory;
	}
	
	pgpAssertErrWithPtr( err, *outRef );
	return( err );
}

	PGPError 
PGPNewKeyIterFromKeyDB (
	PGPKeyDB *		keyDB,
	PGPKeyIterRef *	outRef)
{
	return PGPNewKeyIterFromKeySet( keyDB->rootSet, outRef );
}


	PGPError  
PGPCopyKeyIter (
	PGPKeyIterRef 	orig,
	PGPKeyIterRef *	outRef)
{
	PGPKeyIterRef	newIter = NULL;
	PGPError		err	= kPGPError_NoErr;

	PGPValidatePtr( outRef );
	*outRef	= NULL;
	PGPValidateKeyIter( orig );
	
	pgpEnterPGPErrorFunction();

	if( orig->isKeyList )
		err	= PGPNewKeyIter (orig->keyList, &newIter );
	else
		err	= PGPNewKeyIterFromKeySet (orig->keySet, &newIter );
	if ( IsntPGPError( err ) )
	{
		newIter->keyIndex = orig->keyIndex;
		newIter->currentObject = orig->currentObject;
		newIter->level = orig->level;

		*outRef = newIter;
	}
	
	pgpAssertErrWithPtr( err, *outRef );
	return err;
}


PGPError 
PGPFreeKeyIter (PGPKeyIterRef iter)
{
	PGPContextRef	context	= NULL;
	
	PGPValidateKeyIter( iter );

	pgpEnterPGPErrorFunction();

	context	= PGPPeekKeyIterContext( iter );

	if( IsntNull(iter->keyList) ) {
	    if (iter->prevIterInList)
		    iter->prevIterInList->nextIterInList = iter->nextIterInList;
		else
		    iter->keyList->firstIterInList = iter->nextIterInList;
		if (iter->nextIterInList)
		    iter->nextIterInList->prevIterInList = iter->prevIterInList;
		PGPFreeKeyList( iter->keyList );
	} else {
		PGPFreeKeySet( iter->keySet );
	}
	iter->magic		= ~ iter->magic;	/* mark as invalid */
	pgpContextMemFree( context, iter);
	
	return( kPGPError_NoErr );
}
		

PGPInt32 
PGPKeyIterIndex (PGPKeyIterRef iter)
{
	if ( ! pgpKeyIterIsValid( iter ) )
		return( 0 );
		
	pgpEnterZeroFunction();

	return iter->keyIndex;
}


	static PGPError 
pgpKeyIterRewind (PGPKeyIterRef iter)
{
	PGPValidateKeyIter( iter );
	
	iter->keyIndex = -1;
	iter->level = -1;
	iter->currentObject = NULL;
	iter->atEndOfLevel = FALSE;
	
	return( kPGPError_NoErr );
}



/* Get the current object or one above us */
	static PGPKeyDBObj *
sKeyIterCurrentObject(
	PGPKeyIterRef	iter,
	PGPInt32		level)
{
	PGPKeyDBObj		*obj;

	if( iter->level == level )
	{
		if( iter->atEndOfLevel )
			obj = NULL;
		else
			obj = iter->currentObject;
	} else if( iter->level > level ) {
		obj = iter->currentObject;
		while( level++ < iter->level ) {
			obj = obj->up;
		}
	} else {
		obj = NULL;
	}
	return obj;
}

/* Returns true if item is a member of the keyiter.  If we are based on
 * a keylist rather than a keyset, we assume that any key or parent key
 * of an object we are called with is in the top level keylist array.
 */
	static PGPBoolean
sKeyIterIsMember( PGPKeyIter *iter, PGPKeyDBObj *obj )
{
	if( IsNull( obj ) )
		return FALSE;
	if( !pgpKeyDBObjIsReal( obj ) )
		return FALSE;
	if( !iter->isKeyList )
		return pgpKeySetIsMember( obj, iter->keySet );
	if( OBJISTOPKEY( obj ) )
		return TRUE;
	return PGPKeySetIsMember( obj, iter->keyList->keySet );
}


/* Call with iter pointing at an object at a certain level, and
 * advance relOffset steps at that level.  Return error if we go too
 * far.  Should not be used for level 0 if a keylist is used, that
 * just steps through the array.  Should be used for level 0 on
 * keysets, or for level > 0 in all cases.  A relOffset of 0 returns
 * the current object if it is in the set, or the next object if the
 * current one is not in the set.  When you first go DOWN to a new level,
 * call with relOffset = 0 to find the first object on that level.
 */
static PGPError
sKeyIterMoveAtLevel(
	PGPKeyIterRef	iter,
	PGPInt32		relOffset)
{
	PGPKeyDBObj *obj;
	PGPKeyDBObj *testobj;
	PGPKeyDBObj *prevobj;

	if( relOffset >= 0 ) {
		/* If at end, can't do any more */
		if( iter->atEndOfLevel )
			return kPGPError_EndOfIteration;

		obj = iter->currentObject;
		if( obj == NULL )
			return kPGPError_EndOfIteration;
			
		/* Count an extra if current object isn't in set */
		if( !sKeyIterIsMember( iter, obj )  &&  relOffset == 0 )
			++relOffset;

		/* Advance key relOffset times */
		while( relOffset > 0 && IsntNull( obj ) )
		{
			iter->currentObject = obj;
			obj = obj->next;
			if(sKeyIterIsMember( iter, obj ) )
				--relOffset;
		}
		if( IsNull( obj ) )
		{
			iter->atEndOfLevel = TRUE;
			return kPGPError_EndOfIteration;
		}
		iter->currentObject = obj;
		iter->atEndOfLevel = FALSE;
		return kPGPError_NoErr;
	} else {
		pgpAssert( relOffset < 0 );

		if( IsNull( iter->currentObject ) )
			return kPGPError_EndOfIteration;

		if( !sKeyIterIsMember( iter, iter->currentObject ) )
		{
			sKeyIterMoveAtLevel( iter, 0 );
		}

		obj = iter->currentObject;
		pgpAssert( (obj == NULL) || sKeyIterIsMember( iter, obj ) );

		/* Scan from beginning, -relOffset times */
		/* Or if we find obj before then, we move back to beginning */

		/* Find first obj in set as testobj */
		if( iter->level == 0 )
		{
			PGPKeyDBRef kdb = PGPPeekKeyDBObjKeyDB( obj );
			testobj = kdb->firstKeyInDB;
		} else {
			testobj = obj->up->down;
		}
		while( IsntNull(testobj) && !sKeyIterIsMember( iter, testobj ) )
			testobj = testobj->next;

		/* There may be no objects at this level */
		if( IsNull( testobj ) )
			return kPGPError_EndOfIteration;

		/* testobj is now first obj in set at this level */
		prevobj = testobj;

		/* Advance testobj -relOffset times, abort if find key */
		while( relOffset < 0 && testobj != obj )
		{
			testobj = testobj->next;
			if(sKeyIterIsMember( iter, testobj ) )
				++relOffset;
		}
		/* If hit key before then, return error */
		if( relOffset < 0 ) {
			/* Set pointer to starting object */
			iter->currentObject = prevobj;
			iter->atEndOfLevel = FALSE;
			return kPGPError_EndOfIteration;
		}
		/* Advance testobj forward until we hit obj, in step with prevobj */
		while( testobj != obj ) {
			do {
				testobj = testobj->next;
			} while(!sKeyIterIsMember( iter, testobj ) );
			do {
				prevobj = prevobj->next;
			} while(!sKeyIterIsMember( iter, prevobj ) );
		}
		iter->currentObject = prevobj;
		iter->atEndOfLevel = FALSE;
	}
	return kPGPError_NoErr;
}



/* Move the current top-level key by the specified offset */
static PGPError
sKeyIterMove( 
	PGPKeyIterRef	iter,
	PGPInt32		relOffset)
{
	PGPKeyDBRef		kdb;
    long       		newOffset;
	PGPKeyListRef	keylist = NULL;
	PGPError		err	= kPGPError_NoErr;

	if( relOffset == 0 )
		return kPGPError_NoErr;

	if( iter->isKeyList )
	{
		pgpAssert( IsntNull( iter->keyList ) );
		keylist		= iter->keyList;
		newOffset	= iter->keyIndex + relOffset;

#if 0
		/*  Check for removed key */
	    if ( IsntNull( iter->currentObject ) && iter->keyIndex >= 0 &&
				( iter->keyIndex >= keylist->keyCount-1 ||
	    		  keylist->keys[iter->keyIndex] != iter->currentObject ) )
	    {
		    /* key removed from keylist */ 
		    if (relOffset == 0) 
			{
				/* pgpFixBeforeShip( "this is probably wrong" ); */
				err	= kPGPError_EndOfIteration;
				return( err );
			}
			else if (relOffset > 0)
			    newOffset--;
		}
#endif

		iter->level = 0;
		if (newOffset >= 0 && newOffset < keylist->keyCount)
		{
			iter->currentObject = keylist->keys[newOffset];
			iter->atEndOfLevel = FALSE;
			iter->keyIndex = newOffset;
		}
		else
		{
			iter->atEndOfLevel = TRUE;
			newOffset = keylist->keyCount - 1;
			iter->keyIndex = newOffset;
			iter->currentObject = keylist->keys[newOffset];
			err = kPGPError_EndOfIteration;
		}
	}
	else
	{
		pgpAssert( IsntNull( iter->keySet ) );

		kdb = iter->keySet->keyDB;
		/* Move up to key we are currently pointing at */
		if( iter->level < 0 ) {
			iter->currentObject = kdb->firstKeyInDB;
			if( IsNull( iter->currentObject ) )
				return kPGPError_EndOfIteration;
			--relOffset;		/* Find first key that matches */
			iter->level = 0;
		} else if( iter->level > 0 ) {
			while( iter->level ) {
				iter->currentObject = iter->currentObject->up;
				--iter->level;
				iter->atEndOfLevel = FALSE;
			}
		}
		pgpAssert( iter->level <= 0 );
		pgpAssert( IsntNull(iter->currentObject) );

		err = sKeyIterMoveAtLevel( iter, relOffset );
		if( IsntPGPError( err ) )
			iter->keyIndex += relOffset;	/* approximate this */
	}
	return err;
}



PGPInt32 
PGPKeyIterSeek (PGPKeyIterRef iter, PGPKeyDBObjRef key)
{
	PGPKeyDBObj	**keys;
	long		i;

	PGPValidateKeyIter( iter );
	PGPValidateKey( key );
	
	pgpEnterZeroFunction();

	iter->keyIndex = -1;
	iter->currentObject = NULL;
	iter->level = -1;
	if( iter->isKeyList ) {
		keys = iter->keyList->keys;
		if (iter->keyList && (keys = iter->keyList->keys) != NULL) {
			for (i = 0; i < iter->keyList->keyCount; i++) {
				if (keys[i] == key) {
					iter->keyIndex = i;
					iter->currentObject = key;
					iter->level = 0;
					iter->atEndOfLevel = FALSE;
					break;
				}
			}
		}
	} else {
		pgpKeyIterRewind( iter );
		while( iter->currentObject != key ) {
			if( IsPGPError( sKeyIterMove( iter, 1 ) ) ) {
				iter->keyIndex = -1;
				iter->level = -1;
				iter->currentObject = NULL;
				iter->atEndOfLevel = FALSE;
				break;
			}
		}
	}
	return iter->keyIndex;
}


PGPError 
PGPKeyIterMove (
	PGPKeyIterRef		iter,
	PGPInt32			relOffset,
	PGPKeyDBObjRef *	outRef )
{
	PGPError		err	= kPGPError_NoErr;

	PGPValidateKeyIter( iter );
	pgpAssertAddrValid( outRef, PGPKeyDBRef );
	
	PGPValidatePtr( outRef );
	*outRef	= NULL;
	PGPValidateKeyIter( iter );
	
	pgpEnterPGPErrorFunction();

	err = sKeyIterMove( iter, relOffset );
	if( IsntPGPError( err ) )
		*outRef = iter->currentObject;
		
	return err;
}


static PGPError 
pgpKeyIterNext (
	PGPKeyIterRef		iter,
	PGPKeyDBObjRef *	outRef)
{
	PGPError	err;
	
	err	= PGPKeyIterMove(iter, 1, outRef );
	
	pgpAssertErrWithPtr( err, *outRef );
	return( err );
}


	static PGPError 
pgpKeyIterPrev (
	PGPKeyIterRef		iter,
	PGPKeyDBObjRef *	outRef)
{
	PGPError	err;
	
	err	= PGPKeyIterMove( iter, -1, outRef);
	
	pgpAssertErrWithPtr( err, *outRef );
	return( err );
}



/* Get next object irrespective of level */
PGPError 
pgpKeyIterNextObject (
	PGPKeyIterRef		iter,
	PGPKeyDBObjRef *	outRef)
{
	PGPKeyDBObj	*obj;
	PGPError	err	= kPGPError_NoErr;
	
	PGPValidatePtr( outRef );
	*outRef	= NULL;
	PGPValidateKeyIter( iter );

	if( iter->level < 0 ) {
		/* Before first object, move forward to it */
		return PGPKeyIterMove( iter, 1, outRef );
	}

	obj = iter->currentObject;
	
	if( !OBJISSIG( obj ) && IsntNull( obj->down ) ) {
		/* Move down if possible */
		++iter->level;
		iter->currentObject = obj->down;
		if( IsntPGPError(err = sKeyIterMoveAtLevel( iter, 0 ) ) )
		{
			*outRef = iter->currentObject;
			return kPGPError_NoErr;
		}
	}
	while( iter->level >= 0 )
	{
		if( iter->level == 0 )
			return PGPKeyIterMove( iter, 1, outRef );
		err = sKeyIterMoveAtLevel( iter, 1 );
		if( IsntPGPError( err ) )
		{
			*outRef = iter->currentObject;
			return kPGPError_NoErr;
		}
		/* Can't go any farther, go up a level */
		pgpAssert( iter->level > 0 );
		--iter->level;
		iter->currentObject = iter->currentObject->up;
		iter->atEndOfLevel = FALSE;
	}
	
	pgpAssert( 0 );
	return( err );
}



	static PGPError 
pgpKeyIterKey (
	PGPKeyIterRef		iter,
	PGPKeyDBObjRef *	outRef)
{
	PGPKeyDBObj	*key;
	PGPError	err	= kPGPError_NoErr;
	
	pgpAssertAddrValid( outRef, PGPKeyDBRef );
	
	PGPValidatePtr( outRef );
	*outRef	= NULL;
	PGPValidateKeyIter( iter );
	
	/* Should be a move(0) ? */
	key = sKeyIterCurrentObject( iter, 0 );

	/* pgpFixBeforeShip( "what if key has been deleted" ) */
	if ( IsNull( key ) )
	{
		err	= kPGPError_EndOfIteration;
	}
	
	*outRef	= key;
	return err;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -