Files
Include/EgtStringConverter.h
Dario Sassi 4ffdb0ce19 Include :
- aggiornamenti prototipi vari.
2020-12-28 18:55:58 +00:00

286 lines
9.1 KiB
C++

//----------------------------------------------------------------------------
// EgalTech 2013-2013
//----------------------------------------------------------------------------
// File : EgtStringConverter.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.
// 15.03.14 DS Agg. classe wcharBuffer per buffer con Windows API.
//
//
//----------------------------------------------------------------------------
#pragma once
//-----------------------------------------------------------------------------
#define NOMINMAX
#include <windows.h>
#include <algorithm>
#include <vector>
//-----------------------------------------------------------------------------
// Funzioni ausiliarie
//-----------------------------------------------------------------------------
template <class _CharType>
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 <class _CharType>
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)
{
// validità parametro
if ( psz == nullptr)
return false ;
// ciclo sulla stringa
const unsigned char* 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 ;
}
//-----------------------------------------------------------------------------
//! Classe per convertire stringhe A (char UTF-8) in stringhe W (wchar_t UTF-16)
//-----------------------------------------------------------------------------
template< int t_nBufferLength = 128>
class AtoWEX
{
public :
AtoWEX( const char* psz) :
m_psz( m_szBuffer)
{
if ( IsTextUtf8( psz))
Init( psz, CP_UTF8) ;
else
Init( psz, CP_ACP) ;
}
AtoWEX( const char* psz, unsigned int nCodePage) :
m_psz( m_szBuffer)
{
Init( psz, nCodePage) ;
}
~AtoWEX( 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 AtoWEX<> AtoW ;
#define stringtoW(s) LPWSTR( AtoW( s.c_str()))
#define strztoW(sz) LPWSTR( AtoW( sz))
//-----------------------------------------------------------------------------
//! Classe per convertire stringhe W (wchar_t UTF-16) in stringhe A (char UTF-8)
//-----------------------------------------------------------------------------
template < int t_nBufferLength = 128>
class WtoAEX
{
public :
WtoAEX( const wchar_t* psz) :
m_psz( m_szBuffer)
{
Init( psz, CP_UTF8) ;
}
WtoAEX( const wchar_t* psz, unsigned int nCodePage) :
m_psz( m_szBuffer)
{
Init( psz, nCodePage) ;
}
~WtoAEX( 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 = ( 2 * nLengthW >= t_nBufferLength ? 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 WtoAEX<> WtoA ;
#define wstringtoA(ws) LPSTR( WtoA( ws.c_str()))
#define wstrztoA(wsz) LPSTR( WtoA( wsz))
//-----------------------------------------------------------------------------
//! Classe contenente un buffer di wchar_t da passare alle funzioni Unicode delle API
//! di Windows, con metodo per terminarlo e macro per convertirlo in char UTF-8.<BR>
//! Esempio di utilizzo :<PRE>
//! wcharBuffer wBuffer( nLen) ;
//! int nChar = GetLine( nCurrLine, wBuffer.data(), nLen) ;
//! wBuffer.terminate( nChar) ;
//! string sCmd = wcharBtoA( wBuffer) ; </PRE>
//----------------------------------------------------------------------------
class wcharBuffer
{
public :
wcharBuffer( size_t nDim)
{ m_wBuffer.resize( nDim) ; }
wchar_t* data( void)
{ return m_wBuffer.data() ; }
void terminate( size_t nLen)
{ nLen = ( nLen <= m_wBuffer.size() - 1 ? nLen : m_wBuffer.size() - 1) ;
m_wBuffer[nLen] = '\0' ; }
private :
std::vector<wchar_t> m_wBuffer ;
} ;
#define wcharBtoA(wcB) LPSTR( WtoA( wcB.data()))