// UC_DES8.CPP
//
// Copyright (c) 1994-1999 Symbian Ltd.  All rights reserved.
//

#include "uc_std.h"

inline TUint8 *memCopy(TAny *aPtr,const TAny *aSrc,TInt aLength)
//
// Copy 8 bit values.
//
	{

	return(Mem::Copy(aPtr,aSrc,aLength));
	}

#pragma warning( disable : 4705 )	// statement has no effect

EXPORT_C TDesC8::TDesC8(const TUint8 *aString)
//
// Constructor for TPtrC8
//
	{

#if defined(__DESC_NO_BIT_FIELDS__)
	iLength=User::StringLength(aString)|(EPtrC<<KShiftDesType8);
#else
	iLength=User::StringLength(aString);
	iType=EPtrC;
#endif
	((SPtrC8 *)this)->ptr=aString;
	}

EXPORT_C TDesC8::TDesC8(const TUint8 *aBuf,TInt aLength)
//
// Constructor for TPtrC8
//
	{

	__ASSERT_ALWAYS(aLength>=0,Panic(ETDes8LengthNegative));
#if defined(__DESC_NO_BIT_FIELDS__)
	iLength=aLength|(EPtrC<<KShiftDesType8);
#else
	iLength=aLength;
	iType=EPtrC;
#endif
	((SPtrC8 *)this)->ptr=aBuf;
	}

EXPORT_C TDesC8::TDesC8(const TDesC8 &aDes)
//
// Constructor for TPtrC8
//
	{

#if defined(__DESC_NO_BIT_FIELDS__)
	iLength=aDes.Length()|(EPtrC<<KShiftDesType8);
#else
	iLength=aDes.Length();
	iType=EPtrC;
#endif
	((SPtrC8 *)this)->ptr=aDes.Ptr();
	}

EXPORT_C TDesC8::TDesC8(const TPtr8& aTPtr)
//
// Constructor for TPtr8
//
	{

#if defined(__DESC_NO_BIT_FIELDS__)
	iLength=aTPtr.Length()|(EPtr<<KShiftDesType8);
#else
	iLength=aTPtr.Length();
	iType=EPtr;
#endif
	((SPtr8 *)this)->maxLength=aTPtr.MaxLength();
	((SPtr8 *)this)->ptr=(TUint8*)aTPtr.Ptr();
	}

EXPORT_C TDesC8::TDesC8(TBufCBase8 *aLcb)
//
// Constructor for TBufC8.
//
	{

#if defined(__DESC_NO_BIT_FIELDS__)
	iLength=(TUint)aLcb|(EBufC<<KShiftDesType8);
#else
	iLength=(TUint)aLcb;
	iType=EBufC;
#endif
	}

EXPORT_C TDesC8::TDesC8(TUint8 *aBuf,TInt aLength,TInt aMaxLength)
//
// Constructor for TPtr8.
//
	{

	__ASSERT_ALWAYS(aMaxLength>=0,Panic(ETDes8MaxLengthNegative));
	__ASSERT_ALWAYS(aLength>=0 && aLength<=aMaxLength,Panic(ETDes8LengthOutOfRange));
#if defined(__DESC_NO_BIT_FIELDS__)
	iLength=aLength|(EPtr<<KShiftDesType8);
#else
	iLength=aLength;
	iType=EPtr;
#endif
	((SPtr8 *)this)->maxLength=aMaxLength;
	((SPtr8 *)this)->ptr=aBuf;
	}

EXPORT_C TDesC8::TDesC8(TBufCBase8 &aLcb,TInt aMaxLength)
//
// Constructor for TBufCBase8.
//
	{

	Set(aLcb,aMaxLength);
	}

#ifndef __DES8_MACHINE_CODED__
EXPORT_C TDesC8::TDesC8(TInt aLength,TInt aMaxLength)
//
// Constructor for TBuf8.
//
	{

	__ASSERT_ALWAYS(aMaxLength>=0,Panic(ETDes8MaxLengthNegative));
	__ASSERT_ALWAYS(aLength>=0 && aLength<=aMaxLength,Panic(ETDes8LengthOutOfRange));
#if defined(__DESC_NO_BIT_FIELDS__)
	iLength=aLength|(EBuf<<KShiftDesType8);
#else
	iLength=aLength;
	iType=EBuf;
#endif
	((SBuf8 *)this)->maxLength=aMaxLength;
	}
#endif
#pragma warning( default : 4705 )

EXPORT_C TInt TDesC8::Type() const
//
// Return the descriptor type
//
	{

#if defined(__DESC_NO_BIT_FIELDS__)
	return(iLength>>KShiftDesType8);
#else
	return(iType);
#endif
	}

EXPORT_C void TDesC8::DoSetLength(TInt aLength)
//
// Set the length of the descriptor.
//
	{

#if defined(__DESC_NO_BIT_FIELDS__)
	iLength=(iLength&(~KMaskDesLength8))|aLength;
#else
	iLength=aLength;
#endif
	if (Type()==EBufCPtr)
		((SBufCPtr8 *)this)->ptr->length=aLength; // Relies on iType==0 for an TBufC
	}

EXPORT_C void TDesC8::DoSetType(TInt aType)
//
// Set the type of the descriptor
//
	{

#if defined(__DESC_NO_BIT_FIELDS__)
	iLength=(iLength&KMaskDesLength8)|(aType<<KShiftDesType8);
#else
	iType=aType;
#endif
	}

EXPORT_C void TDesC8::Set(TBufCBase8 &aLcb,TInt aMaxLength)
//
// Set value for a TBufCBase8.
//
	{

	TInt len=aLcb.Length();
	__ASSERT_ALWAYS(len<=aMaxLength,Panic(ETDes8LengthOutOfRange));
#if defined(__DESC_NO_BIT_FIELDS__)
	iLength=len|(EBufCPtr<<KShiftDesType8);
#else
	iLength=len;
	iType=EBufCPtr;
#endif
	((SBufCPtr8 *)this)->maxLength=aMaxLength;
	((SBufCPtr8 *)this)->ptr=(SBufC8 *)(&aLcb);
	}

EXPORT_C void TDesC8::SetHBufC()
//
// Set up the members of TDesC8 for a HBufC8.
//
	{

#if defined(__DESC_NO_BIT_FIELDS__)
	iLength=(EBufC<<KShiftDesType8);
#else
	iLength=0;
	iType=EBufC;
#endif
	}

#ifndef __DES8_MACHINE_CODED__
EXPORT_C const TUint8 *TDesC8::Ptr() const
//
// Return a pointer to the buffer.
//
	{

	switch (Type())
		{
	case EBufC:
		return(&((SBufC8 *)this)->buf[0]);
	case EPtrC:
		return(((SPtrC8 *)this)->ptr);
	case EPtr:
		return(((SPtr8 *)this)->ptr);
	case EBuf:
		return(&((SBuf8 *)this)->buf[0]);
	case EBufCPtr:
		return(&((SBufCPtr8 *)this)->ptr->buf[0]);
		}
	Panic(ETDes8BadDescriptorType);
	return(NULL);
	}

EXPORT_C const TUint8 &TDesC8::AtC(TInt anIndex) const
//
// Return a reference to the character in the buffer.
//
	{

	__ASSERT_ALWAYS(anIndex>=0 && anIndex<Length(),Panic(ETDes8IndexOutOfRange));
	return(Ptr()[anIndex]);
	}

EXPORT_C TInt TDesC8::Compare(const TDesC8 &aDes) const
//
// Compare a descriptor to this descriptor.
//
	{

	return(Mem::Compare(Ptr(),Length(),aDes.Ptr(),aDes.Length()));
	}

EXPORT_C TInt TDesC8::CompareF(const TDesC8 &aDes) const
//
// Compare a descriptor to this descriptor folded.
//
	{

	return(Mem::CompareF(Ptr(),Length(),aDes.Ptr(),aDes.Length()));
	}

EXPORT_C TInt TDesC8::CompareC(const TDesC8 &aDes) const
//
// Compare a descriptor to this descriptor collated.
//
	{

	return(Mem::CompareC(Ptr(),Length(),aDes.Ptr(),aDes.Length()));
	}
#endif

EXPORT_C TInt TDesC8::Find(const TUint8 *pS,TInt aLenS) const
//
// Find the location of pS in pB.
//
	{

	if (!aLenS)
		return(0);
	__ASSERT_ALWAYS(aLenS>0,Panic(ETDes8LengthNegative));
	const TUint8 *pB=Ptr();
	TInt aLenB=Length();
	const TUint8 *pC=pB-1;			// using pre-increment addressing
	TInt i=aLenB-aLenS;
	if (i>=0)
		{
		const TUint8* pEndS=pS+aLenS-1;		// using pre-increment addressing
		const TUint8 *pEndB=pB+i;			// using pre-increment addressing
		TUint s=*pS;
		for (;;)
			{
			do
				{
				if (pC==pEndB)
					return KErrNotFound;
				} while (*++pC!=s);
			const TUint8 *p1=pC;
			const TUint8 *p2=pS;
			do
				{
				if (p2==pEndS)
					return (pC-pB);
				} while (*++p1==*++p2);
			}
		}
	return(KErrNotFound);
	}

EXPORT_C TInt TDesC8::Find(const TDesC8 &aDes) const
//
// Find a descriptor to this descriptor.
//
	{

	return(Find(aDes.Ptr(),aDes.Length()));
	}

EXPORT_C TInt TDesC8::FindF(const TUint8 *pS,TInt aLenS) const
//
// Find the location of pS in pB folded.
//
	{

	return(Exec::Find8(*this,pS,aLenS,EMatchFolded));
	}

EXPORT_C TInt TDesC8::FindF(const TDesC8 &aDes) const
//
// Find a descriptor to this descriptor folded.
//
	{

	return(FindF(aDes.Ptr(),aDes.Length()));
	}

EXPORT_C TInt TDesC8::FindC(const TUint8 *pS,TInt aLenS) const
//
// Find the location of pS in pB collated.
//
	{
	
	return(Exec::Find8(*this,pS,aLenS,EMatchCollated));
	}

EXPORT_C TInt TDesC8::FindC(const TDesC8 &aDes) const
//
// Find a descriptor to this descriptor collated.
//
	{

	return(FindC(aDes.Ptr(),aDes.Length()));
	}

#ifndef __DES8_MACHINE_CODED__
EXPORT_C TInt TDesC8::Locate(TChar aChar) const
//
// Locate character aChar in the descriptor.
//
	{

	const TUint8 *pBuf=Ptr();
	const TUint8 *pB=pBuf-1;
	const TUint8 *pE=pB+Length();
	do
		{
		if (pB==pE)
			return KErrNotFound;
		} while (*++pB!=aChar);
	return pB-pBuf;
	}
#endif

EXPORT_C TInt TDesC8::LocateF(TChar aChar) const
//
// Locate character aChar in the descriptor folded.
//
	{

	return(Exec::LocateF8(*this,aChar));
	}

#ifndef __DES8_MACHINE_CODED__
EXPORT_C TInt TDesC8::LocateReverse(TChar aChar) const
//
// Locate character aChar in the descriptor in reverse.
//
	{

	TInt len=Length();
	if (len==0)
		return(KErrNotFound);
	const TUint8 *pB=Ptr();
	const TUint8 *pE=pB+len-1;
	while (pE>=pB)
		{
		if (*pE==aChar)
			break;
		pE--;
		}
	return(pE<pB ? KErrNotFound : pE-pB);
	}
#endif

EXPORT_C TInt TDesC8::LocateReverseF(TChar aChar) const
//
// Locate character aChar in the descriptor in reverse folded.
//
	{

	TInt len=Length();
	if (len==0)
		return(KErrNotFound);
	const TUint8 *pB=Ptr();
	const TUint8 *pE=pB+len-1;
	aChar.Fold();
	while (pE>=pB)
		{
		TCharF c(*pE);
		if (c==aChar)
			break;
		pE--;
		}
	return(pE<pB ? KErrNotFound : pE-pB);
	}

EXPORT_C HBufC8 *TDesC8::Alloc() const
//
// Allocate a HBufC and then copy this descriptor into it.
//
	{

	HBufC8 *pH=HBufC8::New(Length());
	if (pH)
		*pH=(*this);
	return(pH);
	}

EXPORT_C HBufC8 *TDesC8::AllocL() const
//
// Allocate a HBufC and then copy this descriptor into it.
//
	{

	HBufC8 *pH=HBufC8::NewL(Length());
	*pH=(*this);
	return(pH);
	}

EXPORT_C HBufC8 *TDesC8::AllocLC() const
//
// Allocate a HBufC and then copy this descriptor into it.
//
	{

	HBufC8 *pH=HBufC8::NewLC(Length());
	*pH=(*this);
	return(pH);
	}

#ifndef __DES8_MACHINE_CODED__
EXPORT_C TPtrC8 TDesC8::Left(TInt aLength) const
//
// Extract the left portion of the descriptor.
//
	{

	__ASSERT_ALWAYS(aLength>=0 && aLength<=Length(),Panic(ETDes8PosOutOfRange));
	return(TPtrC8(Ptr(),aLength));
	}

EXPORT_C TPtrC8 TDesC8::Right(TInt aLength) const
//
// Extract the right portion of the descriptor.
//
	{

	TInt len=Length();
	__ASSERT_ALWAYS(aLength>=0 && aLength<=len,Panic(ETDes8PosOutOfRange));
    return(TPtrC8(Ptr()+len-aLength,aLength));
	}

EXPORT_C TPtrC8 TDesC8::Mid(TInt aPos) const
//
// Extract the middle portion of the descriptor.
//
	{

	TInt len=Length();
	__ASSERT_ALWAYS(aPos>=0 && aPos<=len,Panic(ETDes8PosOutOfRange));
    return(TPtrC8(Ptr()+aPos,len-aPos));
	}

EXPORT_C TPtrC8 TDesC8::Mid(TInt aPos,TInt aLength) const
//
// Extract the middle portion of the descriptor.
//
	{

	__ASSERT_ALWAYS(aPos>=0 && (aPos+aLength)<=Length(),Panic(ETDes8PosOutOfRange));
    return(TPtrC8(Ptr()+aPos,aLength));
	}

EXPORT_C TBufCBase8::TBufCBase8()
//
// Constructor
//
	: TDesC8((TBufCBase8 *)NULL)
	{}

EXPORT_C TBufCBase8::TBufCBase8(const TUint8 *aString,TInt aMaxLength)
//
// Constructor
//
	: TDesC8((TBufCBase8 *)User::StringLength(aString))
	{

	TInt len=Length();
	__ASSERT_ALWAYS(len<=aMaxLength,Panic(ETDes8LengthOutOfRange));
	memCopy(WPtr(),aString,len);
	}

EXPORT_C TBufCBase8::TBufCBase8(const TDesC8 &aDes,TInt aMaxLength)
//
// Constructor
//
	: TDesC8((TBufCBase8 *)aDes.Length())
	{

	TInt len=Length();
	__ASSERT_ALWAYS(len<=aMaxLength,Panic(ETDes8LengthOutOfRange));
	memCopy(WPtr(),aDes.Ptr(),len);
	}

EXPORT_C void TBufCBase8::Copy(const TUint8 *aString,TInt aMaxLength)
//
// Copy from a string.
//
	{

	TInt len=User::StringLength(aString);
	__ASSERT_ALWAYS(len<=aMaxLength,Panic(ETDes8Overflow));
	memCopy(WPtr(),aString,len);
	DoSetLength(len);
	}

EXPORT_C void TBufCBase8::Copy(const TDesC8 &aDes,TInt aMaxLength)
//
// Copy from a descriptor.
//
	{

	TInt len=aDes.Length();
	__ASSERT_ALWAYS(len<=aMaxLength,Panic(ETDes8Overflow));
	memCopy(WPtr(),aDes.Ptr(),len);
	DoSetLength(len);
	}

EXPORT_C void TBufCBase8::Copy(const TBufCBase8 &aLcb,TInt aMaxLength)
//
// Copy from another TBufC8.
//
	{

	TInt len=aLcb.Length();
	__ASSERT_ALWAYS(len<=aMaxLength,Panic(ETDes8Overflow));
	memCopy(WPtr(),aLcb.Ptr(),len);
	DoSetLength(len);
	}

EXPORT_C TPtr8 TBufCBase8::DoDes(TInt aMaxLength)
//
// Convert a TBufC8 to TPtr8.
//
	{

	return(TPtr8(*this,aMaxLength));
	}
#endif

EXPORT_C HBufC8 *HBufC8::New(TInt aMaxLength)
//
// Create a new HBufC8 with maximum size aMaxLength.
//
	{

	__ASSERT_ALWAYS(aMaxLength>=0,Panic(ETDes8MaxLengthNegative));
	HBufC8 *pH=(HBufC8 *)User::Alloc((aMaxLength*sizeof(TUint8))+sizeof(TDesC8));
	if (pH)
		pH->SetHBufC();
	return(pH);
	}

EXPORT_C HBufC8 *HBufC8::NewL(TInt aMaxLength)
//
// Create a new HBufC8 with maximum size aMaxLength.
//
	{

	__ASSERT_ALWAYS(aMaxLength>=0,Panic(ETDes8MaxLengthNegative));
	HBufC8 *pH=(HBufC8 *)User::AllocL((aMaxLength*sizeof(TUint8))+sizeof(TDesC8));
	pH->SetHBufC();
	return(pH);
	}

EXPORT_C HBufC8 *HBufC8::NewLC(TInt aMaxLength)
//
// Create a new HBufC8 with maximum size aMaxLength.
//
	{

	__ASSERT_ALWAYS(aMaxLength>=0,Panic(ETDes8MaxLengthNegative));
	HBufC8 *pH=(HBufC8 *)User::AllocLC((aMaxLength*sizeof(TUint8))+sizeof(TDesC8));
	pH->SetHBufC();
	return(pH);
	}

EXPORT_C HBufC8 *HBufC8::NewMax(TInt aMaxLength)
//
// Create a new HBufC8 with maximum size aMaxLength.
//
	{

	HBufC8 *pH=New(aMaxLength);
	if (pH)
		pH->Des().SetLength(aMaxLength);
	return(pH);
	}

EXPORT_C HBufC8 *HBufC8::NewMaxL(TInt aMaxLength)
//
// Create a new HBufC8 with maximum size aMaxLength.
//
	{

	HBufC8 *pH=NewL(aMaxLength);
	pH->Des().SetLength(aMaxLength);
	return(pH);
	}

EXPORT_C HBufC8 *HBufC8::NewMaxLC(TInt aMaxLength)
//
// Create a new HBufC8 with maximum size aMaxLength.
//
	{

	HBufC8 *pH=NewLC(aMaxLength);
	pH->Des().SetLength(aMaxLength);
	return(pH);
	}

