Symbian
Symbian Developer Library

SYMBIAN OS V9.4

Feedback

[Index] [Previous] [Next]


File stores example code

These examples demonstrate aspects of streaming and file stores.

[Top]


WriteDirectFS: externalising a network of objects to a direct file store


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\FileStores\WriteDirectFS

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

// Example to demonstrate writing out a network of objects
// to a direct file store and then loading them all back in.
//
// Demonstrates the persistence of a direct file store and the idea
// of the root stream. 
//
// The example:
//      constructs three different types of object,
//
//      puts data into the objects,
//
//      displays the content of the objects,
//
//      creates a direct file store (replacing any existing direct 
//      file store of the same name),
//
//      writes the objects to a single stream,
//
//      makes this stream the root stream,
//
//      closes the store and deletes the objects (from memory),
//
//      re-opens the store and restores the objects from the root stream,
//
//      displays the contents of the restored objects
//
//
// Notes:
//      The file name and extension of the direct file store is 
// "WriteDirectFS.dat" and will be created in the data folder of the 
//  writable drive"


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

                // Constructs objects of type CClassA, CClassB and CClassC,
                // externalizes them to a direct file store and then destroys the
                // CClassA, CClassB and CClassC objects. 
LOCAL_C void doMakeAndStoreL(const TDesC& aName);

                // Constructs "empty" CClassA, ClassB and CCLassC objects and
                // restores them from the direct file store.
LOCAL_C void doRestoreL(const TDesC& aName);

                // Displays the contents of a CClassA object
class CClassA;
LOCAL_C void doShow(const TDesC& aHeading,const CClassA& anA);

                // Displays the contents of a CClassB object
class CClassB;
LOCAL_C void doShow(const TDesC& aHeading,const CClassB& aB);

                // Displays the contents of a CClassB object
class CClassC;
LOCAL_C void doShow(const TDesC& aHeading,const CClassC& aC);

                // definition of CClassA
class CClassA : public CBase
    {
public :
    static CClassA* NewLC();
    ~CClassA();
    void     SetTextL(const TDesC& aData);
    void     ExternalizeL(RWriteStream& aStream) const;
    void     InternalizeL(RReadStream& aStream);
public :
    HBufC*   iVarBuffer;
    TInt     iIntValue;
    TUint    iUintValue;
    };

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

// definition of CClassC

#define KStdirectClassCGranularity 4

class CClassC : public CBase
    {
public :
    static CClassC* NewLC();
    ~CClassC();
    void     ConstructL();
    void     AddNumberToArrayL(TInt aValue);
    void     ExternalizeL(RWriteStream& aStream) const;
    void     InternalizeL(RReadStream& aStream);
public :
    TBuf<32> iFixBuffer;
    CArrayFixFlat<TInt>* iArray;
    };



// The file name, extension and path for the file store
_LIT(KFullNameOfFileStore,"\\epoc32ex\\data\\WriteDirectFS.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)
    {
                // Construct an object of type CClassA and put some 
                // data into it
    _LIT(KTxtForClassA,"Text for CClassA");
    CClassA* theA = CClassA::NewLC();
    theA->SetTextL(KTxtForClassA);   
    theA->iIntValue  = -1;
    theA->iUintValue = 2;

                // Construct an object of type CClassB and put some 
                // data into it
    _LIT(KTxtForClassB,"Text for CClassB");
    CClassB* theB = CClassB::NewLC();
    theB->iFixBuffer = KTxtForClassB;
    theB->iIntValue  = -3;
    theB->iUintValue = 4; 
    theB->iRealValue = 5.6;

                // Construct an object of type CClassC and put some 
                // data into it
    _LIT(KTxtForClassC,"Text for CClassC");
    CClassC* theC = CClassC::NewLC();
    theC->iFixBuffer = KTxtForClassC;  
    theC->AddNumberToArrayL(21);
    theC->AddNumberToArrayL(42);
    theC->AddNumberToArrayL(101);

                // Show contents of the CClassA object
    _LIT(KTxtClassAContent,"CClassA content ...");
    doShow(KTxtClassAContent,*theA);

                // Show contents of the CClassB object
    _LIT(KTxtClassBContent,"CClassB content ...");
    doShow(KTxtClassBContent,*theB);                    

                // Show contents of the CClassC object
    _LIT(KTxtClassCContent,"CClassC content ...");
    doShow(KTxtClassCContent,*theC);                    
                
                // Create (replace) 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 output stream.
    RStoreWriteStream outstream;
    TStreamId id = outstream.CreateLC(*store);

                // Stream out the CClassA object, the
                // CClassB object and the CClassC object
    outstream  << *theA << *theB << *theC; 

                // Equally we could have done:
                //      outstream << *theA;
                //      outstream << *theB;
                //      outstream << *theC;
                // to the same effect
                
                // The order in which the objects are written out is
                // arbitrary, but it is important to note that 
                // THE ORDER IN WHICH THEY ARE WRITTEN OUT IS THE SAME
                // AS THE ORDER IN WHICH THEY WILL BE READ IN LATER !
                
                // Commit changes to the stream
    outstream.CommitL();

                // Cleanup the stream object
    CleanupStack::PopAndDestroy();

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

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

                // Destroy the direct file store object (closes the file),
                // Destroy the CClassC object,
                // Destroy the CClassB object,
                // Destroy the CClassA object.
    CleanupStack::PopAndDestroy(4); 
    }

LOCAL_C void doRestoreL(const TDesC& aName)
    {
                // Construct "empty" CClassA, CClassB and CClassC objects
    CClassA* theA = CClassA::NewLC();
    CClassB* theB = CClassB::NewLC();
    CClassC* theC = CClassC::NewLC();
                    
                // Open the direct file store
    TParse  filestorename;
    fsSession.Parse(aName,filestorename);
    CFileStore* store = CDirectFileStore::OpenLC(fsSession,filestorename.FullName(),EFileRead);

                // Construct and open the root stream which 
                // contains the representation of our objects.
    RStoreReadStream instream;
    instream.OpenLC(*store,store->Root());
    
                // Stream in the CClassA object, the
                // CClassB object and the CClassC object
    instream  >> *theA >> *theB >> *theC; 

                // Equally we could have done:
                //      instream >> *theA;
                //      instream >> *theB;
                //      instream >> *theC;
                // to the same effect

                // Cleanup the stream object
    CleanupStack::PopAndDestroy();

                // Show restored contents of the CClassA object
    _LIT(KTxtRestoredCClassA,"Restored CClassA content ...");
    doShow(KTxtRestoredCClassA,*theA);

                // Show restored contents of the CClassB object
    _LIT(KTxtRestoredCClassB,"Restored CClassB content ...");
    doShow(KTxtRestoredCClassB,*theB);                  

                // Show restored contents of the CClassC object
    _LIT(KTxtRestoredCClassC,"Restored CClassC content ...");
    doShow(KTxtRestoredCClassC,*theC);  
                
                // Destroy the direct file store object (closes the file) 
                // Destroy the CClassC object, 
                // Destroy the CClassB object, 
                // Destroy the CClassA object, 
    CleanupStack::PopAndDestroy(4);
    }
    
                                    
_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.iVarBuffer);
    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.iFixBuffer);
    console->Printf(KFormatType2,aB.iIntValue);
    console->Printf(KFormatType4,aB.iUintValue);
    console->Printf(KFormatType5,aB.iRealValue);
    console->Printf(KTxtNewLine);
    }

_LIT(KTxtNoArrayItems,"<No array items>");
_LIT(KTxtColonsep,": ");
_LIT(KTxtCommasep,", ");
_LIT(KFormatType6,"%d array item(s)");
_LIT(KFormatType7,"%S%d");

