Symbian
Symbian OS Library

SYMBIAN OS V9.3

[Index] [Spacer] [Previous] [Next]



Cleanup support example code


ErrorOnFail: cleanup, TRAPD and leaving


Example code

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

Found in: examples\Base\MemMan\Cleanup\ErrorOnFail

// ErrorOnFail.cpp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.
//
// Example shows attempt to construct an object and return an
// appropriate error code on failure.
//
// NOTE: the structure of this example is different to standard E32 examples


#include <e32cons.h>


//
// Common formats
//


_LIT(KCommonFormat1,"Value of iInt is %d.\n");


  // All messages written to this
LOCAL_D CConsoleBase* console;
  
  // Flag which determines whether the doSomething() member function
  // of the CExample class should leave when called.
LOCAL_D TBool leaveFlag = ETrue;

  // Parameter for __UHEAP_SETFAIL
  // Allocation guaranteed to fail at this number of allocation attempts;
  // i.e. if set to n, allocation fails on the nth attempt. 
  // NB only used in debug mode
#ifdef _DEBUG
LOCAL_D TInt allocFailNumber = 1;
#endif
  
  // Function prototypes
LOCAL_C TInt doExample();      
LOCAL_C void callExampleL();



//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (definition)
//
// The class is used by the example code
//
//////////////////////////////////////////////////////////////////////////////
class CExample : public CBase
    {
public :
    void DoSomethingL();
public :
    TInt iInt;
    };


//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (implementation)
//
//////////////////////////////////////////////////////////////////////////////
void CExample::DoSomethingL() 
    {
      // Leave if the global flag is set
    if (leaveFlag)
        {
        _LIT(KMsgLeaving,"DoSomethingL leaving.\n");
        console->Printf(KMsgLeaving);
        User::Leave(KErrGeneral);       
        }
    console->Printf(KCommonFormat1,iInt);
    }

//////////////////////////////////////////////////////////////////////////////
//
// Main function called by E32
//
//////////////////////////////////////////////////////////////////////////////
GLDEF_C TInt E32Main()
    {
      // Get cleanup stack
    CTrapCleanup* cleanup=CTrapCleanup::New();

      // Some more initialization, then do the example
    TRAPD(error,callExampleL());
      
      // callExampleL() should never leave.
    _LIT(KMsgPanicEpoc32ex,"EPOC32EX");
    __ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));

      // destroy the cleanup stack
    delete cleanup;
    
      // return
    return 0;
    }


//////////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////////
LOCAL_C void callExampleL() 
    {
      // Initialize and call the example code under cleanup stack
    _LIT(KMsgExampleCode,"Symbian OS Example Code");
    console = Console::NewL(KMsgExampleCode,TSize(KConsFullScreen,KConsFullScreen));
      // Put console onto the cleanup stack
    CleanupStack::PushL(console);

      // Perform the example function
    TInt retVal;
    retVal = doExample();

      // Show the value returned from the example
    _LIT(KFormat2,"Return code=%d.\n");
    console->Printf(KFormat2, retVal);
    _LIT(KMsgPressAnyKey," [press any key]");
    console->Printf(KMsgPressAnyKey);
    console->Getch();

      // Remove the console object from the cleanupstack
      // and destroy it 
    CleanupStack::PopAndDestroy();
    }


//////////////////////////////////////////////////////////////////////////////
//
// Do the example
//
//////////////////////////////////////////////////////////////////////////////
TInt doExample()
    {
      // Memory alloc fails on the 'allocFailNumber' attempt.
    __UHEAP_SETFAIL(RHeap::EDeterministic,allocFailNumber);
      // Allocate and test
    CExample* myExample = new CExample;
    if (!myExample) return(KErrNoMemory); 
      // Do something with the CExample object
    myExample->iInt = 5;
      //
    console->Printf(KCommonFormat1,myExample->iInt);
      // Delete the CExample object
    delete myExample;
      // Completed OK
    return KErrNone;
    }

// BLD.INF
// Component description file 
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

PRJ_MMPFILES

ErrorOnFail.mmp

// ErrorOnFail.mmp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// using relative paths for source and userinclude directories

// No explicit capabilities required to run this.

TARGET        ErrorOnFail.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        ErrorOnFail.cpp

USERINCLUDE   .
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib

CAPABILITY    None


Description

The example attempts to construct an object, and on failure it returns an appropriate error code.

This example shows use of the TRAPD macro, the cleanup stack and its functions PushL(), PopAndDestroy() and the process of leaving. It also uses the heap debugging macro __UHEAP_SETFAIL.


Classes used


Security issues

The example requires no specific capabilities in order to run - and does not demonstrate any security issues.

[Top]


LeaveOnFail: cleanup, TRAPD and leaving

Example code

Found in: examples\Base\MemMan\Cleanup\LeaveOnFail

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

// LeaveOnFail.cpp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// Example shows attempt to construct an object and leaves on failure. 

// NOTE: the structure of this example is different to standard E32 examples


#include <e32cons.h>

//
// Common literal text
//


_LIT(KCommonFormat1,"Value of iInt is %d.\n");


  // All messages written to this
LOCAL_D CConsoleBase* console;
  
  // Flag which determines whether the doSomething() member function
  // of the CExample class should leave when called.
LOCAL_D TBool leaveFlag = ETrue;

  // Parameter for __UHEAP_SETFAIL
  // Allocation guaranteed to fail at this number of allocation attempts;
  // i.e. if set to n, allocation fails on the nth attempt. 
  // NB only used in debug mode
#ifdef _DEBUG
LOCAL_D TInt allocFailNumber = 1;
#endif
  
  // Function prototypes
LOCAL_C void doExampleL();      
LOCAL_C void callExampleL();


//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (definition)
//
// The class is used by the example code
//
//////////////////////////////////////////////////////////////////////////////
class CExample : public CBase
    {
public :
    void DoSomethingL();
public :
    TInt iInt;
    };


//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (implementation)
//
//////////////////////////////////////////////////////////////////////////////
void CExample::DoSomethingL() 
    {
      // Leave if the global flag is set
    if (leaveFlag)
        {
        _LIT(KMsgLeaving,"DoSomethingL leaving.\n");
        console->Printf(KMsgLeaving);
        User::Leave(KErrGeneral);       
        }
    console->Printf(KCommonFormat1,iInt);
    }

//////////////////////////////////////////////////////////////////////////////
//
// Main function called by E32
//
//////////////////////////////////////////////////////////////////////////////
GLDEF_C TInt E32Main()
    {
      // Get cleanup stack
    CTrapCleanup* cleanup=CTrapCleanup::New();

      // Some more initialization, then do the example
    TRAPD(error,callExampleL());
      
      // callExampleL() should never leave.
    _LIT(KMsgPanicEpoc32ex,"EPOC32EX");
    __ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));

      // destroy the cleanup stack
    delete cleanup;
    
      // return
    return 0;
    }


//////////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////////
LOCAL_C void callExampleL() 
    {
      // Initialize and call the example code under cleanup stack.
    _LIT(KMsgExampleCode,"Symbian OS Example Code");
    console = Console::NewL(KMsgExampleCode,TSize(KConsFullScreen,KConsFullScreen));
      // Put console onto the cleanup stack.
    CleanupStack::PushL(console);

      // Perform the example function under the protection of a 
      // TRAP harness.
    TRAPD(error,doExampleL());
    _LIT(KFormat2,"failed: leave code = %d");
    _LIT(KMsgOK,"ok");
    if (error)
        console->Printf(KFormat2,error);
    else
        console->Printf(KMsgOK);
      
      // Continue
    _LIT(KMsgPressAnyKey," [press any key]");
    console->Printf(KMsgPressAnyKey);
    console->Getch();

      // Remove the console object from the cleanupstack
      // and destroy it. 
    CleanupStack::PopAndDestroy();
    }


//////////////////////////////////////////////////////////////////////////////
//
// Do the example
//
//////////////////////////////////////////////////////////////////////////////
void doExampleL()
    {
      // Memory alloc fails on the 'allocFailNumber' attempt. 
    __UHEAP_SETFAIL(RHeap::EDeterministic,allocFailNumber);
      // Allocate - leave if allocation fails.
      // Leave is used in place of return to indicate an error.
      //
      // Could also use - User::LeaveIfNull(myExample);
    CExample* myExample = new CExample;
    if (!myExample) User::Leave(KErrNoMemory); 
      // Do something with the CExample object
    myExample->iInt = 5;
      //
    console->Printf(KCommonFormat1,myExample->iInt);
      // Delete the CExample object
    delete myExample;
    }

// LeaveOnFail.mmp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// using relative paths for source and userinclude directories

// No explicit capabilities required to run this.

TARGET        LeaveOnFail.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        LeaveOnFail.cpp

USERINCLUDE   .
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib

CAPABILITY    None

// BLD.INF
// Component description file 
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

PRJ_MMPFILES

LeaveOnFail.mmp


Description

As with the ErrorOnFail example, this example also attempts to construct an object, however on failure it simply leaves.

This example shows use of the TRAPD macro, the cleanup stack and its functions PushL(), PopAndDestroy() and the process of leaving. It also uses the heap debugging macro __UHEAP_SETFAIL.


Classes used


Security issues

The example requires no specific capabilities in order to run - and does not demonstrate any security issues.

[Top]


ELeaveOnFail: cleanup, TRAPD and leaving

Example code

