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

📄 cmacfile.cp

📁 著名的 helix realplayer 基于手机 symbian 系统的 播放器全套源代码
💻 CP
📖 第 1 页 / 共 2 页
字号:
/* ***** BEGIN LICENSE BLOCK ***** 
 * Version: RCSL 1.0/RPSL 1.0 
 *  
 * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved. 
 *      
 * The contents of this file, and the files included with this file, are 
 * subject to the current version of the RealNetworks Public Source License 
 * Version 1.0 (the "RPSL") available at 
 * http://www.helixcommunity.org/content/rpsl unless you have licensed 
 * the file under the RealNetworks Community Source License Version 1.0 
 * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl, 
 * in which case the RCSL will apply. You may also obtain the license terms 
 * directly from RealNetworks.  You may not use this file except in 
 * compliance with the RPSL or, if you have a valid RCSL with RealNetworks 
 * applicable to this file, the RCSL.  Please see the applicable RPSL or 
 * RCSL for the rights, obligations and limitations governing use of the 
 * contents of the file.  
 *  
 * This file is part of the Helix DNA Technology. RealNetworks is the 
 * developer of the Original Code and owns the copyrights in the portions 
 * it created. 
 *  
 * This file, and the files included with this file, is distributed and made 
 * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 
 * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES, 
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS 
 * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 
 * 
 * Technology Compatibility Kit Test Suite(s) Location: 
 *    http://www.helixcommunity.org/content/tck 
 * 
 * Contributor(s): 
 *  
 * ***** END LICENSE BLOCK ***** */ 

// include platform specific headers here
#include <stdio.h>
#include <fcntl.h>
#include <Folders.h>
#include <Script.h>

#include "CMacFile.h"
#include "hxtick.h"
#include "FullPathName.h"
#include "hxcom.h"
#include "hxbuffer.h"
#include "hxmm.h"
#include "hxfiles.h" /* for HX_FILE_WRITE */

#ifndef _CARBON
#include "FSpCompat.h"
#include "MoreFilesExtras.h"
#else
#include "MoreFilesX.h"
#endif

OSType CMacFile::sCreator	= 'PNst';
OSType CMacFile::sFileType 	= 'PNRA';

BOOL gReadDone = FALSE;
ULONG32 gReadCount = 0;



// async callback proc
pascal void ReadCallback(ParamBlockRec* pb);

// async callback UPP
#ifdef _CARBON
static IOCompletionUPP			gReadCallbackUPP=NewIOCompletionUPP(ReadCallback);
#else
static IOCompletionUPP			gReadCallbackUPP=NewIOCompletionProc(ReadCallback);
#endif


CHXDataFile*
CHXDataFile::Construct (UINT32 ulFlags)
{
    return (CHXDataFile *) new CMacFile;
}

// CHXFile should set the file reference to a value indicating the file is not open
CMacFile::CMacFile (void)
{
	mRefNum = 0;
	mLastError = noErr;
	mAppendMode = FALSE;
	mBufferFile = NULL;
	mBufferedRead = FALSE;
	mWriteFile = NULL;
	mBufferedWrite = FALSE;
	
	m_pseudoFileHandle = NULL;	// if non-null, a memory manager handle containing the "file data"
	m_pseudoFileOffset = 0;		// current "read" position in the pseudo file
	m_pseudoFileSize = 0;		// total pseudo file size
}

// ~CHXFile should close the file if it is open
CMacFile::~CMacFile(void)
{
	/* if(mBufferFile)
	{ 
		delete mBufferFile;
		mBufferFile = NULL;
	}
	
	if(mWriteFile) 
	{
		delete mWriteFile;
		mWriteFile = NULL;
	} */
	
	Close();		// close file if necessary
}

// Create a file with the specified mode
// Close the previous file if it was open
HX_RESULT CMacFile::Create(const char *filename, UINT16 mode,BOOL textflag)
{
	Close();		// close previous file if necessary

	FSSpec		theSpec;
	
	
	OSErr	theErr=noErr;
	
	Close();	// close previous file if necessary

	theErr = FSSpecFromPathName(filename, &theSpec);

	if(!theErr)
	{
		Boolean targetIsFolder,wasAliased;
		theErr = ::ResolveAliasFile(&theSpec,true,&targetIsFolder,&wasAliased);
	}

	if(theErr==fnfErr)
		theErr = FSCreateDataFile(&theSpec,textflag ? 'ttxt' : sCreator ,textflag ? 'TEXT' : sFileType);
				
	if(!theErr)
		theErr = FSOpenFile(&theSpec, fsRdWrPerm, &mRefNum);
				
	if(!theErr)
		theErr = ::SetEOF(mRefNum, 0L);

	if(!theErr)
		mFile = theSpec;

	mLastError = theErr;
	
	return(theErr ? -1 : 0);	
}

// Open a file with the specified permissions
// Close the previous file if it was open
//
// If the file isn't found, look for a 'RLFL' resource *in the current
// resource chain* with the same name as the file.

HX_RESULT CMacFile::Open(const char *filename, UINT16 mode,BOOL textflag)
{
	OSErr	theErr 	= noErr;
	short 	perm	= fsCurPerm;
	UCHAR   length 	= ::strlen(filename);
	FSSpec	theSpec;
	
	if(!theErr)
	{	
	
		Close();	// close previous file if necessary
	
		theErr = FSSpecFromPathName(filename,&theSpec);
		if (theErr)  //try adding ':' (partial path)
		{
		    UCHAR* partial = new UCHAR[length + 2];
		    partial[0] = length+1;
		    partial[1] = ':';
		    ::BlockMoveData(filename,&partial[2],length);
		    theErr = FSMakeFSSpec(0,0,partial,&theSpec);
		    if (theErr == dirNFErr)
		    	theErr = fnfErr;
		    delete [] partial;
		
		}

		if(!theErr)
		{
			Boolean targetIsFolder,wasAliased;
			theErr = ::ResolveAliasFile(&theSpec,true,&targetIsFolder,&wasAliased);
		}
	}
	
	
	if(!theErr)
	{
		// figure out mac file permission
		perm = fsRdWrPerm;
		if (mode & O_WRONLY)	
			perm = fsWrPerm;
		else if (mode & O_RDONLY)
			perm = fsRdPerm;
		
		// Store the permissions for this file for later.
		m_mode=mode;
	
		theErr = FSOpenFile(&theSpec, perm, &mRefNum);
	}
	
	if(theErr != noErr)
	{
		if(theErr == fnfErr)
		{
			theErr = FSSpecFromPathName(filename,&theSpec);
			if ((mode & O_CREAT) || (mode & O_WRONLY)) //always create if Write mode
				theErr = FSCreateDataFile(&theSpec,textflag ? 'ttxt' : sCreator ,textflag ? 'TEXT' : sFileType);
				
			if(!theErr)
				theErr = FSOpenFile(&theSpec, perm, &mRefNum);
		}
	}
	
	if ((theErr) && (mode & O_RDONLY))
	{
		Handle	resHandle;		
		SInt32	resSize;
		
		// We couldn't open the file, and the request was read-only
		//
		// See if there's a pseudo-file resource we can use
		//
		// We need a handle to the resource so we can read from it, but
		// we don't want the whole resource loaded into memory, so we
		// set ResLoad to false.
		
		SetResLoad(false);
		resHandle = GetNamedResource(kRealFileResource, theSpec.name); // 'RLFL'
		SetResLoad(true);
		
		if (resHandle)
		{
			// we have a handle to the resource; determine
			// its size and reset our "file pointer"
			
			resSize = GetResourceSizeOnDisk(resHandle);
			if (resSize > 0)
			{
				m_pseudoFileHandle = resHandle;
				m_pseudoFileSize = resSize;
				m_pseudoFileOffset = 0;
				
				theErr = noErr;
				mRefNum = -1;	// signals that we're using a pseudo-file and no actual file is open
			}
		}
	}
	
	if (!m_pseudoFileHandle)
	{
		if(!theErr && (mode & O_CREAT))
			theErr = ::SetEOF(mRefNum, 0L);

		if(!theErr)
		{
			mAppendMode = (mode & O_APPEND);
			mFile = theSpec;
			if(mode & O_TRUNC) theErr = ::SetEOF(mRefNum, 0L);
		}

		
		if(theErr && mRefNum != 0) Close();
	}
	
	mLastError = theErr;
	
	return(theErr ? HXR_DOC_MISSING : 0);	
		
}

// Close the previous file if it was open
HX_RESULT CMacFile::Close(void)
{
OSErr theErr = noErr;

	if (m_pseudoFileHandle)
	{
		// "close" our pseudo file
		//
		// We don't need or want to dispose or release our pseudo-
		// file handle since it's not using up memory anyway, and
		// releasing it would hurt anyone else who happens to be
		// reading from it.  The handle will be released 
		// automatically when its owning resource file closes.
		
		m_pseudoFileHandle = 0;
		m_pseudoFileOffset = 0;
		m_pseudoFileSize = 0;
		theErr = noErr;
		mRefNum = 0;
	}
	
	else if (mRefNum) 
	{
		if(mBufferFile)
		{ 
			delete mBufferFile;
			mBufferFile = NULL;
		}
		
		if(mWriteFile) 
		{
			delete mWriteFile;
			mWriteFile = NULL;
		}

		// close a real file
		theErr = ::FSClose(mRefNum);
		mRefNum = 0;
		if(!theErr) theErr =::FlushVol(nil, mFile.vRefNum);
	}
	
	mLastError = theErr;
	return(theErr ? -1 : 0);	
}

