kernel/eka/klib/kdes8.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of the License "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // e32\klib\kdes8.cpp
       
    15 // 
       
    16 //
       
    17 
       
    18 #include <kernel/kernel.h>
       
    19 #include <kernel/kern_priv.h>
       
    20 
       
    21 /**
       
    22 Creates, and returns a pointer to, a new 8-bit heap descriptor.
       
    23 
       
    24 On construction, the heap descriptor is empty and has zero length.
       
    25 
       
    26 @param aMaxLength The requested maximum length of the descriptor.
       
    27                   This value must be non-negative otherwise the current thread
       
    28                   is panicked.
       
    29                   Note that the resulting heap cell size and, therefore, the
       
    30                   resulting maximum length of the descriptor may be larger than
       
    31                   requested.
       
    32 @return A pointer to the new 8-bit heap descriptor; NULL,
       
    33         if the descriptor cannot be created.
       
    34 
       
    35 @pre Calling thread must be in a critical section.
       
    36 @pre Interrupts must be enabled.
       
    37 @pre Kernel must be unlocked.
       
    38 @pre No fast mutex can be held.
       
    39 @pre Call in a thread context.
       
    40 @pre Can be used in a device driver.
       
    41      
       
    42 @post Calling thread is in a critical section.
       
    43        
       
    44 @panic KernLib 30, if the requested maximum length is negative.
       
    45 */
       
    46 EXPORT_C HBuf8* HBuf8::New(TInt aMaxLength)
       
    47 	{
       
    48 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"HBuf8::New(TInt aMaxLength)");
       
    49 	__ASSERT_ALWAYS(aMaxLength>=0,KL::Panic(KL::ETDes8MaxLengthNegative));
       
    50 	TAny* pM=Kern::Alloc(aMaxLength*sizeof(TUint8)+sizeof(TBufBase8));
       
    51 	if (pM)
       
    52 		new (pM) HBuf8(aMaxLength);
       
    53 	return (HBuf8*)pM;
       
    54 	}
       
    55 
       
    56 
       
    57 /**
       
    58 Creates, and returns a pointer to, a new 8-bit heap descriptor, and copies the
       
    59 content of the specified descriptor into it.
       
    60 
       
    61 Both the length and the maximum length of the new heap descriptor are set to
       
    62 the same value as the length of the specified descriptor.
       
    63 
       
    64 @param aDes The descriptor whose content is to be copied into the new heap
       
    65             descriptor.
       
    66             
       
    67 @pre Calling thread must be in a critical section.
       
    68 @pre Interrupts must be enabled.
       
    69 @pre Kernel must be unlocked.
       
    70 @pre No fast mutex can be held.
       
    71 @pre Call in a thread context.
       
    72 @pre Can be used in a device driver.
       
    73      
       
    74 @post Calling thread is in a critical section.
       
    75             
       
    76 @return  A pointer to the new 8-bit heap descriptor; NULL,
       
    77          if the descriptor cannot be created.
       
    78 */
       
    79 EXPORT_C HBuf8* HBuf8::New(const TDesC8& aDes)
       
    80 	{
       
    81 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"HBuf8::New(const TDesC8& aDes)");	
       
    82 	HBuf8* pB=HBuf8::New(aDes.Length());
       
    83 	if (pB)
       
    84 		pB->Copy(aDes);
       
    85 	return pB;
       
    86 	}
       
    87 
       
    88 
       
    89 /**
       
    90 Expands or contracts the heap descriptor.
       
    91 
       
    92 This is done by: creating a new heap descriptor, copying the original data
       
    93 into the new descriptor, and then deleting the original descriptor.
       
    94 
       
    95 @param aNewMax The requested maximum length of data that the new descriptor
       
    96                is to represent.This value must be non-negative and it must not
       
    97                be less than the length of any existing data, otherwise the
       
    98                current thread is panicked.
       
    99                Note that the resulting heap cell size and, therefore, the
       
   100                resulting maximum length of the descriptor may be larger than
       
   101                requested.
       
   102 
       
   103 @return A pointer to the new expanded or contracted 8-bit heap descriptor;
       
   104         the original descriptor is deleted. NULL, if the new 8-bit heap
       
   105         descriptor cannot be created - the original descriptor remains unchanged.
       
   106 
       
   107 @pre Calling thread must be in a critical section.
       
   108 @pre Interrupts must be enabled.
       
   109 @pre Kernel must be unlocked.
       
   110 @pre No fast mutex can be held.
       
   111 @pre Call in a thread context.
       
   112 @pre Can be used in a device driver.
       
   113      
       
   114 @post Calling thread is in a critical section.   
       
   115 
       
   116 @panic  KernLib 30, if the requested maximum length is negative.
       
   117 @panic  KernLib 26, if the requested length is less than the length of any existing data.
       
   118 */
       
   119 EXPORT_C HBuf8* HBuf8::ReAlloc(TInt aNewMax)
       
   120 	{
       
   121 	CHECK_PRECONDITIONS(MASK_THREAD_CRITICAL,"HBuf8::ReAlloc");	
       
   122 	__ASSERT_ALWAYS(aNewMax>=0,KL::Panic(KL::ETDes8MaxLengthNegative));
       
   123 	__ASSERT_ALWAYS(Length()<=aNewMax,KL::Panic(KL::ETDes8ReAllocTooSmall));
       
   124 	HBuf8* pNew=(HBuf8*)Kern::ReAlloc(this, aNewMax*sizeof(TUint8)+sizeof(TDes8) );
       
   125 	if(pNew)
       
   126 		pNew->iMaxLength=aNewMax;
       
   127 	return pNew;
       
   128 	}
       
   129 
       
   130 
       
   131 /**
       
   132 Copies the content of the source descriptor to the destination descriptor.
       
   133 
       
   134 If the current thread is a user thread, i.e. the mode in spsr_svc is 'User',
       
   135 then data is read using user mode privileges .
       
   136 
       
   137 @param aDest The destination descriptor.
       
   138 @param aSrc  The source descriptor.
       
   139 
       
   140 @panic KERN-COMMON 19, if aDest is not a valid descriptor type.
       
   141 @panic KERN-COMMON 23, if aSrc is longer that the maximum length of aDest.
       
   142 @panic KERN-EXEC   33, if aSrc is not a valid descriptor type.
       
   143 
       
   144 @pre Do not call from User thread if in a critical section.
       
   145 @pre Interrupts must be enabled.
       
   146 @pre Kernel must be unlocked.
       
   147 @pre No fast mutex can be held.
       
   148 @pre Call in a thread context.
       
   149 @pre Can be used in a device driver.
       
   150 
       
   151 @post The length of the destination descriptor is equal to the length of the source descriptor.
       
   152 */
       
   153 EXPORT_C void Kern::KUDesGet(TDes8& aDest, const TDesC8& aSrc)
       
   154 	{
       
   155 	CHECK_PRECONDITIONS(MASK_NO_CRITICAL_IF_USER|MASK_THREAD_STANDARD,"Kern::KUDesGet");	
       
   156 //ETDes8BadDescriptorType = 19
       
   157 //ETDes8Overflow = 23
       
   158 //EKUDesInfoInvalidType= 33
       
   159 	TInt ulen, umax;
       
   160 	TUint8* kptr=(TUint8*)aDest.Ptr();
       
   161 	const TUint8* uptr=Kern::KUDesInfo(aSrc, ulen, umax);
       
   162 	aDest.SetLength(ulen);
       
   163 	kumemget(kptr,uptr,ulen);
       
   164 	}
       
   165 
       
   166 
       
   167 /**
       
   168 Copies the content of the source descriptor to the destination descriptor.
       
   169 
       
   170 If the current thread is a user thread, i.e. the mode in spsr_svc is 'User',
       
   171 then data is written using user mode privileges.
       
   172 
       
   173 @param aDest The destination descriptor.
       
   174 @param aSrc  The source descriptor.
       
   175 
       
   176 @panic KERN-COMMON 19, if aSrc is not a valid descriptor type.
       
   177 @panic KERN-EXEC 33, if aDest is not a valid descriptor type.
       
   178 @panic KERN-EXEC 34, if aDest is not a modifiable descriptor type.
       
   179 @panic KERN-EXEC 35, if aSrc is longer that the maximum length of aDest.
       
   180 
       
   181 @pre  Do not call from User thread if in a critical section.
       
   182 @pre  Interrupts must be enabled.
       
   183 @pre  Kernel must be unlocked.
       
   184 @pre  No fast mutex can be held.
       
   185 @pre  Call in a thread context.
       
   186 @pre  Can be used in a device driver.
       
   187 
       
   188 @post The length of aDest is equal to the length of aSrc.
       
   189 @post If aDest is a TPtr type then its maximum length is equal its new length.
       
   190 */
       
   191 //ETDes8BadDescriptorType = 19
       
   192 //EKUDesInfoInvalidType = 33
       
   193 //EKUDesSetLengthInvalidType = 34
       
   194 //EKUDesSetLengthOverflow = 35
       
   195 EXPORT_C void Kern::KUDesPut(TDes8& aDest, const TDesC8& aSrc)
       
   196 	{
       
   197 	CHECK_PRECONDITIONS(MASK_NO_CRITICAL_IF_USER|MASK_THREAD_STANDARD,"Kern::KUDesPut");	
       
   198 	TInt ulen, umax;
       
   199 	TInt klen=aSrc.Length();
       
   200 	const TUint8* kptr=aSrc.Ptr();
       
   201 	TUint8* uptr=(TUint8*)Kern::KUDesInfo(aDest, ulen, umax);
       
   202 	Kern::KUDesSetLength(aDest, klen);
       
   203 	kumemput(uptr,kptr,klen);
       
   204 	}
       
   205 
       
   206 #ifndef __DES8_MACHINE_CODED__
       
   207 
       
   208 
       
   209 /**
       
   210 Gets information about the specified descriptor.
       
   211 
       
   212 If the current thread is a user thread, i.e. if the mode in spsr_svc is 'User',
       
   213 then the descriptor is read using user mode privileges.
       
   214 
       
   215 @param aSrc The descriptor for which information is to be fetched.
       
   216 @param aLength On return, set to the length of the descriptor.
       
   217 @param aMaxLength On return, set to the maximum length of the descriptor,
       
   218                   or -1 if the descriptor is not writable.
       
   219 
       
   220 @return Address of first byte in descriptor.
       
   221 
       
   222 @panic KERN-EXEC 33, if aSrc is not a valid descriptor type.
       
   223 
       
   224 @pre  Do not call from User thread if in a critical section.
       
   225 @pre  Interrupts must be enabled.
       
   226 @pre  Kernel must be unlocked.
       
   227 @pre  No fast mutex can be held.
       
   228 @pre  Call in a thread context.
       
   229 @pre  Can be used in a device driver.
       
   230 
       
   231 */
       
   232 EXPORT_C const TUint8* Kern::KUDesInfo(const TDesC8& aSrc, TInt& aLength, TInt& aMaxLength)
       
   233 	{
       
   234 	CHECK_PRECONDITIONS(MASK_NO_CRITICAL_IF_USER|MASK_THREAD_STANDARD,"Kern::KUDesInfo");	
       
   235 //EKUDesInfoInvalidType 33
       
   236 	TUint32 typelen;
       
   237 	kumemget32(&typelen,&aSrc,sizeof(typelen));
       
   238 	TInt type=typelen>>KShiftDesType;
       
   239 	aLength=typelen&KMaskDesLength;
       
   240 	aMaxLength=-1;	// if descriptor not writeable
       
   241 	const TUint8* p=NULL;
       
   242 	const TAny** pA=(const TAny**)&aSrc;
       
   243 	switch(type)
       
   244 		{
       
   245 		case EBufC: p=(const TUint8*)(pA+1); return p;
       
   246 		case EPtrC: kumemget32(&p,pA+1,sizeof(TAny*)); return p;
       
   247 		case EPtr: kumemget32(&p,pA+2,sizeof(TAny*)); break;
       
   248 		case EBuf: p=(const TUint8*)(pA+2); break;
       
   249 		case EBufCPtr: kumemget32(&p,pA+2,sizeof(TAny*)); p+=sizeof(TDesC8); break;
       
   250 		default: K::PanicKernExec(EKUDesInfoInvalidType);
       
   251 		}
       
   252 	kumemget32(&aMaxLength,pA+1,sizeof(TInt));
       
   253 	return p;
       
   254 	}
       
   255 
       
   256 
       
   257 /**
       
   258 Sets the length of the specified descriptor.
       
   259 
       
   260 If the current thread is a user thread, i.e. if the mode in spsr_svc is 'User',
       
   261 then the length is written using user mode privileges.
       
   262 
       
   263 @param aDes The descriptor.
       
   264 @param aLength The new descriptor length.
       
   265 
       
   266 @panic KERN-EXEC 34, if aDes is not a modifiable descriptor type.
       
   267 @panic KERN-EXEC 35, if aLength is longer that the maximum length of aDes.
       
   268 
       
   269 @pre  Do not call from User thread if in a critical section.
       
   270 @pre  Interrupts must be enabled.
       
   271 @pre  Kernel must be unlocked.
       
   272 @pre  No fast mutex can be held.
       
   273 @pre  Call in a thread context.
       
   274 @pre  Can be used in a device driver.
       
   275 
       
   276 @post The length of aDes is equal to aLength.
       
   277 @post If aDes is a TPtr type then its maximum length is equal its new length.
       
   278 */
       
   279 EXPORT_C void Kern::KUDesSetLength(TDes8& aDes, TInt aLength)
       
   280 	{
       
   281 	CHECK_PRECONDITIONS(MASK_NO_CRITICAL_IF_USER|MASK_THREAD_STANDARD,"Kern::KUDesSetLength");	
       
   282 //EKUDesSetLengthInvalidType=34
       
   283 //EKUDesSetLengthOverflow=35
       
   284 	TUint32 deshdr[2];
       
   285 	kumemget32(deshdr,&aDes,sizeof(TDes8));
       
   286 	TInt type=deshdr[0]>>KShiftDesType;
       
   287 	if (type!=EPtr && type!=EBuf && type!=EBufCPtr)
       
   288 		K::PanicKernExec(EKUDesSetLengthInvalidType);
       
   289 	if ((TUint32)aLength>deshdr[1])
       
   290 		K::PanicKernExec(EKUDesSetLengthOverflow);
       
   291 	deshdr[0]=(TUint32(type)<<KShiftDesType)|aLength;
       
   292 	deshdr[1]=aLength;
       
   293 	kumemput32(&aDes,deshdr,sizeof(TUint32));
       
   294 	if (type==EBufCPtr)
       
   295 		{
       
   296 		TUint32 bufcptr;
       
   297 		kumemget32(&bufcptr,(&aDes)+1,sizeof(bufcptr));
       
   298 		kumemput32((TAny*)bufcptr,deshdr+1,sizeof(TUint32));
       
   299 		}
       
   300 	}
       
   301 #endif
       
   302 
       
   303 
       
   304 #ifndef __DES8_MACHINE_CODED__
       
   305 /**
       
   306 Checks whether the specified name is a valid Kernel-side object name.
       
   307 
       
   308 A name is invalid, if it contains non-ascii characters, or any of
       
   309 the three characters: "*", "?", ":".
       
   310 
       
   311 @param  aName The name to be checked.
       
   312 
       
   313 @return KErrNone, if the name is valid; KErrBadName, if the name is invalid.
       
   314 
       
   315 @pre Calling thread can be either in a critical section or not.
       
   316 @pre Interrupts must be enabled.
       
   317 @pre Kernel must be unlocked.
       
   318 @pre No fast mutex can be held.
       
   319 @pre Call in a thread context.
       
   320 @pre Can be used in a device driver.
       
   321 */
       
   322 #ifndef __KERNEL_MODE__
       
   323 #error "TDesC is not 8-bit as __KERNEL_MODE__ is not defined (see e32cmn.h)"
       
   324 #endif
       
   325 EXPORT_C TInt Kern::ValidateName(const TDesC& aName)
       
   326 	{
       
   327 	CHECK_PRECONDITIONS(MASK_THREAD_STANDARD,"Kern::ValidateName");	
       
   328 	TUint8*	pName = const_cast<TUint8*>(aName.Ptr());
       
   329 	TInt	pNameLen = aName.Length();
       
   330 	for(;pNameLen;pName++,pNameLen--)
       
   331 		if(*pName>0x7e || *pName<0x20 || *pName=='*' || *pName=='?' || *pName==':')
       
   332 			return KErrBadName;
       
   333 	return KErrNone;
       
   334 	}
       
   335 
       
   336 extern "C" EXPORT_C TInt memicmp(const TAny* aLeft, const TAny* aRight, TUint aLength)
       
   337     {
       
   338 	const TUint8* l = (const TUint8*) aLeft;
       
   339 	const TUint8* r = (const TUint8*) aRight;
       
   340 	while (aLength--)
       
   341 		{
       
   342 		TInt lc = *l++;
       
   343 		TInt rc = *r++;
       
   344 		if (lc>='A' && lc<='Z') lc += ('a'-'A');
       
   345 		if (rc>='A' && rc<='Z') rc += ('a'-'A');
       
   346 		lc -= rc;
       
   347 		if (lc)
       
   348 			return lc;
       
   349 		}
       
   350 	return 0;
       
   351 	}
       
   352 #endif
       
   353 
       
   354 #ifdef __DES8_MACHINE_CODED__
       
   355 GLDEF_C void KUDesInfoPanicBadDesType()
       
   356 	{
       
   357 	K::PanicKernExec(EKUDesInfoInvalidType);
       
   358 	}
       
   359 
       
   360 GLDEF_C void KUDesSetLengthPanicBadDesType()
       
   361 	{
       
   362 	K::PanicKernExec(EKUDesSetLengthInvalidType);
       
   363 	}
       
   364 
       
   365 GLDEF_C void KUDesSetLengthPanicOverflow()
       
   366 	{
       
   367 	K::PanicKernExec(EKUDesSetLengthOverflow);
       
   368 	}
       
   369 #endif