4ffdb0ce19
- aggiornamenti prototipi vari.
286 lines
9.1 KiB
C++
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()))
|