HX_RESULT	CMacFile::Delete	(const char *filename)
{
    OSErr theErr = noErr;
    FSSpec theSpec;

	HX_ASSERT (!m_pseudoFileHandle);

	theErr = FSSpecFromPathName(filename,&theSpec);
	if (noErr == theErr) 
	{
		theErr = ::FSpDelete(&theSpec);
	}
	
	mLastError = theErr;
	return(theErr ? -1 : 0);	
}

/*	Returns the size of the file in bytes. */
ULONG32		CMacFile::GetSize(void)
{
	ULONG32 size=0;
	
	if (m_pseudoFileHandle)
	{
		size = m_pseudoFileSize;
	}
	
	else if (mRefNum) 
	{
    	::GetEOF(mRefNum,(long*)&size);
    }
    return size;
}

// Rewinds the file position to the start of the file
HX_RESULT CMacFile::Rewind(void)
{
	OSErr theErr;
	if (m_pseudoFileHandle)
	{
		m_pseudoFileOffset = 0;
		theErr = noErr;
	}
	else
	{
		theErr = ::SetFPos(mRefNum,fsFromStart,0L);
	}
	mLastError = theErr;
	return(theErr ? HXR_INVALID_FILE : 0);
}
	

// Seek moves the current file position to the offset from the fromWhere specifier
HX_RESULT CMacFile::Seek(ULONG32 offset, UINT16 fromWhere)
{
OSErr theErr = noErr;
		
	if (m_pseudoFileHandle)
	{
		switch(fromWhere)
		{
			case SEEK_SET:
				m_pseudoFileOffset = offset;
				break;

			case SEEK_CUR:
				m_pseudoFileOffset += offset;
				break;

			case SEEK_END:
				m_pseudoFileOffset = (m_pseudoFileSize - 1) - offset;
				break;
		}
		
		// don't go beyond the end (we won't return eofErr either to match
		// the real seek below)
		if (m_pseudoFileOffset >= m_pseudoFileSize)
		{
			m_pseudoFileOffset = m_pseudoFileSize - 1;
		}
		theErr = HXR_OK;
	}
	else if (mBufferedWrite)
	{
		long pos = 0;
		switch(fromWhere)
		{
			case SEEK_SET:
				pos = offset;
				break;

			case SEEK_CUR:
				pos = mWriteFile->GetCurPos() + offset;
				break;

			case SEEK_END:
				pos = (mWriteFile->GetBufSize() - 1) - offset;
				break;
		}
		mWriteFile->Seek(pos);
	}
	else
	{
		switch(fromWhere)
		{
			case SEEK_SET:
				fromWhere = fsFromStart;
				break;

			case SEEK_CUR:
				fromWhere = fsFromMark;
				break;

			case SEEK_END:
				fromWhere = fsFromLEOF;
				break;
		}
		
		theErr =  ::SetFPos(mRefNum,fromWhere,offset);

		// returning eofErr was causing problems for ChunkyRes during http play
		if (theErr == eofErr)
		{
			theErr = ::SetEOF(mRefNum,offset);
			theErr = ::SetFPos(mRefNum,fromWhere,offset);
			theErr = HXR_OK;
		}
			
		long pos;
		::GetFPos(mRefNum,(long *)&pos);

		if(!theErr && mBufferedRead)
		{
			long count; 
			::GetEOF(mRefNum, &count);
			mBufferFile->PreLoad(pos,count - offset);
		}

		/* if(!theErr && mBufferedWrite)
		{
			mWriteFile->Seek(pos);
		} */
	}
	mLastError = theErr;
	return(theErr ? HXR_INVALID_FILE : 0);	
}

// Tell 
ULONG32 CMacFile::Tell(void)
{
ULONG32	pos;

	if (m_pseudoFileHandle)
	{
		pos = m_pseudoFileOffset;
		mLastError = noErr;
	}
	else
	{
		mLastError = ::GetFPos(mRefNum,(long *)&pos);
	}
	return(pos);	
}

// callback could be at interrupt time
pascal void ReadCallback(ParamBlockRec* pb)
{
    OSErr theErr = (*pb).ioParam.ioResult;    	 
    gReadCount = pb->ioParam.ioActCount;
    gReadDone = TRUE;
}

/* 	Read reads up to count bytes of data into buf.
	returns the number of bytes read, EOF, or -1 if the read failed */
ULONG32 CMacFile::Read (char *buf, ULONG32 count)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -