diff -r 000000000000 -r eb1f2e154e89 textinput/peninputvkbcn/ctrlsrc/AknFepVkbPinyinAnalyser.cpp --- /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 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 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