//---------------------------------------------------------------------------- // EgalTech 2013-2013 //---------------------------------------------------------------------------- // File : EgnStringConverter.h Data : 10.02.13 Versione : 1.3a1 // Contenuto : Insieme di classi per convertire stringhe tra vari formati. // // // // Modifiche : 10.02.13 DS Creazione modulo. // // //---------------------------------------------------------------------------- //----------------------------------------------------------------------------- #include //----------------------------------------------------------------------------- template inline void SmartAllocMemory( _CharType** ppBuff, int nLength, _CharType* pszFixedBuffer, int nFixedBufferLength) { // controlli if ( ppBuff == nullptr) return ; if ( nLength < 0 || pszFixedBuffer == nullptr) { *ppBuff = nullptr ; return ; } // se buffer già allocato, lo rialloco if ( *ppBuff != pszFixedBuffer) { if ( nLength > nFixedBufferLength) { *ppBuff = static_cast<_CharType*>( _recalloc( *ppBuff, nLength,sizeof( _CharType))) ; } else { free( *ppBuff) ; *ppBuff = pszFixedBuffer ; } } // altrimenti buffer non già allocato else { if ( nLength > nFixedBufferLength) { *ppBuff = static_cast<_CharType*>( calloc( nLength, sizeof( _CharType))) ; } else { *ppBuff = pszFixedBuffer ; } } } //----------------------------------------------------------------------------- template inline void SmartFreeMemory( _CharType* pBuff, _CharType* pszFixedBuffer, int nFixedBufferLength) { if ( pBuff != pszFixedBuffer) free( pBuff) ; #if defined( _DEBUG) else memset( pszFixedBuffer, 0xFE, nFixedBufferLength * sizeof(_CharType)) ; #endif } //----------------------------------------------------------------------------- inline bool IsTextUtf8( const char* psz) { const unsigned char* p ; // validità parametro if ( psz == nullptr) return false ; // ciclo sulla stringa p = ( const unsigned char*) psz ; while ( *p != '\0') { // caratteri ASCII if ( 0x00 <= p[0] && p[0] <= 0x7F) p += 1 ; // 2 byte else if ( (0xC2 <= p[0] && p[0] <= 0xDF) && (0x80 <= p[1] && p[1] <= 0xBF) ) p += 2 ; // 3byte else if ( ( // escludo extralunghi p[0] == 0xE0 && ( 0xA0 <= p[1] && p[1] <= 0xBF) && ( 0x80 <= p[2] && p[2] <= 0xBF) ) || ( // normali (( 0xE1 <= p[0] && p[0] <= 0xEC) || p[0] == 0xEE || p[0] == 0xEF) && ( 0x80 <= p[1] && p[1] <= 0xBF) && ( 0x80 <= p[2] && p[2] <= 0xBF) ) || ( // escludo surrogati p[0] == 0xED && ( 0x80 <= p[1] && p[1] <= 0x9F) && ( 0x80 <= p[2] && p[2] <= 0xBF) ) ) p += 3 ; // 4byte else if ( ( // piani 1-3 p[0] == 0xF0 && ( 0x90 <= p[1] && p[1] <= 0xBF) && ( 0x80 <= p[2] && p[2] <= 0xBF) && ( 0x80 <= p[3] && p[3] <= 0xBF) ) || ( // piani 4-15 ( 0xF1 <= p[0] && p[0] <= 0xF3) && ( 0x80 <= p[1] && p[1] <= 0xBF) && ( 0x80 <= p[2] && p[2] <= 0xBF) && ( 0x80 <= p[3] && p[3] <= 0xBF) ) || ( // piano 16 p[0] == 0xF4 && ( 0x80 <= p[1] && p[1] <= 0x8F) && ( 0x80 <= p[2] && p[2] <= 0xBF) && ( 0x80 <= p[3] && p[3] <= 0xBF) ) ) p += 4 ; // non validi else return false ; } return true ; } //----------------------------------------------------------------------------- template< int t_nBufferLength = 128 > class CAtoWEX { public : CAtoWEX( const char* psz) : m_psz( m_szBuffer) { if ( IsTextUtf8( psz)) Init( psz, CP_UTF8) ; else Init( psz, CP_ACP) ; } CAtoWEX( const char* psz, unsigned int nCodePage) : m_psz( m_szBuffer) { Init( psz, nCodePage) ; } ~CAtoWEX( void) { SmartFreeMemory( m_psz, m_szBuffer, t_nBufferLength) ; } operator LPWSTR( void) { return ( m_psz) ; } private : void Init( const char* psz, unsigned int nCodePage) { if ( psz == nullptr) { m_psz = nullptr ; return ; } int nLengthA = lstrlenA( psz) + 1 ; int nLengthW = nLengthA ; SmartAllocMemory( &m_psz, nLengthW, m_szBuffer, t_nBufferLength) ; BOOL bFailed = ( MultiByteToWideChar( nCodePage, 0, psz, nLengthA, m_psz, nLengthW) == 0) ; if ( bFailed) { if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER) { nLengthW = ::MultiByteToWideChar( nCodePage, 0, psz, nLengthA, nullptr, 0) ; SmartAllocMemory( &m_psz, nLengthW, m_szBuffer, t_nBufferLength) ; bFailed =( MultiByteToWideChar( nCodePage, 0, psz, nLengthA, m_psz, nLengthW) == 0) ; } } if ( bFailed) m_psz = nullptr ; } public : wchar_t* m_psz ; wchar_t m_szBuffer[t_nBufferLength] ; } ; typedef CAtoWEX<> CAtoW ; #define stringtoW(s) LPWSTR( CAtoW( s.c_str())) //----------------------------------------------------------------------------- template < int t_nBufferLength = 128 > class CWtoAEX { public : CWtoAEX( const wchar_t* psz) : m_psz( m_szBuffer) { Init( psz, CP_UTF8) ; } CWtoAEX( const wchar_t* psz, unsigned int nCodePage) : m_psz( m_szBuffer) { Init( psz, nCodePage) ; } ~CWtoAEX( void) { SmartFreeMemory( m_psz, m_szBuffer, t_nBufferLength) ; } operator LPSTR( void) { return ( m_psz) ; } int GetLength( void) { return strlen( m_psz) ; } private : void Init( const wchar_t* psz, unsigned int nCodePage) { if ( psz == nullptr) { m_psz = nullptr ; return ; } int nLengthW = lstrlenW( psz) + 1 ; int nLengthA = max( 2 * nLengthW, t_nBufferLength) ; SmartAllocMemory( &m_psz, nLengthA, m_szBuffer, t_nBufferLength) ; BOOL bFailed = ( WideCharToMultiByte( nCodePage, 0, psz, nLengthW, m_psz, nLengthA, nullptr, nullptr) == 0) ; if ( bFailed) { if ( GetLastError() == ERROR_INSUFFICIENT_BUFFER) { nLengthA = ::WideCharToMultiByte( nCodePage, 0, psz, nLengthW, nullptr, 0, nullptr, nullptr) ; SmartAllocMemory( &m_psz, nLengthA, m_szBuffer, t_nBufferLength) ; bFailed = ( WideCharToMultiByte( nCodePage, 0, psz, nLengthW, m_psz, nLengthA, nullptr, nullptr) == 0) ; } } if ( bFailed) m_psz = nullptr ; } public : char* m_psz ; char m_szBuffer[t_nBufferLength] ; } ; typedef CWtoAEX<> CWtoA ; #define wstringtoA(ws) LPSTR( CWtoA( ws.c_str()))