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