Author: dbertoni
Date: Thu Jul 17 14:33:40 2008
New Revision: 677743

URL: http://svn.apache.org/viewvc?rev=677743&view=rev
Log:
Fix for XERCESC-1818.

Modified:
    
xerces/c/branches/xerces-2/src/xercesc/util/Transcoders/Win32/Win32TransService.cpp
    
xerces/c/branches/xerces-2/src/xercesc/util/Transcoders/Win32/Win32TransService.hpp

Modified: 
xerces/c/branches/xerces-2/src/xercesc/util/Transcoders/Win32/Win32TransService.cpp
URL: 
http://svn.apache.org/viewvc/xerces/c/branches/xerces-2/src/xercesc/util/Transcoders/Win32/Win32TransService.cpp?rev=677743&r1=677742&r2=677743&view=diff
==============================================================================
--- 
xerces/c/branches/xerces-2/src/xercesc/util/Transcoders/Win32/Win32TransService.cpp
 (original)
+++ 
xerces/c/branches/xerces-2/src/xercesc/util/Transcoders/Win32/Win32TransService.cpp
 Thu Jul 17 14:33:40 2008
@@ -193,6 +193,9 @@
 
 
 
+static bool onXPOrLater = false;
+
+
 //---------------------------------------------------------------------------
 //
 //  class Win32TransService Implementation ...
