sl@0: // Copyright (c) 2008-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Overview: sl@0: // Test methods of the LManagedX and LCleanedupX classes. sl@0: // Tests CONSTRUCTORS_MAY_LEAVE and OR_LEAVE macros sl@0: // sl@0: // sl@0: sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include sl@0: #include "emisc.h" sl@0: #include "euserhl.h" sl@0: sl@0: sl@0: RTest test(_L("RAII-based automatic resource management tests")); sl@0: sl@0: sl@0: TInt TExtendedTestL(); sl@0: sl@0: class CTracker : public CBase sl@0: { sl@0: public: sl@0: CONSTRUCTORS_MAY_LEAVE sl@0: sl@0: enum TConstructionMode { ENonleavingConstructor, EConstructorLeaves}; sl@0: sl@0: static CTracker* NewL() sl@0: { sl@0: return new(ELeave) CTracker; sl@0: } sl@0: sl@0: static CTracker* NewL(TConstructionMode aMode) sl@0: { sl@0: return new(ELeave) CTracker(aMode); sl@0: } sl@0: sl@0: CTracker() sl@0: : iData(new(ELeave) TInt) sl@0: { sl@0: test.Printf(_L(" CTracker - %x\n"), this); sl@0: *iData = 3; sl@0: } sl@0: sl@0: explicit CTracker(TConstructionMode aMode) sl@0: : iData(new(ELeave) TInt(aMode)) sl@0: { sl@0: if (aMode == EConstructorLeaves) sl@0: { sl@0: test.Printf(_L("CTracker(EConstructorLeaves): Now leaving with User::Leave(KErrGeneral)\n")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: sl@0: test.Printf(_L(" CTracker - %x\n"), this); sl@0: } sl@0: sl@0: CTracker(CTracker& aTracker) sl@0: : iData(aTracker.iData.Unmanage()) sl@0: { sl@0: test.Printf(_L(" CTracker::CTracker(const CTracker&) - %x (copy)\n"), this); sl@0: } sl@0: sl@0: CTracker& operator=(CTracker& aTracker) sl@0: { sl@0: iData = aTracker.iData.Unmanage(); sl@0: test.Printf(_L(" CTracker::operator=(const CTracker&) - %x (copy)\n"), this); sl@0: return *this; sl@0: } sl@0: sl@0: virtual ~CTracker() sl@0: { sl@0: test.Printf(_L(" ~CTracker - %x\n"), this); sl@0: } sl@0: sl@0: virtual void MemFunc() sl@0: { sl@0: test.Printf(_L(" CTracker::MemFunc - %x\n"), this); sl@0: } sl@0: sl@0: virtual TInt Value() sl@0: { sl@0: return *iData; sl@0: } sl@0: sl@0: static void StaticMemberRef(const CTracker& aTracker) sl@0: { sl@0: test.Printf(_L(" CTracker::StaticMemberRef - %x\n"), &aTracker); sl@0: } sl@0: sl@0: static void StaticMemberPtr(CTracker* aTracker) sl@0: { sl@0: test.Printf(_L(" CTracker::StaticMemberPtr - %x\n"), aTracker); sl@0: } sl@0: sl@0: private: sl@0: LManagedPtr iData; sl@0: }; sl@0: sl@0: TBool trackerDestroyed = EFalse; sl@0: sl@0: class TCTrackerDestroy sl@0: { sl@0: public: sl@0: static void Cleanup(CTracker* aPtr) sl@0: { sl@0: test.Printf(_L("TCTrackerDestroy::Cleanup\n")); sl@0: delete aPtr; sl@0: trackerDestroyed = ETrue; sl@0: } sl@0: }; sl@0: sl@0: class CDerivedTracker: public CTracker sl@0: { sl@0: public: sl@0: CONSTRUCTORS_MAY_LEAVE sl@0: sl@0: static CDerivedTracker* NewL() sl@0: { sl@0: return new(ELeave) CDerivedTracker; sl@0: } sl@0: sl@0: static CDerivedTracker* NewL(CTracker::TConstructionMode aMode) sl@0: { sl@0: return new(ELeave) CDerivedTracker(aMode); sl@0: } sl@0: sl@0: CDerivedTracker() sl@0: : iRealData(new(ELeave) TReal64) sl@0: { sl@0: test.Printf(_L(" CDerivedTracker - %x\n"), this); sl@0: *iRealData = 5.5; sl@0: } sl@0: sl@0: CDerivedTracker(CTracker::TConstructionMode aMode) sl@0: { sl@0: if (aMode == EConstructorLeaves) sl@0: { sl@0: test.Printf(_L("CDerivedTracker(EConstructorLeaves): Now leaving with User::Leave(KErrGeneral)\n")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: sl@0: test.Printf(_L(" CDerivedTracker - %x\n"), this); sl@0: } sl@0: sl@0: CDerivedTracker(CDerivedTracker& aDerivedTracker) sl@0: : CTracker(aDerivedTracker), sl@0: iRealData(aDerivedTracker.iRealData.Unmanage()) sl@0: { sl@0: test.Printf(_L(" CDerivedTracker::CDerivedTracker(const CDerivedTracker&) - %x (copy)\n"), this); sl@0: } sl@0: sl@0: CDerivedTracker& operator=(CDerivedTracker& aDerivedTracker) sl@0: { sl@0: CTracker::operator=(aDerivedTracker); sl@0: iRealData = aDerivedTracker.iRealData.Unmanage(); sl@0: test.Printf(_L(" CDerivedTracker::operator=(const CDerivedTracker&) - %x (copy)\n"), this); sl@0: return *this; sl@0: } sl@0: sl@0: virtual ~CDerivedTracker() sl@0: { sl@0: test.Printf(_L(" ~CDerivedTracker - %x\n"), this); sl@0: } sl@0: sl@0: virtual void MemFunc() sl@0: { sl@0: test.Printf(_L(" CDerivedTracker::MemFunc - %x\n"), this); sl@0: } sl@0: sl@0: static void StaticMemberRef(const CDerivedTracker& aTracker) sl@0: { sl@0: test.Printf(_L(" CDerivedTracker::StaticMemberRef - %x\n"), &aTracker); sl@0: } sl@0: sl@0: static void StaticMemberPtr(CDerivedTracker* aTracker) sl@0: { sl@0: test.Printf(_L(" CDerivedTracker::StaticMemberPtr - %x\n"), aTracker); sl@0: } sl@0: sl@0: private: sl@0: LManagedPtr iRealData; sl@0: }; sl@0: sl@0: sl@0: namespace Log sl@0: { sl@0: sl@0: class RLogger sl@0: { sl@0: public: sl@0: RLogger() sl@0: : iData(NULL) sl@0: { sl@0: test.Printf(_L(" RLogger - %x\n"), this); sl@0: } sl@0: sl@0: RLogger(TInt* aData) sl@0: : iData(aData) sl@0: { sl@0: test.Printf(_L(" RLogger - %x ptr %x -> val %d\n"), this, aData, *iData); sl@0: } sl@0: sl@0: RLogger(TInt aValue) sl@0: : iData(new(ELeave) TInt(aValue)) sl@0: { sl@0: test.Printf(_L(" RLogger - %x value %d\n"), this, *iData); sl@0: } sl@0: sl@0: void OpenL(TInt aValue) sl@0: { sl@0: iData = new(ELeave) TInt(aValue); sl@0: test.Printf(_L(" RLogger::OpenL(TInt aValue) - %x value %d\n"), this, *iData); sl@0: } sl@0: sl@0: RLogger(const RLogger& aLogger) sl@0: : iData(aLogger.iData) sl@0: { sl@0: test.Printf(_L(" RLogger::RLogger(const RLogger&) - %x (copy)\n"), this); sl@0: } sl@0: sl@0: sl@0: RLogger& operator=(const RLogger& aLogger) sl@0: { sl@0: iData = aLogger.iData; sl@0: sl@0: test.Printf(_L(" RLogger::operator=(const RLogger&) - %x copy from %x val %d\n"), this, &aLogger, *aLogger.iData); sl@0: return *this; sl@0: } sl@0: sl@0: sl@0: ~RLogger() sl@0: { sl@0: test.Printf(_L(" ~RLogger - %x\n"), this); sl@0: } sl@0: sl@0: sl@0: void Close() sl@0: { sl@0: test.Printf(_L(" RLogger::Close - %x\n"), this); sl@0: sl@0: // Open or non-NULL initializing constructor not called or sl@0: // cleanup function already called sl@0: sl@0: __ASSERT_ALWAYS(iData != NULL, test.Panic(_L("NULL pointer"))); sl@0: delete iData; sl@0: iData = NULL; sl@0: } sl@0: sl@0: sl@0: void Release() sl@0: { sl@0: test.Printf(_L(" RLogger::Release - %x\n"), this); sl@0: sl@0: // Open or non-NULL initializing constructor not called or sl@0: // cleanup function already called sl@0: sl@0: __ASSERT_ALWAYS(iData != NULL, test.Panic(_L("NULL pointer"))); sl@0: delete iData; sl@0: iData = NULL; sl@0: } sl@0: sl@0: sl@0: void Destroy() sl@0: { sl@0: test.Printf(_L(" RLogger::Destroy - %x\n"), this); sl@0: sl@0: // Open or non-NULL initializing constructor not called or sl@0: // cleanup function already called sl@0: sl@0: __ASSERT_ALWAYS(iData != NULL, test.Panic(_L("NULL pointer"))); sl@0: delete iData; sl@0: iData = NULL; sl@0: } sl@0: sl@0: sl@0: void Free() sl@0: { sl@0: test.Printf(_L(" RLogger::Free - %x\n"), this); sl@0: sl@0: // Open or non-NULL initializing constructor not called or sl@0: // cleanup function already called sl@0: sl@0: __ASSERT_ALWAYS(iData != NULL, test.Panic(_L("NULL pointer"))); sl@0: delete iData; sl@0: iData = NULL; sl@0: } sl@0: sl@0: void MemFunc() sl@0: { sl@0: test.Printf(_L(" RLogger::MemFunc - %x %x\n"), this, iData); sl@0: } sl@0: sl@0: static void StaticMemberRef(const RLogger& aTracker) sl@0: { sl@0: test.Printf(_L(" RLogger::StaticMemberRef - %x\n"), &aTracker); sl@0: } sl@0: sl@0: static void StaticMemberPtr(RLogger* aTracker) sl@0: { sl@0: test.Printf(_L(" RLogger::StaticMemberPtr - %x\n"), aTracker); sl@0: } sl@0: sl@0: static void Cleanup(TAny* aRlogger) sl@0: { sl@0: static_cast(aRlogger)->Close(); sl@0: } sl@0: sl@0: TInt* GetData() const sl@0: { sl@0: return iData; sl@0: } sl@0: sl@0: protected: sl@0: TInt* iData; sl@0: }; sl@0: sl@0: sl@0: DEFINE_CLEANUP_FUNCTION(RLogger, Release); sl@0: sl@0: sl@0: class ROtherLogger sl@0: { sl@0: public: sl@0: ROtherLogger() sl@0: : iData(NULL) sl@0: { sl@0: test.Printf(_L(" ROtherLogger - %x\n"), this); sl@0: } sl@0: sl@0: ROtherLogger(TInt* aData) sl@0: : iData(aData) sl@0: { sl@0: test.Printf(_L(" ROtherLogger - %x ptr %x -> val %d\n"), this, aData, *iData); sl@0: } sl@0: sl@0: ROtherLogger(TInt aValue) sl@0: : iData(new(ELeave) TInt(aValue)) sl@0: { sl@0: test.Printf(_L(" ROtherLogger - %x value %d\n"), this, *iData); sl@0: } sl@0: sl@0: void OpenL(TInt aValue) sl@0: { sl@0: iData = new(ELeave) TInt(aValue); sl@0: test.Printf(_L(" ROtherLogger::OpenL(TInt aValue) - %x value %d\n"), this, *iData); sl@0: } sl@0: sl@0: ROtherLogger(const ROtherLogger& aLogger) sl@0: : iData(aLogger.iData) sl@0: { sl@0: test.Printf(_L(" ROtherLogger::ROtherLogger(const ROtherLogger&) - %x (copy)\n"), this); sl@0: } sl@0: sl@0: sl@0: ROtherLogger& operator=(const ROtherLogger& aLogger) sl@0: { sl@0: iData = aLogger.iData; sl@0: sl@0: test.Printf(_L(" ROtherLogger::operator=(const ROtherLogger&) - %x copy from %x ptr %x\n"), this, &aLogger, aLogger.iData); sl@0: return *this; sl@0: } sl@0: sl@0: sl@0: ~ROtherLogger() sl@0: { sl@0: test.Printf(_L(" ~ROtherLogger - %x\n"), this); sl@0: } sl@0: sl@0: sl@0: void Close() sl@0: { sl@0: test.Printf(_L(" ROtherLogger::Close - %x\n"), this); sl@0: sl@0: // Open or non-NULL initializing constructor not called or sl@0: // cleanup function already called sl@0: sl@0: __ASSERT_ALWAYS(iData != NULL, test.Panic(_L("NULL pointer"))); sl@0: delete iData; sl@0: iData = NULL; sl@0: } sl@0: sl@0: sl@0: void Release() sl@0: { sl@0: test.Printf(_L(" ROtherLogger::Release - %x\n"), this); sl@0: sl@0: // Open or non-NULL initializing constructor not called or sl@0: // cleanup function already called sl@0: sl@0: __ASSERT_ALWAYS(iData != NULL, test.Panic(_L("NULL pointer"))); sl@0: delete iData; sl@0: iData = NULL; sl@0: } sl@0: sl@0: sl@0: void Destroy() sl@0: { sl@0: test.Printf(_L(" ROtherLogger::Destroy - %x\n"), this); sl@0: sl@0: // Open or non-NULL initializing constructor not called or sl@0: // cleanup function already called sl@0: sl@0: __ASSERT_ALWAYS(iData != NULL, test.Panic(_L("NULL pointer"))); sl@0: delete iData; sl@0: iData = NULL; sl@0: } sl@0: sl@0: sl@0: void Free() sl@0: { sl@0: test.Printf(_L(" ROtherLogger::Free - %x\n"), this); sl@0: sl@0: // Open or non-NULL initializing constructor not called or sl@0: // cleanup function already called sl@0: sl@0: __ASSERT_ALWAYS(iData != NULL, test.Panic(_L("NULL pointer"))); sl@0: delete iData; sl@0: iData = NULL; sl@0: } sl@0: sl@0: void MemFunc() sl@0: { sl@0: test.Printf(_L(" ROtherLogger::MemFunc - %x %x\n"), this, iData); sl@0: } sl@0: sl@0: static void StaticMemberRef(const ROtherLogger& aTracker) sl@0: { sl@0: test.Printf(_L(" ROtherLogger::StaticMemberRef - %x\n"), &aTracker); sl@0: } sl@0: sl@0: static void StaticMemberPtr(ROtherLogger* aTracker) sl@0: { sl@0: test.Printf(_L(" ROtherLogger::StaticMemberPtr - %x\n"), aTracker); sl@0: } sl@0: sl@0: static void Cleanup(TAny* aRlogger) sl@0: { sl@0: static_cast(aRlogger)->Close(); sl@0: } sl@0: sl@0: operator RLogger() const sl@0: { sl@0: test.Printf(_L(" ROtherLogger::operator RLogger() - %x\n"), this); sl@0: return RLogger(iData); sl@0: } sl@0: sl@0: ROtherLogger& operator=(const RLogger& aLogger) sl@0: { sl@0: iData = aLogger.GetData(); sl@0: sl@0: test.Printf(_L(" ROtherLogger::operator=(const RLogger&) - %x copy from %x ptr %x\n"), this, &aLogger, aLogger.GetData()); sl@0: return *this; sl@0: } sl@0: sl@0: protected: sl@0: TInt* iData; sl@0: }; sl@0: sl@0: } // namespace Log sl@0: sl@0: class RPair sl@0: { sl@0: public: sl@0: RPair(const TInt& x, const TInt& y) sl@0: : iX(x), iY(y) sl@0: { sl@0: test.Printf(_L(" RPair::RPair(const TInt& x, const TInt& y) %x %d %d\n"), iX, iY); sl@0: } sl@0: sl@0: RPair(TInt& x, TInt& y) sl@0: : iX(x), iY(y) sl@0: { sl@0: test.Printf(_L(" RPair::RPair(TInt& x, TInt& y) %x %d %d\n"), iX, iY); sl@0: } sl@0: sl@0: void Close() sl@0: { sl@0: test.Printf(_L(" RPair::Close() %x %d %d\n"), iX, iY); sl@0: } sl@0: sl@0: private: sl@0: TInt iX; sl@0: TInt iY; sl@0: }; sl@0: sl@0: sl@0: using Log::RLogger; sl@0: using Log::ROtherLogger; sl@0: sl@0: class TLogger sl@0: { sl@0: public: sl@0: TLogger() sl@0: { sl@0: test.Printf(_L(" TLogger - %x\n"), this); sl@0: } sl@0: sl@0: TLogger(const TLogger&) sl@0: { sl@0: test.Printf(_L(" TLogger::TLogger(const TLogger& aLogger) - %x (copy)\n"), this); sl@0: } sl@0: sl@0: sl@0: TLogger& operator=(const TLogger&) sl@0: { sl@0: test.Printf(_L(" TLogger::operator=(const TLogger& aLogger) - %x (copy)\n"), this); sl@0: return *this; sl@0: } sl@0: sl@0: ~TLogger() sl@0: { sl@0: test.Printf(_L(" ~TLogger - %x\n"), this); sl@0: } sl@0: sl@0: void Test() sl@0: { sl@0: test.Printf(_L(" TLogger::Test - %x\n"), this); sl@0: } sl@0: }; sl@0: sl@0: sl@0: static TInt one = 1; sl@0: static TInt two = 2; sl@0: sl@0: // CComposite object owns other objects: sl@0: sl@0: class CComposite: public CBase sl@0: { sl@0: public: sl@0: enum TConstructionMode sl@0: { sl@0: ENonleavingConstructor, sl@0: EConstructorLeaves, sl@0: EMemberConstructorLeaves sl@0: }; sl@0: sl@0: static CComposite* NewL() sl@0: { sl@0: return new(ELeave) CComposite; sl@0: } sl@0: sl@0: static CComposite* NewL(TConstructionMode aMode) sl@0: { sl@0: return new(ELeave) CComposite(aMode); sl@0: } sl@0: sl@0: CONSTRUCTORS_MAY_LEAVE sl@0: sl@0: CComposite(); sl@0: CComposite(TConstructionMode aMode); sl@0: ~CComposite(); sl@0: sl@0: void ReleaseLoggers(); sl@0: void ReleaseArrays(); sl@0: sl@0: private: sl@0: TInt iVal; sl@0: sl@0: // By-value component objects sl@0: const LManagedHandle iConstLogger; sl@0: LManagedHandle iLogger; sl@0: LManagedHandle iLogger2; sl@0: LManagedHandle iLogger3; sl@0: sl@0: ROtherLogger iOther; sl@0: LManagedRef iOtherRef; sl@0: LManagedHandle iAnotherLogger; sl@0: sl@0: LManagedHandle iDestroyer; sl@0: sl@0: // Component objects contained by pointer sl@0: LManagedPtr iNullPtr; sl@0: //Define a custom cleanup strategy for CTracker sl@0: LManagedPtr iAutoPtr; sl@0: LManagedPtr iAutoPtr2; sl@0: LManagedPtr iAutoPtr3; sl@0: LManagedPtr iAutoPtr4; sl@0: LManagedPtr iAutoPtr5; sl@0: sl@0: LManagedArray iEmptyArray; sl@0: LManagedArray iAutoArray; sl@0: LManagedArray iAutoArray2; sl@0: static const TInt KNumTrackers = 3; sl@0: sl@0: LManagedHandle, TResetAndDestroy> iPtrArray; sl@0: sl@0: RPointerArray iArray; sl@0: RPointerArray iArray2; sl@0: LManagedRef, TResetAndDestroy> iArrayWrapper; sl@0: sl@0: RLogger iRawLogger; sl@0: LManagedGuard iGuard; sl@0: sl@0: LManagedHandle iPair1; sl@0: LManagedHandle iPair2; sl@0: LManagedHandle iPair3; sl@0: LManagedHandle iPair4; sl@0: }; sl@0: sl@0: CComposite::CComposite() sl@0: : iConstLogger(42), sl@0: iLogger(1), sl@0: iLogger2(2), sl@0: iOther(42), sl@0: iOtherRef(iOther), sl@0: iAnotherLogger(iOtherRef.Unmanage()), sl@0: iDestroyer(2), sl@0: iAutoPtr(CTracker::NewL()), sl@0: iAutoPtr2(CTracker::NewL()), sl@0: iAutoPtr3(CTracker::NewL()), sl@0: iAutoPtr4(CTracker::NewL()), sl@0: iAutoPtr5(CDerivedTracker::NewL()), sl@0: iAutoArray(new(ELeave) CTracker[KNumTrackers]), sl@0: iAutoArray2(new(ELeave) CTracker[KNumTrackers]), sl@0: iPtrArray(3), sl@0: iArrayWrapper(iArray), sl@0: iRawLogger(42), sl@0: iGuard(RLogger::Cleanup, &iRawLogger), sl@0: iPair1(1, 2), sl@0: iPair2(one, 2), sl@0: iPair3(1, two), sl@0: iPair4(one, two) sl@0: { sl@0: test.Printf(_L(" CComposite - %x\n"), this); sl@0: sl@0: //Clear the trackerDestroyed flag. This flag is set sl@0: //in the custom cleanup strategy for CTracker which is sl@0: //defined for iAutoPtr sl@0: trackerDestroyed = EFalse; sl@0: sl@0: iLogger = iLogger2.Unmanage(); sl@0: iLogger3->OpenL(3); sl@0: sl@0: RLogger logger = iLogger3.Unmanage(); sl@0: iLogger3.ReleaseResource(); sl@0: logger.Release(); sl@0: sl@0: iAutoPtr = iAutoPtr2.Unmanage(); sl@0: iAutoPtr2.ReleaseResource(); sl@0: sl@0: iAutoPtr4 = iAutoPtr5.Unmanage(); sl@0: sl@0: sl@0: if (iAutoPtr3) sl@0: { sl@0: test.Printf(_L(" iAutoPtr3 pointer = %x\n"), iAutoPtr3.Get()); sl@0: } sl@0: else sl@0: { sl@0: test.Printf(_L(" iAutoPtr3 pointer is null (%x)\n"), iAutoPtr3.Get()); sl@0: } sl@0: sl@0: if (!iNullPtr) sl@0: { sl@0: test.Printf(_L(" iNullPtr is null (%x)\n"), iNullPtr.Get()); sl@0: } sl@0: else sl@0: { sl@0: test.Printf(_L(" iNullPtr is (%x)\n"), iNullPtr.Get()); sl@0: } sl@0: sl@0: if (iAutoPtr3 != iNullPtr) sl@0: { sl@0: test.Printf(_L(" iAutoPtr3 pointer is not null = %x\n"), iAutoPtr3.Get()); sl@0: } sl@0: sl@0: if (iAutoPtr3 == iNullPtr) sl@0: { sl@0: test.Printf(_L(" iAutoPtr3 pointer is null (%x)\n"), iAutoPtr3.Get()); sl@0: } sl@0: sl@0: if (iNullPtr < iAutoPtr3) sl@0: { sl@0: test.Printf(_L(" iNullPtr < iAutoPtr3 (%x)\n"), iAutoPtr3.Get()); sl@0: } sl@0: sl@0: iAutoPtr3 = NULL; sl@0: sl@0: sl@0: iAutoArray = iAutoArray2.Unmanage(); sl@0: iAutoArray2.ReleaseResource(); sl@0: sl@0: iPtrArray->Append(CTracker::NewL()); sl@0: iPtrArray->Append(CTracker::NewL()); sl@0: sl@0: iArrayWrapper->Append(CTracker::NewL()); sl@0: sl@0: iArrayWrapper = iArray2; sl@0: sl@0: iArrayWrapper->Append(CTracker::NewL()); sl@0: iArrayWrapper->Append(CTracker::NewL()); sl@0: sl@0: test.Printf(_L(" iLogger val = %d\n"), iLogger->GetData()); sl@0: test.Printf(_L(" iDestroyer val = %d\n"), (*iDestroyer).GetData()); sl@0: sl@0: test.Printf(_L(" iConstLogger val = %d\n"), iConstLogger->GetData()); sl@0: test.Printf(_L(" iConstLogger val = %d\n"), (*iConstLogger).GetData()); sl@0: sl@0: test.Printf(_L(" iAutoArray[0] val = %d\n"), iAutoArray[0].Value()); sl@0: sl@0: iOtherRef.ReleaseResource(); sl@0: } sl@0: sl@0: sl@0: CComposite::CComposite(TConstructionMode aMode) sl@0: : iConstLogger(42), sl@0: iLogger(1), sl@0: iLogger2(2), sl@0: iLogger3(new int(3)), sl@0: iOther(42), sl@0: iOtherRef(iOther), sl@0: iAnotherLogger(iOtherRef.Unmanage()), sl@0: iDestroyer(2), sl@0: iAutoPtr(CTracker::NewL(aMode == EMemberConstructorLeaves ? CTracker::EConstructorLeaves : CTracker::ENonleavingConstructor)), sl@0: iAutoArray(new(ELeave) CTracker[KNumTrackers]), sl@0: iPtrArray(3), sl@0: iArrayWrapper(iArray), sl@0: iRawLogger(42), sl@0: iGuard(RLogger::Cleanup, &iRawLogger), sl@0: iPair1(1, 2), sl@0: iPair2(one, 2), sl@0: iPair3(1, two), sl@0: iPair4(one, two) sl@0: { sl@0: test.Printf(_L(" CComposite(%d) with leaving constructor - %x\n"), sl@0: aMode, sl@0: this); sl@0: sl@0: iLogger = iLogger2.Unmanage(); sl@0: sl@0: iPtrArray->Append(CTracker::NewL()); sl@0: iPtrArray->Append(CTracker::NewL()); sl@0: sl@0: iArrayWrapper->Append(CTracker::NewL()); sl@0: iArrayWrapper->Append(CTracker::NewL()); sl@0: sl@0: if (aMode == EConstructorLeaves) sl@0: { sl@0: test.Printf(_L("CComposite(EConstructorLeaves): Now leaving with User::Leave(KErrGeneral)\n")); sl@0: User::Leave(KErrGeneral); sl@0: } sl@0: } sl@0: sl@0: CComposite::~CComposite() sl@0: { sl@0: test.Printf(_L(" ~CComposite - %x\n"), this); sl@0: } sl@0: sl@0: sl@0: void CComposite::ReleaseLoggers() sl@0: { sl@0: test.Printf(_L(" CComposite::ReleaseLoggers - %x\n"), this); sl@0: sl@0: iLogger.ReleaseResource(); sl@0: iDestroyer.ReleaseResource(); sl@0: sl@0: iGuard.Dismiss(); sl@0: iRawLogger.Release(); sl@0: } sl@0: sl@0: sl@0: void CComposite::ReleaseArrays() sl@0: { sl@0: test.Printf(_L(" CComposite::ReleaseArrays - %x\n"), this); sl@0: sl@0: iAutoArray.ReleaseResource(); sl@0: } sl@0: sl@0: sl@0: void TrackingDesCall(const TDesC& aConst, TDes& aMut) sl@0: { sl@0: test.Printf(_L("TrackingDesCall const=%S, mut=%S\n"), &aConst, &aMut); sl@0: aMut.Append(_L(": Appended")); sl@0: } sl@0: sl@0: sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4028 sl@0: @SYMTestCaseDesc Tests automatic cleanup if a leave occurs in a Constructor sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates a new CTracker instance passing EConstructorLeaves to the sl@0: factory function which causes the constructor to leave. sl@0: Verifies that all memory allocated in the constructor is sl@0: automatically freed if the constructor leaves. sl@0: @SYMTestExpectedResults All memory allocated in the constructor of CTracker should sl@0: be automatically freed if the constructor leaves. sl@0: @SYMREQ 10368 sl@0: */ sl@0: void TestLeaveFromConstructor() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4028")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("Test CONSTRUCTORS_MAY_LEAVE")); sl@0: sl@0: TRAPD(status, sl@0: { sl@0: CTracker* tracker = CTracker::NewL(CTracker::EConstructorLeaves); sl@0: tracker->MemFunc(); sl@0: }); sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4029 sl@0: @SYMTestCaseDesc Tests automatic cleanup of LCleanedupHandle using different sl@0: cleanup strategies sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates a LCleanedupHandle objects with different cleanup strategies. sl@0: Verifies that the objects are automatically cleaned up when they go sl@0: out of scope sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupHandle sl@0: objects is automatically freed when the object goes out of scope. sl@0: @SYMREQ 10373-8 sl@0: */ sl@0: void TestLCleanedupHandleStrategies() sl@0: { sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4029")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupHandle - test cleanup strategies")); sl@0: sl@0: { sl@0: LCleanedupHandle logger(1); sl@0: LCleanedupHandle logger2(2); sl@0: LCleanedupHandle logger3(3); sl@0: LCleanedupHandle logger4(4); sl@0: LCleanedupHandle logger5(5); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4030 sl@0: @SYMTestCaseDesc Tests construction of LCleanedUpHandle objects using complex constructors sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates a LCleanedupHandle objects using different constructors. sl@0: Verifies that the objects are automatically cleaned up when they go sl@0: out of scope sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupHandle sl@0: objects is automatically freed when the object goes out of scope. sl@0: @SYMREQ 10373-8 sl@0: */ sl@0: void TestLCleanedupConstructors() sl@0: { sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4030")); sl@0: sl@0: __UHEAP_MARK; sl@0: sl@0: { sl@0: LCleanedupHandle logger(1); sl@0: sl@0: LCleanedupHandle pair1(1, 2); sl@0: LCleanedupHandle pair2(one, 2); sl@0: LCleanedupHandle pair3(1, two); sl@0: LCleanedupHandle pair4(one, two); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4031 sl@0: @SYMTestCaseDesc Tests automatic cleanup of LCleanedupHandle sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupHandle on the stack and uses the object. sl@0: Verifies that the object is automatically cleaned up when it goes out of scope sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupHandle sl@0: is automatically freed when the object goes out of scope sl@0: @SYMREQ 10373-8 sl@0: */ sl@0: void TestLCleanedupHandleNormalL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4031")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupHandle - test normal exit from a block scope")); sl@0: sl@0: { sl@0: LCleanedupHandle logger; sl@0: logger->OpenL(42); sl@0: sl@0: LCleanedupHandle logger2(42); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4032 sl@0: @SYMTestCaseDesc Tests automatic cleanup of LCleanedupHandle object on a leave sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates a LCleanedupHandle on the stack and uses the object. sl@0: Verifies that the object is automatically cleaned up when a leave occurs sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupHandle sl@0: is automatically freed when a leave occurs sl@0: @SYMREQ 10373-8 sl@0: */ sl@0: void TestLCleanedupHandleLeave() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4032")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupHandle - test leave")); sl@0: sl@0: TRAPD(status, sl@0: { sl@0: LCleanedupHandle logger(42); sl@0: test.Printf(_L("TestLCleanedupHandleLeave(): Now leaving with User::Leave(KErrGeneral)\n")); sl@0: User::Leave(KErrGeneral); sl@0: }); sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4033 sl@0: @SYMTestCaseDesc Tests manual cleanup of LCleanedupHandle object. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates LCleanedupHandle objects on the stack and sl@0: manually Unmanages and Closes the Handles. sl@0: Verifies that all memory allocated for the objects can be freed sl@0: manually. sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupHandle sl@0: is freed by calling Unmanage() and Close() sl@0: @SYMREQ 10373-8, 10375-5 sl@0: */ sl@0: void TestLCleanedupHandleUnmanage() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4033")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupHandle - test LCleanedupHandle::Unmanage")); sl@0: sl@0: LCleanedupHandle logger1(1); sl@0: LCleanedupHandle logger2(2); sl@0: logger1.Unmanage(); sl@0: logger1->Close(); sl@0: logger2.Unmanage(); sl@0: logger2->Close(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4034 sl@0: @SYMTestCaseDesc Tests manual cleanup of LCleanedupHandle object on a leave sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates LCleanedupHandle objects on the stack and sl@0: manually Unmanages them. sl@0: Forces a leave and then Closes the Handles. sl@0: Verifies that all memory allocated for the objects can be freed sl@0: manually in the event of a leave occuring sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupHandle sl@0: is freed by calling Unmanage() and Close() sl@0: @SYMREQ 10373-8, 10375-5 sl@0: */ sl@0: void TestLCleanedupHandleUnmanageLeave() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4034")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupHandle - test LCleanedupHandle::Unmanage and leave")); sl@0: sl@0: RLogger logger1; sl@0: RLogger logger2; sl@0: TRAPD(status, sl@0: { sl@0: LCleanedupHandle auto_logger1(1); sl@0: LCleanedupHandle auto_logger2(2); sl@0: sl@0: logger1 = auto_logger1.Unmanage(); sl@0: logger2 = auto_logger2.Unmanage(); sl@0: sl@0: test.Printf(_L("TestLCleanedupHandleUnmanageLeave(): Now leaving with User::Leave(KErrGeneral)\n")); sl@0: sl@0: User::Leave(KErrGeneral); sl@0: }); sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status); sl@0: logger1.Close(); sl@0: logger2.Close(); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4035 sl@0: @SYMTestCaseDesc Tests access to managed object through LCleanedupHandle sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates a LCleanedupHandle on the stack and sl@0: uses the LCleanedupHandle object to access RLogger methods sl@0: via the -> operator and the LCleanedupHandle methods via sl@0: the . operator sl@0: @SYMTestExpectedResults All public RLogger methods and LCleanedupHandle methods sl@0: should be accessible through the LCleanedupHandle object. sl@0: @SYMREQ 10373-8 sl@0: */ sl@0: void TestLCleanedupHandleObjectAccess() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4035")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupHandle - test object access")); sl@0: sl@0: { sl@0: LCleanedupHandle logger(42); sl@0: logger->MemFunc(); sl@0: RLogger::StaticMemberRef(*logger); sl@0: RLogger::StaticMemberPtr(&logger.Get()); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4036 sl@0: @SYMTestCaseDesc Tests forced cleanup of LCleanedupHandle object. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates a LCleanedupHandle on the stack and sl@0: forces cleanup by calling ReleaseResource(). sl@0: Verifies that all memory allocated for the object is freed sl@0: by calling ReleaseResource(); sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupHandle sl@0: is freed by calling ReleaseResource(). sl@0: @SYMREQ 10373-8, 10375-4 sl@0: */ sl@0: void TestLCleanedupHandleRelease() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4036")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupHandle - test LCleanedupHandle::ReleaseResource")); sl@0: sl@0: LCleanedupHandle logger(42); sl@0: logger.ReleaseResource(); sl@0: sl@0: LCleanedupHandle logger2(2); sl@0: RLogger raw_logger = logger2.Unmanage(); sl@0: logger2.ReleaseResource(); sl@0: raw_logger.Close(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4037 sl@0: @SYMTestCaseDesc Tests cleanup of derived objects using LCleanedupHandle sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates LCleanedupHandle objects on the stack by instantiating sl@0: derived classes. sl@0: Verifies that all memory allocated for the objects is freed sl@0: automatically when the objects go out of scope. sl@0: @SYMTestExpectedResults All memory allocated for the derived classes is freed sl@0: automatically. sl@0: @SYMREQ 10373-8 sl@0: */ sl@0: void TestLCleanedupHandleConversionL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4037")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupHandle - test convertible type support")); sl@0: sl@0: { sl@0: ROtherLogger olog; sl@0: olog.OpenL(1); sl@0: LCleanedupHandle logger(olog); sl@0: } sl@0: sl@0: { sl@0: RLogger log2; sl@0: log2.OpenL(2); sl@0: LCleanedupHandle ologger(3); sl@0: ologger = log2; sl@0: sl@0: ROtherLogger olog4(4); sl@0: ologger = olog4; sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: void TestLCleanedupHandleL() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: TestLCleanedupHandleStrategies(); sl@0: TestLCleanedupConstructors(); sl@0: TestLCleanedupHandleNormalL(); sl@0: TestLCleanedupHandleLeave(); sl@0: TestLCleanedupHandleUnmanage(); sl@0: TestLCleanedupHandleUnmanageLeave(); sl@0: TestLCleanedupHandleObjectAccess(); sl@0: TestLCleanedupHandleRelease(); sl@0: TestLCleanedupHandleConversionL(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4038 sl@0: @SYMTestCaseDesc Tests cleanup of Null pointer LCleanedupPtr object sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupPtr on the stack but doesnt sl@0: intialise the pointer. sl@0: Verifies that the object is cleaned up when it goes out of scope sl@0: @SYMTestExpectedResults Cleanup of a NULL pointer should complete successfully sl@0: @SYMREQ 10373-6 sl@0: */ sl@0: void TestLCleanedupPtrNull() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4038")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupPtr - test null pointer")); sl@0: sl@0: { sl@0: LCleanedupPtr tracker; sl@0: LCleanedupPtr tint; sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4039 sl@0: @SYMTestCaseDesc Tests automatic cleanup of LCleanedupPtr object sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupPtr on the stack and uses the object. sl@0: Verifies that the object is automatically cleaned up when it goes out of scope sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupPtr sl@0: is automatically freed when it goes out of scope. sl@0: @SYMREQ 10373-6 sl@0: */ sl@0: void TestLCleanedupPtrNormalL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4039")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupPtr - test normal exit from a block scope")); sl@0: sl@0: { sl@0: LCleanedupPtr tracker(CTracker::NewL()); sl@0: LCleanedupPtr tint(new TInt(42)); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4040 sl@0: @SYMTestCaseDesc Tests automatic cleanup of LCleanedupPtr object on a leave sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupPtr on the stack and uses the object. sl@0: Verifies that the object is automatically cleaned up when a leave occurs sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupPtr sl@0: is automatically freed when a leave occurs sl@0: @SYMREQ 10373-6 sl@0: */ sl@0: void TestLCleanedupPtrLeave() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4040")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupPtr - test leave")); sl@0: sl@0: TRAPD(status, sl@0: { sl@0: LCleanedupPtr tracker(CTracker::NewL()); sl@0: LCleanedupPtr nulltracker; sl@0: LCleanedupPtr tint(new TInt(42)); sl@0: LCleanedupPtr nullint; sl@0: sl@0: test.Printf(_L("TestLCleanedupPtrLeave(): Now leaving with User::Leave(KErrGeneral)\n")); sl@0: User::Leave(KErrGeneral); sl@0: }); sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4041 sl@0: @SYMTestCaseDesc Tests manual cleanup of LCleanedupPtr object. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates 2 LCleanedupPtr objects on the stack and sl@0: manually Unmanages and deletes the CTracker objects sl@0: Verifies that all memory allocated for the objects can be freed sl@0: manually. sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupPtr sl@0: is freed by calling Unmanage() and deleting the objects sl@0: @SYMREQ 10373-6, 10375-5 sl@0: */ sl@0: void TestLCleanedupPtrUnmanageL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4041")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupPtr - test LCleanedupPtr::Unmanage")); sl@0: sl@0: { sl@0: LCleanedupPtr tracker1(CTracker::NewL()); sl@0: LCleanedupPtr tracker2(CTracker::NewL()); sl@0: delete tracker1.Unmanage(); sl@0: delete tracker2.Unmanage(); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4042 sl@0: @SYMTestCaseDesc Tests manual cleanup of LCleanedupPtr object on a leave sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates 2 LCleanedupPtr objects on the stack and sl@0: manually Unmanages them. sl@0: Forces a leave and then deletes the CTracker objects. sl@0: Verifies that all memory allocated for the objects can be freed sl@0: manually in the event of a leave occuring sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupPtr sl@0: is freed by calling Unmanage() and deleting the objects sl@0: @SYMREQ 10373-6, 10375-5 sl@0: */ sl@0: void TestLCleanedupPtrUnmanageLeave() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4042")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupPtr - test LCleanedupPtr::Unmanage and leave")); sl@0: sl@0: sl@0: { sl@0: CTracker* ptr1 = NULL; sl@0: CTracker* ptr2 = NULL; sl@0: TRAPD(status2, sl@0: { sl@0: LCleanedupPtr tracker1(CTracker::NewL()); sl@0: LCleanedupPtr tracker2(CTracker::NewL()); sl@0: sl@0: ptr1 = tracker1.Unmanage(); sl@0: ptr2 = tracker2.Unmanage(); sl@0: sl@0: test.Printf(_L("TestLCleanedupPtrUnmanageLeave(): Now leaving with User::Leave(KErrGeneral)\n")); sl@0: User::Leave(KErrGeneral); sl@0: }); sl@0: sl@0: if (status2 != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status2); sl@0: delete ptr1; sl@0: delete ptr2; sl@0: } sl@0: } sl@0: sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4043 sl@0: @SYMTestCaseDesc Tests access to managed object through LCleanedupPtr sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupPtr on the stack and sl@0: uses the LCleanedupPtr object to access CTracker methods sl@0: via the -> operator and the LCleanedupPtr methods via sl@0: the . operator sl@0: @SYMTestExpectedResults All public CTracker methods and LCleanedupPtr sl@0: should be accessible through the LCleanedupPtr object. sl@0: @SYMREQ 10373-6 sl@0: */ sl@0: void TestLCleanedupPtrObjectAccessL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4043")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupPtr - test managed object access")); sl@0: sl@0: { sl@0: LCleanedupPtr tracker(CTracker::NewL()); sl@0: tracker->MemFunc(); sl@0: CTracker::StaticMemberRef(*tracker); sl@0: CTracker::StaticMemberPtr(tracker.Get()); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4044 sl@0: @SYMTestCaseDesc Tests forced cleanup of LCleanedupPtr object. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupPtr> on the stack and sl@0: forces cleanup by calling ReleaseResource(). sl@0: Verifies that all memory allocated for the object is freed sl@0: by calling ReleaseResource() sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupPtr sl@0: is freed by calling ReleaseResource(). sl@0: @SYMREQ 10373-6, 10375-4 sl@0: */ sl@0: void TestLCleanedupPtrReleaseL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4044")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupPtr - test LCleanedupPtr::ReleaseResource")); sl@0: sl@0: sl@0: { sl@0: LCleanedupPtr tracker(CTracker::NewL()); sl@0: tracker.ReleaseResource(); sl@0: sl@0: LCleanedupPtr tracker2(CTracker::NewL()); sl@0: CTracker* ptracker2 = tracker2.Unmanage(); sl@0: tracker2.ReleaseResource(); sl@0: delete ptracker2; sl@0: sl@0: LCleanedupPtr tracker3(CTracker::NewL()); sl@0: tracker3 = NULL; sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4045 sl@0: @SYMTestCaseDesc Tests cleanup of LCleanedupPtr object using TPointerFree strategy sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupPtr on the stack and sl@0: uses the object. sl@0: Verifies that all memory allocated for the object is freed by the sl@0: TPointerFree cleanup strategy when the object goes out of scope. sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupPtr sl@0: object is freed by the TPointerFree cleanup strategy. sl@0: @SYMREQ 10373-6 sl@0: */ sl@0: void TestLCleanedupPtrPointerFree() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4045")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupPtr - test TPointerFree")); sl@0: sl@0: { sl@0: LCleanedupPtr buffer( sl@0: static_cast(User::Alloc(100 * sizeof(TText)))); sl@0: TPtr bufferPtr(buffer.Get(), 100); // create a pointer to the buffer sl@0: // use the buffer sl@0: bufferPtr.Copy(_L("Hello RAII")); sl@0: test.Printf(_L("%S\n"), &bufferPtr); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: void TestLCleanedupPtrConversionL() sl@0: { sl@0: LCleanedupPtr tracker(CDerivedTracker::NewL()); sl@0: sl@0: LCleanedupPtr real( sl@0: static_cast(User::Alloc(sizeof(TReal64)))); sl@0: sl@0: LCleanedupPtr tracker1(CTracker::NewL()); sl@0: LCleanedupPtr derivedTracker(CDerivedTracker::NewL()); sl@0: sl@0: tracker1 = derivedTracker.Unmanage(); sl@0: sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4046 sl@0: @SYMTestCaseDesc Tests cleanup of derived objects using LCleanedupPtr sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupPtr objects on the stack by instantiating sl@0: derived classes. sl@0: Verifies that all memory allocated for the objects is freed sl@0: automatically when the objects go out of scope. sl@0: @SYMTestExpectedResults All memory allocated for the derived classes is freed sl@0: automatically. sl@0: @SYMREQ 10373-6 sl@0: */ sl@0: void TestLCleanedupPtrConversion() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4046")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupPtr - test convertible type support")); sl@0: sl@0: TRAPD(status, TestLCleanedupPtrConversionL()); sl@0: sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4047 sl@0: @SYMTestCaseDesc Tests assignment of LCleanedupPtr objects sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates 2 LCleanedupPtr objects on the stack. sl@0: Unamanages one of the objects and assigns the managed pointer sl@0: to the second LCleanedupPtr sl@0: Verifies that all memory allocated for the objects is freed sl@0: automatically when the objects go out of scope. sl@0: @SYMTestExpectedResults All memory allocated for the objects is freed sl@0: automatically when the objects go out of scope. sl@0: @SYMREQ 10373-6 sl@0: */ sl@0: void TestLCleanedupPtrAssignL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4047")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupPtr - test LCleanedupPtr reset")); sl@0: sl@0: { sl@0: LCleanedupPtr tracker1(CTracker::NewL()); sl@0: LCleanedupPtr tracker2(CTracker::NewL()); sl@0: sl@0: tracker2 = tracker1.Unmanage(); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: void TestLCleanedupPtrBoolConversionL() sl@0: { sl@0: LCleanedupPtr tracker1(CTracker::NewL()); sl@0: sl@0: if (tracker1) sl@0: { sl@0: test.Printf(_L("TestLCleanedupPtrBoolConversion: tracker1 pointer = %x\n"), tracker1.Get()); sl@0: } sl@0: else sl@0: { sl@0: test.Printf(_L("TestLCleanedupPtrBoolConversion: tracker1 pointer is null (%x)\n"), tracker1.Get()); sl@0: } sl@0: sl@0: LCleanedupPtr nullPtr; sl@0: sl@0: if (!nullPtr) sl@0: { sl@0: test.Printf(_L("TestLCleanedupPtrBoolConversion: nullPtr pointer is null (%x)\n"), nullPtr.Get()); sl@0: } sl@0: else sl@0: { sl@0: test.Printf(_L("TestLCleanedupPtrBoolConversion: nullPtr pointer = %x\n"), nullPtr.Get()); sl@0: } sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4048 sl@0: @SYMTestCaseDesc Tests conversion of LCleanedupPtr objects sl@0: @SYMTestPriority High sl@0: @SYMTestActions Calls TestLCleanedupPtrBoolConversionL which creates 2 sl@0: LCleanedupPtr objects on the stack, one of which sl@0: is a null pointer. Tests conversion of the null pointer sl@0: into a CTracker* via the Get() method and ensures all sl@0: memory is freed on scope exit. sl@0: @SYMTestExpectedResults All memory allocated for the objects is freed sl@0: automatically when the objects go out of scope. sl@0: @SYMREQ 10373-6 sl@0: */ sl@0: void TestLCleanedupPtrBoolConversion() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4048")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupPtr - test bool conversion")); sl@0: sl@0: TRAPD(status, TestLCleanedupPtrBoolConversionL()); sl@0: sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: void TestLCleanedupPtrCompareL() sl@0: { sl@0: LCleanedupPtr tracker1(CTracker::NewL()); sl@0: LCleanedupPtr tracker2(CTracker::NewL()); sl@0: sl@0: if (tracker1 == tracker2) sl@0: { sl@0: test.Printf(_L("tracker1 == tracker2 %x %x\n"), tracker1.Get(), tracker2.Get()); sl@0: } sl@0: sl@0: if (tracker1 != tracker2) sl@0: { sl@0: test.Printf(_L("tracker1 != tracker2 %x %x\n"), tracker1.Get(), tracker2.Get()); sl@0: } sl@0: sl@0: sl@0: if (tracker1 < tracker2) sl@0: { sl@0: test.Printf(_L("tracker1 < tracker2 %x %x\n"), tracker1.Get(), tracker2.Get()); sl@0: } sl@0: sl@0: sl@0: tracker2 = tracker1.Get(); sl@0: sl@0: if (tracker1 == tracker2) sl@0: { sl@0: test.Printf(_L("tracker1 == tracker2 %x %x\n"), tracker1.Get(), tracker2.Get()); sl@0: } sl@0: sl@0: if (tracker1 != tracker2) sl@0: { sl@0: test.Printf(_L("tracker1 != tracker2 %x %x\n"), tracker1.Get(), tracker2.Get()); sl@0: } sl@0: sl@0: if (tracker1 < tracker2) sl@0: { sl@0: test.Printf(_L("tracker1 < tracker2 %x %x\n"), tracker1.Get(), tracker2.Get()); sl@0: } sl@0: sl@0: tracker1.Unmanage(); sl@0: } sl@0: sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4049 sl@0: @SYMTestCaseDesc Tests comparison of LCleanedupPtr objects sl@0: @SYMTestPriority High sl@0: @SYMTestActions Calls TestLCleanedupPtrCompareL which creates 2 sl@0: LCleanedupPtr objects on the stack. sl@0: Compares the objects using the comparison operators sl@0: and ensures all memory is freed on scope exit. sl@0: @SYMTestExpectedResults All memory allocated for the objects is freed sl@0: automatically when the objects go out of scope. sl@0: @SYMREQ 10373-6 sl@0: */ sl@0: void TestLCleanedupPtrCompare() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4049")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupPtr - test compare")); sl@0: sl@0: TRAPD(status, TestLCleanedupPtrCompareL()); sl@0: sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4067 sl@0: @SYMTestCaseDesc Tests execution of custom cleanup strategy for LCleanedupPtr objects sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupPtr object sl@0: on the stack which uses a custom cleanup strategy. sl@0: Verifies that the custom strategy is invoked when the object goes out sl@0: of scope. sl@0: @SYMTestExpectedResults All memory allocated for the object is freed automatically by sl@0: the custom cleanup strategy when the objecs goes out of scope. sl@0: @SYMREQ 10373 sl@0: */ sl@0: void TestLCleanedupPtrCustomStrategyL() sl@0: { sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4067")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupPtr - test TCTrackerDestroy strategy")); sl@0: sl@0: { sl@0: LCleanedupPtr t(new(ELeave) CTracker); sl@0: } sl@0: sl@0: test(trackerDestroyed); sl@0: sl@0: __UHEAP_MARKEND; sl@0: sl@0: } sl@0: sl@0: sl@0: void TestLCleanedupPtrL() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: TestLCleanedupPtrNull(); sl@0: TestLCleanedupPtrNormalL(); sl@0: TestLCleanedupPtrLeave(); sl@0: TestLCleanedupPtrUnmanageL(); sl@0: TestLCleanedupPtrUnmanageLeave(); sl@0: TestLCleanedupPtrObjectAccessL(); sl@0: TestLCleanedupPtrReleaseL(); sl@0: TestLCleanedupPtrPointerFree(); sl@0: TestLCleanedupPtrConversion(); sl@0: TestLCleanedupPtrAssignL(); sl@0: TestLCleanedupPtrBoolConversion(); sl@0: TestLCleanedupPtrCompare(); sl@0: TestLCleanedupPtrCustomStrategyL(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: class TLogCleanupStrategy sl@0: { sl@0: public: sl@0: template sl@0: static void Cleanup(T* aObjPtr) sl@0: { sl@0: test.Printf(_L("Cleanup log: %x\n"), aObjPtr); sl@0: } sl@0: }; sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4050 sl@0: @SYMTestCaseDesc Tests automatic cleanup of LManagedXX objects sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupPtr on the stack - sl@0: CComposite internally contains LManagedXX objects sl@0: Verify that all LManagedXX objects are cleaned up when sl@0: the LCleanedupPtr object goes out of scope. sl@0: @SYMTestExpectedResults All memory allocated for the CComposite object sl@0: is automatically freed when it goes out of scope. sl@0: @SYMREQ 10374 sl@0: */ sl@0: void TestLManagedNormalL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4050")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LManaged - test composite object with normal exit from a block scope ")); sl@0: sl@0: { sl@0: LCleanedupPtr comp(CComposite::NewL()); sl@0: } sl@0: sl@0: //Check that the custom cleanup strategy for the iAutoPtr member of sl@0: //CComposite has been invoked sl@0: test(trackerDestroyed); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4051 sl@0: @SYMTestCaseDesc Tests automatic cleanup of LManagedXX objects if sl@0: a leave occurs in a Constructor sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupPtr object on the stack sl@0: passing EConstructorLeaves to the CComposite factory function sl@0: which causes the constructor to leave. sl@0: Verifies that all memory allocated in the constructor is sl@0: automatically freed if the constructor leaves. sl@0: @SYMTestExpectedResults All memory allocated for the CComposite object sl@0: is automatically freed when it goes out of scope. sl@0: @SYMREQ 10368, 10374 sl@0: */ sl@0: void TestLManagedConstructorLeave() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4051")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LManaged - test composite object with leave from constructor")); sl@0: sl@0: TRAPD(status, sl@0: { sl@0: LCleanedupPtr comp(CComposite::NewL(CComposite::EConstructorLeaves)); sl@0: }); sl@0: sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status); sl@0: } sl@0: sl@0: //Check that the custom cleanup strategy for the iAutoPtr member of sl@0: //CComposite has been invoked sl@0: test(trackerDestroyed); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4052 sl@0: @SYMTestCaseDesc Tests automatic cleanup of LManagedXX objects if sl@0: a leave occurs in a Constructor sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupPtr object on the stack sl@0: passing EMemberConstructorLeaves to the CComposite factory function sl@0: which causes the constructor of the CTracker member to leave. sl@0: The CComposite object contains several LManagedX members which are sl@0: instantiated in the constructor. sl@0: Verifies that all memory allocated in the constructor is sl@0: automatically freed if the constructor leaves. sl@0: @SYMTestExpectedResults All memory allocated for the CComposite object sl@0: is automatically freed when it goes out of scope. sl@0: @SYMREQ 10368, 10374 sl@0: */ sl@0: void TestLManagedMemberConstructorLeave() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4052")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LManaged - test composite object with leave from member constructor")); sl@0: sl@0: TRAPD(status, sl@0: { sl@0: LCleanedupPtr comp(CComposite::NewL(CComposite::EMemberConstructorLeaves)); sl@0: }); sl@0: sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status); sl@0: } sl@0: sl@0: //Check that the custom cleanup strategy for the iAutoPtr member of sl@0: //CComposite has been invoked sl@0: test(trackerDestroyed); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4053 sl@0: @SYMTestCaseDesc Tests realease of LManagedX classes sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates 2 LCleanedupPtr objects on the stack. sl@0: Calls ReleaseLoggers() and ReleaseArrays() on the managed objects. sl@0: Verifies that all memory allocated for the objects is freed sl@0: automatically when the objects go out of scope. sl@0: @SYMTestExpectedResults All memory allocated for the objects is freed sl@0: automatically when the objects go out of scope. sl@0: @SYMREQ 10374 sl@0: */ sl@0: void TestLManagedReleaseL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4053")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LManaged - test composite object release")); sl@0: sl@0: { sl@0: LCleanedupPtr comp1(CComposite::NewL()); sl@0: comp1->ReleaseLoggers(); sl@0: sl@0: LCleanedupPtr comp2(CComposite::NewL()); sl@0: comp2->ReleaseArrays(); sl@0: } sl@0: sl@0: //Check that the custom cleanup strategy for the iAutoPtr member of sl@0: //CComposite has been invoked sl@0: test(trackerDestroyed); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: void TestCompositeL() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: TestLManagedNormalL(); sl@0: TestLManagedConstructorLeave(); sl@0: TestLManagedMemberConstructorLeave(); sl@0: TestLManagedReleaseL(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4054 sl@0: @SYMTestCaseDesc Tests automatic cleanup of LCleanedupRef object sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates a LCleanedupRef on the stack and uses the object. sl@0: Verifies that the object is automatically cleaned up when it goes out of scope sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupRef sl@0: is automatically freed when it goes out of scope. sl@0: @SYMREQ 10373-7 sl@0: */ sl@0: void TestLCleanedupRefNormalL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4054")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupRef - test normal exit from a block scope")); sl@0: sl@0: { sl@0: RLogger logger; sl@0: logger.OpenL(42); sl@0: LCleanedupRef wlogger(logger); sl@0: wlogger->MemFunc(); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4055 sl@0: @SYMTestCaseDesc Tests automatic cleanup of LCleanedupRef object on a leave sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupRef on the stack and uses the object. sl@0: Verifies that the object is automatically cleaned up when a leave occurs sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupRef sl@0: is automatically freed when a leave occurs sl@0: @SYMREQ 10373-7 sl@0: */ sl@0: void TestLCleanedupRefLeave() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4055")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupRef - test leave")); sl@0: sl@0: TRAPD(status, sl@0: { sl@0: RLogger logger; sl@0: logger.OpenL(42); sl@0: LCleanedupRef wlogger(logger); sl@0: wlogger->MemFunc(); sl@0: sl@0: test.Printf(_L("TestLCleanedupRefLeave(): Now leaving with User::Leave(KErrGeneral)\n")); sl@0: User::Leave(KErrGeneral); sl@0: }); sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4056 sl@0: @SYMTestCaseDesc Tests manual cleanup of LCleanedupRef object. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupRef object on the stack and sl@0: manually Unmanages and closes the RLogger. sl@0: Verifies that all memory allocated for the object can be freed sl@0: manually. sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupRef sl@0: is freed by calling Unmanage() and Close() sl@0: @SYMREQ 10373-7, 10375-5 sl@0: */ sl@0: void TestLCleanedupRefUnmanageL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4056")); sl@0: sl@0: __UHEAP_MARK; sl@0: sl@0: test.Next(_L("LCleanedupPtr - test LCleanedupPtr::Unmanage")); sl@0: sl@0: RLogger logger; sl@0: sl@0: LCleanedupRef rlog(logger); sl@0: rlog->OpenL(42); sl@0: rlog->MemFunc(); sl@0: rlog.Unmanage(); sl@0: logger.Close(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4057 sl@0: @SYMTestCaseDesc Tests manual cleanup of LCleanedupRef object on a leave sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates LCleanedupRef objects on the stack and sl@0: manually Unmanages them. sl@0: Forces a leave and then Closes the RLogger objects. sl@0: Verifies that all memory allocated for the objects can be freed sl@0: manually in the event of a leave occuring sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupRef sl@0: is freed by calling Unmanage() and Close() sl@0: @SYMREQ 10373-7, 10375-5 sl@0: */ sl@0: void TestLCleanedupRefUnmanageLeave() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4057")); sl@0: sl@0: __UHEAP_MARK; sl@0: sl@0: test.Next(_L("LCleanedupRef - test LCleanedupRef::Unmanage")); sl@0: sl@0: RLogger logger1(1); sl@0: RLogger logger2(2); sl@0: sl@0: TRAPD(status, sl@0: { sl@0: LCleanedupRef rlog1(logger1); sl@0: LCleanedupRef rlog2(logger2); sl@0: rlog1->MemFunc(); sl@0: rlog2->MemFunc(); sl@0: rlog1.Unmanage(); sl@0: rlog2.Unmanage(); sl@0: sl@0: test.Printf(_L("TestLCleanedupRefUnmanageLeave(): Now leaving with User::Leave(KErrGeneral)\n")); sl@0: User::Leave(KErrGeneral); sl@0: }); sl@0: sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status); sl@0: logger1.Close(); sl@0: logger2.Close(); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4058 sl@0: @SYMTestCaseDesc Tests access to managed object through LCleanedupRef sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupRef on the stack and sl@0: uses the LCleanedupRef object to access RLogger methods sl@0: via the -> operator and the LCleanedupRef methods via sl@0: the . operator sl@0: @SYMTestExpectedResults All public RLogger methods and LCleanedupRef sl@0: should be accessible through the LCleanedupRef object. sl@0: @SYMREQ 10373-7 sl@0: */ sl@0: void TestLCleanedupRefObjectAccessL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4058")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupRef - test managed object access")); sl@0: sl@0: { sl@0: RLogger logger; sl@0: logger.OpenL(42); sl@0: LCleanedupRef rlog(logger); sl@0: rlog->MemFunc(); sl@0: RLogger::StaticMemberRef(*rlog); sl@0: RLogger::StaticMemberPtr(&rlog.Get()); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4059 sl@0: @SYMTestCaseDesc Tests forced cleanup of LCleanedupRef object. sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupRef on the stack and sl@0: forces cleanup by calling ReleaseResource(). sl@0: Verifies that all memory allocated for the object is freed sl@0: by calling ReleaseResource() sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupRef sl@0: is freed by calling ReleaseResource(). sl@0: @SYMREQ 10373-7, 10375-4 sl@0: */ sl@0: void TestLCleanedupRefReleaseL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4059")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupRef - test LCleanedupRef::ReleaseResource")); sl@0: sl@0: { sl@0: RLogger logger; sl@0: logger.OpenL(42); sl@0: sl@0: LCleanedupRef wlogger(logger); sl@0: wlogger->MemFunc(); sl@0: wlogger.ReleaseResource(); sl@0: sl@0: RLogger logger2(2); sl@0: LCleanedupRef wlogger2(logger2); sl@0: wlogger2->MemFunc(); sl@0: RLogger& logref2 = wlogger2.Unmanage(); sl@0: wlogger2.ReleaseResource(); sl@0: logref2.Release(); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4060 sl@0: @SYMTestCaseDesc Tests assignment of LCleanedupRef objects sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates 2 LCleanedupRef objects on the stack. sl@0: Unamanages one of the objects and assigns the managed sl@0: reference to the second LCleanedupPtr sl@0: Verifies that all memory allocated for the objects is freed sl@0: automatically when the objects go out of scope. sl@0: @SYMTestExpectedResults All memory allocated for the objects is freed sl@0: automatically when the objects go out of scope. sl@0: @SYMREQ 10373-7 sl@0: */ sl@0: void TestLCleanedupRefAssignL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4060")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupRef - test LCleanedupRef::operator=")); sl@0: sl@0: { sl@0: RLogger logger1; sl@0: logger1.OpenL(1); sl@0: LCleanedupRef wlogger1(logger1); sl@0: sl@0: RLogger logger2; sl@0: logger2.OpenL(2); sl@0: LCleanedupRef wlogger2(logger2); sl@0: sl@0: //The assignment results in logger2 being cleaned up before sl@0: //logger1 is assigned sl@0: wlogger2 = wlogger1.Unmanage(); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: sl@0: void TestLCleanedupRefL() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: TestLCleanedupRefNormalL(); sl@0: TestLCleanedupRefLeave(); sl@0: TestLCleanedupRefUnmanageL(); sl@0: TestLCleanedupRefUnmanageLeave(); sl@0: TestLCleanedupRefObjectAccessL(); sl@0: TestLCleanedupRefReleaseL(); sl@0: TestLCleanedupRefAssignL(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4061 sl@0: @SYMTestCaseDesc Tests automatic cleanup of LCleanedupGuard object sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupGuard on the stack to clean up an RLogger object sl@0: via the RLogger::Cleanup function. sl@0: Verifies that the object is automatically cleaned up when it goes sl@0: out of scope sl@0: @SYMTestExpectedResults All memory allocated for the RLogger sl@0: is automatically freed when it goes out of scope. sl@0: @SYMREQ 10373-10 sl@0: */ sl@0: void TestLCleanedupGuardNormal() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4061")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Printf(_L("LCleanedupGuard - test normal exit from a block scope\n")); sl@0: sl@0: { sl@0: RLogger logger(42); sl@0: LCleanedupGuard cleanGuard(RLogger::Cleanup, &logger); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4062 sl@0: @SYMTestCaseDesc Tests automatic cleanup of LCleanedupGuard object on a leave sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupGuard on the stack to clean up an RLogger object sl@0: via the RLogger::Cleanup function. sl@0: Verifies that the object is automatically cleaned up when a leave occurs sl@0: @SYMTestExpectedResults All memory allocated for the RLogger sl@0: is automatically freed when a leave occurs sl@0: @SYMREQ 10373-10 sl@0: */ sl@0: void TestLCleanedupGuardLeave() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4062")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Printf(_L("LCleanedupGuard - test leave")); sl@0: sl@0: TRAPD(status, sl@0: { sl@0: RLogger logger(42); sl@0: LCleanedupGuard cleanGuard(RLogger::Cleanup, &logger); sl@0: sl@0: test.Printf(_L("TestLCleanedupGuardLeave(): Now leaving with User::Leave(KErrGeneral)\n")); sl@0: User::Leave(KErrGeneral); sl@0: }); sl@0: sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4063 sl@0: @SYMTestCaseDesc Tests dissmissing of LCleanedupGuard sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupGuard on the stack to clean up an RLogger object sl@0: via the RLogger::Cleanup function. sl@0: Calls LCleanedupGuard::Dismiss to disable the guard and manually calls sl@0: cleanup function. sl@0: Verifies that the memory allocated for the RLogger object is cleaned up sl@0: @SYMTestExpectedResults All memory allocated for the RLogger is freed by calling sl@0: Dismiss and manually calling RLogger::Cleanup() sl@0: @SYMREQ 10373-10 sl@0: */ sl@0: void TestLCleanedupGuardDismiss() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4063")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Printf(_L("LCleanedupGuard - test LCleanedupGuard::Dismiss\n")); sl@0: sl@0: sl@0: RLogger logger(42); sl@0: LCleanedupGuard cleanGuard(RLogger::Cleanup, &logger); sl@0: cleanGuard.Dismiss(); sl@0: RLogger::Cleanup(&logger); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4064 sl@0: @SYMTestCaseDesc Tests dismissing of LCleanedupGuard on a leave sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupGuard on the stack to clean up an RLogger object sl@0: via the RLogger::Cleanup function. sl@0: Calls LCleanedupGuard::Dismiss to disable the guard and forces a leave. sl@0: Manually calls the RLogger cleanup function. sl@0: Verifies that the memory allocated for the RLogger object is cleaned up sl@0: @SYMTestExpectedResults All memory allocated for the RLogger is freed on a leave by sl@0: calling Dismiss and manually cleaning up the object. sl@0: @SYMREQ 10373-10 sl@0: */ sl@0: void TestLCleanedupGuardDismissLeave() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4064")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Printf(_L("LCleanedupGuard - test LCleanedupGuard::Dismiss\n")); sl@0: sl@0: RLogger logger(42); sl@0: TRAPD(status, sl@0: { sl@0: LCleanedupGuard cleanGuard(RLogger::Cleanup, &logger); sl@0: cleanGuard.Dismiss(); sl@0: sl@0: test.Printf(_L("TestLCleanedupGuardDismissLeave(): Now leaving with User::Leave(KErrGeneral)\n")); sl@0: User::Leave(KErrGeneral); sl@0: }); sl@0: sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status); sl@0: RLogger::Cleanup(&logger); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: void TestLCleanedupGuard() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: TestLCleanedupGuardNormal(); sl@0: TestLCleanedupGuardLeave(); sl@0: TestLCleanedupGuardDismiss(); sl@0: TestLCleanedupGuardDismissLeave(); sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4065 sl@0: @SYMTestCaseDesc Tests manual cleanup of LCleanedupArray object on a leave sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupArray on the stack and calls Unmanage(). sl@0: Forces a leave and then manually cleans up the array. sl@0: Verifies that the objects are automatically cleaned up when they go sl@0: out of scope sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupArray objects sl@0: is automatically freed when they go out of scope. sl@0: @SYMREQ 10373-9, 10375-5 sl@0: */ sl@0: void TestLCleanedupArrayUnmanageLeave() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4065")); sl@0: sl@0: __UHEAP_MARK; sl@0: sl@0: const TInt KNumLoggers = 3; sl@0: TLogger* ploggers = NULL; sl@0: TRAPD(status, sl@0: { sl@0: LCleanedupArray loggers(new(ELeave) TLogger[KNumLoggers]); sl@0: sl@0: ploggers = loggers.Unmanage(); sl@0: sl@0: test.Printf(_L("TestLCleanedupArrayUnmanageLeave(): Now leaving with User::Leave(KErrGeneral)\n")); sl@0: sl@0: User::Leave(KErrGeneral); sl@0: }); sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Leave trapped; leave code: %d\n"), status); sl@0: delete[] ploggers; sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: /** sl@0: @SYMTestCaseID SYSLIB-EUSERHL-UT-4066 sl@0: @SYMTestCaseDesc Tests automatic cleanup of LCleanedupArray object sl@0: @SYMTestPriority High sl@0: @SYMTestActions Creates an LCleanedupArrayand uses the object. sl@0: Creates an LCleanedupArray with a custom sl@0: cleanup strategy and uses the object. sl@0: Creates an LCleanedupArray and forces cleanup sl@0: Creates an LCleanedupArray and calls UNmanage() sl@0: Verifies that the objects are automatically cleaned up when they go sl@0: out of scope sl@0: @SYMTestExpectedResults All memory allocated for the LCleanedupArray objects sl@0: is automatically freed when they go out of scope. sl@0: @SYMREQ 10373-9, 10375-4, 10375-5 sl@0: */ sl@0: void TestLCleanedupArrayL() sl@0: { sl@0: sl@0: test.Next(_L ("@SYMTestCaseID:SYSLIB-EUSERHL-UT-4066")); sl@0: sl@0: __UHEAP_MARK; sl@0: test.Next(_L("LCleanedupArray - test normal exit from a block scope")); sl@0: sl@0: { sl@0: const TInt KNumLoggers = 3; sl@0: LCleanedupArray array(new(ELeave) TLogger[KNumLoggers]); sl@0: array[0].Test(); sl@0: sl@0: TLogger rawarr[2]; sl@0: LCleanedupArray marr(rawarr); sl@0: marr[0].Test(); sl@0: sl@0: LCleanedupArray array2(new(ELeave) TLogger[KNumLoggers]); sl@0: array2.ReleaseResource(); sl@0: sl@0: LCleanedupArray array3(new(ELeave) TLogger[KNumLoggers]); sl@0: array2 = array3.Unmanage(); sl@0: sl@0: LCleanedupArray nullarr; sl@0: sl@0: TestLCleanedupArrayUnmanageLeave(); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: void TestOrLeave() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: { sl@0: TRAPD(err,KErrGeneral OR_LEAVE); sl@0: test(err == KErrGeneral); sl@0: sl@0: TRAP(err,(5-7) OR_LEAVE); sl@0: test(err == -2); sl@0: sl@0: RLogger logger; sl@0: logger.OpenL(KErrNoMemory); sl@0: sl@0: LCleanedupRef cLogger(logger); sl@0: TRAP(err,{ sl@0: *(cLogger->GetData()) OR_LEAVE; sl@0: }); sl@0: test(err == KErrNoMemory); sl@0: sl@0: LCleanedupHandle cFs; sl@0: LCleanedupHandle cFile; sl@0: sl@0: TRAP(err, cFs->Connect() OR_LEAVE); sl@0: test(err == KErrNone); sl@0: sl@0: _LIT(KTestFile,"c:\\test_emanaged"); sl@0: err = cFile->Open(*cFs, KTestFile,EFileRead); sl@0: if (err != KErrNone) sl@0: { sl@0: test.Printf(_L("Error opening file: %d\n"), err); sl@0: if (err == KErrNotFound) sl@0: { sl@0: test.Printf(_L("Creating new file c:\\test_emanaged ... ")); sl@0: err = cFile->Create(*cFs, sl@0: KTestFile, sl@0: EFileWrite | EFileShareAny); sl@0: test.Printf(_L("File created\n")); sl@0: } sl@0: } sl@0: sl@0: test(err == KErrNone); sl@0: sl@0: LCleanedupHandle dir; sl@0: err = dir->Open(*cFs, _L("c:\\resource"), KEntryAttMaskSupported); sl@0: sl@0: LCleanedupHandle aFs(cFs.Unmanage()); sl@0: LCleanedupHandle aFile(cFile.Unmanage()); sl@0: LCleanedupHandle adir(dir.Unmanage()); sl@0: sl@0: test(err == KErrNone); sl@0: } sl@0: sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: void TestL() sl@0: { sl@0: __UHEAP_MARK; sl@0: sl@0: TestLeaveFromConstructor(); sl@0: sl@0: TestLCleanedupHandleL(); sl@0: TestLCleanedupPtrL(); sl@0: TestLCleanedupArrayL(); sl@0: TestLCleanedupRefL(); sl@0: TestLCleanedupGuard(); sl@0: TestCompositeL(); sl@0: TestOrLeave(); sl@0: TExtendedTestL(); sl@0: __UHEAP_MARKEND; sl@0: } sl@0: sl@0: sl@0: TInt E32Main() sl@0: { sl@0: CTrapCleanup* stack = CTrapCleanup::New(); sl@0: if (stack == NULL) sl@0: return KErrNoMemory; sl@0: sl@0: test.Title(); sl@0: test.Start(_L("RAII-based automatic resource management tests")); sl@0: sl@0: TRAPD(status, TestL()); sl@0: if (status != KErrNone) sl@0: { sl@0: test.Printf(_L("Test leave trapped; leave code: %d\n"), status); sl@0: } sl@0: else sl@0: { sl@0: test.End(); sl@0: } sl@0: sl@0: delete stack; sl@0: return status; sl@0: } sl@0: sl@0: