hxdir.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 928 行 · 第 1/2 页
CPP
928 行
int nSpecPos = nextFSpec.name[0] - nCompareLen + 1;
if (0 != strncasecmp((char*)&nextFSpec.name[nSpecPos], &m_pPattern[patternOffset+1], nCompareLen))
bContinue = FALSE;
}
}
else
{
if ((patlen != nextFSpec.name[0]) ||
(0 != strncasecmp((char*)&nextFSpec.name[1], szPattern, patlen)))
bContinue = FALSE;
}
}
}
if (bContinue)
{
strncpy(m_pNextFileName, (char*)&nextFSpec.name[1], len); /* Flawfinder: ignore */
m_pNextFileName[len] = 0;
tempStr = m_strPath;
if (m_strPath.GetLength())
{
if (tempStr[tempStr.GetLength()-1] != ':')
tempStr += ":";
}
tempStr += m_pNextFileName;
SafeStrCpy(szPath, (const char*)tempStr, nSize);
if (IsFolder(&nextFSpec))
return FSOBJ_DIRECTORY;
else
return FSOBJ_FILE;
}
}
RetVal = FindNext(szPath, nSize);
}
return RetVal;
}
/* Continues enumeration process. */
CHXDirectory::FSOBJ
CHXDirectory::FindNext(char* szPath, UINT16 nSize)
{
FSOBJ RetVal = FSOBJ_NOTVALID;
CHXString tempStr;
FSSpec nextFSpec;
BOOL bContinue;
if (m_pNextFileName)
{
SafeStrCpy(m_pCurrentFileName, m_pNextFileName, nSize);
}
else
{
if (m_pCurrentFileName)
{
delete [] m_pCurrentFileName;
m_pCurrentFileName = NULL;
}
}
/*
tempStr = szPath;
::FSMakeFSSpec(0,0,*((Str255*)tempStr),&nextFSpec);
if (IsFolder(&nextFSpec, 1))
{
strcpy(szPath, (const char*)tempStr);
return FSOBJ_DIRECTORY;
}
*/
if (m_pNextFileName)
{
INT16 len = 0;
char* patternStart;
CInfoPBRec pb;
OSErr err=noErr;
memset(&pb,0,sizeof(pb));
pb.hFileInfo.ioVRefNum=m_fileSpec.vRefNum;
pb.hFileInfo.ioFDirIndex=0;
pb.hFileInfo.ioNamePtr=m_fileSpec.name;
pb.hFileInfo.ioDirID=m_fileSpec.parID;
err = PBGetCatInfoSync(&pb);
UINT16 dirItems = pb.dirInfo.ioDrNmFls;
if (dirItems < m_nDirItems) // items have been deleted
{
m_nIndex -= (m_nDirItems - dirItems);
m_nDirItems = dirItems;
}
while (::FSpIterateDirectory(&m_fileSpec, ++m_nIndex, &nextFSpec))
{
bContinue = TRUE;
if (m_pPattern)
{
INT16 patlen = strlen(m_pPattern);
if ( 0 == strcmp("*.*", m_pPattern) || // *.*
((m_pPattern[0] == '*') && (strlen(m_pPattern) == 1)) ) // *
bContinue = TRUE;
else
{
if (m_pPattern[0] == '*') //eg. *.dll
{
if (0 != strncasecmp((char*)&nextFSpec.name[len-2], &m_pPattern[strlen(m_pPattern)-3], 3))
bContinue = FALSE;
}
else if ((patternStart = strchr(m_pPattern, '*')) != 0) //eg. pncrt*.dll
{
INT16 patternOffset = patternStart-m_pPattern;
if (0 != strncasecmp((char*)&nextFSpec.name[1], m_pPattern, patternOffset))
bContinue = FALSE;
if (bContinue && (patternOffset < patlen))
{
int nCompareLen = (patlen > nextFSpec.name[0]) ? nextFSpec.name[0] - patternOffset
: patlen - patternOffset - 1;
int nSpecPos = nextFSpec.name[0] - nCompareLen + 1;
if (0 != strncasecmp((char*)&nextFSpec.name[nSpecPos], &m_pPattern[patternOffset+1], nCompareLen))
bContinue = FALSE;
}
}
else // eg. pncrtd.dll
{
if (0 != strncasecmp((char*)&nextFSpec.name[1], m_pPattern, patlen))
bContinue = FALSE;
}
}
}
if (bContinue)
{
len = nextFSpec.name[0];
strncpy(m_pNextFileName, (char*)&nextFSpec.name[1], len); /* Flawfinder: ignore */
m_pNextFileName[len] = 0;
tempStr = m_strPath;
if (m_strPath.GetLength())
{
if (tempStr[tempStr.GetLength()-1] != ':')
tempStr += ":";
}
tempStr += m_pNextFileName;
SafeStrCpy(szPath, (const char*)tempStr, nSize);
if (IsFolder(&nextFSpec))
return FSOBJ_DIRECTORY;
else
return FSOBJ_FILE;
}
}
if (RetVal != FSOBJ_FILE)
{
delete [] m_pNextFileName;
m_pNextFileName = 0;
}
}
return RetVal;
}
OSErr
CHXDirectory::GetDirID(long& dirID)
{
FSSpec dirSpec;
CInfoPBRec cinfo;
OSErr err;
Boolean dirFlag;
if (EnsureValidPathSpec())
{
dirSpec = m_dirSpec;
// call GetCatInfo to get it's dirID
cinfo.dirInfo.ioNamePtr = dirSpec.name;
cinfo.dirInfo.ioVRefNum = dirSpec.vRefNum;
cinfo.dirInfo.ioDrDirID = dirSpec.parID;
cinfo.dirInfo.ioFDirIndex = 0; // use name and dirID
err = PBGetCatInfoSync(&cinfo);
// be sure it's really a directory
if (err == noErr)
{
dirFlag = ((cinfo.dirInfo.ioFlAttrib & ioDirMask) != 0);
if (!dirFlag) err = dirNFErr;
}
if (err == noErr)
{
dirID = cinfo.dirInfo.ioDrDirID;
}
}
else
{
// invalid path
err = fnfErr;
}
return err;
}
BOOL
CHXDirectory::DeleteFile(const char* szRelPath)
{
CHXString relativeStr(szRelPath);
CHXString fullFileStr;
FSSpec fileSpec;
OSErr err;
// make a full pathname to the file if we don't have a
// directory set (since some callers use a null dir
// just to delete files)
if (IsPartialMacPath(relativeStr) && (m_strPath.GetLength() > 0))
{
// we're deleting for a partial path from the current obj directory
fullFileStr = m_strPath;
// add seperator if needed
if ((fullFileStr.GetLength() > 0) && (fullFileStr[fullFileStr.GetLength()-1] != ':'))
fullFileStr += ':';
fullFileStr += relativeStr;
}
else
{
HX_ASSERT(IsFullMacPath(relativeStr)); // object's dir not set, so this works only for full paths
fullFileStr = relativeStr;
}
// delete the file
fileSpec = fullFileStr;
err = FSpDelete(&fileSpec);
// we really should return an error
// this gets called frequently if the file doesn't exist - not an error
// so return error only if file is busy
return (err != fBsyErr);
}
/* Sets itself to current directory. */
BOOL
CHXDirectory::SetCurrentDir()
{
// This was never implemented, doesn't work reliably on
// Macs, and since it's a bad idea, it's not worth implementing.
long dirID;
short vRefNum;
OSErr err = ::HGetVol(NULL, &vRefNum, &dirID);
err = ::FSMakeFSSpec(vRefNum, dirID, "\p", &m_dirSpec);
if (noErr == err)
{
m_strPath = m_dirSpec;
m_strPath = m_strPath.Left(m_strPath.GetLength()-1);
return TRUE;
}
return FALSE;
}
/* Makes itself a current directory. */
BOOL
CHXDirectory::MakeCurrentDir()
{
// Relying on a global current default directory is a bad
// idea, so never call this.
//
// Also beware that calling GetVol() won't work properly
// after this, anyway. See ch. 2 of Inside Mac: Files
// (under Manipulating the Default Volume and Directory)
// for an explanation of why.
//
// SetVol, GetVol, and everything using
// WDRefNums has been obsolete since 1987.
// Use FSSpecs (or full pathnames, if necessary) instead.
OSErr err;
long dirID;
err = GetDirID(dirID);
if (err == noErr)
{
err = HSetVol(NULL, m_dirSpec.vRefNum, dirID);
}
return (err == noErr);
}
UINT32
CHXDirectory::Rename(const char* szOldName, const char* szNewName)
{
UINT32 err;
// Unfortunately, the semantics of the parameters for this call aren't clear
//
// presumably, szOldName is a full path, or a partial path in the current directory
// presumably, szNewName is a full path, or just a name
CHXString oldFileStr(szOldName);
CHXString newFileStr(szNewName);
StringPtr newNamePtr;
FSSpec oldFileSpec;
FSSpec newFileSpec;
FSSpec destDirSpec;
(void) EnsureValidPathSpec();
oldFileSpec.vRefNum = 0;
if (oldFileStr.Find(':') >= 0)
{
// the old name has a colon; convert it to a file spec
oldFileSpec = oldFileStr;
}
if (oldFileSpec.vRefNum == 0)
{
// we couldn't get a valid FSSpec for the old name,
// so assume it's relative to the current directory,
// and make a file spec for it
oldFileStr = m_dirSpec;
oldFileStr += ":";
oldFileStr += szOldName;
oldFileSpec = oldFileStr;
}
require_action(oldFileSpec.vRefNum != 0, CantGetSourceForRename, err = fnfErr);
newFileSpec.vRefNum = 0;
if (newFileStr.Find(':') >= 0)
{
// the new name has a colon; try to convert it to a file spec
newFileSpec = newFileStr;
}
// make a filespec for the destination folder
//
// use the directory of the new file if it was specified, otherwise use
// the directory of the old file
err = FSMakeFSSpec(newFileSpec.vRefNum,
(newFileSpec.vRefNum == 0 ? oldFileSpec.parID : newFileSpec.parID),
"\p", &destDirSpec);
check_noerr(err);
// make sure we're not trying to move to another volume
require_action(destDirSpec.vRefNum == oldFileSpec.vRefNum, CantChangeVolumes, err = HXR_FAILED);
// they're on the same drive; possibly in different folders
// use the name from the new file spec, if we have one, or else from the parameter
newNamePtr = (newFileSpec.vRefNum ? newFileSpec.name : newFileStr);
// use morefiles' Move/Rename call
err = FSpMoveRenameCompat(&oldFileSpec, &destDirSpec, newNamePtr);
if (err == dupFNErr)
{
err = FSpDelete(&newFileSpec);
if (err == noErr)
{
err = FSpMoveRenameCompat(&oldFileSpec, &destDirSpec, newNamePtr);
}
}
CantChangeVolumes:
CantGetSourceForRename:
if (err == noErr) err = HXR_OK;
else err = HXR_FAILED;
return err;
}
// this moves or copies and renames a file
BOOL
CHXDirectory::MoveRename(const char* szSrcName, const char* szDestName, BOOL bMove)
{
OSErr err;
FSSpec srcSpec, destSpec, deleteSpec;
CHXString strSourcePath(szSrcName);
srcSpec = strSourcePath;
CHXString strDestFilePath(szDestName);
CHXString strDestFile;
strDestFile = (strrchr(szDestName, OS_SEPARATOR_CHAR)+1);
CHXString strDestPath(szDestName);
strDestPath = strDestPath.Left(strDestPath.ReverseFind(OS_SEPARATOR_CHAR));
destSpec = strDestPath;
if (noErr == FSSpecFromPathName(strDestFilePath, &deleteSpec))
{
err = ::FSpDelete(&deleteSpec); //delete existing file
}
// Note, FSpMoveRenameCompat doesn't move across volumes,
// so copy, then delete original (below) if a move has to be done??
if (bMove)
{
err = FSpMoveRenameCompat(&srcSpec, &destSpec, *((Str255*)strDestFile));
}
if (!bMove || (diffVolErr == err))
{
char* buffer = new char[0x40000];
err = FSpFileCopy(&srcSpec,&destSpec, (ConstStr255Param)strDestFile, buffer, 0x40000, FALSE);
delete buffer;
}
return (err == noErr);
}
/* Checks if directory is on CD or removable drive. */
BOOL
CHXDirectory::IsRemovable()
{
#ifdef _CARBON
if (EnsureValidPathSpec())
{
return CHXFileSpecUtils::IsDiskEjectable(m_dirSpec);
}
return FALSE;
#else
OSErr err;
HParamBlockRec hpb;
DrvQElPtr queueElPtr;
QHdrPtr queueHeader;
Ptr p;
if (EnsureValidPathSpec())
{
hpb.volumeParam.ioVRefNum = m_dirSpec.vRefNum;
hpb.volumeParam.ioNamePtr = NULL;
hpb.volumeParam.ioVolIndex = 0; // use vRefNum only
err = PBHGetVInfoSync(&hpb);
check_noerr(err);
if (err != noErr) return false;
// check the flag bits in the drive queue (from Technote FL 530)
queueHeader = GetDrvQHdr();
queueElPtr = (DrvQElPtr) queueHeader->qHead;
while (queueElPtr != nil)
{
if (queueElPtr->dQDrive == hpb.volumeParam.ioVDrvInfo)
{
p = (Ptr) queueElPtr;
p -= 3; /* to get to the byte with eject info */
if ((*p) & 8) return false; // non-ejectable
else return true; // ejectable
}
queueElPtr = (DrvQElPtr) queueElPtr->qLink;
}
}
return false; // we can't find this drive
#endif
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?