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

📄 pgpoptionlist.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/*____________________________________________________________________________
	pgpOptionList.c
	
	Copyright (C) 1997 Network Associates Inc. and affiliated companies.
	All rights reserved.
	
	$Id: pgpOptionList.c,v 1.68 1999/03/10 02:53:58 heller Exp $
____________________________________________________________________________*/

#include <string.h>

#include "pgpFileSpec.h"
#include "pgpContext.h"
#include "pgpOptionList.h"
#include "pgpEncodePriv.h"
#include "pgpErrors.h"

#if PGP_CLIENT_LIBRARY
#include "pgpClientLib.h"	/* No PFL dependencies for client library */
#else
#include "pgpDebug.h"
#include "pgpMem.h"
#endif

enum
{
	kPGPOptionList_Magic		= 0x4F4C7374,	/* 'OLst' */
	
	kPGPOptionList_MajorVersion	= 1,
	kPGPOptionList_MinorVersion	= 1,
	
	kPGPOptionList_NumGrowElements	= 5
};

enum
{
	kPGPOptionListFlag_PersistentList	= ( 1 << 0 )
};

struct PGPOptionList
{
	PGPUInt32		magic;			/* Always kPGPOptionList_Magic */
	PGPVersion		version;
	PGPContextRef	context;
	PGPError		err;			/* Important that this field is second */
	PGPFlags		flags;
	PGPUInt16		maxOptions;
	PGPUInt16		numOptions;
	
	PGPOption		*options;
};

	PGPBoolean
pgpOptionListIsReal(PGPOptionListRef optionList)
{
	return( optionList != kPGPEndOfArgsOptionListRef &&
			optionList != kPGPOutOfMemoryOptionListRef &&
			optionList != kPGPBadParamsOptionListRef &&
			optionList != kPGPNullOptionListRef );
}


	PGPError
pgpOptionListToError( PGPOptionListRef optionList )
{
	PGPError	err	= kPGPError_NoErr;
	
	if ( optionList == kPGPEndOfArgsOptionListRef ||
		optionList == kPGPBadParamsOptionListRef ||
		optionList == kPGPNullOptionListRef )
	{
		err	= kPGPError_BadParams;
	}
	else if ( optionList == kPGPOutOfMemoryOptionListRef )
	{
		err	= kPGPError_OutOfMemory;
	}
	else
	{
		pgpAssert( pgpOptionListIsReal( optionList ) );
		err	= kPGPError_NoErr;
	}
	
	return( err );
}

	static PGPBoolean
pgpVerifyOptionList(PGPOptionListRef optionList)
{
	PGPBoolean	isValid = TRUE;
	
	if( pgpOptionListIsReal( optionList ) )
	{
		if( optionList->numOptions <= optionList->maxOptions )
		{
			PGPUInt32	optionIndex;
			
			for( optionIndex = 0; optionIndex < optionList->numOptions;
					++optionIndex )
			{
				const PGPOption	*curOption;
				
				curOption = &optionList->options[optionIndex];
				
				if( ( (PGPInt32) curOption->type >=
							kPGPOptionType_FirstSDKOption &&
					  curOption->type < kPGPOptionType_LastSDKOption ) ||
					( curOption->type >= kPGPOptionType_FirstUIOption &&
					  curOption->type < kPGPOptionType_LastUIOption ) ||
					( curOption->type >= kPGPOptionType_FirstNetOption &&
					  curOption->type < kPGPOptionType_LastNetOption ) )
				{
					/* OK */
				}
				else
				{
					isValid = FALSE;
					break;
				}
				
				if( PGPOptionListRefIsValid( curOption->subOptions ) )
				{
					isValid = pgpVerifyOptionList( curOption->subOptions );
					if( ! isValid )
						break;
				}
			}
		}
		else
		{
			isValid = FALSE;
		}
	}
			
	return( isValid );
}

/*____________________________________________________________________________
	This function validates a PGPOptionList data structure. It does not assert
	so it can be used within assert macros.
____________________________________________________________________________*/

	PGPBoolean
pgpOptionListIsValid(PGPOptionListRef optionList)
{
	PGPBoolean	isValid;
	
	if( pgpOptionListIsReal( optionList ) )
	{
		isValid = ( optionList != NULL &&
					optionList->magic == kPGPOptionList_Magic );

#if PGP_DEBUG	/* [ */
		if( isValid )
		{
			/* Perform more stringent check */
			isValid = pgpVerifyOptionList( optionList );
		}
#endif	/* ] */
	}
	else
	{
		isValid = TRUE;
	}
	
	return( isValid );
}

	PGPError
pgpGetOptionListError(PGPOptionListRef optionList)
{
	PGPError	err;
	
	PGPValidateParam( pgpOptionListIsValid( optionList ) );

	if( optionList == kPGPEndOfArgsOptionListRef ||
		optionList == kPGPNullOptionListRef )
	{
		err = kPGPError_NoErr;
	}
	else if( optionList == kPGPOutOfMemoryOptionListRef )
	{
		err = kPGPError_OutOfMemory;
	}
	else if( optionList == kPGPBadParamsOptionListRef )
	{
		err = kPGPError_BadParams;
	}
	else
	{
		err = optionList->err;
	}
	
	return( err );
}

	PGPUInt32
