fullpathname.cp

来自「symbian 下的helix player源代码」· CP 代码 · 共 694 行 · 第 1/2 页

CP
694
字号
/* ***** BEGIN LICENSE BLOCK *****
 * Source last modified: $Id: fullpathname.cp,v 1.5.2.3 2004/07/09 01:47:27 hubbe Exp $
 * 
 * Portions Copyright (c) 1995-2004 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 (the "RPSL") available at
 * http://www.helixcommunity.org/content/rpsl unless you have licensed
 * the file under the current version of the RealNetworks Community
 * Source License (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.
 * 
 * Alternatively, the contents of this file may be used under the
 * terms of the GNU General Public License Version 2 or later (the
 * "GPL") in which case the provisions of the GPL are applicable
 * instead of those above. If you wish to allow use of your version of
 * this file only under the terms of the GPL, and not to allow others
 * to use your version of this file under the terms of either the RPSL
 * or RCSL, indicate your decision by deleting the provisions above
 * and replace them with the notice and other provisions required by
 * the GPL. If you do not delete the provisions above, a recipient may
 * use your version of this file under the terms of any one of the
 * RPSL, the RCSL or the GPL.
 * 
 * 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
	

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?