languageinterworkingfw/servicehandler/src/liwvariant.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Thu, 10 Sep 2009 12:58:32 +0300
changeset 18 a7062f7f0b79
parent 10 e20d19ef9b09
permissions -rw-r--r--
Revision: 200935 Kit: 200937

/*
* Copyright (c) 2003-2005 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:       Implementation of class TLiwVariant.
*
*/







// INCLUDES
#ifdef _DEBUG
#include <e32svr.h>
#endif
#include "liwvariant.h"
#include "liwgenericparam.h" 

// ============================= LOCAL FUNCTIONS ===============================

using namespace LIW;
namespace {

// CONSTANTS
/// TLiwVariant streaming version
const TInt KVersion = 10;  // Version 1.0


const TInt KBufSizeMid = 128;
const TInt KBufSizeSmall = 64;
const TInt KBufSizeLarge = 8192;

   
// Debug helpers
#ifdef _DEBUG

enum TPanicCode
    {
    EPanicPostCond_Constructor = 1,
    EPanicPostCond_Reset,
    EPanicPostCond_Set_TInt32,
    EPanicPostCond_Set_TUid,
    EPanicPostCond_Set_TTime,
    EPanicPostCond_Set_TDesC,
    EPanicPostCond_CopyL,
    EPanicInvariant_InvalidDesCState,
    EPanicPostCond_Set_TDesC8,
    EPanicPreCond_DataSizeMismatch,
    EPanicPostCond_Set_TBool,
    EPanicPostCond_Set_TUint,
    EPanicPostCond_Set_TReal,
    EPanicPostCond_Set_TInt64
    };

void Panic(TPanicCode aCode)
    {
    _LIT(KPanicText, "TLiwVariant");
    User::Panic(KPanicText, aCode);
    }

#endif  // #ifdef _DEBUG

}  // namespace
 
_LIT8(KDummy, "Dummy"); // needed for BC-preserving hack to store info about ownership of container

/*
 * class CLiwContainer, class CLiwIterable, class CLiwList, class CLiwMap,
 * class CLiwDefaultList, class CLiwDefaultMap
 */

EXPORT_C void CLiwContainer::PushL() 
    {
    CleanupClosePushL(*this);
    }

EXPORT_C void CLiwContainer::ExternalizeL(RWriteStream&) const
    {
    User::Leave(KErrNotSupported);
    }

EXPORT_C TInt CLiwContainer::Size() const
    {
    return KErrNotSupported;
    }

EXPORT_C CLiwContainer::~CLiwContainer()
    {
   /*
    * Since CLiwContainer is based on reference count mechanism, it does not go with CleanupStack::PushL()
    *
    * LIW takes care of managing the memory in heap for CLiwContainer using the reference count logic
    * 
    * The container should not be destroyed until the reference count is ZERO.
    * If the reference count is not equal to ZERO, it means there are some more owners of that container
    * 
    * This panics if the reference count is not equal to ZERO, in DEBUG Mode only
    *
    * Hence it is recommended to use CleanupClosePushL for Container objects when using CleanupStack
    */
    
    __ASSERT_DEBUG(iRefCount == 0, User::Panic(_L("E32USER-CBase: 33"), 1));
    }

EXPORT_C void CLiwContainer::Close()
    {
    DecRef();
    }


EXPORT_C TBool CLiwIterable::operator==(CLiwIterable& aOther)
    {
    if (this == &aOther)
    return ETrue;

    Reset();
    aOther.Reset();

    TBool rval = ETrue;
    TLiwVariant variant1, variant2;

    TRAPD(error, {
    while (NextL(variant1)) 
	    {
	      if (!aOther.NextL(variant2) || (variant1 != variant2))
	        rval = EFalse;
	    }
    });

    if (rval && (error == KErrNone))
        {
        TRAP(error, (rval = !(aOther.NextL(variant2))));
        }

    variant1.Reset();
    variant2.Reset();
    
    return (error == KErrNone) ? rval : EFalse;
    }

EXPORT_C TBool CLiwList::operator==(const CLiwList& aOther) const
    {
    TInt count = Count();
    if (count != aOther.Count())
    return EFalse;

    TInt error = KErrNone;
    TBool retval = ETrue;
    TLiwVariant variant1, variant2;
    for (TInt index = 0; index < count; index++) {
    TRAP(error, {
      AtL(index, variant1); aOther.AtL(index, variant2);
    });
    if ((error != KErrNone) || (!(variant1 == variant2)))
        {
        retval = EFalse;
        break;
        }
    }
    variant1.Reset();
    variant2.Reset();
    return retval;
    }

EXPORT_C TBool CLiwMap::operator==(const CLiwMap& aOther) const
    {
    TInt count = Count();
    if (count != aOther.Count())
    return EFalse;

    TInt error = KErrNone;
    TBool retval = ETrue;
    TLiwVariant variant1, variant2;
    TBuf8<KBufSizeMid> buf1, buf2;
    for (TInt index = 0; index < count; index++)
        {
        TRAP(error, {
          AtL(index, buf1); aOther.AtL(index, buf2);
          retval = (FindL(buf1, variant1) && aOther.FindL(buf2, variant2));
        });
        if (error != KErrNone)
          retval = EFalse;
        if (!retval || (!(variant1 == variant2)))
            {
            retval = EFalse;
            break;
            }
        }
    variant1.Reset();
    variant2.Reset();
    return retval;
    }

EXPORT_C CLiwDefaultList* CLiwDefaultList::NewL()
    {
    CLiwGenericParamList* gl = CLiwGenericParamList::NewLC();
    CLiwDefaultList* tempList = new (ELeave) CLiwDefaultList(gl);
    CleanupStack::Pop(gl); // gl
    return tempList;
    }

EXPORT_C CLiwDefaultList* CLiwDefaultList::NewLC()
    {
    CLiwGenericParamList* gl = CLiwGenericParamList::NewLC();
    CLiwDefaultList* tempList = new (ELeave) CLiwDefaultList(gl);
    CleanupStack::Pop(gl); // gl
    CleanupClosePushL(*tempList);
    return tempList;
    }

EXPORT_C CLiwDefaultList* CLiwDefaultList::NewLC(RReadStream& aStream)
    {
    CLiwDefaultList* tempList = CLiwDefaultList::NewL();
    CleanupClosePushL(*tempList);
    tempList->iList->InternalizeL(aStream);
    return tempList;
    }

