presencecache/presencecacheutils/src/presencecachebuddyinfo.cpp
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 14 Sep 2010 20:54:53 +0300
branchRCL_3
changeset 21 9da50d567e3c
parent 0 e686773b3f54
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* Copyright (c) 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 <bamdesca.h>
#include <s32strm.h>
#include "presencecachebuddyinfo.h"
#include <utf.h>

#define STRCNST(x)  (const_cast<TDesC*>( &x ))

// -----------------------------------------------------------------------------
CPresenceCacheBuddyInfo::CPresenceCacheBuddyInfo()
    {
    // No implementation required
    }

// -----------------------------------------------------------------------------
CPresenceCacheBuddyInfo::~CPresenceCacheBuddyInfo()
    {      
    iHashMap.Close();  
    delete iAvailabilityTextBuf;
    delete iStatusTextBuf;
    delete iBuddyId;
    
    iIds.ResetAndDestroy();
    iIds.Close();
    iValues.ResetAndDestroy();
    iValues.Close();    
    }

// ---------------------------------------------------------------------------
// MPresenceBuddyInfo2::NewL()
// ---------------------------------------------------------------------------
//
EXPORT_C MPresenceBuddyInfo2* MPresenceBuddyInfo2::NewL( )
    {
    return CPresenceCacheBuddyInfo::NewL( );
    }
    
EXPORT_C MPresenceBuddyInfo2* MPresenceBuddyInfo2::NewLC( )
    {
    CPresenceCacheBuddyInfo* info = CPresenceCacheBuddyInfo::NewLC( );
    CleanupStack::Pop(info);
    MPresenceBuddyInfo2* minfo = info;  
    CleanupDeletePushL(minfo);
    return minfo; 
    }
    
// -----------------------------------------------------------------------------
CPresenceCacheBuddyInfo* CPresenceCacheBuddyInfo::NewL()
    {
    CPresenceCacheBuddyInfo* self = NewLC();
    CleanupStack::Pop(); // self;    
    return self;
    }
    
// -----------------------------------------------------------------------------
CPresenceCacheBuddyInfo* CPresenceCacheBuddyInfo::NewLC()
    {
    CPresenceCacheBuddyInfo* self = new (ELeave)CPresenceCacheBuddyInfo();
    CleanupStack::PushL(self);
    self->ConstructL();  
    return self;
    }    
    
// -----------------------------------------------------------------------------
static TUint32 StringPtrHash( TDesC* const& aValue )
    {
    return DefaultHash::Des16( *aValue );
    }

// -----------------------------------------------------------------------------
static TBool StringIdentity( TDesC* const& aA, TDesC* const& aB )
    {
    return !aA->CompareF( *aB );
    }

// -----------------------------------------------------------------------------
void CPresenceCacheBuddyInfo::ConstructL()
    {
    iHashMap.Close();
    iHashMap = RHashMap<TDesC*, TInt>(    
        THashFunction32<TDesC*>( StringPtrHash ),
        TIdentityRelation<TDesC*>( StringIdentity ) );
    }

// -----------------------------------------------------------------------------
void CPresenceCacheBuddyInfo::SetIdentityL( 
    const TDesC& aBuddyId )
    {
    delete iBuddyId;
    iBuddyId = NULL;
    iBuddyId = aBuddyId.AllocL( );        
    }
    
// -----------------------------------------------------------------------------
TPtrC CPresenceCacheBuddyInfo::BuddyId( ) const
    {
    return iBuddyId ? iBuddyId->Des() : TPtrC();
    }

// -----------------------------------------------------------------------------
void CPresenceCacheBuddyInfo::SetAvailabilityL( 
    TAvailabilityValues aAvailability,
    const TDesC& aAvailabilityText )
    {  
    iAvailability = aAvailability;    
    DoSet16BitValueL( NPresenceCacheFieldName::KAvailability, aAvailabilityText );
    }

// -----------------------------------------------------------------------------
MPresenceBuddyInfo2::TAvailabilityValues CPresenceCacheBuddyInfo::Availability( )
    {
    return iAvailability;    
    }
    
// -----------------------------------------------------------------------------
TPtrC CPresenceCacheBuddyInfo::AvailabilityText( )
    {
    return DoGet16BitValue( NPresenceCacheFieldName::KAvailability );
    }

// -----------------------------------------------------------------------------
void CPresenceCacheBuddyInfo::DoSet16BitValueL( 
    const TDesC& aKey,    
    const TDesC& aValue )
    {   
      
    // Remove old values first
    RemoveField( aKey );
    
    //Convert Unicode to Utf-8
    HBufC8* convertBuffer =  CnvUtfConverter::ConvertFromUnicodeToUtf8L( aValue );
    CleanupStack::PushL( convertBuffer );
    HBufC* keyBuffer = aKey.AllocLC();    
    
    TInt insertPos = iIds.Find(0);
    if ( insertPos < 0 )
        {
        insertPos = iIds.Count();
        iIds.Append( keyBuffer );
        iValues.Append( convertBuffer );
        }
    else
        {
        iIds[insertPos] = keyBuffer;
        iValues[insertPos] = convertBuffer;
        }
    
    iHashMap.InsertL( keyBuffer, insertPos  );
        
    CleanupStack::Pop( keyBuffer );
    CleanupStack::Pop( convertBuffer );       
    }

