filespecutils_carbon.cpp
来自「symbian 下的helix player源代码」· C++ 代码 · 共 1,621 行 · 第 1/3 页
CPP
1,621 行
HX_RESULT CHXFileSpecUtils::RemoveDir(const CHXDirSpecifier& dirSpec)
{
FSRef dirRef;
OSErr err;
require_return(dirSpec.IsSet(), HXR_INVALID_PARAMETER);
dirRef = (FSRef) dirSpec;
err = FSDeleteObject(&dirRef);
return err;
}
// ------------------------------------------------------------------------------------
//
// RemoveFile
//
// ------------------------------------------------------------------------------------
HX_RESULT CHXFileSpecUtils::RemoveFile(const CHXFileSpecifier& fileSpec)
{
FSRef fileRef;
OSErr err;
require_return(fileSpec.IsSet(), HXR_INVALID_PARAMETER);
fileRef = (FSRef) fileSpec;
err = FSDeleteObject(&fileRef);
return err;
}
// ------------------------------------------------------------------------------------
//
// MakeFileReadOnly/MakeFileNotReadOnly
//
// ------------------------------------------------------------------------------------
HX_RESULT CHXFileSpecUtils::MakeFileReadOnly(const CHXFileSpecifier& fileSpec)
{
FSSpec fileFSSpec;
OSErr err;
require_return(fileSpec.IsSet(), HXR_INVALID_PARAMETER);
fileFSSpec = (FSSpec) fileSpec;
err = FSpSetFLock(&fileFSSpec); // is there an FSRef variant for this?
if (err)
{
err = HXR_FAIL; // poor-man's OSErr-to-HX_RESULT conversion
}
return err;
}
HX_RESULT CHXFileSpecUtils::MakeFileNotReadOnly(const CHXFileSpecifier& fileSpec)
{
FSSpec fileFSSpec;
OSErr err;
require_return(fileSpec.IsSet(), HXR_INVALID_PARAMETER);
fileFSSpec = (FSSpec) fileSpec;
err = FSpRstFLock(&fileFSSpec); // is there an FSRef variant for this?
if (err)
{
err = HXR_FAIL; // poor-man's OSErr-to-HX_RESULT conversion
}
return err;
}
// ------------------------------------------------------------------------------------
//
// RenameMoveFile
//
// ------------------------------------------------------------------------------------
HX_RESULT CHXFileSpecUtils::RenameMoveFile(CHXFileSpecifier& fileSpec, const char* pNewNameIfAny,
const CHXDirSpecifier* pNewDirectoryIfAny)
{
HX_RESULT res;
CHXDirSpecifier fileDir, destDir;
CHXFileSpecifier interimFileSpec;
CHXString strNewName;
FSRef fileRef, interimRef, targetRef;
HFSUniStr255 newUniName;
BOOL bRenaming, bMoving, bRenamed, bMoved;
res = HXR_FAIL;
bRenamed = bMoved = FALSE;
require_return(fileSpec.IsSet(), HXR_INVALID_PARAMETER);
fileDir = fileSpec.GetParentDirectory();
if (pNewDirectoryIfAny)
{
destDir = *pNewDirectoryIfAny;
bMoving = (destDir != fileDir) ? TRUE : FALSE;
}
else
{
destDir = fileDir;
bMoving = FALSE;
}
if (pNewNameIfAny)
{
strNewName = pNewNameIfAny;
bRenaming = (strNewName != fileSpec.GetName()) ? TRUE : FALSE;
}
else
{
strNewName = fileSpec.GetName();
bRenaming = FALSE;
}
// ensure there's not already something there with this name
CHXFileSpecifier specTestDest = destDir.SpecifyChildFile(strNewName);
require( (!CHXFileSpecUtils::FileExists(specTestDest)), Bail);
// try renaming, then move, then rename if we couldn't originally
fileRef = (FSRef) fileSpec;
// rename
interimFileSpec = fileDir.SpecifyChildFile(strNewName); // new name in old directory
if (bRenaming && interimFileSpec.IsSet() && !CHXFileSpecUtils::FileExists(interimFileSpec))
{
newUniName = interimFileSpec.GetNameHFSUniStr255();
res = FSRenameUnicode(&fileRef, newUniName.length, newUniName.unicode,
kTextEncodingUnknown, &interimRef);
if (res == noErr)
{
bRenamed = TRUE;
fileRef = interimRef;
}
}
// move
if (bMoving)
{
targetRef = (FSRef) destDir;
res = FSMoveObject(&fileRef, &targetRef, &interimRef);
if (res == noErr)
{
bMoved = TRUE;
fileRef = interimRef;
}
}
// rename -- don't try to rename if we were supposed to move & didn't
if (bRenaming && !bRenamed && (bMoved || !bMoving))
{
interimFileSpec = destDir.SpecifyChildFile(strNewName); // new name in new directory
newUniName = interimFileSpec.GetNameHFSUniStr255();
res = FSRenameUnicode(&fileRef, newUniName.length, newUniName.unicode,
kTextEncodingUnknown, &interimRef);
if (res == noErr)
{
bRenamed = TRUE;
fileRef = interimRef;
}
}
if ((bRenamed || !bRenaming) && (bMoved || !bMoving))
{
fileSpec = fileRef;
res = HXR_OK;
}
else
{
res = HXR_FAIL;
}
Bail:
return res;
}
// ------------------------------------------------------------------------------------
//
// read/write files
//
// ------------------------------------------------------------------------------------
static HX_RESULT WriteFileInternal(CHXFileSpecifier& fileSpec, const void *pBuff, UInt32 length, BOOL bReplaceExistingFile);
static HX_RESULT ReadFileInternal(const CHXFileSpecifier& fileSpec, IHXBuffer*& pOutBuffer);
HX_RESULT CHXFileSpecUtils::WriteBinaryFile(CHXFileSpecifier& fileSpec, IHXBuffer* inBuffer, BOOL bReplaceExistingFile)
{
return WriteFileInternal(fileSpec, (void *) inBuffer->GetBuffer(), inBuffer->GetSize(), bReplaceExistingFile);
}
HX_RESULT CHXFileSpecUtils::WriteTextFile(CHXFileSpecifier& fileSpec, const CHXString& inStr, BOOL bReplaceExistingFile)
{
return WriteFileInternal(fileSpec, (const char *) inStr, inStr.GetLength(), bReplaceExistingFile);
}
HX_RESULT WriteFileInternal(CHXFileSpecifier& fileSpec, const void *pBuff, UInt32 length, BOOL bReplaceExistingFile)
{
check_nonnull(pBuff);
require_return(fileSpec.IsSet(), HXR_INVALID_PARAMETER);
long * kDontWantNodeID = NULL;
FSCatalogInfo * kDontSetCatInfo = NULL;
FSSpec * kDontWantFileFSSpec = NULL;
CHXDirSpecifier parentDirSpec;
Boolean targetIsDir;
Boolean targetAlreadyExists;
HFSUniStr255 uniName, dataForkName;
FSRef fileFSRef;
SInt16 forkRefNum;
OSErr err;
// if an item is there already, bail if we're in dont replace mode
// or if the item is a directory
fileFSRef = (FSRef) fileSpec;
targetAlreadyExists = (FSGetNodeID(&fileFSRef, kDontWantNodeID, &targetIsDir) == noErr);
// before we delete an old file, save the parent and filename info so we can create the new one
// (since the FSRef for the file in the old file spec becomes invalid once we delete the file)
parentDirSpec = fileSpec.GetParentDirectory();
uniName = fileSpec.GetNameHFSUniStr255();
if (targetAlreadyExists)
{
if (targetIsDir) return HXR_INVALID_PATH;
if (!bReplaceExistingFile) return HXR_FILE_EXISTS;
if (bReplaceExistingFile)
{
err = FSDeleteObject(&fileFSRef);
}
}
// create, open, write into the file, and close it
err = FSCreateFileUnicode((FSRef *) parentDirSpec, uniName.length, uniName.unicode,
kFSCatInfoNone, kDontSetCatInfo, &fileFSRef, kDontWantFileFSSpec);
if (err == noErr)
{
dataForkName.length = 0;
err = FSGetDataForkName(&dataForkName);
check_noerr(err);
err = FSOpenFork(&fileFSRef, dataForkName.length, dataForkName.unicode,
fsWrPerm, &forkRefNum);
if (err == noErr)
{
long ioBytes = length;
err = FSWrite(forkRefNum, &ioBytes, pBuff);
check_noerr(err);
FSCloseFork(forkRefNum);
}
if (err == noErr)
{
// update the file spec to point to the new file
fileSpec = fileFSRef;
}
else
{
// we failed to write it; delete it
(void) FSDeleteObject(&fileFSRef);
}
}
return (err == noErr ? HXR_OK : HXR_FAIL);
}
HX_RESULT CHXFileSpecUtils::ReadBinaryFile(const CHXFileSpecifier& fileSpec, IHXBuffer*& pOutBuffer)
{
return ReadFileInternal(fileSpec, pOutBuffer);
}
HX_RESULT CHXFileSpecUtils::ReadTextFile(const CHXFileSpecifier& fileSpec, CHXString& outStr)
{
HX_RESULT res;
IHXBuffer *pBuff = NULL;
res = ReadFileInternal(fileSpec, pBuff);
if (SUCCEEDED(res))
{
outStr = CHXString((const char *) pBuff->GetBuffer(), (int) pBuff->GetSize());
HX_RELEASE(pBuff);
}
return res;
}
HX_RESULT ReadFileInternal(const CHXFileSpecifier& fileSpec, IHXBuffer*& pOutBuffer)
{
require_return(fileSpec.IsSet(), HXR_INVALID_PARAMETER);
HFSUniStr255 dataForkName;
FSRef fileFSRef;
SInt16 forkRefNum = -1;
SInt64 forkSize;
OSStatus err;
pOutBuffer = new CHXBuffer();
require_nonnull_action(pOutBuffer, Bail, err = HXR_OUTOFMEMORY);
pOutBuffer->AddRef();
dataForkName.length = 0;
err = FSGetDataForkName(&dataForkName);
require_noerr(err, Bail);
fileFSRef = (FSRef) fileSpec;
err = FSOpenFork(&fileFSRef, dataForkName.length, dataForkName.unicode,
fsRdPerm, &forkRefNum);
require_noerr_quiet(err, Bail);
err = FSGetForkSize(forkRefNum, &forkSize);
require_noerr(err, Bail);
require_action(forkSize <= 0x07FFFFFFF, Bail, err = HXR_INVALID_PATH); // file is too big for a 32-bit signed length
err = pOutBuffer->SetSize((UInt32) forkSize);
require_noerr(err, Bail);
{
long ioBytes = forkSize;
err = FSRead(forkRefNum, &ioBytes, pOutBuffer->GetBuffer());
require_noerr(err, Bail);
(void) FSCloseFork(forkRefNum);
return HXR_OK;
}
Bail:
HX_RELEASE(pOutBuffer);
if (forkRefNum != -1) (void) FSCloseFork(forkRefNum);
return HXR_FAIL;
}
// ------------------------------------------------------------------------------------
//
// GetFileType
//
// ------------------------------------------------------------------------------------
FOURCC CHXFileSpecUtils::GetFileType(const CHXFileSpecifier& fileSpec)
{
FOURCC fileType;
OSErr err;
require_return(fileSpec.IsSet(), 0);
fileType = 0;
FSRef fileRef;
FinderInfo fndrInfo;
Boolean isDir;
ExtendedFinderInfo * kDontWantExtendedInfo = NULL;
fileRef = (FSRef) fileSpec;
err = FSGetFinderInfo(&fileRef, &fndrInfo, kDontWantExtendedInfo, &isDir);
if ((err == noErr) && !isDir)
{
fileType = fndrInfo.file.fileType;
}
return fileType;
}
// ------------------------------------------------------------------------------------
//
// MakeNameLegal
//
// returns TRUE if the name was changed
//
// ------------------------------------------------------------------------------------
BOOL CHXFileSpecUtils::MakeNameLegal(char *pszName)
{
const char *badChars = ":";
const char replacementChar = '-';
const long maxNameLength = 255;
long len, idx;
BOOL bChanged;
require_nonnull_return(pszName, FALSE);
bChanged = FALSE;
len = strlen(pszName);
// replace any illegal characters
for (idx = 0; idx < len; idx++)
{
if (strchr(badChars, pszName[idx]))
{
pszName[idx] = replacementChar;
bChanged = TRUE;
}
}
// be sure the name isn't too long
if (len > maxNameLength)
{
pszName[maxNameLength] = 0;
bChanged = TRUE;
}
return bChanged;
}
// ------------------------------------------------------------------------------------
//
// FindFolder
//
// ------------------------------------------------------------------------------------
CHXDirSpecifier CHXFileSpecUtils::MacFindFolder(short vRefNum, FolderType foldType)
{
CHXDirSpecifier foundDirSpec;
OSErr err;
FSRef folderRef;
err = ::FSFindFolder(vRefNum, foldType, kCreateFolder, &folderRef);
if (err == noErr)
{
foundDirSpec = folderRef;
}
return foundDirSpec;
}
CHXFileSpecifier CHXFileSpecUtils::SpecifyFileWithMacFindFolder(short vRefNum, FolderType foldType, const char *pszChildFile)
{
CHXDirSpecifier parentDir;
CHXFileSpecifier targetFile;
parentDir = CHXFileSpecUtils::MacFindFolder(vRefNum, foldType);
check(parentDir.IsSet());
if (CHXFileSpecUtils::DirectoryExists(parentDir))
{
targetFile = parentDir.SpecifyChildFile(pszChildFile);
}
return targetFile;
}
CHXDirSpecifier CHXFileSpecUtils::SpecifyFolderWithMacFindFolder(short vRefNum, FolderType foldType, const char *pszChildFolder)
{
CHXDirSpecifier parentDir;
CHXDirSpecifier targetDir;
parentDir = CHXFileSpecUtils::MacFindFolder(vRefNum, foldType);
check(parentDir.IsSet());
if (CHXFileSpecUtils::DirectoryExists(parentDir))
{
targetDir = parentDir.SpecifyChildDirectory(pszChildFolder);
}
return targetDir;
}
// ------------------------------------------------------------------------------------
//
// ResolveFileSpecifierAlias
// ResolveDirSpecifierAlias
//
// These resolve a file spec to an alias file in place
//
// ------------------------------------------------------------------------------------
HX_RESULT CHXFileSpecUtils::ResolveFileSpecifierAlias(CHXFileSpecifier& fileSpec)
{
HX_RESULT res;
res = HXR_FAIL;
// GR 7/8/02
// check that the file exists before resolving it in hopes of avoiding
// a mysterious crash on 10.1.5
if (CHXFileSpecUtils::FileExists(fileSpec))
{
FSRef fileRef;
OSErr err;
Boolean bIsFolder;
Boolean bWasAliased;
const Boolean kShouldResolveChains = true;
fileRef = (FSRef) fileSpec;
err = FSResolveAliasFileWithMountFlags(&fileRef, kShouldResolveChains,
&bIsFolder, &bWasAliased, kResolveAliasFileNoUI);
if ((err == noErr) && !bIsFolder)
{
res = HXR_OK;
if (bWasAliased)
{
fileSpec = fileRef;
}
}
else
{
// error occurred
}
}
return res;
}
HX_RESULT CHXFileSpecUtils::ResolveDirSpecifierAlias(CHXDirSpecifier& dirSpec)
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?