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

/****************************************************************************
**
**  Name:   CFmtadr.cpp
**
**  Description:  Main file of CFmtadr.cpp.
**                This file describe the class of CFormatAddress.
**                CFormatAddress deprived from the base class of CFormat.
**
**  Status:    Initialization
**             1996/9/16      Annie Yi
**
**  Copyright (C) 1996 Microtek International.  All rights reserved.
*****************************************************************************/

                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/
#include "stdafx.h"                        
#include "address.h"                // Include main head file
#include <ctype.h>
                       /****************************
                        *                          *
                        *    EXTERNAL VARIABLES    *
                        *                          *
                        ****************************/

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

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

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

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

/****************************************************************************
**  Name:   CFormatAddress();
**
**  Description: Constructor. Only do some initialize
**
**  Parameters:
**     input:  none
**
**     output: none
**
*****************************************************************************/

CFormatAddress :: CFormatAddress()
{
	m_strOriginAdr.Empty();    // Original address string. No any change
                            // Get from construct or Set function
    m_dwAddress = 0;        // The data of address(converted form string,
                            // or get from constructor)
                            // After converted successful, the m_dwAddress
                            // is the address.
                            // In
    m_strPrefix.Empty();       // Prefix front the address.
                            // Such as in 51 base family the prefix of
                            // p:0x987 is "p"
                            // In 86 family, the prefix is the segment or
                            // descriptor
                            // etc;
    m_strAddress.Empty();      // After split the prefix,
                            // In 51 family, it is the absoluted address
                            // In 86 family, it is the offset
                            // etc;

    m_strAddressHex.Empty();   // The converted hex address
    m_strAddressDec.Empty();   // The converted dec address
}

/**------------------------------------------------------------------------**
 ** SkipHeadWS                                                             **
 **   Filter all white soace char at the head of the string.               **
 **   The original string will change.                                     **
 **                                                                        **
 ** parameter :                                                            **
 **      char*    pszInput    -- the string                                **
 **                                                                        **
 ** return value :                                                         **
 **      char*    the converted string                                     **
 **------------------------------------------------------------------------**/

void
CFormatAddress::SkipHeadWS(char* pszInput)
{  
   	int   uCount = 0;
   	ASSERT(NULL != pszInput);
   	char *pszTemp = new char[strlen(pszInput)+2];
   	memset(pszTemp, 0, strlen(pszInput)+2);
   	ASSERT(NULL != pszTemp);
   	if (NULL == pszTemp) {
      	AfxMessageBox("memory alloc error!!!!");
      	return;
   	}
   
   	strcpy(pszTemp, pszInput);
   	while(IsSpace(pszTemp[uCount]))    
     	++uCount;
   	strcpy(pszInput, pszTemp+uCount);
   
   	delete []pszTemp;
   
   	return;
}

/**------------------------------------------------------------------------**
 ** IsSpace                                                                **
 **   Distinguish the input char is white space or not                     **
 **                                                                        **
 ** parameter :                                                            **
 **    char   chInput    -- the char inputed                               **
 **                                                                        **
 ** return value :                                                         **
 **    BOOL   TRUE     -- the char is white space                          **
 **           FASLE    -- the char is not white space                      **
 **------------------------------------------------------------------------**/

BOOL
CFormatAddress::IsSpace(char chInput)
{
   	return (chInput == ' '
           || chInput == '\t'
           || chInput == '\n'
           || chInput == '\r');
}

/**------------------------------------------------------------------------**
 ** CutTailWS                                                              **
 **   Filter the white space at the end of the string                      **
 **   The original string will change                                      **
 **                                                                        **
 ** parameter :                                                            **
 **      char*    pszInput    -- the string                                **
 **                                                                        **
 ** return value :                                                         **
 **   none                                                                 **
 **------------------------------------------------------------------------**/

