Pointer Descriptors TPtr and TPtrC 1
Use to reference data stored elsewhere Usage example - porting from legacy code:
const unsigned char KBuffer[] =
{0x00, 0x33, 0x66, 0x99, Oxbk., Oxff}; TPtrC8 bufferPtr(KBuffer, sizeof ( KBuff er) ) ; // send data via connected TCP/IP socket iSo ck.e t. Write (hiufferPt r, iStatus) ;
Memory illustration (TPtrC8):
descriptor
descriptor
|
<5 |
Oxl115C532 |
|
r length |
data address |
constant data
constant data
|
OX |
OK |
Ox |
Ox |
Ox |
Ox | |
|
00 |
33 |
66 |
99 |
Refers to data stored elsewhere that is not owned by the descriptor. Using a TPtr or TPtrC to access a string is much safer than maintaining pointers to zero-terminated C strings. TPtrC TPtrC is derived from TDesc and only provides additional methods to associate the pointer with the constant data buffer. No methods to reset or modify the data are provided. See the descriptors overview section for example usage of a TPtrc. TPtr TPtr is derived from TDes and provides additional methods to associate the pointer with the data buffer, set the maximum length, and copy new data into the referenced buffer (overwriting the old data). Here is an example: _LIT(KHelloWorld, "Hello World"); TBufC<maxBuf> buf; buf = KHelloWorld; // set the contents TPtr ptr = buf.Des(); // obtain a pointer to the buffer ptr[7] = 'a'; // Change the 'o' to an 'a' CEikonEnv::Static()->InfoMsg(ptr); // The buffer now holds "Hello Wales" Heap Descriptors: HBufC
This encapsulates data stored on the heap that is owned by the descriptor. The data is allocated dynamically and so the maximum length of this descriptor can be set and changed at run-time by reallocating the heap buffer. HBufc is based on TDesc and provides methods to change the size of the data stored (HBufC::ReAlloc() and HBufc::ReAllocL()) and an assignment operator to set the contents of the data (subject to the maximum length not being exceeded). The contents can be modified by using HBufc::Des() to obtain a modifiable pointer descriptor. HBufcs are commonly used in the scenarios where the length of a returned string does not need to be known by the caller: • Loading strings from a resource file at run-time. • Getting strings from UI elements, for example query dialogs. • Getting strings from application engines, for example names from the contacts database. Modifying HBufCs Modifying HBufCs _LIT(KHello, "Hello!"); _LIT (KWorld, "World!"); HBufC* heapBuf = HBufC: : NewL (KHello (). Length ()) ; *heapBuf = KHello; // But holds "Hello!" // Increase heap buffer size - will still hold "Hello!" heapBuf = heapBuf->ReAllocL (KHello () . Length () + KWorld () . Length () ) ; CleanupStack: :EushL (heapBuf); // Don't use: TPtr ptr = heapBuf->Des(); This will set // max length to 6 and not 12 so code below will panic TPtr ptr (heapBuf->Des () ) ; ptr [KHello () . Length () - 1] = ' ' ; // Buf holds "Hello " ptr += KJJorld; // Buf holds "Hello World!" iTopLabel->SetTeiitL (ptr) ; // Set screen label CleanupStack.: : PopAndDest roy () ; // ptr not valid now NOKIA The example on the slide illustrates how HBufcs can be modified and also expanded in size. A HBufc is initially created to be 6 (Unicode) characters long and to contain the string "Hello!". Remember that HBufcs can have their data set and reset, but not modified directly by the HBufc APIs. The next section of the code reallocates the heap buffer so that it is 12 Unicode characters long. The ReAllocL() function copies the existing "Hello!" data into the newly reallocated buffer and sets the length to 6. It also deletes the previous heap buffer. The heap buffer is then put on the cleanup stack so that if the following code leaves there will not be a memory leak. HBufc::Des() is used to get a pointer descriptor which is used to modify the contents of the heap buffer. Note that the TPtr(const TPtr& aTPtr) constructor overload is used to pass in the TPtr returned from HBufc::Des(). This will copy the contents of the heap buffer into the pointer descriptor, set the length to 6 and the max length to 12. By contrast, if TPtr ptr = heapBuf->Des(); were used, the max length of the newly declared TPtr would be 6. This would cause the ptr+= KWorld; statement to panic since the max length would be exceeded. If the heap buffer was reallocated in the future, the pointer descriptor should be updated by calling: Once the pointer descriptor is constructed on the slide, it can be used to modify the heap buffer string. Individual characters can be modified - '!' is changed to a space above. The slide also shows an example of a string being appended onto the current string. The contents of the heap buffer are displayed on the screen (this assumes the program is a GUI application). The function cEikLabel::SetTextL(const TDesc& aText) is called to update the text of a label that is stored in a member variable. The TPtr passed in is implicitly cast down to a TDesc (a base class) which is the parameter type expected. Finally the heap buffer is deleted by calling cleanupstack::PopAndDestroy() .After this is called, the pointer descriptor's data is no longer valid (since it still points to the now deleted heap buffer data). The call to ccoeControl::DrawNow() requests that the screen is updated. |
Post a comment