Symbian3/SDK/Source/GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A.dita
author Dominic Pinkman <dominic.pinkman@nokia.com>
Tue, 20 Jul 2010 12:00:49 +0100
changeset 13 48780e181b38
parent 0 89d6a7a84779
permissions -rw-r--r--
Week 28 contribution of SDK documentation content. See release notes for details. Fixes bugs Bug 1897 and Bug 1522.

<?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 id="GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A" xml:lang="en"><title>How to
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>
<p>A resizable buffer descriptor is an <xref href="GUID-BFBC574B-EFF6-37A4-9189-B71DA1505BC8.dita"><apiname>RBuf</apiname></xref> type. Use the
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
change the data in the descriptor. See <xref href="GUID-C85B4EA2-0184-52AF-B097-152E4A023CEF.dita">Abstract
base descriptor classes</xref>. </p>
<p>This buffer of the descriptor is put on the heap. The buffer is the place
where the data is put. This is useful if you do not know the maximum size
of the data until run time. </p>
<p>The resizable buffer descriptors are similar to what are called <xref href="GUID-2762FDF6-F76D-5268-AE2D-4ABA807CFFEE.dita">Heap
descriptors</xref>, or <xref href="GUID-A103FB19-60B3-3E45-97A5-1F295934ACA1.dita"><apiname>HBufC</apiname></xref> types, but the API provided
by <codeph>RBuf</codeph> is easier to use. The <codeph>RBuf</codeph> API also
makes it easier to change the maximum size of the buffer containing the data,
a task often referred to as reallocating the buffer. </p>
<p>The general guidelines are: use <xref href="GUID-A103FB19-60B3-3E45-97A5-1F295934ACA1.dita"><apiname>HBufC</apiname></xref> descriptors to
contain data that rarely changes; use <xref href="GUID-BFBC574B-EFF6-37A4-9189-B71DA1505BC8.dita"><apiname>RBuf</apiname></xref> descriptors
to contain data that changes frequently. However, in practice, <codeph>RBuf</codeph> types
are equally suitable for both cases, and you should <i>always consider</i> using
an <codeph>RBuf</codeph> in preference to an <codeph>HBufC</codeph>. </p>
<p>For cases where your code uses APIs that return an <codeph>HBufC</codeph> type,
you can convert this to an <codeph>RBuf</codeph>. In effect, <codeph>RBuf</codeph> can
act as a wrapper around the <codeph>HBufC</codeph>; access and manipulation
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
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>
<p>Some key points about resizable buffer descriptors: </p>
<ul>
<li id="GUID-C9051973-DFA3-57E6-8AD2-E6E1B49B0A74"><p>For text data, it is
usual to construct an <codeph>RBuf</codeph> type and allow the appropriate
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
be selected at build time. </p> </li>
<li id="GUID-93CD2C60-ABB6-5063-8CCA-B63B09139A3F"><p>For binary data, an
explicit <xref href="GUID-955061A8-A83E-39E5-8745-8FAC7DEA7BCC.dita"><apiname>RBuf8</apiname></xref> is used. </p> </li>
<li id="GUID-82B1C228-51A3-5FED-9797-206805BD3DA5"><p>It is rare to use an
explicit <xref href="GUID-BEFF9C91-DA64-3032-96E8-F5054405DC74.dita"><apiname>RBuf16</apiname></xref>. </p> </li>
<li id="GUID-2F339945-4741-59A1-AEAA-B405379E25DB"><p>Data can be changed
through <codeph>RBuf</codeph> as well as replaced using its assignment operators.
Like all descriptors, <codeph>RBuf</codeph> is derived from: </p> <ul>
<li id="GUID-7145D7BB-ABCC-5BF8-B367-6D8F9C308AF9"><p>the <xref href="GUID-49D4E917-57EA-39AE-8941-144AA8AC2584.dita"><apiname>TDes</apiname></xref> class,
through which the data can be manipulated </p> </li>
<li id="GUID-18DF3A17-15E7-54C7-8E3D-1A968AD46D14"><p>the <xref href="GUID-52D07F46-2162-380C-A775-C3BB335C42F5.dita"><apiname>TDesC</apiname></xref> class,
through which information about the data (such as its length) can be retrieved. </p> </li>
</ul> </li>
<li id="GUID-F2EE3065-3D20-5D2B-9887-2C2181FB0195"><p>You can pass an <codeph>RBuf</codeph> to
a function that takes a <codeph>TDesC&amp;</codeph> parameter, and a <codeph>TDes&amp;</codeph> parameter. </p> </li>
<li id="GUID-83C851DA-BC8C-543D-9987-656FA19832C2"><p>Memory that has already
been allocated by your code can be transferred to an <codeph>RBuf</codeph>.
This allows any data that may be in that location to be managed through the
descriptor. </p> </li>
<li id="GUID-6C6B51EE-486C-5ED1-A343-F6777DB5D130"><p>Ownership of an existing <codeph>HBufC</codeph> can
be transferred to an <codeph>RBuf</codeph>. This allows the data contained
within the <codeph>HBufC</codeph> to be managed through the <codeph>RBuf</codeph> API. </p> </li>
</ul>
<p>Although the following notes refer to the build independent types, they
are equally valid for the explicit 8-bit and 16-bit types. </p>
<ul>
<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>
<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>
<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>
<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>
<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>
</ul>
<section id="GUID-A72C3172-7185-5D87-B4CB-6266AC6146A3"><title>Creating an
RBuf</title> <p>An <xref href="GUID-BFBC574B-EFF6-37A4-9189-B71DA1505BC8.dita"><apiname>RBuf</apiname></xref> object behaves like a handle to
a resource. In this case, the resource is the buffer that contains the data.
While this might seem to be an implementation issue, you need to understand
that much of the interface provided by the <codeph>RBuf</codeph> class itself
is involved in allocating, freeing and resizing this buffer. </p> <p>An <codeph>RBuf</codeph> object
can: </p> <ul>
<li id="GUID-38116609-9E75-57B4-9F34-FEC8AD3AA285"><p>be placed on the program
stack. </p> </li>
<li id="GUID-FD4007BC-6EA8-5DC0-B61E-59B2BA17B5C2"><p>be a member of another
'C' type class. </p> </li>
</ul> <p>An <codeph>RBuf</codeph> object cannot be a member of a 'T' type
class. </p> <p>See also <xref href="GUID-2458916B-55B2-5E08-A825-4EBDB3503E67.dita">Class
types</xref>. </p> <p>The default constructor does not allocate a buffer,
and means that, by default, the object represents no data. In descriptor terminology,
its length is zero and its maximum length is zero. </p> <p>Before an <codeph>RBuf</codeph> can
hold any data, you need to create the buffer. </p> <ul>
<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>
<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>
<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>
<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>
</ul> <p id="GUID-A15FC714-C2D3-51F9-A336-4043F9F6DA1C"><b>Simple construction</b> </p> <p>The
simplest way to create the buffer is to use the <codeph>Create()</codeph> or
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
buffer descriptor that can hold up to 15 data items. In descriptor terminology,
this means that the maximum length is set to 15. The current length of the
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;
...
buf.CreateL(15);
...</codeblock> <p>Note that <codeph>CreateL()</codeph> is similar to <codeph>Create()</codeph>,
but leaves if memory cannot be allocated. </p> <p id="GUID-82460E76-D738-51BD-AC7F-29C2CA54C597"><b>More advanced construction</b> </p> <p>A
variation on the simple creation technique is to use the <codeph>CreateMax()</codeph> or
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
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;
...
buf.CreateMaxL(15);
...</codeblock> <p>No data has been assigned to the descriptor, and in effect
it contains "arbitrary" data. However, this can be useful in cases where the
descriptor needs to have a current length before calling another function.
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;
...
buf.CreateMaxL(15);
buf.Fillz();
...</codeblock> <p> <codeph>FillZ()</codeph> provided by the <xref href="GUID-445B19E5-E2EE-32E2-8D6C-C7D6A9B3C507.dita"><apiname>TDes8</apiname></xref> base
class, sets the data to binary zeroes for the length of the descriptor, 15
bytes in this example. Note that we have explicitly used the 8-bit variant
here. </p> <p>There are other ways of achieving this, but this is an economical
technique. </p> <p id="GUID-19A5BFF9-0B7E-54C1-BC27-2F69B65FAC47"><b>Creating an RBuf from an
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
to copy the data from an existing descriptor of any type. <codeph>RBuf</codeph> provides
variants of <codeph>Create()</codeph> and <codeph>CreateL()</codeph> to do
this. </p> <p>In the following code fragment, a <xref href="GUID-0B9C8884-6BFF-35E2-AA6F-E4057B85AFCF.dita"><apiname>TBuf</apiname></xref> descriptor
is passed to a function, which then passes it to this <codeph>CreateL()</codeph> variant.
The source descriptor has a maximum length of 15, which means that the <codeph>RBuf</codeph> buffer
is allocated so that the <codeph>RBuf</codeph> maximum length is also 15. </p> <p>The
content of the source descriptor is copied into the <codeph>RBuf</codeph>,
and the length of the <codeph>RBuf</codeph> (i.e. the length of data that
the descriptor represents) is set to be the same as that of the source descriptor
- in this case 11. </p> <codeblock id="GUID-4961B664-D22A-5086-97B4-C52E8EB96101" xml:space="preserve">_LIT(KSampleText,"Hello World");
...
TBuf&lt;15&gt; sampletext(KSampleText);
FuncL(sampletext);
...
void FuncL(TDesC&amp; aSource)
    {
    RBuf buf;

    buf.CreateL(aSource);
    ...
    }
