📄 cmacfile.cp
字号:
OSErr theErr = noErr;
if (m_pseudoFileHandle)
{
INT32 actualCount;
theErr = Read(buf, count, &actualCount);
count = actualCount;
}
else
{
if(mBufferedRead)
{
count = Copy(buf,count);
if(count == 0)
theErr = eofErr;
}
else
{
// can't do synchronous read at interrupt time
if (!HXMM_ATINTERRUPT())
{
theErr = ::FSRead(mRefNum, (long *)&count, buf);
}
else
{ // async i/o - callback could be at interrupt time
#if 1
ParamBlockRec pb;
gReadCount = 0;
gReadDone = FALSE;
pb.ioParam.ioRefNum = mRefNum;
pb.ioParam.ioBuffer = buf;
pb.ioParam.ioReqCount = count;
pb.ioParam.ioPosMode=fsAtMark;
pb.ioParam.ioCompletion = gReadCallbackUPP;
theErr = PBReadAsync(&pb);
UINT32 timeout = TickCount() + 60L;
while (!gReadDone && timeout-TickCount() > 0)
{
}
count = gReadCount;
#endif
}
}
if(theErr == eofErr && count > 0)
theErr = noErr;
}
mLastError = theErr;
return(mLastError ? 0 : count); //smplfsys::read assumes we return 0 for eof
}
/* Read reads up to count bytes of data into buf.
returns the number of bytes read, EOF, or -1 if the read failed */
INT16 CMacFile::Read (char *buf, INT32 count, INT32 *actualCount)
{
OSErr theErr = noErr;
long readCount = (long) count;
if (m_pseudoFileHandle)
{
// read from our pseudo-file
SInt32 remainingBytes;
remainingBytes = m_pseudoFileSize - m_pseudoFileOffset;
if (remainingBytes <= 0)
{
// we've already exhausted the buffer
theErr = eofErr;
}
else
{
// some bytes remain to be "read" so read them directly
// from the resource into the caller's buffer
if (remainingBytes < count)
{
count = remainingBytes;
}
ReadPartialResource(m_pseudoFileHandle, m_pseudoFileOffset, buf, count);
theErr = ResError();
HX_ASSERT(theErr == noErr);
// while we don't expect any errors, -188 (resourceInMemory) isn't fatal
if (theErr == noErr || theErr == resourceInMemory)
{
// update our pseudo-file pointer
readCount = count;
m_pseudoFileOffset += count;
theErr = noErr;
}
}
}
else
{
if(mBufferedRead)
{
readCount = Copy(buf,readCount);
if(readCount == 0)
theErr = eofErr;
}
else
{
if (!HXMM_ATINTERRUPT())
theErr = ::FSRead(mRefNum, &readCount, buf);
else
{ // async i/o - callback could be at interrupt time
#if 0
ParamBlockRec pb;
// IOCompletionUPP proc = NewIOCompletionProc(ReadCallback);
gReadCount = 0;
gReadDone = FALSE;
pb.ioParam.ioRefNum = mRefNum;
pb.ioParam.ioBuffer = buf;
pb.ioParam.ioReqCount = count;
pb.ioParam.ioPosMode=fsAtMark;
pb.ioParam.ioCompletion = m_CompletionProc;
theErr = PBReadAsync(&pb);
EventRecord theEvent;
long sleepTime=10;
long timeout = 0;
// timeout, in case file read can't complete
while (!gReadDone && timeout < 100)
{
::WaitNextEvent(everyEvent, &theEvent, sleepTime, nil);
timeout++;
}
count = gReadCount;
#endif
}
}
}
if(theErr == eofErr && readCount > 0)
theErr = noErr;
if (actualCount)
{
*actualCount = (INT32) readCount;
}
return(theErr);
}
/* Write writes up to count bytes of data from buf.
returns the number of bytes written, or -1 if the write failed */
ULONG32 CMacFile::Write(const char *buf, ULONG32 count)
{
HX_ASSERT(!m_pseudoFileHandle);
OSErr theErr = noErr;
if (!HXMM_ATINTERRUPT())
{
if(mAppendMode)
theErr = ::SetFPos(mRefNum,fsFromLEOF,0L);
if(!theErr)
{
if(mBufferedWrite)
mWriteFile->write_data((Ptr)buf,(long)count);
else
{
theErr = ::FSWrite(mRefNum, (long *)&count, buf);
//check_noerr(theErr); a disk full error may occur
}
}
mLastError = theErr;
// return(theErr ? -1 : count);
}
else
{
if(mBufferedWrite)
mWriteFile->write_data((Ptr)buf,(long)count);
mLastError = theErr;
}
// return count;
return (theErr == noErr? count : -1);
}
/* Write writes up to count bytes of data from buf.
returns the number of bytes written, or -1 if the write failed */
INT16 CMacFile::Write(const char *buf, INT32 count, INT32 *actualCount)
{
HX_ASSERT(!m_pseudoFileHandle);
OSErr theErr = noErr;
*actualCount = 0;
if (!HXMM_ATINTERRUPT())
{
long writeCount = 0;
if(mAppendMode)
theErr = ::SetFPos(mRefNum,fsFromLEOF,0L);
if(!theErr)
{
writeCount = count;
theErr = ::FSWrite(mRefNum, &writeCount, buf);
}
*actualCount = (INT32) writeCount;
}
//check_noerr(theErr); a disk full error may occur
// elsewhere the file code expects a negative actualCount when
// the write failed
if (theErr != noErr) *actualCount = -1;
return(theErr);
}
OSErr CMacFile::FSOpenFile(FSSpec *theSpec, short perm, short *fRefNum)
{
OSErr theErr = noErr;
Boolean targetIsFolder,wasAliased;
*fRefNum = 0;
theErr = ResolveAliasFile(theSpec,true,&targetIsFolder,&wasAliased);
if(!theErr) theErr = ::FSpOpenDF(theSpec,perm,fRefNum);
if(theErr) *fRefNum = 0;
return(theErr);
}
OSErr CMacFile::FSCreateDataFile(FSSpec *sfFile, OSType creator, OSType type)
{
OSErr theErr = noErr;
theErr = ::FSpCreate(sfFile,creator,type,smSystemScript);
if(theErr)
{
if(theErr == dupFNErr)
theErr = FSSetFInfo(sfFile, creator, type);
}
return(theErr);
}
OSErr CMacFile::FSSetFInfo(FSSpec *theSpec, OSType creator, OSType type)
{
OSErr theErr = noErr;
#ifndef _CARBON
theErr = FSpChangeCreatorType(theSpec, creator, type);
#else
FSRef ref;
theErr = FSpMakeFSRef(theSpec, &ref);
if (theErr == noErr)
{
theErr = FSChangeCreatorType(&ref, creator, type);
}
#endif
return(theErr);
}
void CMacFile::SetFileType(OSType creator, OSType type)
{
sFileType = type;
sCreator = creator;
}
OSErr CMacFile::FSSetFilePos(short fRefNum, short fromWhere, long offset)
{
HX_ASSERT(fRefNum != -1); // we can't do this on a pseudo file (since this method's static)
/*
if (m_pseudoFileHandle)
{
OSErr err;
switch (fromWhere)
{
case fsAtMark:
err = noErr;
break;
case fsFromMark:
offset += m_pseudoFileOffset;
// fall through...
case fsFromStart:
if (offset < 0) err = posErr;
else if (offset < m_pseudoFileSize)
{
m_pseudoFileOffset = offset;
err = noErr;
}
else
{
// offset is >= m_pseudoFileSize
err = eofErr;
m_pseudoFileOffset = m_pseudoFileSize;
}
break;
case fsFromLEOF:
if (offset > 0) err = posErr;
else if (m_pseudoFileSize - (offset + 1) >= 0)
{
m_pseudoFileOffset = m_pseudoFileSize - (offset + 1);
err = noErr;
}
else
{
// offset is >= -m_pseudoFileSize
err = posErr;
m_pseudoFileOffset = 0;
}
break;
}
return err;
}
*/
return ::SetFPos(fRefNum,fromWhere,offset);
}
long CMacFile::Copy(Ptr destBuf, long numBytes)
{
long count;
// check for buffered i/o
if(mBufferedRead)
count = mBufferFile->Copy(destBuf,numBytes);
else
count = 0;
return(count);
}
HX_RESULT CMacFile::set_buffered_read (char buffered)
{
Boolean OK = TRUE;
HX_ASSERT(!m_pseudoFileHandle);
// If this file is setup for writing then we don't want to do any buffered reading.
if (m_mode & O_WRONLY) return HXR_OK;
if (m_mode & O_RDWR) return HXR_OK;
mBufferedRead = 0;
return HXR_OK; //HACK! - this needs to be redone!
// set up buffered read object if necessary
if(buffered && !mBufferedRead)
{
if(mBufferFile == NULL)
{
mBufferFile = new CBufferFile;
OK = mBufferFile != NULL;
}
if(OK)
OK = mBufferFile->Specify(mRefNum);
}
else if(!buffered && mBufferedRead)
{
if(mBufferFile != NULL)
{
delete mBufferFile;
mBufferFile = NULL;
}
}
mBufferedRead = buffered != 0;
if(OK)
Seek(0,SEEK_SET);
return(OK ? HXR_OK : HXR_OUTOFMEMORY);
}
HX_RESULT CMacFile::set_buffered_write (char buffered)
{
Boolean OK = TRUE;
HX_ASSERT(!m_pseudoFileHandle);
// set up buffered read object if necessary
if(buffered && !mBufferedWrite)
{
if(mWriteFile == NULL)
{
mWriteFile = new CWriteFile;
OK = mWriteFile != NULL;
}
if(OK)
{
OK = mWriteFile->Specify(mRefNum,Tell());
}
}
else if(!buffered && mBufferedWrite)
{
if(mWriteFile != NULL)
{
delete mWriteFile;
mWriteFile = NULL;
}
}
mBufferedWrite = buffered != 0;
return(OK ? HXR_OK : HXR_OUTOFMEMORY);
}
INT16 CMacFile::FileSize(long *size)
{
return ::GetEOF(mRefNum,size);
}
static ULONG32 sPrevSuffix = 0;
BOOL CMacFile::GetTemporaryFileName(const char *tag, char* name)
{
short tempVRefNum;
long tempDirID;
Str255 tempFileName;
FSSpec tempSpec;
OSErr theErr = noErr;
// build the temp file name in the form tag_sPrevSuffix
// changed from tag.sPrevSuffix because many other portions
// of code STRIP the suffix, and add their own
// thus yielding a very NON unique file name <rlovejoy>
::sprintf((char *)tempFileName,"%s_%ld",tag,sPrevSuffix++);
// copy the temo file name into the caller's name field in case we
// can't find the Temporary Folder
::strcpy(name,(char *)tempFileName);
// Try to get the FSSpec of the System Folder's Temporary Folder
// starting with System 8, the preferred temporary folder is the Chewable Items
// folder (aka Cleanup at Startup) GR 12/8/98
theErr = ::FindFolder(kOnSystemDisk,kChewableItemsFolderType,kCreateFolder,&tempVRefNum,&tempDirID);
if (theErr != noErr)
theErr = ::FindFolder(kOnSystemDisk,kTemporaryFolderType,kCreateFolder,&tempVRefNum,&tempDirID);
if(!theErr)
{
// Build an FSSpec for the temp file in the Temporary Folder
#ifdef _CARBON
c2pstrcpy((StringPtr)tempFileName, (char*)tempFileName);
#else
::c2pstr((char *)tempFileName);
#endif
theErr = ::FSMakeFSSpec(tempVRefNum,tempDirID,tempFileName,&tempSpec);
}
// Note: it is okay for FSMakeFSSpec to return fnfErr since the caller
// is going to create the file.
// Now create the full path name to the temp file
if(!theErr || theErr == fnfErr)
{
theErr = noErr;
CHXString theString;
theErr = PathNameFromFSSpec(&tempSpec, theString);
if(!theErr)
::strcpy(name,theString);
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -