📄 pflprefs.c
字号:
/*____________________________________________________________________________
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, ¤tPrefData);
}
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 + -