// -----------------------------------------------------------------------------
void CPresenceCacheBuddyInfo::RemoveField(const TDesC& aKey )
    {
    TInt* pos = iHashMap.Find( STRCNST( aKey ) );    
    if ( pos )
        {
        TInt mypos = *pos;
        iHashMap.Remove( iIds[mypos ]);
        
        delete iIds[mypos];
        iIds[mypos] = NULL;
        
        delete iValues[mypos];
        iValues[mypos] = NULL;               
        }    
    }

// -----------------------------------------------------------------------------
TPtrC CPresenceCacheBuddyInfo::DoGet16BitValue(const TDesC& aKey )
    {
    HBufC8* val = NULL;        
    TInt* pos = iHashMap.Find( STRCNST( aKey ) );
    TPtrC result( KNullDesC() );
    
    if ( pos )
        {       
        val = iValues[*pos];
        if ( val )
            {
            HBufC* temp = NULL;
            // Convert  Utf-8 to Unicode
            TRAPD( errx,  temp = CnvUtfConverter::ConvertToUnicodeFromUtf8L( *val ) );
            if ( !errx && temp )
                { 
                // Avalibility text handled here
                if ( !aKey.CompareF( NPresenceCacheFieldName::KAvailability ) )
                	{
                    delete iAvailabilityTextBuf;
                    iAvailabilityTextBuf = NULL;                 	
                    iAvailabilityTextBuf = temp; 
                    result.Set( iAvailabilityTextBuf->Des() );
                	}
                // Status message handled here
                else if( !aKey.CompareF( NPresenceCacheFieldName::KStatusMessage ) )
                	{
                    delete iStatusTextBuf;
                    iStatusTextBuf = NULL;                 	
                    iStatusTextBuf = temp;  
                    result.Set( iStatusTextBuf->Des() );
                	}
                }
            }
        }
    return result;
    }
    
// -----------------------------------------------------------------------------
void CPresenceCacheBuddyInfo::SetAvatarL( 
    const TDesC8& aAvatar )
    {
    SetAnyFieldL( NPresenceCacheFieldName::KAvatar, aAvatar);
    }
    
// -----------------------------------------------------------------------------
TPtrC8 CPresenceCacheBuddyInfo::Avatar( )
    {
    return GetAnyField( NPresenceCacheFieldName::KAvatar ); 
    }
    
// -----------------------------------------------------------------------------
void CPresenceCacheBuddyInfo::SetStatusMessageL( 
    const TDesC& aStatusMessage )
    {
    DoSet16BitValueL( NPresenceCacheFieldName::KStatusMessage, aStatusMessage );
    }


// -----------------------------------------------------------------------------
TPtrC CPresenceCacheBuddyInfo::StatusMessage(  )
    {
    return DoGet16BitValue( NPresenceCacheFieldName::KStatusMessage );
    }
    
// -----------------------------------------------------------------------------
void CPresenceCacheBuddyInfo::SetAnyFieldL( 
    const TDesC16& aKey,
    const TDesC8& aValue )
    {
    if( NPresenceCacheFieldName::KExpiry().CompareF( aKey ) == 0 )
        {
        TPckg<TInt64> expiryPck( iExpiryTime );
        expiryPck.Copy( aValue );
        // write also to key-value map
        }
    
    // Remove old values first
    RemoveField( aKey );    
    
    HBufC8* valueBuffer = aValue.AllocLC();      
    HBufC* keyBuffer = aKey.AllocLC();  
    
    TInt insertPos = iIds.Find(0);
    if ( insertPos < 0 )
        {
        insertPos = iIds.Count();
        iIds.Append( keyBuffer );
        iValues.Append( valueBuffer );
        }
    else
        {
        iIds[insertPos] = keyBuffer;
        iValues[insertPos] = valueBuffer;
        }
    
    iHashMap.InsertL( keyBuffer, insertPos  ); 
    
    CleanupStack::Pop( keyBuffer );
    CleanupStack::Pop( valueBuffer );    
    }

// -----------------------------------------------------------------------------
void CPresenceCacheBuddyInfo::SetAnyFieldPtrL( 
    HBufC16* aKey,
    HBufC8* aValue )
    {  
    if ( !aKey )
        {
        User::Leave( KErrArgument );
        }
    // Remove old values first
    RemoveField( aKey->Des() );
         
    TInt insertPos = iIds.Find(0);
    if ( insertPos < 0 )
        {
        insertPos = iIds.Count();
        iIds.Append( aKey );
        iValues.Append( aValue );
        }
    else
        {
        iIds[insertPos] = aKey;
        iValues[insertPos] = aValue;
        }
    iHashMap.InsertL( aKey, insertPos  );       
    }
    
// -----------------------------------------------------------------------------
TPtrC8 CPresenceCacheBuddyInfo::GetAnyField( 
    const TDesC16& aKey )
    {
    HBufC8* val = NULL;    
    TInt* pos = iHashMap.Find( STRCNST( aKey ) );
    if ( pos )
        {       
        val = iValues[*pos];        
        } 
    return val ? val->Des() : TPtrC8();    
    }
    
// -----------------------------------------------------------------------------
void CPresenceCacheBuddyInfo::GetFieldKeysL( 
    CDesCArrayFlat& aKeys )
    {
    aKeys.Reset();
    THashMapIter<TDesC*, TInt> iter(iHashMap);    
    TDesC* const* nextKey = iter.NextKey();
    while (nextKey)
        {
        aKeys.AppendL( **nextKey );
        nextKey = iter.NextKey();
        }    
    }
                                                                          
// -----------------------------------------------------------------------------
TBool CPresenceCacheBuddyInfo::EqualsIdentity(
    const MPresenceBuddyInfo2& aOtherInstance ) const
    {
    TBool same = ETrue;

    TBool x;
    x = 0 == BuddyId().CompareF( aOtherInstance.BuddyId() );
    same &= x;

    return same;
    }  

// -----------------------------------------------------------------------------
void CPresenceCacheBuddyInfo::ExternalizeL( RWriteStream& aStream ) const
    {
    aStream.WriteInt32L( iAvailability ); 
    ExternalizeFieldL( BuddyId(), aStream );
           
    // externalize expiry time
    TUint32 time_high = I64HIGH( iExpiryTime );
    TUint32 time_low = I64LOW( iExpiryTime );
    aStream.WriteUint32L(time_high);
    aStream.WriteUint32L(time_low);
    
    TInt count = iIds.Count();
    aStream.WriteInt32L( count );     
    for ( TInt i=0; i < count; i++ )
        {
        if ( iIds[i] )
            {
            TPtrC key = iIds[i]->Des();
            TPtrC8 value = iValues[i] ? iValues[i]->Des() : TPtrC8();        
            ExternalizeFieldL( key, aStream );        
            ExternalizeFieldL( value, aStream );             
            }
        else
            {
            // nothing to insert, special case if replacement has been failed earlier
            }
        }
    } 

// -----------------------------------------------------------------------------
void CPresenceCacheBuddyInfo::InternalizeL( RReadStream& aStream )
    {
    iAvailability = (MPresenceBuddyInfo2::TAvailabilityValues)aStream.ReadInt32L( ); 
    
    HBufC* temp  = InternalizeFieldL( aStream );
    iBuddyId = temp;
       
    iIds.ResetAndDestroy();
    iValues.ResetAndDestroy();
    
    HBufC* key = NULL;
    HBufC8* value = NULL;

    // internalize expiry time
    TUint32 time_high = aStream.ReadUint32L();
    TUint32 time_low = aStream.ReadUint32L();
    iExpiryTime = MAKE_TINT64( time_high, time_low );
    
    TInt count = aStream.ReadInt32L( );    
    for ( TInt i=0; i < count; i++ )
        {
        key = InternalizeFieldL( aStream ); 
        
        CleanupStack::PushL( key );
        value = InternalizeField8L( aStream );
        CleanupStack::Pop( key );          
        // This takes ownership anyway.
        SetAnyFieldPtrL( key, value );                       
        }      
    } 

// -----------------------------------------------------------------------------
void CPresenceCacheBuddyInfo::ExternalizeFieldL( const TDesC& aData, RWriteStream& aStream ) const
    {
    TInt32 length = aData.Length();    
    aStream.WriteInt32L( length  );
    aStream.WriteL( aData, length );
    }

// -----------------------------------------------------------------------------
void CPresenceCacheBuddyInfo::ExternalizeFieldL( const TDesC8& aData, RWriteStream& aStream ) const
    {
    TInt32 length = aData.Length();    
    aStream.WriteInt32L( length  );
    aStream.WriteL( aData, length );
    }

// -----------------------------------------------------------------------------
HBufC* CPresenceCacheBuddyInfo::InternalizeFieldL( RReadStream& aStream )
    {
    HBufC16* temp = NULL;    
    TInt32 length = aStream.ReadInt32L();
    if ( length > 0 )
        { 
        temp = HBufC::NewLC( length);
        TPtr stringPtr = temp->Des(); 
        aStream.ReadL( stringPtr, length );
        CleanupStack::Pop( temp );
        } 
    else
        {
        }
    return temp;
    }

// -----------------------------------------------------------------------------
HBufC8* CPresenceCacheBuddyInfo::InternalizeField8L( RReadStream& aStream )
    {
    HBufC8* temp = NULL;    
    TInt32 length = aStream.ReadInt32L();
    if ( length > 0 )
        { 
        temp = HBufC8::NewLC( length);
        TPtr8 stringPtr = temp->Des(); 
        aStream.ReadL( stringPtr, length );
        CleanupStack::Pop( temp );
        } 
    else
        {
        }
    return temp;
    }