EXPORT_C HBufC8 &HBufC8::operator=(const TUint8 *aString)
//
// Assignment
//
	{

	Copy(aString,(User::AllocLen(this)-sizeof(TDesC8))/sizeof(TUint8));
	return(*this);
	}

EXPORT_C HBufC8 &HBufC8::operator=(const TDesC8 &aDes)
//
// Assignment
//
	{

	Copy(aDes,(User::AllocLen(this)-sizeof(TDesC8))/sizeof(TUint8));
	return(*this);
	}

EXPORT_C HBufC8 &HBufC8::operator=(const HBufC8 &aLcb)
//
// Assignment
//
	{

	Copy(aLcb,(User::AllocLen(this)-sizeof(TDesC8))/sizeof(TUint8));
	return(*this);
	}

EXPORT_C HBufC8 *HBufC8::ReAlloc(TInt aMaxLength)
//
// Re-Allocate.
//
	{

	__ASSERT_ALWAYS(aMaxLength>=0,Panic(ETDes8MaxLengthNegative));
	__ASSERT_ALWAYS(Length()<=aMaxLength,Panic(ETDes8ReAllocTooSmall));
	return((HBufC8 *)User::ReAlloc(this,(aMaxLength*sizeof(TUint8))+sizeof(TDesC8)));
	}

EXPORT_C HBufC8 *HBufC8::ReAllocL(TInt aMaxLength)
//
// Re-Allocate.
//
	{

	__ASSERT_ALWAYS(aMaxLength>=0,Panic(ETDes8MaxLengthNegative));
	__ASSERT_ALWAYS(Length()<=aMaxLength,Panic(ETDes8ReAllocTooSmall));
	return((HBufC8 *)User::ReAllocL(this,(aMaxLength*sizeof(TUint8))+sizeof(TDesC8)));
	}

EXPORT_C TPtr8 HBufC8::Des()
//
// Create a writeable descriptor.
//
	{

	return(TPtr8(*this,(User::AllocLen(this)-sizeof(TDesC8))/sizeof(TUint8)));
	}

EXPORT_C TDes8 &TDes8::operator=(const TUint8 *aString)
//
// Assign a string
//
    {

    Copy(aString);
    return(*this);
    }

EXPORT_C TDes8 &TDes8::operator=(const TDesC8 &aDes)
//
// Assign a constant descriptor.
//
    {

    Copy(aDes);
    return(*this);
    }

EXPORT_C TDes8 &TDes8::operator=(const TDes8 &aDes)
//
// Assign a descriptor.
//
    {

    Copy(aDes);
    return(*this);
    }

#ifndef __DES8_MACHINE_CODED__
EXPORT_C void TDes8::SetLength(TInt aLength)
//
// Set the length of the descriptor, checking the length is O.K.
//
	{

	__ASSERT_ALWAYS(aLength>=0 && aLength<=MaxLength(),Panic(ETDes8Overflow));
	DoSetLength(aLength);
  	}

EXPORT_C void TDes8::SetMax()
//
// Set the length to MaxLength().
//
	{

	SetLength(iMaxLength);
	}

EXPORT_C void TDes8::Copy(const TUint8 *aString)
//
// Copy a string to this descriptor.
//
	{

	TInt len=User::StringLength(aString);
	SetLength(len);
    memCopy(WPtr(),aString,len);
	}

EXPORT_C void TDes8::Copy(const TUint8 *aBuf,TInt aLength)
//
// Copy the aLength characters to the descriptor.
//
	{

	SetLength(aLength);
    memCopy(WPtr(),aBuf,aLength);
	}

EXPORT_C void TDes8::Copy(const TDesC8 &aDes)
//
// Copy a descriptor to this descriptor.
//
	{

	TInt len=aDes.Length();
	SetLength(len);
    memCopy(WPtr(),aDes.Ptr(),len);
	}
#endif

EXPORT_C void TDes8::Copy(const TDesC16 &aDes)
//
// Copy a descriptor 16 to this descriptor.
//
	{

	TInt len=aDes.Length();
	SetLength(len);
	const TUint16 *pS=aDes.Ptr();
	const TUint16 *pE=pS+len;
	TUint8 *pT=WPtr();
	while (pS<pE)
		{
		TUint c=(*pS++);
		if (c>=0x100)
			c=1;
		*pT++=(TUint8)c;
		}
	}

#ifndef __DES8_MACHINE_CODED__
EXPORT_C void TDes8::Append(TChar aChar)
//
// Add a character at the end of the string.
//
	{

	TInt len=Length();
	TUint8 *pB=WPtr()+len;
	SetLength(len+1);
	*pB++=(TUint8)aChar;
	}

EXPORT_C void TDes8::Append(const TUint8 *aBuf,TInt aLength)
//
// Append aLength from aBuf characters to the descriptor.
//
	{

	__ASSERT_ALWAYS(aLength>=0,Panic(ETDes8LengthNegative));
	TInt len=Length();
	SetLength(len+aLength);
    memCopy(WPtr()+len,aBuf,aLength);
	}

EXPORT_C void TDes8::Append(const TDesC8 &aDes)
//
// Append a descriptor to this descriptor.
//
	{

	TInt len=Length();
    TInt n=aDes.Length();
	SetLength(len+n);
    memCopy(WPtr()+len,aDes.Ptr(),n);
	}
#endif

EXPORT_C void TDes8::Append(const TDesC16 &aDes)
//
// Append a descriptor to this descriptor.
//
	{

	TInt len=Length();
	TInt n=aDes.Length();
	const TUint16* pS=aDes.Ptr();
	const TUint16* pE=pS+n;
	TUint8 *pT=WPtr()+len;
	SetLength(len+n);
	while (pS<pE)
		{
		TUint c=(*pS++);
		if (c>=0x100)
			c=1;
		*pT++=(TUint8)c;
		}
	}

EXPORT_C void TDes8::Swap(TDes8 &aDes)
//
// Swap the contents of the two descriptors.
//
	{

	TInt l=Length();
	TInt r=aDes.Length();
	aDes.SetLength(l);
	SetLength(r);
	TInt s=Min(l,r);
	l-=s;
	r-=s;
	TUint8 *pL=WPtr();
	TUint8 *pR=aDes.WPtr();
	while (s--)
		{
		TChar a=(*pL);
		*pL++=(*pR);
		*pR++=(TUint8)a;
		}
	while (l--)
		*pR++=(*pL++);
	while (r--)
		*pL++=(*pR++);
	}

