/***************************************************************************
**
**    $Header$
**
**    $Log$
** 
****************************************************************************/

/****************************************************************************
**
**  Name:   FmtStr.cpp
**
**  Description:  This file describe the sub class of string format type.
**
**  Status:       Initialization
**                1996/03/04                    Daniel Lin
**
**  Copyright (C) 1996 Microtek International.  All rights reserved.
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#include "stdafx.h"                                                
#include "address.h"                // Include main head file

                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *     LOCAL DEFINITIONS    *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *       GLOBAL VARS        *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *     LOCAL PROTOTYPES     *
                        *                          *
                        ****************************/

                       /****************************
                        *                          *
                        *      EXECUTABLE CODE     *
                        *                          *
                        ****************************/

/**------------------------------------------------------------------------**
 ** Dec2Num                                                                **
 **   Convert decimal string to decimal numeric.If the string include      **
 **   invalid character such as 'A', 'b', '?' etc. the convert will        **
 **   failure. Otherwise, the convert will be successful                   **
 **                                                                        **
 ** parameter :                                                            **
 **      char*    pszInput    -- the string which format is decimal        **
 **      int&     dwAddress   -- the converted address                     **
 **                                                                        **
 ** return value :                                                         **
 **      BOOL     TRUE        -- convert successful                        **
 **               FALSE       -- convert failure                           **
 **------------------------------------------------------------------------**/

BOOL
CFormatString :: Dec2Num( char* pszInput, DWORD& dwAddress )
{
   	char * p = pszInput;

   	int l = strlen(p);
   	if (l == 0)  return FALSE;

   	DWORD dw = 1;
  	dwAddress = 0;
   	p += l - 1;
   	
   	// This method include filter the zero at head
   	// The mothod is describe as following:
   	//  n bit decimal numerica:  A(n-1)A(n-2)...A(0) is 
   	//     A(n-1)*10^(n-1)+A*10^(n-2)...+A*10^(0)
   	//    eg:
   	//       1996 is 1*10^3+9*10^2+9*10^1+6*10^0
   	// If the numerica is 00000000001, the all zero at head is filtered by 
   	// the method
   	//
   	for (int i = 0; i < l; i ++, p --, dw *= 10) {
       	if (*p < '0' || *p > '9')
         	return FALSE;
       	dwAddress += (*p - '0') * dw;
   	}

   	return TRUE;
}

/**------------------------------------------------------------------------**
 ** Hex2Num                                                                **
 **   Convert hexadecimal string to  hexadecimal numeric.If the string     **
 **   include invalid character such as 'X', 'y', '?' etc. the convert will**
 **   failure. Otherwise, the convert will be successful                   **
 **                                                                        **
 ** parameter :                                                            **
 **      char*    pszInput    -- the string which format is decimal        **
 **                              The input string must not include 0x as   **
 **                              prefix                                    **
 **      int&     dwAddress   -- the converted address                     **
 **                                                                        **
 ** return value :                                                         **
 **      BOOL     TRUE        -- convert successful                        **
 **               FALSE       -- convert failure                           **
 **------------------------------------------------------------------------**/
static char BASED_CODE szMax[] = "FFFFFFFF";

BOOL
CFormatString :: Hex2Num( const char* pszInput, DWORD& dwAddress )
{

//Added by Annie, 3/4/97   	
   	CString str(pszInput);
   	
	for ( int i = 0; i < str.GetLength(); i++ ) {
		if ( str[i] != '0' )
			break;	
	}
	if ( str.GetLength() > 1 ) {
		str = str.Right(str.GetLength()-i);	
	}	
	if ( str.IsEmpty() ) {
		str = '0';
	}
	if ( str.GetLength() > 8 ) 
		str = szMax ;			
			   	
   	char * pointer = new char[strlen(str/*pszInput*/)+1];
                                        
   	strcpy(pointer, str/*pszInput*/);
   	
   	char *p;
   	p = pointer;
   	int l = strlen(str/*pszInput*/);
   	if (l == 0) {
      	delete []pointer;
      	return FALSE;
   	}      
   
   	DWORD dw  = 1;
   	dwAddress = 0;
   	p += l - 1;        
   
   
   	// This mothod is the same as described in Dec2Num. The different is
   	// that the base is 16, not 10
   	// The all zero behind 0x will be filtered by the mothod
   
   	for ( i = 0; i < l; p --, i ++, dw *= 16) {
       	if(*p >= '0' && *p <= '9') dwAddress += (*p - '0') * dw;
       	else if(*p >= 'a' && *p <= 'f') dwAddress += (*p - 'a' + 10) * dw;
       	else if(*p >= 'A' && *p <= 'F') dwAddress += (*p - 'A' + 10) * dw;
       	else {
         	delete []pointer;
         	return FALSE;
       	}         
   	}
   
   	delete []pointer;
   	return TRUE;
}

