|
1 <?xml version="1.0" encoding="utf-8"?> |
|
2 <!-- Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies) All rights reserved. --> |
|
3 <!-- This component and the accompanying materials are made available under the terms of the License |
|
4 "Eclipse Public License v1.0" which accompanies this distribution, |
|
5 and is available at the URL "http://www.eclipse.org/legal/epl-v10.html". --> |
|
6 <!-- Initial Contributors: |
|
7 Nokia Corporation - initial contribution. |
|
8 Contributors: |
|
9 --> |
|
10 <!DOCTYPE concept |
|
11 PUBLIC "-//OASIS//DTD DITA Concept//EN" "concept.dtd"> |
|
12 <concept id="GUID-9F82E4D3-DDD4-50A5-AB12-50B216B73368" xml:lang="en"><title>How to use the heap descriptor - HBufC</title><shortdesc>Heap descriptors provide a buffer of fixed length, allocated on the heap. Descriptors are useful for holding constant strings or data, when the length of the data may not be known until run time.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
13 |
|
14 <section id="CONTEXT_361D960801D14A01BDCA84C4583DBC07"><p>Some key points about heap descriptors:</p><ul id="UL_1B2EE288A79A45CDADC061A8AD013AA1"><li id="LI_593B247AD60649A3995B848E524423FF">For text data, it is usual to construct a <code><codeph>HBufC</codeph></code> type and allow the appropriate variant, either a <code><codeph>HBufC8</codeph></code> or a <codeph>HBufC16</codeph> to be selected at build time.</li><li id="LI_5FB940C2E42143B9BFE6961D6CD72B86">For binary data, an explicit <codeph>HBufC8</codeph> is used.</li><li id="LI_9D41DDF6F4544E90A79494F10D453DC4">It is rare to use an explicit <codeph>HBufC16</codeph>.</li><li id="LI_0C6D6B9242EC473B8754A321A68A1BB2">Data cannot be changed through this descriptor although it can be |
|
15 replaced using the assignment operators. |
|
16 </li><li id="LI_FFFA4A8EB811448BB63BED6865555087">If you need to pass an <codeph>HBufC</codeph> to a function that takes a <codeph>TDesC&</codeph> parameter, simply dereference the <codeph>HBufC</codeph> pointer.</li><li id="LI_D010A4CD7E26494EA8AB123A6FD76BEA">If you need to modify the <codeph>HBufC</codeph>'s data, use its <codeph>Des()</codeph> function to construct a <codeph>TPtr/TPtr8/TPtr16</codeph> modifiable pointer descriptor for the buffer's data.</li><li id="LI_1317203B41FC4D1887AC3E4F9E62EEBC">The size of the heap descriptor buffer can be replaced by |
|
17 reallocating it with a new length. |
|
18 </li></ul><p>Although the following notes refer to the build independent types, they are equally valid for the 8 bit and 16 bit types.</p> |
|
19 |
|
20 |
|
21 </section> |
|
22 <section id="SECTION_C424B2F2D52D477AA71C739E4B27BBBC"> |
|
23 <title>Constructing an <codeph>HBufC</codeph></title> |
|
24 <p> |
|
25 A heap descriptor can be constructed in one of two ways: |
|
26 </p> |
|
27 |
|
28 <ul id="UL_97F558DD94EA45068D1C8B885D092AB1"> |
|
29 <li id="LI_FAA60C6043CB42BF84558932764C1054"> |
|
30 <p> |
|
31 using the static member functions <codeph>New()</codeph>, |
|
32 <codeph>NewL()</codeph> or <codeph>NewLC()</codeph> |
|
33 </p> |
|
34 </li> |
|
35 <li id="LI_3A20A3574E404335BFFE058BB3DEA02F"> |
|
36 <p> |
|
37 using the <codeph>Alloc()</codeph>, <codeph>AllocL()</codeph> or |
|
38 <codeph>AllocLC()</codeph> functions of an existing descriptor |
|
39 </p> |
|
40 </li> |
|
41 </ul> |
|
42 |
|
43 <p> |
|
44 The following code fragment constructs a heap descriptor which can hold up to 15 data items. The current length is zero. |
|
45 </p> |
|
46 <codeblock xml:space="preserve">HBufC* buf; |
|
47 ... |
|
48 buf = HBufC::NewL(15);</codeblock> |
|
49 <p> |
|
50 The following code fragment constructs a heap descriptor from an existing descriptor. The new heap descriptor is initialised with the content of |
|
51 <codeph>buf1</codeph>, i.e. the string: "Hello World!" |
|
52 </p> |
|
53 <p> |
|
54 The source descriptor is a literal which is converted to descriptor type. |
|
55 </p> |
|
56 <codeblock xml:space="preserve">_LIT(KText,"Hello World!"); |
|
57 TBufC<16> buf1(KText); |
|
58 ... |
|
59 HBufC* hptr; |
|
60 hptr = buf1.AllocL(); |
|
61 ...</codeblock> |
|
62 </section> |
|
63 |
|
64 <section id="SECTION_B06A1A56ECEE4F02BEB57288C759CF80"> |
|
65 <title>Replacing data and re-allocating</title> |
|
66 <p> |
|
67 Although existing data within a heap descriptor cannot be modified, the |
|
68 assignment operator can be used to replace that data. |
|
69 </p> |
|
70 <codeblock xml:space="preserve">_LIT(KText,"Hello World!"); |
|
71 ... |
|
72 HBufC* buf; |
|
73 ... |
|
74 buf = HBufC::NewL(15); |
|
75 *buf = KText;</codeblock> |
|
76 <p> |
|
77 The source descriptor is a literal which is converted to descriptor |
|
78 type. |
|
79 </p> |
|
80 <p> |
|
81 To allow more than 15 characters or data items to be assigned into the |
|
82 heap descriptor, it must be reallocated: |
|
83 </p> |
|
84 <codeblock xml:space="preserve">buf = buf->ReAllocL(20);</codeblock> |
|
85 <p> |
|
86 This permits the following assignment to be done without raising a |
|
87 panic: |
|
88 </p> |
|
89 <codeblock xml:space="preserve">_LIT(KNewText,"Hello World! Morning"); |
|
90 ... |
|
91 *buf = KNewText;</codeblock> |
|
92 <p> |
|
93 <codeph>buf</codeph> may or may not point to a different location in the |
|
94 heap after reallocation. The location of the reallocated descriptor depends on |
|
95 the heap fragmentation and the size of the new cell. It is always safer to |
|
96 assume that the location changes. |
|
97 </p> |
|
98 </section> |
|
99 |
|
100 <section id="SECTION_27A2310F89E141159A3DF3169D860CDA"> |
|
101 <title>Changing data through a modifiable pointer descriptor.</title> |
|
102 <p> |
|
103 The data contained by a heap descriptor <i>can</i> be changed by |
|
104 constructing a <codeph>TPtr</codeph> modifiable pointer descriptor using the |
|
105 <codeph>Des()</codeph> member function and then changing the data through that |
|
106 <codeph>TPtr</codeph>. |
|
107 </p> |
|
108 <p> |
|
109 The maximum length of the <codeph>TPtr</codeph> is determined from the size |
|
110 of the cell allocated to the data area of the heap descriptor. |
|
111 </p> |
|
112 <p> |
|
113 The following code fragment changes the data in the heap descriptor and |
|
114 the length of the heap descriptor. |
|
115 </p> |
|
116 <codeblock xml:space="preserve">TPtr ptr = buf->Des(); |
|
117 ... |
|
118 ptr.Delete((ptr.Length()-9),9); |
|
119 ptr.Append(_LIT(" & Hi"));</codeblock> |
|
120 <p> |
|
121 Take particular care if a the heap descriptor is re-allocated after the |
|
122 <codeph>TPtr</codeph> has been constructed. A <codeph>TPtr</codeph> created before |
|
123 re-allocating the heap descriptor is not guaranteed to have a valid pointer |
|
124 after re-allocation. Any attempt to modify data through the original |
|
125 <codeph>TPtr</codeph> after re-allocation may have undefined consequences. |
|
126 </p><note>it is a common error to use <codeph>Des()</codeph> to create a |
|
127 <codeph>TDesC&</codeph> reference. While not incorrect, it is simpler and much |
|
128 more efficient to simply dereference the heap descriptor.</note> |
|
129 |
|
130 </section> |
|
131 </conbody></concept> |