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 AIM: To provide examples for the documentation of exceptions & traps 00029 Situation3 - examples of cleanup-stack support for TAny* and RItems 00030 */ 00031 00032 00033 00034 00035 #include "CommonFramework.h" 00036 00037 // Name of file to be used 00038 _LIT(KFileName,"TAnyandRObjects2.dat"); 00039 00040 // Test data to be put into the file. 00041 _LIT(KTestData,"Test data for TAnyandRObjects2\n"); 00042 00043 // #include specific files 00044 #include <f32file.h> 00045 #include "EUHEXDMP.H" 00046 00047 00049 // 00050 // -----> RFileWithCleanup(definition) 00051 // 00052 // Function Cleanup() and operator TCleanupItem() needed to provide 00053 // Cleanup Stack for RFile 00054 // 00056 class RFileWithCleanup : public RFile 00057 { 00058 private: 00059 static void Cleanup(TAny *aPtr); 00060 public: 00061 operator TCleanupItem(); 00062 public: 00063 void OpenL(RFs &aFs,const TDesC &aName,TUint aMode); 00064 void OpenLC(RFs &aFs,const TDesC &aName,TUint aMode); 00065 }; 00066 00067 00069 // 00070 // -----> RFileWithCleanup(implementation) 00071 // 00073 void RFileWithCleanup::Cleanup(TAny *aPtr) 00074 { 00075 _LIT(KMsgDoingCleanup,"Doing cleanup of file.\n"); 00076 console->Printf(KMsgDoingCleanup); 00077 // Invoke the Close member on the RItem at aPtr 00078 ((RFileWithCleanup *)aPtr)->Close(); 00079 } 00080 00081 RFileWithCleanup::operator TCleanupItem() 00082 { 00083 return TCleanupItem(Cleanup,this); 00084 } 00085 00086 void RFileWithCleanup::OpenL(RFs &aFs,const TDesC &aName,TUint aMode) 00087 { 00088 User::LeaveIfError(RFile::Open(aFs,aName,aMode)); 00089 } 00090 00091 void RFileWithCleanup::OpenLC(RFs &aFs,const TDesC &aName,TUint aMode) 00092 { 00093 OpenL(aFs,aName,aMode); 00094 CleanupStack::PushL(*this); // NB. 'this' would have been a TAny* 00095 } 00096 00097 LOCAL_C void createDataFileL() 00098 { 00099 // utility function to create some data which we can later read 00100 RFs createFileSession; 00101 RFileWithCleanup createFile; 00102 00103 // connect to filserver session 00104 User::LeaveIfError(createFileSession.Connect()); 00105 00106 00107 // create the private directory 00108 // on the writable drive 00109 // i.e. "\private\0FFFFF01\" 00110 // Note that the number 0FFFFF01 is the 00111 // process security id taken from the 2nd UID 00112 // specified in the mmp file. 00113 createFileSession.CreatePrivatePath(RFs::GetSystemDrive()); 00114 00115 // Set the session path to 00116 // this private directory on writable drive 00117 createFileSession.SetSessionToPrivate(RFs::GetSystemDrive()); 00118 00119 // create TAnyandRObjects2.dat and open for writing 00120 User::LeaveIfError(createFile.Replace(createFileSession, 00121 KFileName, 00122 EFileWrite|EFileStreamText)); 00123 00124 // Note that Write() requires a TDesC8 00125 // type so we need to construct an explicit 00126 // TDesC8 type to represent the data contained 00127 // in the standard (16-bit) descriptor. 00128 TPtrC8 representation((TUint8*)(&KTestData)->Ptr(), (&KTestData)->Size()); 00129 00130 // write and commit text 00131 User::LeaveIfError(createFile.Write(representation)); 00132 User::LeaveIfError(createFile.Flush()); 00133 _LIT(KMsgDataWritten,"Data written to file\n"); 00134 console->Printf(KMsgDataWritten); 00135 00136 // close file and session 00137 // (NB. no LeaveIfError due to RFile.close and 00138 // RFs.close guaranteed to complete) 00139 createFile.Close(); // close file 00140 createFileSession.Close(); // close file server session 00141 } 00142 00143 void useBufferL(TPtr8& bufferPtr) 00144 { 00145 printBuffer(0,bufferPtr); 00146 // Remove following comment to force a leave 00147 // while using the buffer 00148 //User::Leave(KErrGeneral); 00149 } 00150 00151 00152 LOCAL_C void doExampleL() 00153 { 00154 // create the datafile for the example 00155 createDataFileL(); 00156 00157 // create a simple buffer. In real code, you 00158 // would probably use an HBufC*, or an RBuf. 00159 // You could also use a TBuf on the stack if it's small. 00160 TText8* buffer=(TText8*) User::Alloc(100*sizeof(TText8)); 00161 00162 // push it to the cleanup stack: treated as TAny* 00163 CleanupStack::PushL(buffer); 00164 00165 // create a pointer to the buffer 00166 TPtr8 bufferPtr(buffer,100); 00167 00168 // the file session to be used 00169 RFs fsSession; 00170 _LIT(KMsgOpeningSession,"Opening session\n"); 00171 console->Printf(KMsgOpeningSession); 00172 00173 // open the file-server session 00174 User::LeaveIfError(fsSession.Connect()); 00175 00176 // the file instance myFile 00177 RFileWithCleanup myFile; 00178 _LIT(KMsgOpeningFile,"Opening file\n"); 00179 console->Printf(KMsgOpeningFile); 00180 00181 // open the file (and leave on cleanup stack) 00182 myFile.OpenLC(fsSession,KFileName,EFileStreamText|EFileRead); 00183 00184 // read stuff from the file to the buffer (may leave) 00185 _LIT(KMsgReadingFile,"Reading file into buffer.\n"); 00186 console->Printf(KMsgReadingFile); 00187 User::LeaveIfError(myFile.Read(bufferPtr)); 00188 // Remove following comment to force a leave 00189 // while using the file 00190 //User::Leave(KErrGeneral); 00191 00192 // destroy the file on the cleanup stack 00193 CleanupStack::PopAndDestroy(); 00194 00195 fsSession.Close(); 00196 00197 // use the buffer 00198 useBufferL(bufferPtr); 00199 // destroy the buffer on the cleanup stack 00200 CleanupStack::PopAndDestroy(); 00201 } 00202