messagingfw/msgtestfw/Framework/src/CMtfEnumeratorConverter.cpp
changeset 62 db3f5fa34ec7
parent 0 8e480a14352b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/msgtestfw/Framework/src/CMtfEnumeratorConverter.cpp	Wed Nov 03 22:41:46 2010 +0530
@@ -0,0 +1,238 @@
+// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of "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:
+//
+
+/**
+ @file
+*/
+
+#include "CMtfEnumeratorConverter.h"
+
+_LIT(KMtfEnumeratorSeparator,"::");
+
+/** Takes a full enumerator value and creates a new empty object.
+It discards the enumerator value and only uses the class name (optional) and
+enumeration name */
+CMtfEnumeratorConverter* CMtfEnumeratorConverter::NewL(const TDesC& aEnumeratorValue)
+{
+	return CMtfEnumeratorConverter::NewL(
+		ParseEnumeratorValueL(aEnumeratorValue,EMtfEnumeratorClassName),
+		ParseEnumeratorValueL(aEnumeratorValue,EMtfEnumeratorEnumerationName));	
+}
+	
+CMtfEnumeratorConverter* CMtfEnumeratorConverter::NewL(const TDesC& aClassName, const TDesC& aEnumerationName)
+{
+	CMtfEnumeratorConverter* self = new (ELeave) CMtfEnumeratorConverter();
+	CleanupStack::PushL(self);
+	self->ConstructL(aClassName,aEnumerationName);
+	CleanupStack::Pop(self);
+	return self;
+}
+
+/** ConstructL allocates the class name and the enumeration name. */
+void CMtfEnumeratorConverter::ConstructL(const TDesC& aClassName, const TDesC& aEnumerationName)
+{
+	iClassName = aClassName.AllocL();
+	iEnumerationName = aEnumerationName.AllocL();
+}
+
+/** If '::' sequence occurs in the given parameter then it is assumed to be a 
+constant enumerator value, as opposed to a parameter name. If KErrNotFound is returned 
+the function returns EFalse. If a positive offset or any other error occur the function 
+returns ETrue. If an error has occurred (and it is not KErrNotFound) then when this 
+parameter is attempted to be used as a constant parameter the error will occur again 
+and it will be handled. */
+TBool CMtfEnumeratorConverter::IsConstantEnumerator(const TDesC& aParameter)
+{
+	return (aParameter.Find(KMtfEnumeratorSeparator) != KErrNotFound);
+}
+
+/** Takes a full enumerator value and returns the required part. Leaves if the required
+part does not exist. 
+@param aEnumeratorValue Full enumerator value including the enumerator constant
+@param aPart Required part
+@return Descriptor containing the required part */
+TPtrC CMtfEnumeratorConverter::ParseEnumeratorValueL(const TDesC& aEnumeratorValue,
+		TMtfEnumeratorPart aPart)
+{
+	if (!CMtfEnumeratorConverter::IsConstantEnumerator(aEnumeratorValue))
+	{
+		// there is no '::' in the string so assume it is a value
+		if (aPart != EMtfEnumeratorValueName)
+		{
+			User::Leave(KErrNotFound);
+		}
+		
+		return aEnumeratorValue;
+	}
+	
+	TPtrC className;
+	TPtrC enumerationName;
+	TPtrC valueName;
+	
+	// '::' is a substring of aEnumeratorValue
+	TInt offset;
+	
+	// the string '::' must exist since it is a constant 
+	User::LeaveIfError(offset = aEnumeratorValue.Find(KMtfEnumeratorSeparator));
+		
+	// take the portion of the string from the start to the sequence '::'
+	// this is either class name or enumeration name
+	TPtrC firstName = aEnumeratorValue.Mid(0,offset);
+	
+	// move over '::' and take the second part of the string
+	TPtrC remainder = aEnumeratorValue.Mid(offset+KMtfEnumeratorSeparator().Length());
+	
+	// attempt to find a second '::' substring
+	TInt secondOffset = remainder.Find(KMtfEnumeratorSeparator);
+		
+	if (secondOffset == KErrNotFound)
+	{	
+		// there is no class name, use an empty string
+		className.Set(KNullDesC());
+		enumerationName.Set(firstName);
+		valueName.Set(remainder);
+	}
+	else if (secondOffset <= 0)
+	{
+		// some other error has occurred, if 0 then the string ends with '::' which
+		// is invalid
+		User::Leave(KErrNotFound);
+	}
+	else
+	{
+		// class name exists
+		className.Set(firstName);
+		enumerationName.Set(remainder.Mid(0,secondOffset));
+		valueName.Set(remainder.Mid(secondOffset+KMtfEnumeratorSeparator().Length()));
+	}
+		
+	switch(aPart)
+	{
+		case EMtfEnumeratorClassName:
+			return className;
+		case EMtfEnumeratorEnumerationName:
+			return enumerationName;
+		case EMtfEnumeratorValueName:
+			return valueName;
+		default:
+			User::Leave(KErrGeneral);
+	}
+	
+	// dead code but required to prevent a compiler warning
+	return valueName;
+}
+	
+CMtfEnumeratorConverter::~CMtfEnumeratorConverter()
+{
+	delete iClassName;
+	delete iEnumerationName;
+	iEnumeratorValues.ResetAndDestroy();
+	iValues.Reset();
+}
+	
+/** Compares the class name and the enumeration name. Doesn't compare actual
+enumerator values. */
+TBool CMtfEnumeratorConverter::operator==(const CMtfEnumeratorConverter& aConverter) const
+{
+	return ((*iClassName == *aConverter.iClassName) && 
+			(*iEnumerationName == *aConverter.iEnumerationName));
+}
+
+/** Compares the class name and the enumeration name. Doesn't compare actual
+enumerator values. */
+TBool CMtfEnumeratorConverter::operator!=(const CMtfEnumeratorConverter& aConverter) const
+{
+	return !(*this==aConverter);
+}
+
+/** If the enumerator value already exists then leave, 
+otherwise add the new constant/value pair. */
+void CMtfEnumeratorConverter::AddEnumeratorValueL(const TDesC& aEnumeratorValue, TInt aValue)
+{
+	TInt err=0;
+	TRAP(err,ConvertL(aEnumeratorValue));
+	
+	if (err == KErrNone)
+	{
+		User::Leave(KErrAlreadyExists);
+	}
+	else if (err != KErrNotFound)
+	{
+		User::Leave(err);
+	}
+
+	User::LeaveIfError(iValues.Append(aValue));
+	
+	// If AllocL leaves then the object is left in an inconsistent state (there is a 
+	// value but no constant associated with that value. That will not cause any problems since
+	// if we leave at this point the whole test case will fail.
+	
+	HBufC* enumeratorValue = aEnumeratorValue.AllocLC();
+	User::LeaveIfError(iEnumeratorValues.Append(enumeratorValue));
+	CleanupStack::Pop(enumeratorValue);
+}
+	
+/** 
+@param aEnumeratorValue Enumerator value to convert. It can be full name (including class name,
+enumeration name and constant, or just the constant name. If the value contains '::' then 
+it is parsed, otherwise it is assumed to be a constant of this enumeration.
+@return Numerical value associated with the constant */
+TInt CMtfEnumeratorConverter::ConvertL(const TDesC& aEnumeratorValue) const
+{
+	TPtrC value = aEnumeratorValue;
+	
+	// does it contain '::' ?
+	if (CMtfEnumeratorConverter::IsConstantEnumerator(aEnumeratorValue))
+	{
+		// extract the name of the enumerator value
+		CMtfEnumeratorConverter* converter = CMtfEnumeratorConverter::NewL(aEnumeratorValue);
+		CleanupStack::PushL(converter);
+		if (*converter != *this)
+		{
+			// wrong converter is being used
+			User::Leave(KErrNotFound);
+		}
+		
+		value.Set(CMtfEnumeratorConverter::ParseEnumeratorValueL(aEnumeratorValue,EMtfEnumeratorValueName));
+		CleanupStack::PopAndDestroy(converter);
+	}
+	
+	TInt i;
+	TBool found = EFalse;
+	
+	TInt count = iEnumeratorValues.Count(); 
+	
+	for (i=0; i<count; i++)
+	{
+		if (*iEnumeratorValues[i] == value)
+		{
+			found = ETrue;
+			break;
+		}
+	}
+	
+	if (!found)
+	{
+		User::Leave(KErrNotFound);
+	}
+	
+	return iValues[i];
+}
+	
+
+CMtfEnumeratorConverter::CMtfEnumeratorConverter()
+{
+}
+