Fix & enable iconv() character conversion, instead of relying on cGoodEnoughConverter everywhere.

This commit is contained in:
Brian Cox 2016-05-06 18:47:56 -07:00
parent b543a36d89
commit ec9b4317ca
1 changed files with 40 additions and 32 deletions

72
src/core/codeconvert.cpp Normal file → Executable file
View File

@ -1,4 +1,4 @@
//
// The developer of the original code and/or files is Tripwire, Inc. // The developer of the original code and/or files is Tripwire, Inc.
// Portions created by Tripwire, Inc. are copyright (C) 2000 Tripwire, // Portions created by Tripwire, Inc. are copyright (C) 2000 Tripwire,
// Inc. Tripwire is a registered trademark of Tripwire, Inc. All rights // Inc. Tripwire is a registered trademark of Tripwire, Inc. All rights
@ -57,20 +57,11 @@
// DEFINES // DEFINES
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
/*
* ICONV conversion seems to be broken under Linux, so until
* this is fixed, we'll wing it ourselves - 20010310 PH
*/
#if 0
#define TSS_USE_ICONV_CCONV16 HAVE_ICONV_H #define TSS_USE_ICONV_CCONV16 HAVE_ICONV_H
#define TSS_USE_UCS2_CCONV16 (!(HAVE_ICONV_H) && WCHAR_REP_IS_UCS2 && WCHAR_IS_16_BITS) #define TSS_USE_UCS2_CCONV16 (!(HAVE_ICONV_H) && WCHAR_REP_IS_UCS2 && WCHAR_IS_16_BITS)
#define TSS_USE_UCS2_CCONV32 (!(HAVE_ICONV_H) && WCHAR_REP_IS_UCS2 && WCHAR_IS_32_BITS) #define TSS_USE_UCS2_CCONV32 (!(HAVE_ICONV_H) && WCHAR_REP_IS_UCS2 && WCHAR_IS_32_BITS)
#else
#define TSS_USE_UCS2_CCONV16 (WCHAR_REP_IS_UCS2 && WCHAR_IS_16_BITS)
#define TSS_USE_UCS2_CCONV32 (WCHAR_REP_IS_UCS2 && WCHAR_IS_32_BITS)
#endif
#define ICONV_SOURCE_TYPE const char #define ICONV_SOURCE_TYPE char
//- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - //- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Static Data // Static Data
@ -245,7 +236,6 @@ namespace /*Unique*/
eConverterUnknownCodepage( eConverterUnknownCodepage(
TSS_GetString( cCore, core::STR_UNKNOWN ) ); TSS_GetString( cCore, core::STR_UNKNOWN ) );
break; break;
default: default:
throw throw
eConverterFatal( eConverterFatal(
@ -677,31 +667,44 @@ namespace /*Unique*/
BufferT* pBuf = pBuffer; BufferT* pBuf = pBuffer;
const SourceT* pSrc = pSource; const SourceT* pSrc = pSource;
//--Start Iterative Conversion
while ( nSourceLeft > 0 ) while ( nSourceLeft > 0 )
{ {
// Convert as much of the sequence as we can. // Convert as much of the sequence as we can.
SourceT* pIconvSrc = (SourceT*)pSrc;
BufferT* pIconvDest = (BufferT*)pBuf;
size_t nbIconvSrc = (size_t)nSourceLeft;
size_t nbIconvDest = (size_t)nBufferLeft;
// NOTE: On solaris sparc, iconv will attempt to NULL terminate the output, size_t nConv = iconv( convForward, (ICONV_SOURCE_TYPE**)&pIconvSrc, &nbIconvSrc, (char**)&pIconvDest, &nbIconvDest );
// so make sure that the buffer has space for a terminating NULL
size_t nConv = // NOTE: if( nConv == -1 )
{
// NOTE: On solaris sparc, iconv will attempt to NULL terminate the output,
// so make sure that the buffer has space for a terminating NULL
size_t nConv = // NOTE:
#if SUPPORTS_EXPLICIT_TEMPLATE_FUNC_INST #if SUPPORTS_EXPLICIT_TEMPLATE_FUNC_INST
tss_ConvertOneCharacter<BufferT, SourceT>( tss_ConvertOneCharacter<BufferT, SourceT>(
#else #else
tss_ConvertOneCharacter( tss_ConvertOneCharacter(
#endif #endif
convForward, convForward,
convReverse, // On return, these addresses convReverse, // On return, these addresses
(const char**)&pSrc, // are set for one past the last (const char**)&pSrc, // are set for one past the last
&nSourceLeft, // "item" converted successfully &nSourceLeft, // "item" converted successfully
(char**)&pBuf, (char**)&pBuf,
&nBufferLeft &nBufferLeft
#if ( ! SUPPORTS_EXPLICIT_TEMPLATE_FUNC_INST ) #if ( ! SUPPORTS_EXPLICIT_TEMPLATE_FUNC_INST )
, BufferT(), SourceT() , BufferT(), SourceT()
#endif #endif
); );
}
else
{
pSrc = pIconvSrc;
pBuf = pIconvDest;
nSourceLeft = nbIconvSrc;
nBufferLeft = nbIconvDest;
}
if ( nConv == (size_t)-1 ) // Indidates Conversion Error! if ( nConv == (size_t)-1 ) // Indidates Conversion Error!
{ {
@ -1131,7 +1134,7 @@ const char* cIconvUtil::GetCodePageID()
const char* pCurCodePage; const char* pCurCodePage;
if( ! GetCodePageID( &pCurCodePage ) ) if( ! GetCodePageID( &pCurCodePage ) )
throw eConverterUnknownCodepage(); return NULL;
return pCurCodePage; return pCurCodePage;
} }
@ -1139,9 +1142,11 @@ const char* cIconvUtil::GetCodePageID()
/* static */ /* static */
const char* cIconvUtil::GetIconvDbIdentifier() const char* cIconvUtil::GetIconvDbIdentifier()
{ {
ASSERT( false ); #ifdef WORDS_BIGENDIAN
throw eConverterUnknownCodepage(); return "UTF-16BE";
return NULL; #else
return "UTF-16LE";
#endif
} }
/* static */ /* static */
@ -1177,6 +1182,9 @@ void cIconvUtil::CloseHandle( iconv_t ic )
/* static */ /* static */
bool cIconvUtil::TestConverter( const char* pTo, const char* pFrom ) bool cIconvUtil::TestConverter( const char* pTo, const char* pFrom )
{ {
if (!pTo || !pFrom)
return false;
cDebug d( "cIconvUtil::TestConverter()" ); cDebug d( "cIconvUtil::TestConverter()" );
iconv_t i = iconv_open( pTo, pFrom ); iconv_t i = iconv_open( pTo, pFrom );