pgpGetOptionListCount(PGPOptionListRef optionList)
{
	pgpAssert( pgpOptionListIsValid( optionList ) );
	
	return( optionList->numOptions );
}

	void
pgpSetOptionListError(
	PGPOptionListRef 	optionList,
	PGPError 			err)
{
	pgpAssert( pgpOptionListIsValid( optionList ) );

	if( pgpOptionListIsReal( optionList ) )
	{
		/* Set the err code iff there isn't already an err for the list */

		if( IsntPGPError( optionList->err ) )
		{
			optionList->err = err;
		}
	}
}

	static void
pgpFreeOptionListInternal(
	PGPOptionListRef 	optionList,
	PGPBoolean			freePersistentList)
{
	pgpAssert( pgpOptionListIsValid( optionList ) );
	
	if( pgpOptionListIsReal( optionList ) )
	{
		PGPBoolean	freeTheList = TRUE;
		
		if( ( optionList->flags & kPGPOptionListFlag_PersistentList ) != 0 )
		{
			freeTheList = freePersistentList;
		}

		if( freeTheList )
		{
			PGPUInt32	optionIndex;
			
			/*
			**	Free all of the allocations and suboption lists hanging
			**	off of the main option list
			*/
			
			for( optionIndex = 0; optionIndex < optionList->numOptions;
						optionIndex++ )
			{
				PGPOption	*curOption = &optionList->options[optionIndex];
				
				if( IsntNull( curOption->handlerProc ) )
				{
					(*curOption->handlerProc)(
								optionList->context,
								kPGPOptionHandler_FreeDataOperation,
								curOption->type,
								curOption->value, curOption->valueSize,
								NULL, NULL );
				}
			
				if( IsntNull( curOption->subOptions ) )
				{
					pgpAssert( ( curOption->subOptions->flags & 
							kPGPOptionListFlag_PersistentList ) == 0 );
							
					pgpFreeOptionListInternal( curOption->subOptions, TRUE );
				}
			}
			
			pgpContextMemFree( optionList->context, optionList->options );
			pgpContextMemFree( optionList->context, optionList );
		}
	}
}

	void
pgpFreeOptionList(PGPOptionListRef optionList)
{
	pgpFreeOptionListInternal( optionList, TRUE );
}

	PGPOptionListRef
pgpNewOptionList(
	PGPContextRef	context,
	PGPBoolean		createPersistentList)
{
	PGPOptionListRef	optionList;
	
	optionList = (PGPOptionListRef)
		pgpContextMemAlloc( context, sizeof( *optionList ), 0);
	if( IsntNull( optionList ) )
	{
		pgpClearMemory( optionList, sizeof( *optionList ) );

		optionList->options = (PGPOption *)
			pgpContextMemAlloc( context,  sizeof( PGPOption ), 0);
		if( IsntNull( optionList->options ) )
		{
			pgpClearMemory( optionList->options, sizeof( PGPOption ) );

			optionList->magic 		= kPGPOptionList_Magic;
			optionList->maxOptions	= 1;
			optionList->context		= context;

			optionList->version.majorVersion	= kPGPOptionList_MajorVersion;
			optionList->version.minorVersion	= kPGPOptionList_MinorVersion;
			
			if( createPersistentList )
				optionList->flags |= kPGPOptionListFlag_PersistentList;
		}
		else
		{
			pgpContextMemFree( optionList->context, optionList );
			optionList = kPGPOutOfMemoryOptionListRef;
		}
	}
	else
	{
		/*
		** We ran out of memory allocating the PGPOptionList (very rare
		** case). Point at the preallocated option list in the context
		** to handle this case.
		*/
		
		optionList = kPGPOutOfMemoryOptionListRef;
	}
	
	return( optionList );
}

/*____________________________________________________________________________
	Grow an existing PGPOptionList by a specified number of PGPOption
	elements. The new elements are cleared out.
____________________________________________________________________________*/

	static PGPError
pgpGrowOptionList(
	PGPOptionListRef	optionList,
	PGPUInt32			numNewOptions)
{
	PGPError	err;
	
	pgpAssert( pgpOptionListIsValid( optionList ) );
	pgpAssert( numNewOptions > 0 );

	err = pgpGetOptionListError( optionList );
	if( IsntPGPError( err ) )
	{
		PGPUInt32		existingListSize;
		PGPUInt32		newListSize;
		
		existingListSize 	= sizeof( PGPOption ) * optionList->maxOptions;
		newListSize 		= existingListSize + ( sizeof( PGPOption ) *
									numNewOptions );
		
		err = pgpContextMemRealloc( optionList->context,
					(void **)&optionList->options, newListSize, 0);
		if( IsntPGPError( err ) )
		{
			/*
			** Delete existing option list direct allocation only. Sub-option
			** lists are still valid.
			*/
			
			pgpClearMemory( ((char *)optionList->options) + existingListSize,
				newListSize - existingListSize );
						
			optionList->maxOptions += numNewOptions;
		}
	}
	
	return( err );
}

	PGPError
