--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/textinput/peninputvkbcn/ctrlsrc/AknFepVkbPinyinAnalyser.cpp Tue Feb 02 01:02:04 2010 +0200
@@ -0,0 +1,451 @@
+/*
+* Copyright (c) 2002-2005 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: Implementation of the vkb data manager
+*
+*/
+
+
+// system includes
+
+
+// user includes
+#include "AknFepVkbPinyinAnalyser.h"
+#include "AknFepVkbPinyinAnalyserDb.h"
+
+class TSpellBand
+{
+public:
+ int iStart;
+ int iCount;
+};
+
+
+class TSpellAnalysis : public TPriQueLink
+{
+public:
+ RArray<TInt> iSeparators;
+ TSpellAnalysis()
+ {
+ iPriority = -0x10000;
+ }
+ ~TSpellAnalysis()
+ {
+ iSeparators.Close();
+ }
+
+ TSpellAnalysis(const TSpellAnalysis& aSource)
+ {
+ iPriority = aSource.iPriority;
+ for( TInt i = 0; i < aSource.iSeparators.Count(); ++i )
+ {
+ iSeparators.Append(aSource.iSeparators[i]);
+ }
+ }
+ void Calculate()
+ {
+ iPriority = (iSeparators.Count() + 1) << 16;
+ TInt multi = 12;
+ for( TInt i = 0; i < iSeparators.Count(); ++i )
+ {
+ iPriority += ( 6 - iSeparators[i]) << multi;
+ if( multi >= 3 )
+ {
+ multi -= 3;
+ }
+ }
+ iPriority = -iPriority;
+ }
+ TInt GetStartPos()
+ {
+ if( iSeparators.Count() == 0)
+ {
+ return 0;
+ }
+ else
+ {
+ return iSeparators[ iSeparators.Count() - 1 ];
+ }
+ }
+ void AddSeparator(TInt aPos)
+ {
+ iSeparators.Append(aPos);
+ Calculate();
+ }
+};
+
+// -----------------------------------------------------------------------------
+// CAknFepVkbPinyinAnalyser::CAknFepVkbPinyinAnalyser
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CAknFepVkbPinyinAnalyser::CAknFepVkbPinyinAnalyser()
+ {
+ iAnalysisFlag = EFalse;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknFepVkbPinyinAnalyser::NewL
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CAknFepVkbPinyinAnalyser* CAknFepVkbPinyinAnalyser::NewL( CPinyinAnalyserDbFeed* aDb )
+ {
+ CAknFepVkbPinyinAnalyser* self = new ( ELeave ) CAknFepVkbPinyinAnalyser();
+ CleanupStack::PushL(self);
+ self->ConstructL( aDb );
+ CleanupStack::Pop();
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CAknFepVkbPinyinAnalyser::~CAknFepVkbPinyinAnalyser
+// (other items were commented in a header).
+// -----------------------------------------------------------------------------
+//
+CAknFepVkbPinyinAnalyser::~CAknFepVkbPinyinAnalyser()
+ {
+ delete []iParagraph;
+ delete []iSpellLibrary;
+ delete iLastResult;
+ delete iDb;
+ }
+
+
+void CAknFepVkbPinyinAnalyser::ConstructL( CPinyinAnalyserDbFeed* aDb )
+ {
+ ASSERT( aDb != NULL );
+ iDb = aDb;
+
+ TInt length = iDb->GetSpellCount();
+
+ iSpellLibrary = new(ELeave) TPtrC[length];
+ for(TInt i = 0; i < length; ++i )
+ {
+ iSpellLibrary[i].Set( aDb->GetSpellByIndex( i ) );
+ }
+
+ TInt current = 0;
+ TInt pinyinElementCount = iDb->GetSpellElementCount();
+ iParagraph = new(ELeave) TSpellBand[pinyinElementCount];
+ iParagraph[current].iStart = 0;
+ for(TInt i = 0; i < length; ++i )
+ {
+ if( iSpellLibrary[i][0] != iDb->GetSpellElementByIndex( current ) )
+ {
+ iParagraph[current].iCount = i - iParagraph[current].iStart;
+ current++;
+ iParagraph[current].iStart = i;
+ while( iSpellLibrary[i][0] != iDb->GetSpellElementByIndex( current ) )
+ {
+ iParagraph[current].iCount = 0;
+ current ++;
+ iParagraph[current].iStart = i;
+ }
+ }
+ }
+
+ iParagraph[current].iCount = length - iParagraph[current].iStart;
+
+ }
+
+
+HBufC* CAknFepVkbPinyinAnalyser::LastAnalysisResult()
+ {
+ return iLastResult;
+ }
+
+TBool CAknFepVkbPinyinAnalyser::AnalyzeL(const TDesC& aInputString)
+ {
+ delete iLastResult;
+ iLastResult = NULL;
+
+ iLastResult = HBufC::NewL(aInputString.Length() * 2);
+
+ if( aInputString.Length() < 1 )
+ {
+ return ETrue;
+ }
+
+ if( aInputString.Length() == 1 )
+ {
+ iLastResult->Des().Append( aInputString[0] );
+ if ( iDb->IsFirstElement( aInputString[0] ) )
+ {
+ return ETrue;
+ }
+ else
+ {
+ return EFalse;
+ }
+ }
+
+ int first = 0;
+ int second = 1;
+ int previous = 0;
+ iAnalysisFlag = ETrue;
+ //rough spilit
+ for(; second < aInputString.Length(); first++, second++ )
+ {
+ if( !iDb->IsNormalElement(aInputString[first]) )
+ {
+ //go to detail analysis
+ if( first > previous)
+ {
+ TPtrC toanalysis = aInputString.Mid(previous, first - previous);
+ DetailAnalyse(toanalysis);
+ }
+
+ iLastResult->Des().Append(aInputString[first]);
+ previous = first + 1;
+ }
+ else if(!iDb->IsNormalElement(aInputString[second]) )
+ {
+ //go to detail analysis
+ if( second > previous)
+ {
+ TPtrC toanalysis = aInputString.Mid(previous, second - previous);
+ DetailAnalyse(toanalysis);
+ }
+
+ iLastResult->Des().Append(aInputString[second]);
+ previous = second + 1;
+ first ++;
+ second ++;
+ }
+ else if( iDb->GetSpellElementType( aInputString[first]) == ESpellVowel ||
+ iDb->GetSpellElementType( aInputString[second]) == ESpellVowel)
+ {
+ continue;
+ }
+ else if( iDb->GetSpellElementType( aInputString[first]) == ESpellConsonant ||
+ iDb->GetSpellElementType( aInputString[second]) == ESpellConsonant )
+ {
+ //go to detail analysis
+ TPtrC toanalysis = aInputString.Mid(previous, second - previous);
+ DetailAnalyse(toanalysis);
+ iLastResult->Des().Append(KProgramSeparator);
+ previous = second;
+ }
+ else
+ {
+ if( (aInputString[second] == L'h' && ( aInputString[first] == L'z' ||
+ aInputString[first] == L'c' || aInputString[first] == L's')) || //ch, sh, zh
+ (aInputString[second] == L'g' && aInputString[first] == L'n') || //ng
+ (aInputString[second] == L'n' && aInputString[first] == L'h') //hn
+ )
+ {
+ }
+ else
+ {
+ //go to detail analysis
+ TPtrC toanalysis = aInputString.Mid(previous, second - previous);
+ DetailAnalyse(toanalysis);
+ iLastResult->Des().Append(KProgramSeparator);
+ previous = second;
+ }
+ }
+ }
+
+ if( aInputString.Length() <= previous || second > aInputString.Length() )
+ {
+ return iAnalysisFlag;
+ }
+
+ TPtrC toanalysis = aInputString.Mid(previous, second - previous);
+ DetailAnalyse(toanalysis);
+ return iAnalysisFlag;
+ }
+
+TSpellAnalysis* CreateTSpellAnalysisL()
+ {
+ return new(ELeave) TSpellAnalysis();
+ }
+TBool CAknFepVkbPinyinAnalyser::DetailAnalyse(const TDesC& aInputString)
+{
+ TPriQue<TSpellAnalysis> open;
+ TSpellAnalysis* p = NULL;
+ TRAP_IGNORE( p = CreateTSpellAnalysisL());
+
+ open.Add(*p);
+
+ int sameLength;
+ int startPos;
+ TBool findRes;
+ TSpellAnalysis* pNext = NULL;
+
+ while( !open.IsEmpty() )
+ {
+ pNext = open.First();
+ pNext->Deque();
+
+ startPos = pNext->GetStartPos();
+ findRes = FindSpell(aInputString.Mid(startPos), sameLength);
+
+ if( findRes || sameLength + startPos == aInputString.Length())
+ {
+ //got it!
+ int start = 0;
+ for( TInt j = 0; j < pNext->iSeparators.Count(); ++j )
+ {
+ iLastResult->Des().Append(aInputString.Mid(start, pNext->iSeparators[j] - start));
+ start = pNext->iSeparators[j];
+ iLastResult->Des().Append(KProgramSeparator);
+ }
+
+ iLastResult->Des().Append(aInputString.Mid(start, aInputString.Length() - start));
+ break;
+ }
+ else if( sameLength == 0 )
+ {
+ delete pNext;
+ pNext = NULL;
+ }
+ else
+ {
+ int partLength = sameLength - 1;
+ while( partLength > 0 )
+ {
+ int templen;
+ if( FindSpell(aInputString.Mid(startPos, partLength), templen) )
+ {
+ TSpellAnalysis* q = new TSpellAnalysis(*pNext);
+ q->AddSeparator(startPos + partLength);
+ open.Add(*q);
+ }
+ partLength --;
+ }
+ pNext->AddSeparator(startPos + sameLength);
+ open.Add(*pNext);
+ }
+ }
+ if( pNext )
+ {
+ delete pNext;
+ pNext = NULL;
+ while( !open.IsEmpty() )
+ {
+ TSpellAnalysis* p = open.First();
+ p->Deque();
+ delete p;
+ }
+ return true;
+ }
+ else
+ {
+ //not found
+ /*
+ FindSpell(aInputString, sameLength);
+ int offset = 0;
+ TBool rtn = sameLength > 0;
+ while( sameLength > 0 )
+ {
+ iLastResult->Des().Append(aInputString.Mid(offset, sameLength));
+ iLastResult->Des().Append(KProgramSeparator);
+ offset += sameLength;
+ FindSpell(aInputString.Mid(offset), sameLength);
+ }
+ */
+ //FindSpell(aInputString, sameLength);
+ int offset = 0;
+
+ while( offset < aInputString.Length() )
+ {
+ FindSpell(aInputString.Mid(offset), sameLength);
+
+ if( sameLength )
+ {
+ iLastResult->Des().Append(aInputString.Mid(offset, sameLength));
+ iLastResult->Des().Append(KProgramSeparator);
+ offset += sameLength;
+ }
+ else
+ {
+ iLastResult->Des().Append(aInputString.Mid(offset, 1));
+
+ iLastResult->Des().Append(KProgramSeparator);
+
+ offset += 1;
+ }
+ }
+ if( iLastResult->Des()[ iLastResult->Length() - 1 ] == KProgramSeparator )
+ {
+ iLastResult->Des().SetLength( iLastResult->Length() - 1 );
+ }
+ iAnalysisFlag = EFalse;
+ return EFalse;
+ }
+}
+
+TBool CAknFepVkbPinyinAnalyser::FindSpell(const TDesC& aSpell, TInt& aSameLength)
+{
+ int index = aSpell[0] - iDb->GetSpellElementByIndex( 0 );
+
+ int start = iParagraph[index].iStart;
+ int end = iParagraph[index].iCount + iParagraph[index].iStart - 1;
+ int mid = ( start + end ) >> 1;
+ int result = 0;
+ aSameLength = 0;
+ while( mid > start && mid < end )
+ {
+ result = Compare(iSpellLibrary[mid], aSpell, aSameLength);
+ if( result == 0 )
+ {
+ return true;
+ }
+ else if( result < 0 )
+ {
+ start = mid;
+ mid = (start + end ) >> 1;
+ }
+ else
+ {
+ end = mid;
+ mid = (start + end) >> 1;
+ }
+ }
+ int newLength;
+ if( result > 0 )
+ {
+ result = Compare(iSpellLibrary[start], aSpell, newLength);
+ }
+ else
+ {
+ result = Compare(iSpellLibrary[end], aSpell, newLength);
+ }
+ newLength > aSameLength ? aSameLength = newLength : aSameLength;
+
+ return result == 0;
+}
+
+TInt CAknFepVkbPinyinAnalyser::Compare(const TDesC& aFirst, const TDesC& aSecond,
+ TInt& aSameLength)
+ {
+ aSameLength = 0;
+
+ TInt length = aFirst.Length() > aSecond.Length() ? aSecond.Length() : aFirst.Length();
+
+ for( TInt i = 0; i < length; ++i )
+ {
+ if( aFirst[i] != aSecond[i] )
+ {
+ return aFirst[i] - aSecond[i];
+ }
+
+ aSameLength ++;
+ }
+
+ return aFirst.Length() - aSecond.Length();
+ }
+
+// End of File