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

📄 pgpstdfileio.c

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

	$Id: pgpStdFileIO.c,v 1.14 2002/08/06 20:10:34 dallen Exp $
____________________________________________________________________________*/
/*
 *	Implementation of FileIO based on a FILE *.  This is a concrete subclass
 *	that can be instantiated using a FILE *.
 */
#include "pgpPFLPriv.h"

#include <stdio.h>
#if PGP_WIN32
/* For lseeki64 and telli64 calls -wjb */
#include <io.h>
#endif

#if PGP_MACINTOSH
#include <unix.h>
#endif

#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif

#include "pgpPFLErrors.h"
#include "pgpMem.h"

#include "pgpStdFileIOPriv.h"

#define PGP_USE_FILE_SPEC_PRIV
#include "pgpFileSpecPriv.h"


#define GetParentVTBL()		pgpFileIOGetClassVTBL()

#define GetSelfVTBL( ref ) \
	(PGPStdFileIOVtbl const *)pgpioGetObjectVTBL( ref )

#if PGP_WIN32 || !HAVE_64BIT_FILES
	static PGPUInt32 
fsetpos64(FILE *stream,PGPFileOffset *pos)
{	
#if PGP_WIN32
	PGPFileOffset rst;

	fflush(stream);
	rst=_lseeki64(fileno(stream), *pos, SEEK_SET);
/*	fflush(stream);*/
	if(rst==(-1))
#else

	fpos_t		tempPos;
	int			result;
	
#if PGP_UNIX_LINUX
	tempPos	= *((fpos_t *)pos);
#else
	tempPos = (fpos_t) *pos;
#endif /* PGP_UNIX_LINUX */

	result	= fsetpos( stream, &tempPos );
	if ( result != 0 )	
#endif /* PGP_WIN32 */
		return -1;

	return 0;
}
/*
	static PGPUInt32 
fgetpos64(FILE *stream,PGPFileOffset *pos)
{
	PGPFileOffset rst;

	rst=ftell(stream);

//	fflush(stream);
//	rst=_telli64(fileno(stream)); // 4096 problem! wjb
//	fflush(stream);
	
	if(rst==(-1))
		return (-1);

	*pos=rst;
	return 0;
}*/

#endif /* HAVE_64BIT_FILES */

	PGPBoolean
PGPStdFileIOIsValid( PGPStdFileIORef self )
{
	if ( ! PGPFileIOIsValid( (PGPFileIORef)self ) )
		return( FALSE );
	
	return( self->stdFileIOMagic == kPGPStdFileIOMagic );
}



	PGPError
PGPNewStdFileIO(
	PGPMemoryMgrRef		context,
	FILE *				stdioFILE,
	PGPBoolean			autoClose,
	PGPStdFileIORef *	outRef )
{
	PGPError			err	= kPGPError_NoErr;
	PGPIORef			newRef;
	PGPStdFileIOData	data;
	
	data.autoClose	= autoClose;
	data.stdioFILE	= stdioFILE;
	
	err	= pgpNewIOFromVTBL( context,
			(PGPIOVtbl const *)pgpStdFileIOGetClassVTBL(),
			sizeof( PGPStdFileIO ), &data, &newRef );
	
	*outRef	= (PGPStdFileIORef)newRef;

	if(IsntPGPError(err))
	{
#if PGP_WIN32
		struct _stati64	buf;
#elif PGP_MACINTOSH
#if HAVE_64BIT_FILES
#error no 64 bit file support yet
#else
		struct stat		buf;
#endif /* HAVE_64BIT_FILES */
#elif PGP_UNIX
#if HAVE_64BIT_FILES
		struct stat64	buf;
#else
		struct stat		buf;
#endif /* HAVE_64BIT_FILES */
#endif /* PGP_UNIX */
		PGPStdFileIORef	self;

		self = (PGPStdFileIORef)newRef;

#if PGP_WIN32
		_fstati64 (fileno (stdioFILE), &buf);
#elif PGP_MACINTOSH
#if HAVE_64BIT_FILES
#error no 64 bit file support yet
#else
		fstat (fileno (stdioFILE), &buf);
#endif /* HAVE_64BIT_FILES */
#elif PGP_UNIX
#if HAVE_64BIT_FILES
		fstat64 (fileno (stdioFILE), &buf);
#else
		fstat (fileno (stdioFILE), &buf);
#endif /* HAVE_64BIT_FILES */
#endif /* PGP_UNIX */

		self->filePos=0;
		self->totalSize = buf.st_size;
	}

	return( err );
}


	static PGPError
