1243 lines
27 KiB
C
1243 lines
27 KiB
C
//////////////////////////////////////////////////
|
|
//Title : pub_convert.c
|
|
//Auhtor : Liu Wei
|
|
//Desc : public format type convert inplementation
|
|
//Created : 2007-06-24
|
|
//Revision :
|
|
//
|
|
//Revision :
|
|
//
|
|
//////////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
// lCRD software network data type assumpsit
|
|
//
|
|
// Memery Low <<============[Little Endian]===========>> Memery High
|
|
// Type abbr. e.g. Remark
|
|
// const value CVal U32 dVal= 0x12345678
|
|
// Host BCD HBcd/Bcd 0x78 0x56 0x34 0x12
|
|
// Anti BCD ABcd 0x87 0x65 0x43 0x21
|
|
// NetBCD NBcd 0x12 0x34 0x56 0x78
|
|
// String Str 0x31 0x32 0x33 0x34 0x35 0x36 0x37 0x38 "12345678"
|
|
// U64 U64 0x4E 0x61 0xBC 0x00 0x00 0x00 0x00 0x00 12345678=0xBC614E
|
|
// Digit Dig 0x01 0x02 0x03 0x04 0x05 0x06 0x07 0x08
|
|
//
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/** @defgroup format pub_fmt.c
|
|
** @{
|
|
**/
|
|
|
|
#include "./include/pub_fmt.h"
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// For test
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
/*
|
|
//define in pub_base.h
|
|
#define u8 unsigned char
|
|
#define u64 unsigned long long
|
|
#define CNULL '\0'
|
|
|
|
#define BitSet(arg,posn) ((arg) | (1L << (posn)))
|
|
#define BitClr(arg,posn) ((arg) & ~(1L << (posn)))
|
|
#define BitFlp(arg,posn) ((arg) ^ (1L << (posn)))
|
|
#define BitTst(arg,posn) (!(!((arg) & (1L << (posn)))))
|
|
|
|
//define in pub_debug.h
|
|
#define WxcAssert
|
|
*/
|
|
|
|
/**
|
|
** @note HexToCh : 0 - > '0'
|
|
**
|
|
**/
|
|
inline char HexToCh( u8 uHex )
|
|
{
|
|
return ( (uHex) + ( ((uHex) > 9)? 'A'-10 : '0') );
|
|
}
|
|
|
|
/**
|
|
** @note ChToHex : '0' - > 0
|
|
**
|
|
**/
|
|
inline u8 ChToHex( char ch)
|
|
{
|
|
static char digits[] = "0123456789abcdef";
|
|
u8 uRel = 0;
|
|
int s;
|
|
|
|
for(s = 0; s < 16; ++s)
|
|
{
|
|
if( digits[s] == tolower(ch) )
|
|
{
|
|
uRel = s;
|
|
return(uRel);
|
|
}
|
|
}
|
|
|
|
return(uRel);
|
|
}
|
|
|
|
|
|
/**
|
|
** @note ReverseByte : 0010 1010 =>> 0101 0100
|
|
**
|
|
**/
|
|
inline u8 ReverseByte(u8 uByteIn )
|
|
{
|
|
u8 i ;
|
|
u8 uByteOut = 0;
|
|
|
|
for( i = 0 ; i < 8 ; i ++ )
|
|
{
|
|
if( BitTst( uByteIn , i ) )
|
|
{
|
|
uByteOut = (u8) ( BitSet( uByteOut , 7-i ) );
|
|
}
|
|
}
|
|
|
|
return uByteOut;
|
|
}
|
|
|
|
/**
|
|
** @note ReverseBCD : 0x12 0x34 0x56 0x78 =>> 0x21 0x43 0x65 0x87
|
|
**
|
|
**/
|
|
inline void ReverseBCD( u8 *pDst , const u8 *pSrc , int nBcdLen )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0 ; i < nBcdLen ; i ++ )
|
|
{
|
|
pDst[i] = (pSrc[i] >> 4) + (pSrc[i] << 4) ;
|
|
}
|
|
}
|
|
|
|
/**
|
|
** ReverseArray : 0x12 0x34 0x56 0x78 =>> 0x78 0x56 0x34 0x12
|
|
**
|
|
**/
|
|
inline void ReverseArray( u8 *pDst , const u8 *pSrc , int nBcdLen )
|
|
{
|
|
int i;
|
|
|
|
for( i = 0 ; i < nBcdLen ; i ++ )
|
|
{
|
|
pDst[i] = pSrc[nBcdLen-i-1];
|
|
}
|
|
}
|
|
|
|
/**
|
|
** @note BcdToStr : 0x12 0x34 0x56 0x78 =>> "12345678"
|
|
**
|
|
**/
|
|
inline void BcdToStr( char *pStr , const u8 *pBcd , int nBcdLen )
|
|
{
|
|
int i , j ;
|
|
int nStrLen = nBcdLen * 2 + 1;
|
|
|
|
memset( pStr , 0 , nStrLen );
|
|
|
|
j = 0;
|
|
for( i = 0 ; i < nBcdLen ; i ++ )
|
|
{
|
|
pStr[j++] = HexToCh(pBcd[i] >> 4 );
|
|
pStr[j++] = HexToCh(pBcd[i] & 0x0F);
|
|
}
|
|
pStr[j] = CNULL;
|
|
}
|
|
|
|
/**
|
|
** @note BcdToU64 : 0x12 0x34 0x56 0x78 =>> 12345678
|
|
**
|
|
**/
|
|
inline u64 BcdToU64( const u8 *pBcd , int nBcdLen )
|
|
{
|
|
u64 llResult = 0;
|
|
u64 llMulti = 1;
|
|
int i;
|
|
|
|
for( i = nBcdLen*2 -1 ; i >= 0 ; i -- )
|
|
{
|
|
u8 uByte = pBcd[i/2] >> (4*((i+1)%2));
|
|
|
|
llResult += ( uByte & 0x0F ) * llMulti;
|
|
llMulti *= 10;
|
|
}
|
|
|
|
return llResult;
|
|
}
|
|
|
|
/**
|
|
** @note BcdToDig : 0x12 0x34 0x56 =>>0x01 0x02 0x03 0x04 0x05 0x06
|
|
**
|
|
**/
|
|
inline int BcdToDig( u8 *pDig , int nDigBuffLen, u8 *pBcd , int nBcdLen )
|
|
{
|
|
int i , j ;
|
|
|
|
i = j = 0;
|
|
if( nDigBuffLen < 2*nBcdLen )
|
|
{
|
|
return 0;
|
|
}
|
|
for( i = 0 ; i <nBcdLen ; i ++ )
|
|
{
|
|
pDig[j++] = pBcd[i] >> 4 ;
|
|
pDig[j++] = pBcd[i] & 0x0F;
|
|
}
|
|
return j;
|
|
}
|
|
|
|
/**
|
|
** @note StrToBcd : "123456" =>> 0x12 0x34 0x56
|
|
**
|
|
**/
|
|
inline int StrToBcd( u8 *pBcd , char *pStr , int nBcdBuffLen )
|
|
{
|
|
int i , j , k;
|
|
int nLen = strlen(pStr);
|
|
|
|
i = j = k = 0;
|
|
j = (nLen + nLen%2) /2;
|
|
if( nBcdBuffLen < j )
|
|
{
|
|
return 0;
|
|
}
|
|
memset( pBcd , 0 , j);
|
|
for( i = 0 ; i <j ; i ++ )
|
|
{
|
|
if( nLen%2 && !i )
|
|
{
|
|
pBcd[i] &= 0x0F;
|
|
}
|
|
else
|
|
{
|
|
pBcd[i] |= (ChToHex( pStr[k++]) & 0x0F) << 4;
|
|
}
|
|
pBcd[i] |= (ChToHex( pStr[k++]) & 0x0F);
|
|
}
|
|
return j;
|
|
}
|
|
|
|
/**
|
|
** @note U64ToBcd : 1234567 => 0x01 0x23 0x45 0x67
|
|
**
|
|
**/
|
|
inline int U64ToBcd( u8 *pBcd ,u64 llInput , int nBcdBuffLen )
|
|
{
|
|
u64 llDiv = 10;
|
|
int nDigNum = 1;
|
|
int nBcdLen = 0;
|
|
int i;
|
|
|
|
while( llDiv < llInput )
|
|
{
|
|
nDigNum++;
|
|
llDiv *= 10;
|
|
}
|
|
llDiv = ( nDigNum % 2 ) ? llDiv : llDiv/10;
|
|
|
|
nDigNum += nDigNum % 2;
|
|
nBcdLen = nDigNum/2;
|
|
if( nBcdBuffLen < nBcdLen )
|
|
{
|
|
return 0;
|
|
}
|
|
memset(pBcd , 0 , nBcdLen );
|
|
for(i = 0; i < nBcdLen; i++)
|
|
{
|
|
pBcd[i] |= (((llInput / llDiv) %10) << 4);
|
|
llDiv /= 10;
|
|
pBcd[i] |= ((llInput / llDiv) % 10) ;
|
|
llDiv /= 10;
|
|
}
|
|
|
|
return nBcdLen;
|
|
}
|
|
|
|
/**
|
|
** @note DigToBcd : 0x01 0x02 0x03 x04 0x05 0x06 0x07 => 0x01 0x23 0x45 0x67
|
|
**
|
|
**/
|
|
inline int DigToBcd( u8* pBcd , int nBcdBuffLen , u8 *pDig , int nDigLen )
|
|
{
|
|
u64 llDiv = 10;
|
|
int nDigNum = 1;
|
|
int nBcdLen = (nDigLen + nDigLen %2)/2;
|
|
int i , j;
|
|
|
|
j=0;
|
|
if( nBcdLen > nBcdBuffLen )
|
|
{
|
|
return 0;
|
|
}
|
|
memset( pBcd , 0 , nBcdLen );
|
|
|
|
for(i = 0; i < nBcdLen; i++)
|
|
{
|
|
if( nDigLen %2 && !i )
|
|
{
|
|
pBcd[i] &= 0x0F;
|
|
}
|
|
else
|
|
{
|
|
pBcd[i] |= pDig[j++] <<4;
|
|
}
|
|
pBcd[i] |= pDig[j++] & 0x0F;
|
|
}
|
|
return nBcdLen;
|
|
}
|
|
|
|
/**
|
|
** @note DigToBcd : 0x08 0x06 0x07 x05 0x05 0x00 0x01 => 0x86 0x75 0x50 0x1E
|
|
**
|
|
**/
|
|
inline int DigToBcdE( u8* pBcd , int nBcdBuffLen , u8 *pDig , int nDigLen , int nEnd )
|
|
{
|
|
u64 llDiv = 10;
|
|
int nDigNum = 1;
|
|
int nBcdLen = (nDigLen + nDigLen %2)/2;
|
|
int i , j;
|
|
|
|
j=0;
|
|
WxcAssert( nEnd <= 0x0F ,"DigToBcdE end code > 0x0F" );
|
|
if( nBcdLen > nBcdBuffLen )
|
|
{
|
|
WxcAssert( 0 , "DigToBcdE buffer overflow!");
|
|
return 0;
|
|
}
|
|
memset( pBcd , 0 , nBcdLen );
|
|
|
|
for(i = 0; i < nBcdLen; i++)
|
|
{
|
|
pBcd[i] |= pDig[j++] <<4;
|
|
if( nDigLen %2 && i == (nBcdLen-1) )
|
|
{
|
|
pBcd[i] |= nEnd;
|
|
}
|
|
else
|
|
{
|
|
pBcd[i] |= pDig[j++] & 0x0F;
|
|
}
|
|
|
|
}
|
|
return nBcdLen;
|
|
}
|
|
|
|
void _______________un_fmt______________()
|
|
{
|
|
|
|
}
|
|
|
|
/* ++++++++++++++++++++++++++++++++++++++ */
|
|
/* transfer ascii code to bcd code */
|
|
/* ++++++++++++++++++++++++++++++++++++++ */
|
|
void AsciiToBcd (BYTE *bcd_buf, const char *ascii_buf, int len)
|
|
{
|
|
int i;
|
|
char ch;
|
|
char flag=0;
|
|
|
|
if (ascii_buf == NULL)
|
|
{
|
|
for (i=0;i<len/2;i++)
|
|
bcd_buf[i] = 0;
|
|
bcd_buf[len/2] = '\0';
|
|
return;
|
|
}
|
|
if (len & 1)
|
|
{
|
|
bcd_buf[0] = 0;
|
|
flag = 1;
|
|
}
|
|
for (i=0; i<len; i++)
|
|
{
|
|
ch = ascii_buf[i];
|
|
if (ch>='a')
|
|
ch -= 'a' - 10;
|
|
else if (ch>='A')
|
|
ch -= 'A' - 10;
|
|
else
|
|
ch -= '0';
|
|
if (flag)
|
|
{
|
|
if (i & 1)
|
|
*bcd_buf = ch << 4;
|
|
else
|
|
*(bcd_buf++) |= ch & 0x0f;
|
|
}
|
|
else
|
|
{
|
|
if (i & 1)
|
|
*(bcd_buf++) |= ch & 0x0f;
|
|
else
|
|
*bcd_buf = ch << 4;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* ++++++++++++++++++++++++++++++++++++++ */
|
|
/* transfer bcd code to ascii code */
|
|
/* ++++++++++++++++++++++++++++++++++++++ */
|
|
void BcdToAscii (char *ascii_buf, const BYTE *bcd_buf, int len)
|
|
{
|
|
int i;
|
|
char ch;
|
|
|
|
if (bcd_buf == NULL)
|
|
{
|
|
for (i=0;i<len;i++)
|
|
ascii_buf[i] = '0';
|
|
ascii_buf[len] = '\0';
|
|
return;
|
|
}
|
|
for (i=0; i<len; i++)
|
|
{
|
|
if (i & 1) ch = *(bcd_buf++) & 0x0f;
|
|
else ch = *bcd_buf >> 4;
|
|
ascii_buf[i] = ch + ((ch > 9)? 'A'-10 : '0');
|
|
}
|
|
ascii_buf[i] = '\0';
|
|
}
|
|
|
|
int Str2Bcd ( BYTE * pBcd, char *pStr, int maxLen )
|
|
{
|
|
int iBcd = 0, iStr = 0, len;
|
|
BYTE flag = 0;
|
|
char val[3];
|
|
|
|
len = strlen ( pStr );
|
|
val[1] = val[2] = 0;
|
|
strcat ( pStr, "F" );
|
|
len++;
|
|
do
|
|
{
|
|
if( !isxdigit ( pStr[iStr] ) )
|
|
continue;
|
|
|
|
val[flag] = pStr[iStr];
|
|
if( flag )
|
|
{
|
|
pBcd[iBcd++] = strtoul ( val, NULL, 16 );
|
|
}
|
|
flag = flag ? 0 : 1;
|
|
}
|
|
while ( iBcd < maxLen && ++iStr < len );
|
|
|
|
memset ( pBcd + iBcd, 0xFF, maxLen - iBcd );
|
|
return iBcd;
|
|
}
|
|
|
|
int Bcd2Str ( char *pStr, const BYTE * pBcd, int len )
|
|
{
|
|
int i;
|
|
|
|
for ( i = 0; i < len; i++ )
|
|
sprintf ( pStr + 2 * i, "%02X", pBcd[i] );
|
|
|
|
pStr[2 * len] = 0;
|
|
return len;
|
|
}
|
|
|
|
int DigitsLen ( BYTE * pDigits, int maxLen )
|
|
{
|
|
int i = 0;
|
|
|
|
for ( i = 0; i < maxLen; i++ )
|
|
{
|
|
if( ( pDigits[i] & 0x0F ) > 0x0A )
|
|
return 2 * i;
|
|
if( ( pDigits[i] & 0xF0 ) > 0xA0 )
|
|
return 2 * i + 1;
|
|
}
|
|
return maxLen * 2;
|
|
}
|
|
|
|
int BcdLen ( BYTE * pBcd, int maxLen )
|
|
{
|
|
int i = 0;
|
|
|
|
for ( i = 0; i < maxLen; i++ )
|
|
{
|
|
if( ( pBcd[i] & 0xF0 ) > 0xA0 )
|
|
return 2 * i;
|
|
if( ( pBcd[i] & 0x0F ) > 0x0A )
|
|
return 2 * i + 1;
|
|
}
|
|
return maxLen * 2;
|
|
}
|
|
|
|
int Digits2Str ( char *pStr, BYTE * pDigits, int DigitsLen )
|
|
{
|
|
int i = 0;
|
|
char low = '0', high = '0';
|
|
|
|
for ( i = 0; i < DigitsLen; i++ )
|
|
{
|
|
low = pDigits[i] & 0xF;
|
|
if( low < 0x0A )
|
|
{
|
|
pStr[2 * i] = low + '0';
|
|
}
|
|
else if( low < 0x0E )
|
|
{
|
|
pStr[2 * i] = low + 'A' - 10;
|
|
}
|
|
else
|
|
{
|
|
pStr[2 * i] = 0;
|
|
break;
|
|
}
|
|
|
|
high = ( pDigits[i] >> 4 );
|
|
if( high < 0x0A )
|
|
{
|
|
pStr[2 * i + 1] = high + '0';
|
|
}
|
|
else if( high < 0x0E )
|
|
{
|
|
pStr[2 * i + 1] = high + 'A' - 10;
|
|
}
|
|
else
|
|
{
|
|
pStr[2 * i + 1] = 0;
|
|
break;
|
|
}
|
|
}
|
|
pStr[2 * DigitsLen] = '\0';
|
|
return 1;
|
|
}
|
|
|
|
ull Digits2Ull ( BYTE * pDigits, int DigitsLen )
|
|
{
|
|
ull result = 0;
|
|
int i;
|
|
BYTE digit;
|
|
|
|
if( DigitsLen > 9 )
|
|
DigitsLen = 9;
|
|
|
|
for ( i = 0; i < DigitsLen; i++ )
|
|
{
|
|
digit = pDigits[i] & 0x0F;
|
|
if( digit > 9 )
|
|
return result;
|
|
result = result * 10 + digit;
|
|
|
|
digit = pDigits[i] >> 4;
|
|
if( digit > 9 )
|
|
return result;
|
|
result = result * 10 + digit;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int Ull2Digits ( BYTE * pDigits, ull value, int DigitsLen )
|
|
{
|
|
char tempStr[64];
|
|
|
|
sprintf ( tempStr, "%lld", value );
|
|
return Str2Digits ( pDigits, tempStr, DigitsLen );
|
|
}
|
|
|
|
int Str2Digits ( BYTE * pDigits, char *pStr, int DigitsLen )
|
|
{
|
|
int i = 0, strLen = strlen ( pStr ), len = 0;
|
|
char valstr[3];
|
|
|
|
len = strLen / 2;
|
|
if( len * 2 < strLen )
|
|
{
|
|
strcat ( pStr, "F" );
|
|
len++;
|
|
}
|
|
if( len > DigitsLen )
|
|
len = DigitsLen;
|
|
|
|
valstr[2] = 0;
|
|
for ( i = 0; i < len; i++ )
|
|
{
|
|
valstr[0] = pStr[2 * i + 1];
|
|
valstr[1] = pStr[2 * i];
|
|
pDigits[i] = strtol ( valstr, NULL, 16 );
|
|
}
|
|
return len;
|
|
}
|
|
|
|
int Ull2Digits_Ralign ( BYTE * pDigits, ull value, int DigitsLen ) //right align
|
|
{
|
|
char tempStr[64];
|
|
char printStr[64];
|
|
|
|
sprintf ( printStr, "%%0%dlld", DigitsLen );
|
|
sprintf ( tempStr, printStr, value );
|
|
return Str2Digits ( pDigits, tempStr, ( DigitsLen + 1 ) / 2 );
|
|
}
|
|
|
|
ull Bcd2Ull ( BYTE * pBcd, int BcdLen )
|
|
{
|
|
ull result = 0;
|
|
int i;
|
|
BYTE digit;
|
|
|
|
if( BcdLen > 9 )
|
|
BcdLen = 9;
|
|
for ( i = 0; i < BcdLen; i++ )
|
|
{
|
|
digit = pBcd[i] >> 4;
|
|
if( digit > 9 )
|
|
return result;
|
|
result = result * 10 + digit;
|
|
|
|
digit = pBcd[i] & 0x0F;
|
|
if( digit > 9 )
|
|
return result;
|
|
result = result * 10 + digit;
|
|
}
|
|
return result;
|
|
}
|
|
|
|
int Ull2Bcd ( BYTE * pBcd, ull value, int BcdLen )
|
|
{
|
|
char tempStr[64];
|
|
|
|
sprintf ( tempStr, "%lld", value );
|
|
return Str2Bcd ( pBcd, tempStr, BcdLen );
|
|
}
|
|
|
|
int Digits2Bcd ( BYTE * pBcd, BYTE * pDigits, int maxLen )
|
|
//return length
|
|
{
|
|
int i = 0;
|
|
|
|
for ( i = 0; i < maxLen; i++ )
|
|
{
|
|
if( ( pDigits[i] & 0x0F ) > 0x0C )
|
|
return i;
|
|
|
|
pBcd[i] = ( pDigits[i] << 4 ) | ( pDigits[i] >> 4 );
|
|
|
|
if( ( pDigits[i] & 0xF0 ) > 0xC0 )
|
|
return i + 1;
|
|
|
|
}
|
|
return maxLen;
|
|
}
|
|
|
|
int Bcd2Digits ( BYTE * pDigits, BYTE * pBcd, int maxLen )
|
|
{
|
|
int i = 0;
|
|
|
|
for ( i = 0; i < maxLen; i++ )
|
|
{
|
|
if( ( pBcd[i] & 0xF0 ) > 0xC0 )
|
|
return i;
|
|
|
|
pDigits[i] = ( pBcd[i] << 4 ) | ( pBcd[i] >> 4 );
|
|
|
|
if( ( pBcd[i] & 0x0F ) > 0x0C )
|
|
return i + 1;
|
|
}
|
|
return maxLen;
|
|
}
|
|
|
|
int Bcd2Digits_dLen ( BYTE * pDigits, BYTE * pBcd, int maxLen ) //return digits len
|
|
{
|
|
int i = 0;
|
|
|
|
for ( i = 0; i < maxLen; i++ )
|
|
{
|
|
if( ( pBcd[i] & 0xF0 ) > 0xC0 )
|
|
return i * 2;
|
|
|
|
pDigits[i] = ( pBcd[i] << 4 ) | ( pBcd[i] >> 4 );
|
|
|
|
if( ( pBcd[i] & 0x0F ) > 0x0C )
|
|
return i * 2 + 1;
|
|
}
|
|
return maxLen * 2;
|
|
}
|
|
|
|
int Str2Oid ( DWORD * pOid, char *pStr, BYTE maxLen )
|
|
{
|
|
BYTE sub = 0;
|
|
short len, i;
|
|
char *pvar;
|
|
|
|
len = strlen ( pStr );
|
|
pvar = pStr;
|
|
for ( i = 0; i < len && sub < maxLen; i++ )
|
|
{
|
|
if( pStr[i] == '.' )
|
|
{
|
|
pStr[i] = '\0';
|
|
if( strlen ( pvar ) == 0 )
|
|
continue;
|
|
pOid[sub++] = atoi ( pvar );
|
|
pvar = pStr + i + 1;
|
|
}
|
|
}
|
|
if( strlen ( pvar ) == 0 )
|
|
return sub;
|
|
pOid[sub++] = atoi ( pvar );
|
|
return sub;
|
|
}
|
|
|
|
//string===>
|
|
int TrimLeft ( char *pStr )
|
|
{
|
|
int i = 0;
|
|
|
|
while ( ( pStr[i] == ' ' || pStr[i] == '\t' ) && i < 16 )
|
|
i++;
|
|
|
|
strcpy ( pStr, pStr + i );
|
|
return 1;
|
|
}
|
|
|
|
int TrimRight ( char *pStr )
|
|
{
|
|
int len = strlen ( pStr );
|
|
|
|
if( len > 1024 )
|
|
return 0;
|
|
|
|
while ( pStr[len - 1] == ' ' || pStr[len - 1] == '\t' )
|
|
{
|
|
pStr[len - 1] = 0;
|
|
len--;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
int Array2Digits ( BYTE * pDigits, BYTE * pArray, int ArrayLen )
|
|
{
|
|
int i;
|
|
|
|
pArray[ArrayLen] = 0xEE;
|
|
for ( i = 0; i < ( ArrayLen + 1 ) / 2; i++ )
|
|
pDigits[i] = ( pArray[2 * i + 1] << 4 ) | ( pArray[2 * i] & 0x0F );
|
|
|
|
return i;
|
|
}
|
|
|
|
ull Str2Ull ( char *pStr )
|
|
{
|
|
ull result, intHigh, intLow;
|
|
DWORD len;
|
|
char strHigh[16] = "\0", *strLow;
|
|
|
|
len = strlen ( pStr );
|
|
if( len > 18 )
|
|
return 0xFFFFFFFFFFFFFFFFll;
|
|
if( len > 9 )
|
|
{
|
|
strLow = pStr + ( len - 9 );
|
|
intLow = strtoul ( strLow, NULL, 10 );
|
|
|
|
strncpy ( strHigh, pStr, len - 9 );
|
|
intHigh = strtoul ( strHigh, NULL, 10 );
|
|
result = intHigh * 1000000000 + intLow;
|
|
return result;
|
|
}
|
|
else
|
|
{
|
|
intLow = strtoul ( pStr, NULL, 10 );
|
|
return intLow;
|
|
}
|
|
}
|
|
|
|
int Digits2Array ( BYTE * pArray, BYTE * pDigits, int DigitsLen )
|
|
{
|
|
int i, len = 0;
|
|
|
|
for ( i = 0; i < DigitsLen; i++ )
|
|
{
|
|
pArray[len] = pDigits[i] & 0x0F;
|
|
if( pArray[len] > 13 )
|
|
return len;
|
|
len++;
|
|
|
|
pArray[len] = pDigits[i] >> 4;
|
|
if( pArray[len] > 13 )
|
|
return len;
|
|
len++;
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
int Bcd2Array ( BYTE * pArray, BYTE * pBcd, int BcdLen )
|
|
{
|
|
int i, len = 0;
|
|
|
|
for ( i = 0; i < BcdLen; i++ )
|
|
{
|
|
pArray[len] = pBcd[i] >> 4;
|
|
if( pArray[len] > 13 )
|
|
return len;
|
|
len++;
|
|
|
|
pArray[len] = pBcd[i] & 0x0F;
|
|
if( pArray[len] > 13 )
|
|
return len;
|
|
len++;
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
int Str2Array ( BYTE * pArray, char *str, int ArrayLen )
|
|
{
|
|
int i, len;
|
|
char mystr[2];
|
|
|
|
mystr[1] = '\0';
|
|
len = strlen ( str );
|
|
if( len > ArrayLen )
|
|
len = ArrayLen;
|
|
|
|
for ( i = 0; i < len; i++ )
|
|
{
|
|
mystr[0] = str[i];
|
|
if( !isxdigit ( mystr[0] ) )
|
|
return i;
|
|
pArray[i] = ( BYTE ) strtol ( mystr, NULL, 16 );
|
|
}
|
|
return len;
|
|
}
|
|
|
|
BYTE EditDigits ( BYTE * digits_out, BYTE len_max, BYTE * digits_in, BYTE len_in, BYTE len_del, BYTE * digits_ins, BYTE len_ins, BYTE filler )
|
|
{
|
|
BYTE len = 0, tmpbuf[64], pos1 = 0, pos2 = 0;
|
|
|
|
if( len_ins > len_max ) //invalid insert length
|
|
{
|
|
memcpy ( digits_out, digits_in, ( len_in + 1 ) / 2 );
|
|
return len_in;
|
|
}
|
|
else if( len_ins > 0 )
|
|
{
|
|
memcpy ( digits_out, digits_ins, ( len_ins + 1 ) / 2 );
|
|
len += len_ins;
|
|
}
|
|
|
|
if( len_del > len_in ) //invalid delete length
|
|
{
|
|
memcpy ( digits_out, digits_in, ( len_in + 1 ) / 2 );
|
|
return len_in;
|
|
}
|
|
else if( len_del == len_in )
|
|
{
|
|
return len;
|
|
}
|
|
|
|
if( ( len & 0x01 ) == ( len_del & 0x01 ) )
|
|
{
|
|
if( len & 0x01 ) //odd
|
|
{
|
|
len_del++;
|
|
len_ins++;
|
|
pos1 = ( len + 1 ) / 2;
|
|
pos2 = ( len_del + 1 ) / 2;
|
|
digits_out[pos1 - 1] = ( digits_out[pos1 - 1] & 0x0F ) | ( digits_in[pos2 - 1] & 0xF0 );
|
|
memcpy ( &digits_out[pos1], &digits_in[pos2], ( len_in - len_del + 1 ) / 2 );
|
|
}
|
|
else //even
|
|
{
|
|
pos1 = len / 2;
|
|
pos2 = len_del / 2;
|
|
memcpy ( &digits_out[pos1], &digits_in[pos2], ( len_in - len_del + 1 ) / 2 );
|
|
}
|
|
|
|
/* daniel added this on 2006-04-18 */
|
|
if( ( len_in + len_ins - len_del ) & 0x01 ) //odd
|
|
{
|
|
pos1 = ( len_in + len_ins - len_del + 1 ) / 2 - 1;
|
|
digits_out[pos1] &= 0x0f;
|
|
digits_out[pos1] |= ( filler & 0xf0 );
|
|
}
|
|
else
|
|
{ //even
|
|
//will not fill the filler
|
|
}
|
|
return len_in + len_ins - len_del;
|
|
/* daniel added this on 2006-04-18 */
|
|
|
|
}
|
|
else
|
|
{
|
|
Digits2Array ( tmpbuf, digits_in, ( len_in + 1 ) / 2 );
|
|
if( len & 0x01 )
|
|
{
|
|
pos1 = ( len + 1 ) / 2;
|
|
digits_out[pos1 - 1] = ( digits_out[pos1 - 1] & 0x0F ) | ( tmpbuf[len_del] << 4 );
|
|
len_del++;
|
|
len_ins++;
|
|
}
|
|
else
|
|
pos1 = len / 2; //victor 2004-10
|
|
tmpbuf[len_in] = filler >> 4;
|
|
Array2Digits ( digits_out + pos1, tmpbuf + len_del, len_in - len_del + 1 );
|
|
len = len_in + len_ins - len_del;
|
|
|
|
return len_in + len_ins - len_del;
|
|
}
|
|
}
|
|
|
|
BYTE DelDigits ( BYTE * in_digit, BYTE in_len, BYTE * out_digit, BYTE count, BYTE filler )
|
|
{
|
|
return EditDigits ( out_digit, 32, in_digit, in_len, count, NULL, 0, filler );
|
|
}
|
|
|
|
void DWORD2BYTE ( BYTE * pdword, BYTE * pbyte, int len )
|
|
{
|
|
int i;
|
|
DWORD *p1, *p2;
|
|
|
|
for ( i = 0; i < len / 4; i++ )
|
|
{
|
|
p1 = ( DWORD * ) ( pdword + 4 * i );
|
|
p2 = ( DWORD * ) ( pbyte + 4 * i );
|
|
*p2 = htonl ( *p1 );
|
|
}
|
|
}
|
|
|
|
/**
|
|
** @note transfer u32 to byte format\n
|
|
** 0x9872 to 00 00 98 72
|
|
**/
|
|
void u32tobyte(u8 *str,u32 data)
|
|
{
|
|
str[0] = data >> 24;
|
|
str[1] = data >> 16;
|
|
str[2] = data >> 8;
|
|
str[3] = data;
|
|
}
|
|
|
|
/**
|
|
** @note transfer u16 to bcd string format
|
|
**/
|
|
u8 u16tobcd(u8 *bcd_string,u16 data)
|
|
{
|
|
u8 bcd_len=0;
|
|
u8 ii;
|
|
u8 flag = 0;
|
|
|
|
if (data == 0)
|
|
{
|
|
bcd_string[0] = 0;
|
|
return 1;
|
|
}
|
|
for (ii = 0;ii < 2;ii ++)
|
|
{
|
|
bcd_string[bcd_len] = data >> ((1-ii) * 8);
|
|
if (bcd_string[bcd_len] != 0 || flag == 1)
|
|
{
|
|
bcd_len ++;
|
|
flag = 1;
|
|
}
|
|
}
|
|
return bcd_len;
|
|
}
|
|
|
|
/**
|
|
** @note transfer bcd string to u16 format
|
|
**/
|
|
u16 bcdtou16(u8 *bcd_string,u8 bcd_len)
|
|
{
|
|
u8 ii;
|
|
u16 data=0;
|
|
|
|
if (bcd_len > 2)
|
|
return 0;
|
|
data = 0;
|
|
for (ii = 0;ii < bcd_len;ii ++)
|
|
data += bcd_string[ii] << ((bcd_len-ii-1) * 8);
|
|
return data;
|
|
}
|
|
|
|
/**
|
|
** @note transfer u32 to bcd string format\n
|
|
** 0x9872 to 98 72 and return len=2
|
|
**/
|
|
u8 u32tobcd(u8 *bcd_string,u32 data)
|
|
{
|
|
u8 ii;
|
|
u8 bcd_len = 0;
|
|
u8 temp_data;
|
|
|
|
if (data == 0)
|
|
{
|
|
bcd_string[0] = 0;
|
|
return 1;
|
|
}
|
|
for (ii = 0;ii < 4;ii ++)
|
|
{
|
|
temp_data = data >> ((3-ii) * 8);
|
|
// if (temp_data != 0 || flag == 1)
|
|
{
|
|
bcd_string[bcd_len++] = temp_data;
|
|
// flag = 1;
|
|
}
|
|
}
|
|
return bcd_len;
|
|
}
|
|
|
|
/**
|
|
** @note transfer bcd string to u32 format
|
|
**/
|
|
u32 bcdtou32(u8 *bcd_string,u8 bcd_len)
|
|
{
|
|
u8 ii;
|
|
u32 data=0;
|
|
|
|
if (bcd_len > 4)
|
|
return 0;
|
|
data = 0;
|
|
for (ii = 0;ii < bcd_len;ii ++)
|
|
data += bcd_string[ii] << ((bcd_len-ii-1) * 8);
|
|
return data;
|
|
}
|
|
/** @} **/
|
|
|
|
|
|
/* Convert data from ASCII form to right-aligned compact BCD form. */
|
|
void AsciiToRbcd (BYTE *bcd_buf, const char *ascii_buf, int len)
|
|
{
|
|
int i;
|
|
char ch;
|
|
|
|
if (len > 0) *bcd_buf = 0x00;
|
|
for (i=0; i<len; i++) {
|
|
ch = ascii_buf[i];
|
|
if (ch>='a') ch -= 'a' - 10;
|
|
else if (ch>='A') ch -= 'A' - 10;
|
|
else ch -= '0';
|
|
if ((len - i) & 1) *(bcd_buf++) |= ch & 0x0f;
|
|
else *bcd_buf = ch << 4;
|
|
}
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Test
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
/*
|
|
//define in pub_log.h
|
|
static void MsgToFmtLog ( const u8 * pBcdBuff, int nBcdLen, char *pStrBuff,
|
|
int nStrBuffSize )
|
|
{
|
|
int i, len = 0;
|
|
int nChar;
|
|
|
|
nChar = ( nBcdLen % 8 ) * 3 + ( nBcdLen / 8 ) * 25 + 1;
|
|
|
|
WxcAssert ( ( nChar < nStrBuffSize ), "sprint bcd string buffer flow" );
|
|
|
|
for ( i = 1; i <= nBcdLen; i++ )
|
|
{
|
|
sprintf ( pStrBuff + len, "%02X ", pBcdBuff[i - 1] );
|
|
len += 3;
|
|
if ( 0 == ( i % 16 ) )
|
|
{
|
|
strcat ( pStrBuff, "\n" );
|
|
len++;
|
|
}
|
|
else if ( 0 == ( i % 8 ) )
|
|
{
|
|
strcat ( pStrBuff, " " );
|
|
len++;
|
|
}
|
|
}
|
|
if ( 0 != ( len % 50 ) )
|
|
{
|
|
strcat ( pStrBuff, "\n" );
|
|
}
|
|
}
|
|
|
|
//define in pub_log.h
|
|
static void ByteBinToStr( char *pDst , const u8 *pSrc , int nByte )
|
|
{
|
|
char tmpStr[2];
|
|
int i , j ;
|
|
|
|
*pDst = CNULL;
|
|
for( i =0 ; i < nByte ; i++ )
|
|
{
|
|
for( j = 7 ; j >= 0 ; j --)
|
|
{
|
|
sprintf( tmpStr , "%d" , pSrc[i] >>j & 0x01);
|
|
strcat( pDst , tmpStr) ;
|
|
}
|
|
}
|
|
}
|
|
|
|
int main()
|
|
{
|
|
u8 aBcd1[] = { 0x12 , 0x34 , 0x56 , 0x78 };
|
|
u8 aBcd2[] = { 0x01 , 0x23 , 0x45 , 0x67 };
|
|
u8 aBcd1Cp[256];
|
|
u8 aBcd2Cp[256];
|
|
u8 aStr[256];
|
|
char tmpStr1[] = "01234567899876543210";
|
|
char tmpStr2[] = "123456789";
|
|
u64 llTmp1 = 1234567890;
|
|
u64 llTmp2 = 123456789;
|
|
u8 aDig1[] = { 0x01 , 0x09 , 0x08 , 0x07 , 0x06 };
|
|
u8 aDig2[] = { 0x01 , 0x09 , 0x08 , 0x07 };
|
|
u8 uByte;
|
|
int nLen = 0;
|
|
|
|
uByte = ReverseByte(aBcd1[1]);
|
|
ByteBinToStr( aBcd1Cp , &uByte , 1 );
|
|
ByteBinToStr( aBcd2Cp , &aBcd1[1] , 1 );
|
|
printf("ReverseByte : aBcd1[1] : 0x%x [%s], Result : 0x%x[%s]\n"
|
|
, aBcd1[1] , aBcd2Cp , uByte , aBcd1Cp );
|
|
|
|
uByte = ReverseByte(aBcd2[1]);
|
|
ByteBinToStr( aBcd1Cp , &uByte , 1 );
|
|
ByteBinToStr( aBcd2Cp , &aBcd2[1], 1 );
|
|
printf("ReverseByte : aBcd2[1] : 0x%x [%s], Result : 0x%x[%s]\n\n"
|
|
, aBcd2[1] , aBcd2Cp , uByte , aBcd1Cp );
|
|
|
|
MsgToFmtLog(aBcd1 , 4 , aStr , 256 );
|
|
printf("ReverseBcd : aBcd1: %s " , aStr );
|
|
ReverseBCD(aBcd1Cp, aBcd1 , 4);
|
|
MsgToFmtLog(aBcd1Cp , 4 , aStr , 256 );
|
|
printf("Result : %s \n" , aStr );
|
|
|
|
MsgToFmtLog(aBcd2 , 4 , aStr , 256 );
|
|
printf("ReverseBcd : aBcd2: %s " , aStr );
|
|
ReverseBCD(aBcd2Cp, aBcd2 , 4);
|
|
MsgToFmtLog(aBcd2Cp , 4 , aStr , 256 );
|
|
printf("Result : %s \n\n" , aStr );
|
|
|
|
|
|
MsgToFmtLog(aBcd1 , 4 , aStr , 256 );
|
|
printf("ReverseArray : aBcd1: %s " , aStr );
|
|
ReverseArray(aBcd1Cp, aBcd1 , 4);
|
|
MsgToFmtLog(aBcd1Cp , 4 , aStr , 256 );
|
|
printf("Result : %s \n" , aStr );
|
|
|
|
MsgToFmtLog(aBcd2 , 4 , aStr , 256 );
|
|
printf("ReverseArray : aBcd2: %s " , aStr );
|
|
ReverseArray(aBcd2Cp, aBcd2 , 4);
|
|
MsgToFmtLog(aBcd2Cp , 4 , aStr , 256 );
|
|
printf("Result : %s \n\n" , aStr );
|
|
|
|
BcdToStr( aStr , aBcd1 , 4);
|
|
MsgToFmtLog(aBcd1 , sizeof(aBcd1) , aBcd2Cp , 256 );
|
|
printf("BcdToStr : aBcd1 : %s result : %s\n", aBcd2Cp , aStr);
|
|
BcdToStr( aStr , aBcd2 , 4);
|
|
MsgToFmtLog(aBcd2 , sizeof(aBcd2) , aBcd2Cp , 256 );
|
|
printf("BcdToStr : aBcd2 : %s result : %s\n\n",aBcd2Cp , aStr);
|
|
|
|
MsgToFmtLog(aBcd1 , sizeof(aBcd1) , aBcd2Cp , 256 );
|
|
printf( "BcdToU64 aBcd1 : %s result: %lld \n" , aBcd2Cp , BcdToU64( aBcd1, 4 ) );
|
|
MsgToFmtLog(aBcd2 , sizeof(aBcd2) , aBcd2Cp , 256 );
|
|
printf( "BcdToU64 aBcd2 : %s result: %lld \n\n" , aBcd2Cp ,BcdToU64( aBcd2, 4 ) );
|
|
|
|
nLen = BcdToDig( aBcd1Cp , 256 ,aBcd1 , 4 );
|
|
MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 );
|
|
MsgToFmtLog(aBcd1 , sizeof(aBcd1) , aBcd2Cp , 256 );
|
|
printf("BcdToDig :aBcd1 : %s result : %s\n" , aBcd2Cp, aStr );
|
|
|
|
nLen = BcdToDig( aBcd1Cp , 256 , aBcd2 ,sizeof(aBcd2));
|
|
MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 );
|
|
MsgToFmtLog(aBcd2 , sizeof(aBcd2) , aBcd2Cp , 256 );
|
|
printf("BcdToDig :aBcd2 : %s result : %s\n\n" , aBcd2Cp,aStr );
|
|
|
|
|
|
nLen = StrToBcd( aBcd1Cp , tmpStr1 , 256);
|
|
MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 );
|
|
printf("StrToBcd :tmpStr1 : %s result : %s\n" ,tmpStr1 , aStr);
|
|
|
|
nLen = StrToBcd( aBcd1Cp , tmpStr2 , 256);
|
|
MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 );
|
|
printf("StrToBcd :tmpStr2 : %s result : %s\n\n" ,tmpStr2 , aStr);
|
|
|
|
nLen = U64ToBcd(aBcd1Cp ,llTmp1 ,256);
|
|
MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 );
|
|
printf("U64ToBcd :llTmp1 : %lld , result: %s \n" ,llTmp1, aStr );
|
|
|
|
nLen = U64ToBcd(aBcd1Cp ,llTmp2 ,256);
|
|
MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 );
|
|
printf("U64ToBcd :llTmp2 : %lld , result: %s \n\n" ,llTmp2, aStr );
|
|
|
|
nLen = DigToBcd(aBcd1Cp, 256 , aDig1 , sizeof(aDig1));
|
|
MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 );
|
|
MsgToFmtLog(aDig1 , sizeof(aDig1) , aBcd2Cp , 256 );
|
|
printf("DigToBcd :aDig1 : %s result: %s \n" ,aBcd2Cp ,aStr );
|
|
|
|
nLen = DigToBcd(aBcd1Cp, 256, aDig2 , sizeof(aDig2) );
|
|
MsgToFmtLog(aBcd1Cp , nLen , aStr , 256 );
|
|
MsgToFmtLog(aDig2 , sizeof(aDig2) , aBcd2Cp , 256 );
|
|
printf("DigToBcd :aDig2 : %s result: %s \n" ,aBcd2Cp , aStr );
|
|
|
|
return 0;
|
|
}
|
|
*/
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// Test result
|
|
//
|
|
///////////////////////////////////////////////////////////////////////////
|
|
|
|
/*
|
|
ReverseByte : aBcd1[1] : 0x34 [00110100], Result : 0x2c[00101100]
|
|
ReverseByte : aBcd2[1] : 0x23 [00100011], Result : 0xc4[11000100]
|
|
|
|
ReverseBcd : aBcd1: 12 34 56 78
|
|
Result : 21 43 65 87
|
|
|
|
ReverseBcd : aBcd2: 01 23 45 67
|
|
Result : 10 32 54 76
|
|
|
|
|
|
ReverseArray : aBcd1: 12 34 56 78
|
|
Result : 78 56 34 12
|
|
|
|
ReverseArray : aBcd2: 01 23 45 67
|
|
Result : 67 45 23 01
|
|
|
|
|
|
BcdToStr : aBcd1 : 12 34 56 78
|
|
result : 12345678
|
|
BcdToStr : aBcd2 : 01 23 45 67
|
|
result : 01234567
|
|
|
|
BcdToU64 aBcd1 : 12 34 56 78
|
|
result: 12345678
|
|
BcdToU64 aBcd2 : 01 23 45 67
|
|
result: 1234567
|
|
|
|
BcdToDig :aBcd1 : 12 34 56 78
|
|
result : 01 02 03 04 05 06 07 08
|
|
|
|
BcdToDig :aBcd2 : 01 23 45 67
|
|
result : 00 01 02 03 04 05 06 07
|
|
|
|
|
|
StrToBcd :tmpStr1 : 01234567899876543210 result : 01 23 45 67 89 98 76 54 32 10
|
|
|
|
StrToBcd :tmpStr2 : 123456789 result : 01 23 45 67 89
|
|
|
|
|
|
U64ToBcd :llTmp1 : 1234567890 , result: 12 34 56 78 90
|
|
|
|
U64ToBcd :llTmp2 : 123456789 , result: 01 23 45 67 89
|
|
|
|
|
|
DigToBcd :aDig1 : 01 09 08 07 06
|
|
result: 01 98 76
|
|
|
|
DigToBcd :aDig2 : 01 09 08 07
|
|
result: 19 87
|
|
|
|
*/
|