XML4C is perfectly compatible with Chinese supplements

xiaoxiao2021-03-06  130

Xml

4C

Perfect compatible Chinese supplement

xml

4C

Compatible with Chinese issues have always been a headache, there are many discussions on this area, but there is no good conclusion. On the website of IBM DeveloperWorks, I found an article in Mr. Zou Yueming. "Analysis XML

4C

Source code, perfect compatible Chinese XML ", this article is XML

4C

The source code analyzes, for XML

4C

The source code has been modified to achieve the purpose of Chinese compatibility. I also target XML

4C

The source code has been modified according to the statement in the article, which is really perfect in my Debug version to solve XML

4C

Perfect compatibility of Chinese. However, the problem has appeared in my Release version, there has been confusing Chinese parsing.

In order to understand the problem, decide to XML

4C

The Release version is tracking, and the result is that the problem is

Zou Yueming

The modifications pointed out in Mr.'s article. This code returned for DEBUG and RELEASE (first need to declare, I have called setLocale (lc_all, "chinese-siimplified") before using the library), as long as Chinese is included in the string, in Release The result of the VALCREQUIREDSIZE (Const Char * Const srcText) function calls MBstowcs is incorrect. Below is a function of the "Analyzing XML4C Source Code" modified function CALCREQUIREDSIZE code:

Unsigned int win32lcptranscoder :: CalcRequiredSize (const char * const srctext)

{

/ *

IF (! srctext)

Return 0;

Unsigned charlen = :: mblen (srctext, mb_cur_max);

IF (charlen == -1)

Return 0;

Else IF (Charlen! = 0)

Charlen = Strlen (srctext) / charlen

IF (charlen == -1)

Return 0;

Return charlen;

* /

IF (! srctext) {

Return 0;

}

Unsigned int RetVal = :: mbstowcs (0, srctext, 0);

IF (retval == -1) {

Return 0;

}

Return RetVal;

}

