WriteToMany
: externalizing to more than one
stream/deferred loading
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 c:\data\
//
#include "WriteToMany.h"
//***************************************************************
//
// Implementations
//
//***************************************************************
// The file name, extension and path for the file store
_LIT(KFullNameOfFileStore,"C:\\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
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.
RStoreWriteStream
: supports creation and
manipulation of a stream in a store
RStoreReadStream
: supports opening and manipulation
of a stream in a store
CDirectFileStore
: a direct file store
TStreamId
: stream identification
TSwizzle
: deferred loading mechanism
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 c:\data\
//
#include "WriteToEmbedded.h"
//***************************************************************
//
// Implementations
//
//***************************************************************
// The file name, extension and path for the file store
_LIT(KFullNameOfFileStore,"C:\\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
This example shows how an object can be externalized to a store embedded within a permanent file store.
RStoreWriteStream
: supports creation and
manipulation of a stream in a store
RStoreReadStream
: supports opening and manipulation
of a stream in a store
CPermanentFileStore
: a permanent file store
TStreamId
: stream identification
CEmbeddedStore
: an embedded store derived from
CPersistentStore
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,"C:\\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
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
).
RStoreWriteStream
: supports creation and
manipulation of a stream in a store
RStoreReadStream
: supports opening and manipulation
of a stream in a store
CPermanentFileStore
: a permanent file store
CStoreMap
: the store map (a table of stream IDs and
associated swizzles; externalizes swizzles as stream IDs)
TSwizzle
: a device for handling the dual
representation of an object as a streamid or as a pointer