--- a/imstutils/imconversationview/imcvuiengine/src/cimcvenginemessagecontainer.cpp Thu Aug 19 09:41:53 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,738 +0,0 @@
-/*
-* 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: message container class implementation
-*
-*/
-
-#include "cimcvenginemessagecontainer.h"
-#include "mimcvenginemessageobserver.h"
-#include "mimcvenginechatinterface.h" // KSendBufferId
-#include "cimcvenginemessagebase.h"
-#include <escapeutils.h>
-#include "imcvuiliterals.h"
-#include "imcvlogger.h"
-#include <collate.h>
-#include "mimcvenginebuffermemoryhandler.h"
-#include "mimcvenginenewmsgobserver.h"
-
-// needed to skip domains in domain-neutral comparison (TUint version)
-const TUint KAtUInt( '@' );
-
-// general colon needed in various places
-_LIT( KColon, ":" );
-
-// general slash needed in various places
-_LIT( KSlash, "/" );
-
-// needed to skip domains in domain-neutral comparison
-_LIT( KAt, "@" );
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::CIMCVEngineMessageContainer
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-CIMCVEngineMessageContainer::CIMCVEngineMessageContainer(
- MIMCVEngineBufferMemoryHandler& aMemoryHandler )
-: iMemoryHandler( aMemoryHandler )
- {
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::~CIMCVEngineMessageContainer
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-CIMCVEngineMessageContainer::~CIMCVEngineMessageContainer()
- {
-
-
- for( TInt a( 0 ); a < iMessageContainer.Count(); ++a )
- {
- if( iMessageContainer[ a ]->DecreaseOwnerCount() )
- {
- delete iMessageContainer[ a ];
- }
- }
- iMessageContainer.Reset();
-
-
- delete iTargetId;
- delete iBuddyDisplayName;
- delete iDecodedTargetId;
- delete iEditerMessge;
- delete iContactLink;
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::NewL
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-CIMCVEngineMessageContainer* CIMCVEngineMessageContainer::NewL(
- TInt aServiceId,
- const TDesC& aTargetId,
- const TDesC& aDisplayName,
- const TDesC8& aContactLink,
- MIMCVEngineBufferMemoryHandler& aMemoryHandler,
- TContainerType aType )
- {
- CIMCVEngineMessageContainer* self = CIMCVEngineMessageContainer::NewLC(
- aServiceId,
- aTargetId,
- aDisplayName,
- aContactLink,
- aMemoryHandler,
- aType );
- CleanupStack::Pop( self );
- return self;
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::NewLC
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-CIMCVEngineMessageContainer* CIMCVEngineMessageContainer::NewLC(
- TInt aServiceId,
- const TDesC& aTargetId,
- const TDesC& aDisplayName,
- const TDesC8& aContactLink,
- MIMCVEngineBufferMemoryHandler& aMemoryHandler,
- TContainerType aType )
- {
- CIMCVEngineMessageContainer* self =
- new ( ELeave ) CIMCVEngineMessageContainer( aMemoryHandler );
- CleanupStack::PushL( self );
- self->ConstructL( aServiceId, aTargetId,aDisplayName,aContactLink, aType );
- return self;
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::ConstructL
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-void CIMCVEngineMessageContainer::ConstructL(
- TInt /*aServiceId*/,
- const TDesC& aTargetId,
- const TDesC& aDisplayName,
- const TDesC8& aContactLink,
- TContainerType aType )
- {
- iTargetId = aTargetId.AllocL();
- iBuddyDisplayName = aDisplayName.AllocL();
- iContactLink = aContactLink.Alloc();
- iDecodedTargetId = EscapeUtils::EscapeDecodeL( *iTargetId );
- ResolveType( aType );
-
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::UnreadCount
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-TInt CIMCVEngineMessageContainer::UnreadCount(
- MIMCVEngineMessageReadInterface::TUnreadFilter aUnreadFilter ) const
- {
- TInt countOfAll = iMessageContainer.Count();
- TInt unreadCount = countOfAll - iUnreadOffset;
- if( aUnreadFilter != EUnreadAll )
- {
- for( TInt a = countOfAll - 1; a >= iUnreadOffset; --a )
- {
- if( iMessageContainer[ a ]->MessagerType() == MIMCVEngineMessage::EMessageSent )
- {
- unreadCount--;
- }
- }
- }
- return unreadCount;
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::StoreEditerMessageL
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-void CIMCVEngineMessageContainer::StoreEditerMessageL(const TDesC& aEditorMessage )
- {
- if( iEditerMessge)
- {
- delete iEditerMessge;
- iEditerMessge = NULL;
- }
- iEditerMessge = aEditorMessage.AllocL();
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::GetEditerMessage
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-
-const TDesC& CIMCVEngineMessageContainer::GetEditerMessage()
- {
- if( iEditerMessge)
- {
- return *iEditerMessge;
- }
- return KNullDesC;
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::MessageCount
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-TInt CIMCVEngineMessageContainer::MessageCount() const
- {
- // Offset is index to first unread message. It is exatly same as count of
- // read messages.
- return iUnreadOffset;
- }
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::Read
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-void CIMCVEngineMessageContainer::Read( TReadType aReadType, TInt aAmount /* = 0 */ )
- {
- TInt messageCount( iMessageContainer.Count() );
- TInt originalUnreadCount = UnreadCount( );
-
- switch( aReadType )
- {
- case EReadAll:
- iUnreadOffset = messageCount;
- break;
- case EReadAmount:
- iUnreadOffset+= aAmount;
- break;
- case EReadOne:
- ++iUnreadOffset;
- break;
- default:
- return;
- }
-
- // Cannot be more than messageCount
- if( iUnreadOffset > messageCount )
- {
- iUnreadOffset = messageCount;
- }
-
- // Inform observers only if unreadcount is changed.
- if( originalUnreadCount != UnreadCount() )
- {
- if (( iChatObserver ) && (!iActiveChat))
- {
- TRAP_IGNORE( iChatObserver->HandleChatEventL(
- MIMCVEngineNewMsgObserver::EUnreadCountChanged ) );
- }
- }
-
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::Message
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-MIMCVEngineMessage& CIMCVEngineMessageContainer::Message( TInt aIndex ) const
- {
- //__CHAT_ASSERT_DEBUG( aIndex >= 0 && aIndex < MessageCount() );
- return *iMessageContainer[ aIndex ];
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::ReadNextUnread
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-MIMCVEngineMessage& CIMCVEngineMessageContainer::ReadNextUnread()
- {
- //__CHAT_ASSERT_DEBUG( UnreadCount() != 0 );
- Read( EReadOne );
- return *iMessageContainer[ MessageCount() - 1 ];
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::ReadUnreadFromIndex
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-MIMCVEngineMessage& CIMCVEngineMessageContainer::ReadUnreadFromIndex( TInt aIndex )
- {
- //__CHAT_ASSERT_DEBUG( UnreadCount() != 0 );
- //__CHAT_ASSERT_DEBUG( aIndex >= 0 && aIndex < iMessageContainer.Count() );
- Read( EReadOne );
- return *iMessageContainer[aIndex];
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::SetObserver
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-void CIMCVEngineMessageContainer::SetObserver( MIMCVEngineMessageObserver* aObserver )
- {
- iObserver = aObserver;
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::SetObserver
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-TPtrC CIMCVEngineMessageContainer::Name() const
- {
- IM_CV_LOGS(TXT("CIMCVEngineMessageContainer::Name Start"));
- if( iBuddyDisplayName && iBuddyDisplayName->Length())
- {
- IM_CV_LOGS(TXT("to_del CIMCVEngineMessageContainer::Name iBuddyDisplayName= %S"),&(*iBuddyDisplayName) );
- //IM_CV_LOGS(TXT("to_del CIMCVEngineMessageContainer::Name iBuddyDisplayName length = %d"),iBuddyDisplayName->Length() );
- return *iBuddyDisplayName;
- }
- if( iTargetId )
- {
- IM_CV_LOGS(TXT("to_del CIMCVEngineMessageContainer::target iTargetId= %S"), &(*iTargetId));
- return DisplayId( *iTargetId );
- }
- return KNullDesC();
- }
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::DisplayName
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-TDesC CIMCVEngineMessageContainer::DisplayName() const
- {
- IM_CV_LOGS(TXT("CIMCVEngineMessageContainer::DisplayName Start" ));
- if( iBuddyDisplayName && iBuddyDisplayName->Length())
- {
- IM_CV_LOGS(TXT("CIMCVEngineMessageContainer::DisplayName EChatContainer: %s"), &(*iBuddyDisplayName));
- return *iBuddyDisplayName;
- }
- return KNullDesC();
- }
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::SetName
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-void CIMCVEngineMessageContainer::SetNameL(const TDesC& aDisplayName)
- {
- IM_CV_LOGS(TXT("CIMCVEngineMessageContainer::SetNameL Start"));
- //if the iBuddydisplayName is same as aDisplayName
- // then no need to set it again.
- if(iBuddyDisplayName && (aDisplayName.Compare(*iBuddyDisplayName)!=0))
- {
- delete iBuddyDisplayName;
- iBuddyDisplayName = NULL;
- IM_CV_LOGS(TXT("CIMCVEngineMessageContainer::SetName=%S"),&aDisplayName);
- iBuddyDisplayName = aDisplayName.AllocL();
- }
- }
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::SetName
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-void CIMCVEngineMessageContainer::SetLinkL(const TDesC8& aContactLink)
- {
- IM_CV_LOGS(TXT(" CIMCVEngineMessageContainer::SetLinkL Start"));
- //if the iContactLink is same as aContactLink
- // then no need to set it again.
- if(iContactLink && (aContactLink.Compare(*iContactLink)!=0))
- {
- delete iContactLink;
- iContactLink = NULL;
- IM_CV_LOGS(TXT(" CIMCVEngineMessageContainer::SetLinkL=%S"),&aContactLink);
- iContactLink = aContactLink.AllocL();
- }
-
- }
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::ContactLink
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-
-TPtrC8 CIMCVEngineMessageContainer::ContactLink() const
- {
- return *iContactLink;
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::DeleteMessage
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-void CIMCVEngineMessageContainer::DeleteMessage( TInt aIndex )
- {
- MIMCVEngineMessage* target = &Message( aIndex );
- iMessageContainer.Remove( aIndex );
- iContainerSizeInBytes -= target->SizeInBytes();
- --iUnreadOffset;
-
- if( iObserver )
- {
- iObserver->HandleMessageEvent( MIMCVEngineMessageObserver::EMessageDeleted,
- aIndex );
- }
-
- if( target->DecreaseOwnerCount() )
- {
- delete target;
- }
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::AppendL
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-void CIMCVEngineMessageContainer::AppendL( MIMCVEngineMessage* aMessage, TBool aSharedOwnership )
- {
- if( !aMessage )
- {
- User::Leave( KErrArgument );
- }
-
- if( !aSharedOwnership )
- {
- CleanupDeletePushL( aMessage );
- }
-
- // Check memory status
- // if failes, leave with KErrNoMemory
- if( !iMemoryHandler.FreeMemoryIfNeededL( aMessage->SizeInBytes() ) )
- {
- User::Leave( KErrNoMemory );
- }
-
- iMessageContainer.AppendL( aMessage );
- iContainerSizeInBytes += aMessage->SizeInBytes();
-
- if( !aSharedOwnership )
- {
- CleanupStack::Pop( aMessage );
- }
-
- aMessage->IncreaseOwnerCount();
-
- aMessage->SetContainerInfo( this );
-
- IM_CV_LOGS(TXT( "Sender %s, Recipient %s" ),
- &aMessage->Sender(),
- &aMessage->Recipient() );
-
-
- if( iObserver )
- {
- iObserver->HandleMessageEvent( MIMCVEngineMessageObserver::ENewMessage );
- }
-
- if ( ( iChatObserver ) && (!iActiveChat) )
- {
- iChatObserver->HandleChatEventL( MIMCVEngineNewMsgObserver::EUnreadCountChanged,
- aMessage );
- }
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::ServerAddress
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-//
-TTime CIMCVEngineMessageContainer::Time()
- {
- TTime time = Time::NullTTime();
- TInt count = iMessageContainer.Count();
- if( count == 0 )
- {
- // no messages, return null
- return time;
- }
- return iMessageContainer[count - 1]->TimeStamp();
- }
-
-
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::Target
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-const TDesC& CIMCVEngineMessageContainer::Target() const
- {
- if( !iTargetId )
- {
- return KNullDesC;
- }
- return *iTargetId;
- }
-
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::OrderUid
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-TInt CIMCVEngineMessageContainer::OrderUid( const CIMCVEngineMessageContainer& aSourceA,
- const CIMCVEngineMessageContainer& aSourceB )
- {
-
- // points to user part of id
- TPtrC ptrId1( aSourceA.ComparableTarget() );
- TPtrC ptrId2( aSourceB.ComparableTarget() );
-
- // find out if we have domains in the ids
- TInt domainPos1( ptrId1.Locate( KAtUInt ) );
- TInt domainPos2( ptrId2.Locate( KAtUInt ) );
-
- TBool domainIn1( KErrNotFound != domainPos1 );
- TBool domainIn2( KErrNotFound != domainPos2 );
-
- // points to domains in the neutral id
- TPtrC ptrDom1( KNullDesC );
- TPtrC ptrDom2( KNullDesC );
-
- // points to user parts in the neutral id
- TPtrC ptrUid1( ptrId1 );
- TPtrC ptrUid2( ptrId2 );
-
- // separate user id parts and domain parts
- if ( domainIn1 )
- {
- ptrDom1.Set( ptrId1.Mid( domainPos1 + 1) );
- ptrUid1.Set( ptrId1.Mid( 0, domainPos1 ) );
- }
-
- if ( domainIn2 )
- {
- ptrDom2.Set( ptrId2.Mid( domainPos2 + 1) );
- ptrUid2.Set( ptrId2.Mid( 0, domainPos2 ) );
- }
-
- // Create custom collation method to ignore punctuations
- // index 0 gets the default method
- TCollationMethod collation =
- *Mem::CollationMethodByIndex( 0 );
- collation.iFlags |= TCollationMethod::EIgnoreNone;
-
- // domains are compared only when it is really needed
- // check if userid part is the same in both ids
- TInt idResult = ptrUid1.CompareC( ptrUid2, KCollationLevel, &collation );
-
- if( idResult != 0 )
- {
- return idResult;
- }
-
- // id part is same, we have to compare domain
-
- // If domain comparison is neutral and one id is without domain
- // -> Domains are same. Other situation domainResult stays valid.
- if ( domainIn1 ^ domainIn2 )
- {
- return 0;
- }
- else
- {
- return ptrDom1.CompareC( ptrDom2, KCollationLevel, &collation );
- }
- }
-
-
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::ContainerType
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-MIMCVEngineMessageReadInterface::TContainerType CIMCVEngineMessageContainer::ContainerType() const
- {
- return iContainerType;
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::ResolveType
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-void CIMCVEngineMessageContainer::SetChatObserver( MIMCVEngineNewMsgObserver* aObserver )
- {
- iChatObserver = aObserver;
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::ResolveType
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-void CIMCVEngineMessageContainer::ResolveType( TContainerType aType )
- {
- if( aType != ENoneContainer )
- {
- iContainerType = aType;
- }
- else if( iTargetId->Compare( KSendBufferId ) == 0 )
- {
- iContainerType = ESendContainer;
- }
- else
- {
- iContainerType = EChatContainer;
- }
- }
-
-
-
-// -----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::TargetId
-// ( Other items commented in header )
-// -----------------------------------------------------------------------------
-//
-MIMCVEngineMessageContainerInfo& CIMCVEngineMessageContainer::TargetId()
- {
- return *this;
- }
-
-// -----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::Lock
-// locks messagecontainer if needed.
-// -----------------------------------------------------------------------------
-//
-void CIMCVEngineMessageContainer::Lock( TBool aLocked )
- {
- iLocked = aLocked;
- }
-
-// -----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::ComparableTarget
-// ( Other items commented in header )
-// -----------------------------------------------------------------------------
-//
-const TDesC& CIMCVEngineMessageContainer::ComparableTarget() const
- {
- if ( !iDecodedTargetId )
- {
- return KNullDesC;
- }
- return *iDecodedTargetId;
- }
-
-// -----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::AllMessagesCount
-// ( Other items commented in header )
-// -----------------------------------------------------------------------------
-//
-TInt CIMCVEngineMessageContainer::AllMessagesCount() const
- {
- return iMessageContainer.Count();
- }
-
-// -----------------------------------------------------------------------------
-// CCABufferManager::NotifyContactForPending
-// ( Other items commented in header )
-// -----------------------------------------------------------------------------
-//
-MIMCVEngineMessage& CIMCVEngineMessageContainer::MessageFromAll( TInt aIndex ) const
- {
- //__CHAT_ASSERT_DEBUG( aIndex >= 0 && aIndex < AllMessagesCount() );
- return *iMessageContainer[ aIndex ];
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::DeleteMessageFromAll
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-//
-void CIMCVEngineMessageContainer::DeleteMessageFromAll( TInt aIndex )
- {
- MIMCVEngineMessage* target = &MessageFromAll( aIndex );
- iMessageContainer.Remove( aIndex );
- iContainerSizeInBytes -= target->SizeInBytes();
- if( iUnreadOffset > aIndex )
- {
- --iUnreadOffset;
- }
-
- if( iObserver )
- {
- iObserver->HandleMessageEvent( MIMCVEngineMessageObserver::EMessageDeleted,
- aIndex );
- }
-
- if( target->DecreaseOwnerCount() )
- {
- delete target;
- }
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::IsLocked
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-//
-TBool CIMCVEngineMessageContainer::IsLocked() const
- {
- return iLocked ;
- }
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::ContainerSizeInBytes
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-//
-TInt CIMCVEngineMessageContainer::ContainerSizeInBytes() const
- {
- return iContainerSizeInBytes;
- }
-
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::SetActive
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-//
-void CIMCVEngineMessageContainer::SetActive( TBool aActiveChat )
- {
- iActiveChat = aActiveChat;
- }
-
-
-//-----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::IsActive
-// ( Other items commented in header )
-//-----------------------------------------------------------------------------
-//
-TBool CIMCVEngineMessageContainer::IsActive()
- {
- return iActiveChat;
- }
-
-
-
-// -----------------------------------------------------------------------------
-// CIMCVEngineMessageContainer::DisplayId
-// -----------------------------------------------------------------------------
-//
-TPtrC CIMCVEngineMessageContainer::DisplayId( const TDesC& aId, TBool aDomainHiding )
- {
- TPtrC ret( aId );
-
- // locate ":" for userid, groupid.
- // locate "/" for list id.
- TInt pos = aId.FindC( aDomainHiding ? KSlash : KColon );
-
- if ( ( pos != KErrNotFound) && ( pos != aId.Length()-1) )
- {
- // contains the special character, and it is not the last char
- // remove everything before the special char (including the char)
- ret.Set( aId.Mid( pos + 1 ) );
- }
- if( aDomainHiding)
- {
- // remove also the domain part
- TInt domainPos = ret.FindC( KAt );
- if ( ( domainPos != KErrNotFound ) && ( domainPos != 0 ) )
- {
- ret.Set( ret.Mid( 0, domainPos ) );
- }
-
- }
-
- return ret;
- }
-
-
-// end of file