LOCAL_C void doShow(const TDesC& aHeading,const CClassC& aC)
    {
    console->Printf(KTxtNewLine);
    console->Printf(aHeading);
    console->Printf(KFormatType1,&aC.iFixBuffer);
    
    TInt count = aC.iArray->Count();
    if (!count)
        console->Printf(KTxtNoArrayItems);
    else
        {
        TPtrC   ptr;
        ptr.Set(KTxtColonsep);
        console->Printf(KFormatType6,count);
        for (TInt index = 0; index < count; index++)
            {
            console->Printf(KFormatType7,&ptr,(*aC.iArray)[index]);
            ptr.Set(KTxtCommasep);      
            }
        }
    console->Printf(KTxtNewLine);
    }

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

void CClassA::SetTextL(const TDesC& aData)
    {
    iVarBuffer = aData.AllocL();  
    }

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

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

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


//***************************************************************
//***************************************************************
CClassC* CClassC::NewLC()
    {
    CClassC* self = new (ELeave) CClassC;
    CleanupStack::PushL(self);
    self->ConstructL();
    return self;
    }
    
void CClassC::ConstructL()
    {
    iArray = new (ELeave) CArrayFixFlat<TInt>(KStdirectClassCGranularity);
    }

void CClassC::AddNumberToArrayL(TInt aValue)
    {
    iArray->AppendL(aValue);
    }

CClassC::~CClassC()
    {
    delete iArray;
    }

void CClassC::ExternalizeL(RWriteStream& aStream) const
    {
    aStream << iFixBuffer;

    TInt count;
    count = iArray->Count();
    aStream.WriteInt32L(count);
    for (TInt index = 0; index < count; index++)
        aStream.WriteInt32L((*iArray)[index]);
    }  
 
void CClassC::InternalizeL(RReadStream& aStream)
    {
    aStream >> iFixBuffer;

    TInt count;
    count  = aStream.ReadInt32L();
    
    for (TInt index = 0; index < count; index++)
        iArray->AppendL(aStream.ReadInt32L());
    }  
       

       



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

PRJ_MMPFILES

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

// using relative paths for source and userinclude directories

TARGET        WriteDirectFS.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        WriteDirectFS.cpp

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

LIBRARY       euser.lib efsrv.lib estor.lib

Description

This example externalises a network of objects to a direct file store and then internalises them again. It demonstrates the persistence of a direct file store and the idea of the root stream.


Classes used

[Top]


WritePermFS1: externalising a network of objects to a permanent file store


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\FileStores\WritePermFS1

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

// Example constructs and writes a network of objects to a permanent file store.
//
// Each object is then loaded back in, one at a time, its content displayed at the 
// console and then destroyed.
//
// The CClassR object is changed and stored back before it is destroyed 
//
// The order in which the objects are loaded from the store is different from the order
// in which they were initially created.
// The example creates an index of "top level" stream ids. The index is stored in its
// own stream and forms the root stream of the store. 
//
//
// The example:
//      creates a permanent file store (replacing any existing permanent 
//      file store of the same name)
//
//      constructs a TExampleIndex object
//
//      constructs a CClassP object, externalizes it in its own stream, 
//      saves the stream id in the index and then destroys the 
//      CClassP object
//              
//      constructs a CClassR object, externalizes it in its own stream, 
//      saves the stream id in the index and then destroys the 
//      CClassR object
//  
//      constructs a CClassABC container object containing a CClassA, 
//      a CClassB and a CClassC object and then completes the construction
//      of these contained objects.
//      The CClassB object is externalized in its own stream. The CClassA, the streamid of the
//      CClassB object and the CClassC object are externalized in a single
//      stream and this streamid is saved into the index
//
//      externalizes the TExampleIndex object in its own stream and makes
//      this stream the root stream of the file store.
//
//      closes the permanent file store.
//
//          ========================================================
//
//      re-opens the permanent file store
//
//      restores the TExampleIndex object from the root stream
//
//      restores the CClassR object from its stream, displays the content,
//      changes the content, replaces the stream and then destroys the object from
//      memory
//
//      restores the CClassR object for a second time from its stream, displays 
//      the (updated) content and then destroys the object from memory again
//
//      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.
//
//      restores the CClassP object from its stream and displays its contents
//      and then destroys it
//
//      (NB that the order in which the objects are restored is different to 
//      the order in which their corresponding streams were created)
//
//      closes the permanent file store.
//
// Notes:
//      The file name and extension of the permanent file store is 
//      "WritePermFS.dat"and will be created in the folder "\epoc32ex\data\" 
//      of the writable drive.
//
#include "WritePermFS1.h"

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


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

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

