Symbian note [3] -- Symbian Descriptor

Source: Internet
Author: User
Tags character classes

[3] The so-called descriptor of Symbian is equivalent to a string to a certain extent. It is only different from the C ++ string. The descriptors in Symbian use an additional integer to describe the length, rather than the terminator '\ 0. Therefore, descriptors can express arbitrary data, strings, or binary strings. The descriptor system opens any book about Symbian, and you can see the complex inheritance system of the Symbian descriptor. Its base class is tdesc. as its name implies, t indicates that it is a t class, and C indicates that it is a constant, where data cannot be modified. Therefore, it only defines some character processing methods, including searching, matching, and getting substrings, without any interface for modifying the data. Modifiable descriptor classes are derived from TDES. They are subclasses of tdesc and provide additional interfaces such as copy, clear, and append. When you need to allocate a descriptor to the stack, you may need to use the tbuf or tbufc class. They are all template classes, and an int type parameter is used as the length information. From the name, we can clearly see the difference. C is a constant. It allocates the required resources in the stack at a time and completes the assignment and initialization at the same time. Once allocated, it cannot be modified again. Tbuf without C is only reserved in the stack during construction, and can be modified in any way within this space range. According to the memory distribution, a 32-bit integer is also placed before the true string information of the tbufc object. The first 4 bits of the tbufc object stores the type information, and the last 28 BITs stores the length information, that is to say, a tbufc object can contain a string of a maximum length of MB, which is absolutely sufficient. In addition to the content contained in tbuf, The tbuf object also adds a max-Length Integer to the length information, which indicates the pre-allocated memory length, length indicates the actual valid data length. Apart from the stack, more descriptor lengths are not determined during the compilation period and need to be dynamically allocated on the stack. This task is completed by hbufc. Hbufc also contains three types of data. The first two items are the same as those of tbuf. The 4 bits type + the actual length of 28bits + the allocated length of 1 integer. But the last one is a pointer pointing to a position in the heap. At this position, the pre-allocated string space is opened. However, the base class of hbufc is not the same as that of tbuf, but the same as that of tbufc. This is like the suffix table of its C, which indicates that it has only some interfaces that are not data modified. Such a design will certainly lead to a series of questions. Why is there a clear max-length information and length information, but it is an immutable descriptor object? What kind of class should I use if I need to dynamically change the descriptor content in the heap? All these questions can be answered through the tptr class. From the perspective of memory data, tptr is exactly the same as hbufc, but from the actual logic, the pointer in hbufc may only point to the data in the heap, while the pointer in tptr can point to a heap data, it can also point to a stack, depending on the object you use to initialize it. If a tbuf is used for initialization, it points to the stack. If hbufc is used for initialization, it points to the heap. However, whether it is pointing to the heap or stack, tptr has only the right to use the data it points to, rather than the right to control its life and death. The data needs to be controlled by its original controller, tbuf or hbufc is responsible for management. Most of the time, tptr exists as a helper of hbufc. When you need to modify the character data in hbufc, call the des () interface and turn it from hbufc to tptr, tptr does not have the suffix of C, which means that it inherits the capability of TDES and can modify the data in it. I have never understood why an hbufc class should be designed for Symbian, instead of an hbuf class. The only explanation I can think of is that the existence of tptr can solve the problem of modifying heap descriptor data, I don't need to implement more interfaces. Although it is far-fetched, I still use this explanation to deceive myself. Tptr also has a twin brother, tptrc. Similar to the relationship between tbufc and tbuf, tptrc removes the max-length field and uses the allocation length. All the design logic of tptrc is consistent with that of tptr. It points to the heap or stack object and only uses resources not managed. It is widely used to express substrings. For example, if the tbuf object wants to extract the first 10 characters for use by the caller, it will return a tptrc object, which points to the character position of hbufc, but has only 10 characters in length, it can control the length and ensure that the data is not modified. So far, the entire descriptor architecture is complete, with both stacks and stacks. There are both modifiable, including immutable, and overall expressions, it also represents local. However, Symbian offered an rbuf class in the bid of buying, giving, and giving. This is an R class with no C suffix. It allocates data on the stack through the create interface and uses release or close to analyze the resources. In essence, it is an R version of hbufc. However, the base class of rbuf is TDES. Therefore, it directly provides a richer data modification interface and does not need to be converted to tptr for processing. In addition, rbuf shields the difference between null and empty strings. Sometimes, when using hbufc, You need to constantly determine whether it is null or empty, but rbuf is not required, null indicates null, and null indicates null. But the inheritance system of rbuf is deeper, and it can be imagined that some of its operations will encapsulate some additional detection operations again, and the efficiency may be slightly reduced (just speculation, if you are interested, you can perform experiments to confirm ...). From the differences between rbuf and hbufc, you can also infer the most suitable use cases of the two. In fact, hbufc should be most appropriate based on its c nature. It is suitable for allocating new descriptors that will not be modified. For example, if a new one is copied from an existing descriptor, hbufc is often returned. Rbuf is more suitable for repeated revisions (otherwise, it will be called a BUF ...), in this scenario, the interface is simpler and clearer to use... Encoding all the descriptors mentioned above is not actually a real class, but a typedef. In non-kernel mode, all descriptors, such as tdesc, are actually implemented as tdesc16 and tdesc8 in kernel mode. Take the name as an example. The descriptor with 8 characters is a single character and 1 byte, And the descriptor with 16 characters is a wide character and 2 byte. In non-kernel mode, a 16-bit descriptor is used as the default value to be compatible with Unicode encoding and be developed in different languages. Most of the system APIs are provided to accept the typedef interface such as tdesc, in fact, is the unicode-16's 16-bit descriptor. However, some io-related interfaces all accept single-character descriptors ending with 8 to be compatible with different data formats. Single-character descriptors generally do not have any constraints on encoding. They can be binary streams, UTF-8, or common ASCII codes. The logic needs to be maintained by the caller. To pass the data read from Io to some system APIs, we usually need to convert the 8-bit descriptor into a 16-bit descriptor. This type of conversion is closely related to the encoding. If it is only a common ASCII string (or another ASCII part of the encoding ...), you can use the TDES copy interface to copy data from 8-bit to 16-bit, or from 16-bit to 8-bit. The first byte is filled with the corresponding 8-character content, and the second byte is filled with '\ 0', that is, all are 0. From 16 to 8, we can imagine that the content of the last byte is truncated and discarded. But if it is some complex encoding conversion, such as UTF-8 transform stream to the unicode-16 required by the system, then you need to use cnvutfconverter, it is responsible for conversion in different character sets. When we see the Symbian descriptor in other character classes, we are not only confused about the complex inheritance system, but also about macros such as _ L and _ others. Open the macro _ prop, and you can see that it is actually defining a tlitc-type const static constant string. In a sense, through _ struct, some common strings can be used as constants, so that they are not repeatedly constructed and destructed. It is a space-for-time policy. From the interface perspective, it reloads a lot of transformation operators operator () and can turn to various tdesc versions, which are compatible with the inheritance system. In terms of memory implementation, it stores: the length of the C ++ string (except \ 0) + original C ++ string (a short Int or char array ending with \ 0 ...), with this structure, it can be consistent with the Symbian descriptor representation and enjoy the original C ++ support. Compared with _ growth, _ L is a great macro, which represents the backwardness of old productivity. In fact, it defines a tptrc, and the content in tptrc points to an array of constants (typedef is called ttext ...), this constant array is actually transformed from an array of char or short int and is also an original C ++ string. In essence, tptrc plays this role, which is entirely a kind of friendship in the case of shortage of manpower. It should not have done this, because it points to the real character space through a pointer internally, many operations go through multiple address fetch operations to reduce efficiency. tlexc, it is tailor-made and well-packaged by natural stars. It optimizes the pointer of the stem and improves efficiency. So it is reasonable to discard _ L and embrace _ others... Another common thing associated with strings is the tlex class. It is the well-known string-parsing. Give it a descriptor that can return an integer or floating point number. The parsing of tlex logarithm is basically based on ASCII encoding. the descriptor you give it must be compatible with ASCII standards. Do not use a full-angle number to embarrass it. It will strike...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.