diff -r 000000000000 -r 7f656887cf89 libraries/ltkutils/inc/descriptorutils.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libraries/ltkutils/inc/descriptorutils.h Wed Jun 23 15:52:26 2010 +0100 @@ -0,0 +1,173 @@ +// descriptorutils.h +// +// Copyright (c) 2010 Accenture. All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Accenture - Initial contribution +// +#ifndef FSHELL_DESCRIPTORUTILS_H +#define FSHELL_DESCRIPTORUTILS_H + +#include + +namespace LtkUtils + { + class TUtf8State; + + NONSHARABLE_CLASS(RLtkBuf16) : public TDes16 + { + public: + IMPORT_C RLtkBuf16(); + IMPORT_C RLtkBuf16(HBufC16* aBuf); // Takes ownership + + // The new, useful functions that RBuf doesn't give you + IMPORT_C HBufC16* ToHBuf(); // Caller is responsible for deleting the result. This function Closes the RLtkBuf. + IMPORT_C HBufC16* GetHBuf() const; + IMPORT_C void AppendL(const TDesC16& aText); + IMPORT_C void AppendL(const TDesC8& aText); + IMPORT_C void AppendL(TChar aChar); + IMPORT_C void AppendFormatL(TRefByValue aFmt, ...); + IMPORT_C void ReplaceL(TInt aPos, TInt aLength, const TDesC16 &aDes); + IMPORT_C void ReplaceAllL(const TDesC& aFrom, const TDesC16& aTo); + IMPORT_C void ReserveExtraL(TInt aExtraCapacity); + IMPORT_C TInt ReserveExtra(TInt aExtraCapacity); + IMPORT_C void CreateLC(TInt aMaxLength); + + /** + Leaves on OOM. Converts the argument aUtf8EncodedText from UTF-8 to the native UTF-16 and appends the result to this + descriptor. You can handle your data in chunks by calling AppendUtf8L repeatedly. You don't have to worry about UTF-8 + sequences being split between chunks - fragmented end sequences are cached and will be reassembled if a further call + to AppendUtf8L is made with the rest of the bytes. Such sequences are not considered malformed unless (a) the next call + to AppendUtf8L doesn't produce a valid sequence, or (b) FinalizeUtf8 is called instead of a further append. Sequences + that are decided to be malformed are replaced with the unicode replacement char U+FFFD. You are free to mix calls to + AppendUtf8L with other normal descriptor operations such as Delete, Insert or ReAlloc. You shouldn't however copy + the buffer or call any other Append functions without finalizing it first. Once you have finished appending UTF-8 + you must call FinalizeUtf8(). + */ + IMPORT_C void AppendUtf8L(const TDesC8& aUtf8EncodedText); + + /** + Like the above, but returns by reference the index of the first byte of the first malformed sequence in aUtf8EncodedText (or + KErrNotFound if it was totally valid). Useful if you want to stop appending the minute you see a malformed sequence + and thus don't want to have to wait until you call FinalizeUtf8() to get that information. + */ + IMPORT_C void AppendUtf8L(const TDesC8& aUtf8EncodedText, TInt& aFirstBadBytePosition); + + /** + Must be called at the end of a sequence of AppendUtf8L() calls. Clears all UTF-8 related state from the descriptor. + Returns KErrCorrupt if any malformed sequences were encountered in any of the AppendUtf8L() calls. You are free to + ignore this return code if you wish: malformed sequences get replaced with U+FFFD and the rest of the string continues + to be parsed. Returns KErrNone if there were no problems. + */ + IMPORT_C TInt FinalizeUtf8(); + + /** + Like the above, but returns by reference the index of the first byte of the first malformed sequence found cumulatively + across all invocations of AppendUtf8L(). aFirstBadBytePosition is set to KErrNotFound if the data was totally valid. + */ + IMPORT_C void FinalizeUtf8(TInt& aFirstBadBytePosition); + + + /** + Convenience method. Equivalent to: + this->Zero(); + this->AppendUtf8L(aText); + User::LeaveIfError(this->FinalizeUtf8()); + */ + IMPORT_C void CopyFromUtf8L(const TDesC8& aUtf8EncodedText); + + // The usual RBuf-like APIs (for everything else, it just inherits from TDes16) + IMPORT_C TInt ReAlloc(TInt aMaxLength); + IMPORT_C void ReAllocL(TInt aMaxLength); + IMPORT_C void Assign(HBufC16* aBuf); + IMPORT_C TInt Create(TInt aMaxLength); + IMPORT_C void CreateL(TInt aMaxLength); + IMPORT_C TInt CreateMax(TInt aMaxLength); + IMPORT_C void CreateMaxL(TInt aMaxLength); + IMPORT_C void Close(); + + private: + TUtf8State* GetUtf8State() const; + void ClearUtf8State(); + + private: + HBufC16* iBuf; + }; + + NONSHARABLE_CLASS(RLtkBuf8) : public TDes8 + { + public: + IMPORT_C RLtkBuf8(); + IMPORT_C RLtkBuf8(HBufC8* aBuf); // Takes ownership + + // The new, useful functions that RBuf doesn't give you + IMPORT_C HBufC8* ToHBuf(); // Caller is responsible for deleting the result. This function Closes the RLtkBuf. + IMPORT_C HBufC8* GetHBuf() const; + IMPORT_C void AppendL(const TDesC8& aText); + IMPORT_C void AppendL(const TDesC16& aText); + IMPORT_C void AppendL(TChar aChar); + IMPORT_C void AppendFormatL(TRefByValue aFmt, ...); + IMPORT_C void ReplaceL(TInt aPos, TInt aLength, const TDesC8& aDes); + IMPORT_C void ReplaceAllL(const TDesC8& aFrom, const TDesC8& aTo); + IMPORT_C void ReserveExtraL(TInt aExtraCapacity); + IMPORT_C TInt ReserveExtra(TInt aExtraCapacity); + IMPORT_C void CreateLC(TInt aMaxLength); + IMPORT_C void CopyAsUtf8L(const TDesC16& aString); + + // The usual RBuf-like APIs (for everything else, it just inherits from TDes8) + IMPORT_C TInt ReAlloc(TInt aMaxLength); + IMPORT_C void ReAllocL(TInt aMaxLength); + IMPORT_C void Assign(HBufC8* aBuf); + IMPORT_C TInt Create(TInt aMaxLength); + IMPORT_C void CreateL(TInt aMaxLength); + IMPORT_C TInt CreateMax(TInt aMaxLength); + IMPORT_C void CreateMaxL(TInt aMaxLength); + IMPORT_C void Close(); + + private: + HBufC8* iBuf; + }; + + typedef RLtkBuf16 RLtkBuf; + + /* Use this class for const static arrays of descriptors. Eg: + * + * const SLitC KData[] = + * { + * DESC("A string"), + * DESC("Another string"), + * }; + * + * You can treat the array items the same as TLitCs - ie most of the time they behave as descriptors but + * sometimes you may need to use operator(). + */ + struct SLitC + { + inline const TDesC* operator&() const { return reinterpret_cast(this); } + inline operator const TDesC&() const { return *reinterpret_cast(this); } + inline const TDesC& operator()() const { return *reinterpret_cast(this); } + + TInt iLength; + const TUint16* iPtr; + }; + struct SLitC8 + { + inline const TDesC8* operator&() const { return reinterpret_cast(this); } + inline operator const TDesC8&() const { return *reinterpret_cast(this); } + inline const TDesC8& operator()() const { return *reinterpret_cast(this); } + + TInt iLength; + const TUint8* iPtr; + }; + +#define DESC(x) { ((sizeof(L##x) / 2)-1) | 0x10000000, (const TUint16*) L##x } +#define DESC8(x) { (sizeof(x) - 1) | 0x10000000, (const TUint8*)x } +// 0x10000000 is EPtrC<