sStdFileIOInitProc(
	PGPIORef	inRef,
	void *		data )
{
	PGPError					err		= kPGPError_NoErr;
	PGPStdFileIORef				self	= (PGPStdFileIORef)inRef;
	const PGPStdFileIOData *	myData	= (PGPStdFileIOData *)data;
	
	PGPValidateIO( inRef );
	
	err	= pgpioInheritInit( inRef, (PGPIOVtbl const *)GetParentVTBL(), data );
	
	self->stdFileIOMagic	= kPGPStdFileIOMagic;
	self->stdioFILE			= myData->stdioFILE;
	self->autoClose			= myData->autoClose;
	
	return( err );
}



	static PGPError
sStdFileIODestroyProc( PGPIORef	inRef )
{
	PGPError		err	= kPGPError_NoErr;
	PGPStdFileIORef	self	= (PGPStdFileIORef)inRef;
	int				closeResult;

	PGPValidateStdFileIO( self );
	PGPValidatePtr( self->stdioFILE );
	
	closeResult	= fclose( self->stdioFILE );
	self->stdioFILE	= NULL;
	
	self->stdFileIOMagic	= 0;
	
	err	= pgpioInheritDestroy( inRef, (PGPIOVtbl const *)GetParentVTBL() );
	
	if ( closeResult != 0 )
		err	= kPGPError_FileOpFailed;
	
	return( err );
}




	static PGPError
sStdFileSetPosProc(
	PGPIORef		ref,
	PGPFileOffset	newPos )
{
	PGPError		err	= kPGPError_NoErr;
	PGPStdFileIORef	self	= (PGPStdFileIORef)ref;
	int			result;
	
	PGPValidatePtr( self->stdioFILE );

	if (newPos < 0 || newPos > self->totalSize)
	{
		return kPGPError_FileOpFailed;
	}

	self->filePos = newPos;

	result	= fsetpos64( self->stdioFILE, &newPos );
	if ( result != 0 )
	{
		err	= kPGPError_FileOpFailed;
	}
	
	return( err );
}




	static PGPError
sStdFileIOReadProc(
	PGPIORef		ref,
	PGPSize			requestCount,
	void *			buffer,
	PGPSize *		bytesRead )
{
	PGPError		err		= kPGPError_NoErr;
	PGPStdFileIORef	self	= (PGPStdFileIORef)ref;
	size_t			result;
	
	PGPValidatePtr( self->stdioFILE );
	
	result	= fread( buffer, 1, requestCount, self->stdioFILE );
	if ( result != requestCount )
	{
		err	= kPGPError_EOF;
	}
	*bytesRead	= result;
	
	self->filePos += *bytesRead;

	return( err );
}

						
	static PGPError
sStdFileIOWriteProc(
	PGPIORef		ref,
	PGPSize			requestCount,
	const void *	buffer )
{
	PGPError		err		= kPGPError_NoErr;
	PGPStdFileIORef	self	= (PGPStdFileIORef)ref;
	size_t			result;
	
	PGPValidatePtr( self->stdioFILE );
	
	result	= fwrite( buffer, 1, requestCount, self->stdioFILE );
	if ( result != requestCount )
	{
		err	= kPGPError_WriteFailed;
	}
	
	self->filePos += result;

	if (self->totalSize < self->filePos)
		self->totalSize = self->filePos;

	return( err );
}

						
	static PGPError