void
CFormatAddress::CutTailWS(char* pszInput)
{ 
   	int l = strlen(pszInput);
   	if (!l)  return;   
   	char* pointer;
   
   	pointer = pszInput; 
  	pointer += (l - 1);
    
   	int i = l; 
   	while(IsSpace(*pointer) && (i>0)) {
      	--pointer;
      	i--;
   	}
   
   	*(pointer+1) = '\0';
   
   	return;
}

/**------------------------------------------------------------------------**
 ** SkipHeadZero                                                           **
 **   Filter all zero char at the head of the string.                      **
 **   The original string will change.                                     **
 **   The function eill be no use                                          **
 **                                                                        **
 ** parameter :                                                            **
 **      char*    pszInput    -- the string which format is decimal        **
 **                                                                        **
 ** return value :                                                         **
 **      char*    the converted string                                     **
 **------------------------------------------------------------------------**/

void
CFormatAddress::SkipHeadZero(char*  pszInput)
{ 
   	int lencount = 0, len, uCount = 0;
   	len = strlen(pszInput);
   	char *pszTemp = new char[len+2];
   	memset(pszTemp, 0, len+2);
   	strcpy(pszTemp, pszInput);   
   
   	while (IsZero(pszTemp[uCount])) {
     	++uCount;
     	lencount++;
   	}

   	if (lencount == len) {      // The string is all zero
      	strcpy(pszInput, pszTemp+uCount-1);
      	delete []pszTemp;
      	return;         // return one zero char
   	}      
   	else {                      // otherwise, return the correct char
      	strcpy(pszInput, pszTemp+uCount);      
      	delete []pszTemp;  
      	return;
   	}      
   
   	return;
}

/**------------------------------------------------------------------------**
 ** IsZero                                                                 **
 **   Distinguish the input char is zero char '0'                          **
 **   The function will be no use                                          **
 **                                                                        **
 ** parameter :                                                            **
 **    char   chInput    -- the char inputed                               **
 **                                                                        **
 ** return value :                                                         **
 **    BOOL   TRUE       -- the char is zero                               **
 **           FASLE      -- the char is not zero                           **
 **------------------------------------------------------------------------**/

BOOL
CFormatAddress::IsZero(char chInput)
{
   	return ('0' == chInput);
}


/****************************************************************************
**  Name:   IsSymbol
**
**  Description:  distinguish the string is symbol
**
**  Parameters:
**     input:  char* lpsz
**
**     output: BOOL
**
*****************************************************************************/

BOOL
CFormatAddress::IsSymbol(char* lpsz)
{
   	if ('#' == lpsz[0])
      	return TRUE;
   	else
      	return FALSE;
}

BOOL
CFormatAddress::IsSymbolData(char* lpsz)
{
   	if ('$' == lpsz[0])
      	return TRUE;
   	else
      	return FALSE;
}      

/****************************************************************************
**  Name:   IsHex
**
**  Description:  distinguish the string is Hex
**
**  Parameters:
**     input:  char* lpsz
**
**     output: BOOL
**
*****************************************************************************/

BOOL
CFormatAddress::IsHex(char* lpsz)
{
   	if ('0' == lpsz[0] ) {
   		if ( 'X' == lpsz[1] || 'x' == lpsz[1] ) {
   		//if ( 'X' == _toupper(lpsz[1]) ) {
      		return TRUE;                                
      	}
      	else {
      		return FALSE;
      	}	
    }  	
   	else {
      	return FALSE;
    }  	
}

/****************************************************************************
**  Name:   IsDec
**
**  Description:  // distinguish the string is Dec
**
**  Parameters:
**     input:  char* lpsz
**
**     output: BOOL
**
*****************************************************************************/

BOOL
CFormatAddress::IsDec(char* /*lpsz*/)
{
   	return TRUE;
}

/****************************************************************************
**  Name:   IsWhichFormat
**
**  Description:  Return the format enum
**
**  Parameters:
**     input:  char* lpsz
**
**     output: FORMATTYPE
**
*****************************************************************************/

