📄 filespec_carbon.cpp
字号:
mbRefSet = true; } else { // if the item doesn't exist, we need to make a spec for the parent // and use the leaf name FSRef parentRef; // 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 handlingCantStuff: 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 + -