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

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: OS2PlatformUtils.cpp,v 1.8 2000/11/30 23:02:22 billsch Exp $
  58.  */
  59. // ---------------------------------------------------------------------------
  60. //  Includes
  61. // ---------------------------------------------------------------------------
  62. #define INCL_DOSSEMAPHORES
  63. #define INCL_DOSERRORS
  64. #define INCL_DOSMISC
  65. #define INCL_DOSFILEMGR
  66. #include    <util/XercesDefs.hpp>
  67. #include    <util/PlatformUtils.hpp>
  68. #include    <util/RuntimeException.hpp>
  69. #include    <util/Janitor.hpp>
  70. #include    <util/XMLString.hpp>
  71. #include    <util/XMLUniDefs.hpp>
  72. #include    <stdio.h>
  73. #include    <stdlib.h>
  74. #include    <io.h>
  75. #if defined(XML_USE_ICU_TRANSCODER)
  76.   #include  <util/Transcoders/ICU/ICUTransService.hpp>
  77. #elif defined(XML_USE_ICONV_TRANSCODER)
  78.   #include  <util/Transcoders/Iconv/IconvTransService.hpp>
  79. #else
  80.   #error A transcoding service must be chosen
  81. #endif
  82. #if defined(XML_USE_INMEMORY_MSGLOADER)
  83.   #include  <util/MsgLoaders/InMemory/InMemMsgLoader.hpp>
  84. #else
  85.   #error A message loading service must be chosen
  86. #endif
  87. #if defined(XML_IBMVAOS2)
  88. #include    <builtin.h>
  89. #endif
  90. #include    <OS2.h>
  91. // ---------------------------------------------------------------------------
  92. //  XMLPlatformUtils: Platform init and term methods
  93. // ---------------------------------------------------------------------------
  94. void XMLPlatformUtils::platformInit()
  95. {
  96. }
  97. void XMLPlatformUtils::platformTerm()
  98. {
  99.     // We don't have any termination requirements at this time
  100. }
  101. // ---------------------------------------------------------------------------
  102. //  XMLPlatformUtils: File Methods
  103. // ---------------------------------------------------------------------------
  104. unsigned int XMLPlatformUtils::curFilePos(FileHandle theFile)
  105. {
  106.     // Get the current position
  107.     int curPos = ftell( (FILE*)theFile);
  108.     if (curPos == -1)
  109.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
  110.     return (unsigned int)curPos;
  111. }
  112. void XMLPlatformUtils::closeFile(FileHandle theFile)
  113. {
  114.     if (fclose((FILE*)theFile))
  115.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
  116. }
  117. unsigned int XMLPlatformUtils::fileSize(FileHandle theFile)
  118. {
  119.     return (unsigned int)filelength(fileno((FILE *)theFile));
  120. }
  121. FileHandle XMLPlatformUtils::openFile(const char* const fileName)
  122. {
  123.     FileHandle retVal = (FILE*)fopen( fileName , "rb" );
  124.     if (retVal == NULL)
  125.         return 0;
  126.     return retVal;
  127. }
  128. FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName)
  129. {
  130.     const char* tmpFileName = XMLString::transcode(fileName);
  131.     ArrayJanitor<char> janText((char*)tmpFileName);
  132.     FileHandle retVal = (FILE*)fopen( tmpFileName , "rb" );
  133.     if (retVal == NULL)
  134.         return 0;
  135.     return retVal;
  136. }
  137. FileHandle XMLPlatformUtils::openStdInHandle()
  138. {
  139.     return (FileHandle)fdopen(dup(0), "rb");
  140. }
  141. unsigned int XMLPlatformUtils::readFileBuffer ( FileHandle      theFile
  142.                             , const unsigned int    toRead
  143.                             ,       XMLByte* const  toFill )
  144. {
  145.     size_t noOfItemsRead = fread( (void*) toFill, 1, toRead, (FILE*)theFile);
  146.     if(ferror((FILE*)theFile))
  147.     {
  148.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile);
  149.     }
  150.     return (unsigned int)noOfItemsRead;
  151. }
  152. void XMLPlatformUtils::resetFile(FileHandle theFile)
  153. {
  154.     // Seek to the start of the file
  155.     if (fseek((FILE*)theFile, 0, SEEK_SET) )
  156.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotResetFile);
  157. }
  158. // -----------------------------------------------------------------------
  159. //  File system methods
  160. // -----------------------------------------------------------------------
  161. XMLCh* XMLPlatformUtils::getFullPath(const XMLCh* const srcPath)
  162. {
  163.     // Transcode the incoming string
  164.     char* tmpSrcPath = XMLString::transcode(srcPath);
  165.     ArrayJanitor<char> janSrcPath(tmpSrcPath);
  166.     char tmpPath[CCHMAXPATH];
  167.     _fullpath(tmpPath, tmpSrcPath, CCHMAXPATH);
  168.     return XMLString::transcode(tmpPath);
  169. }
  170. bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
  171. {
  172.     // Check for pathological case of an empty path
  173.     if (!toCheck[0])
  174.         return false;
  175.     //
  176.     //  If it starts with a drive, then it cannot be relative. Note that
  177.     //  we checked the drive not being empty above, so worst case it's one
  178.     //  char long and the check of the 1st char will fail because it's really
  179.     //  a null character.
  180.     //
  181.     if (toCheck[1] == chColon)
  182.     {
  183.         if (((toCheck[0] >= chLatin_A) && (toCheck[0] <= chLatin_Z))
  184.         ||  ((toCheck[0] >= chLatin_a) && (toCheck[0] <= chLatin_z)))
  185.         {
  186.             return false;
  187.         }
  188.     }
  189.     //
  190.     //  If it starts with a double slash, then it cannot be relative since
  191.     //  its a remote file.
  192.     //
  193.     if ((toCheck[0] == chBackSlash) && (toCheck[1] == chBackSlash))
  194.         return false;
  195.     // Else assume its a relative path
  196.     return true;
  197. }
  198. XMLCh* XMLPlatformUtils::weavePaths( const   XMLCh* const    basePath
  199.                                    , const XMLCh* const    relativePath )
  200. {
  201.     // Create a buffer as large as both parts and empty it
  202.     XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
  203.                               + XMLString::stringLen(relativePath)
  204.                               + 2];
  205.     *tmpBuf = 0;
  206.     //
  207.     //  If we have no base path, then just take the relative path as
  208.     //  is.
  209.     //
  210.     if (!basePath || !*basePath)
  211.     {
  212.         XMLString::copyString(tmpBuf, relativePath);
  213.         return tmpBuf;
  214.     }
  215.     const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
  216.     if ((*basePtr != chForwardSlash)
  217.     &&  (*basePtr != chBackSlash))
  218.     {
  219.         while ((basePtr >= basePath)
  220.         &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
  221.         {
  222.             basePtr--;
  223.         }
  224.     }
  225.     // There is no relevant base path, so just take the relative part
  226.     if (basePtr < basePath)
  227.     {
  228.         XMLString::copyString(tmpBuf, relativePath);
  229.         return tmpBuf;
  230.     }
  231.     // After this, make sure the buffer gets handled if we exit early
  232.     ArrayJanitor<XMLCh> janBuf(tmpBuf);
  233.     //
  234.     //  We have some path part, so we need to check to see if we ahve to
  235.     //  weave any of the parts together.
  236.     //
  237.     const XMLCh* pathPtr = relativePath;
  238.     while (true)
  239.     {
  240.         // If it does not start with some period, then we are done
  241.         if (*pathPtr != chPeriod)
  242.             break;
  243.         unsigned int periodCount = 1;
  244.         pathPtr++;
  245.         if (*pathPtr == chPeriod)
  246.         {
  247.             pathPtr++;
  248.             periodCount++;
  249.         }
  250.         // Has to be followed by a  or / or the null to mean anything
  251.         if ((*pathPtr != chForwardSlash) && (*pathPtr != chBackSlash)
  252.         &&  *pathPtr)
  253.         {
  254.             break;
  255.         }
  256.         if (*pathPtr)
  257.             pathPtr++;
  258.         // If its one period, just eat it, else move backwards in the base
  259.         if (periodCount == 2)
  260.         {
  261.             basePtr--;
  262.             while ((basePtr >= basePath)
  263.             &&     ((*basePtr != chForwardSlash) && (*basePtr != chBackSlash)))
  264.             {
  265.                 basePtr--;
  266.             }
  267.             if (basePtr < basePath)
  268.             {
  269.                 // The base cannot provide enough levels, so its in error
  270.                 // <TBD>
  271.             }
  272.         }
  273.     }
  274.     // Copy the base part up to the base pointer
  275.     XMLCh* bufPtr = tmpBuf;
  276.     const XMLCh* tmpPtr = basePath;
  277.     while (tmpPtr <= basePtr)
  278.         *bufPtr++ = *tmpPtr++;
  279.     // And then copy on the rest of our path
  280.     XMLString::copyString(bufPtr, pathPtr);
  281.     // Orphan the buffer and return it
  282.     janBuf.orphan();
  283.     return tmpBuf;
  284. }
  285. // -----------------------------------------------------------------------
  286. //  Timing methods
  287. // -----------------------------------------------------------------------
  288. unsigned long XMLPlatformUtils::getCurrentMillis()
  289. {
  290.     APIRET  retr;
  291.     ULONG   timerBuf = 0;
  292.     retr =  DosQuerySysInfo( QSV_MS_COUNT, QSV_MS_COUNT, (PVOID) &timerBuf,
  293.                              sizeof( ULONG ) );
  294. //  if ( retr != NO_ERROR )
  295. //     return (timerBuf);
  296.     return (timerBuf);
  297. }
  298. // -----------------------------------------------------------------------
  299. //  Mutex methods
  300. // -----------------------------------------------------------------------
  301. void XMLPlatformUtils::closeMutex(void* const mtxHandle)
  302. {
  303. #if ! defined(APP_NO_THREADS)
  304.     if (mtxHandle == NULL)
  305.       return;
  306.     if (DosCloseMutexSem( (HMTX)mtxHandle))
  307.     {
  308.       ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotDestroy);
  309.     }
  310. #endif
  311. }
  312. void XMLPlatformUtils::lockMutex(void* const mtxHandle)
  313. {
  314. #if ! defined(APP_NO_THREADS)
  315.     if (mtxHandle == NULL)
  316.       return;
  317.     if (DosRequestMutexSem( (HMTX)mtxHandle,(ULONG) SEM_INDEFINITE_WAIT) )
  318.     {
  319.       ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotLock);
  320.     }
  321. #endif
  322. }
  323. void* XMLPlatformUtils::makeMutex()
  324. {
  325. #if ! defined(APP_NO_THREADS)
  326.     HMTX hRet; // Mutex Handle
  327.     if (DosCreateMutexSem(NULL, &hRet, 0, FALSE))
  328.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotCreate);
  329.     return (void*)hRet;
  330. #else
  331.     return 0;
  332. #endif
  333. }
  334. void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
  335. {
  336. #if ! defined(APP_NO_THREADS)
  337.     if (mtxHandle == NULL)
  338.        return;
  339.     if (DosReleaseMutexSem( (HMTX)mtxHandle))
  340.     {
  341.       ThrowXML(XMLPlatformUtilsException, XMLExcepts::Mutex_CouldNotUnlock);
  342.     }
  343. #endif
  344. }
  345. // -----------------------------------------------------------------------
  346. //  Miscellaneous synchronization methods
  347. // -----------------------------------------------------------------------
  348. void* XMLPlatformUtils::compareAndSwap ( void**      toFill
  349.                                        , const void* const newValue
  350.                                        , const void* const toCompare )
  351. {
  352. #if defined(XML_IBMVA4_OS2)
  353.     return (void *)__smp_cmpxchg4((unsigned int *)toFill,
  354.                                   (unsigned int)newValue,
  355.                                   (unsigned int)toCompare);
  356. #elif defined(__GNUG__)
  357.     char ret;
  358.     long int readval;
  359.     long int * p    = (long **)toFill;
  360.     __asm__ __volatile__ ("lock; cmpxchgl %3, %1ntsete %0"
  361.                           : "=q" (ret), "=m" (*p), "=a" (readval)
  362.                           : "r" (newValue), "m" (*p), "a" (toCompare)
  363.                           : "memory");
  364.     return (void *)(long)ret;
  365. #else
  366.     void * retVal = *toFill;
  367.     if (*toFill == toCompare)
  368.       *toFill = (void *)newValue;
  369.     return
  370. #endif
  371. }
  372. // -----------------------------------------------------------------------
  373. //  Atomic Increment and Decrement
  374. //
  375. //  The function return value is positive if the result of the operation
  376. //  was positive. Zero if the result of the operation was zero. Negative
  377. //  if the result of the operation was negative. Except for the zero
  378. //  case, the value returned may differ from the actual result of the
  379. //  operation - only the sign and zero/nonzero state is guaranteed to be
  380. //  correct.
  381. // -----------------------------------------------------------------------
  382. int XMLPlatformUtils::atomicIncrement(int& location)
  383. {
  384. #if defined(XML_IBMVA4_OS2)
  385.     return __smp_inc4(&location);
  386. #elif defined(__GNUG__)
  387.     __asm__ __volatile__ ("lock; incl %0" : "=m" (location) : );
  388.     return location;
  389. #else
  390.     return ++location;
  391. #endif
  392. }
  393. int XMLPlatformUtils::atomicDecrement(int& location)
  394. {
  395. #if defined(XML_IBMVA4_OS2)
  396.     return __smp_dec4(&location);
  397. #elif defined(__GNUG__)
  398.     __asm__ __volatile__ ("lock; decl %0" : "=m" (location) : );
  399.     return location;
  400. #else
  401.     return --location;
  402. #endif
  403. }
  404. // ---------------------------------------------------------------------------
  405. //  XMLPlatformUtils: The panic method
  406. // ---------------------------------------------------------------------------
  407. void XMLPlatformUtils::panic(const PanicReasons reason)
  408. {
  409.     const char* reasonStr = "Unknown reason";
  410.     switch (reason)
  411.     {
  412.     case Panic_NoTransService:
  413.         reasonStr = "Could not load a transcoding service";
  414.         break;
  415.     case Panic_NoDefTranscoder:
  416.         reasonStr = "Could not load a local code page transcoder";
  417.         break;
  418.     case Panic_CantFindLib:
  419.         reasonStr = "Could not find the xerces-c DLL";
  420.         break;
  421.     case Panic_UnknownMsgDomain:
  422.         reasonStr = "Unknown message domain";
  423.         break;
  424.     case Panic_CantLoadMsgDomain:
  425.         reasonStr = "Cannot load message domain";
  426.         break;
  427.     case Panic_SynchronizationErr:
  428.         reasonStr = "Cannot synchronize system or mutex";
  429.         break;
  430.     case Panic_SystemInit:
  431.         reasonStr = "Cannot initialize the system or mutex";
  432.         break;
  433.     }
  434.     fprintf(stderr, "%sn", reasonStr);
  435.     exit(-1);
  436. }
  437. // -----------------------------------------------------------------------
  438. //  Private static methods. These are provided by the per-platform
  439. //  implementation files.
  440. // -----------------------------------------------------------------------
  441. XMLMsgLoader* XMLPlatformUtils::loadAMsgSet(const XMLCh* const msgDomain)
  442. {
  443. #if defined(XML_USE_INMEMORY_MSGLOADER)
  444.     return new InMemMsgLoader(msgDomain);
  445. #else
  446.     return 0;
  447. #endif
  448. }
  449. XMLNetAccessor* XMLPlatformUtils::makeNetAccessor()
  450. {
  451.   return 0;
  452. }
  453. XMLTransService* XMLPlatformUtils::makeTransService()
  454. {
  455. #if defined(XML_USE_ICU_TRANSCODER)
  456.     return new ICUTransService;
  457. #elif defined(XML_USE_ICONV_TRANSCODER)
  458.     return new IconvTransService;
  459. #else
  460.     return 0;
  461. #endif
  462. }