srsf/sisrscontrollerplugin/src/silexicondb.cpp
branchRCL_3
changeset 23 e36f3802f733
equal deleted inserted replaced
22:cad71a31b7fc 23:e36f3802f733
       
     1 /*
       
     2 * Copyright (c) 2004-2007 Nokia Corporation and/or its subsidiary(-ies). 
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  This class handles the storage and access of speaker independent
       
    15 *               lexicons.  It is also responsible for allocating memory when
       
    16 *               loading lexicons into the recognizer.
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 // INCLUDE FILES
       
    22 #include "silexicondb.h"
       
    23 #include "rubydebug.h"
       
    24 
       
    25 // CONSTANTS
       
    26 
       
    27 
       
    28 // ============================ MEMBER FUNCTIONS ===============================
       
    29 
       
    30 // -----------------------------------------------------------------------------
       
    31 // CSILexiconDB::CSILexiconDB
       
    32 // C++ default constructor can NOT contain any code, that
       
    33 // might leave.
       
    34 // -----------------------------------------------------------------------------
       
    35 //
       
    36 CSILexiconDB::CSILexiconDB( RDbNamedDatabase& aDatabase, 
       
    37                             RDbs& aDbSession,
       
    38                             TInt aDrive )
       
    39 :	CSICommonDB(aDatabase, aDbSession, aDrive )
       
    40 {
       
    41 }
       
    42 
       
    43 // -----------------------------------------------------------------------------
       
    44 // CSILexiconDB::ConstructL
       
    45 // Symbian 2nd phase constructor can leave.
       
    46 // -----------------------------------------------------------------------------
       
    47 //
       
    48 void CSILexiconDB::ConstructL()
       
    49     {
       
    50     RUBY_DEBUG_BLOCK( "CSILexiconDB::ConstructL" );
       
    51     }
       
    52 
       
    53 // -----------------------------------------------------------------------------
       
    54 // CSILexiconDB::NewL
       
    55 // Two-phased constructor.
       
    56 // -----------------------------------------------------------------------------
       
    57 //
       
    58 CSILexiconDB* CSILexiconDB::NewL( RDbNamedDatabase& aDatabase, 
       
    59                                   RDbs& aDbSession,
       
    60                                   TInt aDrive )
       
    61     {
       
    62     RUBY_DEBUG_BLOCK( "CSILexiconDB::NewL" );
       
    63     CSILexiconDB* self 
       
    64         = new( ELeave ) CSILexiconDB( aDatabase, aDbSession, aDrive );
       
    65     CleanupStack::PushL( self );
       
    66     self->ConstructL();
       
    67     CleanupStack::Pop( self );	
       
    68     return self;
       
    69     }
       
    70 
       
    71 // -----------------------------------------------------------------------------
       
    72 // CSILexiconDB::~CSILexiconDB
       
    73 // Destructor
       
    74 // -----------------------------------------------------------------------------
       
    75 //
       
    76 CSILexiconDB::~CSILexiconDB()
       
    77     {
       
    78     // Delete all elements of the array before deleting the array
       
    79     //	iLexiconArray.ResetAndDestroy();
       
    80     //	iLexiconArray.Close();
       
    81     RUBY_DEBUG0( "CSILexiconDB::~CSILexiconDB" );
       
    82     }
       
    83 
       
    84 // -----------------------------------------------------------------------------
       
    85 // CSILexiconDB::CreateLexiconL
       
    86 // Creates a new lexicon table in the database.
       
    87 // -----------------------------------------------------------------------------
       
    88 //
       
    89 TSILexiconID CSILexiconDB::CreateLexiconL( TUid aClientUid )
       
    90     {
       
    91     RUBY_DEBUG_BLOCK( "CSILexiconDB::CreateLexiconL" );
       
    92     
       
    93     User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, sizeof( CSILexicon ) ) );
       
    94     
       
    95     // Generate a new Lexicon ID
       
    96     TSILexiconID lexiconID = STATIC_CAST(TSILexiconID,CreateNewIDL(KLexiconIdTable, KLexiconIdColumn, aClientUid ));
       
    97     
       
    98     // Construct the table name using the new lexicon ID
       
    99     TBuf<40> KLexiconName( KSILexiconTable );
       
   100     KLexiconName.AppendNumUC( lexiconID );
       
   101     RUBY_DEBUG1( "CSILexiconDB::CreateLexiconL lexicon ID: %i", lexiconID );
       
   102 	
       
   103     
       
   104     // Create a table definition
       
   105     CDbColSet* columns = CDbColSet::NewLC();
       
   106     
       
   107     // add the columns  
       
   108     // 1) Binary data, 2) binary data size
       
   109     columns->AddL( TDbCol( KBinaryLexiconColumn, EDbColLongBinary ) );
       
   110     columns->AddL( TDbCol( KBinaryLexiconColumnSize, EDbColUint32 ) );
       
   111     
       
   112     // Create a table
       
   113     TInt err =iDb.CreateTable( KLexiconName, *columns );
       
   114     
       
   115     if ( err != KErrNone )
       
   116         {
       
   117         // Failed to create the table.
       
   118         // Need to release the new Lexicon ID and leave.
       
   119         ReleaseIdL( KLexiconIdTable, KLexiconIdColumn, lexiconID );
       
   120         User::Leave( err );
       
   121         }
       
   122     
       
   123     // cleanup the column set
       
   124     CleanupStack::PopAndDestroy( columns );
       
   125     // Construct the table name using the provided grammar ID
       
   126     // Declare a literal string to hold the SQL statement
       
   127     // SELECT KBinaryLexiconColumn , KBinaryLexiconColumn FROM  KLexiconName
       
   128     _LIT(KSQLSelect1,"select  ");	
       
   129     _LIT(KSQLSelect2," from  ");		
       
   130     TBuf<120> KSQLStatement;		
       
   131     KSQLStatement.Append(KSQLSelect1  );	
       
   132     KSQLStatement.Append(KBinaryLexiconColumn );
       
   133     KSQLStatement.Append(KNext);
       
   134     KSQLStatement.Append(KBinaryLexiconColumnSize );	
       
   135     KSQLStatement.Append(KSQLSelect2  );
       
   136     KSQLStatement.Append(KLexiconName); 
       
   137     
       
   138     // create a view on the database
       
   139     RDbView view;
       
   140     User::LeaveIfError(view.Prepare(iDb,TDbQuery(KSQLStatement,EDbCompareNormal)));
       
   141     User::LeaveIfError(view.EvaluateAll());
       
   142     
       
   143     // Get the structure of rowset
       
   144     CDbColSet* colSet = view.ColSetL(); 
       
   145     view.InsertL();
       
   146     view.PutL();
       
   147     
       
   148     
       
   149     // close the view
       
   150     view.Close();
       
   151     delete colSet; 
       
   152     
       
   153     // add an empty lexicon
       
   154     CSILexicon *aLexicon=CSILexicon::NewL(lexiconID);	
       
   155     CleanupStack::PushL(aLexicon);
       
   156     UpdateLexiconL(aClientUid,aLexicon);
       
   157     CleanupStack::PopAndDestroy(aLexicon);	
       
   158     
       
   159     iDbSession.FreeReservedSpace( iDrive );
       
   160     
       
   161     return lexiconID;
       
   162     }
       
   163 
       
   164 
       
   165 // -----------------------------------------------------------------------------
       
   166 // CSILexiconDB::UpdateLexiconL
       
   167 // Inserts the externalized SI Lexicon into the specified grammar table.
       
   168 // Save the Lexicon into the database
       
   169 // -----------------------------------------------------------------------------
       
   170 //
       
   171 void CSILexiconDB::UpdateLexiconL( TUid aClientUid, 
       
   172 								   CSILexicon *aSILexicon )
       
   173     {
       
   174     
       
   175     //	__UHEAP_MARK;
       
   176     TSILexiconID aLexiconID=aSILexicon->LexiconID();
       
   177     VerifyOwnershipL(aClientUid, KLexiconIdTable, KLexiconIndex, aLexiconID);
       
   178     
       
   179     // Construct the table name using the provided grammar ID
       
   180     // Declare a literal string to hold the SQL statement
       
   181     // SELECT KBinaryLexiconColumn , KBinaryLexiconColumn FROM  KLexiconName
       
   182     TBuf<40> KLexiconName(KSILexiconTable);
       
   183     KLexiconName.AppendNumUC(aLexiconID);	
       
   184     _LIT(KSQLSelect1,"select  ");	
       
   185     _LIT(KSQLSelect2," from  ");		
       
   186     TBuf<120> KSQLStatement;		
       
   187     KSQLStatement.Append(KSQLSelect1  );	
       
   188     KSQLStatement.Append(KBinaryLexiconColumn );
       
   189     KSQLStatement.Append(KNext);
       
   190     KSQLStatement.Append(KBinaryLexiconColumnSize );	
       
   191     KSQLStatement.Append(KSQLSelect2  );
       
   192     KSQLStatement.Append(KLexiconName); 
       
   193     
       
   194     // create a view on the database
       
   195     RDbView view;
       
   196     User::LeaveIfError(view.Prepare(iDb,TDbQuery(KSQLStatement,EDbCompareNormal)));
       
   197     User::LeaveIfError(view.EvaluateAll());
       
   198     
       
   199     // Get the structure of rowset
       
   200     CDbColSet* colSet = view.ColSetL(); 
       
   201     
       
   202     view.FirstL(); 
       
   203     view.UpdateL();
       
   204     
       
   205     
       
   206     // Externalize grammar
       
   207     CBufFlat* dataCopyBuffer = CBufFlat::NewL( 100 ); // 100 = expand 100 bytes
       
   208     CleanupStack::PushL(dataCopyBuffer);              // when the buffer is full
       
   209     //TPtr8 Buft((TUint8*) abuf,3,3);
       
   210     //dataCopyBuffer->InsertL(0,Buft);
       
   211     RBufWriteStream stream;
       
   212     stream.Open(*dataCopyBuffer);
       
   213     CleanupClosePushL(stream);
       
   214     aSILexicon->ExternalizeL(stream);
       
   215     CleanupStack::PopAndDestroy( &stream );
       
   216     
       
   217     TPtr8 aWriteBuf(dataCopyBuffer->Ptr(0));
       
   218     TInt BufSize =aWriteBuf.Size();
       
   219     
       
   220     // add binary buffer by Using the stream  
       
   221     RDbColWriteStream out;
       
   222     TDbColNo col = colSet->ColNo(KBinaryLexiconColumn); // Ordinal position of long column	
       
   223     out.OpenLC(view, col);
       
   224     out.WriteL(aWriteBuf);	
       
   225     out.Close();	
       
   226     CleanupStack::PopAndDestroy(); // out
       
   227     // add  size of the buffer
       
   228     col = colSet->ColNo(KBinaryLexiconColumnSize); // Ordinal position of  size	
       
   229     view.SetColL( col,BufSize); 
       
   230     
       
   231     view.PutL();
       
   232     
       
   233     // close the view
       
   234     view.Close();
       
   235     
       
   236     
       
   237     delete colSet; 
       
   238     CleanupStack::PopAndDestroy( dataCopyBuffer ); 
       
   239     //	__UHEAP_MARKEND;
       
   240     }
       
   241 
       
   242 // -----------------------------------------------------------------------------
       
   243 // CSIGrammarDB::GetNewID
       
   244 // Get a new uniq ID 
       
   245 // -----------------------------------------------------------------------------
       
   246 TInt CSILexiconDB::GetNewID( RArray<TSIRuleID>& aMyIds ) 
       
   247     {
       
   248     RArray<TSIRuleID> myIDs = aMyIds;
       
   249     TInt Count = myIDs.Count();
       
   250     TInt id = 0;
       
   251     if ( Count == 0 ) 
       
   252         {
       
   253         id = 1; // empty ,first id will be 1
       
   254         }
       
   255     else
       
   256         { 
       
   257         // Find a unique Rulevariant ID
       
   258         myIDs.SortUnsigned();
       
   259         id = myIDs[myIDs.Count() - 1] + 1; //by default , the last one 
       
   260         for ( TInt i = 0; i < myIDs.Count(); i++ ) 
       
   261             {
       
   262             TInt index = i + 1; 
       
   263             TInt s = myIDs[i];
       
   264             if ( s > index ) 
       
   265                 {
       
   266                 id = index;
       
   267                 break;
       
   268                 }
       
   269             }
       
   270         }
       
   271     return id;
       
   272     }
       
   273 
       
   274 
       
   275 // -----------------------------------------------------------------------------
       
   276 // CSILexiconDB::CreateIDTableL
       
   277 // Creates a new lexicon ID table in the database.
       
   278 // -----------------------------------------------------------------------------
       
   279 //
       
   280 void CSILexiconDB::CreateIDTableL()
       
   281     {
       
   282     // Invoke function in the base class CSICommonDB.
       
   283     CSICommonDB::CreateIDTableL(KLexiconIdTable, KLexiconIdColumn, KLexiconIndex);
       
   284     }
       
   285 
       
   286 // -----------------------------------------------------------------------------
       
   287 // CSILexiconDB::GetAllClientLexiconIDsL
       
   288 // This function returns all Lexicon IDs owned by the specified client.
       
   289 // -----------------------------------------------------------------------------
       
   290 //
       
   291 void CSILexiconDB::GetAllClientLexiconIDsL( TUid aClientUid,
       
   292 										    RArray<TSILexiconID>& aLexiconIDs )
       
   293     {
       
   294     //	GetAllClientIDsL(KLexiconIdTable, KLexiconIdColumn, aClientUid, aLexiconIDs);
       
   295     RArray<TUint32> ix;
       
   296     ix.Reset();
       
   297     GetAllClientIDsL(KLexiconIdTable, KLexiconIdColumn, aClientUid, ix);
       
   298     for(TInt i=0;i<ix.Count();i++) 
       
   299         aLexiconIDs.Append(STATIC_CAST(TSILexiconID,ix[i]));
       
   300     ix.Close();
       
   301     }
       
   302 
       
   303 // -----------------------------------------------------------------------------
       
   304 // CSILexiconDB::GetAllLexiconIDsL
       
   305 // This function returns all Lexicon IDs in the database.
       
   306 // -----------------------------------------------------------------------------
       
   307 //
       
   308 void CSILexiconDB::GetAllLexiconIDsL( RArray<TSILexiconID>& aLexiconIDs )
       
   309     {
       
   310     // This is a hack to get the id aligned to 4-byte boundary,
       
   311     // for some reason this does not happen in winscw build if 
       
   312     // TSILexiconID is taken from stack.
       
   313     TSILexiconID* id = new (ELeave) TSILexiconID;
       
   314     CleanupStack::PushL( id );
       
   315     
       
   316     //	GetAllIDsL(KLexiconIdTable, KLexiconIdColumn, aLexiconIDs);
       
   317     RArray<TUint32> ix;
       
   318     ix.Reset();
       
   319     GetAllIDsL(KLexiconIdTable, KLexiconIdColumn, ix);
       
   320     for(TInt i=0;i<ix.Count();i++) 
       
   321         {
       
   322         *id = STATIC_CAST( TSILexiconID, ix[i] );
       
   323         aLexiconIDs.Append( *id );
       
   324         }
       
   325     ix.Close();
       
   326     CleanupStack::PopAndDestroy( id );
       
   327     }
       
   328 
       
   329 // -----------------------------------------------------------------------------
       
   330 // CSILexiconDB::GetAllPronunciationIDsL
       
   331 // This function returns all Pronunciation IDs within the specified Lexicon.
       
   332 // Lexicon have to be loaded 
       
   333 // -----------------------------------------------------------------------------
       
   334 //
       
   335 void CSILexiconDB::GetAllPronunciationIDsL( TSILexiconID aLexiconID, RArray<TSIPronunciationID>& aPronunciationIDs )
       
   336     {
       
   337 	CleanupClosePushL( aPronunciationIDs ); 
       
   338 	
       
   339     // Construct the table name using the provided Lexicon ID
       
   340     TBuf<40> KLexiconName(KSILexiconTable);
       
   341     KLexiconName.AppendNumUC(aLexiconID);
       
   342     
       
   343     CSILexicon* newLexicon = LexiconL( aLexiconID) ;// Load the Lexicon from database	
       
   344     CleanupStack::PushL(newLexicon);
       
   345     
       
   346     TSIPronunciationID	aPronunciationID;
       
   347     for (TInt  i=0;i<newLexicon->Count();i++) {
       
   348         CSIPronunciation* aPronunciation=&(newLexicon->AtL(i));
       
   349         aPronunciationID=aPronunciation->PronunciationID();		
       
   350         User::LeaveIfError(aPronunciationIDs.Append(aPronunciationID));
       
   351         } 
       
   352     
       
   353     CleanupStack::PopAndDestroy(newLexicon); // newLexicon
       
   354     //	GetAllIDsL(KLexiconName, KPronunciationIDColumn, aPronunciationIDs);
       
   355     CleanupStack::Pop(); 
       
   356     }
       
   357 
       
   358 // -----------------------------------------------------------------------------
       
   359 // CSILexiconDB::RemoveLexiconL
       
   360 // Deletes a Lexicon table from the database.
       
   361 // -----------------------------------------------------------------------------
       
   362 //
       
   363 void CSILexiconDB::RemoveLexiconL( TUid aClientUid,
       
   364 								   TSILexiconID aLexiconID )
       
   365     {
       
   366     
       
   367     VerifyOwnershipL(aClientUid, KLexiconIdTable, KLexiconIndex, aLexiconID);
       
   368     
       
   369     
       
   370     /* Some times removing of corrupted lexicon fails because of this:
       
   371     TInt diskSpace = ( PronunciationCountL(aLexiconID) * sizeof( CSIPronunciation ) )
       
   372         + sizeof( CSILexicon );
       
   373     User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, diskSpace ) );
       
   374     */
       
   375     
       
   376     // Construct the table name using the provided Lexicon ID
       
   377     TBuf<40> KLexiconName(KSILexiconTable);
       
   378     KLexiconName.AppendNumUC(aLexiconID);
       
   379     
       
   380     TBuf<50> KSQLStatement;
       
   381     // Declare a literal string to hold the SQL statement
       
   382     // DROP TABLE KLexiconName
       
   383     _LIT(KSQLDelete1, "DROP TABLE ");
       
   384     
       
   385     KSQLStatement = KSQLDelete1;
       
   386     KSQLStatement.Append(KLexiconName);
       
   387     
       
   388     User::LeaveIfError(iDb.Execute(KSQLStatement));
       
   389     
       
   390     // Release the Lexicon ID
       
   391     ReleaseIdL(KLexiconIdTable, KLexiconIdColumn, aLexiconID);
       
   392     
       
   393     // Cancel free disk space request
       
   394     //iDbSession.FreeReservedSpace( iDrive );
       
   395     
       
   396     }
       
   397 
       
   398 // -----------------------------------------------------------------------------
       
   399 // CSILexiconDB::PronunciationCountL
       
   400 // Returns the number of Pronunciations in the specified Lexicon.
       
   401 // -----------------------------------------------------------------------------
       
   402 TInt CSILexiconDB::PronunciationCountL( TSILexiconID aLexiconID )
       
   403     {
       
   404     
       
   405     CSILexicon* newLexicon = LexiconL( aLexiconID) ;	
       
   406     CleanupStack::PushL(newLexicon);
       
   407     
       
   408     TInt PronunciationCount=newLexicon->Count();	 
       
   409     CleanupStack::PopAndDestroy(newLexicon); 	
       
   410     return PronunciationCount;
       
   411 
       
   412     }
       
   413 
       
   414 // -----------------------------------------------------------------------------
       
   415 // CSILexiconDB::IsPronunciationValidL
       
   416 // Checks if the specified pronunciation exists in the specified loaded	.
       
   417 // 
       
   418 // -----------------------------------------------------------------------------
       
   419 //
       
   420 TBool CSILexiconDB::IsPronunciationValidL( TSILexiconID aLexiconID,
       
   421                                            TSIPronunciationID aPronunciationID )
       
   422     {
       
   423     CSILexicon* newLexicon = LexiconL( aLexiconID) ;		 
       
   424     CleanupStack::PushL(newLexicon);
       
   425     
       
   426     if (newLexicon->Find(aPronunciationID)==KErrNotFound) {
       
   427         CleanupStack::PopAndDestroy(newLexicon); // newLexicon
       
   428         return EFalse; 
       
   429         }
       
   430     else {
       
   431         CleanupStack::PopAndDestroy(newLexicon); // newLexicon
       
   432         return ETrue;	
       
   433         }
       
   434     }
       
   435 
       
   436 
       
   437 // -----------------------------------------------------------------------------
       
   438 // CSILexiconDB::ResetAndDestroy
       
   439 // Deallocates the temporary memory containing the Lexicon object created with
       
   440 // AllPronunciationsL.
       
   441 // -----------------------------------------------------------------------------
       
   442 //
       
   443 void CSILexiconDB::ResetAndDestroy()
       
   444     {
       
   445     //	iLexiconArray.ResetAndDestroy();
       
   446     }
       
   447 
       
   448 // -----------------------------------------------------------------------------
       
   449 // CSILexiconDB::RemovePronunciationL
       
   450 // Deletes Pronunciation from the database.
       
   451 // -----------------------------------------------------------------------------
       
   452 //
       
   453 void CSILexiconDB::RemovePronunciationL(  TUid aClientUid, 
       
   454                                         TSILexiconID aLexiconID,
       
   455                                         TSIPronunciationID aPronunciationID
       
   456                                         )
       
   457     {
       
   458     // Check the ownership first
       
   459     VerifyOwnershipL(aClientUid, KLexiconIdTable, KLexiconIndex, aLexiconID);
       
   460     
       
   461     CSILexicon* newLexicon = LexiconL( aLexiconID);		 
       
   462     CleanupStack::PushL(newLexicon);
       
   463     
       
   464     if (newLexicon->Find(aPronunciationID)==KErrNotFound)
       
   465         User::Leave(KErrNotFound);				 
       
   466     else  
       
   467         newLexicon->DeleteL(aPronunciationID);
       
   468     UpdateLexiconL(aClientUid  , newLexicon);
       
   469     CleanupStack::PopAndDestroy(newLexicon); // newLexicon
       
   470     }
       
   471 
       
   472 // -----------------------------------------------------------------------------
       
   473 // CSILexiconDB::AddPronunciationL
       
   474 // Add Pronunciation to the database.
       
   475 // -----------------------------------------------------------------------------
       
   476 //
       
   477 TSIPronunciationID CSILexiconDB::AddPronunciationL( TUid aClientUid, 
       
   478                                                    TSILexiconID aLexiconID,
       
   479                                                    TDesC8& aPronunciationPr,
       
   480                                                    TSIModelBankID aModelBankID)
       
   481     {
       
   482     // Check the ownership first
       
   483     VerifyOwnershipL( aClientUid, KLexiconIdTable, KLexiconIndex, aLexiconID );
       
   484     
       
   485     CSILexicon* aLexicon = LexiconL( aLexiconID );
       
   486     CleanupStack::PushL( aLexicon );
       
   487     
       
   488     // existing myPronunciationID
       
   489     RArray<TSIPronunciationID> myPronunciationID;
       
   490     myPronunciationID.Reset();
       
   491     for( TInt i = 0; i < aLexicon->Count(); i++ )
       
   492         {
       
   493         CSIPronunciation* aPronunciation = &( aLexicon->AtL( i ) );
       
   494         myPronunciationID.Append( aPronunciation->PronunciationID() );
       
   495         }
       
   496     
       
   497     // Find a uniq new id 
       
   498     TSIPronunciationID aPronunciationID = GetNewID( myPronunciationID );
       
   499     myPronunciationID.Close();
       
   500     
       
   501     // add the  phoneme sequence  to the Pronunciation
       
   502     CSIPronunciation* pronunciation = CSIPronunciation::NewL( aPronunciationID, aModelBankID );
       
   503     CleanupStack::PushL( pronunciation );	
       
   504     pronunciation->SetPhonemeSequenceL( aPronunciationPr );
       
   505     aLexicon->AddL( pronunciation );
       
   506     CleanupStack::Pop( pronunciation ); // aPronunciation
       
   507     UpdateLexiconL( aClientUid,aLexicon );
       
   508     CleanupStack::PopAndDestroy( aLexicon ); // aLexicon
       
   509     return aPronunciationID;
       
   510     }
       
   511 
       
   512 // -----------------------------------------------------------------------------
       
   513 // CSILexiconDB::LexiconL
       
   514 // Loads all pronunciations within the specified lexicon into a lexicon object
       
   515 // -----------------------------------------------------------------------------
       
   516 //
       
   517 CSILexicon* CSILexiconDB::LexiconL( TSILexiconID aLexiconID )
       
   518     {
       
   519     
       
   520     // Construct the table name using the provided grammar ID
       
   521     // Construct the table name using the provided grammar ID
       
   522     // Declare a literal string to hold the SQL statement
       
   523     // SELECT KBinaryLexiconColumn , KBinaryLexiconColumn FROM  KLexiconName
       
   524     TBuf<40> KLexiconName(KSILexiconTable);
       
   525     KLexiconName.AppendNumUC(aLexiconID);
       
   526     // Create newLexicon object	
       
   527     CSILexicon* lexicon = CSILexicon::NewLC( aLexiconID );	
       
   528     _LIT(KSQLSelect1,"select  ");	
       
   529     _LIT(KSQLSelect2," from  ");
       
   530     TBuf<120> KSQLStatement;		
       
   531     KSQLStatement.Append(KSQLSelect1  );		
       
   532     KSQLStatement.Append(KBinaryLexiconColumn );
       
   533     KSQLStatement.Append(KNext);
       
   534     KSQLStatement.Append(KBinaryLexiconColumnSize );
       
   535     KSQLStatement.Append(KSQLSelect2  );
       
   536     KSQLStatement.Append(KLexiconName); 
       
   537     
       
   538     // create a view on the database
       
   539     RDbView view;
       
   540     CleanupClosePushL( view );
       
   541     
       
   542     User::LeaveIfError(view.Prepare(iDb,TDbQuery(KSQLStatement,EDbCompareNormal)));
       
   543     User::LeaveIfError(view.EvaluateAll());
       
   544     
       
   545     // Get the structure of the rowset 
       
   546     CDbColSet* colSet = view.ColSetL();
       
   547     CleanupStack::PushL( colSet );
       
   548     
       
   549     // iterate across the row set, one row only
       
   550     for (view.FirstL();view.AtRow();view.NextL())
       
   551         {
       
   552         
       
   553         // retrieve the row
       
   554         view.GetL();
       
   555         
       
   556         // first retrieve the size of binary package 
       
   557         TDbColNo col = colSet->ColNo(KBinaryLexiconColumnSize); // Ordinal position of long column 
       
   558         TInt32 size = view.ColUint32( col);
       
   559         
       
   560         TUint8* buf = new (ELeave) TUint8[size];		
       
   561         CleanupStack::PushL( buf);			
       
   562         TPtr8 readBuf( buf, size, size);
       
   563         CBufFlat* dataCopyBuffer = CBufFlat::NewL( 100 ); // 100 = expand 100 bytes
       
   564         CleanupStack::PushL( dataCopyBuffer );              // when the buffer is full
       
   565         
       
   566         RBufReadStream stream;
       
   567         CleanupClosePushL( stream );
       
   568         stream.Open(*dataCopyBuffer);
       
   569         
       
   570         // and a stream for long columns
       
   571         RDbColReadStream in;
       
   572         CleanupClosePushL( in );
       
   573         col = colSet->ColNo(KBinaryLexiconColumn); // Ordinal position of long column 
       
   574         
       
   575         
       
   576         in.OpenLC(view, col);
       
   577         in.ReadL(readBuf, view.ColLength(col));
       
   578         dataCopyBuffer->InsertL(0,readBuf);
       
   579         lexicon->InternalizeL( stream );
       
   580         
       
   581         CleanupStack::PopAndDestroy( col );
       
   582         CleanupStack::PopAndDestroy( &in );
       
   583         CleanupStack::PopAndDestroy( &stream ); 
       
   584         CleanupStack::PopAndDestroy( dataCopyBuffer );
       
   585         CleanupStack::PopAndDestroy( buf );
       
   586         }
       
   587     
       
   588     CleanupStack::PopAndDestroy( colSet );
       
   589     CleanupStack::PopAndDestroy( &view );
       
   590     
       
   591 
       
   592  
       
   593     // Cleanup lexicon
       
   594     CleanupStack::Pop( lexicon );
       
   595     return lexicon;
       
   596     }
       
   597 
       
   598 //  End of File