--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kernel/eka/klib/kdes8.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,369 @@
+// Copyright (c) 1998-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\klib\kdes8.cpp
+//
+//
+
+#include <kernel/kernel.h>
+#include <kernel/kern_priv.h>
+
+/**
+Creates, and returns a pointer to, a new 8-bit heap descriptor.
+
+On construction, the heap descriptor is empty and has zero length.
+
+@param aMaxLength The requested maximum length of the descriptor.
+ This value must be non-negative otherwise the current thread
+ is panicked.
+ Note that the resulting heap cell size and, therefore, the
+ resulting maximum length of the descriptor may be larger than
+ requested.
+@return A pointer to the new 8-bit heap descriptor; NULL,
+ if the descriptor cannot be created.
+
+@pre Calling thread must be in a critical section.
+@pre Interrupts must be enabled.
+@pre Kernel must be unlocked.
+@pre No fast mutex can be held.
+@pre Call in a thread context.
+@pre Can be used in a device driver.
+
+@post Calling thread is in a critical section.
+
+@panic KernLib 30, if the requested maximum length is negative.
+*/
+EXPORT_C HBuf8* HBuf8::New(TInt aMaxLength)
+ {
+ CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"HBuf8::New(TInt aMaxLength)");
+ __ASSERT_ALWAYS(aMaxLength>=0,KL::Panic(KL::ETDes8MaxLengthNegative));
+ TAny* pM=Kern::Alloc(aMaxLength*sizeof(TUint8)+sizeof(TBufBase8));
+ if (pM)
+ new (pM) HBuf8(aMaxLength);
+ return (HBuf8*)pM;
+ }
+
+
+/**
+Creates, and returns a pointer to, a new 8-bit heap descriptor, and copies the
+content of the specified descriptor into it.
+
+Both the length and the maximum length of the new heap descriptor are set to
+the same value as the length of the specified descriptor.
+
+@param aDes The descriptor whose content is to be copied into the new heap
+ descriptor.
+
+@pre Calling thread must be in a critical section.
+@pre Interrupts must be enabled.
+@pre Kernel must be unlocked.
+@pre No fast mutex can be held.
+@pre Call in a thread context.
+@pre Can be used in a device driver.
+
+@post Calling thread is in a critical section.
+
+@return A pointer to the new 8-bit heap descriptor; NULL,
+ if the descriptor cannot be created.
+*/
+EXPORT_C HBuf8* HBuf8::New(const TDesC8& aDes)
+ {
+ CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"HBuf8::New(const TDesC8& aDes)");
+ HBuf8* pB=HBuf8::New(aDes.Length());
+ if (pB)
+ pB->Copy(aDes);
+ return pB;
+ }
+
+
+/**
+Expands or contracts the heap descriptor.
+
+This is done by: creating a new heap descriptor, copying the original data
+into the new descriptor, and then deleting the original descriptor.
+
+@param aNewMax The requested maximum length of data that the new descriptor
+ is to represent.This value must be non-negative and it must not
+ be less than the length of any existing data, otherwise the
+ current thread is panicked.
+ Note that the resulting heap cell size and, therefore, the
+ resulting maximum length of the descriptor may be larger than
+ requested.
+
+@return A pointer to the new expanded or contracted 8-bit heap descriptor;
+ the original descriptor is deleted. NULL, if the new 8-bit heap
+ descriptor cannot be created - the original descriptor remains unchanged.
+
+@pre Calling thread must be in a critical section.
+@pre Interrupts must be enabled.
+@pre Kernel must be unlocked.
+@pre No fast mutex can be held.
+@pre Call in a thread context.
+@pre Can be used in a device driver.
+
+@post Calling thread is in a critical section.
+
+@panic KernLib 30, if the requested maximum length is negative.
+@panic KernLib 26, if the requested length is less than the length of any existing data.
+*/
+EXPORT_C HBuf8* HBuf8::ReAlloc(TInt aNewMax)
+ {
+ CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"HBuf8::ReAlloc");
+ __ASSERT_ALWAYS(aNewMax>=0,KL::Panic(KL::ETDes8MaxLengthNegative));
+ __ASSERT_ALWAYS(Length()<=aNewMax,KL::Panic(KL::ETDes8ReAllocTooSmall));
+ HBuf8* pNew=(HBuf8*)Kern::ReAlloc(this, aNewMax*sizeof(TUint8)+sizeof(TDes8) );
+ if(pNew)
+ pNew->iMaxLength=aNewMax;
+ return pNew;
+ }
+
+
+/**
+Copies the content of the source descriptor to the destination descriptor.
+
+If the current thread is a user thread, i.e. the mode in spsr_svc is 'User',
+then data is read using user mode privileges .
+
+@param aDest The destination descriptor.
+@param aSrc The source descriptor.
+
+@panic KERN-COMMON 19, if aDest is not a valid descriptor type.
+@panic KERN-COMMON 23, if aSrc is longer that the maximum length of aDest.
+@panic KERN-EXEC 33, if aSrc is not a valid descriptor type.
+
+@pre Do not call from User thread if in a critical section.
+@pre Interrupts must be enabled.
+@pre Kernel must be unlocked.
+@pre No fast mutex can be held.
+@pre Call in a thread context.
+@pre Can be used in a device driver.
+
+@post The length of the destination descriptor is equal to the length of the source descriptor.
+*/
+EXPORT_C void Kern::KUDesGet(TDes8& aDest, const TDesC8& aSrc)
+ {
+ CHECK_PRECONDITIONS(MASK_NO_CRITICAL_IF_USER|MASK_THREAD_STANDARD,"Kern::KUDesGet");
+//ETDes8BadDescriptorType = 19
+//ETDes8Overflow = 23
+//EKUDesInfoInvalidType= 33
+ TInt ulen, umax;
+ TUint8* kptr=(TUint8*)aDest.Ptr();
+ const TUint8* uptr=Kern::KUDesInfo(aSrc, ulen, umax);
+ aDest.SetLength(ulen);
+ kumemget(kptr,uptr,ulen);
+ }
+
+
+/**
+Copies the content of the source descriptor to the destination descriptor.
+
+If the current thread is a user thread, i.e. the mode in spsr_svc is 'User',
+then data is written using user mode privileges.
+
+@param aDest The destination descriptor.
+@param aSrc The source descriptor.
+
+@panic KERN-COMMON 19, if aSrc is not a valid descriptor type.
+@panic KERN-EXEC 33, if aDest is not a valid descriptor type.
+@panic KERN-EXEC 34, if aDest is not a modifiable descriptor type.
+@panic KERN-EXEC 35, if aSrc is longer that the maximum length of aDest.
+
+@pre Do not call from User thread if in a critical section.
+@pre Interrupts must be enabled.
+@pre Kernel must be unlocked.
+@pre No fast mutex can be held.
+@pre Call in a thread context.
+@pre Can be used in a device driver.
+
+@post The length of aDest is equal to the length of aSrc.
+@post If aDest is a TPtr type then its maximum length is equal its new length.
+*/
+//ETDes8BadDescriptorType = 19
+//EKUDesInfoInvalidType = 33
+//EKUDesSetLengthInvalidType = 34
+//EKUDesSetLengthOverflow = 35
+EXPORT_C void Kern::KUDesPut(TDes8& aDest, const TDesC8& aSrc)
+ {
+ CHECK_PRECONDITIONS(MASK_NO_CRITICAL_IF_USER|MASK_THREAD_STANDARD,"Kern::KUDesPut");
+ TInt ulen, umax;
+ TInt klen=aSrc.Length();
+ const TUint8* kptr=aSrc.Ptr();
+ TUint8* uptr=(TUint8*)Kern::KUDesInfo(aDest, ulen, umax);
+ Kern::KUDesSetLength(aDest, klen);
+ kumemput(uptr,kptr,klen);
+ }
+
+#ifndef __DES8_MACHINE_CODED__
+
+
+/**
+Gets information about the specified descriptor.
+
+If the current thread is a user thread, i.e. if the mode in spsr_svc is 'User',
+then the descriptor is read using user mode privileges.
+
+@param aSrc The descriptor for which information is to be fetched.
+@param aLength On return, set to the length of the descriptor.
+@param aMaxLength On return, set to the maximum length of the descriptor,
+ or -1 if the descriptor is not writable.
+
+@return Address of first byte in descriptor.
+
+@panic KERN-EXEC 33, if aSrc is not a valid descriptor type.
+
+@pre Do not call from User thread if in a critical section.
+@pre Interrupts must be enabled.
+@pre Kernel must be unlocked.
+@pre No fast mutex can be held.
+@pre Call in a thread context.
+@pre Can be used in a device driver.
+
+*/
+EXPORT_C const TUint8* Kern::KUDesInfo(const TDesC8& aSrc, TInt& aLength, TInt& aMaxLength)
+ {
+ CHECK_PRECONDITIONS(MASK_NO_CRITICAL_IF_USER|MASK_THREAD_STANDARD,"Kern::KUDesInfo");
+//EKUDesInfoInvalidType 33
+ TUint32 typelen;
+ kumemget32(&typelen,&aSrc,sizeof(typelen));
+ TInt type=typelen>>KShiftDesType;
+ aLength=typelen&KMaskDesLength;
+ aMaxLength=-1; // if descriptor not writeable
+ const TUint8* p=NULL;
+ const TAny** pA=(const TAny**)&aSrc;
+ switch(type)
+ {
+ case EBufC: p=(const TUint8*)(pA+1); return p;
+ case EPtrC: kumemget32(&p,pA+1,sizeof(TAny*)); return p;
+ case EPtr: kumemget32(&p,pA+2,sizeof(TAny*)); break;
+ case EBuf: p=(const TUint8*)(pA+2); break;
+ case EBufCPtr: kumemget32(&p,pA+2,sizeof(TAny*)); p+=sizeof(TDesC8); break;
+ default: K::PanicKernExec(EKUDesInfoInvalidType);
+ }
+ kumemget32(&aMaxLength,pA+1,sizeof(TInt));
+ return p;
+ }
+
+
+/**
+Sets the length of the specified descriptor.
+
+If the current thread is a user thread, i.e. if the mode in spsr_svc is 'User',
+then the length is written using user mode privileges.
+
+@param aDes The descriptor.
+@param aLength The new descriptor length.
+
+@panic KERN-EXEC 34, if aDes is not a modifiable descriptor type.
+@panic KERN-EXEC 35, if aLength is longer that the maximum length of aDes.
+
+@pre Do not call from User thread if in a critical section.
+@pre Interrupts must be enabled.
+@pre Kernel must be unlocked.
+@pre No fast mutex can be held.
+@pre Call in a thread context.
+@pre Can be used in a device driver.
+
+@post The length of aDes is equal to aLength.
+@post If aDes is a TPtr type then its maximum length is equal its new length.
+*/
+EXPORT_C void Kern::KUDesSetLength(TDes8& aDes, TInt aLength)
+ {
+ CHECK_PRECONDITIONS(MASK_NO_CRITICAL_IF_USER|MASK_THREAD_STANDARD,"Kern::KUDesSetLength");
+//EKUDesSetLengthInvalidType=34
+//EKUDesSetLengthOverflow=35
+ TUint32 deshdr[2];
+ kumemget32(deshdr,&aDes,sizeof(TDes8));
+ TInt type=deshdr[0]>>KShiftDesType;
+ if (type!=EPtr && type!=EBuf && type!=EBufCPtr)
+ K::PanicKernExec(EKUDesSetLengthInvalidType);
+ if ((TUint32)aLength>deshdr[1])
+ K::PanicKernExec(EKUDesSetLengthOverflow);
+ deshdr[0]=(TUint32(type)<<KShiftDesType)|aLength;
+ deshdr[1]=aLength;
+ kumemput32(&aDes,deshdr,sizeof(TUint32));
+ if (type==EBufCPtr)
+ {
+ TUint32 bufcptr;
+ kumemget32(&bufcptr,(&aDes)+1,sizeof(bufcptr));
+ kumemput32((TAny*)bufcptr,deshdr+1,sizeof(TUint32));
+ }
+ }
+#endif
+
+
+#ifndef __DES8_MACHINE_CODED__
+/**
+Checks whether the specified name is a valid Kernel-side object name.
+
+A name is invalid, if it contains non-ascii characters, or any of
+the three characters: "*", "?", ":".
+
+@param aName The name to be checked.
+
+@return KErrNone, if the name is valid; KErrBadName, if the name is invalid.
+
+@pre Calling thread can be either in a critical section or not.
+@pre Interrupts must be enabled.
+@pre Kernel must be unlocked.
+@pre No fast mutex can be held.
+@pre Call in a thread context.
+@pre Can be used in a device driver.
+*/
+#ifndef __KERNEL_MODE__
+#error "TDesC is not 8-bit as __KERNEL_MODE__ is not defined (see e32cmn.h)"
+#endif
+EXPORT_C TInt Kern::ValidateName(const TDesC& aName)
+ {
+ CHECK_PRECONDITIONS(MASK_THREAD_STANDARD,"Kern::ValidateName");
+ TUint8* pName = const_cast<TUint8*>(aName.Ptr());
+ TInt pNameLen = aName.Length();
+ for(;pNameLen;pName++,pNameLen--)
+ if(*pName>0x7e || *pName<0x20 || *pName=='*' || *pName=='?' || *pName==':')
+ return KErrBadName;
+ return KErrNone;
+ }
+
+extern "C" EXPORT_C TInt memicmp(const TAny* aLeft, const TAny* aRight, TUint aLength)
+ {
+ const TUint8* l = (const TUint8*) aLeft;
+ const TUint8* r = (const TUint8*) aRight;
+ while (aLength--)
+ {
+ TInt lc = *l++;
+ TInt rc = *r++;
+ if (lc>='A' && lc<='Z') lc += ('a'-'A');
+ if (rc>='A' && rc<='Z') rc += ('a'-'A');
+ lc -= rc;
+ if (lc)
+ return lc;
+ }
+ return 0;
+ }
+#endif
+
+#ifdef __DES8_MACHINE_CODED__
+GLDEF_C void KUDesInfoPanicBadDesType()
+ {
+ K::PanicKernExec(EKUDesInfoInvalidType);
+ }
+
+GLDEF_C void KUDesSetLengthPanicBadDesType()
+ {
+ K::PanicKernExec(EKUDesSetLengthInvalidType);
+ }
+
+GLDEF_C void KUDesSetLengthPanicOverflow()
+ {
+ K::PanicKernExec(EKUDesSetLengthOverflow);
+ }
+#endif