Conversions Involving Descriptors and Strings
The following examples use TDes8::Copy(const TDesC16&) and TDes16::Copy(const TDesC8&) to convert between narrow and wide descriptors.
TDes8::Copy(const TDesC16&) strips out alternate wide characters while TDes16::Copy(const TDesC8&) pads each character with a trailing zero as part of the copy operation. These methods thus form a rudimentary way of copying and converting when the character set is encoded with one byte per character and the last byte of each wide character is NULL-padded.
To perform full conversions in both directions where the data is encoded in UTF-16, UTF-7 and UTF-8 see the CCnvCharacterSet-Converter and CnvUtfConverter classes. Further details can be found in your SDK.
From a wide descriptor to a narrow descriptor
|
_LIT(KTxtWideHello, "Hello"); | |
|
TBuf<5> wide(KTxtWideHello); | |
|
TBuf8<5> narrow; | |
|
narrow.Copy(wide); // Uses TDes8 |
::Copy(const TDesC16&) |
Note that there is also a method TDes8::Append(const TDesC16&).
From a narrow descriptor to a wide descriptor
_LIT8(KTxtNarrowHello,"Hello"); TBuf8<5> narrow(KTxtNarrowHello); TBuf<5> wide; wide.Copy(narrow);
If you are using Symbian OS v8.1 or later then you may also use TBuf8::Expand() which extends each character with zero to 16 bits. There is no corresponding TDes16::Append(const TDesC8&).
From a narrow string to a narrow descriptor const unsigned char* constNarrowString = ... unsigned char* narrowString = ...
// conversion to TPtrC8
TPtrC8 ptrc(constNarrowString, User::StringLength(constNarrowString)); // conversion to TPtr8
Tint stringLen = User::StringLength(narrowString); TPtr8 ptr(narrowString, stringLen, stringLen);
// conversion to TBuf8 TBuf8<5> buf(narrowString);
From a narrow string to a wide descriptor
You can first convert to a narrow descriptor and then use TDes16:: Copy(TDesC8&aDes) to subsequently convert from a narrow descriptor to a wide descriptor:
unsigned char* narrowString = ...
Tint stringLen = User::StringLength(narrowString); TPtr8 ptr(narrowString, stringLen, stringLen); TBuf<5> buf; buf.Copy(ptr);
From a wide string to a wide descriptor unsigned short int* wideString = ...
Tint stringLen = User::StringLength(wideString);
TPtr ptr(wideString, stringLen, stringLen);
From a wide string to a narrow descriptor
You can first convert to a wide descriptor and then use TDes8:: Copy (const TDesC16&aDes) to subsequently convert to a narrow descriptor:
unsigned short int* wideString = ...
Tint stringLen = User::StringLength(wideString);
TPtr ptr(wideString, stringLen, stringLen);
buf.Copy(ptr);
From a narrow descriptor to a narrow string
_LIT8(KTxtNarrowHello,"Hello"); TBuf8<5> narrow(KTxtNarrowHello); TText8 string[6];
Mem::Copy(string, narrow.Ptr(), narrow.Size()); string[narrow.Size()] = '\0'; // append NULL terminator
From a narrow descriptor to a wide string
_LIT8(KTxtNarrowHello,"Hello"); TBuf8<5> narrow(KTxtNarrowHello); TBuf<5> wide; wide.Copy(narrow); TText string[6];
Mem::Copy(string, wide.Ptr(), wide.Size()); string[wide.Length()] = 'XO'; // append NULL terminator
Be careful not to confuse Size() with Length(). The Size() method must be used with Mem::Copy(), otherwise only half the descriptor is copied; Length() must be used when indexing into the array otherwise memory beyond the array's bounds is accessed.
From a wide descriptor to a wide string
_LIT(KTxtHello,"Hello"); TBuf<5> wide(KTxtHello);
|
TText string[6]; | ||
|
Mem::Copy(string, wide. |
• Ptr(), |
wide.Size()); |
|
string[wide.Length()] = |
= ■\0'; |
// append NULL terminator |
From a wide descriptor to a narrow string
|
_LIT(KTxtHello,"Hello"); | |
|
TBuf<5> wide(KTxtHello); | |
|
TBuf8<5> narrow; | |
|
narrow.Copy(wide); | |
|
TText8 string[6]; | |
|
Mem::Copy(string, narrow. |
.Ptr(), narrow.Size()); |
|
string[narrow.Length()] = |
= ' \0'; // append NULL terminator |
Using Collapse() and Expand()
From Symbian OS v8.1 onwards, these methods may be used to aid with conversion operations between narrow and wide descriptors.
Expand() widens a narrow descriptor while Collapse() narrows a wide descriptor:
void TakeNarrowDes(const TDesC8& aDes) {
// aDes contains "AABB"
_LIT(KTxtWideData, "\x11AA\x22BB"); TBuf<5> wideBuf(KTxtWideData); Tint wideSize = wideBuf.Size(); Tint wideLength = wideBuf.Length(); TakeNarrowDes(wideBuf.Collapse()); wideSize = wideBuf.Size(); wideLength = wideBuf.Length();
// contains AA11BB22
// now contains AABBBB22
The Collapse() method returns a TPtr8 where every second byte has been stripped from the original wide data, hence the aDes parameter of TakeNarrowDes() is of length and size 2 and contains AABB. Note that the length and size of wideBuf are unaffected by calling Collapse() despite its contents having been altered. Thus it is not meaningful to use a descriptor directly once its Collapse() method has been called, instead it should be accessed via the returned TPtr8.
void TakeWideDes(const TDesC& aDes) {
Tint size = aDes.Size(); // 10 Tint len = aDes.Length(); // 5
|
_LIT8(KTxtNarrowHello, "Hello"); | ||||
|
TBuf8<10> narrowHello(KTxtNarrowHello), | ||||
|
// must contain space for expansion | ||||
|
Tint narrowSize = narrowHello.Size(); |
// |
5 | ||
|
Tint narrowLen = narrowHello.Length(); |
// |
5 | ||
|
TakeWideDes(narrowHello.Expand()); | ||||
|
narrowSize = narrowHello.Size(); // |
10, |
twice |
previous |
size |
|
narrowLen = narrowHello.Length(); // |
10, |
twice |
previous |
length |
With expansion the descriptor is modified and an extra zero extension byte is inserted after each existing byte. The descriptor must have a maximum length at least twice its current length. Notice the difference in lengths between that of aDes and that of narrowHello after Expand() has been called.
If you use this function, you must be aware that if the descriptor is a pointer descriptor then the memory pointed to (i.e., the result of calling TDesC::Ptr()) must be at an even-numbered address because the ARM processor can only access 16-bit quantities at even-numbered addresses.
Post a comment