EXPORT_C void CLiwDefaultList::AppendL(const TLiwVariant& aValue)
    {
    iList->AppendL(TLiwGenericParam(EGenericParamUnspecified, aValue));
    }

EXPORT_C TBool CLiwDefaultList::AtL(TInt aIndex, TLiwVariant& aValue) const
    {
    if(0 <= aIndex && aIndex < iList->Count())
        {
        aValue.SetL((*iList)[aIndex].Value());
        return ETrue;   
        }
    else
        {
        return EFalse;    
        }
    }

EXPORT_C void CLiwDefaultList::Remove(TInt aIndex)
    {
    if(0 <= aIndex && aIndex < iList->Count())
        {
        iList->iParameters[aIndex].Destroy();
        iList->iParameters.Remove(aIndex);   
        }
    }

EXPORT_C TInt CLiwDefaultList::Count() const
    {
    return iList->Count();
    }

EXPORT_C void CLiwDefaultList::ExternalizeL(RWriteStream& aStream) const
    {
    iList->ExternalizeL(aStream);
    }

EXPORT_C TInt CLiwDefaultList::Size() const
    {
    return iList->Size();
    }

EXPORT_C CLiwDefaultList::~CLiwDefaultList()
    {
    delete iList;
    }

EXPORT_C CLiwDefaultMap* CLiwDefaultMap::NewL()
    {
    CLiwGenericParamList* gl = CLiwGenericParamList::NewLC();
    CLiwDefaultMap* tempMap = new (ELeave) CLiwDefaultMap(gl);
    CleanupStack::Pop(gl); // gl
    return tempMap;
    }

EXPORT_C CLiwDefaultMap* CLiwDefaultMap::NewLC()
    {
    CLiwGenericParamList* gl = CLiwGenericParamList::NewLC();
    CLiwDefaultMap* tempMap = new (ELeave) CLiwDefaultMap(gl);
    CleanupStack::Pop(gl); // gl
    CleanupClosePushL(*tempMap);
    return tempMap;
    }

EXPORT_C CLiwDefaultMap* CLiwDefaultMap::NewLC(RReadStream& aStream)
    {
    CLiwDefaultMap* tempMap = CLiwDefaultMap::NewL();
    CleanupClosePushL(*tempMap);
    tempMap->iMap->InternalizeL(aStream);
    return tempMap;
    }

EXPORT_C void CLiwDefaultMap::InsertL(const TDesC8& aKey, const TLiwVariant& aValue)
    {
    Remove(aKey);
    TLiwGenericParam mp;
    mp.SetNameAndValueL(aKey, aValue);
    iMap->AppendL(mp);
    mp.Reset();
    }

EXPORT_C TBool CLiwDefaultMap::FindL(const TDesC8& aKey, TLiwVariant& aValue) const
    {
    TInt pos = 0;
    const TLiwGenericParam* tempParam = iMap->FindFirst(pos, aKey);
    if (tempParam)
        {
        aValue.SetL(tempParam->Value());
        return ETrue;
        }
    else
        return EFalse;
    }

EXPORT_C TInt CLiwDefaultMap::Count() const
    {
    return iMap->Count();
    }

EXPORT_C TBool CLiwDefaultMap::AtL(TInt aIndex, TDes8& aKey) const
    {
    if(0 <= aIndex && aIndex < iMap->Count())
        {
        aKey = ((*iMap)[aIndex]).Name();
        return ETrue;   
        }
    else
        {
        return EFalse;  
        }
    }

EXPORT_C const TDesC8& CLiwDefaultMap::AtL(TInt aIndex) const
    {
    if(0 <= aIndex && aIndex < iMap->Count())
        {
        return ((*iMap)[aIndex]).Name();
        }
    else
        {
        User::LeaveIfError(KErrArgument);  
        return KNullDesC8;
        }
    }

EXPORT_C void CLiwDefaultMap::Remove(const TDesC8& aKey)
    {
    TInt pos = 0;
    iMap->FindFirst(pos, aKey);
    if (pos != KErrNotFound)
        {
        iMap->iParameters[pos].Destroy();
        iMap->iParameters.Remove(pos);
        }
    }

EXPORT_C void CLiwDefaultMap::ExternalizeL(RWriteStream& aStream) const
    {
    iMap->ExternalizeL(aStream);
    }

EXPORT_C TInt CLiwDefaultMap::Size() const
    {
    return iMap->Size();
    }

EXPORT_C CLiwDefaultMap::~CLiwDefaultMap()
    {
    delete iMap;
    }

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

#ifdef _DEBUG
void TLiwVariant::__DbgTestInvariant() const
    {
    if (iTypeId==EVariantTypeDesC && iData.iBufC)
        {
        __ASSERT_ALWAYS(iData.iBufC->Ptr() == iPtrC.Ptr(), 
            Panic(EPanicInvariant_InvalidDesCState));
        
        }
    }
#endif  // #ifdef _DEBUG


EXPORT_C void TLiwVariant::PushL()
    {
    CleanupStack::PushL( TCleanupItem( TLiwVariant::VariantCleanup , this) );
    }

EXPORT_C void TLiwVariant::VariantCleanup( TAny* aObj )
    {
    static_cast<TLiwVariant*>(aObj)->Destroy();
    }

inline void TLiwVariant::SInt64::InternalizeL(RReadStream& aStream)
    {
    TInt32 low = aStream.ReadInt32L();
    iHigh = aStream.ReadInt32L();
    iLow = low;
    }

inline void TLiwVariant::SInt64::ExternalizeL(RWriteStream& aStream) const
    {
    aStream.WriteInt32L(iLow);
    aStream.WriteInt32L(iHigh);
    }

inline void TLiwVariant::SInt64::Set(const TInt64& aTInt64)
    {
    iLow = I64LOW(aTInt64);
    iHigh = I64HIGH(aTInt64);
    }

inline TLiwVariant::SInt64::operator TInt64() const
    {
    return MAKE_TINT64(iHigh,iLow);
    }

inline TBool TLiwVariant::SInt64::operator==(const SInt64& aRhs) const
    {
    return (iHigh==aRhs.iHigh && iLow==aRhs.iLow);
    }


EXPORT_C TLiwVariant::TLiwVariant(const TLiwVariant& aSrc) :
    iTypeId(aSrc.iTypeId), iData(aSrc.iData), iPtrC(), iPtrC8()
    {
    if (iTypeId == EVariantTypeDesC)
        {
        iPtrC.Set(aSrc.iPtrC);
        // Do not take ownership of data
        iData.iBufC = NULL;
        }
    else if ( iTypeId == EVariantTypeDesC8 )
        {
        iPtrC8.Set( aSrc.iPtrC8 );
        // Do not take ownership of data
        iData.iBufC8 = NULL;
        }
    }

