Friday, June 17, 2005

 

Tip 10: Use operator>> and operator<< to internalize and externalize descriptor data. But remember that they can leave!

When externalizing data to a writable stream, or internalizing it from a readable stream, use the operators crafted for this purpose rather than 'rolling your own'. This code, which reads/writes the descriptor length using 4 bytes, then the data itself, is awkward and inefficient.

// Write the contents of aDes to aStream
void CMyClass::ExternalizeL(RWriteStream& aStream, const TDesC& aDes) const

{// Write the length of aDes

aStream.WriteUint32L(aDes.Length());

// Write the data from aDes

aStream.WriteL(aDes, aDes.Length());

}


// Read the contents of aStream and create an HBufC

HBufC* CMyClass::InternalizeL(RReadStream& aStream)

{// Read the length of aDes

TInt size=aStream.ReadUint32L();

// Allocate a buffer

HBufC* heapBuf = HBufC::NewL(size);

// Create a modifiable descriptor over heapBuffer

TPtr ptr(heapBuffer->Des());

// Read the descriptor data

aStream.ReadL(ptr,size);

return (heapBuf);

}


If you link against estor.lib, you can use the templated stream operators that Symbian OS provides, for much more efficient internalization and externalization. The length information of the descriptor is compressed to make descriptor storage as compact as possible.

You can use operator>> to internalize string data, if it was externalized using operator>>, but additionally, the stream data can be passed to HBufC::NewL(), as a read stream, to recreate the descriptor. Either of these are a significantly more efficient approach to that above:

// Write the contents of aDes to aStream

void CMyClass::ExternalizeL(RWriteStream& aStream, const TDesC& aDes) const

{

aStream << aDes;

}


// Read the contents of aStream and create an HBufC

HBufC* CMyClass::InternalizeL(RReadStream& aStream)

{// KMaxLength is defined elsewhere as the maximum length read from the stream

HBufC* heapBuf = HBufC::NewL(aStream, KMaxLength);

}


You’ll notice that the ExternalizeL() and InternalizeL functions above are leaving functions. This is because the templated streaming operators, operator>> and operator<<, may leave. They are not suffixed with L because they are operators, and can't be named according to the convention for leaving functions on Symbian OS. This makes it easy to forget that they leave, which isn't helped by the fact that the leave-checking tool LeaveScan doesn't flag them.

So, if you write code which uses them, you should make a special point of checking that it is leave-safe.

Comments:
I think you made a mistake there:
"You can use operator>> to internalize string data, if it was externalized using operator>>, ..."

truf
 
Post a Comment

<< Home

This page is powered by Blogger. Isn't yours?

Google
WWW Top Tips for Descriptors