|
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 |