EXPORT_C TLiwVariant& TLiwVariant::operator=(const TLiwVariant& aSrc)
    {
    // Check self-assignment first.
    if (this == &aSrc)
        {
        return *this;
        }
    Reset(); 
    iTypeId = aSrc.iTypeId;
    iData = aSrc.iData;
    if (iTypeId == EVariantTypeDesC)
        {
        iPtrC.Set(aSrc.iPtrC);
        // Do not take ownership of data
        iData.iBufC = NULL;
        }
    else if ( iTypeId == EVariantTypeDesC8 )
        {
        iPtrC8.Set( aSrc.iPtrC8 );
        // Do not take ownership of data
        iData.iBufC8 = NULL;
        }
    return *this;
    }

EXPORT_C TBool TLiwVariant::Get(TInt32& aValue) const
    {
    __TEST_INVARIANT;
    if (iTypeId == EVariantTypeTInt32)
        {
        aValue = iData.iInt32;
        return ETrue;
        }
    else if (iTypeId == EVariantTypeTReal)
	    {
	    aValue = (TInt32)iData.iReal;
	    return ETrue;
	    }
	else if (iTypeId == EVariantTypeDesC8)  //string to real conversion
		{
		TLex8 parseString(iPtrC8);
		TInt err = parseString.Val(aValue);
		if(err == KErrNone)
			return ETrue;
		}
	else if (iTypeId == EVariantTypeDesC)  //string to real conversion
		{
		TLex16 parseString(iPtrC);
		TInt err = parseString.Val(aValue);
		if(err == KErrNone)
			return ETrue;		
		}
	else if (iTypeId == EVariantTypeTUint) //TUint to int conversion
	    {
	    aValue = (TInt32)iData.iUint;
	    return ETrue;
	    }
	else if (iTypeId == EVariantTypeTInt64) //TInt64 to TInt32 conversion
	    {
	    aValue = (TInt32)iData.iLong; //Warning : Results in loss of data sometimes
	    return ETrue;
	    }
	return EFalse;
    }
    
EXPORT_C TBool TLiwVariant::Get(TInt64& aValue) const
    {
    __TEST_INVARIANT;
    if (iTypeId == EVariantTypeTInt64)
        {
        aValue = iData.iLong;
        return ETrue;
        }
    else if (iTypeId == EVariantTypeTInt32)
        {
        aValue = iData.iInt32;
        return ETrue;
        }
    else if (iTypeId == EVariantTypeTReal)
	    {
	    aValue = (TInt32)iData.iReal;
	    return ETrue;
	    }
	else if (iTypeId == EVariantTypeDesC8)  //string to real conversion
		{
		TLex8 parseString(iPtrC8);
		TInt err = parseString.Val(aValue);
		if(err == KErrNone)
			return ETrue;
		}
	else if (iTypeId == EVariantTypeDesC)  //string to real conversion
		{
		TLex16 parseString(iPtrC);
		TInt err = parseString.Val(aValue);
		if(err == KErrNone)
			return ETrue;		
		}
	else if (iTypeId == EVariantTypeTUint) //TUint to int conversion
	    {
	    aValue = (TInt32)iData.iUint;
	    return ETrue;
	    }
    return EFalse;
    }
    
EXPORT_C TBool TLiwVariant::Get(TReal& aValue) const
    {
    __TEST_INVARIANT;
    if (iTypeId == EVariantTypeTReal)
        {
        aValue = iData.iReal;
        return ETrue;
        }
    else if(iTypeId == EVariantTypeTInt32)
    	{
    	aValue = iData.iInt32;
    	return ETrue;
    	}
    else if (iTypeId == EVariantTypeDesC8)  //string to integer conversion
		{
		TLex8 parseString(iPtrC8);
		TInt err = parseString.Val(aValue);
		if(err == KErrNone)
			return ETrue;		
		}
	else if (iTypeId == EVariantTypeDesC)  //string to integer conversion
		{
		TLex16 parseString(iPtrC);
		TInt err = parseString.Val(aValue);
		if(err == KErrNone)
			return ETrue;		
		}
	else if (iTypeId == EVariantTypeTUint) //TUint to real conversion
	    {
	    aValue = iData.iUint;
	    return ETrue;
	    }
    else if(iTypeId == EVariantTypeTInt64)
    	{
    	aValue = iData.iLong; //Warning : Results in loss of data
    	return ETrue;
    	}
    return EFalse;
    }
EXPORT_C TBool TLiwVariant::Get(TBool& aValue) const
    {
    __TEST_INVARIANT;
    if (iTypeId == EVariantTypeTBool)
        {
        aValue = iData.iBool;
        return ETrue;
        }
    return EFalse;
    }
    
EXPORT_C TBool TLiwVariant::Get(TUint& aValue) const
    {
    __TEST_INVARIANT;
    if (iTypeId == EVariantTypeTUint)
        {
        aValue = iData.iUint;
        return ETrue;
        }        
    else if (iTypeId == EVariantTypeTReal) //real to TUint conversion
        {
        aValue = static_cast<TUint>(iData.iReal);
        return ETrue;
        }
    else if(iTypeId == EVariantTypeTInt32) // TInt32 to TUint conversion
    	{
        aValue = static_cast<TUint>(iData.iInt32);
    	return ETrue;
    	}
    else if (iTypeId == EVariantTypeDesC8)  //desc8 to TUint conversion
		{
		TLex8 parseString(iPtrC8);
		TInt err = parseString.Val(aValue);
		if(err == KErrNone)
			return ETrue;		
		}
	else if (iTypeId == EVariantTypeDesC)  //desc16 to TUint conversion
		{
		TLex16 parseString(iPtrC);
		TInt err = parseString.Val(aValue);
		if(err == KErrNone)
        return ETrue;
        }
    else if(iTypeId == EVariantTypeTInt64) // TInt32 to TUint conversion
    	{
        aValue = static_cast<TUint>(iData.iLong); //Warning : Results in loss of data
    	return ETrue;
    	}
    return EFalse;
    }

EXPORT_C TBool TLiwVariant::Get(TUid& aValue) const
    {
    __TEST_INVARIANT;
    if (iTypeId == EVariantTypeTUid)
        {
        aValue = TUid::Uid(iData.iInt32);
        return ETrue;
        }
    return EFalse;
    }

EXPORT_C TBool TLiwVariant::Get(TPtrC& aValue) const
    {
    __TEST_INVARIANT;
    if (iTypeId == EVariantTypeDesC)
        {
        aValue.Set(iPtrC);
        return ETrue;
        }
    return EFalse;
    }

EXPORT_C TBool TLiwVariant::Get(TTime& aValue) const
    {
    __TEST_INVARIANT;
    if (iTypeId == EVariantTypeTTime)
        {
        aValue = TTime(iData.iInt64);
        return ETrue;
        }
    return EFalse;
    }


EXPORT_C TBool TLiwVariant::Get(TPtrC8& aValue) const
    {
     __TEST_INVARIANT;  
    if (iTypeId == EVariantTypeDesC8)
        {
        aValue.Set(iPtrC8);
        return ETrue;
        }   

    return EFalse;
    }

EXPORT_C TBool TLiwVariant::Get(TDes& aValue) const
    {
     __TEST_INVARIANT;  
    if (iTypeId == EVariantTypeDesC)
        {
        aValue.Copy(iPtrC);
        return ETrue;
        }   
	else if (iTypeId == EVariantTypeDesC8)
        {
        aValue.Copy(iPtrC8);
        return ETrue;
        }   
	else if (iTypeId == EVariantTypeTReal) //real to TDes conversion
        {
        const TRealFormat realFormat;
        aValue.Num(iData.iReal,realFormat);
        return ETrue;
        }
    else if(iTypeId == EVariantTypeTInt32) // TInt32 to TDes conversion
    	{
    	aValue.Num(iData.iInt32);
    	return ETrue;
    	}
    else if(iTypeId == EVariantTypeTUint) // TInt32 to TDes conversion
    	{
    	aValue.Num(iData.iUint,EDecimal);
    	return ETrue;
    	}
    else if(iTypeId == EVariantTypeTInt64) // TInt32 to TDes conversion
    	{
    	aValue.Num(iData.iLong);
    	return ETrue;
    	}
    return EFalse;
    }


EXPORT_C TBool TLiwVariant::Get(TDes8& aValue) const
    {
     __TEST_INVARIANT;  
    if (iTypeId == EVariantTypeDesC8)
        {
        aValue.Copy(iPtrC8);
        return ETrue;
        }   
	else if (iTypeId == EVariantTypeDesC)
        {
        aValue.Copy(iPtrC);
        return ETrue;
        }   
	else if (iTypeId == EVariantTypeTReal) //real to TDes8 conversion
        {
        const TRealFormat realFormat;
        aValue.Num(iData.iReal,realFormat);
        return ETrue;
        }
   else if(iTypeId == EVariantTypeTInt32) // TInt32 to TDes8 conversion
    	{
    	aValue.Num(iData.iInt32);
    	return ETrue;
    	}
    else if(iTypeId == EVariantTypeTUint) // TInt32 to TDes conversion
    	{
    	aValue.Num(iData.iUint,EDecimal);
    	return ETrue;
    	}
    else if(iTypeId == EVariantTypeTInt64) // TInt32 to TDes8 conversion
    	{
    	aValue.Num(iData.iLong);
    	return ETrue;
    	}
    return EFalse;
    }


EXPORT_C TBool TLiwVariant::Get(RFile& aValue) const
    {
    __TEST_INVARIANT;
    if (iTypeId == EVariantTypeFileHandle)
        {
        aValue = *((RFile*)&iData.iInt64);      
        return ETrue;
        }

    return EFalse;
    }

EXPORT_C TBool TLiwVariant::Get(CLiwList& aValue) const
    {
    __TEST_INVARIANT;
    if (iTypeId == EVariantTypeList)
        {
        TInt pos = 0;
        TLiwVariant tempVarient;
        tempVarient.PushL();
        // Overwrite the list
        if(0 != aValue.Count())
            {
            // make the list Empty
            for (pos = aValue.Count() - 1; pos >= 0 ; pos--)
                aValue.Remove(pos);
            }
        // Copy List varient by varient
        for (pos = 0; pos < iData.iList->Count(); pos++)
            {
            iData.iList->AtL(pos, tempVarient);
            aValue.AppendL(tempVarient);
            }
        CleanupStack::Pop(&tempVarient);
    	tempVarient.Reset();
        return ETrue;
        }

    return EFalse;
    }
    
EXPORT_C TBool TLiwVariant::Get(CLiwMap& aValue) const
    {
    __TEST_INVARIANT;
    if (iTypeId == EVariantTypeMap)
        {
        TInt pos = 0;
        TLiwVariant tempVarient;
        tempVarient.PushL();
        // Overwrite the Map
        if(0 != aValue.Count())
            {
            // make the Map Empty
            for (pos = aValue.Count() - 1; pos >= 0 ; pos--)
                {
                TBuf8<KBufSizeSmall> mapKey;
                aValue.AtL(pos, mapKey);
                aValue.Remove(mapKey);
                }
            }
        // Copy Map varient by varient
        for (pos = 0; pos < iData.iMap->Count(); pos++)
            {
            TBuf8<KBufSizeSmall> mapKey;
            iData.iMap->AtL(pos, mapKey);
            iData.iMap->FindL(mapKey, tempVarient);
            aValue.InsertL(mapKey, tempVarient);
            }
        CleanupStack::Pop(&tempVarient);
    	tempVarient.Reset();      
        return ETrue;
        }

    return EFalse;
    }
EXPORT_C TReal TLiwVariant::AsTReal() const
    {
    TReal value = 0;
    Get(value);
    return value;
    }   
    
EXPORT_C TInt32 TLiwVariant::AsTInt32() const
    {
    TInt32 value = 0;
    Get(value);
    return value;
    }   

EXPORT_C TInt64 TLiwVariant::AsTInt64() const
    {
    TInt64 value = 0;
    Get(value);
    return value;
    }   

EXPORT_C CLiwBuffer* TLiwVariant::AsBuffer() const
    {
    __TEST_INVARIANT;
    if (iTypeId == EVariantTypeBuffer)
    	{
	    return iData.iBuffer;
    	}    
    	
    return NULL;	
    }   
    
EXPORT_C TBool TLiwVariant::AsTBool() const
    {
    TBool value = 0;
    Get(value);
    return value;
    }   

EXPORT_C TBool TLiwVariant::AsTUint() const
    {
    TUint value = 0;
    Get(value);
    return value;
    } 

