Strings

Symbian doesn't use the C char * strings but provides classes that does range checking called descriptors. (an overflow in a char str[n] string is probably the most common mistake that allows an attacker to take control over a system. This is achieved by overwriting the stack frame. So it's nice that Symbian libraries does all the range checking).

There are several classes of the desctiptors. The TDesC is an abstract class which is an ancestor of constant strings. The TDes is a subclass TDesC and adds some functions to modify strings - it is an ancestor of all the modifiable strings. A TBuf<n> is a class that keeps n characters as a part of itself (thrus the T prefix). It is usually used to keep some temporary strings as automatic variables. However because of the small stack in Symbian devices you should not keep too many string on the stack.

TPtrC objects stores a pointer to a constant buffer which it doesn't own and the information about it's length. E.g. a TPtrC can point to characters 5 to 10 of a TBuf<64>. Destroying the TPtrC will not hurt the data in the TBuf. However if you destory the TBuf, the TPtrC will become invalid. A TPtr is a modifiable version of TPtrC (i.e. you can modify the data in the buffer).

If you want to keep the string on the heap use a HBufC. The HBufC objects cannot be kept on the stack but must be created on the heap like C classes but on the other hand it also doesn't need a virtual destructor as all the data is inlined like in T classes. That's why is has a special prefix - H. As the C suffix suggests that class is non-modifiable directly but there is a Des() function which returns a TPtr to the data, which will allow you to modify the content.

Symbian also needs to introduce it's own way to handle string literals (i.e. which are hard-coded in the source code). There is a macro _LIT. For example _LIT(a, "Text") will declare the constant a as a TDesC-derived object (more exactly of type TLit) with the content "Text". It can be used both to declare global constants as well as literals inside functions:

_LIT(KFormat, "String: %S");

void Function()
{
    TBuf<64> buffer;
    _LIT(tmp, "ABC");
    buffer.Format(KFormat, &tmp);
    /* ... */
}

(this code will generate "String: ABC"). There is also a _L macro which has one parameter and is used like this: buffer.Format(_L("Count: %d"), 17); however it is discouraged as it generate worse code.