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 +