Found in: examples\Base\MemMan\Cleanup\ELeaveOnFail

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

// ELeaveOnFail.cpp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// Example shows attempt to construct an object and specifying
// (ELeave) after the 'new' operator. 
// Specifying (ELeave) causes a leave on failure to allocate memory 
// for the new object. 

// NOTE: the structure of this example is different to standard E32 examples


#include <e32cons.h>

//
// Common format text
//

_LIT(KCommonFormat1,"Value of iInt is %d.\n");


  // All messages written to this
LOCAL_D CConsoleBase* console;
  
  // Flag which determines whether the doSomething() member function
  // of the CExample class should leave when called.
LOCAL_D TBool leaveFlag = ETrue;

  // Parameter for __UHEAP_SETFAIL
  // Allocation guaranteed to fail at this number of allocation attempts;
  // i.e. if set to n, allocation fails on the nth attempt. 
  // NB only used in debug mode
#ifdef _DEBUG
LOCAL_D TInt allocFailNumber = 1;
#endif
  
  // Function prototypes
LOCAL_C void doExampleL();      
LOCAL_C void callExampleL();



//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (definition)
//
// The class is used by the example code
//
//////////////////////////////////////////////////////////////////////////////
class CExample : public CBase
    {
public :
    void DoSomethingL();
public :
    TInt iInt;
    };


//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (implementation)
//
//////////////////////////////////////////////////////////////////////////////
void CExample::DoSomethingL() 
    {
      // Leave if the global flag is set
    if (leaveFlag)
        {
        _LIT(KMsgLeaving,"DoSomethingL leaving.\n");
        console->Printf(KMsgLeaving);
        User::Leave(KErrGeneral);       
        }
    console->Printf(KCommonFormat1,iInt);
    }

//////////////////////////////////////////////////////////////////////////////
//
// Main function called by E32
//
//////////////////////////////////////////////////////////////////////////////
GLDEF_C TInt E32Main()
    {
      // Get cleanup stack
    CTrapCleanup* cleanup=CTrapCleanup::New();

      // Some more initialization, then do the example
    TRAPD(error,callExampleL());
      
      // callExampleL() should never leave.
    _LIT(KMsgPanicEpoc32ex,"EPOC32EX");
    __ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));

      // destroy the cleanup stack
    delete cleanup;
    
      // return
    return 0;
    }


//////////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////////
LOCAL_C void callExampleL() 
    {
      // Initialize and call the example code under cleanup stack.
    _LIT(KMsgExampleCode,"Symbian OS Example Code");
    console = Console::NewL(KMsgExampleCode,TSize(KConsFullScreen,KConsFullScreen));
      // Put console onto the cleanup stack.
    CleanupStack::PushL(console);

      // Perform the example function under the protection of a 
      // TRAP harness.
    TRAPD(error,doExampleL());
    _LIT(KMsgOK,"ok");
    _LIT(KFormat2,"failed: leave code = %d");
    if (error)
        console->Printf(KFormat2,error);
    else
        console->Printf(KMsgOK);
      
      // Continue
    _LIT(KMsgPressAnyKey," [press any key]");
    console->Printf(KMsgPressAnyKey);
    console->Getch();

      // Remove the console object from the cleanupstack
      // and destroy it. 
    CleanupStack::PopAndDestroy();
    }


//////////////////////////////////////////////////////////////////////////////
//
// Do the example
//
//////////////////////////////////////////////////////////////////////////////
void doExampleL()
    {
      // Memory alloc fails on the 'allocFailNumber' attempt. 
      //
      // Note that if you set this to some low value sucah as 1 or 2, then as a side effect,
      // you may also see a dialog box stating "Not enough memory".
    __UHEAP_SETFAIL(RHeap::EDeterministic,allocFailNumber);
      // Allocate - leave if allocation fails.
      // The (ELeave) causes a leave if allocation fails; replaces
      // a call to User::LeaveIfNull(myExample);
      // Compare with the code in LeaveOnFailure
      //
      // Note that the memory allocation will fail and the "new" operation
      // will leave if allocFailNumber is 1.
    CExample* myExample = new (ELeave) CExample;
      // Do something with the CExample object
    myExample->iInt = 5;
      //
    console->Printf(KCommonFormat1,myExample->iInt);
      // Delete the CExample object
    delete myExample;
    }

// ELeaveOnFail.mmp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// using relative paths for source and userinclude directories

// No explicit capabilities required to run this.


TARGET        ELeaveOnFail.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        ELeaveOnFail.cpp

USERINCLUDE   .
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib

CAPABILITY    None

// BLD.INF
// Component description file 
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

PRJ_MMPFILES

ELeaveOnFail.mmp


Description

This example attempts to construct an object using the overloaded new operator new (ELeave). Specifying (ELeave) will cause a leave to occur if it was unable to allocate memory for the new object.

This example shows use of the TRAPD macro, the cleanup stack and its functions PushL(), PopAndDestroy() and the process of leaving. It also uses the heap debugging macro __UHEAP_SETFAIL.


Classes used


Security issues

The example requires no specific capabilities in order to run - and does not demonstrate any security issues.

[Top]


TrapD: cleanup, TRAPD and leaving

Example code

Found in: examples\Base\MemMan\Cleanup\TrapD

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// Example shows creation and use of of an object protected by a TRAPD

// NOTE: the structure of this example is different to standard E32 examples


#include <e32cons.h>

  // All messages written to this
LOCAL_D CConsoleBase* console;
  
  // Flag which determines whether the doSomething() member function
  // of the CExample class should leave when called.
LOCAL_D TBool leaveFlag = ETrue;

  // Parameter for __UHEAP_SETFAIL
  // Allocation guaranteed to fail at this number of allocation attempts;
  // i.e. if set to n, allocation fails on the nth attempt. 
  // NB only used in debug mode
#ifdef _DEBUG
LOCAL_D TInt allocFailNumber = 1;
#endif
  
  // Function prototypes
LOCAL_C void doExampleL();      
LOCAL_C void callExampleL();



//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (definition)
//
// The class is used by the example code
//
//////////////////////////////////////////////////////////////////////////////
class CExample : public CBase
    {
public :
    void DoSomethingL();
public :
    TInt iInt;
    };


//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (implementation)
//
//////////////////////////////////////////////////////////////////////////////
void CExample::DoSomethingL() 
    {
      // Leave if the global flag is set
    if (leaveFlag)
        {
        _LIT(KMsgLeaving,"DoSomethingL leaving.\n");
        console->Printf(KMsgLeaving);
        User::Leave(KErrGeneral);       
        }
    _LIT(KFormat1,"Value of iInt is %d.\n");
    console->Printf(KFormat1,iInt);
    }

//////////////////////////////////////////////////////////////////////////////
//
// Main function called by E32
//
//////////////////////////////////////////////////////////////////////////////
GLDEF_C TInt E32Main()
    {
      // Get cleanup stack
    CTrapCleanup* cleanup=CTrapCleanup::New();

      // Some more initialization, then do the example
    TRAPD(error,callExampleL());
      
      // callExampleL() should never leave.
    _LIT(KMsgPanicEpoc32ex,"EPOC32EX");
    __ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));

      // destroy the cleanup stack
    delete cleanup;
    
      // return
    return 0;
    }


//////////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////////
LOCAL_C void callExampleL() 
    {
      // Initialize and call the example code under cleanup stack.
    _LIT(KMsgExampleCode,"Symbian OS Example Code");
    console = Console::NewL(KMsgExampleCode,TSize(KConsFullScreen,KConsFullScreen));
      // Put console onto the cleanup stack.
    CleanupStack::PushL(console);

      // Perform the example function under the protection of a 
      // TRAP harness.
    TRAPD(error,doExampleL());
    _LIT(KMsgOK,"ok");
    _LIT(KFormat2,"failed: leave code = %d");
    if (error)
        console->Printf(KFormat2,error);
    else
        console->Printf(KMsgOK);
      
      // Continue
    _LIT(KMsgPressAnyKey," [press any key]");
    console->Printf(KMsgPressAnyKey);
    console->Getch();

      // Remove the console object from the cleanupstack
      // and destroy it. 
    CleanupStack::PopAndDestroy();
    }


//////////////////////////////////////////////////////////////////////////////
//
// Do the example
//
// Create and use an instance of CExample, protected by TRAPD
//
//////////////////////////////////////////////////////////////////////////////
void doExampleL()
    {
      // Memory alloc fails on the 'allocFailNumber' attempt. 
    __UHEAP_SETFAIL(RHeap::EDeterministic,allocFailNumber);
      // Allocate - leave if allocation fails.
    CExample* myExample = new (ELeave) CExample;
      // Do something that cannot leave (no protection needed)
    myExample->iInt = 5;
      // Do something that can leave and trap the failure
    TRAPD(error,myExample->DoSomethingL());
      // Delete the CExample object
    delete myExample;
      // Now check whether DoSomethingL() left
    User::LeaveIfError(error);
    }

// TrapD.mmp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// using relative paths for source and userinclude directories

// No explicit capabilities required to run this.

TARGET        TrapD.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        TrapD.cpp

USERINCLUDE   .
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib

CAPABILITY    None

// BLD.INF
// Component description file 
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

PRJ_MMPFILES

TrapD.mmp


Description

The example shows the use of the TRAPD macro. It shows how a newly created object can be protected by the TRAPD macro.


Classes used


Security issues

The example requires no specific capabilities in order to run - and does not demonstrate any security issues.

[Top]


PushLAndPop: cleanup, TRAPD and leaving


Example code

Found in: examples\Base\MemMan\Cleanup\PushLAndPop

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

// PushLAndPop.cpp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// Example shows use of the cleanup stack fucntions PushL() and Pop()

// NOTE: the structure of this example is different to standard E32 examples


#include <e32cons.h>


  // All messages written to this
LOCAL_D CConsoleBase* console;
  
  // Flag which determines whether the doSomething() member function
  // of the CExample class should leave when called.
LOCAL_D TBool leaveFlag = ETrue;

  // Parameter for __UHEAP_SETFAIL
  // Allocation guaranteed to fail at this number of allocation attempts;
  // i.e. if set to n, allocation fails on the nth attempt. 
  // NB only used in debug mode
#ifdef _DEBUG
LOCAL_D TInt allocFailNumber = 1;
#endif
  
  // Function prototypes
LOCAL_C void doExampleL();      
LOCAL_C void callExampleL();



//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (definition)
//
// The class is used by the example code
//
//////////////////////////////////////////////////////////////////////////////
class CExample : public CBase
    {
public :
    void DoSomethingL();
public :
    TInt iInt;
    };


//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (implementation)
//
//////////////////////////////////////////////////////////////////////////////
void CExample::DoSomethingL() 
    {
      // Leave if the global flag is set
    if (leaveFlag)
        {
        _LIT(KMsgLeaving,"DoSomethingL leaving.\n");
        console->Printf(KMsgLeaving);
        User::Leave(KErrGeneral);       
        }
    _LIT(KFormat1,"Value of iInt is %d.\n");
    console->Printf(KFormat1,iInt);
    }

//////////////////////////////////////////////////////////////////////////////
//
// Main function called by E32
//
//////////////////////////////////////////////////////////////////////////////
GLDEF_C TInt E32Main()
    {
      // Get cleanup stack
    CTrapCleanup* cleanup=CTrapCleanup::New();

      // Some more initialization, then do the example
    TRAPD(error,callExampleL());
      
      // callExampleL() should never leave.
    _LIT(KMsgPanicEpoc32ex,"EPOC32EX");
    __ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));

      // destroy the cleanup stack
    delete cleanup;
    
      // return
    return 0;
    }


//////////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////////
LOCAL_C void callExampleL() 
    {
      // Initialize and call the example code under cleanup stack.
    _LIT(KMsgExampleCode,"Symbian OS Example Code");
    console = Console::NewL(KMsgExampleCode,TSize(KConsFullScreen,KConsFullScreen));
      // Put console onto the cleanup stack.
    CleanupStack::PushL(console);

      // Perform the example function under the protection of a 
      // TRAP harness.
    TRAPD(error,doExampleL());
    _LIT(KMsgOK,"ok");
    _LIT(KFormat2,"failed: leave code = %d");
    if (error)
        console->Printf(KFormat2,error);
    else
        console->Printf(KMsgOK);
      
      // Continue
    _LIT(KMsgPressAnyKey," [press any key]");
    console->Printf(KMsgPressAnyKey);
    console->Getch();

      // Remove the console object from the cleanupstack
      // and destroy it. 
    CleanupStack::PopAndDestroy();
    }


//////////////////////////////////////////////////////////////////////////////
//
// Do the example
//
// Surround something that might leave with a PushL() and a Pop()
// Compare this with the example: UsingPushLAndPopAndDestroy
//
//////////////////////////////////////////////////////////////////////////////
void doExampleL()
    {
      // Memory alloc fails on the 'allocFailNumber' attempt. 
    __UHEAP_SETFAIL(RHeap::EDeterministic,allocFailNumber);
      // Allocate - leave if allocation fails.
    CExample* myExample = new (ELeave) CExample;
      // Do something that cannot leave (no protection needed)
    myExample->iInt = 5;
      // Do something that can leave.
      // Use the cleanup stack - put the pointer to the CExample object on 
      // the cleanup stack
    CleanupStack::PushL(myExample);
      // This is something that might leave
    myExample->DoSomethingL();
      // It didn't leave, so pop the pointer off the stack
    CleanupStack::Pop();
      // Delete the CExample object
    delete myExample;
    }

// PushLAndPop.mmp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// using relative paths for source and userinclude directories

// No explicit capabilities required to run this.

TARGET        PushLAndPop.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        PushLAndPop.cpp

USERINCLUDE   .
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib

CAPABILITY    None

// BLD.INF
// Component description file 
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

PRJ_MMPFILES

PushLAndPop.mmp


Description

The example shows the use of the cleanup stack and its functions PushL() and Pop().

The example also uses the heap debugging macro __UHEAP_SETFAIL.


Classes used


Security issues

The example requires no specific capabilities in order to run - and does not demonstrate any security issues.

[Top]


PushLPopDest: cleanup, TRAPD and leaving

Found in: examples\Base\MemMan\Cleanup\PushLPopDest

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

// PushLPopDest.cpp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// Example shows use of the cleanup stack fucntions PushL()
// and PopAndDestroy().

// NOTE: the structure of this example is different to standard E32 examples


#include <e32cons.h>

  // All messages written to this
LOCAL_D CConsoleBase* console;
  
  // Flag which determines whether the doSomething() member function
  // of the CExample class should leave when called.
LOCAL_D TBool leaveFlag = ETrue;

  // Parameter for __UHEAP_SETFAIL
  // Allocation guaranteed to fail at this number of allocation attempts;
  // i.e. if set to n, allocation fails on the nth attempt. 
  // NB only used in debug mode
#ifdef _DEBUG
LOCAL_D TInt allocFailNumber = 1;
#endif
  
  // Function prototypes
LOCAL_C void doExampleL();      
LOCAL_C void callExampleL();



//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (definition)
//
// The class is used by the example code
//
//////////////////////////////////////////////////////////////////////////////
class CExample : public CBase
    {
public :
    void DoSomethingL();
public :
    TInt iInt;
    };


//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (implementation)
//
//////////////////////////////////////////////////////////////////////////////
void CExample::DoSomethingL() 
    {
      // Leave if the global flag is set
    if (leaveFlag)
        {
        _LIT(KMsgLeaving,"DoSomethingL leaving.\n");
        console->Printf(KMsgLeaving);
        User::Leave(KErrGeneral);       
        }
    _LIT(KFormat1,"Value of iInt is %d.\n");
    console->Printf(KFormat1,iInt);
    }

//////////////////////////////////////////////////////////////////////////////
//
// Main function called by E32
//
//////////////////////////////////////////////////////////////////////////////
GLDEF_C TInt E32Main()
    {
      // Get cleanup stack
    CTrapCleanup* cleanup=CTrapCleanup::New();

      // Some more initialization, then do the example
    TRAPD(error,callExampleL());
      
      // callExampleL() should never leave.
    _LIT(KMsgPanicEpoc32ex,"EPOC32EX");
    __ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));

      // destroy the cleanup stack
    delete cleanup;
    
      // return
    return 0;
    }


//////////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////////
LOCAL_C void callExampleL() 
    {
      // Initialize and call the example code under cleanup stack.
    _LIT(KMsgExampleCode,"Symbian OS Example Code");
    console = Console::NewL(KMsgExampleCode,TSize(KConsFullScreen,KConsFullScreen));
      // Put console onto the cleanup stack.
    CleanupStack::PushL(console);

      // Perform the example function under the protection of a 
      // TRAP harness.
    TRAPD(error,doExampleL());
    _LIT(KMsgOK,"ok");
    _LIT(KFormat2,"failed: leave code = %d");
    if (error)
        console->Printf(KFormat2,error);
    else
        console->Printf(KMsgOK);
      
      // Continue
    _LIT(KMsgPressAnyKey," [press any key]");
    console->Printf(KMsgPressAnyKey);
    console->Getch();

      // Remove the console object from the cleanupstack
      // and destroy it. 
    CleanupStack::PopAndDestroy();
    }


//////////////////////////////////////////////////////////////////////////////
//
// Do the example
//
// Surround something that might leave with a PushL() and a PopAndDestroy()
// Compare this with the example: EUCLNA5
//
//////////////////////////////////////////////////////////////////////////////
void doExampleL()
    {
      // Memory alloc fails on the 'allocFailNumber' attempt. 
    __UHEAP_SETFAIL(RHeap::EDeterministic,allocFailNumber);
      // Allocate - leave if allocation fails.
    CExample* myExample = new (ELeave) CExample;
      // Do something that cannot leave (no protection needed)
    myExample->iInt = 5;
      // Do something that can leave.
      // Use the cleanup stack - put the pointer to the CExample 
      // object on the cleanup stack
    CleanupStack::PushL(myExample);
      // This is something that might leave
    myExample->DoSomethingL();
      // It didn't leave, so pop the pointer off the stack and
      // delete the CExample object in one operation
      // (Equivalent to: CleanupStack::Pop();
      //                 delete myExample;
      // in example UsingPushLAndPop)
    CleanupStack::PopAndDestroy();
    }

// PushLPopDest.mmp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// using relative paths for source and userinclude directories

// No explicit capabilities required to run this.

TARGET        PushLPopDest.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        PushLPopDest.cpp

USERINCLUDE   .
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib

CAPABILITY    None

// BLD.INF
// Component description file
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

PRJ_MMPFILES

PushLPopDest.mmp


Description

The example shows the use of the cleanup stack and its functions PushL() and PopAndDestroy().

The example also uses the heap debugging macro __UHEAP_SETFAIL.


Classes used


Security issues

The example requires no specific capabilities in order to run - and does not demonstrate any security issues.

[Top]


NewL: cleanup, TRAPD and leaving

Example code

Found in: examples\Base\MemMan\Cleanup\NewL

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

// NewL.cpp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// NOTE: the structure of this example is different to standard E32 examples

#include <e32cons.h>

  // All messages written to this
LOCAL_D CConsoleBase* console;
  
  // Flag which determines whether the doSomething() member function
  // of the CExample class should leave when called.
LOCAL_D TBool leaveFlag = ETrue;

  // Parameter for __UHEAP_SETFAIL
  // Allocation guaranteed to fail at this number of allocation attempts;
  // i.e. if set to n, allocation fails on the nth attempt. 
  // NB only used in debug mode
#ifdef _DEBUG
LOCAL_D TInt allocFailNumber = 1;
#endif
  
  // Function prototypes
LOCAL_C void doExampleL();      
LOCAL_C void callExampleL();



//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (definition)
//
// The class is used by the example code
//
//////////////////////////////////////////////////////////////////////////////
class CExample : public CBase
    {
public :
    static CExample* NewL(TInt aVal);
    void DoSomethingL();
public :
    TInt iInt;
    };


//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (implementation)
//
//////////////////////////////////////////////////////////////////////////////
CExample* CExample::NewL(TInt aVal)
    {
    CExample* self = new (ELeave) CExample;
    self->iInt = aVal;
    return self;
    }


void CExample::DoSomethingL() 
    {
      // Leave if the global flag is set
    if (leaveFlag)
        {
        _LIT(KMsgLeaving,"DoSomethingL leaving.\n");
        console->Printf(KMsgLeaving);
        User::Leave(KErrGeneral);       
        }
    _LIT(KFormat1,"Value of iInt is %d.\n");
    console->Printf(KFormat1,iInt);
    }

//////////////////////////////////////////////////////////////////////////////
//
// Main function called by E32
//
//////////////////////////////////////////////////////////////////////////////
GLDEF_C TInt E32Main()
    {
      // Get cleanup stack
    CTrapCleanup* cleanup=CTrapCleanup::New();

      // Some more initialization, then do the example
    TRAPD(error,callExampleL());
      
      // callExampleL() should never leave.
    _LIT(KMsgPanicEpoc32ex,"EPOC32EX");
    __ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));

      // destroy the cleanup stack
    delete cleanup;
    
      // return
    return 0;
    }


//////////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////////
LOCAL_C void callExampleL() 
    {
      // Initialize and call the example code under cleanup stack.
    _LIT(KMsgExampleCode,"Symbian OS Example Code");
    console = Console::NewL(KMsgExampleCode,TSize(KConsFullScreen,KConsFullScreen));
      // Put console onto the cleanup stack.
    CleanupStack::PushL(console);

      // Perform the example function under the protection of a 
      // TRAP harness.
    TRAPD(error,doExampleL());
    _LIT(KMsgOK,"ok");
    _LIT(KFormat2,"failed: leave code = %d");
    if (error)
        console->Printf(KFormat2,error);
    else
        console->Printf(KMsgOK);
      
      // Continue
    _LIT(KMsgPressAnyKey," [press any key]");
    console->Printf(KMsgPressAnyKey);
    console->Getch();

      // Remove the console object from the cleanupstack
      // and destroy it. 
    CleanupStack::PopAndDestroy();
    }


//////////////////////////////////////////////////////////////////////////////
//
// Do the example
//
// Example includes a NewL() function of the CExample class which may leave
//
//////////////////////////////////////////////////////////////////////////////
void doExampleL()
    {
      // Memory alloc fails on the 'allocFailNumber' attempt. 
    __UHEAP_SETFAIL(RHeap::EDeterministic,allocFailNumber);
      // Allocate - leave if allocation fails.
    CExample* myExample = CExample::NewL(5);
      // Push onto the cleanup stack, if successful
    CleanupStack::PushL(myExample);
      // Do something that can leave.
    myExample->DoSomethingL();
      // Pop from the cleanup stack and destroy
    CleanupStack::PopAndDestroy();
    }

// NewL.mmp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// using relative paths for source and userinclude directories

// No explicit capabilities required to run this.

TARGET        NewL.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        NewL.cpp

USERINCLUDE   .
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib

CAPABILITY    None

// BLD.INF
// Component description file
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

PRJ_MMPFILES

NewL.mmp


Description

The example shows use of the NewL() static function.

The example also uses the heap debugging macro __UHEAP_SETFAIL.


Classes used


Security issues

The example requires no specific capabilities in order to run - and does not demonstrate any security issues.

[Top]


NewLC: cleanup, TRAPD and leaving

Found in: examples\Base\MemMan\Cleanup\NewLC

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

// NewLC.cpp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// Example shows use of the NewLC() static function.

// NOTE: the structure of this example is different to standard E32 examples


#include <e32cons.h>

  // All messages written to this
LOCAL_D CConsoleBase* console;
  
  // Flag which determines whether the doSomething() member function
  // of the CExample class should leave when called.
LOCAL_D TBool leaveFlag = ETrue;

  // Parameter for __UHEAP_SETFAIL
  // Allocation guaranteed to fail at this number of allocation attempts;
  // i.e. if set to n, allocation fails on the nth attempt. 
  // NB only used in debug mode
#ifdef _DEBUG
LOCAL_D TInt allocFailNumber = 1;
#endif
  
  // Function prototypes
LOCAL_C void doExampleL();      
LOCAL_C void callExampleL();



//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (definition)
//
// The class is used by the example code
//
//////////////////////////////////////////////////////////////////////////////
class CExample : public CBase
    {
public :
    static CExample* NewLC(TInt aVal);
    void DoSomethingL();
public :
    TInt iInt;
    };


//////////////////////////////////////////////////////////////////////////////
//
// -----> CExample (implementation)
//
//////////////////////////////////////////////////////////////////////////////
CExample* CExample::NewLC(TInt aVal)
    {
    CExample* self = new (ELeave) CExample;
    CleanupStack::PushL(self);
    self->iInt = aVal;
    return self;
    }


void CExample::DoSomethingL() 
    {
      // Leave if the global flag is set
    if (leaveFlag)
        {
        _LIT(KMsgLeaving,"DoSomethingL leaving.\n");
        console->Printf(KMsgLeaving);
        User::Leave(KErrGeneral);       
        }
    _LIT(KFormat1,"Value of iInt is %d.\n");
    console->Printf(KFormat1,iInt);
    }

//////////////////////////////////////////////////////////////////////////////
//
// Main function called by E32
//
//////////////////////////////////////////////////////////////////////////////
GLDEF_C TInt E32Main()
    {
      // Get cleanup stack
    CTrapCleanup* cleanup=CTrapCleanup::New();

      // Some more initialization, then do the example
    TRAPD(error,callExampleL());
      
      // callExampleL() should never leave.
    _LIT(KMsgPanicEpoc32ex,"EPOC32EX");
    __ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));

      // destroy the cleanup stack
    delete cleanup;
    
      // return
    return 0;
    }


//////////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////////
LOCAL_C void callExampleL() 
    {
      // Initialize and call the example code under cleanup stack.
    _LIT(KMsgExampleCode,"Symbian OS Example Code");
    console = Console::NewL(KMsgExampleCode,TSize(KConsFullScreen,KConsFullScreen));
      // Put console onto the cleanup stack.
    CleanupStack::PushL(console);

      // Perform the example function under the protection of a 
      // TRAP harness.
    TRAPD(error,doExampleL());
    _LIT(KMsgOK,"ok");
    _LIT(KFormat2,"failed: leave code = %d");
    if (error)
        console->Printf(KFormat2,error);
    else
        console->Printf(KMsgOK);
      
      // Continue
    _LIT(KMsgPressAnyKey," [press any key]");
    console->Printf(KMsgPressAnyKey);
    console->Getch();

      // Remove the console object from the cleanupstack
      // and destroy it. 
    CleanupStack::PopAndDestroy();
    }


//////////////////////////////////////////////////////////////////////////////
//
// Do the example
//
// Enriched example UsingNewL by using NewLC() instead of NewL().
// The function NewLC() both allocates a CExample object and pushes
// the object onto the cleanup stack
//
//////////////////////////////////////////////////////////////////////////////
void doExampleL()
    {
      // Memory alloc fails on the 'allocFailNumber' attempt. 
    __UHEAP_SETFAIL(RHeap::EDeterministic,allocFailNumber);
      // Allocate and push onto the cleanup stack - leave if 
      // allocation fails.
    CExample* myExample = CExample::NewLC(5);
      // Do something that can leave.
    myExample->DoSomethingL();
      // Pop from the cleanup stack and destroy
    CleanupStack::PopAndDestroy();
    }

// NewLC.mmp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// using relative paths for source and userinclude directories

// No explicit capabilities required to run this.

TARGET        NewLC.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        NewLC.cpp

USERINCLUDE   .
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib

CAPABILITY    None

// BLD.INF
// Component description file
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

PRJ_MMPFILES

NewLC.mmp


Description

The example shows use of the NewLC() static function.

The example also uses the heap debugging macro __UHEAP_SETFAIL.


Classes used


Security issues

