HPPlatformUtils.cpp
上传用户:zhuqijet
上传日期:2013-06-25
资源大小:10074k
文件大小:21k
源码类别:

词法分析

开发平台:

Visual C++

  1. /*
  2.  * The Apache Software License, Version 1.1
  3.  *
  4.  * Copyright (c) 1999-2000 The Apache Software Foundation.  All rights
  5.  * reserved.
  6.  *
  7.  * Redistribution and use in source and binary forms, with or without
  8.  * modification, are permitted provided that the following conditions
  9.  * are met:
  10.  *
  11.  * 1. Redistributions of source code must retain the above copyright
  12.  *    notice, this list of conditions and the following disclaimer.
  13.  *
  14.  * 2. Redistributions in binary form must reproduce the above copyright
  15.  *    notice, this list of conditions and the following disclaimer in
  16.  *    the documentation and/or other materials provided with the
  17.  *    distribution.
  18.  *
  19.  * 3. The end-user documentation included with the redistribution,
  20.  *    if any, must include the following acknowledgment:
  21.  *       "This product includes software developed by the
  22.  *        Apache Software Foundation (http://www.apache.org/)."
  23.  *    Alternately, this acknowledgment may appear in the software itself,
  24.  *    if and wherever such third-party acknowledgments normally appear.
  25.  *
  26.  * 4. The names "Xerces" and "Apache Software Foundation" must
  27.  *    not be used to endorse or promote products derived from this
  28.  *    software without prior written permission. For written
  29.  *    permission, please contact apache@apache.org.
  30.  *
  31.  * 5. Products derived from this software may not be called "Apache",
  32.  *    nor may "Apache" appear in their name, without prior written
  33.  *    permission of the Apache Software Foundation.
  34.  *
  35.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
  36.  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  37.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  38.  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
  39.  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  40.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  41.  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
  42.  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  43.  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  44.  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  45.  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  46.  * SUCH DAMAGE.
  47.  * ====================================================================
  48.  *
  49.  * This software consists of voluntary contributions made by many
  50.  * individuals on behalf of the Apache Software Foundation, and was
  51.  * originally based on software copyright (c) 1999, International
  52.  * Business Machines, Inc., http://www.ibm.com .  For more information
  53.  * on the Apache Software Foundation, please see
  54.  * <http://www.apache.org/>.
  55.  */
  56. /*
  57.  * $Log: HPPlatformUtils.cpp,v $
  58.  * Revision 1.13  2003/05/15 18:37:48  knoaman
  59.  * Partial implementation of the configurable memory manager.
  60.  *
  61.  * Revision 1.12  2003/04/25 17:19:26  peiyongz
  62.  * throw exception if getcwd() fails
  63.  *
  64.  * Revision 1.11  2003/04/24 02:53:52  peiyongz
  65.  * Logical Path Resolution
  66.  *
  67.  * Revision 1.10  2003/03/09 16:53:55  peiyongz
  68.  * PanicHandler
  69.  *
  70.  * Revision 1.9  2002/12/02 19:17:00  tng
  71.  * [Bug 14723] Memory leak in atomicOpsMutex.  Patch from Adam Zell.
  72.  *
  73.  * Revision 1.8  2002/11/07 22:37:51  peiyongz
  74.  * build -miconv on hpux and linux
  75.  *
  76.  * Revision 1.7  2002/11/04 15:13:00  tng
  77.  * C++ Namespace Support.
  78.  *
  79.  * Revision 1.6  2002/07/15 21:52:48  peiyongz
  80.  * CouldNotWriteToFile
  81.  *
  82.  * Revision 1.5  2002/06/24 15:55:03  peiyongz
  83.  * Change from James Berry( jberry@criticalpath.com)
  84.  *
  85.  * Revision 1.4  2002/06/20 15:27:27  peiyongz
  86.  * Fix to compilation error
  87.  *
  88.  * Revision 1.2  2002/05/21 20:31:47  tng
  89.  * Minor update: Remove obsolete code
  90.  *
  91.  * Revision 1.1.1.1  2002/02/01 22:22:24  peiyongz
  92.  * sane_include
  93.  *
  94.  * Revision 1.17  2001/10/25 15:20:31  tng
  95.  * Need to guard with NO_APP_THREADS when destroying the mutex.
  96.  *
  97.  * Revision 1.16  2001/10/23 23:10:00  peiyongz
  98.  * [Bug#880] patch to PlatformUtils:init()/term() and related. from Mark Weaver
  99.  *
  100.  * Revision 1.15  2000/09/22 18:31:41  andyh
  101.  * HPUX PlatformUtils - Removed incorrect use of ArrayJanitor on a local array.
  102.  * Patch submitted by "Torbj鰎n B鋍kstr鰉" <torbjorn.backstrom@teleteknik.goteborg.se>
  103.  *
  104.  * Revision 1.14  2000/07/25 22:29:36  aruna1
  105.  * Char definitions in XMLUni moved to XMLUniDefs
  106.  *
  107.  * Revision 1.13  2000/03/24 00:16:00  aruna1
  108.  * Platform initialization taken care for both threaded and non-threaded environment
  109.  *
  110.  * Revision 1.12  2000/03/20 23:48:51  rahulj
  111.  * Added Socket based NetAccessor. This will enable one to
  112.  * use HTTP URL's for system id's. Default build options do
  113.  * not use this NetAccessor. Specify the '-n socket' option
  114.  * to 'runConfigure' to configure Xerces-C to use this new
  115.  * feature. The code works under Solaris 2.6, Linux, AIX
  116.  * and HPUX 11 with aCC.
  117.  * Todo's: enable proper error handling.
  118.  *
  119.  * Revision 1.11  2000/03/17 23:59:59  roddey
  120.  * Initial updates for two way transcoding support
  121.  *
  122.  * Revision 1.10  2000/03/02 21:10:35  abagchi
  123.  * Added empty function platformTerm()
  124.  *
  125.  * Revision 1.9  2000/03/02 20:42:40  abagchi
  126.  * Fixed typo in XMLExcepts
  127.  *
  128.  * Revision 1.8  2000/03/02 19:55:21  roddey
  129.  * This checkin includes many changes done while waiting for the
  130.  * 1.1.0 code to be finished. I can't list them all here, but a list is
  131.  * available elsewhere.
  132.  *
  133.  * Revision 1.7  2000/02/06 07:48:26  rahulj
  134.  * Year 2K copyright swat.
  135.  *
  136.  * Revision 1.6  2000/01/25 22:32:45  aruna1
  137.  * Updated panic information
  138.  *
  139.  * Revision 1.5  2000/01/20 20:37:55  abagchi
  140.  * Removed fgLibLocation and cleaned up ICU path related stuff
  141.  *
  142.  * Revision 1.4  2000/01/18 21:33:17  aruna1
  143.  * Changed getBasePath to getFullPath,
  144.  * added weavePath()
  145.  *
  146.  * Revision 1.3  1999/12/14 23:53:31  rahulj
  147.  * Removed the offending Ctrl-M's from the commit message
  148.  * logs which was giving packaging problems.
  149.  *
  150.  * PR:
  151.  * Obtained from:
  152.  * Submitted by:
  153.  * Reviewed by:
  154.  *
  155.  * Revision 1.2  1999/11/23 02:00:44  rahulj
  156.  * Code now works under HPUX 11. Tested inmemory message loader.
  157.  * Revamped makefiles. Builds with both DCE threads as well as pthread libraries.
  158.  *
  159.  * Revision 1.1.1.1  1999/11/09 01:07:05  twl
  160.  * Initial checkin
  161.  *
  162.  * Revision 1.3  1999/11/08 20:45:29  rahul
  163.  * Swat for adding in Product name and CVS comment log variable.
  164.  *
  165.  */
  166. // ---------------------------------------------------------------------------
  167. //  Includes
  168. // ---------------------------------------------------------------------------
  169. #if !defined(APP_NO_THREADS)
  170. #include    <pthread.h>
  171. #endif // APP_NO_THREADS
  172. #include    <xercesc/util/PlatformUtils.hpp>
  173. #include    <xercesc/util/RuntimeException.hpp>
  174. #include    <xercesc/util/Janitor.hpp>
  175. #include    <xercesc/util/Mutexes.hpp>
  176. #include    <dl.h>
  177. #include    <stdio.h>
  178. #include    <stdlib.h>
  179. #include    <errno.h>
  180. #include    <libgen.h>
  181. #include    <string.h>
  182. #include    <limits.h>
  183. #include    <unistd.h>
  184. #include    <xercesc/util/XMLString.hpp>
  185. #include    <xercesc/util/XMLUniDefs.hpp>
  186. #include    <xercesc/util/XMLUni.hpp>
  187. #include    <xercesc/util/PanicHandler.hpp>
  188. #if defined(XML_USE_ICU_TRANSCODER)
  189.     #include <xercesc/util/Transcoders/ICU/ICUTransService.hpp>
  190. #else
  191.     // Use native transcoder. Same as -DXML_USE_NATIVE_TRANSCODER
  192.     #include <xercesc/util/Transcoders/Iconv/IconvTransService.hpp>
  193. #endif
  194. #if defined(XML_USE_ICU_MESSAGELOADER)
  195.     #include <xercesc/util/MsgLoaders/ICU/ICUMsgLoader.hpp>
  196. #elif defined (XML_USE_ICONV_MESSAGELOADER)
  197.     #include <xercesc/util/MsgLoaders/MsgCatalog/MsgCatalogLoader.hpp>
  198. #else
  199.     // Same as -DXML_USE_INMEM_MESSAGELOADER
  200.     #include <xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.hpp>
  201. #endif
  202. #if defined (XML_USE_NETACCESSOR_SOCKET)
  203.     #include <xercesc/util/NetAccessors/Socket/SocketNetAccessor.hpp>
  204. #endif
  205. #if !defined(XML_HPUX_KAICC)
  206. #include    <sys/timeb.h>             // does not work with KAI compiler
  207. #endif
  208. XERCES_CPP_NAMESPACE_BEGIN
  209. // ---------------------------------------------------------------------------
  210. //  XMLPlatformUtils: Private Static Methods
  211. // ---------------------------------------------------------------------------
  212. //
  213. //  This method is called by the platform independent part of this class
  214. //  during initialization. We have to create the type of net accessor that
  215. //  we want to use.
  216. //
  217. XMLNetAccessor* XMLPlatformUtils::makeNetAccessor()
  218. {
  219. #if defined (XML_USE_NETACCESSOR_SOCKET)
  220.     return new SocketNetAccessor();
  221. #else
  222.     return 0;
  223. #endif
  224. }
  225. //
  226. //  This method is called by the platform independent part of this class
  227. //  when client code asks to have one of the supported message sets loaded.
  228. //  In our case, we use the ICU based message loader mechanism.
  229. //
  230. XMLMsgLoader* XMLPlatformUtils::loadAMsgSet(const XMLCh* const msgDomain)
  231. {
  232.     XMLMsgLoader* retVal;
  233.     try
  234.     {
  235. #if defined (XML_USE_ICU_MESSAGELOADER)
  236.         retVal = new ICUMsgLoader(msgDomain);
  237. #elif defined (XML_USE_ICONV_MESSAGELOADER)
  238.         retVal = new MsgCatalogLoader(msgDomain);
  239. #else
  240.         // same as -DXML_USE_INMEM_MESSAGELOADER
  241.         retVal = new InMemMsgLoader(msgDomain);
  242. #endif
  243.     }
  244.     catch(...)
  245.     {
  246.         panic(PanicHandler::Panic_CantLoadMsgDomain);
  247.     }
  248.     return retVal;
  249. }
  250. //
  251. //  This method is called very early in the bootstrapping process. This guy
  252. //  must create a transcoding service and return it. It cannot use any string
  253. //  methods, any transcoding services, throw any exceptions, etc... It just
  254. //  makes a transcoding service and returns it, or returns zero on failure.
  255. //
  256. XMLTransService* XMLPlatformUtils::makeTransService()
  257. {
  258. #if defined (XML_USE_ICU_TRANSCODER)
  259.     return new ICUTransService;
  260. #else
  261.     // Use native transcoding services.
  262.     // same as -DXML_USE_INMEM_MESSAGELOADER
  263.     return new IconvTransService;
  264. #endif
  265. } // XMLPlatformUtils::makeTransService
  266. // ---------------------------------------------------------------------------
  267. //  XMLPlatformUtils: The panic method
  268. // ---------------------------------------------------------------------------
  269. void XMLPlatformUtils::panic(const PanicHandler::PanicReasons reason)
  270. {
  271.     fgUserPanicHandler? fgUserPanicHandler->panic(reason) : fgDefaultPanicHandler->panic(reason);
  272. }
  273. // ---------------------------------------------------------------------------
  274. //  XMLPlatformUtils: File Methods
  275. // ---------------------------------------------------------------------------
  276. unsigned int XMLPlatformUtils::curFilePos(FileHandle theFile)
  277. {
  278.     // Get the current position
  279.     long  curPos = ftell((FILE*) theFile);
  280.     if (curPos == -1)
  281.         ThrowXML(XMLPlatformUtilsException,
  282.                  XMLExcepts::File_CouldNotGetCurPos);
  283.     return (unsigned int) curPos;
  284. }
  285. void XMLPlatformUtils::closeFile(FileHandle theFile)
  286. {
  287.     if (fclose((FILE*) theFile))
  288.         ThrowXML(XMLPlatformUtilsException,
  289.                  XMLExcepts::File_CouldNotCloseFile);
  290. }
  291. unsigned int XMLPlatformUtils::fileSize(FileHandle theFile)
  292. {
  293.     // Get the current position
  294.     long  int curPos = ftell((FILE*) theFile);
  295.     if (curPos == -1)
  296.     {
  297.         ThrowXML(XMLPlatformUtilsException,
  298.                  XMLExcepts::File_CouldNotGetCurPos);
  299.     }
  300.     // Seek to the end and save that value for return
  301.      if (fseek((FILE*) theFile, 0, SEEK_END))
  302.      {
  303.         ThrowXML(XMLPlatformUtilsException,
  304.                  XMLExcepts::File_CouldNotSeekToEnd);
  305.      }
  306.     long int retVal = ftell((FILE*) theFile);
  307.     if (retVal == -1)
  308.         ThrowXML(XMLPlatformUtilsException,
  309.                  XMLExcepts::File_CouldNotGetSize);
  310.     // And put the pointer back
  311.     if (fseek((FILE*) theFile, curPos, SEEK_SET))
  312.         ThrowXML(XMLPlatformUtilsException,
  313.                  XMLExcepts::File_CouldNotSeekToPos);
  314.     return (unsigned int) retVal;
  315. }
  316. FileHandle XMLPlatformUtils::openFile(const char* const fileName)
  317. {
  318.     FileHandle retVal = (FILE*) fopen(fileName , "rb");
  319.     return retVal;
  320. }
  321. FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName)
  322. {
  323.     char* tmpFileName = XMLString::transcode(fileName, fgMemoryManager);
  324.     FileHandle retVal = (FILE*) fopen(tmpFileName , "rb");
  325.     fgMemoryManager->deallocate(tmpFileName);//delete [] tmpFileName;
  326.     return retVal;
  327. }
  328. FileHandle XMLPlatformUtils::openFileToWrite(const XMLCh* const fileName)
  329. {
  330.     const char* tmpFileName = XMLString::transcode(fileName, fgMemoryManager);
  331.     ArrayJanitor<char> janText((char*)tmpFileName, fgMemoryManager);
  332.     return fopen( tmpFileName , "wb" );
  333. }
  334. FileHandle XMLPlatformUtils::openFileToWrite(const char* const fileName)
  335. {
  336.     return fopen( fileName , "wb" );
  337. }
  338. FileHandle XMLPlatformUtils::openStdInHandle()
  339. {
  340.     return (FileHandle) fdopen(dup(0), "rb");
  341. }
  342. unsigned int
  343. XMLPlatformUtils::readFileBuffer(       FileHandle      theFile
  344.                                 , const unsigned int    toRead
  345.                                 ,       XMLByte* const  toFill)
  346. {
  347.     size_t noOfItemsRead = fread((void*) toFill, 1, toRead, (FILE*)theFile);
  348.     if (ferror((FILE*)theFile))
  349.     {
  350.         ThrowXML(XMLPlatformUtilsException,
  351.                  XMLExcepts::File_CouldNotReadFromFile);
  352.     }
  353.     return (unsigned int) noOfItemsRead;
  354. }
  355. void
  356. XMLPlatformUtils::writeBufferToFile( FileHandle     const  theFile
  357.                                    , long                  toWrite
  358.                                    , const XMLByte* const  toFlush)
  359. {
  360.     if (!theFile        ||
  361.         (toWrite <= 0 ) ||
  362.         !toFlush         )
  363.         return;
  364.     const XMLByte* tmpFlush = (const XMLByte*) toFlush;
  365.     size_t bytesWritten = 0;
  366.     while (true)
  367.     {
  368.         bytesWritten=fwrite(tmpFlush, sizeof(XMLByte), toWrite, (FILE*)theFile);
  369.         if(ferror((FILE*)theFile))
  370.         {
  371.             ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotWriteToFile);
  372.         }
  373.         if (bytesWritten < toWrite) //incomplete write
  374.         {
  375.             tmpFlush+=bytesWritten;
  376.             toWrite-=bytesWritten;
  377.             bytesWritten=0;
  378.         }
  379.         else
  380.             return;
  381.     }
  382.     return;
  383. }
  384. void XMLPlatformUtils::resetFile(FileHandle theFile)
  385. {
  386.     // Seek to the start of the file
  387.     if (fseek((FILE*) theFile, 0, SEEK_SET))
  388.         ThrowXML(XMLPlatformUtilsException,
  389.                  XMLExcepts::File_CouldNotResetFile);
  390. }
  391. // ---------------------------------------------------------------------------
  392. //  XMLPlatformUtils: File system methods
  393. // ---------------------------------------------------------------------------
  394. XMLCh* XMLPlatformUtils::getFullPath(const XMLCh* const srcPath,
  395.                                      MemoryManager* const manager)
  396. {
  397.     //
  398.     //  NOTE: THe path provided has always already been opened successfully,
  399.     //  so we know that its not some pathological freaky path. It comes in
  400.     //  in native format, and goes out as Unicode always
  401.     //
  402.     char* newSrc = XMLString::transcode(srcPath, fgMemoryManager);
  403.     ArrayJanitor<char> janText(newSrc, fgMemoryManager);
  404.     // Use a local buffer that is big enough for the largest legal path
  405.     char absPath[PATH_MAX + 1];
  406.     //get the absolute path
  407.     char* retPath = realpath(newSrc, &absPath[0]);
  408.     if (!retPath)
  409.     {
  410.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetBasePathName);
  411.     }
  412.     return XMLString::transcode(absPath, manager);
  413. }
  414. bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
  415. {
  416.     // Check for pathological case of empty path
  417.     if (!toCheck[0])
  418.         return false;
  419.     //
  420.     //  If it starts with a slash, then it cannot be relative. This covers
  421.     //  both something like "TestFile.xml" and an NT Lan type remote path
  422.     //  that starts with a node like "\MyNodeTestFile.xml".
  423.     //
  424.     if (toCheck[0] == XMLCh('/'))
  425.         return false;
  426.     // Else assume its a relative path
  427.     return true;
  428. }
  429. XMLCh* XMLPlatformUtils::getCurrentDirectory(MemoryManager* const manager)
  430. {
  431.     char  dirBuf[PATH_MAX + 1];
  432.     char  *curDir = getcwd(&dirBuf[0], PATH_MAX + 1);
  433.     if (!curDir)
  434.     {
  435.         ThrowXML(XMLPlatformUtilsException,
  436.                  XMLExcepts::File_CouldNotGetBasePathName);
  437.     }
  438.     return XMLString::transcode(curDir, manager);
  439. }
  440. inline bool XMLPlatformUtils::isAnySlash(XMLCh c) 
  441. {
  442.     return ( chBackSlash == c || chForwardSlash == c);
  443. }
  444. // ---------------------------------------------------------------------------
  445. //  XMLPlatformUtils: Timing Methods
  446. // ---------------------------------------------------------------------------
  447. unsigned long XMLPlatformUtils::getCurrentMillis()
  448. {
  449. #if defined(XML_HPUX_KAICC)         // should be reimplemented by someone with
  450.                                     // HP/UX and KAI knowledge.
  451.     return (unsigned long) 0;
  452. #else
  453.     timeb aTime;
  454.     ftime(&aTime);
  455.     return (unsigned long)(aTime.time*1000 + aTime.millitm);
  456. #endif
  457. }
  458. // -----------------------------------------------------------------------
  459. //  Mutex methods
  460. // -----------------------------------------------------------------------
  461. #if !defined(APP_NO_THREADS)
  462. // ---------------------------------------------------------------------------
  463. //  XMLPlatformUtils: Platform init method
  464. // ---------------------------------------------------------------------------
  465. static XMLMutex atomicOpsMutex;
  466. void XMLPlatformUtils::platformInit()
  467. {
  468.     //
  469.     // The atomicOps mutex needs to be created early.
  470.     // Normally, mutexes are created on first use, but there is a
  471.     // circular dependency between compareAndExchange() and
  472.     // mutex creation that must be broken.
  473.     if (atomicOpsMutex.fHandle == 0)
  474.         atomicOpsMutex.fHandle = XMLPlatformUtils::makeMutex();
  475. }
  476. void* XMLPlatformUtils::makeMutex()
  477. {
  478.     pthread_mutex_t* mutex = new pthread_mutex_t;
  479.     pthread_mutexattr_t*  attr = new pthread_mutexattr_t;
  480. #if defined(XML_USE_DCE)
  481.     pthread_mutexattr_create(attr);
  482.     pthread_mutexattr_setkind_np(attr, MUTEX_RECURSIVE_NP);
  483.     if (pthread_mutex_init(mutex, *attr))
  484.     {
  485.         ThrowXML(XMLPlatformUtilsException,
  486.                  XMLExcepts::Mutex_CouldNotCreate);
  487.     }
  488.     pthread_mutexattr_delete(attr);
  489. #else
  490.     pthread_mutexattr_init(attr);
  491.     pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
  492.     if (pthread_mutex_init(mutex, attr))
  493.     {
  494.         ThrowXML(XMLPlatformUtilsException,
  495.                  XMLExcepts::Mutex_CouldNotCreate);
  496.     }
  497.     pthread_mutexattr_destroy(attr);
  498. #endif
  499.     delete attr;
  500.     return (void*) mutex;
  501. }
  502. void XMLPlatformUtils::closeMutex(void* const mtxHandle)
  503. {
  504.     pthread_mutex_t* mutex = (pthread_mutex_t *) mtxHandle;
  505.     if (mutex != NULL)
  506.     {
  507.         if (pthread_mutex_destroy(mutex))
  508.             ThrowXML(XMLPlatformUtilsException,
  509.                   XMLExcepts::Mutex_CouldNotDestroy);
  510.         delete mutex;
  511.     }
  512. }
  513. void XMLPlatformUtils::lockMutex(void* const mtxHandle)
  514. {
  515.     if (mtxHandle != NULL)
  516.     {
  517.         if (pthread_mutex_lock((pthread_mutex_t *) mtxHandle))
  518.         {
  519.             ThrowXML(XMLPlatformUtilsException,
  520.                      XMLExcepts::Mutex_CouldNotLock);
  521.         }
  522.     }
  523. }
  524. void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
  525. {
  526.     if (mtxHandle != NULL)
  527.     {
  528.         if (pthread_mutex_unlock((pthread_mutex_t *) mtxHandle))
  529.         {
  530.             ThrowXML(XMLPlatformUtilsException,
  531.                      XMLExcepts::Mutex_CouldNotUnlock);
  532.         }
  533.     }
  534. }
  535. // -----------------------------------------------------------------------
  536. //  Miscellaneous synchronization methods
  537. // -----------------------------------------------------------------------
  538. void* XMLPlatformUtils::compareAndSwap ( void**      toFill,
  539.                                    const void* const newValue,
  540.                                    const void* const toCompare)
  541. {
  542.     XMLMutexLock  localLock(&atomicOpsMutex);
  543.     void *retVal = *toFill;
  544.     if (*toFill == toCompare)
  545.     {
  546.        *toFill = (void *)newValue;
  547.     }
  548.     return retVal;
  549. }
  550. int XMLPlatformUtils::atomicIncrement(int &location)
  551. {
  552.     XMLMutexLock localLock(&atomicOpsMutex);
  553.     return ++location;
  554. }
  555. int XMLPlatformUtils::atomicDecrement(int &location)
  556. {
  557.     XMLMutexLock localLock(&atomicOpsMutex);
  558.     return --location;
  559. }
  560. #else // #if !defined (APP_NO_THREADS)
  561. void XMLPlatformUtils::platformInit()
  562. {
  563. }
  564. void XMLPlatformUtils::closeMutex(void* const mtxHandle)
  565. {
  566. }
  567. void XMLPlatformUtils::lockMutex(void* const mtxHandle)
  568. {
  569. }
  570. void* XMLPlatformUtils::makeMutex()
  571. {
  572.     return 0;
  573. }
  574. void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
  575. {
  576. }
  577. void* XMLPlatformUtils::compareAndSwap (void**             toFill,
  578.                                         const void* const  newValue,
  579.                                         const void* const  toCompare)
  580. {
  581.     void *retVal = *toFill;
  582.     if (*toFill == toCompare)
  583.        *toFill = (void *)newValue;
  584.     return retVal;
  585. }
  586. int XMLPlatformUtils::atomicIncrement(int &location)
  587. {
  588.     return ++location;
  589. }
  590. int XMLPlatformUtils::atomicDecrement(int &location)
  591. {
  592.     return --location;
  593. }
  594. #endif // APP_NO_THREADS
  595. void XMLPlatformUtils::platformTerm()
  596. {
  597. #if !defined(APP_NO_THREADS)
  598.     // delete the mutex we created
  599. closeMutex(atomicOpsMutex.fHandle);
  600. atomicOpsMutex.fHandle = 0;
  601. #endif
  602. }
  603. #include <xercesc/util/LogicalPath.c>
  604. XERCES_CPP_NAMESPACE_END