LOCAL_C void doMakeL(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);

                // Create a TExampleIndex object to hold the stream ids of all
                // the component streams
    TExampleIndex theIndex;

                // Construct the CClassP object, putting some data into it, 
                // write it to its own stream and save the stream id in
                // the index.
                // Destroy the CClassP object after stream creation
    _LIT(KTxtDataForClassP,"Data for CClassP - PPPPP");
    CClassP* theP = CClassP::NewLC(KTxtDataForClassP,*store);
    theIndex.iPid = theP->StoreL();
    CleanupStack::PopAndDestroy();
    
                // Construct the CClassR object, put some data into it, 
                // write it to its own stream and save the stream id in
                // the index.
                // Destroy the CClassR object after stream creation
    _LIT(KTxtDataForClassR,"Data for the CClassR - RRRRR");
    CClassR* theR = CClassR::NewLC(KTxtDataForClassR,*store);
    theIndex.iRid = theR->StoreL();
    CleanupStack::PopAndDestroy();                          
                
                // Construct the container object for CClassA,CClassB and CClassC.
                // Complete the construction of the contained CClassA, CClassB
                // and CClassC objects.
                //  
                // Write out this object network and save the top level stream id
                // in the index.
                // Destroy this object network after stream creation
    _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);
    theIndex.iABCid = theABC->StoreL();
    CleanupStack::PopAndDestroy();                          

                // Now write the index itself to its own stream ...
    TStreamId id  = theIndex.StoreL(*store);

                // ... and make this stream the root stream
    store->SetRootL(id);

                // Now commit all changes to the store
    store->CommitL();
            
                // Destroy the permanent file store object (closes the file)
    CleanupStack::PopAndDestroy();  
    }


LOCAL_C void doUseL(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 index of streamids so that we can access (restore)
                // all the other objects. The index is found in the root stream 
    TExampleIndex theIndex;
    theIndex.RestoreL(*store,store->Root());
                
                // Restore the CClassR object, display the content, make a change and
                // update the stream to reflect the changed content.
                // If updating the stream succeeds, commit the changes to the store
                // otherwise attempt to revert the store to its state at the last
                // commit point.
                // Destroy the CClassR object.
    CClassR* theR;

    _LIT(KTxtClassRContent,"CClassR content ...");
    _LIT(KTxtNewForClassR,"New data for the CClassR +++++++");

    theR = CClassR::NewLC(*store,theIndex.iRid);
    doShow(KTxtClassRContent,*theR);
    theR->ChangeDataL(KTxtNewForClassR);
    CleanupStack::PopAndDestroy();
                
                // Restore the CClassR object again, display the content and
                // then destroy it
    _LIT(KTxtUpadtedClassR,"Updated CClassR content ...");

    theR = CClassR::NewLC(*store,theIndex.iRid);
    doShow(KTxtUpadtedClassR,*theR);
    CleanupStack::PopAndDestroy();

                // Restore the CClassABC and display content of all contained objects.
                // Note that the loading of the CClassB object is deferred until it 
                // is needed.
                // Destroy the CClassABC 
    _LIT(KTxtShowClassA,"CClassA content ...");
    _LIT(KTxtShowClassB,"CClassB content ...");
    _LIT(KTxtShowClassC,"CClassC content ...");

    CClassABC* theABC = CClassABC::NewLC(*store,theIndex.iABCid);
    doShow(KTxtShowClassA,*theABC->PtrA());
    doShow(KTxtShowClassB,*theABC->PtrB());// CClassB object is loaded at this point
    doShow(KTxtShowClassC,*theABC->PtrC());  
    CleanupStack::PopAndDestroy();

                // Restore the CClassP object, display the content and
                // then destroy it;
    _LIT(KTxtShowClassP,"CClassP content ...");

    CClassP* theP = CClassP::NewLC(*store,theIndex.iPid);
    doShow(KTxtShowClassP,*theP);
    CleanupStack::PopAndDestroy();

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

_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);
    }

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

LOCAL_C void doShow(const TDesC& aHeading,const CClassR& aR)
    {
    console->Printf(KTxtNewLine);
    console->Printf(aHeading);
    console->Printf(KFormatType1,&aR.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;
    }  

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

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

CClassP* CClassP::NewLC(const TDesC& aData,CStreamStore& aStore)
    {
    CClassP* self = new (ELeave) CClassP(aStore);
    CleanupStack::PushL(self);
    self->Construct(aData);
    return self;
    }

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

void CClassP::Construct(const TDesC& aData)
    {
    iFixBuf = aData;
    }

void CClassP::RestoreL()
    {
    RStoreReadStream instream;
    instream.OpenLC(iStore,iId);
    InternalizeL(instream);         // or we can say instream >> *this;
    CleanupStack::PopAndDestroy();  
    }

TStreamId CClassP::StoreL()
    {
    RStoreWriteStream outstream;
    TStreamId id = outstream.CreateLC(iStore);
    ExternalizeL(outstream);        // or we can say outstream << *this;
    outstream.CommitL();
    CleanupStack::PopAndDestroy();  
    return id;
    }

void CClassP::ExternalizeL(RWriteStream& aStream) const
    {
    aStream << iFixBuf;
    }  
 
void CClassP::InternalizeL(RReadStream& aStream)
    {
    aStream >> iFixBuf;
    }  


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

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

CClassR* CClassR::NewLC(const TDesC& aData,CStreamStore& aStore)
    {
    CClassR* self = new (ELeave) CClassR(aStore);
    CleanupStack::PushL(self);
    self->Construct(aData);
    return self;
    }

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

void CClassR::Construct(const TDesC& aData)
    {
    iFixBuf = aData;
    }

_LIT(KTxtFailedMsg,"Failed to update CClassR stream\n");

void CClassR::ChangeDataL(const TDesC& aData)
    {
    iFixBuf = aData;
    TRAPD(error,UpdateStoreL());
    if (error!=KErrNone)
        {
        iStore.Revert();
        console->Printf(KTxtFailedMsg);
        User::Leave(error);
        }
    }
        
void CClassR::RestoreL()
    {
    RStoreReadStream instream;
    instream.OpenLC(iStore,iId);
    InternalizeL(instream);         // or we can say instream >> *this;
    CleanupStack::PopAndDestroy();  
    }

TStreamId CClassR::StoreL()
    {
    RStoreWriteStream outstream;
    TStreamId id = outstream.CreateLC(iStore);
    ExternalizeL(outstream);        // or we can say outstream << *this;
    outstream.CommitL();
    CleanupStack::PopAndDestroy();  
    return id;
    }

void CClassR::UpdateStoreL()
    {
    RStoreWriteStream outstream;
    outstream.ReplaceLC(iStore,iId);
    ExternalizeL(outstream);        // or we can say outstream << *this;
    outstream.CommitL();
    CleanupStack::PopAndDestroy();
    iStore.CommitL();// commit the changes to the store
    }

void CClassR::ExternalizeL(RWriteStream& aStream) const
    {
    aStream << iFixBuf;
    }  
 
void CClassR::InternalizeL(RReadStream& aStream)
    {
    aStream >> iFixBuf;
    }  

//***************************************************************
//
// TExampleIndex Implementation
//
//***************************************************************

TStreamId TExampleIndex::StoreL(CStreamStore& aStore)
    {
    RStoreWriteStream outstream;
    TStreamId id = outstream.CreateLC(aStore);
    ExternalizeL(outstream);        // or we can say outstream << *this;
    outstream.CommitL();
    CleanupStack::PopAndDestroy();  
    return id;
    }

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

void TExampleIndex::ExternalizeL(RWriteStream& aStream) const
    {
    aStream << iPid;
    aStream << iRid;
    aStream << iABCid;
    }  

void TExampleIndex::InternalizeL(RReadStream& aStream)
    {
    aStream >> iPid;
    aStream >> iRid;
    aStream >> iABCid;
    }  
// WritePermFS1.h
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.
//

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

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

LOCAL_C void doMakeL(const TDesC& aName);
LOCAL_C void doUseL(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 CClassP;
LOCAL_C void doShow(const TDesC& aHeading,const CClassP& aP);

class CClassR;
LOCAL_C void doShow(const TDesC& aHeading,const CClassR& aR);

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 CClassP : public CBase
    {
public  :
    static CClassP* NewLC(const TDesC& aData,CStreamStore& aStore);
    static CClassP* NewLC(CStreamStore& aStore, TStreamId anId);
public  :
    CClassP(CStreamStore& aStore);
    CClassP(CStreamStore& aStore,TStreamId anId);
public  :
    TStreamId     StoreL();
    void          RestoreL();
    void          ExternalizeL(RWriteStream& aStream) const;
    void          InternalizeL(RReadStream& aStream);
private :
    void          Construct(const TDesC& aData);
public :
    TBuf<32>      iFixBuf;
    CStreamStore& iStore; // Store to/Restore from this store
    TStreamId     iId;    // Restore from/replace this stream
    };


class CClassR : public CBase
    {
public  :
    static CClassR* NewLC(const TDesC& aData,CStreamStore& aStore);
    static CClassR* NewLC(CStreamStore& aStore, TStreamId anId);
public  :
    CClassR(CStreamStore& aStore);
    CClassR(CStreamStore& aStore,TStreamId anId);
public  :
    TStreamId     StoreL();
    void          UpdateStoreL();
    void          RestoreL();
    void          ExternalizeL(RWriteStream& aStream) const;
    void          InternalizeL(RReadStream& aStream);
    void          ChangeDataL(const TDesC& aData);
private :
    void          Construct(const TDesC& aData);
public :
    TBuf<32>      iFixBuf;
    CStreamStore& iStore; // Store to/Restore from this store
    TStreamId     iId;    // Restore from/replace this stream
    };


class TExampleIndex
    {
public :
    TStreamId StoreL(CStreamStore& aStore);
    void      RestoreL(CStreamStore& aStore, TStreamId anId);
    void      ExternalizeL(RWriteStream& aStream) const;
    void      InternalizeL(RReadStream& aStream);
public :
    TStreamId iPid;
    TStreamId iRid;
    TStreamId iABCid;
    };


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

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

// using relative paths for source and userinclude directories

TARGET        WritePermFS1.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        WritePermFS1.cpp

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

LIBRARY       euser.lib efsrv.lib estor.lib

Description

This example constructs and writes a network of objects to a permanent file store. Each object is then loaded back in, one at a time, its content displayed at the console and then destroyed.


Classes used

[Top]


WritePermFS2: externalising a network of objects to a permanent file store


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\FileStores\WritePermFS2

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

// Example to demonstrate use of CPermanentFileStore


// The Store root stream is an example of a persistent data structure
// The internal representation is the class CItemArray


#include "CommonStreamStore.h"
#include <s32file.h>
    
                // Create a permanent file store
                // and initialise its stream structure
LOCAL_C void doMakeStoreL(const TDesC& aName);

                // Use the store, preserving the stream structure
LOCAL_C void doUseStoreL(const TDesC& aName);

                // Update the data in the store
LOCAL_C void doUpdateStoreL(CPersistentStore& aStore);

                // Display the store contents
LOCAL_C void doShowL(const TDesC& aHeading,CPersistentStore& aStore);


typedef TBuf<100> TItem;

                // The main object's in-memory representation
class CItemArray : public CBase
    {
public:
    static TStreamId CreateL(CStreamStore& aStore);
        //
    ~CItemArray();
    static CItemArray* NewLC(CStreamStore& aStore,TStreamId anId);
    void RestoreL();
    void StoreL() const;
    void ExternalizeL(RWriteStream& aStream) const;
        //
    void AddItemL(const TItem& anItem);
    void RemoveItemL(TInt anIndex);
    TInt Count() const;
    void GetItemL(TItem& anItem,TInt anIndex) const;
protected:
    CItemArray(CStreamStore& aStore);
    void ConstructL();
    void InternalizeL(RReadStream& aStream);
private:
    CStreamStore& iStore;
    TStreamId iMyId;
    CArrayFixFlat<TStreamId>* iArray;
    };


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


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


LOCAL_C void doMakeStoreL(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(),EFileRead|EFileWrite);
                // Easy way to set the layout type
    store->SetTypeL(store->Layout());
        
                // create the required stream for CItemArray
    TStreamId id=CItemArray::CreateL(*store);

                // make it the root
    store->SetRootL(id);
            
                // Commit changes to the store
    store->CommitL();

                // Show contents of the store
    _LIT(KTxtStoreContent,"Store content ...");
    doShowL(KTxtStoreContent,*store);

                // Cleanup the store
    CleanupStack::PopAndDestroy();
    }


LOCAL_C void doUseStoreL(const TDesC& aName)
    {
    TParse  filestorename;
    fsSession.Parse(aName,filestorename);
                // construct file store object - specifying the file
                // containing the store.
                // Do not need to specify the file store type, this is
                // specified by the file itself
    CFileStore* store = CFileStore::OpenL(fsSession,filestorename.FullName(),EFileRead|EFileWrite);

                // The standard form for using permanent file stores:
                // 1. The store object is not owned by the updating code
                // 2  Failure at any point during update, including the
                //    final commit, should result in Revert() being called
                //    on the store (before destruction).

    _LIT(KTxtErrorOccurred,"\n** Error %d occured during store update");

    TRAPD(error,doUpdateStoreL(*store));
    if (error!=KErrNone)
        {
        store->Revert();
        console->Printf(KTxtErrorOccurred);
        }

                // the store is not on the cleanup stack
    delete store;
    }


LOCAL_C void doUpdateStoreL(CPersistentStore& aStore)
    {
                // get the root stream into memory
    CItemArray* array=CItemArray::NewLC(aStore,aStore.Root());

                // Add some items
    _LIT(KTxtHello,"hello");
    _LIT(KTxtWorld," world!");

    TItem item;
    item = KTxtHello;
    array->AddItemL(item);
    item = KTxtWorld;
    array->AddItemL(item);
                // Re-write the root stream with new data
    array->StoreL();
                // commit all changes
    aStore.CommitL();

    _LIT(KTxtAfterAdding,"After adding...");
    doShowL(KTxtAfterAdding,aStore);

                // remove an item
    array->RemoveItemL(1);       // " world!"
                // Re-write the root stream with new data
    array->StoreL();
                // commit all changes
    aStore.CommitL();

    _LIT(KTxtAfterRemoving,"After removing...");
    doShowL(KTxtAfterRemoving,aStore);

                // Add an item
    _LIT(KTxtCapWorld," WORLD!");
    item= KTxtCapWorld;
    array->AddItemL(item);
                // Re-write the root stream with new data
    array->StoreL();
                // Discard all changes since last store commit
    aStore.Revert();

    _LIT(KTxtAfterRevert,"After revert...");
    doShowL(KTxtAfterRevert,aStore);

                // array and aStore are not in snych after revert...
                // restore in-memory version to match store version
    array->RestoreL();

                    // Add the item again
    array->AddItemL(item);
                // Re-write the root stream with new data
    array->StoreL();
                // commit all changes
    aStore.CommitL();

    _LIT(KTxtAfterCommit,"After commit...");
    doShowL(KTxtAfterCommit,aStore);

                // cleanup array
    CleanupStack::PopAndDestroy();
    }

_LIT(KTxtNewLine,"\n");
_LIT(KFormatType1,"\n%d item(s):");
_LIT(KFormatType2,"\n  %S");
_LIT(KFormatType3,"\n[any key to continue]\n");


LOCAL_C void doShowL(const TDesC& aHeading,CPersistentStore& aStore)
    {
                // Get an in-memory representation of the root stream
    CItemArray* array=CItemArray::NewLC(aStore,aStore.Root());

    console->Printf(KTxtNewLine);
    console->Printf(aHeading);
    console->Printf(KFormatType1,array->Count());
    for (TInt ii=0;ii<array->Count();++ii)
        {
                // for each item in the array
                //    get the item
        TItem item;
        array->GetItemL(item,ii);
                //    display the data
        console->Printf(KFormatType2,&item);
        }
                // cleanup the array
    CleanupStack::PopAndDestroy();

    console->Printf(KFormatType3);
    console->Getch();
    }


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

CItemArray::~CItemArray()
    {
    delete iArray;
    }

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

TStreamId CItemArray::CreateL(CStreamStore& aStore)
// create the stream representation of the class
    {
                // use a temporary CItemArray
    CItemArray* self=new(ELeave) CItemArray(aStore);
    CleanupStack::PushL(self);
                // construct object
    self->ConstructL();
                // create new stream
    RStoreWriteStream outstream;
    TStreamId id=outstream.CreateLC(aStore);
                // write  external rep
    self->ExternalizeL(outstream);
                // commit stream
    outstream.CommitL();
                // cleanup stream and temporary self
    CleanupStack::PopAndDestroy(2);
    return id;
    }

CItemArray* CItemArray::NewLC(CStreamStore& aStore,TStreamId anId)
// construct a CItemArray from persistent storage
    {
    CItemArray* self=new(ELeave) CItemArray(aStore);
    CleanupStack::PushL(self);
                // construct object
    self->ConstructL();
                // set the stream id for StoreL/RestoreL
    self->iMyId=anId;
                // restore the internal rep.
    self->RestoreL();
    return self;
    }

void CItemArray::StoreL() const
// replace external rep. with internal one
    {
    RStoreWriteStream outstream;
    outstream.ReplaceLC(iStore,iMyId);
    ExternalizeL(outstream);
    outstream.CommitL();
    CleanupStack::PopAndDestroy();
    }

void CItemArray::RestoreL()
// replace internal rep with external one
    {
    iArray->Reset();
    RStoreReadStream instream;
    instream.OpenLC(iStore,iMyId);
    InternalizeL(instream);
    CleanupStack::PopAndDestroy();
    }

void CItemArray::AddItemL(const TItem& anItem)
// add item to the collection
    {
                // write external rep of item
    RStoreWriteStream outstream;
    TStreamId id=outstream.CreateLC(iStore);
    outstream<<anItem;
    outstream.CommitL();
    CleanupStack::PopAndDestroy();
                // add new stream id to the internal array
    iArray->AppendL(id);
    }

void CItemArray::RemoveItemL(TInt anIndex)
// remove an item from the collection
    {
                // remove the stream from the store
    iStore.DeleteL((*iArray)[anIndex]);
                // remove the entry from the internal array
    iArray->Delete(anIndex);
    }

TInt CItemArray::Count() const
    {
    return iArray->Count();
    }

void CItemArray::GetItemL(TItem& anItem,TInt anIndex) const
// retrieve an item from the store
    {
    RStoreReadStream instream;
    instream.OpenLC(iStore,(*iArray)[anIndex]);
    instream>>anItem;
    CleanupStack::PopAndDestroy();
    }

void CItemArray::ConstructL()
    {
    iArray=new(ELeave) CArrayFixFlat<TStreamId>(8);
    }

void CItemArray::ExternalizeL(RWriteStream& aStream) const
    {
                // stream out the array
    aStream<<*iArray;
    }

void CItemArray::InternalizeL(RReadStream& aStream)
    {
                // stream in the array
    aStream>>*iArray;
    }
// BLD.INF
// Component description file
//
// Copyright (c) 2000 Symbian Ltd.  All rights reserved.

PRJ_MMPFILES

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

// using relative paths for source and userinclude directories

TARGET        WritePermFS2.exe
TARGETTYPE    exe
UID           0
VENDORID 0x70000001

SOURCEPATH    .
SOURCE        WritePermFS2.cpp

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

LIBRARY       euser.lib efsrv.lib estor.lib

Description

This example shows further use of a permanent file store.


Classes used