There are two templated stream operators,
operator<<
and operator>>
that can be
used to externalise and internalise data of all types. They use a syntax that
is familiar to users of C++ iostreams, or Java streams.
An object can be externalised to a stream, using a write stream:
writeStream << object;
and later, assuming the operation starts from the appropriate place on the stream, the data can be internalised again, using a read stream:
readStream >> object;
The implementation of the operators depends on the type of object on which they are called.
ExternalizeL()
& InternalizeL()
For a class that defines and implements the
ExternalizeL()
and InternalizeL()
functions, the
Store framework:
implements operator<<
by calling the
ExternalizeL()
member function of that class.
implements operator>>
by calling the
InternalizeL()
member function of that class.
The Store framework provides the necessary implementation for the operators to externalise and internalise the following:
The basic types: TInt8
, TInt16
,
TInt32
, TInt64
, TUint8
,
TUint16
, TUint32
, TReal32
and
TReal64
.
The graphics API classes: TPoint
,
TSize
and TRect
.
The UID Manipulation API class: TUid
.
The Dynamic Buffers API classes: CBufFlat
and
CBufSeg
.
For non-class types, for example enumerators, a specialized implementation of the operators must be defined and implemented for that specific non-class type. The definition of the operators must conform to the templated definitions.
For example, for a class TSimple
that contains an
enumeration of type TXxx
as a data member:
enum TXxx {EX1,EX2,EX3};
class TSimple
{
public :
void ExternalizeL(RWriteStream& aStream) const;
void InternalizeL(RReadStream& aStream);
public :
TXxx iTheEnum;
...
TUint iUintValue;
...
};
The iTheEnum
data member is externalised using
operator<<
and internalised using
operator>>
:
void TSimple::ExternalizeL(RWriteStream& aStream) const
{
aStream << iTheEnum;
...
}
void TSimple::InternalizeL(RReadStream& aStream)
{
aStream >> iTheEnum;
...
}
As TXxx
is a non-class type, the operators are
implemented:
RWriteStream& operator<<(RWriteStream& aStream, const TXxx& anXxx)
{
aStream.WriteInt8L(anXxx);
return aStream;
}
RReadStream& operator>>(RReadStream& aStream, TXxx& anXxx)
{
anXxx = TXxx(aStream.ReadInt8L());
return aStream;
}
The enumerator value is written to the stream using
RWriteStream::WriteInt8L()
. Implicit here is the assumption that
the enumeration can be represented by just 8 bits.
The operators may be used on class types that do not define and
implement InternalizeL()
and ExternalizeL()
functions. This is done by defining and implementing some extra global
functions.
In practice, it is much simpler to define and implement
InternlizeL()
and ExternalizeL()
for a class, and all
new classes should include these functions. However, there may be rare
situations, for example, when porting classes, where it may be undesirable to
define them.
To support the use of the operators for such a class, for example,
for the class TNonStore
defined as:
class TNonStore
{
public :
void SetBuffer(const TDesC& aData);
TPtrC GetBuffer() const;
private :
TBuf<32> iBuffer;
public :
TInt iIntValue;
TUint iUintValue;
TReal iRealValue;
};
implement the following
Externalization()
and Internalization()
global functions:
inline Externalize::Function Externalization(const TNonstore*)
{return Externalize::Function();}
inline Internalize::Function Internalization(TNonstore*)
{return Internalize::Function();}
declare the following ExternalizeL()
and InternalizeL()
global functions:
void ExternalizeL(const TNonstore& aClass,RWriteStream& aStream);
void InternalizeL(TNonstore& aClass,RReadStream& aStream);
implement the ExternalizeL()
and
InternalizeL()
global functions to implement the
streaming of TNonstore
's components. For this example
class:
void ExternalizeL(const TNonStore& aClass,RWriteStream& aStream)
{
aStream.WriteInt32L(aClass.iIntValue);
aStream.WriteUint32L(aClass.iUintValue);
aStream.WriteReal64L(aClass.iRealValue);
aStream << aClass.GetBuffer();
}
void InternalizeL(TNonStore& aClass,RReadStream& aStream)
{
aClass.iIntValue = aStream.ReadInt32L();
aClass.iUintValue = aStream.ReadUint32L();
aClass.iRealValue = aStream.ReadReal64L();
TBuf<32> temp;
aStream >> temp;
aClass.SetBuffer(temp);
}