The example requires no specific capabilities in order to run - and does not demonstrate any security issues.

[Top]


SimpleOOM—cleaning up compound classes

Example

Found in: examples\Base\MemMan\Cleanup\SimpleOOM

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

// SimpleOOM.cpp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// Example checks the robustness of a simple class on Out Of Memory (OOM)
 
// NOTE: the structure of this example is different to standard E32 examples


#include <e32cons.h>



  // All messages written to this
LOCAL_D CConsoleBase* console;
  
  // Function prototypes
LOCAL_C void doExampleL();      
LOCAL_C void callExampleL();


//////////////////////////////////////////////////////////////////////////////
//
// -----> CSimple (definition)
//
//////////////////////////////////////////////////////////////////////////////
class CSimple : public CBase
      {
public :
    static CSimple* NewL(TInt aVal);
    static CSimple* NewLC(TInt aVal);
    void   Display();
protected: 
    CSimple(TInt aVal);
public: 
    TInt   iVal;
    };


//////////////////////////////////////////////////////////////////////////////
//
// -----> CSimple (implementation)
//
//////////////////////////////////////////////////////////////////////////////
CSimple* CSimple::NewL(TInt aVal) 
    {
      // NB The NewL function uses the C++ constructor mechanism.
    CSimple* self=new (ELeave) CSimple(aVal);
    return self;
    }

                
CSimple* CSimple::NewLC(TInt aVal)
    {
      // NewLC is enriched with a push to the cleanup stack
    CSimple* self=NewL(aVal);     
    CleanupStack::PushL(self);
    return self;
    }

                
void CSimple::Display() 
    {
      // Display class data member on the console.
    _LIT(KFormat1,"Value=%d.\n");
    console->Printf(KFormat1,iVal);
    }
 
CSimple::CSimple(TInt aVal) 
    : iVal(aVal)
    {}


//////////////////////////////////////////////////////////////////////////////
//
// Main function called by E32
//
//////////////////////////////////////////////////////////////////////////////
GLDEF_C TInt E32Main()
    {
      // Get cleanup stack
    CTrapCleanup* cleanup=CTrapCleanup::New();

      // Some more initialization, then do the example
    TRAPD(error,callExampleL());
      
      // callExampleL() should never leave.
    _LIT(KMsgPanicEpoc32ex,"EPOC32EX");
    __ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));

      // destroy the cleanup stack
    delete cleanup;
    
      // return
    return 0;
    }


//////////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////////
LOCAL_C void callExampleL() 
    {
      // Initialize and call the example code under cleanup stack.
    _LIT(KMsgExampleCode,"Symbian OS Example Code");
    console = Console::NewL(KMsgExampleCode,TSize(KConsFullScreen,KConsFullScreen));
      // Put console onto the cleanup stack.
    CleanupStack::PushL(console);

      // Mark for alloc heaven tool
    __UHEAP_MARK;              

      // Perform the example function under the protection of a 
      // TRAP harness.
    TRAPD(error,doExampleL());
    
      // Test the example for alloc heaven
      __UHEAP_MARKEND;

      // 
    _LIT(KMsgOK,"ok");
    _LIT(KFormat2,"Overall example Trap Harness failed: leave code=%d");
    if (error)
        console->Printf(KFormat2, error);
    else
        console->Printf(KMsgOK);
      
      // Continue
    _LIT(KMsgPressAnyKey," [press any key]");
    console->Printf(KMsgPressAnyKey);
    console->Getch();

      // Remove the console object from the cleanupstack
      // and destroy it. 
    CleanupStack::PopAndDestroy();
    }


//////////////////////////////////////////////////////////////////////////////
//
// Do the example
//
// Example checks the robustness of class on OOM
//////////////////////////////////////////////////////////////////////////////
void doExampleL()
    {
      // Start up the allocation failure tool to fail 
      // in the third cycle (arg=3 as there is 1 new
      // per cycle)
    __UHEAP_SETFAIL(RHeap::EDeterministic,3);
    
    for(TInt ii=1;ii<4;ii++)
        {
          // Display status information
        _LIT(KFormat3,"Cycle %d.\n");
        console->Printf(KFormat3,ii);
          // Create new instance
        CSimple* mySimpleExample = CSimple::NewL(2);
          // Display the instance
        mySimpleExample->Display();
          // Destroy the instance
        delete mySimpleExample;
        }
    }

// SimpleOOM.mmp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// using relative paths for source and userinclude directories

// No explicit capabilities required to run this.

TARGET        SimpleOOM.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        SimpleOOM.cpp

USERINCLUDE   .
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib

CAPABILITY    None

// BLD.INF
// Component description file
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

PRJ_MMPFILES

SimpleOOM.mmp


Description

This example shows cleanup handling for compound classes. The robustness of a simple class on Out Of Memory (OOM) is tested.


Classes used


Security issues

The example requires no specific capabilities in order to run - and does not demonstrate any security issues.

[Top]


MemLeakOOM: cleaning up compound classes

Example Code

Found in: examples\Base\MemMan\Cleanup\MemLeakOOM

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

// MemLeakOOM.cpp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.
//
// NOTE: the structure of this example is different to standard E32 examples


#include <e32cons.h>

  // All messages written to this
LOCAL_D CConsoleBase* console;
  
  // Function prototypes
LOCAL_C void doExampleL();      
LOCAL_C void callExampleL();


//////////////////////////////////////////////////////////////////////////////
//
// -----> CSimple (definition)
//
//////////////////////////////////////////////////////////////////////////////
class CSimple : public CBase
      {
public :
    static CSimple* NewL(TInt aVal);
    static CSimple* NewLC(TInt aVal);
    void   Display();
protected: 
    CSimple(TInt aVal);
public: 
    TInt   iVal;
    };


//////////////////////////////////////////////////////////////////////////////
//
// -----> CCompound (definition)
//
//////////////////////////////////////////////////////////////////////////////
class CCompound : public CBase
      {
public :
    virtual  ~CCompound();
    void     Display();
    static   CCompound* NewL(TInt aRoot,TInt aChild);
    static   CCompound* NewLC(TInt aRoot,TInt aChild);
private:
    TInt     iRoot;
    CSimple* iChild;
protected:
    CCompound(TInt aRoot,TInt aChild);
    };

//////////////////////////////////////////////////////////////////////////////
//
// -----> CCompound (implementation)
//
//////////////////////////////////////////////////////////////////////////////

                // A one stage construction technique
                // using the C++ constructor mechanism
CCompound* CCompound::NewL(TInt aRoot,TInt aChild)
   {         
      // Allocate and construct object; leave if allocation fails
    CCompound* self=new (ELeave) CCompound(aRoot,aChild);
    return self;
    }

CCompound* CCompound::NewLC(TInt aRoot,TInt aChild) 
    {
    CCompound* self=NewL(aRoot,aChild);    
    CleanupStack::PushL(self);
    return self;
    }

CCompound::CCompound(TInt aRoot,TInt aChild)
    {
    iRoot = aRoot;
   iChild = CSimple::NewL(aChild);     
            // problem:if this line leaves, memory 
            // leak (orphan) will result
    iChild->iVal = aChild;
    }
                
void CCompound::Display() 
    {
      // Display class member data on the console
    _LIT(KFormat4,"Root=%d. Child=%d.\n");
    console->Printf(KFormat4,iRoot,iChild->iVal);
    }
                
CCompound::~CCompound() 
    {
    _LIT(KMsgDestCCompound,"Destructing CCompound\n");
    console->Printf(KMsgDestCCompound);
    delete iChild;
    }


//////////////////////////////////////////////////////////////////////////////
//
// -----> CSimple (implementation)
//
//////////////////////////////////////////////////////////////////////////////
CSimple* CSimple::NewL(TInt aVal) 
    {
      // NB The NewL function uses the C++ constructor mechanism.
    CSimple* self=new (ELeave) CSimple(aVal);
    return self;
    }

                
CSimple* CSimple::NewLC(TInt aVal)
    {
      // NewLC is enriched with a push to the cleanup stack
    CSimple* self=NewL(aVal);     
    CleanupStack::PushL(self);
    return self;
    }

                
void CSimple::Display() 
    {
      // Display class data member on the console.
    _LIT(KFormat1,"Value=%d.\n");
    console->Printf(KFormat1,iVal);
    }
 
CSimple::CSimple(TInt aVal) 
    : iVal(aVal)
    {}


//////////////////////////////////////////////////////////////////////////////
//
// Main function called by E32
//
//////////////////////////////////////////////////////////////////////////////
GLDEF_C TInt E32Main()
    {
      // Get cleanup stack
    CTrapCleanup* cleanup=CTrapCleanup::New();

      // Some more initialization, then do the example
    TRAPD(error,callExampleL());
      
      // callExampleL() should never leave.
    _LIT(KMsgPanicEpoc32ex,"EPOC32EX");
    __ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));

      // destroy the cleanup stack
    delete cleanup;
    
      // return
    return 0;
    }


