charconvfw/numbergrouping/Src/RegularExpression.cpp
changeset 0 1fb32624e06b
child 16 56cd22a7a1cb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/charconvfw/numbergrouping/Src/RegularExpression.cpp	Tue Feb 02 02:02:46 2010 +0200
@@ -0,0 +1,280 @@
+/*
+* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+#include "RegularExpression.h"
+
+#define KNumOfRecognisedChars 13
+
+// Panic is implemented in NumberGrouping.cpp
+GLDEF_C void Panic(TNumberGroupingPanic aPanic);
+
+CRegularExpression::CRegularExpression()
+{
+}
+
+CRegularExpression* CRegularExpression::NewL(RPointerArray<TDesC>* aPatterns)
+{
+	CRegularExpression* s = NewLC(aPatterns);
+	CleanupStack::Pop();
+	return s;
+}
+
+CRegularExpression* CRegularExpression::NewLC(RPointerArray<TDesC>* aPatterns)
+{
+	CRegularExpression* s = new(ELeave)CRegularExpression();
+	CleanupStack::PushL(s);
+	s->ConstructL(aPatterns);
+	return s;
+}
+
+void CRegularExpression::ConstructL(RPointerArray<TDesC>* aPatterns)
+{
+	GenerateStateTablesL(aPatterns);
+}
+
+CRegularExpression::~CRegularExpression()
+{
+	for(TInt i = 0; i < iStateMachines.Count(); i++)
+		delete iStateMachines[i];
+	
+	iStateMachines.Close();
+}
+
+TInt CRegularExpression::Search(const TDesC& aString)
+{
+	return SearchFrom(0, aString);
+}
+
+TInt CRegularExpression::SearchFrom(TInt aIndex, const TDesC& aString)
+{
+	for(TInt i = aIndex; i < iStateMachines.Count(); ++i)
+	{
+		if(iStateMachines[i]->Matches(aString))
+			return i;
+	}
+
+	return KErrNotFound;
+}
+
+// Do the parsing
+void CRegularExpression::GenerateStateTablesL(RPointerArray<TDesC>* aPatterns)
+{	
+	for(TInt nPatternCount = 0; nPatternCount < aPatterns->Count(); ++nPatternCount)
+	{
+		const TDesC& desPattern = *((*aPatterns)[nPatternCount]) ;	// I know it looks horrific, but it makes the
+																	// rest of the method _so_ much easier to read
+		
+		CStateMachine* StateMachine = CStateMachine::NewLC(KNumOfRecognisedChars, desPattern.Length());
+		iStateMachines.Append(StateMachine);
+
+		// parse the desPattern
+
+		enum TParseState
+		{
+			EAny,
+			EOpenBracketFound,
+			EChoiceOrRange,
+			EChoice,
+			ERange,
+			ELookingForCloseBracket
+		};
+
+		TParseState	parseState = EAny;
+
+		TInt		nPatternIndex = 0;
+		TInt		nState = 0;
+
+		TBuf<10>	bufChoice;
+		bufChoice.Zero();
+
+		TBuf<20>	bufParsingError = _L("Parsing syntax error");
+
+		while(nPatternIndex < desPattern.Length() )
+		{
+			TChar cChar = desPattern[nPatternIndex];
+			TBool bEndOfParse = EFalse;
+
+			if(nPatternIndex == desPattern.Length() - 1) // end of the parse
+				bEndOfParse = ETrue;
+		
+			switch(cChar)
+			{
+			case '1':
+			case '2':
+			case '3':
+			case '4':
+			case '5':
+			case '6':
+			case '7':
+			case '8':
+			case '9':
+			case '0':
+				switch(parseState)
+				{
+				case EAny:
+					iStateMachines[nPatternCount]->AddStateTransistionL(cChar, nState, bEndOfParse?
+																					KStateMatched:
+																					(nState + 1)); 
+					++nState;
+					break;
+				case EOpenBracketFound:
+					bufChoice.Append(cChar);
+					parseState = EChoiceOrRange;					
+					break;
+				case EChoiceOrRange:
+				case EChoice:
+					bufChoice.Append(cChar);
+					parseState = EChoice;
+					break;
+				case ERange:
+					bufChoice.Append(cChar);
+					parseState = ELookingForCloseBracket;
+					break;
+				//case ELookingForCloseBracket:						
+				default:
+					User::Panic(bufParsingError, KErrSyntaxError);
+					break;
+				}
+				break;
+			case '[':
+				switch(parseState)
+				{
+				case EAny:						
+					bufChoice.Zero();
+					parseState = EOpenBracketFound;
+					break;
+				//case EOpenBracketFound:			
+				//case EChoiceOrRange:			
+				//case EChoice:					
+				//case ERange:					
+				//case ELookingForCloseBracket:	
+				default:
+					User::Panic(bufParsingError, KErrSyntaxError);
+					break;
+				
+    			}	
+				break;
+			case ']':
+				switch(parseState)
+				{
+				case EChoice:
+					{
+						for(TInt i = 0; i < bufChoice.Length(); ++i)
+						{
+							TChar cChar = bufChoice[i];
+							
+							iStateMachines[nPatternCount]->AddStateTransistionL(cChar.GetNumericValue(), 
+																				nState, 
+																				bEndOfParse?
+																					KStateMatched:
+																					(nState + 1));
+						}
+						
+						++nState;
+						parseState = EAny;
+					}
+					break;
+				case ELookingForCloseBracket:
+					{
+						TChar cTopOfRange = bufChoice[1];
+						TChar cBottomOfRange = bufChoice[0];
+
+						TInt nTopOfRange = cTopOfRange.GetNumericValue();		// if they're not there then something
+						TInt nBottomOfRange = cBottomOfRange.GetNumericValue();	// is seriously amiss...
+						
+						if(nTopOfRange < nBottomOfRange)
+							User::Panic(bufParsingError, KErrSyntaxError);
+					
+						for(TInt i = nBottomOfRange; i <= nTopOfRange; ++i)
+						{
+							iStateMachines[nPatternCount]->AddStateTransistionL(i, nState, bEndOfParse?
+																							KStateMatched:
+																							(nState + 1));
+						}
+						++nState;
+						parseState = EAny;
+					}
+					break;
+				//case EAny:						
+				//case EOpenBracketFound:			
+				//case EChoiceOrRange:			
+				//case ERange:		
+				default:
+					User::Panic(bufParsingError, KErrSyntaxError);
+					break;
+				}	
+				break;
+			case '-':
+				switch(parseState)
+				{
+				case EChoiceOrRange:			
+					parseState = ERange;
+					break;	
+				//case EAny:						
+				//case EOpenBracketFound:			
+				//case ELookingForCloseBracket:	
+				//case ERange:					
+				//case EChoice:
+				default:
+					User::Panic(bufParsingError, KErrSyntaxError);
+					break;
+				}
+				break;
+			case '.':
+			case '+':
+				switch(parseState)
+				{
+				case EAny:						
+					iStateMachines[nPatternCount]->AddStateTransistionL(cChar, nState, bEndOfParse?
+																					KStateMatched:
+																					(nState + 1));
+					++nState;
+					break;
+				//case EOpenBracketFound:			
+				//case EChoiceOrRange:			
+				//case ELookingForCloseBracket:	
+				//case ERange:					
+				//case EChoice:
+				default:
+					User::Panic(bufParsingError, KErrSyntaxError);
+					break;					
+				}
+				break;
+			default:
+				User::Panic(bufParsingError, KErrSyntaxError);
+				break;
+			}
+
+			++nPatternIndex;
+		}
+
+		if(parseState != EAny)
+			User::Panic(bufParsingError, KErrSyntaxError);
+					
+		CleanupStack::Pop(); // iStateMachine[nPatternCount]
+	}
+}
+
+void CRegularExpression::GetWildcardVersionOfPattern( 
+    TInt aPatternIndex, TText aWildcard, TDes& aWildcardedPattern) const
+    {
+    __ASSERT_ALWAYS( (0 <= aPatternIndex) && (aPatternIndex < iStateMachines.Count()),
+        Panic(ENumberGroupingNoSuchStateMachine) );
+    iStateMachines[aPatternIndex]->GetWildcardVersionOfPattern( aWildcard, aWildcardedPattern );
+    }
+
+// End of File