@@ -205,6 +208,18 @@
 // ---------------------------------------------------------------------------
 Win32TransService::Win32TransService()
 {
+    // Figure out if we are on XP or later and save that flag for later use.
+    // We need this because of certain code page conversion calls.
+    OSVERSIONINFO   OSVer;
+    OSVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
+    ::GetVersionEx(&OSVer);
+
+    if ((OSVer.dwPlatformId == VER_PLATFORM_WIN32_NT) &&
+        ((OSVer.dwMajorVersion == 5) && (OSVer.dwMinorVersion > 0)))
+    {
+        onXPOrLater = true;
+    }
+
     fCPMap = new RefHashTableOf<CPMapEntry>(109);
 
     //
@@ -558,6 +573,42 @@
 //---------------------------------------------------------------------------
 
 
+inline DWORD
+getFlagsValue(
+            UINT    idCP,
+            DWORD   desiredFlags)
+{
+    if (idCP == 50220 ||
+        idCP == 50227 ||
+        (idCP >= 57002 &&
+         idCP <= 57011))
+    {
+        // These code pages do not support any
+        // flag options.
+        return 0;
+    }
+    else if (idCP == 65001)
+    {
+        // UTF-8 only supports MB_ERR_INVALID_CHARS on
+        // versions of Windows since XP
+        if (!onXPOrLater)
+        {
+            return 0;
+        }
+        else
+        {
+            return desiredFlags & MB_ERR_INVALID_CHARS ?
+                        MB_ERR_INVALID_CHARS : 0;
+        }
+    }
+    else
+    {
+        return desiredFlags;
+    }
+}
+
+
+
 // ---------------------------------------------------------------------------
 //  Win32Transcoder: Constructors and Destructor
 // ---------------------------------------------------------------------------
@@ -570,7 +621,24 @@
     XMLTranscoder(encodingName, blockSize, manager)
     , fIECP(ieCP)
     , fWinCP(winCP)
-{
+    , fUsedDef(FALSE)
+    , fPtrUsedDef(0)
+    , fFromFlags(getFlagsValue(ieCP, MB_PRECOMPOSED | MB_ERR_INVALID_CHARS))
+#if defined(WC_NO_BEST_FIT_CHARS)
+    , fToFlags(getFlagsValue(ieCP, WC_COMPOSITECHECK | WC_SEPCHARS | 
WC_NO_BEST_FIT_CHARS))
+#else
+    , fToFlags(getFlagsValue(ieCP, WC_COMPOSITECHECK | WC_SEPCHARS))
+#endif
+{
+    // Some code pages require that MultiByteToWideChar and WideCharToMultiByte
+    // be passed 0 for their second parameters (dwFlags).  If that's the case,
+    // it's also necessary to pass null pointers for the last two parameters
+    // to WideCharToMultiByte.  This is apparently because it's impossible to
+    // determine whether or not a substitution (replacement) character was 
used.
+    if (fToFlags)
+    {
+        fPtrUsedDef = &fUsedDef;
+    }
 }
 
 Win32Transcoder::~Win32Transcoder()
@@ -612,7 +680,7 @@
         unsigned char toEat = ::IsDBCSLeadByteEx(fIECP, *inPtr) ?
                                     2 : 1;
 
-        // Make sure a whol char is in the source
+        // Make sure a whole char is in the source
         if (inPtr + toEat > inEnd)
             break;
 
@@ -620,7 +688,7 @@
         const unsigned int converted = ::MultiByteToWideChar
         (
             fIECP
-            , MB_PRECOMPOSED | MB_ERR_INVALID_CHARS
+            , fFromFlags
             , (const char*)inPtr
             , toEat
             , outPtr
@@ -686,7 +754,7 @@
     //  conversion API is too dumb to tell us how many chars it converted if
     //  it couldn't do the whole source.
     //
-    BOOL usedDef;
+    fUsedDef = FALSE;
     while ((outPtr < outEnd) && (srcPtr < srcEnd))
     {
         //
@@ -694,13 +762,13 @@
         const unsigned int bytesStored = ::WideCharToMultiByte
         (
             fIECP
-            , WC_COMPOSITECHECK | WC_SEPCHARS | WC_NO_BEST_FIT_CHARS
+            , fToFlags
             , srcPtr
             , 1
             , (char*)outPtr
             , outEnd - outPtr
             , 0
-            , &usedDef
+            , fPtrUsedDef
         );
 
         // If we didn't transcode anything, then we are done
@@ -711,7 +779,7 @@
         //  If the defaault char was used and the options indicate that
         //  this isn't allowed, then throw.
         //
-        if (usedDef && (options == UnRep_Throw))
+        if (fUsedDef && (options == UnRep_Throw))
         {
             XMLCh tmpBuf[17];
             XMLString::binToText((unsigned int)*srcPtr, tmpBuf, 16, 16, 
getMemoryManager());
@@ -763,20 +831,24 @@
     //
     char tmpBuf[64];
 
-    BOOL usedDef;
+    if (fPtrUsedDef)
+    {
+        *fPtrUsedDef = FALSE;
+    }
+
     const unsigned int bytesStored = ::WideCharToMultiByte
     (
         fIECP
-        , WC_COMPOSITECHECK | WC_SEPCHARS | WC_NO_BEST_FIT_CHARS
+        , fToFlags
         , srcBuf
         , srcCount
         , tmpBuf
         , 64
         , 0
-        , &usedDef
+        , fPtrUsedDef
     );
 
-    if (!bytesStored || usedDef)
+    if (!bytesStored || fUsedDef)
         return false;
 
     return true;

Modified: 
xerces/c/branches/xerces-2/src/xercesc/util/Transcoders/Win32/Win32TransService.hpp
URL: 
http://svn.apache.org/viewvc/xerces/c/branches/xerces-2/src/xercesc/util/Transcoders/Win32/Win32TransService.hpp?rev=677743&r1=677742&r2=677743&view=diff
==============================================================================
--- 
xerces/c/branches/xerces-2/src/xercesc/util/Transcoders/Win32/Win32TransService.hpp
 (original)
+++ 
xerces/c/branches/xerces-2/src/xercesc/util/Transcoders/Win32/Win32TransService.hpp
 Thu Jul 17 14:33:40 2008
@@ -186,9 +186,39 @@
     //
     //  fWinCP
     //      This is the windows code page for this encoding.
+    //
+    //  fUsedDef
+    //      A flag passed into the conversions routines that is set to
+    //      TRUE when a default character was substituted for the actual
+    //      character.
+    //
+    //  fPtrUsedDef
+    //      A pointer to fUsedDef or a null pointer if the code page does not
+    //      support the parameter that returns whether or not a default
+    //      character was substituted.
+    //
+    //  fFromFlags
+    //      These are the flags passed to MultiByteToWideChar.  For some
+    //      code pages, this must be 0.  See the documentation of the function
+    //      for more details.
+    //
+    //  fToFlags
+    //      These are the flags passed to WideCharToMultiByte.  For some
+    //      code pages, this must be 0.  See the documentation of the function
+    //      for more details.
+    //
     // -----------------------------------------------------------------------
-    unsigned int    fIECP;
-    unsigned int    fWinCP;
+    UINT    fIECP;
+
+    UINT    fWinCP;
+
+    BOOL    fUsedDef;
+
+    BOOL*   fPtrUsedDef;
+
+    DWORD   fFromFlags;
+
+    DWORD   fToFlags;
 };
 
 



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to