//////////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////////
LOCAL_C void callExampleL() 
    {
      // Initialize and call the example code under cleanup stack.
    _LIT(KMsgExampleCode,"Symbian OS Example Code");
    console = Console::NewL(KMsgExampleCode,TSize(KConsFullScreen,KConsFullScreen));
      // Put console onto the cleanup stack.
    CleanupStack::PushL(console);

      // Mark for alloc heaven tool
    __UHEAP_MARK;              

      // Perform the example function under the protection of a 
      // TRAP harness.
    TRAPD(error,doExampleL());
    
      // Test the example for alloc heaven
      __UHEAP_MARKEND;

      // 
    _LIT(KMsgOK,"ok");
    _LIT(KFormat2,"Overall example Trap Harness failed: leave code=%d");
    if (error)
        console->Printf(KFormat2, error);
    else
        console->Printf(KMsgOK);
      
      // Continue
    _LIT(KMsgPressAnyKey," [press any key]");
    console->Printf(KMsgPressAnyKey);
    console->Getch();

      // Remove the console object from the cleanupstack
      // and destroy it. 
    CleanupStack::PopAndDestroy();
    }


//////////////////////////////////////////////////////////////////////////////
//
// Do the example
//
// Example to check robustness of class on OOM and attempt to provoke
// memory leaks (orphans).
//////////////////////////////////////////////////////////////////////////////
void doExampleL()
    {
    #if defined(_DEBUG)  //only ever used in debug mode
    TInt failValue = 5;
    #endif

      // Startup the alloc failure tool to fail in the third cycle.
      // To test for alloc heaven:
      //
      // An even value for 'failValue' should provoke memory leak,
      // an odd value should not.
    __UHEAP_SETFAIL(RHeap::EDeterministic,failValue);
    
    for(TInt ii=1;ii<4;ii++)
        {
          // Display status information
        _LIT(KFormat3,"Cycle %d.\n");
         console->Printf(KFormat3,ii);
          // Create new instance 
        CCompound* myCompoundExample = CCompound::NewL(1,2);
          // Display the instance
        myCompoundExample->Display();
          // Destroy the instance
        delete myCompoundExample;
        } 
    }

// MemLeakOOM.mmp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// using relative paths for source and userinclude directories

// No explicit capabilities required to run this.


TARGET        MemLeakOOM.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        MemLeakOOM.cpp

USERINCLUDE   .
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib

CAPABILITY    None

// BLD.INF
// Component description file
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

PRJ_MMPFILES

MemLeakOOM.mmp


Description

This example shows cleanup handling for compound classes. The robustness of a compound class on Out Of Memory (OOM) is tested. It also shows how memory leaks can occur.


Classes used


Security issues

The example requires no specific capabilities in order to run - and does not demonstrate any security issues.

[Top]


TwoPhaseOOM: cleaning up compound classes

Found in: examples\Base\MemMan\Cleanup\TwoPhaseOOM

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

// TwoPhaseOOM.cpp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.
//
// NOTE: the structure of this example is different to standard E32 examples


#include <e32cons.h>

  // All messages written to this
LOCAL_D CConsoleBase* console;
  
  // Function prototypes
LOCAL_C void doExampleL();      
LOCAL_C void callExampleL();


//////////////////////////////////////////////////////////////////////////////
//
// -----> CSimple (definition)
//
//////////////////////////////////////////////////////////////////////////////
class CSimple : public CBase
      {
public :
    static CSimple* NewL(TInt aVal);
    static CSimple* NewLC(TInt aVal);
    void   Display();
protected: 
    CSimple(TInt aVal);
public: 
    TInt   iVal;
    };


//////////////////////////////////////////////////////////////////////////////
//
// -----> CCompound (definition)
//
//////////////////////////////////////////////////////////////////////////////
class CCompound : public CBase
      {
public :
    virtual  ~CCompound();
    void     Display();
    static   CCompound* NewL(TInt aRoot,TInt aChild);
    static   CCompound* NewLC(TInt aRoot,TInt aChild);
private:
    void     ConstructL(TInt aRoot,TInt aChild);
private:
    TInt     iRoot;
    CSimple* iChild;
    };

//////////////////////////////////////////////////////////////////////////////
//
// -----> CCompound (implementation)
//
//////////////////////////////////////////////////////////////////////////////

                // Use two stage construction technique to 
                // prevent alloc heaven.
                // NB. due to use of cleanup stack, NewLC is
                // now the primitive, rather than NewL

                // NewLC with two stage construct
CCompound* CCompound::NewLC(TInt aRoot,TInt aChild) 
        {       // get new, leave if can't  
        CCompound* self=new (ELeave) CCompound;
        CleanupStack::PushL(self);
                // push onto cleanup stack (in 
                // case self->ConstructL leaves).
                // Use two-stage construct
       self->ConstructL(aRoot,aChild);
        return self;
        }
                // version of NewLC which leaves 
                // nothing on the cleanup stack
CCompound* CCompound::NewL(TInt aRoot,TInt aChild) 
        {
        CCompound* self=NewLC(aRoot,aChild);
        CleanupStack::Pop();
        return self;
        }
                // NB. function may leave, 
                // as CSimple::NewL may leave
void CCompound::ConstructL(TInt aRoot,TInt aChild) 
        {
        iRoot = aRoot;
        iChild = CSimple::NewL(aChild);    
        iChild->iVal = aChild;
        }               

void CCompound::Display() 
    {
      // Display class member data on the console
    _LIT(KFormat4,"Root=%d. Child=%d.\n");
    console->Printf(KFormat4,iRoot,iChild->iVal);
    }
                
CCompound::~CCompound() 
    {
    _LIT(KMsgDestCCompound,"Destructing CCompound\n");
    console->Printf(KMsgDestCCompound);
    delete iChild;
    }


//////////////////////////////////////////////////////////////////////////////
//
// -----> CSimple (implementation)
//
//////////////////////////////////////////////////////////////////////////////
CSimple* CSimple::NewL(TInt aVal) 
    {
      // NB The NewL function uses the C++ constructor mechanism.
    CSimple* self=new (ELeave) CSimple(aVal);
    return self;
    }

                
CSimple* CSimple::NewLC(TInt aVal)
    {
      // NewLC is enriched with a push to the cleanup stack
    CSimple* self=NewL(aVal);     
    CleanupStack::PushL(self);
    return self;
    }

                
void CSimple::Display() 
    {
      // Display class data member on the console.
    _LIT(KFormat1,"Value=%d.\n");
    console->Printf(KFormat1,iVal);
    }
 
CSimple::CSimple(TInt aVal) 
    : iVal(aVal)
    {}


//////////////////////////////////////////////////////////////////////////////
//
// Main function called by E32
//
//////////////////////////////////////////////////////////////////////////////
GLDEF_C TInt E32Main()
    {
      // Get cleanup stack
    CTrapCleanup* cleanup=CTrapCleanup::New();

      // Some more initialization, then do the example
    TRAPD(error,callExampleL());
      
      // callExampleL() should never leave.
    _LIT(KMsgPanicEpoc32ex,"EPOC32EX");
    __ASSERT_ALWAYS(!error,User::Panic(KMsgPanicEpoc32ex,error));

      // destroy the cleanup stack
    delete cleanup;
    
      // return
    return 0;
    }


//////////////////////////////////////////////////////////////////////////////
//
//
//
//////////////////////////////////////////////////////////////////////////////
LOCAL_C void callExampleL() 
    {
      // Initialize and call the example code under cleanup stack.
    _LIT(KMsgExampleCode,"Symbian OS Example Code");
    console = Console::NewL(KMsgExampleCode,TSize(KConsFullScreen,KConsFullScreen));
      // Put console onto the cleanup stack.
    CleanupStack::PushL(console);

      // Mark for alloc heaven tool
    __UHEAP_MARK;              

      // Perform the example function under the protection of a 
      // TRAP harness.
    TRAPD(error,doExampleL());
    
      // Test the example for alloc heaven
      __UHEAP_MARKEND;

      // 
    _LIT(KMsgOK,"ok");
    _LIT(KFormat2,"Overall example Trap Harness failed: leave code=%d");
    if (error)
        console->Printf(KFormat2, error);
    else
        console->Printf(KMsgOK);
      
      // Continue
    _LIT(KMsgPressAnyKey," [press any key]");
    console->Printf(KMsgPressAnyKey);
    console->Getch();

      // Remove the console object from the cleanupstack
      // and destroy it. 
    CleanupStack::PopAndDestroy();
    }


//////////////////////////////////////////////////////////////////////////////
//
// Do the example
//
// Example to check robustness of class on OOM and attempt to provoke
// memory leaks (orphans).
//////////////////////////////////////////////////////////////////////////////
void doExampleL()
    {
    #if defined(_DEBUG)  //only ever used in debug mode
    TInt failValue = 5;
    #endif

      // Startup the alloc failure tool to fail in the third cycle.
      // To test for alloc heaven:
      //
      // An even value for 'failValue' should provoke memory leak,
      // an odd value should not.
    __UHEAP_SETFAIL(RHeap::EDeterministic,failValue);
    
    for(TInt ii=1;ii<4;ii++)
        {
          // Display status information
        _LIT(KFormat3,"Cycle %d.\n");
         console->Printf(KFormat3,ii);
          // Create new instance 
        CCompound* myCompoundExample = CCompound::NewL(1,2);
          // Display the instance
        myCompoundExample->Display();
          // Destroy the instance
        delete myCompoundExample;
        } 
    }

// TwoPhaseOOM.mmp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// using relative paths for source and userinclude directories

// No explicit capabilities required to run this.

TARGET        TwoPhaseOOM.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        TwoPhaseOOM.cpp

USERINCLUDE   .
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib

CAPABILITY    None

// BLD.INF
// Component description file
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

PRJ_MMPFILES

TwoPhaseOOM.mmp


Description

