ncdengine/engine/src/catalogsutils.cpp
changeset 0 ba25891c3a9e
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ncdengine/engine/src/catalogsutils.cpp	Thu Dec 17 08:51:10 2009 +0200
@@ -0,0 +1,1261 @@
+/*
+* Copyright (c) 2006 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "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 "catalogsutils.h"
+
+#include <utf.h>
+#include <e32base.h>
+#include <f32file.h>
+#include <bautils.h>
+#include <s32strm.h>
+#include <s32mem.h>
+#include <sysutil.h>
+#include <pathinfo.h> 
+
+#ifndef __S60_32__
+#include <platform/mw/languages.hrh>
+#endif
+
+#include "catalogsconstants.h"
+#include "catalogsbasemessage.h"
+
+#include "catalogsdebug.h"
+
+// Maximum length of a signed 16 bit integer when converted to a string
+const TInt K16BitIntAsDescLength = 6;
+
+// Maximum length of a signed 32 bit integer when converted to a string
+const TInt K32BitIntAsDescLength = 11;
+
+_LIT( KInitialSearchDrive, "Y:" );
+
+void TCatalogsVersion::ConvertL( TCatalogsVersion& aTarget, const TDesC& aVersion )
+    {
+    TUint16 major = 0;
+    TUint16 minor = 0;
+    TUint32 build = 0;
+    
+    if ( aVersion.Length() ) 
+        {        
+        DesToVersionL( aVersion, major, minor, build );
+        }
+    
+    aTarget = TCatalogsVersion( major, minor, build );        
+    }
+    
+    
+HBufC* TCatalogsVersion::ConvertLC( const TCatalogsVersion& aSource )
+    {
+    DLTRACEIN(("input: %u.%u.%u", 
+        aSource.iMajor,
+        aSource.iMinor,
+        aSource.iBuild ));
+        
+    _LIT( KFormatString, "%u.%u.%u");
+    
+    HBufC* target = HBufC::NewLC( 
+        // Length of major + minor
+        2 * K16BitIntAsDescLength +
+        // length of build
+        K32BitIntAsDescLength + 
+        // separators: '.'
+        2 );
+        
+    TPtr ptr( target->Des() );
+    ptr.Format( 
+        KFormatString, 
+        aSource.iMajor, 
+        aSource.iMinor, 
+        aSource.iBuild );
+        
+    DLTRACEOUT(( _L("Output: %S"), target));    
+    return target;
+    }
+    
+
+TCatalogsVersion::TCatalogsVersion()
+    {
+    iMajor = 0;
+    iMinor = 0;
+    iBuild = 0;
+    }
+    
+
+TCatalogsVersion::TCatalogsVersion( TUint16 aMajor,
+                                    TUint16 aMinor,
+                                    TUint32 aBuild )
+    {
+    iMajor = aMajor;
+    iMinor = aMinor;
+    iBuild = aBuild;
+    }
+
+TBool TCatalogsVersion::operator==( const TCatalogsVersion& aVersion ) const
+    {
+    return iMajor == aVersion.iMajor && 
+           iMinor == aVersion.iMinor &&
+           iBuild == aVersion.iBuild;
+    }
+
+TBool TCatalogsVersion::operator>( const TCatalogsVersion& aVersion ) const
+    {
+    return ( iMajor > aVersion.iMajor ) || 
+        ( iMajor == aVersion.iMajor && ( iMinor > aVersion.iMinor ||
+        ( iMinor == aVersion.iMinor && iBuild > aVersion.iBuild ) ) );
+    }
+    
+TBool TCatalogsVersion::operator>=( const TCatalogsVersion& aVersion ) const
+    {
+    return operator==( aVersion ) || operator>( aVersion );
+    }
+
+
+
+
+#ifndef NCD_STORAGE_TESTING
+
+// ---------------------------------------------------------------------------
+// RCatalogsMessageReader
+// ---------------------------------------------------------------------------
+//    
+
+RCatalogsMessageReader::RCatalogsMessageReader()
+    {
+    }
+
+void RCatalogsMessageReader::OpenL( MCatalogsBaseMessage& aMessage )
+    {
+    iBuf.CreateL( aMessage.InputLength() );    
+    User::LeaveIfError( aMessage.ReadInput( iBuf ) );
+    iStream.Open( iBuf );
+    }
+
+
+void RCatalogsMessageReader::OpenLC( MCatalogsBaseMessage& aMessage )
+    {
+    CleanupClosePushL( *this );
+    OpenL( aMessage );    
+    }
+    
+
+void RCatalogsMessageReader::Close()
+    {
+    iStream.Close();
+    iBuf.Close();        
+    }
+    
+    
+RCatalogsMessageReader::~RCatalogsMessageReader()
+    {
+    }
+
+#endif
+
+// ---------------------------------------------------------------------------
+// RCatalogsBufferWriter
+// ---------------------------------------------------------------------------
+//    
+
+RCatalogsBufferWriter::RCatalogsBufferWriter() : iBuf( NULL )
+    {
+    }
+
+void RCatalogsBufferWriter::OpenL()
+    {    
+    iBuf = CBufFlat::NewL( KBufExpandSize );    
+    iStream.Open( *iBuf );
+    }
+
+
+void RCatalogsBufferWriter::OpenLC()
+    {
+    CleanupClosePushL( *this );
+    OpenL();
+    }
+    
+
+void RCatalogsBufferWriter::Close()
+    {
+    iStream.Close();
+    delete iBuf;
+    iBuf = NULL;
+    }
+    
+    
+RCatalogsBufferWriter::~RCatalogsBufferWriter()
+    {
+    }
+
+
+// ---------------------------------------------------------------------------
+// Utility functions
+// ---------------------------------------------------------------------------
+//    
+    
+
+
+void AssignDesL( HBufC8*& aDes, const TDesC8& aSource )
+    {
+    delete aDes;
+    aDes = 0;
+    aDes = aSource.AllocL();
+    }
+
+
+void AssignDesL( HBufC16*& aDes, const TDesC16& aSource )
+    {
+    delete aDes;
+    aDes = 0;
+    aDes = aSource.AllocL();
+    }
+
+void AssignDesL( HBufC16*& aDes, const TDesC8& aSource )
+    {
+    delete aDes;
+    aDes = 0;
+    aDes = ConvertUtf8ToUnicodeL( aSource );
+    }
+
+HBufC16* ConvertUtf8ToUnicodeL( const TDesC8& aUtfText )
+    {
+    HBufC16* buffer = HBufC16::NewLC( aUtfText.Length() );
+    TPtr ptr( buffer->Des() );
+    User::LeaveIfError( 
+        CnvUtfConverter::ConvertToUnicodeFromUtf8( ptr,
+                                                   aUtfText ) );
+    CleanupStack::Pop( buffer );
+    return buffer;
+    }
+
+
+HBufC8* ConvertUnicodeToUtf8L( const TDesC16& aUnicodeText )
+    {
+    const TInt KConvertBufferSize = 32;
+
+    // Place converted data here, initial size double the conversion buffer.
+    HBufC8* convertedData = HBufC8::NewL( KConvertBufferSize * 2 );
+    CleanupStack::PushL( convertedData );
+    TPtr8 destination( convertedData->Des() );
+
+    // Create a small output buffer
+    TBuf8<KConvertBufferSize> outputBuffer;
+    
+    // Create a buffer for the unconverted text - initialised with the 
+    // input text
+    TPtrC16 remainderOfUnicodeText( aUnicodeText );
+
+    for ( ;; ) // conversion loop
+        {
+        // Start conversion. When the output buffer is full, return the 
+        // number of characters that were not converted
+        const TInt returnValue
+            = CnvUtfConverter::ConvertFromUnicodeToUtf8( outputBuffer, 
+            remainderOfUnicodeText );
+
+        // check to see that the descriptor isn’t corrupt - leave if it is
+        if ( returnValue == CnvUtfConverter::EErrorIllFormedInput )
+            {            
+            User::Leave( KErrCorrupt );
+            }
+        else if ( returnValue < 0 ) // future-proof against "TError" expanding
+            {            
+            User::Leave( KErrGeneral );
+            }
+
+        // Do something here to store the contents of the output buffer.
+        if ( destination.Length() + outputBuffer.Length() >= 
+             destination.MaxLength() )
+            {
+            HBufC8* newBuffer = convertedData->ReAllocL(
+                ( destination.MaxLength() + outputBuffer.Length() ) * 2 );
+            
+            CleanupStack::Pop( convertedData );
+            convertedData = newBuffer;
+            CleanupStack::PushL( convertedData );
+            destination.Set( convertedData->Des() );
+            }
+
+        destination.Append( outputBuffer );
+        outputBuffer.Zero();
+
+        // Finish conversion if there are no unconverted characters 
+        // in the remainder buffer
+        if ( returnValue == 0 ) 
+            {            
+            break; 
+            }
+
+        // Remove the converted source text from the remainder buffer.
+        // The remainder buffer is then fed back into loop
+        remainderOfUnicodeText.Set( 
+            remainderOfUnicodeText.Right( returnValue) );
+        }
+        
+    CleanupStack::Pop( convertedData );
+    return convertedData;
+    }
+
+
+HBufC8* Des16ToDes8LC( const TDesC16& aDes )
+    {
+    HBufC8* buffer = HBufC8::NewLC( aDes.Length() );
+    buffer->Des().Copy( aDes );
+    return buffer;
+    }
+    
+HBufC8* Des16ToDes8L( const TDesC16& aDes )
+    {
+    HBufC8* t = Des16ToDes8LC( aDes );
+    CleanupStack::Pop();
+    return t;
+    }
+
+HBufC16* Des8ToDes16LC( const TDesC8& aDes )
+    {
+    HBufC16* buffer = HBufC16::NewLC( aDes.Length() );
+    buffer->Des().Copy( aDes );
+    return buffer;
+    }
+
+HBufC16* Des8ToDes16L( const TDesC8& aDes )
+    {
+    HBufC16* t = Des8ToDes16LC( aDes );
+    CleanupStack::Pop();
+    return t;
+    }    
+
+TInt DesDecToIntL( const TDesC& aDes )
+    {
+    TLex lex( aDes );
+    TInt value;
+    User::LeaveIfError( lex.Val( value ) );
+    return value;
+    }
+
+TInt DesDecToInt( const TDesC8& aDes, TInt& aValue )
+    {
+    TLex8 lex( aDes );
+    return lex.Val( aValue );
+    }
+
+TInt DesDecToInt( const TDesC16& aDes, TInt& aValue )
+    {
+    TLex16 lex( aDes );
+    return lex.Val( aValue );
+    }
+
+TInt DesHexToIntL( const TDesC& aDes )
+    {
+    TLex lex( aDes );
+    TInt position = aDes.LocateF( 'x' );
+    if ( position != KErrNotFound ) 
+        {
+        // Hex format is of type '0xABC' or 'xABC'
+        // Skip over the x-part.
+        lex.Assign( aDes.Mid( position+1 ) );
+        }
+    TUint value;
+    User::LeaveIfError( lex.Val( value, EHex ) );
+    return value;
+    }
+
+TInt Des8ToInt( const TDesC8& aDes )
+    {
+    return *(( TInt* )aDes.Ptr());
+    }
+
+TUint Des8ToUint( const TDesC8& aDes )
+    {
+    return *(( TUint* )aDes.Ptr());
+    }
+
+
+HBufC8* IntToDes8LC( TInt aInt )
+    {
+    HBufC8* buffer = HBufC8::NewMaxLC( sizeof( aInt ) );
+    TPtr8 ptr( buffer->Des() );
+    *(( TInt* )ptr.Ptr()) = aInt;
+    return buffer;
+    }
+
+HBufC8* IntToDes8L( TInt aInt )
+    {
+    HBufC8* t = IntToDes8LC( aInt );
+    CleanupStack::Pop();
+    return t;
+    }
+
+HBufC8* UintToDes8LC( TUint aUint )
+    {
+    HBufC8* buffer = HBufC8::NewMaxLC( sizeof( aUint ) );
+    TPtr8 ptr( buffer->Des() );
+    *(( TUint* )ptr.Ptr()) = aUint;
+    return buffer;
+    }
+
+HBufC8* UintToDes8L( TUint aUint )
+    {
+    HBufC8* t = UintToDes8LC( aUint );
+    CleanupStack::Pop();
+    return t;
+    }
+
+
+// ---------------------------------------------------------------------------
+// ExternalizeDesL
+// ---------------------------------------------------------------------------
+//    
+void ExternalizeDesL( const TDesC16& aDes, RWriteStream& aStream )
+    {
+    aStream.WriteInt32L( aDes.Length() );
+    aStream.WriteL( aDes );
+    }
+
+
+// ---------------------------------------------------------------------------
+// InternalizeDesL
+// ---------------------------------------------------------------------------
+//    
+TInt InternalizeDesL( HBufC16*& aDes, RReadStream& aStream )
+    {
+    //DLTRACEIN(("16bit"));
+    TInt length = aStream.ReadInt32L();
+    //DLTRACE(("length: %i", length));
+    if ( length > 0 ) 
+        {
+        HBufC* target = HBufC::NewLC( length );
+        TPtr ptr( target->Des() );
+        
+        aStream.ReadL( ptr, length );
+        delete aDes;
+        aDes = target;
+        CleanupStack::Pop( target );
+        }
+    else
+        {
+        delete aDes;
+        aDes = KNullDesC16().AllocL();
+        }
+    //DLTRACEOUT((""));
+    return length;
+    }
+
+
+// ---------------------------------------------------------------------------
+// ExternalizeDesL
+// ---------------------------------------------------------------------------
+//    
+void ExternalizeDesL( const TDesC8& aDes, RWriteStream& aStream )
+    {
+    aStream.WriteInt32L( aDes.Length() );
+    aStream.WriteL( aDes );
+    }
+
+
+// ---------------------------------------------------------------------------
+// InternalizeDesL
+// ---------------------------------------------------------------------------
+//    
+TInt InternalizeDesL( HBufC8*& aDes, RReadStream& aStream )
+    {
+    //DLTRACEIN(("8bit"));
+    TInt length = aStream.ReadInt32L();
+    //DLTRACE(("length: %i", length));
+    if ( length > 0 ) 
+        {
+        HBufC8* target = HBufC8::NewLC( length );
+        TPtr8 ptr( target->Des() );
+        
+        aStream.ReadL( ptr, length );
+        delete aDes;
+        aDes = target;
+        CleanupStack::Pop( target );
+        }
+    else
+        {
+        delete aDes;
+        aDes = KNullDesC8().AllocL();
+        }
+    //DLTRACEOUT((""));
+    return length;
+    }
+
+
+
+HBufC* FindEngineFileL( RFs& aFs, const TDesC& aFilename )
+    {
+    DLTRACEIN(( _L("Find: %S"), &aFilename ));
+    // Get engine's private path
+    RBuf target;
+    CleanupClosePushL( target );
+    target.CreateL( KMaxPath );
+    User::LeaveIfError( aFs.PrivatePath( target ) );
+
+    // Set Y: as the first drive to be searched instead of session
+    // path's drive which is C:       
+    target.Insert( 0, KInitialSearchDrive );
+    
+    DLTRACE(( _L("Path to search from: %S"), &target ));
+    
+    // Find the file
+    TFindFile find( aFs );
+
+    User::LeaveIfError( find.FindByDir( aFilename, target ) );
+    
+    CleanupStack::PopAndDestroy( &target );    
+    DLTRACEOUT(( _L("Found the file from: %S"), 
+        &find.File() ));
+        
+    return find.File().AllocL();    
+    }
+    
+
+TBool IsRomDriveL( RFs& aFs, TChar aDriveChar )
+    {   
+    DLTRACEIN((""));
+    TDriveInfo info;
+    TInt drive;
+    User::LeaveIfError( RFs::CharToDrive( aDriveChar, drive ) );
+    User::LeaveIfError( aFs.Drive( info, drive ) );
+    return info.iDriveAtt & KDriveAttRom;
+    }
+
+
+TChar DriveToCharL( TInt aDrive )
+    {
+    TChar c;
+    User::LeaveIfError( RFs::DriveToChar( aDrive, c ) );
+    return c;
+    }
+
+
+HBufC* DriveRootPathLC( RFs& aFs, const TChar& aDriveLetter )
+    {
+    DLTRACEIN((""));
+
+    HBufC* rootPath( NULL );
+        
+    // Get the drive num that corresponds the given letter
+    TInt driveNum( EDriveA );
+    User::LeaveIfError( aFs.CharToDrive( aDriveLetter, driveNum ) );
+
+    // Get the information about the drive
+    TDriveInfo info;
+    User::LeaveIfError( aFs.Drive( info, driveNum ) );
+
+    // Compare drive information to check what is the correct root path
+    if ( info.iDriveAtt & KDriveAttRom )
+        {
+        DLINFO(("ROM drive"));
+        rootPath = PathInfo::RomRootPath().AllocLC();
+        }
+    else if ( info.iDriveAtt & KDriveAttRemovable )
+        {
+        DLINFO(("Memory card"));
+        // Memory card
+        rootPath = PathInfo::MemoryCardRootPath().AllocLC();
+        }
+    else
+        {
+        // Phone memory
+        DLINFO(("Phone memory"));
+        rootPath = PathInfo::PhoneMemoryRootPath().AllocLC();
+        }
+
+    HBufC* charDes( HBufC::NewLC( 1 ) );
+    charDes->Des().Append( aDriveLetter );
+    // Let us make sure that the drive letter is correct
+    // if there are multiple same kind of drives...
+    rootPath->Des().Replace( 0, 1, *charDes );
+    CleanupStack::PopAndDestroy( charDes );
+
+    DLTRACEOUT((""));
+    return rootPath;
+    }
+
+
+HBufC* LangCodeToDescLC( TLanguage aLang )
+    {
+    switch ( aLang )
+        {
+        case ELangEnglish:
+            return _L( "en_EN" ).AllocLC();
+        case ELangFrench:
+            return _L( "fr_FR" ).AllocLC();
+        case ELangGerman: 
+            return _L( "de_DE" ).AllocLC();
+        case ELangSpanish:
+            return _L( "es_ES" ).AllocLC();
+        case ELangItalian: 
+            return _L( "it_IT" ).AllocLC();
+        case ELangSwedish: 
+            return _L( "sv_SE" ).AllocLC();
+        case ELangDanish: 
+            return _L( "da_DK" ).AllocLC();
+        case ELangNorwegian:
+            return _L( "no_NO" ).AllocLC();
+        case ELangFinnish:
+            return _L( "fi_FI" ).AllocLC();
+        case ELangAmerican:
+            return _L( "en_US" ).AllocLC();
+        case ELangSwissFrench:
+            return _L( "fr_CH" ).AllocLC();
+        case ELangSwissGerman:
+            return _L( "de_CH" ).AllocLC();
+        case ELangPortuguese:
+            return _L( "pt_PT" ).AllocLC();
+        case ELangTurkish:
+            return _L( "tr_TR" ).AllocLC();
+        case ELangIcelandic:
+            return _L( "is_IS" ).AllocLC();
+        case ELangRussian:
+            return _L( "ru_RU" ).AllocLC();
+        case ELangHungarian:
+            return _L( "hu_HU" ).AllocLC();
+        case ELangDutch:
+            return _L( "nl_NL" ).AllocLC();
+        case ELangBelgianFlemish:
+            return _L( "nl_BE" ).AllocLC();
+        case ELangAustralian:
+            return _L( "en_AU" ).AllocLC();
+        case ELangBelgianFrench:
+            return _L( "fr_BE" ).AllocLC();
+        case ELangAustrian:
+            return _L( "de_AT" ).AllocLC();
+        case ELangNewZealand:
+            return _L( "en_NZ" ).AllocLC();
+        case ELangInternationalFrench:
+            return _L( "fr" ).AllocLC();
+        case ELangCzech:
+            return _L( "cs_CZ" ).AllocLC();
+        case ELangSlovak:
+            return _L( "sk_SK" ).AllocLC();
+        case ELangPolish:
+            return _L( "pl_PL" ).AllocLC();
+        case ELangSlovenian:
+            return _L( "sl_SI" ).AllocLC();
+        case ELangTaiwanChinese:
+            return _L( "zh_TW" ).AllocLC();
+        case ELangHongKongChinese:
+            return _L( "zh_HK" ).AllocLC();
+        case ELangPrcChinese:
+            return _L( "zh_CN" ).AllocLC();
+        case ELangJapanese:
+            return _L( "ja_JP" ).AllocLC();
+        case ELangThai:
+            return _L( "th_TH" ).AllocLC();
+        case ELangAfrikaans:
+            return _L( "af_ZA" ).AllocLC();
+        case ELangAlbanian:
+            return _L( "sq_AL" ).AllocLC();
+        case ELangAmharic:
+            return _L( "am_ET" ).AllocLC();
+        case ELangArabic:
+            return _L( "ar" ).AllocLC();
+        case ELangArmenian:
+            return _L( "hy_AM" ).AllocLC();
+        case ELangTagalog:
+            return _L( "tl" ).AllocLC();
+        case ELangBelarussian:
+            return _L( "be_BY" ).AllocLC();
+        case ELangBengali:
+            return _L( "bn_IN" ).AllocLC();
+        case ELangBulgarian:
+            return _L( "bg_BG" ).AllocLC();
+        case ELangBurmese:
+            return _L( "my_MM" ).AllocLC();
+        case ELangCatalan:
+            return _L( "ca_ES" ).AllocLC();
+        case ELangCroatian:
+            return _L( "hr_HR" ).AllocLC();
+        case ELangCanadianEnglish:
+            return _L( "en_CA" ).AllocLC();
+        case ELangInternationalEnglish:
+            return _L( "en" ).AllocLC();
+        case ELangSouthAfricanEnglish:
+            return _L( "en_ZA" ).AllocLC();
+        case ELangEstonian:
+            return _L( "et_EE" ).AllocLC();
+        case ELangFarsi:
+            return _L( "fa_IR" ).AllocLC();
+        case ELangCanadianFrench:
+            return _L( "fr_CA" ).AllocLC();
+        case ELangScotsGaelic:
+            return _L( "gd_GB" ).AllocLC();
+        case ELangGeorgian:
+            return _L( "ka_GE" ).AllocLC();
+        case ELangGreek:
+            return _L( "el_GR" ).AllocLC();
+        case ELangCyprusGreek:
+            return _L( "el_CY" ).AllocLC();
+        case ELangGujarati:
+            return _L( "gu_IN" ).AllocLC();
+        case ELangHebrew:
+            return _L( "he" ).AllocLC();
+        case ELangHindi:
+            return _L( "hi_IN" ).AllocLC();
+        case ELangIndonesian:
+            return _L( "id_ID" ).AllocLC();
+        case ELangIrish:
+            return _L( "ga_IE" ).AllocLC();
+        case ELangSwissItalian:
+            return _L( "it_CH" ).AllocLC();
+        case ELangKannada:
+            return _L( "kn_IN" ).AllocLC();
+        case ELangKazakh:
+            return _L( "kk_KZ" ).AllocLC();
+        case ELangKhmer:
+            return _L( "kh_KH" ).AllocLC();
+        case ELangKorean:
+            return _L( "ko_KR" ).AllocLC();
+        case ELangLao:
+            return _L( "lo_LA" ).AllocLC();
+        case ELangLatvian:
+            return _L( "lv_LV" ).AllocLC();
+        case ELangLithuanian:
+            return _L( "lt_LT" ).AllocLC();
+        case ELangMacedonian:
+            return _L( "mk_MK" ).AllocLC();
+        case ELangMalay:
+            return _L( "ms_MY" ).AllocLC();
+        case ELangMalayalam:
+            return _L( "ml_IN" ).AllocLC();
+        case ELangMarathi:
+            return _L( "mr_IN" ).AllocLC();
+        case ELangMoldavian:
+            return _L( "mo_MD" ).AllocLC();
+        case ELangMongolian:
+            return _L( "mn_MN" ).AllocLC();
+        case ELangNorwegianNynorsk:
+            return _L( "nn_NO" ).AllocLC();
+        case ELangBrazilianPortuguese:
+            return _L( "pt_BR" ).AllocLC();
+        case ELangPunjabi:
+            return _L( "pa_IN" ).AllocLC();
+        case ELangRomanian:
+            return _L( "ro_RO" ).AllocLC();
+        case ELangSerbian:
+            return _L( "sr" ).AllocLC();
+        case ELangSinhalese:
+            return _L( "si_LK" ).AllocLC();
+        case ELangSomali:
+            return _L( "so_SO" ).AllocLC();
+        case ELangInternationalSpanish:
+            return _L( "es" ).AllocLC();
+        case ELangLatinAmericanSpanish:
+            return _L( "esa" ).AllocLC();
+        case ELangSwahili:
+            return _L( "sw_KE" ).AllocLC();
+        case ELangFinlandSwedish:
+            return _L( "sv_FI" ).AllocLC();
+        case ELangTamil:
+            return _L( "ta_IN" ).AllocLC();
+        case ELangTelugu:
+            return _L( "te_IN" ).AllocLC();
+        case ELangTibetan:
+            return _L( "bo" ).AllocLC();
+        case ELangTigrinya:
+            return _L( "ti_ET" ).AllocLC();
+        case ELangCyprusTurkish:
+            return _L( "tr_CY" ).AllocLC();
+        case ELangTurkmen:
+            return _L( "tk_TM" ).AllocLC();
+        case ELangUkrainian:
+            return _L( "uk_UA" ).AllocLC();
+        case ELangUrdu:
+            return _L( "ur_PK" ).AllocLC();
+        case ELangVietnamese:
+            return _L( "vi_VN" ).AllocLC();
+        case ELangWelsh:
+            return _L( "cy_GB" ).AllocLC();
+        case ELangZulu:
+            return _L( "zu_ZA" ).AllocLC();  
+
+#ifdef __S60_32__
+            
+        case 129: // APAC English = 129
+            return _L( "en_APAC" ).AllocLC();
+        case 157: // APAC TW (a.k.a Chinese TW English) = 157
+            return _L( "en_TW" ).AllocLC();
+        case 158: // APAC HK = 158
+            return _L( "en_HK" ).AllocLC();
+        case 159: // APAC PRC = 159
+            return _L( "en_CN" ).AllocLC();
+        case 160: // Japanese English = 160
+            return _L( "en_JP" ).AllocLC();
+        case 161: // Thai English = 161
+            return _L( "en_TH" ).AllocLC();
+        case 326: // Bahasa Malay (Chinese) = 326
+            return _L( "ms_MY" ).AllocLC();
+        case 401: // Basque
+            return _L( "eu" ).AllocLC();
+        case 402: // Galician
+            return _L( "gl_ES" ).AllocLC();
+
+#else // __S60_32__
+
+        case KLangApacEnglish: // APAC English = 129
+            return _L( "en_APAC" ).AllocLC();
+        case KLangTaiwanEnglish: // APAC TW (a.k.a Chinese TW English) = 157
+            return _L( "en_TW" ).AllocLC();
+        case KLangHongKongEnglish: // APAC HK = 158
+            return _L( "en_HK" ).AllocLC();
+        case KLangPrcEnglish: // APAC PRC = 159
+            return _L( "en_CN" ).AllocLC();
+        case KLangJapaneseEnglish: // Japanese English = 160
+            return _L( "en_JP" ).AllocLC();
+        case KLangThaiEnglish: // Thai English = 161
+            return _L( "en_TH" ).AllocLC();
+        case KLangApacMalay: // Bahasa Malay (Chinese) = 326
+            return _L( "ms_MY" ).AllocLC();
+        case KLangBasque: // Basque = 102 on 5.0 platform
+            return _L( "eu" ).AllocLC();
+        case KLangGalician: // Galician = 103 on 5.0 platform
+            return _L( "gl_ES" ).AllocLC();
+
+#endif // __S60_32__
+            
+        default:
+            return _L( "undef" ).AllocLC();
+        }
+    }
+
+
+// ---------------------------------------------------------------------------
+// CleanUidName
+// ---------------------------------------------------------------------------
+//    
+TUidName CleanUidName( const TUid& aUid )
+    {
+    TUidName uidName( aUid.Name() );
+    DASSERT( uidName.Length() > 2 );
+    // Rip '[' and ']' out of uid name
+    return uidName.Mid( 1, uidName.Length() - 2 );
+    }    
+
+// ---------------------------------------------------------------------------
+// Encodes a filename 
+// ---------------------------------------------------------------------------
+// 
+HBufC* EncodeFilenameLC( const TDesC& aFileName, RFs& aFs )
+    {
+    DLTRACEIN(( _L("Path: %S"), &aFileName ));
+    // If each character gets replaced with a number, it would quadruple the
+    // length: "abc" -> "xxxxyyyyzzzz". Multiply by 8 to be safe : )
+    HBufC* encoded = HBufC::NewLC( aFileName.Length() * 8 );
+    TPtr ptr( encoded->Des() );
+
+    // First some basic legality checks.
+    // It seems that RFs::IsValidName() acts very strangely in some cases
+    // ( returns 0x20 as badChar even though there is no such char in the desc )
+    // so it's better to do as much as we can by ourselves.
+
+    for ( TInt i = 0; i < aFileName.Length(); i++ )
+        {
+        TChar c = aFileName[i];
+        switch ( c )
+            {
+            // List partly from TNameChecker
+            case '"':
+            case '*':
+            case '/':
+            case ':':
+            case '<':
+            case '>':
+            case '?':
+            case '\'':
+            case '\000':
+            case '\\':
+            case '|':
+            case '.':
+                {
+                TBuf<8> num;
+                num.NumUC( c, EHex );
+                ptr.Append( num );
+                break;
+                }
+            default:
+                {
+                ptr.Append( c );
+                break;
+                }
+            };
+        }
+
+    // Then try with system's tools.
+    TText badChar = 0;
+    while ( ! aFs.IsValidName( ptr, badChar ) )
+        {
+        TInt position = ptr.Locate( badChar );
+        if ( position == KErrNotFound )
+            {
+            // This should not happen. 
+            DLERROR(( _L("->encode filename abort! %S "),
+                             &aFileName ));
+            break;
+            }
+        // Replace evil characters with uppercase numeric codes.
+        TBuf<8> num;
+        num.NumUC( badChar, EHex );
+        ptr.Replace( position, 1, num );
+        }
+
+
+    DLTRACEOUT(( _L("%S"), encoded ));
+    return encoded;
+    }    
+    
+
+// ---------------------------------------------------------------------------
+// Creates a private directory
+// ---------------------------------------------------------------------------
+// 
+void CreatePrivatePathL( RFs& aFs, const TDesC& aDriveAndColon, TDes& aPath ) 
+    {
+    DLTRACEIN((""));
+    TInt driveNum;
+    User::LeaveIfError( aFs.CharToDrive( aDriveAndColon[0], driveNum ) );
+
+    DLTRACE(("Creating private path"));
+    User::LeaveIfError( aFs.CreatePrivatePath( driveNum ) );
+    User::LeaveIfError( aFs.PrivatePath( aPath ) );
+    
+    aPath.Insert( 0, aDriveAndColon );    
+    }
+
+        
+// ---------------------------------------------------------------------------
+// Free disk space
+// ---------------------------------------------------------------------------
+// 
+TInt64 FreeDiskSpaceL( RFs& aFs, TInt aDriveNumber )
+    {
+    DLTRACEIN((""));        
+
+    TInt64 freeSpace = 0;
+    TVolumeInfo volumeInfo;
+    
+    if ( aFs.Volume( volumeInfo, aDriveNumber ) == KErrNone)
+        {
+        freeSpace = volumeInfo.iFree;
+        }
+
+    DLTRACEOUT(( "Free space: %li", freeSpace ));
+    return freeSpace;
+    }    
+        
+    
+ // Specialization for 64-bit integers
+template<>
+void IntToDes16<TInt64>( const TInt64& aInt, TDes& aDes )
+    {
+    DLTRACEIN(("Int: %Li, aDes.MaxLength() = %d", aInt, aDes.MaxLength() ));
+    DASSERT( aDes.MaxLength() > 3 );
+    
+    IntToDes16( I64HIGH( aInt ), aDes );
+    aDes.SetLength( 4 );
+    TPtr16 ptr( aDes.MidTPtr( 2 ) );
+    TDes& des( ptr );
+    IntToDes16( I64LOW( aInt ), des );
+    DLTRACEOUT(( _L("High: %i, low: %i, Des: %S"), 
+        I64HIGH( aInt ), I64LOW( aInt ), &aDes ));    
+    }
+
+
+
+// Specialization for 64-bit integers    
+template<>
+void Des16ToInt<TInt64>( const TDesC& aDes, TInt64& aInt )
+    {
+    DLTRACEIN(( _L("aDes: %S"), &aDes ));
+    DASSERT( aDes.Length() > 3 );
+    TUint32 high = 0;
+    Des16ToInt( aDes, high );
+    
+    TUint32 low = 0;
+    Des16ToInt( aDes.Mid( 2 ), low );
+        
+    aInt = MAKE_TINT64( high, low );        
+    DLTRACEOUT(("Int: %Li, High: %i, low: %i", aInt, high, low ));
+    }
+
+// ---------------------------------------------------------------------------
+// Checks if the URI is a HTTPS URI
+// ---------------------------------------------------------------------------
+// 
+TBool IsHttpsUri( const TDesC& aUri )
+    {
+    _LIT(KHttps, "https");
+    return aUri.Left( KHttps().Length() ) == KHttps();
+    }
+
+
+// ---------------------------------------------------------------------------
+// 
+// ---------------------------------------------------------------------------
+// 
+TInt FileSystemAllocationL( RFs& aFs, const TDesC& aDir )
+    {
+    TInt allocation = 0;    
+
+    CDirScan* dirScan = CDirScan::NewLC( aFs );
+
+    dirScan->SetScanDataL( aDir,
+                           KEntryAttNormal,
+                           ESortByName,
+                           CDirScan::EScanDownTree );
+    CDir* dir = 0;
+    dirScan->NextL( dir );
+    while ( dir )
+        {
+        CleanupStack::PushL( dir );
+        TInt count = dir->Count();
+        
+        for ( TInt i = 0; i < count; i++ )
+            {
+            const TEntry& entry = ( *dir )[i];
+            allocation += entry.iSize;
+            }
+        CleanupStack::PopAndDestroy( dir );
+        dirScan->NextL( dir );
+        }
+
+    CleanupStack::PopAndDestroy( dirScan );
+    return allocation;
+    }
+    
+    
+// ---------------------------------------------------------------------------
+// Read file
+// ---------------------------------------------------------------------------
+// 
+HBufC8* ReadFileL( RFs& aFs, const TDesC& aFileName )
+    {
+    DLTRACEIN(( _L("File: %S"), &aFileName ));
+    RFile file;
+    User::LeaveIfError( file.Open( aFs,
+                                   aFileName,
+                                   EFileRead ) );
+    CleanupClosePushL( file );
+    HBufC8* buffer = ReadFileL( file );
+    CleanupStack::PopAndDestroy(); // file
+    
+    return buffer;
+    }
+
+// ---------------------------------------------------------------------------
+// Read file
+// ---------------------------------------------------------------------------
+// 
+HBufC8* ReadFileL( RFile& aFile )
+    {
+    DLTRACEIN(( "" ));
+    TInt size;
+    User::LeaveIfError( aFile.Size( size ) );
+    HBufC8* buffer = HBufC8::NewLC( size );
+    TPtr8 ptr( buffer->Des() );
+    User::LeaveIfError( aFile.Read( ptr, size ) );
+    CleanupStack::Pop( buffer );
+    
+    return buffer;
+    }
+
+
+// ---------------------------------------------------------------------------
+// Checks if there's enough space on the drive
+// ---------------------------------------------------------------------------
+// 
+void WouldDiskSpaceGoBelowCriticalLevelL( const TDesC& aPath,
+                                          RFs& aFs,
+                                          TInt aSpaceNeeded )
+    {
+    DLTRACEIN(( ""));
+    if ( aPath.Length() <= 0 )
+        { 
+        DLERROR(("Invalid path"));
+        User::Leave( KErrArgument );
+        }
+
+    TInt driveNumber = 0;
+    User::LeaveIfError( RFs::CharToDrive( aPath[0], driveNumber ) );
+    if ( SysUtil::DiskSpaceBelowCriticalLevelL( &aFs,
+                                                aSpaceNeeded,
+                                                driveNumber ) )
+        {
+        DLERROR(( _L( "Disk space would go below critical level, path: %S, space requested: %d " ),
+                         &aPath, aSpaceNeeded ));
+        User::Leave( KErrDiskFull );
+        }
+    }
+
+
+// Accepts "x", "x.y" or "x.y.z" format version strings.
+void DesToVersionL( const TDesC& aVersion, 
+    TUint16& aMajor, TUint16& aMinor, TUint32& aBuild )
+    {
+    DLTRACEIN(( _L("Version: %S"), &aVersion ));
+    // Initial values. -1 indicates that the value has not been yet parsed.
+    // using double sizes to ensure that TUints fit without sign conversion
+    TInt32 major = -1;
+    TInt32 minor = -1;
+    TInt64 build = -1;
+
+    TLex lex( aVersion );
+    lex.Mark();
+    for( ;; )
+        {
+        if( lex.Eos() || lex.Peek() == '.' )
+            {
+            TPtrC data = lex.MarkedToken();
+            TLex num;
+            num.Assign( data );
+            TInt64 value = 0;
+            User::LeaveIfError( num.Val( value ) );
+
+            if( major < 0 )
+                {
+                major = value;
+                }
+            else if( minor < 0 )
+                {
+                minor = value;
+                }
+            else if( build < 0 )
+                {
+                build = value;
+                // all values received now, exit loop.
+                break;
+                }
+            
+            if( lex.Eos() )
+                {
+                break;
+                }
+            else
+                {
+                lex.SkipAndMark( 1 );
+                }
+            }
+        else 
+            {
+            lex.Inc();
+            }
+        }
+
+    if( major < 0 )
+        {
+        DLERROR(("No major value, leaving"));
+        // Major required.
+        User::Leave( KErrArgument );
+        }
+        
+    if( minor < 0 )
+        {
+        // Assume zero for this one if not given.
+        minor = 0;
+        }
+        
+    if( build < 0 )
+        {
+        // Assume zero for this one if not given.
+        build = 0;
+        }
+    
+    aMajor = major;
+    aMinor = minor;
+    aBuild = build;
+    DLTRACEOUT(("Interpreted version: %d.%d.%d", aMajor, aMinor, aBuild ));
+    }
+
+// ---------------------------------------------------------------------------
+// Appends to paths
+// ---------------------------------------------------------------------------
+//
+void AppendPathsLC( 
+    RBuf& aPath, 
+    const TDesC& aRoot,
+    const TDesC& aAppendPath )
+    {
+    DLTRACEIN((""));
+    CleanupClosePushL( aPath );
+    aPath.CreateL( aRoot.Length() + 
+        aAppendPath.Length() );
+    aPath.Append( aRoot );
+    aPath.Append( aAppendPath );
+    DLTRACEOUT(( _L("Path: %S"), &aPath ));
+    }
+
+
+
+// ---------------------------------------------------------------------------
+// Leave helpers
+// ---------------------------------------------------------------------------
+//
+void LeaveIfNotErrorL( TInt aError, TInt aAcceptErr )
+    {   
+    if ( aError != KErrNone &&
+         aError != aAcceptErr )
+        {        
+        DLERROR(("Error: %d, leaving", aError));
+        User::Leave( aError );
+        }
+    }
+    
+    
+void LeaveIfNotErrorL( TInt aError, TInt aAcceptErr, TInt aAcceptErr2 )
+    {    
+    if ( aError != KErrNone &&
+         aError != aAcceptErr &&
+         aError != aAcceptErr2 )
+        {
+        DLERROR(("Error: %d, leaving", aError));
+        User::Leave( aError );
+        }    
+    }
+
+
+void LeaveIfNotErrorL( TInt aError, TInt aAcceptErr, 
+    TInt aAcceptErr2, TInt aAcceptErr3 )
+    {
+    if ( aError != KErrNone &&
+         aError != aAcceptErr &&
+         aError != aAcceptErr2 &&
+         aError != aAcceptErr3 )
+        {
+        DLERROR(("Error: %d, leaving", aError));
+        User::Leave( aError );
+        }    
+    }
+    
+
+void OpenOrCreateFileL( 
+    RFs& aFs, RFile& aFile, const TDesC& aFilePath, TUint aFileMode )
+    {
+    DLTRACEIN((""));
+    TInt err = aFile.Open( aFs, aFilePath, aFileMode );
+    if ( err == KErrNotFound ) 
+        {
+        DLTRACE(("file not found, creating"));
+        User::LeaveIfError( aFile.Create( aFs, aFilePath, aFileMode ) );
+        }
+    else if ( err != KErrNone ) 
+        {
+        DLERROR(("Error when opening: %d", err));
+        User::Leave( err );
+        }    
+    }