📄 pgpmacfilemapping.c
字号:
char cName[ 256 ];
const char * extension;
/* not really a param, but does desired thing */
PGPValidatePtr( sMappingTable );
p2cstrcpy( cName, name );
extension = PGPGetFileNameExtension( cName );
for( idx = 0; idx < sMappingTable->numEntries; ++idx )
{
CreatorTypeToExtensionEntry const * entry;
entry = &sMappingTable->entries[ idx ];
if ( pgpCompareStringsIgnoreCase( entry->extension,
extension ) == 0 )
{
/* extension matches. If the type and creator are
not wild cards, the use it */
if ( entry->creator != kWildCard &&
entry->type != kWildCard )
{
err = noErr;
*creator = entry->creator;
*type = entry->type;
break;
}
}
}
return( err );
}
PGPBoolean
pgpOKToEncodeFSSpecWithoutMacBinary( const FSSpec *spec )
{
OSStatus err;
CInfoPBRec cpb;
PGPBoolean encodeAsMacBinary = TRUE;
pgpAssert( IsntNull( sMappingTable ) );
if ( IsNull( sMappingTable ) )
return( FALSE );
err = FSpGetCatInfo( spec, &cpb );
pgpAssertNoErr( err );
if ( IsntPGPError( err ) )
{
CreatorTypeToExtensionEntry const * entry;
entry = sMatchMacBinaryCreatorAndType( cpbFileCreator( &cpb ),
cpbFileType( &cpb ) );
if ( IsntNull( entry ) )
{
encodeAsMacBinary = FALSE;
}
else
{
#define kMaxResForkSize 400
/* programatically determine */
/* should we allow files without resource forks? */
if ( cpbResForkSize( &cpb ) < kMaxResForkSize )
{
encodeAsMacBinary = FALSE;
}
}
}
return( ! encodeAsMacBinary );
}
#endif /* ] PGP_MACINTOSH */
#define IsEndOfLine( c ) ((c) == '\r' || (c) == '\n' )
static const char *
sSkipWhite(
const char * cur,
const char * last )
{
while ( cur <= last )
{
if ( isspace( *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( *cur ) )
break;
extension[ length ] = *cur++;
++length;
*valid = TRUE;
if ( length == 3 )
break;
}
extension[ length ] = '\0';
if ( cur <= last &&
! (isspace( *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
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 );
}
PGPError
pgpInitMacBinaryMappings( void )
{
PGPError err = kPGPError_NoErr;
PGPMemoryMgrRef memoryMgr = PGPGetDefaultMemoryMgr();
err = sInitFromBuiltIn( memoryMgr );
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 + -