Symbian
Symbian Developer Library

SYMBIAN OS V9.4

Feedback

[Index] [Previous] [Next]


Store streams example code

[Top]


WriteToMany: externalizing to more than one stream/deferred loading


Example code

These are the main files contained in the examples. Some extra files may be needed to run the examples, and these will be found in the appropriate examples directory.

Found in: examples\Syslibs\Streams\WriteToMany

// WriteToMany.cpp
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.
//


// Example to demonstrate how a network of objects can be written 
// to more than one stream in a direct file store, and how the loading
// of an object from the store into memory may be deferred.
//
// The example:
//      creates a direct file store (replacing any existing direct 
//      file store of the same name)
//
//      constructs a CClassABC container object and then constructs a 
//      contained CClassA, CClassB and CClassC object.
//
//      Displays the content of the CClassA, CClassB and CClassC objects
//
//      externalizes the CClassB object in its own stream and  keeps hold of the
//      stream id. Externalizes the CClassA object, the streamid of the
//      CClassB object and the CClassC object in a single
//      stream. Makes this latter stream the root stream of the store
//
//      closes the store and deletes the container and its contained CClassA, 
//      CClassB and CCLassC objects (from memory)
//
//          ========================================================
//
//      re-opens the direct file store
//
//      restores the CClassABC container object; in effect, this restores 
//      its contained CClassA and CClassC objects and the stream id of its
//      CClassB object. The CClassB object is not restored into memory until 
//      it is needed.
//
//      displays the content of the CClassA, CClassB and CClassC objects; it is
//      at this time that the CClassB object is restored into memory. (This 
//      illustrates the necessity of keeping the store open.
//
//      closes the store and deletes the container and its contained CClassA, 
//      CClassB and CCLassC objects (from memory)
//
// Notes:
//      The file name and extension of the direct file store is "WriteToMany.dat".
//      and will be created in "\data\" folder of the writable drive.
//
#include "WriteToMany.h"


//***************************************************************
//
// Implementations
//
//***************************************************************


// The file name, extension and path for the file store
_LIT(KFullNameOfFileStore,"\\epoc32ex\\data\\WriteToMany.dat");

                //  Do the example
LOCAL_C void doExampleL()
    {
                // make sure directory exists
    fsSession.MkDirAll(KFullNameOfFileStore);
    doMakeAndStoreL(KFullNameOfFileStore);
    doRestoreL(KFullNameOfFileStore);
    }
 

LOCAL_C void doMakeAndStoreL(const TDesC& aName)
    {
                // Create (replace, if it exists) the direct file store
    TParse  filestorename;
    fsSession.Parse(aName,filestorename);
    CFileStore* store = CDirectFileStore::ReplaceLC(fsSession,filestorename.FullName(),EFileWrite);

                // Must say what kind of file store.
    store->SetTypeL(KDirectFileStoreLayoutUid);

                // Construct the container object for CClassA,CClassB and CClassC.
                // Complete the construction of the contained CClassA, CClassB
                // and CClassC objects.
    _LIT(KTxtDataForClassA,"Data for the CClassA - AAAAA");
    _LIT(KTxtDataForClassB,"Data for the CClassB - BBBBB");
    _LIT(KTxtDataForClassC,"Data for the CClassC - CCCCC");

    CClassABC* theABC = CClassABC::NewLC(*store);
    theABC->ConstructAL(KTxtDataForClassA,-1,2);
    theABC->ConstructB(KTxtDataForClassB,-3,4,5.6);
    theABC->ConstructC(KTxtDataForClassC);

                // Show contents of the CClassA, CClassB & CClassC objects
    _LIT(KTxtClassAContent,"CClassA content ...");
    _LIT(KTxtClassBContent,"CClassB content ...");
    _LIT(KTxtClassCContent,"CClassC content ...");

    doShow(KTxtClassAContent,*theABC->PtrA());
    doShow(KTxtClassBContent,*theABC->PtrB());                   
    doShow(KTxtClassCContent,*theABC->PtrC());                   

                // Store the object network by:
                // storing the CClassB object in its own stream and 
                // then storing:
                //      the CClassA object
                //      the streamid of the CClassB object
                //      the CClassC object
                // in a separate stream.
      TStreamId id = theABC->StoreL();          
    
                  // Set this stream id as the root stream
    store->SetRootL(id);

                // Destroy:
                //      the container object.
                //      the direct file store object (closes the file),
                //      
    CleanupStack::PopAndDestroy(2); 
    }


LOCAL_C void doRestoreL(const TDesC& aName)
    {
                // Open the direct file store
    TParse  filestorename;
    fsSession.Parse(aName,filestorename);
    CFileStore* store = CDirectFileStore::OpenLC(fsSession,filestorename.FullName(),EFileRead);

                // Restore the container object from the root stream.
                // This constructs a CClassA and a CClassC object 
                // and restores them from the root stream. 
                // The swizzle for the CClassB object is
                // constructed from the streamid in the root stream.
                // Note that the CClassB object itself is not loaded into 
                // memory until it is needed.
    CClassABC* theABC = CClassABC::NewLC(*store,store->Root());

                // Show restored contents of the CClassA, CClassB and CClassC
                // objects. Note that the CClassB object may not be in memory and
                // will be loaded in when needed.
    _LIT(KTxtRestoredClassA,"Restored CClassA content ...");
    _LIT(KTxtRestoredClassB,"Restored CClassB content ...");
    _LIT(KTxtRestoredClassC,"Restored CClassC content ...");

    doShow(KTxtRestoredClassA,*theABC->PtrA());
    doShow(KTxtRestoredClassB,*theABC->PtrB());                  
    doShow(KTxtRestoredClassC,*theABC->PtrC());  
                
                // Destroy:
                //      the CClassABC object, 
                //      the direct file store object (closes the file) 
    CleanupStack::PopAndDestroy(2);
    } 

_LIT(KTxtNewLine,"\n");
_LIT(KFormatType1,"\n%S, ");
_LIT(KFormatType2,"%d, ");
_LIT(KFormatType3,"%u  ");
_LIT(KFormatType4,"%u, ");
_LIT(KFormatType5,"%f  ");
                                    
LOCAL_C void doShow(const TDesC& aHeading,const CClassA& anA)
    {
    console->Printf(KTxtNewLine);
    console->Printf(aHeading);
    console->Printf(KFormatType1,anA.iVarBuf);
    console->Printf(KFormatType2,anA.iIntValue);
    console->Printf(KFormatType3,anA.iUintValue);
    console->Printf(KTxtNewLine);
    }



LOCAL_C void doShow(const TDesC& aHeading,const CClassB& aB)
    {
    console->Printf(KTxtNewLine);
    console->Printf(aHeading);
    console->Printf(KFormatType1,&aB.iFixBuf);
    console->Printf(KFormatType2,aB.iIntValue);
    console->Printf(KFormatType4,aB.iUintValue);
    console->Printf(KFormatType5,aB.iRealValue);
    console->Printf(KTxtNewLine);
    }

LOCAL_C void doShow(const TDesC& aHeading,const CClassC& aC)
    {
    console->Printf(KTxtNewLine);
    console->Printf(aHeading);
    console->Printf(KFormatType1,&aC.iFixBuf);
    console->Printf(KTxtNewLine);
    }