#ifndef __DES8_MACHINE_CODED__
EXPORT_C void TDes8::Fill(TChar aChar)
//
// Fill the descriptor with aChar.
//
	{

    Mem::Fill(WPtr(),Length(),aChar);
	}
#endif

EXPORT_C void TDes8::Fill(TChar aChar,TInt aLength)
//
// Fill the descriptor with aChar, for length aLength, checking for length.
//
	{

	SetLength(aLength);
    Mem::Fill(WPtr(),aLength,aChar);
	}

EXPORT_C void TDes8::AppendFill(TChar aChar,TInt aLength)
//
// Append fill the descriptor with aChar, for length aLength, checking for length.
//
	{

	TInt len=Length();
	SetLength(len+aLength);
    Mem::Fill(WPtr()+len,aLength,aChar);
	}

#ifndef __DES8_MACHINE_CODED__
EXPORT_C void TDes8::ZeroTerminate()
//
// Zero terminate at Length().
//
	{

	TInt len=Length();
	__ASSERT_ALWAYS(len<MaxLength(),Panic(ETDes8Overflow));
	WPtr()[len]=0;
	}

EXPORT_C void TDes8::Zero()
//
// Zero the buffer.
//
	{

	SetLength(0);
	}

EXPORT_C const TUint8 *TDes8::PtrZ()
//
// Return a pointer to a 0 terminated string.
//
	{

	ZeroTerminate();
	return(Ptr());
	}

EXPORT_C void TDes8::FillZ()
//
// Fill the descriptor with 0.
//
	{

    Mem::FillZ(WPtr(),Length());
	}
#endif

EXPORT_C void TDes8::FillZ(TInt aLength)
//
// Fill the descriptor with 0, for length aLength, checking for length.
//
	{

	SetLength(aLength);
    Mem::FillZ(WPtr(),aLength);
	}

EXPORT_C void TDes8::Fold()
//
// Convert the descriptor to folded.
//
	{

	TUint8 *pB=WPtr();
	TInt len=Length();
	while (len--)
		{
		TCharF c(*pB);
		*pB++=(TUint8)c;
		}
	}

EXPORT_C void TDes8::Collate()
//
// Convert the descriptor to collated.
//
	{

	TUint8 *pB=WPtr();
	TInt len=Length();
	while (len--)
		{
		TChar c=User::Collate(*pB);
		*pB++=(TUint8)c;
		}
	}

EXPORT_C void TDes8::LowerCase()
//
// Convert the descriptor to lower case.
//
	{

	TUint8 *pB=WPtr();
	TInt len=Length();
	while (len--)
		{
		TCharLC c(*pB);
		*pB++=(TUint8)c;
		}
	}

EXPORT_C void TDes8::UpperCase()
//
// Convert the descriptor to upper case.
//
	{

	TUint8 *pB=WPtr();
	TInt len=Length();
	while (len--)
		{
		TCharUC c(*pB);
		*pB++=(TUint8)c;
		}
	}

EXPORT_C void TDes8::Capitalize()
//
// Convert the descriptor to capitalised.
//
	{

	TUint8 *pB=WPtr();
	TInt len=Length();
	if (len--)
		{
		TChar c(*pB);
#ifdef _UNICODE
		c.TitleCase();
#else
		c.UpperCase();
#endif
		*pB++=(TUint8)c;
		while (len--)
			{
			TCharLC c=(*pB);
			c.LowerCase();
			*pB++=(TUint8)c;
			}
		}
	}

EXPORT_C void TDes8::CopyF(const TDesC8 &aDes)
//
// Copy a descriptor to this descriptor folded.
//
	{

	TInt len=aDes.Length();
	SetLength(len);
	const TUint8 *pS=aDes.Ptr();
	TUint8 *pT=WPtr();
	while (len--)
		{
		TCharF c(*pS++);
		*pT++=(TUint8)c;
		}
	}

EXPORT_C void TDes8::CopyC(const TDesC8 &aDes)
//
// Copy a descriptor to this descriptor collated.
//
	{

	TInt len=aDes.Length();
	SetLength(len);
	const TUint8 *pS=aDes.Ptr();
	TUint8 *pT=WPtr();
	while (len--)
		{
		TChar c=User::Collate(*pS++);
		*pT++=(TUint8)c;
		}
	}

EXPORT_C void TDes8::CopyLC(const TDesC8 &aDes)
//
// Copy a descriptor to this descriptor lower case.
//
	{

	TInt len=aDes.Length();
	SetLength(len);
	const TUint8 *pS=aDes.Ptr();
	TUint8 *pT=WPtr();
	while (len--)
		{
		TCharLC c(*pS++);
		*pT++=(TUint8)c;
		}
	}

EXPORT_C void TDes8::CopyUC(const TDesC8 &aDes)
//
// Copy a descriptor to this descriptor upper case.
//
	{

	TInt len=aDes.Length();
	SetLength(len);
	const TUint8 *pS=aDes.Ptr();
	TUint8 *pT=WPtr();
	while (len--)
		{
		TCharUC c(*pS++);
		*pT++=(TUint8)c;
		}
	}

EXPORT_C void TDes8::CopyCP(const TDesC8 &aDes)
//
// Copy a descriptor to this descriptor capitalised.
//
	{

	TInt len=aDes.Length();
	SetLength(len);
	const TUint8 *pS=aDes.Ptr();
	TUint8 *pT=WPtr();
	if (len--)
		{
		TChar c(*pS++);
#ifdef _UNICODE
		c.TitleCase();
#else
		c.UpperCase();
#endif
		*pT++=(TUint8)c;
		while (len--)
			{
			TCharLC c=(*pS++);
			*pT++=(TUint8)c;
			}
		}
	}

EXPORT_C void TDes8::Repeat(const TUint8 *aBuf,TInt aLength)
//
// Repeat a aBuf as many times as possible in the descriptor.
//
	{

	__ASSERT_ALWAYS(aLength>=0,Panic(ETDes8LengthNegative));
	TUint8 *pB=WPtr();
	TInt len=Length();
	if (len && aLength)
		{
		while (len)
			{
			TInt i=Min(len,aLength);
			pB=memCopy(pB,aBuf,i);
			len-=i;
			}
		}
	}

