macosplatformutils.cpp

来自「IBM的解析xml的工具Xerces的源代码」· C++ 代码 · 共 1,527 行 · 第 1/4 页

CPP
1,527
字号
// to using Xerces in a multithreaded environment. The memory allocator// under Mac OS 9, for instance, is not thread safe.// ---------------------------------------------------------------------------void*XMLPlatformUtils::makeMutex(){	if (gHasMPAPIs)	{		MPCriticalRegionID criticalRegion = NULL;		OSStatus status = MPCreateCriticalRegion(&criticalRegion);		return (status == noErr) ? (void*)(criticalRegion) : NULL;	}	else		return (void*)1;}voidXMLPlatformUtils::closeMutex(void* const mtxHandle){	if (gHasMPAPIs)	{		MPCriticalRegionID criticalRegion = reinterpret_cast<MPCriticalRegionID>(mtxHandle);		OSStatus status = MPDeleteCriticalRegion(criticalRegion);		status = noErr;	// ignore any error and zap compiler warning	}	else		;}voidXMLPlatformUtils::lockMutex(void* const mtxHandle){	if (gHasMPAPIs)	{		MPCriticalRegionID criticalRegion = reinterpret_cast<MPCriticalRegionID>(mtxHandle);		OSStatus status = MPEnterCriticalRegion(criticalRegion, kDurationForever);		status = noErr;	// ignore any error and zap compiler warning	}	else		;}voidXMLPlatformUtils::unlockMutex(void* const mtxHandle){	if (gHasMPAPIs)	{		MPCriticalRegionID criticalRegion = reinterpret_cast<MPCriticalRegionID>(mtxHandle);		OSStatus status = MPExitCriticalRegion(criticalRegion);		status = noErr;	// ignore any error and zap compiler warning	}	else		;}// ---------------------------------------------------------------------------//  Miscellaneous synchronization methods//// Atomic manipulation is implemented atop routines that were traditionally// part of DriverServices, but are now a part of Carbon.// ---------------------------------------------------------------------------void*XMLPlatformUtils::compareAndSwap(       void**      toFill                                 , const void* const newValue                                 , const void* const toCompare){    // Replace *toFill with newValue iff *toFill == toCompare,    // returning previous value of *toFill    Boolean success = CompareAndSwap(        reinterpret_cast<UInt32>(toCompare),        reinterpret_cast<UInt32>(newValue),        reinterpret_cast<UInt32*>(toFill));    return (success) ? const_cast<void*>(toCompare) : *toFill;}////	Atomic Increment and Decrement////	Apple's routines return the value as it was before the//	operation, while these routines want to return it as it//	is after. So we perform the translation before returning//	the value.//intXMLPlatformUtils::atomicIncrement(int &location){    return IncrementAtomic(reinterpret_cast<long*>(&location)) + 1;}intXMLPlatformUtils::atomicDecrement(int &location){    return DecrementAtomic(reinterpret_cast<long*>(&location)) - 1;}// ---------------------------------------------------------------------------//  XMLPlatformUtils: Private Static Methods// ---------------------------------------------------------------------------////  This method handles the MacOS basic init functions.//voidXMLPlatformUtils::platformInit(){	long value = 0;	//	Detect available functions		//  Check whether we're on OS X	gMacOSXOrBetter			= noErr == Gestalt(gestaltSystemVersion, &value)							  && value >= 0x00001000							  ;	    //	Look for file system services    if (noErr == Gestalt(gestaltFSAttr, &value))    {        gHasFSSpecAPIs		= (value & (1 << gestaltHasFSSpecCalls)) != 0;        gHasFS2TBAPIs		= (value & (1 << gestaltFSSupports2TBVols)) != 0;        gHasHFSPlusAPIs		= (value & (1 << gestaltHasHFSPlusAPIs)) != 0;        #if TARGET_API_MAC_CARBON        gHasFSPathAPIs		= ((void*)kUnresolvedCFragSymbolAddress != FSPathMakeRef);        #else        gHasFSPathAPIs		= false;        #endif        gPathAPIsUsePosixPaths = gHasFSPathAPIs								 && (value & (1 << gestaltFSUsesPOSIXPathsForConversion));    }	//	We require FSSpecs at a minimum    gFileSystemCompatible	= gHasFSSpecAPIs;	//	Determine which file system to use (posix or carbon file access)	//	If we're using Metrowerks MSL, we surely don't want posix paths,	//	as MSL doesn't use them.	#if __MSL__ && (__MSL__ < 0x08000 || _MSL_CARBON_FILE_APIS)	gUsePosixFiles			= false;	#else	gUsePosixFiles			= gMacOSXOrBetter;	#endif		//  Determine whether to use getcwd or not. We use it only if we're not using MSL,	//  and we're on a Mac OS X system.	#if __MSL__	gUseGETCWD				= false;	#else	gUseGETCWD				= gMacOSXOrBetter;	#endif    //	Look for MP	gHasMPAPIs				= MPLibraryIsLoaded();}////  This method handles the MacOS basic termination functions.//voidXMLPlatformUtils::platformTerm(){}// ---------------------------------------------------------------------------//  XMLPlatformUtils: Private Static Methods// ---------------------------------------------------------------------------////  This method is called by the platform independent part of this class//  during initialization. We have to create the type of net accessor that//  we want to use. If none, then just return zero.//XMLNetAccessor*XMLPlatformUtils::makeNetAccessor(){    //	The selection of NetAcessor is made through    //	the following preprocessor defines:    //    //	XML_USE_NETACCESSOR_URLACCESS		-- Use netaccessor based on URLAccess    //	XML_USE_NETACCESSOR_URLACCESSCF		-- Use netaccessor based on CFURLAccess (CoreFoundation based)    //	XML_USE_NETACCESSOR_NATIVE			-- In absence of above selections, chooses URLACCESSCF    //										   if targetting Carbon, and URLAccess otherwise    //    //	These choices are resolved at the ^^^top^^^ of this file.#if (defined(USE_URLACCESSCF))    //	Use the URLAccess code that relies only on CoreFoundation	return new MacOSURLAccessCF;#elif (defined(USE_URLACCESS))	//	Only try to use URLAccess if it's actually available	if (URLAccessAvailable())		return new MacOSURLAccess;#endif	//	No netaccessor available--we can live with it, but you won't	//	get net access.	return 0;}////  This method is called by the platform independent part of this class//  when client code asks to have one of the supported message sets loaded.//XMLMsgLoader*XMLPlatformUtils::loadAMsgSet(const XMLCh* const msgDomain){#if (defined(XML_USE_INMEMORY_MSGLOADER) || defined(XML_USE_INMEM_MESSAGELOADER))    return new InMemMsgLoader(msgDomain);#else    #error You must provide a message loader    return 0;#endif}////  This method is called very early in the bootstrapping process. This guy//  must create a transcoding service and return it. It cannot use any string//  methods, any transcoding services, throw any exceptions, etc... It just//  makes a transcoding service and returns it, or returns zero on failure.//XMLTransService*XMLPlatformUtils::makeTransService(){#if (defined(XML_USE_MACOS_UNICODECONVERTER) || defined(XML_USE_NATIVE_TRANSCODER))    if (MacOSUnicodeConverter::IsMacOSUnicodeConverterSupported())        return new MacOSUnicodeConverter;#else    #error You must provide a transcoding service implementation#endif    //	If we got here it's because we didn't detect the Mac OS    //	Unicode Converter or Text Encoding Converter routines    //	that we require to function properly. Xerces will not    //	survive this condition.    return NULL;}// ---------------------------------------------------------------------------//	Utility Functions// ---------------------------------------------------------------------------XMLCh*CopyUniCharsToXMLChs(const UniChar* src, XMLCh* dst, std::size_t charCount, std::size_t maxChars){	//	Ensure we don't step on anybody's toes	std::size_t cnt = std::min(charCount, maxChars);		//	Copy the characters. UniChar is unsigned, so we shouldn't have	//	any sign extension problems.	//	To allow copy within a identical range, we copy backwards,	//	since XMLCh (may be) larger than UniChar.	dst += cnt;	src += cnt;	for (; cnt > 0; --cnt)		*--dst = *--src;			return dst;}UniChar*CopyXMLChsToUniChars(const XMLCh* src, UniChar* dst, std::size_t charCount, std::size_t maxChars){	UniChar* dstBegin = dst;		//	Ensure we don't step on anybody's toes	std::size_t cnt = std::min(charCount, maxChars);		//	Copy the characters. XMLCh's will be truncated on copy to UniChar's.	//	To allow copy within a identical range, we copy forwards,	//	since XMLCh (may be) larger than UniChar.	for (; cnt > 0; --cnt)		*dst++ = *src++;			return dstBegin;}XMLCh*ConvertColonToSlash(XMLCh* p, std::size_t charCount){	XMLCh* start = p;	for (; charCount > 0; --charCount)	{		XMLCh c = *p;		if (c == ':')			*p++ = '/';		else			p++;	}	return start;}XMLCh*ConvertSlashToColon(XMLCh* p, std::size_t charCount){	XMLCh* start = p;	for (; charCount > 0; --charCount)	{		XMLCh c = *p;		if (c == '/')			*p++ = ':';		else			p++;	}	return start;}char*ConvertSlashToColon(char* p, std::size_t charCount){	char* start = p;	for (; charCount > 0; --charCount)	{		char c = *p;		if (c == '/')			*p++ = ':';		else			p++;	}	return start;}//	Factory method to make an appropriate subclass of XMLMacAbstractFile//	for our useXMLMacAbstractFile*XMLMakeMacFile(void){	XMLMacAbstractFile* result = NULL;		if (gUsePosixFiles)		result = new XMLMacPosixFile;	else		result = new XMLMacCarbonFile;			return result;}boolXMLParsePathToFSRef(const XMLCh* const pathName, FSRef& ref, MemoryManager* const manager){	bool result;		//	If FSPathMakeRef is available, we use it to parse the	//	path: this gives us "standard" path support under MacOS X.	//	Without this, our paths in that environment would always	//	have a volume name at their root...which would look	//	"normal" to Mac users, but not normal to unix users. Since	//	we're making "unix" paths, we'll stick with the unix	//	style paths. This also allows us to easilly take paths	//	off the command line.	//	//	FSPathMakeRef is available on Mac OS X and in CarbonLib 1.1	//	and greater. But on classic under CarbonLib, it expects paths	//	to contain ':' separators, for which we're not prepared. Since	//	this isn't a case where we need to use it, we drop back to the	//	classic case for this.			if (TARGET_API_MAC_CARBON && gHasFSPathAPIs && gPathAPIsUsePosixPaths)		result = XMLParsePathToFSRef_X(pathName, ref, manager);	else		result = XMLParsePathToFSRef_Classic(pathName, ref, manager);

⌨️ 快捷键说明

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