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]