srsf/sisrscontrollerplugin/src/silexicondb.cpp
changeset 0 bf1d17376201
child 15 6347473a7bb2
equal deleted inserted replaced
-1:000000000000 0:bf1d17376201
       
     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     // Construct the table name using the provided Lexicon ID
       
   338     TBuf<40> KLexiconName(KSILexiconTable);
       
   339     KLexiconName.AppendNumUC(aLexiconID);
       
   340     
       
   341     CSILexicon* newLexicon = LexiconL( aLexiconID) ;// Load the Lexicon from database	
       
   342     CleanupStack::PushL(newLexicon);
       
   343     
       
   344     TSIPronunciationID	aPronunciationID;
       
   345     for (TInt  i=0;i<newLexicon->Count();i++) {
       
   346         CSIPronunciation* aPronunciation=&(newLexicon->AtL(i));
       
   347         aPronunciationID=aPronunciation->PronunciationID();		
       
   348         User::LeaveIfError(aPronunciationIDs.Append(aPronunciationID));
       
   349         } 
       
   350     
       
   351     CleanupStack::PopAndDestroy(newLexicon); // newLexicon
       
   352     //	GetAllIDsL(KLexiconName, KPronunciationIDColumn, aPronunciationIDs);
       
   353     }
       
   354 
       
   355 // -----------------------------------------------------------------------------
       
   356 // CSILexiconDB::RemoveLexiconL
       
   357 // Deletes a Lexicon table from the database.
       
   358 // -----------------------------------------------------------------------------
       
   359 //
       
   360 void CSILexiconDB::RemoveLexiconL( TUid aClientUid,
       
   361 								   TSILexiconID aLexiconID )
       
   362     {
       
   363     
       
   364     VerifyOwnershipL(aClientUid, KLexiconIdTable, KLexiconIndex, aLexiconID);
       
   365     
       
   366     
       
   367     /* Some times removing of corrupted lexicon fails because of this:
       
   368     TInt diskSpace = ( PronunciationCountL(aLexiconID) * sizeof( CSIPronunciation ) )
       
   369         + sizeof( CSILexicon );
       
   370     User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, diskSpace ) );
       
   371     */
       
   372     
       
   373     // Construct the table name using the provided Lexicon ID
       
   374     TBuf<40> KLexiconName(KSILexiconTable);
       
   375     KLexiconName.AppendNumUC(aLexiconID);
       
   376     
       
   377     TBuf<50> KSQLStatement;
       
   378     // Declare a literal string to hold the SQL statement
       
   379     // DROP TABLE KLexiconName
       
   380     _LIT(KSQLDelete1, "DROP TABLE ");
       
   381     
       
   382     KSQLStatement = KSQLDelete1;
       
   383     KSQLStatement.Append(KLexiconName);
       
   384     
       
   385     User::LeaveIfError(iDb.Execute(KSQLStatement));
       
   386     
       
   387     // Release the Lexicon ID
       
   388     ReleaseIdL(KLexiconIdTable, KLexiconIdColumn, aLexiconID);
       
   389     
       
   390     // Cancel free disk space request
       
   391     //iDbSession.FreeReservedSpace( iDrive );
       
   392     
       
   393     }
       
   394 
       
   395 // -----------------------------------------------------------------------------
       
   396 // CSILexiconDB::PronunciationCountL
       
   397 // Returns the number of Pronunciations in the specified Lexicon.
       
   398 // -----------------------------------------------------------------------------
       
   399 TInt CSILexiconDB::PronunciationCountL( TSILexiconID aLexiconID )
       
   400     {
       
   401     
       
   402     CSILexicon* newLexicon = LexiconL( aLexiconID) ;	
       
   403     CleanupStack::PushL(newLexicon);
       
   404     
       
   405     TInt PronunciationCount=newLexicon->Count();	 
       
   406     CleanupStack::PopAndDestroy(newLexicon); 	
       
   407     return PronunciationCount;
       
   408 
       
   409     }
       
   410 
       
   411 // -----------------------------------------------------------------------------
       
   412 // CSILexiconDB::IsPronunciationValidL
       
   413 // Checks if the specified pronunciation exists in the specified loaded	.
       
   414 // 
       
   415 // -----------------------------------------------------------------------------
       
   416 //
       
   417 TBool CSILexiconDB::IsPronunciationValidL( TSILexiconID aLexiconID,
       
   418                                            TSIPronunciationID aPronunciationID )
       
   419     {
       
   420     CSILexicon* newLexicon = LexiconL( aLexiconID) ;		 
       
   421     CleanupStack::PushL(newLexicon);
       
   422     
       
   423     if (newLexicon->Find(aPronunciationID)==KErrNotFound) {
       
   424         CleanupStack::PopAndDestroy(newLexicon); // newLexicon
       
   425         return EFalse; 
       
   426         }
       
   427     else {
       
   428         CleanupStack::PopAndDestroy(newLexicon); // newLexicon
       
   429         return ETrue;	
       
   430         }
       
   431     }
       
   432 
       
   433 
       
   434 // -----------------------------------------------------------------------------
       
   435 // CSILexiconDB::ResetAndDestroy
       
   436 // Deallocates the temporary memory containing the Lexicon object created with
       
   437 // AllPronunciationsL.
       
   438 // -----------------------------------------------------------------------------
       
   439 //
       
   440 void CSILexiconDB::ResetAndDestroy()
       
   441     {
       
   442     //	iLexiconArray.ResetAndDestroy();
       
   443     }
       
   444 
       
   445 // -----------------------------------------------------------------------------
       
   446 // CSILexiconDB::RemovePronunciationL
       
   447 // Deletes Pronunciation from the database.
       
   448 // -----------------------------------------------------------------------------
       
   449 //
       
   450 void CSILexiconDB::RemovePronunciationL(  TUid aClientUid, 
       
   451                                         TSILexiconID aLexiconID,
       
   452                                         TSIPronunciationID aPronunciationID
       
   453                                         )
       
   454     {
       
   455     // Check the ownership first
       
   456     VerifyOwnershipL(aClientUid, KLexiconIdTable, KLexiconIndex, aLexiconID);
       
   457     
       
   458     CSILexicon* newLexicon = LexiconL( aLexiconID);		 
       
   459     CleanupStack::PushL(newLexicon);
       
   460     
       
   461     if (newLexicon->Find(aPronunciationID)==KErrNotFound)
       
   462         User::Leave(KErrNotFound);				 
       
   463     else  
       
   464         newLexicon->DeleteL(aPronunciationID);
       
   465     UpdateLexiconL(aClientUid  , newLexicon);
       
   466     CleanupStack::PopAndDestroy(newLexicon); // newLexicon
       
   467     }
       
   468 
       
   469 // -----------------------------------------------------------------------------
       
   470 // CSILexiconDB::AddPronunciationL
       
   471 // Add Pronunciation to the database.
       
   472 // -----------------------------------------------------------------------------
       
   473 //
       
   474 TSIPronunciationID CSILexiconDB::AddPronunciationL( TUid aClientUid, 
       
   475                                                    TSILexiconID aLexiconID,
       
   476                                                    TDesC8& aPronunciationPr,
       
   477                                                    TSIModelBankID aModelBankID)
       
   478     {
       
   479     // Check the ownership first
       
   480     VerifyOwnershipL( aClientUid, KLexiconIdTable, KLexiconIndex, aLexiconID );
       
   481     
       
   482     CSILexicon* aLexicon = LexiconL( aLexiconID );
       
   483     CleanupStack::PushL( aLexicon );
       
   484     
       
   485     // existing myPronunciationID
       
   486     RArray<TSIPronunciationID> myPronunciationID;
       
   487     myPronunciationID.Reset();
       
   488     for( TInt i = 0; i < aLexicon->Count(); i++ )
       
   489         {
       
   490         CSIPronunciation* aPronunciation = &( aLexicon->AtL( i ) );
       
   491         myPronunciationID.Append( aPronunciation->PronunciationID() );
       
   492         }
       
   493     
       
   494     // Find a uniq new id 
       
   495     TSIPronunciationID aPronunciationID = GetNewID( myPronunciationID );
       
   496     myPronunciationID.Close();
       
   497     
       
   498     // add the  phoneme sequence  to the Pronunciation
       
   499     CSIPronunciation* pronunciation = CSIPronunciation::NewL( aPronunciationID, aModelBankID );
       
   500     CleanupStack::PushL( pronunciation );	
       
   501     pronunciation->SetPhonemeSequenceL( aPronunciationPr );
       
   502     aLexicon->AddL( pronunciation );
       
   503     CleanupStack::Pop( pronunciation ); // aPronunciation
       
   504     UpdateLexiconL( aClientUid,aLexicon );
       
   505     CleanupStack::PopAndDestroy( aLexicon ); // aLexicon
       
   506     return aPronunciationID;
       
   507     }
       
   508 
       
   509 // -----------------------------------------------------------------------------
       
   510 // CSILexiconDB::LexiconL
       
   511 // Loads all pronunciations within the specified lexicon into a lexicon object
       
   512 // -----------------------------------------------------------------------------
       
   513 //
       
   514 CSILexicon* CSILexiconDB::LexiconL( TSILexiconID aLexiconID )
       
   515     {
       
   516     
       
   517     // Construct the table name using the provided grammar ID
       
   518     // Construct the table name using the provided grammar ID
       
   519     // Declare a literal string to hold the SQL statement
       
   520     // SELECT KBinaryLexiconColumn , KBinaryLexiconColumn FROM  KLexiconName
       
   521     TBuf<40> KLexiconName(KSILexiconTable);
       
   522     KLexiconName.AppendNumUC(aLexiconID);
       
   523     // Create newLexicon object	
       
   524     CSILexicon* lexicon = CSILexicon::NewLC( aLexiconID );	
       
   525     _LIT(KSQLSelect1,"select  ");	
       
   526     _LIT(KSQLSelect2," from  ");
       
   527     TBuf<120> KSQLStatement;		
       
   528     KSQLStatement.Append(KSQLSelect1  );		
       
   529     KSQLStatement.Append(KBinaryLexiconColumn );
       
   530     KSQLStatement.Append(KNext);
       
   531     KSQLStatement.Append(KBinaryLexiconColumnSize );
       
   532     KSQLStatement.Append(KSQLSelect2  );
       
   533     KSQLStatement.Append(KLexiconName); 
       
   534     
       
   535     // create a view on the database
       
   536     RDbView view;
       
   537     CleanupClosePushL( view );
       
   538     
       
   539     User::LeaveIfError(view.Prepare(iDb,TDbQuery(KSQLStatement,EDbCompareNormal)));
       
   540     User::LeaveIfError(view.EvaluateAll());
       
   541     
       
   542     // Get the structure of the rowset 
       
   543     CDbColSet* colSet = view.ColSetL();
       
   544     CleanupStack::PushL( colSet );
       
   545     
       
   546     // iterate across the row set, one row only
       
   547     for (view.FirstL();view.AtRow();view.NextL())
       
   548         {
       
   549         
       
   550         // retrieve the row
       
   551         view.GetL();
       
   552         
       
   553         // first retrieve the size of binary package 
       
   554         TDbColNo col = colSet->ColNo(KBinaryLexiconColumnSize); // Ordinal position of long column 
       
   555         TInt32 size = view.ColUint32( col);
       
   556         
       
   557         TUint8* buf = new (ELeave) TUint8[size];		
       
   558         CleanupStack::PushL( buf);			
       
   559         TPtr8 readBuf( buf, size, size);
       
   560         CBufFlat* dataCopyBuffer = CBufFlat::NewL( 100 ); // 100 = expand 100 bytes
       
   561         CleanupStack::PushL( dataCopyBuffer );              // when the buffer is full
       
   562         
       
   563         RBufReadStream stream;
       
   564         CleanupClosePushL( stream );
       
   565         stream.Open(*dataCopyBuffer);
       
   566         
       
   567         // and a stream for long columns
       
   568         RDbColReadStream in;
       
   569         CleanupClosePushL( in );
       
   570         col = colSet->ColNo(KBinaryLexiconColumn); // Ordinal position of long column 
       
   571         
       
   572         
       
   573         in.OpenLC(view, col);
       
   574         in.ReadL(readBuf, view.ColLength(col));
       
   575         dataCopyBuffer->InsertL(0,readBuf);
       
   576         lexicon->InternalizeL( stream );
       
   577         
       
   578         CleanupStack::PopAndDestroy( col );
       
   579         CleanupStack::PopAndDestroy( &in );
       
   580         CleanupStack::PopAndDestroy( &stream ); 
       
   581         CleanupStack::PopAndDestroy( dataCopyBuffer );
       
   582         CleanupStack::PopAndDestroy( buf );
       
   583         }
       
   584     
       
   585     CleanupStack::PopAndDestroy( colSet );
       
   586     CleanupStack::PopAndDestroy( &view );
       
   587     
       
   588 
       
   589  
       
   590     // Cleanup lexicon
       
   591     CleanupStack::Pop( lexicon );
       
   592     return lexicon;
       
   593     }
       
   594 
       
   595 //  End of File