|
1 /* |
|
2 * Copyright (c) 2003 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 the License "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: |
|
15 * Implementation of CBookmarkFileImporter. |
|
16 * |
|
17 * |
|
18 */ |
|
19 |
|
20 |
|
21 // INCLUDE FILES |
|
22 |
|
23 #include "BookmarkFileImporter.h" |
|
24 #include <FavouritesLimits.h> |
|
25 // TEMP |
|
26 #include <s32file.h> |
|
27 // END TEMP |
|
28 |
|
29 // CONSTANTS |
|
30 |
|
31 /// ',' character. |
|
32 LOCAL_C const TUint KComma = ','; |
|
33 /// '#' character. |
|
34 LOCAL_C const TUint KHash = '#'; |
|
35 /// EOF (0) character. |
|
36 LOCAL_C const TUint KEof = 0; |
|
37 /// '\r' character. |
|
38 LOCAL_C const TUint KCr = '\r'; |
|
39 /// '\n' character. |
|
40 LOCAL_C const TUint KLf = '\n'; |
|
41 |
|
42 /// LF-EOF stop token set. |
|
43 _LIT( KStopLfEof, "\n\0" ); |
|
44 /// Comma stop token set. |
|
45 _LIT( KStopComma, "," ); |
|
46 /// Comma-LF-EOF stop token set. |
|
47 _LIT( KStopCommaLfEof, ",\n\0" ); |
|
48 |
|
49 /// "Folder" kewyword. |
|
50 _LIT( KFolder, "Folder" ); |
|
51 /// "Item" kewyword. |
|
52 _LIT( KItem, "Item" ); |
|
53 /// "Homepage" kewyword. |
|
54 _LIT( KHomepage, "Homepage" ); |
|
55 /// "LastVisited" kewyword. |
|
56 _LIT( KLastVisited, "LastVisited" ); |
|
57 |
|
58 // ================= MEMBER FUNCTIONS ======================= |
|
59 |
|
60 // --------------------------------------------------------- |
|
61 // CBookmarkFileImporter::NewLC |
|
62 // --------------------------------------------------------- |
|
63 // |
|
64 CBookmarkFileImporter* CBookmarkFileImporter::NewL() |
|
65 { |
|
66 CBookmarkFileImporter* importer = new (ELeave) CBookmarkFileImporter(); |
|
67 CleanupStack::PushL( importer ); |
|
68 importer->ConstructL(); |
|
69 CleanupStack::Pop(); // importer |
|
70 return importer; |
|
71 } |
|
72 |
|
73 // --------------------------------------------------------- |
|
74 // CBookmarkFileImporter::~CBookmarkFileImporter |
|
75 // --------------------------------------------------------- |
|
76 // |
|
77 CBookmarkFileImporter::~CBookmarkFileImporter() |
|
78 { |
|
79 delete iBuf; |
|
80 iFile.Close(); |
|
81 iFs.Close(); |
|
82 delete iItem; |
|
83 iDb.Close(); |
|
84 iSess.Close(); |
|
85 } |
|
86 |
|
87 // --------------------------------------------------------- |
|
88 // CBookmarkFileImporter::ImportL |
|
89 // --------------------------------------------------------- |
|
90 // |
|
91 void CBookmarkFileImporter::ImportL( const TDesC& aFileName ) |
|
92 { |
|
93 User::LeaveIfError( iFile.Open( iFs, aFileName, |
|
94 EFileRead | EFileShareReadersOnly ) ); |
|
95 CleanupClosePushL<RUnicodeFile>( iFile ); |
|
96 User::LeaveIfError( iDb.Open( iSess, KBrowserBookmarks ) ); |
|
97 // Import is done in a transaction - all or nothing. |
|
98 User::LeaveIfError( iDb.Begin( /*aWrite=*/ETrue ) ); |
|
99 iDb.CleanupRollbackPushL(); |
|
100 GetCharL(); |
|
101 while( NextLineL() ); |
|
102 User::LeaveIfError( iDb.Commit() ); |
|
103 CleanupStack::Pop(); // the rollback |
|
104 CleanupStack::PopAndDestroy(); // close iFile |
|
105 } |
|
106 |
|
107 // --------------------------------------------------------- |
|
108 // CBookmarkFileImporter::CBookmarkFileImporter |
|
109 // --------------------------------------------------------- |
|
110 // |
|
111 CBookmarkFileImporter::CBookmarkFileImporter() |
|
112 { |
|
113 } |
|
114 |
|
115 // --------------------------------------------------------- |
|
116 // CBookmarkFileImporter::ConstructL |
|
117 // --------------------------------------------------------- |
|
118 // |
|
119 void CBookmarkFileImporter::ConstructL() |
|
120 { |
|
121 User::LeaveIfError( iSess.Connect() ); |
|
122 iItem = CFavouritesItem::NewL(); |
|
123 User::LeaveIfError( iFs.Connect() ); |
|
124 iBuf = new (ELeave) TText16[KFavouritesMaxUrl]; |
|
125 iMaxCh = iBuf + KFavouritesMaxUrl; |
|
126 } |
|
127 |
|
128 // --------------------------------------------------------- |
|
129 // CBookmarkFileImporter::GetCharL |
|
130 // --------------------------------------------------------- |
|
131 // |
|
132 void CBookmarkFileImporter::GetCharL() |
|
133 { |
|
134 iCurCh = iFile.GetCharL(); |
|
135 if ( iCurCh == KCr ) |
|
136 { |
|
137 // CR character found - ignore it. Not expecting CR to appear anywhere |
|
138 // else than before an LF. |
|
139 iCurCh = iFile.GetCharL(); |
|
140 } |
|
141 } |
|
142 |
|
143 // --------------------------------------------------------- |
|
144 // CBookmarkFileImporter::NextLineL |
|
145 // --------------------------------------------------------- |
|
146 // |
|
147 TBool CBookmarkFileImporter::NextLineL() |
|
148 { |
|
149 switch( iCurCh ) |
|
150 { |
|
151 case KEof: |
|
152 // EOF |
|
153 return EFalse; |
|
154 |
|
155 case KHash: |
|
156 // Comment line; skip over. |
|
157 SkipL( KStopLfEof ); |
|
158 GetCharL(); |
|
159 break; |
|
160 |
|
161 case KCr: |
|
162 case KLf: |
|
163 // Empty line; skip over. |
|
164 GetCharL(); |
|
165 break; |
|
166 |
|
167 default: |
|
168 // Parse bookmark attributes. |
|
169 AttrsL(); |
|
170 break; |
|
171 } |
|
172 return ETrue; |
|
173 } |
|
174 |
|
175 // --------------------------------------------------------- |
|
176 // CBookmarkFileImporter::NextTokenL |
|
177 // --------------------------------------------------------- |
|
178 // |
|
179 TPtrC CBookmarkFileImporter::NextTokenL( const TDesC& aStopCharSet ) |
|
180 { |
|
181 iNextCh = iBuf; // Start storing token at start of buffer. |
|
182 while ( iNextCh < iMaxCh ) |
|
183 { |
|
184 if ( aStopCharSet.Locate( iCurCh ) != KErrNotFound ) |
|
185 { |
|
186 // Stop character found - return what we have stored so far. This |
|
187 // may be an empty string as well. |
|
188 return TPtrC( iBuf, iNextCh - iBuf ); |
|
189 } |
|
190 *iNextCh = STATIC_CAST( TText16, iCurCh ); |
|
191 iNextCh++; |
|
192 GetCharL(); |
|
193 } |
|
194 // No more space in buffer to store token. |
|
195 User::Leave( KErrOverflow ); |
|
196 /*NOTREACHED*/ |
|
197 return TPtrC(); |
|
198 } |
|
199 |
|
200 // --------------------------------------------------------- |
|
201 // CBookmarkFileImporter::NextIntTokenL |
|
202 // --------------------------------------------------------- |
|
203 // |
|
204 TInt CBookmarkFileImporter::NextIntTokenL( const TDesC& aStopCharSet ) |
|
205 { |
|
206 TInt ret = 0; |
|
207 TPtrC token( NextTokenL( aStopCharSet ) ); |
|
208 if ( token.Length() ) |
|
209 { |
|
210 TLex lex( token ); |
|
211 User::LeaveIfError( lex.Val( ret ) ); |
|
212 } |
|
213 return ret; |
|
214 } |
|
215 |
|
216 // --------------------------------------------------------- |
|
217 // CBookmarkFileImporter::NextHexTokenL |
|
218 // --------------------------------------------------------- |
|
219 // |
|
220 TInt32 CBookmarkFileImporter::NextHexTokenL( const TDesC& aStopCharSet ) |
|
221 { |
|
222 TUint32 ret = 0; |
|
223 TPtrC token( NextTokenL( aStopCharSet ) ); |
|
224 if ( token.Length() ) |
|
225 { |
|
226 TLex lex( token ); |
|
227 User::LeaveIfError( lex.Val( ret, EHex ) ); |
|
228 } |
|
229 return STATIC_CAST( TInt32, ret ); |
|
230 } |
|
231 |
|
232 // --------------------------------------------------------- |
|
233 // CBookmarkFileImporter::SkipL |
|
234 // --------------------------------------------------------- |
|
235 // |
|
236 void CBookmarkFileImporter::SkipL( const TDesC& aStopCharSet ) |
|
237 { |
|
238 // Note that EOF also can be a stop character; aStopChar check has |
|
239 // precendence over EOF check. That is the 'expected EOF' case. |
|
240 while( aStopCharSet.Locate( iCurCh ) == KErrNotFound ) |
|
241 { |
|
242 if ( iCurCh == KEof ) |
|
243 { |
|
244 // Unexpected EOF. |
|
245 User::Leave( KErrEof ); |
|
246 } |
|
247 GetCharL(); |
|
248 } |
|
249 } |
|
250 |
|
251 // --------------------------------------------------------- |
|
252 // CBookmarkFileImporter::AttrsL |
|
253 // --------------------------------------------------------- |
|
254 // |
|
255 void CBookmarkFileImporter::AttrsL() |
|
256 { |
|
257 TPtrC token; |
|
258 TInt num; |
|
259 TBool readOnly( EFalse ); |
|
260 TBool factoryItem( ETrue ); |
|
261 TBool homePage( EFalse ); |
|
262 TBool lastVisited( EFalse ); |
|
263 TBool preferred( EFalse ); |
|
264 |
|
265 // Parse the line and fill item. |
|
266 iItem->ClearL(); |
|
267 |
|
268 // Type (including special items). |
|
269 token.Set( NextTokenL( KStopComma ) ); |
|
270 if ( !token.Compare( KFolder ) ) |
|
271 { |
|
272 iItem->SetType( CFavouritesItem::EFolder ); |
|
273 } |
|
274 else if ( !token.Compare( KItem ) ) |
|
275 { |
|
276 iItem->SetType( CFavouritesItem::EItem ); |
|
277 } |
|
278 else if ( !token.Compare( KHomepage ) ) |
|
279 { |
|
280 iItem->SetType( CFavouritesItem::EItem ); |
|
281 homePage = ETrue; |
|
282 } |
|
283 else if ( !token.Compare( KLastVisited ) ) |
|
284 { |
|
285 iItem->SetType( CFavouritesItem::EItem ); |
|
286 lastVisited = ETrue; |
|
287 } |
|
288 else |
|
289 { |
|
290 // Expected "Folder", "Item", "Homepage" or "LastVisited". |
|
291 User::Leave( KErrCorrupt ); |
|
292 } |
|
293 GetCharL(); |
|
294 |
|
295 // Name. |
|
296 iItem->SetNameL( NextTokenL( KStopComma ) ); |
|
297 GetCharL(); |
|
298 |
|
299 // Parent folder. |
|
300 iItem->SetParentFolder( FolderByNameL( NextTokenL( KStopComma ) ) ); |
|
301 GetCharL(); |
|
302 |
|
303 // URL. |
|
304 iItem->SetUrlL( NextTokenL( KStopComma ) ); |
|
305 GetCharL(); |
|
306 |
|
307 // WAP AP. |
|
308 num = NextIntTokenL( KStopComma ); |
|
309 if( num ) |
|
310 { |
|
311 TFavouritesWapAp ap; |
|
312 ap = num; |
|
313 iItem->SetWapAp( ap ); |
|
314 } |
|
315 GetCharL(); |
|
316 |
|
317 // User name. |
|
318 iItem->SetUserNameL( NextTokenL( KStopComma ) ); |
|
319 GetCharL(); |
|
320 |
|
321 // Password. |
|
322 iItem->SetPasswordL( NextTokenL( KStopComma ) ); |
|
323 GetCharL(); |
|
324 |
|
325 // Read-only flag. |
|
326 num = NextIntTokenL( KStopComma ); |
|
327 if ( num == 0 ) |
|
328 { |
|
329 readOnly = EFalse; |
|
330 } |
|
331 else if ( num == 1 ) |
|
332 { |
|
333 readOnly = ETrue; |
|
334 } |
|
335 else |
|
336 { |
|
337 // Expected "0" or "1". |
|
338 User::Leave( KErrCorrupt ); |
|
339 } |
|
340 GetCharL(); |
|
341 |
|
342 // Factory item flag. |
|
343 num = NextIntTokenL( KStopComma ); |
|
344 if ( num == 0 ) |
|
345 { |
|
346 factoryItem = EFalse; |
|
347 } |
|
348 else if ( num == 1 ) |
|
349 { |
|
350 factoryItem = ETrue; |
|
351 } |
|
352 else |
|
353 { |
|
354 // Expected "0" or "1". |
|
355 User::Leave( KErrCorrupt ); |
|
356 } |
|
357 GetCharL(); |
|
358 |
|
359 // Context id. |
|
360 iItem->SetContextId( NextHexTokenL( KStopCommaLfEof ) ); |
|
361 // No GetCharL yet - PreferredUid is optional, so we need to investigate |
|
362 // lookeahed character first. |
|
363 |
|
364 // Preferred flag (optional). |
|
365 if ( iCurCh == KComma ) |
|
366 { |
|
367 GetCharL(); |
|
368 num = NextIntTokenL( KStopLfEof ); |
|
369 if ( num == 0 ) |
|
370 { |
|
371 preferred = EFalse; |
|
372 } |
|
373 else if ( num == 1 ) |
|
374 { |
|
375 preferred = ETrue; |
|
376 } |
|
377 else |
|
378 { |
|
379 // Expected "0" or "1". |
|
380 User::Leave( KErrCorrupt ); |
|
381 } |
|
382 } |
|
383 GetCharL(); |
|
384 |
|
385 // Add item and set flags. |
|
386 if ( homePage ) |
|
387 { |
|
388 User::LeaveIfError( iDb.SetHomepage( *iItem ) ); |
|
389 } |
|
390 else if ( lastVisited ) |
|
391 { |
|
392 User::LeaveIfError( iDb.SetLastVisited( *iItem ) ); |
|
393 } |
|
394 else |
|
395 { |
|
396 User::LeaveIfError( iDb.Add( *iItem, /*aAutoRename=*/EFalse ) ); |
|
397 } |
|
398 User::LeaveIfError( iDb.SetReadOnly( iItem->Uid(), readOnly ) ); |
|
399 User::LeaveIfError( iDb.SetFactoryItem( iItem->Uid(), factoryItem ) ); |
|
400 if ( preferred ) |
|
401 { |
|
402 User::LeaveIfError( iDb.SetPreferredUid |
|
403 ( iItem->ParentFolder(), iItem->Uid() ) ); |
|
404 } |
|
405 } |
|
406 |
|
407 // --------------------------------------------------------- |
|
408 // CBookmarkFileImporter::FolderByNameL |
|
409 // --------------------------------------------------------- |
|
410 // |
|
411 TInt CBookmarkFileImporter::FolderByNameL( const TDesC& aName ) |
|
412 { |
|
413 TInt folder = KFavouritesRootUid; |
|
414 if ( aName.Length() ) |
|
415 { |
|
416 CArrayFix<TInt>* uids = new (ELeave) CArrayFixFlat<TInt>( 1 ); |
|
417 CleanupStack::PushL( uids ); |
|
418 User::LeaveIfError( iDb.GetUids |
|
419 ( |
|
420 *uids, |
|
421 KFavouritesNullUid, |
|
422 CFavouritesItem::EFolder, |
|
423 &aName, |
|
424 KFavouritesNullContextId |
|
425 ) ); |
|
426 if( uids->Count() == 0 ) |
|
427 { |
|
428 User::Leave( KErrNotFound ); |
|
429 } |
|
430 if( uids->Count() == 1 ) |
|
431 { |
|
432 folder = uids->At( 0 ); |
|
433 } |
|
434 else |
|
435 { |
|
436 // This would worth a panic - more folders with the same name? |
|
437 User::Leave( KErrCorrupt ); |
|
438 } |
|
439 CleanupStack::PopAndDestroy(); // uids |
|
440 } |
|
441 return folder; |
|
442 } |