AIXPlatformUtils.cpp
上传用户:huihehuasu
上传日期:2007-01-10
资源大小:6948k
文件大小:19k
源码类别:

xml/soap/webservice

开发平台:

C/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.  * $Id: AIXPlatformUtils.cpp,v 1.18 2001/07/03 16:51:25 tng Exp $
  58.  */
  59. // ---------------------------------------------------------------------------
  60. //  Includes
  61. // ---------------------------------------------------------------------------
  62. #ifndef APP_NO_THREADS
  63. #  if defined(XML_USE_DCE)
  64. #    include    <dce/pthread.h>
  65. #  else
  66. #    include    <pthread.h>
  67. #  endif // XML_USE_DCE
  68. #include    <sys/atomic_op.h>
  69. #endif
  70. #include    <stdio.h>
  71. #include    <stdlib.h>
  72. #include    <errno.h>
  73. #include    <libgen.h>
  74. #include    <sys/timeb.h>
  75. #include    <string.h>
  76. #include    <unistd.h>
  77. #include    <limits.h>
  78. #include    <sys/ldr.h>
  79. #include    <util/PlatformUtils.hpp>
  80. #include    <util/RuntimeException.hpp>
  81. #include    <util/Janitor.hpp>
  82. #include    <util/XMLString.hpp>
  83. #include    <util/XMLUniDefs.hpp>
  84. #if defined (XML_USE_ICU_TRANSCODER)
  85.     #include <util/Transcoders/ICU/ICUTransService.hpp>
  86. #else   // use native transcoder
  87.     #include <util/Transcoders/Iconv/IconvTransService.hpp>
  88. #endif
  89. #if defined (XML_USE_ICU_MESSAGELOADER)
  90.     #include <util/MsgLoaders/ICU/ICUMsgLoader.hpp>
  91. #elif defined (XML_USE_ICONV_MESSAGELOADER)
  92.     #include <util/MsgLoaders/MsgCatalog/MsgCatalogLoader.hpp>
  93. #else   // use In-memory message loader
  94.     #include <util/MsgLoaders/InMemory/InMemMsgLoader.hpp>   //hint for the user to include this file.
  95. #endif
  96. #if defined (XML_USE_NETACCESSOR_SOCKET)
  97.     #include <util/NetAccessors/Socket/SocketNetAccessor.hpp>
  98. #endif
  99. // ---------------------------------------------------------------------------
  100. //  Local Methods
  101. // ---------------------------------------------------------------------------
  102. static void WriteCharStr( FILE* stream, const char* const toWrite)
  103. {
  104.     if (fputs(toWrite, stream) == EOF)
  105.     {
  106.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::Strm_StdErrWriteFailure);
  107.     }
  108. }
  109. static void WriteUStrStdErr( const XMLCh* const toWrite)
  110. {
  111.     char* tmpVal = XMLString::transcode(toWrite);
  112.     ArrayJanitor<char> janText(tmpVal);
  113.     if (fputs(tmpVal, stderr) == EOF)
  114.     {
  115.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::Strm_StdErrWriteFailure);
  116.     }
  117. }
  118. static void WriteUStrStdOut( const XMLCh* const toWrite)
  119. {
  120.     char* tmpVal = XMLString::transcode(toWrite);
  121.     ArrayJanitor<char> janText(tmpVal);
  122.     if (fputs(tmpVal, stdout) == EOF)
  123.     {
  124.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::Strm_StdOutWriteFailure);
  125.     }
  126. }
  127. XMLNetAccessor* XMLPlatformUtils::makeNetAccessor()
  128. {
  129. #if defined (XML_USE_NETACCESSOR_SOCKET)
  130.     return new SocketNetAccessor();
  131. #else
  132.     return 0;
  133. #endif
  134. }
  135. // ---------------------------------------------------------------------------
  136. //  XMLPlatformUtils: Platform init method
  137. // ---------------------------------------------------------------------------
  138. void XMLPlatformUtils::platformInit()
  139. {
  140. }
  141. //
  142. //  This method is called very early in the bootstrapping process. This guy
  143. //  must create a transcoding service and return it. It cannot use any string
  144. //  methods, any transcoding services, throw any exceptions, etc... It just
  145. //  makes a transcoding service and returns it, or returns zero on failure.
  146. //
  147. XMLTransService* XMLPlatformUtils::makeTransService()
  148. #if defined (XML_USE_ICU_TRANSCODER)
  149. {
  150.     return new ICUTransService;
  151. }
  152. #else
  153. {
  154.     return new IconvTransService;
  155. }
  156. #endif
  157. //
  158. //  This method is called by the platform independent part of this class
  159. //  when client code asks to have one of the supported message sets loaded.
  160. //  In our case, we use the ICU based message loader mechanism.
  161. //
  162. XMLMsgLoader* XMLPlatformUtils::loadAMsgSet(const XMLCh* const msgDomain)
  163. {
  164.     XMLMsgLoader* retVal;
  165.     try
  166.     {
  167. #if defined (XML_USE_ICU_MESSAGELOADER)
  168.         retVal = new ICUMsgLoader(msgDomain);
  169. #elif defined (XML_USE_ICONV_MESSAGELOADER)
  170.         retVal = new MsgCatalogLoader(msgDomain);
  171. #else
  172.         retVal = new InMemMsgLoader(msgDomain);
  173. #endif
  174.     }
  175.     catch(...)
  176.     {
  177.          panic(XMLPlatformUtils::Panic_CantLoadMsgDomain);
  178.     }
  179.     return retVal;
  180. }
  181. // ---------------------------------------------------------------------------
  182. //  XMLPlatformUtils: The panic method
  183. // ---------------------------------------------------------------------------
  184. void XMLPlatformUtils::panic(const PanicReasons reason)
  185. {
  186.     const char* reasonStr = "Unknown reason";
  187.     if (reason == Panic_NoTransService)
  188.         reasonStr = "Could not load a transcoding service";
  189.     else if (reason == Panic_NoDefTranscoder)
  190.         reasonStr = "Could not load a local code page transcoder";
  191.     else if (reason == Panic_CantFindLib)
  192.         reasonStr = "Could not find the xerces-c DLL";
  193.     else if (reason == Panic_UnknownMsgDomain)
  194.         reasonStr = "Unknown message domain";
  195.     else if (reason == Panic_CantLoadMsgDomain)
  196.         reasonStr = "Cannot load message domain";
  197.     else if (reason == Panic_SynchronizationErr)
  198.         reasonStr = "Cannot synchronize system or mutex";
  199.     else if (reason == Panic_SystemInit)
  200.         reasonStr = "Cannot initialize the system or mutex";
  201.     fprintf(stderr, "%sn", reasonStr);
  202.     exit(-1);
  203. }
  204. // ---------------------------------------------------------------------------
  205. //  XMLPlatformUtils: File Methods
  206. // ---------------------------------------------------------------------------
  207. unsigned int XMLPlatformUtils::curFilePos(FileHandle theFile)
  208. {
  209.     // Get the current position
  210.     int curPos = ftell( (FILE*)theFile);
  211.     if (curPos == -1)
  212.     ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetSize);
  213.     return (unsigned int)curPos;
  214. }
  215. void XMLPlatformUtils::closeFile(FileHandle theFile)
  216. {
  217.     if (fclose((FILE*)theFile))
  218.     ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
  219. }
  220. unsigned int XMLPlatformUtils::fileSize(FileHandle theFile)
  221. {
  222.     // Get the current position
  223.     long  int curPos = ftell((FILE*)theFile);
  224.     if (curPos == -1)
  225.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
  226.     // Seek to the end and save that value for return
  227.      if (fseek( (FILE*)theFile, 0, SEEK_END) )
  228.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd);
  229.     long int retVal = ftell( (FILE*)theFile);
  230.     if (retVal == -1)
  231.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd);
  232.     // And put the pointer back
  233.     if (fseek( (FILE*)theFile, curPos, SEEK_SET) )
  234.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToPos);
  235.     return (unsigned int)retVal;
  236. }
  237. FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName)
  238. {
  239.     const char* tmpFileName = XMLString::transcode(fileName);
  240.     ArrayJanitor<char> janText((char*)tmpFileName);
  241.     FileHandle retVal = (FILE*)fopen( tmpFileName , "rb" );
  242.     if (retVal == NULL)
  243.         return 0;
  244.     return retVal;
  245. }
  246. FileHandle XMLPlatformUtils::openFile(const char* const fileName)
  247. {
  248.     FileHandle retVal = (FILE*)fopen( fileName , "rb" );
  249.     if (retVal == NULL)
  250.         return 0;
  251.     return retVal;
  252. }
  253. unsigned int
  254. XMLPlatformUtils::readFileBuffer(  FileHandle      theFile
  255.                                 , const unsigned int    toRead
  256.                                 , XMLByte* const  toFill)
  257. {
  258.     size_t noOfItemsRead = fread( (void*) toFill, 1, toRead, (FILE*)theFile);
  259.     if(ferror((FILE*)theFile))
  260.     {
  261.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile);
  262.     }
  263.     return (unsigned int)noOfItemsRead;
  264. }
  265. void XMLPlatformUtils::resetFile(FileHandle theFile)
  266. {
  267.     // Seek to the start of the file
  268.     if (fseek((FILE*)theFile, 0, SEEK_SET) )
  269.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotResetFile);
  270. }
  271. // ---------------------------------------------------------------------------
  272. //  XMLPlatformUtils: Timing Methods
  273. // ---------------------------------------------------------------------------
  274. unsigned long XMLPlatformUtils::getCurrentMillis()
  275. {
  276.     timeb aTime;
  277.     ftime(&aTime);
  278.     return (unsigned long)(aTime.time*1000 + aTime.millitm);
  279. }
  280. XMLCh* XMLPlatformUtils::getFullPath(const XMLCh* const srcPath)
  281. {
  282.     //
  283.     //  NOTE: THe path provided has always already been opened successfully,
  284.     //  so we know that its not some pathological freaky path. It comes in
  285.     //  in native format, and goes out as Unicode always
  286.     //
  287.     char* newSrc = XMLString::transcode(srcPath);
  288.     ArrayJanitor<char> janText(newSrc);
  289.     // Use a local buffer that is big enough for the largest legal path
  290.     char *absPath = new char[PATH_MAX];
  291.     ArrayJanitor<char> janText2(absPath);
  292.     //get the absolute path 
  293.     char* retPath = realpath(newSrc, absPath);  
  294.     
  295.     if (!retPath)
  296.     {
  297.         ThrowXML(XMLPlatformUtilsException,
  298.                  XMLExcepts::File_CouldNotGetBasePathName);
  299.     }
  300.     return XMLString::transcode(absPath);
  301. }
  302. bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
  303. {
  304.     // Check for pathological case of empty path
  305.     if (!toCheck[0])
  306.         return false;
  307.     //
  308.     //  If it starts with a slash, then it cannot be relative. This covers
  309.     //  both something like "TestFile.xml" and an NT Lan type remote path
  310.     //  that starts with a node like "\MyNodeTestFile.xml".
  311.     //
  312.     if (toCheck[0] == XMLCh('/'))
  313.         return false;
  314.     // Else assume its a relative path
  315.     return true;
  316. }
  317. XMLCh* XMLPlatformUtils::weavePaths
  318.     (
  319.         const   XMLCh* const    basePath
  320.         , const XMLCh* const    relativePath
  321.     )
  322. {
  323. // Create a buffer as large as both parts and empty it
  324.     XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
  325.                               + XMLString::stringLen(relativePath)
  326.                               + 2];
  327.     *tmpBuf = 0;
  328.     //
  329.     //  If we have no base path, then just take the relative path as
  330.     //  is.
  331.     //
  332.     if (!basePath)
  333.     {
  334.         XMLString::copyString(tmpBuf, relativePath);
  335.         return tmpBuf;
  336.     }
  337.     if (!*basePath)
  338.     {
  339.         XMLString::copyString(tmpBuf, relativePath);
  340.         return tmpBuf;
  341.     }
  342.     const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
  343.     if ((*basePtr != chForwardSlash)
  344.     &&  (*basePtr != chBackSlash))
  345.     {
  346.         while ((basePtr >= basePath)
  347.         &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
  348.         {
  349.             basePtr--;
  350.         }
  351.     }
  352.     // There is no relevant base path, so just take the relative part
  353.     if (basePtr < basePath)
  354.     {
  355.         XMLString::copyString(tmpBuf, relativePath);
  356.         return tmpBuf;
  357.     }
  358.     // After this, make sure the buffer gets handled if we exit early
  359.     ArrayJanitor<XMLCh> janBuf(tmpBuf);
  360.     //
  361.     //  We have some path part, so we need to check to see if we ahve to
  362.     //  weave any of the parts together.
  363.     //
  364.     const XMLCh* pathPtr = relativePath;
  365.     while (true)
  366.     {
  367.         // If it does not start with some period, then we are done
  368.         if (*pathPtr != chPeriod)
  369.             break;
  370.         unsigned int periodCount = 1;
  371.         pathPtr++;
  372.         if (*pathPtr == chPeriod)
  373.         {
  374.             pathPtr++;
  375.             periodCount++;
  376.         }
  377.         // Has to be followed by a  or / or the null to mean anything
  378.         if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
  379.         &&  *pathPtr)
  380.         {
  381.             break;
  382.         }
  383.         if (*pathPtr)
  384.             pathPtr++;
  385.         // If its one period, just eat it, else move backwards in the base
  386.         if (periodCount == 2)
  387.         {
  388.             basePtr--;
  389.             while ((basePtr >= basePath)
  390.             &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
  391.             {
  392.                 basePtr--;
  393.             }
  394.             // The base cannot provide enough levels, so its in error/
  395.             if (basePtr < basePath)
  396.                 ThrowXML(XMLPlatformUtilsException,
  397.                          XMLExcepts::File_BasePathUnderflow);
  398.         }
  399.     }
  400.     // Copy the base part up to the base pointer
  401.     XMLCh* bufPtr = tmpBuf;
  402.     const XMLCh* tmpPtr = basePath;
  403.     while (tmpPtr <= basePtr)
  404.         *bufPtr++ = *tmpPtr++;
  405.     // And then copy on the rest of our path
  406.     XMLString::copyString(bufPtr, pathPtr);
  407.     // Orphan the buffer and return it
  408.     janBuf.orphan();
  409.     return tmpBuf;
  410. }
  411. // -----------------------------------------------------------------------
  412. //  Mutex methods
  413. // -----------------------------------------------------------------------
  414. #ifndef APP_NO_THREADS
  415. void XMLPlatformUtils::closeMutex(void* const mtxHandle)
  416. {
  417.     if (mtxHandle == NULL)
  418.         return;
  419.     if (pthread_mutex_destroy( (pthread_mutex_t*)mtxHandle))
  420.     {
  421.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotDestroy);
  422.     }
  423.     if ( (pthread_mutex_t*)mtxHandle)
  424.         delete mtxHandle;
  425. }
  426. void XMLPlatformUtils::lockMutex(void* const mtxHandle)
  427. {
  428.     if (mtxHandle == NULL)
  429.         return;
  430.     if (pthread_mutex_lock( (pthread_mutex_t*)mtxHandle))
  431.     {
  432.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotLock);
  433.     }
  434. }
  435. void* XMLPlatformUtils::makeMutex()
  436. {
  437.     pthread_mutex_t* mutex = new pthread_mutex_t;
  438.     if (mutex ==  NULL)
  439.     {
  440.         ThrowXML(XMLPlatformUtilsException,
  441.                  XMLExcepts::Mutex_CouldNotCreate);
  442.     }
  443.     pthread_mutexattr_t*  attr = new pthread_mutexattr_t;
  444. #if defined(XML_USE_DCE)
  445.     pthread_mutexattr_create(attr);
  446.     pthread_mutexattr_setkind_np(attr, MUTEX_RECURSIVE_NP);
  447.     if (pthread_mutex_init(mutex, *attr))
  448.     {
  449.           ThrowXML(XMLPlatformUtilsException,
  450.                    XMLExcepts::Mutex_CouldNotCreate);
  451.     }
  452.     pthread_mutexattr_delete(attr);
  453. #else
  454.     pthread_mutexattr_init(attr);
  455.     pthread_mutexattr_setkind_np(attr, MUTEX_RECURSIVE_NP);
  456.     if (pthread_mutex_init(mutex, attr))
  457.     {
  458.         ThrowXML(XMLPlatformUtilsException,
  459.                  XMLExcepts::Mutex_CouldNotCreate);
  460.     }
  461.     pthread_mutexattr_destroy(attr);
  462. #endif
  463.     delete attr;
  464.     return (void*)(mutex);
  465. }
  466. void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
  467. {
  468.     if (mtxHandle == NULL)
  469.         return;
  470.     if (pthread_mutex_unlock( (pthread_mutex_t*)mtxHandle))
  471.     {
  472.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotUnlock);
  473.     }
  474. }
  475. #else // #ifndef APP_NO_THREADS
  476. void XMLPlatformUtils::closeMutex(void* const mtxHandle)
  477. {
  478. }
  479. void XMLPlatformUtils::lockMutex(void* const mtxHandle)
  480. {
  481. }
  482. void* XMLPlatformUtils::makeMutex()
  483. {
  484.         return 0;
  485. }
  486. void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
  487. {
  488. }
  489. #endif // APP_NO_THREADS
  490. #ifndef APP_NO_THREADS
  491. // -----------------------------------------------------------------------
  492. //  Miscellaneous synchronization methods
  493. // -----------------------------------------------------------------------
  494. void* XMLPlatformUtils::compareAndSwap ( void**      toFill ,
  495.                     const void* const newValue ,
  496.                     const void* const toCompare)
  497. {
  498.     boolean_t boolVar = compare_and_swap((atomic_p)toFill, (int *)&toCompare, (int)newValue );
  499.     return (void *)toCompare;
  500. }
  501. int XMLPlatformUtils::atomicIncrement(int &location)
  502. {
  503.     int retVal = fetch_and_add( (atomic_p)&location, 1);
  504.     return retVal+1;
  505. }
  506. int XMLPlatformUtils::atomicDecrement(int &location)
  507. {
  508.     int retVal = fetch_and_add( (atomic_p)&location, -1);
  509.     return retVal-1;
  510. }
  511. #else
  512. // -----------------------------------------------------------------------
  513. //  Miscellaneous synchronization methods
  514. // -----------------------------------------------------------------------
  515. void* XMLPlatformUtils::compareAndSwap ( void**      toFill,
  516.                                    const void* const newValue,
  517.                                    const void* const toCompare)
  518. {
  519.     void *retVal = *toFill;
  520.     if (*toFill == toCompare)
  521.        *toFill = (void *)newValue;
  522.     return retVal;
  523. }
  524. int XMLPlatformUtils::atomicIncrement(int &location)
  525. {
  526.     return ++location;
  527. }
  528. int XMLPlatformUtils::atomicDecrement(int &location)
  529. {
  530.     return --location;
  531. }
  532. #endif // APP_NO_THREADS
  533. FileHandle XMLPlatformUtils::openStdInHandle()
  534. {
  535.     return (FileHandle)fdopen(dup(0), "rb");
  536. }
  537. void XMLPlatformUtils::platformTerm()
  538. {
  539.     // We don't have any termination requirements at this time
  540. }
  541. /**************** Beginning of code attic *******************************
  542. void XMLPlatformUtils::platformInit()
  543. {
  544. }
  545. ********************* End of code attic *******************************/