messagingfw/msgtestfw/Framework/src/CMtfEnumeratorConverter.cpp
changeset 0 8e480a14352b
equal deleted inserted replaced
-1:000000000000 0:8e480a14352b
       
     1 // Copyright (c) 2003-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 "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 //
       
    15 
       
    16 /**
       
    17  @file
       
    18 */
       
    19 
       
    20 #include "CMtfEnumeratorConverter.h"
       
    21 
       
    22 _LIT(KMtfEnumeratorSeparator,"::");
       
    23 
       
    24 /** Takes a full enumerator value and creates a new empty object.
       
    25 It discards the enumerator value and only uses the class name (optional) and
       
    26 enumeration name */
       
    27 CMtfEnumeratorConverter* CMtfEnumeratorConverter::NewL(const TDesC& aEnumeratorValue)
       
    28 {
       
    29 	return CMtfEnumeratorConverter::NewL(
       
    30 		ParseEnumeratorValueL(aEnumeratorValue,EMtfEnumeratorClassName),
       
    31 		ParseEnumeratorValueL(aEnumeratorValue,EMtfEnumeratorEnumerationName));	
       
    32 }
       
    33 	
       
    34 CMtfEnumeratorConverter* CMtfEnumeratorConverter::NewL(const TDesC& aClassName, const TDesC& aEnumerationName)
       
    35 {
       
    36 	CMtfEnumeratorConverter* self = new (ELeave) CMtfEnumeratorConverter();
       
    37 	CleanupStack::PushL(self);
       
    38 	self->ConstructL(aClassName,aEnumerationName);
       
    39 	CleanupStack::Pop(self);
       
    40 	return self;
       
    41 }
       
    42 
       
    43 /** ConstructL allocates the class name and the enumeration name. */
       
    44 void CMtfEnumeratorConverter::ConstructL(const TDesC& aClassName, const TDesC& aEnumerationName)
       
    45 {
       
    46 	iClassName = aClassName.AllocL();
       
    47 	iEnumerationName = aEnumerationName.AllocL();
       
    48 }
       
    49 
       
    50 /** If '::' sequence occurs in the given parameter then it is assumed to be a 
       
    51 constant enumerator value, as opposed to a parameter name. If KErrNotFound is returned 
       
    52 the function returns EFalse. If a positive offset or any other error occur the function 
       
    53 returns ETrue. If an error has occurred (and it is not KErrNotFound) then when this 
       
    54 parameter is attempted to be used as a constant parameter the error will occur again 
       
    55 and it will be handled. */
       
    56 TBool CMtfEnumeratorConverter::IsConstantEnumerator(const TDesC& aParameter)
       
    57 {
       
    58 	return (aParameter.Find(KMtfEnumeratorSeparator) != KErrNotFound);
       
    59 }
       
    60 
       
    61 /** Takes a full enumerator value and returns the required part. Leaves if the required
       
    62 part does not exist. 
       
    63 @param aEnumeratorValue Full enumerator value including the enumerator constant
       
    64 @param aPart Required part
       
    65 @return Descriptor containing the required part */
       
    66 TPtrC CMtfEnumeratorConverter::ParseEnumeratorValueL(const TDesC& aEnumeratorValue,
       
    67 		TMtfEnumeratorPart aPart)
       
    68 {
       
    69 	if (!CMtfEnumeratorConverter::IsConstantEnumerator(aEnumeratorValue))
       
    70 	{
       
    71 		// there is no '::' in the string so assume it is a value
       
    72 		if (aPart != EMtfEnumeratorValueName)
       
    73 		{
       
    74 			User::Leave(KErrNotFound);
       
    75 		}
       
    76 		
       
    77 		return aEnumeratorValue;
       
    78 	}
       
    79 	
       
    80 	TPtrC className;
       
    81 	TPtrC enumerationName;
       
    82 	TPtrC valueName;
       
    83 	
       
    84 	// '::' is a substring of aEnumeratorValue
       
    85 	TInt offset;
       
    86 	
       
    87 	// the string '::' must exist since it is a constant 
       
    88 	User::LeaveIfError(offset = aEnumeratorValue.Find(KMtfEnumeratorSeparator));
       
    89 		
       
    90 	// take the portion of the string from the start to the sequence '::'
       
    91 	// this is either class name or enumeration name
       
    92 	TPtrC firstName = aEnumeratorValue.Mid(0,offset);
       
    93 	
       
    94 	// move over '::' and take the second part of the string
       
    95 	TPtrC remainder = aEnumeratorValue.Mid(offset+KMtfEnumeratorSeparator().Length());
       
    96 	
       
    97 	// attempt to find a second '::' substring
       
    98 	TInt secondOffset = remainder.Find(KMtfEnumeratorSeparator);
       
    99 		
       
   100 	if (secondOffset == KErrNotFound)
       
   101 	{	
       
   102 		// there is no class name, use an empty string
       
   103 		className.Set(KNullDesC());
       
   104 		enumerationName.Set(firstName);
       
   105 		valueName.Set(remainder);
       
   106 	}
       
   107 	else if (secondOffset <= 0)
       
   108 	{
       
   109 		// some other error has occurred, if 0 then the string ends with '::' which
       
   110 		// is invalid
       
   111 		User::Leave(KErrNotFound);
       
   112 	}
       
   113 	else
       
   114 	{
       
   115 		// class name exists
       
   116 		className.Set(firstName);
       
   117 		enumerationName.Set(remainder.Mid(0,secondOffset));
       
   118 		valueName.Set(remainder.Mid(secondOffset+KMtfEnumeratorSeparator().Length()));
       
   119 	}
       
   120 		
       
   121 	switch(aPart)
       
   122 	{
       
   123 		case EMtfEnumeratorClassName:
       
   124 			return className;
       
   125 		case EMtfEnumeratorEnumerationName:
       
   126 			return enumerationName;
       
   127 		case EMtfEnumeratorValueName:
       
   128 			return valueName;
       
   129 		default:
       
   130 			User::Leave(KErrGeneral);
       
   131 	}
       
   132 	
       
   133 	// dead code but required to prevent a compiler warning
       
   134 	return valueName;
       
   135 }
       
   136 	
       
   137 CMtfEnumeratorConverter::~CMtfEnumeratorConverter()
       
   138 {
       
   139 	delete iClassName;
       
   140 	delete iEnumerationName;
       
   141 	iEnumeratorValues.ResetAndDestroy();
       
   142 	iValues.Reset();
       
   143 }
       
   144 	
       
   145 /** Compares the class name and the enumeration name. Doesn't compare actual
       
   146 enumerator values. */
       
   147 TBool CMtfEnumeratorConverter::operator==(const CMtfEnumeratorConverter& aConverter) const
       
   148 {
       
   149 	return ((*iClassName == *aConverter.iClassName) && 
       
   150 			(*iEnumerationName == *aConverter.iEnumerationName));
       
   151 }
       
   152 
       
   153 /** Compares the class name and the enumeration name. Doesn't compare actual
       
   154 enumerator values. */
       
   155 TBool CMtfEnumeratorConverter::operator!=(const CMtfEnumeratorConverter& aConverter) const
       
   156 {
       
   157 	return !(*this==aConverter);
       
   158 }
       
   159 
       
   160 /** If the enumerator value already exists then leave, 
       
   161 otherwise add the new constant/value pair. */
       
   162 void CMtfEnumeratorConverter::AddEnumeratorValueL(const TDesC& aEnumeratorValue, TInt aValue)
       
   163 {
       
   164 	TInt err=0;
       
   165 	TRAP(err,ConvertL(aEnumeratorValue));
       
   166 	
       
   167 	if (err == KErrNone)
       
   168 	{
       
   169 		User::Leave(KErrAlreadyExists);
       
   170 	}
       
   171 	else if (err != KErrNotFound)
       
   172 	{
       
   173 		User::Leave(err);
       
   174 	}
       
   175 
       
   176 	User::LeaveIfError(iValues.Append(aValue));
       
   177 	
       
   178 	// If AllocL leaves then the object is left in an inconsistent state (there is a 
       
   179 	// value but no constant associated with that value. That will not cause any problems since
       
   180 	// if we leave at this point the whole test case will fail.
       
   181 	
       
   182 	HBufC* enumeratorValue = aEnumeratorValue.AllocLC();
       
   183 	User::LeaveIfError(iEnumeratorValues.Append(enumeratorValue));
       
   184 	CleanupStack::Pop(enumeratorValue);
       
   185 }
       
   186 	
       
   187 /** 
       
   188 @param aEnumeratorValue Enumerator value to convert. It can be full name (including class name,
       
   189 enumeration name and constant, or just the constant name. If the value contains '::' then 
       
   190 it is parsed, otherwise it is assumed to be a constant of this enumeration.
       
   191 @return Numerical value associated with the constant */
       
   192 TInt CMtfEnumeratorConverter::ConvertL(const TDesC& aEnumeratorValue) const
       
   193 {
       
   194 	TPtrC value = aEnumeratorValue;
       
   195 	
       
   196 	// does it contain '::' ?
       
   197 	if (CMtfEnumeratorConverter::IsConstantEnumerator(aEnumeratorValue))
       
   198 	{
       
   199 		// extract the name of the enumerator value
       
   200 		CMtfEnumeratorConverter* converter = CMtfEnumeratorConverter::NewL(aEnumeratorValue);
       
   201 		CleanupStack::PushL(converter);
       
   202 		if (*converter != *this)
       
   203 		{
       
   204 			// wrong converter is being used
       
   205 			User::Leave(KErrNotFound);
       
   206 		}
       
   207 		
       
   208 		value.Set(CMtfEnumeratorConverter::ParseEnumeratorValueL(aEnumeratorValue,EMtfEnumeratorValueName));
       
   209 		CleanupStack::PopAndDestroy(converter);
       
   210 	}
       
   211 	
       
   212 	TInt i;
       
   213 	TBool found = EFalse;
       
   214 	
       
   215 	TInt count = iEnumeratorValues.Count(); 
       
   216 	
       
   217 	for (i=0; i<count; i++)
       
   218 	{
       
   219 		if (*iEnumeratorValues[i] == value)
       
   220 		{
       
   221 			found = ETrue;
       
   222 			break;
       
   223 		}
       
   224 	}
       
   225 	
       
   226 	if (!found)
       
   227 	{
       
   228 		User::Leave(KErrNotFound);
       
   229 	}
       
   230 	
       
   231 	return iValues[i];
       
   232 }
       
   233 	
       
   234 
       
   235 CMtfEnumeratorConverter::CMtfEnumeratorConverter()
       
   236 {
       
   237 }
       
   238