pgpCopyOption(
	PGPContextRef	context,
	const PGPOption	*sourceOption,
	PGPOption		*destOption)
{
	PGPError	err = kPGPError_NoErr;
	
	pgpAssertAddrValid( sourceOption, PGPOption );
	pgpAssertAddrValid( destOption, PGPOption );

	*destOption 			= *sourceOption;
	destOption->subOptions	= kInvalidPGPOptionListRef;
	destOption->handlerProc = NULL;
	
	if( IsntNull( sourceOption->handlerProc ) )
	{
		/* We have a handler proc, so a deep copy is possibly needed. */

		err = (*sourceOption->handlerProc)(
					context,
					kPGPOptionHandler_CopyDataOperation,
					sourceOption->type,
					sourceOption->value, sourceOption->valueSize,
					&destOption->value, &destOption->valueSize );
		if( IsntPGPError( err ) )
		{
			destOption->handlerProc = sourceOption->handlerProc;
		}
	}

	if( IsntPGPError( err ) &&
		PGPOptionListRefIsValid( sourceOption->subOptions ) )
	{
		destOption->subOptions = pgpCopyOptionList( sourceOption->subOptions );
		err = pgpGetOptionListError( destOption->subOptions );
	}
	
	return( err );
}

/*____________________________________________________________________________
	Add a single PGPOption to a PGPOptionList. The option is added such that
	the options in the list are kept in ascending type order. No policy is
	enforced at this point about which options are duplicates.
____________________________________________________________________________*/

	static PGPError
pgpAddOptionToPGPOptionList(
	PGPOptionListRef	optionList,
	const PGPOption		*newOption)
{
	PGPError	err;

	pgpAssert( pgpOptionListIsValid( optionList ) );
	pgpAssertAddrValid( newOption, PGPOption );

	err = pgpGetOptionListError( optionList );
	if( IsntPGPError( err ) )
	{
		/* Do we need to grow the list? */
		if( optionList->numOptions == optionList->maxOptions )
		{
			err = pgpGrowOptionList( optionList,
								kPGPOptionList_NumGrowElements );
		}
	
		if( IsntPGPError( err ) )
		{
			PGPOption	addedOption;
			
			addedOption = *newOption;
			
			addedOption.flags &= ~(kPGPOptionFlag_Recognized |
									kPGPOptionFlag_Frozen );
			
			optionList->options[optionList->numOptions] = addedOption;
			++optionList->numOptions;
		}
	}
	
	pgpSetOptionListError( optionList, err );
	
	return( err );
}


	PGPOptionListRef
pgpCopyOptionList(PGPOptionListRef optionList) 
{
	PGPOptionListRef	newOptionList;
	PGPError			err;
	
	newOptionList = pgpNewOptionList( optionList->context, FALSE );

	err = pgpGetOptionListError( newOptionList );	
	if( IsntPGPError( err ) )
	{
		err = pgpGetOptionListError( optionList );
		if( IsntPGPError( err ) )
		{
			PGPUInt32	optionIndex;
			
			for( optionIndex = 0; optionIndex < optionList->numOptions;
					optionIndex++)
			{
				PGPOption	newOption;
				
				err = pgpCopyOption( optionList->context,
							&optionList->options[optionIndex],
							&newOption );
				if( IsntPGPError( err ) )
				{
					err = pgpAddOptionToPGPOptionList( newOptionList,
								&newOption );
				}
				
				if( IsPGPError( err ) )
					break;
			}
		}
	}
	
	pgpSetOptionListError( newOptionList, err );
	
	return( newOptionList );
}

/*____________________________________________________________________________
	Merge all of the OptionList records from sourceOptionList into
	destOptionList and dispose of sourceOptionList if it is not a persistent
	list. Assumes both option lists are real.
____________________________________________________________________________*/

	static PGPError
pgpMergeOptionLists(
	PGPOptionListRef	sourceOptionList,
	PGPOptionListRef	destOptionList)
{
	PGPError	err = kPGPError_NoErr;
	
	pgpAssert( pgpOptionListIsValid( sourceOptionList ) );
	pgpAssert( pgpOptionListIsReal( sourceOptionList ) );
	pgpAssert( pgpOptionListIsValid( destOptionList ) );
	pgpAssert( pgpOptionListIsReal( destOptionList ) );
	
	err = pgpGetOptionListError( sourceOptionList );
	if( IsntPGPError( err ) )
	{
		err = pgpGetOptionListError( destOptionList );
		if( IsntPGPError( err ) )
		{

⌨️ 快捷键说明

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