diff -r 000000000000 -r dd21522fd290 webengine/osswebengine/WebCore/platform/network/symbian/DataConnection.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/webengine/osswebengine/WebCore/platform/network/symbian/DataConnection.cpp Mon Mar 30 12:54:55 2009 +0300 @@ -0,0 +1,211 @@ +/* +* Copyright (c) 2007 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of the License "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* +*/ + +#include +#include +#include +#include +#include +#include +#include "ResourceHandle.h" +#include "ResourceRequest.h" +#include "DataConnection.h" +#include "FileReader.h" +#include "ResourceHandleManagerSymbian.h" +#include "StaticObjectsContainer.h" + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS +_LIT8( KDefaultCharset, "iso-8859-1" ); +_LIT8( KDefaultContentType, "text/plain" ); +_LIT8( KDataScheme, "data:" ); +_LIT8( KContentTypeKey, "content type:" ); +_LIT8( KCharsetKey, "charset=" ); + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +static int s_dataTransactionsCount = 0; + +using namespace WebCore; + +DataConnection::DataConnection(ResourceHandle* _handle) : MUrlConnection(_handle) +{ + s_dataTransactionsCount++; + m_scheduler = NULL; + m_maxSize = 0; +} + +DataConnection::~DataConnection() +{ + s_dataTransactionsCount--; + if (m_scheduler) { + m_scheduler->Cancel(); + delete m_scheduler; + } +} + +int DataConnection::submit() +{ + TRAPD(error, submitL()); + return error; +} + +void DataConnection::submitL() +{ + m_scheduler = CPeriodic::NewL( CActive::EPriorityStandard ); + m_scheduler->Start( 0, 0, TCallBack( &sendResponseCb, this ) ); +} + +void DataConnection::parseUrlLC(HBufC8*& contentType, HBufC8*& encoding, HBufC8*& body) +{ + TPtrC8 url = m_handle->request().url().des(); + // set content type and content encoding + // parse url to get header information + // http://www.faqs.org/rfcs/rfc2397.html + // 3. Syntax + + // dataurl := "data:" [ mediatype ] [ ";base64" ] "," data + // mediatype := [ type "/" subtype ] *( ";" parameter ) + // data := *urlchar + // parameter := attribute "=" value + // + // data:text/plain;charset=iso-8859-7,%be%fg%be + + TPtrC8 urlPtr8 = m_handle->request().url().des(); + TInt colonPos( urlPtr8.Locate( ',' ) ); + if( colonPos != KErrNotFound ) { + // set header including , + TPtrC8 headersStr( urlPtr8.Left( colonPos + 1 ) ); + // cut off scheme data: + headersStr.Set( headersStr.Mid( KDataScheme().Length() ) ); + // check for ;base64 + TBool base64( headersStr.Find( _L8( ";base64" ) ) != KErrNotFound ); + // check for ; + TInt semicolonPos; + do { + semicolonPos = headersStr.Locate( ';' ); + // no semicolon means one mediatype. set semiPos to the end of the str + // unless we are at the end of the string + if( headersStr.Length() > 1 ) { + semicolonPos = semicolonPos == -1 ? headersStr.Length() - 1 : semicolonPos; + } + if( semicolonPos != -1 ) { + // str = text/plain + TPtrC8 str( headersStr.Left( semicolonPos ) ); + if( str.Locate( '/' ) != KErrNotFound ) { + contentType = str.AllocLC(); + } + else if( str.Find( KCharsetKey ) == 0 ) { + encoding = (str.Mid( KCharsetKey().Length()).AllocLC()); + } + // headersStr = charset=iso-8859-7,%be%fg%be + headersStr.Set( headersStr.Mid( semicolonPos + 1 ) ); + } + } + while( semicolonPos != KErrNotFound ); + // simulate header strings + // content type: text/html + // charset: iso-8859-1 + if (contentType == NULL) { + contentType = KDefaultContentType().AllocLC(); + } + if (encoding == NULL) { + encoding = KDefaultCharset().AllocLC(); + } + + // make sure there is stuff to decode + if( ( colonPos + 1 ) < urlPtr8.Length() ) { + TBool ok( EFalse ); + TPtrC8 data( urlPtr8.Mid( colonPos + 1 ) ); + // decode body + if( base64 ) { + // allocate twice as big buffer for decoded string + body = HBufC8::NewLC( 2 * data.Length() ); + TPtr8 decodedBody( body->Des() ); + // urlPtr8 + TImCodecB64 codec; + codec.Initialise(); + ok = codec.Decode( data, decodedBody ); + } + if( !ok ) { // if not base64, simple copy + if( !body ) { + body = HBufC8::NewLC( data.Length() ); + } + body->Des().Copy( data ); + } + } + } + m_maxSize = body->Length(); +} + +void DataConnection::cancel() +{ + if (m_scheduler) { + m_scheduler->Cancel(); + delete m_scheduler; + m_scheduler = NULL; + } +} + +void DataConnection::download(WebCore::ResourceHandle* handle, + const WebCore::ResourceRequest& request, + const WebCore::ResourceResponse& response) +{ + __ASSERT_ALWAYS(EFalse, User::Panic(_L("Resource Loader"), KErrArgument)); +} + +TInt DataConnection::sendResponseCb(TAny* aPtr) +{ + DataConnection* self = static_cast(aPtr); + TRAPD(error, self->sendResponseL()); + if (error != KErrNone) { + CResourceHandleManager::self()->receivedFinished(self->m_handle, error, self); + } + return KErrNone; +} + +void DataConnection::sendResponseL() +{ + m_scheduler->Cancel(); + delete m_scheduler; + m_scheduler = NULL; + + HBufC8* contentType = NULL; + HBufC8* encoding = NULL; + HBufC8* body = NULL; + parseUrlLC(contentType, encoding, body); + + ResourceResponse response(m_handle->request().url().des(), contentType->Des(), body->Length(), encoding->Des(), String() ); + CResourceHandleManager::self()->receivedResponse(m_handle, response, this); + CResourceHandleManager::self()->receivedData(m_handle, body->Des(), body->Length(), this); + CResourceHandleManager::self()->receivedFinished(m_handle, KErrNone, this); + CleanupStack::PopAndDestroy(3); // contentType, encoding, body + derefHandle(); + } + +// end of file