menufw/hierarchynavigator/hnmetadatamodel/src/hnmdlocalizationelement.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 17 Dec 2009 08:40:49 +0200
changeset 0 f72a12da539e
permissions -rw-r--r--
Revision: 200949 Kit: 200951

/*
* Copyright (c) 2007-2008 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 <f32file.h>
#include "hnmdlocalizationelement.h"
#include "hnglobals.h"
#include "hnconvutils.h"
#include "hnutils.h"

const TText8 KSPChar = ' ';
const TText8 KNLChar = '\n';
const TInt KWholeFileReadLimit = 1024;

// ======== MEMBER FUNCTIONS ========

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
TUint32 HBufC8Hash( HBufC8* const &  aBuf )
    {
    return DefaultHash::Des8(*aBuf);
    }
// ---------------------------------------------------------------------------
//
// ---------------------------------------------------------------------------
//
TBool HBufC8Ident( HBufC8* const & aL, HBufC8* const & aR )
    {
    return DefaultIdentity::Des8(*aL, *aR);
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CHnMdLocalizationElement::ConstructL( const TDesC& aNamespace, 
                                           const TDesC& aSource )
    {
    iNamespace.CreateL( aNamespace );
    iSource.CreateL( aSource );
    iSource.LowerCase();
    LocateLanguageFileL();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CHnMdLocalizationElement::ConstructL( TXmlEngElement aElement )
    {
    ASSERT( aElement.HasAttributeL( KNameSpaceAttrName8 ) );

    SetNamespaceL( aElement.AttributeNodeL( KNameSpaceAttrName8 ) );
    SetSourceL( aElement.AttributeNodeL( KSourceAttrName8 ) );
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CHnMdLocalizationElement::SetNamespaceL( TXmlEngAttr aNamespace )
    {
    HBufC* namespac = HnConvUtils::Str8ToStrLC( aNamespace.Value() );
    
    iNamespace.Close();
    iNamespace.CreateL( *namespac );

    CleanupStack::PopAndDestroy( namespac );
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CHnMdLocalizationElement::SetSourceL( TXmlEngAttr aSource )
    {
    HBufC* source = HnConvUtils::Str8ToStrLC( aSource.Value() );
    iSource.Close();
    iSource.CreateL( *source );
    iSource.LowerCase();
    LocateLanguageFileL();
    CleanupStack::PopAndDestroy( source );
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
CHnMdLocalizationElement* CHnMdLocalizationElement::NewL(
        TXmlEngElement aElement )
    {
    CHnMdLocalizationElement* self = new( ELeave ) CHnMdLocalizationElement;
    CleanupStack::PushL( self );
    self->ConstructL( aElement );
    CleanupStack::Pop( self );
    return self;
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
CHnMdLocalizationElement* CHnMdLocalizationElement::NewL(const TDesC& aNamespace, 
                                                         const TDesC& aSource)
    {
    CHnMdLocalizationElement* self = new( ELeave ) CHnMdLocalizationElement;
    CleanupStack::PushL( self );
    self->ConstructL( aNamespace, aSource );
    CleanupStack::Pop( self );
    return self;
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
CHnMdLocalizationElement::CHnMdLocalizationElement():
    iResourceIDs( &HBufC8Hash, &HBufC8Ident )
    {
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
CHnMdLocalizationElement::~CHnMdLocalizationElement()
    {
    iNamespace.Close();
    iSource.Close();
    delete iSourcePath;
    THashMapIter<HBufC8*, TInt> iter( iResourceIDs );
    while ( HBufC8* const * ptr = iter.NextKey() )
        {       
        delete *ptr;
        }    
    iResourceIDs.Close();
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
const TDesC& CHnMdLocalizationElement::Namespace() const
    {
    return iNamespace;
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
const TDesC& CHnMdLocalizationElement::Source() const
    {
    return iSource;
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
HBufC* CHnMdLocalizationElement::SourcePath() const
    {
    return iSourcePath;
    }
// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
TBool CHnMdLocalizationElement::SourceExists() const
    {
    if ( iSourcePath )
    	{
        return iSourcePath->Compare(KNullDesC) != 0;
    	}
    else
    	{
    	return EFalse;
    	}
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CHnMdLocalizationElement::LocateLanguageFileL()
	{
	delete iSourcePath;
    iSourcePath = NULL;
    iSourcePath = HnUtils::LocateNearestLanguageFileLC( iSource );
    CleanupStack::Pop( iSourcePath );
	}

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
const TInt& CHnMdLocalizationElement::FindResourceIdL( HBufC8* aResourceName )
    {
    if ( iState&EInitialized )
        {
        // check if we have it in cache
        TInt* result = iResourceIDs.Find(aResourceName);
        if (result)
            {
            return *result;
            }
        else if (iState&EWholeFileCached) // all should be in cache
            {
            User::Leave(KErrNotFound);
            }
        }
    
    if (!(iState&EInitialized) || iState&EUsedItemsCached )
        {
        // set initialized here, as we could have problem with file read
        // i.e. file is missing, but we dont want to go here next time
        iState |= EInitialized;
        HBufC8* rsgContent = ReadRsgContentLC( );
		if (rsgContent->Length() < KWholeFileReadLimit)
			{
			iState |= EWholeFileCached;
			ParseRsgContentL(*rsgContent);
			}
		else
			{
			iState |= EUsedItemsCached;
			ParseRsgContentL(*rsgContent, *aResourceName);
			}          
        //cleanup
        CleanupStack::PopAndDestroy(rsgContent);   
        }
    
    return iResourceIDs.FindL(aResourceName);
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
HBufC8* CHnMdLocalizationElement::ReadRsgContentLC( )
    {
    HBufC8* result(NULL);
    if ( iSourcePath->Compare( KNullDesC ) )
    	{
    	HBufC* fPath = iSourcePath->AllocLC();
		// change extension to rsg        
		TInt extPos = fPath->LocateReverse(KExtDelimiter);
		fPath->Des().Replace(extPos, fPath->Length() - extPos, KRsg);
		result = HnUtils::ReadFileLC(*fPath);
		CleanupStack::Pop(result);
		CleanupStack::PopAndDestroy(fPath);
		CleanupStack::PushL(result);
    	}
    else
    	{
        result = KNullDesC8().AllocLC();   
    	}
    return result;
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CHnMdLocalizationElement::ParseRsgContentL( const TDesC8& aContent )
    {
    TPtrC8 content(aContent);
    TInt posEoL(-1);
    // iterate over each line
    while ((posEoL = content.Locate(KNLChar)) > 0)
        {
        TPtrC8 line = content.Left( posEoL - 1 );        
        TInt firstSpace  = line.Locate(KSPChar);
        TInt lastSpace  = line.LocateReverse(KSPChar);
        // resource name
        TPtrC8 rname =  line.Mid(firstSpace, lastSpace - firstSpace);
        // resource id
        TPtrC8 rid =  line.Right( line.Length() - lastSpace - 1 );
        // trim resource name
        HBufC8* rnameTrimmed = rname.AllocLC();
        rnameTrimmed->Des().Trim();                
        // parse numer and insert to map
        TInt id(0);
        User::LeaveIfError( HnConvUtils::Str8ToInt(rid, id) );        
        User::LeaveIfError( iResourceIDs.Insert(rnameTrimmed->AllocL(), id) );        
        CleanupStack::PopAndDestroy(rnameTrimmed);
        // start search from next line
        content.Set(content.Mid( posEoL + 1 ));
        }    
    }

// ---------------------------------------------------------------------------
// 
// ---------------------------------------------------------------------------
//
void CHnMdLocalizationElement::ParseRsgContentL( const TDesC8& aContent, 
                                                 const TDesC8& aResourceName )
    {
    TPtrC8 content(aContent);
    
    HBufC8* resourceName = HBufC8::NewLC( aResourceName.Length() 
                                          + 2 /* extra spaces */  );
    // add extra space to make sure that we find the right one    
    resourceName->Des().Append(KSPChar);
    resourceName->Des().Append(aResourceName);
    resourceName->Des().Append(KSPChar);    
    
    TInt position = content.Find(*resourceName);
    User::LeaveIfError(position); // we can not find resource
    TPtrC8 contentAfterMid = content.Mid( position + 
                                          resourceName->Length());

    TInt posResId = contentAfterMid.Locate(KNLChar);
    User::LeaveIfError(posResId); // we can not find resource
    TPtrC8 rid = contentAfterMid.Left(posResId - 1);    
    
    HBufC8* ridTrimmed = rid.AllocLC();
    ridTrimmed->Des().Trim();
    // trim also resource name
    resourceName->Des().Trim();

    TInt id(0);
    User::LeaveIfError( HnConvUtils::Str8ToInt( *ridTrimmed, id) );      
    User::LeaveIfError( iResourceIDs.Insert( resourceName->AllocL(), id) );
    // clean up
    CleanupStack::PopAndDestroy(ridTrimmed);
    CleanupStack::PopAndDestroy(resourceName);        
    }