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

📄 pflprefs.c

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

	$Id: pflPrefs.c,v 1.35 2002/08/06 20:10:33 dallen Exp $
____________________________________________________________________________*/

#include <stdio.h>
#include <string.h>

#include "pflPrefs.h"
#include "pgpPFLPriv.h"
#include "pgpMemoryMgrPriv.h"
#include "pgpMem.h"
#include "pgpDebug.h"
#include "pgpPFLErrors.h"
#include "pgpFileUtilities.h"
#include "pgpEndianConversion.h"
#include "pgpHex.h"
#include "pgpStrings.h"
#include "pgpMemoryIO.h"

typedef struct PGPPrefData	PGPPrefData;

typedef union PGPPrefDataUnion
{
	PGPBoolean		b;
	PGPUInt32		i;
	char *			str;
	PGPByte *		p;
	PGPPrefStruct *	strct;
	PGPPrefArray *	a;
	char *			raw;
} PGPPrefDataUnion;

struct PGPPrefData
{
	char *				prefComments;
	PGPPrefIndex		prefIndex;
	char *				prefName;
	PGPPrefType			prefType;
	PGPSize				dataLength;
	PGPPrefDataUnion	data;
	PGPUInt32			highestIndex;
	PGPUInt32			flags;

	PGPPrefData *	nextPrefData;
	PGPPrefData *	lastPrefData;
};

struct PGPPref 
{
	PGPMemoryMgrRef				memoryMgr;
	PFLFileSpecRef				prefFileSpec;
	PGPBoolean					dirty;

	PGPPrefData *				prefList;
	PGPPrefData *				prefListEnd;
	
	// new in 7.5
	PGPUInt32					wrap;
	PGPUserValue				userValue;
	PGPFreePrefsUserValueProc	userValueFreeProc;
} PGPPref;

#define IsLineEndChar(c)	((c == '\r') || (c == '\n'))
#define IsWhitespace(c)		((c == ' ') || (c == '\t'))

#define kPGPInvalidPrefIndex	-1

#ifndef kPGPLineEndString
#	if PGP_WIN32
#		define kPGPLineEndString	"\r\n"
#	elif PGP_MACINTOSH
#		define kPGPLineEndString	"\r"
#	elif PGP_UNIX
#		define kPGPLineEndString	"\n"
#	else
#		error Must set one of {PGP_WIN32, PGP_MACINTOSH, PGP_UNIX} = 1
#	endif
#endif


static PGPError sCreatePrefStruct(PGPMemoryMgrRef memoryMgr,
									PGPPrefStruct *templateStruct,
									PGPPrefStruct **newStruct);

static PGPError sCopyPrefFlags(PGPPrefRef prefRef,
					PGPPrefIndex prefIndex,
					PGPUInt32 flags);

static PGPError sFindPrefDataByIndex(PGPPrefRef prefRef,
					PGPPrefIndex prefIndex, 
					PGPPrefData **prefData);

static PGPError sFindPrefDataByName(PGPPrefRef prefRef,
					char *prefName, 
					PGPPrefData **prefData);

static PGPError sFreePref(PGPPrefRef prefRef);

static PGPError sAddPrefData(PGPPrefRef prefRef, 
					PGPPrefData *prefData);

static PGPError sRemovePrefData(PGPPrefRef prefRef,
					PGPPrefData *prefData);

static PGPError sGetNextPrefData(const PGPPrefData *currentPrefData,
					PGPPrefData **nextPrefData);

static PGPError sReadPrefData(PGPIORef prefIO, PGPPrefData *prefData,
					PGPUInt32 *arrayIndex);

static PGPError sWritePrefData(PGPIORef prefIO, PGPPrefData *prefData,
					PGPUInt32 wrap);

static PGPError sWritePrefLine(PGPIORef prefIO,
					PGPPrefData *prefData, PGPUInt32 index, PGPUInt32 wrap);

static PGPError sConvertRawData(PGPMemoryMgrRef memoryMgr, 
					PGPPrefData *oldPrefData, PGPPrefData *newPrefData,
					PGPUInt32 arrayIndex);

static PGPError sConvertRawDataToStruct(PGPMemoryMgrRef memoryMgr, 
					char *value, PGPUInt32 length, PGPPrefStruct *prefStruct);

static void sCleanupArrays(PGPPrefRef prefRef);

static void sFreePrefData(PGPPrefData *prefData, PGPBoolean freeAll);

