authenticationservices/authenticationserver/source/common/authexpression.cpp
changeset 29 ece3df019add
equal deleted inserted replaced
19:cd501b96611d 29:ece3df019add
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description: 
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include "authcommon_impl.h"
       
    20 #include <scs/cleanuputils.h>
       
    21 
       
    22 using namespace AuthServer;
       
    23 
       
    24 const TInt CAuthExpressionImpl::KVersion = 1;
       
    25 
       
    26 // -------- TAuthExpressionWrapper --------
       
    27 
       
    28 
       
    29 TAuthExpressionWrapper::TAuthExpressionWrapper(CAuthExpression* aExpression)
       
    30 /**
       
    31 	This constructor stores the supplied expression pointer.
       
    32 	
       
    33 	@param	aExpression		A pointer to the supplied expression
       
    34 							is stored in the TAuthExpressionWrapper
       
    35 							object.  On exit, this object owns
       
    36 							the expression.
       
    37  */
       
    38 :	iPtr(aExpression)
       
    39 	{
       
    40 	// empty.
       
    41 	}
       
    42 
       
    43 
       
    44 TAuthExpressionWrapper::TAuthExpressionWrapper(TAuthPluginType aType)
       
    45 /**
       
    46 	Allocates a new instance of CAuthExpressionImpl which
       
    47 	describes the supplied plugin type.  If there is not
       
    48 	enough memory, the pointer is NULL on exit.
       
    49 	
       
    50 	@param	aType			Plugin type used to create new instance
       
    51 							of CAuthExpressionImpl.
       
    52  */
       
    53 :	iPtr(new CAuthExpressionImpl(aType))
       
    54 	{
       
    55 	// empty.
       
    56 	}
       
    57 
       
    58 
       
    59 TAuthExpressionWrapper::TAuthExpressionWrapper(TPluginId aPluginId)
       
    60 /**
       
    61 	Allocates a new instance of CAuthExpressionImpl which
       
    62 	describes the supplied plugin ID.  If there is not
       
    63 	enough memory, the pointer is NULL on exit.
       
    64 	
       
    65 	@param	aPluginId		Value which describes a specific plugin.
       
    66  */
       
    67 :	iPtr(new CAuthExpressionImpl(aPluginId))
       
    68 	{
       
    69 	// empty.
       
    70 	}
       
    71 
       
    72 TAuthExpressionWrapper::TAuthExpressionWrapper()
       
    73 /**
       
    74 	Allocates a new instance of CAuthExpressionImpl which
       
    75 	describes the default plugin ID.  If there is not
       
    76 	enough memory, the pointer is NULL on exit.
       
    77 	
       
    78  */
       
    79 :	iPtr(new CAuthExpressionImpl())
       
    80 	{
       
    81 	// empty.
       
    82 	}
       
    83 
       
    84 // -------- factory functions --------
       
    85 
       
    86 
       
    87 static CAuthExpressionImpl* AuthComb(
       
    88 	CAuthExpressionImpl::TType aType, CAuthExpressionImpl* aLeft, CAuthExpressionImpl* aRight);
       
    89 
       
    90 
       
    91 EXPORT_C TAuthExpressionWrapper AuthServer::AuthExpr(TAuthPluginType aType)
       
    92 /**
       
    93 	Returns a wrapper around a new authentication expression.
       
    94 	
       
    95 	@param	aType			Identifies a type of plugin.
       
    96 	@return					Wrapper object for an instance
       
    97 							of CAuthExpressionImpl.  The authentication
       
    98 							expression is allocated on the heap,
       
    99 							and is NULL if there is not
       
   100 							enough memory.
       
   101  */
       
   102 	{
       
   103 	return TAuthExpressionWrapper(aType);
       
   104 	}
       
   105 
       
   106 
       
   107 EXPORT_C TAuthExpressionWrapper AuthServer::AuthExpr(TPluginId aPluginId)
       
   108 /**
       
   109 	Returns a wrapper around a new authentication expression.
       
   110 	
       
   111 	@param	aPluginId		Identifies a specific plugin.
       
   112 	@return					Wrapper object for an instance
       
   113 							of CAuthExpressionImpl.  The authentication
       
   114 							expression is allocated on the heap,
       
   115 							and is NULL if there is not
       
   116 							enough memory.
       
   117  */
       
   118 	{
       
   119 	return TAuthExpressionWrapper(aPluginId);
       
   120 	}
       
   121 
       
   122 EXPORT_C TAuthExpressionWrapper AuthServer::AuthExpr()
       
   123 /**
       
   124 	Returns a wrapper around a new authentication expression.
       
   125 	
       
   126 	@return					Wrapper object for an instance
       
   127 							of CAuthExpressionImpl.  The authentication
       
   128 							expression is allocated on the heap,
       
   129 							and is NULL if there is not
       
   130 							enough memory.
       
   131  */
       
   132 	{
       
   133 	return TAuthExpressionWrapper();
       
   134 	}
       
   135 
       
   136 EXPORT_C TAuthExpressionWrapper AuthServer::AuthOr(CAuthExpression* aLeft, CAuthExpression* aRight)
       
   137 /**
       
   138 	Allocate a CAuthExpressionImpl node which combines the supplied
       
   139 	left and right nodes as an OR operation.
       
   140 	
       
   141 	If either aLeft or aRight are NULL, or this operation fails
       
   142 	to allocate the required memory, then any allocated memory
       
   143 	is cleaned up NULL is returned.
       
   144 	
       
   145 	@param	aLeft			Left node.  This must be an instance
       
   146 							of CAuthExpresionImpl.
       
   147 	@param	aRight			Right node.  This must be an instance
       
   148 							of CAuthExpresionImpl.
       
   149 	@return					New wrapper around CAuthExpression, NULL
       
   150 							if could not allocate, or if either the
       
   151 							supplied nodes were NULL.
       
   152  */
       
   153 	{
       
   154 	CAuthExpressionImpl* leftImpl = static_cast<CAuthExpressionImpl*>(aLeft);
       
   155 	CAuthExpressionImpl* rightImpl = static_cast<CAuthExpressionImpl*>(aRight);
       
   156 	return AuthComb(CAuthExpressionImpl::EOr, leftImpl, rightImpl);
       
   157 	}
       
   158 
       
   159 
       
   160 EXPORT_C TAuthExpressionWrapper AuthServer::AuthAnd(CAuthExpression* aLeft, CAuthExpression* aRight)
       
   161 /**
       
   162 	Allocate a CAuthExpressionImpl node which combines the supplied
       
   163 	left and right nodes as an AND operation.
       
   164 	
       
   165 	If either aLeft or aRight are NULL, or this operation fails
       
   166 	to allocate the required memory, then the subexpressions are
       
   167 	deleted and this function returns NULL.
       
   168 	
       
   169 	@param	aLeft			Left node.
       
   170 	@param	aRight			Right node.
       
   171 	@return					New wrapper around CAuthExpression, NULL
       
   172 							if could not allocate, or if either the
       
   173 							supplied nodes were NULL.
       
   174 	@see AuthOr
       
   175  */
       
   176 	{
       
   177 	CAuthExpressionImpl* leftImpl = static_cast<CAuthExpressionImpl*>(aLeft);
       
   178 	CAuthExpressionImpl* rightImpl = static_cast<CAuthExpressionImpl*>(aRight);
       
   179 	return AuthComb(CAuthExpressionImpl::EAnd, leftImpl, rightImpl);
       
   180 	}
       
   181 
       
   182 
       
   183 static CAuthExpressionImpl* AuthComb(
       
   184 	CAuthExpressionImpl::TType aType, CAuthExpressionImpl* aLeft, CAuthExpressionImpl* aRight)
       
   185 /**
       
   186 	Helper function for AuthOr and AuthAnd.  This function
       
   187 	allocates the combining node, storing the combining method (AND
       
   188 	or OR) and pointers to the left and right nodes.
       
   189 	
       
   190 	If aLeft or aRight are NULL on entry, or this function cannot
       
   191 	allocate the required memory, then any previously allocated nodes
       
   192 	are freed, and this function returns NULL.
       
   193 	
       
   194 	@param	aType			Type of expression, AND/OR
       
   195 	@param	aLeft			Left node.
       
   196 	@param	aRight			Right node.
       
   197 	@return					New wrapper around CAuthExpression, NULL
       
   198 							if could not allocate, or if either the
       
   199 							supplied nodes were NULL.
       
   200 	@see AuthAnd
       
   201 	@see AuthOr
       
   202  */
       
   203 	{
       
   204 	CAuthExpressionImpl* compound = 0;
       
   205 	
       
   206 	if (aLeft == 0 || aRight == 0)
       
   207 		goto failed;
       
   208 	
       
   209 	compound = new CAuthExpressionImpl(aType, aLeft, aRight);
       
   210 	if (compound == 0)
       
   211 		goto failed;
       
   212 	
       
   213 	return compound;
       
   214 	
       
   215 failed:
       
   216 	delete aLeft;
       
   217 	delete aRight;
       
   218 	
       
   219 	return 0;
       
   220 	}
       
   221 
       
   222 
       
   223 // -------- TSizeStream --------
       
   224 
       
   225 
       
   226 EXPORT_C void TSizeStream::DoWriteL(const TAny* /* aPtr */, TInt aLength)
       
   227 /**
       
   228 	Override MStreamBuf by incrementing the
       
   229 	accumulated size by aLength.
       
   230 	
       
   231 	@param	aLength			Length of data to write to stream.
       
   232  */
       
   233 	{
       
   234 	iSize += aLength;
       
   235 	}
       
   236 
       
   237 
       
   238 // -------- CAuthExpressionImpl --------
       
   239 
       
   240 
       
   241 #ifdef _DEBUG
       
   242 #define VAR_FOLLOWS(___c, ___v1, ___v2)	\
       
   243 	(_FOFF(___c, ___v2) >= _FOFF(___c, ___v1) + sizeof(___c::___v1))
       
   244 #endif
       
   245 
       
   246 
       
   247 CAuthExpressionImpl::CAuthExpressionImpl(TAuthPluginType aType)
       
   248 :	iType(EPluginType),
       
   249 	iPluginType(aType)
       
   250 /**
       
   251 	Initialise this leaf node authentication expression
       
   252 	as describing a plugin type.
       
   253 	
       
   254 	@param	aType			Identifies a type of plugin.
       
   255 	@panic AUTHEXPR 16		This constructed object is internally
       
   256 							inconsistent (debug only.)
       
   257  */
       
   258 	{
       
   259 #ifdef _DEBUG
       
   260 	// non-aligned value to detect invalid node pointers
       
   261 	__ASSERT_COMPILE(VAR_FOLLOWS(CAuthExpressionImpl, iPluginType, iComb.iRight));
       
   262 	iComb.iRight = (CAuthExpressionImpl*)0xB51DE;
       
   263 #endif
       
   264 
       
   265 	__ASSERT_DEBUG(Invariant(), Panic(ECtTyInvariant));
       
   266 	}
       
   267 
       
   268 
       
   269 CAuthExpressionImpl::CAuthExpressionImpl(TPluginId aPluginId)
       
   270 /**
       
   271 	Initialise this leaf node authentication expression
       
   272 	as describing a specific plugin.
       
   273 	
       
   274 	@param	aPluginId		Identifies a specific plugin.
       
   275 	@panic	AUTHEXPR 32		This constructed object is internally
       
   276 							inconsistent (debug only.)
       
   277  */
       
   278 :	iType(EPluginId),
       
   279 	iPluginId(aPluginId)
       
   280 	{
       
   281 #ifdef _DEBUG
       
   282 	// non-aligned value to detect invalid node pointers
       
   283 	__ASSERT_COMPILE(VAR_FOLLOWS(CAuthExpressionImpl, iPluginId, iComb.iRight));
       
   284 	iComb.iRight = (CAuthExpressionImpl*)0xB51DE;
       
   285 #endif
       
   286 
       
   287 	__ASSERT_DEBUG(Invariant(), Panic(ECtIdInvariant));
       
   288 	}
       
   289 
       
   290 CAuthExpressionImpl::CAuthExpressionImpl()
       
   291 /**
       
   292 	Initialise this leaf node authentication expression
       
   293 	as describing a specific plugin.
       
   294 
       
   295 	@panic	AUTHEXPR 32		This constructed object is internally
       
   296 							inconsistent (debug only.)
       
   297  */
       
   298 :	iType(ENull)
       
   299 	{
       
   300 #ifdef _DEBUG
       
   301 	// non-aligned value to detect invalid node pointers
       
   302 	__ASSERT_COMPILE(VAR_FOLLOWS(CAuthExpressionImpl, iPluginId, iComb.iRight));
       
   303 	iComb.iRight = (CAuthExpressionImpl*)0xB51DE;
       
   304 #endif
       
   305 
       
   306 	__ASSERT_DEBUG(Invariant(), Panic(ECtIdInvariant));
       
   307 
       
   308 	}
       
   309 
       
   310 
       
   311 CAuthExpressionImpl::CAuthExpressionImpl(TType aType, CAuthExpressionImpl* aLeft, CAuthExpressionImpl* aRight)
       
   312 /**
       
   313 	Initialise a complex - AND or OR - expression.
       
   314 	
       
   315 	@param	aType			The type of combination.  The only
       
   316 							allowed values are EAnd and EOr.
       
   317 	@param	aLeft			Left expression.  This cannot be NULL.
       
   318 	@param	aRight			Right expression.  This cannot be NULL.
       
   319 	@panic	AUTHEXPR 48		Called with expression type that was
       
   320 							neither AND nor OR (debug only.)
       
   321 	@panic	AUTHEXPR 49		Called with NULL left node (debug only.)
       
   322 	@panic	AUTHEXPR 50		Called with NULL right node (debug only.)
       
   323 	@panic	AUTHEXPR 51		This object is internally inconsistent
       
   324 							after construction (debug only.)
       
   325  */
       
   326 :	iType(aType)
       
   327 	{
       
   328 	__ASSERT_DEBUG(aType == EAnd || aType == EOr, Panic(ECt2BadComb));
       
   329 	__ASSERT_DEBUG(aLeft != 0, Panic(ECt2NullLeft));
       
   330 	__ASSERT_DEBUG(aRight != 0, Panic(ECt2NullRight));
       
   331 	
       
   332 	iComb.iLeft = aLeft;
       
   333 	iComb.iRight = aRight;
       
   334 	aLeft->iParent = aRight->iParent = this;
       
   335 	
       
   336 	__ASSERT_DEBUG(Invariant(), Panic(ECt2Invariant));
       
   337 	}
       
   338 
       
   339 
       
   340 CAuthExpressionImpl::~CAuthExpressionImpl()
       
   341 /**
       
   342 	Deletes resources used by this expression.  If this is a complex
       
   343 	expression then it deletes the subexpression nodes.
       
   344  */
       
   345 	{
       
   346 	// by construction iType is always correctly initialized
       
   347 	// before this function is called.
       
   348 	if (iType == EAnd || iType == EOr)
       
   349 		{
       
   350 		delete iComb.iLeft;
       
   351 		delete iComb.iRight;
       
   352 		}
       
   353 	}
       
   354 
       
   355 
       
   356 EXPORT_C void CAuthExpressionImpl::ExternalizeL(RWriteStream& aWriteStream) const
       
   357 /**
       
   358 	Write a persistent version of this object to the supplied
       
   359 	stream.  This function is used to transfer the expression
       
   360 	to the authentication server.
       
   361 	
       
   362 	@param	aWriteStream	Stream to write object to.
       
   363 	@panic	AUTHEXPR 160	This object is internally inconsistent
       
   364 							when this function is called.
       
   365  */
       
   366 	{
       
   367 	__ASSERT_DEBUG(Invariant(), Panic(EExtInvariant));
       
   368 	
       
   369 	aWriteStream.WriteInt8L(KVersion);
       
   370 	Externalize2L(aWriteStream);
       
   371 	}
       
   372 
       
   373 
       
   374 void CAuthExpressionImpl::Externalize2L(RWriteStream& aWriteStream) const
       
   375 /**
       
   376 	Helper function for ExternalizeL.  This function writes
       
   377 	a persistent version of this expression object, including
       
   378 	any subexpressions, to the supplied stream.
       
   379 	
       
   380 	@param	aWriteStream	Stream to write object to.
       
   381 	@panic	AUTHEXPR 144	This object is internally inconsistent
       
   382 							when this function is called.
       
   383  */
       
   384 	{
       
   385 	__ASSERT_DEBUG(Invariant(), Panic(EExtInvariant));
       
   386 	
       
   387 	aWriteStream.WriteInt8L(iType);
       
   388 	
       
   389 	switch (iType)
       
   390 		{
       
   391 	case EAnd:
       
   392 	case EOr:
       
   393 		iComb.iLeft->Externalize2L(aWriteStream);
       
   394 		iComb.iRight->Externalize2L(aWriteStream);
       
   395 		break;
       
   396 	
       
   397 	case EPluginId:
       
   398 		aWriteStream.WriteInt32L(iPluginId);
       
   399 		break;
       
   400 	
       
   401 	case EPluginType:
       
   402 		aWriteStream.WriteInt32L(iPluginType);
       
   403 		break;
       
   404 		
       
   405 	case ENull:
       
   406 		aWriteStream.WriteInt32L(iPluginId);
       
   407 		break;
       
   408 	default:
       
   409 		// this case should not be reached because this
       
   410 		// object has passed the invariant.
       
   411 		break;
       
   412 		}
       
   413 	}
       
   414 
       
   415 
       
   416 // restore the encoded authentication expression
       
   417 
       
   418 
       
   419 EXPORT_C CAuthExpressionImpl* CAuthExpressionImpl::NewL(RReadStream& aReadStream)
       
   420 /**
       
   421 	Factory function reconstructs an authentication
       
   422 	expression from the supplied stream.
       
   423 	
       
   424 	@param	aReadStream		Stream containing externalized
       
   425 							authentication expression.  This must
       
   426 							have been generated with CAuthExpressionImpl::ExternalizeL.	
       
   427 	@return					Authorisation expression internalized
       
   428 							from the supplied stream.
       
   429 	@leave KErrNoMemory		Not enough memory to reconstruct the expression.
       
   430 	@leave KErrInternalizeInvalidAuthExpr The supplied stream does not
       
   431 							describe a valid authentication expression.
       
   432 	@leave KErrAuthServUnsupportedExprVersion The supplied stream
       
   433 							was created with a later version of CAuthExpressionImpl.
       
   434 	@see CAuthExpressionImpl::ExternalizeL
       
   435  */
       
   436 	{
       
   437 	TInt8 ver = aReadStream.ReadInt8L();
       
   438 	if (ver > KVersion)
       
   439 		User::Leave(KErrAuthServUnsupportedExprVersion);
       
   440 	
       
   441 	return New2L(aReadStream);
       
   442 	}
       
   443 	
       
   444 CAuthExpressionImpl* CAuthExpressionImpl::New2L(RReadStream& aReadStream)
       
   445 /**
       
   446 	Helper function for NewL.  This recursively constructs the
       
   447 	authentication expression after NewL has checked that it
       
   448 	supports the encoded version.
       
   449 	
       
   450 	@param	aReadStream		Stream containing externalized
       
   451 							authentication expression.  This must
       
   452 							have been generated with CAuthExpressionImpl::ExternalizeL.	
       
   453 	@return					Authorisation expression internalized
       
   454 							from the supplied stream.
       
   455 	@leave KErrNoMemory		Not enough memory to reconstruct the expression.
       
   456 	@leave KErrInternalizeInvalidAuthExpr The supplied stream does not
       
   457 							describe a valid authentication expression.
       
   458 	@see CAuthExpressionImpl::ExternalizeL
       
   459  */
       
   460 	{
       
   461 	CAuthExpressionImpl::TType t;
       
   462 	t = static_cast<CAuthExpressionImpl::TType>(aReadStream.ReadInt8L());
       
   463 	
       
   464 	switch(t)
       
   465 		{
       
   466 	case CAuthExpressionImpl::EAnd:
       
   467 	case CAuthExpressionImpl::EOr:
       
   468 		{
       
   469 		CAuthExpressionImpl* left = CAuthExpressionImpl::New2L(aReadStream);
       
   470 		CleanupStack::PushL(left);
       
   471 		CAuthExpressionImpl* right = CAuthExpressionImpl::New2L(aReadStream);
       
   472 		CleanupStack::PushL(right);
       
   473 		CAuthExpressionImpl* complex = new(ELeave) CAuthExpressionImpl(t, left, right);
       
   474 		CleanupStack::Pop(2, left);	// complex now owns left and right
       
   475 		return complex;
       
   476 		}
       
   477 	
       
   478 	case CAuthExpressionImpl::EPluginId:
       
   479 		return new(ELeave) CAuthExpressionImpl(
       
   480 			static_cast<TPluginId>(aReadStream.ReadInt32L()));
       
   481 	
       
   482 	case CAuthExpressionImpl::EPluginType:
       
   483 		return new(ELeave) CAuthExpressionImpl(
       
   484 			static_cast<TAuthPluginType>(aReadStream.ReadInt32L()));
       
   485 	
       
   486 		
       
   487 	case CAuthExpressionImpl::ENull:
       
   488 		return new(ELeave) CAuthExpressionImpl();	
       
   489 	
       
   490 	default:
       
   491 		User::Leave(KErrAuthServInvalidInternalizeExpr);
       
   492 		return 0;	// avoid 'return value expected' warning
       
   493 		}
       
   494 	}
       
   495 	
       
   496 /**
       
   497   Helper function which converts the string into a form that can 
       
   498   be processed as tokens by TLex.Essentially, this method parses and appends
       
   499   space in the input string when delimiters("(",")","&" and "|") are
       
   500   encountered, consequenty the resultant string thus obtained can be parsed
       
   501   using TLex.
       
   502  
       
   503   @param	aStringToBeProcessed	string to be processed.	
       
   504   @param	aResultantString		a buffer which does not already own any allocated memory, and is populated 
       
   505   									with a string resulting from processing aStringToBeProcessed.
       
   506  	 									
       
   507  */ 	
       
   508 
       
   509 EXPORT_C void CAuthExpressionImpl::InsertSpaceBetweenOperatorsL(const TDesC& aStringToBeProcessed, RBuf& aResultantString)
       
   510 	{
       
   511 	TChar ch = 0;
       
   512 	_LIT(KSeparator, " ");
       
   513 	HBufC* strBuffer = HBufC::NewLC(KMaxBufferSize);
       
   514 	TPtr strPtr(strBuffer->Des());
       
   515 	
       
   516 	// length of 2 KSeparator and 1 ch.
       
   517 	const TInt KAddLength = 3;
       
   518 	
       
   519 	for(TInt i = 0; i < aStringToBeProcessed.Length(); ++i)
       
   520 		{
       
   521 		ch = aStringToBeProcessed[i];
       
   522 		
       
   523 		// check whether appending 3 characters(2 KSeparator and 1 ch) to
       
   524 		// aResultantAliasString exceeds the Maxlength.
       
   525 		TInt resultingLen = strPtr.Length() + KAddLength;
       
   526 		if(resultingLen > KMaxBufferSize)
       
   527 			{
       
   528 			strBuffer->ReAllocL(resultingLen);
       
   529 			}
       
   530 				
       
   531 		if(ch == '(' || ch == ')' || ch == '&' || ch == '|')
       
   532 			{
       
   533 			strPtr.Append(KSeparator);
       
   534 			strPtr.Append(ch);
       
   535 			strPtr.Append(KSeparator);
       
   536 			}
       
   537 			
       
   538 		else
       
   539 			{
       
   540 			strPtr.Append(ch);
       
   541 			}
       
   542 		}
       
   543 	
       
   544 	CleanupStack::Pop(strBuffer);
       
   545 	aResultantString.Assign(strBuffer);
       
   546 	}
       
   547 		
       
   548 /**
       
   549   Creates CAuthExpression object from a string defining an authentication.
       
   550   strength.The ownership of CAuthExpression object is transferred to the caller.
       
   551  
       
   552   @param aStrengthAliasString a string defining an authentication.
       
   553   strength obtained from the authserver cenrep file.
       
   554  
       
   555   @return CAuthExpression object.
       
   556  
       
   557   @leave KErrAuthServInvalidAliasStringExpression, when aStrengthAliasString contains tokens other than pluginId, pluginType
       
   558   and operators '&', '|', '(' and ')'		
       
   559  
       
   560  */  
       
   561     
       
   562  EXPORT_C CAuthExpression* CAuthExpressionImpl::CreateAuthExprObjectL(const TDesC& aStrengthAliasString)
       
   563  	{
       
   564    	RBuf resultantAliasString;
       
   565    	CleanupClosePushL(resultantAliasString);
       
   566      	
       
   567    	// tokenize aStrengthAliasString, to facilitate parsing using TLex. 
       
   568    	InsertSpaceBetweenOperatorsL(aStrengthAliasString, resultantAliasString);
       
   569 		
       
   570     // facilitates ordering of expression evaluation via brackets.
       
   571     CAuthExpression* authExpression = EvaluateAliasStringL(resultantAliasString);
       
   572     CleanupStack::PopAndDestroy(); 
       
   573 
       
   574     return authExpression;
       
   575     }
       
   576     
       
   577   
       
   578  /**
       
   579   This method facilitates ordering of alias string expression (containing pluginIds or pluginTypes
       
   580   or a combination of both) evaluation via brackets.The ownership of CAuthExpression object is 
       
   581   transferred to the caller.
       
   582  
       
   583   @param aStrengthAliasString	an alias string to be parsed and processed.This must be enclosed within brackets.
       
   584  
       
   585   @return CAuthExpression object.
       
   586  
       
   587   @leave KErrAuthServInvalidAliasStringExpression, when aStrengthAliasString contains tokens other than pluginId, pluginType
       
   588   						and operators('&', '|') and brackets.		
       
   589  
       
   590  */ 
       
   591     
       
   592   CAuthExpression* CAuthExpressionImpl::EvaluateAliasStringL(const RBuf& aStrengthAliasString)
       
   593   	{
       
   594   	TLex input(aStrengthAliasString);
       
   595 
       
   596   	// array of operators (& and |) and brackets.
       
   597   	const TInt KGranularity = 8;
       
   598   	CArrayFixFlat<TPtrC>* opStack = new(ELeave) CArrayFixFlat<TPtrC>(KGranularity);
       
   599    	CleanupStack::PushL(opStack);
       
   600    	
       
   601    	// array of CAuthExpression objects.
       
   602     RPointerArray<CAuthExpression> authExpressionArray;
       
   603     CleanupResetAndDestroyPushL(authExpressionArray);
       
   604    	
       
   605     for (TPtrC token = input.NextToken(); token.Size() > 0 ; 
       
   606          token.Set(input.NextToken()))
       
   607     	{
       
   608     	TInt count = 0;
       
   609     	TInt index = 0;
       
   610     	if(token.CompareF(KAuthOpOr) == 0)
       
   611     		{
       
   612     		count = opStack->Count();
       
   613     		index = count - 1;
       
   614     		// only when the previous element in the opStack is not "&" , will token be added on the opStack.
       
   615     		if(index >= 0 && opStack->At(index) != KAuthOpAnd)
       
   616     			{
       
   617     			opStack->AppendL(token);
       
   618     			}
       
   619     				
       
   620     		else
       
   621     			{
       
   622     			// atleast 1 element in opStack is "&",hence iterate through opStack and   
       
   623     			// keep creating auth expression object until the loop ends.
       
   624     			while(index >= 0 && opStack->At(index) == KAuthOpAnd)
       
   625     				{
       
   626     				CAuthExpression* authExpr = CreateAuthExpressionL(authExpressionArray, opStack->At(index));
       
   627     				opStack->Delete(index);
       
   628     				opStack->Compress();
       
   629     				CleanupStack::PushL(authExpr);
       
   630 					authExpressionArray.AppendL(authExpr);
       
   631 					CleanupStack::Pop(authExpr);
       
   632 					--index;
       
   633     				}
       
   634     					
       
   635     			opStack->AppendL(token);	
       
   636     			}	
       
   637     		} //if(token.CompareF(KAuthOpOr) == 0)
       
   638     			
       
   639     	else if(token.CompareF(KAuthOpAnd) == 0 || token.CompareF(KOpenBracket) == 0)
       
   640     		{
       
   641     		opStack->AppendL(token);
       
   642     		}
       
   643     				
       
   644     	else if(token.CompareF(KCloseBracket) == 0)
       
   645     		{
       
   646     		// when the previous element in the opStack is "(", delete it.
       
   647     		count = opStack->Count();
       
   648     		index = count - 1;
       
   649     		TInt exprCount = authExpressionArray.Count();
       
   650     			
       
   651     		if(index >= 0 && opStack->At(index) == KOpenBracket)
       
   652     			{
       
   653     			opStack->Delete(index);
       
   654     			opStack->Compress();
       
   655     			}
       
   656     			
       
   657     		// the previous element could be an operator/operators of same precedence.	
       
   658     		else
       
   659     			{
       
   660     			while(index >= 0 && opStack->At(index) != KOpenBracket)
       
   661 					{
       
   662 					CAuthExpression* expr = CreateAuthExpressionL(authExpressionArray, opStack->At(index));
       
   663 					CleanupStack::PushL(expr);
       
   664 					authExpressionArray.AppendL(expr);
       
   665 					CleanupStack::Pop(expr);
       
   666 					opStack->Delete(index);	
       
   667 					opStack->Compress();
       
   668 					--index;
       
   669 					}	//while
       
   670 						
       
   671 				if(index == -1)
       
   672 					{
       
   673 					User::Leave(KErrAuthServInvalidAliasStringExpression);
       
   674 					}
       
   675 						
       
   676 				opStack->Delete(index);
       
   677 				opStack->Compress();
       
   678     			}
       
   679 			}	//else if(token.CompareF(KCloseBracket) == 0)
       
   680     		
       
   681     	//when the token is neither "(","|","&" and ")" , it must be a plugin id or plugin Type,
       
   682     	//hence create a CAuthExpression object.
       
   683     	else
       
   684     		{
       
   685     		CAuthExpression* expression = CreateAuthExpressionL(token);
       
   686     		CleanupStack::PushL(expression);
       
   687 			authExpressionArray.AppendL(expression);
       
   688 			CleanupStack::Pop(expression);
       
   689     		}
       
   690 		}	//for loop
       
   691     
       
   692   // since authExpressionArray will eventually contain only 1 authExpression pointer,
       
   693   // remove it from the array, as the ownership of this pointer is transferred to the caller.
       
   694   __ASSERT_ALWAYS((authExpressionArray.Count() == 1), User::Leave(KErrAuthServInvalidAliasStringExpression));
       
   695    		
       
   696   CAuthExpression* authExpression = authExpressionArray[0];
       
   697   authExpressionArray.Remove(0);
       
   698   
       
   699   CleanupStack::PopAndDestroy(2, opStack);	//opStack and authExpressionArray
       
   700   return authExpression;
       
   701   
       
   702   }
       
   703         
       
   704 /**
       
   705   Creates CAuthExpression object from an alias string containing either 
       
   706   plugin Id  or plugin type.The ownership of the object is transferred to the caller.
       
   707  
       
   708   @param aAliasString	string containing either plugin Id or plugin Type.
       
   709  
       
   710   @return CAuthExpression object.
       
   711  
       
   712   @leave KErrAuthServInvalidAliasStringExpression, if the operands or operators are invalid strings.	
       
   713  
       
   714   @leave KErrNoMemory, if there was insufficient memory to allocate the CAuthExpression object.
       
   715  */ 	
       
   716   CAuthExpression* CAuthExpressionImpl::CreateAuthExpressionL(const TDesC& aAliasString)
       
   717   	{
       
   718    	TLex  input(aAliasString);
       
   719    	CAuthExpression* expression = 0;
       
   720     TPluginId plugin = 0;
       
   721     	
       
   722   	for (TPtrC token = input.NextToken(); token.Size() > 0 ; 
       
   723          token.Set(input.NextToken()))
       
   724        {
       
   725     	TLex lexer(token);
       
   726     	if(token.CompareF(KAuthBiometric) == 0)
       
   727     		{
       
   728     		expression = AuthExpr(EAuthBiometric);
       
   729     		}
       
   730     	else if(token.CompareF(KAuthKnowledge) == 0)
       
   731     		{
       
   732     		expression = AuthExpr(EAuthKnowledge);
       
   733     		}
       
   734     	else if(token.CompareF(KAuthToken) == 0)
       
   735     		{
       
   736     		expression = AuthExpr(EAuthToken);
       
   737     		}
       
   738     	else if(token.CompareF(KAuthPerformance) == 0)
       
   739     		{
       
   740     		expression = AuthExpr(EAuthPerformance);
       
   741     		}
       
   742     	else if(token.CompareF(KAuthDefault) == 0)
       
   743     		{
       
   744     		expression = AuthExpr(EAuthDefault);
       
   745     		}	
       
   746        	else if(lexer.Val(plugin, EHex) == KErrNone)
       
   747     		{
       
   748     		expression = AuthExpr(plugin);
       
   749     		}	
       
   750     	else
       
   751     		{
       
   752     		User::Leave(KErrAuthServInvalidAliasStringExpression);
       
   753     		}
       
   754        }
       
   755      		
       
   756 
       
   757     if(expression == NULL)
       
   758 		{
       
   759 		User::Leave(KErrNoMemory);
       
   760 		}
       
   761 
       
   762     return expression;    	
       
   763    	}
       
   764  
       
   765 /**
       
   766   Creates CAuthExpression object from an array of authexpression objects and an operator.
       
   767   The ownership of the object is transferred to the caller.
       
   768  
       
   769   @param aAuthExprArray		an array of authexpression objects. 
       
   770   @param aOperator			an authexpression operator ( '&' or '|').
       
   771   
       
   772   @return CAuthExpression object.
       
   773   @leave KErrAuthServInvalidAliasStringExpression, if the operands or operators are invalid strings.
       
   774  
       
   775  */  	
       
   776  CAuthExpression* CAuthExpressionImpl::CreateAuthExpressionL(RPointerArray<CAuthExpression>& aAuthExprArray, TPtrC aOperator)
       
   777   	{
       
   778   	// aAuthExprArray must contain minimum of 2 elements.
       
   779   	__ASSERT_ALWAYS((aAuthExprArray.Count() >= 2), User::Leave(KErrAuthServInvalidAliasStringExpression));
       
   780   	
       
   781   	CAuthExpression* authExpression = 0;
       
   782    	TInt exprIndex = aAuthExprArray.Count() - 1;
       
   783    	
       
   784   	if(aOperator.CompareF(KAuthOpAnd) == 0)
       
   785   		{
       
   786   		authExpression = AuthAnd(aAuthExprArray[exprIndex], aAuthExprArray[exprIndex-1]);
       
   787   		}
       
   788     	
       
   789   	else if(aOperator.CompareF(KAuthOpOr) == 0)
       
   790   		{
       
   791   		authExpression = AuthOr(aAuthExprArray[exprIndex], aAuthExprArray[exprIndex-1]);
       
   792   		}
       
   793   		
       
   794     else
       
   795     	{
       
   796     	User::Leave(KErrAuthServInvalidAliasStringExpression);
       
   797     	}
       
   798 	
       
   799 	// array elements are not deleted since the ownership is transferred to authExpression,
       
   800 	aAuthExprArray.Remove(exprIndex);
       
   801 	aAuthExprArray.Remove(exprIndex-1);
       
   802 	aAuthExprArray.Compress();
       
   803 	
       
   804 	return authExpression;
       
   805   	}
       
   806 
       
   807 
       
   808 #ifndef _DEBUG
       
   809 // In release mode provide stub functions for Panic() and Invariant().
       
   810 
       
   811 EXPORT_C void CAuthExpressionImpl::Panic(TPanic /* aPanic */)
       
   812 	{
       
   813 	// empty.
       
   814 	}
       
   815 
       
   816 EXPORT_C TBool CAuthExpressionImpl::Invariant() const
       
   817 	{
       
   818 	return ETrue;
       
   819 	}
       
   820 
       
   821 #else
       
   822 
       
   823 EXPORT_C void CAuthExpressionImpl::Panic(TPanic aPanic)
       
   824 /**
       
   825 	This function is defined for debug builds only.
       
   826 	It halts the current thread when an invalid
       
   827 	argument is supplied to one of CAuthExpressionImpl's functions.
       
   828 	
       
   829 	The current thread is panicked with category "AUTHEXPR"
       
   830 	and the supplied reason.
       
   831 	
       
   832 	@param	aPanic			Panic reason.
       
   833  */
       
   834 	{
       
   835 	_LIT(KPanicCat, "AUTHEXPR");
       
   836 	User::Panic(KPanicCat, aPanic);
       
   837 	}
       
   838 
       
   839 EXPORT_C TBool CAuthExpressionImpl::Invariant() const
       
   840 /**
       
   841 	This function is defined for debug builds, and
       
   842 	checks that the object is internally consistent.
       
   843 	
       
   844 	The node's type must be a supported value - AND, OR,
       
   845 	plugin ID, or plugin type.
       
   846 	
       
   847 	If this is a combining node then recursively ensure
       
   848 	that both the left and right nodes are internally
       
   849 	consistent.
       
   850  */
       
   851 	{
       
   852 	// this node's parent sees it as a child
       
   853 	if (iParent != 0 && !(iParent->iComb.iLeft == this || iParent->iComb.iRight == this))
       
   854 		return EFalse;
       
   855 	
       
   856 	switch (iType)
       
   857 		{
       
   858 	case EPluginId:
       
   859 	case EPluginType:
       
   860 		return ETrue;
       
   861 		
       
   862 	case EAnd:
       
   863 	case EOr:
       
   864 		// these will fault, as opposed to fail the invariant,
       
   865 		// if the pointers are invalid, but so would the original
       
   866 		// call to this function if the this pointer were invalid.
       
   867 		
       
   868 		// this node's children see it as the parent
       
   869 		// don't use Parent() because that asserts on the
       
   870 		// subexpression, whereas this function should
       
   871 		// return EFalse.
       
   872 		if (iComb.iLeft->iParent != this)
       
   873 			return EFalse;
       
   874 		
       
   875 		if (iComb.iRight->iParent != this)
       
   876 			return EFalse;
       
   877 		
       
   878 		return iComb.iLeft->Invariant() && iComb.iRight->Invariant();
       
   879 	
       
   880 	case ENull:
       
   881 		return ETrue;
       
   882 		
       
   883 	default:
       
   884 		// unrecognized node type, so fail invariant
       
   885 		return EFalse;
       
   886 		}
       
   887 	}
       
   888 	
       
   889 #endif	// #ifdef _DEBUG
       
   890 
       
   891