Symbian3/SDK/Source/GUID-4AC3CC42-6E8D-584A-AA39-84B5E0F3C16A.dita
changeset 7 51a74ef9ed63
parent 0 89d6a7a84779
equal deleted inserted replaced
6:43e37759235e 7:51a74ef9ed63
       
     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&amp;</codeph> parameter, and a <codeph>TDes&amp;</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&lt;15&gt; sampletext(KSampleText);
       
   134 FuncL(sampletext);
       
   135 ...
       
   136 void FuncL(TDesC&amp; 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&amp; 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&lt;15&gt; sampletext(KSampleText);
       
   257 FuncL(sampletext);
       
   258 ...
       
   259 void FuncL(TDesC&amp; 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&lt;15&gt; sampletext(KSampleText);
       
   275 FuncL(sampletext);
       
   276 ...
       
   277 void FuncL(TDesC&amp; 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&lt;15&gt; sampletext(KSampleText);
       
   291 FuncL(sampletext);
       
   292 ...
       
   293 void FuncL(TDesC&amp; 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&lt;15&gt; sampletext(KSampleText);
       
   334 FuncL(sampletext);
       
   335 ...
       
   336 void FuncL(TDesC&amp; 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>