//***************************************************************
//
// CClassABC Implementation
//
//***************************************************************
CClassABC::CClassABC(CStreamStore& aStore)
    : iStore(aStore)
    {}

CClassABC::CClassABC(CStreamStore& aStore,TStreamId anId)
    : iStore(aStore), iId(anId)
    {}

CClassABC* CClassABC::NewLC(CStreamStore& aStore)
    {
    CClassABC* self = new (ELeave) CClassABC(aStore);
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
    }

CClassABC* CClassABC::NewLC(CStreamStore& aStore, TStreamId anId)
    {                                                           
    CClassABC* self = new (ELeave) CClassABC(aStore,anId);
    CleanupStack::PushL(self);
    self->RestoreL();
    return self;
    }
        
void CClassABC::ConstructL()
    {
    iA = CClassA::NewL();
    iB = CClassB::NewL();// assigns CClassB* to TSwizzle<CClassB>. Uses TSwizzle operator=(T*)
    iC = CClassC::NewL();
    }

void CClassABC::ConstructAL(const TDesC& aData,TInt anInt,TUint aUint)
    {
    iA->iVarBuf    = aData.AllocL();    
    iA->iIntValue  = anInt;
    iA->iUintValue = aUint;
    }
            
void CClassABC::ConstructB(const TDesC& aData,TInt anInt,TUint aUint,TReal aReal)
    {
    iB->iFixBuf    = aData;
    iB->iIntValue  = anInt; 
    iB->iUintValue = aUint;
    iB->iRealValue = aReal;
    }
            
void CClassABC::ConstructC(const TDesC& aData)
    {
    iC->iFixBuf = aData;
    }


            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
            // Destructor deletes the CClassB object only if it is in memory.
            // The IsPtr() function can be used to determine whether the 
            // CClassB object is memory. 
            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
CClassABC::~CClassABC()
    {
    delete iA;
    delete iC;
    if (iB.IsPtr())
        delete iB.AsPtr(); // can also "delete iB;" makes implicit call to "operator T*()"
    }

    
                // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
                // Stores the CClassB object in its own stream and
                // then stores:
                //      the CClassA object,
                //      the streamid of the CClassB object,
                //      the CClassC object
                // in a separate stream.
                // Returns the streamid of this last stream
                // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
TStreamId CClassABC::StoreL()
    {
                // Construct the output stream which is intended
                // to hold the CClassB object only.
    RStoreWriteStream outstream;
    TStreamId idForB = outstream.CreateLC(iStore);
                // Stream out the CClassB object.
                // Note that the right hand side returns a reference
                // to CClassB
    outstream  << *iB; 
                // Commit changes to the stream
    outstream.CommitL();
                // Cleanup the stream object
    CleanupStack::PopAndDestroy();  
                // Now construct the output stream which is intended
                // to hold:
                //      the CClassA object,
                //      the streamid of the CClassB object,
                //      the CClassC object
    TStreamId id = outstream.CreateLC(iStore);
                // Write out the CClassA object.
    outstream  << *iA; 
                // Write out the stream id of the CClassB object
    outstream  << idForB;
                // Write out the CClassC object.
    outstream  << *iC;
                // Commit changes to the stream
    outstream.CommitL();
                // Cleanup the stream object,
    CleanupStack::PopAndDestroy();  
                // Return this stream id
    return id;
    }

                
const CClassA* CClassABC::PtrA()
    {
    return iA; // Return a pointer to the contained CClassA object
    }

                
const CClassB* CClassABC::PtrB()
    {
    if (iB.IsId())     // If the contained CClassB object is not in memory, it must
        RestoreBL();    // be loaded in before a pointer can be returned to the caller
    return iB.AsPtr();
    }

                
const CClassC* CClassABC::PtrC()
    {
    return iC; //Returns a pointer to the contained CClassC object
    }
                
                // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
                // Restores the CClassA and CClassC objects and the streamid for the
                // CClassB object.
                // The swizzle for the CClassB object is constructed from the
                // streamid but the CClassB object itself is NOT restored at 
                // this time.
                // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
void CClassABC::RestoreL()
    {
                // Construct the input stream.
    RStoreReadStream instream;
    instream.OpenLC(iStore,iId);
                // Construct a CClassA object and restore from the stream
    iA = CClassA::NewL();
    instream >> *iA;
                // Construct the swizzle for the CClassB object. This
                // stream contains the id of the stream which 
                // actually contains the full CClassB object. The loading of
                // the CClassB object into memory is deferred until later.
                // The resulting swizzle represents the CClassB object as 
                // a streamid 
    instream >> iB;
                // Construct a CClassC object and restrore from the stream
    iC = CClassC::NewL();
    instream >> *iC;
                // Cleanup the stream object
    CleanupStack::PopAndDestroy();
    }


                // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
                // Loads the CClassB object into memory and changes the swizzle's
                // representation from "streamid" to "pointer".
                // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
void CClassABC::RestoreBL()
    {
                // Construct the input stream. Assumes we have the correct store (this
                // emphasizes the need to ensure that the store remain open)
    RStoreReadStream instream;
    instream.OpenLC(iStore,iB.AsId());
                // Construct a CClassB object and restore from the stream. The 
                // assignment: CClassB* to TSwizzle<CClassB> changes the
                // swizzle's representation of the CClassB object 
                // from "streamid" to "pointer"
    CClassB* ptrB = CClassB::NewLC();
    instream >> *ptrB;
    CleanupStack::Pop();
    iB = ptrB;
                // Cleanup the stream object            
    CleanupStack::PopAndDestroy();
    }   

//***************************************************************
//
// CClassA Implementation
//
//***************************************************************
CClassA* CClassA::NewL()
    {
    CClassA* self = CClassA::NewLC();
    CleanupStack::Pop();
    return self;
    }

CClassA* CClassA::NewLC()
    {
    CClassA* self = new (ELeave) CClassA;
    CleanupStack::PushL(self);
    return self;
    }

CClassA::~CClassA()
    {
    delete iVarBuf;
    }

void CClassA::ExternalizeL(RWriteStream& aStream) const
    {
    aStream.WriteInt32L(iVarBuf->Des().MaxLength());
    aStream << *iVarBuf;
    aStream.WriteInt32L(iIntValue);
    aStream.WriteUint32L(iUintValue);
    }  
 
void CClassA::InternalizeL(RReadStream& aStream)
    {
    TInt maxlen;
    maxlen     = aStream.ReadInt32L();
    iVarBuf    = HBufC::NewL(aStream,maxlen);
    iIntValue  = aStream.ReadInt32L();
    iUintValue = aStream.ReadUint32L();
    }  
       

//***************************************************************
//
// CClassB Implementation
//
//***************************************************************
CClassB* CClassB::NewLC()
    {
    CClassB* self = new (ELeave) CClassB;
    CleanupStack::PushL(self);
    return self;
    }

CClassB* CClassB::NewL()   
    {
    CClassB* self = CClassB::NewLC();
    CleanupStack::Pop();    
    return self;
    }

void CClassB::ExternalizeL(RWriteStream& aStream) const
    {
    aStream << iFixBuf;
    aStream.WriteInt32L(iIntValue);
    aStream.WriteUint32L(iUintValue);
    aStream.WriteReal64L(iRealValue);
    }  
 
void CClassB::InternalizeL(RReadStream& aStream)
    {
    aStream >> iFixBuf;
    iIntValue  = aStream.ReadInt32L();
    iUintValue = aStream.ReadUint32L();
    iRealValue = aStream.ReadReal64L();
    }  

//***************************************************************
//
// CClassC Implementation
//
//***************************************************************
CClassC* CClassC::NewL()
    {
    CClassC* self = CClassC::NewLC();
    CleanupStack::Pop();
    return self;
    }

CClassC* CClassC::NewLC()
    {
    CClassC* self = new (ELeave) CClassC;
    CleanupStack::PushL(self);
    return self;
    }

void CClassC::ExternalizeL(RWriteStream& aStream) const
    {
    aStream << iFixBuf;
    }  
 
void CClassC::InternalizeL(RReadStream& aStream)
    {
    aStream >> iFixBuf;
    }  
// WriteToMany.h
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.
//

//***************************************************************
//
// Function and class definitions used in the 
// WriteToMany example
//
//***************************************************************
#ifndef __WriteToMany_H
#define __WriteToMany_H

#include "CommonStreamStore.h"
#include <s32file.h>

LOCAL_C void doMakeAndStoreL(const TDesC& aName);
LOCAL_C void doRestoreL(const TDesC& aName);

class CClassA;
LOCAL_C void doShow(const TDesC& aHeading,const CClassA& anA);

class CClassB;
LOCAL_C void doShow(const TDesC& aHeading,const CClassB& aB);

class CClassC;
LOCAL_C void doShow(const TDesC& aHeading,const CClassC& aC);


class CClassA : public CBase
    {
public :
    static CClassA* NewL();
    static CClassA* NewLC();
public :
    ~CClassA();
    void     ExternalizeL(RWriteStream& aStream) const;
    void     InternalizeL(RReadStream& aStream);
public :
    HBufC*   iVarBuf;
    TInt     iIntValue;
    TUint    iUintValue;
    };

class CClassB : public CBase
    {
public :
    static CClassB* NewL();
    static CClassB* NewLC();
public :
    void     ExternalizeL(RWriteStream& aStream) const;
    void     InternalizeL(RReadStream& aStream);
public :
    TBuf<32> iFixBuf;
    TUint    iUintValue;
    TInt     iIntValue;
    TReal    iRealValue;
    };

class CClassC : public CBase
    {
public  :
    static CClassC* NewL();
    static CClassC* NewLC();
public  :
    void     ExternalizeL(RWriteStream& aStream) const;
    void     InternalizeL(RReadStream& aStream);
public :
    TBuf<32> iFixBuf;
    };



class CClassABC : public CBase
    {
public :
    static CClassABC* NewLC(CStreamStore& aStore);
    static CClassABC* NewLC(CStreamStore& aStore, TStreamId anId);
public :
    CClassABC(CStreamStore& aStore);
    CClassABC(CStreamStore& aStore,TStreamId anId);
    ~CClassABC();
    TStreamId         StoreL();
    void              RestoreL();
    void              ConstructAL(const TDesC& aData,TInt anInt,TUint aUint);
    void              ConstructB(const TDesC& aData,TInt anInt,TUint aUint,TReal aReal);
    void              ConstructC(const TDesC& aData);
    const CClassA*    PtrA();
    const CClassB*    PtrB();
    const CClassC*    PtrC();
private :
    void              ConstructL();
    void              RestoreBL();
private :
    CClassA*          iA;
    TSwizzle<CClassB> iB;     // Note use of swizzle here
    CClassC*          iC;
    CStreamStore&     iStore; // Store to/Restore from this store
    TStreamId         iId;    // Restore from/replace this stream
    };

#endif
// BLD.INF
// Component description file 
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.


PRJ_MMPFILES

WriteToMany.mmp
// WriteToMany.mmp
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.

// using relative paths for source and userinclude directories

TARGET        WriteToMany.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        WriteToMany.cpp

USERINCLUDE   .
USERINCLUDE   ..\..\CommonFramework
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib efsrv.lib estor.lib

Description

This example shows how a network of objects can be written to more than one stream in a direct file store, and how the loading of an object from the store into memory may be deferred.


Classes used

[Top]


WriteToEmbedded: using an embedded store

Found in: examples\Syslibs\Streams\WriteToEmbedded

// WriteToEmbedded.cpp
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.

// Example uses an embedded store.
//
// This example uses a permanent file store. It constructs a CMainClass object
// which has a CClassABC object as a component. The CClassABC object itself
// has other components and its structure is the same as found in the
// WriteToMany example.
//
// Here, the CClassABC component object network is stored in an embedded store.
//
// The example:
//      creates a permanent file store
//
//      constructs a CMainClass object. This results in the construction
//      of a CClassABC objet network which is stored in its own embedded
//      store (within the main store). 
//      
//      stores the CMainClass object in its own stream in the main store
//      and makes that stream the root stream.
//
//      closes the store and deletes the CMainClass object from memory
//
//          ========================================================
//
//      re-opens the permanent file store
//
//      restores the CMainClass object and opens the embedded store. As the 
//      the contained CClassABC object itself has components which are only 
//      loaded in when needed, then the embedded store is kept open.
//
//      Displays the content of the CClassA, CClassB and CClassC objects.
//
//      Deletes the CClassABC object from CMainClass and deletes its representation
//      from the permanent file store. Note that knowledge of the detailed
//      structure of the CClassABC object network is not needed. 
//
//      Attempts to redisplay the content of the CClassA, CClassB and CClassC 
//      objects; this should fail as they have been deleted.
//
//      closes the store and deletes the CMainClass object from memory.
//
// Notes:
//      The file name and extension of the direct file store is "WriteToEmbedded.dat".
//      and will be created in the "\data\" folder of the writable drive.
//
#include "WriteToEmbedded.h"
    
//***************************************************************
//
// Implementations
//
//***************************************************************

// The file name, extension and path for the file store
_LIT(KFullNameOfFileStore,"\\epoc32ex\\data\\WriteToEmbedded.dat");

                //  Do the example
LOCAL_C void doExampleL()
    {
                // make sure directory exists
    fsSession.MkDirAll(KFullNameOfFileStore);
    doMakeAndStoreL(KFullNameOfFileStore);
    doDeleteComponentL(KFullNameOfFileStore);
    }
 
LOCAL_C void doMakeAndStoreL(const TDesC& aName)
    {
                // Create (replace, if it exists) the permanent file store
    TParse  filestorename;
    fsSession.Parse(aName,filestorename);
    CFileStore* store = CPermanentFileStore::ReplaceLC(fsSession,filestorename.FullName(),EFileWrite);

                // Must say what kind of file store.
    store->SetTypeL(KPermanentFileStoreLayoutUid);
    
                // Construct a main object and its component
                // CClassABC object; the CClassABC component object
                // and its components are stored in an embedded store
                // within the main store.  
    CMainClass* theMain = CMainClass::NewLC(*store);

                // Store the CMainClass object in its own stream 
                // in the top level store
    TStreamId theId = theMain->StoreL();

                // Set this stream id as the root stream
    store->SetRootL(theId);

                // Commit theses changes to the top level store
    store->CommitL();

                // Destroy:
                //      the CMainClass object,
                //      the permanent file store object (closes the file)
    CleanupStack::PopAndDestroy(2); 
    }