This code runs correctly under Debug, but under Release, the calculation length will have problems, and the result is incorrect. Start thinking is that the local environmental service started by the program is modified, but it is not changed when tracking the code, which makes people feel confused, do not know what is caused. When the current local environmental service (SetLocale (lc_all, null) is set before MBstowCS, the function MBstowcs can work correctly. If anyone knows, you can tell (email: flyelfsky@hotmail.com).

So, the code after modification is as follows:

Unsigned int win32lcptranscoder :: CalcRequiredSize (const char * const srctext)

{

IF (! srctext) {

Return 0;

}

#ifndef _debug

/ / Ensure that the correct result can be obtained under Release

SetLocale (lc_all, null);

#ENDIF

Unsigned int RetVal = :: mbstowcs (0, srctext, 0); if (RetVal == -1) {

Return 0;

}

Return RetVal;

}

Of course, not only this function needs to add this, add this code for all MBstowcs functions: setLocale (lc_all, null); The following is the function you need to modify:

Unsigned int win32lcptranscoder :: CalcRequiredSize (const char * const srctext

, MemoryManager * const manager)

Char * Win32lcptranscoder :: Transcode (const Xmlch * const today);

Char * Win32lcptranscoder :: Transcode (const Xmlch * const today,

MemoryManager * Const Manager)

XMLCH * Win32lcptranscoder :: Transcode (const char * const today ") CODE (Const Char * Const Totranscode)

XMLCH * Win32lcptranscoder :: Transcode (const char * const today,

MemoryManager * Const Manager)

Bool Win32lcptranscoder :: Transcode (Const Char * Const Totranscode

, XMLCH * Const Tofill

Const unsigned int maxchars

, MemoryManager * const manager)

Bool Win32lcptranscoder :: Transcode (const Xmlch * Const Totranscode

Char * const tofill

, Const unsigned int Maxbytes

, MemoryManager * const manager)

Conversion using functions MBstowcs and WCSTOMBS, but for porting, additional APIs have been provided in Win32 to perform conversion: WideChartomultibyte and multibytetowideChar, in these conversion functions, replace MBSTOWCS to multibytetowidechar, replace WCSTOMBS to WideChartomultibyte. This will not have this problem after so.

Appendix: Some cold content of Win32Transservice.cpp after modification

/ / -------------------------------------------------------------------------------------------- ---------------------------

// Win32lcptranscoder: Implementation of the Virtual Transcoder Interface

/ / -------------------------------------------------------------------------------------------- ---------------------------

Unsigned int win32lcptranscoder :: CalcRequiredSize (const char * const srctext

, MemoryManager * const manager)

{

IF (! srctext)

{

Return 0;

}

#ifdef _win32

Unsigned int Retval = :: MultibyTetowideChar (CP_ACP, 0,

SrcText,

-1,

NULL,

0);

#ELSE

#ifndef _debug

SetLocale (lc_all, ");

#ENDIF

Unsigned int RetVal = :: mbstowcs (0, srctext, 0);

#ENDIF

IF (RetVal == -1)

{

Return 0;

}

Return RetVal;

}

Char * Win32lcptranscoder :: Transcode (const Xmlch * const today)

{

IF (! totranscode)

Return 0;

Char * retval = 0;

IF (* Totranscode)

{

// Calc the needed size

Const unsigned int neededledlen = CALCREQUIREDSIZE (TOTRANSCODE);

// Allocate a Buffer of That Size Plus One for the Null and Transcode

Retval = new char [Neededlen 1];

#ifdef _win32

:: WideChartomultibyte (CP_ACP,

0,

TOTRANSCODE,

-1,

RetVal,

Neededlen,

""

NULL);

#ELSE

#ifndef _debug

SetLocale (lc_all, ");

#ENDIF

:: WCSTombs (Retval, Totranscode, Neededlen 1);

#ENDIF

// and cap it off off, just to make sure

RetVal [Neededledlen] = 0;

}

Else

{

Retval = new char [1];

RetVal [0] = 0;

}

Return RetVal;

}

Char * Win32lcptranscoder :: Transcode (const Xmlch * const today,

MemoryManager * Const Manager)

{

IF (! totranscode)

Return 0;

Char * retval = 0;

IF (* Totranscode)

{

// Calc the needed size

Const unsigned int neededledlen = CALCREQUIREDSIZE (TOTRANSCODE, MANAGER);

// Allocate a Buffer of That Size Plus One for the Null and Transcode

Retval = (char *) Manager-> Allocate ((NEEDELEN 1) * Sizeof (char)); // new char [needededledlen 1];

#ifdef _win32

:: WideChartomultibyte (CP_ACP,

0,

TOTRANSCODE,

-1,

RetVal,

Neededlen,

""

NULL);

#ELSE

#ifndef _debug

SetLocale (lc_all, ");

#ENDIF

:: WCSTombs (Retval, Totranscode, Neededlen 1);

#ENDIF

// and cap it off off the anyway just to makeretval [neededledlen] = 0;

}

Else

{

Retval = (char *) Manager-> Allocate (Sizeof (Char)); // New char [1];

RetVal [0] = 0;

}

Return RetVal;

}

XMLCH * Win32lcptranscoder :: Transcode (const char * const today ") CODE (Const Char * Const Totranscode)

{

IF (! totranscode)

Return 0;

XMLCH * RETVAL = 0;

IF (* Totranscode)

{

// Calculate The Buffer Size Required

Const unsigned int neededledlen = CALCREQUIREDSIZE (TOTRANSCODE);

IF (Neededlen == 0)

{

Retval = new XMLCH [1];

RetVal [0] = 0;

Return RetVal;

}

// Allocate a Buffer of That Size Plus One for the Null and Transcode

Retval = new XMLCH [Neededlen 1];

#ifdef _win32

:: MultibyTetowideChar (CP_ACP,

0,

TOTRANSCODE,

-1,

RetVal,

Neededlen;

#ELSE

#ifndef _debug

SetLocale (lc_all, ");

#ENDIF

:: Mbstowcs (Retval, Totranscode, Neededlen 1);

#ENDIF

// CAP IT Off Just to make Sure. WE Are So Paranoid!

RetVal [Neededledlen] = 0;

}

Else

{

Retval = new XMLCH [1];

RetVal [0] = 0;

}

Return RetVal;

}

XMLCH * Win32lcptranscoder :: Transcode (const char * const today,

MemoryManager * Const Manager)

{

IF (! totranscode)

Return 0;

XMLCH * RETVAL = 0;

IF (* Totranscode)

{

// Calculate The Buffer Size Required

Const unsigned int neededledlen = CALCREQUIREDSIZE (TOTRANSCODE, MANAGER);

IF (Neededlen == 0)

{

Retval = (xmlch *) manager-> allocate (sizeof (xmlch)); // new XMLCH [1];

RetVal [0] = 0;

Return RetVal;

}

// Allocate a Buffer of That Size Plus One for the Null and Transcode

Retval = (xmlch *) Manager-> Allocate ((Neededlen 1) * sizeof (XMLCH)); // new XMLCH [Neededelen 1];

#ifdef _win32

:: MultibyTetowideChar (CP_ACP,

0,

TOTRANSCODE,

-1,

RetVal, Neededledlen;

#ELSE

#ifndef _debug

SetLocale (lc_all, ");

#ENDIF

:: Mbstowcs (Retval, Totranscode, Neededlen 1);

#ENDIF

// CAP IT Off Just to make Sure. WE Are So Paranoid!

RetVal [Neededledlen] = 0;

}

Else

{

Retval = (xmlch *) manager-> allocate (sizeof (xmlch)); // new XMLCH [1];

RetVal [0] = 0;

}

Return RetVal;

}

Bool Win32lcptranscoder :: Transcode (Const Char * Const Totranscode

, XMLCH * Const Tofill

Const unsigned int maxchars

, MemoryManager * const manager)

{

// Check for a couple of psycho corner case

IF (! Totranscode ||! Maxchars)

{

TOFILL [0] = 0;

Return True;

}

IF (! * Totranscode)

{

TOFILL [0] = 0;

Return True;

}

// this One Has A Fixed Size Output, SO TRY IT and if IT Fails It Fails

#ifdef _win32

SIZE_T TO_ = :: MultibyTetowideChar (CP_ACP,

0,

TOTRANSCODE,

-1,

TOFILL,

Maxchars);

#ELSE

#ifndef _debug

SetLocale (lc_all, ");

#ENDIF

Size_t to_ = :: MBSTOWCS (Tofill, Totranscode, Maxchars 1);

#ENDIF

Return (TO_! = size_t (-1));

//

}

Bool Win32lcptranscoder :: Transcode (const Xmlch * Const Totranscode

Char * const tofill

, Const unsigned int Maxbytes

, MemoryManager * const manager)

{

// Watch for a couple of pyscho corner case

IF (! Totranscode ||! Maxbytes)

{

TOFILL [0] = 0;

Return True;

}

IF (! * Totranscode)

{

TOFILL [0] = 0;

Return True;

}

// this One Has A Fixed Size Output, SO TRY IT and if IT Fails It Fails

//

#ifdef _win32

Size_t to_ = :: widechartomultibyte (cp_acp,

0,

TOTRANSCODE,

-1,

TOFILL,

Maxbytes,

""

NULL);

#ELSE

#ifndef _debug

SetLocale (lc_all, ");

#ENDIF

Size_t to_ = :: WCSTombs (Tofill, Totranscode, MaxBytes 1); # Endif

IF (TO_ == SIZE_T (-1))

{

Return False;

}

// CAP IT Off Just In Case

TOFILL [MAXBYTES] = 0;

Return True;

}

转载请注明原文地址:https://www.9cbs.com/read-126118.html

New Post(0)