diff -r cad71a31b7fc -r e36f3802f733 srsf/sisrscontrollerplugin/src/sigrammardb.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/srsf/sisrscontrollerplugin/src/sigrammardb.cpp Wed Sep 01 12:29:17 2010 +0100 @@ -0,0 +1,806 @@ +/* +* Copyright (c) 2004-2007 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: This class handles the storage and access of speaker independent +* grammars. It is also responsible for allocating memory when +* loading grammars into the recognizer. +* +*/ + + +// INCLUDE FILES +#include "sigrammardb.h" +#include "rubydebug.h" + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::CSIGrammarDB +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CSIGrammarDB::CSIGrammarDB( RDbNamedDatabase& aDatabase, + RDbs& aDbSession, + TInt aDrive ) +: CSICommonDB(aDatabase, aDbSession, aDrive ) + { + // Nothing + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::ConstructL +// Symbian 2nd phase constructor can leave. +// ----------------------------------------------------------------------------- +// +void CSIGrammarDB::ConstructL() + { + // Nothing + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CSIGrammarDB* CSIGrammarDB::NewL( RDbNamedDatabase& aDatabase, + RDbs& aDbSession, + TInt aDrive ) + { + RUBY_DEBUG_BLOCK( "CSIGrammarDB::NewL" ); + + CSIGrammarDB* self + = new( ELeave ) CSIGrammarDB( aDatabase, aDbSession, aDrive ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::~CSIGrammarDB +// Destructor +// ----------------------------------------------------------------------------- +// +CSIGrammarDB::~CSIGrammarDB() + { + RUBY_DEBUG0( "CSIGrammarDB::~CSIGrammarDB" ); + // Delete all elements of the array before deleting the array + iGrammarArray.ResetAndDestroy(); + iGrammarArray.Close(); + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::CreateGrammarL +// Creates a new grammar in the database. +// ----------------------------------------------------------------------------- +// +TSIGrammarID CSIGrammarDB::CreateGrammarL( TUid aClientUid ) + { + RUBY_DEBUG_BLOCK( "CSIGrammarDB::CreateGrammarL" ); + + User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, sizeof( CSIGrammar ) ) ); + + TSIGrammarID grammarID = STATIC_CAST(TSIGrammarID,CreateNewIDL(KGrammarIdTable, KGrammarIdColumn, aClientUid)); + // Construct the table name using the new grammar ID + TBuf<40> KGrammarName( KSIGrammarTable ); + KGrammarName.AppendNumUC( grammarID ); + RUBY_DEBUG1( "CSIGrammarDB::CreateGrammarL grammar ID: %i", grammarID ); + + // Create a table definition + CDbColSet* columns = CDbColSet::NewLC(); + + // add the columns + // 1) Binary data, 2) binary data size + columns->AddL( TDbCol( KBinaryGrammarColumn, EDbColLongBinary ) ); + columns->AddL( TDbCol( KBinaryGrammarColumnSize, EDbColUint32 ) ); + + // Create a table + TInt err =iDb.CreateTable( KGrammarName, *columns ); + + if ( err != KErrNone ) + { + // Failed to create the table. + // Need to release the new grammar ID and leave. + ReleaseIdL( KGrammarIdTable, KGrammarIdColumn, grammarID ); + User::Leave( err ); + } + + // Cleanup the column set + CleanupStack::PopAndDestroy( columns ); + + // Construct the table name using the provided grammar ID + // Declare a literal string to hold the SQL statement + // SELECT KBinaryGrammarColumn , KBinaryGrammarColumn FROM KGrammarName + _LIT(KSQLSelect1,"select "); + _LIT(KSQLSelect2," from "); + TBuf<120> KSQLStatement; + KSQLStatement.Append(KSQLSelect1 ); + KSQLStatement.Append(KBinaryGrammarColumn ); + KSQLStatement.Append(KNext); + KSQLStatement.Append(KBinaryGrammarColumnSize ); + KSQLStatement.Append(KSQLSelect2 ); + KSQLStatement.Append(KGrammarName); + + // Create a view on the database + RDbView view; + User::LeaveIfError(view.Prepare(iDb,TDbQuery(KSQLStatement,EDbCompareNormal))); + User::LeaveIfError(view.EvaluateAll()); + + // Get the structure of rowset + CDbColSet* colSet = view.ColSetL(); + // Insert a row + view.InsertL(); + view.PutL(); + // Close the view + view.Close(); + delete colSet; + + // Put a empty grammar into the database + CSICompiledGrammar *aSICompiledGrammar=CSICompiledGrammar::NewL(grammarID); + CleanupStack::PushL(aSICompiledGrammar); + UpdateGrammarL(aClientUid,aSICompiledGrammar); + CleanupStack::PopAndDestroy(aSICompiledGrammar); + + iDbSession.FreeReservedSpace( iDrive ); + + return grammarID; + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::UpdateGrammarL +// Inserts the externalized SI compiled grammar into the specified grammar table. +// Save the grammar into the database +// ----------------------------------------------------------------------------- +// +void CSIGrammarDB::UpdateGrammarL( TUid aClientUid, + CSICompiledGrammar *aSICompiledGrammar ) + { + RUBY_DEBUG_BLOCK( "CSIGrammarDB::UpdateGrammarL" ); + + // verify ownership + TSIGrammarID aGrammarID=aSICompiledGrammar->GrammarID(); + VerifyOwnershipL(aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID); + + // Construct the table name using the provided grammar ID + // Declare a literal string to hold the SQL statement + // SELECT KBinaryGrammarColumn , KBinaryGrammarColumn FROM KGrammarName + TBuf<40> KGrammarName(KSIGrammarTable); + KGrammarName.AppendNumUC(aGrammarID); + _LIT(KSQLSelect1,"select "); + _LIT(KSQLSelect2," from "); + TBuf<120> KSQLStatement; + KSQLStatement.Append(KSQLSelect1 ); + KSQLStatement.Append(KBinaryGrammarColumn ); + KSQLStatement.Append(KNext); + KSQLStatement.Append(KBinaryGrammarColumnSize ); + KSQLStatement.Append(KSQLSelect2 ); + KSQLStatement.Append(KGrammarName); + + // Create a view on the database + RDbView view; + User::LeaveIfError( view.Prepare( iDb, TDbQuery( KSQLStatement,EDbCompareNormal ) ) ); + User::LeaveIfError( view.EvaluateAll() ); + CleanupClosePushL( view ); + + // Get the structure of rowset + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL( colSet ); + view.FirstL(); + view.UpdateL(); + + // Externalize a compiled grammar + CBufFlat* dataCopyBuffer = CBufFlat::NewL( 100 ); // 100 = expand 100 bytes + CleanupStack::PushL( dataCopyBuffer ); // when the buffer is full + RBufWriteStream stream; + stream.Open( *dataCopyBuffer ); + CleanupClosePushL( stream ); + aSICompiledGrammar->ExternalizeL( stream ); + CleanupStack::PopAndDestroy( &stream ); + + TPtr8 aWriteBuf( dataCopyBuffer->Ptr( 0 ) ); + TInt BufSize = aWriteBuf.Size(); + + // add binary buffer by Using the stream + RDbColWriteStream out; + TDbColNo col = colSet->ColNo( KBinaryGrammarColumn ); // Ordinal position of long column + out.OpenLC( view, col ); + out.WriteL( aWriteBuf ); + out.Close(); + CleanupStack::PopAndDestroy(); // out + + // add size of the buffer + col = colSet->ColNo( KBinaryGrammarColumnSize ); // Ordinal position of size + view.SetColL( col, BufSize ); + view.PutL(); + + CleanupStack::PopAndDestroy( dataCopyBuffer ); + CleanupStack::PopAndDestroy( colSet ); + + // close the view + CleanupStack::PopAndDestroy( &view ); // Close view + } + + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::FindGrammarL +// Find a grammar from loaded grammar array +// ----------------------------------------------------------------------------- +CSICompiledGrammar* CSIGrammarDB::FindGrammarL(TSIGrammarID aGrammarID) + { + RUBY_DEBUG_BLOCK( "CSIGrammarDB::FindGrammarL" ); + + TInt i(0); + CSICompiledGrammar* aGrammar=NULL; + + // Check if grammar already loaded + for ( i = 0; i < iGrammarArray.Count(); i++ ) + { + if ( iGrammarArray[i]->GrammarID()==aGrammarID ) + { + aGrammar=iGrammarArray[i]; + break; + } + } + // Can not found in the loaded grammar array + if(i==iGrammarArray.Count()) + User::Leave(KErrNotFound); + + return aGrammar; + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::GetNewID +// Get a new uniq ID +// ----------------------------------------------------------------------------- +TInt CSIGrammarDB::GetNewID( RArray& aMyIds ) + { + RArray myIDs = aMyIds; + TInt Count = myIDs.Count(); + TInt id = 0; + if ( Count == 0 ) + { + id = 1; // empty ,first id will be 1 + } + else + { + // Find a unique ID + myIDs.SortUnsigned(); + id = myIDs[myIDs.Count() - 1] + 1; //by default , the last one + for ( TInt i = 0; i < myIDs.Count(); i++ ) + { + TInt index = i + 1; + TInt s = myIDs[i]; + if ( s > index ) + { + id = index; + break; + } + } + } + return id; + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::CreateRuleL +// Creates a new empty rule. +// ----------------------------------------------------------------------------- +void CSIGrammarDB::CreateRuleL( TUid aClientUid, TSIGrammarID aGrammarID, + TSIRuleID& aRuleID ) + { + RUBY_DEBUG_BLOCK( "CSIGrammarDB::CreateRuleL" ); + + //__UHEAP_MARK; + VerifyOwnershipL( aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID ); + // find the grammar from the database + CSICompiledGrammar* aGrammar = (CSICompiledGrammar*) GrammarL( aGrammarID ); + CleanupStack::PushL( aGrammar ); + + TInt aID = 0; + TInt Count=aGrammar->Count(); + + // existing myRuleVariantID + RArray myIDs; + myIDs.Reset(); + for(TInt i = 0; i < Count; i++ ) + { + CSIRule* aRule = &( aGrammar->AtL( i ) ); + myIDs.Append( aRule->RuleID() ); + } + + // Find a uniq new id + aID=GetNewID( myIDs ); + myIDs.Close(); + aRuleID=aID; + + // add the rule to the grammar + CSIRule* rule = CSIRule::NewL( aRuleID ); + CleanupStack::PushL( rule ); + aGrammar->AddL( rule ); + CleanupStack::Pop( rule ); + + UpdateGrammarL( aClientUid, aGrammar ); + CleanupStack::PopAndDestroy( aGrammar ); + //__UHEAP_MARKEND; + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::AddRuleVariantL +// Add Rule Variant to the array that hold the grammar array +// ----------------------------------------------------------------------------- +void CSIGrammarDB::AddRuleVariantL(TUid aClientUid, + TSIGrammarID aGrammarID, + TSILexiconID aLexiconID, + const RArray& aPronunciationIDs, + TSIRuleID aRuleID, + TSIRuleVariantID& aRuleVariantID) + { + VerifyOwnershipL(aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID); + + CSICompiledGrammar* aGrammar=(CSICompiledGrammar*)GrammarL(aGrammarID); + CleanupStack::PushL(aGrammar); + + CSIRule* aRule=&(aGrammar->RuleL(aRuleID)); + // existing myRuleVariantID + RArray myID; + myID.Reset(); + for( TInt i = 0; i < aRule->Count(); i++ ) + { + CSIRuleVariant* aRuleVariant=&(aRule->AtL(i)); + myID.Append(aRuleVariant->RuleVariantID()); + } + + // Find a uniq new id + aRuleVariantID=STATIC_CAST(TSIRuleVariantID,GetNewID(myID)); + myID.Close(); + + // add the rule variant to the rule + CSIRuleVariant* ruleVariant = CSIRuleVariant::NewL( aRuleVariantID, aLexiconID ); + CleanupStack::PushL( ruleVariant ); + ruleVariant->SetPronunciationIDsL(aPronunciationIDs); + aRule->AddL( ruleVariant ); + CleanupStack::Pop( ruleVariant ); + UpdateGrammarL( aClientUid, aGrammar ); + CleanupStack::PopAndDestroy( aGrammar ); + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::LoadGrammarL +// Loads all rules within the specified grammar into a grammar object, which +// is loaded into recognizer during recognition session. +// Note : Will leave if already loaded +// ----------------------------------------------------------------------------- +// +const CSICompiledGrammar* CSIGrammarDB::LoadGrammarL( TSIGrammarID aGrammarID ) + { + // Construct the table name using the provided grammar ID + // Construct the table name using the provided grammar ID + // Declare a literal string to hold the SQL statement + // SELECT KBinaryGrammarColumn , KBinaryGrammarColumn FROM KGrammarName + TBuf<40> KGrammarName(KSIGrammarTable); + KGrammarName.AppendNumUC(aGrammarID); + + // Create newGrammar object + CSICompiledGrammar* grammar = CSICompiledGrammar::NewLC( aGrammarID ); + _LIT(KSQLSelect1,"select "); + _LIT(KSQLSelect2," from "); + TBuf<120> KSQLStatement; + KSQLStatement.Append(KSQLSelect1 ); + KSQLStatement.Append(KBinaryGrammarColumn ); + KSQLStatement.Append(KNext); + KSQLStatement.Append(KBinaryGrammarColumnSize ); + KSQLStatement.Append(KSQLSelect2 ); + KSQLStatement.Append(KGrammarName); + + // create a view on the database + RDbView view; + CleanupClosePushL( view ); + + User::LeaveIfError(view.Prepare(iDb,TDbQuery(KSQLStatement,EDbCompareNormal))); + User::LeaveIfError(view.EvaluateAll()); + + // Get the structure of the rowset + CDbColSet* colSet = view.ColSetL(); + CleanupStack::PushL( colSet ); + + // iterate across the row set, one row only + for (view.FirstL();view.AtRow();view.NextL()) + { + + // retrieve the row + view.GetL(); + + // first retrieve the size of binary package + TDbColNo col = colSet->ColNo(KBinaryGrammarColumnSize); // Ordinal position of long column + TInt32 size = view.ColUint32( col); + + TUint8* buf = new (ELeave) TUint8[size]; + CleanupStack::PushL( buf); + TPtr8 readBuf( buf, size, size); + CBufFlat* dataCopyBuffer = CBufFlat::NewL( 100 ); // 100 = expand 100 bytes + CleanupStack::PushL(dataCopyBuffer); // when the buffer is full + + RBufReadStream stream; + CleanupClosePushL( stream ); + stream.Open(*dataCopyBuffer); + + // and a stream for long columns + RDbColReadStream in; + CleanupClosePushL( in ); + col = colSet->ColNo(KBinaryGrammarColumn); // Ordinal position of long column + + + in.OpenLC(view, col); + in.ReadL( readBuf, view.ColLength(col)); + dataCopyBuffer->InsertL(0,readBuf); + grammar->InternalizeL( stream ); + + CleanupStack::PopAndDestroy( col ); + CleanupStack::PopAndDestroy( &in ); + CleanupStack::PopAndDestroy( &stream ); + CleanupStack::PopAndDestroy( dataCopyBuffer ); + CleanupStack::PopAndDestroy( buf ); + } + + CleanupStack::PopAndDestroy( colSet ); + CleanupStack::PopAndDestroy( &view ); + + // Keep the reference of the grammar object + User::LeaveIfError(iGrammarArray.Append(grammar)); + // Cleanup grammar + CleanupStack::Pop(grammar ); + return grammar; + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::GrammarL +// Loads all rules within the specified grammar into a grammar object, which +// is loaded into recognizer during recognition session. +// Note : Will leave if already loaded +// ----------------------------------------------------------------------------- +// +const CSICompiledGrammar* CSIGrammarDB::GrammarL( TSIGrammarID aGrammarID ) + { + + // Construct the table name using the provided grammar ID + // Construct the table name using the provided grammar ID + // Declare a literal string to hold the SQL statement + // SELECT KBinaryGrammarColumn , KBinaryGrammarColumn FROM KGrammarName + TBuf<40> KGrammarName(KSIGrammarTable); + KGrammarName.AppendNumUC(aGrammarID); + // Create newGrammar object + CSICompiledGrammar* aGrammar = CSICompiledGrammar::NewLC( aGrammarID ); + _LIT(KSQLSelect1,"select "); + _LIT(KSQLSelect2," from "); + + TBuf<120> KSQLStatement; + KSQLStatement.Append(KSQLSelect1 ); + KSQLStatement.Append(KBinaryGrammarColumn ); + KSQLStatement.Append(KNext); + KSQLStatement.Append(KBinaryGrammarColumnSize ); + KSQLStatement.Append(KSQLSelect2 ); + KSQLStatement.Append(KGrammarName); + + // create a view on the database + RDbView view; + User::LeaveIfError(view.Prepare(iDb,TDbQuery(KSQLStatement,EDbCompareNormal))); + + User::LeaveIfError(view.EvaluateAll()); + + // Get the structure of the rowset + CDbColSet* colSet = view.ColSetL(); + + // iterate across the row set, one row only + for (view.FirstL();view.AtRow();view.NextL()) + { + + // retrieve the row + view.GetL(); + + // first retrieve the size of binary package + TDbColNo col = colSet->ColNo(KBinaryGrammarColumnSize); // Ordinal position of long column + TInt32 Size = view.ColUint32( col); + + TUint8* aBuf = new (ELeave) TUint8[Size]; + CleanupStack::PushL(aBuf); + TPtr8 aReadBuf(aBuf, Size, Size); + CBufFlat* dataCopyBuffer = CBufFlat::NewL( 100 ); // 100 = expand 100 bytes + CleanupStack::PushL(dataCopyBuffer); // when the buffer is full + + RBufReadStream stream; + stream.Open(*dataCopyBuffer); + + // and a stream for long columns + RDbColReadStream in; + col = colSet->ColNo(KBinaryGrammarColumn); // Ordinal position of long column + + + in.OpenLC(view, col); + in.ReadL(aReadBuf, view.ColLength(col)); + dataCopyBuffer->InsertL(0,aReadBuf); + aGrammar->InternalizeL( stream ); + + in.Close(); + CleanupStack::PopAndDestroy(3); // in dataCopyBuffer aBuf + } + //! clean the memory + delete colSet; + view.Close(); + + // Keep the reference of the grammar object + // Cleanup grammar + CleanupStack::Pop( aGrammar ); + + return aGrammar; + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::CreateIDTableL +// Creates a new grammar ID table in the database. +// ----------------------------------------------------------------------------- +// +void CSIGrammarDB::CreateIDTableL() + { + // Invoke function in the base class CSICommonDB. + CSICommonDB::CreateIDTableL(KGrammarIdTable, KGrammarIdColumn, KGrammarIndex); + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::GetAllClientGrammarIDsL +// This function returns all grammar IDs owned by the specified client. +// ----------------------------------------------------------------------------- +// +void CSIGrammarDB::GetAllClientGrammarIDsL( TUid aClientUid, + RArray& aGrammarIDs ) + { + RArray ix; + ix.Reset(); + GetAllClientIDsL(KGrammarIdTable, KGrammarIdColumn, aClientUid, ix); + for(TInt i=0;i& aGrammarIDs ) + { + // This is a hack to get the id aligned to 4-byte boundary, + // for some reason this does not happen in winscw build if + // TSIGrammarID is taken from stack. + TSIGrammarID* id = new (ELeave) TSIGrammarID; + + CleanupStack::PushL( id ); + + RArray ix; + //! Reset + ix.Reset(); + GetAllIDsL(KGrammarIdTable, KGrammarIdColumn, ix); + for(TInt i=0;i& aRuleIDs ) + { + CleanupClosePushL( aRuleIDs ); + + // Construct the table name using the provided grammar ID + TBuf<40> KGrammarName(KSIGrammarTable); + KGrammarName.AppendNumUC(aGrammarID); + + CSICompiledGrammar* newgrammar =( CSICompiledGrammar* )GrammarL( aGrammarID) ;// Load the grammar from database + CleanupStack::PushL(newgrammar); + TSIRuleID RuleId; + + for (TInt i=0;iCount();i++) { + CSIRule* aRule=&(newgrammar->AtL(i)); + RuleId=aRule->RuleID(); + User::LeaveIfError(aRuleIDs.Append(RuleId)); + } + CleanupStack::PopAndDestroy(newgrammar); + CleanupStack::Pop(); + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::RemoveGrammarL +// Deletes a grammar table from the database. +// ----------------------------------------------------------------------------- +// +void CSIGrammarDB::RemoveGrammarL( TUid aClientUid, + TSIGrammarID aGrammarID ) + { + VerifyOwnershipL(aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID); + + TInt diskSpace = ( RuleCountL(aGrammarID) * sizeof( CSIRule) ) + + sizeof( CSIGrammar ); + User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, diskSpace ) ); + + // Construct the table name using the provided grammar ID + TBuf<40> KGrammarName(KSIGrammarTable); + KGrammarName.AppendNumUC(aGrammarID); + + TBuf<50> KSQLStatement; + // Declare a literal string to hold the SQL statement + // DROP TABLE KGrammarName + _LIT(KSQLDelete1, "DROP TABLE "); + + KSQLStatement = KSQLDelete1; + KSQLStatement.Append(KGrammarName); + + User::LeaveIfError(iDb.Execute(KSQLStatement)); + + // Release the grammar ID + ReleaseIdL(KGrammarIdTable, KGrammarIdColumn, aGrammarID); + + // Cancel free disk space request + iDbSession.FreeReservedSpace( iDrive ); + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::RuleCountL +// Returns the number of rules in the specified grammar. +// Grammar have to be loaded +// ----------------------------------------------------------------------------- +// +TInt CSIGrammarDB::RuleCountL( TSIGrammarID aGrammarID ) + { + // Load a grammar + CSICompiledGrammar* aGrammar=(CSICompiledGrammar*)GrammarL(aGrammarID); + CleanupStack::PushL(aGrammar); + // Count the number of the rules inside the grammar + TInt RuleCount=aGrammar->Count(); + CleanupStack::PopAndDestroy(aGrammar); + return RuleCount; + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::RemoveRuleL +// Deletes Rule from the database. +// Grammar have to be loaded +// ----------------------------------------------------------------------------- +// +void CSIGrammarDB::RemoveRuleL( TUid aClientUid, + TSIGrammarID aGrammarID, + TSIRuleID aRuleID ) + { + VerifyOwnershipL(aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID); + CSICompiledGrammar* aGrammar=(CSICompiledGrammar*)GrammarL(aGrammarID); + + CleanupStack::PushL(aGrammar); + if (aGrammar->Find(aRuleID)==KErrNotFound) + { + User::Leave(KErrNotFound); + } + else + { + aGrammar->DeleteL(aRuleID); + } + UpdateGrammarL(aClientUid,aGrammar); + CleanupStack::PopAndDestroy(aGrammar); + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::IsGrammarLoaded +// Checks to see if a valid grammar is loaded into the recognizer. This is +// useful to check if any rules are still loaded after performing UnloadRule(). +// ----------------------------------------------------------------------------- +// +TBool CSIGrammarDB::IsGrammarLoaded() + { + for ( TInt i = 0; i < iGrammarArray.Count(); i++ ) + { + if ( iGrammarArray[i]->Count() > 0 ) + { + // As long as there is still a rule. + return ETrue; + } + } + return EFalse; + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::IsRuleValidL +// Checks if the rule is valid or not. +// ----------------------------------------------------------------------------- +// +TBool CSIGrammarDB::IsRuleValidL( TSIGrammarID aGrammarID, TSIRuleID aRuleID ) + { + CSICompiledGrammar* aGrammar=(CSICompiledGrammar*)GrammarL(aGrammarID); + CleanupStack::PushL(aGrammar); + if (aGrammar->Find(aRuleID)==KErrNotFound) + { + CleanupStack::PopAndDestroy(aGrammar); + return EFalse; + } + else { + CleanupStack::PopAndDestroy(aGrammar); + return ETrue; + } + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::ResetAndDestroy +// Deallocates the temporary memory containing the grammar object created with +// AllRulesL. +// ----------------------------------------------------------------------------- +// +void CSIGrammarDB::ResetAndDestroy() + { + iGrammarArray.ResetAndDestroy(); + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::UnloadRule +// Unloads the specified rule from the specified grammar in temporary memory, +// previously loaded with AllRulesL. The rule in the database remains intact. +// ----------------------------------------------------------------------------- +// +void CSIGrammarDB::UnloadRuleL( TSIGrammarID aGrammarID, + TSIRuleID aRuleID ) + { + CSIGrammar* grammar; + + for( TInt i = 0; i < iGrammarArray.Count(); i++ ) + { + grammar = iGrammarArray[i]; + if ( grammar->GrammarID() == aGrammarID ) + { + grammar->DeleteL(aRuleID); + return; + } + } + User::Leave(KErrNotFound); + } + +// ----------------------------------------------------------------------------- +// CSIGrammarDB::UnloadGrammar +// Unloads the specified grammar in temporary memory, +// previously loaded with AllRulesL. The grammar in the database remains intact. +// ----------------------------------------------------------------------------- +// +void CSIGrammarDB::UnloadGrammarL( TSIGrammarID aGrammarID) + { + CSIGrammar* grammar; + + for( TInt i = 0; i < iGrammarArray.Count(); i++ ) + { + grammar = iGrammarArray[i]; + if ( grammar->GrammarID() == aGrammarID ) + { + //! delete the object + delete iGrammarArray[i]; + // remove the pointer + iGrammarArray.Remove(i); + return; + } + } + User::Leave(KErrNotFound); + } + +// End of File