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

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: Win32PlatformUtils.cpp,v 1.28 2001/06/06 20:09:08 knoaman Exp $
  58.  */
  59. // ---------------------------------------------------------------------------
  60. //  Includes
  61. // ---------------------------------------------------------------------------
  62. #include <util/Janitor.hpp>
  63. #include <util/PlatformUtils.hpp>
  64. #include <util/RuntimeException.hpp>
  65. #include <util/XMLExceptMsgs.hpp>
  66. #include <util/XMLString.hpp>
  67. #include <util/XMLUniDefs.hpp>
  68. #include <util/XMLUni.hpp>
  69. #include <windows.h>
  70. #include <stdlib.h>
  71. #ifdef _DEBUG
  72.  #ifdef _MSC_VER
  73.     #include <crtdbg.h>
  74.  #else
  75.     #include <assert.h>
  76.  #endif
  77. #endif
  78. //
  79. //  These control which transcoding service is used by the Win32 version.
  80. //  They allow this to be controlled from the build process by just defining
  81. //  one of these values.
  82. //
  83. #if defined (XML_USE_ICU_TRANSCODER)
  84.     #include <util/Transcoders/ICU/ICUTransService.hpp>
  85. #elif defined (XML_USE_WIN32_TRANSCODER)
  86.     #include <util/Transcoders/Win32/Win32TransService.hpp>
  87. #else
  88.     #error A transcoding service must be chosen
  89. #endif
  90. //
  91. //  These control which message loading service is used by the Win32 version.
  92. //  They allow this to be controlled from the build process by just defining
  93. //  one of these values.
  94. //
  95. #if defined (XML_USE_INMEMORY_MSGLOADER)
  96.     #include <util/MsgLoaders/InMemory/InMemMsgLoader.hpp>
  97. #elif defined (XML_USE_WIN32_MSGLOADER)
  98.     #include <util/MsgLoaders/Win32/Win32MsgLoader.hpp>
  99. #else
  100.     #error A message loading service must be chosen
  101. #endif
  102. //
  103. //  These control which network access service is used by the Win32 version.
  104. //  They allow this to be controlled from the build process by just defining
  105. //  one of these values.
  106. //
  107. #if defined (XML_USE_NETACCESSOR_LIBWWW)
  108.     #include <util/NetAccessors/libWWW/LibWWWNetAccessor.hpp>
  109. #elif defined (XML_USE_NETACCESSOR_WINSOCK)
  110.     #include <util/NetAccessors/WinSock/WinSockNetAccessor.hpp>
  111. #endif
  112. // ---------------------------------------------------------------------------
  113. //  Local data
  114. //
  115. //  gOnNT
  116. //      We figure out during init if we are on NT or not. If we are, then
  117. //      we can avoid a lot of transcoding in our system services stuff.
  118. // ---------------------------------------------------------------------------
  119. static bool     gOnNT;
  120. // ---------------------------------------------------------------------------
  121. //  XMLPlatformUtils: The panic method
  122. // ---------------------------------------------------------------------------
  123. void XMLPlatformUtils::panic(const PanicReasons reason)
  124. {
  125.     const char* reasonStr = "Unknown reason";
  126.     if (reason == Panic_NoTransService)
  127.         reasonStr = "Could not load a transcoding service";
  128.     else if (reason == Panic_NoDefTranscoder)
  129.         reasonStr = "Could not load a local code page transcoder";
  130.     else if (reason == Panic_CantFindLib)
  131.         reasonStr = "Could not find the xerces-c DLL";
  132.     else if (reason == Panic_UnknownMsgDomain)
  133.         reasonStr = "Unknown message domain";
  134.     else if (reason == Panic_CantLoadMsgDomain)
  135.         reasonStr = "Cannot load message domain";
  136.     else if (reason == Panic_SynchronizationErr)
  137.         reasonStr = "A system synchronization error occurred";
  138.     else if (reason == Panic_SystemInit)
  139.         reasonStr = "Failed to complete platfrom dependent initialization";
  140.     //
  141.     //  We just do a popup and exit. Replace this code to do whatever
  142.     //  you need to do.
  143.     //
  144.     MessageBoxA
  145.     (
  146.         0
  147.         , "Xerces Panic Error"
  148.         , reasonStr
  149.         , MB_OK | MB_ICONSTOP
  150.     );
  151.     exit(-1);
  152. }
  153. // ---------------------------------------------------------------------------
  154. //  XMLPlatformUtils: File Methods
  155. // ---------------------------------------------------------------------------
  156. //
  157. //  Functions to look for Unicode forward and back slashes.
  158. //  This operation is complicated by the fact that some Japanese and Korean
  159. //    encodings use the same encoding for both '' and their currency symbol
  160. //    (Yen or Won).  In these encodings, which is meant is context dependent.
  161. //    Unicode converters choose the currency symbols.  But in the context
  162. //    of a Windows file name, '' is generally what was intended.
  163. //
  164. //    So we make a leap of faith, and assume that if we get a Yen or Won
  165. //    here, in the context of a file name, that it originated in one of
  166. //    these encodings, and is really supposed to be a ''.
  167. //
  168. static bool isBackSlash(XMLCh c) {
  169.     return c == chBackSlash ||
  170.            c == chYenSign   ||
  171.            c == chWonSign;
  172. }
  173. static bool isAnySlash(XMLCh c) {
  174.     return c == chBackSlash    ||
  175.            c == chForwardSlash ||
  176.            c == chYenSign      ||
  177.            c == chWonSign;
  178. }
  179. unsigned int XMLPlatformUtils::curFilePos(FileHandle theFile)
  180. {
  181.     // Get the current position
  182.     const unsigned int curPos = ::SetFilePointer(theFile, 0, 0, FILE_CURRENT);
  183.     if (curPos == 0xFFFFFFFF)
  184.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
  185.     return curPos;
  186. }
  187. void XMLPlatformUtils::closeFile(FileHandle theFile)
  188. {
  189.     if (!::CloseHandle(theFile))
  190.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotCloseFile);
  191. }
  192. unsigned int XMLPlatformUtils::fileSize(FileHandle theFile)
  193. {
  194.     // Get the current position
  195.     const unsigned int curPos = ::SetFilePointer(theFile, 0, 0, FILE_CURRENT);
  196.     if (curPos == 0xFFFFFFFF)
  197.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotGetCurPos);
  198.     // Seek to the end and save that value for return
  199.     const unsigned int retVal = ::SetFilePointer(theFile, 0, 0, FILE_END);
  200.     if (retVal == 0xFFFFFFFF)
  201.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToEnd);
  202.     // And put the pointer back
  203.     if (::SetFilePointer(theFile, curPos, 0, FILE_BEGIN) == 0xFFFFFFFF)
  204.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotSeekToPos);
  205.     return retVal;
  206. }
  207. FileHandle XMLPlatformUtils::openFile(const char* const fileName)
  208. {
  209.     FileHandle retVal = ::CreateFileA
  210.     (
  211.         fileName
  212.         , GENERIC_READ
  213.         , FILE_SHARE_READ
  214.         , 0
  215.         , OPEN_EXISTING
  216.         , FILE_FLAG_SEQUENTIAL_SCAN
  217.         , 0
  218.     );
  219.     if (retVal == INVALID_HANDLE_VALUE)
  220.         return 0;
  221.     return retVal;
  222. }
  223. FileHandle XMLPlatformUtils::openFile(const XMLCh* const fileName)
  224. {
  225.     // Watch for obvious wierdness
  226.     if (!fileName)
  227.         return 0;
  228.     //  Ok, this might look stupid but its a semi-expedient way to deal
  229.     //  with a thorny problem. Shift-JIS and some other Asian encodings
  230.     //  are fundamentally broken and map both the backslash and the Yen
  231.     //  sign to the same code point. Transcoders have to pick one or the
  232.     //  other to map '' to Unicode and tend to choose the Yen sign. 
  233.     //
  234.     //  Unicode Yen or Won signs as directory separators will fail.
  235.     //
  236.     //  So, we will check this path name for Yen or won signs and, if they are
  237.     //  there, we'll replace them with slashes.  
  238.     //
  239.     //  A further twist:  we replace Yen and Won with forward slashes rather 
  240.     //   than back slashes.  Either form of slash will work as a directory
  241.     //   separator.  On Win 95 and 98, though, Unicode back-slashes may
  242.     //   fail to transode back to 8-bit 0x5C with some Unicode converters
  243.     //   to  some of the problematic code pages.  Forward slashes always
  244.     //   transcode correctly back to 8 bit char * form.
  245.     //
  246.     XMLCh *tmpUName = 0;
  247.     const XMLCh *nameToOpen = fileName;
  248.     
  249.     const XMLCh* srcPtr = fileName;
  250.     while (*srcPtr)
  251.     {
  252.         if (*srcPtr == chYenSign ||
  253.             *srcPtr == chWonSign)
  254.             break;
  255.         srcPtr++;
  256.     }
  257.     
  258.     //
  259.     //  If we found a yen, then we have to create a temp file name. Else
  260.     //  go with the file name as is and save the overhead.
  261.     //
  262.     if (*srcPtr)
  263.     {
  264.         tmpUName = XMLString::replicate(fileName);
  265.         
  266.         XMLCh* tmpPtr = tmpUName;
  267.         while (*tmpPtr)
  268.         {
  269.             if (*tmpPtr == chYenSign ||
  270.                 *tmpPtr == chWonSign)
  271.                 *tmpPtr = chForwardSlash;
  272.             tmpPtr++;
  273.         }
  274.         nameToOpen = tmpUName;
  275.     }
  276.     FileHandle retVal = 0;
  277.     if (gOnNT)
  278.     {
  279.         retVal = ::CreateFileW
  280.             (
  281.             nameToOpen
  282.             , GENERIC_READ
  283.             , FILE_SHARE_READ
  284.             , 0
  285.             , OPEN_EXISTING
  286.             , FILE_FLAG_SEQUENTIAL_SCAN
  287.             , 0
  288.             );
  289.     }
  290.     else
  291.     {
  292.         //
  293.         //  We are Win 95 / 98.  Take the Unicode file name back to (char *)
  294.         //    so that we can open it.
  295.         //
  296.         char* tmpName = XMLString::transcode(nameToOpen);
  297.         retVal = ::CreateFileA
  298.             (
  299.             tmpName
  300.             , GENERIC_READ
  301.             , FILE_SHARE_READ
  302.             , 0
  303.             , OPEN_EXISTING
  304.             , FILE_FLAG_SEQUENTIAL_SCAN
  305.             , 0
  306.             );
  307.         delete [] tmpName;
  308.     }
  309.     if (tmpUName)  
  310.         delete [] tmpUName;
  311.     
  312.     if (retVal == INVALID_HANDLE_VALUE)
  313.         return 0;
  314.     
  315.     return retVal;
  316. }
  317. FileHandle XMLPlatformUtils::openStdInHandle()
  318. {
  319.     //
  320.     //  Get the standard input handle. Duplicate it and return that copy
  321.     //  since the outside world cannot tell the difference and will shut
  322.     //  down this handle when its done with it. If we gave out the orignal,
  323.     //  shutting it would prevent any further output.
  324.     //
  325.     HANDLE stdInOrg = ::GetStdHandle(STD_INPUT_HANDLE);
  326.     if (stdInOrg == INVALID_HANDLE_VALUE)
  327.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotOpenFile);
  328.     HANDLE retHandle;
  329.     if (!::DuplicateHandle
  330.     (
  331.         ::GetCurrentProcess()
  332.         , stdInOrg
  333.         , ::GetCurrentProcess()
  334.         , &retHandle
  335.         , 0
  336.         , FALSE
  337.         , DUPLICATE_SAME_ACCESS))
  338.     {
  339.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotDupHandle);
  340.     }
  341.     return retHandle;
  342. }
  343. unsigned int
  344. XMLPlatformUtils::readFileBuffer(       FileHandle      theFile
  345.                                 , const unsigned int    toRead
  346.                                 ,       XMLByte* const  toFill)
  347. {
  348.     unsigned long bytesRead = 0;
  349.     if (!::ReadFile(theFile, toFill, toRead, &bytesRead, 0))
  350.     {
  351.         //
  352.         //  Check specially for a broken pipe error. If we get this, it just
  353.         //  means no more data from the pipe, so return zero.
  354.         //
  355.         if (::GetLastError() != ERROR_BROKEN_PIPE)
  356.             ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotReadFromFile);
  357.     }
  358.     return (unsigned int)bytesRead;
  359. }
  360. void XMLPlatformUtils::resetFile(FileHandle theFile)
  361. {
  362.     // Seek to the start of the file
  363.     if (::SetFilePointer(theFile, 0, 0, FILE_BEGIN) == 0xFFFFFFFF)
  364.         ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_CouldNotResetFile);
  365. }
  366. // ---------------------------------------------------------------------------
  367. //  XMLPlatformUtils: File system methods
  368. // ---------------------------------------------------------------------------
  369. XMLCh* XMLPlatformUtils::getFullPath(const XMLCh* const srcPath)
  370. {
  371.     //
  372.     //  If we are on NT, then use wide character APIs, else use ASCII APIs.
  373.     //  We have to do it manually since we are only built in ASCII mode from
  374.     //  the standpoint of the APIs.
  375.     //
  376.     if (gOnNT)
  377.     {
  378.         // Use a local buffer that is big enough for the largest legal path
  379.         const unsigned int bufSize = 1024;
  380.         XMLCh tmpPath[bufSize + 1];
  381.         XMLCh* namePart = 0;
  382.         if (!::GetFullPathNameW(srcPath, bufSize, tmpPath, &namePart))
  383.             return 0;
  384.         // Return a copy of the path
  385.         return XMLString::replicate(tmpPath);
  386.     }
  387.      else
  388.     {
  389.         // Transcode the incoming string
  390.         char* tmpSrcPath = XMLString::transcode(srcPath);
  391.         ArrayJanitor<char> janSrcPath(tmpSrcPath);
  392.         // Use a local buffer that is big enough for the largest legal path
  393.         const unsigned int bufSize = 511;
  394.         char tmpPath[511 + 1];
  395.         char* namePart = 0;
  396.         if (!::GetFullPathNameA(tmpSrcPath, bufSize, tmpPath, &namePart))
  397.             return 0;
  398.         // Return a transcoded copy of the path
  399.         return XMLString::transcode(tmpPath);
  400.     }
  401. }
  402. bool XMLPlatformUtils::isRelative(const XMLCh* const toCheck)
  403. {
  404.     // Check for pathological case of empty path
  405.     if (!toCheck[0])
  406.         return false;
  407.     //
  408.     //  If its starts with a drive, then it cannot be relative. Note that
  409.     //  we checked the drive not being empty above, so worst case its one
  410.     //  char long and the check of the 1st char will fail because its really
  411.     //  a null character.
  412.     //
  413.     if (toCheck[1] == chColon)
  414.     {
  415.         if (((toCheck[0] >= chLatin_A) && (toCheck[0] <= chLatin_Z))
  416.         ||  ((toCheck[0] >= chLatin_a) && (toCheck[0] <= chLatin_z)))
  417.         {
  418.             return false;
  419.         }
  420.     }
  421.     //
  422.     //  If it starts with a double slash, then it cannot be relative since
  423.     //  it's a remote file.
  424.     //
  425.     if (isBackSlash(toCheck[0]) && isBackSlash(toCheck[1]))
  426.         return false;
  427.     // Else assume its a relative path
  428.     return true;
  429. }
  430. XMLCh* XMLPlatformUtils::weavePaths(const   XMLCh* const    basePath
  431.                                     , const XMLCh* const    relativePath)
  432. {
  433.     // Create a buffer as large as both parts and empty it
  434.     XMLCh* tmpBuf = new XMLCh[XMLString::stringLen(basePath)
  435.                               + XMLString::stringLen(relativePath)
  436.                               + 2];
  437.     *tmpBuf = 0;
  438.     //
  439.     //  If we have no base path, then just take the relative path as
  440.     //  is.
  441.     //
  442.     if (!basePath)
  443.     {
  444.         XMLString::copyString(tmpBuf, relativePath);
  445.         return tmpBuf;
  446.     }
  447.     if (!*basePath)
  448.     {
  449.         XMLString::copyString(tmpBuf, relativePath);
  450.         return tmpBuf;
  451.     }
  452.     const XMLCh* basePtr = basePath + (XMLString::stringLen(basePath) - 1);
  453.     while ((basePtr >= basePath)  &&  ((isAnySlash(*basePtr) == false)))
  454.     {
  455.         basePtr--;
  456.     }
  457.     // There is no relevant base path, so just take the relative part
  458.     if (basePtr < basePath)
  459.     {
  460.         XMLString::copyString(tmpBuf, relativePath);
  461.         return tmpBuf;
  462.     }
  463.     // After this, make sure the buffer gets handled if we exit early
  464.     ArrayJanitor<XMLCh> janBuf(tmpBuf);
  465.     //
  466.     //  We have some path part, so we need to check to see if we ahve to
  467.     //  weave any of the parts together.
  468.     //
  469.     const XMLCh* pathPtr = relativePath;
  470.     while (true)
  471.     {
  472.         // If it does not start with some period, then we are done
  473.         if (*pathPtr != chPeriod)
  474.             break;
  475.         unsigned int periodCount = 1;
  476.         pathPtr++;
  477.         if (*pathPtr == chPeriod)
  478.         {
  479.             pathPtr++;
  480.             periodCount++;
  481.         }
  482.         // Has to be followed by a  or / or the null to mean anything
  483.         if (isAnySlash(*pathPtr) == false &&  *pathPtr)
  484.         {
  485.             break;
  486.         }
  487.         if (*pathPtr)
  488.             pathPtr++;
  489.         // If its one period, just eat it, else move backwards in the base
  490.         if (periodCount == 2)
  491.         {
  492.             basePtr--;
  493.             while ((basePtr >= basePath) &&  (isAnySlash(*basePtr) == false))
  494.             {
  495.                 basePtr--;
  496.             }
  497.             // The base cannot provide enough levels, so its in error/
  498.             if (basePtr < basePath)
  499.                 ThrowXML(XMLPlatformUtilsException, XMLExcepts::File_BasePathUnderflow);
  500.         }
  501.     }
  502.     // Copy the base part up to the base pointer
  503.     XMLCh* bufPtr = tmpBuf;
  504.     const XMLCh* tmpPtr = basePath;
  505.     while (tmpPtr <= basePtr)
  506.         *bufPtr++ = *tmpPtr++;
  507.     // And then copy on the rest of our path
  508.     XMLString::copyString(bufPtr, pathPtr);
  509.     // Orphan the buffer and return it
  510.     janBuf.orphan();
  511.     return tmpBuf;
  512. }
  513. // ---------------------------------------------------------------------------
  514. //  XMLPlatformUtils: Timing Methods
  515. // ---------------------------------------------------------------------------
  516. unsigned long XMLPlatformUtils::getCurrentMillis()
  517. {
  518.     return (unsigned long)::GetTickCount();
  519. }
  520. // ---------------------------------------------------------------------------
  521. //  Mutex methods
  522. // ---------------------------------------------------------------------------
  523. void XMLPlatformUtils::closeMutex(void* const mtxHandle)
  524. {
  525.     ::DeleteCriticalSection((LPCRITICAL_SECTION)mtxHandle);
  526.     delete mtxHandle;
  527. }
  528. void XMLPlatformUtils::lockMutex(void* const mtxHandle)
  529. {
  530.     ::EnterCriticalSection((LPCRITICAL_SECTION)mtxHandle);
  531. }
  532. void* XMLPlatformUtils::makeMutex()
  533. {
  534.     CRITICAL_SECTION* newCS = new CRITICAL_SECTION;
  535.     InitializeCriticalSection(newCS);
  536.     return newCS;
  537. }
  538. void XMLPlatformUtils::unlockMutex(void* const mtxHandle)
  539. {
  540.     ::LeaveCriticalSection((LPCRITICAL_SECTION)mtxHandle);
  541. }
  542. // ---------------------------------------------------------------------------
  543. //  Miscellaneous synchronization methods
  544. // ---------------------------------------------------------------------------
  545. void*
  546. XMLPlatformUtils::compareAndSwap(       void**      toFill
  547.                                 , const void* const newValue
  548.                                 , const void* const toCompare)
  549. {
  550.     //
  551.     //  InterlockedCompareExchange is only supported on Windows 98,
  552.     //  Windows NT 4.0, and newer -- not on Windows 95...
  553.     //  If you are willing to give up Win95 support change this to #if 0
  554.     //  otherwise we are back to using assembler.
  555.     //  (But only if building with compilers that support inline assembler.)
  556.     //
  557.     #if defined(_MSC_VER) || defined(__BCPLUSPLUS__)
  558.     void*   result;
  559.     __asm
  560.     {
  561.         mov             eax, toCompare;
  562.         mov             ebx, newValue;
  563.         mov             ecx, toFill
  564.         lock cmpxchg    [ecx], ebx;
  565.         mov             result, eax;
  566.     }
  567.     return result;
  568.     #else
  569.     //    
  570.     //  Note we have to cast off the constness of some of these because
  571.     //  the system APIs are not C++ aware in all cases.
  572.     //
  573.     return (void *) ::InterlockedCompareExchange
  574.     (
  575.         (long *)toFill
  576.         , (long)newValue
  577.         , (long)toCompare
  578.     );
  579.     #endif
  580. }
  581. // ---------------------------------------------------------------------------
  582. //  Atomic increment and decrement methods
  583. // ---------------------------------------------------------------------------
  584. int XMLPlatformUtils::atomicIncrement(int &location)
  585. {
  586.     return ::InterlockedIncrement(&(long &)location);
  587. }
  588. int XMLPlatformUtils::atomicDecrement(int &location)
  589. {
  590.     return ::InterlockedDecrement(&(long &)location);
  591. }
  592. // ---------------------------------------------------------------------------
  593. //  XMLPlatformUtils: Private Static Methods
  594. // ---------------------------------------------------------------------------
  595. //
  596. //  This method is called by the platform independent part of this class
  597. //  during initialization. We have to create the type of net accessor that
  598. //  we want to use. If none, then just return zero.
  599. //
  600. XMLNetAccessor* XMLPlatformUtils::makeNetAccessor()
  601. {
  602. #if defined (XML_USE_NETACCESSOR_LIBWWW)
  603.     return new LibWWWNetAccessor();
  604. #elif defined (XML_USE_NETACCESSOR_WINSOCK)
  605.     return new WinSockNetAccessor();
  606. #else
  607.     return 0;
  608. #endif
  609. }
  610. //
  611. //  This method is called by the platform independent part of this class
  612. //  when client code asks to have one of the supported message sets loaded.
  613. //  In our case, we use the ICU based message loader mechanism.
  614. //
  615. XMLMsgLoader* XMLPlatformUtils::loadAMsgSet(const XMLCh* const msgDomain)
  616. {
  617. #if defined (XML_USE_INMEMORY_MSGLOADER)
  618.     return new InMemMsgLoader(msgDomain);
  619. #elif defined (XML_USE_WIN32_MSGLOADER)
  620.     return new Win32MsgLoader(msgDomain);
  621. #else
  622.     #error You must provide a message loader
  623. #endif
  624. }
  625. //
  626. //  This method is called very early in the bootstrapping process. This guy
  627. //  must create a transcoding service and return it. It cannot use any string
  628. //  methods, any transcoding services, throw any exceptions, etc... It just
  629. //  makes a transcoding service and returns it, or returns zero on failure.
  630. //
  631. XMLTransService* XMLPlatformUtils::makeTransService()
  632. {
  633.     //
  634.     //  Since we are going to use the ICU service, we have to tell it where
  635.     //  its converter files are. If the ICU_DATA environment variable is set,
  636.     //  then its been told. Otherwise, we tell it our default value relative
  637.     //  to our DLL.
  638.     //
  639. #if defined (XML_USE_ICU_TRANSCODER)
  640.     return new ICUTransService;
  641. #elif defined (XML_USE_WIN32_TRANSCODER)
  642.     return new Win32TransService;
  643. #else
  644.     #error You must provide a transcoding service implementation
  645. #endif
  646. }
  647. //
  648. //  This method handles the Win32 per-platform basic init functions. The
  649. //  primary jobs here are getting the path to our DLL and to get the
  650. //  stdout and stderr file handles setup.
  651. //
  652. void XMLPlatformUtils::platformInit()
  653. {
  654. #if 0 && defined(_DEBUG)
  655.     //  Enable this code for memeory leak testing
  656.     
  657.    // Send all reports to STDOUT
  658.    _CrtSetReportMode( _CRT_WARN, _CRTDBG_MODE_FILE );
  659.    _CrtSetReportFile( _CRT_WARN, _CRTDBG_FILE_STDOUT );
  660.    _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_FILE );
  661.    _CrtSetReportFile( _CRT_ERROR, _CRTDBG_FILE_STDOUT );
  662.    _CrtSetReportMode( _CRT_ASSERT, _CRTDBG_MODE_FILE );
  663.    _CrtSetReportFile( _CRT_ASSERT, _CRTDBG_FILE_STDOUT );
  664.     int tmpDbgFlag;
  665.     tmpDbgFlag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG);
  666.     tmpDbgFlag |= _CRTDBG_LEAK_CHECK_DF;
  667.     _CrtSetDbgFlag(tmpDbgFlag);
  668. #endif
  669.     // Figure out if we are on NT and save that flag for later use
  670.     OSVERSIONINFO   OSVer;
  671.     OSVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
  672.     ::GetVersionEx(&OSVer);
  673.     gOnNT = (OSVer.dwPlatformId == VER_PLATFORM_WIN32_NT);
  674. }
  675. void XMLPlatformUtils::platformTerm()
  676. {
  677.     // We don't have any temrination requirements for win32 at this time
  678. }