Symbian
Symbian OS Library

FAQ-0599 How do I use descriptors for my strings?

[Index][spacer] [Previous] [Next]



 

Classification: C++ Category: Base
Created: 06/20/97 Modified: 07/22/2003
Number: FAQ-0599
Platform: Not Applicable

Question:
I'm a programmer used to other C++ environments.
Please could I have a crib sheet to help me use descriptors?


Answer:
Here are some guidelines and examples for translating from C or C++ in other environments to the Symbian OS environment.
· Replace char* data members, variables and function return values with TPtr, TPtrC or HBufC*
· Replace char* parameters to functions with (const TDesC&) or (TDes&)
· Replace char[N] data members and variables with TBuf or TBufC
· Replace const char* with the 'C' versions of the classes
· For allocated memory use HBufC*.
· Use the constructor or Set() to change what a descriptor points to; use the assignment operator to change what its buffer contains.
· Warning: Initialisation and assignment have totally different semantics. This contravenes almost every C++ style guide in existence, but the decision dates back to before most of them existed and now we're stuck with it. The assignment operator does a memory copy.
In the following examples, string represents a read-only character string. buf represents a modifiable buffer for manipulating strings.

Data Members and Initialization

Typical C++ For Null-Terminated Strings In Psion EPOC32
char buf[BUFSIZE]; TDes buf;
// String referenced by a class:

const char* iString;

iString = ...;

TPtrC iString;

iString.Set( ... );

// String managed by a class

char * iBuf = ... ;

HBufC* ipBuf = ... ;
const char* string = "Hello"; TPtrC string( _L( "Hello" ) );
const char* string = charArrayZ; TPtrC string( charArrayZ );
Parameters and values
foo( const char* aString ) foo( const TDesC& aString )
modify( char * aBuf, int iSize ); modify( TDes& aBuf );
// Returning allocated memory

char* buf = foo()

delete [] buf;

HBufC* pBuf = foo()

delete pBuf;

// Returning ptr to another's mem

const char* string = foo();

TPtrC string = foo();
Operations on strings
strlen( string ); string.Length();
memset( buf, '\0', BUFSIZE ); buf.FillZ( buf.MaxLength() );
buf[0] = '\0'; buf.Zero();
strcpy( buf, "Hello" ); buf = _L( "Hello" );
sprintf( buf, "%s\n", string ); buf.Format( _L("%S\n"), &string);
strcpy( buf, string1 );

strcat( buf, string2 );

buf = string1;

buf.Append( string2 );

char * iBuf = strdup( string ); HBufC* ipBuf = string.AllocL();
Notes

Descriptors reference chunks of memory of known size. Compared with standard C they replace the common combination of char* plus integer buffer length.

      Descriptors combine

      The data adress [ char* x; ]

      The data length [ strlen( x ) ], and, for modifiable buffers:

      The buffer size [int xBufferSize; ] They cope seamlessly with unicode (two-byte) characters.

      What the classes actually contain:

      TDesC (abstract base class for everything) has a length;

      TPtrC adds a memory address to TDesC.

      TDes (abstract) is a modifiable TDesC, and therefore adds a maximum length to TDesC

      TPtr adds a memory address to TDes

      TBufC contains a read-only char array of size N

      TBuf contains a read-write char array of max size N, plus its current length

      HBufC adds an allocated buffer to TDes. The 'C' is misleading; an HBufC is modifiable; just call Des() on it to get a TPtr. You might think of it as similar to a Pascal string, combining length and allocated memory. Use HBufC::New(), NewL() or NewLC() to allocate an empty buffer, or use the function AllocL() on any descriptor to make an allocated copy of its data.