|
1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // TDumper test module |
|
15 // |
|
16 // |
|
17 |
|
18 // System includes |
|
19 #include <e32test.h> |
|
20 #include <f32file.h> |
|
21 #include <s32file.h> |
|
22 #include <s32stor.h> |
|
23 #include <charconv.h> |
|
24 |
|
25 // User includes |
|
26 #include "HLPMODEL.H" |
|
27 |
|
28 // Globals |
|
29 static RFs TheFs; |
|
30 static RTest TheTest(_L("TDUMPER - Dumps a help file to a plain text file")); |
|
31 static CTrapCleanup* TheTrapCleanup; |
|
32 static CActiveScheduler* TheScheduler; |
|
33 static CCnvCharacterSetConverter* TheConverter; |
|
34 |
|
35 // Literal constants |
|
36 _LIT(KDumpOutputFile, "C:\\%S-Dump.txt"); |
|
37 _LIT(KSQLTopicIdColumn, "TopicId"); |
|
38 _LIT(KSQLIndexIdColumn, "IndexId"); |
|
39 _LIT(KSQLTopicTitleColumn, "TopicTitle"); |
|
40 _LIT(KSQLTopicTextColumn, "TopicText"); |
|
41 _LIT(KSQLCategoryColumn, "Category"); |
|
42 _LIT(KSQLSynonymColumn, "Synonym"); |
|
43 _LIT(KSQLIndexColumn, "Index"); |
|
44 _LIT(KSQLContextColumn, "Context"); |
|
45 _LIT(KSQLCategoryUidColumn, "CategoryUID"); |
|
46 |
|
47 // Constants |
|
48 const TInt KTestCleanupStack = 0x20; |
|
49 |
|
50 // Typedefs |
|
51 typedef TBuf<80> TConsoleLine; |
|
52 |
|
53 |
|
54 static TBool GetLine(TConsoleLine& aLine) |
|
55 { |
|
56 TPoint posStart = TheTest.Console()->CursorPos(); |
|
57 TheTest.Console()->Write(aLine); |
|
58 |
|
59 TKeyCode key; |
|
60 TConsoleLine line(aLine); |
|
61 FOREVER |
|
62 { |
|
63 key = TheTest.Console()->Getch(); |
|
64 |
|
65 switch(key) |
|
66 { |
|
67 case EKeyEscape: |
|
68 return EFalse; |
|
69 case EKeyEnter: |
|
70 aLine = line; |
|
71 return ETrue; |
|
72 case EKeyBackspace: |
|
73 case EKeyDelete: |
|
74 { |
|
75 if (line.Length()) |
|
76 line = line.Left(line.Length()-1); |
|
77 break; |
|
78 } |
|
79 default: |
|
80 line.Append(TChar(key)); |
|
81 break; |
|
82 } |
|
83 |
|
84 TheTest.Console()->SetCursorPosAbs(posStart); |
|
85 TheTest.Console()->ClearToEndOfLine(); |
|
86 TheTest.Console()->Write(line); |
|
87 } |
|
88 } |
|
89 |
|
90 static void WriteTopicTableL(RFile& aOutputFile, RDbStoreDatabase& aDatabase) |
|
91 { |
|
92 TInt count = 0; |
|
93 _LIT(KCategoryTable, "TOPIC"); |
|
94 |
|
95 // Open the topic table so that we can use it to build the category list |
|
96 RDbTable table; |
|
97 User::LeaveIfError(table.Open(aDatabase, KCategoryTable, RDbRowSet::EReadOnly)); |
|
98 CleanupClosePushL(table); |
|
99 |
|
100 // Now build the list |
|
101 if (!table.FirstL()) |
|
102 { |
|
103 CleanupStack::PopAndDestroy(); // table |
|
104 return; // assume no rows |
|
105 } |
|
106 |
|
107 // Get the column of the category |
|
108 CDbColSet* colset = table.ColSetL(); |
|
109 TDbColNo titleCol = colset->ColNo(KSQLTopicTitleColumn); |
|
110 TDbColNo catCol = colset->ColNo(KSQLCategoryColumn); |
|
111 TDbColNo topicIdCol = colset->ColNo(KSQLTopicIdColumn); |
|
112 TDbColNo synonymCol = colset->ColNo(KSQLSynonymColumn); |
|
113 TDbColNo catIdCol = colset->ColNo(KSQLCategoryUidColumn); |
|
114 TDbColNo topicTextCol = colset->ColNo(KSQLTopicTextColumn); |
|
115 delete colset; |
|
116 |
|
117 // |
|
118 // WRITE THE TOPIC TABLE |
|
119 // |
|
120 TBuf8<1000> buffer; |
|
121 aOutputFile.Write(_L8("==============================\r\n")); |
|
122 aOutputFile.Write(_L8("== TOPIC TABLE ==\r\n")); |
|
123 aOutputFile.Write(_L8("==============================\r\n")); |
|
124 do |
|
125 { |
|
126 count++; |
|
127 table.GetL(); |
|
128 |
|
129 // Write category & category Id |
|
130 TBuf8<150> category; |
|
131 User::LeaveIfError(TheConverter->ConvertFromUnicode(category, table.ColDes(catCol))); |
|
132 buffer.Format(_L8("Category (Id): %S (%d)\r\n"), &category, table.ColUint32(catIdCol)); |
|
133 aOutputFile.Write(buffer); |
|
134 |
|
135 // Write topic Id |
|
136 buffer.Format(_L8("Topic Id: %d\r\n"), table.ColUint32(topicIdCol)); |
|
137 aOutputFile.Write(buffer); |
|
138 |
|
139 // Write title |
|
140 TBuf8<150> title; |
|
141 User::LeaveIfError(TheConverter->ConvertFromUnicode(title, table.ColDes(titleCol))); |
|
142 buffer.Format(_L8("Title: %S\r\n"), &title); |
|
143 aOutputFile.Write(buffer); |
|
144 |
|
145 // Write synonym |
|
146 TBuf8<200> synonym; |
|
147 User::LeaveIfError(TheConverter->ConvertFromUnicode(synonym, table.ColDes(synonymCol))); |
|
148 buffer.Format(_L8("Synonym: %S\r\n"), &synonym); |
|
149 aOutputFile.Write(buffer); |
|
150 |
|
151 // Write topic text |
|
152 TInt len = table.ColLength(topicTextCol); |
|
153 HBufC* text = HBufC::NewLC(len); |
|
154 TPtr pText(text->Des()); |
|
155 |
|
156 // Retrieve actual text from column |
|
157 RDbColReadStream stream; |
|
158 stream.OpenLC(table, topicTextCol); |
|
159 stream.ReadL(pText, len); |
|
160 CleanupStack::PopAndDestroy(); // stream |
|
161 |
|
162 // Write the text |
|
163 HBufC8* narrowText = HBufC8::NewLC(len); |
|
164 TPtr8 pNarrowText(narrowText->Des()); |
|
165 User::LeaveIfError(TheConverter->ConvertFromUnicode(pNarrowText, pText)); |
|
166 CleanupStack::Pop(); // narrowText |
|
167 CleanupStack::PopAndDestroy(); // text |
|
168 |
|
169 aOutputFile.Write(_L8("Body: ")); |
|
170 aOutputFile.Write(*narrowText); |
|
171 aOutputFile.Write(_L8("\r\n")); |
|
172 delete narrowText; |
|
173 |
|
174 aOutputFile.Write(_L8("\r\n")); |
|
175 } |
|
176 while (table.NextL()); |
|
177 aOutputFile.Write(_L8("\r\n")); |
|
178 |
|
179 CleanupStack::PopAndDestroy(); // table |
|
180 } |
|
181 |
|
182 static void WriteContextTableL(RFile& aOutputFile, RDbStoreDatabase& aDatabase) |
|
183 { |
|
184 _LIT(KContextTable, "CONTEXT"); |
|
185 |
|
186 // Open the topic table so that we can use it to build the category list |
|
187 RDbTable table; |
|
188 User::LeaveIfError(table.Open(aDatabase, KContextTable, RDbRowSet::EReadOnly)); |
|
189 CleanupClosePushL(table); |
|
190 |
|
191 // Now build the list |
|
192 if (!table.FirstL()) |
|
193 { |
|
194 CleanupStack::PopAndDestroy(); // table |
|
195 return; // assume no rows |
|
196 } |
|
197 |
|
198 // Get the column of the category |
|
199 CDbColSet* colset = table.ColSetL(); |
|
200 TDbColNo contextCol = colset->ColNo(KSQLContextColumn); |
|
201 TDbColNo topicIdCol = colset->ColNo(KSQLTopicIdColumn); |
|
202 delete colset; |
|
203 |
|
204 // |
|
205 // WRITE THE TOPIC TABLE |
|
206 // |
|
207 TBuf8<1000> buffer; |
|
208 aOutputFile.Write(_L8("==============================\r\n")); |
|
209 aOutputFile.Write(_L8("== CONTEXT TABLE ==\r\n")); |
|
210 aOutputFile.Write(_L8("==============================\r\n")); |
|
211 do |
|
212 { |
|
213 table.GetL(); |
|
214 |
|
215 { |
|
216 // Write context |
|
217 TBuf8<150> context; |
|
218 User::LeaveIfError(TheConverter->ConvertFromUnicode(context, table.ColDes(contextCol))); |
|
219 buffer.Format(_L8("Context: %S\r\n"), &context); |
|
220 aOutputFile.Write(buffer); |
|
221 } |
|
222 { |
|
223 // Write topic Id |
|
224 buffer.Format(_L8("Topic Id: %d\r\n"), table.ColUint32(topicIdCol)); |
|
225 aOutputFile.Write(buffer); |
|
226 } |
|
227 aOutputFile.Write(_L8("\r\n")); |
|
228 } |
|
229 while (table.NextL()); |
|
230 aOutputFile.Write(_L8("\r\n")); |
|
231 |
|
232 CleanupStack::PopAndDestroy(); // table |
|
233 } |
|
234 |
|
235 |
|
236 static void WriteTopicIndexTableL(RFile& aOutputFile, RDbStoreDatabase& aDatabase) |
|
237 { |
|
238 _LIT(KTopicIndexTable, "TOPICINDEX"); |
|
239 |
|
240 // Open the topic table so that we can use it to build the category list |
|
241 RDbTable table; |
|
242 User::LeaveIfError(table.Open(aDatabase, KTopicIndexTable, RDbRowSet::EReadOnly)); |
|
243 CleanupClosePushL(table); |
|
244 |
|
245 // Now build the list |
|
246 if (!table.FirstL()) |
|
247 { |
|
248 CleanupStack::PopAndDestroy(); // table |
|
249 return; // assume no rows |
|
250 } |
|
251 |
|
252 // Get the column of the category |
|
253 CDbColSet* colset = table.ColSetL(); |
|
254 TDbColNo topicIdCol = colset->ColNo(KSQLTopicIdColumn); |
|
255 TDbColNo indexIdCol = colset->ColNo(KSQLIndexIdColumn); |
|
256 TDbColNo categoryUidCol = colset->ColNo(KSQLCategoryUidColumn); |
|
257 TDbColNo titleCol = colset->ColNo(KSQLTopicTitleColumn); |
|
258 delete colset; |
|
259 |
|
260 // |
|
261 // WRITE THE TOPIC TABLE |
|
262 // |
|
263 TBuf8<1000> buffer; |
|
264 aOutputFile.Write(_L8("==============================\r\n")); |
|
265 aOutputFile.Write(_L8("== TOPIC/INDEX TABLE ==\r\n")); |
|
266 aOutputFile.Write(_L8("==============================\r\n")); |
|
267 do |
|
268 { |
|
269 table.GetL(); |
|
270 |
|
271 // Write topic Id |
|
272 buffer.Format(_L8("Topic Id: %d\r\n"), table.ColUint32(topicIdCol)); |
|
273 aOutputFile.Write(buffer); |
|
274 |
|
275 // Write index Id |
|
276 buffer.Format(_L8("Index Id: %d\r\n"), table.ColUint32(indexIdCol)); |
|
277 aOutputFile.Write(buffer); |
|
278 |
|
279 // Write out the category uid |
|
280 buffer.Format(_L8("Category Uid: %d\r\n"), table.ColUint32(categoryUidCol)); |
|
281 aOutputFile.Write(buffer); |
|
282 |
|
283 { |
|
284 // Write out the topic title |
|
285 TBuf8<150> topicTitle; |
|
286 User::LeaveIfError(TheConverter->ConvertFromUnicode(topicTitle, table.ColDes(titleCol))); |
|
287 buffer.Format(_L8("TopicTitle: %S\r\n"), &topicTitle); |
|
288 aOutputFile.Write(buffer); |
|
289 } |
|
290 |
|
291 aOutputFile.Write(_L8("\r\n")); |
|
292 } |
|
293 while (table.NextL()); |
|
294 aOutputFile.Write(_L8("\r\n")); |
|
295 |
|
296 CleanupStack::PopAndDestroy(); // table |
|
297 } |
|
298 |
|
299 static void WriteIndexTableL(RFile& aOutputFile, RDbStoreDatabase& aDatabase) |
|
300 { |
|
301 _LIT(KIndexTable, "INDEX"); |
|
302 |
|
303 // Open the topic table so that we can use it to build the category list |
|
304 RDbTable table; |
|
305 User::LeaveIfError(table.Open(aDatabase, KIndexTable, RDbRowSet::EReadOnly)); |
|
306 CleanupClosePushL(table); |
|
307 |
|
308 // Now build the list |
|
309 if (!table.FirstL()) |
|
310 { |
|
311 CleanupStack::PopAndDestroy(); // table |
|
312 return; // assume no rows |
|
313 } |
|
314 |
|
315 // Get the column of the category |
|
316 CDbColSet* colset = table.ColSetL(); |
|
317 TDbColNo indexCol = colset->ColNo(KSQLIndexColumn); |
|
318 TDbColNo indexIdCol = colset->ColNo(KSQLIndexIdColumn); |
|
319 delete colset; |
|
320 |
|
321 // |
|
322 // WRITE THE TOPIC TABLE |
|
323 // |
|
324 TBuf8<1000> buffer; |
|
325 aOutputFile.Write(_L8("==============================\r\n")); |
|
326 aOutputFile.Write(_L8("== INDEX TABLE ==\r\n")); |
|
327 aOutputFile.Write(_L8("==============================\r\n")); |
|
328 do |
|
329 { |
|
330 table.GetL(); |
|
331 |
|
332 // Write topic Id |
|
333 TBuf8<140> index; |
|
334 User::LeaveIfError(TheConverter->ConvertFromUnicode(index, table.ColDes(indexCol))); |
|
335 buffer.Format(_L8("Index (Id): %S (%d)\r\n"), &index, table.ColUint32(indexIdCol)); |
|
336 aOutputFile.Write(buffer); |
|
337 |
|
338 aOutputFile.Write(_L8("\r\n")); |
|
339 } |
|
340 while (table.NextL()); |
|
341 aOutputFile.Write(_L8("\r\n")); |
|
342 |
|
343 CleanupStack::PopAndDestroy(); // table |
|
344 } |
|
345 |
|
346 static void WriteFileUidL(RFile& aOutputFile, const TDesC& aFileName) |
|
347 { |
|
348 // |
|
349 // WRITE THE TOPIC TABLE |
|
350 // |
|
351 TBuf8<1000> buffer; |
|
352 aOutputFile.Write(_L8("==============================\r\n")); |
|
353 aOutputFile.Write(_L8("== FILE UID ==\r\n")); |
|
354 aOutputFile.Write(_L8("==============================\r\n")); |
|
355 |
|
356 TEntry entry; |
|
357 TheFs.Entry(aFileName, entry); |
|
358 buffer.Format(_L8("File Uids: [0x%x][0x%x][0x%x]\r\n"), entry[0], entry[1], entry[2]); |
|
359 aOutputFile.Write(buffer); |
|
360 aOutputFile.Write(_L8("\r\n")); |
|
361 } |
|
362 |
|
363 static void Test1L() |
|
364 { |
|
365 |
|
366 TConsoleLine inputFile(_L("C:\\Resource\\Help\\")); |
|
367 TheTest.Printf(_L("Enter filename: ")); |
|
368 if (!GetLine(inputFile)) |
|
369 { |
|
370 // Escape'd |
|
371 return; |
|
372 } |
|
373 |
|
374 TFileName outputFileName; |
|
375 TParsePtrC parser(inputFile); |
|
376 TPtrC pName(parser.Name()); |
|
377 outputFileName.Format(KDumpOutputFile, &pName); |
|
378 |
|
379 RFile outputFile; |
|
380 User::LeaveIfError(outputFile.Replace(TheFs, outputFileName, EFileShareExclusive | EFileWrite)); |
|
381 CleanupClosePushL(outputFile); |
|
382 |
|
383 CPermanentFileStore* store = CPermanentFileStore::OpenLC(TheFs, inputFile, EFileRead); |
|
384 CStreamDictionary* dictionary = CStreamDictionary::NewLC(); |
|
385 RStoreReadStream in; |
|
386 in.OpenLC(*store, store->Root()); |
|
387 dictionary->InternalizeL(in); |
|
388 CleanupStack::PopAndDestroy(); // in |
|
389 |
|
390 // restore the database |
|
391 RDbStoreDatabase database; |
|
392 database.OpenL(store, dictionary->At(KUidHlpDbStream)); |
|
393 CleanupClosePushL(database); |
|
394 |
|
395 // Write the topic table |
|
396 WriteTopicTableL(outputFile, database); |
|
397 |
|
398 // Write the context table |
|
399 WriteContextTableL(outputFile, database); |
|
400 |
|
401 // Write topic/index table |
|
402 WriteTopicIndexTableL(outputFile, database); |
|
403 |
|
404 // Write index table |
|
405 WriteIndexTableL(outputFile, database); |
|
406 |
|
407 // Write the uid of the file itself |
|
408 WriteFileUidL(outputFile, inputFile); |
|
409 |
|
410 CleanupStack::PopAndDestroy(4); // database, dictionary, store, outputFile |
|
411 } |
|
412 |
|
413 |
|
414 |
|
415 |
|
416 |
|
417 static void setupUnicodeConverterL() |
|
418 // |
|
419 // Initialise charconv |
|
420 // |
|
421 { |
|
422 TheConverter = CCnvCharacterSetConverter::NewL(); |
|
423 CArrayFix<CCnvCharacterSetConverter::SCharacterSet>* arrayOfCharacterSetsAvailable = TheConverter->CreateArrayOfCharacterSetsAvailableL(TheFs); |
|
424 CleanupStack::PushL(arrayOfCharacterSetsAvailable); |
|
425 TheConverter->PrepareToConvertToOrFromL(0x100012b6, *arrayOfCharacterSetsAvailable, TheFs); // 0x100012b6 is KCharacterSetIdentifierCodePage1252 |
|
426 TheConverter->SetReplacementForUnconvertibleUnicodeCharactersL(_L8("?")); |
|
427 CleanupStack::PopAndDestroy(); // arrayOfCharacterSetsAvailable |
|
428 } |
|
429 |
|
430 |
|
431 static void setupFileServerAndSchedulerL() |
|
432 // |
|
433 // Initialise the cleanup stack. |
|
434 // |
|
435 { |
|
436 TheTest(TheFs.Connect() == KErrNone); |
|
437 TheScheduler = new (ELeave) CActiveScheduler; |
|
438 CActiveScheduler::Install(TheScheduler); |
|
439 } |
|
440 |
|
441 |
|
442 static void setupCleanup() |
|
443 // |
|
444 // Initialise the cleanup stack. |
|
445 // |
|
446 { |
|
447 TheTrapCleanup = CTrapCleanup::New(); |
|
448 TheTest(TheTrapCleanup!=NULL); |
|
449 TRAPD(r,\ |
|
450 {\ |
|
451 for (TInt i=KTestCleanupStack;i>0;i--)\ |
|
452 CleanupStack::PushL((TAny*)0);\ |
|
453 CleanupStack::Pop(KTestCleanupStack);\ |
|
454 }); |
|
455 TheTest(r==KErrNone); |
|
456 } |
|
457 |
|
458 GLDEF_C TInt E32Main() |
|
459 // |
|
460 // Test Help Model API |
|
461 /** |
|
462 @SYMTestCaseID PIM-TDUMPER-0001 |
|
463 */ |
|
464 // |
|
465 { |
|
466 __UHEAP_MARK; |
|
467 |
|
468 TheTest.Start(_L("@SYMTestCaseID PIM-TDUMPER-0001 ")); |
|
469 TheTest.Title(); |
|
470 setupCleanup(); |
|
471 |
|
472 TRAPD(r, |
|
473 setupFileServerAndSchedulerL(); |
|
474 setupUnicodeConverterL(); |
|
475 Test1L(); |
|
476 ); |
|
477 TheTest(r==KErrNone); |
|
478 |
|
479 delete TheConverter; |
|
480 delete TheScheduler; |
|
481 delete TheTrapCleanup; |
|
482 TheFs.Close(); |
|
483 TheTest.End(); |
|
484 TheTest.Close(); |
|
485 |
|
486 __UHEAP_MARKEND; |
|
487 return KErrNone; |
|
488 } |