EXPORT_C void TDes8::Repeat(const TDesC8 &aDes)
//
// Repeat a aDes as many times as possible in the descriptor.
//
	{

	Repeat(aDes.Ptr(),aDes.Length());
	}

EXPORT_C void TDes8::Trim()
//
// Trim spaces from both ends of a descriptor.
//
	{

	TrimLeft();
	TrimRight();
	}

EXPORT_C void TDes8::TrimAll()
//
// Trim spaces from both ends of a descriptor and convert multiple spaces
// to singles spaces within the descriptor.
//
	{

	TrimLeft();
	TrimRight();
	TUint8 *pBuf=(TUint8 *)Ptr();
	TUint8 *pSrc=pBuf;
	TUint8 *pDst=pBuf;
	TInt len=Length();
	TInt spaces=0;
	while (len--)
		{
		TChar c=*pSrc;
		if (c.IsSpace())
			{
			if (spaces++==0)
				{
				if (pDst!=pSrc)
					*pDst=*pSrc;
				pDst++;
				}
			}
		else
			{
			spaces=0;
			if (pDst!=pSrc)
				*pDst=*pSrc;
			pDst++;
			}
		pSrc++;
		}
	Delete(pDst-pBuf, pSrc-pDst);
	}

EXPORT_C void TDes8::TrimLeft()
//
// Trim spaces from the left end of the descriptor.
//
	{

	const TUint8 *pBuf=Ptr();
	const TUint8 *pB=pBuf;
	TInt len=Length();
	while (len--)
		{
		TChar c=(*pB);
		if (!c.IsSpace())
			break;
		pB++;
		}
	Delete(0,pB-pBuf);
	}

EXPORT_C void TDes8::TrimRight()
//
// Trim spaces from the rigth end of the descriptor.
//
	{

	TInt len=Length();
	if (len==0)
		return;
	const TUint8 *pB=Ptr()+len-1;
	TInt s=len;
	while (s)
		{
		TChar c=(*pB--);
		if (!c.IsSpace())
			break;
		s--;
		}
	Delete(s,len-s);
	}

EXPORT_C void TDes8::Insert(TInt aPos,const TDesC8 &aDes)
//
// Insert a descriptor into this descriptor.
//
	{

	TInt len=Length();
	__ASSERT_ALWAYS(aPos>=0 && aPos<=len,Panic(ETDes8PosOutOfRange));
	TInt s=aDes.Length();
	__ASSERT_ALWAYS((len+s)<=MaxLength(),Panic(ETDes8Overflow));
	TUint8 *pB=WPtr();
	memCopy(pB+aPos+s,pB+aPos,len-aPos);
	memCopy(pB+aPos,aDes.Ptr(),aDes.Length());
	SetLength(len+s);
	}

EXPORT_C void TDes8::Delete(TInt aPos,TInt aLength)
//
// Delete a portion of the descriptor.
//
	{

	TInt len=Length();
	__ASSERT_ALWAYS(aPos>=0 && aPos<=len,Panic(ETDes8PosOutOfRange));
	TInt d=Min(len-aPos,aLength);
	TUint8 *pB=WPtr();
	memCopy(pB+aPos,pB+aPos+d,len-aPos-d);
	SetLength(len-d);
	}

EXPORT_C void TDes8::Replace(TInt aPos,TInt aLength,const TDesC8 &aDes)
//
// Replace part of this descriptor.
//
	{

	TInt len=Length();
	__ASSERT_ALWAYS(aPos>=0 && aPos<=len,Panic(ETDes8PosOutOfRange));
	__ASSERT_ALWAYS(aLength>=0 && aPos+aLength<=len,Panic(ETDes8LengthOutOfRange));
	TInt s=aDes.Length();
	TInt maxlen=MaxLength();
	__ASSERT_ALWAYS(s>=0 && s<=maxlen,Panic(ETDes8RemoteLengthOutOfRange));
	__ASSERT_ALWAYS((len+s-aLength)<=maxlen,Panic(ETDes8Overflow));
	TUint8 *pB=WPtr();
	memCopy(pB+aPos+s,pB+aPos+aLength,len-aPos-aLength);
	memCopy(pB+aPos,aDes.Ptr(),s);
	SetLength(len+s-aLength);
	}

EXPORT_C void TDes8::Justify(const TDesC8 &aDes,TInt aWidth,TAlign anAlignment,TChar aFill)
//
// Justify a descriptor in the descriptor.
//
	{

    Zero();
    AppendJustify(aDes.Ptr(),aDes.Length(),aWidth,anAlignment,aFill);
    }

EXPORT_C void TDes8::AppendJustify(const TDesC8 &aDes,TInt aWidth,TAlign anAlignment,TChar aFill)
//
// Append a justified descriptor to the descriptor.
//
	{

    AppendJustify(aDes.Ptr(),aDes.Length(),aWidth,anAlignment,aFill);
    } 

EXPORT_C void TDes8::AppendJustify(const TDesC8 &aDes,TInt aLength,TInt aWidth,TAlign anAlignment,TChar aFill)
//
// Append a justified buffer to the descriptor.
//
	{

    AppendJustify(aDes.Ptr(),aLength,aWidth,anAlignment,aFill);
    } 

EXPORT_C void TDes8::AppendJustify(const TUint8 *aString,TInt aWidth,TAlign anAlignment,TChar aFill)
//
// Append a justified string to the descriptor.
//
	{

    AppendJustify(aString,User::StringLength(aString),aWidth,anAlignment,aFill);
    } 