These examples show cleanup handling for compound classes. The robustness of a compound class on Out Of Memory (OOM) is tested. It also shows the use of the two phase construction technique.


Classes used


Security issues

The example requires no specific capabilities in order to run - and does not demonstrate any security issues.

[Top]


TAnyRObjects1: cleaning up TAny* and R type objects

Example code

Found in: examples\Base\MemMan\Cleanup\TAnyRObjects1

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

// TAnyRObjects1.cpp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// AIM: To provide examples for the documentation of exceptions & traps
// Situation3 - examples of cleanup-stack support for TAny* and RItems


#include "CommonFramework.h"

// Name of file to be used
_LIT(KFileName,"TAnyandRObjects1.dat");

// Test data to be put into the file.
_LIT(KTestData,"Test data for TAnyandRObjects1\n");

// #include specific files
#include <f32file.h>
#include "euhexdmp.h"


//////////////////////////////////////////////////////////////////////////////
//
// ----->  RFileWithCleanup(definition)
//
// Function Cleanup() and operator TCleanupItem() needed to provide 
// Cleanup Stack for RFile
//
//////////////////////////////////////////////////////////////////////////////
class RFileWithCleanup : public RFile
    {
private:
    static void Cleanup(TAny *aPtr);
public:
    operator TCleanupItem();
    };


//////////////////////////////////////////////////////////////////////////////
//
// ----->  RFileWithCleanup(implementation)
//
//////////////////////////////////////////////////////////////////////////////
void RFileWithCleanup::Cleanup(TAny *aPtr)
    {
    _LIT(KMsgDoingCleanup,"Doing cleanup of file.\n");
    console->Printf(KMsgDoingCleanup);                       
      // Invoke the Close member on the RItem at aPtr
    ((RFileWithCleanup *)aPtr)->Close();
    }

RFileWithCleanup::operator TCleanupItem()
    {
    return TCleanupItem(Cleanup,this);
    }

LOCAL_C void createDataFileL()
    {
      // utility function to create some data which we can later read
    RFs createFileSession;
    RFileWithCleanup createFile;

      // connect to filserver session     
    User::LeaveIfError(createFileSession.Connect());

      // create the private directory
      // on drive C:
      // i.e. C:\private\0FFFFF01\
      // Note that the number 0FFFFF01 is the 
      // process security id taken from the 2nd UID
      // specified in the mmp file.
    createFileSession.CreatePrivatePath(EDriveC);
    
      // Set the session path to
      // this private directory on drive C:
    createFileSession.SetSessionToPrivate(EDriveC);

      // create TAnyandRObjects1.dat and open for writing
    User::LeaveIfError(createFile.Replace(createFileSession,
                                          KFileName,
                                          EFileWrite|EFileStreamText));

      // Note that Write() requires a TDesC8
      // type so we need to construct an explicit
      // TDesC8 type to represent the data contained
      // in the standard (16-bit) descriptor.
    TPtrC8 representation((TUint8*)(&KTestData)->Ptr(), (&KTestData)->Size());


      // write and commit text
    User::LeaveIfError(createFile.Write(representation));
    User::LeaveIfError(createFile.Flush());
    _LIT(KMsgDataWritten,"Data written to file\n");
    console->Printf(KMsgDataWritten);

      // close file and session
      // (NB. no LeaveIfError due to RFile.close and 
      // RFs.close guaranteed to complete)
    createFile.Close();                       // close file
    createFileSession.Close();                   // close file server session
    }

void useBufferL(TPtr8& bufferPtr)
    {
    printBuffer(0,bufferPtr);
      // Remove following comment to force a leave
      // while using the buffer
    //User::Leave(KErrGeneral);
    }


LOCAL_C void doExampleL()
    {
                // create the datafile for the example
    createDataFileL();

                // create a simple buffer. In real code, you
                // would probably use an HBufC*, or an RBuf.
                // You could also use a TBuf on the stack if it's small.
    TText8* buffer=(TText8*) User::Alloc(100*sizeof(TText8));
                
                // push it to the cleanup stack: treated as TAny*
    CleanupStack::PushL(buffer);

                // create a pointer to the buffer
    TPtr8 bufferPtr(buffer,100); 
    
                // the file session to be used
    RFs fsSession;
    _LIT(KMsgOpeningSession,"Opening session\n");
    console->Printf(KMsgOpeningSession);

                // open the file-server session
    User::LeaveIfError(fsSession.Connect());

                // the file instance myFile
    RFileWithCleanup myFile;
    _LIT(KMsgOpeningFile,"Opening file\n");
    console->Printf(KMsgOpeningFile);

                // open the file
    User::LeaveIfError(myFile.Open(fsSession,KFileName,EFileStreamText|EFileRead));

                // push the file instance to the cleanup stack
    CleanupStack::PushL(myFile);          

                // read stuff from the file to the buffer (may leave)
    _LIT(KMsgReadingFile,"Reading file into buffer.\n");
    console->Printf(KMsgReadingFile);
    User::LeaveIfError(myFile.Read(bufferPtr));

      // Remove following comment to force a leave
      // while using the file
    //User::Leave(KErrGeneral);

                // destroy the file on the cleanup stack
    CleanupStack::PopAndDestroy();      

    fsSession.Close();

                // use the buffer
    useBufferL(bufferPtr);

                // destroy the buffer on the cleanup stack
    CleanupStack::PopAndDestroy();      
    }

// TAnyRObjects1.mmp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// using relative paths for source and userinclude directories

// No explicit capabilities required to run this.

// Please note that the 2nd UID listed here has not been
// allocated from the central pool of UI's and is not 
// guaranteed to be unique.
// The value is used for demonstration purposes only.
//

TARGET        TAnyRObjects1.exe
TARGETTYPE    exe
UID           0 0x0FFFFF01
VENDORID      0x70000001

SOURCEPATH    .
SOURCE        TAnyRObjects1.cpp

USERINCLUDE   .
USERINCLUDE   ..\..\..\CommonFramework
USERINCLUDE   ..\HeaderFile
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib efsrv.lib

CAPABILITY    None

// BLD.INF
// Component description file
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

PRJ_MMPFILES

TAnyRObjects1.mmp


Description

The example shows how cleanup can be implemented for TAny* type objects and 'R' type (resource type) objects.

This example shows the use of TAny* cleanup type, for pushing a buffer to the cleanup stack. The buffer data is read from a file.

Class RFileWithCleanup is derived from class RFile, to show how to add cleanup support to a general R class.

This example adds cleanup support to the RFile.


Classes used


Security issues

The example writes files to the executable's process private directory: C:\private\0FFFFF01\.

The second UID in the .mmp file is defined as 0x0FFFFF01 and this is used as the secure ID on which the name of the private directory is based.

[Top]


TAnyRObjects2: cleaning up TAny* and R type objects

Example code

Found in: examples\Base\MemMan\Cleanup\TAnyRObjects2

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

/ TAnyRObjects2.cpp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// AIM: To provide examples for the documentation of exceptions & traps
// Situation3 - examples of cleanup-stack support for TAny* and RItems


#include "CommonFramework.h"

// Name of file to be used
_LIT(KFileName,"TAnyandRObjects2.dat");

// Test data to be put into the file.
_LIT(KTestData,"Test data for TAnyandRObjects2\n");

// #include specific files
#include <f32file.h>
#include "euhexdmp.h"


//////////////////////////////////////////////////////////////////////////////
//
// ----->  RFileWithCleanup(definition)
//
// Function Cleanup() and operator TCleanupItem() needed to provide 
// Cleanup Stack for RFile
//
//////////////////////////////////////////////////////////////////////////////
class RFileWithCleanup : public RFile
    {
private:
    static void Cleanup(TAny *aPtr);
public:
    operator TCleanupItem();
public:
    void OpenL(RFs &aFs,const TDesC &aName,TUint aMode);
    void OpenLC(RFs &aFs,const TDesC &aName,TUint aMode);
    };


//////////////////////////////////////////////////////////////////////////////
//
// ----->  RFileWithCleanup(implementation)
//
//////////////////////////////////////////////////////////////////////////////
void RFileWithCleanup::Cleanup(TAny *aPtr)
    {
    _LIT(KMsgDoingCleanup,"Doing cleanup of file.\n");
    console->Printf(KMsgDoingCleanup);                       
      // Invoke the Close member on the RItem at aPtr
    ((RFileWithCleanup *)aPtr)->Close();
    }

RFileWithCleanup::operator TCleanupItem()
    {
    return TCleanupItem(Cleanup,this);
    }

void RFileWithCleanup::OpenL(RFs &aFs,const TDesC &aName,TUint aMode)
    {
    User::LeaveIfError(RFile::Open(aFs,aName,aMode));
    }

void RFileWithCleanup::OpenLC(RFs &aFs,const TDesC &aName,TUint aMode)
    {
    OpenL(aFs,aName,aMode);
    CleanupStack::PushL(*this); // NB. 'this' would have been a TAny*
    }

