Introduction
Descriptors encapsulates strings and binary data to replace null strings in C. Its length and data are encapsulated in descriptors, and all of which are descriptors in the Symbian API. For example:
Tptrc PTR (khelloworld); ceikonenv: static ()-> infomsg (PTR );
Main Types of descriptors
It can be divided into the following categories, where C is unchangeable.
- Abstract: (TDES, tdesc), the base class of other descriptors, which cannot be instantiated and is generally used as a function parameter.
- Literal :( tlitc, _ encode (), used to store literal strings. The latter is generally used.
- Buffer :( tbuf, tbufc), data is stored on the stack, and the size is determined during compilation.
- Heap: (hbufc), data is stored on the heap, And the size is determined during running.
- Pointer :( tptr, tptrc), references data stored outside the class
Descriptor Modification
The descriptor can be changeable or unchangeable. Generally, the class with C cannot be modified, but the class with C can be modified.
- Moidfiable: provides APIs for accessing and modifying data, such as tbuf.
- Non-modifiable: data can only be accessed and cannot be modified. However, the des () function returns a modifiable pointer.
Descriptor width
The addition of 8 or 16 after the descriptor class affects the width of the data stored in the descriptor. The default value is 16 bits, and 8 bits are used for processing binary or ASCII data.
- 8-bit: (tdesc8), used for binary data or ASCII strings
- 16-bit: (tdesc16), default: Unicode
The following describes the five class descriptors in detail. First, let's take a look at the class inheritance relationship.
The display is 8 bits, and the default class inheritance relationship of 16 bits is consistent with this
Abstract Descriptors
The base classes of all descriptors except literal provide basic interfaces and basic functions. They cannot be instantiated and are generally used as function parameters.
Tdesc: provides functions for comparing, copying, searching, and extracting some strings.
Tint tdescutil: sumlengths (const tdesc & adesc1, const tdesc & adesc2)
{
Return adesc1.length () + adesc2.length ();
}
TDES: inherits from tdesc and adds many functions for modifying data. The maximum length is determined when the descriptor is created.
Tint tdescutil: appendl (tdesc & atarget, const tdesc & adesc)
{
Tint sumlen = atarget. Length () + adesc. Length ();
If (atarget. maxlength () <sumlen)
{
User: Leave (kerroverflow );
}
Atarget. appendl (adesc );
}
Literal Descriptors
Provides a mechanism to put strings in a read-only bucket (actually stored in the data zone of the program, rather than in the ROM ). Generally, _ random () macro is directly used instead of tlitc. _ Empty (khelloworld, "Hello world! ");
The const tdesc & can be obtained through the () operator &. Tint length = khelloworld (). Length ();
When the function parameter is const tdesc & you can use khelloworld directly. Ilabel-> settextl (khelloworld );
Buffer Descriptors
Store data as a part of the stack, and their maximum length is determined during compilation.
Tbuf <16> helloworld = khelloworld;
Tint Len = khelloworld (). Length ();
Helloworld [len-1] = '? ';
The memory is as follows:
The tbufc usage is as follows:
_ Partition (khelloworld, "Hello World ");
Const tint maxbuf = 32;
Tbufc <maxbuf> Buf;
Tint currentlen = Buf. Length (); // = 0
Buf = khelloworld;
Currentlen = Buf. Length (); // = 11
Ttext CH = Buf [2]; // = 'l'
The tbuf usage is as follows:
Const tint buflen = 6;
Tuint8 objtype = 1;
Tuint8 objid = 1;
Tuint8 xcoord = 128;
Tuint8 ycoord = 192;
....
Tbuf8 <buflen> Buf;
Buf. append (objtype );
Buf. append (objid );
...
// We can now do something with the buffer such as writting it to a binary file or send via socket.
Pointer Descriptor
Used to reference data stored elsewhere, for example:
Const unsigned char kbuffer [] = {0x00, 0x33, 0x66, 0x99, 0xbb, 0xff };
Tptrc8 bufferptr (kbuffer, sizeof (kbuffer ));
Isocket. Write (bufferptr, istatus );
The memory is as follows:
Tptr usage:
_ Partition (khelloworld, "Hello World ");
Const tint maxbuf = 32;
Tbufc <maxbuf> Buf;
Buf = khelloworld;
Tptr = Buf. Des ();
PTR [7] = 'a'; PTR [8] = 'l'; PTR [9] = 'E'; PTR [10] ='s ';
Ceikonenv: static ()-> infomsg (PTR); // "Hello Wales"
Heap Descriptors
Dynamically allocated on heap. data can be set and reset through hbufc APIs, but cannot be modified. For example:
Hbufc * heapbuf = hbufc: newl (khelloworld (). Length ());
* Heapbuf = khelloworld ();
Delete heapbuf;
Shows the memory usage:
Hbufc is generally used in the following scenarios:
- Load strings from the resource file at runtime
- Receives user input strings from the user interface
- Receives a string from the application engine, such as the name in contacts database.
Modify hbufc content:
_ Activities (khello, "Hello! ");
_ Empty (kworld, "World! ");
Hbufc * heapbuf = hbufc: newl (khello (). Length ());
* Heapbuf = khello; // Buf holds "Hello! "
Heapbuf = heapbuf-> reallocl (khello (). Length () + kworld (). Length ());
Cleanupstack: pushl (heapbuf );
Tptr (heapbuf-> des (); // don't use tptr = heapbuf-> des (); this will set maxlen to 6 but not 12...
PTR [khello (). Length ()-1] = '';
PTR + = kworld;
Itoplabel-> settextl (PTR );
Cleanupstack: popanddestroy ();
Drawnow ();
The following describes how to use descriptors:
Non-modifying methods
Length (), size (), left (), right (), mid (), compare (), locate (), locatereverse (), find (), match (). The following code example describes how to locate the content in <> In a descriptor. If the content does not exist, the entire string is returned:
Static const tuint kaddressstartchar = '<';
Static const tuint kaddressendchar = '> ';
Tptrc extractaddressnumber (const tdesc & aaddressstring)
{
Tint addrstart = aaddressstring. Locate (kaddressstartchar) + 1;
Tint addrend = aaddressstring. locatereverse (kaddressendchar );
If (addrstart = kerrnotfound) | (addrend = kerrnotfound) | (addrstart> = addrend ))
{
Addrstart = 0;
Addend = aaddressstring. Length ();
}
Return (aaddressstring. mid (addrstart, (addrend-addrstart )));
}
Modifying Methods
Zero (), copy (), num (), format (), insert (), replace (), delete (), append (), trim (), and so on. Sample Code:
_ Empty (ktext, "Hello world! ");
_ Partition (knewtext, "new text ");
_ Reply (kreplaced, "replaced ");
Tbuf <16> buf1 (ktext );
Buf1.delete (6, 6); // length is now 6, leaving "hello" in the buffer
Tbuf <16> buf2 (knewtext );
Buf2.copy (kreplaced); // buf2 now contains "replaced"
Buf2.append (knewtext); // buf2 now contains "replaced New text"
Buf2.delete (99, 1); // will cause a panic !!!
Descriptors in method declarations
- Use the base class as much as possible in function parameters
- Use a neutral descriptor. Generally, tdesc is used instead of tdesc8 or tdesc16.
- When the descriptor content should not be changed, use the const Modifier
- Classic usage: void settext (const tdesc & atext); tptrc text () const;
Character Conversions
The ccnvcharactersetconverter class provides conversion methods between Unicode and other character set encodings.
ASCII is a subset of Unicode and does not need to be used. The conversion method between Unicode and Unicode is as follows:
Tbuf16 <64> unicodebuf;
_ Lit8 (kasciistr, "hello ");
Unicodebuf. Copy (kasciistr );
The following code can be used for conversion between Unicode and Latin:
Tbuf8 <64> latin1buf;
_ Lit16 (kunicodestr1, "hello ");
_ Lit16 (kunicodestr2, "I have got 10/x20ac."); // x20ac is a euro
Latin1buf. Copy (kunicodestr1); // OK
Latin1buf. Copy (kunicdoestr2); // not as you wanted.
To be added: conversion between Unicode and Chinese
Post reading
For beginners, this part is the most difficult to accept at the beginning, because they are used to the strings in C.
However, after a period of adaptation, I will gradually become familiar with it. This kind of things can be understood through many times. This training course is indeed very good and I am very clear about it.
Take a look at the examples on Forum Nokia and Open Source Code such as internetradio.
Symbian, it's not easy to love you! Haha ~