examples/Base/ArraysAndLists/FixedArrays/RangeChecking.cpp

00001 /*
00002 Copyright (c) 2000-2010 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  Code to demonstrate the range checking wrapper class
00029  for C++ arrays; i.e. the TFixedArray<class T,TInt S>.
00030 */
00031 
00032 
00033 #include "CommonFramework.h"
00034 
00035 //
00036 // Definition of the TTest class
00037 //
00038 class TTest
00039         {       
00040 public:
00041         TTest();
00042         TTest(TInt aValue);
00043         void SetValue(TInt aValue);
00044         TInt GetValue() const;
00045 private :
00046         TInt     iX;
00047         TBuf<8>  iPadding; // never used in this example
00048         };
00049 
00050 TTest::TTest()
00051         : iX(1)
00052         {}
00053 
00054 TTest::TTest(TInt aValue)
00055         : iX(aValue)
00056         {}
00057 
00058 TInt TTest::GetValue() const
00059         {
00060         return iX;
00061         }
00062 
00063 void TTest::SetValue(TInt aValue)
00064         {
00065         iX = aValue;
00066         }
00067 
00068 //
00069 // Definition of the CTest class
00070 //
00071 class CTest : public CBase 
00072         {       
00073 public:
00074         static CTest* NewL(const TDesC& aText);
00075         ~CTest();
00076         void ConstructL(const TDesC& aText);
00077 private :
00078         HBufC*   iSomeText;
00079         };      
00080 
00081 CTest* CTest::NewL(const TDesC& aText)
00082         {
00083         CTest* self=new (ELeave) CTest;
00084         CleanupStack::PushL(self);
00085         self->ConstructL(aText);
00086         CleanupStack::Pop();
00087         return self;
00088         }
00089 
00090 void CTest::ConstructL(const TDesC& aText)
00091         {
00092         iSomeText = aText.AllocL();
00093         }
00094 
00095 CTest::~CTest()
00096         {
00097         delete iSomeText;
00098         }
00099 
00100 
00101 
00102 // Some source data
00103 const TTest data[] = {TTest(1),TTest(2),TTest(3),TTest(4)};
00104 
00105 //
00106 // main body of the example
00107 //
00108 static void doExampleL()
00109     {
00110 
00111         // A C++ array of 4 elements of type class TTest.
00112         //
00113         // Effectively the same as if we had explicitly
00114         // declared: TTest array[4];
00115         //
00116         TFixedArray<TTest,4> array;
00117         
00118                         
00119         //
00120         // Copy 4 elements into the array.
00121         //
00122         // We could have constructed the array by:
00123         // TFixedArray<TTest,4> array(&data[0],4);
00124         array.Copy(&data[0],4);
00125 
00126         //
00127         // Trying to execute the following call would result
00128         // in a USER 133 panic in a debug build. The range checking
00129         // stops us from trying to write to a 5th element which 
00130         // does not (legitimately) exist.
00131         //
00132         //array.Copy(&array[0],5);
00133 
00134         //
00135         // Count() should return the number of array elements, i.e. 4
00136         //
00137         _LIT(KTxtFormat1,"Array size is %d\n");
00138         console->Printf(KTxtFormat1,array.Count());
00139         
00140         //
00141         // Length() should return the size of an array element; here
00142         // that should be the size of a TTest object.
00143         //
00144         _LIT(KTxtFormat2,"Length of an array element is %d\n\n");
00145         console->Printf(KTxtFormat2,array.Length());
00146         
00147         //
00148         // Pointers to the beginning and end of the array
00149         //
00150         _LIT(KTxtFormat3,"Array ends   at ---> 0x%x\n      starts at ---> 0x%x\n");
00151         _LIT(KTxtFormat4,"Difference is decimal %d bytes (hopefully 4 times the size of TTest)\n\n");
00152         console->Printf(KTxtFormat3,array.End(),array.Begin());
00153         console->Printf(KTxtFormat4,((TUint8*)array.End() - (TUint8*)array.Begin()));
00154         
00155         //
00156         // Access the second element of the array and change it
00157         // using At().
00158         //
00159         array.At(1).SetValue(100);
00160 
00161         //
00162         // Access the second element of the array and change it
00163         // using the [] operator.
00164         //
00165         array[1].SetValue(99);
00166         
00167         // The following call using At() will panic in both a
00168         // release and a debug build.
00169         //array.At(4).SetValue(100);
00170 
00171         // The following call using the [] operator will only panic
00172         // in a debug build. In a release build, this  code
00173         // will go undetected and cause damage.
00174         //array[4].SetValue(99);
00175         
00176         // In this example we can also replace an entire element;
00177         // here we replace the third element.
00178         // In more complex cases, the TTest class could have 
00179         // a suitable operator= defined 
00180         _LIT(KTxtFormat5,"The new 3rd element has value %d\n\n");
00181         TTest x(256);
00182         array.At(2) = x; 
00183         console->Printf(KTxtFormat5,array.At(2).GetValue());
00184 
00185         //
00186         // Construct a generic array.
00187         //
00188         // Once done, we can use the standard TArray functions
00189         // Count() and operator[]
00190         // Remember that a TArray cannot be used to change data in the
00191         // original array.
00192         //
00193         TArray<TTest> generic = array.Array();
00194 
00195         _LIT(KTxtFormat6,"Array size as reported by TArray's Count() is %d\n\n");
00196         console->Printf(KTxtFormat6,generic.Count());
00197 
00198         // The value contained in the 2nd TTest element of the array
00199         // using the generic array's operator[]
00200         _LIT(KTxtFormat7,"Value contained in the 2nd TTest element of\nthe array using TArray's operator[] is %d\n\n");
00201         console->Printf(KTxtFormat7,generic[1].GetValue());
00202 
00203         // the following line will NOT compile
00204         //generic[1].SetValue(101);
00205 
00206         
00207         // This is A C++ array of 4 elements to contain
00208         // pointers to CTest type objects.
00209         // This is equivalent to
00210         // the naked declaration:
00211         // CTest* ptrarray[4];
00212         // 
00213         //
00214         TFixedArray<CTest*,4> ptrarray;
00215 
00216         
00217         // Allocate 4 CTest objects and put their pointers
00218         // into the array.
00219         //
00220         // We ignore cleanup issues arising from possible
00221         // failure of 'new'; this would need to be
00222         // considered in a real application.
00223 
00224         _LIT(KTxtDefault,"Default text");
00225         _LIT(KTxtState1,"The 4 elements are:     ");
00226         _LIT(KTxtState2,"After Reset() they are: ");
00227         _LIT(KTxtNewLine,"\n");
00228         _LIT(KTxtFormat8,"0x%08x ");
00229                         
00230         CTest* ptr;
00231         TInt   ix;
00232         for (ix = 0; ix<4; ix++)
00233                 {
00234                 ptr = CTest::NewL(KTxtDefault);
00235                 ptrarray.At(ix) = ptr;
00236                 }
00237 
00238         console->Printf(KTxtState1);
00239         for (ix = 0; ix<4; ix++)
00240                 {
00241                 console->Printf(KTxtFormat8,ptrarray[ix]);
00242                 }
00243         console->Printf(KTxtNewLine);
00244 
00245         // Now delete all the CTest objects
00246         ptrarray.DeleteAll();
00247 
00248         // Set the array's data members to NULL 
00249         ptrarray.Reset();
00250 
00251         console->Printf(KTxtState2);
00252         for (ix = 0; ix<4; ix++)
00253                 {
00254                 console->Printf(KTxtFormat8,ptrarray[ix]);
00255                 }
00256         console->Printf(KTxtNewLine);
00257 
00258         }

Generated by  doxygen 1.6.2