Mastering Symbian OS Descriptors, Page 2
RBuf Descriptor Class
Well, now you have three (actually, six to be honest) sibling classes you may instantiate. They are closely related to each other. In other words, you can perform various transformations from one type to another via the Des(), Ptr(), and AllocL() methods plus assignment operators within a 16- or 8-bit line. To add a bit more to this discussion, you have a RBuf descriptor type that is some kind of a hybrid of TPtr and HBufC*. This means that you either can create its own data buffer or delegate it an ownership of a pre-existing allocated memory chunk or heap descriptor. Regardless of the way this buffer was obtained, RBuf class is responsible for releasing it when an object is about to be destroyed.
Its usage is quite straightforward:
_LIT(KSourcePath,"dataFile\"); ... TFileName path; fsSession.PrivatePath(path); ... RBuf pathSource; pathSource.CreateL(sizeof(TFileName)); pathSource.CleanupClosePushL(); pathSource.Append(path); pathSource.Append(KSourcePath); ... CleanupStack::PopAndDestroy();
Now, put your hands on very practical issues: how to transform different types of descriptors from one type to another. This problem covers also raw conversions from ASCII to UNICODE and vice versa.
Below, you find several useful typical cases you may come across at some point:
// TBufC -> TBuf _LIT(KTestBuf,"Buffer"); TBufC<16> bufC1(KTestBuf); TBuf<16> buf1(bufC1.Des()); // TBuf -> TBufC TBuf<16> buf2(KTestBuf); TBufC<16> bufC2(buf2); // TBuf/TBufC -> TPtr TPtr ptr1(0,0); ptr1.Set((TUint16*)(buf2.Ptr()),buf2.Length(),32); TPtr ptr2(bufC2.Des()); // TPtr -> TBuf/TBufC TBuf<16> buf3 = ptr1; TBufC<16> bufC3 = ptr2; // TBuf/TBufC -> TPtrC TPtrC ptrC1(ptr1); TPtrC ptrC2(buf2); TPtrC ptrC3(bufC2); // All above -> HBufCW HBufC *pHeap1 = ptrC1.AllocLC(); HBufC *pHeap2 = ptr1.AllocLC(); HBufC *pHeap3 = bufC1.AllocLC(); HBufC *pHeap4 = buf1.AllocLC(); // or assignment operator HBufC *pHeap5 = HBufC::NewLC(32); *pHeap5 = ptr1; // or via Copy method HBufC *pHeap6 = HBufC::NewMaxLC(32); pHeap6->Des().Copy(ptr2);
The latter scenario helps you in raw conversion from 16-bit to 8-bit data and vice versa:
HBufC8 *pHeap8 = HBufC8::NewMaxLC(buf1.Length()); pHeap8->Des().Copy(buf1); HBufC *pHeap16 = HBufC::NewMaxLC(pHeap8->Length()); pHeap16->Des().Copy(*pHeap8);
Please notice the very last line in the example above. It is considered to be common mistake to create TDesC& references by calling the Des() method. It is much easier to de-reference the HBufC descriptor to get the desired result.
If you need a more accurate conversion with real UNICODE characters, you can use the CnvUtfConverter class, as in the following simple snippet:
HBufC8 *pHeapUTF = CnvUtfConverter::ConvertFromUnicodeToUtf8L(buf1); HBufC *pHeapUCS2 = CnvUtfConverter::ConvertToUnicodeFromUtf8L(*pHeapUTF);
So as you can see, it is quite simple. Just use Des(), Ptr(), & Co. at the proper time and position.
This article has focused on the Symbian OS equivalent of strings—various types of descriptors. Descriptors were optimized to be as efficient as possible in the limited environment of a smartphone. You saw typical operations you might want to perform upon descriptors and also some scenarios of transformation from one type to another. With all this information in mind, I hope using them in your own applications will be a piece of cake.
About the Author
Alex Gusev started to play with mainframes at the end of the 1980s, using Pascal and REXX, but soon switched to C/C++ and Java on different platforms. When mobile PDAs seriously rose their heads in the IT market, Alex did it too. After working almost a decade for an international retail software company as a team leader of the Windows Mobile R department, he has decided to dive into Symbian OS ™ Core development.