</codeblock> <p>The following code fragment constructs a resizable buffer
descriptor and copies data from a source descriptor. The length of data copied
is limited by the value of the second parameter. If this is less than the
length of the source descriptor, then only this length of data is copied.
The buffer allocated is large enough to contain data of length specified by
this second parameter. </p> <p>This is often used in cases where the length
of the source data is not easily predictable, and it is important to limit
the size of the <codeph>RBuf</codeph> buffer created. </p> <p>There are two
possibilities in this code fragment : </p> <ul>
<li id="GUID-90C4F9FE-BE4B-52B1-96F6-89803743D065"><p>if the length of <codeph>aSource</codeph> is
20, then the maximum length of <codeph>buf</codeph> is limited to 10, only
half the data in <codeph>aSource</codeph> is copied, and the length of <codeph>buf</codeph> is
set to 10. </p> </li>
<li id="GUID-1FF37B48-27C9-5B60-8443-46633F609548"><p>if the length of <codeph>aSource</codeph> is
8, then the maximum length of <codeph>buf</codeph> is still set to 10; all
8 items are copied, and the length of <codeph>buf</codeph> is set to 8. </p> </li>
</ul> <codeblock id="GUID-A7309735-947B-57AF-9EA3-F2721EBFDDBD" xml:space="preserve">void FuncL(TDesC&amp; aSource)
    {
    RBuf buf;
    ...
    buf.CreateL(aSource,10);
    ...
    }
