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.