📄 filespec_carbon.cpp
字号:
// make a ref for the parent directory
err = FSMakeFSRef(spec.vRefNum, spec.parID, "\p", &parentRef);
check_noerr(err);
if (err == noErr)
{
CHXString strName;
strName.SetFromStr255(spec.name);
err = SetFromParentAndLeaf(parentRef, (const char *) strName, CFStringGetSystemEncoding());
}
}
}
else
{
err = paramErr;
}
UpdateDebugOnlyPath();
return err;
}
// ------------------------------------------------------------------------------------
OSErr CHXMacInternalSpec::SetFromAlias(AliasHandle alias)
{
OSErr err;
ClearSpec();
if (alias)
{
Boolean changed;
err = FSResolveAliasWithMountFlags(NULL, alias,
&mItemRef, &changed, kResolveAliasFileNoUI);
if (err == noErr)
{
mbRefSet = true;
}
else
{
// the item may not exist; try to make an FSSpec
// from the alias and set from that
FSSpec fsspec;
err = ResolveAliasWithMountFlags(NULL, alias,
&fsspec, &changed, kResolveAliasFileNoUI);
if (err == noErr || err == fnfErr)
{
SetFromFSSpec(fsspec);
}
}
}
UpdateDebugOnlyPath(); // for debugging
return err;
}
// ------------------------------------------------------------------------------------
OSErr CHXMacInternalSpec::SetFromURL(const char *pBuffer)
{
Boolean bSuccess;
CHXCFURL cfurl;
FSRef ref;
OSErr err;
// unset our specifier in case we fail
ClearSpec();
require_quiet(pBuffer != NULL && *pBuffer != '\0', CantMakeURL);
require_quiet(0 == ::strnicmp("file:", pBuffer, 5), CantMakeURL);
// make a CFURL from which we can get an FSRef
cfurl = pBuffer;
require(cfurl.IsSet(), CantMakeURL);
bSuccess = ::CFURLGetFSRef(cfurl, &ref);
if (bSuccess)
{
err = SetFromFSRef(ref);
}
else
{
// in case item doesn't exist, try using a pathname
CHXString strPath;
if (noErr == PathFromURL(pBuffer, strPath))
{
err = SetFromPath((const char *) strPath);
}
}
CantMakeURL:
return IsSet() ? HXR_OK : HXR_FAILED;
}
// ------------------------------------------------------------------------------------
void CHXMacInternalSpec::SplitPath(const char *pPath, char separator, CHXString& outParent, CHXString& outLeaf)
{
CHXString strFull(pPath);
INT32 offset;
// remove any trailing separator, in case this is a directory
if (strFull.Right(1) == separator)
{
strFull = strFull.Left(strFull.GetLength() - 1);
}
offset = strFull.ReverseFind(separator);
if (offset != -1)
{
outParent = strFull.Left(offset + 1); // +1 includes the separator
outLeaf = strFull.Mid(offset + 1);
}
else
{
outLeaf = strFull;
}
}
// ------------------------------------------------------------------------------------
CHXMacInternalSpec &CHXMacInternalSpec::operator=(CHXMacInternalSpec& other)
{
CopyInternalSpec(other);
return *this;
}
// ------------------------------------------------------------------------------------
BOOL CHXMacInternalSpec::operator==(const CHXMacInternalSpec &other)
{
OSErr err;
BOOL bSame = FALSE;
if (mbRefSet && other.mbRefSet)
{
err = FSCompareFSRefs(&mItemRef, &other.mItemRef);
if (err == noErr)
{
bSame = TRUE;
}
}
else if (mbParentAndLeafSet && other.mbParentAndLeafSet)
{
err = FSCompareFSRefs(&mParentAndLeaf.mItemParentRef, &other.mParentAndLeaf.mItemParentRef);
if (err == noErr)
{
if (mParentAndLeaf.mpLeafName->length == other.mParentAndLeaf.mpLeafName->length)
{
if (0 == memcmp(&mParentAndLeaf.mpLeafName->unicode, &other.mParentAndLeaf.mpLeafName->unicode,
mParentAndLeaf.mpLeafName->length * sizeof(UniChar)))
{
bSame = TRUE;
}
}
}
}
return bSame;
}
// ------------------------------------------------------------------------------------
BOOL CHXMacInternalSpec::operator!=(const CHXMacInternalSpec &other)
{
return !(*this == other);
}
// ------------------------------------------------------------------------------------
BOOL CHXMacInternalSpec::IsSet() const // object has been set to a file (which may or may not exist)
{
return (mbRefSet || mbParentAndLeafSet);
}
// ------------------------------------------------------------------------------------
void CHXMacInternalSpec::Unset()
{
ClearSpec();
}
// ------------------------------------------------------------------------------------
CHXString CHXMacInternalSpec::GetPersistentString() const
{
FSRef ref;
OSErr err;
CHXString strPersistent;
err = GetFSRef(ref);
if (err == noErr)
{
strPersistent = MakePersistentStringForRef(NULL, ref);
}
return strPersistent;
}
// ------------------------------------------------------------------------------------
CHXString CHXMacInternalSpec::GetRelativePersistentString(const CHXMacInternalSpec& fromFile) const
{
CHXString strResult;
FSRef fromFileRef, targetRef;
OSErr err;
err = GetFSRef(targetRef);
require_noerr(err, CantGetTargetRef);
err = fromFile.GetFSRef(fromFileRef);
require_noerr(err, CantGetFromFileRef);
strResult = MakePersistentStringForRef(&fromFileRef, targetRef);
return strResult;
CantGetFromFileRef:
CantGetTargetRef:
return "";
}
// ------------------------------------------------------------------------------------
CHXString CHXMacInternalSpec::MakePersistentStringForRef(const FSRef *pAnchorRef, const FSRef& targetRef)
{
HX_RESULT err;
CHXString str;
char* pBuff;
Handle hHexBuffer;
Size sHexBuffSize;
AliasHandle hAlias;
// be sure we have a target to specify
err = FSNewAlias(pAnchorRef, &targetRef, &hAlias);
require_noerr(err, CantMakeAlias);
// fill a temporary buffer with hex of the alias
hHexBuffer = NewHandle(0);
err = StuffHexHandle((Handle) hAlias, hHexBuffer);
require_noerr(err, CantStuff);
// copy our hex buffer to the string
sHexBuffSize = GetHandleSize(hHexBuffer);
pBuff = str.GetBuffer(sHexBuffSize + 1); // leave space for terminating null
BlockMoveData(*hHexBuffer, pBuff, sHexBuffSize);
pBuff[sHexBuffSize] = 0; // make it a C-string
str.ReleaseBuffer();
DisposeHandle(hHexBuffer);
DisposeHandle((Handle) hAlias);
#ifdef _DEBUG
{
// during debugging, we'll immediately check that the persistent specifier
// points to the same place as the actual target
CHXMacInternalSpec tempAliasTarget;
tempAliasTarget.SetFromPersistentString(str);
if (noErr != FSCompareFSRefs(&targetRef, &tempAliasTarget.mItemRef))
{
check(!"Persistent alias doesn't self-resolve");
}
}
#endif
return str;
// error handling
CantStuff:
DisposeHandle(hHexBuffer);
DisposeHandle((Handle) hAlias);
CantMakeAlias:
str = "";
return str;
}
// ------------------------------------------------------------------------------------
HX_RESULT CHXMacInternalSpec::SetFromPersistentString(const char *pBuffer)
{
HX_RESULT err;
Handle hHexBuffer;
Size sBufferSize;
AliasHandle hAlias;
check_nonnull(pBuffer);
sBufferSize = strlen(pBuffer);
// handle empty buffers
if (sBufferSize == 0)
{
ClearSpec();
return HXR_OK;
}
// allocate an empty handle to fill
hAlias = (AliasHandle) NewHandle(0);
// make a temporary buffer with the hex passed in
err = PtrToHand(pBuffer, &hHexBuffer, sBufferSize);
require_noerr(err, CantAllocateHexBuffer);
// turn the hex into our binary alias
err = UnstuffHexHandle(hHexBuffer, (Handle) hAlias);
DisposeHandle(hHexBuffer);
if (err == noErr)
{
SetFromAlias(hAlias);
}
else
{
// we couldn't interpret it as hex; try it as a full path
CHXString path(pBuffer);
// resolve 莊old
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -