The so-called descriptor, to some extent, is equivalent to a string. Just unlike C + + strings, the descriptors in Symbian describe their length with an additional integer, rather than a ' yes ' terminator. Thus, descriptors can express arbitrary data, strings, or binary strings.
Descriptor system
Open any book about Symbian, and you can see the complex inheritance system of the Symbian descriptor. Its base class is Tdesc, as the name implies, T is representative of it is T class, suffix C means that it is a constant, where the data cannot be modified. Therefore, it only defines some methods of character processing, including finding, matching, fetching substrings, and so on, without including any interfaces that modify the data in them. Modifiable descriptor classes, all derived from tdes, are subclasses of TDESC that provide additional copies, 0, and append interfaces.
When you need to assign a descriptor on the stack, you may need to use a tbuf or TBUFC class. They are all template classes that accept an int parameter as the length information. From the name can be seen at a glance the difference, with C is the nature of the constant, it is a one-time allocation of the necessary resources in the stack, and the completion of the assignment and initialization work, once assigned, you can not modify again. Instead of Tbuf with C, it is only necessary to reserve the required space in the stack at the time of construction, and then you can modify the required content arbitrarily in this space. From the memory distribution, TBUFC object in the real string information, also put a 32-bit integer, its first 4bits storage type information, 28bits storage length information, that is, a TBUFC object contains up to 256M length of strings, this is absolutely enough. The Tbuf object, in addition to the content contained in the TBUF, adds an additional max-length integer after the length information, which indicates the length of the allocated memory, while length is used to represent the actual valid length of the data.
In addition to the stack, more descriptor lengths are not defined at compile time and need to be distributed dynamically on the heap, and the task is left to HBUFC to complete. HBUFC also contains three data, the first two are consistent with TBUF, 4bits type + 28bits true length + 1 The allocation length of the shaping. But the last item is a pointer that points to a location in the heap, where it opens up a string space for the allocated length. But the base class of the HBUFC is not identical to the TBUF, but to the TBUFC, which is the unfading of its C suffix, which means that it has only some data-modified interfaces. Such a design, will certainly cause a series of questions, why obviously have max-length information, but also has the length information, but is an immutable descriptor object? If you need to dynamically change the contents of a descriptor in a heap, what class should you use?
All of these questions can be answered by tptr this class. In terms of memory data alone, TPTR is exactly the same as HBUFC, but from the actual logic, the pointer in HBUFC can only point to the data in the heap, and the pointer in Tptr can point to a heap of data, or to a stack of data, depending on what object you use to initialize it. If initialized with a tbuf, then point to the stack, initialize it with HBUFC, and point to the heap, the entire wall of grass. But whether it is pointing to the heap or pointing to the stack, TPTR only has access to the data pointed to, without the right to control its life and death, the data needs to be managed by its original controller, TBUF or HBUFC. Most of the time, Tptr is a helper of HBUFC, when you need to modify the character data in HBUFC, call the DES () interface, from HBUFC gorgeous turn to tptr,tptr no C suffix, which means that it inherits the Tdes ability, can modify the data. I've never understood why Symbian designed a HBUFC class, rather than Hbuf class, the only conceivable explanation is that, because of the existence of tptr, can solve the problem of modifying the heap descriptor data, and do not need to implement a number of interfaces, although a bit far-fetched, but I have been using this explanation self-deception.
Tptr also has a twin brother Tptrc. Similar to the TBUFC and Tbuf, TPTRC removes the max-length domain and allocates length to length. TPTRC All design logic is consistent with tptr, pointing to heap or stack objects, using only not managing resources, and so on. The most widely used occasion is to express substrings. For example, if the Tbuf object wants to take out the first 10 characters for use by the caller, it returns a Tptrc object that points to the HBUFC character position but only has 10 lengths, which can control the length and ensure that the data is not modified to kill two birds and stone.
So far, the entire structure of the descriptor is complete, both stack and heap, both of which are modifiable and contain immutable, both expressive and local. But Symbian in the spirit of buying one to get one, departs big gift attitude, also provides a rbuf class. This is a R class and does not have a C suffix. It allocates data on the heap through the Create interface, uses release or close destructor to grasp the resources, in essence, it is a R version of HBUFC. However, the base class of Rbuf is Tdes, so it provides a richer data modification interface directly, and does not need to turn into a tptr to deal with. Also, rbuf masks the difference between null and empty strings, sometimes in the use of HBUFC need to determine whether null or empty, but with rbuf is not required, NULL is NULL, NULL is NULL. But Rbuf's inheritance system is deeper, and it can be imagined that some of its operations will encapsulate some additional detection operations again, possibly with a slight reduction in efficiency (just guessing, and interested in doing experiments to confirm ...). )。 From the difference between rbuf and HBUFC, you can also infer the most appropriate use scenarios for both. HBUFC in fact, the most appropriate thing is to be based on the nature of its C to do, suitable for the allocation of no longer modify the occasion, such as from an existing descriptor copy a new descriptor, at this time the return is often hbufc. and rbuf more suitable for repeated modification of the occasion (otherwise white blind call it a buf ... In such a scenario, its interface is more simple and straightforward to use ...
Coding
All the descriptors mentioned above are actually not real classes, but a typedef. In non-kernel mode, all descriptors, such as Tdesc, whose true implementation is TDesC16, are TDesC8 in kernel mode. Or look at the name of righteousness, with 8 is a single character 1 bytes descriptor, with 16 is a wide-character 2-byte descriptor. In a non-kernel state, the 16-bit descriptor is used uniformly as the default value, and is designed to be compatible with Unicode encoding, helping to develop in different languages. Most system APIs provide interfaces that accept a typedef such as TDESC, which is actually a unicode-16 16-bit descriptor. However, in some IO-related interfaces, it is a single character descriptor that accepts the end of 8 to be compatible with different data formats. Given descriptors usually do not have any constraints on encoding, can be binary streams, can be utf-8, can be normal ASCII code. What is specific, logic needs to be maintained by the caller himself. In order to pass IO-read data to some system APIs, it is often necessary to turn the 8-bit descriptor into a 16-bit descriptor. This conversion and coding are closely related, if only the general ASCII string (or other encoded ASCII parts ...). , you can use the Tdes copy interface to copy from 8-bit to 16-bit, or from 16-bit to 8-bit. From the 8-bit copy of 16 bits, the first byte fills the corresponding 8-bit character's content, and the second byte is populated with ' yes ', or all 0. From 16 bits to 8 bits, it is conceivable that the contents of the latter byte are intercepted and discarded. However, if there are some complex coding transformations, such as the utf-8 of the character flow into the system required unicode-16, then need to use the cnvutfconverter, it is responsible for the different character sets to do the conversion.
Other character type classes
The most confusing thing to see Symbian's descriptor is not just the complex succession system, but also the _l and _lit macros. Open the _lit macro and you can see that it is actually a const static constant string that defines a TLITC type. In a sense, through _lit, some common strings can be used as constants so that they do not construct and reconstruct, and it is the strategy of space changing time. From the interface, it overloads many transformation operators operator (), which can turn into versions of TDESC, compatible with the inheritance system , and from the memory implementation, it holds: C + + string length (except the) + authentic C + + string (that is, the end of a short int or a char array). , through this structure, on the one hand and Symbian descriptor can be consistent, but also enjoy the original C + + support, kill both.
Compared to the gorgeous _lit, _l this macro on a lot of turtles, representing the backwardness of the old productivity. It actually defines an array of constants in the contents of a TPTRC,TPTRC (the typedef is called Ttext ...). , this constant array, in fact, is transformed into an array of char or short int and is an authentic C + + string. In essence, TPTRC play this role, is completely in the hands of the friendship guest, it should not be to do this thing, because its internal is through a pointer to the real character space, many operations have been through multiple access operations, reducing efficiency; and tlexc, is tailored to create a carefully packaged natural star, it optimizes the zuogeng of the pointer, improve efficiency. So abandoning _l, embracing _lit, is the content of all Symbian teachings, or is it reasonable ...
There is also a common and string-related thing, is the Tlex class. It does the work, is the famous string-parsing. Give it a descriptor, it can return you an integer or a floating-point number. Tlex log parsing, in essence, is based on ASCII encoding, you give its descriptor code, need to compatible with ASCII standards, do not take a full corner of the number to embarrass it, it will strike.