--- a/kernel/eka/common/des16.cpp Thu Aug 19 11:14:22 2010 +0300
+++ b/kernel/eka/common/des16.cpp Tue Aug 31 16:34:26 2010 +0300
@@ -765,6 +765,13 @@
#endif
}
+// Surrogate-aware version of lookup() above.
+// aChar can be over 0xFFFF.
+inline TUint lookup2(const TUint aChar, const TText *aConv)
+ {
+ return TUnicode(aChar).Fold((TInt)aConv, GetLocaleCharSet()->iCharDataSet);
+ }
+
TInt DoMatch16(const TDesC16 &aLeftD,const TDesC16 &aRightD,TMatchType aType)
{
const TText* table=convTable(aType);
@@ -1368,6 +1375,557 @@
#endif // !defined(__DES16_MACHINE_CODED__)
+
+/**
+ * A helper function, which moves a pointer one Unicode character forward.
+ *
+ * @aStart points to the head of the string to process.
+ * @aEnd points to the end of the string. Note that aEnd points to the first
+ * 16-bit unit after the string. That is, the string length (i.e, count
+ * of 16-bit units) is (aEnd-aStart).
+ *
+ * On return,
+ * if find valid character, then return KErrNone, with aNewStart pointing
+ * to the 16-bit unit after the found character;
+ * if meet corrupt surrogate before find a valid character, then return
+ * KErrCorruptSurrogateFound, with aNewStart pointing to the corrupt surrogate;
+ * if meet aEnd before find a valid character, then return KErrNotFound.
+ *
+ * @return KErrNone if ok;
+ * KErrNotFound if get to aEnd;
+ * KErrCorruptSurrogateFound if meet corrupt surrogate.
+ */
+TInt ProceedOneCharacter(const TText16* aStart, const TText16* aEnd, TText16*& aNewStart, TUint& aCurrentChar)
+ {
+ if (!aStart || !aEnd || aStart>=aEnd)
+ return KErrNotFound;
+ if (!TChar::IsSurrogate(aStart[0]))
+ {
+ aCurrentChar = aStart[0];
+ aNewStart = const_cast<TText16*> (aStart + 1);
+ return KErrNone;
+ }
+ else if (TChar::IsHighSurrogate(aStart[0]))
+ {
+ if (aEnd < aStart + 2)
+ return KErrCorruptSurrogateFound;
+ if (!TChar::IsLowSurrogate(aStart[1]))
+ {
+ aNewStart = const_cast<TText16*> (aStart + 2);
+ return KErrCorruptSurrogateFound;
+ }
+ aCurrentChar = TChar::JoinSurrogate(aStart[0], aStart[1]);
+ aNewStart = const_cast<TText16*> (aStart + 2);
+ return KErrNone;
+ }
+ else
+ {
+ aNewStart = const_cast<TText16*> (aStart);
+ return KErrCorruptSurrogateFound;
+ }
+ }
+
+/**
+ * A helper function, which moves a pointer one or more Unicode characters forward.
+ *
+ * This function starts from aStart, stops when one of below conditions matched:
+ * 1) 16-bit position >= (aEnd - aStart);
+ * 2) 16-bit position >= aMaxInt16Position;
+ * 3) character position >= aMaxCharacterPosition;
+ *
+ * Specify a huge integer (say KMaskDesLength16) for aMaxInt16Position or
+ * aMaxCharacterPosition to indicate unlimited 16-bit position or character
+ * position.
+ *
+ * When return, aOutInt16Position, aOutCharacterPosition and aLastChar will
+ * indicate the same one character, whose
+ * 16-bit position <= aMaxInt16Position, and
+ * character position <= aMaxCharacterPosition.
+ *
+ * @return KErrNone if no error found;
+ * KErrNotFound if get to aEnd before find wanted position; or,
+ * if aMaxIntPosition<=0 or aMaxCharacterPosition<=0;
+ * KErrCorruptSurrogateFound if meet corrupt surrogate.
+ */
+TInt ProceedMultiCharacters(const TText16* aStart, const TText16* aEnd,
+ const TInt aMaxInt16Position, const TInt aMaxCharacterPosition,
+ TInt& aOutInt16Position, TInt& aOutCharacterPosition, TUint& aLastChar)
+ {
+ TText16 *next;
+ TInt status = KErrNotFound;
+ aOutInt16Position = 0;
+ aOutCharacterPosition = 0;
+ while (aOutInt16Position <= aMaxInt16Position && aOutCharacterPosition <= aMaxCharacterPosition)
+ {
+ status = ::ProceedOneCharacter(aStart+aOutInt16Position, aEnd, next, aLastChar);
+ if (status == KErrNotFound || status == KErrCorruptSurrogateFound)
+ return status;
+ if (next - aStart > aMaxInt16Position || aOutInt16Position == aMaxInt16Position || aOutCharacterPosition == aMaxCharacterPosition)
+ {
+ return status;
+ }
+ aOutInt16Position = (next - aStart);
+ ++aOutCharacterPosition;
+ }
+ return status;
+ }
+
+EXPORT_C TInt TDesC16::FindCorruptSurrogate() const
+/**
+Look for the first corrupt surrogate in the descriptor.
+
+@return The 16-bit position of the first corrupt surrogate. KErrNotFound, if
+ not found.
+*/
+ {
+ // Do not use TUTF32Iterator, because it hides some characters, including corrupt surrogate.
+ TInt strLength = Length();
+
+ const TText16* start = Ptr();
+ const TText16* end = Ptr() + strLength;
+ TInt int16Pos;
+ TInt charPos;
+ TUint lastChar;
+ TInt status = ::ProceedMultiCharacters(start, end, KMaskDesLength16, KMaskDesLength16, int16Pos, charPos, lastChar);
+ if (status == KErrCorruptSurrogateFound)
+ return int16Pos;
+ return KErrNotFound;
+ }
+
+EXPORT_C TInt TDesC16::Locate2(TChar aChar) const
+/**
+The surrogate aware version of Locate().
+
+Searches for the first occurrence of a character within this descriptor's
+data.
+
+The search starts at the beginning of the data, i.e. at the leftmost
+position.
+
+@param aChar The Unicode character to be found. Can be inside or outside BMP.
+
+@return The offset of the character position from the beginning of the data.
+ KErrNotFound, if no matching character can be found.
+ KErrCorruptSurrogateFound, if meet corrupt surrogate in the searching.
+
+@see TDesC16::Locate()
+*/
+ {
+ TInt strLength = Length();
+ const TText16* start = Ptr();
+ const TText16* end = Ptr() + strLength;
+ TText16* next;
+ TUint currentChar;
+ TInt int16Index = 0;
+ TInt status = KErrNone;
+ FOREVER
+ {
+ status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+ if (status != KErrNone)
+ return status;
+ if (currentChar == aChar)
+ return int16Index;
+ int16Index = (next - start);
+ }
+ }
+
+LOCAL_C TInt DoLocateF16_2(const TDesC16& aDes, TUint aChar)
+// Surrogate-aware version of DoLocateF16().
+// Locate character aChar in the descriptor folded.
+ {
+ const TText* table = convTable(EMatchFolded);
+ TUint aChar32 = aChar;
+ aChar = lookup2(aChar32, table);
+
+ // find aChar in aDes
+ TInt strLength = aDes.Length();
+ const TText16* start = aDes.Ptr();
+ const TText16* end = aDes.Ptr() + strLength;
+ TText16* next;
+ TUint currentChar;
+ TInt int16Index = 0;
+ TInt status = KErrNone;
+ while (status == KErrNone)
+ {
+ status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+ if (status != KErrNone)
+ break;
+ if (lookup2(currentChar, table) == aChar)
+ return int16Index;
+ int16Index = (next - start);
+ }
+ return status;
+ }
+
+EXPORT_C TInt TDesC16::LocateF2(TChar aChar) const
+/**
+The surrogate aware version of LocateF().
+
+Searches for the first occurrence of a folded character within this
+descriptor's folded data.
+
+The search starts at the beginning of the data, i.e. at the leftmost
+position.
+
+Note that folding is locale-independent behaviour. It is also important to
+note that there can be no guarantee that folding is in any way culturally
+appropriate, and should not be used for searching strings in natural language.
+
+@param aChar The Unicode character to be found. Can be inside or outside BMP.
+
+@return The offset of the character position from the beginning of the data.
+ KErrNotFound, if no matching character can be found.
+ KErrCorruptSurrogateFound, if meet corrupt surrogate in the searching.
+
+@see TDesC16::LocateF()
+*/
+ {
+ return DoLocateF16_2(*this, aChar);
+ }
+
+/**
+ * Proceed backward from aEnd toward aStart by one character.
+ *
+ * @aStart points to the first 16-bit unit in a descriptor.
+ * @aEnd points to the 16-bit unit after the last one. So, count of 16-bit
+ * units to process is (aEnd-aStart).
+ *
+ * On return,
+ * if valid character found, then return KErrNone, with aNewEnd pointing
+ * to the character found;
+ * if meet corrupt surrogate before find a valid character, then return
+ * KErrCorruptSurrogateFound, with aNewStart point to the corrupt
+ * surrogate;
+ * if aStart met, then return KErrNotFound.
+ *
+ * @return KErrNone if ok;
+ * KErrNotFound if get to aStart;
+ * KErrCorruptSurrogateFound if meet corrupt surrogate.
+ */
+TInt RecedeOneCharacter(const TText16* aStart, const TText16* aEnd, TText16*& aNewEnd, TUint& aCurrentChar)
+ {
+ if (!aStart || !aEnd || aStart>=aEnd)
+ return KErrNotFound;
+ if (!TChar::IsSurrogate(aEnd[-1]))
+ {
+ aCurrentChar = aEnd[-1];
+ aNewEnd = const_cast<TText16*> (aEnd - 1);
+ return KErrNone;
+ }
+ else if (TChar::IsLowSurrogate(aEnd[-1]))
+ {
+ if (aEnd < aStart + 2)
+ return KErrNotFound;
+ if (!TChar::IsHighSurrogate(aEnd[-2]))
+ {
+ aNewEnd = const_cast<TText16*> (aEnd - 2);
+ return KErrCorruptSurrogateFound;
+ }
+ aCurrentChar = TChar::JoinSurrogate(aEnd[-2], aEnd[-1]);
+ aNewEnd = const_cast<TText16*> (aEnd - 2);
+ return KErrNone;
+ }
+ else
+ {
+ aNewEnd = const_cast<TText16*> (aEnd);
+ return KErrCorruptSurrogateFound;
+ }
+ }
+
+EXPORT_C TInt TDesC16::LocateReverse2(TChar aChar) const
+/**
+The surrogate aware version of LocateReverse().
+
+Searches for the first occurrence of a character within this descriptor's
+data, searching from the end of the data.
+
+The search starts at the rightmost position.
+
+@param aChar The Unicode character to be found. Can be inside or outside BMP.
+
+@return The offset of the character position from the beginning of the data.
+ KErrNotFound, if no matching character can be found.
+ KErrCorruptSurrogateFound, if meet corrupt surrogate in the searching.
+
+@see TDesC16::LocateReverse()
+*/
+ {
+ TInt strLength = Length();
+ const TText16* start = Ptr();
+ TText16* newEnd;
+ TUint currentChar;
+ TInt int16Index = strLength;
+ TInt status = KErrNone;
+ FOREVER
+ {
+ status = ::RecedeOneCharacter(start, start+int16Index, newEnd, currentChar);
+ if (status != KErrNone)
+ return status;
+ int16Index = (newEnd - start);
+ if (currentChar == aChar)
+ return int16Index;
+ }
+ }
+
+EXPORT_C TInt TDesC16::LocateReverseF2(TChar aChar) const
+/**
+The surrogate aware version of LocateReverseF().
+
+Searches for the first occurrence of a folded character within this descriptor's
+folded data, searching from the end of the data.
+
+The search starts at the rightmost position.
+
+Note that folding is locale-independent behaviour. It is also important to
+note that there can be no guarantee that folding is in any way culturally
+appropriate, and should not be used for searching strings in natural language.
+
+@param aChar The Unicode character to be found. Can be inside or outside BMP.
+
+@return The offset of the character position from the beginning of the data.
+ KErrNotFound, if no matching character can be found.
+ KErrCorruptSurrogateFound, if meet corrupt surrogate in the searching.
+
+@see TDesC16::LocateReverseF()
+*/
+ {
+ TInt strLength = Length();
+ const TText16* start = Ptr();
+ TText16* newEnd;
+ TUint currentChar;
+ TInt int16Index = strLength;
+ TInt status = KErrNone;
+ FOREVER
+ {
+ status = ::RecedeOneCharacter(start, start+int16Index, newEnd, currentChar);
+ if (status != KErrNone)
+ return status;
+ int16Index = (newEnd - start);
+ TCharF c(currentChar);
+ if (c == aChar)
+ return int16Index;
+ }
+ }
+
+inline TUint conv2(TUint aChar, const TText *aConv, const TUnicodeDataSet* aCharDataSet)
+// Surrogate-aware version of conv().
+// If aConv is not NULL then convert the character.
+ {
+ if (aConv)
+ return TUnicode(aChar).Fold((TInt)aConv, aCharDataSet);
+ else
+ return aChar;
+ }
+
+// Surrogate-aware version of DoMatch16().
+// This helper function uses the same search algorithm as DoMatch16().
+TInt DoMatch16_2(const TDesC16 &aLeftD, const TDesC16 &aRightD, TMatchType aType)
+ {
+ const TText* table=convTable(aType);
+ const TUint16* const pRight=aRightD.Ptr();
+ const TUint16* pM=pRight-1; // pre-increment addressing
+ const TUint16* const pP=pM+aRightD.Length();
+ const TUint16* const pLeft=aLeftD.Ptr()-1; // pre-increment addressing
+ const TUint16* pB=pLeft;
+ const TUint16* pB2=pLeft; // always points to current char; pB2==pB or pB-1
+ const TUint16* const pE=pB+aLeftD.Length();
+
+ // Note: pM and pB always point to the int16 unit before the character to handle.
+ // so, pM[0] and pB[0] may be a low surrogate.
+ // but, pM[1] and pB[1] must be start of a character.
+ // Note: pB2 always points to current character being handled.
+ // pB2 is used to generated return value.
+ // if pB[0] is low surrogate, then pB2=pB-1;
+ // if pB[0] is BMP, then pB2=pB.
+ //
+ // A 'diagram' shows the pointers:
+ //
+ // before search:
+ // left: ############################
+ // ^ ^
+ // pLeft/pB/pB2 pE
+ //
+ // right: ############################
+ // ^^ ^
+ // pM pRight pP
+ //
+ //
+ // after several iterations (C is the next character going to be checked):
+ // left: ###############C############
+ // ^ ^ ^
+ // pLeft pB/pB2 pE
+ //
+ // right: ##########C#################
+ // ^ ^ ^
+ // pRight pM pP
+ //
+
+ const TUnicodeDataSet* charDataSet = GetLocaleCharSet()->iCharDataSet;
+
+ // Match any pattern up to the first star
+ TUint c;
+ TInt status;
+ TText* newStart;
+ for (;;)
+ {
+ status = ::ProceedOneCharacter(pM+1, pP+1, newStart, c);
+ if (status == KErrCorruptSurrogateFound)
+ return KErrCorruptSurrogateFound;
+ if (status == KErrNotFound) // exhausted the pattern
+ return pB==pE ? 0 : KErrNotFound;
+ pM = newStart - 1;
+ c = conv2(c, table, charDataSet);
+ if (c==KMatchAny)
+ break;
+ if (pB==pE) // no more input
+ return KErrNotFound;
+ TUint c2;
+ pB2 = pB + 1;
+ status = ::ProceedOneCharacter(pB+1, pE+1, newStart, c2);
+ if (status == KErrCorruptSurrogateFound)
+ return KErrCorruptSurrogateFound;
+ pB = newStart - 1;
+ if (c != conv2(c2, table, charDataSet) && c != KMatchOne) // match failed
+ return KErrNotFound;
+ }
+ // reached a star
+ if (pM==pP)
+ return 0;
+ TInt r=pM==pRight ? -1 : 0; // r = how many int16 has been matched in candidate (aLeftD)
+ for (;;)
+ {
+ status = ::ProceedOneCharacter(pM+1, pP+1, newStart, c);
+ if (status == KErrCorruptSurrogateFound)
+ return KErrCorruptSurrogateFound;
+ pM = newStart - 1;
+ c = conv2(c, table, charDataSet);
+ if (c==KMatchAny)
+ {
+star: if (pM==pP) // star at end of pattern, always matches
+ return Max(r,0);
+ if (r<-1) // skipped some '?', matches at beginning
+ r=0;
+ continue;
+ }
+ if (pB==pE) // no more input
+ return KErrNotFound;
+ if (c==KMatchOne)
+ { // skip a character in the input
+ if (pM==pP)
+ return r+((r>=0) ? 0 : (pE-pLeft));
+ TUint dummyC;
+ pB2 = pB + 1;
+ status = ::ProceedOneCharacter(pB+1, pE+1, newStart, dummyC);
+ if (status == KErrCorruptSurrogateFound)
+ return KErrCorruptSurrogateFound;
+ pB = newStart - 1;
+ if (r < 0)
+ r -= (newStart - pB2); // back r by 1 or 2, depending on dummyC is BMP or non-BMP.
+ continue;
+ }
+ // Matching a non-wild character
+ for (;;)
+ {
+ if (table)
+ {
+ TUint c2;
+ for (;;)
+ {
+ pB2 = pB + 1;
+ status = ::ProceedOneCharacter(pB+1, pE+1, newStart, c2);
+ if (status == KErrCorruptSurrogateFound)
+ return KErrCorruptSurrogateFound;
+ pB = newStart - 1;
+ if (lookup2(c2, table) == c)
+ break;
+ if (pB==pE) // no more input
+ return KErrNotFound;
+ }
+ }
+ else
+ {
+ TUint c2;
+ for (;;)
+ {
+ pB2 = pB + 1;
+ status = ::ProceedOneCharacter(pB+1, pE+1, newStart, c2);
+ if (status == KErrCorruptSurrogateFound)
+ return KErrCorruptSurrogateFound;
+ pB = newStart - 1;
+ if (c2 == c)
+ break;
+ if (pB==pE) // no more input
+ return KErrNotFound;
+ }
+ }
+ // Try to match up to the next star
+ const TUint16* pb=pB;
+ const TUint16* pm=pM;
+ for (;;)
+ {
+ if (pm<pP)
+ {
+ TUint cc;
+ status = ::ProceedOneCharacter(pm+1, pP+1, newStart, cc);
+ if (status == KErrCorruptSurrogateFound)
+ return KErrCorruptSurrogateFound;
+ pm = newStart - 1;
+ cc = conv2(cc, table, charDataSet);
+ if (cc==KMatchAny)
+ { // sub-match successful, back to main loop
+ r+=(r>=0 ? 0 : pB2-pLeft);
+ pB=pb;
+ pM=pm;
+ goto star;
+ }
+ if (pb==pE)
+ return KErrNotFound; // no more input
+ TUint cc2;
+ status = ::ProceedOneCharacter(pb+1, pE+1, newStart, cc2);
+ if (status == KErrCorruptSurrogateFound)
+ return KErrCorruptSurrogateFound;
+ pb = newStart - 1;
+ if (cc != conv2(cc2, table, charDataSet) && cc != KMatchOne)
+ break; // sub-match failed, try next input character
+ }
+ else if (pb==pE) // end of matching pattern
+ {
+ return r+(r>=0 ? 0 : pB2-pLeft); // end of input, so have a match
+ }
+ else
+ break; // try next input character
+ }
+ }
+ }
+ }
+
+EXPORT_C TInt TDesC16::Match2(const TDesC16 &aDes) const
+/**
+The surrogate aware version of Match().
+
+Searches this descriptor's data for a match with the match pattern supplied
+in the specified descriptor.
+
+The match pattern can contain the wildcard characters "*" and "?", where "*"
+matches zero or more consecutive occurrences of any character and "?" matches
+a single occurrence of any character.
+
+Note that there is no 'escape character', which means that it is not possible
+to match either the "*" character itself or the "?" character itself using
+this function.
+
+@param aDes A 16-bit non-modifable descriptor containing the match pattern.
+
+@return If a match is found, the offset within this descriptor's data where
+ the match first occurs. KErrNotFound, if there is no match.
+ KErrCorruptSurrogateFound, if meet corrupt surrogate in the searching.
+
+@see TDesC16::Match()
+*/
+ {
+ return DoMatch16_2(*this, aDes, EMatchNormal);
+ }
+
#if !defined( __DES16_MACHINE_CODED__) | defined(__EABI_CTORS__)
EXPORT_C TBufCBase16::TBufCBase16()
//
@@ -3383,6 +3941,936 @@
AppendFormatList(aFmt,list);
}
+EXPORT_C void TDes16::Append2(TChar aChar)
+/**
+The surrogate aware version of Append().
+
+Appends data onto the end of this descriptor's data.
+
+The length of this descriptor is incremented to reflect the new content. The
+length will be increased by 1 if aChar is inside BMP or 2 if aChar is outside
+BMP.
+
+@param aChar A single character to be appended. Can be inside or outside BMP.
+
+@panic USER 11 if the resulting new length of this descriptor is greater than
+ its maximum length.
+
+@panic USER 217 if corrupt surrogate found in aChar. This functions will not
+ validate already existing surrogate in the descriptor.
+
+@see TDes16::Append()
+*/
+ {
+ __ASSERT_ALWAYS(TChar::IsSupplementary(aChar) || !TChar::IsSurrogate((TText16)aChar), Panic(ECorruptSurrogateFound));
+
+ TInt len = Length();
+ TUint16 *pB = WPtr() + len;
+ if (TChar::IsSupplementary(aChar))
+ {
+ SetLength(len + 2);
+ *pB++ = TChar::GetHighSurrogate(aChar);
+ *pB = TChar::GetLowSurrogate(aChar);
+ }
+ else
+ {
+ SetLength(len + 1);
+ *pB = (TText16)aChar;
+ }
+ }
+
+EXPORT_C void TDes16::Fill2(TChar aChar)
+/**
+The surrogate aware version of Fill().
+
+Fills the descriptor's data area with the specified character, replacing any
+existing data.
+
+The descriptor is filled from the beginning up to its current length. The
+descriptor's length does not change. It is not filled to its maximum length.
+If aChar is supplementary character, and available space to fill is odd in
+16-bit unit, then the last 16-bit unit will be filled with high surrogate,
+and the length will keep unchanged.
+
+@param aChar The fill character. Can be inside or outside BMP.
+
+@see TDes16::Fill()
+*/
+ {
+ TUint16 *pB = WPtr();
+ TUint16 *pE = pB + Length();
+ if (!TChar::IsSupplementary(aChar))
+ {
+ while (pB < pE)
+ *pB++ = (TUint16)aChar;
+ }
+ else
+ {
+ while (pB < pE - 1)
+ {
+ *pB++ = TChar::GetHighSurrogate(aChar);
+ *pB++ = TChar::GetLowSurrogate(aChar);
+ }
+ // fill the last 16-bit unit
+ if (pB < pE)
+ *pB++ = TChar::GetHighSurrogate(aChar);
+ }
+ }
+
+EXPORT_C void TDes16::Fill2(TChar aChar, TInt aLength)
+/**
+The surrogate aware version of Fill().
+
+Fills the descriptor's data area with the specified character, replacing any
+existing data.
+
+The descriptor is filled with the specified number of characters,
+and its length is changed to reflect this.
+
+If aChar is supplementary character, and available space to fill is odd in
+16-bit unit, then the last 16-bit unit will be left unchanged.
+
+@param aChar The fill character. Can be inside or outside BMP.
+@param aLength The new length of the descriptor.
+
+@panic USER 11 if aLength is negative or is greater than the maximum length
+ of this descriptor.
+
+@panic USER 217 if corrupt surrogate found in aChar. These functions will not
+ validate already existing surrogate in the descriptor.
+
+@see TDes16::Fill()
+*/
+ {
+ __ASSERT_ALWAYS(TChar::IsSupplementary(aChar) || !TChar::IsSurrogate((TText16)aChar), Panic(ECorruptSurrogateFound));
+
+ SetLength(aLength);
+ Fill2(aChar);
+ }
+
+EXPORT_C void TDes16::AppendFill2(TChar aChar, TInt aLength)
+/**
+The surrogate aware version of AppendFill().
+
+Appends and fills this descriptor with the specified character.
+
+The descriptor is appended with the specified number of characters, and its
+length is changed to reflect this.
+
+If aChar is supplementary character, and available space to fill is odd in
+16-bit unit, then the last 16-bit unit will be filled with high surrogate.
+
+@param aChar The fill character. Can be inside or outside BMP.
+@param aLength The length of additional space to append into.
+
+@panic USER 11 if aLength is negative, or the resulting length of this
+ descriptor is greater than its maximum length.
+
+@panic USER 217 if corrupt surrogate found in aChar. These functions will not
+ validate already existing surrogate in the descriptor.
+
+@see TDes16::AppendFill()
+*/
+ {
+ __ASSERT_ALWAYS(TChar::IsSupplementary(aChar) || !TChar::IsSurrogate((TText16)aChar), Panic(ECorruptSurrogateFound));
+
+ TInt len=Length();
+ TUint16 *pB=WPtr()+len;
+ SetLength(len+aLength);
+ TUint16 *pE=pB+aLength;
+ if (!TChar::IsSupplementary(aChar))
+ {
+ while (pB < pE)
+ *pB++ = (TUint16)aChar;
+ }
+ else
+ {
+ while (pB < pE - 1)
+ {
+ *pB++ = TChar::GetHighSurrogate(aChar);
+ *pB++ = TChar::GetLowSurrogate(aChar);
+ }
+ // fill the last 16-bit unit
+ if (pB < pE)
+ *pB++ = TChar::GetHighSurrogate(aChar);
+ }
+ }
+
+EXPORT_C void TDes16::Justify2(const TDesC16 &aDes, TInt aWidth, TAlign anAlignment, TChar aFill)
+/**
+The surrogate aware version of Justify().
+
+Copies data into this descriptor and justifies it, replacing any existing data.
+
+The length of this descriptor is set to reflect the new data.
+
+The target area is considered to be an area of specified width positioned at
+the beginning of this descriptor's data area. Source data is copied into, and
+aligned within this target area according to the specified alignment
+instruction.
+
+If the length of the target area is larger than the length of the source, then
+spare space within the target area is padded with the fill character.
+
+@param aDes A 16-bit non-modifiable descriptor containing the source data.
+ The length of the data to be copied is the smaller of:
+ the length of the source descriptor, and
+ the width of the target area (only if this is not the
+ explicit negative value KDefaultJustifyWidth).
+
+@param aWidth The width of the target area. If this has the specific
+ negative value KDefaultJustifyWidth, then the width is
+ re-set to the length of the data source.
+
+@param anAlignment The alignment of the data within the target area
+
+@param aFill The fill character used to pad the target area. Can be
+ inside or outside BMP.
+
+@panic USER 11 if the resulting length of this descriptor is greater than
+ its maximum length or aWidth has a negative value other
+ than KDefaultJustifyWidth.
+
+@panic USER 217 if corrupt surrogate found in the parameters or in the
+ descriptor.
+
+@see TDes16::Justify()
+*/
+ {
+ Zero();
+ AppendJustify2(aDes.Ptr(),aDes.Length(),aWidth,anAlignment,aFill);
+ }
+
+EXPORT_C void TDes16::AppendJustify2(const TDesC16 &aDes, TInt aWidth, TAlign anAlignment, TChar aFill)
+/**
+The surrogate aware version of AppendJustify.
+
+Appends data onto the end of this descriptor's data and justifies it.
+
+The source of the appended data is an existing descriptor.
+
+The target area is considered to be an area of specified width, immediately
+following this descriptor's existing data. Source data is copied into, and
+aligned within this target area according to the specified alignment instruction.
+
+If the length of the target area is larger than the length of the source,
+then spare space within the target area is padded with the fill character.
+
+@param aDes A 16-bit non-modifiable descriptor containing the source
+ data. The length of the data to be copied is the smaller of:
+ the length of the source descriptor, and
+ the width of the target area (only if this is not the
+ explicit negative value KDefaultJustifyWidth).
+
+@param aWidth The width of the target area. If this has the specific
+ negative value KDefaultJustifyWidth, then the width is
+ re-set to the length of the data source.
+
+@param anAlignment The alignment of the data within the target area.
+
+@param aFill The fill character used to pad the target area. Can be
+ inside or outside BMP.
+
+@panic USER 11 if the resulting length of this descriptor is greater than
+ its maximum length or aWidth has a negative value other
+ than KDefaultJustifyWidth.
+
+@panic USER 217 if corrupt surrogate found in the parameters or in the
+ descriptor.
+
+@see TDes16::AppendJustify()
+*/
+ {
+ AppendJustify2(aDes.Ptr(),aDes.Length(),aWidth,anAlignment,aFill);
+ }
+
+EXPORT_C void TDes16::AppendJustify2(const TDesC16 &aDes, TInt aLength, TInt aWidth, TAlign anAlignment, TChar aFill)
+/**
+The surrogate aware version of AppendJustify.
+
+Appends data onto the end of this descriptor's data and justifies it.
+
+The source of the appended data is an existing descriptor.
+
+The target area is considered to be an area of specified width, immediately
+following this descriptor's existing data. Source data is copied into, and
+aligned within this target area according to the specified alignment instruction.
+
+If the length of the target area is larger than the length of the source,
+then spare space within the target area is padded with the fill character.
+
+@param aDes An 8-bit non-modifiable descriptor containing the source data.
+
+@param aLength The length of data to be copied from the source descriptor.
+ If this is greater than the width of the target area, then
+ the length of data copied is limited to the width.
+ The length of data to be copied must not be greater than
+ the length of the source descriptor. Note that this
+ condition is not automatically tested.
+
+@param aWidth The width of the target area. If this has the specific negative
+ value KDefaultJustifyWidth, then the width is
+ re-set to the length of the data source.
+
+@param anAlignment The alignment of the data within the target area.
+
+@param aFill The fill character used to pad the target area. Can be
+ inside or outside BMP.
+
+@panic USER 11 if the resulting length of this descriptor is greater than
+ its maximum length or aWidth has a negative value other
+ than KDefaultJustifyWidth.
+
+@panic USER 217 if corrupt surrogate found in the parameters or in the
+ descriptor.
+
+@see TDes16::AppendJustify()
+*/
+ {
+ AppendJustify2(aDes.Ptr(),aLength,aWidth,anAlignment,aFill);
+ }
+
+EXPORT_C void TDes16::AppendJustify2(const TUint16 *aString, TInt aWidth, TAlign anAlignment, TChar aFill)
+/**
+The surrogate aware version of AppendJustify.
+
+Appends a zero terminated string onto the end of this descriptor's data and
+justifies it.
+
+The zero terminator is not copied.
+
+The target area is considered to be an area of specified width, immediately
+following this descriptor's existing data. Source data is copied into, and
+aligned within, this target area according to the specified alignment instruction.
+
+If the length of the target area is larger than the length of the source,
+then spare space within the target area is padded with the fill character.
+
+@param aString A pointer to a zero terminated string The length of the data
+ to be copied is the smaller of: the length of the string (excluding the zero
+ terminator), the width of the target area (only if this is not the explicit
+ negative value KDefaultJustifyWidth).
+
+@param aWidth The width of the target area. If this has the specific negative
+ value KDefaultJustifyWidth, then the width is re-set to the length of the
+ zero terminated string (excluding the zero terminator).
+
+@param anAlignment The alignment of the data within the target area.
+
+@param aFill The fill character used to pad the target area. Can be
+ inside or outside BMP.
+
+@panic USER 11 if the resulting length of this descriptor is greater than
+ its maximum length or aWidth has a negative value other
+ than KDefaultJustifyWidth.
+
+@panic USER 217 if corrupt surrogate found in the parameters or in the
+ descriptor.
+
+@see TDes16::AppendJustify()
+*/
+ {
+ __CHECK_ALIGNMENT(aString,ETDes16AppendJustify1);
+ AppendJustify2(aString,STRING_LENGTH_16(aString),aWidth,anAlignment,aFill);
+ }
+
+EXPORT_C void TDes16::AppendJustify2(const TUint16 *aString, TInt aLength, TInt aWidth, TAlign anAlignment, TChar aFill)
+/**
+The surrogate aware version of AppendJustify.
+
+Appends data onto the end of this descriptor's data and justifies it.
+
+The source of the appended data is a memory location.
+
+The target area is considered to be an area of specified width, immediately
+following this descriptor's existing data. Source data is copied into, and
+aligned within, this target area according to the specified alignment instruction.
+
+If the length of the target area is larger than the length of the source,
+then spare space within the target area is padded with the fill character.
+
+@param aString A pointer to a source memory location.
+
+@param aLength The length of data to be copied. If this is greater than the
+ width of the target area, then the length of data copied is
+ limited to the width.
+
+@param aWidth The width of the target area. If this has the specific negative
+ value KDefaultJustifyWidth, then the width is
+ re-set to the length of the data source.
+
+@param anAlignment The alignment of the data within the target area.
+
+@param aFill The fill character used to pad the target area. Can be
+ inside or outside BMP.
+
+@panic USER 11 if the resulting length of this descriptor is greater than
+ its maximum length or aWidth has a negative value other
+ than KDefaultJustifyWidth.
+
+@panic USER 17 if aLength is negative.
+
+@panic USER 217 if corrupt surrogate found in the parameters or in the
+ descriptor.
+
+@see TDes16::AppendJustify()
+*/
+ {
+ __ASSERT_ALWAYS(aLength>=0,Panic(ETDes16LengthNegative));
+ __CHECK_ALIGNMENT(aString,ETDes16AppendJustify2);
+ if (aWidth==KDefaultJustifyWidth)
+ aWidth=aLength;
+ if (aLength>aWidth)
+ aLength=aWidth;
+ TInt offset=Length();
+ AppendFill2(aFill,aWidth);
+ TInt r=aWidth-aLength;
+ if (anAlignment==ECenter)
+ r>>=1;
+ else if (anAlignment==ELeft)
+ r=0;
+ memCopy(WPtr()+offset+r,aString,aLength);
+ }
+
+EXPORT_C void TDes16::Fold2()
+/**
+The surrogate aware version of Fold().
+
+Performs folding on the content of this descriptor.
+
+Note that folding is locale-independent behaviour. It is also important to
+note that there can be no guarantee that folding is in any way culturally
+appropriate, and should not be used when dealing with strings in natural
+language.
+
+@panic USER 217 if corrupt surrogate found in the descriptor.
+
+@see TDes16::Fold()
+*/
+ {
+ TInt strLength = Length();
+ TText16* start = WPtr();
+ const TText16* end = Ptr() + strLength;
+ TText16* next;
+ TUint currentChar;
+ TInt int16Index = 0;
+ TInt status = KErrNone;
+ FOREVER
+ {
+ status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+ __ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+ if (status == KErrNotFound)
+ break;
+ TCharF c(currentChar);
+ // at present, c and currentChar always in the same plane
+ if (TChar::IsSupplementary(c))
+ {
+ start[int16Index] = TChar::GetHighSurrogate(c);
+ start[int16Index+1] = TChar::GetLowSurrogate(c);
+ }
+ else
+ {
+ start[int16Index] = (TText16)c;
+ }
+ int16Index = (next - start);
+ }
+ }
+
+EXPORT_C void TDes16::Collate2()
+/**
+The surrogate aware version of Collate().
+
+Performs collation on the content of this descriptor.
+
+@panic USER 217 if corrupt surrogate found in the descriptor.
+
+@see TDes16::Collate()
+*/
+ {
+ TInt strLength = Length();
+ TText16* start = WPtr();
+ const TText16* end = Ptr() + strLength;
+ TText16* next;
+ TUint currentChar;
+ TInt int16Index = 0;
+ TInt status = KErrNone;
+ FOREVER
+ {
+ status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+ __ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+ if (status == KErrNotFound)
+ break;
+ TChar c = User::Collate(currentChar);
+ // at present, c and currentChar always in the same plane
+ if (TChar::IsSupplementary(c))
+ {
+ start[int16Index] = TChar::GetHighSurrogate(c);
+ start[int16Index+1] = TChar::GetLowSurrogate(c);
+ }
+ else
+ {
+ start[int16Index] = (TText16)c;
+ }
+ int16Index = (next - start);
+ }
+ }
+
+EXPORT_C void TDes16::LowerCase2()
+/**
+The surrogate aware version of LowerCase().
+
+Converts the content of this descriptor to lower case.
+
+Conversion is implemented as appropriate to the current locale.
+
+@panic USER 217 if corrupt surrogate found in the descriptor.
+
+@see TDes16::LowerCase()
+*/
+ {
+ TInt strLength = Length();
+ TText16* start = WPtr();
+ const TText16* end = Ptr() + strLength;
+ TText16* next;
+ TUint currentChar;
+ TInt int16Index = 0;
+ TInt status = KErrNone;
+ FOREVER
+ {
+ status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+ __ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+ if (status == KErrNotFound)
+ break;
+ TCharLC c(currentChar);
+ // at present, c and currentChar always in the same plane
+ if (TChar::IsSupplementary(c))
+ {
+ start[int16Index] = TChar::GetHighSurrogate(c);
+ start[int16Index+1] = TChar::GetLowSurrogate(c);
+ }
+ else
+ {
+ start[int16Index] = (TText16)c;
+ }
+ int16Index = (next - start);
+ }
+ }
+
+EXPORT_C void TDes16::UpperCase2()
+/**
+The surrogate aware version of UpperCase().
+
+Converts the content of this descriptor to upper case.
+
+Conversion is implemented as appropriate to the current locale.
+
+@panic USER 217 if corrupt surrogate found in the descriptor.
+
+@see TDes16::UpperCase()
+*/
+ {
+ TInt strLength = Length();
+ TText16* start = WPtr();
+ const TText16* end = Ptr() + strLength;
+ TText16* next;
+ TUint currentChar;
+ TInt int16Index = 0;
+ TInt status = KErrNone;
+ FOREVER
+ {
+ status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+ __ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+ if (status == KErrNotFound)
+ break;
+ TCharUC c(currentChar);
+ // at present, c and currentChar always in the same plane
+ if (TChar::IsSupplementary(c))
+ {
+ start[int16Index] = TChar::GetHighSurrogate(c);
+ start[int16Index+1] = TChar::GetLowSurrogate(c);
+ }
+ else
+ {
+ start[int16Index] = (TText16)c;
+ }
+ int16Index = (next - start);
+ }
+ }
+
+EXPORT_C void TDes16::Capitalize2()
+/**
+The surrogate aware version of Capitalize().
+
+Capitalises the content of this descriptor.
+
+Capitalisation is implemented as appropriate to the current locale.
+
+@panic USER 217 if corrupt surrogate found in the descriptor.
+
+@see TDes16::Capitalize()
+*/
+ {
+ TInt strLength = Length();
+ TText16* start = WPtr();
+ const TText16* end = Ptr() + strLength;
+ TText16* next;
+ TUint currentChar;
+ TInt int16Index = 0;
+ TInt status = KErrNone;
+
+ // the first character: title case
+ status = ::ProceedOneCharacter(start, end, next, currentChar);
+ __ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+ TChar c = User::TitleCase(currentChar);
+ // at present, c and currentChar always in the same plane
+ if (TChar::IsSupplementary(c))
+ {
+ start[0] = TChar::GetHighSurrogate(c);
+ start[1] = TChar::GetLowSurrogate(c);
+ }
+ else
+ {
+ start[0] = (TText16)c;
+ }
+ int16Index = (next - start);
+
+ // following characters: lower case
+ FOREVER
+ {
+ status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+ __ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+ if (status == KErrNotFound)
+ break;
+ TChar c = User::LowerCase(currentChar);
+ // at present, c and currentChar always in the same plane
+ if (TChar::IsSupplementary(c))
+ {
+ start[int16Index] = TChar::GetHighSurrogate(c);
+ start[int16Index+1] = TChar::GetLowSurrogate(c);
+ }
+ else
+ {
+ start[int16Index] = (TText16)c;
+ }
+ int16Index = (next - start);
+ }
+ }
+
+EXPORT_C void TDes16::CopyF2(const TDesC16 &aDes)
+/**
+The surrogate aware version of CopyF().
+
+Copies and folds data from the specified descriptor into this descriptor replacing
+any existing data.
+
+The length of this descriptor is set to reflect the new
+data.
+
+Note that folding is locale-independent behaviour. It is also important to
+note that there can be no guarantee that folding is in any way culturally
+appropriate, and should not be used when dealing with strings in natural
+language.
+
+@param aDes A 16-bit non-modifiable descriptor.
+
+@panic USER 11 if the length of aDes is greater than the maximum length of
+ this target descriptor.
+
+@panic USER 217 if corrupt surrogate found in aDes or in the descriptor.
+
+@see TDes16::CopyF()
+*/
+ {
+ TText16* pT = WPtr();
+ TInt len = 0;
+ const TInt maxLen = MaxLength();
+
+ // iterate through aDes
+ TInt strLength = aDes.Length();
+ const TText16* start = aDes.Ptr();
+ const TText16* end = aDes.Ptr() + strLength;
+ TText16* next;
+ TUint currentChar;
+ TInt int16Index = 0;
+ TInt status = KErrNone;
+ FOREVER
+ {
+ status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+ __ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+ if (status == KErrNotFound)
+ break;
+ int16Index = (next - start);
+ TCharF c(currentChar);
+ if (TChar::IsSupplementary(c))
+ {
+ len += 2;
+ __ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+ pT[len-2] = TChar::GetHighSurrogate(c);
+ pT[len-1] = TChar::GetLowSurrogate(c);
+ }
+ else
+ {
+ ++len;
+ __ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+ pT[len-1] = (TText16)c;
+ }
+ }
+ SetLength(len);
+ }
+
+EXPORT_C void TDes16::CopyC2(const TDesC16 &aDes)
+/**
+The surrogate aware version of CopyC().
+
+Copies and collates data from the specified descriptor
+into this descriptor replacing any existing data.
+
+The length of this descriptor is set to reflect the new data.
+
+@param aDes A 16-bit non-modifiable descriptor.
+
+@panic USER 11 if the length of aDes is greater than the maximum length of
+ this target descriptor.
+
+@panic USER 217 if corrupt surrogate found in aDes or in the descriptor.
+
+@see TDes16::CopyC()
+*/
+ {
+ TText16* pT = WPtr();
+ TInt len = 0;
+ const TInt maxLen = MaxLength();
+
+ // iterate through aDes
+ TInt strLength = aDes.Length();
+ const TText16* start = aDes.Ptr();
+ const TText16* end = aDes.Ptr() + strLength;
+ TText16* next;
+ TUint currentChar;
+ TInt int16Index = 0;
+ TInt status = KErrNone;
+ FOREVER
+ {
+ status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+ __ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+ if (status == KErrNotFound)
+ break;
+ int16Index = (next - start);
+ TChar c = User::Collate(currentChar);
+ if (TChar::IsSupplementary(c))
+ {
+ len += 2;
+ __ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+ pT[len-2] = TChar::GetHighSurrogate(c);
+ pT[len-1] = TChar::GetLowSurrogate(c);
+ }
+ else
+ {
+ ++len;
+ __ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+ pT[len-1] = (TText16)c;
+ }
+ }
+ SetLength(len);
+ }
+
+EXPORT_C void TDes16::CopyLC2(const TDesC16 &aDes)
+/**
+The surrogate aware version of CopyLC().
+
+Copies text from the specified descriptor and converts it to lower case before
+putting it into this descriptor, replacing any existing data.
+
+The length of this descriptor is set to reflect the new data.
+
+Conversion to lower case is implemented as appropriate to the current locale.
+
+@param aDes A 16-bit non modifiable descriptor.
+
+@panic USER 11 if the length of aDes is greater than the maximum length of
+ this target descriptor.
+
+@panic USER 217 if corrupt surrogate found in aDes or in the descriptor.
+
+@see TDes16::CopyLC()
+*/
+ {
+ TText16* pT = WPtr();
+ TInt len = 0;
+ const TInt maxLen = MaxLength();
+
+ // iterate through aDes
+ TInt strLength = aDes.Length();
+ const TText16* start = aDes.Ptr();
+ const TText16* end = aDes.Ptr() + strLength;
+ TText16* next;
+ TUint currentChar;
+ TInt int16Index = 0;
+ TInt status = KErrNone;
+ FOREVER
+ {
+ status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+ __ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+ if (status == KErrNotFound)
+ break;
+ int16Index = (next - start);
+ TCharLC c(currentChar);
+ if (TChar::IsSupplementary(c))
+ {
+ len += 2;
+ __ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+ pT[len-2] = TChar::GetHighSurrogate(c);
+ pT[len-1] = TChar::GetLowSurrogate(c);
+ }
+ else
+ {
+ ++len;
+ __ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+ pT[len-1] = (TText16)c;
+ }
+ }
+ SetLength(len);
+ }
+
+EXPORT_C void TDes16::CopyUC2(const TDesC16 &aDes)
+/**
+The surrogate aware version of CopyUC().
+
+Copies text from the specified descriptor and converts it to upper case before
+putting it into this descriptor, replacing any existing data.
+
+The length of this descriptor is set to reflect the new data.
+
+Conversion to upper case is implemented as appropriate to the current locale.
+
+@param aDes A 16-bit non modifiable descriptor.
+
+@panic USER 11 if the length of aDes is greater than the maximum length of
+ this target descriptor.
+
+@panic USER 217 if corrupt surrogate found in aDes or in the descriptor.
+
+@see TDes16::CopyUC()
+*/
+ {
+ TText16* pT = WPtr();
+ TInt len = 0;
+ const TInt maxLen = MaxLength();
+
+ // iterate through aDes
+ TInt strLength = aDes.Length();
+ const TText16* start = aDes.Ptr();
+ const TText16* end = aDes.Ptr() + strLength;
+ TText16* next;
+ TUint currentChar;
+ TInt int16Index = 0;
+ TInt status = KErrNone;
+ FOREVER
+ {
+ status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+ __ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+ if (status == KErrNotFound)
+ break;
+ int16Index = (next - start);
+ TCharUC c(currentChar);
+ if (TChar::IsSupplementary(c))
+ {
+ len += 2;
+ __ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+ pT[len-2] = TChar::GetHighSurrogate(c);
+ pT[len-1] = TChar::GetLowSurrogate(c);
+ }
+ else
+ {
+ ++len;
+ __ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+ pT[len-1] = (TText16)c;
+ }
+ }
+ SetLength(len);
+ }
+
+EXPORT_C void TDes16::CopyCP2(const TDesC16 &aDes)
+/**
+The surrogate aware version of CopyCP().
+
+Copies text from the specified descriptor and capitalises it before putting
+it into this descriptor, replacing any existing data.
+
+The length of this descriptor is set to reflect the new data.
+
+Capitalisation is implemented as appropriate to the current locale.
+
+@param aDes A 16-bit non-modifiable descriptor.
+
+@panic USER 11 if the length of aDes is greater than the maximum length of
+ this target descriptor.
+
+@panic USER 217 if corrupt surrogate found in aDes or in the descriptor.
+
+@see TDes16::CopyCP()
+*/
+ {
+ TText16* pT = WPtr();
+ TInt len = 0;
+ const TInt maxLen = MaxLength();
+
+ // iterate through aDes
+ TInt strLength = aDes.Length();
+ const TText16* start = aDes.Ptr();
+ const TText16* end = aDes.Ptr() + strLength;
+ TText16* next;
+ TUint currentChar;
+ TInt int16Index = 0;
+ TInt status = KErrNone;
+
+ // first character: title case
+ status = ::ProceedOneCharacter(start, end, next, currentChar);
+ __ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+ int16Index = (next - start);
+ TChar c(currentChar);
+ c.TitleCase();
+ if (TChar::IsSupplementary(c))
+ {
+ len += 2;
+ __ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+ pT[len-2] = TChar::GetHighSurrogate(c);
+ pT[len-1] = TChar::GetLowSurrogate(c);
+ }
+ else
+ {
+ ++len;
+ __ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+ pT[len-1] = (TText16)c;
+ }
+
+ // following characters: lower case
+ FOREVER
+ {
+ status = ::ProceedOneCharacter(start+int16Index, end, next, currentChar);
+ __ASSERT_ALWAYS(status != KErrCorruptSurrogateFound, Panic(ECorruptSurrogateFound));
+ if (status == KErrNotFound)
+ break;
+ int16Index = (next - start);
+ TCharLC c(currentChar);
+ if (TChar::IsSupplementary(c))
+ {
+ len += 2;
+ __ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+ pT[len-2] = TChar::GetHighSurrogate(c);
+ pT[len-1] = TChar::GetLowSurrogate(c);
+ }
+ else
+ {
+ ++len;
+ __ASSERT_ALWAYS(len<=maxLen, Panic(ETDes16Overflow));
+ pT[len-1] = (TText16)c;
+ }
+ }
+ SetLength(len);
+ }
+
+
#if !defined(__DES16_MACHINE_CODED__) | defined(__EABI_CTORS__)
EXPORT_C TPtrC16::TPtrC16()
: TDesC16(EPtrC,0),iPtr(0)