EXPORT_C TUid TLiwVariant::AsTUid() const
    {
    __TEST_INVARIANT;
    TUid value = {0};
    Get(value);
    return value;
    }

EXPORT_C TPtrC TLiwVariant::AsDes() const
    {
    __TEST_INVARIANT;
    TPtrC value;
    Get(value);
    return value;
    }

EXPORT_C TTime TLiwVariant::AsTTime() const
    {
    __TEST_INVARIANT;
    TTime value(Time::NullTTime());
    Get(value);
    return value;
    }


EXPORT_C TPtrC8 TLiwVariant::AsData() const
    {
     __TEST_INVARIANT;
    TPtrC8 value;
    Get(value);
    return value;
    }


EXPORT_C RFile TLiwVariant::AsFileHandle() const
    {
    __TEST_INVARIANT;
    RFile value;
    Get(value);
    return value;
    }

EXPORT_C const CLiwList* TLiwVariant::AsList() const
    {
    __TEST_INVARIANT;
    return (iTypeId == EVariantTypeList) ? iData.iList : NULL;
    }

EXPORT_C const CLiwMap* TLiwVariant::AsMap() const
   {
   __TEST_INVARIANT;
   return (iTypeId == EVariantTypeMap) ? iData.iMap : NULL;
   }

EXPORT_C MLiwInterface* TLiwVariant::AsInterface() const
   {
   __TEST_INVARIANT;
   return (iTypeId == EVariantTypeInterface) ? iData.iSession : NULL;
   }

EXPORT_C CLiwIterable* TLiwVariant::AsIterable() const
    {
    __TEST_INVARIANT;
    return (iTypeId == EVariantTypeIterable) ? iData.iIterable : NULL;
    }

EXPORT_C void TLiwVariant::Reset()
    {
    __TEST_INVARIANT;

    if (iTypeId == EVariantTypeDesC)
        {
        // Delete any owned buffer
        delete iData.iBufC;
        iData.iBufC = NULL;
        }
    else if (iTypeId == EVariantTypeDesC8)
        {
        delete iData.iBufC8;
        iData.iBufC8 = NULL;
        }       
    else if (iTypeId == EVariantTypeList)
        {
        if (iPtrC8.Compare(KDummy) == 0)
            {
            iData.iList->DecRef();
            iData.iList = NULL;
            iPtrC8.Set(TPtrC8());
            }
        }   
    else if (iTypeId == EVariantTypeMap)
        {
        if (iPtrC8.Compare(KDummy) == 0)
            {
            iData.iMap->DecRef();
            iData.iMap = NULL;
            iPtrC8.Set(TPtrC8());
            }
        }   
    else if (iTypeId == EVariantTypeIterable)
        {
        if (iPtrC8.Compare(KDummy) == 0)
            {
            iData.iIterable->DecRef();
            iData.iIterable = NULL;
            iPtrC8.Set(TPtrC8());
            }
        }
	else if (iTypeId == EVariantTypeBuffer)
        {
        if (iPtrC8.Compare(KDummy) == 0)
            {
            iData.iBuffer->DecRef();
            iData.iBuffer = NULL;
            iPtrC8.Set(TPtrC8());
            }
        }        
    // No need to clear other data, because Get methods wont't do anything if type
    // is Null.
    iTypeId = EVariantTypeNull;

    __ASSERT_DEBUG(IsEmpty(), Panic(EPanicPostCond_Reset));
    __TEST_INVARIANT;
    }

EXPORT_C void TLiwVariant::Set(TInt32 aValue)
    {
    __TEST_INVARIANT;
    
    Reset();
    iTypeId = EVariantTypeTInt32;
    iData.iInt32 = aValue;
    
    __ASSERT_DEBUG(this->AsTInt32()==aValue, Panic(EPanicPostCond_Set_TInt32));
    __TEST_INVARIANT;
    }

EXPORT_C void TLiwVariant::Set(TInt64 aValue)
    {
    __TEST_INVARIANT;
    
    Reset();
    iTypeId = EVariantTypeTInt64;
    iData.iLong = aValue;
    
    __ASSERT_DEBUG(this->AsTInt64()==aValue, Panic(EPanicPostCond_Set_TInt64));
    __TEST_INVARIANT;
    }

EXPORT_C void TLiwVariant::Set(TReal aValue)
    {
    __TEST_INVARIANT;
    
    Reset();
    iTypeId = EVariantTypeTReal;
    iData.iReal = aValue;
    
    __ASSERT_DEBUG(this->AsTReal()==aValue, Panic(EPanicPostCond_Set_TReal));
    __TEST_INVARIANT;
    }
EXPORT_C void TLiwVariant::Set(const CLiwBuffer* aValue)
    {
    __TEST_INVARIANT;
    
    Reset();
    iTypeId = EVariantTypeBuffer;
    iData.iBuffer = (CLiwBuffer*)aValue;
    
    __TEST_INVARIANT;
    }

EXPORT_C void TLiwVariant::Set(TBool aValue)
    {
    __TEST_INVARIANT;
    
    Reset();
    iTypeId = EVariantTypeTBool;
    iData.iBool = aValue;
    
    __ASSERT_DEBUG(this->AsTBool()==aValue, Panic(EPanicPostCond_Set_TBool));
    __TEST_INVARIANT;
    }

EXPORT_C void TLiwVariant::Set(TUint aValue)
    {
    __TEST_INVARIANT;
    
    Reset();
    iTypeId = EVariantTypeTUint;
    iData.iUint = aValue;
    
    __ASSERT_DEBUG(this->AsTUint()==aValue, Panic(EPanicPostCond_Set_TUint));
    __TEST_INVARIANT;
    }

EXPORT_C void TLiwVariant::Set(const TUid& aValue)
    {
    __TEST_INVARIANT;
    
    Reset();
    iTypeId = EVariantTypeTUid;
    iData.iInt32 = aValue.iUid;
    
    __ASSERT_DEBUG(this->AsTUid()==aValue, Panic(EPanicPostCond_Set_TUid));
    __TEST_INVARIANT;
    }

EXPORT_C void TLiwVariant::Set(const TTime& aValue)
    {
    __TEST_INVARIANT;
    
    Reset();
    iTypeId = EVariantTypeTTime;
    iData.iInt64.Set(aValue.Int64());
    
    __ASSERT_DEBUG(this->AsTTime()==aValue, Panic(EPanicPostCond_Set_TTime));
    __TEST_INVARIANT;
    }

EXPORT_C void TLiwVariant::Set(const TDesC& aValue)
    {
    __TEST_INVARIANT;

    Reset();
    iTypeId = EVariantTypeDesC;
    iData.iBufC = NULL;  // not owned
    iPtrC.Set(aValue);

    __ASSERT_DEBUG(this->AsDes()==aValue, Panic(EPanicPostCond_Set_TDesC));
    __TEST_INVARIANT;
    }



EXPORT_C void TLiwVariant::Set(const TDesC8& aValue)
    {
   __TEST_INVARIANT;

    Reset();
    iTypeId = EVariantTypeDesC8;
    iData.iBufC8 = NULL;  // not owned
    iPtrC8.Set(aValue);

    __ASSERT_DEBUG(this->AsData()==aValue, Panic(EPanicPostCond_Set_TDesC));
    __TEST_INVARIANT;
    }



EXPORT_C void TLiwVariant::Set(const RFile& aValue)
    {
    __TEST_INVARIANT;
    __ASSERT_DEBUG(sizeof(SInt64) == sizeof(RFile), Panic(EPanicPreCond_DataSizeMismatch));

    Reset();
    iTypeId = EVariantTypeFileHandle;
    *((RFile*)&iData.iInt64) = aValue;

    __TEST_INVARIANT;
    }

EXPORT_C void TLiwVariant::Set(const CLiwList* aValue)
    {
    __TEST_INVARIANT;

    Reset();
    iTypeId = EVariantTypeList;
    iData.iList = (CLiwList*)aValue;

    __TEST_INVARIANT;
    }

EXPORT_C void TLiwVariant::Set(const CLiwMap* aValue)
    {
    __TEST_INVARIANT;

    Reset();
    iTypeId = EVariantTypeMap;
    iData.iMap = (CLiwMap*)aValue;

    __TEST_INVARIANT;
    }

EXPORT_C void TLiwVariant::Set(const MLiwInterface* aValue)
    {
    __TEST_INVARIANT;

    Reset();
    iTypeId = EVariantTypeInterface;
    iData.iSession = (MLiwInterface*)aValue;

    __TEST_INVARIANT;
    }

EXPORT_C void TLiwVariant::Set(const CLiwIterable* aValue)
    {
    __TEST_INVARIANT;

    Reset();
    iTypeId = EVariantTypeIterable;
    iData.iIterable = (CLiwIterable*)aValue;

    __TEST_INVARIANT;
    }
    
EXPORT_C void TLiwVariant::SetL(const TLiwVariant& aValue)
    {
    __TEST_INVARIANT;

    if (aValue.iTypeId == EVariantTypeDesC)
        {
        // Take an own copy of the string value
        HBufC* buf = aValue.iPtrC.AllocL();
        Reset();
        iTypeId = EVariantTypeDesC;
        iData.iBufC = buf;
        iPtrC.Set(*iData.iBufC);
        }
    else if (aValue.iTypeId == EVariantTypeDesC8)
        {
        // Take an own copy of the data
        HBufC8* buf = aValue.iPtrC8.AllocL();
        Reset();
        iTypeId = EVariantTypeDesC8;
        iData.iBufC8 = buf;
        iPtrC8.Set(*iData.iBufC8);
        }
    else if (aValue.iTypeId == EVariantTypeList)
        {
        // Take an own copy of the data by increasing the reference count
        Reset();
        iTypeId = EVariantTypeList;
        iData.iList = aValue.iData.iList;
        iData.iList->IncRef();
        iPtrC8.Set(KDummy);  // hack: mark owned
        }
    else if (aValue.iTypeId == EVariantTypeMap) 
        {
        // Take an own copy of the data by increasing the reference count
        Reset();
        iTypeId = EVariantTypeMap;
        iData.iMap = aValue.iData.iMap;
        iData.iMap->IncRef();
        iPtrC8.Set(KDummy);  // hack: mark owned
        }
    else if (aValue.iTypeId == EVariantTypeIterable) 
        {
        // Take an own copy of the data by increasing the reference count
        Reset();
        iTypeId = EVariantTypeIterable;
        iData.iIterable = aValue.iData.iIterable;
        iData.iIterable->IncRef();
        iPtrC8.Set(KDummy);  // hack: mark owned
        }
	else if (aValue.iTypeId == EVariantTypeBuffer) 
        {
        Reset();
        iTypeId = EVariantTypeBuffer;
        iData.iBuffer = aValue.iData.iBuffer;
       	iData.iBuffer->IncRef();
        iPtrC8.Set(KDummy);  // hack: mark owned
        }        
    else
        {
        Reset();
        iTypeId = aValue.iTypeId;
        // Copy the data union as one block
        iData = aValue.iData;
        }

    //__ASSERT_DEBUG(*this == aValue, Panic(EPanicPostCond_CopyL));
    __TEST_INVARIANT;
    }

void TLiwVariant::Destroy()
    {
    __TEST_INVARIANT;

    if (iTypeId == EVariantTypeDesC)
        {
        // Delete any owned buffer
        delete iData.iBufC;
        iData.iBufC = NULL;
        }
    else if (iTypeId == EVariantTypeDesC8)
        {
        delete iData.iBufC8;
        iData.iBufC8 = NULL;
        }
    else if (iTypeId == EVariantTypeList)
        {
        if (iPtrC8.Compare(KDummy) == 0)
            {
            iData.iList->DecRef();
            iData.iList = NULL;
            iPtrC8.Set(TPtrC8());
            }
        }
    else if (iTypeId == EVariantTypeMap) 
        {
        if (iPtrC8.Compare(KDummy) == 0)
            {
            iData.iMap->DecRef();
            iData.iMap = NULL;
            iPtrC8.Set(TPtrC8());
            }
        }
    else if (iTypeId == EVariantTypeIterable)  
        {
        if (iPtrC8.Compare(KDummy) == 0)
            {
            iData.iIterable->DecRef();
            iData.iIterable = NULL;
            iPtrC8.Set(TPtrC8());
            }
        }
    else if (iTypeId == EVariantTypeBuffer)  
        {
        if (iPtrC8.Compare(KDummy) == 0)
            {
            iData.iBuffer->DecRef();
            iData.iBuffer = NULL;
            iPtrC8.Set(TPtrC8());
            }
        }
    }

