filespecutils_carbon.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,621 行 · 第 1/3 页
CPP
1,621 行
{
HX_RESULT res;
res = HXR_FAIL;
if (dirSpec.IsSet())
{
FSRef dirRef;
OSErr err;
Boolean bIsFolder;
Boolean bWasAliased;
const Boolean kShouldResolveChains = true;
dirRef = dirSpec;
err = FSResolveAliasFileWithMountFlags(&dirRef, kShouldResolveChains,
&bIsFolder, &bWasAliased, kResolveAliasFileNoUI);
if ((err == noErr) && bIsFolder)
{
res = HXR_OK;
if (bWasAliased)
{
dirSpec = dirRef;
}
}
else
{
// error occurred
}
}
return res;
}
// ------------------------------------------------------------------------------------
//
// MoveFileToTrash
// MoveFolderToTrash
// MoveFileToFolderWithRenaming
// MoveFolderToFolderWithRenaming
//
// ------------------------------------------------------------------------------------
static HX_RESULT MoveToFolderWithRenamingInternal(const FSRef* itemRef, const CHXDirSpecifier& targetSpec, BOOL bDeleteIfCantMove, FSRef& outNewItemRef);
HX_RESULT CHXFileSpecUtils::MoveFileToTrash(const CHXFileSpecifier& fileSpec)
{
if (!CHXFileSpecUtils::FileExists(fileSpec)) return HXR_INVALID_PARAMETER;
CHXDirSpecifier trashSpec;
FSRef itemRef, newItemRef;
const BOOL bDeleteIfCantMove = TRUE;
itemRef = (FSRef) fileSpec;
trashSpec = CHXFileSpecUtils::MacFindFolder(fileSpec.GetVRefNum(), kTrashFolderType);
return MoveToFolderWithRenamingInternal(&itemRef, trashSpec, bDeleteIfCantMove, newItemRef);
}
HX_RESULT CHXFileSpecUtils::MoveFolderToTrash(const CHXDirSpecifier& dirSpec)
{
if (!CHXFileSpecUtils::DirectoryExists(dirSpec)) return HXR_INVALID_PARAMETER;
CHXDirSpecifier trashSpec;
FSRef itemRef, newItemRef;
const BOOL bDeleteIfCantMove = TRUE;
itemRef = (FSRef) dirSpec;
trashSpec = CHXFileSpecUtils::MacFindFolder(dirSpec.GetVRefNum(), kTrashFolderType);
return MoveToFolderWithRenamingInternal(&itemRef, trashSpec, bDeleteIfCantMove, newItemRef);
}
HX_RESULT CHXFileSpecUtils::MoveFileToCleanupAtStartup(const CHXFileSpecifier& fileSpec, BOOL bDeleteIfCantMove)
{
CHXFileSpecifier nonConstFileSpec(fileSpec);
return MoveFileToCleanupAtStartup(nonConstFileSpec, bDeleteIfCantMove);
}
HX_RESULT CHXFileSpecUtils::MoveFileToCleanupAtStartup(CHXFileSpecifier& fileSpec, BOOL bDeleteIfCantMove)
{
if (!CHXFileSpecUtils::FileExists(fileSpec)) return HXR_INVALID_PARAMETER;
CHXDirSpecifier cleanupSpec;
FSRef itemRef, newItemRef;
HX_RESULT res;
itemRef = (FSRef) fileSpec;
cleanupSpec = CHXFileSpecUtils::MacFindFolder(fileSpec.GetVRefNum(), kChewableItemsFolderType);
res = MoveToFolderWithRenamingInternal(&itemRef, cleanupSpec, bDeleteIfCantMove, newItemRef);
if (SUCCEEDED(res))
{
fileSpec = newItemRef;
}
return res;
}
HX_RESULT CHXFileSpecUtils::MoveFolderToCleanupAtStartup(const CHXDirSpecifier& dirSpec, BOOL bDeleteIfCantMove)
{
CHXDirSpecifier nonConstDirSpec(dirSpec);
return MoveFolderToCleanupAtStartup(nonConstDirSpec, bDeleteIfCantMove);
}
HX_RESULT CHXFileSpecUtils::MoveFolderToCleanupAtStartup(CHXDirSpecifier& dirSpec, BOOL bDeleteIfCantMove)
{
if (!CHXFileSpecUtils::DirectoryExists(dirSpec)) return HXR_INVALID_PARAMETER;
CHXDirSpecifier cleanupSpec;
FSRef itemRef, newItemRef;
HX_RESULT res;
itemRef = (FSRef) dirSpec;
cleanupSpec = CHXFileSpecUtils::MacFindFolder(dirSpec.GetVRefNum(), kChewableItemsFolderType);
res = MoveToFolderWithRenamingInternal(&itemRef, cleanupSpec, bDeleteIfCantMove, newItemRef);
if (SUCCEEDED(res))
{
dirSpec = newItemRef;
}
return res;
}
HX_RESULT CHXFileSpecUtils::MoveFileToFolderWithRenaming(CHXFileSpecifier& fileSpec, const CHXDirSpecifier& targetSpec, BOOL bDeleteIfCantMove)
{
if (!CHXFileSpecUtils::FileExists(fileSpec)) return HXR_INVALID_PARAMETER;
if (!CHXFileSpecUtils::DirectoryExists(targetSpec)) return HXR_INVALID_PARAMETER;
FSRef itemRef, newItemRef;
HX_RESULT res;
itemRef = (FSRef) fileSpec;
res = MoveToFolderWithRenamingInternal(&itemRef, targetSpec, bDeleteIfCantMove, newItemRef);
if (SUCCEEDED(res))
{
fileSpec = newItemRef;
}
return res;
}
HX_RESULT CHXFileSpecUtils::MoveFolderToFolderWithRenaming(CHXDirSpecifier& dirSpec, const CHXDirSpecifier& targetSpec, BOOL bDeleteIfCantMove)
{
if (!CHXFileSpecUtils::DirectoryExists(dirSpec)) return HXR_INVALID_PARAMETER;
if (!CHXFileSpecUtils::DirectoryExists(targetSpec)) return HXR_INVALID_PARAMETER;
FSRef itemRef, newItemRef;
HX_RESULT res;
itemRef = (FSRef) dirSpec;
res = MoveToFolderWithRenamingInternal(&itemRef, targetSpec, bDeleteIfCantMove, newItemRef);
if (SUCCEEDED(res))
{
dirSpec = newItemRef;
}
return res;
}
static HX_RESULT MoveToFolderWithRenamingInternal(const FSRef* itemRef, const CHXDirSpecifier& targetSpec, BOOL bDeleteIfCantMove, FSRef& outNewItemRef)
{
check_nonnull(itemRef);
HX_RESULT pnres;
OSErr err;
pnres = HXR_FAILED;
ZeroInit(&outNewItemRef);
if (!targetSpec.IsSet())
{
// targetSpec wasn't set, nowhere to move to
if (bDeleteIfCantMove)
{
err = FSDeleteObject(itemRef);
if (err == noErr)
{
pnres = HXR_OK;
}
}
}
else
{
// targetSpec is set
//
// try to move the file to the target
FSRef newItemRef, targetRef, newNameRef;
targetRef = (FSRef) targetSpec;
err = FSMoveObject(itemRef, &targetRef, &newItemRef);
if (err == noErr)
{
outNewItemRef = newItemRef;
pnres = HXR_OK;
}
else if (err != dupFNErr)
{
// catmove failed for some unknown reason, not a name conflict
if (bDeleteIfCantMove)
{
err = FSDeleteObject(itemRef);
if (err == noErr)
{
pnres = HXR_OK;
}
}
}
else
{
// there's a name conflict; find a unique name for the file we're moving in the
// target folder, rename it, and then move it again
CHXString strName, strTemplate;
CHXFileSpecifier specNewNamedFile;
HFSUniStr255 uniName, newUniName;
INT32 periodOffset;
const char* const kWildcard = "%-%-%";
err = FSGetFileDirName(itemRef, &uniName);
strName.SetFromHFSUniStr255(uniName, CFStringGetSystemEncoding()); // make a template like "filename_%-%-%"
periodOffset = strName.ReverseFind('.');
if (periodOffset != -1)
{
// put the _2 or whatever just before the extension
strTemplate = strName.Left(periodOffset);
strTemplate += "_";
strTemplate += kWildcard;
strTemplate += strName.Mid(periodOffset);
}
else
{
// put the _2 or whatever after the filename
strTemplate = strName + "_";
strTemplate += kWildcard;
}
specNewNamedFile = CHXFileSpecUtils::GetUniqueFileSpec(targetSpec, strName, strTemplate, kWildcard);
newUniName = specNewNamedFile.GetNameHFSUniStr255();
err = FSRenameUnicode(itemRef, newUniName.length, newUniName.unicode, kTextEncodingUnknown, &newNameRef);
if (err == noErr)
{
err = FSMoveObject(&newNameRef, &targetRef, &newItemRef);
if (err == noErr)
{
outNewItemRef = newItemRef;
pnres = HXR_OK;
}
else if (err != noErr && bDeleteIfCantMove)
{
// couldn't move it; delete the renamed file
err = FSDeleteObject(&newNameRef);
if (err == noErr)
{
pnres = HXR_OK;
}
}
else
{
// couldn't move it; change the name back
err = FSRenameUnicode(&newNameRef, uniName.length, uniName.unicode,
kTextEncodingUnknown, &newNameRef);
}
}
else
{
// rename failed for some reason
if (bDeleteIfCantMove)
{
// couldn't move it; delete the renamed file
err = FSDeleteObject(itemRef);
if (err == noErr)
{
pnres = HXR_OK;
}
}
}
}
}
return pnres;
}
// ------------------------------------------------------------------------------------
//
// GetSystemTempDirectory
//
// ------------------------------------------------------------------------------------
CHXDirSpecifier CHXFileSpecUtils::GetSystemTempDirectory()
{
return CHXFileSpecUtils::MacFindFolder(kOnAppropriateDisk, kChewableItemsFolderType);
}
// ------------------------------------------------------------------------------------
//
// GetUniqueFileSpec
// GetUniqueTempFileSpec
//
// ------------------------------------------------------------------------------------
static CHXFileSpecifier GetUniqueFileSpecInternal(const CHXDirSpecifier& locationSpec,
const char *pszNameFirst, const char *pszTemplate,
const char *pszWildcard, UINT32 nStartNum);
const UINT32 kNumWrapValue = 9999+1; // limit insertions to 4-digit numbers
CHXFileSpecifier CHXFileSpecUtils::GetUniqueFileSpec(const CHXDirSpecifier& locationSpec,
const char *pszNameFirst, const char *pszTemplate,
const char *pszWildcard)
{
return GetUniqueFileSpecInternal(locationSpec, pszNameFirst, pszTemplate, pszWildcard, 0);
}
CHXFileSpecifier CHXFileSpecUtils::GetUniqueTempFileSpec(const CHXDirSpecifier& locationSpec,
const char *pszTemplate, const char *pszWildcard)
{
CMultiplePrimeRandom rand(HX_GET_TICKCOUNT());
UINT32 num;
num = rand.GetRandomNumber();
num %= kNumWrapValue;
// skip 0, which means "don't substitute for the wildcard", and 1
if (num == 0 || num == 1) num = 2;
return GetUniqueFileSpecInternal(locationSpec, NULL, pszTemplate, pszWildcard, num);
}
static CHXFileSpecifier GetUniqueFileSpecInternal(const CHXDirSpecifier& locationSpec,
const char *pszNameFirst, const char *pszTemplate,
const char *pszWildcard, UINT32 nStartNum)
{
CHXFileSpecifier resultFileSpec;
require_return(locationSpec.IsSet(), resultFileSpec);
require_return(pszTemplate != NULL && pszWildcard != NULL, resultFileSpec);
require_return(pszNameFirst != NULL || nStartNum != 0, resultFileSpec);
CHXFileSpecifier testFileSpec;
CHXDirSpecifier testDirSpec;
CHXString strNumber;
CHXString strName;
UINT32 nCurrentNum;
nCurrentNum = nStartNum;
while (1)
{
// if the number is non-zero, make a string from the template;
// if the number is zero, user the initial name string
if (nCurrentNum == 0)
{
// replace the wildcard in the template with the number string
strName = pszNameFirst;
}
else
{
// replace the wildcard in the template with the number string
strNumber.Empty();
strNumber.AppendULONG(nCurrentNum);
strName = pszTemplate;
strName.FindAndReplace(pszWildcard, strNumber); // replace first wildcard with number string
}
// test if a file or directory exists with that name
testFileSpec = locationSpec.SpecifyChildFile(strName);
testDirSpec = locationSpec.SpecifyChildDirectory(strName);
if (CHXFileSpecUtils::FileExists(testFileSpec)
|| CHXFileSpecUtils::DirectoryExists(testDirSpec))
{
// an item already has that name, so increment & wrap the number
nCurrentNum++;
nCurrentNum %= kNumWrapValue;
// don't use 0 again, and skip 1 since "MyFile2.txt" logically follows "MyFile.txt"
if (nCurrentNum == 0 || nCurrentNum == 1)
{
nCurrentNum = 2;
}
// a quick sanity check
if (nCurrentNum == nStartNum)
{
check(!"GetUniqueFileSpecInternal number wrapped");
break;
}
}
else
{
// the name is unique
resultFileSpec = testFileSpec;
break;
}
} // while
return resultFileSpec;
}
CHXDirSpecifier
CHXFileSpecUtils::GetAppDataDir(const char* szAppName)
{
// we'll use a com.RealNetworks.data folder in user's prefs
CHXDirSpecifier targetDir;
CHXDirSpecifier prefsDir = CHXFileSpecUtils::MacFindFolder(kUserDomain, kPreferencesFolderType);
CHXDirSpecifier dataDir = prefsDir.SpecifyChildDirectory( "com.RealNetworks.data" );
if (!CHXFileSpecUtils::DirectoryExists(dataDir))
{
CHXFileSpecUtils::CreateDir(dataDir);
}
if (szAppName == NULL || *szAppName == 0)
{
targetDir = dataDir;
}
else
{
targetDir = dataDir.SpecifyChildDirectory(szAppName);
if (!CHXFileSpecUtils::DirectoryExists(targetDir))
{
CHXFileSpecUtils::CreateDir(targetDir);
}
}
HX_ASSERT(CHXFileSpecUtils::DirectoryExists(targetDir));
return targetDir;
}
#ifdef _DEBUG
void CHXFileSpecUtils::TestMacFileSpecUtils()
{
CHXString drive1Name = "Tenspot:";
CHXString drive2Name = "Sandy:";
CHXString driveEjectableLockedName = "Dev.CD Feb 01 TC Disk 1:";
CHXString driveServerName = "grobbins:";
CHXDirSpecifier dirServerSpec = drive2Name;
dirServerSpec = "Dev.CD Feb 01 TC Disk 1:Tool Chest:fake";
dirServerSpec = "Sandy:fake:";
//dirServerSpec = "grobbins:Sites:";
//dirServerSpec = "grobbins:Sites:fake";
CHXDirSpecifier dirServer2Spec = driveServerName;
CHXFileSpecifier file1Spec = "Tenspot:123456789a123456789b123456789c123456789d.png";
CHXFileSpecifier file2Spec = "Tenspot:123456789a123456789b123456789c123456789d:LVd";
CHXFileSpecifier fileFake1Spec = "Tenspot:123456789a123456789b123456789c123456789d:BOO";
CHXDirSpecifier dirFake1Spec = "Tenspot:123456789a123456789b123456789c123456789d:BOO Folder";
CHXFileSpecifier fromNameSpec = "RealPlayer.xSYM";
CHXFileSpecifier fromPartialPath = ":RealPlayer.xSYM";
CHXFileSpecifier fromBadName = "BOO";
HX_RESULT res;
INT64 spaceFree, spaceTotal, fileSize;
BOOL bFlag;
res = CHXFileSpecUtils::GetFreeSpaceOnDisk(drive1Name, spaceFree);
res = CHXFileSpecUtils::GetTotalSpaceOnDisk(drive1Name, spaceTotal);
check(spaceTotal > spaceFree);
bFlag = CHXFileSpecUtils::IsDiskEjectable(drive1Name);
check(!bFlag);
bFlag = CHXFileSpecUtils::IsDiskEjectable(driveEjectableLockedName);
check(bFlag);
bFlag = CHXFileSpecUtils::IsDiskWritable(drive1Name);
check(bFlag);
bFlag = CHXFileSpecUtils::IsDiskWritable(driveEjectableLockedName);
check(!bFlag);
bFlag = CHXFileSpecUtils::IsDiskLocal(drive1Name);
check(bFlag);
//bFlag = CHXFileSpecUtils::IsDiskLocal(driveServerName); this fails because HFS<-->FSRef fails on mounted vols
//check(!bFlag);
res = CHXFileSpecUtils::GetFileSize(file1Spec, fileSize);
res = CHXFileSpecUtils::GetFileSize(file2Spec, fileSize);
res = CHXFileSpecUtils::GetFileSize(fileFake1Spec, fileSize);
res = CHXFileSpecUtils::FileExists(file1Spec);
res = CHXFileSpecUtils::FileExists(file2Spec);
res = CHXFileSpecUtils::FileExists(fileFake1Spec);
bFlag = CHXFileSpecUtils::DirectoryExists(dirFake1Spec);
check(!bFlag);
res = CHXFileSpecUtils::CreateDir(dirFake1Spec);
bFlag = CHXFileSpecUtils::DirectoryExists(dirFake1Spec);
check(bFlag);
res = CHXFileSpecUtils::RemoveDir(dirFake1Spec);
bFlag = CHXFileSpecUtils::DirectoryExists(dirFake1Spec);
check(!bFlag);
CHXDirSpecifier ffDir = CHXFileSpecUtils::SpecifyFolderWithMacFindFolder(file1Spec.GetVRefNum(), kPreferencesFolderType, "Real Folder");
res = CHXFileSpecUtils::CreateDir(ffDir);
bFlag = CHXFileSpecUtils::DirectoryExists(ffDir);
check(bFlag);
res = CHXFileSpecUtils::MoveFolderToCleanupAtStartup(ffDir);
bFlag = CHXFileSpecUtils::DirectoryExists(ffDir);
check(!bFlag);
}
#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?