|
/*
|
|
* $Id: cdpapi.c 16590 2011-04-14 18:20:18Z druzus $
|
|
*/
|
|
|
|
/*
|
|
* Harbour Project source code:
|
|
* The CodePages API
|
|
*
|
|
* Copyright 2002 Alexander S.Kresin <alex@belacy.belgorod.su>
|
|
* Copyright 2009 Przemyslaw Czerpak <druzus / at / priv.onet.pl>
|
|
* www - http://harbour-project.org
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2, or (at your option)
|
|
* any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this software; see the file COPYING. If not, write to
|
|
* the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
|
|
* Boston, MA 02111-1307 USA (or visit the web site http://www.gnu.org/).
|
|
*
|
|
* As a special exception, the Harbour Project gives permission for
|
|
* additional uses of the text contained in its release of Harbour.
|
|
*
|
|
* The exception is that, if you link the Harbour libraries with other
|
|
* files to produce an executable, this does not by itself cause the
|
|
* resulting executable to be covered by the GNU General Public License.
|
|
* Your use of that executable is in no way restricted on account of
|
|
* linking the Harbour library code into it.
|
|
*
|
|
* This exception does not however invalidate any other reasons why
|
|
* the executable file might be covered by the GNU General Public License.
|
|
*
|
|
* This exception applies only to the code released by the Harbour
|
|
* Project under the name Harbour. If you copy code from other
|
|
* Harbour Project or Free Software Foundation releases into a copy of
|
|
* Harbour, as the General Public License permits, the exception does
|
|
* not apply to the code that you add in this way. To avoid misleading
|
|
* anyone as to the status of such modified files, you must delete
|
|
* this exception notice from them.
|
|
*
|
|
* If you write modifications of your own for Harbour, it is your choice
|
|
* whether to permit this exception to apply to your modifications.
|
|
* If you do not wish that, delete this exception notice.
|
|
*
|
|
*/
|
|
|
|
#include "hbapi.h"
|
|
#include "hbapierr.h"
|
|
#include "hbapicdp.h"
|
|
#include "hbthread.h"
|
|
|
|
|
|
/* MT macros */
|
|
#define HB_CDP_LOCK hb_threadEnterCriticalSection( &s_cdpMtx );
|
|
#define HB_CDP_UNLOCK hb_threadLeaveCriticalSection( &s_cdpMtx );
|
|
static HB_CRITICAL_NEW( s_cdpMtx );
|
|
|
|
|
|
#define NUMBER_OF_CHARS 256
|
|
|
|
static const HB_WCHAR s_uniCtrls[ 32 ] =
|
|
{
|
|
0x2007, 0x263A, 0x263B, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
|
|
0x25D8, 0x25CB, 0x25D9, 0x2642, 0x2640, 0x266A, 0x266B, 0x263C,
|
|
0x25BA, 0x25C4, 0x2195, 0x203C, 0x00B6, 0x00A7, 0x25AC, 0x21A8,
|
|
0x2191, 0x2193, 0x2192, 0x2190, 0x221F, 0x2194, 0x25B2, 0x25BC
|
|
};
|
|
|
|
static const HB_WCHAR s_uniCodes[ NUMBER_OF_CHARS ] =
|
|
{
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
|
|
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
|
|
0x0028, 0x0029, 0x002A, 0x002B, 0x002C, 0x002D, 0x002E, 0x002F,
|
|
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
|
|
0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
|
|
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
|
|
0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
|
|
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
|
|
0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x005F,
|
|
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
|
|
0x0068, 0x0069, 0x006A, 0x006B, 0x006C, 0x006D, 0x006E, 0x006F,
|
|
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
|
|
0x0078, 0x0079, 0x007A, 0x007B, 0x007C, 0x007D, 0x007E, 0x007F,
|
|
0x00C7, 0x00FC, 0x00E9, 0x00E2, 0x00E4, 0x00E0, 0x00E5, 0x00E7,
|
|
0x00EA, 0x00EB, 0x00E8, 0x00EF, 0x00EE, 0x00EC, 0x00C4, 0x00C5,
|
|
0x00C9, 0x00E6, 0x00C6, 0x00F4, 0x00F6, 0x00F2, 0x00FB, 0x00F9,
|
|
0x00FF, 0x00D6, 0x00DC, 0x00A2, 0x00A3, 0x00A5, 0x20A7, 0x0192,
|
|
0x00E1, 0x00ED, 0x00F3, 0x00FA, 0x00F1, 0x00D1, 0x00AA, 0x00BA,
|
|
0x00BF, 0x2310, 0x00AC, 0x00BD, 0x00BC, 0x00A1, 0x00AB, 0x00BB,
|
|
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
|
|
0x2555, 0x2563, 0x2551, 0x2557, 0x255D, 0x255C, 0x255B, 0x2510,
|
|
0x2514, 0x2534, 0x252C, 0x251C, 0x2500, 0x253C, 0x255E, 0x255F,
|
|
0x255A, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256C, 0x2567,
|
|
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256B,
|
|
0x256A, 0x2518, 0x250C, 0x2588, 0x2584, 0x258C, 0x2590, 0x2580,
|
|
0x03B1, 0x00DF, 0x0393, 0x03C0, 0x03A3, 0x03C3, 0x00B5, 0x03C4,
|
|
0x03A6, 0x0398, 0x03A9, 0x03B4, 0x221E, 0x03C6, 0x03B5, 0x2229,
|
|
0x2261, 0x00B1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00F7, 0x2248,
|
|
0x00B0, 0x2219, 0x00B7, 0x221A, 0x207F, 0x00B2, 0x25A0, 0x00A0
|
|
};
|
|
|
|
HB_UNITABLE hb_uniTbl_437 = { HB_CPID_437, s_uniCodes, NULL, 0 };
|
|
|
|
static HB_CDP_GET_FUNC( hb_cdpStd_get );
|
|
static HB_CDP_PUT_FUNC( hb_cdpStd_put );
|
|
static HB_CDP_LEN_FUNC( hb_cdpStd_len );
|
|
|
|
static HB_CDP_GET_FUNC( hb_cdpUTF8_get );
|
|
static HB_CDP_PUT_FUNC( hb_cdpUTF8_put );
|
|
static HB_CDP_LEN_FUNC( hb_cdpUTF8_len );
|
|
|
|
HB_UNITABLE hb_uniTbl_UTF8 = { HB_CPID_437, s_uniCodes, NULL, 0 };
|
|
|
|
/* pseudo codepage for translations only */
|
|
static HB_CODEPAGE s_utf8_codepage =
|
|
{ "UTF8", "UTF-8", &hb_uniTbl_UTF8,
|
|
NULL, NULL, NULL, NULL, NULL, 0,
|
|
HB_FALSE, hb_cdpUTF8_get, hb_cdpUTF8_put, hb_cdpUTF8_len,
|
|
0, 0, NULL, NULL, NULL };
|
|
|
|
HB_CODEPAGE_ANNOUNCE( UTF8 )
|
|
|
|
static HB_CODEPAGE s_en_codepage =
|
|
{ "EN", "English CP-437", HB_UNITB_437,
|
|
NULL, NULL, NULL, NULL, NULL, 0,
|
|
HB_FALSE, hb_cdpStd_get, hb_cdpStd_put, hb_cdpStd_len,
|
|
0, 0, NULL, NULL, &s_utf8_codepage };
|
|
|
|
HB_CODEPAGE_ANNOUNCE( EN )
|
|
|
|
static PHB_CODEPAGE s_cdpList = NULL;
|
|
|
|
|
|
/*
|
|
* conversions
|
|
*/
|
|
void hb_cdpBuildTransTable( PHB_UNITABLE uniTable )
|
|
{
|
|
HB_WCHAR wcMax = 0;
|
|
int i;
|
|
|
|
HB_CDP_LOCK
|
|
if( uniTable->uniTrans == NULL )
|
|
{
|
|
HB_UCHAR * uniTrans;
|
|
|
|
for( i = 0; i < 256; ++i )
|
|
{
|
|
HB_WCHAR wc = uniTable->uniCodes[ i ];
|
|
if( wc > wcMax )
|
|
wcMax = wc;
|
|
}
|
|
uniTrans = ( HB_UCHAR * )
|
|
hb_xgrab( ( wcMax + 1 ) * sizeof( HB_UCHAR ) );
|
|
memset( uniTrans, '\0', ( wcMax + 1 ) * sizeof( HB_UCHAR ) );
|
|
for( i = 0; i < 256; ++i )
|
|
{
|
|
if( uniTable->uniCodes[ i ] )
|
|
uniTrans[ uniTable->uniCodes[ i ] ] = ( HB_UCHAR ) i;
|
|
}
|
|
|
|
uniTable->wcMax = wcMax;
|
|
uniTable->uniTrans = uniTrans;
|
|
}
|
|
HB_CDP_UNLOCK
|
|
}
|
|
|
|
/*
|
|
* standard conversion functions
|
|
*/
|
|
static HB_BOOL hb_cdpStd_get( PHB_CODEPAGE cdp,
|
|
const char * pSrc, HB_SIZE nLen,
|
|
HB_SIZE * pnIndex, HB_WCHAR * wc )
|
|
{
|
|
if( *pnIndex < nLen )
|
|
{
|
|
HB_UCHAR uc = ( HB_UCHAR ) pSrc[ ( * pnIndex )++ ];
|
|
|
|
*wc = cdp->uniTable->uniCodes[ uc ];
|
|
if( *wc == 0 )
|
|
*wc = uc;
|
|
|
|
return HB_TRUE;
|
|
}
|
|
return HB_FALSE;
|
|
}
|
|
|
|
static HB_BOOL hb_cdpStd_put( PHB_CODEPAGE cdp,
|
|
char * pDst, HB_SIZE nLen,
|
|
HB_SIZE * pnIndex, HB_WCHAR wc )
|
|
{
|
|
if( *pnIndex < nLen )
|
|
{
|
|
if( cdp->uniTable->uniTrans == NULL )
|
|
hb_cdpBuildTransTable( cdp->uniTable );
|
|
|
|
if( wc <= cdp->uniTable->wcMax &&
|
|
cdp->uniTable->uniTrans[ wc ] )
|
|
pDst[ ( * pnIndex )++ ] = cdp->uniTable->uniTrans[ wc ];
|
|
else
|
|
pDst[ ( * pnIndex )++ ] = wc >= 0x100 ? '?' : ( HB_UCHAR ) wc;
|
|
|
|
return HB_TRUE;
|
|
}
|
|
return HB_FALSE;
|
|
}
|
|
|
|
static int hb_cdpStd_len( PHB_CODEPAGE cdp, HB_WCHAR wc )
|
|
{
|
|
HB_SYMBOL_UNUSED( cdp );
|
|
HB_SYMBOL_UNUSED( wc );
|
|
return 1;
|
|
}
|
|
|
|
static HB_BOOL hb_cdpUTF8_get( PHB_CODEPAGE cdp,
|
|
const char * pSrc, HB_SIZE nLen,
|
|
HB_SIZE * pnIndex, HB_WCHAR * wc )
|
|
{
|
|
HB_SIZE nIndex = *pnIndex;
|
|
int n = 0;
|
|
|
|
HB_SYMBOL_UNUSED( cdp );
|
|
|
|
*wc = 0;
|
|
while( nIndex < nLen )
|
|
{
|
|
if( hb_cdpUTF8ToU16NextChar( ( HB_UCHAR ) pSrc[ nIndex++ ], &n, wc ) )
|
|
{
|
|
if( n == 0 )
|
|
{
|
|
*pnIndex = nIndex;
|
|
return HB_TRUE;
|
|
}
|
|
}
|
|
}
|
|
return HB_FALSE;
|
|
}
|
|
|
|
static HB_BOOL hb_cdpUTF8_put( PHB_CODEPAGE cdp,
|
|
char * pDst, HB_SIZE nLen,
|
|
HB_SIZE * pnIndex, HB_WCHAR wc )
|
|
{
|
|
int i = hb_cdpUTF8CharSize( wc );
|
|
|
|
HB_SYMBOL_UNUSED( cdp );
|
|
|
|
if( *pnIndex + i <= nLen )
|
|
{
|
|
hb_cdpU16CharToUTF8( &pDst[ *pnIndex ], wc );
|
|
*pnIndex += i;
|
|
return HB_TRUE;
|
|
}
|
|
return HB_FALSE;
|
|
}
|
|
|
|
static int hb_cdpUTF8_len( PHB_CODEPAGE cdp, HB_WCHAR wc )
|
|
{
|
|
HB_SYMBOL_UNUSED( cdp );
|
|
|
|
return hb_cdpUTF8CharSize( wc );
|
|
}
|
|
|
|
static HB_BOOL hb_cdpMulti_get( PHB_CODEPAGE cdp,
|
|
const char * pSrc, HB_SIZE nLen,
|
|
HB_SIZE * pnIndex, HB_WCHAR * wc )
|
|
{
|
|
if( *pnIndex < nLen )
|
|
{
|
|
HB_UCHAR uc = ( HB_UCHAR ) pSrc[ ( * pnIndex )++ ];
|
|
|
|
*wc = cdp->uniTable->uniCodes[ uc ];
|
|
if( *wc == 0 )
|
|
*wc = uc;
|
|
else if( ( cdp->flags[ uc ] & HB_CDP_MULTI1 ) != 0 &&
|
|
*pnIndex < nLen )
|
|
{
|
|
HB_UCHAR uc2 = ( HB_UCHAR ) pSrc[ *pnIndex + 1 ];
|
|
if( ( cdp->flags[ uc2 ] & HB_CDP_MULTI2 ) != 0 )
|
|
{
|
|
int i;
|
|
for( i = 0; i < cdp->nMulti; ++i )
|
|
{
|
|
if( uc2 == cdp->multi[ i ].cLast[ 0 ] ||
|
|
uc2 == cdp->multi[ i ].cLast[ 1 ] )
|
|
{
|
|
if( uc == cdp->multi[ i ].cFirst[ 0 ] )
|
|
{
|
|
if( cdp->multi[ i ].wcUp )
|
|
{
|
|
*wc = cdp->multi[ i ].wcUp;
|
|
++( * pnIndex );
|
|
}
|
|
break;
|
|
}
|
|
else if( uc == cdp->multi[ i ].cFirst[ 1 ] )
|
|
{
|
|
if( cdp->multi[ i ].wcLo )
|
|
{
|
|
*wc = cdp->multi[ i ].wcLo;
|
|
++( * pnIndex );
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return HB_TRUE;
|
|
}
|
|
return HB_FALSE;
|
|
}
|
|
|
|
static HB_BOOL hb_cdpMulti_put( PHB_CODEPAGE cdp,
|
|
char * pDst, HB_SIZE nLen,
|
|
HB_SIZE * pnIndex, HB_WCHAR wc )
|
|
{
|
|
if( *pnIndex < nLen )
|
|
{
|
|
if( cdp->uniTable->uniTrans == NULL )
|
|
hb_cdpBuildTransTable( cdp->uniTable );
|
|
|
|
if( wc <= cdp->uniTable->wcMax && cdp->uniTable->uniTrans[ wc ] )
|
|
pDst[ ( * pnIndex )++ ] = cdp->uniTable->uniTrans[ wc ];
|
|
else if( wc == 0 )
|
|
pDst[ ( * pnIndex )++ ] = 0;
|
|
else
|
|
{
|
|
int i;
|
|
for( i = 0; i < cdp->nMulti; ++i )
|
|
{
|
|
if( wc == cdp->multi[ i ].wcUp )
|
|
{
|
|
pDst[ ( * pnIndex )++ ] = cdp->multi[ i ].cFirst[ 0 ];
|
|
if( *pnIndex < nLen )
|
|
pDst[ ( * pnIndex )++ ] = cdp->multi[ i ].cLast[ 0 ];
|
|
return HB_TRUE;
|
|
}
|
|
if( wc == cdp->multi[ i ].wcLo )
|
|
{
|
|
pDst[ ( * pnIndex )++ ] = cdp->multi[ i ].cFirst[ 1 ];
|
|
if( *pnIndex < nLen )
|
|
pDst[ ( * pnIndex )++ ] = cdp->multi[ i ].cLast[ 1 ];
|
|
return HB_TRUE;
|
|
}
|
|
}
|
|
pDst[ ( * pnIndex )++ ] = wc >= 0x100 ? '?' : ( HB_UCHAR ) wc;
|
|
}
|
|
return HB_TRUE;
|
|
}
|
|
return HB_FALSE;
|
|
}
|
|
|
|
static int hb_cdpMulti_len( PHB_CODEPAGE cdp, HB_WCHAR wc )
|
|
{
|
|
int i, n = 1;
|
|
|
|
if( wc ) for( i = 0; i < cdp->nMulti; ++i )
|
|
{
|
|
if( wc == cdp->multi[ i ].wcUp ||
|
|
wc == cdp->multi[ i ].wcLo )
|
|
{
|
|
++n;
|
|
break;
|
|
}
|
|
}
|
|
return n;
|
|
}
|
|
|
|
|
|
/*
|
|
* basic CP functions
|
|
*/
|
|
HB_BOOL hb_cdpIsDigit( PHB_CODEPAGE cdp, int iChar )
|
|
{
|
|
if( cdp )
|
|
return ( cdp->flags[ iChar & 0x0ff ] & HB_CDP_DIGIT ) != 0;
|
|
else
|
|
return HB_ISDIGIT( iChar );
|
|
}
|
|
|
|
HB_BOOL hb_cdpIsAlpha( PHB_CODEPAGE cdp, int iChar )
|
|
{
|
|
if( cdp )
|
|
return ( cdp->flags[ iChar & 0x0ff ] & HB_CDP_ALPHA ) != 0;
|
|
else
|
|
return HB_ISALPHA( iChar );
|
|
}
|
|
|
|
HB_BOOL hb_cdpIsLower( PHB_CODEPAGE cdp, int iChar )
|
|
{
|
|
if( cdp )
|
|
return ( cdp->flags[ iChar & 0x0ff ] & HB_CDP_LOWER ) != 0;
|
|
else
|
|
return HB_ISLOWER( iChar );
|
|
}
|
|
|
|
HB_BOOL hb_cdpIsUpper( PHB_CODEPAGE cdp, int iChar )
|
|
{
|
|
if( cdp )
|
|
return ( cdp->flags[ iChar & 0x0ff ] & HB_CDP_UPPER ) != 0;
|
|
else
|
|
return HB_ISUPPER( iChar );
|
|
}
|
|
|
|
HB_BOOL hb_charIsDigit( int iChar )
|
|
{
|
|
PHB_CODEPAGE cdp = hb_vmCDP();
|
|
|
|
if( cdp )
|
|
return ( cdp->flags[ iChar & 0x0ff ] & HB_CDP_DIGIT ) != 0;
|
|
else
|
|
return HB_ISDIGIT( iChar );
|
|
}
|
|
|
|
HB_BOOL hb_charIsAlpha( int iChar )
|
|
{
|
|
PHB_CODEPAGE cdp = hb_vmCDP();
|
|
|
|
if( cdp )
|
|
return ( cdp->flags[ iChar & 0x0ff ] & HB_CDP_ALPHA ) != 0;
|
|
else
|
|
return HB_ISALPHA( iChar );
|
|
}
|
|
|
|
HB_BOOL hb_charIsLower( int iChar )
|
|
{
|
|
PHB_CODEPAGE cdp = hb_vmCDP();
|
|
|
|
if( cdp )
|
|
return ( cdp->flags[ iChar & 0x0ff ] & HB_CDP_LOWER ) != 0;
|
|
else
|
|
return HB_ISLOWER( iChar );
|
|
}
|
|
|
|
HB_BOOL hb_charIsUpper( int iChar )
|
|
{
|
|
PHB_CODEPAGE cdp = hb_vmCDP();
|
|
|
|
if( cdp )
|
|
return ( cdp->flags[ iChar & 0x0ff ] & HB_CDP_UPPER ) != 0;
|
|
else
|
|
return HB_ISUPPER( iChar );
|
|
}
|
|
|
|
int hb_charLower( int iChar )
|
|
{
|
|
PHB_CODEPAGE cdp = hb_vmCDP();
|
|
|
|
if( cdp )
|
|
return cdp->lower[ iChar & 0x0ff ];
|
|
else
|
|
return HB_TOLOWER( iChar );
|
|
}
|
|
|
|
int hb_charUpper( int iChar )
|
|
{
|
|
PHB_CODEPAGE cdp = hb_vmCDP();
|
|
|
|
if( cdp )
|
|
return cdp->upper[ iChar & 0x0ff ];
|
|
else
|
|
return HB_TOUPPER( iChar );
|
|
}
|
|
|
|
char * hb_strLower( char * szText, HB_SIZE nLen )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_strLower(%s, %" HB_PFS "u)", szText, nLen));
|
|
|
|
{
|
|
PHB_CODEPAGE cdp = hb_vmCDP();
|
|
HB_SIZE u;
|
|
|
|
if( cdp )
|
|
for( u = 0; u < nLen; u++ )
|
|
szText[ u ] = ( char ) cdp->lower[ ( HB_UCHAR ) szText[ u ] ];
|
|
else
|
|
for( u = 0; u < nLen; u++ )
|
|
szText[ u ] = HB_TOLOWER( szText[ u ] );
|
|
}
|
|
|
|
return szText;
|
|
}
|
|
|
|
char * hb_strUpper( char * szText, HB_SIZE nLen )
|
|
{
|
|
HB_TRACE(HB_TR_DEBUG, ("hb_strUpper(%s, %" HB_PFS "u)", szText, nLen));
|
|
|
|
{
|
|
PHB_CODEPAGE cdp = hb_vmCDP();
|
|
HB_SIZE u;
|
|
|
|
if( cdp )
|
|
for( u = 0; u < nLen; u++ )
|
|
szText[ u ] = ( char ) cdp->upper[ ( HB_UCHAR ) szText[ u ] ];
|
|
else
|
|
for( u = 0; u < nLen; u++ )
|
|
szText[ u ] = HB_TOUPPER( szText[ u ] );
|
|
}
|
|
|
|
return szText;
|
|
}
|
|
|
|
/*
|
|
* comparison
|
|
*/
|
|
int hb_cdpchrcmp( char cFirst, char cSecond, PHB_CODEPAGE cdp )
|
|
{
|
|
if( cFirst == cSecond )
|
|
return 0;
|
|
|
|
if( cdp->sort )
|
|
{
|
|
int n1 = cdp->sort[ ( HB_UCHAR ) cFirst ],
|
|
n2 = cdp->sort[ ( HB_UCHAR ) cSecond ];
|
|
|
|
if( cdp->nMulti == 0 || ( n1 != 0 && n2 != 0 ) )
|
|
{
|
|
if( n1 == n2 )
|
|
{
|
|
if( cdp->acc )
|
|
{
|
|
n1 = cdp->acc[ ( HB_UCHAR ) cFirst ];
|
|
n2 = cdp->acc[ ( HB_UCHAR ) cSecond ];
|
|
}
|
|
else
|
|
return 0;
|
|
}
|
|
return ( n1 < n2 ) ? -1 : 1;
|
|
}
|
|
}
|
|
|
|
return ( ( HB_UCHAR ) cFirst < ( HB_UCHAR ) cSecond ) ? -1 : 1;
|
|
}
|
|
|
|
static int hb_cdpMultiWeight( PHB_CODEPAGE cdp, const char * szChar )
|
|
{
|
|
PHB_MULTICHAR pmulti = cdp->multi;
|
|
int i;
|
|
|
|
for( i = cdp->nMulti; i; --i, ++pmulti )
|
|
{
|
|
if( ( szChar[ 0 ] == pmulti->cFirst[ 0 ] ||
|
|
szChar[ 0 ] == pmulti->cFirst[ 1 ] ) &&
|
|
( szChar[ 1 ] == pmulti->cLast[ 0 ] ||
|
|
szChar[ 1 ] == pmulti->cLast[ 1 ] ) )
|
|
{
|
|
return ( szChar[ 0 ] == pmulti->cFirst[ 0 ] ) ?
|
|
pmulti->sortUp : pmulti->sortLo;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int hb_cdpcmp( const char * szFirst, HB_SIZE nLenFirst,
|
|
const char * szSecond, HB_SIZE nLenSecond,
|
|
PHB_CODEPAGE cdp, HB_BOOL fExact )
|
|
{
|
|
int iRet = 0, iAcc = 0, n, n1, n2;
|
|
HB_SIZE ul, nLen;
|
|
|
|
nLen = nLenFirst < nLenSecond ? nLenFirst : nLenSecond;
|
|
if( cdp->sort == NULL )
|
|
{
|
|
iRet = memcmp( szFirst, szSecond, nLen );
|
|
}
|
|
else if( cdp->nMulti )
|
|
{
|
|
for( ul = 0; ul < nLen; ++szFirst, ++szSecond, ++ul )
|
|
{
|
|
HB_UCHAR u1 = ( HB_UCHAR ) * szFirst;
|
|
HB_UCHAR u2 = ( HB_UCHAR ) * szSecond;
|
|
|
|
n1 = cdp->sort[ u1 ];
|
|
if( ( cdp->flags[ u1 ] & HB_CDP_MULTI1 ) != 0 &&
|
|
( ul < nLenFirst - 1 ) &&
|
|
( cdp->flags[ ( HB_UCHAR ) szFirst[ 1 ] ] & HB_CDP_MULTI2 ) != 0 )
|
|
{
|
|
n = hb_cdpMultiWeight( cdp, szFirst );
|
|
if( n != 0 )
|
|
{
|
|
n1 = n;
|
|
++szFirst;
|
|
if( --nLenFirst < nLen )
|
|
nLen = nLenFirst;
|
|
}
|
|
}
|
|
n2 = cdp->sort[ u2 ];
|
|
if( ( cdp->flags[ u2 ] & HB_CDP_MULTI1 ) != 0 &&
|
|
( ul < nLenSecond - 1 ) &&
|
|
( cdp->flags[ ( HB_UCHAR ) szSecond[ 1 ] ] & HB_CDP_MULTI2 ) != 0 )
|
|
{
|
|
n = hb_cdpMultiWeight( cdp, szSecond );
|
|
if( n != 0 )
|
|
{
|
|
n2 = n;
|
|
++szSecond;
|
|
if( --nLenSecond < nLen )
|
|
nLen = nLenSecond;
|
|
}
|
|
}
|
|
if( n1 != n2 )
|
|
{
|
|
if( n1 == 0 || n2 == 0 )
|
|
/* One of characters doesn't belong to the national characters */
|
|
iRet = ( u1 < u2 ) ? -1 : 1;
|
|
else
|
|
iRet = ( n1 < n2 ) ? -1 : 1;
|
|
break;
|
|
}
|
|
else if( u1 != u2 )
|
|
{
|
|
if( n1 == 0 )
|
|
{
|
|
iRet = ( u1 < u2 ) ? -1 : 1;
|
|
break;
|
|
}
|
|
if( iAcc == 0 && ( fExact || ( nLenFirst == nLenSecond && cdp->acc ) ) )
|
|
{
|
|
if( cdp->acc )
|
|
iAcc = ( cdp->acc[ u1 ] < cdp->acc[ u2 ] ) ? -1 : 1;
|
|
else
|
|
iAcc = ( u1 < u2 ) ? -1 : 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( ul = 0; ul < nLen; ++szFirst, ++szSecond, ++ul )
|
|
{
|
|
if( *szFirst != *szSecond )
|
|
{
|
|
n1 = ( HB_UCHAR ) cdp->sort[ ( HB_UCHAR ) * szFirst ];
|
|
n2 = ( HB_UCHAR ) cdp->sort[ ( HB_UCHAR ) * szSecond ];
|
|
if( n1 != n2 )
|
|
{
|
|
iRet = ( n1 < n2 ) ? -1 : 1;
|
|
break;
|
|
}
|
|
if( iAcc == 0 && ( fExact || ( nLenFirst == nLenSecond && cdp->acc ) ) )
|
|
{
|
|
if( cdp->acc )
|
|
iAcc = ( cdp->acc[ ( HB_UCHAR ) * szFirst ] <
|
|
cdp->acc[ ( HB_UCHAR ) * szSecond ] ) ? -1 : 1;
|
|
else
|
|
iAcc = ( ( HB_UCHAR ) * szFirst < ( HB_UCHAR ) * szSecond ) ? -1 : 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( !iRet )
|
|
{
|
|
if( iAcc )
|
|
iRet = iAcc;
|
|
else if( nLenSecond > nLenFirst )
|
|
iRet = -1;
|
|
else if( fExact && nLenSecond < nLenFirst )
|
|
iRet = 1;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
static int hb_cdpMultiWeightI( PHB_CODEPAGE cdp, const char * szChar )
|
|
{
|
|
PHB_MULTICHAR pmulti = cdp->multi;
|
|
int i;
|
|
|
|
for( i = cdp->nMulti; i; --i, ++pmulti )
|
|
{
|
|
if( ( szChar[ 0 ] == pmulti->cFirst[ 0 ] ||
|
|
szChar[ 0 ] == pmulti->cFirst[ 1 ] ) &&
|
|
( szChar[ 1 ] == pmulti->cLast[ 0 ] ||
|
|
szChar[ 1 ] == pmulti->cLast[ 1 ] ) )
|
|
{
|
|
return pmulti->sortUp;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int hb_cdpicmp( const char * szFirst, HB_SIZE nLenFirst,
|
|
const char * szSecond, HB_SIZE nLenSecond,
|
|
PHB_CODEPAGE cdp, HB_BOOL fExact )
|
|
{
|
|
int iRet = 0, iAcc = 0, n, n1, n2, u1, u2;
|
|
HB_SIZE ul, nLen;
|
|
|
|
nLen = nLenFirst < nLenSecond ? nLenFirst : nLenSecond;
|
|
if( cdp->sort == NULL )
|
|
{
|
|
for( ul = 0; ul < nLen; ++szFirst, ++szSecond, ++ul )
|
|
{
|
|
u1 = cdp->upper[ ( HB_UCHAR ) * szFirst ];
|
|
u2 = cdp->upper[ ( HB_UCHAR ) * szSecond ];
|
|
if( u1 != u2 )
|
|
{
|
|
iRet = ( u1 < u2 ) ? -1 : 1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else if( cdp->nMulti )
|
|
{
|
|
for( ul = 0; ul < nLen; ++szFirst, ++szSecond, ++ul )
|
|
{
|
|
u1 = cdp->upper[ ( HB_UCHAR ) * szFirst ];
|
|
u2 = cdp->upper[ ( HB_UCHAR ) * szSecond ];
|
|
|
|
if( ( cdp->flags[ u1 ] & HB_CDP_MULTI1 ) != 0 &&
|
|
( ul < nLenFirst - 1 ) &&
|
|
( cdp->flags[ ( HB_UCHAR ) szFirst[ 1 ] ] & HB_CDP_MULTI2 ) != 0 )
|
|
{
|
|
n = hb_cdpMultiWeightI( cdp, szFirst );
|
|
if( n != 0 )
|
|
{
|
|
n1 = n;
|
|
++szFirst;
|
|
if( --nLenFirst < nLen )
|
|
nLen = nLenFirst;
|
|
}
|
|
else
|
|
n1 = cdp->sort[ u1 ];
|
|
}
|
|
else
|
|
n1 = cdp->sort[ u1 ];
|
|
|
|
if( ( cdp->flags[ u2 ] & HB_CDP_MULTI1 ) != 0 &&
|
|
( ul < nLenSecond - 1 ) &&
|
|
( cdp->flags[ ( HB_UCHAR ) szSecond[ 1 ] ] & HB_CDP_MULTI2 ) != 0 )
|
|
{
|
|
n = hb_cdpMultiWeightI( cdp, szSecond );
|
|
if( n != 0 )
|
|
{
|
|
n2 = n;
|
|
++szSecond;
|
|
if( --nLenSecond < nLen )
|
|
nLen = nLenSecond;
|
|
}
|
|
else
|
|
n2 = cdp->sort[ u2 ];
|
|
}
|
|
else
|
|
n2 = cdp->sort[ u2 ];
|
|
|
|
if( n1 != n2 )
|
|
{
|
|
if( n1 == 0 || n2 == 0 )
|
|
/* One of characters doesn't belong to the national characters */
|
|
iRet = ( u1 < u2 ) ? -1 : 1;
|
|
else
|
|
iRet = ( n1 < n2 ) ? -1 : 1;
|
|
break;
|
|
}
|
|
else if( u1 != u2 )
|
|
{
|
|
if( n1 == 0 )
|
|
{
|
|
iRet = ( u1 < u2 ) ? -1 : 1;
|
|
break;
|
|
}
|
|
if( iAcc == 0 && ( fExact || ( nLenFirst == nLenSecond && cdp->acc ) ) )
|
|
{
|
|
if( cdp->acc )
|
|
iAcc = ( cdp->acc[ u1 ] < cdp->acc[ u2 ] ) ? -1 : 1;
|
|
else
|
|
iAcc = ( u1 < u2 ) ? -1 : 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( ul = 0; ul < nLen; ++szFirst, ++szSecond, ++ul )
|
|
{
|
|
u1 = cdp->upper[ ( HB_UCHAR ) * szFirst ];
|
|
u2 = cdp->upper[ ( HB_UCHAR ) * szSecond ];
|
|
|
|
if( u1 != u2 )
|
|
{
|
|
n1 = ( HB_UCHAR ) cdp->sort[ u1 ];
|
|
n2 = ( HB_UCHAR ) cdp->sort[ u2 ];
|
|
if( n1 != n2 )
|
|
{
|
|
iRet = ( n1 < n2 ) ? -1 : 1;
|
|
break;
|
|
}
|
|
if( iAcc == 0 && ( fExact || ( nLenFirst == nLenSecond && cdp->acc ) ) )
|
|
{
|
|
if( cdp->acc )
|
|
iAcc = ( cdp->acc[ u1 ] < cdp->acc[ u2 ] ) ? -1 : 1;
|
|
else
|
|
iAcc = ( u1 < u2 ) ? -1 : 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( !iRet )
|
|
{
|
|
if( iAcc )
|
|
iRet = iAcc;
|
|
else if( nLenSecond > nLenFirst )
|
|
iRet = -1;
|
|
else if( fExact && nLenSecond < nLenFirst )
|
|
iRet = 1;
|
|
}
|
|
|
|
return iRet;
|
|
}
|
|
|
|
/*
|
|
* UTF8 conversions
|
|
*/
|
|
int hb_cdpUTF8CharSize( HB_WCHAR wc )
|
|
{
|
|
if( wc < 0x0080 )
|
|
return 1;
|
|
else if( wc < 0x0800 )
|
|
return 2;
|
|
else /* if( wc <= 0xffff ) */
|
|
return 3;
|
|
}
|
|
|
|
int hb_cdpU16CharToUTF8( char * szUTF8, HB_WCHAR wc )
|
|
{
|
|
int n;
|
|
|
|
if( wc < 0x0080 )
|
|
{
|
|
szUTF8[0] = wc & 0xff;
|
|
n = 1;
|
|
}
|
|
else if( wc < 0x0800 )
|
|
{
|
|
szUTF8[0] = 0xc0 | ( ( wc >> 6 ) & 0x1f );
|
|
szUTF8[1] = 0x80 | ( wc & 0x3f );
|
|
n = 2;
|
|
}
|
|
else /* if( wc <= 0xffff ) */
|
|
{
|
|
szUTF8[0] = 0xe0 | ( ( wc >> 12 ) & 0x0f );
|
|
szUTF8[1] = 0x80 | ( ( wc >> 6 ) & 0x3f );
|
|
szUTF8[2] = 0x80 | ( wc & 0x3f );
|
|
n = 3;
|
|
}
|
|
/*
|
|
else
|
|
{
|
|
n = 0;
|
|
}
|
|
*/
|
|
return n;
|
|
}
|
|
|
|
HB_BOOL hb_cdpUTF8ToU16NextChar( HB_UCHAR ucChar, int * n, HB_WCHAR * pwc )
|
|
{
|
|
if( *n > 0 )
|
|
{
|
|
if( ( ucChar & 0xc0 ) != 0x80 )
|
|
return HB_FALSE;
|
|
*pwc = ( *pwc << 6 ) | ( ucChar & 0x3f );
|
|
( *n )--;
|
|
return HB_TRUE;
|
|
}
|
|
|
|
*n = 0;
|
|
*pwc = ucChar;
|
|
if( ucChar >= 0xc0 )
|
|
{
|
|
if( ucChar < 0xe0 )
|
|
{
|
|
*pwc &= 0x1f;
|
|
*n = 1;
|
|
}
|
|
else if( ucChar < 0xf0 )
|
|
{
|
|
*pwc &= 0x0f;
|
|
*n = 2;
|
|
}
|
|
else if( ucChar < 0xf8 )
|
|
{
|
|
*pwc &= 0x07;
|
|
*n = 3;
|
|
}
|
|
else if( ucChar < 0xfc )
|
|
{
|
|
*pwc &= 0x03;
|
|
*n = 4;
|
|
}
|
|
else if( ucChar < 0xfe )
|
|
{
|
|
*pwc &= 0x01;
|
|
*n = 5;
|
|
}
|
|
}
|
|
return HB_TRUE;
|
|
}
|
|
|
|
HB_SIZE hb_cdpUTF8StringLength( const char * pSrc, HB_SIZE nLen )
|
|
{
|
|
HB_SIZE ul, nDst;
|
|
HB_WCHAR wc;
|
|
int n = 0;
|
|
|
|
for( ul = nDst = 0; ul < nLen; ++ul )
|
|
{
|
|
if( hb_cdpUTF8ToU16NextChar( ( HB_UCHAR ) pSrc[ ul ], &n, &wc ) )
|
|
{
|
|
if( n == 0 )
|
|
++nDst;
|
|
}
|
|
}
|
|
|
|
return nDst;
|
|
}
|
|
|
|
HB_SIZE hb_cdpUTF8StringAt( const char * szNeedle, HB_SIZE nLenN,
|
|
const char * szHaystack, HB_SIZE nLenH,
|
|
HB_SIZE nStart, HB_SIZE nEnd, HB_BOOL fReverse )
|
|
{
|
|
HB_SIZE nPosN = 0;
|
|
HB_SIZE nPosH = 0;
|
|
HB_SIZE nPosX = 0;
|
|
HB_SIZE nPos = 0;
|
|
HB_SIZE nRAt = 0;
|
|
HB_SIZE nAt = 0;
|
|
|
|
HB_WCHAR wcN = 0;
|
|
HB_WCHAR wcH = 0;
|
|
int nN = 0;
|
|
int nH = 0;
|
|
|
|
while( nPosH < nLenH && nPosN < nLenN && nPos < nEnd )
|
|
{
|
|
do
|
|
{
|
|
if( !hb_cdpUTF8ToU16NextChar( ( HB_UCHAR ) szHaystack[ nPosH++ ], &nH, &wcH ) )
|
|
{
|
|
--nPosH;
|
|
nH = 0;
|
|
}
|
|
} while( nH );
|
|
|
|
if( ++nPos < nStart )
|
|
continue;
|
|
|
|
do
|
|
{
|
|
if( !hb_cdpUTF8ToU16NextChar( ( HB_UCHAR ) szNeedle[ nPosN++ ], &nN, &wcN ) )
|
|
{
|
|
--nPosN;
|
|
nN = 0;
|
|
}
|
|
} while( nN );
|
|
|
|
if( wcH == wcN )
|
|
{
|
|
if( nAt == 0 )
|
|
{
|
|
nAt = nPos;
|
|
nPosX = nPosH;
|
|
}
|
|
|
|
if( nPosN == nLenN )
|
|
{
|
|
if( fReverse )
|
|
{
|
|
nRAt = nAt;
|
|
nPos = nAt;
|
|
nAt = 0;
|
|
nPosH = nPosX;
|
|
nPosX = 0;
|
|
nPosN = 0;
|
|
}
|
|
else
|
|
return nAt;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( nAt )
|
|
{
|
|
nPos = nAt;
|
|
nAt = 0;
|
|
nPosH = nPosX;
|
|
nPosX = 0;
|
|
}
|
|
nPosN = 0;
|
|
}
|
|
}
|
|
|
|
return nRAt;
|
|
}
|
|
|
|
HB_SIZE hb_cdpUTF8StringPeek( const char * pSrc, HB_SIZE nLen, HB_SIZE nPos )
|
|
{
|
|
if( nLen )
|
|
{
|
|
HB_SIZE ul;
|
|
HB_WCHAR wc = 0;
|
|
int n = 0;
|
|
|
|
for( ul = 0; ul < nLen && nPos; ++ul )
|
|
{
|
|
if( hb_cdpUTF8ToU16NextChar( ( HB_UCHAR ) pSrc[ ul ], &n, &wc ) )
|
|
{
|
|
if( n == 0 )
|
|
--nPos;
|
|
}
|
|
}
|
|
|
|
if( ul < nLen )
|
|
{
|
|
n = 0;
|
|
do
|
|
{
|
|
if( hb_cdpUTF8ToU16NextChar( ( HB_UCHAR ) pSrc[ ul ], &n, &wc ) )
|
|
{
|
|
if( n == 0 )
|
|
return wc;
|
|
}
|
|
}
|
|
while( ++ul < nLen );
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/* caller must free the returned buffer if not NULL */
|
|
char * hb_cdpUTF8StringSubstr( const char * pSrc, HB_SIZE nLen,
|
|
HB_SIZE nFrom, HB_SIZE nCount, HB_SIZE * pulDest )
|
|
{
|
|
HB_SIZE ul, nCnt, nDst = 0;
|
|
HB_WCHAR wc;
|
|
int n;
|
|
char * pDst = NULL;
|
|
|
|
if( nCount && nLen )
|
|
{
|
|
n = 0;
|
|
for( ul = 0; ul < nLen && nFrom; ++ul )
|
|
{
|
|
if( hb_cdpUTF8ToU16NextChar( pSrc[ ul ], &n, &wc ) )
|
|
{
|
|
if( n == 0 )
|
|
--nFrom;
|
|
}
|
|
}
|
|
|
|
if( ul < nLen )
|
|
{
|
|
nFrom = ul;
|
|
nCnt = nCount;
|
|
n = 0;
|
|
do
|
|
{
|
|
if( hb_cdpUTF8ToU16NextChar( pSrc[ ul ], &n, &wc ) )
|
|
{
|
|
if( n == 0 )
|
|
--nCnt;
|
|
}
|
|
}
|
|
while( ++ul < nLen && nCnt );
|
|
|
|
nDst = ul - nFrom;
|
|
pDst = ( char * ) hb_xgrab( nDst + 1 );
|
|
memcpy( pDst, &pSrc[ nFrom ], nDst );
|
|
pDst[ nDst ] = '\0';
|
|
}
|
|
}
|
|
|
|
if( pulDest )
|
|
*pulDest = nDst;
|
|
|
|
return pDst;
|
|
}
|
|
|
|
HB_BOOL hb_cdpGetFromUTF8( PHB_CODEPAGE cdp, HB_UCHAR ch,
|
|
int * n, HB_WCHAR * pwc )
|
|
{
|
|
if( hb_cdpUTF8ToU16NextChar( ch, n, pwc ) )
|
|
{
|
|
if( *n == 0 && cdp )
|
|
{
|
|
if( cdp->fCustom )
|
|
{
|
|
if( HB_CDPCHAR_LEN( cdp, *pwc ) == 1 )
|
|
{
|
|
HB_SIZE n = 0;
|
|
char c;
|
|
|
|
if( HB_CDPCHAR_PUT( cdp, &c, 1, &n, *pwc ) )
|
|
*pwc = ( HB_UCHAR ) c;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( cdp->uniTable->uniTrans == NULL )
|
|
hb_cdpBuildTransTable( cdp->uniTable );
|
|
|
|
if( *pwc <= cdp->uniTable->wcMax )
|
|
{
|
|
HB_UCHAR uc = cdp->uniTable->uniTrans[ *pwc ];
|
|
if( uc )
|
|
*pwc = uc;
|
|
}
|
|
}
|
|
}
|
|
return HB_TRUE;
|
|
}
|
|
return HB_FALSE;
|
|
}
|
|
|
|
HB_SIZE hb_cdpStrAsUTF8Len( PHB_CODEPAGE cdp,
|
|
const char * pSrc, HB_SIZE nSrc,
|
|
HB_SIZE nMax )
|
|
{
|
|
HB_SIZE ulS, ulD;
|
|
int i, n;
|
|
|
|
if( cdp == &s_utf8_codepage )
|
|
return ( nMax && nSrc > nMax ) ? nMax : nSrc;
|
|
else if( cdp->fCustom )
|
|
{
|
|
HB_WCHAR wc;
|
|
ulS = ulD = 0;
|
|
while( HB_CDPCHAR_GET( cdp, pSrc, nSrc, &ulS, &wc ) )
|
|
{
|
|
i = hb_cdpUTF8CharSize( wc );
|
|
if( nMax && ulD + i > nMax )
|
|
break;
|
|
ulD += i;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const HB_WCHAR * uniCodes = cdp->uniTable->uniCodes;
|
|
for( ulS = ulD = 0; ulS < nSrc; ++ulS )
|
|
{
|
|
HB_UCHAR uc = ( HB_UCHAR ) pSrc[ ulS ];
|
|
HB_WCHAR wc = uniCodes[ uc ];
|
|
|
|
if( wc == 0 )
|
|
wc = uc;
|
|
n = hb_cdpUTF8CharSize( wc );
|
|
if( nMax && ulD + n > nMax )
|
|
break;
|
|
ulD += n;
|
|
}
|
|
}
|
|
|
|
return ulD;
|
|
}
|
|
|
|
HB_SIZE hb_cdpStrToUTF8( PHB_CODEPAGE cdp,
|
|
const char * pSrc, HB_SIZE nSrc,
|
|
char * pDst, HB_SIZE nDst )
|
|
{
|
|
HB_SIZE ulS, ulD, u;
|
|
|
|
if( cdp == &s_utf8_codepage )
|
|
{
|
|
if( nSrc > nDst )
|
|
nSrc = nDst;
|
|
else if( nSrc < nDst )
|
|
pDst[ nSrc ] = '\0';
|
|
memcpy( pDst, pSrc, nSrc );
|
|
return nSrc;
|
|
}
|
|
else if( cdp->fCustom )
|
|
{
|
|
HB_WCHAR wc;
|
|
ulS = ulD = 0;
|
|
while( ulD < nDst && HB_CDPCHAR_GET( cdp, pSrc, nSrc, &ulS, &wc ) )
|
|
{
|
|
u = hb_cdpUTF8CharSize( wc );
|
|
if( ulD + u <= nDst )
|
|
{
|
|
hb_cdpU16CharToUTF8( &pDst[ ulD ], wc );
|
|
ulD += u;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const HB_WCHAR * uniCodes = cdp->uniTable->uniCodes;
|
|
for( ulS = ulD = 0; ulS < nSrc && ulD < nDst; ++ulS )
|
|
{
|
|
HB_UCHAR uc = ( HB_UCHAR ) pSrc[ ulS ];
|
|
HB_WCHAR wc = uniCodes[ uc ];
|
|
|
|
if( wc == 0 )
|
|
wc = uc;
|
|
u = hb_cdpUTF8CharSize( wc );
|
|
if( ulD + u <= nDst )
|
|
{
|
|
hb_cdpU16CharToUTF8( &pDst[ ulD ], wc );
|
|
ulD += u;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( ulD < nDst )
|
|
pDst[ ulD ] = '\0';
|
|
|
|
return ulD;
|
|
}
|
|
|
|
HB_SIZE hb_cdpStrToUTF8Disp( PHB_CODEPAGE cdp,
|
|
const char * pSrc, HB_SIZE nSrc,
|
|
char * pDst, HB_SIZE nDst )
|
|
{
|
|
HB_SIZE ulS, ulD, u;
|
|
|
|
if( cdp == &s_utf8_codepage )
|
|
{
|
|
if( nSrc > nDst )
|
|
nSrc = nDst;
|
|
else if( nSrc < nDst )
|
|
pDst[ nSrc ] = '\0';
|
|
memcpy( pDst, pSrc, nSrc );
|
|
return nSrc;
|
|
}
|
|
else if( cdp->fCustom )
|
|
{
|
|
HB_WCHAR wc;
|
|
ulS = ulD = 0;
|
|
while( ulD < nDst && HB_CDPCHAR_GET( cdp, pSrc, nSrc, &ulS, &wc ) )
|
|
{
|
|
if( wc < 32 )
|
|
wc = s_uniCtrls[ wc ];
|
|
u = hb_cdpUTF8CharSize( wc );
|
|
if( ulD + u <= nDst )
|
|
{
|
|
hb_cdpU16CharToUTF8( &pDst[ ulD ], wc );
|
|
ulD += u;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
const HB_WCHAR * uniCodes = cdp->uniTable->uniCodes;
|
|
for( ulS = ulD = 0; ulS < nSrc && ulD < nDst; ++ulS )
|
|
{
|
|
HB_UCHAR uc = ( HB_UCHAR ) pSrc[ ulS ];
|
|
HB_WCHAR wc = uniCodes[ uc ];
|
|
|
|
if( wc == 0 )
|
|
wc = uc < 32 ? s_uniCtrls[ uc ] : s_uniCodes[ uc ];
|
|
|
|
u = hb_cdpUTF8CharSize( wc );
|
|
if( ulD + u <= nDst )
|
|
{
|
|
hb_cdpU16CharToUTF8( &pDst[ ulD ], wc );
|
|
ulD += u;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
if( ulD < nDst )
|
|
pDst[ ulD ] = '\0';
|
|
|
|
return ulD;
|
|
}
|
|
|
|
HB_SIZE hb_cdpUTF8AsStrLen( PHB_CODEPAGE cdp, const char * pSrc, HB_SIZE nSrc,
|
|
HB_SIZE nMax )
|
|
{
|
|
HB_WCHAR wc = 0;
|
|
HB_SIZE ulS, ulD;
|
|
int n = 0, i;
|
|
|
|
if( cdp == &s_utf8_codepage )
|
|
return ( nMax && nSrc > nMax ) ? nMax : nSrc;
|
|
else if( cdp->fCustom )
|
|
{
|
|
for( ulS = ulD = 0; ulS < nSrc; ++ulS )
|
|
{
|
|
if( hb_cdpUTF8ToU16NextChar( ( HB_UCHAR ) pSrc[ ulS ], &n, &wc ) )
|
|
{
|
|
if( n == 0 )
|
|
{
|
|
i = HB_CDPCHAR_LEN( cdp, wc );
|
|
if( nMax && ulD + i > nMax )
|
|
break;
|
|
ulD += i;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for( ulS = ulD = 0; ulS < nSrc; ++ulS )
|
|
{
|
|
if( hb_cdpUTF8ToU16NextChar( ( HB_UCHAR ) pSrc[ ulS ], &n, &wc ) )
|
|
{
|
|
if( n == 0 )
|
|
{
|
|
++ulD;
|
|
if( nMax && ulD >= nMax )
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return ulD;
|
|
}
|
|
|
|
HB_SIZE hb_cdpUTF8ToStr( PHB_CODEPAGE cdp,
|
|
const char * pSrc, HB_SIZE nSrc,
|
|
char * pDst, HB_SIZE nDst )
|
|
{
|
|
HB_UCHAR * uniTrans;
|
|
HB_WCHAR wcMax, wc = 0;
|
|
HB_SIZE ulS, ulD;
|
|
int n = 0;
|
|
|
|
if( cdp == &s_utf8_codepage )
|
|
{
|
|
if( nSrc > nDst )
|
|
nSrc = nDst;
|
|
else if( nSrc < nDst )
|
|
pDst[ nSrc ] = '\0';
|
|
memcpy( pDst, pSrc, nSrc );
|
|
return nSrc;
|
|
}
|
|
else if( cdp->fCustom )
|
|
{
|
|
for( ulS = ulD = 0; ulS < nSrc && ulD < nDst; ++ulS )
|
|
{
|
|
if( hb_cdpUTF8ToU16NextChar( ( HB_UCHAR ) pSrc[ ulS ], &n, &wc ) )
|
|
{
|
|
if( n == 0 )
|
|
{
|
|
if( ! HB_CDPCHAR_PUT( cdp, pDst, nDst, &ulD, wc ) )
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( cdp->uniTable->uniTrans == NULL )
|
|
hb_cdpBuildTransTable( cdp->uniTable );
|
|
uniTrans = cdp->uniTable->uniTrans;
|
|
wcMax = cdp->uniTable->wcMax;
|
|
|
|
for( ulS = ulD = 0; ulS < nSrc && ulD < nDst; ++ulS )
|
|
{
|
|
if( hb_cdpUTF8ToU16NextChar( ( HB_UCHAR ) pSrc[ ulS ], &n, &wc ) )
|
|
{
|
|
if( n == 0 )
|
|
{
|
|
if( wc <= wcMax && uniTrans[ wc ] )
|
|
pDst[ ulD++ ] = uniTrans[ wc ];
|
|
else
|
|
pDst[ ulD++ ] = wc >= 0x100 ? '?' : ( HB_UCHAR ) wc;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( ulD < nDst )
|
|
pDst[ ulD ] = '\0';
|
|
|
|
return ulD;
|
|
}
|
|
|
|
/*
|
|
* U16 (hb wide char) conversions
|
|
*/
|
|
HB_WCHAR hb_cdpGetU16( PHB_CODEPAGE cdp, HB_UCHAR ch )
|
|
{
|
|
if( cdp )
|
|
{
|
|
HB_WCHAR wc;
|
|
if( cdp->fCustom )
|
|
{
|
|
HB_SIZE n = 0;
|
|
if( ! HB_CDPCHAR_GET( cdp, ( const char * ) &ch, 1, &n, &wc ) )
|
|
wc = 0;
|
|
}
|
|
else
|
|
wc = cdp->uniTable->uniCodes[ ch ];
|
|
return wc == 0 ? ch : wc;
|
|
}
|
|
else
|
|
return ch;
|
|
}
|
|
|
|
HB_WCHAR hb_cdpGetU16Disp( PHB_CODEPAGE cdp, HB_UCHAR ch )
|
|
{
|
|
if( cdp )
|
|
{
|
|
HB_WCHAR wc;
|
|
if( cdp->fCustom )
|
|
{
|
|
HB_SIZE n = 0;
|
|
if( ! HB_CDPCHAR_GET( cdp, ( const char * ) &ch, 1, &n, &wc ) )
|
|
wc = 0;
|
|
}
|
|
else
|
|
wc = cdp->uniTable->uniCodes[ ch ];
|
|
if( wc == 0 )
|
|
wc = ch < 32 ? s_uniCtrls[ ch ] : s_uniCodes[ ch ];
|
|
return wc;
|
|
}
|
|
else
|
|
return ch;
|
|
}
|
|
|
|
HB_UCHAR hb_cdpGetChar( PHB_CODEPAGE cdp, HB_WCHAR wc )
|
|
{
|
|
if( cdp )
|
|
{
|
|
if( cdp->fCustom )
|
|
{
|
|
if( HB_CDPCHAR_LEN( cdp, wc ) == 1 )
|
|
{
|
|
HB_SIZE n = 0;
|
|
char c;
|
|
|
|
if( ! HB_CDPCHAR_PUT( cdp, &c, 1, &n, wc ) )
|
|
wc = '?';
|
|
else
|
|
wc = ( HB_UCHAR ) c;
|
|
}
|
|
else
|
|
wc = '?';
|
|
}
|
|
else
|
|
{
|
|
if( cdp->uniTable->uniTrans == NULL )
|
|
hb_cdpBuildTransTable( cdp->uniTable );
|
|
|
|
if( wc <= cdp->uniTable->wcMax )
|
|
{
|
|
HB_UCHAR uc = cdp->uniTable->uniTrans[ wc ];
|
|
if( uc )
|
|
wc = uc;
|
|
}
|
|
}
|
|
}
|
|
return wc >= 0x100 ? '?' : ( HB_UCHAR ) wc;
|
|
}
|
|
|
|
HB_SIZE hb_cdpStrAsU16Len( PHB_CODEPAGE cdp,
|
|
const char * pSrc, HB_SIZE nSrc,
|
|
HB_SIZE nMax )
|
|
{
|
|
HB_SIZE ulS, ulD;
|
|
|
|
if( cdp == &s_utf8_codepage )
|
|
{
|
|
nSrc = hb_cdpUTF8StringLength( pSrc, nSrc );
|
|
}
|
|
else if( cdp->fCustom )
|
|
{
|
|
HB_WCHAR wc;
|
|
ulS = ulD = 0;
|
|
while( HB_CDPCHAR_GET( cdp, pSrc, nSrc, &ulS, &wc ) )
|
|
{
|
|
++ulD;
|
|
if( nMax && ulD >= nMax )
|
|
break;
|
|
}
|
|
return ulD;
|
|
}
|
|
|
|
return ( nMax && nSrc > nMax ) ? nMax : nSrc;
|
|
}
|
|
|
|
#undef HB_CDP_ENDIAN_SWAP
|
|
#if defined( HB_BIG_ENDIAN )
|
|
# define HB_CDP_ENDIAN_SWAP HB_CDP_ENDIAN_LITTLE
|
|
#elif defined( HB_LITTLE_ENDIAN )
|
|
# define HB_CDP_ENDIAN_SWAP HB_CDP_ENDIAN_BIG
|
|
#endif
|
|
|
|
HB_SIZE hb_cdpStrToU16( PHB_CODEPAGE cdp, int iEndian,
|
|
const char * pSrc, HB_SIZE nSrc,
|
|
HB_WCHAR * pDst, HB_SIZE nDst )
|
|
{
|
|
const HB_WCHAR * uniCodes;
|
|
HB_SIZE ulS, ulD;
|
|
|
|
if( cdp == &s_utf8_codepage )
|
|
{
|
|
HB_WCHAR wc = 0;
|
|
int n = 0;
|
|
|
|
for( ulS = ulD = 0; ulS < nSrc && ulD < nDst; ++ulS )
|
|
{
|
|
if( hb_cdpUTF8ToU16NextChar( ( HB_UCHAR ) pSrc[ ulS ], &n, &wc ) )
|
|
{
|
|
if( n == 0 )
|
|
{
|
|
#if defined( HB_CDP_ENDIAN_SWAP )
|
|
if( iEndian == HB_CDP_ENDIAN_SWAP )
|
|
wc = HB_SWAP_UINT16( wc );
|
|
pDst[ ulD++ ] = wc;
|
|
#else
|
|
if( iEndian == HB_CDP_ENDIAN_LITTLE )
|
|
HB_PUT_LE_UINT16( &pDst[ ulD ], wc );
|
|
else if( iEndian == HB_CDP_ENDIAN_BIG )
|
|
HB_PUT_BE_UINT16( &pDst[ ulD ], wc );
|
|
else
|
|
pDst[ ulD ] = wc;
|
|
++ulD;
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else if( cdp->fCustom )
|
|
{
|
|
HB_WCHAR wc;
|
|
ulS = ulD = 0;
|
|
while( ulD < nDst && HB_CDPCHAR_GET( cdp, pSrc, nSrc, &ulS, &wc ) )
|
|
{
|
|
#if defined( HB_CDP_ENDIAN_SWAP )
|
|
if( iEndian == HB_CDP_ENDIAN_SWAP )
|
|
wc = HB_SWAP_UINT16( wc );
|
|
pDst[ ulD++ ] = wc;
|
|
#else
|
|
if( iEndian == HB_CDP_ENDIAN_LITTLE )
|
|
HB_PUT_LE_UINT16( &pDst[ ulD ], wc );
|
|
else if( iEndian == HB_CDP_ENDIAN_BIG )
|
|
HB_PUT_BE_UINT16( &pDst[ ulD ], wc );
|
|
else
|
|
pDst[ ulD ] = wc;
|
|
++ulD;
|
|
#endif
|
|
}
|
|
}
|
|
else
|
|
{
|
|
uniCodes = cdp->uniTable->uniCodes;
|
|
for( ulS = ulD = 0; ulS < nSrc && ulD < nDst; ++ulS )
|
|
{
|
|
HB_UCHAR uc = ( HB_UCHAR ) pSrc[ ulS ];
|
|
HB_WCHAR wc = uniCodes[ uc ];
|
|
|
|
if( wc == 0 )
|
|
wc = uc;
|
|
#if defined( HB_CDP_ENDIAN_SWAP )
|
|
if( iEndian == HB_CDP_ENDIAN_SWAP )
|
|
wc = HB_SWAP_UINT16( wc );
|
|
pDst[ ulD++ ] = wc;
|
|
#else
|
|
if( iEndian == HB_CDP_ENDIAN_LITTLE )
|
|
HB_PUT_LE_UINT16( &pDst[ ulD ], wc );
|
|
else if( iEndian == HB_CDP_ENDIAN_BIG )
|
|
HB_PUT_BE_UINT16( &pDst[ ulD ], wc );
|
|
else
|
|
pDst[ ulD ] = wc;
|
|
++ulD;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
if( ulD < nDst )
|
|
pDst[ ulD ] = '\0';
|
|
|
|
return ulD;
|
|
}
|
|
|
|
HB_SIZE hb_cdpU16AsStrLen( PHB_CODEPAGE cdp,
|
|
const HB_WCHAR * pSrc, HB_SIZE nSrc,
|
|
HB_SIZE nMax )
|
|
{
|
|
HB_SIZE ulS, ulD;
|
|
int i;
|
|
|
|
if( cdp == &s_utf8_codepage )
|
|
{
|
|
for( ulS = ulD = 0; ulS < nSrc; ++ulS )
|
|
{
|
|
i = hb_cdpUTF8CharSize( pSrc[ ulS ] );
|
|
if( nMax && ulD + i > nMax )
|
|
break;
|
|
ulD += i;
|
|
}
|
|
}
|
|
else if( cdp->fCustom )
|
|
{
|
|
for( ulS = ulD = 0; ulS < nSrc; ++ulS )
|
|
{
|
|
i = HB_CDPCHAR_LEN( cdp, pSrc[ ulS ] );
|
|
if( nMax && ulD + i > nMax )
|
|
break;
|
|
ulD += i;
|
|
}
|
|
}
|
|
else
|
|
ulD = ( nMax && nSrc > nMax ) ? nMax : nSrc;
|
|
|
|
return ulD;
|
|
}
|
|
|
|
HB_SIZE hb_cdpU16ToStr( PHB_CODEPAGE cdp, int iEndian,
|
|
const HB_WCHAR * pSrc, HB_SIZE nSrc,
|
|
char * pDst, HB_SIZE nDst )
|
|
{
|
|
HB_UCHAR * uniTrans;
|
|
HB_WCHAR wcMax, wc;
|
|
HB_SIZE ulS, ulD;
|
|
int i;
|
|
|
|
if( cdp == &s_utf8_codepage )
|
|
{
|
|
for( ulS = ulD = 0; ulS < nSrc; ++ulS )
|
|
{
|
|
#if defined( HB_CDP_ENDIAN_SWAP )
|
|
wc = pSrc[ ulS ];
|
|
if( iEndian == HB_CDP_ENDIAN_SWAP )
|
|
wc = HB_SWAP_UINT16( wc );
|
|
#else
|
|
if( iEndian == HB_CDP_ENDIAN_LITTLE )
|
|
wc = HB_GET_LE_UINT16( &pSrc[ ulS ] );
|
|
else if( iEndian == HB_CDP_ENDIAN_BIG )
|
|
wc = HB_GET_BE_UINT16( &pSrc[ ulS ] );
|
|
else
|
|
wc = pSrc[ ulS ];
|
|
#endif
|
|
i = hb_cdpUTF8CharSize( wc );
|
|
if( ulD + i <= nDst )
|
|
{
|
|
hb_cdpU16CharToUTF8( &pDst[ ulD ], wc );
|
|
ulD += i;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
else if( cdp->fCustom )
|
|
{
|
|
for( ulS = ulD = 0; ulS < nSrc; ++ulS )
|
|
{
|
|
#if defined( HB_CDP_ENDIAN_SWAP )
|
|
wc = pSrc[ ulS ];
|
|
if( iEndian == HB_CDP_ENDIAN_SWAP )
|
|
wc = HB_SWAP_UINT16( wc );
|
|
#else
|
|
if( iEndian == HB_CDP_ENDIAN_LITTLE )
|
|
wc = HB_GET_LE_UINT16( &pSrc[ ulS ] );
|
|
else if( iEndian == HB_CDP_ENDIAN_BIG )
|
|
wc = HB_GET_BE_UINT16( &pSrc[ ulS ] );
|
|
else
|
|
wc = pSrc[ ulS ];
|
|
#endif
|
|
if( ! HB_CDPCHAR_PUT( cdp, pDst, nDst, &ulD, wc ) )
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if( cdp->uniTable->uniTrans == NULL )
|
|
hb_cdpBuildTransTable( cdp->uniTable );
|
|
uniTrans = cdp->uniTable->uniTrans;
|
|
wcMax = cdp->uniTable->wcMax;
|
|
|
|
for( ulS = ulD = 0; ulS < nSrc && ulD < nDst; ++ulS )
|
|
{
|
|
#if defined( HB_CDP_ENDIAN_SWAP )
|
|
wc = pSrc[ ulS ];
|
|
if( iEndian == HB_CDP_ENDIAN_SWAP )
|
|
wc = HB_SWAP_UINT16( wc );
|
|
#else
|
|
if( iEndian == HB_CDP_ENDIAN_LITTLE )
|
|
wc = HB_GET_LE_UINT16( &pSrc[ ulS ] );
|
|
else if( iEndian == HB_CDP_ENDIAN_BIG )
|
|
wc = HB_GET_BE_UINT16( &pSrc[ ulS ] );
|
|
else
|
|
wc = pSrc[ ulS ];
|
|
#endif
|
|
if( wc <= wcMax && uniTrans[ wc ] )
|
|
pDst[ ulD++ ] = uniTrans[ wc ];
|
|
else
|
|
pDst[ ulD++ ] = wc >= 0x100 ? '?' : ( HB_UCHAR ) wc;
|
|
}
|
|
}
|
|
|
|
if( ulD < nDst )
|
|
pDst[ ulD ] = '\0';
|
|
|
|
return ulD;
|
|
}
|
|
|
|
|
|
/*
|
|
* CP translations
|
|
*/
|
|
HB_SIZE hb_cdpTransLen( const char * pSrc, HB_SIZE nSrc, HB_SIZE nMax,
|
|
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut )
|
|
{
|
|
HB_SIZE nSize;
|
|
|
|
if( cdpIn && cdpOut && cdpIn != cdpOut &&
|
|
( cdpIn->uniTable != cdpOut->uniTable ||
|
|
cdpIn->fCustom || cdpOut->fCustom ) )
|
|
{
|
|
if( cdpIn == &s_utf8_codepage )
|
|
return hb_cdpUTF8AsStrLen( cdpOut, pSrc, nSrc, nMax );
|
|
else if( cdpOut == &s_utf8_codepage )
|
|
return hb_cdpStrAsUTF8Len( cdpIn, pSrc, nSrc, nMax );
|
|
else if( cdpIn->fCustom || cdpOut->fCustom )
|
|
{
|
|
HB_SIZE ulS;
|
|
HB_WCHAR wc;
|
|
|
|
ulS = nSize = 0;
|
|
while( HB_CDPCHAR_GET( cdpIn, pSrc, nSrc, &ulS, &wc ) )
|
|
{
|
|
int i = HB_CDPCHAR_LEN( cdpOut, wc );
|
|
if( nMax && nSize + i > nMax )
|
|
break;
|
|
nSize += i;
|
|
}
|
|
}
|
|
else
|
|
nSize = ( nMax && nSrc > nMax ) ? nMax : nSrc;
|
|
}
|
|
else
|
|
nSize = ( nMax && nSrc > nMax ) ? nMax : nSrc;
|
|
|
|
return nSize;
|
|
}
|
|
|
|
HB_SIZE hb_cdpTransTo( const char * pSrc, HB_SIZE nSrc,
|
|
char * pDst, HB_SIZE nDst,
|
|
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut )
|
|
{
|
|
HB_SIZE nSize;
|
|
|
|
if( cdpIn && cdpOut && cdpIn != cdpOut &&
|
|
( cdpIn->uniTable != cdpOut->uniTable ||
|
|
cdpIn->fCustom || cdpOut->fCustom ) )
|
|
{
|
|
if( cdpIn == &s_utf8_codepage )
|
|
return hb_cdpUTF8ToStr( cdpOut, pSrc, nSrc, pDst, nDst );
|
|
else if( cdpOut == &s_utf8_codepage )
|
|
return hb_cdpStrToUTF8( cdpIn, pSrc, nSrc, pDst, nDst );
|
|
else if( cdpIn->fCustom || cdpOut->fCustom )
|
|
{
|
|
HB_SIZE ulS;
|
|
HB_WCHAR wc;
|
|
|
|
ulS = nSize = 0;
|
|
while( nSize < nDst && HB_CDPCHAR_GET( cdpIn, pSrc, nSrc, &ulS, &wc ) )
|
|
{
|
|
if( ! HB_CDPCHAR_PUT( cdpOut, pDst, nDst, &nSize, wc ) )
|
|
break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
HB_UCHAR * uniTrans;
|
|
HB_WCHAR wcMax;
|
|
|
|
if( cdpOut->uniTable->uniTrans == NULL )
|
|
hb_cdpBuildTransTable( cdpOut->uniTable );
|
|
uniTrans = cdpOut->uniTable->uniTrans;
|
|
wcMax = cdpOut->uniTable->wcMax;
|
|
|
|
if( nSrc > nDst )
|
|
nSrc = nDst;
|
|
for( nSize = 0; nSize < nSrc; ++nSize )
|
|
{
|
|
HB_UCHAR uc = ( HB_UCHAR ) pSrc[ nSize ];
|
|
HB_WCHAR wc = cdpIn->uniTable->uniCodes[ uc ];
|
|
if( wc && wc <= wcMax && uniTrans[ wc ] )
|
|
uc = uniTrans[ wc ];
|
|
pDst[ nSize ] = uc;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
nSize = ( nSrc > nDst ) ? nDst : nSrc;
|
|
memcpy( pDst, pSrc, nSize );
|
|
}
|
|
|
|
if( nSize < nDst )
|
|
pDst[ nSize ] = '\0';
|
|
|
|
return nSize;
|
|
}
|
|
|
|
int hb_cdpTranslateChar( int iChar, PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut )
|
|
{
|
|
if( cdpIn && cdpOut && cdpIn != cdpOut &&
|
|
( cdpIn->uniTable != cdpOut->uniTable ||
|
|
cdpIn->fCustom || cdpOut->fCustom ) &&
|
|
iChar >= 0 && iChar < 256 )
|
|
{
|
|
HB_WCHAR wc;
|
|
|
|
if( cdpIn->fCustom || cdpOut->fCustom )
|
|
{
|
|
HB_SIZE n = 0;
|
|
char c = ( char ) iChar;
|
|
|
|
if( HB_CDPCHAR_GET( cdpIn, &c, 1, &n, &wc ) )
|
|
{
|
|
if( HB_CDPCHAR_PUT( cdpOut, &c, 1, &n, wc ) )
|
|
{
|
|
if( c != '?' )
|
|
iChar = ( HB_UCHAR ) c;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wc = cdpIn->uniTable->uniCodes[ iChar ];
|
|
|
|
if( wc )
|
|
{
|
|
if( cdpOut->uniTable->uniTrans == NULL )
|
|
hb_cdpBuildTransTable( cdpOut->uniTable );
|
|
|
|
if( wc <= cdpOut->uniTable->wcMax )
|
|
{
|
|
wc = cdpOut->uniTable->uniTrans[ wc ];
|
|
if( wc )
|
|
iChar = wc;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return iChar;
|
|
}
|
|
|
|
int hb_cdpTranslateDispChar( int iChar, PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut )
|
|
{
|
|
if( cdpIn && cdpOut && cdpIn != cdpOut &&
|
|
( cdpIn->uniTable != cdpOut->uniTable ||
|
|
cdpIn->fCustom || cdpOut->fCustom ) &&
|
|
iChar >= 0 && iChar < 256 )
|
|
{
|
|
HB_WCHAR wc;
|
|
|
|
|
|
if( cdpIn->fCustom || cdpOut->fCustom )
|
|
{
|
|
HB_SIZE n = 0;
|
|
char c = ( char ) iChar;
|
|
|
|
if( !HB_CDPCHAR_GET( cdpIn, &c, 1, &n, &wc ) )
|
|
wc = ( HB_WCHAR ) iChar;
|
|
if( wc < 32 )
|
|
wc = s_uniCtrls[ iChar ];
|
|
if( HB_CDPCHAR_PUT( cdpOut, &c, 1, &n, wc ) )
|
|
{
|
|
if( c != '?' )
|
|
iChar = ( HB_UCHAR ) c;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
wc = cdpIn->uniTable->uniCodes[ iChar ];
|
|
|
|
if( wc == 0 )
|
|
wc = iChar < 32 ? s_uniCtrls[ iChar ] : s_uniCodes[ iChar ];
|
|
|
|
if( wc )
|
|
{
|
|
if( cdpOut->uniTable->uniTrans == NULL )
|
|
hb_cdpBuildTransTable( cdpOut->uniTable );
|
|
|
|
if( wc <= cdpOut->uniTable->wcMax )
|
|
{
|
|
wc = cdpOut->uniTable->uniTrans[ wc ];
|
|
if( wc )
|
|
iChar = wc;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return iChar;
|
|
}
|
|
|
|
HB_SIZE hb_cdpnDupLen( const char * pSrc, HB_SIZE nSrc,
|
|
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut )
|
|
{
|
|
return hb_cdpTransLen( pSrc, nSrc, 0, cdpIn, cdpOut );
|
|
}
|
|
|
|
HB_SIZE hb_cdpnDup2Len( const char * pSrc, HB_SIZE nSrc, HB_SIZE nMax,
|
|
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut )
|
|
{
|
|
return hb_cdpTransLen( pSrc, nSrc, nMax, cdpIn, cdpOut );
|
|
}
|
|
|
|
char * hb_cdpnDup( const char * pSrc, HB_SIZE * pnLen,
|
|
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut )
|
|
{
|
|
char * pDst;
|
|
HB_SIZE nDst;
|
|
|
|
nDst = hb_cdpTransLen( pSrc, *pnLen, 0, cdpIn, cdpOut );
|
|
pDst = ( char * ) hb_xgrab( nDst + 1 );
|
|
hb_cdpTransTo( pSrc, *pnLen, pDst, nDst + 1, cdpIn, cdpOut );
|
|
*pnLen = nDst;
|
|
|
|
return pDst;
|
|
}
|
|
|
|
const char * hb_cdpnDup2( const char * pSrc, HB_SIZE nSrc,
|
|
char * pDst, HB_SIZE * pnDst,
|
|
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut )
|
|
{
|
|
* pnDst = hb_cdpTransTo( pSrc, nSrc, pDst, *pnDst, cdpIn, cdpOut );
|
|
return pDst;
|
|
}
|
|
|
|
const char * hb_cdpnDup3( const char * pSrc, HB_SIZE nSrc,
|
|
char * pDst, HB_SIZE * pnDst,
|
|
char ** pFree, HB_SIZE * pnSize,
|
|
PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut )
|
|
{
|
|
if( cdpIn && cdpOut && cdpIn != cdpOut && nSrc &&
|
|
( cdpIn->uniTable != cdpOut->uniTable ||
|
|
cdpIn->fCustom || cdpOut->fCustom ) )
|
|
{
|
|
char * pPrev = NULL;
|
|
HB_SIZE nDst = hb_cdpTransLen( pSrc, nSrc, 0, cdpIn, cdpOut );
|
|
|
|
if( pDst == NULL )
|
|
{
|
|
pDst = *pFree;
|
|
if( pDst == NULL && *pnSize > 0 )
|
|
pDst = ( char * ) pSrc;
|
|
}
|
|
|
|
if( nDst >= *pnSize || ( pDst == pSrc &&
|
|
( cdpOut == &s_utf8_codepage || cdpOut->fCustom ) ) )
|
|
{
|
|
pPrev = *pFree;
|
|
pDst = *pFree = ( char * ) hb_xgrab( nDst + 1 );
|
|
*pnSize = nDst + 1;
|
|
}
|
|
|
|
nDst = hb_cdpTransTo( pSrc, nSrc, pDst, *pnSize, cdpIn, cdpOut );
|
|
|
|
if( pPrev )
|
|
hb_xfree( pPrev );
|
|
if( pnDst )
|
|
*pnDst = nDst;
|
|
return pDst;
|
|
}
|
|
|
|
if( pnDst )
|
|
*pnDst = nSrc;
|
|
return pSrc;
|
|
}
|
|
|
|
char * hb_cdpDup( const char * pszSrc, PHB_CODEPAGE cdpIn, PHB_CODEPAGE cdpOut )
|
|
{
|
|
HB_SIZE nLen = strlen( pszSrc );
|
|
return hb_cdpnDup( pszSrc, &nLen, cdpIn, cdpOut );
|
|
}
|
|
|
|
|
|
/*
|
|
* CP management
|
|
*/
|
|
static PHB_CODEPAGE hb_buildCodePage( const char * id, const char * info,
|
|
PHB_UNITABLE uniTable,
|
|
const char * pszUpper,
|
|
const char * pszLower,
|
|
unsigned int nACSort,
|
|
unsigned int nCaseSort )
|
|
{
|
|
HB_BOOL lSort, fError;
|
|
int iMulti, iAcc, iAccUp, iAccLo, iSortUp, iSortLo, i;
|
|
const char * pup, * plo;
|
|
HB_UCHAR ucUp, ucLo, ucUp2, ucLo2;
|
|
HB_SIZE nSize, ul;
|
|
HB_UCHAR * buffer, * flags, * upper, * lower, * sort, * acc;
|
|
HB_UCHAR used[ 256 ];
|
|
PHB_CODEPAGE cdp;
|
|
PHB_MULTICHAR multi;
|
|
|
|
memset( used, '\0', sizeof( used ) );
|
|
|
|
iMulti = iAcc = iSortUp = iSortLo = 0;
|
|
fError = lSort = HB_FALSE;
|
|
|
|
ucUp2 = ucLo2 = 0;
|
|
pup = pszUpper;
|
|
plo = pszLower;
|
|
for( ;; )
|
|
{
|
|
ucUp = ( HB_UCHAR ) *pup++;
|
|
ucLo = ( HB_UCHAR ) *plo++;
|
|
if( ucUp == 0 || ucLo == 0 )
|
|
{
|
|
if( ucUp || ucLo )
|
|
fError = HB_TRUE;
|
|
break;
|
|
}
|
|
if( ucUp == '.' )
|
|
{
|
|
if( ucLo == '.' &&
|
|
pup[ 0 ] && pup[ 1 ] &&
|
|
( pup[ 2 ] == '.' || pup[ 2 ] == '=' ) &&
|
|
plo[ 0 ] && plo[ 1 ] &&
|
|
( plo[ 2 ] == '.' || plo[ 2 ] == '=' ) )
|
|
{
|
|
ucUp = ( HB_UCHAR ) *pup;
|
|
ucLo = ( HB_UCHAR ) *plo;
|
|
|
|
if( ( ucUp != ' ' || ucLo != ' ' ) &&
|
|
( ucUp == ( HB_UCHAR ) *pup || ( ucUp != ' ' && *pup != ' ' ) ) &&
|
|
( ucLo == ( HB_UCHAR ) *plo || ( ucLo != ' ' && *plo != ' ' ) ) )
|
|
{
|
|
if( ucUp != ' ' )
|
|
++iSortLo;
|
|
pup += 2;
|
|
plo += 2;
|
|
if( *pup == '=' )
|
|
{
|
|
do
|
|
++pup;
|
|
while( HB_ISXDIGIT( *pup ) );
|
|
}
|
|
if( *plo == '=' )
|
|
{
|
|
do
|
|
++plo;
|
|
while( HB_ISXDIGIT( *plo ) );
|
|
}
|
|
if( *pup == '.' && *plo == '.' )
|
|
{
|
|
lSort = HB_TRUE;
|
|
iMulti++;
|
|
pup++;
|
|
plo++;
|
|
continue;
|
|
}
|
|
}
|
|
}
|
|
fError = HB_TRUE;
|
|
break;
|
|
}
|
|
if( ucUp == '~' )
|
|
{
|
|
if( ucLo != '~' || *pup == '\0' || *plo == '\0' )
|
|
{
|
|
fError = HB_TRUE;
|
|
break;
|
|
}
|
|
ucUp = ( HB_UCHAR ) *pup++;
|
|
ucLo = ( HB_UCHAR ) *plo++;
|
|
++iAcc;
|
|
}
|
|
if( used[ ucUp ] != 0 )
|
|
ucUp = ' ';
|
|
if( used[ ucLo ] != 0 )
|
|
ucLo = ' ';
|
|
if( ucUp == ' ' && ucLo == ' ' )
|
|
{
|
|
fError = HB_TRUE;
|
|
break;
|
|
}
|
|
if( ucUp != ' ' )
|
|
{
|
|
used[ ucUp ] = 1;
|
|
if( ucUp < ucUp2 )
|
|
lSort = HB_TRUE;
|
|
ucUp2 = ucUp;
|
|
++iSortLo;
|
|
}
|
|
if( ucLo != ' ' )
|
|
{
|
|
used[ ucLo ] = 1;
|
|
if( ucLo < ucLo2 )
|
|
lSort = HB_TRUE;
|
|
ucLo2 = ucLo;
|
|
}
|
|
}
|
|
|
|
if( iMulti > 64 )
|
|
fError = HB_TRUE;
|
|
|
|
if( fError || nACSort > HB_CDP_ACSORT_INTERLEAVED ||
|
|
nCaseSort > HB_CDP_CSSORT_IGNORE )
|
|
{
|
|
#ifdef __HB_IGNORE_CP_ERRORS
|
|
return NULL;
|
|
#else
|
|
hb_errInternal( 9994, "Harbour CP (%s) initialization failure", id, NULL );
|
|
#endif
|
|
}
|
|
|
|
if( iAcc == 0 )
|
|
nACSort = HB_CDP_ACSORT_NONE;
|
|
else if( nACSort != HB_CDP_ACSORT_NONE )
|
|
lSort = HB_TRUE;
|
|
|
|
if( nCaseSort != HB_CDP_CSSORT_UPLO )
|
|
lSort = HB_TRUE;
|
|
|
|
nSize = 0x300;
|
|
if( lSort )
|
|
{
|
|
nSize += 0x100;
|
|
if( nACSort == HB_CDP_ACSORT_INTERLEAVED )
|
|
nSize += 0x100;
|
|
}
|
|
ul = nSize;
|
|
nSize += sizeof( HB_CODEPAGE );
|
|
if( iMulti )
|
|
nSize += iMulti * sizeof( HB_MULTICHAR );
|
|
|
|
buffer = ( HB_UCHAR * ) hb_xgrab( nSize );
|
|
memset( buffer, '\0', nSize );
|
|
cdp = ( PHB_CODEPAGE ) &buffer[ ul ];
|
|
cdp->buffer = buffer;
|
|
|
|
cdp->flags = flags = buffer;
|
|
buffer += 0x100;
|
|
cdp->upper = upper = buffer;
|
|
buffer += 0x100;
|
|
cdp->lower = lower = buffer;
|
|
buffer += 0x100;
|
|
sort = acc = NULL;
|
|
if( lSort )
|
|
{
|
|
cdp->sort = sort = buffer;
|
|
buffer += 0x100;
|
|
if( nACSort == HB_CDP_ACSORT_INTERLEAVED )
|
|
{
|
|
cdp->acc = acc = buffer;
|
|
buffer += 0x100;
|
|
}
|
|
}
|
|
if( iMulti )
|
|
cdp->multi = ( PHB_MULTICHAR ) &buffer[ sizeof( HB_CODEPAGE ) ];
|
|
|
|
cdp->id = id;
|
|
cdp->info = info;
|
|
cdp->uniTable = uniTable;
|
|
cdp->nACSort = nACSort;
|
|
cdp->nMulti = iMulti;
|
|
for( i = 0; i < 0x100; ++i )
|
|
{
|
|
if( HB_ISDIGIT( i ) )
|
|
flags[ i ] |= HB_CDP_DIGIT;
|
|
if( HB_ISALPHA( i ) )
|
|
flags[ i ] |= HB_CDP_ALPHA;
|
|
if( HB_ISUPPER( i ) )
|
|
flags[ i ] |= HB_CDP_UPPER;
|
|
if( HB_ISLOWER( i ) )
|
|
flags[ i ] |= HB_CDP_LOWER;
|
|
upper[ i ] = ( HB_UCHAR ) HB_TOUPPER( i );
|
|
lower[ i ] = ( HB_UCHAR ) HB_TOLOWER( i );
|
|
}
|
|
|
|
iAccUp = iAccLo = 0;
|
|
multi = cdp->multi;
|
|
pup = pszUpper;
|
|
plo = pszLower;
|
|
ucUp2 = ucLo2 = 255;
|
|
memset( used, '\0', sizeof( used ) );
|
|
while( *pup )
|
|
{
|
|
ucUp = ( HB_UCHAR ) *pup++;
|
|
ucLo = ( HB_UCHAR ) *plo++;
|
|
if( ucUp == '.' )
|
|
{
|
|
multi->cFirst[ 0 ] = *pup++;
|
|
multi->cLast [ 0 ] = *pup++;
|
|
multi->cFirst[ 1 ] = *plo++;
|
|
multi->cLast [ 1 ] = *plo++;
|
|
if( multi->cFirst[ 0 ] != ' ' )
|
|
{
|
|
flags[ ( HB_UCHAR ) multi->cFirst[ 0 ] ] |= HB_CDP_MULTI1;
|
|
flags[ ( HB_UCHAR ) multi->cLast [ 0 ] ] |= HB_CDP_MULTI2;
|
|
multi->sortUp = ++iSortUp - iAccUp;
|
|
}
|
|
if( multi->cFirst[ 1 ] != ' ' )
|
|
{
|
|
flags[ ( HB_UCHAR ) multi->cFirst[ 1 ] ] |= HB_CDP_MULTI1;
|
|
flags[ ( HB_UCHAR ) multi->cLast [ 1 ] ] |= HB_CDP_MULTI2;
|
|
|
|
if( nCaseSort == HB_CDP_CSSORT_UPLO )
|
|
++iSortLo;
|
|
else if( nCaseSort == HB_CDP_CSSORT_MIXED )
|
|
iSortLo = ++iSortUp;
|
|
else
|
|
iSortLo = iSortUp;
|
|
multi->sortLo = iSortLo - iAccLo;
|
|
}
|
|
if( *pup == '=' )
|
|
{
|
|
++pup;
|
|
while( HB_ISXDIGIT( *pup ) )
|
|
{
|
|
multi->wcUp = ( multi->wcUp << 4 ) |
|
|
( *pup >= 'a' ? ( *pup - 'a' + 10 ) :
|
|
( *pup >= 'A' ? ( *pup - 'A' + 10 ) :
|
|
( *pup - '0' ) ) );
|
|
++pup;
|
|
}
|
|
}
|
|
pup++;
|
|
if( *plo == '=' )
|
|
{
|
|
++plo;
|
|
while( HB_ISXDIGIT( *plo ) )
|
|
{
|
|
multi->wcLo = ( multi->wcLo << 4 ) |
|
|
( *plo >= 'a' ? ( *plo - 'a' + 10 ) :
|
|
( *plo >= 'A' ? ( *plo - 'A' + 10 ) :
|
|
( *plo - '0' ) ) );
|
|
++plo;
|
|
}
|
|
}
|
|
plo++;
|
|
if( multi->wcUp || multi->wcLo )
|
|
cdp->nMultiUC++;
|
|
multi++;
|
|
}
|
|
else
|
|
{
|
|
iAcc = 0;
|
|
if( ucUp == '~' )
|
|
{
|
|
iAcc = 1;
|
|
ucUp = ( HB_UCHAR ) *pup++;
|
|
ucLo = ( HB_UCHAR ) *plo++;
|
|
}
|
|
if( ucUp != ' ' )
|
|
{
|
|
flags[ ucUp ] |= HB_CDP_ALPHA;
|
|
flags[ ucUp ] |= HB_CDP_UPPER;
|
|
if( ucLo != ' ' && ( used[ ucUp ] & HB_CDP_UPPER ) == 0 )
|
|
{
|
|
lower[ ucUp ] = ucLo;
|
|
used[ ucUp ] |= HB_CDP_UPPER;
|
|
}
|
|
if( sort )
|
|
{
|
|
if( sort[ ucUp ] == 0 )
|
|
{
|
|
if( iAcc && nACSort != HB_CDP_ACSORT_NONE )
|
|
++iAccUp;
|
|
sort[ ucUp ] = ( HB_UCHAR ) ( ++iSortUp - iAccUp );
|
|
if( acc )
|
|
acc[ ucUp ] = ( HB_UCHAR ) iSortUp;
|
|
if( ucUp2 > ucUp )
|
|
ucUp2 = ucUp;
|
|
}
|
|
}
|
|
}
|
|
if( ucLo != ' ' )
|
|
{
|
|
flags[ ucLo ] |= HB_CDP_ALPHA;
|
|
flags[ ucLo ] |= HB_CDP_LOWER;
|
|
if( ucUp != ' ' && ( used[ ucLo ] & HB_CDP_LOWER ) == 0 )
|
|
{
|
|
upper[ ucLo ] = ucUp;
|
|
used[ ucLo ] |= HB_CDP_LOWER;
|
|
}
|
|
if( sort )
|
|
{
|
|
if( sort[ ucLo ] == 0 )
|
|
{
|
|
if( nCaseSort == HB_CDP_CSSORT_UPLO )
|
|
{
|
|
if( iAcc && nACSort != HB_CDP_ACSORT_NONE )
|
|
++iAccLo;
|
|
++iSortLo;
|
|
}
|
|
else
|
|
{
|
|
if( nCaseSort == HB_CDP_CSSORT_MIXED )
|
|
{
|
|
if( iAcc && nACSort != HB_CDP_ACSORT_NONE )
|
|
++iAccUp;
|
|
++iSortUp;
|
|
}
|
|
iAccLo = iAccUp;
|
|
iSortLo = iSortUp;
|
|
}
|
|
sort[ ucLo ] = ( HB_UCHAR ) ( iSortLo - iAccLo );
|
|
if( acc )
|
|
acc[ ucLo ] = ( HB_UCHAR ) iSortLo;
|
|
if( ucLo2 > ucLo )
|
|
ucLo2 = ucLo;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if( sort )
|
|
{
|
|
int iUp, iLo, iSort1, iSort2, iSort3, iAdd;
|
|
|
|
if( iMulti > 0 )
|
|
{
|
|
if( iMulti > ucUp2 || iMulti > ucLo2 )
|
|
{
|
|
#ifdef __HB_IGNORE_CP_ERRORS
|
|
hb_xfree( buffer );
|
|
return NULL;
|
|
#else
|
|
hb_errInternal( 9994, "Harbour CP (%s) initialization failure", id, NULL );
|
|
#endif
|
|
}
|
|
|
|
if( iMulti <= 32 )
|
|
iMulti = 33;
|
|
else
|
|
iMulti = 65;
|
|
}
|
|
else
|
|
iMulti = 1;
|
|
|
|
if( nCaseSort != HB_CDP_CSSORT_UPLO )
|
|
ucLo2 = 0;
|
|
|
|
for( iUp = iLo = 0, i = iMulti; i < 256; ++i )
|
|
{
|
|
if( sort[ i ] == 0 )
|
|
{
|
|
if( i < ( int ) ucUp2 )
|
|
++iUp;
|
|
else if( i < ( int ) ucLo2 )
|
|
++iLo;
|
|
}
|
|
}
|
|
for( iSort1 = iSort2 = iSort3 = 0, i = iMulti; i < 256; ++i )
|
|
{
|
|
if( sort[ i ] == 0 )
|
|
{
|
|
if( i < ( int ) ucUp2 )
|
|
iAdd = ++iSort1;
|
|
else if( i < ( int ) ucLo2 )
|
|
iAdd = ++iSort2 + iSortUp + iUp;
|
|
else
|
|
iAdd = ++iSort3 + iUp + iSortLo + iLo;
|
|
}
|
|
else if( sort[ i ] <= iSortUp )
|
|
iAdd = iUp;
|
|
else
|
|
iAdd = iUp + iLo;
|
|
|
|
sort[ i ] += ( HB_UCHAR ) iAdd;
|
|
if( acc )
|
|
acc[ i ] += ( HB_UCHAR ) iAdd;
|
|
}
|
|
for( i = 0; i < cdp->nMulti; ++i )
|
|
{
|
|
cdp->multi[ i ].sortUp += iUp;
|
|
cdp->multi[ i ].sortLo += iUp + iLo;
|
|
}
|
|
}
|
|
|
|
if( cdp->nMultiUC )
|
|
{
|
|
cdp->wcharGet = hb_cdpMulti_get;
|
|
cdp->wcharPut = hb_cdpMulti_put;
|
|
cdp->wcharLen = hb_cdpMulti_len;
|
|
cdp->fCustom = HB_TRUE;
|
|
}
|
|
else
|
|
{
|
|
cdp->wcharGet = hb_cdpStd_get;
|
|
cdp->wcharPut = hb_cdpStd_put;
|
|
cdp->wcharLen = hb_cdpStd_len;
|
|
}
|
|
|
|
return cdp;
|
|
}
|
|
|
|
static PHB_CODEPAGE * hb_cdpFindPos( const char * id )
|
|
{
|
|
PHB_CODEPAGE * cdp_ptr;
|
|
|
|
if( s_cdpList == NULL )
|
|
{
|
|
HB_UCHAR * flags, * upper, * lower;
|
|
int i;
|
|
|
|
s_en_codepage.buffer = ( HB_UCHAR * ) hb_xgrab( 0x300 );
|
|
memset( s_en_codepage.buffer, '\0', 0x300 );
|
|
s_en_codepage.flags = flags = ( HB_UCHAR * ) s_en_codepage.buffer;
|
|
s_en_codepage.upper = upper = ( HB_UCHAR * ) s_en_codepage.buffer + 0x100;
|
|
s_en_codepage.lower = lower = ( HB_UCHAR * ) s_en_codepage.buffer + 0x200;
|
|
for( i = 0; i < 0x100; ++i )
|
|
{
|
|
if( HB_ISDIGIT( i ) )
|
|
flags[ i ] |= HB_CDP_DIGIT;
|
|
if( HB_ISALPHA( i ) )
|
|
flags[ i ] |= HB_CDP_ALPHA;
|
|
if( HB_ISUPPER( i ) )
|
|
flags[ i ] |= HB_CDP_UPPER;
|
|
if( HB_ISLOWER( i ) )
|
|
flags[ i ] |= HB_CDP_LOWER;
|
|
upper[ i ] = ( HB_UCHAR ) HB_TOUPPER( i );
|
|
lower[ i ] = ( HB_UCHAR ) HB_TOLOWER( i );
|
|
}
|
|
s_utf8_codepage.flags = s_en_codepage.flags;
|
|
s_utf8_codepage.upper = s_en_codepage.upper;
|
|
s_utf8_codepage.lower = s_en_codepage.lower;
|
|
s_cdpList = &s_en_codepage;
|
|
}
|
|
|
|
cdp_ptr = &s_cdpList;
|
|
|
|
while( *cdp_ptr )
|
|
{
|
|
if( strcmp( ( *cdp_ptr )->id, id ) == 0 )
|
|
break;
|
|
cdp_ptr = &( *cdp_ptr )->next;
|
|
}
|
|
|
|
return cdp_ptr;
|
|
}
|
|
|
|
HB_BOOL hb_cdpRegisterRaw( PHB_CODEPAGE cdp )
|
|
{
|
|
PHB_CODEPAGE * cdp_ptr;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_cdpRegisterRaw(%p)", cdp ) );
|
|
|
|
cdp_ptr = hb_cdpFindPos( cdp->id );
|
|
if( *cdp_ptr == NULL )
|
|
{
|
|
if( !cdp->fCustom )
|
|
{
|
|
cdp->wcharGet = hb_cdpStd_get;
|
|
cdp->wcharPut = hb_cdpStd_put;
|
|
cdp->wcharLen = hb_cdpStd_len;
|
|
}
|
|
*cdp_ptr = cdp;
|
|
return HB_TRUE;
|
|
}
|
|
return HB_FALSE;
|
|
}
|
|
|
|
HB_BOOL hb_cdpRegisterNew( const char * id, const char * info,
|
|
PHB_UNITABLE uniTable,
|
|
const char * pszUpper, const char * pszLower,
|
|
unsigned int nACSort,
|
|
unsigned int nCaseSort )
|
|
{
|
|
PHB_CODEPAGE * cdp_ptr;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_cdpRegisterNew(%s,%s,%s,%s,%u,%u)", id, info, pszUpper, pszLower, nACSort, nCaseSort ) );
|
|
|
|
cdp_ptr = hb_cdpFindPos( id );
|
|
if( *cdp_ptr == NULL )
|
|
{
|
|
*cdp_ptr = hb_buildCodePage( id, info, uniTable, pszUpper, pszLower,
|
|
nACSort, nCaseSort );
|
|
return *cdp_ptr != NULL;
|
|
}
|
|
return HB_FALSE;
|
|
}
|
|
|
|
void hb_cdpReleaseAll( void )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_cdpReleaseAll()" ) );
|
|
|
|
while( s_cdpList )
|
|
{
|
|
void * buffer = s_cdpList->buffer;
|
|
if( s_cdpList->uniTable->uniTrans )
|
|
{
|
|
hb_xfree( s_cdpList->uniTable->uniTrans );
|
|
s_cdpList->uniTable->uniTrans = NULL;
|
|
}
|
|
s_cdpList = s_cdpList->next;
|
|
if( buffer )
|
|
hb_xfree( buffer );
|
|
}
|
|
}
|
|
|
|
PHB_CODEPAGE hb_cdpFind( const char * id )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_cdpFind(%s)", id ) );
|
|
|
|
return id ? * hb_cdpFindPos( id ) : NULL;
|
|
}
|
|
|
|
PHB_CODEPAGE hb_cdpFindExt( const char * id )
|
|
{
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_cdpFindExt(%s)", id ) );
|
|
|
|
return id ? * hb_cdpFindPos( id ) : NULL;
|
|
}
|
|
|
|
PHB_CODEPAGE hb_cdpSelect( PHB_CODEPAGE cdp )
|
|
{
|
|
PHB_CODEPAGE cdpOld;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_cdpSelect(%p)", cdp ) );
|
|
|
|
cdpOld = hb_vmCDP();
|
|
if( cdp )
|
|
hb_vmSetCDP( cdp );
|
|
|
|
return cdpOld;
|
|
}
|
|
|
|
const char * hb_cdpID( void )
|
|
{
|
|
PHB_CODEPAGE cdp;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_cdpID()" ) );
|
|
|
|
cdp = hb_vmCDP();
|
|
|
|
return cdp ? cdp->id : NULL;
|
|
}
|
|
|
|
const char * hb_cdpSelectID( const char * id )
|
|
{
|
|
PHB_CODEPAGE cdp;
|
|
|
|
HB_TRACE( HB_TR_DEBUG, ( "hb_cdpSelectID(%s)", id ) );
|
|
|
|
cdp = hb_cdpSelect( hb_cdpFind( id ) );
|
|
|
|
return cdp ? cdp->id : NULL;
|
|
}
|
|
|
|
/* Caller must release the pointer */
|
|
const char ** hb_cdpList( void )
|
|
{
|
|
PHB_CODEPAGE cdp;
|
|
int iCount, iPos;
|
|
const char ** list;
|
|
|
|
cdp = s_cdpList;
|
|
iCount = 0;
|
|
while( cdp )
|
|
{
|
|
++iCount;
|
|
cdp = cdp->next;
|
|
}
|
|
|
|
list = ( const char ** ) hb_xgrab( ( iCount + 1 ) * sizeof( char * ) );
|
|
|
|
cdp = s_cdpList;
|
|
iPos = 0;
|
|
while( cdp && iPos < iCount )
|
|
{
|
|
list[ iPos++ ] = cdp->id;
|
|
cdp = cdp->next;
|
|
}
|
|
list[ iPos ] = NULL;
|
|
|
|
return list;
|
|
}
|