textandlocutils/numbergrouping/src/StateMachine.cpp
author hgs
Thu, 24 Jun 2010 11:25:56 +0800
changeset 41 ea44a32a96bc
parent 40 91ef7621b7fc
permissions -rw-r--r--
201024_03
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
40
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
     1
/*
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
     2
* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
     3
* All rights reserved.
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
     4
* This component and the accompanying materials are made available
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
     5
* under the terms of the License "Eclipse Public License v1.0"
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
     6
* which accompanies this distribution, and is available
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
     8
*
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
     9
* Initial Contributors:
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    11
*
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    12
* Contributors:
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    13
*
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    14
* Description: 
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    15
*
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    16
*/
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    17
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    18
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    19
#include "StateMachine.h"
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    20
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    21
// CStateMachine
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    22
CStateMachine::CStateMachine(TInt aMaxNumberChars, TInt aMaxNumberStates) : iMaxNumberChars(static_cast<TInt>(aMaxNumberChars)),
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    23
																			iMaxNumberStates(static_cast<TInt>(aMaxNumberStates))
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    24
{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    25
}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    26
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    27
CStateMachine* CStateMachine::NewL(TInt aMaxNumberChars, TInt aMaxNumberStates)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    28
{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    29
	CStateMachine* s = NewLC(aMaxNumberChars, aMaxNumberStates);
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    30
	CleanupStack::Pop();
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    31
	return s;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    32
}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    33
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    34
CStateMachine* CStateMachine::NewLC(TInt aMaxNumberChars, TInt aMaxNumberStates)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    35
{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    36
	CStateMachine* s = new(ELeave)CStateMachine(aMaxNumberChars, aMaxNumberStates);
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    37
	CleanupStack::PushL(s);
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    38
	s->ConstructL();
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    39
	return s;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    40
}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    41
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    42
CStateMachine::~CStateMachine()
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    43
{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    44
	for(TInt i = 0; i < iMaxNumberChars; ++i)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    45
		delete iStateTable[i];
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    46
	
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    47
	delete iStateTable;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    48
}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    49
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    50
void CStateMachine::ConstructL()
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    51
{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    52
	iStateTable = new TInt*[iMaxNumberChars];	
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    53
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    54
	for(TInt i = 0; i < iMaxNumberChars; ++i)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    55
	{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    56
		iStateTable[i] = new TInt[iMaxNumberStates];
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    57
		for(TInt j = 0; j < iMaxNumberStates; j++)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    58
			iStateTable[i][j] = 0;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    59
	}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    60
}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    61
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    62
void CStateMachine::AddStateTransistionL(TChar aChar, TInt aState, TInt aNextState)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    63
{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    64
	RArray<TInt> Dummy;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    65
	TInt CharIndex = MapIndex(aChar, Dummy);
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    66
	Dummy.Close();
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    67
	
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    68
	AddStateTransistionL(CharIndex, aState, aNextState);
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    69
}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    70
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    71
void CStateMachine::AddStateTransistionL(TInt aIndex, TInt aState, TInt aNextState)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    72
{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    73
    if(aIndex < 0 || aIndex > iMaxNumberChars || aState > iMaxNumberStates || aNextState > iMaxNumberStates)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    74
		User::Leave(KErrGeneral);
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    75
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    76
	iStateTable[static_cast<TInt>(aIndex)][static_cast<TInt>(aState)] = static_cast<TInt>(aNextState);
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    77
}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    78
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    79
TBool CStateMachine::Matches(const TDesC& aString)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    80
{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    81
	// Walk the state table and return true if the string matches the pattern.
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    82
	
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    83
	TInt			nTableState = KStateNoMatch;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    84
	RArray<TInt>	arrIndices;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    85
	TBool			bFound = EFalse;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    86
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    87
	for(TInt nStringIndex = 0; nStringIndex < aString.Length(); ++nStringIndex)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    88
	{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    89
		arrIndices.Reset();
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    90
		
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    91
		TChar	charChar = aString[nStringIndex];
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    92
		TInt	nTableIndex = MapIndex(charChar, arrIndices);
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    93
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    94
		if(nTableIndex == -1) 
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    95
			return EFalse;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    96
		
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    97
		TInt nCount = arrIndices.Count();
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    98
		
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
    99
		if(nCount)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   100
		{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   101
			for(TInt i = 0; i < nCount; i++)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   102
			{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   103
				nTableIndex = arrIndices[i];
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   104
				TInt NewTableState = iStateTable[nTableIndex][nTableState];
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   105
				
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   106
				if( NewTableState != KStateNoMatch || 
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   107
					(NewTableState == KStateNoMatch && i == (arrIndices.Count() - 1)) ||
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   108
					NewTableState == KStateMatched)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   109
				{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   110
					nTableState = NewTableState;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   111
					break;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   112
				}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   113
			}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   114
		}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   115
		else
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   116
		{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   117
			nTableState = iStateTable[nTableIndex][nTableState];
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   118
		}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   119
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   120
		if(nTableState == KStateNoMatch)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   121
			break;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   122
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   123
		if(nTableState == KStateMatched)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   124
		{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   125
			bFound = ETrue;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   126
			break;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   127
		}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   128
	}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   129
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   130
	arrIndices.Close();
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   131
	
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   132
	return bFound;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   133
}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   134
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   135
TInt CStateMachine::MapIndex(TChar aChar, RArray<TInt>& aIndices)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   136
{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   137
    // Check the type of aChar and return the relevant index or indicies
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   138
	if(aChar.IsDigit())
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   139
	{
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   140
		TInt nIndex = static_cast<TInt>(aChar.GetNumericValue());
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   141
		
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   142
		TInt ret = KErrNone;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   143
		ret |= aIndices.Append(nIndex);
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   144
		ret |= aIndices.Append(KCharacterDot);
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   145
		__ASSERT_DEBUG(!ret, User::Panic(_L("RArray append failure"), ret));
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   146
		if (KErrNone != ret) return ret;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   147
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   148
		return nIndex;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   149
	}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   150
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   151
	if(aChar == '+')	return KCharacterPlus;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   152
	if(aChar == '.')	return KCharacterDot;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   153
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   154
    return -1;  // TO DO : define 
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   155
}
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   156
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   157
void CStateMachine::GetWildcardVersionOfPattern( 
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   158
    TText aWildcardChar, 
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   159
    TDes& aWildcardedPattern ) const
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   160
    {
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   161
    aWildcardedPattern.SetLength(0);
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   162
    TInt maxLength = aWildcardedPattern.MaxLength();
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   163
    // There is a column in the StateTable for each character in the regular expression. The first character
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   164
    // of the regexp in column [0], last in column [Length()-1]
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   165
    // The non-zero values found within a column of the StateTable represent the characters
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   166
    // that are valid at that position in a candidate match.
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   167
    // An example pattern is calculated by examining the StateTable.
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   168
    // For each column, count the number of matching ( i.e. not KStateNoMatch) states
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   169
    // If only one, then place that character in the example pattern.
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   170
    // If more than one, put the wildcard in.
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   171
    for(TInt stateIndex = 0; stateIndex < iMaxNumberStates && stateIndex < maxLength; stateIndex++)
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   172
        {
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   173
        TInt matches = 0;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   174
        TInt matchedIndex = -1;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   175
        for (TInt charIndex = 0; charIndex < iMaxNumberChars; charIndex++ )
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   176
            {
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   177
            TInt nextState = iStateTable[charIndex][stateIndex];
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   178
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   179
            if ( nextState != KStateNoMatch )
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   180
                {
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   181
                matches++;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   182
                matchedIndex = charIndex;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   183
                if (matches > 1 )
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   184
                    break;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   185
                }
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   186
            }
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   187
        if ( matches == 0 ) // Have found an empty column.  Unused part of state machine. Stop filling
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   188
            {
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   189
            break;
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   190
            }
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   191
        else if ( matches > 1 )
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   192
            aWildcardedPattern.Append(aWildcardChar);
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   193
        else
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   194
            {
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   195
            if ( 0 <= matchedIndex && matchedIndex <= 9 ) // Must be a numeric digit
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   196
                {
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   197
                aWildcardedPattern.Append((TText)(matchedIndex+'0'));
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   198
                }
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   199
            else if ( matchedIndex == KCharacterDot )
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   200
                {
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   201
                aWildcardedPattern.Append(aWildcardChar);
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   202
                }
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   203
            else if ( matchedIndex == KCharacterPlus )
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   204
                {
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   205
                aWildcardedPattern.Append('+');
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   206
                }
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   207
            else
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   208
                {
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   209
                aWildcardedPattern.Append(aWildcardChar);
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   210
                }
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   211
            }
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   212
        }
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   213
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   214
    }
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   215
// End of File
91ef7621b7fc 201019_08
hgs
parents:
diff changeset
   216