LOCAL_C void doDeleteComponentL(const TDesC& aName)
    {
                // Open the permanent file store
    TParse  filestorename;
    fsSession.Parse(aName,filestorename);
    CFileStore* store = CPermanentFileStore::OpenLC(fsSession,filestorename.FullName(),EFileRead|EFileWrite);
                
                // Restore the main object
    CMainClass* theMain = CMainClass::NewLC(*store,store->Root());
    
                // Show the content of the classes contained by CClassABC,
                // loading as needed
    CClassABC* abc = theMain->PtrAbc();
    
    _LIT(KTxtClassAContent,"CClassA content ...");
    _LIT(KTxtClassBContent,"CClassB content ...");
    _LIT(KTxtClassCContent,"CClassC content ...");
    _LIT(KTxtClassABCDeleted,"CClassABC component deleted");

    if (abc)
        {
        doShow(KTxtClassAContent,*abc->PtrA());
        doShow(KTxtClassBContent,*abc->PtrB());                  
        doShow(KTxtClassCContent,*abc->PtrC());
        }
    else
        doShow(KTxtClassABCDeleted);
        
                // remove the CClassABC component from CMainClass and
                // and remove its representation from the store
    theMain->RemoveAbcL();

                // Try and show the contents again; the pointer
                // abc should now be NULL
    abc = theMain->PtrAbc();
    if (abc)
        {
        doShow(KTxtClassAContent,*abc->PtrA());
        doShow(KTxtClassBContent,*abc->PtrB());                  
        doShow(KTxtClassCContent,*abc->PtrC());
        }
    else
        doShow(KTxtClassABCDeleted);

                // Destroy:
                //      the CMainClass object, 
                //      the permanent file store object (closes the file) 
    CleanupStack::PopAndDestroy(2);
    }

_LIT(KTxtNewLine,"\n");
_LIT(KFormatType1,"\n%S, ");
_LIT(KFormatType2,"%d, ");
_LIT(KFormatType3,"%u  ");
_LIT(KFormatType4,"%u, ");
_LIT(KFormatType5,"%f  ");
 
LOCAL_C void doShow(const TDesC& aComment)
    {
    console->Printf(KTxtNewLine);
    console->Printf(aComment);
    console->Printf(KTxtNewLine);
    }
    
LOCAL_C void doShow(const TDesC& aHeading,const CClassA& anA)
    {
    console->Printf(KTxtNewLine);
    console->Printf(aHeading);
    console->Printf(KFormatType1,anA.iVarBuf);
    console->Printf(KFormatType2,anA.iIntValue);
    console->Printf(KFormatType3,anA.iUintValue);
    console->Printf(KTxtNewLine);
    }

LOCAL_C void doShow(const TDesC& aHeading,const CClassB& aB)
    {
    console->Printf(KTxtNewLine);
    console->Printf(aHeading);
    console->Printf(KFormatType1,&aB.iFixBuf);
    console->Printf(KFormatType2,aB.iIntValue);
    console->Printf(KFormatType4,aB.iUintValue);
    console->Printf(KFormatType5,aB.iRealValue);
    console->Printf(KTxtNewLine);
    }

LOCAL_C void doShow(const TDesC& aHeading,const CClassC& aC)
    {
    console->Printf(KTxtNewLine);
    console->Printf(aHeading);
    console->Printf(KFormatType1,&aC.iFixBuf);
    console->Printf(KTxtNewLine);
    }

//***************************************************************
//
// CMainClass Implementation
//
//***************************************************************
CMainClass* CMainClass::NewLC(CStreamStore& aStore)
    {
    CMainClass* self = new (ELeave) CMainClass(aStore);
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
    }

CMainClass* CMainClass::NewLC(CStreamStore& aStore,TStreamId anId)
    {
    CMainClass* self = new (ELeave) CMainClass(aStore,anId);
    CleanupStack::PushL(self);
    self->RestoreL();
    return self;
    }

CMainClass::CMainClass(CStreamStore& aStore)
    : iStore(aStore)
    {}

CMainClass::CMainClass(CStreamStore& aStore,TStreamId anId)
    : iStore(aStore), iId(anId)
    {}

_LIT(KTxtMainData,"Main data");
_LIT(KTxtClassAData,"Data for the CClassA - AAAAA");
_LIT(KTxtClassBData,"Data for the CClassB - BBBBB");
_LIT(KTxtClassCData,"Data for the CClassC - CCCCC");

void CMainClass::ConstructL()
    {
    iSomeData = KTxtMainData;
                // create the stream to contain the embedded store
    RStoreWriteStream childStream;
                // we need to keep track of this stream id
    iEmbeddedStoreId = childStream.CreateLC(iStore);
                // construct the embedded store
    CPersistentStore* embeddedStore = CEmbeddedStore::NewLC(childStream);
                // construct the CClassABC and its containees. Note that
                // the store it uses is the embedded store.
    iAbc = CClassABC::NewL(*embeddedStore); 
    iAbc->ConstructAL(KTxtClassAData,-1,2);
    iAbc->ConstructB(KTxtClassBData,-3,4,5.6);
    iAbc->ConstructC(KTxtClassCData);
                // store the CClassABC and its containees in the
                // embedded store ...
    TStreamId idForAbc = iAbc->StoreL();
                // ... and set this stream id as the root 
                // stream of the embedded store
    embeddedStore->SetRootL(idForAbc);   
                // Commit changes to the embedded store
    embeddedStore->CommitL();
                // Commit changes to the stream containing the 
                // embedded store.
    childStream.CommitL();
                // Destroy the embedded store object
                // Cleanup the stream containing the emmbedded store 
    CleanupStack::PopAndDestroy(2);
    }

CMainClass::~CMainClass()
    {
    delete iEmbeddedStore;
    iChildStream.Release(); //stream cleanup
    delete iAbc;
    }

TStreamId CMainClass::StoreL()
    {
    RStoreWriteStream stream;
    TStreamId id = stream.CreateLC(iStore);
    ExternalizeL(stream);
    stream.CommitL();
    CleanupStack::PopAndDestroy();
    return id;
    }
    
void CMainClass::ExternalizeL(RWriteStream& aStream)
    {
    aStream << iSomeData; 
    aStream << iEmbeddedStoreId;
    }

void CMainClass::RestoreL()
    {
    RStoreReadStream stream;
    stream.OpenLC(iStore,iId);
                // restore the CMainClass object
    InternalizeL(stream);
                // clean up the stream
    CleanupStack::PopAndDestroy();
                // open stream containing the embedded store
                // (and keep it open)
    if (iEmbeddedStoreId != KNullStreamId)
        {
        iChildStream.OpenL(iStore,iEmbeddedStoreId);
                // construct the embedded store 
                // (and keep it open)
        iEmbeddedStore = CEmbeddedStore::FromL(iChildStream);
                // restore the CClassABC object network from the
                // embedded store. Note that not all of CClassABC's
                // containees are loaded in, hence the need to keep
                // the embedded store open 
        iAbc = CClassABC::NewL(*iEmbeddedStore,iEmbeddedStore->Root());
        }
    }

void CMainClass::InternalizeL(RReadStream& aStream)
    {
    aStream >> iSomeData; 
    aStream >> iEmbeddedStoreId;
    }

CClassABC* CMainClass::PtrAbc()
    {
    return iAbc;
    }