</codeblock> <p id="GUID-2C934B0F-97D7-5118-A6C4-7CE375F6E0F7"><b>Creating an RBuf by transferring
ownership of a pre-existing buffer</b> </p> <p>An important technique is to
create an <xref href="GUID-BFBC574B-EFF6-37A4-9189-B71DA1505BC8.dita"><apiname>RBuf</apiname></xref> and transfer ownership of existing allocated
memory to it. This allows any data in that block of memory to be managed through
the <codeph>RBuf</codeph>. </p> <p>There are three main cases to consider: </p> <ul>
<li id="GUID-E5C30864-1E72-54EC-B321-3A5F27D5A590"><p>transferring ownership
of a preexisting heap descriptor, an <xref href="GUID-A103FB19-60B3-3E45-97A5-1F295934ACA1.dita"><apiname>HBufC</apiname></xref> type. </p> </li>
<li id="GUID-9E7CC922-7B86-5044-A5D7-CFCB76617312"><p>transferring ownership
of allocated memory </p> </li>
<li id="GUID-45EDF081-0E89-50EE-96D7-4E2FF28993B3"><p>transferring ownership
of the buffer owned by a different <codeph>RBuf</codeph>. </p> </li>
</ul> <p id="GUID-11BEB9E8-CE72-5DF8-869E-2C2FF9E43A35"><b> Transferring ownership
of an HBufC</b> </p> <p>This is a mechanism you would use if an existing API
returned an <xref href="GUID-A103FB19-60B3-3E45-97A5-1F295934ACA1.dita"><apiname>HBufC</apiname></xref>, and you wanted to deal with its data
through an <xref href="GUID-BFBC574B-EFF6-37A4-9189-B71DA1505BC8.dita"><apiname>RBuf</apiname></xref> instead. </p> <p>The following code fragment
shows how this could be done. Note that the <codeph>HBufC</codeph> pointer
is passed to the <codeph>RBuf</codeph> constructor. </p> <p>Following construction,
ownership of the heap descriptor has been passed to the <codeph>RBuf</codeph> object.
In descriptor terminology, the maximum length of the <codeph>RBuf</codeph> is
15, and its length is 11, reflecting the state of the original <codeph>HBufC</codeph> object. </p> <p>You
can now manipulate any data that may have been assigned to the original <codeph>HBufC</codeph>,
through the functions in the <codeph>RBuf</codeph> base classes. </p> <codeblock id="GUID-C5351B54-85D9-5E98-A781-F9B00A06A87D" xml:space="preserve">HBufC* hptr;
_LIT(KSampleText,"Hello World");
...
hptr = HBufC::NewL(15);    // Creates a heap descriptor which can hold up
...                        // to 15 data items. The current length is zero.
*hptr = KSampleText;     // Assigns some data to the heap descriptor.
...                        // The current length of the heap descriptor is now 11.
RBuf buf(hptr);            // Ownership of the heap descriptor is passed
...                        // to the RBuf during construction of the RBuf.
</codeblock> <p>There is an alternative technique that allows you to assign
ownership of the <codeph>HBufC</codeph>  <i>after</i> construction of the <codeph>RBuf</codeph> using
the <codeph>Assign()</codeph> function. This allows you to reuse the same <codeph>RBuf</codeph> object.
For example: </p> <codeblock id="GUID-DE70696E-3E46-5377-8A10-6141BF58DB1B" xml:space="preserve">HBufC* hptr;
_LIT(KSampleText,"Hello World");
...
hptr = HBufC::NewL(15);    // Creates a heap descriptor which can hold up
...                        // to 15 data items. The current length is zero.
*hptr = KSampleText;     // Assigns some data to the heap descriptor.
...                        // The current length of the heap descriptor is now 11.
RBuf buf;
...
buf.Assign(hptr);        // Ownership of the heap descriptor is passed
...                        // to the RBuf after construction of the RBuf.
</codeblock> <p>Once ownership has been transferred, you must not access the
data through the original <codeph>HBufC</codeph> pointer. </p> <p>There is
no mechanism for reversing the transfer of ownership. The freeing of the buffer
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
ownership of allocated memory</b> </p> <p>In the following code fragment, <codeph>ptr</codeph> is
assumed to contain the address of memory previously allocated. The code fragment
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;
TInt length(32);
...                // Assume memory of length 32 has been allocated
                // and its address stored in ptr.

