📄 pgpmacfilemapping.c
字号:
#endif /* ] PGP_MACINTOSH */
#if PGP_MACINTOSH
const char kMappingFileName[] = "PGP MacBinary Mappings";
#else
const char kMappingFileName[] = "PGPMacBinaryMappings.txt";
#endif
static PGPError
sGetMacBinaryFileSpec(
PGPMemoryMgrRef context,
PFLFileSpecRef * spec )
{
PGPError err = kPGPError_NoErr;
err = pgpGetPrefsSpec( context, spec );
if ( IsntPGPError( err ) )
{
err = PFLSetFileSpecName( *spec, kMappingFileName );
if ( IsPGPError( err ) )
{
PFLFreeFileSpec( *spec );
*spec = NULL;
}
}
return( err );
}
#define IsEndOfLine( c ) ((c) == '\r' || (c) == '\n' )
static const char *
sSkipWhite(
const char * cur,
const char * last )
{
while ( cur <= last )
{
if ( isspace( (int) (*cur) ) )
++cur;
else
break;
}
return( cur );
}
static const char *
sSkipToNextLine(
const char * cur,
const char * last )
{
while ( cur <= last )
{
if ( ! IsEndOfLine( *cur ) )
++cur;
else
break;
}
while ( cur <= last )
{
if ( IsEndOfLine( *cur ) )
++cur;
else
break;
}
return( cur );
}
static PGPUInt32
sGetLineLength(
const char * cur,
const char * last )
{
PGPUInt32 length = 0;
while ( cur <= last )
{
if ( IsEndOfLine( *cur ) )
break;
++length;
++cur;
}
return( length );
}
static const char *
sParseOSType(
const char * cur,
const char * last,
OSType * osType,
PGPBoolean * valid )
{
PGPUInt32 lineLength;
PGPByte buffer[ 4 ];
PGPUInt32 result;
*valid = FALSE;
lineLength = sGetLineLength( cur, last );
/* does it start with "0x"? */
if ( ( *cur == '0' && *(cur + 1) == 'x' ) )
{
cur += 2;
if ( lineLength >= 8 )
{
pgpHexToBytes( cur, 4, buffer );
cur += 8;
*valid = TRUE;
}
}
else if ( lineLength >= 4 )
{
buffer[ 0 ] = *cur++;
buffer[ 1 ] = *cur++;
buffer[ 2 ] = *cur++;
buffer[ 3 ] = *cur++;
*valid = TRUE;
}
result = buffer[ 0 ];
result = ( result << 8 ) | buffer[ 1 ];
result = ( result << 8 ) | buffer[ 2 ];
result = ( result << 8 ) | buffer[ 3 ];
*osType = result;
return( cur );
}
static const char *
sParseExtension(
const char * cur,
const char * last,
char extension[ 3 + 1 ],
PGPBoolean * valid )
{
PGPUInt32 length = 0;
*valid = FALSE;
pgpFillMemory( extension, 3 + 1, '\0' );
while ( cur <= last )
{
if ( isspace( (int) (*cur) ) )
break;
extension[ length ] = *cur++;
++length;
*valid = TRUE;
if ( length == 3 )
break;
}
extension[ length ] = '\0';
if ( cur <= last &&
! (isspace( (int) (*cur) ) || IsEndOfLine( *cur ) ) )
{
pgpDebugMsg( "malformed line" );
*valid = FALSE;
}
return( cur );
}
/*____________________________________________________________________________
Return TRUE if a valid line was found
____________________________________________________________________________*/
static const char *
sParseLine(
const char * cur,
const char * last,
CreatorTypeToExtensionEntry * entry,
PGPBoolean * foundEntry )
{
*foundEntry = FALSE;
pgpClearMemory( entry, sizeof( *entry ) );
#define kCommentChar '#'
/* skip comment and blank lines */
if ( *cur == kCommentChar || IsEndOfLine( *cur ))
{
cur = sSkipToNextLine( cur, last );
}
else
{
/* potentially a valid line */
PGPUInt32 lineLength;
lineLength = sGetLineLength( cur, last );
/* CCCCTTTTExx with no space */
/* or hex variants of such of form 0xHHHHHHHH */
#define kMinLineLength (4 + 4 + 3)
if ( lineLength >= kMinLineLength )
{
PGPBoolean valid;
cur = sParseOSType( cur, last, &entry->creator, &valid );
cur = sSkipWhite( cur, last );
if ( valid )
{
cur = sParseOSType( cur, last, &entry->type, &valid );
cur = sSkipWhite( cur, last );
if ( valid )
{
cur = sParseExtension( cur,
last, entry->extension, &valid );
}
}
pgpDebugMsgIf( ! valid, "malformed line" );
*foundEntry = valid;
}
else
{
pgpDebugMsgIf( lineLength != 0, "malformed line" );
}
cur = sSkipToNextLine( cur, last );
}
return( cur );
}
static PGPError
sAddEntryToMappingTable(
CreatorTypeToExtensionEntry const * entry)
{
PGPError err = kPGPError_NoErr;
CreatorTypeToExtensionTable * table;
table = sMappingTable;
if ( table->numEntries + 1 > table->numAllocated )
{
PGPUInt32 newNumAllocated;
PGPSize newSize;
/* allocate them 10 at a time to save space */
newNumAllocated = table->numAllocated + 10;
newSize = sizeof( CreatorTypeToExtensionTable ) +
newNumAllocated * sizeof( table->entries[ 0 ] );
err = pgpRealloc( (void **) &table, newSize );
if ( IsntPGPError( err ) )
{
table->numAllocated = newNumAllocated;
}
}
if ( IsntPGPError( err ) )
{
pgpAssert( table->numAllocated > table->numEntries );
table->entries[ table->numEntries ] = *entry;
table->numEntries++;
}
sMappingTable = table;
return( err );
}
static PGPError
sParseMappings(
void const * memIn,
PGPSize length )
{
PGPError err = kPGPError_NoErr;
pgpAssert( IsntNull( memIn ) );
pgpAssert( IsNull( sMappingTable ) );
/* special case: use pgpAlloc() since we don't have a user context */
sMappingTable = (CreatorTypeToExtensionTable *)
pgpAlloc( sizeof( *sMappingTable ) );
if ( IsntNull( sMappingTable ) )
{
CreatorTypeToExtensionEntry entry;
const char * cur;
const char * last;
pgpClearMemory( sMappingTable, sizeof( *sMappingTable) );
sMappingTable->numEntries = 0;
sMappingTable->numAllocated = 0;
cur = (char const *)memIn;
last = cur + (length -1);
while ( cur <= last )
{
PGPBoolean foundEntry;
cur = sParseLine( cur, last, &entry, &foundEntry );
if ( foundEntry )
{
err = sAddEntryToMappingTable( &entry );
if ( IsPGPError( err ) )
break;
}
}
}
else
{
err = kPGPError_OutOfMemory;
}
return( err );
}
static PGPError
sReadMappingsFromIO( PGPIORef io)
{
PGPError err = kPGPError_NoErr;
PGPFileOffset eof;
err = PGPIOGetEOF( io, &eof );
if ( IsntPGPError( err ) )
{
void * mem;
PGPMemoryMgrRef memoryMgr;
PGPSize bufferSize;
bufferSize = (PGPSize)eof;
memoryMgr = PGPIOGetMemoryMgr( io );
mem = PGPNewData( memoryMgr, bufferSize, 0 );
if ( IsntNull( mem ) )
{
err = PGPIORead( io, bufferSize, mem, NULL );
if ( IsntPGPError( err ) )
{
err = sParseMappings( mem, bufferSize );
}
PGPFreeData( mem );
}
else
{
err = kPGPError_OutOfMemory;
}
}
return( err );
}
static PGPError
pgpReadMacBinaryMappings( PFLFileSpecRef spec )
{
PGPError err = kPGPError_NoErr;
PGPIORef io;
err = PGPOpenFileSpec( spec,
kPFLFileOpenFlags_ReadOnly, (PGPFileIORef *)&io );
if ( IsntPGPError( err ) )
{
err = sReadMappingsFromIO( io );
PGPFreeIO( io );
io = NULL;
}
return( err );
}
static PGPError
sWriteBuiltInMappingsToIO( PGPIORef io )
{
PGPError err = kPGPError_NoErr;
err = PGPIOWrite( io,
strlen( sCreatorTypeToExtensionDefaults ),
sCreatorTypeToExtensionDefaults );
return( err );
}
/*____________________________________________________________________________
Initialize the mappings from the built-in table. Generally called only if
(a) the mapping file can't be found and
(b) we couldn't create a mapping file.
Here we use a trick: first write them into a memory io, then init them
from this memory IO.
____________________________________________________________________________*/
static PGPError
sInitFromBuiltIn( PGPMemoryMgrRef context)
{
PGPError err = kPGPError_NoErr;
PGPIORef io;
err = PGPNewMemoryIO( context, (PGPMemoryIORef *)&io );
if ( IsntPGPError( err ) )
{
err = sWriteBuiltInMappingsToIO( io );
if ( IsntPGPError( err ) )
{
err = PGPIOSetPos( io, 0 );
if ( IsntPGPError( err ) )
err = sReadMappingsFromIO( io );
}
PGPFreeIO( io );
}
return( err );
}
static PGPError
sWriteBuiltInMappingsToFile( PFLFileSpecRef spec )
{
PGPError err = kPGPError_NoErr;
PGPIORef io = NULL;
err = PFLFileSpecCreate( spec );
if ( IsntPGPError( err ) )
{
err = PGPOpenFileSpec( spec,
kPFLFileOpenFlags_ReadWrite, (PGPFileIORef *)&io );
if ( IsntPGPError( err ) )
{
err = sWriteBuiltInMappingsToIO( io );
PGPFreeIO( io );
io = NULL;
}
}
return( err );
}
#if PGP_MACINTOSH
static PGPError
sAddFileInfoToSpec( PFLFileSpecRef spec )
{
PFLFileSpecMacMetaInfo metaInfo;
PGPError err = kPGPError_NoErr;
metaInfo.fInfo.fileCreator = 'ttxt';
metaInfo.fInfo.fileType = 'TEXT';
metaInfo.fInfo.finderFlags = 0;
metaInfo.fInfo.location.h = -1;
metaInfo.fInfo.location.v = -1;
metaInfo.fInfo.reserved = 0;
err = PFLSetFileSpecMetaInfo( spec, &metaInfo );
return( err );
}
#else
#define sAddFileInfoToSpec( spec ) kPGPError_NoErr
#endif
static PGPError
pgpWriteMacBinaryMappings( PFLFileSpecRef toFile )
{
PGPError err = kPGPError_NoErr;
err = sAddFileInfoToSpec( toFile );
if ( IsntPGPError( err ) )
{
err = sWriteBuiltInMappingsToFile( toFile );
}
return( err );
}
PGPError
pgpInitMacBinaryMappings( void )
{
PGPError err = kPGPError_NoErr;
PFLFileSpecRef spec = NULL;
PGPMemoryMgrRef memoryMgr = PGPGetDefaultMemoryMgr();
err = sGetMacBinaryFileSpec( memoryMgr, &spec );
if ( IsntPGPError( err ) )
{
PGPBoolean exists;
err = PFLFileSpecExists( spec, &exists );
/* if file doesn't exist, then create it */
if ( IsntPGPError( err ) )
{
if ( ! exists )
{
err = pgpWriteMacBinaryMappings( spec );
}
if ( IsntPGPError( err ) )
{
err = pgpReadMacBinaryMappings( spec );
}
}
PFLFreeFileSpec( spec );
spec = NULL;
}
/* "soft" failure: init from built-in if we have to */
if ( IsPGPError( err ) )
{
err = sInitFromBuiltIn( memoryMgr );
pgpAssertNoErr( err );
}
pgpAssertNoErr( err );
return( err );
}
PGPError
pgpDisposeMacBinaryMappings( void )
{
PGPError err = kPGPError_NoErr;
if ( IsntNull( sMappingTable ) )
{
pgpFree( sMappingTable );
sMappingTable = NULL;
}
return( err );
}
/*__Editor_settings____
Local Variables:
tab-width: 4
End:
vi: ts=4 sw=4
vim: si
_____________________*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -