Wiley.Symbian.OS.C.plus.plus.for.Mobile.Phones.Aug.2007 (779890), страница 27
Текст из файла (страница 27)
See your SDK for furtherdetails.The TLex class provides a range of functionality intended to aid lexicalprocessing of text data. Consult your SDK for further details.Converting a Number to a DescriptorA numeric value can be converted into a descriptor using the Num()method:TInt minusThirtyFour(-34);TBuf<8> des;des.Num(minusThirtyFour);This creates a descriptor of length three, containing the characters ‘-’,‘3’, ‘4’.SOME DESCRIPTOR OPERATIONS123There are several overloads of Num() for conversions from differentnumerical types and including options for conversion from decimal,binary, octal, etc.
There are also overloaded AppendNum() methods forappending a number to a descriptor.Externalizing and Internalizing DescriptorsDescriptors have their own operator<< and operator>> methodsdefined; they externalize a compressed form of the length. It is a commonmistake to externalize the length and data of the descriptors explicitly, asin the following code:void CSomeClass::ExternalizeL(RWriteStream& aStream) const{// externalize an HBufCTInt size = iData->Length();// iData is an HBufC*aStream.WriteUint32L(size);aStream.WriteL(iData->Des(), size);// unnecessary call to HBufC::Des()// externalize a TBuf<>size = iBuffer.Length();// iBuffer is a TBuf<>aStream.WriteUInt32(size);aStream.WriteL(aData.Ptr(), size);}The correct way to write this code is:void CSomeClass::ExternalizeL(RWriteStream& aStream) const{// externalize an HBufCaStream << *iData;// iData is an HBufC*// externalize a TBuf<>aStream << iBuffer;// iBuffer is a TBuf<>}The corresponding internalization code is:void CSomeClass:InternalizeL(RReadStream& aStream) const{// internalize into an HBufCdelete iData;// assuming iData is already allocatediData = NULL;iData = HBufC::NewL(aStream, KMaxDataLength);// internalize into a TBuf<>aStream >> iBuffer;// should be large enough to accommodate all the data}124DESCRIPTORSHBufC::NewL(RReadStream &aStream, TInt aMaxLength)takes a read stream as a parameter and reads up to aMaxLength ofdescriptor data into an HBufC* that it creates.Similarly to HBufC::NewL(), RBuf also has a CreateL() variantthat takes an RReadStream method parameter.To use the operator<< and operator>> methods of descriptors,you must link to estor.lib in the MMP file.
Remember that, as withall streaming operators, they may leave.Putting Binary Data into a LITThe \x escape sequence can be used to place binary data into a _LIT. Thefollowing code produces a literal of length five containing the sequenceof bytes 0x01 0x02 0x03 0x45 0xEF:_LIT8(KNarrowLiteral, "\x01\x02\x03\x45\xEF");TPtrC8 narrowPtr(KNarrowLiteral);With wide literals, you may need to be concerned with byte orderingdepending upon your intended usage, because \x12 in a Unicode stringactually means 0x0012; on Symbian OS, it is stored as 0x12 0x00. Thefollowing code produces a literal of length two containing the sequenceof bytes 0x34 0x12 0xFF 0x33:_LIT(KWideLiteral,"\x1234\x33FF");TPtrC widePtr(KWideLiteral);Conversions Involving Descriptors and StringsThe following examples use TDes8::Copy(const TDesC16&) andTDes16::Copy(const TDesC8&) to convert between narrow andwide descriptors.TDes8::Copy(const TDesC16&) strips out alternate wide characters while TDes16::Copy(const TDesC8&) pads each character witha trailing zero as part of the copy operation.
These methods thus forma rudimentary way of copying and converting when the character setis encoded with one byte per character and the last byte of each widecharacter is NULL-padded.To perform full conversions in both directions where the data isencoded in UTF-16, UTF-7 and UTF-8 see the CCnvCharacterSetConverter and CnvUtfConverter classes. Further details can befound in your SDK.SOME DESCRIPTOR OPERATIONS125From 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(constTDesC16&).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 useTBuf8::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 descriptorconst unsigned char* constNarrowString = .
. .unsigned char* narrowString = . . .// conversion to TPtrC8TPtrC8 ptrc(constNarrowString, User::StringLength(constNarrowString));// conversion to TPtr8TInt stringLen = User::StringLength(narrowString);TPtr8 ptr(narrowString, stringLen, stringLen);// conversion to TBuf8TBuf8<5> buf(narrowString);From a narrow string to a wide descriptorYou can first convert to a narrow descriptor and then use TDes16::Copy(TDesC8&aDes) to subsequently convert from a narrow descriptorto a wide descriptor:unsigned char* narrowString = .
. .TInt stringLen = User::StringLength(narrowString);TPtr8 ptr(narrowString, stringLen, stringLen);TBuf<5> buf;buf.Copy(ptr);126DESCRIPTORSFrom a wide string to a wide descriptorunsigned short int* wideString = . . .TInt stringLen = User::StringLength(wideString);TPtr ptr(wideString, stringLen, stringLen);From a wide string to a narrow descriptorYou can first convert to a wide descriptor and then use TDes8::Copy (const TDesC16&aDes) to subsequently convert to a narrowdescriptor:unsigned short int* wideString = .
. .TInt stringLen = User::StringLength(wideString);TPtr ptr(wideString, stringLen, stringLen);TBuf8<5> buf;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 terminatorFrom 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()] = ‘\0’; // append NULL terminatorBe careful not to confuse Size() with Length().
The Size()method must be used with Mem::Copy(), otherwise only half thedescriptor is copied; Length() must be used when indexing into thearray otherwise memory beyond the array’s bounds is accessed.From a wide descriptor to a wide string_LIT(KTxtHello,"Hello");TBuf<5> wide(KTxtHello);SOME DESCRIPTOR OPERATIONS127TText string[6];Mem::Copy(string, wide.Ptr(), wide.Size());string[wide.Length()] = ‘\0’; // append NULL terminatorFrom 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 terminatorUsing Collapse() and Expand()From Symbian OS v8.1 onwards, these methods may be used to aid withconversion operations between narrow and wide descriptors.Expand() widens a narrow descriptor while Collapse() narrowsa wide descriptor:void TakeNarrowDes(const TDesC8& aDes){// aDes contains "AABB"TInt size = aDes.Size(); // 2TInt len = aDes.Length(); // 2}_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 AA11BB2242now contains AABBBB2242The Collapse() method returns a TPtr8 where every second bytehas been stripped from the original wide data, hence the aDes parameterof TakeNarrowDes() is of length and size 2 and contains AABB.Note that the length and size of wideBuf are unaffected by callingCollapse() despite its contents having been altered.
Thus it is notmeaningful to use a descriptor directly once its Collapse() methodhas been called, instead it should be accessed via the returned TPtr8.void TakeWideDes(const TDesC& aDes){TInt size = aDes.Size(); // 10TInt len = aDes.Length(); // 5}128DESCRIPTORS_LIT8(KTxtNarrowHello, "Hello");TBuf8<10> narrowHello(KTxtNarrowHello);// must contain space for expansionTInt narrowSize = narrowHello.Size();TInt narrowLen = narrowHello.Length();TakeWideDes(narrowHello.Expand());narrowSize = narrowHello.Size();narrowLen = narrowHello.Length();// 5// 5// 10, twice previous size// 10, twice previous lengthWith expansion the descriptor is modified and an extra zero extensionbyte is inserted after each existing byte.