📄 filespecutils.cpp
字号:
res = HXR_FAIL; if (fileSpec.IsSet()) { FSSpec fileFSSpec; OSErr err; Boolean bIsFolder; Boolean bWasAliased; const Boolean kShouldResolveChains = true; fileFSSpec = fileSpec; err = ResolveAliasFileWithMountFlags(&fileFSSpec, kShouldResolveChains, &bIsFolder, &bWasAliased, kResolveAliasFileNoUI); check(err == noErr); if ((err == noErr) && !bIsFolder) { res = HXR_OK; if (bWasAliased) { fileSpec = fileFSSpec; } } else { // error occurred } } return res;}HX_RESULT CHXFileSpecUtils::ResolveDirSpecifierAlias(CHXDirSpecifier& dirSpec){ HX_RESULT res; res = HXR_FAIL; if (dirSpec.IsSet()) { FSSpec dirFSSpec; OSErr err; Boolean bIsFolder; Boolean bWasAliased; const Boolean kShouldResolveChains = true; dirFSSpec = dirSpec; err = ResolveAliasFileWithMountFlags(&dirFSSpec, kShouldResolveChains, &bIsFolder, &bWasAliased, kResolveAliasFileNoUI); if ((err == noErr) && bIsFolder) { res = HXR_OK; if (bWasAliased) { dirSpec = dirFSSpec; } } else { // error occurred } } return res;}// ------------------------------------------------------------------------------------//// MoveFileToTrash// MoveFolderToTrash// MoveFileToFolderWithRenaming// MoveFolderToFolderWithRenaming//// ------------------------------------------------------------------------------------static HX_RESULT MoveToFolderWithRenamingInternal(const FSSpec* itemFSSpec, const CHXDirSpecifier& targetSpec, BOOL bDeleteIfCantMove);HX_RESULT CHXFileSpecUtils::MoveFileToTrash(const CHXFileSpecifier& fileSpec) { if (!CHXFileSpecUtils::FileExists(fileSpec)) return HXR_INVALID_PARAMETER; CHXDirSpecifier trashSpec; FSSpec itemFSSpec; itemFSSpec = fileSpec; trashSpec = CHXFileSpecUtils::MacFindFolder(itemFSSpec.vRefNum, kTrashFolderType); return MoveToFolderWithRenamingInternal(&itemFSSpec, trashSpec, TRUE);}HX_RESULT CHXFileSpecUtils::MoveFolderToTrash(const CHXDirSpecifier& dirSpec) { if (!CHXFileSpecUtils::DirectoryExists(dirSpec)) return HXR_INVALID_PARAMETER; CHXDirSpecifier trashSpec; FSSpec itemFSSpec; itemFSSpec = dirSpec; trashSpec = CHXFileSpecUtils::MacFindFolder(itemFSSpec.vRefNum, kTrashFolderType); return MoveToFolderWithRenamingInternal(&itemFSSpec, trashSpec, TRUE);}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; FSSpec itemFSSpec; itemFSSpec = fileSpec; cleanupSpec = CHXFileSpecUtils::MacFindFolder(itemFSSpec.vRefNum, kChewableItemsFolderType); return MoveToFolderWithRenamingInternal(&itemFSSpec, cleanupSpec, TRUE);}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; FSSpec itemFSSpec; itemFSSpec = dirSpec; cleanupSpec = CHXFileSpecUtils::MacFindFolder(itemFSSpec.vRefNum, kChewableItemsFolderType); return MoveToFolderWithRenamingInternal(&itemFSSpec, cleanupSpec, TRUE);}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; FSSpec fsSpec; fsSpec = fileSpec; return MoveToFolderWithRenamingInternal(&fsSpec, targetSpec, bDeleteIfCantMove);}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; FSSpec fsSpec; fsSpec = dirSpec; return MoveToFolderWithRenamingInternal(&fsSpec, targetSpec, bDeleteIfCantMove);}static HX_RESULT MoveToFolderWithRenamingInternal(const FSSpec* itemFSSpec, const CHXDirSpecifier& targetSpec, BOOL bDeleteIfCantMove) { check_nonnull(itemFSSpec); HX_RESULT pnres; OSErr err; FSSpec targetFSSpec; pnres = HXR_FAILED; // find the trash for the disk containing the file if (!targetSpec.IsSet()) { // targetSpec wasn't set, nowhere to move to if (bDeleteIfCantMove) { err = FSpDelete(itemFSSpec); if (err == noErr) { pnres = HXR_OK; } } } else { // targetSpec is set // // try to move the file to the target targetFSSpec = targetSpec; err = CatMove(itemFSSpec->vRefNum, itemFSSpec->parID, itemFSSpec->name, targetFSSpec.parID, targetFSSpec.name); if (err == noErr) { pnres = HXR_OK; } else if (err == dupFNErr) { // 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; strName.SetFromStr255(itemFSSpec->name); // make a template like "filename_N" strTemplate = strName + "_%-%-%"; specNewNamedFile = CHXFileSpecUtils::GetUniqueFileSpec(targetSpec, strName, strTemplate, "%-%-%"); err = FSpRename(itemFSSpec, (ConstStr255Param) specNewNamedFile.GetName()); if (err == noErr) { err = CatMove(itemFSSpec->vRefNum, itemFSSpec->parID, (ConstStr255Param) specNewNamedFile.GetName(), targetFSSpec.parID, targetFSSpec.name); if (err == noErr) { pnres = HXR_OK; } else if (err != noErr && bDeleteIfCantMove) { // couldn't move it; delete the renamed file err = HDelete(itemFSSpec->vRefNum, itemFSSpec->parID, (ConstStr255Param) specNewNamedFile.GetName()); if (err == noErr) { pnres = HXR_OK; } } else { // couldn't move it; change the name back err = FSpRename((FSSpec *) specNewNamedFile, itemFSSpec->name); } } else { // rename failed for some reason if (bDeleteIfCantMove) { err = FSpDelete(itemFSSpec); if (err == noErr) { pnres = HXR_OK; } } } } else { // catmove failed for some unknown reason, not a name conflict if (bDeleteIfCantMove) { err = FSpDelete(itemFSSpec); if (err == noErr) { pnres = HXR_OK; } } } } return pnres;}// ------------------------------------------------------------------------------------//// GetSystemTempDirectory//// ------------------------------------------------------------------------------------CHXDirSpecifier CHXFileSpecUtils::GetSystemTempDirectory(){ return CHXFileSpecUtils::MacFindFolder(kOnSystemDisk, 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){ // XXXSEH: Placeholder. check(!"GetAppDataDir doesn't find anyplace useful on the Mac"); // GR 3/19/02 What is supposed to go in the "app data dir"? // // We could make an appName folder in the users documents directory // with MacFindFolder(kUserDomain, kDocumentsFolderType), // but it's not normal for applications to hardcode that location for anything. // // The windows implementation finds someplace in the user directories, but this implementation doesn't. return GetCurrentApplicationDir();}#ifdef _DEBUGvoid CHXFileSpecUtils::TestMacFileSpecUtils(){}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -