Typically, externalizing a Swizzle is a two stage process which involves:
externalizing the in-memory object which the Swizzle represents, to its own stream
externalizing the resulting stream ID.
For example, given a container type object, CClassABC
,
with a data member TSwizzle<CClassB> iB
representing
a CClassB
object in memory, the diagram below illustrates the
result of storing the container object.
The following code fragments illustrates the process.
iB
is a CClassB
type component of a class
CClassABC
, and is represented by a Swizzle. The data member is
defined as:
class CCClassABC : public CBase
{
...
TSwizzle<CClassB> iB;
...
}
Typically, a CClassB
object is constructed and assigned
to iB
; this uses the Swizzle’s assignment operator:
iB = CClassB::NewL();
The Swizzle now represents the CClassB
object by
pointer.
The StoreL()
member function of CClassABC
constructs a store map, an object of type CStoreMap
, before
calling StoreComponentsL()
to externalise the swizzled
CClassB
object to its own stream.
TStreamId CClassABC::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;
}
The variable iStore
is a member of
CClassABC
containing a reference to the store.
StoreComponentsL()
externalises the swizzled
CClassB
object by calling CClassB
’s own
StoreL()
member function which constructs a stream, externalises
itself to the stream and returns the ID of that stream:
void CClassABC::StoreComponentsL(CStoreMap& aMap) const
{
...
TStreamId id;
if (iB)
{
id = iB->StoreL(iStore); // Id of the CClassB stream
aMap.BindL(iB,id);
}
...
}
The Swizzle must represent the CClassB
type object as a
pointer, i.e. the swizzled object must be in memory. The
operator->
applied to the Swizzle iB
gives access
to the StoreL()
member function of the CClassB
object.
The condition if (iB)
is equivalent to if
(iB.IsPtr())
and returns true only if the Swizzle represents the
CClassB
object as a pointer . The act of externalizing the
CClassB
object, does not, and need not change the way that the
Swizzle represents that object. Here, the CClassB
object remains
in memory and the Swizzle maintains its representation of it as a pointer, even
after it has been externalised.
The Stream ID of the externalised CClassB
object is
stored in the store map along with the associated Swizzle using
CStoreMap
’s BindL()
member function .The store map
is used again later when the stream ID is externalised as part of
CClassABC
’s data.
The ExternalizeL()
member function of
CClassABC
externalises CClassABC
's member data. This
includes the stream ID of the externalised CClassB
object which is
externalised by applying the templated stream operator<<
to
the Swizzle iB
.
void CCompound::ExternalizeL(RWriteStream& aStream) const
{
...
aStream << iB
...
}
At this point, the Swizzle still represents the CClassB
object as a pointer, and the object itself is still in memory.
The mechanism underlying the implementation of the stream
operator<<
, assumes that the stream ID associated with the
Swizzle has been placed in the store map. It also assumes that the
RStoreWriteStream
object has been constructed, specifying the
store map as an externalizer.
The end result of the operation aStream << iB;
, is
to externalise, to the stream, the stream ID associated with the Swizzle
iB
. The following diagram shows this: