/* * Copyright 1999-2000,2004 The Apache Software Foundation. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * $Id: OS2PlatformUtils.cpp 225512 2005-07-27 13:59:44Z cargilld $ */ // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #define INCL_DOSSEMAPHORES #define INCL_DOSERRORS #define INCL_DOSMISC #define INCL_DOSFILEMGR #include #include #include #include #include #include #include #include #include #include #include #if defined(XML_USE_ICU_TRANSCODER) #include #elif defined(XML_USE_ICONV_TRANSCODER) #include #else #error A transcoding service must be chosen #endif #if defined(XML_USE_INMEMORY_MSGLOADER) #include #else #error A message loading service must be chosen #endif #if defined(XML_IBMVAOS2) #include #endif #include XERCES_CPP_NAMESPACE_BEGIN // --------------------------------------------------------------------------- // XMLPlatformUtils: Platform init and term methods // --------------------------------------------------------------------------- void XMLPlatformUtils::platformInit() { } void XMLPlatformUtils::platformTerm() { // We don't have any termination requirements at this time } // --------------------------------------------------------------------------- // XMLPlatformUtils: File Methods // --------------------------------------------------------------------------- unsigned int XMLPlatformUtils::curFilePos(FileHandle theFile , MemoryManager* const manager) { // Get the current position int curPos = ftell( (FILE*)theFile); if (curPos == -1) ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos, manager); return (unsigned int)curPos; } void XMLPlatformUtils::closeFile(FileHandle theFile , MemoryManager* const manager) { if (fclose((FILE*)theFile)) ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile, manager); } unsigned int XMLPlatformUtils::fileSize(FileHandle theFile , MemoryManager* const manager) { return (unsigned int)filelength(fileno((FILE *)theFile)); } FileHandle XMLPlatformUtils::openFile(const char* const fileName , MemoryManager* const manager) { FileHandle retVal = (FILE*)fopen( fileName , "rb" ); if (retVal == NULL) return 0; return retVal; } FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName , MemoryManager* const manager) { const char* tmpFileName = XMLString::transcode(fileName, manager); ArrayJanitor janText((char*)tmpFileName, manager); FileHandle retVal = (FILE*)fopen( tmpFileName , "rb" ); if (retVal == NULL) return 0; return retVal; } FileHandle XMLPlatformUtils::openStdInHandle(MemoryManager* const manager) { return (FileHandle)fdopen(dup(0), "rb"); } unsigned int XMLPlatformUtils::readFileBuffer ( FileHandle theFile , const unsigned int toRead , XMLByte* const toFill , MemoryManager* const manager) { size_t noOfItemsRead = fread( (void*) toFill, 1, toRead, (FILE*)theFile); if(ferror((FILE*)theFile)) { ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile, manager); } return (unsigned int)noOfItemsRead; } void XMLPlatformUtils::resetFile(FileHandle theFile , MemoryManager* const manager) { // Seek to the start of the file if (fseek((FILE*)theFile, 0, SEEK_SET) ) ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::File_CouldNotResetFile, manager); } // ----------------------------------------------------------------------- // File system methods // ----------------------------------------------------------------------- XMLCh* XMLPlatformUtils::getFullPath(const XMLCh* const srcPath, MemoryManager* const manager) { // Transcode the incoming string char* tmpSrcPath = XMLString::transcode(srcPath, fgMemoryManager); ArrayJanitor janSrcPath(tmpSrcPath, fgMemoryManager); char tmpPath[CCHMAXPATH]; _fullpath(tmpPath, tmpSrcPath, CCHMAXPATH); return XMLString::transcode(tmpPath, manager); } bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck , MemoryManager* const manager) { // Check for pathological case of an empty path if (!toCheck[0]) return false; // // If it starts with a drive, then it cannot be relative. Note that // we checked the drive not being empty above, so worst case it's one // char long and the check of the 1st char will fail because it's really // a null character. // if (toCheck[1] == chColon) { if (((toCheck[0] >= chLatin_A) && (toCheck[0] <= chLatin_Z)) || ((toCheck[0] >= chLatin_a) && (toCheck[0] <= chLatin_z))) { return false; } } // // If it starts with a double slash, then it cannot be relative since // its a remote file. // if ((toCheck[0] == chBackSlash) && (toCheck[1] == chBackSlash)) return false; // Else assume its a relative path return true; } XMLCh* XMLPlatformUtils::getCurrentDirectory(MemoryManager* const manager) { /*** * REVISIT: * * To be implemented later ***/ XMLCh curDir[]={ chPeriod, chForwardSlash, chNull}; return getFullPath(curDir, manager); } inline bool XMLPlatformUtils::isAnySlash(XMLCh c) { return ( chBackSlash == c || chForwardSlash == c); } // ----------------------------------------------------------------------- // Timing methods // ----------------------------------------------------------------------- unsigned long XMLPlatformUtils::getCurrentMillis() { APIRET retr; ULONG timerBuf = 0; retr = DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, (PVOID) &timerBuf, sizeof( ULONG ) ); // if ( retr != NO_ERROR ) // return (timerBuf); return (timerBuf); } // ----------------------------------------------------------------------- // Mutex methods // ----------------------------------------------------------------------- void XMLPlatformUtils::closeMutex(void* const mtxHandle) { #if ! defined(APP_NO_THREADS) if (mtxHandle == NULL) return; if (DosCloseMutexSem( (HMTX)mtxHandle)) { ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotDestroy, fgMemoryManager); } #endif } void XMLPlatformUtils::lockMutex(void* const mtxHandle) { #if ! defined(APP_NO_THREADS) if (mtxHandle == NULL) return; if (DosRequestMutexSem( (HMTX)mtxHandle,(ULONG) SEM_INDEFINITE_WAIT) ) { panic(PanicHandler::Panic_MutexErr); } #endif } void* XMLPlatformUtils::makeMutex(MemoryManager*) { #if ! defined(APP_NO_THREADS) HMTX hRet; // Mutex Handle if (DosCreateMutexSem(NULL, &hRet, 0, FALSE)) panic(PanicHandler::Panic_MutexErr); return (void*)hRet; #else return 0; #endif } void XMLPlatformUtils::unlockMutex(void* const mtxHandle) { #if ! defined(APP_NO_THREADS) if (mtxHandle == NULL) return; if (DosReleaseMutexSem( (HMTX)mtxHandle)) { panic(PanicHandler::Panic_MutexErr); } #endif } // ----------------------------------------------------------------------- // Miscellaneous synchronization methods // ----------------------------------------------------------------------- void* XMLPlatformUtils::compareAndSwap ( void** toFill , const void* const newValue , const void* const toCompare ) { #if defined(XML_IBMVA4_OS2) return (void *)__smp_cmpxchg4((unsigned int *)toFill, (unsigned int)newValue, (unsigned int)toCompare); #elif defined(__GNUG__) char ret; long int readval; long int * p = (long **)toFill; __asm__ __volatile__ ("lock; cmpxchgl %3, %1\n\tsete %0" : "=q" (ret), "=m" (*p), "=a" (readval) : "r" (newValue), "m" (*p), "a" (toCompare) : "memory"); return (void *)(long)ret; #else void * retVal = *toFill; if (*toFill == toCompare) *toFill = (void *)newValue; return retVal; #endif } // ----------------------------------------------------------------------- // Atomic Increment and Decrement // // The function return value is positive if the result of the operation // was positive. Zero if the result of the operation was zero. Negative // if the result of the operation was negative. Except for the zero // case, the value returned may differ from the actual result of the // operation - only the sign and zero/nonzero state is guaranteed to be // correct. // ----------------------------------------------------------------------- int XMLPlatformUtils::atomicIncrement(int& location) { #if defined(XML_IBMVA4_OS2) return __smp_inc4(&location); #elif defined(__GNUG__) __asm__ __volatile__ ("lock; incl %0" : "=m" (location) : ); return location; #else return ++location; #endif } int XMLPlatformUtils::atomicDecrement(int& location) { #if defined(XML_IBMVA4_OS2) return __smp_dec4(&location); #elif defined(__GNUG__) __asm__ __volatile__ ("lock; decl %0" : "=m" (location) : ); return location; #else return --location; #endif } // --------------------------------------------------------------------------- // XMLPlatformUtils: The panic method // --------------------------------------------------------------------------- void XMLPlatformUtils::panic(const PanicHandler::PanicReasons reason) { fgUserPanicHandler? fgUserPanicHandler->panic(reason) : fgDefaultPanicHandler->panic(reason); } // ----------------------------------------------------------------------- // Private static methods. These are provided by the per-platform // implementation files. // ----------------------------------------------------------------------- XMLMsgLoader* XMLPlatformUtils::loadAMsgSet(const XMLCh* const msgDomain) { XMLMsgLoader* retVal; try { #if defined(XML_USE_INMEMORY_MSGLOADER) retVal = new (fgMemoryManager) InMemMsgLoader(msgDomain); #else #error You must provide a message loader return 0; #endif } catch(const OutOfMemoryException&) { throw; } catch(...) { panic(PanicHandler::Panic_CantLoadMsgDomain); } return retVal; } XMLNetAccessor* XMLPlatformUtils::makeNetAccessor() { return 0; } XMLTransService* XMLPlatformUtils::makeTransService() { #if defined(XML_USE_ICU_TRANSCODER) return new (fgMemoryManager) ICUTransService; #elif defined(XML_USE_ICONV_TRANSCODER) return new (fgMemoryManager) IconvTransService; #else return 0; #endif } #include XERCES_CPP_NAMESPACE_END