/**------------------------------------------------------------------------**
 ** Str2Num                                                                **
 **   Convert a string to a numeric.If the string include invalid          **
 **   character such as 'A', 'b', '?' etc. the convert will failure.       **
 **   Otherwise, the convert will be successful                            **
 **                                                                        **
 ** parameter :                                                            **
 **      char*    pszInput    -- the string which format is decimal        **
 **      int&     dwAddress   -- the converted address                     **
 **                                                                        **
 ** return value :                                                         **
 **      BOOL     TRUE        -- convert successful                        **
 **               FALSE       -- convert failure                           **
 **------------------------------------------------------------------------**/

BOOL
CFormatString :: Str2Num( char* pszInput, DWORD&  dwAddress )
{
   	BOOL bIsOk = FALSE;
   
   	char *pszTemp2 = new char[strlen(pszInput) + 2];
   	char *pszTemp3;
   
   	memset(pszTemp2, 0, strlen(pszInput) + 2);
   	strcpy(pszTemp2, pszInput);
   
   	//Cut the input string to 4 bytes
   
   	if (strlen(pszTemp2) > 8)
      	return FALSE;
   	else {
      	if(*pszTemp2 == '0' && (*(pszTemp2+1) == 'x' || *(pszTemp2+1) == 'X')) {
          	pszTemp3 = pszTemp2+2;
          	bIsOk = Hex2Num(pszTemp3, dwAddress);
      	}
      	else
        	bIsOk = Dec2Num(pszTemp2, dwAddress);
   	}      
   
   	delete []pszTemp2;
   	return  bIsOk;
}

/**------------------------------------------------------------------------**
 ** Str2Num                                                                **
 **   Convert a string to a numeric.If the string include invalid          **
 **   character such as 'A', 'b', '?' etc. the convert will failure.       **
 **   Otherwise, the convert will be successful                            **
 **                                                                        **
 ** parameter :                                                            **
 **      CString& pszInput    -- the string which format is decimal        **
 **      int&     dwAddress   -- the converted address                     **
 **                                                                        **
 ** return value :                                                         **
 **      BOOL     TRUE        -- convert successful                        **
 **               FALSE       -- convert failure                           **
 **------------------------------------------------------------------------**/

BOOL 
CFormatString :: Str2Num( CString strInput, DWORD&  dwAddress )
{
   	int strLen;
   	char* strBuffer;
   	BOOL bRet;
   
   	if (strInput.IsEmpty()) {      	
      	ASSERT(FALSE);
      	return FALSE;
   	}
   
   	strLen = strInput.GetLength();     // Get the input string's length
   	strBuffer = new char[strLen+2];    // alloc the temp buffer
   	if (!strBuffer) {      	
      	ASSERT (!strBuffer);
      	return FALSE;
   	}
   	memset(strBuffer, 0, strLen+2);
   	strcpy(strBuffer, strInput.GetBuffer(strLen)); 
   
   	bRet = Str2Num(strBuffer, dwAddress);  // Call another Str2Num();
   	if (FALSE == bRet) {
      	delete strBuffer;
      	return FALSE;
   	}
   	else {
      	delete strBuffer;
      	return TRUE;
   	}
}
   
//
// convert numerica to hex string
//
BOOL
CFormatString :: Num2HexStr( const DWORD iAddr, char* strAddr )
{  
   	char strConvert[35];
   
   	if (NULL == strAddr) {      	
      	ASSERT(FALSE);
    	return FALSE;
   	}
   	strConvert[0] = '0';strConvert[1] = 'X';
   	_ultoa(iAddr, strConvert+2, 16);

   	#ifdef _DEBUG
    DWORD dwConvert  = 0;
    dwConvert = (DWORD)atol(strConvert+2);
    if (dwConvert != iAddr) {
        AfxMessageBox("Error  convert!!!");
    	return FALSE;
    }
   	#endif

   	strcpy(strAddr, strConvert);
   	return TRUE;
}

//
// convert numerica to hex string
//
BOOL
CFormatString :: Num2HexStr( const DWORD iAddr, CString& strAddr )
{
   	return Num2HexStr(iAddr, strAddr.GetBuffer(strAddr.GetLength()));
}
  
//  
// convert numerica to dec string
//
BOOL
CFormatString :: Num2DecStr( const DWORD iAddr, char* strAddr )
{
   	char strConvert[35];
   
   	if (NULL == strAddr) {      	
      	ASSERT(FALSE);
      	return FALSE;
   	}
   
   	_ultoa(iAddr, strConvert, 10);

   	#ifdef _DEBUG
    DWORD dwConvert = 0;
    dwConvert = (DWORD)atol(strConvert);
    if (dwConvert != iAddr) {
        AfxMessageBox("Error convert!!!");
    	return FALSE;
    }
   	#endif

   	strcpy(strAddr, strConvert);

   	return TRUE;
}

//  
// convert numerica to dec string
//
BOOL
CFormatString :: Num2DecStr( const DWORD iAddr, CString& strAddr )
{
   	return Num2DecStr(iAddr, strAddr.GetBuffer(strAddr.GetLength()));
}

void
CFormatString :: Convert()
{
   //Empty function
}