RBuf buf;
...
buf.Assign(ptr,length);
...                // The memory passed to the descriptor becomes the
                // descriptor's buffer. In descriptor terminology,
                // the maximum length of the RBuf is 32; its length
                // is zero, meaning that the descriptor represents
                // no data.
</codeblock> <p><b> Transferring
ownership of the buffer owned by a different RBuf</b> </p> <p>In the following
code fragment, an <codeph>RBuf</codeph> is created, a buffer created for it,
and then ownership is transferred to another <codeph>RBuf</codeph>. </p> <codeblock id="GUID-4A96EC93-A868-5463-8FED-E849BF0B7A00" xml:space="preserve">RBuf bufSource;
RBuf bufTarget;
...
bufSource.CreateL(15);    // Creates memory buffer for the descriptor
                        // that can hold up to 15 data items. In descriptor
                        // terminology, the maximum length is set to 15 and
                        // the current length is set to 0.

bufTarget.Assign(bufSource); // Transfers ownership of the memory buffer
                             // to the bufTarget descriptor.
...</codeblock> </section>
<section id="GUID-2B23F296-D414-5ABD-82CA-DDCEE2F48459"><title>Re-allocating
the memory buffer</title> <p>You can change the size of the memory buffer,
by using the <codeph>ReAlloc()</codeph> or <codeph>ReAllocL()</codeph> member
functions of <codeph>RBuf</codeph>. </p> <p>It does not matter how the original
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
from an <codeph>HBufC</codeph>). You do this if you intend to increase (or
significantly decrease) the amount of data that the descriptor is to represent.
Remember that the amount of memory allocated to the buffer is not automatically
changed in response to changes in the amount of data. </p> <p>In the following
code fragment, an <codeph>RBuf</codeph> is created by copying from an existing
descriptor. It is then reallocated so that its maximum length is doubled.
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");
...
TBuf&lt;15&gt; sampletext(KSampleText);
FuncL(sampletext);
...
void FuncL(TDesC&amp; aSource)
    {
    RBuf buf;
    Tint max;

    buf.CreateL(aSource);    // max size is 15, length is 11.
    max = buf.MaxLength() * 2;    
    buf.ReallocL(max);        // max size is now 30, but length is still 11.
    ...
    }
