Click here to Skip to main content
15,881,803 members
Articles / Mobile Apps / Windows Mobile

Using Symbain OS String Descriptors

Rate me:
Please Sign up or sign in to vote.
3.90/5 (8 votes)
1 Mar 2005CPOL5 min read 45.1K   22   3
This article shows startup usage of Symbian OS descriptors.

Introduction

When I was new to Symbian, The first thing I encountered was Symbian OS String handling and manipulations. It was then days of nightmare that struck me :). What I found was that it's a bit tricky to remember the descriptor stuffs, but once you get the trick it’s easy. No, I am not kidding..

So here I am trying to explain how I learned the basic Symbian OS string handling and tried to remember the things. I will not go into a war of words regarding whether having descriptors is a good approach or not, because whether it is good or bad you have to use it :(. Another thing I will not discuss here is how you can do similar things using plain C++ or how to do something with plain C++ string manipulation techniques. This article is just about descriptors.

The prerequisite of this article is a working knowledge of the Symbian OS.

Background

The very first thing you need to do is to remember the descriptor hierarchy. This is very important as all of the five descriptors you are going to use are derived from some classes and you must know from which class they are derived to be able to successfully decide which particular descriptor should be used and in which scenario. I am not going to explain what a buffer descriptor and Heap Descriptor mean, and also what is meant by modifiable and non modifiable descriptors. I believe you must be having enough information about what is meant by the above terminologies. I will also not use 8 and 16 bit variants, as functionality wise there is a similarity between these two and also these are not important in understanding the descriptors. The Symbian Descriptor Hierarchy looks fabulous. (Sorry for not providing fabulous pictures of Descriptor hierarchy). You can have a look at newlc for pictures.

Usage of TPtrC<n>

If you want a literal meaning for this, then it is a "Pointer to a data that cannot be manipulated". The basic thing to remember about TPtrC<n> is that it contains no manipulation functionalities of its own and that it just contains constructors and set methods, and since it is derived directly from TDesC it contains all the functionalities of TDesC.

The pointer will point to data in one of the two ways:

  • Create an empty TPtrC<N> and then point it to some data using Set(...) functions.
  • Pass the data while constructing by using any one of the overloaded constructors.

Let's see the above statements with the help of a few examples given below:

  • Example 1:- Getting TPtrC from TBuf and TBufC :
    LIT(KText , "Test Code");
    TBufC<10> Buf ( KText ); OR(/) TBuf<10> Buf ( KText );
    // Creation of TPtr using Constructor
    TPtrC    Ptr (Buf);
    // Creation of TPtr using Member Function
    TPtrC    Ptr1;
    Ptr1.Set(Buf);
  • Example 2:- Getting TPtrC from TText*:

    The example below uses TText16:

    TText * text = _S("Hello World\n");
    TPtrC ptr(text);
    // OR
    TPtrC Ptr1;
    Ptr1.Set(text);
    // To store only a part of TText we can use the following 
    // This descriptor pointer will store only Hello
    TPtrC   ptr4 ( text , 5 );
  • Example 3:- Getting TPtrC from another TPtrC:

    You can easily assign one TPtrC to another.

    TText * text = _S("Hello World\n");
    TPtrC ptr(text);
    // Get TPtrC from another TPtrC
    TPtrC p1(ptr);
    // OR
    TPtrC p2;
    p2.Set(ptr);
  • Example 4:- Getting TText * from TPtrC:

    We can get the TText * from TPtrC by using the Ptr() member.

    // Set the TPtrC
    _LIT(KText , "Test Code");
    TBufC<10> Buf ( KText ); 
    TPtrC    Ptr1 (Buf);
    // Get the TText *
    TText * Text1 = (TText *)Ptr1.Ptr();

Usage of TBufC<n>

The examples used to describe the working TPtrC gives some understanding about the usage of TBufC<n>, Nevertheless here are a few examples on how to create TBufC<n>.

  • Example 5:- Instantiating the TBufC<N>:
    // Instantiating the TBufC from Literals
    _LIT(Ktext, "TestText");
    TBufC<10> Buf (Ktext);
    // or
    TBufC<10> Buf2;
    Buf2 = Ktext;
    // Creating a new TBufC with existing TBufC
    TBufC<10> Buf3(Buf2);

    TBufC<n> is used generally for text data. For binary data, explicit TBufC8<n> is used. Though TBufC<n> means that the data cannot be modified ('C' stands for Constant), there are two ways by which this data can be modified:

    • The data can be replaced by using assignment operator.
    • By using Des() function to construct a TPtr modifiable pointer descriptor for the buffer data.

    Let's see the first way to change the contents of TBufC<n>.

  • Example 6:- Changing the contents of TBufC<N>:
    // Describe some literals for Testing example
    _LIT(Ktext , "Test Text");         
    _LIT(Ktext1 , "Test1Text");
    // Generate TPtrC
    TBufC<10> Buf1 ( Ktext );
    TBufC<10> Buf2 ( Ktext1 );
    // Change the contents of Buf2
    Buf2 = Buf1;
    // Create an Empty TBufC and assign it to Buf1
    TBufC<10> Buf3;
    Buf3 = Buf1;

    Another way of changing the contents of TBufC<n> is by using the Des() member. This member function returns TPtr modifiable pointer descriptor using members of the TPtr. The maximum length of the TPtr is the value of the TBufC<n> template parameter. All the manipulating functions are from TDesC base.

  • Example 7:- Changing the contents of TBufC<N> using Des():
    _LIT(Ktext , "Test Text");
    _LIT(KXtraText , "New:");
     
    TBufC<10> Buf1 ( Ktext );
    TPtr Pointer = Buf1.Des();
     
    // delete the last 4 characters 
    Pointer.Delete(Pointer.Length()-4, 4 );
     
    // the length should be changed now
    TInt Len = Pointer.Length();
     
    // Append the new one
    Pointer.Append(KXtraText);
     
    Len = Pointer.Length();
    // To completly changed the buffer we can use following
    _LIT(NewText , "New1");
    _LIT(NewText1 , "New2");
     
    TBufC<10> Buf2(NewText);
    // change the context
     
    Pointer.Copy(Buf2);
    // or Directly from literal
     
    Pointer.Copy(NewText1);
    // All the above changed actually changing the contents of Buf1

Working with Heap Descriptor HBufC

HBufC is the descriptor of choice when we don’t know the size of the data that we want to have in the descriptor. Here 'C' stands for constant that means the data is constant but it can also be changed in two ways as it was changed in the case of TBufC<n>. First using the assignment operator and another by using the modifiable pointer descriptor, i.e. TPtr using Des() member function. There are two things to remember while using the HBufC.

  • If you need to pass HBufC to a function that takes TDesC & as a parameter, you need to simply dereference the HBufC pointer.
  • The size of Heap Descriptor buffer can be changed using ReAlloc function as opposed to TBufC<N>.
  • Example 8:- Usage of HBufC:
    // Creation of a Heap Descriptor . There are 2 ways to do it
    // 1st way use either New(), NewL(), or NewLC()  
    // Let see the example for this. This wills construct the HBufC with
    // a Data space for 15, but the current size is Zero.
    HBufC * Buf = HBufC::NewL(15);
             
    // 2nd way to used the Alloc(), AllocL(), or AllocLC() of
    // the existing descriptors. The new Heap descriptor is automatically 
    // initialized with the content of descriptor.
    _LIT (KText , "Test Text");
    TBufC<10>  CBuf = KText;
    HBufC * Buf1 = CBuf.AllocL();
     
    // Lets Check the size and Length . The size will be 18 
    // and length will be 9 
    TInt BufSize = Buf->Size();
    TInt BufLength = Buf->Length();             
             
    // Changing what HBufC is pointing to 
    _LIT ( KText1 , "Text1");
    // Change the buffer to Point to KText1 using assignment operator
    *Buf1 = KText1;
             
    // And now changing the Data through Modifiable pointer descriptor
    TPtr Pointer = Buf1->Des();
    Pointer.Delete( Pointer.Length() - 2, 2 );
     
    // All operations that were done in case of TBufC<n> 
    // is applicable here also.
    // here is one such operation      
    _LIT ( KNew, "New:");
    Pointer.Append( KNew );

Usage of TPtr

Ahaa, we are using it in place of TBufC<N> and HBufC, so we know most of it. So let’s remember how we can create TPtr.

  • Another TPtr.
  • From TBufC<N>, HBufC using Des() member function.
  • From an explicit pointer to the memory and specifying the max length.
  • From an explicit pointer to the memory and specifying the data as well as the maximum length.
  • Example 9:- Usage of TPtr:
    // First lets see 2nd way of Getting TPtr
    _LIT(KText, "Test Data");
    TBufC<10> NBuf ( KText );
    TPtr     Pointer = NBuf.Des();
             
    // 1st way 
    TPtr     Pointer2 ( Pointer );
             
    //3rd way using a memory area , Data and max length 
    TText * Text = _S("Test Second");
    TPtr    Pointer3 ( Text ,11, 12);
             
    // Now we will see how to replace the data with TPtr ,it can 
    // be done completly by using assignment Operator or copy function
             
    _LIT(K1, "Text1");
    _LIT(K2, "Text2");
             
    Pointer2 = K1; // Data will be Text1
    Pointer.Copy(K2); // Data Will be Text2;
     
    // we can also change the length of the data or set it to zero
    Pointer2.SetLength(2); // Only Te will be there
    Pointer2.Zero(); // Make length of data as Zero 
     
    // Data can be altered using the delete function as it used to alter 
    // in the earlier examples.

Usage of TBuf<n>

In this the data doesn't remain constant. The operations, instantiation and assignment will be similar to that of the TBufC<n> along with the modification functions that can be applied to it as it was applied in the case of TPtr, like Copy, Delete, assignments etc.. I hope I don’t need to give examples for this section.

History

  • Latest update.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Architect
India India
A programmer by heart since 1998. Written code in C++, Java, JavaScript, Python & Ruby, Worked on Stack Development to Web Development. Data Specialist with SQL and NoSQL DBs

Comments and Discussions

 
Questionone confusiton about cleanup stack Pin
ankitapatel14-Apr-06 17:32
ankitapatel14-Apr-06 17:32 
AnswerRe: one confusiton about cleanup stack [modified] Pin
Symadept30-Aug-06 23:19
Symadept30-Aug-06 23:19 
Hi Ankita,
Cleanupstack helps you in getting control over the objects allocated dynamically by pushing the reference onto the stack which is always monitored by the system. Upon any discripancies it will unwind the memory allocated by the objects on the stack.

hence, you push the objects onto the stack which can create discripancies while invoking operations on them and upon them you can easily free them.

Ex:
X* lObj = new X;
CleanupStack::Push(lObj);
//Leaving stmts.
CleanupStack::PopAndDestroy();

Note: Keep the following points in mind.
Donot push
1) Stack variables.
2) Member variables.



All the best
Symadept
symadept@gmail.com


-- modified at 5:26 Thursday 31st August, 2006
GeneralSymbian OS Descriptor Resources Pin
Anonymous11-Jun-05 10:22
Anonymous11-Jun-05 10:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.