EXPORT_C void TDes8::AppendJustify(const TUint8 *aString,TInt aLength,TInt aWidth,TAlign anAlignment,TChar aFill)
//
// Justify a buffer into the descriptor, in a field aWidth wide.
//
	{

	__ASSERT_ALWAYS(aLength>=0,Panic(ETDes8LengthNegative));
	if (aWidth==KDefaultJustifyWidth)
		aWidth=aLength;
	if (aLength>aWidth)
		aLength=aWidth;
	TInt offset=Length();
	AppendFill(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 TDes8::Num(TInt aVal)
//
// Convert a signed int to the descriptor.
//
	{

    Zero();
    AppendNum(aVal);
    }

EXPORT_C void TDes8::Num(TUint aVal,TRadix aRadix)
//
// Convert an unsigned int to the descriptor.
//
	{

	Zero();
	AppendNum(aVal,aRadix);
	}

EXPORT_C void TDes8::NumUC(TUint aVal,TRadix aRadix)
//
// Convert an unsigned int to the descriptor converting to upper case.
//
	{

    Zero();
    AppendNumUC(aVal,aRadix);
    }

EXPORT_C void TDes8::NumFixedWidth(TUint aVal,TRadix aRadix,TInt aWidth)
//
// Convert an unsigned int to the descriptor.
//
	{

	Zero();
	AppendNumFixedWidth(aVal,aRadix,aWidth);
	}

EXPORT_C void TDes8::NumFixedWidthUC(TUint aVal,TRadix aRadix,TInt aWidth)
//
// Convert an unsigned int to the descriptor converting to upper case.
//
	{

    Zero();
    AppendNumFixedWidthUC(aVal,aRadix,aWidth);
    }

EXPORT_C void TDes8::Num(TInt64 aVal)
//
// Convert a TInt64 to the descriptor.
//
	{

	Zero();
	AppendNum(aVal);
	}

EXPORT_C void TDes8::Num(TInt64 aVal,TRadix aRadix)
//
// Convert a TInt64 to the descriptor, treat as unsigned.
//
	{

	Zero();
	AppendNum(aVal,aRadix);
	}

EXPORT_C void TDes8::NumUC(TInt64 aVal,TRadix aRadix)
//
// Convert a TInt64 to the descriptor, treat as unsigned.
//
	{

	Zero();
	AppendNumUC(aVal,aRadix);
	}

EXPORT_C void TDes8::AppendNum(TInt aVal)
//
// Convert a signed integer into the descriptor.
//
	{

	TUint v=aVal;
	if (aVal<0)
		{
		Append('-');
		v=(-aVal);
		}
	AppendNum(v,EDecimal);
	}

#if !defined(__DES_MACHINE_CODED__)
EXPORT_C void TDes8::AppendNum(TUint aVal,TRadix aRadix)
//
// Convert an unsigned integer into the descriptor.
//
	{

	if (aVal>=(TUint)aRadix)
		{
		AppendNum(aVal/aRadix,aRadix);
		aVal=(aVal%aRadix);
		}
	Append(aVal+(aVal<10 ? '0' : ('a'-10)));
	}

EXPORT_C void TDes8::AppendNumUC(TUint aVal,TRadix aRadix)
//
// Convert an unsigned integer into the descriptor in upper case.
//
	{

	if (aVal>=(TUint)aRadix)
		{
		AppendNumUC(aVal/aRadix,aRadix);
		aVal=(aVal%aRadix);
		}
	Append(aVal+(aVal<10 ? '0' : ('A'-10)));
	}

EXPORT_C void TDes8::AppendNumFixedWidth(TUint aVal,TRadix aRadix,TInt aWidth)
//
// Convert an unsigned integer into the descriptor.
// Append aWidth characters, adding leading zeros if necessary
//
	{

	TBuf8<32> buf;
	buf.Num(aVal,aRadix);
	if (buf.Length()>=aWidth)
		Append(buf.Left(aWidth));
	else
		{
		TInt i=aWidth-buf.Length();
		while(i--)
			Append(TChar('0'));
		Append(buf);
		}
	}

EXPORT_C void TDes8::AppendNumFixedWidthUC(TUint aVal,TRadix aRadix,TInt aWidth)
//
// Convert an unsigned integer into the descriptor in upper case.
// Append aWidth characters, adding leading zeros if necessary
//
	{

	TBuf8<32> buf;
	buf.NumUC(aVal,aRadix);
	if (buf.Length()>=aWidth)
		Append(buf.Left(aWidth));
	else
		{
		TInt i=aWidth-buf.Length();
		while(i--)
			Append(TChar('0'));
		Append(buf);
		}
	}
#endif

EXPORT_C void TDes8::AppendNum(TInt64 aVal)
//
// Convert a TInt64 into the descriptor.
//
	{

	if (aVal<0)
		{
		Append('-');
		aVal=-aVal;
		}
	AppendNum(aVal,EDecimal);
	}

EXPORT_C void TDes8::AppendNum(TInt64 aVal,TRadix aRadix)
//
// Convert a TInt64 into the descriptor, treat as unsigned.
//
	{

	if (aVal.High()==0)
		AppendNum(aVal.Low(),aRadix);
	else
		{
		TInt64 radix((TUint)aRadix);
		TInt64 shifted=aVal;
		shifted>>=1;
		shifted.Set(shifted.High()&0x7fffffffu,shifted.Low());
		AppendNum(shifted/(radix>>1),aRadix);
		if (aVal.High()&0x80000000u)
			{
			aVal+=TInt64(0x80000000u,0);
			if (aRadix==EDecimal)
				{
				if (aVal>=2)
					aVal-=2;
				 else
					aVal+=8;
				}
			}
		aVal=(aVal%radix);
		Append(aVal.Low()+(aVal.Low()<10 ? '0' : ('a'-10)));
		}
	}

EXPORT_C void TDes8::AppendNumUC(TInt64 aVal,TRadix aRadix)
//
// Convert a TInt64 into the descriptor, treat as unsigned.
//
	{

	if (aVal.High()==0)
		AppendNumUC(aVal.Low(),aRadix);
	else
		{
		TInt64 radix((TUint)aRadix);
		AppendNumUC(aVal/radix,aRadix);
		aVal=(aVal%radix);
		Append(aVal.Low()+(aVal.Low()<10 ? '0' : ('A'-10)));
		}
	}

EXPORT_C void TDes8::Format(TRefByValue<const TDesC8> aFmt,...)
//
// Convert arguments to the descriptor.
//
	{

    VA_LIST list;
    VA_START(list,aFmt);
    FormatList(aFmt,list);
    }

EXPORT_C void TDes8::FormatList(const TDesC8 &aFmt,VA_LIST aList)
//
// Convert arguments to the descriptor.
//
	{

	Zero();
	AppendFormatList(aFmt,aList);
	}

EXPORT_C void TDes8::AppendFormat(TRefByValue<const TDesC8> aFmt,TDes8Overflow *aOverflowHandler,...)
//
// Convert arguments to the descriptor.
//
	{

	VA_LIST list;
	VA_START(list, aOverflowHandler);
	AppendFormatList(aFmt,list,aOverflowHandler);
	}

EXPORT_C void TDes8::AppendFormat(TRefByValue<const TDesC8> aFmt,...)
//
// Convert arguments to the descriptor.
//
	{

    VA_LIST list;
    VA_START(list,aFmt);
    AppendFormatList(aFmt,list);
    }

#ifndef __DES8_MACHINE_CODED__
EXPORT_C TPtrC8::TPtrC8()
//
// Default constructor
//
	: TDesC8((const TText8 *)NULL,0)
	{}

EXPORT_C TPtrC8::TPtrC8(const TDesC8 &aDes)
//
// Constructor
//
	: TDesC8(aDes)
	{}

EXPORT_C TPtrC8::TPtrC8(const TPtrC8 &aDes)
//
// Copy constructor
//
	: TDesC8(aDes)
	{}

EXPORT_C TPtrC8::TPtrC8(const TUint8 *aString)
//
// Constructor
//
	: TDesC8(aString)
	{}

EXPORT_C TPtrC8::TPtrC8(const TUint8 *aBuf,TInt aLength)
//
// Constructor
//
	: TDesC8(aBuf,aLength)
	{}

EXPORT_C void TPtrC8::Set(const TUint8 *aBuf,TInt aLength)
//
// Copy constructor by another name.
//
	{

	__ASSERT_ALWAYS(aLength>=0,Panic(ETDes8Overflow));
	DoSetLength(aLength);
	iPtr=aBuf;
	}

EXPORT_C void TPtrC8::Set(const TDesC8 &aDes)
//
// Copy constructor by another name.
//
	{

	DoSetLength(aDes.Length());
	iPtr=aDes.Ptr();
	}

EXPORT_C TPtr8::TPtr8(TUint8 *aBuf,TInt aMaxLength)
//
// Constructor
//
	: TDes8(aBuf,0,aMaxLength)
	{}

EXPORT_C TPtr8::TPtr8(TUint8 *aBuf,TInt aLength,TInt aMaxLength)
//
// Constructor
//
	: TDes8(aBuf,aLength,aMaxLength)
	{}

EXPORT_C TPtr8::TPtr8(TBufCBase8 &aLcb,TInt aMaxLength)
//
// Constructor
//
	: TDes8(aLcb,aMaxLength)
	{}

EXPORT_C TPtr8::TPtr8(const TPtr8& aTPtr)
//
// Copy constructor
//
	: TDes8(aTPtr)
	{}

EXPORT_C void TPtr8::Set(TUint8 *aBuf,TInt aLength,TInt aMaxLength)
//
// Copy constructor by another name.
//
	{

	__ASSERT_ALWAYS(aMaxLength>=0,Panic(ETDes8MaxLengthNegative));
	__ASSERT_ALWAYS(aLength>=0 && aLength<=aMaxLength,Panic(ETDes8LengthOutOfRange));
	iPtr=aBuf;
	iMaxLength=aMaxLength;
	DoSetType(EPtr);
	DoSetLength(aLength);
	}

EXPORT_C void TPtr8::Set(TPtr8 &aPtr)
//
// Copy constructor by another name.
//
	{

	if (aPtr.Type()==EBufCPtr)
		TDesC8::Set(*((TBufCBase8 *)aPtr.iPtr),aPtr.MaxLength());
	else
		{
		iPtr=aPtr.WPtr();
		iMaxLength=aPtr.MaxLength();
		DoSetType(EPtr);
		DoSetLength(aPtr.Length());
		}
	}
#endif

EXPORT_C void TDesC8::__DbgTestInvariant() const
//
// Test that the class obeys its invariant.
//
    {

#if defined(_DEBUG)
	switch (Type())
		{
	case EBufC:
	case EPtrC:
	case EPtr:
	case EBuf:
	case EBufCPtr:
		break;
	default:
		User::Invariant();
		}
	if (Ptr()==NULL)
		User::Invariant();
#endif
    }

EXPORT_C void TPtrC8::__DbgTestInvariant() const
//
// Test that the class obeys its invariant.
//
    {

#if defined(_DEBUG)
	TDesC8::__DbgTestInvariant(); // Test base class
	if (iPtr==NULL || Type()!=EPtrC)
		User::Invariant();
#endif
	}

EXPORT_C void TDes8::__DbgTestInvariant() const
//
// Test that the class obeys its invariant.
//
    {

#if defined(_DEBUG)
	TDesC8::__DbgTestInvariant(); // Test base class
	if (Length()>MaxLength() || !(Type()==EPtr || Type()==EBufCPtr || Type()==EBuf))
		User::Invariant();
#endif
	}

EXPORT_C void HBufC8::__DbgTestInvariant() const
//
// Test that the class obeys its invariant.
//
    {

#if defined(_DEBUG)
	TDesC8::__DbgTestInvariant(); // Test base class
	if (Length()>(TInt)(User::AllocLen(this)-sizeof(TDesC8)) || Type()!=EBufCPtr)
		User::Invariant();
#endif
	}

EXPORT_C void TPtr8::__DbgTestInvariant() const
//
// Test that the class obeys its invariant.
//
    {

#if defined(_DEBUG)
	TDes8::__DbgTestInvariant(); // Test base class
	if (iPtr==NULL || !(Type()==EPtr || Type()==EBufCPtr))
		User::Invariant();
#endif
	}

#ifdef __DES8_MACHINE_CODED__
GLDEF_C void Des8PanicBadDesType()
	{
	Panic(ETDes8BadDescriptorType);
	}

GLDEF_C void Des8PanicLengthNegative()
	{
	Panic(ETDes8LengthNegative);
	}

GLDEF_C void Des8PanicMaxLengthNegative()
	{
	Panic(ETDes8MaxLengthNegative);
	}

GLDEF_C void Des8PanicLengthOutOfRange()
	{
	Panic(ETDes8LengthOutOfRange);
	}

GLDEF_C void Des8PanicDesOverflow()
	{
	Panic(ETDes8Overflow);
	}

GLDEF_C void Des8PanicDesIndexOutOfRange()
	{
	Panic(ETDes8IndexOutOfRange);
	}

GLDEF_C void Des8PanicPosOutOfRange()
	{
	Panic(ETDes8PosOutOfRange);
	}
#endif