0
|
1 |
/*
|
|
2 |
* Copyright (c) 2009 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:
|
|
15 |
*
|
|
16 |
*/
|
|
17 |
|
|
18 |
|
|
19 |
#include <emulator.h>
|
|
20 |
#include <uri16.h>
|
|
21 |
#include <apmrec.h>
|
|
22 |
#include <apgcli.h>
|
|
23 |
#include "ResourceHandle.h"
|
|
24 |
#include "W32FileConnection.h"
|
|
25 |
#include "W32FileReader.h"
|
|
26 |
#include "ResourceHandleManagerSymbian.h"
|
|
27 |
#include "StaticObjectsContainer.h"
|
|
28 |
#include "ResourceRequest.h"
|
|
29 |
#include <BrCtlSpecialLoadObserver.h>
|
|
30 |
#include "brctl.h"
|
|
31 |
#include "DeprecatedString.h"
|
|
32 |
HANDLE iFh;
|
|
33 |
const TInt KFileReadChunkSize = 23920; // bytes
|
|
34 |
_LIT8( KResLoaderLatin1, "iso-8859-1" );
|
|
35 |
_LIT8( KResLoaderUCS2, "iso-10646-ucs-2" );
|
|
36 |
_LIT8( KResLoaderWapWmlc, "application/vnd.wap.wmlc" );
|
|
37 |
|
|
38 |
|
|
39 |
static int s_fileTransactionsCount = 0;
|
|
40 |
|
|
41 |
using namespace WebCore;
|
|
42 |
|
|
43 |
CW32FileConnection::CW32FileConnection(ResourceHandle* _handle) : MUrlConnection(_handle)
|
|
44 |
{
|
|
45 |
m_fileName = 0;
|
|
46 |
m_fileReader = 0;
|
|
47 |
s_fileTransactionsCount++;
|
|
48 |
m_chunkIndex = 0;
|
|
49 |
m_charset = 0;
|
|
50 |
m_contentType = 0;
|
|
51 |
}
|
|
52 |
|
|
53 |
CW32FileConnection::~CW32FileConnection()
|
|
54 |
{
|
|
55 |
::CloseHandle(iFh);
|
|
56 |
s_fileTransactionsCount--;
|
|
57 |
delete m_fileName;
|
|
58 |
delete m_fileReader;
|
|
59 |
delete m_charset;
|
|
60 |
delete m_contentType;
|
|
61 |
// m_file.Close();
|
|
62 |
}
|
|
63 |
|
|
64 |
TInt CW32FileConnection::submit()
|
|
65 |
{
|
|
66 |
TRAPD(error, submitL());
|
|
67 |
return error;
|
|
68 |
}
|
|
69 |
|
|
70 |
//========================================================================
|
|
71 |
// CW32FileConnection::submitL
|
|
72 |
//========================================================================
|
|
73 |
TInt CW32FileConnection::submitL()
|
|
74 |
{
|
|
75 |
TInt error(KErrNone);
|
|
76 |
TPtrC8 urlPtr( m_handle->request().url().des() );
|
|
77 |
m_fileName = parseFileNameL( urlPtr );
|
|
78 |
if (m_fileName) {
|
|
79 |
iFh = Emulator::CreateFile(m_fileName->Des().PtrZ(), GENERIC_READ,
|
|
80 |
FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
|
|
81 |
|
|
82 |
if (iFh == INVALID_HANDLE_VALUE) {
|
|
83 |
error = Emulator::LastError();
|
|
84 |
}
|
|
85 |
else {
|
|
86 |
TUint32 fileSize = ::GetFileSize(iFh, NULL); //W32 call
|
|
87 |
m_maxSize = fileSize;
|
|
88 |
if (m_fileReader == NULL) {
|
|
89 |
m_fileReader = CW32FileReader::NewL(iFh, KFileReadChunkSize, this);
|
|
90 |
}
|
|
91 |
m_fileReader->StartReading();
|
|
92 |
}
|
|
93 |
}
|
|
94 |
else {
|
|
95 |
error = KErrArgument;
|
|
96 |
}
|
|
97 |
|
|
98 |
User::LeaveIfError(error);
|
|
99 |
}
|
|
100 |
|
|
101 |
|
|
102 |
// -----------------------------------------------------------------------------
|
|
103 |
// CW32FileConnection::parseFileNameL
|
|
104 |
// Translate the file name from a URL to a valid file name in the system.
|
|
105 |
// -----------------------------------------------------------------------------
|
|
106 |
//
|
|
107 |
HBufC* CW32FileConnection::parseFileNameL(const TDesC8& aUrl )
|
|
108 |
{
|
|
109 |
//To convert TPtrC8 to Tptr16
|
|
110 |
TBufC8<200> Urlbuf(aUrl);
|
|
111 |
HBufC16* buf16 = HBufC16::NewL(256);//delete buf16 dont forget.
|
|
112 |
TPtr16 bufptr16(buf16->Des());
|
|
113 |
bufptr16.Copy(Urlbuf.Des());
|
|
114 |
TInt status;
|
|
115 |
TUriParser parser;
|
|
116 |
HBufC* fileName = NULL;
|
|
117 |
status = parser.Parse( bufptr16 );
|
|
118 |
if( status == KErrNone ) {
|
|
119 |
// this must be the drive letter
|
|
120 |
TPtrC host = parser.Extract( EUriHost );
|
|
121 |
TPtrC path = parser.Extract( EUriPath );
|
|
122 |
// add missing ":"
|
|
123 |
fileName = HBufC::NewL( (host.Length()?host.Length()+1:0) + path.Length()+ 1/*0 terminated*/ );
|
|
124 |
TPtr fileNamePtr( fileName->Des() );
|
|
125 |
if( host.Length() == 1 ) {
|
|
126 |
// fix c to c:
|
|
127 |
fileNamePtr.Copy( host );
|
|
128 |
fileNamePtr.Append( _L(":") );
|
|
129 |
}
|
|
130 |
else {
|
|
131 |
// according to symbian uri parser in case of
|
|
132 |
// file:///c:\foo.html
|
|
133 |
// host: /c:\foo.html
|
|
134 |
// path: /c:\foo.html
|
|
135 |
// remove: / from the begenning of the path
|
|
136 |
if( path.Length() > 2 && path[0] == '/' && path[2] == ':' ) {
|
|
137 |
// move pointer from "/c:\" to "c:\"
|
|
138 |
path.Set( path.Mid( 1 ) );
|
|
139 |
|
|
140 |
}
|
|
141 |
}
|
|
142 |
fileNamePtr.Append( path );
|
|
143 |
// fix slashes
|
|
144 |
for( TInt i = 0; i < fileNamePtr.Length(); i++ ) {
|
|
145 |
if( fileNamePtr[ i ] == '/' ) {
|
|
146 |
fileNamePtr[ i ] = '\\';
|
|
147 |
}
|
|
148 |
}
|
|
149 |
// then replace possible %20-sequences with blank
|
|
150 |
TInt pos = 0;
|
|
151 |
_LIT(KWinSP, "%20");
|
|
152 |
_LIT(KSpace, " ");
|
|
153 |
TInt len = (&KWinSP)->Length();
|
|
154 |
while ((pos = fileNamePtr.FindC(KWinSP)) != KErrNotFound) {
|
|
155 |
fileNamePtr.Replace(pos, (&KWinSP)->Length(), KSpace);
|
|
156 |
}
|
|
157 |
// return fileName16;
|
|
158 |
// CleanupStack::PushL( fileName16 );
|
|
159 |
delete buf16;
|
|
160 |
return fileName;
|
|
161 |
}
|
|
162 |
}
|
|
163 |
void CW32FileConnection::cancel()
|
|
164 |
{
|
|
165 |
if( m_fileReader ) {
|
|
166 |
m_fileReader->StopReading();
|
|
167 |
}
|
|
168 |
}
|
|
169 |
|
|
170 |
void CW32FileConnection::download(WebCore::ResourceHandle* handle,
|
|
171 |
const WebCore::ResourceRequest& request,
|
|
172 |
const WebCore::ResourceResponse& response)
|
|
173 |
{
|
|
174 |
// stop reading and close the file
|
|
175 |
m_fileReader->StopReading();
|
|
176 |
m_cancelled = true;
|
|
177 |
::CloseHandle(iFh); //windows call
|
|
178 |
// send data to the host application
|
|
179 |
MBrCtlSpecialLoadObserver* loadObserver = StaticObjectsContainer::instance()->brctl()->brCtlSpecialLoadObserver();
|
|
180 |
if(loadObserver) {
|
|
181 |
RArray<TUint> typeArray;
|
|
182 |
CDesCArrayFlat* desArray = new (ELeave) CDesCArrayFlat(4);
|
|
183 |
CleanupStack::PushL(desArray);
|
|
184 |
//
|
|
185 |
HBufC* url = HBufC::NewLC(handle->request().url().url().length());
|
|
186 |
url->Des().Copy(handle->request().url().des());
|
|
187 |
typeArray.Append(EParamRequestUrl);
|
|
188 |
desArray->AppendL(*url);
|
|
189 |
|
|
190 |
typeArray.Append(EParamCharset);
|
|
191 |
desArray->AppendL(*m_charset);
|
|
192 |
|
|
193 |
typeArray.Append(EParamReceivedContentType);
|
|
194 |
desArray->AppendL(*m_contentType);
|
|
195 |
|
|
196 |
typeArray.Append(EParamLocalFileName);
|
|
197 |
desArray->AppendL(*m_fileName);
|
|
198 |
//
|
|
199 |
loadObserver->HandleDownloadL(&typeArray, desArray);
|
|
200 |
//
|
|
201 |
typeArray.Close();
|
|
202 |
desArray->Reset();
|
|
203 |
CleanupStack::PopAndDestroy(2); // desArray, url
|
|
204 |
}
|
|
205 |
}
|
|
206 |
|
|
207 |
// -----------------------------------------------------------------------------
|
|
208 |
// CW32FileConnection::contentTypeL
|
|
209 |
// Determine the content type of the file.
|
|
210 |
// -----------------------------------------------------------------------------
|
|
211 |
HBufC8* CW32FileConnection::contentTypeL()
|
|
212 |
{
|
|
213 |
TPtrC8 contentTypePtr;
|
|
214 |
HBufC8* contentType = NULL;
|
|
215 |
TDataRecognitionResult dataType;
|
|
216 |
RApaLsSession apaSession;
|
|
217 |
TInt ret;
|
|
218 |
|
|
219 |
User::LeaveIfError( apaSession.Connect() );
|
|
220 |
// Ask the application architecture to find the file type
|
|
221 |
TPtrC8 chunkPtr;
|
|
222 |
|
|
223 |
m_fileReader->GetChunkBuffer( chunkPtr );
|
|
224 |
ret = apaSession.RecognizeData( m_fileName->Des(), chunkPtr, dataType );
|
|
225 |
apaSession.Close();
|
|
226 |
|
|
227 |
if( ret == KErrNone &&
|
|
228 |
( dataType.iConfidence == CApaDataRecognizerType::ECertain ) ||
|
|
229 |
( dataType.iConfidence == CApaDataRecognizerType::EProbable ) ) {
|
|
230 |
// If the file type was found, try to match it to a known file type
|
|
231 |
contentTypePtr.Set( dataType.iDataType.Des8() );
|
|
232 |
}
|
|
233 |
else {
|
|
234 |
// extensions
|
|
235 |
_LIT( KCssExt, ".css" );
|
|
236 |
_LIT(KWbmpExt, ".wbmp");
|
|
237 |
_LIT(KEcmaScriptExt, ".es");
|
|
238 |
_LIT(KJavaScriptExt, ".js");
|
|
239 |
|
|
240 |
TPtrC extPtr( m_fileName->Right( m_fileName->Length() - m_fileName->LocateReverse('.') ) );
|
|
241 |
|
|
242 |
if( extPtr.CompareF( KCssExt() ) == 0 ) {
|
|
243 |
contentTypePtr.Set( _L8( "text/css" ) );
|
|
244 |
}
|
|
245 |
else if( extPtr.CompareF( KWbmpExt() ) == 0 ) {
|
|
246 |
contentTypePtr.Set( _L8( "image/vnd.wap.wbmp" ) );
|
|
247 |
}
|
|
248 |
else if( extPtr.CompareF( KEcmaScriptExt() ) == 0 ||
|
|
249 |
extPtr.CompareF( KJavaScriptExt() ) == 0 ) {
|
|
250 |
contentTypePtr.Set( _L8( "text/ecmascript" ) );
|
|
251 |
}
|
|
252 |
|
|
253 |
}
|
|
254 |
if( contentTypePtr.Length() ) {
|
|
255 |
contentType = HBufC8::NewL( contentTypePtr.Length() );
|
|
256 |
contentType->Des().Copy( contentTypePtr );
|
|
257 |
}
|
|
258 |
return contentType;
|
|
259 |
}
|
|
260 |
|
|
261 |
// -----------------------------------------------------------------------------
|
|
262 |
// CW32FileConnection::contentEncoding
|
|
263 |
// Determine the content encoding of the file.
|
|
264 |
// -----------------------------------------------------------------------------
|
|
265 |
//
|
|
266 |
TPtrC8 CW32FileConnection::contentEncoding(const TDesC8& aContentTypeString ) const
|
|
267 |
{
|
|
268 |
// Assume Latin-1 for xhtml and html. ucs2 for any other
|
|
269 |
TPtrC8 charset( KResLoaderLatin1 );
|
|
270 |
|
|
271 |
TPtrC8 httpAppString( KResLoaderWapWmlc );
|
|
272 |
TPtrC8 contentString( aContentTypeString );
|
|
273 |
|
|
274 |
// Is the contentType a HTTP_application_vnd_wap_wmlc_string
|
|
275 |
TUint index = contentString.FindF( httpAppString );
|
|
276 |
if( index == 0 ) {
|
|
277 |
// This is a HTTP_application_vnd_wap_wmlc_string
|
|
278 |
charset.Set( KResLoaderUCS2 );
|
|
279 |
}
|
|
280 |
return charset;
|
|
281 |
}
|
|
282 |
|
|
283 |
void CW32FileConnection::response()
|
|
284 |
{
|
|
285 |
TRAPD(error, responseL());
|
|
286 |
if (error) {
|
|
287 |
complete(error);
|
|
288 |
}
|
|
289 |
}
|
|
290 |
|
|
291 |
void CW32FileConnection::responseL()
|
|
292 |
{
|
|
293 |
if (m_chunkIndex == 0 ) {
|
|
294 |
HBufC8* contentType = contentTypeL();
|
|
295 |
|
|
296 |
if( contentType ) {
|
|
297 |
m_contentType = HBufC::NewL(contentType->Length());
|
|
298 |
m_contentType->Des().Copy(*contentType);
|
|
299 |
|
|
300 |
TPtrC8 contentEncodingPtr( contentEncoding( contentType->Des() ) );
|
|
301 |
ResourceResponse response(m_handle->request().url().des(), contentType->Des(), m_maxSize, contentEncodingPtr, String() );
|
|
302 |
|
|
303 |
|
|
304 |
const TDesC& charset = response.textEncodingName().des();
|
|
305 |
m_charset = charset.AllocL();
|
|
306 |
response.setHTTPStatusCode(200);
|
|
307 |
|
|
308 |
CResourceHandleManager::self()->receivedResponse(m_handle, response, this);
|
|
309 |
}
|
|
310 |
}
|
|
311 |
// If it is not Browser content, reading the file is canceled in CW32FileConnection::download().
|
|
312 |
if (!m_cancelled) {
|
|
313 |
TPtrC8 chunkPtr;
|
|
314 |
m_fileReader->GetChunkBuffer( chunkPtr );
|
|
315 |
m_chunkIndex++;
|
|
316 |
CResourceHandleManager::self()->receivedData(m_handle, chunkPtr, m_maxSize, this);
|
|
317 |
}
|
|
318 |
}
|
|
319 |
|
|
320 |
void CW32FileConnection::complete(int error)
|
|
321 |
{
|
|
322 |
CResourceHandleManager::self()->receivedFinished(m_handle, error, this);
|
|
323 |
derefHandle();
|
|
324 |
}
|
|
325 |
|
|
326 |
|
|
327 |
// end of file
|