os/textandloc/textandlocutils/numbergrouping/src/StateMachine.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/textandloc/textandlocutils/numbergrouping/src/StateMachine.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,216 @@
     1.4 +/*
     1.5 +* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
     1.6 +* All rights reserved.
     1.7 +* This component and the accompanying materials are made available
     1.8 +* under the terms of the License "Eclipse Public License v1.0"
     1.9 +* which accompanies this distribution, and is available
    1.10 +* at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.11 +*
    1.12 +* Initial Contributors:
    1.13 +* Nokia Corporation - initial contribution.
    1.14 +*
    1.15 +* Contributors:
    1.16 +*
    1.17 +* Description: 
    1.18 +*
    1.19 +*/
    1.20 +
    1.21 +
    1.22 +#include "StateMachine.h"
    1.23 +
    1.24 +// CStateMachine
    1.25 +CStateMachine::CStateMachine(TInt aMaxNumberChars, TInt aMaxNumberStates) : iMaxNumberChars(static_cast<TInt>(aMaxNumberChars)),
    1.26 +																			iMaxNumberStates(static_cast<TInt>(aMaxNumberStates))
    1.27 +{
    1.28 +}
    1.29 +
    1.30 +CStateMachine* CStateMachine::NewL(TInt aMaxNumberChars, TInt aMaxNumberStates)
    1.31 +{
    1.32 +	CStateMachine* s = NewLC(aMaxNumberChars, aMaxNumberStates);
    1.33 +	CleanupStack::Pop();
    1.34 +	return s;
    1.35 +}
    1.36 +
    1.37 +CStateMachine* CStateMachine::NewLC(TInt aMaxNumberChars, TInt aMaxNumberStates)
    1.38 +{
    1.39 +	CStateMachine* s = new(ELeave)CStateMachine(aMaxNumberChars, aMaxNumberStates);
    1.40 +	CleanupStack::PushL(s);
    1.41 +	s->ConstructL();
    1.42 +	return s;
    1.43 +}
    1.44 +
    1.45 +CStateMachine::~CStateMachine()
    1.46 +{
    1.47 +	for(TInt i = 0; i < iMaxNumberChars; ++i)
    1.48 +		delete iStateTable[i];
    1.49 +	
    1.50 +	delete iStateTable;
    1.51 +}
    1.52 +
    1.53 +void CStateMachine::ConstructL()
    1.54 +{
    1.55 +	iStateTable = new TInt*[iMaxNumberChars];	
    1.56 +
    1.57 +	for(TInt i = 0; i < iMaxNumberChars; ++i)
    1.58 +	{
    1.59 +		iStateTable[i] = new TInt[iMaxNumberStates];
    1.60 +		for(TInt j = 0; j < iMaxNumberStates; j++)
    1.61 +			iStateTable[i][j] = 0;
    1.62 +	}
    1.63 +}
    1.64 +
    1.65 +void CStateMachine::AddStateTransistionL(TChar aChar, TInt aState, TInt aNextState)
    1.66 +{
    1.67 +	RArray<TInt> Dummy;
    1.68 +	TInt CharIndex = MapIndex(aChar, Dummy);
    1.69 +	Dummy.Close();
    1.70 +	
    1.71 +	AddStateTransistionL(CharIndex, aState, aNextState);
    1.72 +}
    1.73 +
    1.74 +void CStateMachine::AddStateTransistionL(TInt aIndex, TInt aState, TInt aNextState)
    1.75 +{
    1.76 +    if(aIndex < 0 || aIndex > iMaxNumberChars || aState > iMaxNumberStates || aNextState > iMaxNumberStates)
    1.77 +		User::Leave(KErrGeneral);
    1.78 +
    1.79 +	iStateTable[static_cast<TInt>(aIndex)][static_cast<TInt>(aState)] = static_cast<TInt>(aNextState);
    1.80 +}
    1.81 +
    1.82 +TBool CStateMachine::Matches(const TDesC& aString)
    1.83 +{
    1.84 +	// Walk the state table and return true if the string matches the pattern.
    1.85 +	
    1.86 +	TInt			nTableState = KStateNoMatch;
    1.87 +	RArray<TInt>	arrIndices;
    1.88 +	TBool			bFound = EFalse;
    1.89 +
    1.90 +	for(TInt nStringIndex = 0; nStringIndex < aString.Length(); ++nStringIndex)
    1.91 +	{
    1.92 +		arrIndices.Reset();
    1.93 +		
    1.94 +		TChar	charChar = aString[nStringIndex];
    1.95 +		TInt	nTableIndex = MapIndex(charChar, arrIndices);
    1.96 +
    1.97 +		if(nTableIndex == -1) 
    1.98 +			return EFalse;
    1.99 +		
   1.100 +		TInt nCount = arrIndices.Count();
   1.101 +		
   1.102 +		if(nCount)
   1.103 +		{
   1.104 +			for(TInt i = 0; i < nCount; i++)
   1.105 +			{
   1.106 +				nTableIndex = arrIndices[i];
   1.107 +				TInt NewTableState = iStateTable[nTableIndex][nTableState];
   1.108 +				
   1.109 +				if( NewTableState != KStateNoMatch || 
   1.110 +					(NewTableState == KStateNoMatch && i == (arrIndices.Count() - 1)) ||
   1.111 +					NewTableState == KStateMatched)
   1.112 +				{
   1.113 +					nTableState = NewTableState;
   1.114 +					break;
   1.115 +				}
   1.116 +			}
   1.117 +		}
   1.118 +		else
   1.119 +		{
   1.120 +			nTableState = iStateTable[nTableIndex][nTableState];
   1.121 +		}
   1.122 +
   1.123 +		if(nTableState == KStateNoMatch)
   1.124 +			break;
   1.125 +
   1.126 +		if(nTableState == KStateMatched)
   1.127 +		{
   1.128 +			bFound = ETrue;
   1.129 +			break;
   1.130 +		}
   1.131 +	}
   1.132 +
   1.133 +	arrIndices.Close();
   1.134 +	
   1.135 +	return bFound;
   1.136 +}
   1.137 +
   1.138 +TInt CStateMachine::MapIndex(TChar aChar, RArray<TInt>& aIndices)
   1.139 +{
   1.140 +    // Check the type of aChar and return the relevant index or indicies
   1.141 +	if(aChar.IsDigit())
   1.142 +	{
   1.143 +		TInt nIndex = static_cast<TInt>(aChar.GetNumericValue());
   1.144 +		
   1.145 +		TInt ret = KErrNone;
   1.146 +		ret |= aIndices.Append(nIndex);
   1.147 +		ret |= aIndices.Append(KCharacterDot);
   1.148 +		__ASSERT_DEBUG(!ret, User::Panic(_L("RArray append failure"), ret));
   1.149 +		if (KErrNone != ret) return ret;
   1.150 +
   1.151 +		return nIndex;
   1.152 +	}
   1.153 +
   1.154 +	if(aChar == '+')	return KCharacterPlus;
   1.155 +	if(aChar == '.')	return KCharacterDot;
   1.156 +
   1.157 +    return -1;  // TO DO : define 
   1.158 +}
   1.159 +
   1.160 +void CStateMachine::GetWildcardVersionOfPattern( 
   1.161 +    TText aWildcardChar, 
   1.162 +    TDes& aWildcardedPattern ) const
   1.163 +    {
   1.164 +    aWildcardedPattern.SetLength(0);
   1.165 +    TInt maxLength = aWildcardedPattern.MaxLength();
   1.166 +    // There is a column in the StateTable for each character in the regular expression. The first character
   1.167 +    // of the regexp in column [0], last in column [Length()-1]
   1.168 +    // The non-zero values found within a column of the StateTable represent the characters
   1.169 +    // that are valid at that position in a candidate match.
   1.170 +    // An example pattern is calculated by examining the StateTable.
   1.171 +    // For each column, count the number of matching ( i.e. not KStateNoMatch) states
   1.172 +    // If only one, then place that character in the example pattern.
   1.173 +    // If more than one, put the wildcard in.
   1.174 +    for(TInt stateIndex = 0; stateIndex < iMaxNumberStates && stateIndex < maxLength; stateIndex++)
   1.175 +        {
   1.176 +        TInt matches = 0;
   1.177 +        TInt matchedIndex = -1;
   1.178 +        for (TInt charIndex = 0; charIndex < iMaxNumberChars; charIndex++ )
   1.179 +            {
   1.180 +            TInt nextState = iStateTable[charIndex][stateIndex];
   1.181 +
   1.182 +            if ( nextState != KStateNoMatch )
   1.183 +                {
   1.184 +                matches++;
   1.185 +                matchedIndex = charIndex;
   1.186 +                if (matches > 1 )
   1.187 +                    break;
   1.188 +                }
   1.189 +            }
   1.190 +        if ( matches == 0 ) // Have found an empty column.  Unused part of state machine. Stop filling
   1.191 +            {
   1.192 +            break;
   1.193 +            }
   1.194 +        else if ( matches > 1 )
   1.195 +            aWildcardedPattern.Append(aWildcardChar);
   1.196 +        else
   1.197 +            {
   1.198 +            if ( 0 <= matchedIndex && matchedIndex <= 9 ) // Must be a numeric digit
   1.199 +                {
   1.200 +                aWildcardedPattern.Append((TText)(matchedIndex+'0'));
   1.201 +                }
   1.202 +            else if ( matchedIndex == KCharacterDot )
   1.203 +                {
   1.204 +                aWildcardedPattern.Append(aWildcardChar);
   1.205 +                }
   1.206 +            else if ( matchedIndex == KCharacterPlus )
   1.207 +                {
   1.208 +                aWildcardedPattern.Append('+');
   1.209 +                }
   1.210 +            else
   1.211 +                {
   1.212 +                aWildcardedPattern.Append(aWildcardChar);
   1.213 +                }
   1.214 +            }
   1.215 +        }
   1.216 +
   1.217 +    }
   1.218 +// End of File
   1.219 +