void CMainClass::RemoveAbcL()
    {
                // Remove the CClassABC component from memory an
                // from the store. 
                // To remove the CClassABC representation from the 
                // store, just delete the stream containing the
                // embedded store which contains the representation of
                // the CClassABC object network.
    if (!iAbc)
        return;
    delete iAbc;
    iAbc = NULL;
                // close the embedded store
    delete iEmbeddedStore;
    iEmbeddedStore = NULL;
                // cleanup the stream (this is in the top 
                // level store) containing the embedded store
    iChildStream.Release();
                // delete the stream from the top level store ...
    iStore.DeleteL(iEmbeddedStoreId);
                // ... and commit these changes to the top
                // level store
    iStore.CommitL();           
    iEmbeddedStoreId = KNullStreamId;
    }

//***************************************************************
//
// CClassABC Implementation
//
//***************************************************************
CClassABC::CClassABC(CStreamStore& aStore)
    : iStore(aStore)
    {}

CClassABC::CClassABC(CStreamStore& aStore,TStreamId anId)
    : iStore(aStore), iId(anId)
    {}

CClassABC* CClassABC::NewLC(CStreamStore& aStore)
    {
    CClassABC* self = new (ELeave) CClassABC(aStore);
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
    }

CClassABC* CClassABC::NewL(CStreamStore& aStore)
    {
    CClassABC* self = CClassABC::NewLC(aStore);
    CleanupStack::Pop();
    return self;
    }

CClassABC* CClassABC::NewLC(CStreamStore& aStore, TStreamId anId)
    {                                                           
    CClassABC* self = new (ELeave) CClassABC(aStore,anId);
    CleanupStack::PushL(self);
    self->RestoreL();
    return self;
    }

CClassABC* CClassABC::NewL(CStreamStore& aStore, TStreamId anId)
    {
    CClassABC* self = CClassABC::NewLC(aStore,anId);
    CleanupStack::Pop();
    return self;
    }
        
void CClassABC::ConstructL()
    {
    iA = CClassA::NewL();
    iB = CClassB::NewL();
    iC = CClassC::NewL();
    }

void CClassABC::ConstructAL(const TDesC& aData,TInt anInt,TUint aUint)
    {
    iA->iVarBuf    = aData.AllocL();    
    iA->iIntValue  = anInt;
    iA->iUintValue = aUint;
    }
            
void CClassABC::ConstructB(const TDesC& aData,TInt anInt,TUint aUint,TReal aReal)
    {
    iB->iFixBuf    = aData;
    iB->iIntValue  = anInt; 
    iB->iUintValue = aUint;
    iB->iRealValue = aReal;
    }
            
void CClassABC::ConstructC(const TDesC& aData)
    {
    iC->iFixBuf = aData;
    }


            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
            // Destructor deletes the CClassB object only if it is in memory.
            // The IsPtr() function can be used to determine whether the 
            // CClassB object is memory. 
            // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
CClassABC::~CClassABC()
    {
    delete iA;
    delete iC;
    if (iB.IsPtr())
        delete iB.AsPtr(); // can also "delete iB;" makes implicit call to "operator T*()"
    }

    
                // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
                // Stores the CClassB object in its own stream and
                // then stores:
                //      the CClassA object,
                //      the streamid of the CClassB object,
                //      the CClassC object
                // in a separate stream.
                // Returns the streamid of this last stream
                // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
TStreamId CClassABC::StoreL()
    {
                // Construct the output stream which is intended
                // to hold the CClassB object only.
    RStoreWriteStream outstream;
    TStreamId idForB = outstream.CreateLC(iStore);
                // Stream out the CClassB object.
                // Note that the right hand side returns a reference
                // to CClassB
    outstream  << *iB; 
                // Commit changes to the stream
    outstream.CommitL();
                // Cleanup the stream object
    CleanupStack::PopAndDestroy();  
                // Now construct the output stream which is intended
                // to hold:
                //      the CClassA object,
                //      the streamid of the CClassB object,
                //      the CClassC object
    TStreamId id = outstream.CreateLC(iStore);
                // Write out the CClassA object.
    outstream  << *iA; 
                // Write out the stream id of the CClassB object
    outstream  << idForB;
                // Write out the CClassC object.
    outstream  << *iC;
                // Commit changes to the stream
    outstream.CommitL();
                // Cleanup the stream object,
    CleanupStack::PopAndDestroy();  
                // Return this stream id
    return id;
    }

                
const CClassA* CClassABC::PtrA()
    {
    return iA; // Return a pointer to the contained CClassA object
    }

                
const CClassB* CClassABC::PtrB()
    {
    if (iB.IsId())     // If the contained CClassB object is not in memory, it must
        RestoreBL();    // be loaded in before a pointer can be returned to the caller
    return iB.AsPtr();
    }

                
const CClassC* CClassABC::PtrC()
    {
    return iC; //Returns a pointer to the contained CClassC object
    }
                
                // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
                // Restores the CClassA and CClassC objects and the streamid for the
                // CClassB object.
                // The swizzle for the CClassB object is constructed from the
                // streamid but the CClassB object itself is NOT restored at 
                // this time.
                // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
void CClassABC::RestoreL()
    {
                // Construct the input stream.
    RStoreReadStream instream;
    instream.OpenLC(iStore,iId);
                // Construct a CClassA object and restore from the stream
    iA = CClassA::NewL();
    instream >> *iA;
                // Construct the swizzle for the CClassB object. This
                // stream contains the id of the stream which 
                // actually contains the full CClassB object. The loading of
                // the CClassB object into memory is deferred until later.
                // The resulting swizzle represents the CClassB object as 
                // a streamid 
    instream >> iB;
                // Construct a CClassC object and restrore from the stream
    iC = CClassC::NewL();
    instream >> *iC;
                // Cleanup the stream object
    CleanupStack::PopAndDestroy();
    }


                // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
                // Loads the CClassB object into memory and changes the swizzle's
                // representation from "streamid" to "pointer".
                // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * 
void CClassABC::RestoreBL()
    {
                // Construct the input stream. Assumes we have the correct store (this
                // emphasizes the need to ensure that the store remain open)
    RStoreReadStream instream;
    instream.OpenLC(iStore,iB.AsId());
                // Construct a CClassB object and restore from the stream. The 
                // assignment: CClassB* to TSwizzle<CClassB> changes the
                // swizzle's representation of the CClassB object 
                // from "streamid" to "pointer"
    CClassB* ptrB = CClassB::NewLC();
    instream >> *ptrB;
    CleanupStack::Pop();
    iB = ptrB;
                // Cleanup the stream object            
    CleanupStack::PopAndDestroy();
    }   

//***************************************************************
//
// CClassA Implementation
//
//***************************************************************
CClassA* CClassA::NewL()
    {
    CClassA* self = CClassA::NewLC();
    CleanupStack::Pop();
    return self;
    }

CClassA* CClassA::NewLC()
    {
    CClassA* self = new (ELeave) CClassA;
    CleanupStack::PushL(self);
    return self;
    }

CClassA::~CClassA()
    {
    delete iVarBuf;
    }

void CClassA::ExternalizeL(RWriteStream& aStream) const
    {
    aStream.WriteInt32L(iVarBuf->Des().MaxLength());
    aStream << *iVarBuf;
    aStream.WriteInt32L(iIntValue);
    aStream.WriteUint32L(iUintValue);
    }  
 