static PGPError sCopyStructDataToPref(PGPPrefRef prefRef, PGPBoolean readData,
					PGPPrefStruct *fromStruct, PGPPrefStruct *toStruct);

static void sStripQuotes(PGPUInt32 stringLen, char *string);

static PGPError sIORead(PGPIORef ioRef, PGPSize dataSize, 
					PGPBoolean crossPlatform, void *data);

static PGPError sIOWrite(PGPIORef ioRef, PGPSize dataSize, 
					PGPBoolean crossPlatform, const void *data);


PGPError PGPOpenPrefFile(PFLFileSpecRef prefFileSpec, 
							const PGPPrefDefinition *prefs,
							PGPUInt32 numPrefs,
							PGPPrefRef *prefRef)
{
	PGPUInt32				arrayIndex;
	PGPMemoryMgrRef			memoryMgr	= NULL;
	PGPIORef				prefIO;
	PGPPrefData *			newPrefData = NULL;
	PGPPrefData *			oldPrefData = NULL;
	PGPError				err = kPGPError_NoErr;

	if (IsntNull(prefRef))
		*prefRef = NULL;

	PFLValidateFileSpec(prefFileSpec);

	memoryMgr = PFLGetFileSpecMemoryMgr( prefFileSpec );

	err = PGPNewMemoryPrefs(memoryMgr, prefs, numPrefs, prefRef);
	if (IsPGPError(err))
	{
		if (IsntNull(*prefRef))
		{
			sFreePref(*prefRef);
			*prefRef = NULL;
		}
		
		return err;
	}

	err = PFLCopyFileSpec(prefFileSpec, &((*prefRef)->prefFileSpec));
	if (IsPGPError(err))
	{
		sFreePref(*prefRef);
		*prefRef = NULL;
		return err;
	}

	err = PGPOpenFileSpec(	(*prefRef)->prefFileSpec, 
							kPFLFileOpenFlags_ReadOnly, 
							(PGPFileIORef *) &prefIO);
	
	if ((err != kPGPError_FileNotFound) && (err != kPGPError_FileOpFailed))
	{
		if (IsPGPError(err))
		{
			sFreePref(*prefRef);
			*prefRef = NULL;
			return err;
		}
		
		pgpAssert(PGPIOIsValid(prefIO));
		if (!PGPIOIsValid(prefIO))
		{
			sFreePref(*prefRef);
			*prefRef = NULL;
			return kPGPError_OutOfMemory;
		}
		
		while (!PGPIOIsAtEOF(prefIO) && IsntPGPError(err))
		{
			newPrefData = (PGPPrefData *) PGPNewData(memoryMgr,
											sizeof(PGPPrefData),
											kPGPMemoryMgrFlags_Clear);
			if (IsNull(newPrefData))
			{
				err = kPGPError_OutOfMemory;
				break;
			}

			err = sReadPrefData(prefIO, newPrefData, &arrayIndex);

			if (IsPGPError(err))
				break;
			
			if (IsntNull(newPrefData->prefName))
			{
				err = sFindPrefDataByName(*prefRef, newPrefData->prefName,
						&oldPrefData);

				if (IsntPGPError(err))
				{
					if (IsntNull(oldPrefData))
					{
						sConvertRawData(memoryMgr, oldPrefData, newPrefData,
							arrayIndex);

						PGPFreeData(newPrefData->prefName);
						PGPFreeData(newPrefData);
						newPrefData = NULL;
					}
					else
					{
						if (arrayIndex > 0)
						{
							char number[20];

							sprintf(number, "%d", arrayIndex);
							strcat(newPrefData->prefName, number);
						}

						sAddPrefData(*prefRef, newPrefData);
					}
				}
				else
				{
					sFreePrefData(newPrefData, TRUE);
					PGPFreeData(newPrefData);
					newPrefData = NULL;
				}
			}
			else
			{
				sFreePrefData(newPrefData, TRUE);
				PGPFreeData(newPrefData);
				newPrefData = NULL;
			}
		}
		
		if (err == kPGPError_EOF)
		{
			if (IsntNull(newPrefData))
			{
				sFreePrefData(newPrefData, TRUE);
				PGPFreeData(newPrefData);
			}

			err = kPGPError_NoErr;
		}
		else if (IsPGPError(err))
		{
			pgpAssertNoErr(err);
			sFreePref(*prefRef);
			*prefRef = NULL;
		}
		
		PGPFreeIO(prefIO);
	}
	else
		err = kPGPError_NoErr;

	if (IsntNull(*prefRef))
		sCleanupArrays(*prefRef);

	if (IsntNull(*prefRef))
		(*prefRef)->dirty = FALSE;

	return err;
}


