char CPL_DLL *CPLRecode( const char *pszSource, const char *pszSrcEncoding, const char *pszDstEncoding ) { /* -------------------------------------------------------------------- */ /* Handle a few common short cuts. */ /* -------------------------------------------------------------------- */ if ( EQUAL(pszSrcEncoding, pszDstEncoding) ) return CPLStrdup(pszSource); if ( EQUAL(pszSrcEncoding, CPL_ENC_ASCII) && ( EQUAL(pszDstEncoding, CPL_ENC_UTF8) || EQUAL(pszDstEncoding, CPL_ENC_ISO8859_1) ) ) return CPLStrdup(pszSource); #ifdef CPL_RECODE_ICONV /* -------------------------------------------------------------------- */ /* CPL_ENC_ISO8859_1 -> CPL_ENC_UTF8 */ /* and CPL_ENC_UTF8 -> CPL_ENC_ISO8859_1 conversions are hadled */ /* very well by the stub implementation which is faster than the */ /* iconv() route. Use a stub for these two ones and iconv() */ /* everything else. */ /* -------------------------------------------------------------------- */ if ( ( EQUAL(pszSrcEncoding, CPL_ENC_ISO8859_1) && EQUAL(pszDstEncoding, CPL_ENC_UTF8) ) || ( EQUAL(pszSrcEncoding, CPL_ENC_UTF8) && EQUAL(pszDstEncoding, CPL_ENC_ISO8859_1) ) ) { return CPLRecodeStub( pszSource, pszSrcEncoding, pszDstEncoding ); } else { return CPLRecodeIconv( pszSource, pszSrcEncoding, pszDstEncoding ); } #else /* CPL_RECODE_STUB */ return CPLRecodeStub( pszSource, pszSrcEncoding, pszDstEncoding ); #endif /* CPL_RECODE_ICONV */ }
wchar_t *CPLRecodeToWCharStub( const char *pszSource, const char *pszSrcEncoding, const char *pszDstEncoding ) { char *pszUTF8Source = (char *) pszSource; if( strcmp(pszSrcEncoding,CPL_ENC_UTF8) != 0 && strcmp(pszSrcEncoding,CPL_ENC_ASCII) != 0 ) { pszUTF8Source = CPLRecodeStub( pszSource, pszSrcEncoding, CPL_ENC_UTF8 ); if( pszUTF8Source == NULL ) return NULL; } /* -------------------------------------------------------------------- */ /* We try to avoid changes of character set. We are just */ /* providing for unicode to unicode. */ /* -------------------------------------------------------------------- */ if( strcmp(pszDstEncoding,"WCHAR_T") != 0 && strcmp(pszDstEncoding,CPL_ENC_UCS2) != 0 && strcmp(pszDstEncoding,CPL_ENC_UCS4) != 0 && strcmp(pszDstEncoding,CPL_ENC_UTF16) != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Stub recoding implementation does not support\n" "CPLRecodeToWCharStub(...,%s,%s)", pszSrcEncoding, pszDstEncoding ); return NULL; } /* -------------------------------------------------------------------- */ /* Do the UTF-8 to UCS-2 recoding. */ /* -------------------------------------------------------------------- */ int nSrcLen = strlen(pszUTF8Source); wchar_t *pwszResult = (wchar_t *) CPLCalloc(sizeof(wchar_t),nSrcLen+1); utf8towc( pszUTF8Source, nSrcLen, pwszResult, nSrcLen+1 ); if( pszUTF8Source != pszSource ) CPLFree( pszUTF8Source ); return pwszResult; }
char *CPLRecodeFromWCharStub( const wchar_t *pwszSource, const char *pszSrcEncoding, const char *pszDstEncoding ) { /* -------------------------------------------------------------------- */ /* We try to avoid changes of character set. We are just */ /* providing for unicode to unicode. */ /* -------------------------------------------------------------------- */ if( strcmp(pszSrcEncoding,"WCHAR_T") != 0 && strcmp(pszSrcEncoding,CPL_ENC_UTF8) != 0 && strcmp(pszSrcEncoding,CPL_ENC_UTF16) != 0 && strcmp(pszSrcEncoding,CPL_ENC_UCS2) != 0 && strcmp(pszSrcEncoding,CPL_ENC_UCS4) != 0 ) { CPLError( CE_Failure, CPLE_AppDefined, "Stub recoding implementation does not support\n" "CPLRecodeFromWCharStub(...,%s,%s)", pszSrcEncoding, pszDstEncoding ); return NULL; } /* -------------------------------------------------------------------- */ /* What is the source length. */ /* -------------------------------------------------------------------- */ int nSrcLen = 0; while( pwszSource[nSrcLen] != 0 ) nSrcLen++; /* -------------------------------------------------------------------- */ /* Allocate destination buffer plenty big. */ /* -------------------------------------------------------------------- */ char *pszResult; int nDstBufSize, nDstLen; nDstBufSize = nSrcLen * 4 + 1; pszResult = (char *) CPLMalloc(nDstBufSize); // nearly worst case. /* -------------------------------------------------------------------- */ /* Convert, and confirm we had enough space. */ /* -------------------------------------------------------------------- */ nDstLen = utf8fromwc( pszResult, nDstBufSize, pwszSource, nSrcLen ); if( nDstLen >= nDstBufSize - 1 ) { CPLAssert( FALSE ); // too small! return NULL; } /* -------------------------------------------------------------------- */ /* If something other than UTF-8 was requested, recode now. */ /* -------------------------------------------------------------------- */ if( strcmp(pszDstEncoding,CPL_ENC_UTF8) == 0 ) return pszResult; char *pszFinalResult = CPLRecodeStub( pszResult, CPL_ENC_UTF8, pszDstEncoding ); CPLFree( pszResult ); return pszFinalResult; }