/* * 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: TandemPlatformUtils.cpp 191054 2005-06-17 02:56:35Z jberry $ */ // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- // XXX #include // XXX #include #include #include #include #include #include #include #include #include #include #include #include #include #if defined (XML_USE_ICU_MESSAGELOADER) #include #elif defined (XML_USE_ICONV_MESSAGELOADER) #include #else // use In-memory message loader #include #endif XERCES_CPP_NAMESPACE_BEGIN // --------------------------------------------------------------------------- // XMLPlatformUtils: Platform init method // --------------------------------------------------------------------------- void XMLPlatformUtils::platformInit() { } // // 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. // In our case, we use the ICU based message loader mechanism. // XMLMsgLoader* XMLPlatformUtils::loadAMsgSet(const XMLCh* const msgDomain) { XMLMsgLoader* retVal; try { #if defined (XML_USE_ICU_MESSAGELOADER) retVal = new (fgMemoryManager) ICUMsgLoader(msgDomain); #elif defined (XML_USE_ICONV_MESSAGELOADER) retVal = new (fgMemoryManager) MsgCatalogLoader(msgDomain); #else retVal = new (fgMemoryManager) InMemMsgLoader(msgDomain); #endif } catch(const OutOfMemoryException&) { throw; } catch(...) { panic(PanicHandler::Panic_CantLoadMsgDomain); } return retVal; } void XMLPlatformUtils::panic(const PanicHandler::PanicReasons reason) { fgUserPanicHandler? fgUserPanicHandler->panic(reason) : fgDefaultPanicHandler->panic(reason); } // --------------------------------------------------------------------------- // XMLPlatformUtils: File Methods // --------------------------------------------------------------------------- unsigned int XMLPlatformUtils::curFilePos(FileHandle theFile , MemoryManager* const manager) { // Get the current position int curPos = ftell( (FILE*)theFile); if (curPos == -1) throw XMLPlatformUtilsException("XMLPlatformUtils::curFilePos - Could not get current pos"); return (unsigned int)curPos; } void XMLPlatformUtils::closeFile(FileHandle theFile , MemoryManager* const manager) { if (fclose((FILE*)theFile)) throw XMLPlatformUtilsException("XMLPlatformUtils::closeFile - Could not close the file handle"); } unsigned int XMLPlatformUtils::fileSize(FileHandle theFile , MemoryManager* const manager) { // Get the current position long int curPos = ftell((FILE*)theFile); if (curPos == -1) throw XMLPlatformUtilsException("XMLPlatformUtils::fileSize - Could not get current pos"); // Seek to the end and save that value for return if (fseek( (FILE*)theFile, 0, SEEK_END) ) throw XMLPlatformUtilsException("XMLPlatformUtils::fileSize - Could not seek to end"); long int retVal = ftell( (FILE*)theFile); if (retVal == -1) throw XMLPlatformUtilsException("XMLPlatformUtils::fileSize - Could not get the file size"); // And put the pointer back if (fseek( (FILE*)theFile, curPos, SEEK_SET) ) throw XMLPlatformUtilsException("XMLPlatformUtils::fileSize - Could not seek back to original pos"); return (unsigned int)retVal; } FileHandle XMLPlatformUtils::openFile(const unsigned short* const fileName , MemoryManager* const manager) { const char* tmpFileName = XMLString::transcode(fileName, manager); ArrayJanitor tmpFileNameJan((char*)tmpFileName , manager); FileHandle retVal = (FILE*)fopen( tmpFileName , "rb" ); if (retVal == NULL) return 0; return retVal; } 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)) { throw XMLPlatformUtilsException("XMLPlatformUtils::readFileBuffer - Read failed"); } 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) ) throw XMLPlatformUtilsException("XMLPlatformUtils::resetFile - Could not seek to beginning"); } // --------------------------------------------------------------------------- // XMLPlatformUtils: File system methods // --------------------------------------------------------------------------- XMLCh* XMLPlatformUtils::getFullPath(const XMLCh* const srcPath, MemoryManager* const manager) { // // NOTE: THe path provided has always already been opened successfully, // so we know that its not some pathological freaky path. It comes in // in native format, and goes out as Unicode always // char* newSrc = XMLString::transcode(srcPath, fgMemoryManager); // Use a local buffer that is big enough for the largest legal path char* tmpPath = dirname((char*)newSrc); if (!tmpPath) { throw XMLPlatformUtilsException("XMLPlatformUtils::resetFile - Could not get the base path name"); } char* newXMLString = (char*) fgMemoryManager->allocate ( (strlen(tmpPath) +1) * sizeof(char) );//new char [strlen(tmpPath) +1]; ArrayJanitor newJanitor(newXMLString, fgMemoryManager); strcpy(newXMLString, tmpPath); strcat(newXMLString , "/"); // Return a copy of the path, in Unicode format return XMLString::transcode(newXMLString, manager); } bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck) { // Check for pathological case of empty path if (!toCheck[0]) return false; // // If it starts with a slash, then it cannot be relative. This covers // both something like "\Test\File.xml" and an NT Lan type remote path // that starts with a node like "\\MyNode\Test\File.xml". // if (toCheck[0] == XMLCh('/')) return false; // Else assume its a relative path return true; } XMLCh* XMLPlatformUtils::getCurrentDirectory() { /*** * REVISIT: * * To be implemented later ***/ XMLCh curDir[]={ chPeriod, chForwardSlash, chNull}; return getFullPath(curDir); } inline bool XMLPlatformUtils::isAnySlash(XMLCh c) { return ( chBackSlash == c || chForwardSlash == c); } // --------------------------------------------------------------------------- // XMLPlatformUtils: Timing Methods // --------------------------------------------------------------------------- unsigned long XMLPlatformUtils::getCurrentMillis() { timeb aTime; ftime(&aTime); return (unsigned long)(aTime.time*1000 + aTime.millitm); } #ifndef __TANDEM // ----------------------------------------------------------------------- // Mutex methods // ----------------------------------------------------------------------- typedef XMLHolder MutexHolderType; void XMLPlatformUtils::closeMutex(void* const mtxHandle) { if (mtxHandle != NULL) { MutexHolderType* const holder = MutexHolderType::castTo(mtxHandle); if (pthread_mutex_destroy(&holder->fInstance)) { delete holder; ThrowXMLwithMemMgr(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotDestroy, fgMemoryManager); } delete holder; } } void XMLPlatformUtils::lockMutex(void* const mtxHandle) { if (mtxHandle != NULL) { if (pthread_mutex_lock(&MutexHolderType::castTo(mtxHandle)->fInstance)) { panic(PanicHandler::Panic_MutexErr); } } } void* XMLPlatformUtils::makeMutex(MemoryManager* manager) { MutexHolderType* const holder = new (manager) MutexHolderType; if (pthread_mutex_init(&holder->fInstance, NULL)) { delete holder; panic(PanicHandler::Panic_MutexErr); } return holder; } void XMLPlatformUtils::unlockMutex(void* const mtxHandle) { if (mtxHandle != NULL) { if (pthread_mutex_unlock(&MutexHolderType::castTo(mtxHandle)->fInstance)) { panic(PanicHandler::Panic_MutexErr); } } } // ----------------------------------------------------------------------- // Miscellaneous synchronization methods // ----------------------------------------------------------------------- void* XMLPlatformUtils::compareAndSwap ( void** toFill , const void* const newValue , const void* const toCompare) { boolean_t boolVar = compare_and_swap((atomic_p)toFill, (int *)&toCompare, (int)newValue ); return (void *)toCompare; } int XMLPlatformUtils::atomicIncrement(int &location) { int retVal = fetch_and_add( (atomic_p)&location, 1); return retVal+1; } int XMLPlatformUtils::atomicDecrement(int &location) { int retVal = fetch_and_add( (atomic_p)&location, -1); return retVal-1; } FileHandle XMLPlatformUtils::openStdInHandle(MemoryManager* const manager) { return (FileHandle)fdopen(dup(0), "rb"); } #endif void XMLPlatformUtils::platformTerm() { // We don't have any termination requirements at this time } #include XERCES_CPP_NAMESPACE_END