1 /* |
|
2 * Copyright (c) 2003 - 2004 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: Handler for loading file scheme. |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 // INCLUDE FILES |
|
21 #include <e32std.h> |
|
22 #include <e32base.h> |
|
23 #include <uri16.h> |
|
24 #include <apmrec.h> |
|
25 #include <apgcli.h> |
|
26 #include <escapeutils.h> |
|
27 |
|
28 #include "fileloader_cfilehandler.h" |
|
29 #include "fileloader_cfileloader.h" |
|
30 //#include "urlloader_loaderutils.h" |
|
31 #include "nwx_http_defs.h" |
|
32 #include "fileloader_csaveddeckhandler.h" |
|
33 #include "TEncodingMapping.h" |
|
34 |
|
35 //#include "PluginHandler.h" |
|
36 |
|
37 // EXTERNAL DATA STRUCTURES |
|
38 |
|
39 // EXTERNAL FUNCTION PROTOTYPES |
|
40 |
|
41 // CONSTANTS |
|
42 |
|
43 // MACROS |
|
44 |
|
45 // LOCAL CONSTANTS AND MACROS |
|
46 |
|
47 // MODULE DATA STRUCTURES |
|
48 |
|
49 // LOCAL FUNCTION PROTOTYPES |
|
50 |
|
51 // FORWARD DECLARATIONS |
|
52 |
|
53 // ============================= LOCAL FUNCTIONS =============================== |
|
54 |
|
55 |
|
56 // ============================ MEMBER FUNCTIONS =============================== |
|
57 |
|
58 // ----------------------------------------------------------------------------- |
|
59 // CFileHandler::CFileHandler |
|
60 // C++ default constructor can NOT contain any code, that |
|
61 // might leave. |
|
62 // ----------------------------------------------------------------------------- |
|
63 // |
|
64 CFileHandler::CFileHandler(const TUint16 *aUrl, |
|
65 TUint8 aMethod, |
|
66 TUint16 aTransId, |
|
67 TUint8 aLoadType, |
|
68 void *aLoadContext, |
|
69 NW_Url_RespCallback_t *aLoadCallback, |
|
70 CKFileLoader* aFileLoader) : |
|
71 CActive(CActive::EPriorityUserInput), iData(NULL, 0), iFileName(NULL, 0), |
|
72 iSize(0) |
|
73 { |
|
74 iUrl = aUrl; |
|
75 iRedirectedUrl = NULL; |
|
76 iTransId = aTransId; |
|
77 iLoadContext = aLoadContext; |
|
78 iLoadCallback = aLoadCallback; |
|
79 iFileLoader = aFileLoader; |
|
80 iRfsOpen = EFalse; |
|
81 iFileOpen = EFalse; |
|
82 iMethod = aMethod; |
|
83 iLoadType = aLoadType; |
|
84 } |
|
85 |
|
86 |
|
87 // ----------------------------------------------------------------------------- |
|
88 // CFileHandler::ConstructL |
|
89 // Symbian 2nd phase constructor can leave. |
|
90 // ----------------------------------------------------------------------------- |
|
91 // |
|
92 void CFileHandler::ConstructL() |
|
93 { |
|
94 TInt ret = KErrNone; |
|
95 |
|
96 if (!GetFileNameL()) |
|
97 { |
|
98 User::Leave(KErrBadName); |
|
99 } |
|
100 |
|
101 // connect to file server |
|
102 User::LeaveIfError(iRfs.Connect(1)); |
|
103 iRfsOpen = ETrue; |
|
104 // Open the file |
|
105 ret = iFile.Open(iRfs, iFileName, EFileRead | EFileShareAny); |
|
106 if (ret == KErrNotFound) |
|
107 { |
|
108 // Try again with the Uri-decoded name. |
|
109 HBufC16* decodedFileName = EscapeUtils::EscapeDecodeL(iFileName); |
|
110 TPtrC decodedFileNamePtr(*decodedFileName); |
|
111 |
|
112 ret = iFile.Open(iRfs, decodedFileNamePtr, EFileRead | EFileShareAny); |
|
113 if (ret == KErrNotFound) |
|
114 { |
|
115 // Convert the error KErrNotFound to a file specific error |
|
116 ret = KErrPathNotFound; |
|
117 } |
|
118 else |
|
119 { |
|
120 // Use the decoded filename |
|
121 iFileName.Copy(decodedFileNamePtr); |
|
122 iFileName.ZeroTerminate(); |
|
123 } |
|
124 delete decodedFileName; |
|
125 } |
|
126 |
|
127 User::LeaveIfError(ret); |
|
128 iFileOpen = ETrue; |
|
129 |
|
130 // Get file size |
|
131 User::LeaveIfError(iFile.Size(iSize)); |
|
132 |
|
133 CActiveScheduler::Add(this); |
|
134 } |
|
135 |
|
136 |
|
137 // ----------------------------------------------------------------------------- |
|
138 // CFileHandler::NewL |
|
139 // Two-phased constructor. |
|
140 // ----------------------------------------------------------------------------- |
|
141 // |
|
142 CFileHandler* CFileHandler::NewL(const TUint16 *aUrl, |
|
143 TUint8 aMethod, |
|
144 TUint16 aTransId, |
|
145 TUint8 aLoadType, |
|
146 void *aLoadContext, |
|
147 NW_Url_RespCallback_t *aLoadCallback, |
|
148 CKFileLoader* aFileLoader) |
|
149 { |
|
150 CFileHandler* self = new( ELeave ) CFileHandler(aUrl, aMethod, aTransId, |
|
151 aLoadType, |
|
152 aLoadContext, aLoadCallback, |
|
153 aFileLoader); |
|
154 |
|
155 CleanupStack::PushL( self ); |
|
156 self->ConstructL(); |
|
157 CleanupStack::Pop(); |
|
158 |
|
159 return self; |
|
160 } |
|
161 |
|
162 |
|
163 // ----------------------------------------------------------------------------- |
|
164 // CFileHandler::~CFileHandler |
|
165 // Destructor. |
|
166 // ----------------------------------------------------------------------------- |
|
167 // |
|
168 CFileHandler::~CFileHandler() |
|
169 { |
|
170 if ((iFileName.Length() > 0) && (iFileName.Ptr() != NULL)) |
|
171 { |
|
172 delete (TUint16*) iFileName.Ptr(); |
|
173 } |
|
174 if (iFileOpen) |
|
175 { |
|
176 iFile.Close(); |
|
177 } |
|
178 if (iRfsOpen) |
|
179 { |
|
180 iRfs.Close(); |
|
181 } |
|
182 if(iContentType) |
|
183 { |
|
184 delete iContentType; |
|
185 } |
|
186 delete (TUint8*)iData.Ptr(); |
|
187 delete iRedirectedUrl; |
|
188 } |
|
189 |
|
190 |
|
191 // ----------------------------------------------------------------------------- |
|
192 // CFileHandler::RunL |
|
193 // Return the response after file loading from the File system is complete. |
|
194 // ----------------------------------------------------------------------------- |
|
195 // |
|
196 void CFileHandler::RunL() |
|
197 { |
|
198 switch (iStatus.Int()) |
|
199 { |
|
200 case KErrNone: |
|
201 { |
|
202 const TText8* wmltStr = (TText8*)"0"; |
|
203 TPtrC8 wmltPtr(wmltStr); |
|
204 const TText8* wmltcStr = (TText8*)"1"; |
|
205 TPtrC8 wmltcPtr(wmltcStr); |
|
206 const TText8* wmlaStr = (TText8*)"2"; |
|
207 TPtrC8 wmlaPtr(wmlaStr); |
|
208 const TText8* wmlacStr = (TText8*)"3"; |
|
209 TPtrC8 wmlacPtr(wmlacStr); |
|
210 |
|
211 _LIT(KContentTypeT,"text/vnd.wap.wml"); |
|
212 _LIT(KContentTypeTC,"text/vnd.wap.wmlc"); |
|
213 _LIT(KContentWMLSType,"application/vnd.wap.wmlscriptc"); |
|
214 _LIT(KContentWMLACType,"application/vnd.wap.wmlc"); |
|
215 |
|
216 TInt len = KContentWMLSType().Length(); |
|
217 TUint8* contentTypeString = new(ELeave) TUint8 [len + 1]; |
|
218 TPtrC8 script = iData.Right(1); |
|
219 if( script.operator==(wmltPtr) ) |
|
220 { |
|
221 TPtr8 contentTypeStringPtr(contentTypeString, KContentTypeT().Length() + 1); |
|
222 contentTypeStringPtr.Copy(KContentTypeT); |
|
223 contentTypeStringPtr.ZeroTerminate(); |
|
224 } |
|
225 else if(script.operator==(wmltcPtr)) |
|
226 { |
|
227 TPtr8 contentTypeStringPtr(contentTypeString, KContentTypeTC().Length() + 1); |
|
228 contentTypeStringPtr.Copy(KContentTypeTC); |
|
229 contentTypeStringPtr.ZeroTerminate(); |
|
230 } |
|
231 else if(script.operator==(wmlaPtr)) |
|
232 { |
|
233 TPtr8 contentTypeStringPtr(contentTypeString, KContentWMLSType().Length() + 1); |
|
234 contentTypeStringPtr.Copy(KContentWMLSType); |
|
235 contentTypeStringPtr.ZeroTerminate(); |
|
236 } |
|
237 else if(script.operator==(wmlacPtr)) |
|
238 { |
|
239 TPtr8 contentTypeStringPtr(contentTypeString, KContentWMLACType().Length() + 1); |
|
240 contentTypeStringPtr.Copy(KContentWMLACType); |
|
241 contentTypeStringPtr.ZeroTerminate(); |
|
242 } |
|
243 |
|
244 // Get the file's content encoding. |
|
245 //If there is charset in the file, use it. Otherwise, get it basing on the content type string |
|
246 TUint16 charset = HTTP_iso_8859_1; //default to latin-1 |
|
247 TBool bHasCharset = ETrue; |
|
248 TInt position = iData.LocateReverse('*'); |
|
249 TInt posDollar = iData.LocateReverse('$'); |
|
250 |
|
251 if((posDollar == KErrNotFound) || (posDollar < position)) //no charset was set |
|
252 { |
|
253 bHasCharset = EFalse; |
|
254 charset = ContentEncoding(contentTypeString); |
|
255 } |
|
256 else |
|
257 { |
|
258 TPtrC8 charsetfromfile = iData.Mid( posDollar + 1, (iData.Length() - (posDollar + 2))); |
|
259 for (int i = 0; supportedCharset[i].uid != 0; i++) |
|
260 { |
|
261 TPtrC8 charsetTemp(supportedCharset[i].charset); |
|
262 if (charsetTemp == charsetfromfile) |
|
263 { |
|
264 charset = supportedCharset[i].ianaEncoding; |
|
265 break; |
|
266 } |
|
267 } |
|
268 } |
|
269 |
|
270 // Check if it is a saved deck. |
|
271 // Put the "application saved page" string const and the |
|
272 // "ContentType" string in TPtrC8 to find if this is a saved page |
|
273 TPtrC8 httpSavedString(HTTP_application_saved_string); |
|
274 TPtrC8 contentString(contentTypeString); |
|
275 |
|
276 TUint index = contentString.FindF(httpSavedString); |
|
277 |
|
278 if ( !((0 == index) && ParseSavedDeck()) ) |
|
279 { |
|
280 // Not a saved deck, send a response |
|
281 //TPtr8 data( iData ); declared up |
|
282 // |
|
283 TUint contentLength = 0; |
|
284 |
|
285 const TUint16* responseUrl = (iRedirectedUrl == NULL) ? iUrl : iRedirectedUrl; |
|
286 |
|
287 |
|
288 if (iMethod == NW_URL_METHOD_GET) |
|
289 { |
|
290 TInt urlLen = 0; |
|
291 if(bHasCharset) |
|
292 { |
|
293 urlLen = posDollar - position; |
|
294 } |
|
295 else |
|
296 { |
|
297 urlLen = iData.Length() - position -1; |
|
298 } |
|
299 |
|
300 //R->fake the url |
|
301 HBufC* newUrl = HBufC::NewL( urlLen ); |
|
302 newUrl->Des().Copy(iData.Mid( position + 1, urlLen-1 )); |
|
303 newUrl->Des().ZeroTerminate(); |
|
304 |
|
305 // Transfer ownership before calling Response |
|
306 TUint8* data = new TUint8[position]; |
|
307 TPtr8 dataDes(data, position); |
|
308 dataDes.Copy(iData.Ptr(), position); |
|
309 iData.Set(NULL,0, 0); |
|
310 delete (TUint8*)iData.Ptr(); |
|
311 |
|
312 responseUrl = (TUint16*)newUrl->Ptr(); |
|
313 |
|
314 // Send the response |
|
315 iFileLoader->PartialResponse( (TUint16*)newUrl->Ptr(), dataDes, NULL, contentTypeString, NULL, NW_FALSE, // multipart information is missing. |
|
316 NULL, NULL, charset, NULL, Success, NW_URL_METHOD_GET, iTransId, 0 /*first chunk*/, NULL, dataDes.Length(), |
|
317 KErrNone, iLoadContext, iLoadCallback); |
|
318 delete newUrl; |
|
319 } |
|
320 |
|
321 // Send the close response |
|
322 iContentType = NULL; |
|
323 TPtr8 emptyData(NULL,0,0); |
|
324 contentTypeString = iContentType; |
|
325 |
|
326 iFileLoader->PartialResponse( responseUrl, emptyData, NULL, contentTypeString, NULL, NW_FALSE, // multipart information is missing |
|
327 NULL, NULL, charset, NULL, Success, iMethod, iTransId, -1 /*last chunk*/, NULL, contentLength, |
|
328 KErrNone, iLoadContext, iLoadCallback); |
|
329 } |
|
330 else |
|
331 { |
|
332 // No response sent with this content type string, |
|
333 // (so no subsequent delete) delete it here. |
|
334 delete contentTypeString; |
|
335 } |
|
336 } |
|
337 |
|
338 break; |
|
339 |
|
340 default: |
|
341 { |
|
342 // Send an error response back |
|
343 iFileLoader->PartialResponse(iTransId, iStatus.Int(), iLoadContext, iLoadCallback); |
|
344 } |
|
345 break; |
|
346 } // end of switch |
|
347 |
|
348 delete this; |
|
349 } |
|
350 |
|
351 |
|
352 // ----------------------------------------------------------------------------- |
|
353 // CFileHandler::DoCancel |
|
354 // Noop. File loading cannot be cancelled. |
|
355 // ----------------------------------------------------------------------------- |
|
356 // |
|
357 void CFileHandler::DoCancel() |
|
358 { |
|
359 } |
|
360 |
|
361 |
|
362 // ----------------------------------------------------------------------------- |
|
363 // CFileHandler::LoadFileL |
|
364 // Create a CFileHandler object and initiate the load. |
|
365 // ----------------------------------------------------------------------------- |
|
366 // |
|
367 void CFileHandler::LoadFileL(const TUint16 *aUrl, |
|
368 TUint16 aTransId, |
|
369 TUint8 aLoadType, |
|
370 void *aLoadContext, |
|
371 NW_Url_RespCallback_t *aLoadCallback, |
|
372 CKFileLoader* aFileLoader) |
|
373 { |
|
374 __ASSERT_DEBUG(aUrl != NULL, LoaderUtils::PanicLoader()); |
|
375 __ASSERT_DEBUG(aLoadCallback != NULL, LoaderUtils::PanicLoader()); |
|
376 |
|
377 // Create a file handler object |
|
378 CFileHandler* handler = CFileHandler::NewL(aUrl, NW_URL_METHOD_GET, |
|
379 aTransId, aLoadType, aLoadContext, aLoadCallback, aFileLoader); |
|
380 |
|
381 // Start reading the file |
|
382 if (handler->iSize > 0) |
|
383 { |
|
384 TUint8* data = NULL; |
|
385 data = new TUint8 [handler->iSize]; |
|
386 User::LeaveIfNull(data); |
|
387 handler->iData.Set(data, 0, handler->iSize); |
|
388 handler->iFile.Read(handler->iData, handler->iStatus); |
|
389 } |
|
390 |
|
391 handler->SetActive(); |
|
392 } |
|
393 |
|
394 |
|
395 // ----------------------------------------------------------------------------- |
|
396 // CFileHandler::LoadFileL |
|
397 // Create a CFileHandler object and initiate the load. |
|
398 // ----------------------------------------------------------------------------- |
|
399 // |
|
400 void CFileHandler::GetFileInfoL(const TUint16 *aUrl, |
|
401 TUint16 aTransId, |
|
402 TUint8 aLoadType, |
|
403 void *aLoadContext, |
|
404 NW_Url_RespCallback_t *aLoadCallback, |
|
405 CKFileLoader* aFileLoader) |
|
406 { |
|
407 __ASSERT_DEBUG(aUrl != NULL, LoaderUtils::PanicLoader()); |
|
408 __ASSERT_DEBUG(aLoadCallback != NULL, LoaderUtils::PanicLoader()); |
|
409 |
|
410 // Create a file handler object |
|
411 CFileHandler* handler = CFileHandler::NewL(aUrl, NW_URL_METHOD_HEAD, |
|
412 aTransId, aLoadType, aLoadContext, aLoadCallback, aFileLoader); |
|
413 |
|
414 // Start reading the file |
|
415 if (handler->iSize > 0) |
|
416 { |
|
417 TUint8* data = NULL; |
|
418 data = new TUint8 [handler->iSize]; |
|
419 User::LeaveIfNull(data); |
|
420 handler->iData.Set(data, 0, handler->iSize); |
|
421 handler->iFile.Read(handler->iData, handler->iStatus); |
|
422 } |
|
423 |
|
424 handler->SetActive(); |
|
425 } |
|
426 |
|
427 |
|
428 // ----------------------------------------------------------------------------- |
|
429 // CFileHandler::ContentTypeL |
|
430 // Determine the content type of the file. |
|
431 // ----------------------------------------------------------------------------- |
|
432 void CFileHandler::ContentTypeL(TUint8** aContentTypeString) |
|
433 { |
|
434 // part of string defined in "Exported mimetypes" section in BrowserRec.h |
|
435 __ASSERT_DEBUG(aContentTypeString != NULL, LoaderUtils::PanicLoader()); |
|
436 |
|
437 TDataRecognitionResult dataType; |
|
438 RApaLsSession apaSession; |
|
439 TInt ret; |
|
440 |
|
441 *aContentTypeString = NULL; |
|
442 User::LeaveIfError(apaSession.Connect()); |
|
443 // Ask the application architecture to find the file type |
|
444 ret = apaSession.RecognizeData(iFileName, iData, dataType); |
|
445 apaSession.Close(); |
|
446 |
|
447 if (ret == KErrNone && |
|
448 (dataType.iConfidence == CApaDataRecognizerType::ECertain) || |
|
449 (dataType.iConfidence == CApaDataRecognizerType::EProbable)) |
|
450 { |
|
451 // If the file type was found, try to match it to a known file type |
|
452 TPtrC8 mimeTypePtr = dataType.iDataType.Des8(); |
|
453 TInt len = mimeTypePtr.Length() + 1; |
|
454 *aContentTypeString = new(ELeave) TUint8 [len]; |
|
455 |
|
456 TPtr8 contentTypeStringPtr(*aContentTypeString, len); |
|
457 contentTypeStringPtr.Copy(mimeTypePtr); |
|
458 contentTypeStringPtr.ZeroTerminate(); |
|
459 return; |
|
460 } |
|
461 |
|
462 // Check if it is css |
|
463 _LIT(KCssExt, ".css"); |
|
464 TPtrC extPtr (iFileName.Right(iFileName.Length() - iFileName.LocateReverse('.'))); |
|
465 if (!extPtr.CompareF(KCssExt())) |
|
466 { |
|
467 TPtrC8 mimeTypePtr(HTTP_text_css_string); |
|
468 TInt len = mimeTypePtr.Length() + 1; |
|
469 *aContentTypeString = new(ELeave) TUint8 [len]; |
|
470 |
|
471 TPtr8 contentTypeStringPtr(*aContentTypeString, len); |
|
472 contentTypeStringPtr.Copy(mimeTypePtr); |
|
473 contentTypeStringPtr.ZeroTerminate(); |
|
474 return; |
|
475 } |
|
476 |
|
477 // Check if it is wbmp |
|
478 _LIT(KWbmpExt, ".wbmp"); |
|
479 extPtr.Set(iFileName.Right(iFileName.Length() - iFileName.LocateReverse('.'))); |
|
480 if (!extPtr.CompareF(KWbmpExt())) |
|
481 { |
|
482 TPtrC8 mimeTypePtr(HTTP_image_vnd_wap_wbmp_string); |
|
483 TInt len = mimeTypePtr.Length() + 1; |
|
484 *aContentTypeString = new(ELeave) TUint8 [len]; |
|
485 |
|
486 TPtr8 contentTypeStringPtr(*aContentTypeString, len); |
|
487 contentTypeStringPtr.Copy(mimeTypePtr); |
|
488 contentTypeStringPtr.ZeroTerminate(); |
|
489 return; |
|
490 } |
|
491 //R->ecma |
|
492 // Check if it is ecma |
|
493 /* |
|
494 _LIT(KEcmaScriptExt, ".es"); |
|
495 _LIT(KJavaScriptExt, ".js"); |
|
496 extPtr.Set(iFileName.Right(iFileName.Length() - iFileName.LocateReverse('.'))); |
|
497 if (!extPtr.CompareF(KEcmaScriptExt()) || !extPtr.CompareF(KJavaScriptExt())) |
|
498 { |
|
499 TPtrC8 mimeTypePtr(HTTP_text_ecmascript_string); |
|
500 TInt len = mimeTypePtr.Length() + 1; |
|
501 *aContentTypeString = new(ELeave) TUint8 [len]; |
|
502 |
|
503 TPtr8 contentTypeStringPtr(*aContentTypeString, len); |
|
504 contentTypeStringPtr.Copy(mimeTypePtr); |
|
505 contentTypeStringPtr.ZeroTerminate(); |
|
506 return; |
|
507 } |
|
508 */ |
|
509 // Check if it is a supported plugin |
|
510 //R->embed |
|
511 //CPluginHandler* pluginHandler = CPluginHandler::GetSingleton(); |
|
512 //NW_ASSERT (pluginHandler != NULL); // we should always have a plugin handler |
|
513 /* //R |
|
514 TUint16* mimeType16 = pluginHandler->GetPluginMimeTypeL(iFileName); |
|
515 if (mimeType16 != NULL) |
|
516 { |
|
517 // This file's extension is supported |
|
518 CleanupStack::PushL(mimeType16); |
|
519 TPtrC16 mimeTypePtr16(mimeType16); |
|
520 TUint8* mimeType8 = new(ELeave) TUint8 [mimeTypePtr16.Length() + 1]; |
|
521 TPtr8 mimeTypePtr8(mimeType8, 0, mimeTypePtr16.Length() + 1); |
|
522 mimeTypePtr8.Copy(mimeTypePtr16); |
|
523 mimeTypePtr8.ZeroTerminate(); |
|
524 CleanupStack::PopAndDestroy(); // mimeType16 |
|
525 *aContentTypeString = mimeType8; |
|
526 return; |
|
527 } |
|
528 */ |
|
529 User::Leave(KBrsrWmlbrowserBadContentType); |
|
530 } |
|
531 |
|
532 |
|
533 // ----------------------------------------------------------------------------- |
|
534 // CFileHandler::ContentEncoding |
|
535 // Determine the content encoding of the file. |
|
536 // ----------------------------------------------------------------------------- |
|
537 // |
|
538 TUint16 CFileHandler::ContentEncoding(TUint8* aContentTypeString) |
|
539 { |
|
540 // Assume Latin-1 for xhtml and wml. ucs2 for any other |
|
541 TUint16 charset = HTTP_iso_8859_1; |
|
542 |
|
543 TPtrC8 httpAppString(HTTP_application_vnd_wap_wmlc_string); |
|
544 TPtrC8 contentString(aContentTypeString); |
|
545 |
|
546 // Is the contentType a HTTP_application_vnd_wap_wmlc_string |
|
547 TUint index = contentString.FindF(httpAppString); |
|
548 if (index == 0) |
|
549 { |
|
550 // This is a HTTP_application_vnd_wap_wmlc_string |
|
551 charset = HTTP_iso_10646_ucs_2; |
|
552 } |
|
553 |
|
554 return charset; |
|
555 } |
|
556 |
|
557 |
|
558 // ----------------------------------------------------------------------------- |
|
559 // CFileHandler::GetFileNameL |
|
560 // Translate the file name from a URL to a valid file name in the system. |
|
561 // ----------------------------------------------------------------------------- |
|
562 // |
|
563 TBool CFileHandler::GetFileNameL() |
|
564 { |
|
565 // This function accepts URLs in the following format: |
|
566 // file://filename.xxx |
|
567 // file:///filename.xxx |
|
568 // file://c:/filename.xxx |
|
569 // file:///c:/filename.xxx |
|
570 // |
|
571 _LIT(KFileScheme, "file://"); |
|
572 _LIT(KDefaultDrivePath, "C:\\"); |
|
573 _LIT(KDefaultDriveInUrl, "C:/"); |
|
574 _LIT(KPathChar, "\\"); |
|
575 |
|
576 TUint16* name = NULL; |
|
577 TInt count; |
|
578 TInt index = 0; |
|
579 TBool drvLetter = EFalse; |
|
580 TUint16 c; |
|
581 |
|
582 // Verify the file scheme |
|
583 TPtrC urlPtr(iUrl); |
|
584 if (urlPtr.FindF(KFileScheme) != 0) |
|
585 { |
|
586 return EFalse; |
|
587 } |
|
588 urlPtr.Set(urlPtr.Mid(KFileScheme().Length())); |
|
589 |
|
590 // make sure there are enough characters in the filename before |
|
591 // trying to check them |
|
592 count = urlPtr.Length(); |
|
593 if(count == 0) |
|
594 { |
|
595 return EFalse; // no filename, so can't look at urlPtr[0] |
|
596 } |
|
597 |
|
598 // Skip the first '/' if there is one |
|
599 if (urlPtr[0] == '/') |
|
600 { |
|
601 urlPtr.Set(urlPtr.Mid(1)); |
|
602 } |
|
603 count = urlPtr.Length(); |
|
604 |
|
605 // Is there a drive letter? |
|
606 if(count > 1) |
|
607 { |
|
608 // can check for drive letter |
|
609 if (urlPtr[1 + index] == ':') |
|
610 { |
|
611 drvLetter = ETrue; |
|
612 } |
|
613 } |
|
614 if(drvLetter == EFalse) |
|
615 { |
|
616 // 3 additional characters for the string "c:\" |
|
617 count = urlPtr.Length() + 3; |
|
618 } |
|
619 name = new(ELeave) TUint16 [count]; |
|
620 CleanupStack::PushL(name); |
|
621 iFileName.Set(name, 0, count); |
|
622 if (!drvLetter) |
|
623 { |
|
624 // If there is no drive letter, add "C:\" |
|
625 iRedirectedUrl = new(ELeave) TUint16[count + 1 + KFileScheme().Length()]; |
|
626 TPtr redirectedUrlPtr(iRedirectedUrl, count + 1 + KFileScheme().Length()); |
|
627 redirectedUrlPtr.Copy(KFileScheme()); |
|
628 redirectedUrlPtr.Append(KDefaultDriveInUrl); |
|
629 redirectedUrlPtr.Append(urlPtr); |
|
630 redirectedUrlPtr.ZeroTerminate(); |
|
631 iFileName.Append(KDefaultDrivePath); |
|
632 } |
|
633 |
|
634 TBool fragment(EFalse); |
|
635 // Convert relative path containing /./ and /../ to absolute path |
|
636 for (; index < urlPtr.Length() && !fragment; index ++) |
|
637 { |
|
638 switch(urlPtr[index]) |
|
639 { |
|
640 case '#': //Check if there is a fragment '#' |
|
641 { |
|
642 fragment = ETrue; |
|
643 continue; // Just stop there |
|
644 } |
|
645 |
|
646 case '/': |
|
647 { |
|
648 iFileName.Append(KPathChar); |
|
649 break; |
|
650 } |
|
651 case '.': |
|
652 { |
|
653 if (index > 1 && urlPtr[index - 1] == '/') |
|
654 { |
|
655 if (index < count - 1 && urlPtr[index + 1] == '/') |
|
656 { |
|
657 index ++; // skip ./ |
|
658 break; |
|
659 } |
|
660 if (index > 2 && index < count - 3 && |
|
661 urlPtr[index + 1] == '.' && urlPtr[index + 2] == '/') |
|
662 { |
|
663 TInt i = index - 2; |
|
664 |
|
665 for (; i > 0 && urlPtr[i] != '/'; i--) {} // skip /../ |
|
666 |
|
667 iFileName.SetLength(iFileName.Length() - (index - i)); |
|
668 index += 2; |
|
669 break; |
|
670 } |
|
671 } |
|
672 } |
|
673 // no break |
|
674 //lint -fallthrough |
|
675 |
|
676 default: |
|
677 { |
|
678 c = urlPtr[index]; |
|
679 iFileName.Append(&c, 1); |
|
680 break; |
|
681 } |
|
682 } // end of switch |
|
683 } |
|
684 CleanupStack::Pop(); // name |
|
685 return ETrue; |
|
686 } |
|
687 |
|
688 |
|
689 // ----------------------------------------------------------------------------- |
|
690 // CFileHandler::ParseSavedDeck |
|
691 // Determine if the file is a saved deck or not. If it is saved deck, parse the file. |
|
692 // ----------------------------------------------------------------------------- |
|
693 // |
|
694 TBool CFileHandler::ParseSavedDeck() |
|
695 { |
|
696 TPtr8 responseData(NULL,0,0); |
|
697 TPtr responseUrl(NULL, 0, 0); |
|
698 TPtr8 contentTypeString(NULL, 0, 0); |
|
699 TUint charset; |
|
700 TBool isSavedDeck; |
|
701 TPtrC8 dataPtr(iData.Ptr(), iData.Length()); |
|
702 TPtrC16 urlPtr(iUrl, User::StringLength(iUrl)); |
|
703 |
|
704 // Create a CSavedDeckHandler object to parse the file |
|
705 TInt ret = CSavedDeckHandler::ParseSavedDeck(dataPtr, urlPtr, responseData, |
|
706 responseUrl, contentTypeString, charset, isSavedDeck); |
|
707 |
|
708 if (isSavedDeck) |
|
709 { |
|
710 // It is a saved deck |
|
711 if (ret == KErrNone) |
|
712 { |
|
713 TUint8* data = (TUint8*)iData.Ptr(); |
|
714 delete data; |
|
715 // Transfer ownership before calling Response |
|
716 iData.Set(NULL, 0, 0); |
|
717 // copy contentTypeString for the second (closing) response |
|
718 TUint8* tempContentTypeString = NULL; |
|
719 tempContentTypeString = (TUint8*)NW_Mem_Malloc( contentTypeString.Length() + 1 ); |
|
720 if( tempContentTypeString ) |
|
721 { |
|
722 NW_Mem_memcpy( tempContentTypeString, contentTypeString.Ptr(), contentTypeString.Length() ); |
|
723 tempContentTypeString[ contentTypeString.Length() ] = 0; |
|
724 // Send the first part of the file as the response |
|
725 iFileLoader->PartialResponse((TUint16*)responseUrl.Ptr(), responseData, NULL, |
|
726 (TUint8*)contentTypeString.Ptr(), NULL, NW_FALSE, // multipart information is missing. |
|
727 NULL, NULL, (TUint16)charset, NULL, Success, 0, iTransId, 0 /*first chunk*/, NULL, responseData.Length(), |
|
728 KErrNone, iLoadContext, iLoadCallback); |
|
729 |
|
730 // Send closing response. pass tempContentTypeString ownership |
|
731 TPtr8 emptyResponseData(NULL,0,0); |
|
732 iFileLoader->PartialResponse((TUint16*)responseUrl.Ptr(), emptyResponseData, NULL, |
|
733 tempContentTypeString, NULL, NW_FALSE, // multipart information is missing. |
|
734 NULL, NULL, (TUint16)charset, NULL, Success, 0, iTransId, -1/*last chunk*/, NULL, 0, |
|
735 KErrNone, iLoadContext, iLoadCallback); |
|
736 } |
|
737 delete (TUint16*)responseUrl.Ptr(); |
|
738 } |
|
739 else |
|
740 { |
|
741 // Send an error response |
|
742 iFileLoader->PartialResponse(iTransId, ret, iLoadContext, iLoadCallback); |
|
743 } |
|
744 } |
|
745 return isSavedDeck; |
|
746 } |
|
747 |
|
748 |
|
749 // ========================== OTHER EXPORTED FUNCTIONS ========================= |
|
750 |
|
751 // End of File |
|