views:

1774

answers:

3

Hi

What is the preferred/easiest way to manipulate TDesC strings, for example to obtain a substring.

I will give you an example of my scenario.

RBuf16 buf;
...
CEikLabel label;
...
label->SetTextL(buf); // (SetTextL takes a const TDesC&)

I want to get a substring from buf. So do I want to manipulate the RBuf16 directly and if so what is the best way?

Is there a way to convert to const char* so I can just use standard C string manipulation.

Thanks in advance

+2  A: 

Read descriptors.blogspot.com (scroll down once loaded).

You can use TDes::LeftTPtr, TDes::RightTPtr or TDes::MidTPtr which will give you a substring as a TPtr (i.e. a descriptor which manipulates the original data).

You can use the TDes::Copy function if you want to create a copy of your substring.

Dynite
+2  A: 

Best or not, I cannot comment, but I use the following methods to extract sub-strings from descriptors:

TDes::LeftTPtr()
TDes::MidTPtr()
TDes::RightTPtr()

or

TDesC::Left()
TDesC::Mid()
TDesC::Right()

with the difference between the two sets being that the former returns a new modifiable descriptor, the latter, a new non-modifiable descriptor, containing the sub-string.

While you develop on the Symbian platform, I would suggest highly to follow the Symbian conventions, and not to think of Symbian C++ from a standard C or C++ point of view all the time. Use the libraries that Symbian has specifically made available, instead of standard C/C++ libraries that Symbian may or may not directly support. Since the ultimate goal of an application developed on the Symbian is to run on a mobile device where reliability and robustness of applications matter the most, you should stick to what Symbian prefers and suggests.

ayaz
I totally agree with your last paragraph and have been trying to force myself to learn the weird and wonderful ways of Symbian.
adam
I agree with the conclusion but not for the same reasons. It's not true that "Symbian knows best" IMO. For instance the performance assumptions guiding the descriptor API designs are out of date for modern smartphones, IMO. But it's better to work with the libraries than push raw chars around.
Steve Jessop
+1  A: 

If you want a substring from an RBuf16, that's straightforward - just use TDes16::MidTPtr

You can convert a const char* by doing this:

TPtr8 narrowBuf;

// Create a buffer with enough space to store every character, plus one for 
// a null terminator
narrowBuf.AllocL( buf.Length() + 1);

// TPtr8::Copy accepts a TDesC16 
narrowBuf.Copy( buf );

// Append a null terminator and return a pointer to the resultant data
const char* ptr = (const char*)narrowBuf.PtrZ();

However, what you now have a is a narrowed copy of the original data. If you want to now set the label again, you'll need to widen it (TDes16::Copy(const TDesC8&)) before use. Trying to make Symbian look like "normal" C++ with char* and wchar_t* doesn't really work - the use of descriptors is too entrenched in the OS.

Airsource Ltd
"what you now have a is a narrowed copy of the original data" - sometimes you need to convert to UTF-8 (with CnvUtfConverter) if you want to do C-style char* manipulation. I agree it's usually best to accept the inevitable and work with descriptors.
Steve Jessop