/*
* Copyright (c) 2003 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: Handler for loading file scheme.
*
*/
// INCLUDE FILES
#include <e32std.h>
#include <e32base.h>
#include <uri16.h>
#include <apmrec.h>
#include <apgcli.h>
#include "fileloader_csaveddeckhandler.h"
#include "fileloader_cfileloader.h"
#include "urlloader_loaderutils.h"
#include "nwx_http_defs.h"
#include "nwx_settings.h"
// EXTERNAL DATA STRUCTURES
// EXTERNAL FUNCTION PROTOTYPES
// CONSTANTS
_LIT8(KUtf8, "utf-8");
_LIT8(KUsAscii, "us-ascii");
_LIT8(KIso10646Ucs2, "iso-10646-ucs-2");
_LIT8(KIso88591, "iso-8859-1");
_LIT8(KBig5, "big5");
_LIT8(KGb2312, "gb2312");
_LIT8(KIso88592, "iso-8859-2");
_LIT8(KIso88593, "iso-8859-3");
_LIT8(KIso88594, "iso-8859-4");
_LIT8(KIso88595, "iso-8859-5");
_LIT8(KIso88596, "iso-8859-6");
_LIT8(KIso88597, "iso-8859-7");
_LIT8(KIso88598, "iso-8859-8");
_LIT8(KIso88599, "iso-8859-9");
_LIT8(KShiftJIS, "shift_JIS");
_LIT8(KWindows1250, "windows-1250");
_LIT8(KWindows1251, "windows-1251");
_LIT8(KWindows1253, "windows-1253");
_LIT8(KWindows1254, "windows-1254");
_LIT8(KWindows1255, "windows-1255");
_LIT8(KWindows1256, "windows-1256");
_LIT8(KWindows1257, "windows-1257");
_LIT8(KTis620, "Tis-620");
_LIT8(KJisX0201_1997, "jis_x0201-1997");
_LIT8(KJisX0208_1997, "jis_x0208-1997");
_LIT8(KIso2022Jp, "iso-2022-jp");
_LIT8(KEucJp, "euc-jp");
_LIT8(KWindows874, "windows-874");
_LIT8(KOI8R, "koi8-r");
_LIT8(KOI8U, "koi8-u");
// MACROS
// LOCAL CONSTANTS AND MACROS
// MODULE DATA STRUCTURES
// LOCAL FUNCTION PROTOTYPES
// FORWARD DECLARATIONS
// ============================= LOCAL FUNCTIONS ===============================
// ============================ MEMBER FUNCTIONS ===============================
// -----------------------------------------------------------------------------
// CSavedDeckPart::Reset
// Zero out all members of the structure CSavedDeckPart.
// -----------------------------------------------------------------------------
//
void CSavedDeckPart::Reset()
{
iUrl.Set(NULL, 0);
iData.Set(NULL, 0);
iContentTypeString.Set(NULL, 0);
iCharset = 0;
iOriCharset = 0;
}
// -----------------------------------------------------------------------------
// CSavedDeckHandler::CSavedDeckHandler
// C++ default constructor can NOT contain any code, that
// might leave.
// -----------------------------------------------------------------------------
//
CSavedDeckHandler::CSavedDeckHandler(TPtrC8& aData) : iData(aData), iDataReader(aData)
{
}
// -----------------------------------------------------------------------------
// CSavedDeckHandler::NewLC
// Two-phased constructor.
// -----------------------------------------------------------------------------
//
CSavedDeckHandler* CSavedDeckHandler::NewLC(TPtrC8& aData)
{
CSavedDeckHandler* self = new( ELeave ) CSavedDeckHandler(aData);
CleanupStack::PushL( self );
return self;
}
// -----------------------------------------------------------------------------
// CSavedDeckHandler::~CSavedDeckHandler
// Destructor.
// -----------------------------------------------------------------------------
//
CSavedDeckHandler::~CSavedDeckHandler()
{
}
// -----------------------------------------------------------------------------
// CSavedDeckHandler::ParseSavedDeck
// Parse the saved deck buffer into the parts and store each part in cache.
// -----------------------------------------------------------------------------
//
TInt CSavedDeckHandler::ParseSavedDeck(TPtrC8& aData, TPtrC& aRequestUrl,
TPtr8& aResponseData,
TPtr& aResponseUrl,
TPtr8& aContentTypeString,
TUint& aCharset, TBool& aSavedDeck)
{
TRAPD(ret, ParseSavedDeckL(aData, aRequestUrl, aResponseData, aResponseUrl,
aContentTypeString, aCharset, aSavedDeck));
LoaderUtils::LogLoaderEvents(ELogTypeSavedDeck, ret);
return ret;
}
// -----------------------------------------------------------------------------
// CSavedDeckHandler::ParseSavedDeckL
// Parse the saved deck buffer into the parts and store each part in cache.
// -----------------------------------------------------------------------------
//
void CSavedDeckHandler::ParseSavedDeckL(TPtrC8& aData, TPtrC& aRequestUrl,
TPtr8& aResponseData,
TPtr& aResponseUrl,
TPtr8& aContentTypeString,
TUint& aCharset, TBool& aSavedDeck)
{
// Is this a SavedDeck?
aSavedDeck = IsSavedDeck(aRequestUrl);
if (!(aSavedDeck))
{
return;
}
CSavedDeckHandler* self = CSavedDeckHandler::NewLC(aData);
TUint i;
CSavedDeckPart savedDeckPart;
// Get the number of parts
TUint count = self->GetUintFromBuffer(self->iDataReader);
for (i = 0; i < count; i++)
{
self->GetNextPartL(savedDeckPart);
if (i == 0)
{
NW_Settings_SetOriginalEncoding(savedDeckPart.iOriCharset);
// First time through loop prepare and then push aResponseData,
// aResponseUrl, aContentTypeString onto CleanupStack
self->PrepareResponseLC(savedDeckPart, aResponseData, aResponseUrl,
aContentTypeString, aCharset);
}
else
{
self->LoadPartToCacheL( savedDeckPart);
}
}
CleanupStack::Pop(3); // aResponseData, aResponseUrl, aContentTypeString
CleanupStack::PopAndDestroy(); // self
}
// -----------------------------------------------------------------------------
// CSavedDeckHandler::IsSavedDeck
// Check if the loaded file is a saved deck, based on the path and extension.
// -----------------------------------------------------------------------------
//
TBool CSavedDeckHandler::IsSavedDeck(TPtrC& aRequestUrl)
{
_LIT(KFileExtension, ".saveddeck");
_LIT(KFilePath, "saveddecks");
return (aRequestUrl.FindF(KFileExtension()) != KErrNotFound &&
aRequestUrl.FindF(KFilePath()) != KErrNotFound);
}
// -----------------------------------------------------------------------------
// CSavedDeckHandler::GetNextPartL
// Extract the next data part from the buffer.
// -----------------------------------------------------------------------------
//
void CSavedDeckHandler::GetNextPartL(CSavedDeckPart& aSavedDeckPart)
{
TInt i;
aSavedDeckPart.Reset();
// Get the version
const TUint8* version = (const TUint8*)SAVED_DECK_VERSION;
TUint versionLen = User::StringLength(version);
// Is it the correct version?
if (iDataReader.Find(version, versionLen) != 0)
{
User::Leave(KErrCorrupt);
}
// The version is contained, so the buffer must be big enough
iDataReader.Set(iDataReader.Mid(versionLen));
// Get the URL
if (iDataReader.Length() < (TInt)sizeof(TUint))
{
User::Leave(KErrCorrupt);
}
i = GetUintFromBuffer(iDataReader) + 1; // 1 for NULL terminator
if (iDataReader.Length() < i)
{
User::Leave(KErrCorrupt);
}
aSavedDeckPart.iUrl.Set(iDataReader.Ptr(), i);
// Find that NULL terminator is still there
if (aSavedDeckPart.iUrl[i - 1] != '\0')
{
User::Leave(KErrCorrupt);
}
iDataReader.Set(iDataReader.Mid(i));
// Get the content type string
if (iDataReader.Length() < (TInt)sizeof(TInt)) // length constant type string
{
User::Leave(KErrCorrupt);
}
i = GetUintFromBuffer(iDataReader) + 1; // 1 for NULL terminator
if (iDataReader.Length() < i)
{
User::Leave(KErrCorrupt);
}
aSavedDeckPart.iContentTypeString.Set(iDataReader.Ptr(), i);
// Find that NULL terminator is still there
if (aSavedDeckPart.iContentTypeString[i - 1] != '\0')
{
User::Leave(KErrCorrupt);
}
iDataReader.Set(iDataReader.Mid(i));
// Get Charset
aSavedDeckPart.iCharset = GetUintFromBuffer(iDataReader);
// Get original Charset setting
aSavedDeckPart.iOriCharset = GetUintFromBuffer(iDataReader);
// Get the body
if (iDataReader.Length() < (TInt)sizeof(TInt))
{
User::Leave(KErrCorrupt);
}
i = GetUintFromBuffer(iDataReader);
if (iDataReader.Length() < i + 1) // 1 for NULL terminator
{
User::Leave(KErrCorrupt);
}
aSavedDeckPart.iData.Set(iDataReader.Ptr(), i);
// Find that NULL terminator is still there
if (iDataReader[i] != '\0')
{
User::Leave(KErrCorrupt);
}
iDataReader.Set(iDataReader.Mid(i+ 1));
}
// -----------------------------------------------------------------------------
// CSavedDeckHandler::PrepareResponseLC
// Copy the data and URL of the first part, to be returned as the response.
// -----------------------------------------------------------------------------
//
void CSavedDeckHandler::PrepareResponseLC(CSavedDeckPart& aSavedDeckPart,
TPtr8& aResponseData,
TPtr& aResponseUrl,
TPtr8& aContentTypeString,
TUint& aCharset)
{
// Copy data
TUint8* data = new(ELeave) TUint8 [aSavedDeckPart.iData.Length()];
CleanupStack::PushL(data);
aResponseData.Set(data, 0, aSavedDeckPart.iData.Length());
aResponseData.Copy(aSavedDeckPart.iData);
// Copy URL
TUint16* url = new(ELeave) TUint16 [aSavedDeckPart.iUrl.Length()];
CleanupStack::PushL(url);
aResponseUrl.Set(url, 0, aSavedDeckPart.iUrl.Length());
aResponseUrl.Copy(aSavedDeckPart.iUrl);
// Copy content type string
// note: string deleted in 'destructor' of reponse class
TUint8* cts = new(ELeave) TUint8 [aSavedDeckPart.iContentTypeString.Length()];
CleanupStack::PushL(cts);
aContentTypeString.Set(cts, 0, aSavedDeckPart.iContentTypeString.Length());
aContentTypeString.Copy(aSavedDeckPart.iContentTypeString);
// Charset
aCharset = aSavedDeckPart.iCharset;
}
// -----------------------------------------------------------------------------
// CSavedDeckHandler::LoadPartToCacheL
// Send a response part to cache.
// -----------------------------------------------------------------------------
//
void CSavedDeckHandler::LoadPartToCacheL(CSavedDeckPart& aSavedDeckPart)
{
TPtrC8 charsetStr = ConvertCharsetToStr(aSavedDeckPart.iCharset);
aSavedDeckPart.iUrl.Set(aSavedDeckPart.iUrl.Ptr(), aSavedDeckPart.iUrl.Length() - 1);
aSavedDeckPart.iContentTypeString.Set(aSavedDeckPart.iContentTypeString.Ptr(), aSavedDeckPart.iContentTypeString.Length() - 1);
}
TPtrC8 CSavedDeckHandler::ConvertCharsetToStr(TUint32 aCharset)
{
if (aCharset == HTTP_utf_8)
return KUtf8().Ptr();
if (aCharset == HTTP_us_ascii)
return KUsAscii().Ptr();
if (aCharset ==HTTP_iso_10646_ucs_2)
return KIso10646Ucs2().Ptr();
if (aCharset == HTTP_iso_8859_1)
return KIso88591().Ptr();
if (aCharset == HTTP_gb2312)
return KGb2312().Ptr();
if (aCharset == HTTP_big5)
return KBig5().Ptr();
if (aCharset == HTTP_iso_8859_2)
return KIso88592().Ptr();
if (aCharset == HTTP_iso_8859_3)
return KIso88593().Ptr();
if (aCharset == HTTP_iso_8859_4)
return KIso88594().Ptr();
if (aCharset == HTTP_iso_8859_5)
return KIso88595().Ptr();
if (aCharset == HTTP_iso_8859_6)
return KIso88596().Ptr();
if (aCharset == HTTP_iso_8859_7)
return KIso88597().Ptr();
if (aCharset == HTTP_iso_8859_8)
return KIso88598().Ptr();
if (aCharset == HTTP_iso_8859_9)
return KIso88599().Ptr();
if (aCharset == HTTP_shift_JIS )
return KShiftJIS().Ptr();
if (aCharset == HTTP_windows_1250)
return KWindows1250().Ptr();
if (aCharset == HTTP_windows_1251)
return KWindows1251().Ptr();
if (aCharset == HTTP_windows_1253)
return KWindows1253().Ptr();
if (aCharset == HTTP_windows_1254)
return KWindows1254().Ptr();
if (aCharset == HTTP_windows_1255)
return KWindows1255().Ptr();
if (aCharset == HTTP_windows_1256)
return KWindows1256().Ptr();
if (aCharset == HTTP_windows_1257)
return KWindows1257().Ptr();
if (aCharset == HTTP_tis_620)
return KTis620().Ptr();
if (aCharset == HTTP_jis_x0201_1997)
return KJisX0201_1997().Ptr();
if (aCharset == HTTP_jis_x0208_1997)
return KJisX0208_1997().Ptr();
if (aCharset == HTTP_iso_2022_jp)
return KIso2022Jp().Ptr();
if (aCharset == HTTP_euc_jp)
return KEucJp().Ptr();
if (aCharset == HTTP_windows_874)
return KWindows874().Ptr();
if (aCharset == HTTP_Koi8_r)
return KOI8R().Ptr();
if (aCharset == HTTP_Koi8_u)
return KOI8U().Ptr();
return KUtf8().Ptr();
}
// ========================== OTHER EXPORTED FUNCTIONS =========================
// End of File