void CClassA::InternalizeL(RReadStream& aStream)
    {
    TInt maxlen;
    maxlen     = aStream.ReadInt32L();
    iVarBuf    = HBufC::NewL(aStream,maxlen);
    iIntValue  = aStream.ReadInt32L();
    iUintValue = aStream.ReadUint32L();
    }  
       

//***************************************************************
//
// CClassB Implementation
//
//***************************************************************
CClassB* CClassB::NewLC()
    {
    CClassB* self = new (ELeave) CClassB;
    CleanupStack::PushL(self);
    return self;
    }

CClassB* CClassB::NewL()   
    {
    CClassB* self = CClassB::NewLC();
    CleanupStack::Pop();    
    return self;
    }

void CClassB::ExternalizeL(RWriteStream& aStream) const
    {
    aStream << iFixBuf;
    aStream.WriteInt32L(iIntValue);
    aStream.WriteUint32L(iUintValue);
    aStream.WriteReal64L(iRealValue);
    }  
 
void CClassB::InternalizeL(RReadStream& aStream)
    {
    aStream >> iFixBuf;
    iIntValue  = aStream.ReadInt32L();
    iUintValue = aStream.ReadUint32L();
    iRealValue = aStream.ReadReal64L();
    }  

//***************************************************************
//
// CClassC Implementation
//
//***************************************************************
CClassC* CClassC::NewL()
    {
    CClassC* self = CClassC::NewLC();
    CleanupStack::Pop();
    return self;
    }

CClassC* CClassC::NewLC()
    {
    CClassC* self = new (ELeave) CClassC;
    CleanupStack::PushL(self);
    return self;
    }

void CClassC::ExternalizeL(RWriteStream& aStream) const
    {
    aStream << iFixBuf;
    }  
 
void CClassC::InternalizeL(RReadStream& aStream)
    {
    aStream >> iFixBuf;
    }  
// WriteToEmbedded.h
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.
//

//***************************************************************
//
// Function and class definitions used in the example
//
//***************************************************************
#ifndef __WriteToEmbedded_H
#define __WriteToEmbedded_H

#include "CommonStreamStore.h"
#include <s32file.h>

LOCAL_C void doMakeAndStoreL(const TDesC& aName);
LOCAL_C void doDeleteComponentL(const TDesC& aName);

LOCAL_C void doShow(const TDesC& aComment);

class CClassA;
LOCAL_C void doShow(const TDesC& aHeading,const CClassA& anA);

class CClassB;
LOCAL_C void doShow(const TDesC& aHeading,const CClassB& aB);

class CClassC;
LOCAL_C void doShow(const TDesC& aHeading,const CClassC& aC);


class CClassA : public CBase
    {
public :
    static CClassA* NewL();
    static CClassA* NewLC();
public :
    ~CClassA();
    void     ExternalizeL(RWriteStream& aStream) const;
    void     InternalizeL(RReadStream& aStream);
public :
    HBufC*   iVarBuf;
    TInt     iIntValue;
    TUint    iUintValue;
    };

class CClassB : public CBase
    {
public :
    static CClassB* NewL();
    static CClassB* NewLC();
public :
    void     ExternalizeL(RWriteStream& aStream) const;
    void     InternalizeL(RReadStream& aStream);
public :
    TBuf<32> iFixBuf;
    TUint    iUintValue;
    TInt     iIntValue;
    TReal    iRealValue;
    };

class CClassC : public CBase
    {
public  :
    static CClassC* NewL();
    static CClassC* NewLC();
public  :
    void     ExternalizeL(RWriteStream& aStream) const;
    void     InternalizeL(RReadStream& aStream);
public :
    TBuf<32> iFixBuf;
    };

class CClassABC : public CBase
    {
public :
    static CClassABC* NewLC(CStreamStore& aStore);
    static CClassABC* NewL(CStreamStore& aStore);
    static CClassABC* NewLC(CStreamStore& aStore, TStreamId anId);
    static CClassABC* NewL(CStreamStore& aStore, TStreamId anId);
public :
    CClassABC(CStreamStore& aStore);
    CClassABC(CStreamStore& aStore,TStreamId anId);
    ~CClassABC();
    TStreamId         StoreL();
    void              RestoreL();
    void              ConstructAL(const TDesC& aData,TInt anInt,TUint aUint);
    void              ConstructB(const TDesC& aData,TInt anInt,TUint aUint,TReal aReal);
    void              ConstructC(const TDesC& aData);
    const CClassA*    PtrA();
    const CClassB*    PtrB();
    const CClassC*    PtrC();
private :
    void              ConstructL();
    void              RestoreBL();
private :
    CClassA*          iA;
    TSwizzle<CClassB> iB;     // Note use of swizzle here
    CClassC*          iC;
    CStreamStore&     iStore; // Store to/Restore from this store
    TStreamId         iId;    // Restore from/replace this stream
    };

class CMainClass : public CBase
    {
public :
    static CMainClass* NewLC(CStreamStore& aStore);
    static CMainClass* NewLC(CStreamStore& aStore, TStreamId anId);
public :
    CMainClass(CStreamStore& aStore);
    CMainClass(CStreamStore& aStore,TStreamId anId);
    ~CMainClass();
    TStreamId           StoreL();
    void                RestoreL();
    void                InternalizeL(RReadStream& aStream);
    void                ExternalizeL(RWriteStream& aStream);
    CClassABC*          PtrAbc();
    void                RemoveAbcL();
private :
    void                ConstructL();
private :
    TBuf<32>            iSomeData;
    TStreamId           iEmbeddedStoreId;
    CEmbeddedStore*     iEmbeddedStore;
    RStoreReadStream    iChildStream;
    CClassABC*          iAbc;
    CStreamStore&       iStore; // Store to/Restore from this store
    TStreamId           iId;    // Restore from/replace this stream
    
    };
#endif
// BLD.INF
// Component description file 
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.

PRJ_MMPFILES

WriteToEmbedded.mmp
// WriteToEmbedded.mmp
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.

// using relative paths for source and userinclude directories

TARGET        WriteToEmbedded.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        WriteToEmbedded.cpp

USERINCLUDE   .
USERINCLUDE   ..\..\CommonFramework
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib efsrv.lib estor.lib

Description

This example shows how an object can be externalized to a store embedded within a permanent file store.


Classes used

[Top]


StoreMap: using a store map

Found in: examples\Base\Syslibs\Streams\StoreMap

// StoreMap.cpp
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.


// Example to demonstrate the streaming of a compound object to
// multiple streams with deferred loading.
// Also illustrates the use of a store map (CStoreMap) 

#include "CommonStreamStore.h"
#include <s32file.h>

//
// Format types and the newline character
//

_LIT(KTxtNewLine,"\n");
_LIT(KFormatType1,"\n%d");
_LIT(KFormatType2,"\n%S");
_LIT(KFormatType3,"\n%u");
_LIT(KFormatType4,"\n%f");

                // Constructs a CCompound object and externalizes
                // it and its components to separate streams.
LOCAL_C void doMakeAndExternalizeL(const TDesC& aName);        

                // Demonstrates deferred loading of
                // component objects.
LOCAL_C void doDeferredLoadingL(const TDesC& aName); 

                // Shows the content of the compound object 
class CCompound;
LOCAL_C void doShowAll(const TDesC& aHeading,const CCompound& aCompound);

                // Shows the content of the CLassA component
                // of the compound object.