void TLiwVariant::InternalizeL(RReadStream& aStream)
    {
    __TEST_INVARIANT;
        
    aStream.ReadInt8L(); // version
    // if older version adapt to changes (who knows if
    // parameters would be also persistent...)

    const TUint8 typeId = aStream.ReadUint8L();
    switch (typeId)
        {
        case EVariantTypeNull:
            {
            Reset();
            break;
            }
        case EVariantTypeTInt32:  // FALLTHROUGH
        case EVariantTypeTUid:
        case EVariantTypeTBool:
        case EVariantTypeTUint:
            {
            TInt32 value = aStream.ReadInt32L();
            Reset();
            iTypeId = typeId;
            iData.iInt32 = value;
            break;
            }
        case EVariantTypeTInt64:
            {
            TInt64 value = aStream.ReadReal64L();
            Reset();
            iTypeId = typeId;
            iData.iLong = value;
            break;
            }
        case EVariantTypeFileHandle: // FALLTHROUGH
        case EVariantTypeTTime:
        case EVariantTypeTReal:
            {
            SInt64 value;
            value.InternalizeL(aStream);
            Reset();
            iTypeId = typeId;
            iData.iInt64 = value;
            break;
            }
        case EVariantTypeDesC:
            {
            const TInt len = aStream.ReadInt32L();
            HBufC* buf = HBufC::NewL(aStream,len);
            Reset();
            iTypeId = typeId;
            iData.iBufC = buf;
            iPtrC.Set(*iData.iBufC);
            break;
            }
        case EVariantTypeDesC8:
            {
            const TInt len = aStream.ReadInt32L();
            HBufC8* buf = HBufC8::NewL(aStream,len);
            Reset();
            iTypeId = typeId;
            iData.iBufC8 = buf;
            iPtrC8.Set(*iData.iBufC8);
            break;
            }
        case EVariantTypeList:  
            {
            CLiwList* list = CLiwDefaultList::NewLC(aStream);
            Reset();
            iTypeId = EVariantTypeList;
            iData.iList = list;
            iPtrC8.Set(KDummy);  // hack: mark owned
            CleanupStack::Pop(list); // list
            break;
            }
        case EVariantTypeMap:  
            {
            CLiwMap* map = CLiwDefaultMap::NewLC(aStream);
            Reset();
            iTypeId = EVariantTypeMap;
            iData.iMap = map;
            iPtrC8.Set(KDummy);  // hack: mark owned
            CleanupStack::Pop(map); // map
            break;
            }
        default:
            {
             // Corrupted data stream.
#ifdef _DEBUG
            RDebug::Print(_L("***ERROR TLiwVariant::InternalizeL"));
#endif
            User::Leave(KErrCorrupt);
            return;
            }
        }

    __TEST_INVARIANT;
    }
    
void TLiwVariant::ExternalizeL(RWriteStream& aStream) const
    {
    __TEST_INVARIANT;

    aStream.WriteInt8L(KVersion);
    // if older version adapt to changes (who knows if parameters would be also persistent...)

    aStream.WriteUint8L(iTypeId);
    switch (iTypeId)
        {
        case EVariantTypeTInt32: // FALLTHROUGH
        case EVariantTypeTUid:
        case EVariantTypeTBool:
        case EVariantTypeTUint:
            {
            aStream.WriteInt32L(iData.iInt32);
            break;
            }
        case EVariantTypeTInt64:
            {
            aStream.WriteReal64L(iData.iLong);
            break;
            }
        case EVariantTypeFileHandle: // FALLTHROUGH
        case EVariantTypeTTime:
        case EVariantTypeTReal:
            {
            iData.iInt64.ExternalizeL(aStream);
            break;
            }
        case EVariantTypeDesC:
            {
            aStream.WriteInt32L(iPtrC.Length());
            aStream << iPtrC;
            break;
            }
        case EVariantTypeDesC8:
            {
            aStream.WriteInt32L(iPtrC8.Length());
            aStream << iPtrC8;
            break;
            }
        case EVariantTypeList:  
            {
            iData.iList->ExternalizeL(aStream);
            break;
            }
        case EVariantTypeMap:  
            {
            iData.iMap->ExternalizeL(aStream);
            break;
            }
        case EVariantTypeInterface:  
            {
            _LIT(KMsg, "TLiwVariant: type Interface not externizable");
            User::Panic(KMsg, 1);
            break;
            }
        default:
            break;
        }

    __TEST_INVARIANT;
    }

TInt TLiwVariant::Size() const
    {
    __TEST_INVARIANT;

    TInt size = sizeof (TInt8); // version
    size += sizeof (TUint8);    // iTypeId
    switch (iTypeId)
        {
        case EVariantTypeTInt32:    // FALLTHROUGH
        case EVariantTypeTUid:
        case EVariantTypeTBool:
        case EVariantTypeTUint:
            {
            size += sizeof (TInt32);
            break;
            }
        case EVariantTypeFileHandle: // FALLTHROUGH
        case EVariantTypeTTime:
        case EVariantTypeTReal:
        case EVariantTypeTInt64:
            {
            size += sizeof (TInt64);
            break;
            }
        case EVariantTypeDesC:
            {
            size += sizeof (TInt32); // length
            //size += 1;              // the externalization method used adds a header byte
            if(iPtrC.Size() >= KBufSizeLarge)
            	{
            	size += 4;
            	}
            else if(iPtrC.Size() >= KBufSizeSmall)
            	{
            	size += 2;
            	}
            else
            	{
            	size += 1;	
            	}
            size += iPtrC.Size();
            size += 1;              // extra one byte for Unicode marker
            break;
            }
        case EVariantTypeDesC8:
            {
            size += sizeof (TInt32); // length
            //size += 1;              // the externalization method used adds a header byte
            if(iPtrC8.Size() >= KBufSizeLarge)
            	{
            	size += 4;
            	}
                      	
            else if(iPtrC8.Size() >= KBufSizeSmall)
            	{
            	size += 2;
            	}
            else
            	{
            	size += 1;
            	}
            size += iPtrC8.Size();
            break;
            }
        case EVariantTypeList:  
            {
            size += iData.iList->Size();
            break;
            }
        case EVariantTypeMap:  
            {
            size += iData.iMap->Size();
            break;
            }
        default:
            break;
        }
    return size;
    }

// ============================ EXTERNAL FUNCTIONS ===============================

EXPORT_C TBool operator==(const TLiwVariant& aLhs, const TLiwVariant& aRhs)
    {
    if (aLhs.iTypeId == aRhs.iTypeId)
        {
        switch (aLhs.iTypeId)
            {
            case EVariantTypeNull:
                {
                // Null equals Null
                return ETrue;
                }
            case EVariantTypeTInt32:  // FALLTHROUGH
            case EVariantTypeTUid:
            case EVariantTypeTBool:
            case EVariantTypeTUint:
                {
                return (aLhs.iData.iInt32 == aRhs.iData.iInt32);
                }
            case EVariantTypeTInt64:
                {
                return (aLhs.iData.iLong == aRhs.iData.iLong);
                }
            case EVariantTypeDesC:
                {
                return (aLhs.iPtrC == aRhs.iPtrC);
                }
            case EVariantTypeDesC8:
                {
                return (aLhs.iPtrC8 == aRhs.iPtrC8);
                }
            case EVariantTypeFileHandle: // FALLTHROUGH
            case EVariantTypeTTime:
            case EVariantTypeTReal:
                {
                return (aLhs.iData.iInt64 == aRhs.iData.iInt64);
                }
            case EVariantTypeList:
                {
                return (*(aLhs.iData.iList) == *(aRhs.iData.iList));
                }
            case EVariantTypeMap:
                {
                return (*(aLhs.iData.iMap) == *(aRhs.iData.iMap));
                }
            case EVariantTypeInterface:
                {
                return (aLhs.iData.iSession == aRhs.iData.iSession);
                }
            case EVariantTypeIterable:
                {
                return (*(aLhs.iData.iIterable) == *(aRhs.iData.iIterable));
                }
            case EVariantTypeBuffer:
                {
                return (aLhs.iData.iBuffer == aRhs.iData.iBuffer);
                }                
            default:
                {
                break;
                }
            }
        }
    return EFalse;
    }

#ifdef _DEBUG
EXPORT_C void Dump(const TLiwVariant& aVariant)
    {
    switch (aVariant.TypeId())
        {
        case EVariantTypeNull:
            {
            RDebug::Print(_L("   TLiwVariant::Dump = Null"));
            break;
            }
        case EVariantTypeTInt32:
            {
            RDebug::Print(_L("   TLiwVariant::Dump(TInt32) = %d"), aVariant.AsTInt32());
            break;
            }
        case EVariantTypeTInt64:
            {
            RDebug::Print(_L("   TLiwVariant::Dump(TInt64) = %d"), aVariant.AsTInt64());
            break;
            }
        case EVariantTypeTReal:
            {
            RDebug::Print(_L("   TLiwVariant::Dump(TReal) = %d"), aVariant.AsTReal());
            break;
            }
        case EVariantTypeTBool:
            {
            RDebug::Print(_L("   TLiwVariant::Dump(TBool) = %d"), aVariant.AsTBool());
            break;
            }
        case EVariantTypeTUint:
            {
            RDebug::Print(_L("   TLiwVariant::Dump(TUint) = %d"), aVariant.AsTUint());
            break;
            }

        case EVariantTypeTUid:
            {
            const TUidName& uidName = aVariant.AsTUid().Name();
            RDebug::Print(_L("   TLiwVariant::Dump(TUid) = %S"), &uidName);
            break;
            }
        case EVariantTypeDesC:
            {
            TPtrC des = aVariant.AsDes();
            RDebug::Print(_L("   TLiwVariant::Dump(TBufC) = %S"), &des);
            break;
            }
        case EVariantTypeDesC8:
            {
            TPtrC8 des = aVariant.AsData();
            RDebug::Print(_L("   TLiwVariant::Dump(TBufC8) = %S"), &des);
            break;
            }
        case EVariantTypeTTime:
            {
            TDateTime dt = aVariant.AsTTime().DateTime();
            RDebug::Print(_L("   TLiwVariant::Dump(TTime): day=%d,mon=%d,year=%d,hh=%d,mm=%d,ss=%d"),
                          dt.Day()+1, dt.Month()+1, dt.Year(),
                          dt.Hour(),dt.Minute(), dt.Second());
            break;          
            }
        case EVariantTypeFileHandle:
            {
            RDebug::Print(_L("   TLiwVariant::Dump(RFile): Value is file handle."));
            break;
            }            
        case EVariantTypeList:  
            {
            const CLiwList* tempList = aVariant.AsList();
            TInt count = tempList->Count();
            TLiwVariant tempVariant;
            tempVariant.PushL();
            RDebug::Print(_L("   TLiwVariant::Dump(List[%d]):"), count);
            for (TInt index = 0; index < count; index++)
                {
                TRAPD(error, {tempList->AtL(index, tempVariant);});
                if(error != KErrNone)
                    RDebug::Print(_L("TLiwVariant::Dump ERROR: %d"), error);
                Dump(tempVariant);
                }
            CleanupStack::Pop(&tempVariant);
    		tempVariant.Reset();
            RDebug::Print(_L("   TLiwVariant::Dump List END"));
            break;
            }
        case EVariantTypeIterable:  
          {
            CLiwIterable* tempItr = aVariant.AsIterable();
            TLiwVariant tempVariant;
            RDebug::Print(_L("   TLiwVariant::Dump(Iterable):"));
            tempItr->Reset();
            TRAPD(errno, {
              while (tempItr->NextL(tempVariant)) {
                Dump(tempVariant);
              }
            });
            if(errno != KErrNone)
                RDebug::Print(_L("TLiwVariant::Dump ERROR: %d"), errno);
            tempVariant.Reset();
            RDebug::Print(_L("   TLiwVariant::Dump Iterable END"));
            break;
          }
        case EVariantTypeMap:  
          {
            const CLiwMap* tempMap = aVariant.AsMap();
            TInt count = tempMap->Count();
            TLiwVariant tempVariant;
            RDebug::Print(_L("   TLiwVariant::Dump(Map):"));
            for (TInt index = 0; index < count; index++) {
              TBuf8<KBufSizeMid> key;
              TRAPD(error, {tempMap->AtL(index, key);});
              RDebug::Print(_L("    key=%S, value= "), &key);
              TRAP(error, {tempMap->FindL(key, tempVariant);});
              Dump(tempVariant);
            }
            tempVariant.Reset();
            RDebug::Print(_L("   TLiwVariant::Dump Map END"));
            break;
          }
        case EVariantTypeInterface:  
            {
            RDebug::Print(_L("   TLiwVariant::Dump(Interface): Value is interface pointer."));
            break;
            }
        default:
            {
            RDebug::Print(_L("  *** TLiwVariant::Dump(Unknown) ***"));
            break;
            }
        }
    }
#else
EXPORT_C void Dump(const TLiwVariant& /*aVariant*/)
    {
    }
    
#endif // ifdef _DEBUG