PGPError PGPSavePrefFile(PGPPrefRef prefRef)
{
	PGPPrefData *	currentPrefData;
	PGPIORef		prefIO;
	PGPError		err;
	PGPBoolean		fileExists;
	
	PGPValidatePref(prefRef);

	/* If this is a memory pref, do nothing */
	if (IsNull(prefRef->prefFileSpec))
		return kPGPError_NoErr;

	/* Create the file if it does not exist */
	err = PFLFileSpecExists( prefRef->prefFileSpec, &fileExists );
	if( IsntPGPError( err ) )
	{
		if( fileExists )
		{
			/* If no changes have been been, don't save the file */

			if (!prefRef->dirty)
				return kPGPError_NoErr;

			(void) PFLFileSpecDelete( prefRef->prefFileSpec );
		}
		err = PFLFileSpecCreate(prefRef->prefFileSpec);
	}
	
	pgpAssertNoErr(err);
	if (IsPGPError(err))
		return err;

	err = PGPOpenFileSpec(	prefRef->prefFileSpec, 
							kPFLFileOpenFlags_ReadWrite, 
							(PGPFileIORef *) &prefIO);
	pgpAssertNoErr(err);
	if (IsPGPError(err))
		return err;

	currentPrefData = prefRef->prefList;

	while (IsntNull(currentPrefData))
	{
		err = sWritePrefData(prefIO, currentPrefData, prefRef->wrap);

		pgpAssertNoErr(err);
		if (IsPGPError(err))
			break;

		sGetNextPrefData(currentPrefData, &currentPrefData);
	}
	
	PGPFreeIO(prefIO);
	prefRef->dirty = FALSE;
	return err;
}


PGPError PGPGetPrefFileSpec(PGPPrefRef prefRef,
								PFLFileSpecRef *prefFileSpec)
{
	PGPError err = kPGPError_NoErr;

	if (IsntNull(prefFileSpec))
		*prefFileSpec = NULL;

	PGPValidatePref(prefRef);
	PGPValidatePtr(prefFileSpec);

	/* If this is a memory pref, the file spec is NULL */
	if (IsNull(prefRef->prefFileSpec))
		return kPGPError_NoErr;

	err = PFLCopyFileSpec(prefRef->prefFileSpec, prefFileSpec);
	if (IsPGPError(err))
		*prefFileSpec = NULL;

	return err;
}