class CClassA;
LOCAL_C void doShowComponent(const TDesC& aHeading,const CClassA& aComponent);

                // Shows the content of the CLassB component
                // of the compound object.
class CClassB; 
LOCAL_C void doShowComponent(const TDesC& aHeading,const CClassB& aComponent);

                // Shows the content of the CLassB component
                // of the compound object.
class CClassC;
LOCAL_C void doShowComponent(const TDesC& aHeading,const CClassC& aComponent);

                // Defintion of classes used by the example
class CClassA
    {
public :
    void        ExternalizeL(RWriteStream& aStream) const;
    void        InternalizeL(RReadStream& aStream);
    TStreamId   StoreL(CStreamStore& aStore) const;
    void        RestoreL(CStreamStore& aStore, TStreamId anId);
public :
    TBuf<32>  iBufferA;
    TInt        iXA;
    TUint       iYA;
    };


class CClassB
    {
public :
    void        ExternalizeL(RWriteStream& aStream) const;
    void        InternalizeL(RReadStream& aStream);
    TStreamId   StoreL(CStreamStore& aStore) const;
    void        RestoreL(CStreamStore& aStore, TStreamId anId);
public :
    TBuf<32>  iBufferB;
    };


class CClassC
    {
public :
    void        ExternalizeL(RWriteStream& aStream) const;
    void        InternalizeL(RReadStream& aStream);
    TStreamId   StoreL(CStreamStore& aStore) const;
    void        RestoreL(CStreamStore& aStore, TStreamId anId);
public :
    TReal       iZC;
    };

    
class CCompound : public CBase
    {
public :
    static      CCompound* NewLC(CStreamStore& aStore);
    static      CCompound* NewLC(CStreamStore& aStore,TStreamId anId);
public :
    CCompound(CStreamStore& aStore);
    CCompound(CStreamStore& aStore,TStreamId anId);
    ~CCompound();
    void        InternalizeL(RReadStream& aStream);
    void        ExternalizeL(RWriteStream& aStream) const;
    TStreamId   StoreL() const;
    void        RestoreL();
    void        StoreComponentsL(CStoreMap& aMap) const;
    void        DisplayAL(const TDesC& aCommentary);
private:
    void        ConstructL();
public :
    TSwizzle<CClassA> iA;
    TSwizzle<CClassB> iB;
    TSwizzle<CClassC> iC;
    CStreamStore&     iStore; // Store to/Restore from this store
    TStreamId         iId;    // Restore from/replace this stream
    };


// The file name, extension and path for the file store
_LIT(KFullNameOfFileStore,"\\epoc32ex\\data\\StoreMapUse.dat");

    // Do the example
LOCAL_C void doExampleL()
    {
                    // make sure directory exists
    fsSession.MkDirAll(KFullNameOfFileStore);
                // Construct a CCompound object and externalize
                // it and its components to separate streams.
    doMakeAndExternalizeL(KFullNameOfFileStore);
            
                // Demonstrate deferred loading of component objects
    doDeferredLoadingL(KFullNameOfFileStore);
    }

LOCAL_C void doMakeAndExternalizeL(const TDesC& aName)
    {
    TParse  filestorename;
    fsSession.Parse(aName,filestorename);
                // construct file store object - the file to contain the
                // the store replaces any existing file of the same name.
    CFileStore* store = CPermanentFileStore::ReplaceLC(fsSession,filestorename.FullName(),EFileWrite);

                // Must say what kind of file store
    store->SetTypeL(KPermanentFileStoreLayoutUid);

                    // Construct an object of type CCompound ... 
    CCompound* thecompound = CCompound::NewLC(*store);

                // ... and put some data into it.
                // Note that "iA->" achieves the same
                // as "iA->AsPtr()->"
    _LIT(KTxtClassAText,"CClassA text");
    _LIT(KTxtClassBText,"CClassB text");
    thecompound->iA.AsPtr()->iBufferA = KTxtClassAText;
    thecompound->iA.AsPtr()->iXA    = -1; 
    thecompound->iA->iYA            = 2; // see note above
    thecompound->iB.AsPtr()->iBufferB = KTxtClassBText;
    thecompound->iC.AsPtr()->iZC    = 3.456;

                // Show contents of the CCompound object (and its
                // components).
    _LIT(KTxtInitialContent,"... Initial content of CCompound");
    doShowAll(KTxtInitialContent,*thecompound);

                // stores all components as separate streams and
                // then streams the store map
    TStreamId id = thecompound->StoreL();

                // Set the stream id as the root
    store->SetRootL(id);

                // Commit changes to the store
    store->CommitL();

                // Destroy:
                // 1. the CCompound object
                // 2. the store object (this also closes 
                //    the file containing the store)
                // Remove both from the cleanup stack
    CleanupStack::PopAndDestroy(2);
    }

LOCAL_C void doDeferredLoadingL(const TDesC& aName)
    {
    TParse  filestorename;
    fsSession.Parse(aName,filestorename);
                // construct file store object - specifying the file
                // containing the store.
    CFileStore* store = CPermanentFileStore::OpenLC(fsSession,filestorename.FullName(),EFileRead);
    
                // Construct an object of type CCompound.
                // The loading of its components is deferred 
                // until needed.
    CCompound* thecompound = CCompound::NewLC(*store,store->Root());
    
                // Display component A.
                // The component is loaded in from the 
                // stream if not already loaded.
    _LIT(KTxtFirstDisplay," (first display)");
    thecompound->DisplayAL(KTxtFirstDisplay);

                // Re-Display component A
                // The component should now be in memory.
    _LIT(KTxtSecondDisplay," (second display)");
    thecompound->DisplayAL(KTxtSecondDisplay);

    console->Printf(KTxtNewLine);

                // Destroy:
                // 1. the CCompound object
                // 2. the store object (this also closes 
                //    the file containing the store)
                // Remove both from the cleanup stack
    CleanupStack::PopAndDestroy(2);
    }

_LIT(KTxtComponentA,"... Component A");
_LIT(KTxtComponentB,"... Component B");
_LIT(KTxtComponentC,"... Component C");
_LIT(KTxtPressKey,"\n (press any key to continue)");

LOCAL_C void doShowAll(const TDesC& aHeading,const CCompound& aCompound)
    { 
    console->Printf(KTxtNewLine);
    console->Printf(aHeading);
    if (aCompound.iA.IsPtr())
        doShowComponent(KTxtComponentA,*aCompound.iA.AsPtr());
    if (aCompound.iB.IsPtr())
        doShowComponent(KTxtComponentB,*aCompound.iB.AsPtr());
    if (aCompound.iB.IsPtr())
        doShowComponent(KTxtComponentC,*aCompound.iC.AsPtr());
    console->Printf(KTxtPressKey);
    console->Getch();
    }

LOCAL_C void doShowComponent(const TDesC& aHeading,const CClassA& aComponent)
    {
    console->Printf(KTxtNewLine);
    console->Printf(aHeading);
    console->Printf(KFormatType2,&aComponent.iBufferA);
    console->Printf(KFormatType1,aComponent.iXA);
    console->Printf(KFormatType3,aComponent.iYA);
    }

LOCAL_C void doShowComponent(const TDesC& aHeading,const CClassB& aComponent)
    {
    console->Printf(KTxtNewLine);
    console->Printf(aHeading);
    console->Printf(KFormatType2,&aComponent.iBufferB);
    }

