diff -r 8ce15fced3a6 -r cad71a31b7fc srsf/sisrscontrollerplugin/src/silexicondb.cpp --- a/srsf/sisrscontrollerplugin/src/silexicondb.cpp Thu Aug 19 09:56:14 2010 +0300 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,598 +0,0 @@ -/* -* 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 -* lexicons. It is also responsible for allocating memory when -* loading lexicons into the recognizer. -* -*/ - - -// INCLUDE FILES -#include "silexicondb.h" -#include "rubydebug.h" - -// CONSTANTS - - -// ============================ MEMBER FUNCTIONS =============================== - -// ----------------------------------------------------------------------------- -// CSILexiconDB::CSILexiconDB -// C++ default constructor can NOT contain any code, that -// might leave. -// ----------------------------------------------------------------------------- -// -CSILexiconDB::CSILexiconDB( RDbNamedDatabase& aDatabase, - RDbs& aDbSession, - TInt aDrive ) -: CSICommonDB(aDatabase, aDbSession, aDrive ) -{ -} - -// ----------------------------------------------------------------------------- -// CSILexiconDB::ConstructL -// Symbian 2nd phase constructor can leave. -// ----------------------------------------------------------------------------- -// -void CSILexiconDB::ConstructL() - { - RUBY_DEBUG_BLOCK( "CSILexiconDB::ConstructL" ); - } - -// ----------------------------------------------------------------------------- -// CSILexiconDB::NewL -// Two-phased constructor. -// ----------------------------------------------------------------------------- -// -CSILexiconDB* CSILexiconDB::NewL( RDbNamedDatabase& aDatabase, - RDbs& aDbSession, - TInt aDrive ) - { - RUBY_DEBUG_BLOCK( "CSILexiconDB::NewL" ); - CSILexiconDB* self - = new( ELeave ) CSILexiconDB( aDatabase, aDbSession, aDrive ); - CleanupStack::PushL( self ); - self->ConstructL(); - CleanupStack::Pop( self ); - return self; - } - -// ----------------------------------------------------------------------------- -// CSILexiconDB::~CSILexiconDB -// Destructor -// ----------------------------------------------------------------------------- -// -CSILexiconDB::~CSILexiconDB() - { - // Delete all elements of the array before deleting the array - // iLexiconArray.ResetAndDestroy(); - // iLexiconArray.Close(); - RUBY_DEBUG0( "CSILexiconDB::~CSILexiconDB" ); - } - -// ----------------------------------------------------------------------------- -// CSILexiconDB::CreateLexiconL -// Creates a new lexicon table in the database. -// ----------------------------------------------------------------------------- -// -TSILexiconID CSILexiconDB::CreateLexiconL( TUid aClientUid ) - { - RUBY_DEBUG_BLOCK( "CSILexiconDB::CreateLexiconL" ); - - User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, sizeof( CSILexicon ) ) ); - - // Generate a new Lexicon ID - TSILexiconID lexiconID = STATIC_CAST(TSILexiconID,CreateNewIDL(KLexiconIdTable, KLexiconIdColumn, aClientUid )); - - // Construct the table name using the new lexicon ID - TBuf<40> KLexiconName( KSILexiconTable ); - KLexiconName.AppendNumUC( lexiconID ); - RUBY_DEBUG1( "CSILexiconDB::CreateLexiconL lexicon ID: %i", lexiconID ); - - - // Create a table definition - CDbColSet* columns = CDbColSet::NewLC(); - - // add the columns - // 1) Binary data, 2) binary data size - columns->AddL( TDbCol( KBinaryLexiconColumn, EDbColLongBinary ) ); - columns->AddL( TDbCol( KBinaryLexiconColumnSize, EDbColUint32 ) ); - - // Create a table - TInt err =iDb.CreateTable( KLexiconName, *columns ); - - if ( err != KErrNone ) - { - // Failed to create the table. - // Need to release the new Lexicon ID and leave. - ReleaseIdL( KLexiconIdTable, KLexiconIdColumn, lexiconID ); - 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 KBinaryLexiconColumn , KBinaryLexiconColumn FROM KLexiconName - _LIT(KSQLSelect1,"select "); - _LIT(KSQLSelect2," from "); - TBuf<120> KSQLStatement; - KSQLStatement.Append(KSQLSelect1 ); - KSQLStatement.Append(KBinaryLexiconColumn ); - KSQLStatement.Append(KNext); - KSQLStatement.Append(KBinaryLexiconColumnSize ); - KSQLStatement.Append(KSQLSelect2 ); - KSQLStatement.Append(KLexiconName); - - // 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(); - view.InsertL(); - view.PutL(); - - - // close the view - view.Close(); - delete colSet; - - // add an empty lexicon - CSILexicon *aLexicon=CSILexicon::NewL(lexiconID); - CleanupStack::PushL(aLexicon); - UpdateLexiconL(aClientUid,aLexicon); - CleanupStack::PopAndDestroy(aLexicon); - - iDbSession.FreeReservedSpace( iDrive ); - - return lexiconID; - } - - -// ----------------------------------------------------------------------------- -// CSILexiconDB::UpdateLexiconL -// Inserts the externalized SI Lexicon into the specified grammar table. -// Save the Lexicon into the database -// ----------------------------------------------------------------------------- -// -void CSILexiconDB::UpdateLexiconL( TUid aClientUid, - CSILexicon *aSILexicon ) - { - - // __UHEAP_MARK; - TSILexiconID aLexiconID=aSILexicon->LexiconID(); - VerifyOwnershipL(aClientUid, KLexiconIdTable, KLexiconIndex, aLexiconID); - - // Construct the table name using the provided grammar ID - // Declare a literal string to hold the SQL statement - // SELECT KBinaryLexiconColumn , KBinaryLexiconColumn FROM KLexiconName - TBuf<40> KLexiconName(KSILexiconTable); - KLexiconName.AppendNumUC(aLexiconID); - _LIT(KSQLSelect1,"select "); - _LIT(KSQLSelect2," from "); - TBuf<120> KSQLStatement; - KSQLStatement.Append(KSQLSelect1 ); - KSQLStatement.Append(KBinaryLexiconColumn ); - KSQLStatement.Append(KNext); - KSQLStatement.Append(KBinaryLexiconColumnSize ); - KSQLStatement.Append(KSQLSelect2 ); - KSQLStatement.Append(KLexiconName); - - // 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(); - - view.FirstL(); - view.UpdateL(); - - - // Externalize grammar - CBufFlat* dataCopyBuffer = CBufFlat::NewL( 100 ); // 100 = expand 100 bytes - CleanupStack::PushL(dataCopyBuffer); // when the buffer is full - //TPtr8 Buft((TUint8*) abuf,3,3); - //dataCopyBuffer->InsertL(0,Buft); - RBufWriteStream stream; - stream.Open(*dataCopyBuffer); - CleanupClosePushL(stream); - aSILexicon->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(KBinaryLexiconColumn); // 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(KBinaryLexiconColumnSize); // Ordinal position of size - view.SetColL( col,BufSize); - - view.PutL(); - - // close the view - view.Close(); - - - delete colSet; - CleanupStack::PopAndDestroy( dataCopyBuffer ); - // __UHEAP_MARKEND; - } - -// ----------------------------------------------------------------------------- -// CSIGrammarDB::GetNewID -// Get a new uniq ID -// ----------------------------------------------------------------------------- -TInt CSILexiconDB::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 Rulevariant 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; - } - - -// ----------------------------------------------------------------------------- -// CSILexiconDB::CreateIDTableL -// Creates a new lexicon ID table in the database. -// ----------------------------------------------------------------------------- -// -void CSILexiconDB::CreateIDTableL() - { - // Invoke function in the base class CSICommonDB. - CSICommonDB::CreateIDTableL(KLexiconIdTable, KLexiconIdColumn, KLexiconIndex); - } - -// ----------------------------------------------------------------------------- -// CSILexiconDB::GetAllClientLexiconIDsL -// This function returns all Lexicon IDs owned by the specified client. -// ----------------------------------------------------------------------------- -// -void CSILexiconDB::GetAllClientLexiconIDsL( TUid aClientUid, - RArray& aLexiconIDs ) - { - // GetAllClientIDsL(KLexiconIdTable, KLexiconIdColumn, aClientUid, aLexiconIDs); - RArray ix; - ix.Reset(); - GetAllClientIDsL(KLexiconIdTable, KLexiconIdColumn, aClientUid, ix); - for(TInt i=0;i& aLexiconIDs ) - { - // This is a hack to get the id aligned to 4-byte boundary, - // for some reason this does not happen in winscw build if - // TSILexiconID is taken from stack. - TSILexiconID* id = new (ELeave) TSILexiconID; - CleanupStack::PushL( id ); - - // GetAllIDsL(KLexiconIdTable, KLexiconIdColumn, aLexiconIDs); - RArray ix; - ix.Reset(); - GetAllIDsL(KLexiconIdTable, KLexiconIdColumn, ix); - for(TInt i=0;i& aPronunciationIDs ) - { - CleanupClosePushL( aPronunciationIDs ); - - // Construct the table name using the provided Lexicon ID - TBuf<40> KLexiconName(KSILexiconTable); - KLexiconName.AppendNumUC(aLexiconID); - - CSILexicon* newLexicon = LexiconL( aLexiconID) ;// Load the Lexicon from database - CleanupStack::PushL(newLexicon); - - TSIPronunciationID aPronunciationID; - for (TInt i=0;iCount();i++) { - CSIPronunciation* aPronunciation=&(newLexicon->AtL(i)); - aPronunciationID=aPronunciation->PronunciationID(); - User::LeaveIfError(aPronunciationIDs.Append(aPronunciationID)); - } - - CleanupStack::PopAndDestroy(newLexicon); // newLexicon - // GetAllIDsL(KLexiconName, KPronunciationIDColumn, aPronunciationIDs); - CleanupStack::Pop(); - } - -// ----------------------------------------------------------------------------- -// CSILexiconDB::RemoveLexiconL -// Deletes a Lexicon table from the database. -// ----------------------------------------------------------------------------- -// -void CSILexiconDB::RemoveLexiconL( TUid aClientUid, - TSILexiconID aLexiconID ) - { - - VerifyOwnershipL(aClientUid, KLexiconIdTable, KLexiconIndex, aLexiconID); - - - /* Some times removing of corrupted lexicon fails because of this: - TInt diskSpace = ( PronunciationCountL(aLexiconID) * sizeof( CSIPronunciation ) ) - + sizeof( CSILexicon ); - User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, diskSpace ) ); - */ - - // Construct the table name using the provided Lexicon ID - TBuf<40> KLexiconName(KSILexiconTable); - KLexiconName.AppendNumUC(aLexiconID); - - TBuf<50> KSQLStatement; - // Declare a literal string to hold the SQL statement - // DROP TABLE KLexiconName - _LIT(KSQLDelete1, "DROP TABLE "); - - KSQLStatement = KSQLDelete1; - KSQLStatement.Append(KLexiconName); - - User::LeaveIfError(iDb.Execute(KSQLStatement)); - - // Release the Lexicon ID - ReleaseIdL(KLexiconIdTable, KLexiconIdColumn, aLexiconID); - - // Cancel free disk space request - //iDbSession.FreeReservedSpace( iDrive ); - - } - -// ----------------------------------------------------------------------------- -// CSILexiconDB::PronunciationCountL -// Returns the number of Pronunciations in the specified Lexicon. -// ----------------------------------------------------------------------------- -TInt CSILexiconDB::PronunciationCountL( TSILexiconID aLexiconID ) - { - - CSILexicon* newLexicon = LexiconL( aLexiconID) ; - CleanupStack::PushL(newLexicon); - - TInt PronunciationCount=newLexicon->Count(); - CleanupStack::PopAndDestroy(newLexicon); - return PronunciationCount; - - } - -// ----------------------------------------------------------------------------- -// CSILexiconDB::IsPronunciationValidL -// Checks if the specified pronunciation exists in the specified loaded . -// -// ----------------------------------------------------------------------------- -// -TBool CSILexiconDB::IsPronunciationValidL( TSILexiconID aLexiconID, - TSIPronunciationID aPronunciationID ) - { - CSILexicon* newLexicon = LexiconL( aLexiconID) ; - CleanupStack::PushL(newLexicon); - - if (newLexicon->Find(aPronunciationID)==KErrNotFound) { - CleanupStack::PopAndDestroy(newLexicon); // newLexicon - return EFalse; - } - else { - CleanupStack::PopAndDestroy(newLexicon); // newLexicon - return ETrue; - } - } - - -// ----------------------------------------------------------------------------- -// CSILexiconDB::ResetAndDestroy -// Deallocates the temporary memory containing the Lexicon object created with -// AllPronunciationsL. -// ----------------------------------------------------------------------------- -// -void CSILexiconDB::ResetAndDestroy() - { - // iLexiconArray.ResetAndDestroy(); - } - -// ----------------------------------------------------------------------------- -// CSILexiconDB::RemovePronunciationL -// Deletes Pronunciation from the database. -// ----------------------------------------------------------------------------- -// -void CSILexiconDB::RemovePronunciationL( TUid aClientUid, - TSILexiconID aLexiconID, - TSIPronunciationID aPronunciationID - ) - { - // Check the ownership first - VerifyOwnershipL(aClientUid, KLexiconIdTable, KLexiconIndex, aLexiconID); - - CSILexicon* newLexicon = LexiconL( aLexiconID); - CleanupStack::PushL(newLexicon); - - if (newLexicon->Find(aPronunciationID)==KErrNotFound) - User::Leave(KErrNotFound); - else - newLexicon->DeleteL(aPronunciationID); - UpdateLexiconL(aClientUid , newLexicon); - CleanupStack::PopAndDestroy(newLexicon); // newLexicon - } - -// ----------------------------------------------------------------------------- -// CSILexiconDB::AddPronunciationL -// Add Pronunciation to the database. -// ----------------------------------------------------------------------------- -// -TSIPronunciationID CSILexiconDB::AddPronunciationL( TUid aClientUid, - TSILexiconID aLexiconID, - TDesC8& aPronunciationPr, - TSIModelBankID aModelBankID) - { - // Check the ownership first - VerifyOwnershipL( aClientUid, KLexiconIdTable, KLexiconIndex, aLexiconID ); - - CSILexicon* aLexicon = LexiconL( aLexiconID ); - CleanupStack::PushL( aLexicon ); - - // existing myPronunciationID - RArray myPronunciationID; - myPronunciationID.Reset(); - for( TInt i = 0; i < aLexicon->Count(); i++ ) - { - CSIPronunciation* aPronunciation = &( aLexicon->AtL( i ) ); - myPronunciationID.Append( aPronunciation->PronunciationID() ); - } - - // Find a uniq new id - TSIPronunciationID aPronunciationID = GetNewID( myPronunciationID ); - myPronunciationID.Close(); - - // add the phoneme sequence to the Pronunciation - CSIPronunciation* pronunciation = CSIPronunciation::NewL( aPronunciationID, aModelBankID ); - CleanupStack::PushL( pronunciation ); - pronunciation->SetPhonemeSequenceL( aPronunciationPr ); - aLexicon->AddL( pronunciation ); - CleanupStack::Pop( pronunciation ); // aPronunciation - UpdateLexiconL( aClientUid,aLexicon ); - CleanupStack::PopAndDestroy( aLexicon ); // aLexicon - return aPronunciationID; - } - -// ----------------------------------------------------------------------------- -// CSILexiconDB::LexiconL -// Loads all pronunciations within the specified lexicon into a lexicon object -// ----------------------------------------------------------------------------- -// -CSILexicon* CSILexiconDB::LexiconL( TSILexiconID aLexiconID ) - { - - // 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 KBinaryLexiconColumn , KBinaryLexiconColumn FROM KLexiconName - TBuf<40> KLexiconName(KSILexiconTable); - KLexiconName.AppendNumUC(aLexiconID); - // Create newLexicon object - CSILexicon* lexicon = CSILexicon::NewLC( aLexiconID ); - _LIT(KSQLSelect1,"select "); - _LIT(KSQLSelect2," from "); - TBuf<120> KSQLStatement; - KSQLStatement.Append(KSQLSelect1 ); - KSQLStatement.Append(KBinaryLexiconColumn ); - KSQLStatement.Append(KNext); - KSQLStatement.Append(KBinaryLexiconColumnSize ); - KSQLStatement.Append(KSQLSelect2 ); - KSQLStatement.Append(KLexiconName); - - // 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(KBinaryLexiconColumnSize); // 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(KBinaryLexiconColumn); // Ordinal position of long column - - - in.OpenLC(view, col); - in.ReadL(readBuf, view.ColLength(col)); - dataCopyBuffer->InsertL(0,readBuf); - lexicon->InternalizeL( stream ); - - CleanupStack::PopAndDestroy( col ); - CleanupStack::PopAndDestroy( &in ); - CleanupStack::PopAndDestroy( &stream ); - CleanupStack::PopAndDestroy( dataCopyBuffer ); - CleanupStack::PopAndDestroy( buf ); - } - - CleanupStack::PopAndDestroy( colSet ); - CleanupStack::PopAndDestroy( &view ); - - - - // Cleanup lexicon - CleanupStack::Pop( lexicon ); - return lexicon; - } - -// End of File