//////////////////////////////////////////////////
//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'
 **                                                                 
 **/
char HexToCh( u8 uHex )
{
	return ( (uHex) + ( ((uHex) > 9)? 'A'-10 : '0') );
}

/**
 **  @note ChToHex :   '0' - > 0
 **                                                                 
 **/
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  
 **
 **/
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
 **                                                                 
 **/
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 
 **                                                                 
 **/
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"
 **                                                                 
 **/
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
 **                                                                 
 **/
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 
 **                                                                 
 **/
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 
 **                                                                 
 **/
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  
 **                                                                 
 **/
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  
 **                                                                 
 **/
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  
 **                                                                 
 **/
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;
}

//only called by VLR to change IMSI to digits
int Ull2Digits ( BYTE * pDigits, ull value, int DigitsLen )
{
    char tempStr[64];

    if((value < 100000000000000LL) && (DigitsLen < 16))//IMSI pad 15 digits
    {
        sprintf ( tempStr, "%015lld", value );
    }
    else
    {
        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;
    u_char 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;
    }
}

int ValidateAsciiMSISDN(char *msisdn, int len)
{
	int i;
	
	if(len>16) return 0;
	if(msisdn == NULL) return 0;

	for(i=0;i<len;i++)
	{
		if(!isdigit(msisdn[i]))
			return 0;
	}
	return 1;
}

///////////////////////////////////////////////////////////////////////////
//  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

*/
