--- /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<TSIRuleID>& aMyIds )
+ {
+ RArray<TSIRuleID> 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<TSIRuleID> 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<TSIPronunciationID>& 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<TSIRuleID> 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<TSIGrammarID>& aGrammarIDs )
+ {
+ RArray<TUint32> ix;
+ ix.Reset();
+ GetAllClientIDsL(KGrammarIdTable, KGrammarIdColumn, aClientUid, ix);
+ for(TInt i=0;i<ix.Count();i++) {
+ aGrammarIDs.Append(STATIC_CAST(TSIGrammarID,ix[i]));
+ }
+ ix.Close();
+ }
+
+// -----------------------------------------------------------------------------
+// CSIGrammarDB::GetAllGrammarIDsL
+// This function returns all grammar IDs in the database.
+// -----------------------------------------------------------------------------
+//
+void CSIGrammarDB::GetAllGrammarIDsL( RArray<TSIGrammarID>& 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<TUint32> ix;
+ //! Reset
+ ix.Reset();
+ GetAllIDsL(KGrammarIdTable, KGrammarIdColumn, ix);
+ for(TInt i=0;i<ix.Count();i++)
+ {
+ *id = STATIC_CAST( TSIGrammarID, ix[i] );
+ aGrammarIDs.Append( *id );
+ }
+ ix.Close();
+ CleanupStack::PopAndDestroy( id );
+ }
+
+// -----------------------------------------------------------------------------
+// CSIGrammarDB::GetAllRuleIDsL
+// This function returns all rule IDs within the specified grammar.
+// grammar have to be loaded
+// -----------------------------------------------------------------------------
+//
+void CSIGrammarDB::GetAllRuleIDsL( TSIGrammarID aGrammarID,
+ RArray<TSIRuleID>& 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;i<newgrammar->Count();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