diff -r 000000000000 -r 094583676ce7 PECengine/CoreUtilsLib2/Src/CPEngTransactionStatus.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/PECengine/CoreUtilsLib2/Src/CPEngTransactionStatus.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,716 @@ +/* +* Copyright (c) 2005 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: Transaction status implementation. +* +*/ + +// INCLUDE FILES +#include "CPEngDetailedResultEntry.h" +#include "CPEngDataResultEntry.h" +#include "CPEngTransactionStatus.h" +#include +#include + + +//DATA TYPES + +/** + * Transaction status panic reasons. + * @since 3.0 + */ +enum TPEngTransactionStatusPanicReasons + { + EPEngDetailedAccessOutOfBounds = 1, + EPEngNoCriteriaForNextDetailByOperation = 2, + EPEngNoCriteriaForNextDataByOperation = 3 + }; + + +/** + * Transaction status panic category. + * @since 3.0 + */ +_LIT( KPEngTransStatPanicCategory, "PEngTransStat" ); + + + + +// ============================ MEMBER FUNCTIONS =============================== +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::NewL() +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +EXPORT_C CPEngTransactionStatus* CPEngTransactionStatus::NewL() + { + CPEngTransactionStatus* self = new ( ELeave ) CPEngTransactionStatus(); + return self; + } + + +// Destructor +CPEngTransactionStatus::~CPEngTransactionStatus() + { + Reset(); + +#if _BullseyeCoverage + cov_write(); +#endif + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::CPEngTransactionStatus +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CPEngTransactionStatus::CPEngTransactionStatus() + : iDetailedResultsQ( _FOFF( CPEngDetailedResultEntry, iLink ) ), // CSI: 33 # + iDetailedResultsQIter( iDetailedResultsQ ), + iDetailedResultsCount( 0 ), + iDetResCurrentOperationId( KErrUnknown ), + iDetResCurrentIndex( 0 ), + iDataResultsQ( _FOFF( CPEngDataResultEntry, iLink ) ), // CSI: 33 # + iDataResultsQIter( iDataResultsQ ), + iDataResultsCount( 0 ), + iDataResCurrentOperationId( KErrUnknown ), + iDataResCurrentIndex( 0 ) + { + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::Status() +// ----------------------------------------------------------------------------- +// +TInt CPEngTransactionStatus::Status() const + { + return iStatusCode; + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::DetailedResultCount() +// ----------------------------------------------------------------------------- +// +TInt CPEngTransactionStatus::DetailedResultCount() const + { + return iDetailedResultsCount; + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::DetailedResult() +// ----------------------------------------------------------------------------- +// +const MPEngDetailedResultEntry2& CPEngTransactionStatus::DetailedResult( + TInt aIndex ) const + { + //a pointer to detailed result entry + //If passed index is out of bounds, panics with + //KPEngTransStatPanicCategory, EPEngDetailedAccessOutOfBounds. + + __ASSERT_ALWAYS( aIndex < iDetailedResultsCount, + CPEngTransactionStatus::Panic( EPEngDetailedAccessOutOfBounds ) ); + + + //Details + CPEngTransactionStatus* self = const_cast( this ); + self->iDetailedResultsQIter.SetToFirst(); + + TInt index = 0; + while ( index < aIndex ) + { + self->iDetailedResultsQIter++; + index++; + } + + const CPEngDetailedResultEntry* entry = self->iDetailedResultsQIter; + return *entry; + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::GetFirstDetailedResultByOperation() +// ----------------------------------------------------------------------------- +// +TInt CPEngTransactionStatus::GetFirstDetailedResultByOperation( + TInt aOperationID, + const MPEngDetailedResultEntry2*& aDetailedResult ) + { + //a pointer to "first" detailed result entry of asked operation. + //If there isn't any detailed result of asked operation, returns KErrNotFound and NULL. + //Else returns KErrNone. + + iDetResCurrentOperationId = aOperationID; + iDetResCurrentIndex = 0; // start searching entries from first element + + return LocateNextDetailByOperation( aDetailedResult ); + } + + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::GetNextDetailedResultByOperation() +// ----------------------------------------------------------------------------- +// +TInt CPEngTransactionStatus::GetNextDetailedResultByOperation( + const MPEngDetailedResultEntry2*& aDetailedResult ) + { + //A pointer to next found detailed result entry. + //If operation criteria hasn't been set previously, panics with + //KPEngTransStatPanicCategory, EPEngNoCriteriaForNextByOrigin. + + __ASSERT_ALWAYS( iDetResCurrentOperationId != KErrUnknown, + CPEngTransactionStatus::Panic( EPEngNoCriteriaForNextDetailByOperation ) ); + + // returns KErrNone if a detailed result of the asked operation ID is found. + // Else KErrNotFound and NULL. + return LocateNextDetailByOperation( aDetailedResult ); + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::GetDesc() +// ----------------------------------------------------------------------------- +// +TInt CPEngTransactionStatus::GetDesc( + TPtrC& /*aDescriptionText*/, + TPEngTransStatusDescriptionText2 /*aDescriptionID*/ ) const + { + return KErrNotFound; + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::GetInt() +// ----------------------------------------------------------------------------- +// +TInt CPEngTransactionStatus::GetInt( + TUint32& /*aDescriptionInt*/, + TPEngTransStatusDescriptionInteger2 /*aDescriptionID*/ ) const + { + return KErrNotFound; + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::CloneLC() +// ----------------------------------------------------------------------------- +// +MPEngTransactionStatusCopy2* CPEngTransactionStatus::CloneLC() const + { + return BaseCloneLC(); + } + + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::StatusExtension() +// ----------------------------------------------------------------------------- +// +MPEngTransactionStatusExtension2* CPEngTransactionStatus::StatusExtension() + { + return NULL; + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::Close() +// from MPEngTransactionStatusCopy +// ----------------------------------------------------------------------------- +// +void CPEngTransactionStatus::Close() + { + delete this; + } + + +// ----------------------------------------------------------------------------- +// From MPEngAdvTransactionStatus +// ----------------------------------------------------------------------------- + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::SetStatus() +// ----------------------------------------------------------------------------- +// +void CPEngTransactionStatus::SetStatus( TInt aStatus ) + { + iStatusCode = aStatus; + } + + + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::AddDetailedResultL() +// ----------------------------------------------------------------------------- +// +void CPEngTransactionStatus::AddDetailedResultL( TInt aOperationID, + TInt aErrorCode, + const TUint32* aAttributeTypeID, + const TDesC* aPresenceID, + const TDesC* aContactListID, + const TDesC* aDescription ) + { + CPEngDetailedResultEntry* entry = CPEngDetailedResultEntry::NewLC( aOperationID, + aErrorCode, + aAttributeTypeID, + aPresenceID, + aContactListID, + aDescription ); + + + + iDetailedResultsQ.AddLast( *entry ); + iDetailedResultsCount++; + CleanupStack::Pop(); //entry + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::AddDataResultL() +// ----------------------------------------------------------------------------- +// +void CPEngTransactionStatus::AddDataResultL( TInt aOperationID, + HBufC16* aDataResult ) + + { + //This function behaves like array append. + //It takes the aDataResult ownership only in full success. + CPEngDataResultEntry* entry = CPEngDataResultEntry::NewLC( aOperationID, + aDataResult ); + + + + iDataResultsQ.AddLast( *entry ); + iDataResultsCount++; + CleanupStack::Pop(); //entry + } + + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::GetFirstDataResultByOperation() +// ----------------------------------------------------------------------------- +// +TInt CPEngTransactionStatus::GetFirstDataResultByOperation( TInt aOperationID, + TPtrC16& aDataResult ) + { + //a pointer to "first" detailed result entry of asked operation. + //If there isn't any detailed result of asked operation, returns KErrNotFound and + //empty descriptor. Else returns KErrNone. + + iDataResCurrentOperationId = aOperationID; + iDataResCurrentIndex = 0; // start searching entries from first element + + return LocateNextDataByOperation( aDataResult ); + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::GetNextDataResultByOperation() +// ----------------------------------------------------------------------------- +// +TInt CPEngTransactionStatus::GetNextDataResultByOperation( TPtrC16& aDataResult ) + { + //A pointer to next found detailed result entry. + //If operation criteria hasn't been set previously, panics with + //KPEngTransStatPanicCategory, EPEngNoCriteriaForNextByOrigin. + + __ASSERT_ALWAYS( iDataResCurrentOperationId != KErrUnknown, + CPEngTransactionStatus::Panic( EPEngNoCriteriaForNextDataByOperation ) ); + + // returns KErrNone if a detailed result of the asked operation ID is found. + // Else KErrNotFound and NULL. + return LocateNextDataByOperation( aDataResult ); + } + + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::Reset() +// ----------------------------------------------------------------------------- +// +EXPORT_C void CPEngTransactionStatus::Reset() + { + CPEngDetailedResultEntry* detailEntry; + iDetailedResultsQIter.SetToFirst(); + + while ( ( detailEntry = iDetailedResultsQIter++ ) != NULL ) // CSI: 64 # + { + iDetailedResultsQ.Remove( *detailEntry ); + delete detailEntry; + } + + + + CPEngDataResultEntry* dataEntry; + + iDataResultsQIter.SetToFirst(); + while ( ( dataEntry = iDataResultsQIter++ ) != NULL ) // CSI: 64 # + { + iDataResultsQ.Remove( *dataEntry ); + delete dataEntry; + } + + + iDetailedResultsCount = 0; + iStatusCode = KErrNone; + iDetResCurrentOperationId = KErrUnknown; + iDetResCurrentIndex = 0; + } + + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::ImportStatusFrom() +// ----------------------------------------------------------------------------- +// +EXPORT_C void CPEngTransactionStatus::ImportStatusFrom( + CPEngTransactionStatus& aSource ) + { + MergeStatusCodes( aSource ); + + CPEngDetailedResultEntry* detailEntry; + aSource.iDetailedResultsQIter.SetToFirst(); + + while ( ( detailEntry = aSource.iDetailedResultsQIter++ ) != NULL ) // CSI: 64 # + { + aSource.iDetailedResultsQ.Remove( *detailEntry ); + + iDetailedResultsQ.AddLast( *detailEntry ); + iDetailedResultsCount++; + } + + + + CPEngDataResultEntry* dataEntry; + aSource.iDataResultsQIter.SetToFirst(); + while ( ( dataEntry = aSource.iDataResultsQIter++ ) != NULL ) // CSI: 64 # + { + aSource.iDataResultsQ.Remove( *dataEntry ); + + iDataResultsQ.AddLast( *dataEntry ); + iDataResultsCount++; + } + + delete &aSource; + } + + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::FullCloneLC() +// ----------------------------------------------------------------------------- +// +CPEngTransactionStatus* CPEngTransactionStatus::FullCloneLC() const + { + CPEngTransactionStatus* self = const_cast( this ); + + CPEngTransactionStatus* copy = BaseCloneLC(); + + + //Copy internal details + self->iDataResultsQIter.SetToFirst(); + CPEngDataResultEntry* dataEntry; + + while ( ( dataEntry = self->iDataResultsQIter++ ) != NULL ) // CSI: 64 # + { + CPEngDataResultEntry* newEntry = CPEngDataResultEntry::NewLC( *dataEntry ); + copy->iDataResultsQ.AddLast( *newEntry ); + copy->iDataResultsCount++; + CleanupStack::Pop(); //newEntry + } + + return copy; + } + + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::PackResultsL() +// ----------------------------------------------------------------------------- +// +EXPORT_C HBufC8* CPEngTransactionStatus::PackResultsL() const + { + TInt size = ExternalizeSize(); + CBufFlat* dynBuffer = CBufFlat::NewL( size ); + CleanupStack::PushL( dynBuffer ); + + RBufWriteStream wstream; + wstream.Open( *dynBuffer ); + CleanupClosePushL( wstream ); + + ExternalizeL( wstream ); + + wstream.CommitL(); + CleanupStack::PopAndDestroy(); //wstream + + TPtrC8 dynBufferPtr( dynBuffer->Ptr( 0 ) ); + HBufC8* heapBuffer = dynBufferPtr.AllocL(); + CleanupStack::PopAndDestroy(); //dynBuffer + + return heapBuffer; + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::UnpackResultsL() +// ----------------------------------------------------------------------------- +// +EXPORT_C void CPEngTransactionStatus::UnpackResultsL( const TDesC8& aResultPkg ) + { + RDesReadStream rstream; + rstream.Open( aResultPkg ); + CleanupClosePushL( rstream ); + + InternalizeL( rstream ); + + CleanupStack::PopAndDestroy(); //rs + } + + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::LocateNextDetailByOperation() +// ----------------------------------------------------------------------------- +// +TInt CPEngTransactionStatus::LocateNextDetailByOperation( + const MPEngDetailedResultEntry2*& aDetailedResult ) + { + iDetailedResultsQIter.SetToFirst(); + CPEngDetailedResultEntry* entry; + TInt index = 0; + while ( index < iDetResCurrentIndex ) + { + iDetailedResultsQIter++; + index++; + } + + + while ( ( entry = iDetailedResultsQIter++ ) != NULL ) // CSI: 64 # + { + index++; + if ( entry->Operation() == iDetResCurrentOperationId ) + { + //match found, update position and return entry + iDetResCurrentIndex = index; + aDetailedResult = entry; + return KErrNone; + } + } + + + aDetailedResult = NULL; + return KErrNotFound; + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::LocateNextDataByOperation() +// ----------------------------------------------------------------------------- +// +TInt CPEngTransactionStatus::LocateNextDataByOperation( TPtrC16& aDataResult ) + { + iDataResultsQIter.SetToFirst(); + CPEngDataResultEntry* entry; + TInt index = 0; + while ( index < iDataResCurrentIndex ) + { + iDataResultsQIter++; + index++; + } + + while ( ( entry = iDataResultsQIter++ ) != NULL ) // CSI: 64 # + { + index++; + if ( entry->Operation() == iDataResCurrentOperationId ) + { + //match found, update position and return entry + iDataResCurrentIndex = index; + aDataResult.Set( entry->Data() ); + return KErrNone; + } + } + + aDataResult.Set( NULL, 0 ); + return KErrNotFound; + } + + + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::MergeStatusCodes() +// ----------------------------------------------------------------------------- +// +void CPEngTransactionStatus::MergeStatusCodes( const CPEngTransactionStatus& aSource ) + { + //If no error yet in this container, take the one from imported one + if ( iStatusCode == KErrNone ) + { + iStatusCode = aSource.iStatusCode; + return; + } + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::BaseCloneLC() +// ----------------------------------------------------------------------------- +// +CPEngTransactionStatus* CPEngTransactionStatus::BaseCloneLC() const + { + CPEngTransactionStatus* self = const_cast( this ); + + + CPEngTransactionStatus* copy = CPEngTransactionStatus::NewL(); + CleanupStack::PushL( copy ); + + //Main status code + copy->iStatusCode = iStatusCode; + + + //Clone only base details - e.g. only those visible to clients + self->iDetailedResultsQIter.SetToFirst(); + + CPEngDetailedResultEntry* entry; + while ( ( entry = self->iDetailedResultsQIter++ ) != NULL ) // CSI: 64 # + { + CPEngDetailedResultEntry* newEntry = CPEngDetailedResultEntry::NewLC( *entry ); + copy->iDetailedResultsQ.AddLast( *newEntry ); + copy->iDetailedResultsCount++; + CleanupStack::Pop(); //newEntry + } + + return copy; + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::ExternalizeSize() +// ----------------------------------------------------------------------------- +// +TInt CPEngTransactionStatus::ExternalizeSize() const + { + CPEngTransactionStatus* self = const_cast( this ); + + TInt size = 12; //iStatusCode: 4 bytes + //iDetailedResultsCount: 4 bytes + //iDataResultsCount: 4 bytes + + + self->iDetailedResultsQIter.SetToFirst(); + CPEngDetailedResultEntry* detailedEntry; + while ( ( detailedEntry = self->iDetailedResultsQIter++ ) != NULL ) // CSI: 64 # + { + size += detailedEntry->ExternalizeSize(); + } + + + self->iDataResultsQIter.SetToFirst() ; + CPEngDataResultEntry* dataEntry; + while ( ( dataEntry = self->iDataResultsQIter++ ) != NULL ) // CSI: 64 # + { + size += dataEntry->ExternalizeSize(); + } + + return size; + } + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::ExternalizeL() +// ----------------------------------------------------------------------------- +// +void CPEngTransactionStatus::ExternalizeL( RWriteStream& aStream ) const + { + CPEngTransactionStatus* self = const_cast( this ); + + aStream.WriteInt32L( iStatusCode ); + + + //Details + aStream.WriteInt32L( iDetailedResultsCount ); + self->iDetailedResultsQIter.SetToFirst(); + CPEngDetailedResultEntry* detailedEntry; + while ( ( detailedEntry = self->iDetailedResultsQIter++ ) != NULL ) // CSI: 64 # + { + detailedEntry->ExternalizeL( aStream ); + } + + + //Datas + aStream.WriteInt32L( iDataResultsCount ); + + self->iDataResultsQIter.SetToFirst(); + CPEngDataResultEntry* dataEntry; + while ( ( dataEntry = self->iDataResultsQIter++ ) != NULL ) // CSI: 64 # + { + dataEntry->ExternalizeL( aStream ); + } + } + + + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::InternalizeL() +// ----------------------------------------------------------------------------- +// +void CPEngTransactionStatus::InternalizeL( RReadStream& aStream ) + { + Reset(); + + iStatusCode = aStream.ReadInt32L(); + TInt ii; + + const TInt detailedCount = aStream.ReadInt32L(); + for ( ii = 0; ii < detailedCount; ii++ ) + { + CPEngDetailedResultEntry* entry = CPEngDetailedResultEntry::NewLC( aStream ); + + iDetailedResultsQ.AddLast( *entry ); + iDetailedResultsCount++; + + CleanupStack::Pop(); //entry + } + + + const TInt dataCount = aStream.ReadInt32L(); + for ( ii = 0; ii < dataCount; ii++ ) + { + CPEngDataResultEntry* entry = CPEngDataResultEntry::NewLC( aStream ); + + iDataResultsQ.AddLast( *entry ); + iDataResultsCount++; + + CleanupStack::Pop(); //entry + } + } + +// ----------------------------------------------------------------------------- +// CPEngTransactionStatus::Panic() +// ----------------------------------------------------------------------------- +void CPEngTransactionStatus::Panic( TInt aReason ) + { + User::Panic( KPEngTransStatPanicCategory, aReason ); + } + + + +// End of File +