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 + -
显示快捷键?