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

词法分析

开发平台:

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.  * 
  58.  *
  59.  */
  60. // ---------------------------------------------------------------------------
  61. //  Includes
  62. // ---------------------------------------------------------------------------
  63. #if !defined(APP_NO_THREADS)
  64. #include    <pthread.h>
  65. #endif
  66. /* #ifndef __USE_UNIX98
  67.     #error __USE_UNIX98 is not defined in your compile settings
  68. #endif */
  69. #include    <unistd.h>
  70. #include    <stdio.h>
  71. #include    <stdlib.h>
  72. #include    <errno.h>
  73. #include    <libgen.h>
  74. #include    <sys/time.h>
  75. #include    <string.h>
  76. #include    <strings.h>/* for strcasecmp & strncasecmp */
  77. #include    <wchar.h>  /* for win_t */
  78. #include    <xercesc/util/PlatformUtils.hpp>
  79. #include    <xercesc/util/RuntimeException.hpp>
  80. #include    <xercesc/util/Janitor.hpp>
  81. #include    <xercesc/util/Mutexes.hpp>
  82. #include    <xercesc/util/XMLString.hpp>
  83. #include    <xercesc/util/XMLUniDefs.hpp>
  84. #include    <xercesc/util/XMLUni.hpp>
  85. #include    <xercesc/util/PanicHandler.hpp>
  86. #if defined(XML_USE_ICU_TRANSCODER)
  87.     #include <xercesc/util/Transcoders/ICU/ICUTransService.hpp>
  88. #else
  89.     // Use native transcoder. Same as -DXML_USE_NATIVE_TRANSCODER
  90.     #include <xercesc/util/Transcoders/Iconv/IconvTransService.hpp>
  91. #endif
  92. #if defined(XML_USE_ICU_MESSAGELOADER)
  93.     #include <xercesc/util/MsgLoaders/ICU/ICUMsgLoader.hpp>
  94. #else
  95.     // Same as -DXML_USE_INMEM_MESSAGELOADER
  96.     #include <xercesc/util/MsgLoaders/InMemory/InMemMsgLoader.hpp>
  97. #endif
  98. #if defined (XML_USE_NETACCESSOR_SOCKET)
  99.     #include <xercesc/util/NetAccessors/Socket/SocketNetAccessor.hpp>
  100. #endif
  101. XERCES_CPP_NAMESPACE_BEGIN
  102. // ---------------------------------------------------------------------------
  103. //  Local Methods
  104. // ---------------------------------------------------------------------------
  105. static void WriteCharStr( FILE* stream, const char* const toWrite)
  106. {
  107.     if (fputs(toWrite, stream) == EOF)
  108.     {
  109.         ThrowXML(XMLPlatformUtilsException,
  110.                  XMLExcepts::Strm_StdErrWriteFailure);
  111.     }
  112. }
  113. static void WriteUStrStdErr( const XMLCh* const toWrite)
  114. {
  115.     char* tmpVal = XMLString::transcode(toWrite);
  116.     ArrayJanitor<char> janText(tmpVal);
  117.     if (fputs(tmpVal, stderr) == EOF)
  118.     {
  119.        ThrowXML(XMLPlatformUtilsException,
  120.                 XMLExcepts::Strm_StdErrWriteFailure);
  121.    }
  122. }
  123. static void WriteUStrStdOut( const XMLCh* const toWrite)
  124.  {
  125.     char* tmpVal = XMLString::transcode(toWrite);
  126.     ArrayJanitor<char> janText(tmpVal);
  127.     if (fputs(tmpVal, stdout) == EOF)
  128.     {
  129.         ThrowXML(XMLPlatformUtilsException,
  130.                  XMLExcepts::Strm_StdOutWriteFailure);
  131.     }
  132. }
  133. XMLNetAccessor* XMLPlatformUtils::makeNetAccessor()
  134. {
  135. #if defined (XML_USE_NETACCESSOR_SOCKET)
  136.     return new SocketNetAccessor();
  137. #else
  138.     return 0;
  139. #endif
  140. }
  141. // ---------------------------------------------------------------------------
  142. //  XMLPlatformUtils: Private Static Methods
  143. // ---------------------------------------------------------------------------
  144. //
  145. //  This method is called by the platform independent part of this class
  146. //  when client code asks to have one of the supported message sets loaded.
  147. //
  148. XMLMsgLoader* XMLPlatformUtils::loadAMsgSet(const XMLCh* const msgDomain)
  149. {
  150.     XMLMsgLoader* retVal;
  151.     try
  152.     {
  153. #if defined (XML_USE_ICU_MESSAGELOADER)
  154.         retVal = new ICUMsgLoader(msgDomain);
  155. #else
  156.         // same as -DXML_USE_INMEM_MESSAGELOADER
  157.         retVal = new InMemMsgLoader(msgDomain);
  158. #endif
  159.     }
  160.     catch(...)
  161.     {
  162.         panic(PanicHandler::Panic_CantLoadMsgDomain);
  163.     }
  164.     return retVal;
  165. }
  166. //
  167. //  This method is called very early in the bootstrapping process. This guy
  168. //  must create a transcoding service and return it. It cannot use any string
  169. //  methods, any transcoding services, throw any exceptions, etc... It just
  170. //  makes a transcoding service and returns it, or returns zero on failure.
  171. //
  172. XMLTransService* XMLPlatformUtils::makeTransService()
  173. {
  174. #if defined (XML_USE_ICU_TRANSCODER)
  175.     // Use ICU transcoding services.
  176.     // same as -DXML_USE_ICU_MESSAGELOADER
  177.     return new ICUTransService;
  178. #else
  179.     // Use native transcoding services.
  180.     // same as -DXML_USE_INMEM_MESSAGELOADER
  181.     return new IconvTransService;
  182. #endif
  183. }
  184. // ---------------------------------------------------------------------------
  185. //  XMLPlatformUtils: The panic method
  186. // ---------------------------------------------------------------------------
  187. void XMLPlatformUtils::panic(const PanicHandler::PanicReasons reason)
  188. {
  189.     fgUserPanicHandler? fgUserPanicHandler->panic(reason) : fgDefaultPanicHandler->panic(reason);
  190. }
  191. // ---------------------------------------------------------------------------
  192. //  XMLPlatformUtils: File Methods
  193. // ---------------------------------------------------------------------------
  194. unsigned int XMLPlatformUtils::curFilePos(FileHandle theFile)
  195. {
  196.     if (theFile == NULL)
  197.         ThrowXML(XMLPlatformUtilsException,
  198.                  XMLExcepts::CPtr_PointerIsZero);
  199.     int curPos = ftell( (FILE*)theFile);
  200.     if (curPos == -1)
  201.         ThrowXML(XMLPlatformUtilsException,
  202.                  XMLExcepts::File_CouldNotGetSize);
  203.     return (unsigned int)curPos;
  204. }
  205. void XMLPlatformUtils::closeFile(FileHandle theFile)
  206. {
  207.     if (theFile == NULL)
  208.         ThrowXML(XMLPlatformUtilsException,
  209.                  XMLExcepts::CPtr_PointerIsZero);
  210.     if (fclose((FILE*)theFile))
  211.         ThrowXML(XMLPlatformUtilsException,
  212.                  XMLExcepts::File_CouldNotCloseFile);
  213. }
  214. unsigned int XMLPlatformUtils::fileSize(FileHandle theFile)
  215. {
  216.     if (theFile == NULL)
  217.         ThrowXML(XMLPlatformUtilsException,
  218.                  XMLExcepts::CPtr_PointerIsZero);
  219.     // Get the current position
  220.     long  int curPos = ftell((FILE*) theFile);
  221.     if (curPos == -1)
  222.         ThrowXML(XMLPlatformUtilsException,
  223.                  XMLExcepts::File_CouldNotGetCurPos);
  224.     // Seek to the end and save that value for return
  225.      if (fseek((FILE*) theFile, 0, SEEK_END))
  226.         ThrowXML(XMLPlatformUtilsException,
  227.                  XMLExcepts::File_CouldNotSeekToEnd);
  228.     long int retVal = ftell((FILE*)theFile);
  229.     if (retVal == -1)
  230.         ThrowXML(XMLPlatformUtilsException,
  231.                  XMLExcepts::File_CouldNotSeekToEnd);
  232.     // And put the pointer back
  233.     if (fseek( (FILE*)theFile, curPos, SEEK_SET) )
  234.         ThrowXML(XMLPlatformUtilsException,
  235.                  XMLExcepts::File_CouldNotSeekToPos);
  236.     return (unsigned int)retVal;
  237. }
  238. FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName)
  239. {
  240.     if (fileName == NULL)
  241.         ThrowXML(XMLPlatformUtilsException,
  242.                  XMLExcepts::CPtr_PointerIsZero);
  243.     const char* tmpFileName = XMLString::transcode(fileName);
  244.     ArrayJanitor<char> janText((char*)tmpFileName);
  245.     FileHandle retVal = (FILE*)fopen( tmpFileName , "r+" );
  246.     if (retVal == NULL)
  247.         return 0;
  248.     return retVal;
  249. }
  250. FileHandle XMLPlatformUtils::openFile(const char* const fileName)
  251. {
  252.     if (fileName == NULL)
  253.         ThrowXML(XMLPlatformUtilsException,
  254.                  XMLExcepts::CPtr_PointerIsZero);
  255.     FileHandle retVal = (FILE*)fopen( fileName , "r+" );
  256.     if (retVal == NULL)
  257.         return 0;
  258.     return retVal;
  259. }
  260. FileHandle XMLPlatformUtils::openFileToWrite(const XMLCh* const fileName)
  261. {
  262.     if (fileName == NULL)
  263.         ThrowXML(XMLPlatformUtilsException,
  264.                  XMLExcepts::CPtr_PointerIsZero);
  265.     const char* tmpFileName = XMLString::transcode(fileName);
  266.     ArrayJanitor<char> janText((char*)tmpFileName);
  267.     FileHandle retVal = (FILE*)fopen( tmpFileName, "r+" );
  268.     if (retVal == NULL)
  269.         return 0;
  270.     return retVal;
  271. }
  272. FileHandle XMLPlatformUtils::openFileToWrite(const char* const fileName)
  273. {
  274.     if (fileName == NULL)
  275.         ThrowXML(XMLPlatformUtilsException,
  276.                  XMLExcepts::CPtr_PointerIsZero);
  277.     FileHandle retVal = (FILE*)fopen( fileName, "r+" );
  278.     if (retVal == NULL)
  279.         return 0;
  280.     return retVal;
  281. }
  282. FileHandle XMLPlatformUtils::openStdInHandle()
  283. {
  284.     int nfd = dup(0);
  285.     if (nfd == -1)
  286.         ThrowXML(XMLPlatformUtilsException,
  287.                 XMLExcepts::File_CouldNotDupHandle);
  288.     return (FileHandle)fdopen(dup(0), "r");
  289. }
  290. unsigned int
  291. XMLPlatformUtils::readFileBuffer( FileHandle          theFile
  292.                                 , const unsigned int  toRead
  293.                                 , XMLByte* const      toFill)
  294. {
  295.     if ( !theFile || !toFill )
  296.         ThrowXML(XMLPlatformUtilsException,
  297.                  XMLExcepts::CPtr_PointerIsZero);
  298.     if (toRead == 0)
  299.         return 0;
  300.     size_t noOfItemsRead = fread((void*) toFill, 1, toRead, (FILE*)theFile);
  301.     if(ferror((FILE*)theFile))
  302.     {
  303.         ThrowXML(XMLPlatformUtilsException,
  304.                  XMLExcepts::File_CouldNotReadFromFile);
  305.     }
  306.     return (unsigned int)noOfItemsRead;
  307. }
  308. void XMLPlatformUtils::writeBufferToFile( FileHandle     const  theFile
  309.                                         , long                  toWrite
  310.                                         , const XMLByte* const  toFlush )
  311. {
  312.     if ( !theFile || !toFlush )
  313.         ThrowXML(XMLPlatformUtilsException,
  314.                  XMLExcepts::CPtr_PointerIsZero);
  315.     if ( toWrite <= 0 )
  316.         return;
  317.     const XMLByte* tmpFlush = (const XMLByte*) toFlush;
  318.     size_t bytesWritten = 0;
  319.     while (true)
  320.     {
  321.         bytesWritten = fwrite(tmpFlush, sizeof(XMLByte), toWrite, (FILE*)theFile);
  322.         if(ferror((FILE*)theFile))
  323.         {
  324. #if 0
  325.             ThrowXML(XMLPlatformUtilsException,
  326.                      XMLExcepts::File_CouldNotWriteToFile);
  327. #else
  328.             ThrowXML(XMLPlatformUtilsException,
  329.                      XMLExcepts::File_CouldNotReadFromFile);
  330. #endif
  331.         }
  332.         if (bytesWritten < (size_t) toWrite) //incomplete write
  333.         {
  334.             tmpFlush += bytesWritten;
  335.             toWrite -= bytesWritten;
  336.             bytesWritten = 0;
  337.         }
  338.         else
  339.             return;
  340.     }
  341. }
  342. void XMLPlatformUtils::resetFile(FileHandle theFile)
  343. {
  344.     if (theFile == NULL)
  345.         ThrowXML(XMLPlatformUtilsException,
  346.                  XMLExcepts::CPtr_PointerIsZero);
  347.     // Seek to the start of the file
  348.     if (fseek((FILE*)theFile, 0, SEEK_SET))
  349.         ThrowXML(XMLPlatformUtilsException,
  350.                  XMLExcepts::File_CouldNotResetFile);
  351. }
  352. // ---------------------------------------------------------------------------
  353. //  XMLPlatformUtils: Timing Methods
  354. // ---------------------------------------------------------------------------
  355. unsigned long XMLPlatformUtils::getCurrentMillis()
  356. {
  357.     struct timeval t;
  358.     struct timezone tz;
  359.     gettimeofday(&t, &tz);
  360.     return (unsigned long)(t.tv_sec*1000 + t.tv_usec);
  361. }
  362. XMLCh* XMLPlatformUtils::getFullPath(const XMLCh* const srcPath)
  363. {
  364.     //
  365.     //  NOTE: THe path provided has always already been opened successfully,
  366.     //  so we know that its not some pathological freaky path. It comes in
  367.     //  in native format, and goes out as Unicode always
  368.     //
  369.     char* newSrc = XMLString::transcode(srcPath);
  370.     ArrayJanitor<char> janText(newSrc);
  371.     // Use a local buffer that is big enough for the largest legal path
  372.     char *absPath = new char[1024];
  373.     // get the absolute path 
  374.     char* retPath = realpath(newSrc, absPath);  
  375.     ArrayJanitor<char> janText2(retPath);
  376.     
  377.     if (!retPath)
  378.     {
  379.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetBasePathName);
  380.     }
  381.     return XMLString::transcode(absPath);
  382. }
  383. bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
  384. {
  385.     // Check for pathological case of empty path
  386.     if (!toCheck[0])
  387.         return false;
  388.     //
  389.     //  If it starts with a slash, then it cannot be relative. This covers
  390.     //  both something like "TestFile.xml" and an NT Lan type remote path
  391.     //  that starts with a node like "\MyNodeTestFile.xml".
  392.     //
  393.     if (toCheck[0] == XMLCh('/'))
  394.         return false;
  395.     // Else assume its a relative path
  396.     return true;
  397. }
  398. XMLCh* XMLPlatformUtils::getCurrentDirectory()
  399. {
  400.     char  dirBuf[PATH_MAX + 1];
  401.     char  *curDir = getcwd(&dirBuf[0], PATH_MAX + 1);
  402.     if (!curDir)
  403.     {
  404.         ThrowXML(XMLPlatformUtilsException,
  405.                  XMLExcepts::File_CouldNotGetBasePathName);
  406.     }
  407.     return XMLString::transcode(curDir);
  408. }
  409. inline bool XMLPlatformUtils::isAnySlash(XMLCh c)
  410. {
  411.     return ( chBackSlash == c || chForwardSlash == c);
  412. }
  413. // -----------------------------------------------------------------------
  414. //  Mutex methods
  415. // -----------------------------------------------------------------------
  416. #if !defined(APP_NO_THREADS)
  417. // ---------------------------------------------------------------------------
  418. //  XMLPlatformUtils: Platform init method
  419. // ---------------------------------------------------------------------------
  420. static XMLMutex atomicOpsMutex;
  421. void XMLPlatformUtils::platformInit()
  422. {
  423.     //
  424.     // The atomicOps mutex needs to be created early.
  425.     // Normally, mutexes are created on first use, but there is a
  426.     // circular dependency between compareAndExchange() and
  427.     // mutex creation that must be broken.
  428.     if (atomicOpsMutex.fHandle == 0)
  429.         atomicOpsMutex.fHandle = XMLPlatformUtils::makeMutex();
  430. }
  431. void* XMLPlatformUtils::makeMutex()
  432. {
  433.     pthread_mutex_t* mutex = new pthread_mutex_t;
  434.     pthread_mutexattr_t*  attr = new pthread_mutexattr_t;
  435.     pthread_mutexattr_init(attr);
  436.     pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
  437.     if (pthread_mutex_init(mutex, attr))
  438.     {
  439.         ThrowXML(XMLPlatformUtilsException,
  440.                  XMLExcepts::Mutex_CouldNotCreate);
  441.     }
  442.     pthread_mutexattr_destroy(attr);
  443.     delete attr;
  444.     return (void*)(mutex);
  445. }
  446. void XMLPlatformUtils::closeMutex(void* const mtxHandle)
  447. {
  448.     if (mtxHandle != NULL)
  449.     {
  450.         if (pthread_mutex_destroy((pthread_mutex_t*) mtxHandle))
  451.         {
  452.             ThrowXML(XMLPlatformUtilsException,
  453.                      XMLExcepts::Mutex_CouldNotDestroy);
  454.         }
  455.         delete (pthread_mutex_t*)mtxHandle;
  456.     }
  457. }
  458. void XMLPlatformUtils::lockMutex(void* const mtxHandle)
  459. {
  460.     if (mtxHandle != NULL)
  461.     {
  462.         if (pthread_mutex_lock((pthread_mutex_t*) mtxHandle))
  463.         {
  464.             ThrowXML(XMLPlatformUtilsException,
  465.                      XMLExcepts::Mutex_CouldNotLock);
  466.         }
  467.     }
  468. }
  469. void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
  470. {
  471.     if (mtxHandle != NULL)
  472.     {
  473.         if (pthread_mutex_unlock((pthread_mutex_t*) mtxHandle))
  474.         {
  475.             ThrowXML(XMLPlatformUtilsException,
  476.                      XMLExcepts::Mutex_CouldNotUnlock);
  477.         }
  478.     }
  479. }
  480. // -----------------------------------------------------------------------
  481. //  Miscellaneous synchronization methods
  482. // -----------------------------------------------------------------------
  483. void* XMLPlatformUtils::compareAndSwap(void**            toFill
  484.                                      , const void* const newValue
  485.                                      , const void* const toCompare)
  486. {
  487.     XMLMutexLock lockMutex(&atomicOpsMutex);
  488.     void *retVal = *toFill;
  489.     if (*toFill == toCompare)
  490.         *toFill = (void *)newValue;
  491.     return retVal;
  492. }
  493. int XMLPlatformUtils::atomicIncrement(int &location)
  494. {
  495.     XMLMutexLock localLock(&atomicOpsMutex);
  496.     return ++location;
  497. }
  498. int XMLPlatformUtils::atomicDecrement(int &location)
  499. {
  500.     XMLMutexLock localLock(&atomicOpsMutex);
  501.     return --location;
  502. }
  503. #else // #if !defined (APP_NO_THREADS)
  504. void XMLPlatformUtils::platformInit()
  505. {
  506. }
  507. void* XMLPlatformUtils::makeMutex()
  508. {
  509.         return 0;
  510. }
  511. void XMLPlatformUtils::closeMutex(void* const mtxHandle)
  512. {
  513. }
  514. void XMLPlatformUtils::lockMutex(void* const mtxHandle)
  515. {
  516. }
  517. void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
  518. {
  519. }
  520. void* XMLPlatformUtils::compareAndSwap (void**             toFill,
  521.                                         const void* const  newValue,
  522.                                         const void* const  toCompare)
  523. {
  524.     void *retVal = *toFill;
  525.     if (*toFill == toCompare)
  526.        *toFill = (void *)newValue;
  527.     return retVal;
  528. }
  529. int XMLPlatformUtils::atomicIncrement(int &location)
  530. {
  531.     return ++location;
  532. }
  533. int XMLPlatformUtils::atomicDecrement(int &location)
  534. {
  535.     return --location;
  536. }
  537. #endif // APP_NO_THREADS
  538. void XMLPlatformUtils::platformTerm()
  539. {
  540. #if !defined(APP_NO_THREADS)
  541.     // delete the mutex we created
  542.         closeMutex(atomicOpsMutex.fHandle);
  543.         atomicOpsMutex.fHandle = 0;
  544. #endif
  545. }
  546. #include <xercesc/util/LogicalPath.c>
  547. XERCES_CPP_NAMESPACE_END