|
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-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A" xml:lang="en"><title>How to |
|
13 use the resizable buffer descriptor - RBuf</title><shortdesc>Use this descriptor to hold a string or binary data.</shortdesc><prolog><metadata><keywords/></metadata></prolog><conbody> |
|
14 <p>A resizable buffer descriptor is an <xref href="GUID-BFBC574B-EFF6-37A4-9189-B71DA1505BC8.dita"><apiname>RBuf</apiname></xref> type. Use the |
|
15 member functions of the base classes: <xref href="GUID-49D4E917-57EA-39AE-8941-144AA8AC2584.dita"><apiname>TDes</apiname></xref> and <xref href="GUID-52D07F46-2162-380C-A775-C3BB335C42F5.dita"><apiname>TDesC</apiname></xref> to |
|
16 change the data in the descriptor. See <xref href="GUID-C85B4EA2-0184-52AF-B097-152E4A023CEF.dita">Abstract |
|
17 base descriptor classes</xref>. </p> |
|
18 <p>This buffer of the descriptor is put on the heap. The buffer is the place |
|
19 where the data is put. This is useful if you do not know the maximum size |
|
20 of the data until run time. </p> |
|
21 <p>The resizable buffer descriptors are similar to what are called <xref href="GUID-2762FDF6-F76D-5268-AE2D-4ABA807CFFEE.dita">Heap |
|
22 descriptors</xref>, or <xref href="GUID-A103FB19-60B3-3E45-97A5-1F295934ACA1.dita"><apiname>HBufC</apiname></xref> types, but the API provided |
|
23 by <codeph>RBuf</codeph> is easier to use. The <codeph>RBuf</codeph> API also |
|
24 makes it easier to change the maximum size of the buffer containing the data, |
|
25 a task often referred to as reallocating the buffer. </p> |
|
26 <p>The general guidelines are: use <xref href="GUID-A103FB19-60B3-3E45-97A5-1F295934ACA1.dita"><apiname>HBufC</apiname></xref> descriptors to |
|
27 contain data that rarely changes; use <xref href="GUID-BFBC574B-EFF6-37A4-9189-B71DA1505BC8.dita"><apiname>RBuf</apiname></xref> descriptors |
|
28 to contain data that changes frequently. However, in practice, <codeph>RBuf</codeph> types |
|
29 are equally suitable for both cases, and you should <i>always consider</i> using |
|
30 an <codeph>RBuf</codeph> in preference to an <codeph>HBufC</codeph>. </p> |
|
31 <p>For cases where your code uses APIs that return an <codeph>HBufC</codeph> type, |
|
32 you can convert this to an <codeph>RBuf</codeph>. In effect, <codeph>RBuf</codeph> can |
|
33 act as a wrapper around the <codeph>HBufC</codeph>; access and manipulation |
|
34 of the data is then done through the member functions of <xref href="GUID-BFBC574B-EFF6-37A4-9189-B71DA1505BC8.dita"><apiname>RBuf</apiname></xref> and |
|
35 its base classes <xref href="GUID-49D4E917-57EA-39AE-8941-144AA8AC2584.dita"><apiname>TDes</apiname></xref> and <xref href="GUID-52D07F46-2162-380C-A775-C3BB335C42F5.dita"><apiname>TDesC</apiname></xref> </p> |
|
36 <p>Some key points about resizable buffer descriptors: </p> |
|
37 <ul> |
|
38 <li id="GUID-C9051973-DFA3-57E6-8AD2-E6E1B49B0A74"><p>For text data, it is |
|
39 usual to construct an <codeph>RBuf</codeph> type and allow the appropriate |
|
40 variant, either a <xref href="GUID-955061A8-A83E-39E5-8745-8FAC7DEA7BCC.dita"><apiname>RBuf8</apiname></xref> or a <xref href="GUID-BEFF9C91-DA64-3032-96E8-F5054405DC74.dita"><apiname>RBuf16</apiname></xref> to |
|
41 be selected at build time. </p> </li> |
|
42 <li id="GUID-93CD2C60-ABB6-5063-8CCA-B63B09139A3F"><p>For binary data, an |
|
43 explicit <xref href="GUID-955061A8-A83E-39E5-8745-8FAC7DEA7BCC.dita"><apiname>RBuf8</apiname></xref> is used. </p> </li> |
|
44 <li id="GUID-82B1C228-51A3-5FED-9797-206805BD3DA5"><p>It is rare to use an |
|
45 explicit <xref href="GUID-BEFF9C91-DA64-3032-96E8-F5054405DC74.dita"><apiname>RBuf16</apiname></xref>. </p> </li> |
|
46 <li id="GUID-2F339945-4741-59A1-AEAA-B405379E25DB"><p>Data can be changed |
|
47 through <codeph>RBuf</codeph> as well as replaced using its assignment operators. |
|
48 Like all descriptors, <codeph>RBuf</codeph> is derived from: </p> <ul> |
|
49 <li id="GUID-7145D7BB-ABCC-5BF8-B367-6D8F9C308AF9"><p>the <xref href="GUID-49D4E917-57EA-39AE-8941-144AA8AC2584.dita"><apiname>TDes</apiname></xref> class, |
|
50 through which the data can be manipulated </p> </li> |
|
51 <li id="GUID-18DF3A17-15E7-54C7-8E3D-1A968AD46D14"><p>the <xref href="GUID-52D07F46-2162-380C-A775-C3BB335C42F5.dita"><apiname>TDesC</apiname></xref> class, |
|
52 through which information about the data (such as its length) can be retrieved. </p> </li> |
|
53 </ul> </li> |
|
54 <li id="GUID-F2EE3065-3D20-5D2B-9887-2C2181FB0195"><p>You can pass an <codeph>RBuf</codeph> to |
|
55 a function that takes a <codeph>TDesC&</codeph> parameter, and a <codeph>TDes&</codeph> parameter. </p> </li> |
|
56 <li id="GUID-83C851DA-BC8C-543D-9987-656FA19832C2"><p>Memory that has already |
|
57 been allocated by your code can be transferred to an <codeph>RBuf</codeph>. |
|
58 This allows any data that may be in that location to be managed through the |
|
59 descriptor. </p> </li> |
|
60 <li id="GUID-6C6B51EE-486C-5ED1-A343-F6777DB5D130"><p>Ownership of an existing <codeph>HBufC</codeph> can |
|
61 be transferred to an <codeph>RBuf</codeph>. This allows the data contained |
|
62 within the <codeph>HBufC</codeph> to be managed through the <codeph>RBuf</codeph> API. </p> </li> |
|
63 </ul> |
|
64 <p>Although the following notes refer to the build independent types, they |
|
65 are equally valid for the explicit 8-bit and 16-bit types. </p> |
|
66 <ul> |
|
67 <li id="GUID-9506E27E-3079-52A9-A993-4DD1DE1BB50B"><p> <xref href="GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A.dita#GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A/GUID-A72C3172-7185-5D87-B4CB-6266AC6146A3">Creating an RBuf</xref> </p> </li> |
|
68 <li id="GUID-C7A121AA-401B-5524-A171-E84352170D71"><p> <xref href="GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A.dita#GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A/GUID-2B23F296-D414-5ABD-82CA-DDCEE2F48459">Re-allocating the memory buffer</xref> </p> </li> |
|
69 <li id="GUID-AC98AE5C-AF3F-5105-BDFF-958D080C92E1"><p> <xref href="GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A.dita#GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A/GUID-A6368F43-9A67-5583-B279-FE68B8CADEC4">Freeing the memory buffer</xref> </p> </li> |
|
70 <li id="GUID-883D98FB-E588-5BCB-A0C0-A64465BFDDA7"><p> <xref href="GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A.dita#GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A/GUID-7ECF515D-D538-5F6C-B2A0-88C1B4E3505C">Cleanup rules</xref> </p> </li> |
|
71 <li id="GUID-94E02925-DDB7-5C8E-9B5B-E98DA78D65D4"><p> <xref href="GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A.dita#GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A/GUID-6732B0A9-4E6E-50A8-9C4F-ADB2BB8FBAEF">Replacing and modifying data</xref> </p> </li> |
|
72 </ul> |
|
73 <section id="GUID-A72C3172-7185-5D87-B4CB-6266AC6146A3"><title>Creating an |
|
74 RBuf</title> <p>An <xref href="GUID-BFBC574B-EFF6-37A4-9189-B71DA1505BC8.dita"><apiname>RBuf</apiname></xref> object behaves like a handle to |
|
75 a resource. In this case, the resource is the buffer that contains the data. |
|
76 While this might seem to be an implementation issue, you need to understand |
|
77 that much of the interface provided by the <codeph>RBuf</codeph> class itself |
|
78 is involved in allocating, freeing and resizing this buffer. </p> <p>An <codeph>RBuf</codeph> object |
|
79 can: </p> <ul> |
|
80 <li id="GUID-38116609-9E75-57B4-9F34-FEC8AD3AA285"><p>be placed on the program |
|
81 stack. </p> </li> |
|
82 <li id="GUID-FD4007BC-6EA8-5DC0-B61E-59B2BA17B5C2"><p>be a member of another |
|
83 'C' type class. </p> </li> |
|
84 </ul> <p>An <codeph>RBuf</codeph> object cannot be a member of a 'T' type |
|
85 class. </p> <p>See also <xref href="GUID-2458916B-55B2-5E08-A825-4EBDB3503E67.dita">Class |
|
86 types</xref>. </p> <p>The default constructor does not allocate a buffer, |
|
87 and means that, by default, the object represents no data. In descriptor terminology, |
|
88 its length is zero and its maximum length is zero. </p> <p>Before an <codeph>RBuf</codeph> can |
|
89 hold any data, you need to create the buffer. </p> <ul> |
|
90 <li id="GUID-8BD20341-B902-5BD2-B121-3596432F4CC9"><p> <xref href="GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A.dita#GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A/GUID-A15FC714-C2D3-51F9-A336-4043F9F6DA1C">Simple construction</xref> </p> </li> |
|
91 <li id="GUID-7EFD2DA7-C50D-54E8-9343-FC26F07387CD"><p> <xref href="GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A.dita#GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A/GUID-82460E76-D738-51BD-AC7F-29C2CA54C597">More advanced construction</xref> </p> </li> |
|
92 <li id="GUID-3A9847B8-8741-5543-B5B2-D7FEB1EB3C4A"><p> <xref href="GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A.dita#GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A/GUID-19A5BFF9-0B7E-54C1-BC27-2F69B65FAC47">Creating an RBuf from an existing descriptor</xref> </p> </li> |
|
93 <li id="GUID-BDE8E0A0-0FF6-5BF2-B276-9B9750DDA383"><p> <xref href="GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A.dita#GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A/GUID-2C934B0F-97D7-5118-A6C4-7CE375F6E0F7">Creating an RBuf by transferring ownership of a pre-existing buffer</xref> </p> </li> |
|
94 </ul> <p id="GUID-A15FC714-C2D3-51F9-A336-4043F9F6DA1C"><b>Simple construction</b> </p> <p>The |
|
95 simplest way to create the buffer is to use the <codeph>Create()</codeph> or |
|
96 the <codeph>CreateL()</codeph> member functions of <xref href="GUID-BFBC574B-EFF6-37A4-9189-B71DA1505BC8.dita"><apiname>RBuf</apiname></xref> [See <xref href="GUID-BEFF9C91-DA64-3032-96E8-F5054405DC74.dita#GUID-BEFF9C91-DA64-3032-96E8-F5054405DC74/GUID-E5E4895B-4BA2-3EB1-AB7E-D676374F12E2"><apiname>RBuf16::Create()</apiname></xref> and <xref href="GUID-BEFF9C91-DA64-3032-96E8-F5054405DC74.dita#GUID-BEFF9C91-DA64-3032-96E8-F5054405DC74/GUID-AE30A4E2-0F85-32F3-A4A7-3A8FF8A5B856"><apiname>RBuf16::CreateL()</apiname></xref>]. </p> <p>For example, the following code fragment constructs a resizable |
|
97 buffer descriptor that can hold up to 15 data items. In descriptor terminology, |
|
98 this means that the maximum length is set to 15. The current length of the |
|
99 descriptor is set to zero, i.e. it contains no data. </p> <codeblock id="GUID-CA817431-E554-5BBA-994F-BDE6FD30B802" xml:space="preserve">RBuf buf; |
|
100 ... |
|
101 buf.CreateL(15); |
|
102 ...</codeblock> <p>Note that <codeph>CreateL()</codeph> is similar to <codeph>Create()</codeph>, |
|
103 but leaves if memory cannot be allocated. </p> <p id="GUID-82460E76-D738-51BD-AC7F-29C2CA54C597"><b>More advanced construction</b> </p> <p>A |
|
104 variation on the simple creation technique is to use the <codeph>CreateMax()</codeph> or |
|
105 the <codeph>CreateMaxL()</codeph> member functions of <xref href="GUID-BFBC574B-EFF6-37A4-9189-B71DA1505BC8.dita"><apiname>RBuf</apiname></xref> [See <xref href="GUID-BEFF9C91-DA64-3032-96E8-F5054405DC74.dita#GUID-BEFF9C91-DA64-3032-96E8-F5054405DC74/GUID-E5E4895B-4BA2-3EB1-AB7E-D676374F12E2"><apiname>RBuf16::Create()</apiname></xref> and <xref href="GUID-BEFF9C91-DA64-3032-96E8-F5054405DC74.dita#GUID-BEFF9C91-DA64-3032-96E8-F5054405DC74/GUID-AE30A4E2-0F85-32F3-A4A7-3A8FF8A5B856"><apiname>RBuf16::CreateL()</apiname></xref>]. </p> <p>These functions not only allocate the buffer, but set the current |
|
106 length of the data to be the same as the maximum length. For example: </p> <codeblock id="GUID-C2FA200E-5D22-5A6D-B192-04B83509D9ED" xml:space="preserve">RBuf buf; |
|
107 ... |
|
108 buf.CreateMaxL(15); |
|
109 ...</codeblock> <p>No data has been assigned to the descriptor, and in effect |
|
110 it contains "arbitrary" data. However, this can be useful in cases where the |
|
111 descriptor needs to have a current length before calling another function. |
|
112 For example, you might want a buffer of 16 bytes initialised to binary zeroes: </p> <codeblock id="GUID-C0B7F0CA-A5D9-5E9E-8DEE-C8BB983B5D4F" xml:space="preserve">RBuf8 buf; |
|
113 ... |
|
114 buf.CreateMaxL(15); |
|
115 buf.Fillz(); |
|
116 ...</codeblock> <p> <codeph>FillZ()</codeph> provided by the <xref href="GUID-445B19E5-E2EE-32E2-8D6C-C7D6A9B3C507.dita"><apiname>TDes8</apiname></xref> base |
|
117 class, sets the data to binary zeroes for the length of the descriptor, 15 |
|
118 bytes in this example. Note that we have explicitly used the 8-bit variant |
|
119 here. </p> <p>There are other ways of achieving this, but this is an economical |
|
120 technique. </p> <p id="GUID-19A5BFF9-0B7E-54C1-BC27-2F69B65FAC47"><b>Creating an RBuf from an |
|
121 existing descriptor</b> </p> <p>A common requirement is to create an <xref href="GUID-BFBC574B-EFF6-37A4-9189-B71DA1505BC8.dita"><apiname>RBuf</apiname></xref> and |
|
122 to copy the data from an existing descriptor of any type. <codeph>RBuf</codeph> provides |
|
123 variants of <codeph>Create()</codeph> and <codeph>CreateL()</codeph> to do |
|
124 this. </p> <p>In the following code fragment, a <xref href="GUID-0B9C8884-6BFF-35E2-AA6F-E4057B85AFCF.dita"><apiname>TBuf</apiname></xref> descriptor |
|
125 is passed to a function, which then passes it to this <codeph>CreateL()</codeph> variant. |
|
126 The source descriptor has a maximum length of 15, which means that the <codeph>RBuf</codeph> buffer |
|
127 is allocated so that the <codeph>RBuf</codeph> maximum length is also 15. </p> <p>The |
|
128 content of the source descriptor is copied into the <codeph>RBuf</codeph>, |
|
129 and the length of the <codeph>RBuf</codeph> (i.e. the length of data that |
|
130 the descriptor represents) is set to be the same as that of the source descriptor |
|
131 - in this case 11. </p> <codeblock id="GUID-4961B664-D22A-5086-97B4-C52E8EB96101" xml:space="preserve">_LIT(KSampleText,"Hello World"); |
|
132 ... |
|
133 TBuf<15> sampletext(KSampleText); |
|
134 FuncL(sampletext); |
|
135 ... |
|
136 void FuncL(TDesC& aSource) |
|
137 { |
|
138 RBuf buf; |
|
139 |
|
140 buf.CreateL(aSource); |
|
141 ... |
|
142 } |
|
143 </codeblock> <p>The following code fragment constructs a resizable buffer |
|
144 descriptor and copies data from a source descriptor. The length of data copied |
|
145 is limited by the value of the second parameter. If this is less than the |
|
146 length of the source descriptor, then only this length of data is copied. |
|
147 The buffer allocated is large enough to contain data of length specified by |
|
148 this second parameter. </p> <p>This is often used in cases where the length |
|
149 of the source data is not easily predictable, and it is important to limit |
|
150 the size of the <codeph>RBuf</codeph> buffer created. </p> <p>There are two |
|
151 possibilities in this code fragment : </p> <ul> |
|
152 <li id="GUID-90C4F9FE-BE4B-52B1-96F6-89803743D065"><p>if the length of <codeph>aSource</codeph> is |
|
153 20, then the maximum length of <codeph>buf</codeph> is limited to 10, only |
|
154 half the data in <codeph>aSource</codeph> is copied, and the length of <codeph>buf</codeph> is |
|
155 set to 10. </p> </li> |
|
156 <li id="GUID-1FF37B48-27C9-5B60-8443-46633F609548"><p>if the length of <codeph>aSource</codeph> is |
|
157 8, then the maximum length of <codeph>buf</codeph> is still set to 10; all |
|
158 8 items are copied, and the length of <codeph>buf</codeph> is set to 8. </p> </li> |
|
159 </ul> <codeblock id="GUID-A7309735-947B-57AF-9EA3-F2721EBFDDBD" xml:space="preserve">void FuncL(TDesC& aSource) |
|
160 { |
|
161 RBuf buf; |
|
162 ... |
|
163 buf.CreateL(aSource,10); |
|
164 ... |
|
165 } |
|
166 </codeblock> <p id="GUID-2C934B0F-97D7-5118-A6C4-7CE375F6E0F7"><b>Creating an RBuf by transferring |
|
167 ownership of a pre-existing buffer</b> </p> <p>An important technique is to |
|
168 create an <xref href="GUID-BFBC574B-EFF6-37A4-9189-B71DA1505BC8.dita"><apiname>RBuf</apiname></xref> and transfer ownership of existing allocated |
|
169 memory to it. This allows any data in that block of memory to be managed through |
|
170 the <codeph>RBuf</codeph>. </p> <p>There are three main cases to consider: </p> <ul> |
|
171 <li id="GUID-E5C30864-1E72-54EC-B321-3A5F27D5A590"><p>transferring ownership |
|
172 of a preexisting heap descriptor, an <xref href="GUID-A103FB19-60B3-3E45-97A5-1F295934ACA1.dita"><apiname>HBufC</apiname></xref> type. </p> </li> |
|
173 <li id="GUID-9E7CC922-7B86-5044-A5D7-CFCB76617312"><p>transferring ownership |
|
174 of allocated memory </p> </li> |
|
175 <li id="GUID-45EDF081-0E89-50EE-96D7-4E2FF28993B3"><p>transferring ownership |
|
176 of the buffer owned by a different <codeph>RBuf</codeph>. </p> </li> |
|
177 </ul> <p id="GUID-11BEB9E8-CE72-5DF8-869E-2C2FF9E43A35"><b> Transferring ownership |
|
178 of an HBufC</b> </p> <p>This is a mechanism you would use if an existing API |
|
179 returned an <xref href="GUID-A103FB19-60B3-3E45-97A5-1F295934ACA1.dita"><apiname>HBufC</apiname></xref>, and you wanted to deal with its data |
|
180 through an <xref href="GUID-BFBC574B-EFF6-37A4-9189-B71DA1505BC8.dita"><apiname>RBuf</apiname></xref> instead. </p> <p>The following code fragment |
|
181 shows how this could be done. Note that the <codeph>HBufC</codeph> pointer |
|
182 is passed to the <codeph>RBuf</codeph> constructor. </p> <p>Following construction, |
|
183 ownership of the heap descriptor has been passed to the <codeph>RBuf</codeph> object. |
|
184 In descriptor terminology, the maximum length of the <codeph>RBuf</codeph> is |
|
185 15, and its length is 11, reflecting the state of the original <codeph>HBufC</codeph> object. </p> <p>You |
|
186 can now manipulate any data that may have been assigned to the original <codeph>HBufC</codeph>, |
|
187 through the functions in the <codeph>RBuf</codeph> base classes. </p> <codeblock id="GUID-C5351B54-85D9-5E98-A781-F9B00A06A87D" xml:space="preserve">HBufC* hptr; |
|
188 _LIT(KSampleText,"Hello World"); |
|
189 ... |
|
190 hptr = HBufC::NewL(15); // Creates a heap descriptor which can hold up |
|
191 ... // to 15 data items. The current length is zero. |
|
192 *hptr = KSampleText; // Assigns some data to the heap descriptor. |
|
193 ... // The current length of the heap descriptor is now 11. |
|
194 RBuf buf(hptr); // Ownership of the heap descriptor is passed |
|
195 ... // to the RBuf during construction of the RBuf. |
|
196 </codeblock> <p>There is an alternative technique that allows you to assign |
|
197 ownership of the <codeph>HBufC</codeph> <i>after</i> construction of the <codeph>RBuf</codeph> using |
|
198 the <codeph>Assign()</codeph> function. This allows you to reuse the same <codeph>RBuf</codeph> object. |
|
199 For example: </p> <codeblock id="GUID-DE70696E-3E46-5377-8A10-6141BF58DB1B" xml:space="preserve">HBufC* hptr; |
|
200 _LIT(KSampleText,"Hello World"); |
|
201 ... |
|
202 hptr = HBufC::NewL(15); // Creates a heap descriptor which can hold up |
|
203 ... // to 15 data items. The current length is zero. |
|
204 *hptr = KSampleText; // Assigns some data to the heap descriptor. |
|
205 ... // The current length of the heap descriptor is now 11. |
|
206 RBuf buf; |
|
207 ... |
|
208 buf.Assign(hptr); // Ownership of the heap descriptor is passed |
|
209 ... // to the RBuf after construction of the RBuf. |
|
210 </codeblock> <p>Once ownership has been transferred, you must not access the |
|
211 data through the original <codeph>HBufC</codeph> pointer. </p> <p>There is |
|
212 no mechanism for reversing the transfer of ownership. The freeing of the buffer |
|
213 can only be done through the <codeph>RBuf</codeph>. See <xref href="GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A.dita#GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A/GUID-A6368F43-9A67-5583-B279-FE68B8CADEC4">Freeing the buffer</xref>. </p> <p><b>Transferring |
|
214 ownership of allocated memory</b> </p> <p>In the following code fragment, <codeph>ptr</codeph> is |
|
215 assumed to contain the address of memory previously allocated. The code fragment |
|
216 shows how ownership of this memory can be transferred to the <codeph>RBuf</codeph>. </p> <codeblock id="GUID-B9FCCFE5-A448-598A-A1F2-DAEB1563274D" xml:space="preserve">TUint16* ptr; |
|
217 TInt length(32); |
|
218 ... // Assume memory of length 32 has been allocated |
|
219 // and its address stored in ptr. |
|
220 |
|
221 RBuf buf; |
|
222 ... |
|
223 buf.Assign(ptr,length); |
|
224 ... // The memory passed to the descriptor becomes the |
|
225 // descriptor's buffer. In descriptor terminology, |
|
226 // the maximum length of the RBuf is 32; its length |
|
227 // is zero, meaning that the descriptor represents |
|
228 // no data. |
|
229 </codeblock> <p><b> Transferring |
|
230 ownership of the buffer owned by a different RBuf</b> </p> <p>In the following |
|
231 code fragment, an <codeph>RBuf</codeph> is created, a buffer created for it, |
|
232 and then ownership is transferred to another <codeph>RBuf</codeph>. </p> <codeblock id="GUID-4A96EC93-A868-5463-8FED-E849BF0B7A00" xml:space="preserve">RBuf bufSource; |
|
233 RBuf bufTarget; |
|
234 ... |
|
235 bufSource.CreateL(15); // Creates memory buffer for the descriptor |
|
236 // that can hold up to 15 data items. In descriptor |
|
237 // terminology, the maximum length is set to 15 and |
|
238 // the current length is set to 0. |
|
239 |
|
240 bufTarget.Assign(bufSource); // Transfers ownership of the memory buffer |
|
241 // to the bufTarget descriptor. |
|
242 ...</codeblock> </section> |
|
243 <section id="GUID-2B23F296-D414-5ABD-82CA-DDCEE2F48459"><title>Re-allocating |
|
244 the memory buffer</title> <p>You can change the size of the memory buffer, |
|
245 by using the <codeph>ReAlloc()</codeph> or <codeph>ReAllocL()</codeph> member |
|
246 functions of <codeph>RBuf</codeph>. </p> <p>It does not matter how the original |
|
247 buffer was allocated, whether directly via <codeph>Create()</codeph>, <codeph>CreateL()</codeph>, <codeph>CreateMax()</codeph> or <codeph>CReateMaxL()</codeph>, or by transfer of ownership of an existing buffer (and this includes transfer |
|
248 from an <codeph>HBufC</codeph>). You do this if you intend to increase (or |
|
249 significantly decrease) the amount of data that the descriptor is to represent. |
|
250 Remember that the amount of memory allocated to the buffer is not automatically |
|
251 changed in response to changes in the amount of data. </p> <p>In the following |
|
252 code fragment, an <codeph>RBuf</codeph> is created by copying from an existing |
|
253 descriptor. It is then reallocated so that its maximum length is doubled. |
|
254 Error conditions, such as out-of-memory conditions are ignored. </p> <codeblock id="GUID-198E0563-2A7E-52B1-A46E-8A1AD5263234" xml:space="preserve">_LIT(KSampleText,"Hello World"); |
|
255 ... |
|
256 TBuf<15> sampletext(KSampleText); |
|
257 FuncL(sampletext); |
|
258 ... |
|
259 void FuncL(TDesC& aSource) |
|
260 { |
|
261 RBuf buf; |
|
262 Tint max; |
|
263 |
|
264 buf.CreateL(aSource); // max size is 15, length is 11. |
|
265 max = buf.MaxLength() * 2; |
|
266 buf.ReallocL(max); // max size is now 30, but length is still 11. |
|
267 ... |
|
268 } |
|
269 </codeblock> </section> |
|
270 <section id="GUID-A6368F43-9A67-5583-B279-FE68B8CADEC4"><title>Freeing the |
|
271 buffer</title> <p>You can free the memory buffer by calling <codeph>ReAlloc()</codeph> or <codeph>ReAllocL()</codeph> and |
|
272 passing a zero value. </p> <codeblock id="GUID-DCC63874-8DAF-530A-9BA4-F7559E773BEC" xml:space="preserve">_LIT(KSampleText,"Hello World"); |
|
273 ... |
|
274 TBuf<15> sampletext(KSampleText); |
|
275 FuncL(sampletext); |
|
276 ... |
|
277 void FuncL(TDesC& aSource) |
|
278 { |
|
279 RBuf buf; |
|
280 |
|
281 buf.CreateL(aSource); // max size is 15, length is 11. |
|
282 buf.ReallocL(0); // max size is now 0, length is 0, the memory |
|
283 // buffer has been freed, and data |
|
284 // has been thrown away. |
|
285 ... |
|
286 } |
|
287 </codeblock> <p>You can also use the <codeph>Close()</codeph> member function |
|
288 of <codeph>RBuf</codeph>. For example: </p> <codeblock id="GUID-2D298A5F-FFB4-584C-9D9C-58A95A88E078" xml:space="preserve">_LIT(KSampleText,"Hello World"); |
|
289 ... |
|
290 TBuf<15> sampletext(KSampleText); |
|
291 FuncL(sampletext); |
|
292 ... |
|
293 void FuncL(TDesC& aSource) |
|
294 { |
|
295 RBuf buf; |
|
296 |
|
297 buf.CreateL(aSource); // max size is 15, length is 11. |
|
298 buf.Close(); // max size is now 0, length is 0, the memory |
|
299 // buffer has been freed, and data |
|
300 // has been thrown away. |
|
301 ... |
|
302 } |
|
303 </codeblock> </section> |
|
304 <section id="GUID-7ECF515D-D538-5F6C-B2A0-88C1B4E3505C"><title>Cleanup rules</title> <ul> |
|
305 <li id="GUID-38476044-1EB5-5488-93A0-CB2C7D2D38B4"><p>To avoid memory leaks |
|
306 when the <codeph>RBuf</codeph> object is placed on the stack, you should use |
|
307 the following programming pattern: </p> <codeblock id="GUID-1B602EF6-BAAC-5F4F-AFF2-B8C2102687D5" xml:space="preserve">{ |
|
308 RBuf buf; |
|
309 buf.CleanupClosePushL(); |
|
310 ... // Use the RBuf |
|
311 CleanupStack::PopAndDestroy() //remove from cleanup stack |
|
312 // and free the buffer to avoid memory |
|
313 }</codeblock> <p>The <codeph>CleanupClosePushL()</codeph> function puts a |
|
314 cleanup item onto the cleanup stack. The effect of this is to cause the class's <xref href="GUID-01D2AF56-21E1-3FF3-BF86-0C356A1658EF.dita"><apiname>Close()</apiname></xref> function |
|
315 to be called in the event of a leave occurring. In its turn, <codeph>Close()</codeph> simply |
|
316 frees off the buffer. </p> </li> |
|
317 <li id="GUID-E285FB76-1079-5F34-8CC5-CE1A5AC39E70"><p>If an <codeph>RBuf</codeph> is |
|
318 a member of a class, then that class's destructor must remember to call either |
|
319 : <codeph>ReAllocL(0)</codeph> or <codeph>Close()</codeph>. </p> </li> |
|
320 <li id="GUID-4B09CAD1-6E16-5FB6-9574-277CE75A48C7"><p>An <codeph>RBuf</codeph> can |
|
321 be reused, but you must remember to call either : <codeph>ReAllocL(0)</codeph> or <codeph>Close()</codeph> before |
|
322 you assign other memory or another <codeph>HBufC</codeph>. Failure to do this |
|
323 will result in a memory leak. </p> </li> |
|
324 <li id="GUID-433E518F-A96F-5EB8-A2BF-DC4D213A2CF0"><p>You should not use an <codeph>RBuf</codeph> as |
|
325 a member of a 'T' type class. See <xref href="GUID-2458916B-55B2-5E08-A825-4EBDB3503E67.dita">Class |
|
326 types</xref>. </p> </li> |
|
327 </ul> </section> |
|
328 <section id="GUID-6732B0A9-4E6E-50A8-9C4F-ADB2BB8FBAEF"><title>Replacing and |
|
329 modifying data</title> <p>Data in an <codeph>RBuf</codeph> descriptor can |
|
330 be replaced. It can also be modified using the standard functionality provided |
|
331 by the <xref href="GUID-49D4E917-57EA-39AE-8941-144AA8AC2584.dita"><apiname>TDes</apiname></xref> base class. </p> <codeblock id="GUID-A507DCDF-F440-51B0-B6CE-86993FE5D7AB" xml:space="preserve">_LIT(KSampleText,"Hello World"); |
|
332 ... |
|
333 TBuf<15> sampletext(KSampleText); |
|
334 FuncL(sampletext); |
|
335 ... |
|
336 void FuncL(TDesC& aSource) |
|
337 { |
|
338 RBuf buf; |
|
339 |
|
340 buf.CreateL(aSource.MaxLength()); // Create the RBuf. |
|
341 buf = aSource; // Copy "Hello World" using the assignment |
|
342 // operator. |
|
343 |
|
344 buf.Delete(1,1); // Delete the 1st character. |
|
345 ... |
|
346 buf.Close(); |
|
347 } |
|
348 </codeblock> </section> |
|
349 </conbody></concept> |