LOCAL_C void doShowComponent(const TDesC& aHeading,const CClassC& aComponent)
    {
    console->Printf(KTxtNewLine);
    console->Printf(aHeading);
    console->Printf(KFormatType4,aComponent.iZC);
    }

//***************************************************************
//***************************************************************
CCompound::CCompound(CStreamStore& aStore)
    : iStore(aStore)
    {}

CCompound::CCompound(CStreamStore& aStore,TStreamId anId)
    : iStore(aStore), iId(anId)
    {}


                // Construct a plain CCompound object and
                // place on the cleanup stack.
CCompound* CCompound::NewLC(CStreamStore& aStore)
    {
    CCompound* self=new (ELeave) CCompound(aStore);
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
    }


                // Construct a CCompound object. The
                // components are restored when needed; however
                // the streamids of the component streams
                // ARE restored.
CCompound* CCompound::NewLC(CStreamStore& aStore,TStreamId anId)
    {
    CCompound* self=new (ELeave) CCompound(aStore,anId);
    CleanupStack::PushL(self);
   self->RestoreL();
    return self;
    }

                // Complete the construction of the 
                // plain CCompound object. Makes implicit 
                // use of  TSwizzle operators.
void CCompound::ConstructL()
    {
    iA = new (ELeave) CClassA;
    iB = new (ELeave) CClassB;
    iC = new (ELeave) CClassC;
    }

                // The CCompound destructor. Destroy the swizzled
                // contained objects only if they are in memory
CCompound::~CCompound()
    {
    if (iA.IsPtr())
        delete iA.AsPtr();
    if (iB.IsPtr())
        delete iB.AsPtr();
    if (iC.IsPtr())
        delete iC.AsPtr();
    }

void CCompound::RestoreL()
    {
    RStoreReadStream stream;
    stream.OpenLC(iStore,iId);
    InternalizeL(stream);
    CleanupStack::PopAndDestroy();
    }
                
void CCompound::InternalizeL(RReadStream& aStream)
    {
    aStream >> iA;  
    aStream >> iB;
    aStream >> iC;
    }
                // Display the content of the "A" component
                // object. The component is fully restored 
                // from the appropriate stream, if it has not
                // already been restored. 
void CCompound::DisplayAL(const TDesC& aCommentary)
    {
    if (iA.IsId())
        {
        CClassA* ptrA = new (ELeave) CClassA;
        CleanupStack::PushL(ptrA);
        ptrA->RestoreL(iStore,iA.AsId());
        iA = ptrA;
        CleanupStack::Pop(); 
        }
    _LIT(KTxtRestoredComponent,"... Displaying restored component A");
    TBuf<96> heading(KTxtRestoredComponent);
    heading.Append(aCommentary); 
    doShowComponent(heading,*iA.AsPtr());
    }


        
void CCompound::ExternalizeL(RWriteStream& aStream) const
    {
    aStream << iA; // these are swizzles
    aStream << iB;
    aStream << iC;
    }

TStreamId CCompound::StoreL() const
    {
    CStoreMap* map=CStoreMap::NewLC(iStore);
    StoreComponentsL(*map);
//
    RStoreWriteStream stream(*map);
    TStreamId id=stream.CreateLC(iStore);
    ExternalizeL(stream);
    stream.CommitL();
//
    map->Reset();
    CleanupStack::PopAndDestroy(2);
    return id;
    }

void CCompound::StoreComponentsL(CStoreMap& aMap) const
    {
    TStreamId id;
    
    if (iA)
        {
        id = iA->StoreL(iStore);
        aMap.BindL(iA,id);
        }

    if (iB)
        {
        id = iB->StoreL(iStore);
        aMap.BindL(iB,id);
        }

    if (iC)
        {
        id = iC->StoreL(iStore);
        aMap.BindL(iC,id);
        }
    }

//***************************************************************
//***************************************************************

                // Read the data members of the CClassA 
                // object from the stream.
void CClassA::InternalizeL(RReadStream& aStream)
    {
    aStream >> iBufferA;
      iXA = aStream.ReadInt32L();
    iYA = aStream.ReadUint32L();
    }  
                // Write the data members of the CClassA 
                // object to the stream.
void CClassA::ExternalizeL(RWriteStream& aStream) const
    {
    aStream << iBufferA;
    aStream.WriteInt32L(iXA);
    aStream.WriteUint32L(iYA);
    }  

TStreamId CClassA::StoreL(CStreamStore& aStore) const
    {
    RStoreWriteStream stream;
    TStreamId id=stream.CreateLC(aStore);
    ExternalizeL(stream);
    stream.CommitL();
    CleanupStack::PopAndDestroy();
    return id;
    }

void CClassA::RestoreL(CStreamStore& aStore, TStreamId anId)
    {
    RStoreReadStream stream;
    stream.OpenLC(aStore,anId);
    InternalizeL(stream);
    CleanupStack::PopAndDestroy();
    }

//***************************************************************
//***************************************************************

                // Read the data member(s) of the CClassB 
                // object from the stream.
void CClassB::InternalizeL(RReadStream& aStream)
    {
    aStream >> iBufferB;
      }
                // Write the data member(s) of the CClassB 
                // object to the stream.
void CClassB::ExternalizeL(RWriteStream& aStream) const
    {
    aStream << iBufferB;
    }  

TStreamId CClassB::StoreL(CStreamStore& aStore) const
    {
    RStoreWriteStream stream;
    TStreamId id=stream.CreateLC(aStore);
    ExternalizeL(stream);
    stream.CommitL();
    CleanupStack::PopAndDestroy();
    return id;
    }

void CClassB::RestoreL(CStreamStore& aStore, TStreamId anId)
    {
    RStoreReadStream stream;
    stream.OpenLC(aStore,anId);
    InternalizeL(stream);
    CleanupStack::PopAndDestroy();
    }


//***************************************************************
//***************************************************************

                // Write the data member(s) of the CClassC 
                // ob ject to the stream.
void CClassC::ExternalizeL(RWriteStream& aStream) const
    {
    aStream.WriteReal64L(iZC);
    }  
                // Read the data member(s) of the CClassC 
                // object from the stream.
void CClassC::InternalizeL(RReadStream& aStream)
    {
    iZC = aStream.ReadReal64L();
    }  
       
TStreamId CClassC::StoreL(CStreamStore& aStore) const
    {
    RStoreWriteStream stream;
    TStreamId id=stream.CreateLC(aStore);
    ExternalizeL(stream);
    stream.CommitL();
    CleanupStack::PopAndDestroy();
    return id;
    }


void CClassC::RestoreL(CStreamStore& aStore, TStreamId anId)
    {
    RStoreReadStream stream;
    stream.OpenLC(aStore,anId);
    InternalizeL(stream);
    CleanupStack::PopAndDestroy();
    }



    
    
// BLD.INF
// Component description file 
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.


PRJ_MMPFILES

StoreMap.mmp
// StoreMap.mmp
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.

// using relative paths for source and userinclude directories

TARGET        StoreMap.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        StoreMap.cpp

USERINCLUDE   .
USERINCLUDE   ..\..\CommonFramework
SYSTEMINCLUDE \Epoc32\include

LIBRARY       euser.lib efsrv.lib estor.lib

Description

This example demonstrates the streaming of a compound object to multiple streams with deferred loading. It also illustrates the use of a store map (CStoreMap).


Classes used