meetingrequest/mrversit2/src/esmricalutil.cpp
changeset 0 8466d47a6819
equal deleted inserted replaced
-1:000000000000 0:8466d47a6819
       
     1 /*
       
     2 * Copyright (c) 2002-2004 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 "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: Utility methods for mrversit2.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 // Class include.
       
    20 #include "emailtrace.h"
       
    21 #include "esmricalutil.h"	// NESMRICalUtil
       
    22 
       
    23 //debug
       
    24 
       
    25 // User includes.
       
    26 #include "esmricalerrors.h"			// Error codes
       
    27 #include "esmricalkeywords.h"		// Literals
       
    28 #include "cesmricalproperty.h"		// CESMRICalProperty
       
    29 #include "cesmricalpropertyparam.h"	// CESMRICalPropertyParam
       
    30 
       
    31 namespace NESMRICalUtil
       
    32 	{
       
    33 	/**
       
    34 	Finds the first occurence of a character within a string which does not occur
       
    35 	between a pair of double quotes.
       
    36 	@param aString The string to search.
       
    37 	@param aChar The character to search for.
       
    38 	@return The position of the character within the string, or KErrNotFound.
       
    39 	@internalTechnology
       
    40 	*/
       
    41 	TInt FindFirstUnquoted(const TDesC& aString, const TChar& aChar)
       
    42 		{
       
    43 		
       
    44 		TBool quoted(EFalse);
       
    45 		
       
    46 		for (TInt pos = 0; pos < aString.Length(); ++pos)
       
    47 			{
       
    48 			TChar val(aString[pos]);
       
    49 			
       
    50 			if (val == KICalQuoteChar)
       
    51 				{
       
    52 				quoted = !quoted;
       
    53 				}
       
    54 			else if ((val == aChar) && (!quoted))
       
    55 				{
       
    56 				return pos;
       
    57 				}
       
    58 			}
       
    59 			
       
    60 		return KErrNotFound;
       
    61 		}
       
    62 
       
    63 	/**
       
    64 	Finds the first occurence of a character within a string which is not escaped
       
    65 	by a backslash character. Searching for a comma will find it in the following
       
    66 	strings: "abc," and "abc\\," but will not find it in "abc\," and "abc\\\,".
       
    67 	Note that backslash cannot exist unescaped, so cannot be searched for.
       
    68 	@param aString The string to search.
       
    69 	@param aChar The character to search for.
       
    70 	@return The position of the character within the string, or KErrNotFound.
       
    71 	@internalTechnology
       
    72 	*/
       
    73 	TInt FindFirstUnescaped(const TDesC& aString, const TChar& aChar)
       
    74 		{
       
    75 		
       
    76 		TBool escaped(EFalse);
       
    77 		
       
    78 		for (TInt pos = 0; pos < aString.Length(); ++pos)
       
    79 			{
       
    80 			TChar val(aString[pos]);
       
    81 			
       
    82 			if (val == KICalBackslashChar)
       
    83 				{
       
    84 				escaped = !escaped;
       
    85 				}
       
    86 			else 
       
    87 				{
       
    88 				if ((val == aChar) && (!escaped))
       
    89 					{
       
    90 					return pos;
       
    91 					}
       
    92 					
       
    93 				escaped = EFalse;
       
    94 				}
       
    95 			}
       
    96 		
       
    97 		return KErrNotFound;	
       
    98 		}
       
    99 
       
   100 	/**
       
   101 	Finds the first occurence of a character within a string, whether or not it
       
   102 	is escaped by a backslash character. If it was escaped, however, the
       
   103 	aWasEscaped parameter will be set to true. Note that backslash cannot exist
       
   104 	unescaped, so cannot be searched for.
       
   105 	@param aString The string to search.
       
   106 	@param aChar The character to search for.
       
   107 	@param aWasEscaped True if the character was escaped, otherwise false.
       
   108 	@return The position of the character within the string, or KErrNotFound.
       
   109 	@internalTechnology
       
   110 	*/
       
   111 	TInt FindFirstAndUnescape(const TDesC& aString, const TChar& aChar, TBool& aWasEscaped)
       
   112 		{
       
   113 		
       
   114 		aWasEscaped = EFalse;
       
   115 		TBool escaped(EFalse);
       
   116 		
       
   117 		for (TInt pos = 0; pos < aString.Length(); ++pos)
       
   118 			{
       
   119 			TChar val(aString[pos]);
       
   120 			
       
   121 			if (val == KICalBackslashChar)
       
   122 				{
       
   123 				escaped = !escaped;
       
   124 				}
       
   125 			else 
       
   126 				{
       
   127 				if (val == aChar)
       
   128 					{
       
   129 					aWasEscaped = escaped;
       
   130 					return pos;
       
   131 					}
       
   132 					
       
   133 				escaped = EFalse;
       
   134 				}
       
   135 			}
       
   136 		
       
   137 		return KErrNotFound;	
       
   138 		}
       
   139 
       
   140 	/**
       
   141 	Take a line and extract the name, parameter and value sections.
       
   142 	@param aLine A line of text in which to find the data.
       
   143 	@param aName A TPtrC referencing the section of aLine containing the name.
       
   144 	@param aParameters A TPtrC referencing the section of aLine containing the
       
   145 	parameters.
       
   146 	@param aValues A TPtrC referencing the section of aLine containing the
       
   147 	values.
       
   148 	@return An error code: either KErrNone or KErrPropertyHasNoValue - avoid
       
   149 	leaving so we can try and recover without the overhead of a trap.
       
   150 	@internalTechnology
       
   151 	*/
       
   152 	TInt ExtractSectionsL(const TDesC& aLine, TPtrC& aName, TPtrC& aParameters, TPtrC& aValues)
       
   153 		{
       
   154 		
       
   155 		// Find the value delimiter.
       
   156 		const TInt colon = FindFirstUnquoted(aLine, KICalColonChar);
       
   157 
       
   158 		// Vague check that the property has a value.
       
   159 		if ((colon == KErrNotFound) || (colon == (aLine.Length() - 1)))
       
   160 			{
       
   161 			return KErrPropertyHasNoValue;	// No value given - the property is invalid.
       
   162 			}
       
   163 
       
   164 		// Find the first parameter delimiter.
       
   165 		const TInt firstSemiColon = aLine.Locate(KICalSemiColonChar);
       
   166 			
       
   167 		// Find the characters dividing each section:
       
   168 		TUint endOfName(colon);
       
   169 
       
   170 		if ((firstSemiColon != KErrNotFound) && (firstSemiColon < colon))
       
   171 			{
       
   172 			endOfName = firstSemiColon;
       
   173 			}
       
   174 		
       
   175 		// Set the name, parameters and values:
       
   176 		aName.Set(aLine.Left(endOfName));
       
   177 	
       
   178 		if (endOfName < colon)
       
   179 			{
       
   180 			const TInt startOfParameters = endOfName + 1;
       
   181 			aParameters.Set(aLine.Mid(startOfParameters, colon - startOfParameters));
       
   182 			}
       
   183 		else
       
   184 			{
       
   185 			aParameters.Set(aLine.Left(0));	// No parameters.
       
   186 			}
       
   187 		
       
   188 		aValues.Set(aLine.Mid(colon + 1));
       
   189 		
       
   190 		return KErrNone;
       
   191 		}
       
   192 
       
   193 	/**
       
   194 	Takes two strings, representing the parameters and values of a property, and
       
   195 	the property itself, and populates the latter with the contents of the first
       
   196 	two.
       
   197 	@param aParameters A string of parameters.
       
   198 	@param aValues A string of values.
       
   199 	@param aProperty A property to add the parameters and values to.
       
   200 	@internalTechnology
       
   201 	*/
       
   202 	void ExtractPropertyL(const TDesC& aParameters, const TDesC& aValues, CESMRICalProperty& aProperty)
       
   203 		{
       
   204 		
       
   205 		ExtractParametersL(aParameters, aProperty);
       
   206 		ExtractPropertyValuesL(aValues, aProperty);
       
   207 		
       
   208 		}
       
   209 
       
   210 	/**
       
   211 	Takes a string representing the parameters of a property, and the property
       
   212 	itself, and populates the property with the contents of the string.
       
   213 	@param aParameters A string of parameters.
       
   214 	@param aProperty A property to add the parameters and values to.
       
   215 	@internalTechnology
       
   216 	*/
       
   217 	void ExtractParametersL(const TDesC& aParameters, CESMRICalProperty& aProperty)
       
   218 		{
       
   219 		
       
   220 		TPtrC remainder(aParameters);
       
   221 		
       
   222 		while (remainder.Length() > 0)
       
   223 			{
       
   224 			TInt endOfParameter(FindFirstUnquoted(remainder, KICalSemiColonChar));
       
   225 			
       
   226 			if (endOfParameter == KErrNotFound)
       
   227 				{
       
   228 				endOfParameter = remainder.Length();
       
   229 				}
       
   230 			
       
   231 			CESMRICalPropertyParam& param = aProperty.AddPropertyParamL();
       
   232 			ExtractParameterL(remainder.Left(endOfParameter), param);
       
   233 			
       
   234 			// Remove the parameter if it has no value.
       
   235 			if (param.Values().Count() == 0)
       
   236 				{
       
   237 				aProperty.RemovePropertyParamL(param);
       
   238 				}
       
   239 
       
   240 			if (endOfParameter < remainder.Length())
       
   241 				{
       
   242 				remainder.Set(remainder.Mid(endOfParameter + 1));
       
   243 				}
       
   244 			else
       
   245 				{
       
   246 				break;
       
   247 				}
       
   248 			}
       
   249 		}
       
   250 
       
   251 	/**
       
   252 	Takes a string representing a single parameter, and a class to store it in.
       
   253 	@param aParameter A string of the form <parameter>[=<value>[,value]*].
       
   254 	@param aPropertyParam A property parameter to store the data in.
       
   255 	@internalTechnology
       
   256 	*/
       
   257 	void ExtractParameterL(const TDesC& aParameter, CESMRICalPropertyParam& aPropertyParam)
       
   258 		{
       
   259 		
       
   260 		TInt firstEquals(aParameter.Locate(KICalEqualsChar));
       
   261 		TInt endOfType(aParameter.Length());
       
   262 		
       
   263 		if (firstEquals != KErrNotFound)
       
   264 			{
       
   265 			endOfType = firstEquals;
       
   266 			}
       
   267 		
       
   268 		aPropertyParam.SetTypeL(aParameter.Left(endOfType));
       
   269 		
       
   270 		if (endOfType < aParameter.Length())
       
   271 			{
       
   272 			ExtractParameterValuesL(aParameter.Mid(endOfType + 1), aPropertyParam);
       
   273 			}
       
   274 		}
       
   275 
       
   276 	/**
       
   277 	Takes a string of comma separated values and adds them to a parameter.
       
   278 	@param aValues A string of the form <value>[,<value>]*.
       
   279 	@param aPropertyParam A property parameter to store the values in.
       
   280 	@internalTechnology
       
   281 	*/
       
   282 	void ExtractParameterValuesL(const TDesC& aValues, CESMRICalPropertyParam& aPropertyParam)
       
   283 		{
       
   284 		
       
   285 		TPtrC remainder(aValues);
       
   286 		
       
   287 		while (remainder.Length() > 0)
       
   288 			{
       
   289 			TInt endOfValue(FindFirstUnquoted(remainder, KICalCommaChar));
       
   290 			
       
   291 			if (endOfValue == KErrNotFound)
       
   292 				{
       
   293 				endOfValue = remainder.Length();
       
   294 				}
       
   295 			
       
   296 			// Add value.
       
   297 			if (endOfValue > 0)
       
   298 				{
       
   299 				aPropertyParam.AddValueL(remainder.Left(endOfValue));
       
   300 				}
       
   301 			
       
   302 			if (endOfValue < remainder.Length())
       
   303 				{
       
   304 				remainder.Set(remainder.Mid(endOfValue + 1));
       
   305 				}
       
   306 			else
       
   307 				{
       
   308 				break;
       
   309 				}
       
   310 			}
       
   311 		}
       
   312 
       
   313 	/**
       
   314 	Takes a string of comma separated values and adds them to a property.
       
   315 	@param aValues A string of the form <value>[,<value>]*.
       
   316 	@param aProperty A property to store the values in.
       
   317 	@param aEscaping Used for dealing with incorrect output from other applications.
       
   318 	@leave Leaves with KErrUnknown if the value of aEscaping is not known.
       
   319 	@internalTechnology
       
   320 	*/
       
   321 	void ExtractPropertyValuesL(const TDesC& aValues, CESMRICalProperty& aProperty, TEscaping aEscaping)
       
   322 		{
       
   323 		
       
   324 		TPtrC remainder(aValues);
       
   325 		TBool wasEscaped(EFalse);
       
   326 		
       
   327 		while (remainder.Length() > 0)
       
   328 			{
       
   329 			TInt endOfValue( KErrNotFound );
       
   330 			
       
   331 			switch (aEscaping)
       
   332 				{
       
   333 				case EEscapeNormal:
       
   334 					endOfValue = FindFirstUnescaped(remainder, KICalCommaChar);
       
   335 					break;
       
   336 				case EEscapeValueSeparators:
       
   337 					endOfValue = FindFirstAndUnescape(remainder, KICalCommaChar, wasEscaped);
       
   338 					break;
       
   339 				default:
       
   340 					User::Leave(KErrUnknown);
       
   341 					break;
       
   342 				}
       
   343 			
       
   344 			if (endOfValue == KErrNotFound)
       
   345 				{
       
   346 				endOfValue = remainder.Length();
       
   347 				}
       
   348 			
       
   349 			// Add value.
       
   350 			if (endOfValue > 0)
       
   351 				{
       
   352 				aProperty.AddValueL(remainder.Left(endOfValue - (wasEscaped ? 1 : 0)));
       
   353 				}
       
   354 			
       
   355 			if (endOfValue < remainder.Length())
       
   356 				{
       
   357 				remainder.Set(remainder.Mid(endOfValue + 1));
       
   358 				}
       
   359 			else
       
   360 				{
       
   361 				break;
       
   362 				}
       
   363 			}
       
   364 		}
       
   365 		
       
   366 	/**
       
   367 	Determines if the given property has a type which holds a text value.
       
   368 	@param aProperty The property to test.
       
   369 	@return ETrue if the property value is a "text" type.
       
   370 	@internalTechnology
       
   371 	*/
       
   372 	TBool PropertyHasTextValueL(const CESMRICalProperty& aProperty)
       
   373 		{
       
   374 		
       
   375 		const TDesC& type = aProperty.Type();
       
   376 		
       
   377 		// First check if it's an X-type.
       
   378 		if ((type.Length() >= 2) && (type.Left(2).CompareF(KICalXProperty) == 0))
       
   379 			{
       
   380 			return ETrue;
       
   381 			}
       
   382 
       
   383 		// Else return ETrue if the property is PRODID, UID, CATEGORIES, COMMENT, CONTACT,
       
   384 		// DESCRIPTION, LOCATION, RELATED-TO, RESOURCES, SUMMARY, TZID or TZNAME.
       
   385 		return ((type.CompareF(KICalProdId) == 0) || (type.CompareF(KICalUid) == 0) ||
       
   386 			(type.CompareF(KICalCategories) == 0) || (type.CompareF(KICalComment) == 0) ||
       
   387 			(type.CompareF(KICalContact) == 0) || (type.CompareF(KICalDescription) == 0) || 
       
   388 			(type.CompareF(KICalLocation) == 0) || (type.CompareF(KICalRelatedto) == 0) || 
       
   389 			(type.CompareF(KICalResources) == 0) || (type.CompareF(KICalSummary) == 0) || 
       
   390 			(type.CompareF(KICalTzid) == 0) || (type.CompareF(KICalTzname) == 0));
       
   391 		}
       
   392 	}
       
   393 
       
   394 // End of File
       
   395