LOCAL_C void createDataFileL()
    {
      // utility function to create some data which we can later read
    RFs createFileSession;
    RFileWithCleanup createFile;

      // connect to filserver session     
    User::LeaveIfError(createFileSession.Connect());


      // create the private directory
      // on drive C:
      // i.e. C:\private\0FFFFF01\
      // Note that the number 0FFFFF01 is the 
      // process security id taken from the 2nd UID
      // specified in the mmp file.
    createFileSession.CreatePrivatePath(EDriveC);
    
      // Set the session path to
      // this private directory on drive C:
    createFileSession.SetSessionToPrivate(EDriveC);

      // create TAnyandRObjects2.dat and open for writing
    User::LeaveIfError(createFile.Replace(createFileSession,
                                          KFileName,
                                          EFileWrite|EFileStreamText));

      // Note that Write() requires a TDesC8
      // type so we need to construct an explicit
      // TDesC8 type to represent the data contained
      // in the standard (16-bit) descriptor.
    TPtrC8 representation((TUint8*)(&KTestData)->Ptr(), (&KTestData)->Size());

      // write and commit text
    User::LeaveIfError(createFile.Write(representation));
    User::LeaveIfError(createFile.Flush());
    _LIT(KMsgDataWritten,"Data written to file\n");
    console->Printf(KMsgDataWritten);

      // close file and session
      // (NB. no LeaveIfError due to RFile.close and 
      // RFs.close guaranteed to complete)
    createFile.Close();                       // close file
    createFileSession.Close();                   // close file server session
    }

void useBufferL(TPtr8& bufferPtr)
    {
    printBuffer(0,bufferPtr);
      // Remove following comment to force a leave
      // while using the buffer
    //User::Leave(KErrGeneral);
    }


LOCAL_C void doExampleL()
    {
                // create the datafile for the example
    createDataFileL();
            
                // create a simple buffer. In real code, you
                // would probably use an HBufC*, or an RBuf.
                // You could also use a TBuf on the stack if it's small.
    TText8* buffer=(TText8*) User::Alloc(100*sizeof(TText8));

                // push it to the cleanup stack: treated as TAny*
    CleanupStack::PushL(buffer);
    
                // create a pointer to the buffer
    TPtr8 bufferPtr(buffer,100);
    
                // the file session to be used
    RFs fsSession;
    _LIT(KMsgOpeningSession,"Opening session\n");
    console->Printf(KMsgOpeningSession);
    
                // open the file-server session
    User::LeaveIfError(fsSession.Connect());
    
                // the file instance myFile
    RFileWithCleanup myFile;
    _LIT(KMsgOpeningFile,"Opening file\n");
    console->Printf(KMsgOpeningFile);
    
            // open the file (and leave on cleanup stack)
    myFile.OpenLC(fsSession,KFileName,EFileStreamText|EFileRead);   
    
                // read stuff from the file to the buffer (may leave)
    _LIT(KMsgReadingFile,"Reading file into buffer.\n");
    console->Printf(KMsgReadingFile);
    User::LeaveIfError(myFile.Read(bufferPtr));
      // Remove following comment to force a leave
      // while using the file
    //User::Leave(KErrGeneral);

                // destroy the file on the cleanup stack
    CleanupStack::PopAndDestroy();      

    fsSession.Close();

                // use the buffer
    useBufferL(bufferPtr);
                // destroy the buffer on the cleanup stack
    CleanupStack::PopAndDestroy();      
    }

// TAnyRObjects2.mmp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// using relative paths for source and userinclude directories

// No explicit capabilities required to run this.

// Please note that the 2nd UID listed here has not been
// allocated from the central pool of UI's and is not 
// guaranteed to be unique.
// The value is used for demonstration purposes only.
//

TARGET        TAnyRObjects2.exe
TARGETTYPE    exe
UID           0 0x0FFFFF02 
VENDORID      0x70000001

SOURCEPATH    .
SOURCE        TAnyRObjects2.cpp

USERINCLUDE   .
USERINCLUDE   ..\..\..\CommonFramework
USERINCLUDE   ..\HeaderFile
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib efsrv.lib

CAPABILITY    None

// BLD.INF
// Component description file
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

PRJ_MMPFILES

TAnyRObjects2.mmp


Description

The example shows how cleanup can be implemented for TAny* type objects and 'R' type (resource type) objects.

This example is similar to the TAnyRObjects1 example. However, it enhances the interface to include an OpenLC() which opens the file, and pushes it on to the cleanup stack in one function call.


Classes used


Security issues

The example writes files to the executable's process private directory: C:\private\0FFFFF02\.

The second UID in the .mmp file is defined as 0x0FFFFF02 and this is used as the secure ID on which the name of the private directory is based.

[Top]


Utilities: cleanup utilities

Example code

Found in: examples\Base\MemMan\Cleanup\Utilities

The files reproduced here are the main files contained in the examples directory. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

 Utilities.cpp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

#include "CommonFramework.h"

//
// Definition of the CTestOne class
//
class CTestOne : public CBase
    {   
public:
    ~CTestOne();
    void     SetTextL(const TDesC& aData);
private :
    HBufC*   iText;
    };


//
// Implementation of the CTestOne class
//
_LIT(KTxtInsideDestructor,"Executing the CTestOne destructor\n");
CTestOne::~CTestOne()
    {
    delete iText;
    console->Printf(KTxtInsideDestructor);
    }

void CTestOne::SetTextL(const TDesC& aData)
    {
    if (iText)
        {
        delete iText;
        iText = NULL;
        }
    iText = aData.AllocL();   
    }



//
// Definition of the RTestTwo class
//
class RTestTwo
    {   
public:
    RTestTwo(TInt aValue);
    void     Close();
private :
    TInt     iX;
    };

//
// Implementation of the RTestTwo class
//
RTestTwo::RTestTwo(TInt aValue)
    : iX(aValue)
    {
    }


_LIT(KTxtCloseRTestTwo,"RTestTwo closing\n");

void RTestTwo::Close()
    {
    console->Printf(KTxtCloseRTestTwo);
    }



//
// Definition of the RTestThree class
//
class RTestThree
    {   
public:
    RTestThree(TInt aValue);
    void     Release();
private :
    TInt     iY;
    };

//
// Implementation of the RTestThree class
//
RTestThree::RTestThree(TInt aValue)
    : iY(aValue)
    {
    }


_LIT(KTxtReleaseRTestThree,"RTestThree releasing\n");

void RTestThree::Release()
    {
    console->Printf(KTxtReleaseRTestThree);
    }

//
// main body of the example
//
_LIT(KTxtHelloWorld,"Hello World!");
LOCAL_C void doExampleL()
    {
        // 1. Construct a CTestOne object on the heap
    CTestOne* one = new (ELeave) CTestOne;
    
        // Use the CleanupDeletePushL() function to put a TCleanUpItem
        // on the cleanup stack
    CleanupDeletePushL(one);

        // Exercise the CTestOne object (just to show it doing something)
    one->SetTextL(KTxtHelloWorld);

        // Pop and destroy the cleanup item off the cleanup stack.
        // The cleanup operation deletes the CTestOne object
    CleanupStack::PopAndDestroy();
    
        // 2. Construct a RTestTwo object on the program stack.
        //
        // The value passed is of no significance; it is just
        // to show that the class is not trivial.
    RTestTwo  two(2);
        
        // Use the CleanupClosePushL() function to put a TCleanUpItem
        // on the cleanup stack
    CleanupClosePushL(two);

        // Pop and destroy the cleanup item off the cleanup stack.
        // The cleanup operation calls the Close() member function of
        // the RTestTwo object
    CleanupStack::PopAndDestroy();
                

        // 3. Construct a RTestThree object on the program stack.
        //
        // The value passed is of no significance; it is just
        // to show that the class is not trivial.
    RTestThree  three(3);
        
        // Use the CleanupClosePushL() function to put a TCleanUpItem
        // on the cleanup stack
    CleanupReleasePushL(three);

        // Pop and destroy the cleanup item off the cleanup stack.
        // The cleanup operation calls the Release() member function of
        // the RTestThree object
    CleanupStack::PopAndDestroy();

        // 4. Construct an array of objects on the heap
    TInt heapSize1 = User::Heap().Count(); // take a count of the heap size now
    
    const TInt KNumObjects = 4;
    const TInt KStringLength = 10;
    TBuf<KStringLength>* four = new (ELeave) TBuf<KStringLength>[KNumObjects];
        // Use the CleanupArrayDeletePushL() function to put a TCleanUpItem
        // on the cleanup stack
    CleanupArrayDeletePushL(four);

        // Do something that might leave - a simple memory allocation
    TAny* mem = User::Alloc(100);
    delete mem;

        // Pop and destroy the cleanup item off the cleanup stack.
        // The cleanup operation deletes the CTestOne object
    CleanupStack::PopAndDestroy();
    if ( User::Heap().Count() == heapSize1 )
        {
        _LIT(KFourComplete,"Array deleted\n");
        console->Printf(KFourComplete);
        }
    }

// Utilities.mmp
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

// using relative paths for source and userinclude directories

// No explicit capabilities required to run this.

TARGET        Utilities.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        Utilities.cpp

USERINCLUDE   .
USERINCLUDE   ..\..\..\CommonFramework
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib

CAPABILITY    None

// BLD.INF
// Component description file
//
// Copyright (C) Symbian Software Ltd 2000-2005.  All rights reserved.

PRJ_MMPFILES

Utilities.mmp


Description

This example shows how the cleanup utilities (the templated functions CleanupDeletePushL(), CleanupClosePushL() and CleanupReleasePushL(), and CleanupArrayDeletePushL()) can be used.


Classes used

In addition to the templated functions:

the examples implicitly use the templated classes:


Security issues

The example requires no specific capabilities in order to run - and does not demonstrate any security issues.