Contents |
EUserHL stands for User High Level library. This library introduces the L classes’ idioms. This new idiom provides a clear indication of the new leaving behavior of these classes. The package still contains a set of template classes that provides automatic resource management and some macros that easy single phase construction and leave launch. In the EUserHL package you will find:
The L prefix denotes that construction, copying, passing and returning by value, assignment and manipulation via operators should all be considered potentially leaving operations unless otherwise explicitly documented. So, this means that all the code that manipulates L instances MUST be leave-safe. To be able to create leave-safe code the programmer will need to set up the cleanup stack the calling thread and use the L class within the scope of a TRAP statement. The main characteristics of L classes are:
Also, they are as simple to use as T classes. So they can be used as built-in types. The main difference is that they own resources that are managed automatically, so the programmer doesn’t need to care about then.
The library is available here
In this package you will find:
The installation is quite simple. You will need to choose in which SDK you will install the package (can be installed in multiples SDKs). The library is compatible with Symbian v9.1 onwards. The installation procedure basically unpacks some files to the SDK folder:
LString is a general-purpose class for string manipulation. It inherits from RBuf class and adds cleanup and on-demand resize of the allocated memory. This class, as a RBuf type, can be passed as argument of functions that accept TDes and TDesC references types.
LString string;
addDatatoString(string);
…
void addDatatoString(TDes& aDes)
{
aDes.Append(_L(“Data”)); //this will PANIC
}
This happens because LString default constructor sets the buffer to zero (0) size. The programmer is responsible for ensuring the size of the buffer is enough to fit the data. To do this the API provides the ReserveFreeCapacityL() function. This function must be called when you cannot use any of the auto-buffer extending LString methods to achieve your objective. This often happens inside functions that receives a TDes& as parameter.
LString string;//zero size
string.ReserveFreeCapacityL(4);
addDatatoString(string);
…
void addDatatoString(TDes& aDes)
{
aDes.Append(_L(“Data”)); //OK!
}
Code without LString:
{
HBufC* queryc =
HBufC::NewLC(KTooBigForStackMaxQuery);
TPtr query(queryc->Des());
BuildQueryL(query);
ExecuteQueryL(query);
CleanupStack::PopAndDestroy();
}
Code WITH LString:
{
LString query;
BuildQueryL(query);
ExecuteQueryL(query);
}
The common cases of construction of the LString can be seen bellow.
{
// A default constructed LString starts empty, doesn't allocate any memory
// on the heap, and therefore the following cannot leave
LString s;
// You can initialize with a MaxLength value
LString s(KMaxFileName); // This operation may leave
// You can initialize from any descriptor (or literal) and the
// string data is copied into the LString
LString s(L"One "); // From a literal
LString half(s.Left(s.Length() / 2)); // Left returns a TPtrC
// On the other hand, you can initialize from a returned
// HBufC* and the LString automatically takes ownership
LString own(AllocateNameL(L"Testing "));
// LStrings can be allocated on the heap if necessary
LString* s = new(ELeave) LString;
}
LCleanedupX are templated classes that avoid explicit calls to cleanup stack funcions automatically cleaning local objects in case of leaves or scope exit. This kind of class put the object in the cleanup stack automatically. The provided LCleanedupX classes and their use are shown bellow:
// Create an HBufC and leave it on the cleanup stack
HBufC* buf = HBufC::NewLC(5);
LCleanedupHandle<RFile> file; //putting file onto the cleanupstack
. . . // Do something with the file and the descriptor
// Cleanup the buffer
CleanupStack::PopAndDestroy(buf); // PANIC! – The LCleanedupHandle item comes off the stack first!
// If a badly-behaved API were to offer only an LC variant, you would have to use it as follows
HBufC* raw = HBufC::NewLC(5);
// Must pop immediately to balance the cleanup stack, before instantiating the manager
CleanupStack::Pop();
LCleanedupPtr<HBufC> wrapped(raw);
// Never do this:
// LCleanedupPtr<HBufC> buf(HBufC::NewLC(5));
// CleanupStack::Pop();
// because the manager will be popped (having been pushed last), not the raw buf pointer as you might have hoped
1) Code increase: 104 bytes
//Without
RFs fs;
// use fs
fs.Close();
//-------------------------
//With
LCleanedupHandle<RFs> fs;
// use fs
2) Code increase: 90 bytes
//Without
HBufC* buf = HBufC::NewL(10);
// use buf
delete buf;
//----------------------------
//With
LCleanedupPtr<HBufC>
buf(HBufC::NewL(10));
// use buf
Bellow you'll see more example of the basic usage of the LCleanedupX classes.
{
// Trivially exercise the manager using classes defined above
CTicker* ticker1 = new(ELeave) CTicker;
LCleanedupPtr<CManagedUserTwoPhase> one(CManagedUserTwoPhase::NewL(ticker1));
CTicker* ticker2 = new(ELeave) CTicker;
LCleanedupPtr<CManagedUserSinglePhase> two(CManagedUserSinglePhase::NewL(ticker2));
// Both instances are automatically deleted as we go out of scope
}
No related wiki articles found