</codeblock> </section>
<section id="GUID-A6368F43-9A67-5583-B279-FE68B8CADEC4"><title>Freeing the
buffer</title> <p>You can free the memory buffer by calling <codeph>ReAlloc()</codeph> or <codeph>ReAllocL()</codeph> and
passing a zero value. </p> <codeblock id="GUID-DCC63874-8DAF-530A-9BA4-F7559E773BEC" xml:space="preserve">_LIT(KSampleText,"Hello World");
...
TBuf&lt;15&gt; sampletext(KSampleText);
FuncL(sampletext);
...
void FuncL(TDesC&amp; aSource)
    {
    RBuf buf;

    buf.CreateL(aSource);    // max size is 15, length is 11.
    buf.ReallocL(0);        // max size is now 0, length is 0, the memory
                            // buffer has been freed, and data
                            // has been thrown away.
    ...
    }
</codeblock> <p>You can also use the <codeph>Close()</codeph> member function
of <codeph>RBuf</codeph>. For example: </p> <codeblock id="GUID-2D298A5F-FFB4-584C-9D9C-58A95A88E078" xml:space="preserve">_LIT(KSampleText,"Hello World");
...
TBuf&lt;15&gt; sampletext(KSampleText);
FuncL(sampletext);
...
void FuncL(TDesC&amp; aSource)
    {
    RBuf buf;

    buf.CreateL(aSource);    // max size is 15, length is 11.
    buf.Close();            // max size is now 0, length is 0, the memory
                            // buffer has been freed, and data
                            // has been thrown away.
    ...
    }
</codeblock> </section>
<section id="GUID-7ECF515D-D538-5F6C-B2A0-88C1B4E3505C"><title>Cleanup rules</title> <ul>
<li id="GUID-38476044-1EB5-5488-93A0-CB2C7D2D38B4"><p>To avoid memory leaks
when the <codeph>RBuf</codeph> object is placed on the stack, you should use
the following programming pattern: </p> <codeblock id="GUID-1B602EF6-BAAC-5F4F-AFF2-B8C2102687D5" xml:space="preserve">{
RBuf buf;
buf.CleanupClosePushL();
...                                 // Use the RBuf
CleanupStack::PopAndDestroy()    //remove from cleanup stack
                                // and free the buffer to avoid memory 
}</codeblock> <p>The <codeph>CleanupClosePushL()</codeph> function puts a
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
to be called in the event of a leave occurring. In its turn, <codeph>Close()</codeph> simply
frees off the buffer. </p> </li>
<li id="GUID-E285FB76-1079-5F34-8CC5-CE1A5AC39E70"><p>If an <codeph>RBuf</codeph> is
a member of a class, then that class's destructor must remember to call either
: <codeph>ReAllocL(0)</codeph> or <codeph>Close()</codeph>. </p> </li>
<li id="GUID-4B09CAD1-6E16-5FB6-9574-277CE75A48C7"><p>An <codeph>RBuf</codeph> can
be reused, but you must remember to call either : <codeph>ReAllocL(0)</codeph> or <codeph>Close()</codeph> before
you assign other memory or another <codeph>HBufC</codeph>. Failure to do this
will result in a memory leak. </p> </li>
<li id="GUID-433E518F-A96F-5EB8-A2BF-DC4D213A2CF0"><p>You should not use an <codeph>RBuf</codeph> as
a member of a 'T' type class. See <xref href="GUID-2458916B-55B2-5E08-A825-4EBDB3503E67.dita">Class
types</xref>. </p> </li>
</ul> </section>
<section id="GUID-6732B0A9-4E6E-50A8-9C4F-ADB2BB8FBAEF"><title>Replacing and
modifying data</title> <p>Data in an <codeph>RBuf</codeph> descriptor can
be replaced. It can also be modified using the standard functionality provided
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");
...
TBuf&lt;15&gt; sampletext(KSampleText);
FuncL(sampletext);
...
void FuncL(TDesC&amp; aSource)
    {
    RBuf buf;

    buf.CreateL(aSource.MaxLength());    // Create the RBuf.
    buf = aSource;                        // Copy "Hello World" using the assignment
                                        // operator.

    buf.Delete(1,1);                    // Delete the 1st character.
    ...
    buf.Close();
    }
</codeblock> </section>
</conbody></concept>