|
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 * grammars. It is also responsible for allocating memory when |
|
16 * loading grammars into the recognizer. |
|
17 * |
|
18 */ |
|
19 |
|
20 |
|
21 // INCLUDE FILES |
|
22 #include "sigrammardb.h" |
|
23 #include "rubydebug.h" |
|
24 |
|
25 // ============================ MEMBER FUNCTIONS =============================== |
|
26 |
|
27 // ----------------------------------------------------------------------------- |
|
28 // CSIGrammarDB::CSIGrammarDB |
|
29 // C++ default constructor can NOT contain any code, that |
|
30 // might leave. |
|
31 // ----------------------------------------------------------------------------- |
|
32 // |
|
33 CSIGrammarDB::CSIGrammarDB( RDbNamedDatabase& aDatabase, |
|
34 RDbs& aDbSession, |
|
35 TInt aDrive ) |
|
36 : CSICommonDB(aDatabase, aDbSession, aDrive ) |
|
37 { |
|
38 // Nothing |
|
39 } |
|
40 |
|
41 // ----------------------------------------------------------------------------- |
|
42 // CSIGrammarDB::ConstructL |
|
43 // Symbian 2nd phase constructor can leave. |
|
44 // ----------------------------------------------------------------------------- |
|
45 // |
|
46 void CSIGrammarDB::ConstructL() |
|
47 { |
|
48 // Nothing |
|
49 } |
|
50 |
|
51 // ----------------------------------------------------------------------------- |
|
52 // CSIGrammarDB::NewL |
|
53 // Two-phased constructor. |
|
54 // ----------------------------------------------------------------------------- |
|
55 // |
|
56 CSIGrammarDB* CSIGrammarDB::NewL( RDbNamedDatabase& aDatabase, |
|
57 RDbs& aDbSession, |
|
58 TInt aDrive ) |
|
59 { |
|
60 RUBY_DEBUG_BLOCK( "CSIGrammarDB::NewL" ); |
|
61 |
|
62 CSIGrammarDB* self |
|
63 = new( ELeave ) CSIGrammarDB( aDatabase, aDbSession, aDrive ); |
|
64 CleanupStack::PushL( self ); |
|
65 self->ConstructL(); |
|
66 CleanupStack::Pop( self ); |
|
67 return self; |
|
68 } |
|
69 |
|
70 // ----------------------------------------------------------------------------- |
|
71 // CSIGrammarDB::~CSIGrammarDB |
|
72 // Destructor |
|
73 // ----------------------------------------------------------------------------- |
|
74 // |
|
75 CSIGrammarDB::~CSIGrammarDB() |
|
76 { |
|
77 RUBY_DEBUG0( "CSIGrammarDB::~CSIGrammarDB" ); |
|
78 // Delete all elements of the array before deleting the array |
|
79 iGrammarArray.ResetAndDestroy(); |
|
80 iGrammarArray.Close(); |
|
81 } |
|
82 |
|
83 // ----------------------------------------------------------------------------- |
|
84 // CSIGrammarDB::CreateGrammarL |
|
85 // Creates a new grammar in the database. |
|
86 // ----------------------------------------------------------------------------- |
|
87 // |
|
88 TSIGrammarID CSIGrammarDB::CreateGrammarL( TUid aClientUid ) |
|
89 { |
|
90 RUBY_DEBUG_BLOCK( "CSIGrammarDB::CreateGrammarL" ); |
|
91 |
|
92 User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, sizeof( CSIGrammar ) ) ); |
|
93 |
|
94 TSIGrammarID grammarID = STATIC_CAST(TSIGrammarID,CreateNewIDL(KGrammarIdTable, KGrammarIdColumn, aClientUid)); |
|
95 // Construct the table name using the new grammar ID |
|
96 TBuf<40> KGrammarName( KSIGrammarTable ); |
|
97 KGrammarName.AppendNumUC( grammarID ); |
|
98 RUBY_DEBUG1( "CSIGrammarDB::CreateGrammarL grammar ID: %i", grammarID ); |
|
99 |
|
100 // Create a table definition |
|
101 CDbColSet* columns = CDbColSet::NewLC(); |
|
102 |
|
103 // add the columns |
|
104 // 1) Binary data, 2) binary data size |
|
105 columns->AddL( TDbCol( KBinaryGrammarColumn, EDbColLongBinary ) ); |
|
106 columns->AddL( TDbCol( KBinaryGrammarColumnSize, EDbColUint32 ) ); |
|
107 |
|
108 // Create a table |
|
109 TInt err =iDb.CreateTable( KGrammarName, *columns ); |
|
110 |
|
111 if ( err != KErrNone ) |
|
112 { |
|
113 // Failed to create the table. |
|
114 // Need to release the new grammar ID and leave. |
|
115 ReleaseIdL( KGrammarIdTable, KGrammarIdColumn, grammarID ); |
|
116 User::Leave( err ); |
|
117 } |
|
118 |
|
119 // Cleanup the column set |
|
120 CleanupStack::PopAndDestroy( columns ); |
|
121 |
|
122 // Construct the table name using the provided grammar ID |
|
123 // Declare a literal string to hold the SQL statement |
|
124 // SELECT KBinaryGrammarColumn , KBinaryGrammarColumn FROM KGrammarName |
|
125 _LIT(KSQLSelect1,"select "); |
|
126 _LIT(KSQLSelect2," from "); |
|
127 TBuf<120> KSQLStatement; |
|
128 KSQLStatement.Append(KSQLSelect1 ); |
|
129 KSQLStatement.Append(KBinaryGrammarColumn ); |
|
130 KSQLStatement.Append(KNext); |
|
131 KSQLStatement.Append(KBinaryGrammarColumnSize ); |
|
132 KSQLStatement.Append(KSQLSelect2 ); |
|
133 KSQLStatement.Append(KGrammarName); |
|
134 |
|
135 // Create a view on the database |
|
136 RDbView view; |
|
137 User::LeaveIfError(view.Prepare(iDb,TDbQuery(KSQLStatement,EDbCompareNormal))); |
|
138 User::LeaveIfError(view.EvaluateAll()); |
|
139 |
|
140 // Get the structure of rowset |
|
141 CDbColSet* colSet = view.ColSetL(); |
|
142 // Insert a row |
|
143 view.InsertL(); |
|
144 view.PutL(); |
|
145 // Close the view |
|
146 view.Close(); |
|
147 delete colSet; |
|
148 |
|
149 // Put a empty grammar into the database |
|
150 CSICompiledGrammar *aSICompiledGrammar=CSICompiledGrammar::NewL(grammarID); |
|
151 CleanupStack::PushL(aSICompiledGrammar); |
|
152 UpdateGrammarL(aClientUid,aSICompiledGrammar); |
|
153 CleanupStack::PopAndDestroy(aSICompiledGrammar); |
|
154 |
|
155 iDbSession.FreeReservedSpace( iDrive ); |
|
156 |
|
157 return grammarID; |
|
158 } |
|
159 |
|
160 // ----------------------------------------------------------------------------- |
|
161 // CSIGrammarDB::UpdateGrammarL |
|
162 // Inserts the externalized SI compiled grammar into the specified grammar table. |
|
163 // Save the grammar into the database |
|
164 // ----------------------------------------------------------------------------- |
|
165 // |
|
166 void CSIGrammarDB::UpdateGrammarL( TUid aClientUid, |
|
167 CSICompiledGrammar *aSICompiledGrammar ) |
|
168 { |
|
169 RUBY_DEBUG_BLOCK( "CSIGrammarDB::UpdateGrammarL" ); |
|
170 |
|
171 // verify ownership |
|
172 TSIGrammarID aGrammarID=aSICompiledGrammar->GrammarID(); |
|
173 VerifyOwnershipL(aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID); |
|
174 |
|
175 // Construct the table name using the provided grammar ID |
|
176 // Declare a literal string to hold the SQL statement |
|
177 // SELECT KBinaryGrammarColumn , KBinaryGrammarColumn FROM KGrammarName |
|
178 TBuf<40> KGrammarName(KSIGrammarTable); |
|
179 KGrammarName.AppendNumUC(aGrammarID); |
|
180 _LIT(KSQLSelect1,"select "); |
|
181 _LIT(KSQLSelect2," from "); |
|
182 TBuf<120> KSQLStatement; |
|
183 KSQLStatement.Append(KSQLSelect1 ); |
|
184 KSQLStatement.Append(KBinaryGrammarColumn ); |
|
185 KSQLStatement.Append(KNext); |
|
186 KSQLStatement.Append(KBinaryGrammarColumnSize ); |
|
187 KSQLStatement.Append(KSQLSelect2 ); |
|
188 KSQLStatement.Append(KGrammarName); |
|
189 |
|
190 // Create a view on the database |
|
191 RDbView view; |
|
192 User::LeaveIfError( view.Prepare( iDb, TDbQuery( KSQLStatement,EDbCompareNormal ) ) ); |
|
193 User::LeaveIfError( view.EvaluateAll() ); |
|
194 CleanupClosePushL( view ); |
|
195 |
|
196 // Get the structure of rowset |
|
197 CDbColSet* colSet = view.ColSetL(); |
|
198 CleanupStack::PushL( colSet ); |
|
199 view.FirstL(); |
|
200 view.UpdateL(); |
|
201 |
|
202 // Externalize a compiled grammar |
|
203 CBufFlat* dataCopyBuffer = CBufFlat::NewL( 100 ); // 100 = expand 100 bytes |
|
204 CleanupStack::PushL( dataCopyBuffer ); // when the buffer is full |
|
205 RBufWriteStream stream; |
|
206 stream.Open( *dataCopyBuffer ); |
|
207 CleanupClosePushL( stream ); |
|
208 aSICompiledGrammar->ExternalizeL( stream ); |
|
209 CleanupStack::PopAndDestroy( &stream ); |
|
210 |
|
211 TPtr8 aWriteBuf( dataCopyBuffer->Ptr( 0 ) ); |
|
212 TInt BufSize = aWriteBuf.Size(); |
|
213 |
|
214 // add binary buffer by Using the stream |
|
215 RDbColWriteStream out; |
|
216 TDbColNo col = colSet->ColNo( KBinaryGrammarColumn ); // Ordinal position of long column |
|
217 out.OpenLC( view, col ); |
|
218 out.WriteL( aWriteBuf ); |
|
219 out.Close(); |
|
220 CleanupStack::PopAndDestroy(); // out |
|
221 |
|
222 // add size of the buffer |
|
223 col = colSet->ColNo( KBinaryGrammarColumnSize ); // Ordinal position of size |
|
224 view.SetColL( col, BufSize ); |
|
225 view.PutL(); |
|
226 |
|
227 CleanupStack::PopAndDestroy( dataCopyBuffer ); |
|
228 CleanupStack::PopAndDestroy( colSet ); |
|
229 |
|
230 // close the view |
|
231 CleanupStack::PopAndDestroy( &view ); // Close view |
|
232 } |
|
233 |
|
234 |
|
235 // ----------------------------------------------------------------------------- |
|
236 // CSIGrammarDB::FindGrammarL |
|
237 // Find a grammar from loaded grammar array |
|
238 // ----------------------------------------------------------------------------- |
|
239 CSICompiledGrammar* CSIGrammarDB::FindGrammarL(TSIGrammarID aGrammarID) |
|
240 { |
|
241 RUBY_DEBUG_BLOCK( "CSIGrammarDB::FindGrammarL" ); |
|
242 |
|
243 TInt i(0); |
|
244 CSICompiledGrammar* aGrammar=NULL; |
|
245 |
|
246 // Check if grammar already loaded |
|
247 for ( i = 0; i < iGrammarArray.Count(); i++ ) |
|
248 { |
|
249 if ( iGrammarArray[i]->GrammarID()==aGrammarID ) |
|
250 { |
|
251 aGrammar=iGrammarArray[i]; |
|
252 break; |
|
253 } |
|
254 } |
|
255 // Can not found in the loaded grammar array |
|
256 if(i==iGrammarArray.Count()) |
|
257 User::Leave(KErrNotFound); |
|
258 |
|
259 return aGrammar; |
|
260 } |
|
261 |
|
262 // ----------------------------------------------------------------------------- |
|
263 // CSIGrammarDB::GetNewID |
|
264 // Get a new uniq ID |
|
265 // ----------------------------------------------------------------------------- |
|
266 TInt CSIGrammarDB::GetNewID( RArray<TSIRuleID>& aMyIds ) |
|
267 { |
|
268 RArray<TSIRuleID> myIDs = aMyIds; |
|
269 TInt Count = myIDs.Count(); |
|
270 TInt id = 0; |
|
271 if ( Count == 0 ) |
|
272 { |
|
273 id = 1; // empty ,first id will be 1 |
|
274 } |
|
275 else |
|
276 { |
|
277 // Find a unique ID |
|
278 myIDs.SortUnsigned(); |
|
279 id = myIDs[myIDs.Count() - 1] + 1; //by default , the last one |
|
280 for ( TInt i = 0; i < myIDs.Count(); i++ ) |
|
281 { |
|
282 TInt index = i + 1; |
|
283 TInt s = myIDs[i]; |
|
284 if ( s > index ) |
|
285 { |
|
286 id = index; |
|
287 break; |
|
288 } |
|
289 } |
|
290 } |
|
291 return id; |
|
292 } |
|
293 |
|
294 // ----------------------------------------------------------------------------- |
|
295 // CSIGrammarDB::CreateRuleL |
|
296 // Creates a new empty rule. |
|
297 // ----------------------------------------------------------------------------- |
|
298 void CSIGrammarDB::CreateRuleL( TUid aClientUid, TSIGrammarID aGrammarID, |
|
299 TSIRuleID& aRuleID ) |
|
300 { |
|
301 RUBY_DEBUG_BLOCK( "CSIGrammarDB::CreateRuleL" ); |
|
302 |
|
303 //__UHEAP_MARK; |
|
304 VerifyOwnershipL( aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID ); |
|
305 // find the grammar from the database |
|
306 CSICompiledGrammar* aGrammar = (CSICompiledGrammar*) GrammarL( aGrammarID ); |
|
307 CleanupStack::PushL( aGrammar ); |
|
308 |
|
309 TInt aID = 0; |
|
310 TInt Count=aGrammar->Count(); |
|
311 |
|
312 // existing myRuleVariantID |
|
313 RArray<TSIRuleID> myIDs; |
|
314 myIDs.Reset(); |
|
315 for(TInt i = 0; i < Count; i++ ) |
|
316 { |
|
317 CSIRule* aRule = &( aGrammar->AtL( i ) ); |
|
318 myIDs.Append( aRule->RuleID() ); |
|
319 } |
|
320 |
|
321 // Find a uniq new id |
|
322 aID=GetNewID( myIDs ); |
|
323 myIDs.Close(); |
|
324 aRuleID=aID; |
|
325 |
|
326 // add the rule to the grammar |
|
327 CSIRule* rule = CSIRule::NewL( aRuleID ); |
|
328 CleanupStack::PushL( rule ); |
|
329 aGrammar->AddL( rule ); |
|
330 CleanupStack::Pop( rule ); |
|
331 |
|
332 UpdateGrammarL( aClientUid, aGrammar ); |
|
333 CleanupStack::PopAndDestroy( aGrammar ); |
|
334 //__UHEAP_MARKEND; |
|
335 } |
|
336 |
|
337 // ----------------------------------------------------------------------------- |
|
338 // CSIGrammarDB::AddRuleVariantL |
|
339 // Add Rule Variant to the array that hold the grammar array |
|
340 // ----------------------------------------------------------------------------- |
|
341 void CSIGrammarDB::AddRuleVariantL(TUid aClientUid, |
|
342 TSIGrammarID aGrammarID, |
|
343 TSILexiconID aLexiconID, |
|
344 const RArray<TSIPronunciationID>& aPronunciationIDs, |
|
345 TSIRuleID aRuleID, |
|
346 TSIRuleVariantID& aRuleVariantID) |
|
347 { |
|
348 VerifyOwnershipL(aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID); |
|
349 |
|
350 CSICompiledGrammar* aGrammar=(CSICompiledGrammar*)GrammarL(aGrammarID); |
|
351 CleanupStack::PushL(aGrammar); |
|
352 |
|
353 CSIRule* aRule=&(aGrammar->RuleL(aRuleID)); |
|
354 // existing myRuleVariantID |
|
355 RArray<TSIRuleID> myID; |
|
356 myID.Reset(); |
|
357 for( TInt i = 0; i < aRule->Count(); i++ ) |
|
358 { |
|
359 CSIRuleVariant* aRuleVariant=&(aRule->AtL(i)); |
|
360 myID.Append(aRuleVariant->RuleVariantID()); |
|
361 } |
|
362 |
|
363 // Find a uniq new id |
|
364 aRuleVariantID=STATIC_CAST(TSIRuleVariantID,GetNewID(myID)); |
|
365 myID.Close(); |
|
366 |
|
367 // add the rule variant to the rule |
|
368 CSIRuleVariant* ruleVariant = CSIRuleVariant::NewL( aRuleVariantID, aLexiconID ); |
|
369 CleanupStack::PushL( ruleVariant ); |
|
370 ruleVariant->SetPronunciationIDsL(aPronunciationIDs); |
|
371 aRule->AddL( ruleVariant ); |
|
372 CleanupStack::Pop( ruleVariant ); |
|
373 UpdateGrammarL( aClientUid, aGrammar ); |
|
374 CleanupStack::PopAndDestroy( aGrammar ); |
|
375 } |
|
376 |
|
377 // ----------------------------------------------------------------------------- |
|
378 // CSIGrammarDB::LoadGrammarL |
|
379 // Loads all rules within the specified grammar into a grammar object, which |
|
380 // is loaded into recognizer during recognition session. |
|
381 // Note : Will leave if already loaded |
|
382 // ----------------------------------------------------------------------------- |
|
383 // |
|
384 const CSICompiledGrammar* CSIGrammarDB::LoadGrammarL( TSIGrammarID aGrammarID ) |
|
385 { |
|
386 // Construct the table name using the provided grammar ID |
|
387 // Construct the table name using the provided grammar ID |
|
388 // Declare a literal string to hold the SQL statement |
|
389 // SELECT KBinaryGrammarColumn , KBinaryGrammarColumn FROM KGrammarName |
|
390 TBuf<40> KGrammarName(KSIGrammarTable); |
|
391 KGrammarName.AppendNumUC(aGrammarID); |
|
392 |
|
393 // Create newGrammar object |
|
394 CSICompiledGrammar* grammar = CSICompiledGrammar::NewLC( aGrammarID ); |
|
395 _LIT(KSQLSelect1,"select "); |
|
396 _LIT(KSQLSelect2," from "); |
|
397 TBuf<120> KSQLStatement; |
|
398 KSQLStatement.Append(KSQLSelect1 ); |
|
399 KSQLStatement.Append(KBinaryGrammarColumn ); |
|
400 KSQLStatement.Append(KNext); |
|
401 KSQLStatement.Append(KBinaryGrammarColumnSize ); |
|
402 KSQLStatement.Append(KSQLSelect2 ); |
|
403 KSQLStatement.Append(KGrammarName); |
|
404 |
|
405 // create a view on the database |
|
406 RDbView view; |
|
407 CleanupClosePushL( view ); |
|
408 |
|
409 User::LeaveIfError(view.Prepare(iDb,TDbQuery(KSQLStatement,EDbCompareNormal))); |
|
410 User::LeaveIfError(view.EvaluateAll()); |
|
411 |
|
412 // Get the structure of the rowset |
|
413 CDbColSet* colSet = view.ColSetL(); |
|
414 CleanupStack::PushL( colSet ); |
|
415 |
|
416 // iterate across the row set, one row only |
|
417 for (view.FirstL();view.AtRow();view.NextL()) |
|
418 { |
|
419 |
|
420 // retrieve the row |
|
421 view.GetL(); |
|
422 |
|
423 // first retrieve the size of binary package |
|
424 TDbColNo col = colSet->ColNo(KBinaryGrammarColumnSize); // Ordinal position of long column |
|
425 TInt32 size = view.ColUint32( col); |
|
426 |
|
427 TUint8* buf = new (ELeave) TUint8[size]; |
|
428 CleanupStack::PushL( buf); |
|
429 TPtr8 readBuf( buf, size, size); |
|
430 CBufFlat* dataCopyBuffer = CBufFlat::NewL( 100 ); // 100 = expand 100 bytes |
|
431 CleanupStack::PushL(dataCopyBuffer); // when the buffer is full |
|
432 |
|
433 RBufReadStream stream; |
|
434 CleanupClosePushL( stream ); |
|
435 stream.Open(*dataCopyBuffer); |
|
436 |
|
437 // and a stream for long columns |
|
438 RDbColReadStream in; |
|
439 CleanupClosePushL( in ); |
|
440 col = colSet->ColNo(KBinaryGrammarColumn); // Ordinal position of long column |
|
441 |
|
442 |
|
443 in.OpenLC(view, col); |
|
444 in.ReadL( readBuf, view.ColLength(col)); |
|
445 dataCopyBuffer->InsertL(0,readBuf); |
|
446 grammar->InternalizeL( stream ); |
|
447 |
|
448 CleanupStack::PopAndDestroy( col ); |
|
449 CleanupStack::PopAndDestroy( &in ); |
|
450 CleanupStack::PopAndDestroy( &stream ); |
|
451 CleanupStack::PopAndDestroy( dataCopyBuffer ); |
|
452 CleanupStack::PopAndDestroy( buf ); |
|
453 } |
|
454 |
|
455 CleanupStack::PopAndDestroy( colSet ); |
|
456 CleanupStack::PopAndDestroy( &view ); |
|
457 |
|
458 // Keep the reference of the grammar object |
|
459 User::LeaveIfError(iGrammarArray.Append(grammar)); |
|
460 // Cleanup grammar |
|
461 CleanupStack::Pop(grammar ); |
|
462 return grammar; |
|
463 } |
|
464 |
|
465 // ----------------------------------------------------------------------------- |
|
466 // CSIGrammarDB::GrammarL |
|
467 // Loads all rules within the specified grammar into a grammar object, which |
|
468 // is loaded into recognizer during recognition session. |
|
469 // Note : Will leave if already loaded |
|
470 // ----------------------------------------------------------------------------- |
|
471 // |
|
472 const CSICompiledGrammar* CSIGrammarDB::GrammarL( TSIGrammarID aGrammarID ) |
|
473 { |
|
474 |
|
475 // Construct the table name using the provided grammar ID |
|
476 // Construct the table name using the provided grammar ID |
|
477 // Declare a literal string to hold the SQL statement |
|
478 // SELECT KBinaryGrammarColumn , KBinaryGrammarColumn FROM KGrammarName |
|
479 TBuf<40> KGrammarName(KSIGrammarTable); |
|
480 KGrammarName.AppendNumUC(aGrammarID); |
|
481 // Create newGrammar object |
|
482 CSICompiledGrammar* aGrammar = CSICompiledGrammar::NewLC( aGrammarID ); |
|
483 _LIT(KSQLSelect1,"select "); |
|
484 _LIT(KSQLSelect2," from "); |
|
485 |
|
486 TBuf<120> KSQLStatement; |
|
487 KSQLStatement.Append(KSQLSelect1 ); |
|
488 KSQLStatement.Append(KBinaryGrammarColumn ); |
|
489 KSQLStatement.Append(KNext); |
|
490 KSQLStatement.Append(KBinaryGrammarColumnSize ); |
|
491 KSQLStatement.Append(KSQLSelect2 ); |
|
492 KSQLStatement.Append(KGrammarName); |
|
493 |
|
494 // create a view on the database |
|
495 RDbView view; |
|
496 User::LeaveIfError(view.Prepare(iDb,TDbQuery(KSQLStatement,EDbCompareNormal))); |
|
497 |
|
498 User::LeaveIfError(view.EvaluateAll()); |
|
499 |
|
500 // Get the structure of the rowset |
|
501 CDbColSet* colSet = view.ColSetL(); |
|
502 |
|
503 // iterate across the row set, one row only |
|
504 for (view.FirstL();view.AtRow();view.NextL()) |
|
505 { |
|
506 |
|
507 // retrieve the row |
|
508 view.GetL(); |
|
509 |
|
510 // first retrieve the size of binary package |
|
511 TDbColNo col = colSet->ColNo(KBinaryGrammarColumnSize); // Ordinal position of long column |
|
512 TInt32 Size = view.ColUint32( col); |
|
513 |
|
514 TUint8* aBuf = new (ELeave) TUint8[Size]; |
|
515 CleanupStack::PushL(aBuf); |
|
516 TPtr8 aReadBuf(aBuf, Size, Size); |
|
517 CBufFlat* dataCopyBuffer = CBufFlat::NewL( 100 ); // 100 = expand 100 bytes |
|
518 CleanupStack::PushL(dataCopyBuffer); // when the buffer is full |
|
519 |
|
520 RBufReadStream stream; |
|
521 stream.Open(*dataCopyBuffer); |
|
522 |
|
523 // and a stream for long columns |
|
524 RDbColReadStream in; |
|
525 col = colSet->ColNo(KBinaryGrammarColumn); // Ordinal position of long column |
|
526 |
|
527 |
|
528 in.OpenLC(view, col); |
|
529 in.ReadL(aReadBuf, view.ColLength(col)); |
|
530 dataCopyBuffer->InsertL(0,aReadBuf); |
|
531 aGrammar->InternalizeL( stream ); |
|
532 |
|
533 in.Close(); |
|
534 CleanupStack::PopAndDestroy(3); // in dataCopyBuffer aBuf |
|
535 } |
|
536 //! clean the memory |
|
537 delete colSet; |
|
538 view.Close(); |
|
539 |
|
540 // Keep the reference of the grammar object |
|
541 // Cleanup grammar |
|
542 CleanupStack::Pop( aGrammar ); |
|
543 |
|
544 return aGrammar; |
|
545 } |
|
546 |
|
547 // ----------------------------------------------------------------------------- |
|
548 // CSIGrammarDB::CreateIDTableL |
|
549 // Creates a new grammar ID table in the database. |
|
550 // ----------------------------------------------------------------------------- |
|
551 // |
|
552 void CSIGrammarDB::CreateIDTableL() |
|
553 { |
|
554 // Invoke function in the base class CSICommonDB. |
|
555 CSICommonDB::CreateIDTableL(KGrammarIdTable, KGrammarIdColumn, KGrammarIndex); |
|
556 } |
|
557 |
|
558 // ----------------------------------------------------------------------------- |
|
559 // CSIGrammarDB::GetAllClientGrammarIDsL |
|
560 // This function returns all grammar IDs owned by the specified client. |
|
561 // ----------------------------------------------------------------------------- |
|
562 // |
|
563 void CSIGrammarDB::GetAllClientGrammarIDsL( TUid aClientUid, |
|
564 RArray<TSIGrammarID>& aGrammarIDs ) |
|
565 { |
|
566 RArray<TUint32> ix; |
|
567 ix.Reset(); |
|
568 GetAllClientIDsL(KGrammarIdTable, KGrammarIdColumn, aClientUid, ix); |
|
569 for(TInt i=0;i<ix.Count();i++) { |
|
570 aGrammarIDs.Append(STATIC_CAST(TSIGrammarID,ix[i])); |
|
571 } |
|
572 ix.Close(); |
|
573 } |
|
574 |
|
575 // ----------------------------------------------------------------------------- |
|
576 // CSIGrammarDB::GetAllGrammarIDsL |
|
577 // This function returns all grammar IDs in the database. |
|
578 // ----------------------------------------------------------------------------- |
|
579 // |
|
580 void CSIGrammarDB::GetAllGrammarIDsL( RArray<TSIGrammarID>& aGrammarIDs ) |
|
581 { |
|
582 // This is a hack to get the id aligned to 4-byte boundary, |
|
583 // for some reason this does not happen in winscw build if |
|
584 // TSIGrammarID is taken from stack. |
|
585 TSIGrammarID* id = new (ELeave) TSIGrammarID; |
|
586 |
|
587 CleanupStack::PushL( id ); |
|
588 |
|
589 RArray<TUint32> ix; |
|
590 //! Reset |
|
591 ix.Reset(); |
|
592 GetAllIDsL(KGrammarIdTable, KGrammarIdColumn, ix); |
|
593 for(TInt i=0;i<ix.Count();i++) |
|
594 { |
|
595 *id = STATIC_CAST( TSIGrammarID, ix[i] ); |
|
596 aGrammarIDs.Append( *id ); |
|
597 } |
|
598 ix.Close(); |
|
599 CleanupStack::PopAndDestroy( id ); |
|
600 } |
|
601 |
|
602 // ----------------------------------------------------------------------------- |
|
603 // CSIGrammarDB::GetAllRuleIDsL |
|
604 // This function returns all rule IDs within the specified grammar. |
|
605 // grammar have to be loaded |
|
606 // ----------------------------------------------------------------------------- |
|
607 // |
|
608 void CSIGrammarDB::GetAllRuleIDsL( TSIGrammarID aGrammarID, |
|
609 RArray<TSIRuleID>& aRuleIDs ) |
|
610 { |
|
611 // Construct the table name using the provided grammar ID |
|
612 TBuf<40> KGrammarName(KSIGrammarTable); |
|
613 KGrammarName.AppendNumUC(aGrammarID); |
|
614 |
|
615 CSICompiledGrammar* newgrammar =( CSICompiledGrammar* )GrammarL( aGrammarID) ;// Load the grammar from database |
|
616 CleanupStack::PushL(newgrammar); |
|
617 TSIRuleID RuleId; |
|
618 |
|
619 for (TInt i=0;i<newgrammar->Count();i++) { |
|
620 CSIRule* aRule=&(newgrammar->AtL(i)); |
|
621 RuleId=aRule->RuleID(); |
|
622 User::LeaveIfError(aRuleIDs.Append(RuleId)); |
|
623 } |
|
624 CleanupStack::PopAndDestroy(newgrammar); |
|
625 } |
|
626 |
|
627 // ----------------------------------------------------------------------------- |
|
628 // CSIGrammarDB::RemoveGrammarL |
|
629 // Deletes a grammar table from the database. |
|
630 // ----------------------------------------------------------------------------- |
|
631 // |
|
632 void CSIGrammarDB::RemoveGrammarL( TUid aClientUid, |
|
633 TSIGrammarID aGrammarID ) |
|
634 { |
|
635 VerifyOwnershipL(aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID); |
|
636 |
|
637 TInt diskSpace = ( RuleCountL(aGrammarID) * sizeof( CSIRule) ) |
|
638 + sizeof( CSIGrammar ); |
|
639 User::LeaveIfError( iDbSession.ReserveDriveSpace( iDrive, diskSpace ) ); |
|
640 |
|
641 // Construct the table name using the provided grammar ID |
|
642 TBuf<40> KGrammarName(KSIGrammarTable); |
|
643 KGrammarName.AppendNumUC(aGrammarID); |
|
644 |
|
645 TBuf<50> KSQLStatement; |
|
646 // Declare a literal string to hold the SQL statement |
|
647 // DROP TABLE KGrammarName |
|
648 _LIT(KSQLDelete1, "DROP TABLE "); |
|
649 |
|
650 KSQLStatement = KSQLDelete1; |
|
651 KSQLStatement.Append(KGrammarName); |
|
652 |
|
653 User::LeaveIfError(iDb.Execute(KSQLStatement)); |
|
654 |
|
655 // Release the grammar ID |
|
656 ReleaseIdL(KGrammarIdTable, KGrammarIdColumn, aGrammarID); |
|
657 |
|
658 // Cancel free disk space request |
|
659 iDbSession.FreeReservedSpace( iDrive ); |
|
660 } |
|
661 |
|
662 // ----------------------------------------------------------------------------- |
|
663 // CSIGrammarDB::RuleCountL |
|
664 // Returns the number of rules in the specified grammar. |
|
665 // Grammar have to be loaded |
|
666 // ----------------------------------------------------------------------------- |
|
667 // |
|
668 TInt CSIGrammarDB::RuleCountL( TSIGrammarID aGrammarID ) |
|
669 { |
|
670 // Load a grammar |
|
671 CSICompiledGrammar* aGrammar=(CSICompiledGrammar*)GrammarL(aGrammarID); |
|
672 CleanupStack::PushL(aGrammar); |
|
673 // Count the number of the rules inside the grammar |
|
674 TInt RuleCount=aGrammar->Count(); |
|
675 CleanupStack::PopAndDestroy(aGrammar); |
|
676 return RuleCount; |
|
677 } |
|
678 |
|
679 // ----------------------------------------------------------------------------- |
|
680 // CSIGrammarDB::RemoveRuleL |
|
681 // Deletes Rule from the database. |
|
682 // Grammar have to be loaded |
|
683 // ----------------------------------------------------------------------------- |
|
684 // |
|
685 void CSIGrammarDB::RemoveRuleL( TUid aClientUid, |
|
686 TSIGrammarID aGrammarID, |
|
687 TSIRuleID aRuleID ) |
|
688 { |
|
689 VerifyOwnershipL(aClientUid, KGrammarIdTable, KGrammarIndex, aGrammarID); |
|
690 CSICompiledGrammar* aGrammar=(CSICompiledGrammar*)GrammarL(aGrammarID); |
|
691 |
|
692 CleanupStack::PushL(aGrammar); |
|
693 if (aGrammar->Find(aRuleID)==KErrNotFound) |
|
694 { |
|
695 User::Leave(KErrNotFound); |
|
696 } |
|
697 else |
|
698 { |
|
699 aGrammar->DeleteL(aRuleID); |
|
700 } |
|
701 UpdateGrammarL(aClientUid,aGrammar); |
|
702 CleanupStack::PopAndDestroy(aGrammar); |
|
703 } |
|
704 |
|
705 // ----------------------------------------------------------------------------- |
|
706 // CSIGrammarDB::IsGrammarLoaded |
|
707 // Checks to see if a valid grammar is loaded into the recognizer. This is |
|
708 // useful to check if any rules are still loaded after performing UnloadRule(). |
|
709 // ----------------------------------------------------------------------------- |
|
710 // |
|
711 TBool CSIGrammarDB::IsGrammarLoaded() |
|
712 { |
|
713 for ( TInt i = 0; i < iGrammarArray.Count(); i++ ) |
|
714 { |
|
715 if ( iGrammarArray[i]->Count() > 0 ) |
|
716 { |
|
717 // As long as there is still a rule. |
|
718 return ETrue; |
|
719 } |
|
720 } |
|
721 return EFalse; |
|
722 } |
|
723 |
|
724 // ----------------------------------------------------------------------------- |
|
725 // CSIGrammarDB::IsRuleValidL |
|
726 // Checks if the rule is valid or not. |
|
727 // ----------------------------------------------------------------------------- |
|
728 // |
|
729 TBool CSIGrammarDB::IsRuleValidL( TSIGrammarID aGrammarID, TSIRuleID aRuleID ) |
|
730 { |
|
731 CSICompiledGrammar* aGrammar=(CSICompiledGrammar*)GrammarL(aGrammarID); |
|
732 CleanupStack::PushL(aGrammar); |
|
733 if (aGrammar->Find(aRuleID)==KErrNotFound) |
|
734 { |
|
735 CleanupStack::PopAndDestroy(aGrammar); |
|
736 return EFalse; |
|
737 } |
|
738 else { |
|
739 CleanupStack::PopAndDestroy(aGrammar); |
|
740 return ETrue; |
|
741 } |
|
742 } |
|
743 |
|
744 // ----------------------------------------------------------------------------- |
|
745 // CSIGrammarDB::ResetAndDestroy |
|
746 // Deallocates the temporary memory containing the grammar object created with |
|
747 // AllRulesL. |
|
748 // ----------------------------------------------------------------------------- |
|
749 // |
|
750 void CSIGrammarDB::ResetAndDestroy() |
|
751 { |
|
752 iGrammarArray.ResetAndDestroy(); |
|
753 } |
|
754 |
|
755 // ----------------------------------------------------------------------------- |
|
756 // CSIGrammarDB::UnloadRule |
|
757 // Unloads the specified rule from the specified grammar in temporary memory, |
|
758 // previously loaded with AllRulesL. The rule in the database remains intact. |
|
759 // ----------------------------------------------------------------------------- |
|
760 // |
|
761 void CSIGrammarDB::UnloadRuleL( TSIGrammarID aGrammarID, |
|
762 TSIRuleID aRuleID ) |
|
763 { |
|
764 CSIGrammar* grammar; |
|
765 |
|
766 for( TInt i = 0; i < iGrammarArray.Count(); i++ ) |
|
767 { |
|
768 grammar = iGrammarArray[i]; |
|
769 if ( grammar->GrammarID() == aGrammarID ) |
|
770 { |
|
771 grammar->DeleteL(aRuleID); |
|
772 return; |
|
773 } |
|
774 } |
|
775 User::Leave(KErrNotFound); |
|
776 } |
|
777 |
|
778 // ----------------------------------------------------------------------------- |
|
779 // CSIGrammarDB::UnloadGrammar |
|
780 // Unloads the specified grammar in temporary memory, |
|
781 // previously loaded with AllRulesL. The grammar in the database remains intact. |
|
782 // ----------------------------------------------------------------------------- |
|
783 // |
|
784 void CSIGrammarDB::UnloadGrammarL( TSIGrammarID aGrammarID) |
|
785 { |
|
786 CSIGrammar* grammar; |
|
787 |
|
788 for( TInt i = 0; i < iGrammarArray.Count(); i++ ) |
|
789 { |
|
790 grammar = iGrammarArray[i]; |
|
791 if ( grammar->GrammarID() == aGrammarID ) |
|
792 { |
|
793 //! delete the object |
|
794 delete iGrammarArray[i]; |
|
795 // remove the pointer |
|
796 iGrammarArray.Remove(i); |
|
797 return; |
|
798 } |
|
799 } |
|
800 User::Leave(KErrNotFound); |
|
801 } |
|
802 |
|
803 // End of File |