00001 /* 00002 Copyright (c) 2002-2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 00003 00004 Redistribution and use in source and binary forms, with or without 00005 modification, are permitted provided that the following conditions are met: 00006 00007 * Redistributions of source code must retain the above copyright notice, this 00008 list of conditions and the following disclaimer. 00009 * Redistributions in binary form must reproduce the above copyright notice, 00010 this list of conditions and the following disclaimer in the documentation 00011 and/or other materials provided with the distribution. 00012 * Neither the name of Nokia Corporation nor the names of its contributors 00013 may be used to endorse or promote products derived from this software 00014 without specific prior written permission. 00015 00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00020 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00021 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00022 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00023 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00024 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00025 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 00027 Description: 00028 */ 00029 00030 #include "ArrayCreationExamples.h" 00031 #include "SharedCode.h" 00032 #include <e32test.h> 00033 00034 extern CConsoleBase* console; 00035 00036 // --------------------------------------------------------- 00037 // void TakeOwnershipL() 00038 // This example shows how to take ownership of a dynamically 00039 // allocated block of memory and assign it to an RArray 00040 // --------------------------------------------------------- 00041 // 00042 LOCAL_C void TakeOwnershipL() 00043 { 00044 TExampleStruct* values = GenerateValuesLC(); 00045 00046 // This array does not own the the memory pointer to values 00047 // rather it just creates a very quick RArray that offers 00048 // all the functionality but onto a block of User::Alloc'd 00049 // memory. 00050 // A call to User::Leave will correctly leave 00051 // as GenerateRandomumbersLC put the memory on the 00052 // cleanup stack, so at this point the RArray does not own 00053 // the memory, the "values" pointer does. 00054 RExampleArray array(sizeof(TExampleStruct), values, KMaxElements); 00055 00056 // now we want to transfer ownership of that memory block 00057 // to array, so we pop the "values" blob from the stack 00058 // and its implicitly transferred to the array 00059 // but now the array needs to put back on the cleanup stack 00060 // to prevent a memory leak as its taken ownership of the blob 00061 // 00062 // Note it might appear that PushL could leave but values would 00063 // not be on the stack. This is not the case, reading the documenation 00064 // for the cleanup stack, you will see PushL will always ensure there is 00065 // at least one element reserved at the top of the cleanup stack. It will 00066 // leave if it cannot preallocate the next element at the top of the stack 00067 00068 CleanupStack::Pop(values); 00069 CleanupClosePushL(array); 00070 00071 // you put your element manipulation code here 00072 00073 // we are finished with the array 00074 CleanupStack::PopAndDestroy(&array); 00075 } 00076 00077 // --------------------------------------------------------- 00078 // void ReserveAndAppendL() 00079 // Another way to create an array is to reserve the space 00080 // then add the items one by one 00081 // obviously inefficient but we can optimize it by 00082 // reserving the data before adding it to prevent 00083 // thrashing (using Reserve) 00084 // --------------------------------------------------------- 00085 // 00086 LOCAL_C void ReserveAndAppendL() 00087 { 00088 TExampleStruct* values = GenerateValuesLC(); 00089 00090 RExampleArray array; 00091 CleanupClosePushL(array); 00092 // Preallocate a lot of memory for all the elements 00093 User::LeaveIfError(array.Reserve(KMaxElements)); 00094 // Now copy the elements over 00095 for (TInt i=0 ;i < KMaxElements; i++) 00096 User::LeaveIfError(array.Append(values[i])); 00097 00098 CleanupStack::PopAndDestroy(2, values); 00099 } 00100 00101 // --------------------------------------------------------- 00102 // void NonAllocatingArrayL() 00103 // Example of creating an array that does not allocate memory 00104 // --------------------------------------------------------- 00105 // 00106 LOCAL_C void NonAllocatingArrayL() 00107 { 00108 static const TInt32 KInts[] = { 1, 2, 3, 4, 5}; 00109 const RArray<TInt32> array(sizeof(TInt32), (TInt32*)KInts, sizeof(KInts) / sizeof(KInts[0])); 00110 00111 // no need to put it on the cleanup stack as does not own any memory 00112 // even a leave is safe were 00113 // remember indices are zero based 00114 if (array[2] != 3) 00115 { 00116 User::Leave(KErrNotFound); 00117 } 00118 00119 00120 } 00121 // --------------------------------------------------------- 00122 // void ArrayCreationExamplesL() 00123 // Example code on creating an array 00124 // --------------------------------------------------------- 00125 // 00126 void ArrayCreationExamplesL() 00127 { 00128 console->Printf(_L("RArray usage without allocating memory\n")); 00129 NonAllocatingArrayL(); 00130 User::After(0); 00131 00132 console->Printf(_L("Taking ownership of memory and transfering it an RArray\n")); 00133 TakeOwnershipL(); 00134 User::After(0); 00135 00136 console->Printf(_L("Reserving space in the array before appending the elements\n")); 00137 ReserveAndAppendL(); 00138 User::After(0); 00139 }