sStdFileIOGetEOFProc(
	PGPIORef		ref,
	PGPFileOffset *	eof )
{
	PGPError		err	= kPGPError_NoErr;
	PGPStdFileIORef	self	= (PGPStdFileIORef)ref;
/*	FILE *			stdioFILE	= self->stdioFILE;
	PGPFileOffset	startPos;
	PGPFileOffset	eofPos;
	int				fResult;
	
	*eof	= 0;
	PGPValidatePtr( self->stdioFILE );
	
	// save current file position 
	fResult	= fgetpos64( stdioFILE, &startPos );
	if ( fResult == 0 )
	{
		// seek to the end of the file so we can get its length 
		fResult	= fseek( stdioFILE, 0, SEEK_END );
		if ( fResult == 0 )
			fResult	= fgetpos64( stdioFILE, &eofPos);
		
		if ( fResult != 0 )
			err	= kPGPError_FileOpFailed;
			
		// restore previous file position 
		fResult	= fsetpos64( stdioFILE, &startPos );
		if ( fResult != 0 )
			err	= kPGPError_FileOpFailed;
	}
	else
	{
		err	= kPGPError_FileOpFailed;
	}
	
	
	*eof	= eofPos;*/
	*eof = self->totalSize;

	return( err );
}




#if PGPIO_EOF
	static PGPError
sChangeFileSize(
	FILE *			file,
	PGPFileOffset	newEOF)
{
	PGPError	err	= kPGPError_NoErr;
	
	(void)file;
	(void)newEOF;
#if defined( PGP_UNIX )

#elif defined( PGP_WIN32 )

#elif defined( PGP_MACINTOSH )

#endif
	return( err );
}



	static PGPError
sStdFileIOSetEOFProc(
	PGPIORef		ref,
	PGPFileOffset 	newEOF )
{
	PGPError		err	= kPGPError_IllegalFileOp;
	PGPStdFileIORef	self	= (PGPStdFileIORef)ref;
	FILE *			stdioFILE	= self->stdioFILE;
	
	PGPValidatePtr( stdioFILE );
	
	err	= sChangeFileSize( stdioFILE, newEOF);
	if ( IsntPGPError( err ) )
	{
		/* stdio buffers may now be whacked */
		/* how to flush them? */
		pgpDebugMsg( "flush buffers" );
	}

	return( err );
}

#endif
					
	static PGPError
sStdFileIOFlushProc( PGPIORef		ref)
{
	PGPError		err		= kPGPError_NoErr;
	PGPStdFileIORef	self	= (PGPStdFileIORef)ref;
	
	PGPValidatePtr( self->stdioFILE );
	if ( fflush( self->stdioFILE ) != 0 )
	{
		err	= kPGPError_FileOpFailed;
	}
	
	return( err );
}




	PGPStdFileIOVtbl const *
pgpStdFileIOGetClassVTBL()
{
	static PGPStdFileIOVtbl	sVTBL	= { {{NULL,}} };
	PGPFileIOVtbl *	parent	= &sVTBL.parentVTBL;
	
	if ( IsNull( parent->parentVTBL.initProc ) )
	{
		/* get default routines */
		*parent	= *pgpFileIOGetClassVTBL();
		
		parent->parentVTBL.initProc		= sStdFileIOInitProc;
		parent->parentVTBL.destroyProc	= sStdFileIODestroyProc;
		
		parent->parentVTBL.readProc		= sStdFileIOReadProc;
		parent->parentVTBL.writeProc	= sStdFileIOWriteProc;
		
		parent->parentVTBL.setPosProc	= sStdFileSetPosProc;
		
		parent->parentVTBL.getEOFProc	= sStdFileIOGetEOFProc;
		
#if PGPIO_EOF
		parent->parentVTBL.setEOFProc	= sStdFileIOSetEOFProc;
#endif
		
		parent->parentVTBL.flushProc	= sStdFileIOFlushProc;
	}
	
	return( &sVTBL );
}


























/*__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 + -