FORMATTYPE
CFormatAddress::IsWhichFormat(void)
{
   	char* lpszTemp;

   	lpszTemp = new char[m_strAddress.GetLength()+2];
   	memset(lpszTemp, 0, m_strAddress.GetLength()+2);
   	strcpy(lpszTemp, m_strAddress.GetBuffer(m_strAddress.GetLength()));

   	if (IsSymbol(lpszTemp)) {
     	delete []lpszTemp;
      	return IS_SYM;
   	}
/*   
   if (IsSymbolData(lpszTemp)) {
      delete []lpszTemp;
      return IS_SYM_DATA;
   }
*/
   	delete []lpszTemp;
         
   	////////////////////////////////
   	// The following is add by Danie Lin(little cow) on 04/16/1996
   	// Only for the new SPEC from MII on 04/16/1996
   	// Address input is must use hexdecimal as default
   	//    The address is as:
   	//          p:FF or p:0xFF are all correct
   	//      There is no decimal input
   	//
//   	CString  strHexAddr = "0x";    // The hex leading
   	CString  strHexAddr;
   	strHexAddr = '0';    // The hex leading
   	strHexAddr += 'X';
   
   	if ( 1 == m_nDefaultIsHex ) {            // Default is set to hex
      	if ( m_strAddress.GetLength() > 2 ) {
         	if ( '0' == m_strAddress[0] && 
            	('x' == m_strAddress[1] || 'X' == m_strAddress[1]) ) {
           	// Do nothing
           	//   
           		lpszTemp = new char[m_strAddress.GetLength()+2];
           		memset(lpszTemp, 0, m_strAddress.GetLength()+2);
           		strcpy(lpszTemp, m_strAddress.GetBuffer(m_strAddress.GetLength()));
         	}
         	else {
           		strHexAddr += m_strAddress;
           		m_strAddress = strHexAddr;
           		lpszTemp = new char[m_strAddress.GetLength()+2];
           		memset(lpszTemp, 0, m_strAddress.GetLength()+2);
           		strcpy(lpszTemp, m_strAddress.GetBuffer(m_strAddress.GetLength()));
         	}
      	}
      	else {
        	strHexAddr += m_strAddress;
        	m_strAddress = strHexAddr;
        	lpszTemp = new char[m_strAddress.GetLength()+2];
        	memset(lpszTemp, 0, m_strAddress.GetLength()+2);
        	strcpy(lpszTemp, m_strAddress.GetBuffer(m_strAddress.GetLength()));
      	}   
   	}
   	else {
      	// Only for process the data   
     	// Do nothing
      
      	lpszTemp = new char[m_strAddress.GetLength()+2];
      	memset(lpszTemp, 0, m_strAddress.GetLength()+2);
      	strcpy(lpszTemp, m_strAddress.GetBuffer(m_strAddress.GetLength()));
   	}
   
   	////////////////////////////////////
   
   	if (IsHex(lpszTemp)) {
     	delete []lpszTemp;
     	return IS_HEX;
   	}   
    
   	if (IsDec(lpszTemp)) {
     	delete []lpszTemp;
     	return IS_DEC;
   	}  
   
   	delete []lpszTemp;
   	return IS_UNKNOWN;
}

/****************************************************************************
**  Name:   CheckLength
**
**  Description:  Check the address length.
**                If greate than the max length, it is overflow
**
**  Parameters:
**     input:  FORMATTYPE  ft    --    Distinguish the address is HEX or DEC
**             char* lpsz        --    The address text string
**
**     output: BOOL  -- FASE if overflow 
**                      TRUE if correct
**
*****************************************************************************/

BOOL
CFormatAddress::CheckLength(FORMATTYPE ft, const CString &lpsz)
{
   	BOOL  bIsOk = TRUE;
   
   	switch(ft) {
      	case  IS_HEX:
            if (lpsz.GetLength() > HEXLENGTH)
               	bIsOk = FALSE;
            break;
            
      case  IS_DEC:
            if (lpsz.GetLength() > DECLENGTH)
               	bIsOk = FALSE;
            break;
   	}      
   	
   	return bIsOk;
}

////////////////////////////////(EOF)///////////////////////////////////////

