--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/euser/us_func.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,2038 @@
+// Copyright (c) 1994-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "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:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32\euser\us_func.cpp
+//
+//
+
+#include "us_std.h"
+//#define __DEBUG_IMAGE__ 1
+#if defined(__DEBUG_IMAGE__) && defined (__EPOC32__)
+#include "e32svr.h"
+#define __IF_DEBUG(t) {RDebug debug;debug.t;}
+#else
+#define __IF_DEBUG(t)
+#endif
+#ifdef _UNICODE
+#include <collate.h>
+#include "CompareImp.h"
+#endif
+
+#include "us_data.h"
+
+typedef union
+ {
+ TAny *tany;
+ TText8 *ttext8;
+ TText16 *ttext16;
+ TDesC8 *tdesc8;
+ TDesC16 *tdesc16;
+ TInt8 *tint8;
+ TInt16 *tint16;
+ TInt32 *tint32;
+ TInt64 *tint64;
+ TInt *tint;
+ TUint8 *tuint8;
+ TUint16 *tuint16;
+ TUint32 *tuint32;
+ TUint *tuint;
+ } UPTR;
+
+const TUint crcTab[256] =
+ {
+ 0x0000,0x1021,0x2042,0x3063,0x4084,0x50a5,0x60c6,0x70e7,0x8108,0x9129,0xa14a,
+ 0xb16b,0xc18c,0xd1ad,0xe1ce,0xf1ef,0x1231,0x0210,0x3273,0x2252,0x52b5,0x4294,
+ 0x72f7,0x62d6,0x9339,0x8318,0xb37b,0xa35a,0xd3bd,0xc39c,0xf3ff,0xe3de,0x2462,
+ 0x3443,0x0420,0x1401,0x64e6,0x74c7,0x44a4,0x5485,0xa56a,0xb54b,0x8528,0x9509,
+ 0xe5ee,0xf5cf,0xc5ac,0xd58d,0x3653,0x2672,0x1611,0x0630,0x76d7,0x66f6,0x5695,
+ 0x46b4,0xb75b,0xa77a,0x9719,0x8738,0xf7df,0xe7fe,0xd79d,0xc7bc,0x48c4,0x58e5,
+ 0x6886,0x78a7,0x0840,0x1861,0x2802,0x3823,0xc9cc,0xd9ed,0xe98e,0xf9af,0x8948,
+ 0x9969,0xa90a,0xb92b,0x5af5,0x4ad4,0x7ab7,0x6a96,0x1a71,0x0a50,0x3a33,0x2a12,
+ 0xdbfd,0xcbdc,0xfbbf,0xeb9e,0x9b79,0x8b58,0xbb3b,0xab1a,0x6ca6,0x7c87,0x4ce4,
+ 0x5cc5,0x2c22,0x3c03,0x0c60,0x1c41,0xedae,0xfd8f,0xcdec,0xddcd,0xad2a,0xbd0b,
+ 0x8d68,0x9d49,0x7e97,0x6eb6,0x5ed5,0x4ef4,0x3e13,0x2e32,0x1e51,0x0e70,0xff9f,
+ 0xefbe,0xdfdd,0xcffc,0xbf1b,0xaf3a,0x9f59,0x8f78,0x9188,0x81a9,0xb1ca,0xa1eb,
+ 0xd10c,0xc12d,0xf14e,0xe16f,0x1080,0x00a1,0x30c2,0x20e3,0x5004,0x4025,0x7046,
+ 0x6067,0x83b9,0x9398,0xa3fb,0xb3da,0xc33d,0xd31c,0xe37f,0xf35e,0x02b1,0x1290,
+ 0x22f3,0x32d2,0x4235,0x5214,0x6277,0x7256,0xb5ea,0xa5cb,0x95a8,0x8589,0xf56e,
+ 0xe54f,0xd52c,0xc50d,0x34e2,0x24c3,0x14a0,0x0481,0x7466,0x6447,0x5424,0x4405,
+ 0xa7db,0xb7fa,0x8799,0x97b8,0xe75f,0xf77e,0xc71d,0xd73c,0x26d3,0x36f2,0x0691,
+ 0x16b0,0x6657,0x7676,0x4615,0x5634,0xd94c,0xc96d,0xf90e,0xe92f,0x99c8,0x89e9,
+ 0xb98a,0xa9ab,0x5844,0x4865,0x7806,0x6827,0x18c0,0x08e1,0x3882,0x28a3,0xcb7d,
+ 0xdb5c,0xeb3f,0xfb1e,0x8bf9,0x9bd8,0xabbb,0xbb9a,0x4a75,0x5a54,0x6a37,0x7a16,
+ 0x0af1,0x1ad0,0x2ab3,0x3a92,0xfd2e,0xed0f,0xdd6c,0xcd4d,0xbdaa,0xad8b,0x9de8,
+ 0x8dc9,0x7c26,0x6c07,0x5c64,0x4c45,0x3ca2,0x2c83,0x1ce0,0x0cc1,0xef1f,0xff3e,
+ 0xcf5d,0xdf7c,0xaf9b,0xbfba,0x8fd9,0x9ff8,0x6e17,0x7e36,0x4e55,0x5e74,0x2e93,
+ 0x3eb2,0x0ed1,0x1ef0
+ };
+
+const TInt KQDepth=150; // Maximum queue depth
+
+LOCAL_C TUint checkSum(const TAny *aPtr)
+//
+// Checksum every other byte
+//
+ {
+
+ const TUint8* pB=(const TUint8*)aPtr;
+ const TUint8* pE=pB+(KMaxCheckedUid*sizeof(TUid));
+ TUint8 buf[(KMaxCheckedUid*sizeof(TUid))>>1];
+ TUint8* pT=(&buf[0]);
+ while (pB<pE)
+ {
+ *pT++=(*pB);
+ pB+=2;
+ }
+ TUint16 crc=0;
+ Mem::Crc(crc,&buf[0],(KMaxCheckedUid*sizeof(TUid))>>1);
+ return(crc);
+ }
+
+LOCAL_C TInt partit(TInt n,TInt m,const TKey &aKey,const TSwap &aSwap)
+//
+// Partition n elements of array stating from element m,
+// return element no. of partition point.
+//
+ {
+
+ TInt i=m-1;
+ TInt j=i+n;
+ TInt pivlin=j;
+ aSwap.Swap((j+m)>>1,j);
+ while (i<j)
+ {
+ for (i++;aKey.Compare(i,pivlin)<0;i++)
+ {
+ }
+ for (--j;j>i;j--)
+ {
+ if (aKey.Compare(j,pivlin)<=0)
+ break;
+ }
+ if (i<j)
+ aSwap.Swap(i,j);
+ }
+ aSwap.Swap(i,m+n-1);
+ return(i);
+ }
+
+static const TCollationMethod TheCollationMethod[] =
+ {
+ {
+ KUidBasicCollationMethod, // this is the standard unlocalised method
+ NULL, // null means use the standard table
+ NULL, // there's no override table
+ 0 // the flags are standard
+ }
+ };
+
+static const TCollationDataSet TheCollationDataSet =
+ {
+ TheCollationMethod,
+ 1
+ };
+
+// The one and only locale character set object.
+const LCharSet TheCharSet =
+ {
+ NULL,
+ &TheCollationDataSet
+ };
+
+const LCharSet* GetLocaleDefaultCharSet()
+ {
+ return &TheCharSet;
+ }
+
+const LCharSet* GetLocaleCharSet()
+ {
+ const LCharSet* charSet = (const LCharSet*)Exec::GetGlobalUserData(ELocaleDefaultCharSet);
+ if(charSet)
+ return charSet;
+ return &TheCharSet;
+ }
+
+const LCharSet* GetLocalePreferredCharSet()
+ {
+ const LCharSet* charSet = (const LCharSet*)Exec::GetGlobalUserData(ELocalePreferredCharSet);
+ if(charSet)
+ return charSet;
+ return &TheCharSet;
+ }
+
+EXPORT_C TCollationMethod TExtendedLocale::GetPreferredCollationMethod(TInt aIndex)
+/**
+Get the preferred collation method for the preferred charset.
+
+Note that some charsets may contain more than one collation
+method (e.g "dictionary" v "phonebook" ordering) so an optional
+index parameter can be used to select between them.
+
+@param aIndex Optional parameter specifying the index of the collation
+ method in the locale to get. This is the responsibility of
+ the caller to make sure that the index is less than the total
+ number of collation methods in the preferred charset in this locale.
+
+@return TCollationMethod representing the requested collation method.
+
+@panic USER 185 In both debug and release builds, if either the current charset
+ is not set up or aIndex is greater than or equal to the total number of
+ collation methods in the preferred charset in this locale.
+
+@see TCollationMethod
+*/
+ {
+ __ASSERT_ALWAYS(iPreferredCharSet && (TUint(aIndex)<=TUint(iPreferredCharSet->iCollationDataSet->iMethods)), Panic(EBadLocaleParameter));
+ return iPreferredCharSet->iCollationDataSet->iMethod[aIndex];
+ }
+
+extern const TUint8 __FoldCollTab8[256];
+
+EXPORT_C TInt Mem::CompareF(const TUint8 *aLeft,TInt aLeftL,const TUint8 *aRight,TInt aRightL)
+/**
+Compares a block of data at one specified location with a block of data at
+another specified location, using the standard folding method appropriate
+to the current locale.
+
+@param aLeft A pointer to the first (or left) block of 8 bit data to be
+ compared.
+@param aLeftL The length of the first (or left) block of data to be compared,
+ i.e. the number of bytes.
+@param aRight A pointer to the second (or right) block of 8 bit data to be
+ compared.
+@param aRightL The length of the second (or right) block of data to be
+ compared, i.e. the number of bytes.
+
+@return Positive, if the first (or left) block of data is greater than the
+ second (or right) block of data.
+ Negative, if the first (or left) block of data is less than the second
+ (or right) block of data.
+ Zero, if both the first (or left) and second (or right) blocks of data
+ have the same length and the same content.
+
+@see Mem::Compare
+*/
+ {
+
+ __ASSERT_DEBUG(aLeftL>=0,Panic(EMemLeftNegative));
+ __ASSERT_DEBUG(aRightL>=0,Panic(EMemRightNegative));
+ const TUint8 *pE=aLeft+Min(aLeftL,aRightL);
+ const TUint8* table=__FoldCollTab8;
+ while (aLeft<pE)
+ {
+ TUint l=*aLeft++;
+ TUint r=*aRight++;
+ l = table[l];
+ r = table[r];
+ TInt d=l-r;
+ if (d!=0)
+ return(d);
+ }
+ return(aLeftL-aRightL);
+ }
+
+
+
+
+EXPORT_C TInt Mem::CompareC(const TUint8 *aLeft,TInt aLeftL,const TUint8 *aRight,TInt aRightL)
+/**
+Compares a block of data at one specified location with a block of data at
+another specified location using the standard collation method appropriate
+to the current locale.
+
+@param aLeft A pointer to the first (or left) block of 8 bit data to be
+ compared.
+@param aLeftL The length of the first (or left) block of data to be compared
+ i.e. the number of bytes.
+@param aRight A pointer to the second (or right) block of 8 bit data to be
+ compared.
+@param aRightL The length of the second (or right) block of data to be compared
+ i.e. the number of bytes.
+
+@return Positive, if the first (or left) block of data is greater than the
+ second (or right) block of data.
+ Negative, if the first (or left) block of data is less than the second
+ (or right) block of data.
+ Zero, if both the first (or left) and second (or right) blocks of data
+ have the same length and the same content.
+
+@see Mem::Compare
+@deprecated
+*/
+ {
+ return Mem::CompareF(aLeft, aLeftL, aRight, aRightL);
+ }
+
+
+
+
+EXPORT_C TInt Mem::Compare(const TUint16 *aLeft,TInt aLeftL,const TUint16 *aRight,TInt aRightL)
+/**
+Compares a block of data at one specified location with a block of data at
+another specified location.
+
+The comparison proceeds on a double-byte for double-byte basis, the result
+of the comparison is based on the difference of the first pair of bytes to
+disagree.
+
+The data at the two locations are equal if they have the same length and content.
+Where the lengths are different and the shorter section of data is the same
+as the first part of the longer section of data, the shorter is considered
+to be less than the longer.
+
+@param aLeft A pointer to the first (or left) block of 16 bit data to be
+ compared.
+@param aLeftL The length of the first (or left) block of data to be compared
+ i.e. the number of double-bytes.
+@param aRight A pointer to the second (or right) block of 16 bit data to be
+ compared.
+@param aRightL The length of the second (or right) block of data to be compared
+ i.e. the number of double-bytes.
+
+@return Positive, if the first (or left) block of data is greater than the
+ second (or right) block of data.
+ Negative, if the first (or left) block of data is less than the second
+ (or right) block of data.
+ Zero, if both the first (or left) and second (or right) blocks of data
+ have the same length and the same content.
+*/
+ {
+
+ __ASSERT_DEBUG(aLeftL>=0,Panic(EMemLeftNegative));
+ __ASSERT_DEBUG(aRightL>=0,Panic(EMemRightNegative));
+ const TUint16 *pE=aLeft+Min(aLeftL,aRightL);
+ while (aLeft<pE)
+ {
+ TInt d=(*aLeft++)-(*aRight++);
+ if (d!=0)
+ return(d);
+ }
+ return(aLeftL-aRightL);
+ }
+
+
+
+
+EXPORT_C TInt Mem::CompareF(const TUint16 *aLeft,TInt aLeftL,const TUint16 *aRight,TInt aRightL)
+/**
+Compares a block of data at one specified location with a block of data at
+another specified location, using the standard folding method appropriate
+to the current locale.
+
+@param aLeft A pointer to the first (or left) block of 16 bit data to be
+ compared.
+@param aLeftL The length of the first (or left) block of data to be compared
+ i.e. the number of double-bytes.
+@param aRight A pointer to the second (or right) block of 16 bit data to be
+ compared.
+@param aRightL The length of the second (or right) block of data to be compared
+ i.e the number of double-bytes.
+
+@return Positive, if the first (or left) block of data is greater than the
+ second (or right) block of data.
+ Negative, if the first (or left) block of data is less than the second
+ (or right) block of data.
+ Zero, if both the first (or left) and second (or right) blocks of data
+ have the same length and the same content.
+
+@see Mem::Compare
+*/
+ {
+ __ASSERT_DEBUG(aLeftL >= 0,Panic(EMemLeftNegative));
+ __ASSERT_DEBUG(aRightL >= 0,Panic(EMemRightNegative));
+
+ const TText16* aLeftEnd = aLeft + aLeftL;
+ const TText16* aRightEnd = aRight + aRightL;
+
+ const TUint8* table=__FoldCollTab8;
+
+ while (aLeft != aLeftEnd)
+ {
+ if (aRight == aRightEnd)
+ return 1;
+
+ TUint l = *aLeft;
+ TUint r = *aRight;
+
+ // check if character is Ascii, if so treat as Ascii
+ if (l < 128 && r < 128)
+ {
+ l = table[l];
+ r = table[r];
+
+ if (r != l)
+ return l-r;
+
+ aLeft++;
+ aRight++;
+ }
+ // covers Unicode characters...
+ else
+ {
+ TUTF32Iterator leftIt(aLeft, aLeftEnd);
+ TUTF32Iterator rightIt(aRight, aRightEnd);
+ return ::CompareFolded(leftIt, rightIt);
+ }
+ }
+
+ return aRight == aRightEnd? 0:-1;
+ }
+
+
+
+
+
+EXPORT_C TInt Mem::CompareC(const TUint16 *aLeft,TInt aLeftL,const TUint16 *aRight,TInt aRightL)
+/**
+Compares a block of data at one specified location with a block of data at
+another specified location using the standard collation method appropriate
+to the current locale.
+
+@param aLeft A pointer to the first (or left) block of 16 bit data to be
+ compared.
+@param aLeftL The length of the first (or left) block of data to be compared
+ i.e. the number of double-bytes).
+@param aRight A pointer to the second (or right) block of 16 bit data to be
+ compared.
+@param aRightL The length of the second (or right) block of data to be compared
+ i.e. the number of double-bytes.
+
+@return Positive, if the first (or left) block of data is greater than the
+ second (or right) block of data.
+ Negative, if the first (or left) block of data is less than the second
+ (or right) block of data.
+ Zero, if both the first (or left) and second (or right) blocks of data
+ have the same length and the same content.
+
+@see Mem::Compare
+*/
+ {
+ __ASSERT_DEBUG(aLeftL>=0,Panic(EMemLeftNegative));
+ __ASSERT_DEBUG(aRightL>=0,Panic(EMemRightNegative));
+#ifdef _UNICODE
+ TCollate c(GetLocaleCharSet());
+ return c.Compare(aLeft,aLeftL,aRight,aRightL);
+#else
+ const TUint16 *pE=aLeft+Min(aLeftL,aRightL);
+ while (aLeft<pE)
+ {
+ TInt d=User::Collate(*aLeft++)-User::Collate(*aRight++);
+ if (d!=0)
+ return(d);
+ }
+ return(aLeftL-aRightL);
+#endif
+ }
+
+
+
+
+#ifdef _UNICODE
+EXPORT_C TInt Mem::CompareC(const TUint16* aLeft,TInt aLeftL,const TUint16* aRight,TInt aRightL,
+ TInt aMaxLevel,const TCollationMethod* aCollationMethod)
+/**
+Compares a block of data at one location with a block of data at another location
+using the specified collation method and collating to the specified maximum
+collation level.
+
+If no collation method is supplied, a default method, appropriate to the current
+locale, is used.
+
+This function is only defined for 16 bit (Unicode) build variants. This means
+that the function is not defined for 8 bit build variants, even when an explicit
+16 bit descriptor is used.
+
+@param aLeft A pointer to the first (or left) block of 16 bit data
+ to be compared.
+@param aLeftL The length of the first (or left) block of data to be
+ compared. This is the number of double-bytes.
+@param aRight A pointer to the second (or right) block of 16 bit data
+ to be compared.
+@param aRightL The length of the second (or right) block of data to be
+ compared. This is the number of double-bytes.
+@param aMaxLevel The maximum collation level.
+@param aCollationMethod A pointer to the collation method or NULL.
+
+@return Positive, if this descriptor is greater than the specified descriptor.
+ Negative, if this descriptor is less than the specified descriptor.
+ Zero, if both descriptors have the same length and their contents
+ are the same.
+*/
+ {
+ __ASSERT_DEBUG(aLeftL>=0,Panic(EMemLeftNegative));
+ __ASSERT_DEBUG(aRightL>=0,Panic(EMemRightNegative));
+ if (aCollationMethod == NULL)
+ {
+ TCollate c(GetLocaleCharSet());
+ return c.Compare(aLeft,aLeftL,aRight,aRightL,aMaxLevel);
+ }
+ else
+ {
+ TCollate c(*aCollationMethod);
+ return c.Compare(aLeft,aLeftL,aRight,aRightL,aMaxLevel);
+ }
+ }
+#endif
+
+
+
+
+#ifdef _UNICODE
+EXPORT_C TInt Mem::CollationMethods()
+/**
+Gets the number of collation methods in this locale.
+
+This function is only defined for 16 bit (Unicode) build variants. This means
+that the function is not defined for 8 bit build variants, even when an
+explicit 16 bit descriptor is used.
+
+@return The number of collation methods.
+*/
+ {
+ return GetLocaleCharSet()->iCollationDataSet->iMethods;
+ }
+#endif
+
+
+
+
+#ifdef _UNICODE
+EXPORT_C TUint Mem::CollationMethodId(TInt aIndex)
+/**
+Gets the Uid associated with the specified collation method.
+
+This function is only defined for 16 bit (Unicode) build variants. This means
+that the function is not defined for 8 bit build variants, even when an
+explicit 16 bit descriptor is used.
+
+@param aIndex An index into the set of collation methods in thie locale. This
+ value is relative to zero; i.e. a zero value refers to the first
+ collation method. This value must not be negative, and must be
+ less than the total number of collation methods in this locale.
+
+@return The Uid of the collation method.
+
+@panic USER 132 In debug builds only, if aIndex is negative or is greater than
+ or equal to the total number of collation methods in this locale.
+*/
+ {
+ const TCollationDataSet* s = GetLocaleCharSet()->iCollationDataSet;
+ __ASSERT_DEBUG(aIndex >= 0 && aIndex < s->iMethods,Panic(EBadCollationRulesIndex));
+ return s->iMethod[aIndex].iId;
+ }
+#endif
+
+
+
+
+#ifdef _UNICODE
+EXPORT_C const TCollationMethod* Mem::CollationMethodByIndex(TInt aIndex)
+/**
+Gets the collation method identified by the specified index.
+
+This function is only defined for 16 bit (Unicode) build variants. This means
+that the function is not defined for 8 bit build variants, even when an
+explicit 16 bit descriptor is used.
+
+@param aIndex An index into the set of collation methods in this locale. This
+ value is relative to zero; i.e. a zero value refers to the first
+ collation method. This value must not be negative, and must be
+ less than the total number of collation methods in this locale.
+
+@return A pointer to the collation method.
+
+@panic USER 132 In debug builds only, if aIndex is negative or is greater than
+ or equal to the total number of collation methods in this locale.
+*/
+ {
+ const TCollationDataSet* s = GetLocaleCharSet()->iCollationDataSet;
+ __ASSERT_DEBUG(aIndex >= 0 && aIndex < s->iMethods,Panic(EBadCollationRulesIndex));
+ return &s->iMethod[aIndex];
+ }
+#endif
+
+
+
+
+#ifdef _UNICODE
+EXPORT_C const TCollationMethod* Mem::CollationMethodById(TUint aId)
+/**
+Gets the collation method identified by the specified Uid.
+
+This function is only defined for 16 bit (Unicode) build variants. This means
+that the function is not defined for 8 bit build variants, even when an
+explicit 16 bit descriptor is used.
+
+@param aId The Uid of a collation method in the set of collation methods in
+ this locale.
+
+@return A pointer to the collation method.
+*/
+ {
+ const TCollationDataSet* set = GetLocaleCharSet()->iCollationDataSet;
+ const TCollationMethod* method = set->iMethod;
+ const TCollationMethod* m = method;
+ int methods = set->iMethods;
+ for (int i = 0; i < methods; i++, m++)
+ if (m->iId == aId)
+ {
+ method = m;
+ break;
+ }
+ return method;
+ }
+#endif
+
+#ifdef _UNICODE
+EXPORT_C const TCollationMethod* Mem::GetDefaultMatchingTable()
+/**
+Gets the collation method specific for matching purpose.
+
+This function is only defined for 16 bit (Unicode) build variants. This means
+that the function is not defined for 8 bit build variants, even when an
+explicit 16 bit descriptor is used.
+
+@return A pointer to the collation method
+*/
+ {
+ const TCollationDataSet* set=GetLocaleCharSet()->iCollationDataSet;
+ const TCollationMethod* method=set->iMethod;
+ const TCollationMethod* m= method;
+ int methods = set->iMethods;
+ for (; methods-->0; m++)
+ if (m->iFlags & TCollationMethod::EMatchingTable)
+ {
+ method=m;
+ break;
+ }
+ return method;
+ }
+#endif
+
+
+#if !defined(__MEM_MACHINE_CODED__)
+EXPORT_C void Mem::Swap(TAny *aPtr1,TAny *aPtr2,TInt aLength)
+/**
+Swaps a number of bytes of data between two specified locations.
+
+The source and target areas can overlap.
+
+@param aPtr1 A pointer to the first location taking part in the swap.
+@param aPtr2 A pointer to second location taking part in the swap.
+@param aLength The number of bytes to be swapped between the two locations.
+ This value must not be negative.
+
+@panic USER 94 In debug builds only, if aLength is negative.
+*/
+ {
+
+ __ASSERT_DEBUG(aLength>=0,Panic(EMemSwapLengthNegative));
+ if (aPtr1==aPtr2)
+ return;
+ TUint8 *pT=(TUint8 *)aPtr1;
+ TUint8 *pE=pT+aLength;
+ TUint8 *pS=(TUint8 *)aPtr2;
+ while (pT<pE)
+ {
+ TUint b=(*pT);
+ *pT++=(*pS);
+ *pS++=(TUint8)b;
+ }
+ }
+#endif
+
+
+
+
+EXPORT_C void Mem::Crc(TUint16& aCrc,const TAny* aPtr,TInt aLength)
+/**
+Performs a CCITT CRC checksum on the specified data.
+
+On return from this function, the referenced 16 bit integer contains the checksummed
+value.
+
+@param aCrc A reference to a 16 bit integer to contain the checksummed value.
+@param aPtr A pointer to the start of the data to be checksummed.
+@param aLength The length of the data to be checksummed.
+*/
+ {
+
+ const TUint8* pB=(const TUint8*)aPtr;
+ const TUint8* pE=pB+aLength;
+ TUint crc=aCrc;
+ while (pB<pE)
+ crc=(crc<<8)^crcTab[((crc>>8)^*pB++)&0xff];
+ aCrc=(TUint16)crc;
+ }
+
+
+
+
+EXPORT_C TInt User::StringLength(const TUint8 *aString)
+/**
+Gets the length of a C style, null terminated, string of single-byte valued
+characters.
+
+The length does not include the null terminator.
+
+@param aString A pointer to the single byte valued, null terminated, string.
+
+@return The length of the string.
+*/
+ {
+
+ const TUint8 *pS=aString;
+ while (*pS)
+ pS++;
+ return(pS-aString);
+ }
+
+
+
+
+EXPORT_C TInt User::StringLength(const TUint16 *aString)
+/**
+Gets the length of a C style, null terminated, string of double-byte valued
+characters.
+
+The length does not include the null terminator.
+
+@param aString A pointer to the double-byte valued, null terminated, string.
+
+@return The length of the string.
+*/
+ {
+
+ const TUint16 *pS=aString;
+ while (*pS)
+ pS++;
+ return(pS-aString);
+ }
+
+
+
+
+EXPORT_C void User::Panic(const TDesC &aCategory,TInt aReason)
+/**
+Panics the current thread, specifying a category name and panic number.
+
+Keep the length of the category name small; it is limited to 16 characters.
+
+@param aCategory A reference to the descriptor containing the text that defines
+ the category for this panic.
+@param aReason The panic number.
+*/
+ {
+
+ __IF_DEBUG(Print(_L("User::Panic %S %d\n"),&aCategory,aReason));
+ TPtrC cat16(aCategory.Ptr(),Min(KMaxExitCategoryName,aCategory.Length()));
+ TBuf8<KMaxExitCategoryName> cat;
+ cat.Copy(cat16);
+ ExitCurrentThread(EExitPanic,aReason,&cat);
+ }
+
+
+
+
+void CallStaticEntryPoints(TBool aInit)
+ {
+ TLinAddr ep[KMaxLibraryEntryPoints];
+ TInt numEps=KMaxLibraryEntryPoints;
+ TInt r=E32Loader::StaticCallList(numEps, ep);
+ if (r!=KErrNone)
+ return;
+ if (aInit)
+ {
+ for (TInt i=0; i<numEps-1; ++i) // last EP is always process entry point
+ {
+ TLibraryEntry f=(TLibraryEntry)ep[i];
+ (*f)(KModuleEntryReasonProcessAttach);
+ }
+ }
+ else
+ {
+ for (TInt i=numEps-2; i>=0; --i) // last EP is always process entry point
+ {
+ TLibraryEntry f=(TLibraryEntry)ep[i];
+ (*f)(KModuleEntryReasonProcessDetach);
+ }
+ }
+ }
+
+
+
+
+EXPORT_C void User::InitProcess()
+/**
+@internalAll
+*/
+ {
+ CallStaticEntryPoints(ETrue);
+ }
+
+
+
+
+EXPORT_C void User::Exit(TInt aReason)
+/**
+Terminates the current thread, specifying a reason.
+All child threads are terminated and all resources are cleaned up.
+
+If the current thread is the main thread in a process, the process is also
+terminated.
+
+@param aReason The reason code.
+*/
+ {
+ // Notify kernel that thread is exiting
+ TBool lastThread = Exec::UserThreadExiting(aReason);
+ if (lastThread)
+ {
+ // Call global destructors if we're the last thread in the process
+ TGlobalDestructorFunc func = (TGlobalDestructorFunc)UserSvr::DllTls(KGlobalDestructorTlsKey, KDllUid_Special);
+ if (func)
+ {
+ func();
+ CallStaticEntryPoints(EFalse);
+ }
+ }
+
+ FOREVER
+ {
+ TInt h=Exec::LastThreadHandle();
+ if (h==0)
+ break;
+ if (Exec::HandleClose(h)>0)
+ RHandleBase::DoExtendedClose();
+ }
+
+#ifdef __USERSIDE_THREAD_DATA__
+ LocalThreadData()->Close();
+#endif
+
+ ExitCurrentThread(EExitKill,aReason,NULL);
+ }
+
+
+
+
+EXPORT_C TInt User::QuickSort(TInt aCount,const TKey &aKey,const TSwap &aSwap)
+//
+// Routine sorts a set of records into the order defined by the key aKey.
+// There are aCount records to sort, each record is numbered, the first is
+// record 0, the last record aCount-1.
+// Each time the quicksort algorithm needs to compare two records it calls
+// aKey.Compare(TInt n,TInt m).
+// where n and m (both type TUint) are the record no.s of the two records to compare.
+// The compare routine should return
+// >0 if record(n) > record(m)
+// 0 if record(n) == record(m)
+// <0 if record(n) < record(m)
+// Each time the quicksort algorithm needs to exchange two records it calls
+// aSwap.Swap(n,m)
+// where n and m (both type TUint) are the record numbers of the two records to
+// exchange.
+// The swap routine should exchange the positions of records n and m so that
+// the value of record m becomes the former value of record n and visa versa.
+//
+/**
+Quick sorts array elements.
+
+It is used by the standard Symbian OS arrays having
+CArrayFixBase, CArrayVarBase or CArrayPakBase in their class hierarchy in
+the implementation of their sort functions. The function can be used by other
+arrays.
+
+The function returns KErrNone if the operation is successful otherwise it
+returns KErrGeneral.
+
+@param aCount The number of elements in the array.
+@param aKey A reference to a suitably initialised TKey derived object.
+@param aSwap A reference to a suitably initialised TSwap derived object.
+
+@return KErrNone if the operation is successful; KErrGeneral otherwise.
+
+@panic USER 96, if aCount is negative.
+*/
+ {
+ TInt *parts_sp; // Stack pointer for partitions todo
+ TInt m; // First element of partition
+ TInt n; // No. of elements in partition
+ TInt d1,d2; // Temporary variables
+ TInt division_point; // Seperation point of partitions
+ TInt parts_todo[KQDepth]; // Stack pairs are <n,base>
+
+ __ASSERT_ALWAYS(aCount>=0,::Panic(ESortCountNegative));
+ if (aCount<=1)
+ return(KErrNone); // Discard trivial sorts
+ parts_sp=(&parts_todo[0]); // Reset partitions to do stack
+ m=0; // Initial limits, first element
+ n=aCount; // No_elm elements to do
+ do {
+ while (n>1 && parts_sp<(&parts_todo[KQDepth-2]))
+ {
+ division_point=partit(n,m,aKey,aSwap);
+ d1=division_point-m;
+ d2=m+n-division_point-1;
+ if (d1<d2)
+ {
+ // Less elements in first partition, do it first
+ // Stack bigger partition for later
+ *(parts_sp++)=d2;
+ *(parts_sp++)=division_point+1;
+ n=d1;
+ }
+ else
+ {
+ // Less elements in second partition,do it first
+ // Stack bigger partition for later
+ *(parts_sp++)=d1;
+ *(parts_sp++)=m;
+ n=d2;
+ m=division_point+1;
+ }
+ }
+ if (parts_sp>=&parts_todo[KQDepth-2])
+ return(KErrGeneral); // Stack overflow
+ m=(*(--parts_sp));
+ n=(*(--parts_sp)); // Unstack next partit to do
+ } while (parts_sp>=(&parts_todo[0])); // Stop on stack underflow
+ return(KErrNone);
+ }
+
+
+
+
+EXPORT_C TInt User::BinarySearch(TInt aCount,const TKey &aKey,TInt &aPos)
+//
+// Perform a binary search on any array. aKey.Compare() will be
+// called to lexically compare a record in the array with the
+// value being searched for. The second index to aKey.Compare() will
+// always be KIndexPtr, meaning the value being compared. The result
+// returned will be 0 if a match is found and >0 if no match is found.
+// The index of the matching record or the index of the record logically
+// following the value being searched for will be returned in aPos.
+//
+/**
+Performs a binary search for an array element containing a specified key.
+
+It can be used on any kind of array where elements can be identified by key.
+It is used by the standard Symbian OS arrays having CArrayFix, CArrayVar or
+CArrayPak in their class hierarchy in the implementation of the various
+functions for inserting, deleting and finding elements by key. The function
+can be used by other arrays.
+
+The function returns a zero value if the search is successful and a non-zero
+value otherwise.
+
+If the search is successful, the function puts the position (i.e. the index)
+of the element into aPos. If the search is unsuccessful, then the function
+puts into aPos the position of the first element in the array whose key is
+greater than the search key.
+
+If the array is empty, i.e. aCount is zero, then the search is unsuccessful
+and aPos is not defined.
+
+@param aCount The number of elements in the array.
+@param aKey A reference to a suitably initialised TKey derived object.
+ In particular, the object will have been initialised with
+ a pointer to a sample element containing the search key.
+@param aPos If the element is found, the reference is set to the position of
+ that element within the array. The position is relative to zero,
+ (i.e. the first element in the array is at position 0).
+ If the element is not found and the array is not empty, then
+ the reference is set to the position of the first element in
+ the array with a key which is greater than the search key.
+ If the element is not found and the array is empty, then the
+ reference is undefined.
+
+@return Zero, if the element with the specified key is found. Non-zero, if
+the element with the specified key is not found.
+
+@panic USER 97, if aCount is negative.
+*/
+ {
+
+ __ASSERT_ALWAYS(aCount>=0,::Panic(EBinarySearchCountNegative));
+ TInt mid=0;
+ TInt r=(-1);
+ if (aCount)
+ {
+ TInt low=0;
+ TInt high=aCount-1;
+ while (low<=high)
+ {
+ mid=(low+high)>>1;
+ if ((r=aKey.Compare(mid,KIndexPtr))==0)
+ break;
+ if (r<0)
+ low=mid+1;
+ else
+ high=mid-1;
+ }
+ }
+ if (r<0)
+ mid++;
+ aPos=mid;
+ return(r);
+ }
+
+
+
+
+EXPORT_C TVersion User::Version()
+/**
+Retrieves the E32 component version number, which is the kernel architecture version number.
+For example for EKA2 the major part of the version number will be 2.
+
+@return The E32 component version number.
+*/
+ {
+
+ return(TVersion(KE32MajorVersionNumber,KE32MinorVersionNumber,KE32BuildVersionNumber));
+ }
+
+
+
+
+EXPORT_C void User::Invariant()
+/**
+Panics the current thread with a USER 0 panic.
+
+Typically, this is called when a test for a class invariant fails, i.e. when
+a test which checks that the internal data of an object is
+self-consistent, fails.
+
+Such tests are almost always done in debug builds, commonly using
+the __ASSERT_DEBUG macro.
+*/
+ {
+
+ ::Panic(EInvariantFalse);
+ }
+
+
+
+
+EXPORT_C TBool User::QueryVersionSupported(const TVersion &aCurrent,const TVersion &aRequested)
+/**
+Compares two version objects and returns true if the test version is less
+than the current version.
+
+Version information is encapsulated by a TVersion type object and consists
+of a major version number, a minor version number and a build number.
+
+The function returns true if one of the following conditions is true:
+
+1. the test major version is strictly less than the current major version
+
+2. the test major version is equal to the current major version and the test
+ minor version is less than or equal to the current minor version
+
+If neither condition is true, the function returns false.
+
+@param aCurrent A reference to the current version against which aRequested
+ is compared.
+@param aRequested A reference to the test version to be compared
+ against aCurrent.
+
+@return True, if one or both conditions are true. False otherwise.
+*/
+ {
+
+ if (aRequested.iMajor<aCurrent.iMajor || (aRequested.iMajor==aCurrent.iMajor && aRequested.iMinor<=aCurrent.iMinor))
+ return(ETrue);
+ return(EFalse);
+ }
+
+
+
+
+EXPORT_C TKey::TKey()
+/**
+Protected default constructor.
+
+This constructor prevents TKey objects from being constructed directly.
+*/
+ {}
+
+
+
+
+EXPORT_C TKey::TKey(TInt anOffset,TKeyCmpText aType)
+ : iKeyOffset(anOffset),iCmpType(ECmpCollated16+aType+1)
+/**
+Constructs the characteristics of a descriptor type key.
+
+This constructor should be called by the corresponding derived class
+constructor that takes the same arguments. Typically, the derived class
+constructor calls this constructor in its constructor initialization list.
+
+No length value is passed as this is implied by the type of key.
+
+Note that the constructor sets the offset value into the protected data member
+iKeyOffset.
+
+@param anOffset The offset of the key from the start of an array element.
+@param aType An enumeration which defines the type of comparison to be made
+ between two descriptor keys.
+
+@panic USER 98, if anOffset is negative.
+
+@see TKeyCmpText
+*/
+ {
+
+ __ASSERT_ALWAYS(iKeyOffset>=0,Panic(EKeyOffsetNegative));
+ }
+
+
+
+
+EXPORT_C TKey::TKey(TInt anOffset,TKeyCmpText aType,TInt aLength)
+ : iKeyOffset(anOffset),iKeyLength(aLength),iCmpType(aType)
+/**
+Constructs the characteristics of a text key.
+
+This constructor should be called by the corresponding derived class
+constructor that takes the same arguments. Typically, the derived class
+constructor calls this constructor in its constructor initialization list.
+
+Note that the constructor sets the offset value into the protected data member
+iKeyOffset.
+
+@param anOffset The offset of the key from the start of an array element.
+@param aType An enumeration which defines the type of comparison to be made
+ between two text keys.
+@param aLength The length of the text key.
+
+@panic USER 98, if anOffset is negative.
+
+@see TKeyCmpText
+*/
+ {
+
+ __ASSERT_ALWAYS(iKeyOffset>=0,Panic(EKeyOffsetNegative));
+ }
+
+
+
+
+EXPORT_C TKey::TKey(TInt anOffset,TKeyCmpNumeric aType)
+ : iKeyOffset(anOffset),iCmpType(aType)
+/**
+Constructs the characteristics of a numeric key.
+
+This constructor should be called by the corresponding derived class
+constructor that takes the same arguments. Typically, the derived class
+constructor calls this constructor in its constructor initialization list.
+
+No length value is passed as this is implied by the type of key.
+
+Note that the constructor sets the offset value into the protected data member
+iKeyOffset.
+
+@param anOffset The offset of the key from the start of an array element.
+@param aType An enumeration which defines the type of the numeric key.
+
+@panic USER 98, if anOffset is negative.
+
+@see TKeyCmpNumeric
+*/
+ {
+
+ __ASSERT_ALWAYS(iKeyOffset>=0,Panic(EKeyOffsetNegative));
+ }
+
+
+
+
+EXPORT_C TInt TKey::Compare(TInt aLeft,TInt aRight) const
+/**
+Compares the keys of two array elements.
+
+This function is called by User::BinarySearch() and User::QuickSort().
+
+The position of the elements are identified by the specified index values.
+The default implementation uses the At() virtual function to convert the index
+values into pointers to the elements themselves.
+
+The default implementation also uses:
+
+1. the TDesC comparison functions to compare descriptor type keys
+
+2. the Mem functions to compare text type keys
+
+3. numeric comparison for numeric type keys.
+
+@param aLeft The index of an array element participating in the comparison,
+ designated the left element.
+@param aRight The index of an array element participating in the comparison,
+ designated the right element.
+
+@return Zero, if the two keys are equal;
+ negative, if the left key is less than the right key;
+ positive, if the left key is greater than the right key.
+
+@see User::BinarySearch()
+@see User::QuickSort()
+@see TDesC
+@see Mem
+*/
+ {
+
+ UPTR left;
+ left.tany=At(aLeft);
+ UPTR right;
+ // coverity[returned_pointer]
+ right.tany=At(aRight);
+ TInt r=(-1);
+ switch (iCmpType)
+ {
+#if !defined(_UNICODE)
+ case ECmpNormal:
+#endif
+ case ECmpNormal8:
+ r=Mem::Compare(left.ttext8,iKeyLength,right.ttext8,iKeyLength);
+ break;
+#if defined(_UNICODE)
+ case ECmpNormal:
+#endif
+ case ECmpNormal16:
+ r=Mem::Compare(left.ttext16,iKeyLength,right.ttext16,iKeyLength);
+ break;
+#if !defined(_UNICODE)
+ case ECmpFolded:
+#endif
+ case ECmpFolded8:
+ r=Mem::CompareF(left.ttext8,iKeyLength,right.ttext8,iKeyLength);
+ break;
+#if defined(_UNICODE)
+ case ECmpFolded:
+#endif
+ case ECmpFolded16:
+ r=Mem::CompareF(left.ttext16,iKeyLength,right.ttext16,iKeyLength);
+ break;
+#if !defined(_UNICODE)
+ case ECmpCollated:
+#endif
+ case ECmpCollated8:
+ r=Mem::CompareC(left.ttext8,iKeyLength,right.ttext8,iKeyLength);
+ break;
+#if defined(_UNICODE)
+ case ECmpCollated:
+#endif
+ case ECmpCollated16:
+ r=Mem::CompareC(left.ttext16,iKeyLength,right.ttext16,iKeyLength);
+ break;
+#if !defined(_UNICODE)
+ case ECmpCollated16+ECmpNormal+1:
+#endif
+ case ECmpCollated16+ECmpNormal8+1:
+ r=left.tdesc8->Compare(*right.tdesc8);
+ break;
+#if defined(_UNICODE)
+ case ECmpCollated16+ECmpNormal+1:
+#endif
+ case ECmpCollated16+ECmpNormal16+1:
+ r=left.tdesc16->Compare(*right.tdesc16);
+ break;
+#if !defined(_UNICODE)
+ case ECmpCollated16+ECmpFolded+1:
+#endif
+ case ECmpCollated16+ECmpFolded8+1:
+ r=left.tdesc8->CompareF(*right.tdesc8);
+ break;
+#if defined(_UNICODE)
+ case ECmpCollated16+ECmpFolded+1:
+#endif
+ case ECmpCollated16+ECmpFolded16+1:
+ r=left.tdesc16->CompareF(*right.tdesc16);
+ break;
+#if !defined(_UNICODE)
+ case ECmpCollated16+ECmpCollated+1:
+#endif
+ case ECmpCollated16+ECmpCollated8+1:
+ r=left.tdesc8->CompareC(*right.tdesc8);
+ break;
+#if defined(_UNICODE)
+ case ECmpCollated16+ECmpCollated+1:
+#endif
+ case ECmpCollated16+ECmpCollated16+1:
+ r=left.tdesc16->CompareC(*right.tdesc16);
+ break;
+ case ECmpTInt:
+ if (*left.tint==*right.tint)
+ r=0;
+ else if (*left.tint>*right.tint)
+ r=1;
+ break;
+ case ECmpTUint:
+ if (*left.tuint==*right.tuint)
+ r=0;
+ else if (*left.tuint>*right.tuint)
+ r=1;
+ break;
+ case ECmpTInt8:
+ if (*left.tint8==*right.tint8)
+ r=0;
+ else if (*left.tint8>*right.tint8)
+ r=1;
+ break;
+ case ECmpTUint8:
+ if (*left.tuint8==*right.tuint8)
+ r=0;
+ else if (*left.tuint8>*right.tuint8)
+ r=1;
+ break;
+ case ECmpTInt16:
+ if (*left.tint16==*right.tint16)
+ r=0;
+ else if (*left.tint16>*right.tint16)
+ r=1;
+ break;
+ case ECmpTUint16:
+ if (*left.tuint16==*right.tuint16)
+ r=0;
+ else if (*left.tuint16>*right.tuint16)
+ r=1;
+ break;
+ case ECmpTInt32:
+ if (*left.tint32==*right.tint32)
+ r=0;
+ else if (*left.tint32>*right.tint32)
+ r=1;
+ break;
+ case ECmpTUint32:
+ if (*left.tuint32==*right.tuint32)
+ r=0;
+ else if (*left.tuint32>*right.tuint32)
+ r=1;
+ break;
+ case ECmpTInt64:
+ if (*left.tint64==*right.tint64)
+ r=0;
+ else if (*left.tint64>*right.tint64)
+ r=1;
+ break;
+ }
+ return(r);
+ }
+
+
+
+
+EXPORT_C TAny* TKey::At(TInt /*anIndex*/) const
+/**
+Gets a pointer to the key of a specified array element.
+
+The default implementation raises a USER 35 panic.
+
+The function is called by TKey::Compare() to compare the keys of two elements.
+
+The implementation provided by a derived class must convert the index to a
+pointer to the key within the corresponding element. The implementation depends
+on the design of the array but, as general rule, use the index value to get
+a pointer to the corresponding element and then add the TKey protected data
+member iKeyOffset to this pointer to get a pointer to the key itself.
+
+By convention, the index value is relative to zero; i.e. a zero value refers
+to the first element in the array. By this convention, the index can take
+any value between zero and the number of elements within the array minus one.
+
+The function must also handle the special index value KIndexPtr. When this
+value is passed, the function should return a pointer to the key within the
+sample element. A pointer to the sample element is held in the protected data
+member iPtr and can be set up using SetPtr().
+
+The implementation of this function also assumes that the derived class has
+a pointer to the array itself or has a function for finding it.
+
+@param anIndex The index of the array element or the special index value KIndexPtr.
+
+@return An untyped pointer to the key within the specified array element or
+ an untyped pointer to the key within the sample element, if KIndexPtr
+ is passed as an argument.
+
+@panic USER 35, if no replacement function has been provided by a derived class.
+
+@see TKey::Compare
+@see TKey::SetPtr
+@see KIndexPtr
+*/
+ {
+
+ Panic(ETFuncTKeyVirtualAt);
+ return(NULL);
+ }
+
+
+
+
+EXPORT_C TSwap::TSwap()
+/**
+Default constructor.
+
+The constructor has an empty implementation.
+*/
+ {}
+
+
+
+
+EXPORT_C void TSwap::Swap(TInt /*aLeft*/,TInt /*aRight*/) const
+/**
+Swaps two elements of an array.
+
+This function is called by User::QuickSort().
+
+The default implementation raises a USER 36 panic.
+
+In general, the class must provide a way of translating the indexes representing
+the two elements into pointers to the elements themselves. The Mem::Swap()
+utility function can then be used to swap the two elements. This implies that
+the derived class must contain a pointer to the array itself and have access
+to other information about the array, such as the length of elements.
+
+By convention, the index value is relative to zero; i.e. a zero value refers
+to the first element in the array.
+
+@param aLeft The index of an array element participating in the swap
+@param aRight The index of an array element participating in the swap
+
+@panic USER 36, if no replacement function has been provided by a derived class.
+
+@see User::QuickSort
+@see Mem::Swap
+*/
+ {
+
+ Panic(ETFuncTSwapVirtualSwap);
+ }
+
+
+
+
+EXPORT_C TVersion::TVersion()
+/**
+Default constructor.
+
+It sets the major, minor and build numbers to zero.
+*/
+ : iMajor(0),iMinor(0),iBuild(0)
+ {}
+
+
+
+
+EXPORT_C TVersion::TVersion(TInt aMajor,TInt aMinor,TInt aBuild)
+/**
+Constructs the object with the specified major version number, the minor
+version number and the build number.
+
+Note that the constructor does not check that the values passed are within
+the specified ranges. As the parameters are TInt types, care must be taken to
+ensure that values passed do not exceed the specified maxima, otherwise they
+will be interpreted as negative values.
+
+@param aMajor The major version number. This must be a number in the
+ range 0 to 127.
+@param aMinor The minor version number. This must be a number in the
+ range 0 to 99.
+@param aBuild The build number. This must be a number in the range 0 to 32,767.
+
+*/
+ : iMajor((TInt8)aMajor),iMinor((TInt8)aMinor),iBuild((TInt16)aBuild)
+ {}
+
+
+
+
+EXPORT_C TVersionName TVersion::Name() const
+/**
+Gets a descriptor buffer containing the formatted character representation
+of the version information.
+
+The general format of the representation is: xxx.yy(zzzzz)
+
+where:
+
+1. xxx is the major version number; depending on the value, this may have
+ a length of one, two or three characters.
+
+2. yy is the minor version number; this is always two characters, padded
+ with a leading zero, if necessary.
+
+3. zzzzz is the build number; depending on the value, this may have a length
+ of one to 5 characters.
+
+Note that if the object is constructed with values that exceed the permitted
+range, they will appear negative in their formatted character representation.
+
+@return A buffer descriptor containing the formatted character representation.
+*/
+ {
+
+ TVersionName v;
+ v.AppendNum(iMajor);
+ v.Append(TChar('.'));
+ v.AppendNumFixedWidth(iMinor,EDecimal,2);
+ v.Append(TChar('('));
+ v.AppendNum(iBuild);
+ v.Append(TChar(')'));
+// v.Format(_L("%d.%02d(%d)"),iMajor,iMinor,iBuild);
+ return(v);
+ }
+
+
+
+
+/**
+Signals the current thread that the asynchronous request associated with the
+specified request status object is complete.
+
+This function is used to complete an asynchronous request originating in the
+same thread as the code that is currently executing. If a request originates
+in another thread, then executing code must use RThread::RequestComplete()
+to signal the completion of that request.
+
+The request is completed with the completion code passed in aReason. This
+value is copied into the request status, pointed to by aStatus, before
+signalling the current thread's request semaphore.
+
+The meaning of the completion code passed in aReason is a matter of convention
+to be decided between the service requester and the service provider.
+
+@param aStatus A reference to a pointer to the request status object. This
+ is a pointer into the current thread's address space.
+ On return, the pointer to the request status is set to NULL.
+ Note that setting the pointer to NULL is a convenience,
+ not all servers need it, and is done before
+ the function returns.
+
+@param aReason The completion code of this request.
+
+@see RThread::RequestComplete
+*/
+EXPORT_C void User::RequestComplete(TRequestStatus * &aStatus,TInt aReason)
+ {
+ *aStatus=KRequestPending;
+ RThread().RequestComplete(aStatus,aReason);
+ }
+
+
+
+
+EXPORT_C TLdrInfo::TLdrInfo()
+//
+// Constructor
+//
+ {
+ memclr(this, sizeof(TLdrInfo));
+ iRequestedVersion = KModuleVersionWild;
+ }
+
+EXPORT_C TPtrC8 TCodeSegCreateInfo::RootName() const
+ {
+ return iFileName.Mid(iRootNameOffset,iRootNameLength);
+ }
+
+EXPORT_C TBool TUid::operator==(const TUid& aUid) const
+/**
+Compares two UIDs for equality.
+
+@param aUid The UID to be compared with this UID.
+
+@return True, if the two UIDs are equal; false otherwise.
+*/
+ {
+
+ return(iUid==aUid.iUid);
+ }
+
+
+
+
+EXPORT_C TBool TUid::operator!=(const TUid& aUid) const
+/**
+Compares two UIDs for inequality.
+
+@param aUid The UID to be compared with this UID.
+
+@return True, if the two UIDs are unequal; false otherwise.
+*/
+ {
+
+ return(iUid!=aUid.iUid);
+ }
+
+
+
+
+EXPORT_C TUidName TUid::Name() const
+/**
+Generates and returns the standard text form of the UID.
+
+The resulting text has the form:
+
+@code
+[12345678]
+@endcode
+
+The function always generates 10 characters, where the first and last characters
+are open and close square brackets enclosing exactly 8 hexadecimal digits
+(padded to the left with zeroes, if necessary).
+
+@return A modifiable descriptor containing the standard text format of the
+ UID.
+*/
+ {
+
+ TUidName n;
+ n.Append(TChar('['));
+ n.AppendNumFixedWidth(iUid,EHex,8);
+ n.Append(TChar(']'));
+// n.Format(_L("[%08x]"),iUid);
+ return(n);
+ }
+
+
+
+
+EXPORT_C TUidType::TUidType()
+/**
+Default constructor.
+
+Creates a UID type, and sets all three component UIDs to KNullUid.
+*/
+ {
+
+ Mem::FillZ(this,sizeof(TUidType));
+ }
+
+
+
+
+EXPORT_C TUidType::TUidType(TUid aUid1)
+/**
+Constructor that creates a UID type and sets the UID1 component
+to the specified value.
+
+The UID2 and UID3 components are set to KNullUid.
+
+@param aUid1 Value for UID1.
+*/
+ {
+
+
+ Mem::FillZ(this,sizeof(TUidType));
+ iUid[0]=aUid1;
+ }
+
+
+
+
+EXPORT_C TUidType::TUidType(TUid aUid1,TUid aUid2)
+/**
+Constructor that creates a UID type and sets the UID1 and UID2 components
+to the specified values.
+
+The UID3 component is set to KNullUid.
+
+@param aUid1 Value for UID1.
+@param aUid2 Value for UID2.
+*/
+ {
+
+ iUid[0]=aUid1;
+ iUid[1]=aUid2;
+ iUid[2]=KNullUid;
+ }
+
+
+
+
+EXPORT_C TUidType::TUidType(TUid aUid1,TUid aUid2,TUid aUid3)
+/**
+Constructor that creates a UID type and sets all three UID components
+to the specified values.
+
+@param aUid1 Value for UID1.
+@param aUid2 Value for UID2.
+@param aUid3 Value for UID3.
+*/
+ {
+
+
+ iUid[0]=aUid1;
+ iUid[1]=aUid2;
+ iUid[2]=aUid3;
+ }
+
+
+
+
+EXPORT_C TBool TUidType::operator==(const TUidType& aUidType) const
+/**
+Compares this UID type for equality with the specified UID type.
+
+@param aUidType The UID type to be compared.
+
+@return True, if each component UID is equal to the corresponding component
+ UID in the specified UID type; false, otherwise.
+*/
+ {
+
+ return(iUid[0]==aUidType.iUid[0] &&
+ iUid[1]==aUidType.iUid[1] &&
+ iUid[2]==aUidType.iUid[2]);
+ }
+
+
+
+
+EXPORT_C TBool TUidType::operator!=(const TUidType& aUidType) const
+/**
+Compares this UID type for inequality with the specified UID type.
+
+@param aUidType The UID type to be compared.
+
+@return True, if any component UID is not equal to the corresponding component
+UID in the specified UID type; false otherwise.
+*/
+ {
+
+
+ return(!(*this==aUidType));
+ }
+
+
+
+
+EXPORT_C const TUid& TUidType::operator[](TInt aIndex) const
+/**
+Gets the UID component as identified by the specified index.
+
+@param aIndex Index value indicating which UID component to return.
+ 0 specifies UID1,
+ 1 specifies UID2,
+ 2 specifies UID3.
+
+@return A reference to the required UID component.
+
+@panic USER 37 if aIndex is not in the range 0 to 2, inclusive.
+*/
+ {
+
+ __ASSERT_ALWAYS(aIndex>=0 && aIndex<KMaxCheckedUid,Panic(ETFuncUidTypeBadIndex));
+ return(iUid[aIndex]);
+ }
+
+
+
+
+EXPORT_C TUid TUidType::MostDerived() const
+/**
+Gets the most derived UID.
+
+Taking the three UID components as a hierarchy with UID1 being the most general,
+UID2 being more specific than UID1 and UID3 being more specific than UID2,
+then the function returns:
+
+UID3, if UID3 is not KNullUid.
+
+UID2, if UID2 is not KNullUid.
+
+UID1, otherwise
+
+@return The most derived UID.
+
+@see KNullUid
+*/
+ {
+
+ if (iUid[2]!=KNullUid)
+ return(iUid[2]);
+ if (iUid[1]!=KNullUid)
+ return(iUid[1]);
+ return(iUid[0]);
+ }
+
+
+
+
+EXPORT_C TBool TUidType::IsPresent(TUid aUid) const
+/**
+Tests if any of the component UIDs are equal to the specified UID.
+
+@param aUid The UID to be tested.
+
+@return True, if any one of the component UIDs are the same as the specified
+ UID; false, if none of the component UIDs are the same.
+*/
+ {
+
+ return(iUid[0]==aUid || iUid[1]==aUid || iUid[2]==aUid);
+ }
+
+
+
+
+EXPORT_C TBool TUidType::IsValid() const
+/**
+Tests the object for a valid (non-KNullUid) UID type.
+
+@return True, if at least one of the component UIDs is not KNullUid; false,
+ if all component UIDs are KNullUid.
+
+@see KNullUid
+*/
+ {
+
+ return(MostDerived()!=KNullUid);
+ }
+
+
+
+
+EXPORT_C TCheckedUid::TCheckedUid()
+/**
+Default constructor.
+
+Initialises the object to binary zeroes.
+*/
+ {
+
+ Mem::FillZ(this,sizeof(TCheckedUid));
+ }
+
+
+
+
+EXPORT_C TCheckedUid::TCheckedUid(const TUidType& aUidType)
+/**
+Constructor taking an existing Uid type.
+
+The constructor calculates a checksum.
+
+@param aUidType The Uid type to be packaged.
+*/
+ {
+
+ Set(aUidType);
+ }
+
+
+
+
+EXPORT_C TCheckedUid::TCheckedUid(const TDesC8& aPtr)
+/**
+Constructor taking an existing TCheckedUid object encapsulated within
+a descriptor.
+
+The checksum is recalculated and must match the checksum value passed in the
+encapsulated TCheckedUid object, otherwise the content of this object is reset
+to binary zeroes.
+
+@param aPtr A pointer to a descriptor containing an existing TCheckedUid object.
+
+@panic USER 38 If the length of the descriptor is not the same as the size
+ of a TCheckedUid object.
+*/
+ {
+
+ Set(aPtr);
+ }
+
+
+
+
+EXPORT_C void TCheckedUid::Set(const TUidType& aUidType)
+/**
+Sets the specified Uid type to be packaged, and recalculates the checksum.
+
+@param aUidType The Uid type to be packaged.
+*/
+ {
+
+ iType=aUidType;
+ iCheck=Check();
+ }
+
+
+
+
+EXPORT_C void TCheckedUid::Set(const TDesC8& aPtr)
+/**
+Sets an existing TCheckedUid object encapsulated within a descriptor.
+
+The checksum is recalculated and must match the checksum value passed in the
+encapsulated TCheckedUid object, otherwise the content of this object is reset
+to binary zeroes.
+
+@param aPtr A pointer to a descriptor containing an existing
+ TCheckedUid object.
+
+@panic USER 38 If the length of the descriptor is not the same as the size
+ of a TCheckedUid object.
+*/
+ {
+
+ __ASSERT_ALWAYS(aPtr.Length()==sizeof(TCheckedUid),Panic(ETFuncCheckedUidBadSet));
+ Mem::Move(this,aPtr.Ptr(),sizeof(TCheckedUid));
+ if (iCheck!=Check())
+ Mem::FillZ(this,sizeof(TCheckedUid));
+ }
+
+
+
+
+EXPORT_C TPtrC8 TCheckedUid::Des() const
+/**
+Gets a pointer descriptor to represent this object's data.
+
+@return The pointer descriptor for this object's data. The descriptor's length
+ is the same as the length of a TCheckedUid object.
+*/
+ {
+
+ return(TPtrC8((const TUint8*)this,sizeof(TCheckedUid)));
+ }
+
+
+
+
+EXPORT_C TUint TCheckedUid::Check() const
+/**
+Calculates the checksum of the UIDs.
+
+@return The checksum.
+*/
+ {
+
+ return((checkSum(((TUint8*)this)+1)<<16)|checkSum(this));
+ }
+
+
+
+
+EXPORT_C TInt User::InfoPrint(const TDesC& aDes)
+/**
+Invokes the notifier server to display a text message on the screen for a short
+time.
+
+@param aDes A reference to the descriptor containing the text to be sent to
+ the notifier server.
+
+@return KErrNone if successful, otherwise one of the system-wide error codes.
+
+@see RNotifier
+*/
+ {
+
+ RNotifier notif;
+ TInt r=notif.Connect();
+ if (r!=KErrNone)
+ return(KErrGeneral);
+ r=notif.InfoPrint(aDes);
+ notif.Close();
+ return(r);
+ }
+
+static const TUint32 CrcTab32[256] =
+ {
+ 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
+ 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
+ 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
+ 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
+ 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+ 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
+ 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
+ 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
+ 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
+ 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+ 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
+ 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
+ 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
+ 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
+ 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+ 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
+ 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
+ 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
+ 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
+ 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+ 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
+ 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
+ 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
+ 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
+ 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+ 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
+ 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
+ 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
+ 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
+ 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+ 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
+ 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
+ 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
+ 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
+ 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+ 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
+ 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
+ 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
+ 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
+ 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+ 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
+ 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
+ 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
+ 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
+ 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+ 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
+ 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
+ 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
+ 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
+ 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+ 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
+ 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
+ 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
+ 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
+ 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+ 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
+ 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
+ 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
+ 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
+ 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+ 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
+ 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
+ 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
+ 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
+ };
+
+/**
+Performs a CCITT CRC-32 checksum on the specified data.
+
+On return from this function, the referenced 32 bit integer contains the CRC
+value.
+
+@param aCrc A reference to a 32 bit integer to contain the CRC value.
+@param aPtr A pointer to the start of the data to be checksummed.
+@param aLength The length of the data to be checksummed.
+*/
+EXPORT_C void Mem::Crc32(TUint32& aCrc, const TAny* aPtr, TInt aLength)
+ {
+ const TUint8* p = (const TUint8*)aPtr;
+ const TUint8* q = p + aLength;
+ TUint32 crc = aCrc;
+ while (p < q)
+ crc = (crc >> 8) ^ CrcTab32[(crc ^ *p++) & 0xff];
+ aCrc = crc;
+ }