Symbian3/SDK/Source/GUID-9C51D27D-BEDB-59D1-8F0E-8426B8FF2230.dita
changeset 8 ae94777fff8f
parent 7 51a74ef9ed63
child 13 48780e181b38
--- a/Symbian3/SDK/Source/GUID-9C51D27D-BEDB-59D1-8F0E-8426B8FF2230.dita	Wed Mar 31 11:11:55 2010 +0100
+++ b/Symbian3/SDK/Source/GUID-9C51D27D-BEDB-59D1-8F0E-8426B8FF2230.dita	Fri Jun 11 12:39:03 2010 +0100
@@ -1,12 +1,12 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
-<!-- This component and the accompanying materials are made available under the terms of the License 
-"Eclipse Public License v1.0" which accompanies this distribution, 
-and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
-<!-- Initial Contributors:
-    Nokia Corporation - initial contribution.
-Contributors: 
--->
-<!DOCTYPE concept
-  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
-<concept xml:lang="en" id="GUID-9C51D27D-BEDB-59D1-8F0E-8426B8FF2230"><title>Descriptors</title><prolog><metadata><keywords/></metadata></prolog><conbody><p>Descriptors are the classes that Symbian platform C++ uses to manage strings. They are fundamental to the Symbian platform, and an excellent example of the difference of approach between non-OO and OO designs. </p> <section><title>Overview</title> <p>In C, a string such as </p> <codeblock id="GUID-D12A339F-7ADE-5BDE-A8B3-59AB67E2BD8B" xml:space="preserve">char* hello="hello";</codeblock> <p>causes some memory to be set aside containing the six characters 'h', 'e', 'l', 'l', 'o', '\0'. A function such as <codeph>strlen()</codeph> works by scanning the bytes starting from the beginning, and counting until it reaches the trailing null character. If you wish to extend the string, you need to know how much memory is allocated to it. </p> <p>In Symbian platform C++ however, strings are managed using a family of classes called descriptors. The abstract descriptor classes define common interfaces for all descriptor classes. Buffer, pointer, and heap descriptor classes provide implementations of the abstract descriptor interfaces, and provide different methods of storing the data. </p> </section> <section><title>Abstract descriptors</title> <p>We can represent the basic requirements for strings by two abstract classes: <codeph>TDesC</codeph> and <codeph>TDes</codeph>. </p> <p> <codeph>TDesC</codeph> is a constant, or non-modifiable, descriptor. It has an address and a length. Using a class like this, you can do any manipulations to a string, provided they do not alter the data. As a consequence, the <codeph>TDesC</codeph> class has many non-modifying functions. </p> <p> <codeph>TDes</codeph> is a modifiable descriptor: it has, in addition, a maximum length. This allows the data to be manipulated, extended or contracted, provided it does not exceed the maximum length. As a consequence, <codeph>TDes</codeph> has many modifying functions which allow string manipulation. </p> <p>It is a fundamental aspect of descriptors that they do not allow modification to exceed the allocated length. Other classes are provided to allow this, for instance <codeph>CBufBase</codeph> and derived classes. If a <codeph>TDes</codeph> function causes overflow, a panic will occur. </p> <p>Because <codeph>TDesC</codeph> and <codeph>TDes</codeph> define all the functions needed to access and manipulate string and memory data, many functions take a <codeph>const TDesC&amp;</codeph> parameter if they need to access data, or a <codeph>TDes&amp;</codeph> parameter if they need to modify it. </p> </section> <section><title>Pointer descriptor</title> <p>The abstract descriptor classes have several implementations. The simplest are pointer descriptors. </p> <p> <codeph>TPtrC</codeph> just has length and address: its representation needs just two machine words. A <codeph>TPtrC</codeph> may be set up to describe any existing data. A <codeph>TPtr</codeph> adds a maximum length, and so may be used to describe a buffer which is perhaps only partially allocated. </p> <fig id="GUID-07AAB2BD-6645-5E19-A69D-C7BDD770FBF6"><image href="GUID-0268102D-D238-5C5E-818F-6ACC4A85B022_d0e7010_href.png" placement="inline"/></fig> <p> <codeph>TPtrC</codeph> and <codeph>TPtr</codeph> are somewhat like C <codeph>char*</codeph> pointers. But because the length is contained in the descriptor itself, there is no need to scan for trailing null characters, or to allocate room for them. </p> </section> <section><title>Buffer descriptors</title> <p>Buffer descriptors, <codeph>TBufC</codeph> and <codeph>TBuf</codeph>, contain their data as part of themselves, like <codeph>char[]</codeph> arrays in C. </p> <fig id="GUID-2D00C669-3E47-5352-9730-73035D059B15"><image href="GUID-356B54BB-E389-5562-A2D9-80A472EAC9A3_d0e7042_href.png" placement="inline"/></fig> <p>These descriptor classes exploit C++'s template mechanism, using an integer parameter to specify the length. </p> </section> <section><title>Heap descriptors</title> <p>Heap descriptors contain their data in heap cell. These are used when you do not know the length required for a buffer at build time, but decide it at run-time. This is like <codeph>(char*) malloc(length+1)</codeph> in C. </p> <p>The non-modifiable heap descriptor type, <codeph>HBufC</codeph>, is allocated on the heap. They are always referred to through an <codeph>HBufC*</codeph>, rather than an <codeph>HBufC</codeph> directly: </p> <fig id="GUID-C2909A73-C585-5A0B-B0B8-15BBB05EBCAE"><image href="GUID-C8D5B104-3F34-513B-BA08-5F2FEE60265C_d0e7071_href.png" placement="inline"/></fig> <p>The modifiable heap descriptor type, <codeph>RBuf</codeph>, can be created on the stack, but contains a pointer to data on the heap. This is similar to a <codeph>TPtr</codeph> pointer descriptor, but an <codeph>RBuf</codeph> owns the data that it points to, and is responsible for freeing the memory when it is closed. An <codeph>RBuf</codeph> object can allocate its own buffer, take ownership of a pre-existing section of allocated memory, or take ownership of a pre-existing heap descriptor. </p> <fig id="GUID-084AC324-8928-53FE-8CF5-75A544522AD8"><image href="GUID-DC37C3A9-B03F-5699-9E05-8ADD62C2FF04_d0e7089_href.png" placement="inline"/></fig> <p> <codeph>RBuf</codeph> is easier to use than <codeph>HBufC</codeph>, so should generally be preferred. <codeph>RBuf</codeph> was only introduced in version 8.0, however, so older code and APIs use <codeph>HBufC</codeph>. </p> </section> <section><title>Descriptor classes</title> <p>The complete descriptor class hierarchy is </p> <fig id="GUID-9FA30B6B-12C7-58CB-92B6-684053EE9FCD"><image href="GUID-7E7BCC57-E14F-56A4-B948-B9FB9E7AB598_d0e7115_href.png" placement="inline"/></fig> <p>It represents an elegant use of OO. The <codeph>TBufCBase</codeph> class is used as an implementation convenience, which is also a frequent OO idiom (though it should be used with caution). </p> <p>Versions of the descriptors classes are available that store 16-bit or 8-bit wide items. When using descriptors for strings, you should always use classes such as <codeph>TDes</codeph> etc. These classes are <codeph>typedef</codeph> ed to use the 16-bit implementations, such as <codeph>TDes16</codeph> etc. </p> <p>Because descriptors may contain any data, including nulls, they may also be used to refer to byte data and general buffers. In these contexts, you should use the 8-bit implementations, such as <codeph>TDes8</codeph>, directly. </p> </section> </conbody></concept>
\ No newline at end of file
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. -->
+<!-- This component and the accompanying materials are made available under the terms of the License 
+"Eclipse Public License v1.0" which accompanies this distribution, 
+and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". -->
+<!-- Initial Contributors:
+    Nokia Corporation - initial contribution.
+Contributors: 
+-->
+<!DOCTYPE concept
+  PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd">
+<concept xml:lang="en" id="GUID-9C51D27D-BEDB-59D1-8F0E-8426B8FF2230"><title>Descriptors</title><prolog><metadata><keywords/></metadata></prolog><conbody><p>Descriptors are the classes that Symbian platform C++ uses to manage strings. They are fundamental to the Symbian platform, and an excellent example of the difference of approach between non-OO and OO designs. </p> <section><title>Overview</title> <p>In C, a string such as </p> <codeblock id="GUID-D12A339F-7ADE-5BDE-A8B3-59AB67E2BD8B" xml:space="preserve">char* hello="hello";</codeblock> <p>causes some memory to be set aside containing the six characters 'h', 'e', 'l', 'l', 'o', '\0'. A function such as <codeph>strlen()</codeph> works by scanning the bytes starting from the beginning, and counting until it reaches the trailing null character. If you wish to extend the string, you need to know how much memory is allocated to it. </p> <p>In Symbian platform C++ however, strings are managed using a family of classes called descriptors. The abstract descriptor classes define common interfaces for all descriptor classes. Buffer, pointer, and heap descriptor classes provide implementations of the abstract descriptor interfaces, and provide different methods of storing the data. </p> </section> <section><title>Abstract descriptors</title> <p>We can represent the basic requirements for strings by two abstract classes: <codeph>TDesC</codeph> and <codeph>TDes</codeph>. </p> <p> <codeph>TDesC</codeph> is a constant, or non-modifiable, descriptor. It has an address and a length. Using a class like this, you can do any manipulations to a string, provided they do not alter the data. As a consequence, the <codeph>TDesC</codeph> class has many non-modifying functions. </p> <p> <codeph>TDes</codeph> is a modifiable descriptor: it has, in addition, a maximum length. This allows the data to be manipulated, extended or contracted, provided it does not exceed the maximum length. As a consequence, <codeph>TDes</codeph> has many modifying functions which allow string manipulation. </p> <p>It is a fundamental aspect of descriptors that they do not allow modification to exceed the allocated length. Other classes are provided to allow this, for instance <codeph>CBufBase</codeph> and derived classes. If a <codeph>TDes</codeph> function causes overflow, a panic will occur. </p> <p>Because <codeph>TDesC</codeph> and <codeph>TDes</codeph> define all the functions needed to access and manipulate string and memory data, many functions take a <codeph>const TDesC&amp;</codeph> parameter if they need to access data, or a <codeph>TDes&amp;</codeph> parameter if they need to modify it. </p> </section> <section><title>Pointer descriptor</title> <p>The abstract descriptor classes have several implementations. The simplest are pointer descriptors. </p> <p> <codeph>TPtrC</codeph> just has length and address: its representation needs just two machine words. A <codeph>TPtrC</codeph> may be set up to describe any existing data. A <codeph>TPtr</codeph> adds a maximum length, and so may be used to describe a buffer which is perhaps only partially allocated. </p> <fig id="GUID-07AAB2BD-6645-5E19-A69D-C7BDD770FBF6"><image href="GUID-0268102D-D238-5C5E-818F-6ACC4A85B022_d0e8285_href.png" placement="inline"/></fig> <p> <codeph>TPtrC</codeph> and <codeph>TPtr</codeph> are somewhat like C <codeph>char*</codeph> pointers. But because the length is contained in the descriptor itself, there is no need to scan for trailing null characters, or to allocate room for them. </p> </section> <section><title>Buffer descriptors</title> <p>Buffer descriptors, <codeph>TBufC</codeph> and <codeph>TBuf</codeph>, contain their data as part of themselves, like <codeph>char[]</codeph> arrays in C. </p> <fig id="GUID-2D00C669-3E47-5352-9730-73035D059B15"><image href="GUID-356B54BB-E389-5562-A2D9-80A472EAC9A3_d0e8317_href.png" placement="inline"/></fig> <p>These descriptor classes exploit C++'s template mechanism, using an integer parameter to specify the length. </p> </section> <section><title>Heap descriptors</title> <p>Heap descriptors contain their data in heap cell. These are used when you do not know the length required for a buffer at build time, but decide it at run-time. This is like <codeph>(char*) malloc(length+1)</codeph> in C. </p> <p>The non-modifiable heap descriptor type, <codeph>HBufC</codeph>, is allocated on the heap. They are always referred to through an <codeph>HBufC*</codeph>, rather than an <codeph>HBufC</codeph> directly: </p> <fig id="GUID-C2909A73-C585-5A0B-B0B8-15BBB05EBCAE"><image href="GUID-C8D5B104-3F34-513B-BA08-5F2FEE60265C_d0e8346_href.png" placement="inline"/></fig> <p>The modifiable heap descriptor type, <codeph>RBuf</codeph>, can be created on the stack, but contains a pointer to data on the heap. This is similar to a <codeph>TPtr</codeph> pointer descriptor, but an <codeph>RBuf</codeph> owns the data that it points to, and is responsible for freeing the memory when it is closed. An <codeph>RBuf</codeph> object can allocate its own buffer, take ownership of a pre-existing section of allocated memory, or take ownership of a pre-existing heap descriptor. </p> <fig id="GUID-084AC324-8928-53FE-8CF5-75A544522AD8"><image href="GUID-DC37C3A9-B03F-5699-9E05-8ADD62C2FF04_d0e8364_href.png" placement="inline"/></fig> <p> <codeph>RBuf</codeph> is easier to use than <codeph>HBufC</codeph>, so should generally be preferred. <codeph>RBuf</codeph> was only introduced in version 8.0, however, so older code and APIs use <codeph>HBufC</codeph>. </p> </section> <section><title>Descriptor classes</title> <p>The complete descriptor class hierarchy is </p> <fig id="GUID-9FA30B6B-12C7-58CB-92B6-684053EE9FCD"><image href="GUID-7E7BCC57-E14F-56A4-B948-B9FB9E7AB598_d0e8390_href.png" placement="inline"/></fig> <p>It represents an elegant use of OO. The <codeph>TBufCBase</codeph> class is used as an implementation convenience, which is also a frequent OO idiom (though it should be used with caution). </p> <p>Versions of the descriptors classes are available that store 16-bit or 8-bit wide items. When using descriptors for strings, you should always use classes such as <codeph>TDes</codeph> etc. These classes are <codeph>typedef</codeph> ed to use the 16-bit implementations, such as <codeph>TDes16</codeph> etc. </p> <p>Because descriptors may contain any data, including nulls, they may also be used to refer to byte data and general buffers. In these contexts, you should use the 8-bit implementations, such as <codeph>TDes8</codeph>, directly. </p> </section> </conbody></concept>
\ No newline at end of file