PGPError PGPNewMemoryPrefs(PGPMemoryMgrRef memoryMgr, 
							const PGPPrefDefinition *prefs,
							PGPUInt32 numPrefs,
							PGPPrefRef *prefRef)
{
	PGPUInt32				index;
	PGPUInt32				arrayIndex;
	PGPPrefArray *			prefArray = NULL;
	PGPPrefArrayElement *	copyElement = NULL;
	PGPPrefArrayElement *	newElement = NULL;
	PGPPrefData *			newPrefData = NULL;
	PGPError				err = kPGPError_NoErr;

	if (IsntNull(prefRef))
		*prefRef = NULL;

	PGPValidatePtr(prefRef);
	PGPValidatePtr(prefs);
	PGPValidateParam(numPrefs > 0);

	pgpAssert(PGPMemoryMgrIsValid(memoryMgr));
	if (!PGPMemoryMgrIsValid(memoryMgr))
		return kPGPError_BadParams;

	*prefRef = (PGPPrefRef) PGPNewData(memoryMgr, 
								sizeof(PGPPref), 
								kPGPMemoryMgrFlags_Clear);

	pgpAssert(IsntNull(*prefRef));
	if (IsNull(*prefRef))
		return kPGPError_OutOfMemory;

	(*prefRef)->memoryMgr			= memoryMgr;
	(*prefRef)->prefFileSpec		= NULL;
	(*prefRef)->userValue			= NULL;
	(*prefRef)->userValueFreeProc	= NULL;
	(*prefRef)->prefList			= NULL;
	(*prefRef)->prefListEnd			= NULL;
	(*prefRef)->wrap				= 70;

	for (index=0; index<numPrefs; index++)
	{
		newPrefData = (PGPPrefData *) PGPNewData(memoryMgr,
										sizeof(PGPPrefData),
										kPGPMemoryMgrFlags_Clear);
		
		if (IsNull(newPrefData))
		{
			err = kPGPError_OutOfMemory;
			break;
		}
		
		newPrefData->prefComments = NULL;
		newPrefData->prefIndex = prefs[index].index;
		newPrefData->prefType = prefs[index].type;
		
		newPrefData->prefName = (char *) PGPNewData(memoryMgr,
											strlen(prefs[index].name)+1,
											kPGPMemoryMgrFlags_Clear);
		
		if (IsNull(newPrefData->prefName))
		{
			err = kPGPError_OutOfMemory;
			break;
		}
		
		pgpCopyMemory(prefs[index].name, newPrefData->prefName,
			strlen(prefs[index].name) + 1);
		
		switch (prefs[index].type)
		{
		case kPGPPrefType_Boolean:
			{
				newPrefData->dataLength = sizeof(PGPBoolean);
				newPrefData->data.b = (PGPBoolean) (size_t) 
										prefs[index].data;
				break;
			}
		case kPGPPrefType_Number:
			{
				newPrefData->dataLength = sizeof(PGPUInt32);
				newPrefData->data.i = (PGPUInt32) (size_t)
										prefs[index].data; 
				break;
			}
			
		case kPGPPrefType_String:
			if (IsntNull(prefs[index].data))
			{
				newPrefData->dataLength = strlen((char *) prefs[index].data) 
											+ 1;
				
				newPrefData->data.str = PGPNewData(memoryMgr,
											newPrefData->dataLength,
											kPGPMemoryMgrFlags_Clear);
				
				if (IsNull(newPrefData->data.str))
				{
					err = kPGPError_OutOfMemory;
					break;
				}
				
				pgpCopyMemory(prefs[index].data, newPrefData->data.str, 
					newPrefData->dataLength);
			}
			else
			{
				newPrefData->dataLength = 0;
				newPrefData->data.str = NULL;
			}
			break;
			
		case kPGPPrefType_Byte:
			if (IsntNull(prefs[index].data))
			{
				newPrefData->dataLength = prefs[index].size;
				newPrefData->data.p = PGPNewData(memoryMgr,
										newPrefData->dataLength,
										kPGPMemoryMgrFlags_Clear);
				
				if (IsNull(newPrefData->data.p))
				{
					err = kPGPError_OutOfMemory;
					break;
				}
				
				pgpCopyMemory(prefs[index].data, newPrefData->data.p,
					newPrefData->dataLength);
			}
			else
			{
				newPrefData->dataLength = 0;
				newPrefData->data.p = NULL;
			}
			break;

		case kPGPPrefType_Struct:
			newPrefData->dataLength = sizeof(PGPPrefStruct);
			newPrefData->data.strct = (PGPPrefStruct *) 
										PGPNewData(memoryMgr,
											sizeof(PGPPrefStruct),
											kPGPMemoryMgrFlags_Clear);

			if (IsNull(newPrefData->data.strct))
			{
				err = kPGPError_OutOfMemory;
				break;
			}

			err = sCopyStructDataToPref(*prefRef, TRUE,
					(PGPPrefStruct *) prefs[index].data,
					newPrefData->data.strct);
			break;

		case kPGPPrefType_Array:
			newPrefData->dataLength = sizeof(PGPPrefArray);
			prefArray = (PGPPrefArray *) prefs[index].data;

			newPrefData->data.a = (PGPPrefArray *) PGPNewData(memoryMgr,
													sizeof(PGPPrefArray),
													kPGPMemoryMgrFlags_Clear);

			if (IsNull(newPrefData->data.a))
			{
				err = kPGPError_OutOfMemory;
				break;
			}

			pgpCopyMemory(prefArray, newPrefData->data.a, 
				sizeof(PGPPrefArray));

			if (prefArray->numElements > 0)
			{
				newPrefData->data.a->elements = PGPNewData(memoryMgr,
												sizeof(PGPPrefArrayElement) *
												prefArray->numElements,
												kPGPMemoryMgrFlags_Clear);

				if (IsNull(newPrefData->data.a->elements))
				{
					PGPFreeData(newPrefData->data.a);
					err = kPGPError_OutOfMemory;
					break;
				}
			}
			
			if (prefArray->type == kPGPPrefType_Struct)
			{
				PGPValidatePtr(prefArray->templateStruct);

				newPrefData->data.a->templateStruct = (PGPPrefStruct *)
											PGPNewData(memoryMgr,
												sizeof(PGPPrefStruct),
												kPGPMemoryMgrFlags_Clear);
			

⌨️ 快捷键说明

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