📄 fullpathname.cp
字号:
/* ***** BEGIN LICENSE BLOCK *****
* Version: RCSL 1.0/RPSL 1.0
*
* Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
*
* The contents of this file, and the files included with this file, are
* subject to the current version of the RealNetworks Public Source License
* Version 1.0 (the "RPSL") available at
* http://www.helixcommunity.org/content/rpsl unless you have licensed
* the file under the RealNetworks Community Source License Version 1.0
* (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
* in which case the RCSL will apply. You may also obtain the license terms
* directly from RealNetworks. You may not use this file except in
* compliance with the RPSL or, if you have a valid RCSL with RealNetworks
* applicable to this file, the RCSL. Please see the applicable RPSL or
* RCSL for the rights, obligations and limitations governing use of the
* contents of the file.
*
* This file is part of the Helix DNA Technology. RealNetworks is the
* developer of the Original Code and owns the copyrights in the portions
* it created.
*
* This file, and the files included with this file, is distributed and made
* available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
* FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
*
* Technology Compatibility Kit Test Suite(s) Location:
* http://www.helixcommunity.org/content/tck
*
* Contributor(s):
*
* ***** END LICENSE BLOCK ***** */
#include "platform/mac/FullPathName.h"
#if defined(_MAC_UNIX) || defined(_CARBON)
#include "platform/mac/MoreFilesX.h"
#include "platform/mac/cfwrappers.h"
#endif
/*
* Pascal string utilities
*/
#ifdef __cplusplus
extern "C" {
#endif
#if defined(_MAC_UNIX) || defined(_CARBON)
// prototypes for internal routines
static OSErr PathFromFSRefInternal(CFURLPathStyle pathStyle, const FSRef *ref, CHXString& fullPathName);
static OSErr FSRefFromPathInternal(CFURLPathStyle pathStyle, const char *path, FSRef *outRef);
static OSErr AlternateFSRefFromHFSPathInternal(const char* hfspath, FSRef* outRef);
static OSStatus URLFromPathInternal(CFURLPathStyle pathStyle, const char *pszPath, CHXString& strURL);
static OSStatus PathFromURLInternal(CFURLPathStyle pathStyle, const char *pszURL, CHXString& fullPathName);
OSStatus PathFromCFURLInternal(CFURLPathStyle pathStyle, CFURLRef urlRef, CHXString& fullPathName);
OSErr PathFromFSRefInternal(CFURLPathStyle pathStyle, const FSRef *ref, CHXString& fullPathName)
{
CHXCFString cfs;
CHXCFURL cfurl;
require_nonnull(ref, BadParam);
// make a CFURL from the FSRef
cfurl = ref;
require(cfurl.IsSet(), CantSetURLToRef);
return PathFromCFURLInternal(pathStyle, cfurl, fullPathName);
CantSetURLToRef:
BadParam:
return errFSBadFSRef;
}
OSErr FSRefFromPathInternal(CFURLPathStyle pathStyle, const char *path, FSRef *outRef)
{
CHXCFURL cfurl;
CHXCFString cfstr;
Boolean bSuccess;
CFStringEncoding encoding;
const Boolean kDirectoryDoesntMatter = false; // we could look at the last char of the string if it mattered
require_nonnull(outRef, BadOutputParam);
// copy the path to a CFString
encoding = (pathStyle == kCFURLHFSPathStyle ? CFStringGetSystemEncoding() : (CFStringEncoding) kCFStringEncodingUTF8);
cfstr = CHXCFString(path, encoding);
require(cfstr.IsSet(), CantMakeCFString);
// make a CFURL from the CFString
cfurl = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfstr, pathStyle, kDirectoryDoesntMatter);
require(cfurl.IsSet(), CantSetURL);
// get an FSRef from the URL; this will fail if the item doesn't really exist
bSuccess = CFURLGetFSRef(cfurl, outRef);
//if (!bSuccess) CFShow(cfurl);
if ((!bSuccess) && (pathStyle == kCFURLHFSPathStyle))
{
OSErr err = AlternateFSRefFromHFSPathInternal(path, outRef);
bSuccess = (err == noErr);
}
require_quiet(bSuccess, CantGetRefFromURL);
// now make an FSRef
return noErr;
CantGetRefFromURL:
CantSetURL:
CantMakeCFString:
BadOutputParam:
return paramErr;
}
// GR 7/23/02 blech...
// AlternateFSRefFromHFSPathInternal exists only because Mac OS X 10.1.5 and maybe later
// can't make CFURLs and then FSRefs from HFS paths that have volume names with high-8 bit
// characters in them.
OSErr AlternateFSRefFromHFSPathInternal(const char* hfspath, FSRef* outRef)
{
require_nonnull_return(outRef, paramErr);
require_nonnull_return(hfspath, paramErr);
OSErr err = -1;
// use FSMakeFSSpec for short paths, NewAliasMinimalFromFullPath for long paths
if (strlen(hfspath) < 256)
{
Str255 pascPath;
FSSpec spec;
c2pstrcpy(pascPath, hfspath);
err = FSMakeFSSpec(0, 0, pascPath, &spec);
if (err == noErr || err == fnfErr)
{
err = FSpMakeFSRef(&spec, outRef);
}
}
else
{
AliasHandle aliasH;
Boolean wasChanged;
err = NewAliasMinimalFromFullPath(strlen(hfspath), hfspath, "\p", "\p", &aliasH);
if (err == noErr)
{
err = FSResolveAliasWithMountFlags(nil, aliasH, outRef, &wasChanged, kResolveAliasFileNoUI);
DisposeHandle((Handle) aliasH);
}
}
return err;
}
OSStatus URLFromPathInternal(CFURLPathStyle pathStyle, const char *pszPath, CHXString& strURL)
{
CHXCFURL cfurl;
CHXCFString cfstr;
CFStringRef cfsNoRelease;
CFStringEncoding encoding;
const Boolean kDirectoryDoesntMatter = false; // we could look at the last char of the string if it mattered
// copy the path into a CFString
encoding = (pathStyle == kCFURLHFSPathStyle ? CFStringGetSystemEncoding() : (CFStringEncoding) kCFStringEncodingUTF8);
cfstr = CHXCFString(pszPath, encoding);
// make a CFURL from the CFString of the path
cfurl = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, cfstr, pathStyle, kDirectoryDoesntMatter);
require(cfurl.IsSet(), CantSetURL);
// get the URL as a CFString
cfsNoRelease = ::CFURLGetString(cfurl); // we are NOT supposed to release the CFString obtained here
require_nonnull(cfsNoRelease, CantGetURLString);
// copy the URL from the CFString into the output CHXString
strURL.SetFromCFString(cfsNoRelease, kCFStringEncodingUTF8);
return noErr;
CantGetURLString:
CantSetURL:
return paramErr;
}
OSStatus PathFromURLInternal(CFURLPathStyle pathStyle, const char *pszURL, CHXString& fullPathName)
{
CHXCFURL cfurl;
CHXCFString cfs;
// make a CFURL from the input url
cfurl = pszURL;
require(cfurl.IsSet(), CantMakeURL);
return PathFromCFURLInternal(pathStyle, cfurl, fullPathName);
CantMakeURL:
return kNSLBadURLSyntax;
}
OSStatus PathFromCFURLInternal(CFURLPathStyle pathStyle, CFURLRef urlRef, CHXString& fullPathName)
{
if (pathStyle == kCFURLHFSPathStyle)
{
CHXCFString cfs;
// get the HFS path as a CFString from the CFURL
cfs = CFURLCopyFileSystemPath (urlRef, pathStyle);
require(cfs.IsSet(), CantSetStringToURL);
// copy the path to the CHXString
fullPathName.SetFromCFString(cfs, CFStringGetSystemEncoding());
}
else
{
#if defined(_MAC_MACHO)
// POSIX paths are canonical UTF-8, as returned by CFURLGetFileSystemRepresentation
const Boolean kAbsolutePath = true;
UInt8* buff = (UInt8*) fullPathName.GetBuffer(1 + MAXPATHLEN);
Boolean succeeded = ::CFURLGetFileSystemRepresentation(urlRef, kAbsolutePath, buff, MAXPATHLEN);
fullPathName.ReleaseBuffer();
require(succeeded, CantSetStringToURL);
#else
HX_ASSERT(!"CFM builds shouldn't be getting posix paths!");
#endif
}
require_quiet(!fullPathName.IsEmpty(), URLCreationFailed);
return noErr;
URLCreationFailed:
CantSetStringToURL:
return kNSLBadURLSyntax;
}
#pragma mark -
// ref <--> path routines
OSErr PathFromFSRef(const FSRef *ref, CHXString& fullPathName)
{
#ifdef _MAC_CFM
return HFSPathFromFSRef(ref, fullPathName);
#else
return POSIXPathFromFSRef(ref, fullPathName);
#endif
}
OSErr FSRefFromPath(const char *path, FSRef *outRef)
{
#ifdef _MAC_CFM
return FSRefFromHFSPath(path, outRef);
#else
return FSRefFromPosixPath(path, outRef);
#endif
}
OSErr PathFromURL(const char *pszURL, CHXString& fullPathName)
{
#ifdef _MAC_CFM
return HFSPathFromURL(pszURL, fullPathName);
#else
return POSIXPathFromURL(pszURL, fullPathName);
#endif
}
OSErr URLFromPath(const char *pszPath, CHXString& strURL)
{
#ifdef _MAC_CFM
return URLFromHFSPath(pszPath, strURL);
#else
return URLFromPOSIXPath(pszPath, strURL);
#endif
}
OSErr HFSPathFromFSRef(const FSRef *pRef, CHXString& fullPathName)
{
OSErr err;
err = PathFromFSRefInternal(kCFURLHFSPathStyle, pRef, fullPathName);
if (err == noErr)
{
// be sure that directory path names end with ':'
OSErr err2;
Boolean isDir;
long *kDontWantNodeID = NULL;
err2 = FSGetNodeID(pRef, kDontWantNodeID, &isDir);
if ((err2 == noErr) && isDir)
{
if (fullPathName.Right(1) != ":")
{
fullPathName += ':';
}
}
}
return err;
}
OSErr FSRefFromHFSPath(const char *path, FSRef *outRef)
{
CHXString strPath;
OSErr err;
err = FullFromPartialHFSPath(path, strPath);
// now we have a full path name to convert
// GR 3/26/02
// ick, this fails for paths on mounted volumes due to CFURL bugs, and none
// of the alternatives I can find seem to work, either
err = FSRefFromPathInternal(kCFURLHFSPathStyle, (const char *) strPath, outRef);
return err;
}
OSStatus POSIXPathFromFSRef (const FSRef *pRef, CHXString& fullPathName)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -