examples/SysLibs/Streams/WriteToMany/WriteToMany.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 Example to demonstrate how a network of objects can be written 
00029 to more than one stream in a direct file store, and how the loading
00030 of an object from the store into memory may be deferred.
00031 The example:
00032 creates a direct file store (replacing any existing direct 
00033 file store of the same name)
00034 constructs a CClassABC container object and then constructs a 
00035 contained CClassA, CClassB and CClassC object.
00036 Displays the content of the CClassA, CClassB and CClassC objects
00037 externalizes the CClassB object in its own stream and  keeps hold of the
00038 stream id. Externalizes the CClassA object, the streamid of the
00039 CClassB object and the CClassC object in a single
00040 stream. Makes this latter stream the root stream of the store
00041 closes the store and deletes the container and its contained CClassA, 
00042 CClassB and CCLassC objects (from memory)
00043 re-opens the direct file store
00044 restores the CClassABC container object; in effect, this restores 
00045 its contained CClassA and CClassC objects and the stream id of its
00046 CClassB object. The CClassB object is not restored into memory until 
00047 it is needed.
00048 displays the content of the CClassA, CClassB and CClassC objects; it is
00049 at this time that the CClassB object is restored into memory. (This 
00050 illustrates the necessity of keeping the store open.
00051 closes the store and deletes the container and its contained CClassA, 
00052 CClassB and CCLassC objects (from memory)
00053 Notes:
00054 The file name and extension of the direct file store is "WriteToMany.dat".
00055 and will be created in "\data\" folder of the writable drive. 
00056 */
00057 
00058 
00059 
00060 #include "WriteToMany.h"
00061 
00062 
00063 //***************************************************************
00064 //
00065 // Implementations
00066 //
00067 //***************************************************************
00068 
00069 
00070 // The file name, extension and path for the file store
00071 _LIT(KFullNameOfFileStore,"\\epoc32ex\\data\\WriteToMany.dat");
00072 
00073 
00074                                 //  Do the example
00075 static void doExampleL()
00076     {
00077                             // make sure directory exists
00078         fsSession.MkDirAll(KFullNameOfFileStore);
00079         doMakeAndStoreL(KFullNameOfFileStore);
00080         doRestoreL(KFullNameOfFileStore);
00081         }
00082  
00083 
00084 static void doMakeAndStoreL(const TDesC& aName)
00085         {
00086                                 // Create (replace, if it exists) the direct file store
00087         TParse  filestorename;
00088         fsSession.Parse(aName,filestorename);
00089         CFileStore* store = CDirectFileStore::ReplaceLC(fsSession,filestorename.FullName(),EFileWrite);
00090 
00091                                 // Must say what kind of file store.
00092         store->SetTypeL(KDirectFileStoreLayoutUid);
00093 
00094                                 // Construct the container object for CClassA,CClassB and CClassC.
00095                                 // Complete the construction of the contained CClassA, CClassB
00096                                 // and CClassC objects.
00097         _LIT(KTxtDataForClassA,"Data for the CClassA - AAAAA");
00098         _LIT(KTxtDataForClassB,"Data for the CClassB - BBBBB");
00099         _LIT(KTxtDataForClassC,"Data for the CClassC - CCCCC");
00100 
00101         CClassABC* theABC = CClassABC::NewLC(*store);
00102         theABC->ConstructAL(KTxtDataForClassA,-1,2);
00103         theABC->ConstructB(KTxtDataForClassB,-3,4,5.6);
00104         theABC->ConstructC(KTxtDataForClassC);
00105 
00106                                 // Show contents of the CClassA, CClassB & CClassC objects
00107         _LIT(KTxtClassAContent,"CClassA content ...");
00108         _LIT(KTxtClassBContent,"CClassB content ...");
00109         _LIT(KTxtClassCContent,"CClassC content ...");
00110 
00111         doShow(KTxtClassAContent,*theABC->PtrA());
00112         doShow(KTxtClassBContent,*theABC->PtrBL());                                     
00113         doShow(KTxtClassCContent,*theABC->PtrC());                                      
00114 
00115                                 // Store the object network by:
00116                                 // storing the CClassB object in its own stream and 
00117                                 // then storing:
00118                                 //              the CClassA object
00119                                 //              the streamid of the CClassB object
00120                                 //      the CClassC object
00121                                 // in a separate stream.
00122         TStreamId id = theABC->StoreL();                        
00123         
00124                                 // Set this stream id as the root stream
00125         store->SetRootL(id);
00126 
00127                                 // Destroy:
00128                                 //              the container object.
00129                                 //              the direct file store object (closes the file),
00130                                 //              
00131         CleanupStack::PopAndDestroy(2); 
00132         }
00133 
00134 
00135 static void doRestoreL(const TDesC& aName)
00136         {
00137                                 // Open the direct file store
00138         TParse  filestorename;
00139         fsSession.Parse(aName,filestorename);
00140         CFileStore* store = CDirectFileStore::OpenLC(fsSession,filestorename.FullName(),EFileRead);
00141 
00142                                 // Restore the container object from the root stream.
00143                                 // This constructs a CClassA and a CClassC object 
00144                                 // and restores them from the root stream. 
00145                                 // The swizzle for the CClassB object is
00146                                 // constructed from the streamid in the root stream.
00147                                 // Note that the CClassB object itself is not loaded into 
00148                                 // memory until it is needed.
00149         CClassABC* theABC = CClassABC::NewLC(*store,store->Root());
00150 
00151                                 // Show restored contents of the CClassA, CClassB and CClassC
00152                                 // objects. Note that the CClassB object may not be in memory and
00153                                 // will be loaded in when needed.
00154         _LIT(KTxtRestoredClassA,"Restored CClassA content ...");
00155         _LIT(KTxtRestoredClassB,"Restored CClassB content ...");
00156         _LIT(KTxtRestoredClassC,"Restored CClassC content ...");
00157 
00158         doShow(KTxtRestoredClassA,*theABC->PtrA());
00159         doShow(KTxtRestoredClassB,*theABC->PtrBL());                                    
00160         doShow(KTxtRestoredClassC,*theABC->PtrC());     
00161                                 
00162                                 // Destroy:
00163                                 //              the CClassABC object, 
00164                                 //      the direct file store object (closes the file) 
00165         CleanupStack::PopAndDestroy(2);
00166         } 
00167 
00168 _LIT(KTxtNewLine,"\n");
00169 _LIT(KFormatType1,"\n%S, ");
00170 _LIT(KFormatType2,"%d, ");
00171 _LIT(KFormatType3,"%u  ");
00172 _LIT(KFormatType4,"%u, ");
00173 _LIT(KFormatType5,"%f  ");
00174                                                                         
00175 static void doShow(const TDesC& aHeading,const CClassA& anA)
00176         {
00177         console->Printf(KTxtNewLine);
00178         console->Printf(aHeading);
00179         console->Printf(KFormatType1,anA.iVarBuf);
00180         console->Printf(KFormatType2,anA.iIntValue);
00181         console->Printf(KFormatType3,anA.iUintValue);
00182         console->Printf(KTxtNewLine);
00183         }
00184 
00185 
00186 
00187 static void doShow(const TDesC& aHeading,const CClassB& aB)
00188         {
00189         console->Printf(KTxtNewLine);
00190         console->Printf(aHeading);
00191         console->Printf(KFormatType1,&aB.iFixBuf);
00192         console->Printf(KFormatType2,aB.iIntValue);
00193         console->Printf(KFormatType4,aB.iUintValue);
00194         console->Printf(KFormatType5,aB.iRealValue);
00195         console->Printf(KTxtNewLine);
00196         }
00197 
00198 static void doShow(const TDesC& aHeading,const CClassC& aC)
00199         {
00200         console->Printf(KTxtNewLine);
00201         console->Printf(aHeading);
00202         console->Printf(KFormatType1,&aC.iFixBuf);
00203         console->Printf(KTxtNewLine);
00204         }
00205 
00206 
00207 //***************************************************************
00208 //
00209 // CClassABC Implementation
00210 //
00211 //***************************************************************
00212 CClassABC::CClassABC(CStreamStore& aStore)
00213         : iStore(aStore)
00214         {}
00215 
00216 CClassABC::CClassABC(CStreamStore& aStore,TStreamId anId)
00217         : iStore(aStore), iId(anId)
00218         {}
00219 
00220 CClassABC* CClassABC::NewLC(CStreamStore& aStore)
00221         {
00222         CClassABC* self = new (ELeave) CClassABC(aStore);
00223         CleanupStack::PushL(self);
00224         self->ConstructL();
00225         return self;
00226         }
00227 
00228 CClassABC* CClassABC::NewLC(CStreamStore& aStore, TStreamId anId)
00229         {                                                                                                                       
00230         CClassABC* self = new (ELeave) CClassABC(aStore,anId);
00231         CleanupStack::PushL(self);
00232         self->RestoreL();
00233         return self;
00234         }
00235                 
00236 void CClassABC::ConstructL()
00237         {
00238         iA = CClassA::NewL();
00239         iB = CClassB::NewL();// assigns CClassB* to TSwizzle<CClassB>. Uses TSwizzle operator=(T*)
00240         iC = CClassC::NewL();
00241         }
00242 
00243 void CClassABC::ConstructAL(const TDesC& aData,TInt anInt,TUint aUint)
00244         {
00245         iA->iVarBuf    = aData.AllocL();        
00246         iA->iIntValue  = anInt;
00247         iA->iUintValue = aUint;
00248         }
00249                         
00250 void CClassABC::ConstructB(const TDesC& aData,TInt anInt,TUint aUint,TReal aReal)
00251         {
00252         iB->iFixBuf    = aData;
00253         iB->iIntValue  = anInt; 
00254         iB->iUintValue = aUint;
00255         iB->iRealValue = aReal;
00256         }
00257                         
00258 void CClassABC::ConstructC(const TDesC& aData)
00259         {
00260         iC->iFixBuf = aData;
00261         }
00262 
00263 
00264                         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
00265                         // Destructor deletes the CClassB object only if it is in memory.
00266                         // The IsPtr() function can be used to determine whether the 
00267                         // CClassB object is memory. 
00268                         // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
00269 CClassABC::~CClassABC()
00270         {
00271         delete iA;
00272         delete iC;
00273         if (iB.IsPtr())
00274                 delete iB.AsPtr(); // can also "delete iB;" makes implicit call to "operator T*()"
00275         }
00276 
00277         
00278                                 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
00279                                 // Stores the CClassB object in its own stream and
00280                                 // then stores:
00281                                 //              the CClassA object,
00282                                 //              the streamid of the CClassB object,
00283                                 //              the CClassC object
00284                                 // in a separate stream.
00285                                 // Returns the streamid of this last stream
00286                                 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
00287 TStreamId CClassABC::StoreL()
00288         {
00289                                 // Construct the output stream which is intended
00290                                 // to hold the CClassB object only.
00291         RStoreWriteStream outstream;
00292         TStreamId idForB = outstream.CreateLC(iStore);
00293                                 // Stream out the CClassB object.
00294                                 // Note that the right hand side returns a reference
00295                                 // to CClassB
00296         outstream  << *iB; 
00297                                 // Commit changes to the stream
00298         outstream.CommitL();
00299                                 // Cleanup the stream object
00300         CleanupStack::PopAndDestroy();  
00301                                 // Now construct the output stream which is intended
00302                                 // to hold:
00303                                 //              the CClassA object,
00304                                 //              the streamid of the CClassB object,
00305                                 //              the CClassC object
00306         TStreamId id = outstream.CreateLC(iStore);
00307                                 // Write out the CClassA object.
00308         outstream  << *iA; 
00309                                 // Write out the stream id of the CClassB object
00310         outstream  << idForB;
00311                                 // Write out the CClassC object.
00312         outstream  << *iC;
00313                                 // Commit changes to the stream
00314         outstream.CommitL();
00315                                 // Cleanup the stream object,
00316         CleanupStack::PopAndDestroy();  
00317                                 // Return this stream id
00318         return id;
00319         }
00320 
00321                                 
00322 const CClassA* CClassABC::PtrA()
00323         {
00324         return iA;      // Return a pointer to the contained CClassA object
00325         }
00326 
00327                                 
00328 const CClassB* CClassABC::PtrBL()
00329         {
00330         if (iB.IsId())          // If the contained CClassB object is not in memory, it must
00331                 RestoreBL();    // be loaded in before a pointer can be returned to the caller
00332         return iB.AsPtr();
00333         }
00334 
00335                                 
00336 const CClassC* CClassABC::PtrC()
00337         {
00338         return iC;      //Returns a pointer to the contained CClassC object
00339         }
00340                                 
00341                                 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
00342                                 // Restores the CClassA and CClassC objects and the streamid for the
00343                                 // CClassB object.
00344                                 // The swizzle for the CClassB object is constructed from the
00345                                 // streamid but the CClassB object itself is NOT restored at 
00346                                 // this time.
00347                                 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
00348 void CClassABC::RestoreL()
00349         {
00350                                 // Construct the input stream.
00351         RStoreReadStream instream;
00352         instream.OpenLC(iStore,iId);
00353                                 // Construct a CClassA object and restore from the stream
00354         iA = CClassA::NewL();
00355         instream >> *iA;
00356                                 // Construct the swizzle for the CClassB object. This
00357                                 // stream contains the id of the stream which 
00358                                 // actually contains the full CClassB object. The loading of
00359                                 // the CClassB object into memory is deferred until later.
00360                                 // The resulting swizzle represents the CClassB object as 
00361                                 // a streamid 
00362         instream >> iB;
00363                                 // Construct a CClassC object and restrore from the stream
00364         iC = CClassC::NewL();
00365         instream >> *iC;
00366                                 // Cleanup the stream object
00367         CleanupStack::PopAndDestroy();
00368         }
00369 
00370 
00371                                 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
00372                                 // Loads the CClassB object into memory and changes the swizzle's
00373                                 // representation from "streamid" to "pointer".
00374                                 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
00375 void CClassABC::RestoreBL()
00376         {
00377                                 // Construct the input stream. Assumes we have the correct store (this
00378                                 // emphasizes the need to ensure that the store remain open)
00379         RStoreReadStream instream;
00380         instream.OpenLC(iStore,iB.AsId());
00381                                 // Construct a CClassB object and restore from the stream. The 
00382                                 // assignment: CClassB* to TSwizzle<CClassB> changes the
00383                                 // swizzle's representation of the CClassB object 
00384                                 // from "streamid" to "pointer"
00385         CClassB* ptrB = CClassB::NewLC();
00386         instream >> *ptrB;
00387         CleanupStack::Pop();
00388         iB = ptrB;
00389                                 // Cleanup the stream object                    
00390         CleanupStack::PopAndDestroy();
00391         }       
00392 
00393 //***************************************************************
00394 //
00395 // CClassA Implementation
00396 //
00397 //***************************************************************
00398 CClassA* CClassA::NewL()
00399         {
00400         CClassA* self = CClassA::NewLC();
00401         CleanupStack::Pop();
00402         return self;
00403         }
00404 
00405 CClassA* CClassA::NewLC()
00406         {
00407         CClassA* self = new (ELeave) CClassA;
00408         CleanupStack::PushL(self);
00409         return self;
00410         }
00411 
00412 CClassA::~CClassA()
00413         {
00414         delete iVarBuf;
00415         }
00416 
00417 void CClassA::ExternalizeL(RWriteStream& aStream) const
00418         {
00419         aStream.WriteInt32L(iVarBuf->Des().MaxLength());
00420         aStream << *iVarBuf;
00421         aStream.WriteInt32L(iIntValue);
00422         aStream.WriteUint32L(iUintValue);
00423         }  
00424  
00425 void CClassA::InternalizeL(RReadStream& aStream)
00426         {
00427         TInt maxlen;
00428         maxlen     = aStream.ReadInt32L();
00429         iVarBuf    = HBufC::NewL(aStream,maxlen);
00430         iIntValue  = aStream.ReadInt32L();
00431         iUintValue = aStream.ReadUint32L();
00432         }  
00433                 
00434 
00435 //***************************************************************
00436 //
00437 // CClassB Implementation
00438 //
00439 //***************************************************************
00440 CClassB* CClassB::NewLC()
00441         {
00442         CClassB* self = new (ELeave) CClassB;
00443         CleanupStack::PushL(self);
00444         return self;
00445         }
00446 
00447 CClassB* CClassB::NewL()        
00448         {
00449         CClassB* self = CClassB::NewLC();
00450         CleanupStack::Pop();    
00451         return self;
00452         }
00453 
00454 void CClassB::ExternalizeL(RWriteStream& aStream) const
00455         {
00456         aStream << iFixBuf;
00457         aStream.WriteInt32L(iIntValue);
00458         aStream.WriteUint32L(iUintValue);
00459         aStream.WriteReal64L(iRealValue);
00460         }  
00461  
00462 void CClassB::InternalizeL(RReadStream& aStream)
00463         {
00464         aStream >> iFixBuf;
00465         iIntValue  = aStream.ReadInt32L();
00466         iUintValue = aStream.ReadUint32L();
00467         iRealValue = aStream.ReadReal64L();
00468         }  
00469 
00470 //***************************************************************
00471 //
00472 // CClassC Implementation
00473 //
00474 //***************************************************************
00475 CClassC* CClassC::NewL()
00476         {
00477         CClassC* self = CClassC::NewLC();
00478         CleanupStack::Pop();
00479         return self;
00480         }
00481 
00482 CClassC* CClassC::NewLC()
00483         {
00484         CClassC* self = new (ELeave) CClassC;
00485         CleanupStack::PushL(self);
00486         return self;
00487         }
00488 
00489 void CClassC::ExternalizeL(RWriteStream& aStream) const
00490         {
00491         aStream << iFixBuf;
00492         }  
00493  
00494 void CClassC::InternalizeL(RReadStream& aStream)
00495         {
00496         aStream >> iFixBuf;
00497         }  

Generated by  doxygen 1.6.2