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

📄 pgpmacfilemapping.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:


#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 + -