calendarengines/versit2/src/ICalProperty.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:   Implements the definition of CICalProperty.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 
       
    20 // Class include.
       
    21 #include "ICalProperty.h"	// CICalProperty
       
    22 
       
    23 //debug
       
    24 #include "calendarengines_debug.h"
       
    25 
       
    26 // User includes.
       
    27 #include "ICalContentLineWriter.h"	// CICalContentLineWriter
       
    28 #include "ICalErrors.h"				// Error values
       
    29 #include "ICalKeyWords.h"			// Literals
       
    30 #include "ICalPropertyParam.h"		// CICalPropertyParam
       
    31 #include "ICalUtil.h"				// NICalUtil
       
    32 #include "ICalValue.h"				// CICalValue
       
    33 
       
    34 /**
       
    35 Constructs a new CICalProperty with given type and value and returns it.
       
    36 Note that other values may be added later.
       
    37 @param aType The type of the property.
       
    38 @param aValue The value of the property.
       
    39 @return a pointer to a new CICalProperty
       
    40 @publishedPartner
       
    41 */
       
    42 EXPORT_C CICalProperty* CICalProperty::NewL(const TDesC& aType, const TDesC& aValue)
       
    43 	{
       
    44 	TRACE_ENTRY_POINT;
       
    45 	
       
    46 	CICalProperty* self = CICalProperty::NewLC(aType, aValue);
       
    47 	CleanupStack::Pop(self);
       
    48 	
       
    49 	TRACE_EXIT_POINT;
       
    50 	return self;
       
    51 	}
       
    52 
       
    53 /**
       
    54 Constructs a new CICalProperty with given type and value, pushes it onto the
       
    55 Cleanup Stack, and returns it. Note that other values may be added later.
       
    56 @param aType The type of the property.
       
    57 @param aValue The value of the property.
       
    58 @return a pointer to a new CICalProperty
       
    59 @publishedPartner
       
    60 */
       
    61 EXPORT_C CICalProperty* CICalProperty::NewLC(const TDesC& aType, const TDesC& aValue)
       
    62 	{
       
    63 	TRACE_ENTRY_POINT;
       
    64 	
       
    65 	CICalProperty* self = new (ELeave) CICalProperty;
       
    66 	CleanupStack::PushL(self);
       
    67 	self->ConstructL(aType, aValue);
       
    68 	
       
    69 	TRACE_EXIT_POINT;
       
    70 	return self;
       
    71 	}
       
    72 
       
    73 /**
       
    74 Constructs a new CICalProperty with given type and value and returns it. Takes
       
    75 ownership of the passed value pointer and deletes it if this function leaves.
       
    76 Note that other values may be added later.
       
    77 @param aType The type of the property.
       
    78 @param aValue The value of the property.
       
    79 @return a pointer to a new CICalProperty
       
    80 @leave Leaves with KErrPropertyHasNoValue if aValue is NULL.
       
    81 @publishedPartner
       
    82 */
       
    83 EXPORT_C CICalProperty* CICalProperty::NewL(const TDesC& aType, CICalValue* aValue)
       
    84 	{
       
    85 	TRACE_ENTRY_POINT;
       
    86 	
       
    87 	CICalProperty* self = CICalProperty::NewLC(aType, aValue);
       
    88 	CleanupStack::Pop(self);
       
    89 	
       
    90 	TRACE_EXIT_POINT;
       
    91 	return self;
       
    92 	}
       
    93 
       
    94 /**
       
    95 Constructs a new CICalProperty with given type and value, pushes it onto the
       
    96 Cleanup Stack, and returns it. Takes ownership of the passed value pointer and
       
    97 deletes it if this function leaves. Note that other values may be added later.
       
    98 @param aType The type of the property.
       
    99 @param aValue The value of the property.
       
   100 @return a pointer to a new CICalProperty
       
   101 @leave Leaves with KErrPropertyHasNoValue if aValue is NULL.
       
   102 @publishedPartner
       
   103 */
       
   104 EXPORT_C CICalProperty* CICalProperty::NewLC(const TDesC& aType, CICalValue* aValue)
       
   105 	{
       
   106 	TRACE_ENTRY_POINT;
       
   107 	
       
   108 	// Test that the value is valid before construction.
       
   109 	if (!aValue)
       
   110 		{
       
   111 		User::Leave(KErrPropertyHasNoValue);
       
   112 		}
       
   113 		
       
   114 	// Push the passed value onto the Cleanup Stack.
       
   115 	CleanupStack::PushL(aValue);
       
   116 	
       
   117 	// Create a new property.
       
   118 	CICalProperty* self = new (ELeave) CICalProperty(aValue);
       
   119 
       
   120 	// Pop the passed value from the Cleanup Stack as it is temporarily owned by self.
       
   121 	CleanupStack::Pop(aValue);
       
   122 
       
   123 	// Construct the property.
       
   124 	CleanupStack::PushL(self);
       
   125 	self->ConstructL(aType, aValue);
       
   126 	
       
   127 	TRACE_EXIT_POINT;
       
   128 	return self;
       
   129 	}
       
   130 
       
   131 /**
       
   132 Destructor.
       
   133 @internalTechnology
       
   134 */
       
   135 CICalProperty::~CICalProperty()
       
   136 	{
       
   137 	TRACE_ENTRY_POINT;
       
   138 	
       
   139 	delete iValue;
       
   140 	delete iType;
       
   141 	iParams.ResetAndDestroy();
       
   142 	iValues.ResetAndDestroy();
       
   143 	
       
   144 	TRACE_EXIT_POINT;
       
   145 	}
       
   146 
       
   147 /**
       
   148 Constructs a new CICalProperty with given type and returns it
       
   149 @param aType The type of the property.
       
   150 @return a pointer to a new CICalProperty
       
   151 @internalTechnology
       
   152 */
       
   153 CICalProperty* CICalProperty::NewL(const TDesC& aType)
       
   154 	{
       
   155 	TRACE_ENTRY_POINT;
       
   156 	
       
   157 	CICalProperty* self = CICalProperty::NewLC(aType);
       
   158 	CleanupStack::Pop(self);
       
   159 	
       
   160 	TRACE_EXIT_POINT;
       
   161 	return self;
       
   162 	}
       
   163 
       
   164 /**
       
   165 Constructs a new CICalProperty with given type, pushes it onto the Cleanup
       
   166 Stack, and returns it.
       
   167 @param aType The type of the property.
       
   168 @return a pointer to a new CICalProperty.
       
   169 @internalTechnology
       
   170 */
       
   171 CICalProperty* CICalProperty::NewLC(const TDesC& aType)
       
   172 	{
       
   173 	TRACE_ENTRY_POINT;
       
   174 	
       
   175 	CICalProperty* self = new (ELeave) CICalProperty;
       
   176 	CleanupStack::PushL(self);
       
   177 	self->ConstructL(aType);
       
   178 	
       
   179 	TRACE_EXIT_POINT;
       
   180 	return self;
       
   181 	}
       
   182 
       
   183 /**
       
   184 Gets the type of the property.
       
   185 @return The type of the property as a string.
       
   186 @publishedPartner
       
   187 */
       
   188 EXPORT_C const TDesC& CICalProperty::Type() const
       
   189 	{
       
   190 	TRACE_ENTRY_POINT;
       
   191 	TRACE_EXIT_POINT;
       
   192 	return *iType;
       
   193 	}
       
   194 	
       
   195 /**
       
   196 Adds a parameter with given type and value to the property, taking ownership of
       
   197 the value. Note that further values may be added later.
       
   198 @param aType The type of property parameter.
       
   199 @param aValue A value of the property parameter - this will be deleted if this function leaves.
       
   200 @return A new property parameter.
       
   201 @leave Leaves with KErrParameterHasNoValue if aValue is NULL.
       
   202 @publishedPartner
       
   203 */
       
   204 EXPORT_C CICalPropertyParam& CICalProperty::AddPropertyParamL(const TDesC& aType, CICalValue* aValue)
       
   205 	{
       
   206 	TRACE_ENTRY_POINT;
       
   207 	
       
   208 	if (!aValue)
       
   209 		{
       
   210 		User::Leave(KErrParameterHasNoValue);
       
   211 		}
       
   212 	
       
   213 	CICalPropertyParam* param = CICalPropertyParam::NewLC(aType, aValue);
       
   214 	User::LeaveIfError(iParams.Append(param));
       
   215 	CleanupStack::Pop(param);
       
   216 	
       
   217 	TRACE_EXIT_POINT;
       
   218 	return *param;
       
   219 	}
       
   220 
       
   221 /**
       
   222 Adds a parameter with given type and value to the property.
       
   223 Note that further values may be added later.
       
   224 @param aType The type of property parameter.
       
   225 @param aValue A value of the property parameter.
       
   226 @return A new property parameter.
       
   227 @leave Leaves with if there is an error adding a parameter.
       
   228 @publishedPartner
       
   229 */
       
   230 EXPORT_C CICalPropertyParam& CICalProperty::AddPropertyParamL(const TDesC& aType, const TDesC& aValue)
       
   231 	{
       
   232 	TRACE_ENTRY_POINT;
       
   233 	
       
   234 	CICalPropertyParam* param = CICalPropertyParam::NewLC(aType, aValue);
       
   235 	User::LeaveIfError(iParams.Append(param));
       
   236 	CleanupStack::Pop(param);
       
   237 	
       
   238 	TRACE_EXIT_POINT;
       
   239 	return *param;
       
   240 	}
       
   241 
       
   242 /**
       
   243 Adds a value to the property. Any escaped characters in the value string are
       
   244 translated to the actual characters.
       
   245 @param aValue The text string of the value, as would be entered into an
       
   246 iCalendar file.
       
   247 @leave Leaves if there is an error adding a value.
       
   248 @publishedPartner
       
   249 */
       
   250 EXPORT_C void CICalProperty::AddValueL(const TDesC& aValue)
       
   251 	{
       
   252 	TRACE_ENTRY_POINT;
       
   253 	
       
   254 	HBufC* parameterValue = NULL;
       
   255 
       
   256 	// Create a new value.
       
   257 	CICalValue* value = CICalValue::NewLC();
       
   258 
       
   259 	// If the property has a text value then find any escaped characters and convert
       
   260 	// them. Property values use backslash to escape the following characters:
       
   261 	// commas, semi-colons, newlines (using \n or \N) and backslash itself.
       
   262 
       
   263 	if (NICalUtil::PropertyHasTextValueL(*this))
       
   264 		{
       
   265 		parameterValue = aValue.AllocLC();
       
   266 		TInt length(parameterValue->Length());
       
   267 		TBool escaped(EFalse);
       
   268 		
       
   269 		for (TInt location = 0; location < length; location++)
       
   270 			{
       
   271 			if (escaped)
       
   272 				{
       
   273 				if (((*parameterValue)[location] == KICalUpperCaseNChar) ||
       
   274 					((*parameterValue)[location] == KICalLowerCaseNChar))
       
   275 					{
       
   276 					// Found an escaped newline - replace with a single linefeed character.
       
   277 					(parameterValue->Des()).operator[](location) = KICalNewlineChar;
       
   278 					}
       
   279 				
       
   280 				// Else found an escaped backslash, semi-colon or comma, or
       
   281 				// a single backslash (which is not valid).
       
   282 				
       
   283 				// In all cases remove the previous backslash character.
       
   284 				// This assumes that (location - 1) >= 0, since escaped == ETrue
       
   285 				// (The previous character was a backslash, so there *is* a previous character.)
       
   286 				parameterValue->Des().Delete(location - 1, 1);
       
   287 				length--;	// The length of the descriptor has shrunk by one.
       
   288 				location--;	// The current character has slipped back a place.
       
   289 				escaped = EFalse;
       
   290 				}
       
   291 			else 
       
   292 			    {
       
   293 			    if ((*parameterValue)[location] == KICalBackslashChar)
       
   294 				    {
       
   295 				    escaped = ETrue;
       
   296 				
       
   297 				    if (location == (length - 1))
       
   298 					    {
       
   299 					    // Found a single backslash at the end - this is not valid, so remove it.
       
   300 					    parameterValue->Des().Delete(location, 1);
       
   301 					    break;
       
   302 					    }
       
   303 				    }			    
       
   304 			    }
       
   305 			}
       
   306 		}
       
   307 
       
   308 	// Set the value.
       
   309 	if (parameterValue)
       
   310 		{
       
   311 		value->SetTextL(*parameterValue);
       
   312 		CleanupStack::PopAndDestroy(parameterValue);
       
   313 		}
       
   314 	else
       
   315 		{
       
   316 		// If the property does not have a text type then just use the given string as is...
       
   317 		value->SetTextL(aValue);
       
   318 		}	
       
   319 
       
   320 	// Append the new value to the list of values.
       
   321 	User::LeaveIfError(iValues.Append(value));
       
   322 	CleanupStack::Pop(value);
       
   323 	TRACE_EXIT_POINT;
       
   324 	}
       
   325 
       
   326 /**
       
   327 Adds value to this property, taking ownership of the passed value pointer and
       
   328 deleting it if this function leaves.
       
   329 @param aValue The value to add - this must not be NULL.
       
   330 @leave Leaves with KErrPropertyHasNoValue if aValue is NULL.
       
   331 @publishedPartner
       
   332 */
       
   333 EXPORT_C void CICalProperty::AddValueL(CICalValue* aValue)
       
   334 	{
       
   335 	TRACE_ENTRY_POINT;
       
   336 	
       
   337 	if (!aValue)
       
   338 		{
       
   339 		User::Leave(KErrPropertyHasNoValue);
       
   340 		}
       
   341 		
       
   342 	// Append the value to the list of values.
       
   343 	TInt err(iValues.Append(aValue));
       
   344 	
       
   345 	if (err)
       
   346 		{
       
   347 		delete aValue;
       
   348 		User::Leave(err);
       
   349 		}
       
   350 	TRACE_EXIT_POINT;
       
   351 	}
       
   352 	
       
   353 /**
       
   354 Access method for the array of parameters.
       
   355 @return The array of parameters.
       
   356 @publishedPartner
       
   357 */
       
   358 EXPORT_C const RPointerArray<CICalPropertyParam>& CICalProperty::Parameters() const
       
   359 	{
       
   360 	TRACE_ENTRY_POINT;
       
   361 	TRACE_EXIT_POINT;
       
   362 	return iParams;
       
   363 	}
       
   364 	
       
   365 /**
       
   366 Access method for the array of properties.
       
   367 @return The array of properties.
       
   368 @publishedPartner
       
   369 */
       
   370 EXPORT_C const RPointerArray<CICalValue>& CICalProperty::Values() const
       
   371 	{
       
   372 	TRACE_ENTRY_POINT;
       
   373 	TRACE_EXIT_POINT;
       
   374 	return iValues;
       
   375 	}
       
   376 	
       
   377 /**
       
   378 Find a parameter with the given name. Ownership is not passed out.
       
   379 @param aType The type of the parameter to search for
       
   380 @return A pointer to the parameter, or NULL if it is not found.
       
   381 @publishedPartner
       
   382 */
       
   383 EXPORT_C const CICalPropertyParam* CICalProperty::FindParam(const TDesC& aType) const
       
   384 	{
       
   385 	TRACE_ENTRY_POINT;
       
   386 	
       
   387 	const TInt count = iParams.Count();
       
   388 	
       
   389 	for (TInt p = 0; p < count; ++p)
       
   390 		{
       
   391 		if (iParams[p]->Type().CompareF(aType) == 0)
       
   392 			{
       
   393 			return iParams[p];
       
   394 			}
       
   395 		}
       
   396 
       
   397     TRACE_EXIT_POINT;		
       
   398 	return NULL;
       
   399 	}
       
   400 
       
   401 /**
       
   402 Adds an empty parameter to the property.
       
   403 @return A new, empty parameter.
       
   404 @leave Leaves if there is an error adding a parameter.
       
   405 @internalTechnology
       
   406 */
       
   407 CICalPropertyParam& CICalProperty::AddPropertyParamL()
       
   408 	{
       
   409 	TRACE_ENTRY_POINT;
       
   410 	
       
   411 	CICalPropertyParam* param = CICalPropertyParam::NewLC();
       
   412 	User::LeaveIfError(iParams.Append(param));
       
   413 	CleanupStack::Pop(param);
       
   414 	
       
   415 	TRACE_EXIT_POINT;
       
   416 	return *param;
       
   417 	}
       
   418 
       
   419 /**
       
   420 Removes the given parameter from the property.
       
   421 @param aParam The parameter to remove.
       
   422 @leave Leaves in debug mode if the parameter is not found (release mode ignores
       
   423 this).
       
   424 @internalTechnology
       
   425 */
       
   426 void CICalProperty::RemovePropertyParamL(const CICalPropertyParam& aParam)
       
   427 	{
       
   428 	TRACE_ENTRY_POINT;
       
   429 	
       
   430 	// Find the parameter to remove.
       
   431 	TInt index = iParams.Find(&aParam, CICalPropertyParam::EqualsL);
       
   432 
       
   433 #ifdef _DEBUG
       
   434 	User::LeaveIfError(index);	// Not expecting this.
       
   435 #else	// _DEBUG
       
   436 	if (index < 0)
       
   437 		{
       
   438 		return;	// Return quietly in release builds
       
   439 		}
       
   440 #endif	// _DEBUG
       
   441 	
       
   442 	// Destroy the parameter and remove it.
       
   443 	delete iParams[index];
       
   444 	iParams.Remove(index);
       
   445 	
       
   446 	TRACE_EXIT_POINT;
       
   447 	}
       
   448 	
       
   449 /**
       
   450 Export this property using the given line writer, escaping any necessary
       
   451 characters. Assumes it contains at least one value from the check in
       
   452 CICalBase::ExternalizeL().
       
   453 @param aWriter The content line writer to export to.
       
   454 @internalTechnology
       
   455 */
       
   456 void CICalProperty::ExternalizeL(CICalContentLineWriter& aWriter)
       
   457 	{
       
   458 	TRACE_ENTRY_POINT;
       
   459 	
       
   460 	// Export property name.
       
   461 	aWriter.AppendL(*iType);
       
   462 	
       
   463 	// Export parameters. 
       
   464 	const TInt paramCount = iParams.Count();
       
   465 	
       
   466 	for (TInt x = 0; x < paramCount; ++x)
       
   467 		{
       
   468 		if (iParams[x]->Values().Count() > 0)
       
   469 			{
       
   470 			aWriter.AppendL(KICalSemiColon());
       
   471 			iParams[x]->ExternalizeL(aWriter);
       
   472 			}
       
   473 		}
       
   474 	
       
   475 	// Export values.
       
   476 	aWriter.AppendL(KICalColon());
       
   477 	
       
   478 	const TInt valCount = iValues.Count();
       
   479 	
       
   480 	for (TInt x = 0; x < valCount; ++x)
       
   481 		{
       
   482 		const TDesC& value = iValues[x]->TextL();
       
   483 		
       
   484 		// If the property has a text value then escape any necessary characters.
       
   485 		if (NICalUtil::PropertyHasTextValueL(*this))
       
   486 			{
       
   487 			const TInt valueLength = value.Length();
       
   488 			
       
   489 			// Export each value a character at a time, translating any characters that need escaping.
       
   490 			for (TInt character = 0; character < valueLength; character++)
       
   491 				{
       
   492 				// Property values use backslash to escape the following characters:
       
   493 				// commas, semi-colons, newlines (using \n or \N) and backslash itself.
       
   494 				if ((value[character] == KICalBackslashChar) ||
       
   495 					(value[character] == KICalSemiColonChar) ||
       
   496 					(value[character] == KICalCommaChar))
       
   497 					{
       
   498 					aWriter.AppendL(KICalBackslash());
       
   499 					aWriter.AppendL(value[character]);
       
   500 					}
       
   501 				else if (value[character] == KICalNewlineChar)
       
   502 					{
       
   503 					aWriter.AppendL(KICalBackslashN());
       
   504 					}
       
   505 				else
       
   506 					{
       
   507 					aWriter.AppendL(value[character]);
       
   508 					}
       
   509 				}
       
   510 			}
       
   511 		else	// No escaping needed.
       
   512 			{
       
   513 			aWriter.AppendL(value);
       
   514 			}
       
   515 		
       
   516 		if (x < valCount -1)
       
   517 			{
       
   518 			aWriter.AppendL(KICalComma());
       
   519 			}
       
   520 		}
       
   521 		
       
   522 	aWriter.WriteContentLineL();
       
   523 	
       
   524 	TRACE_EXIT_POINT;
       
   525 	}
       
   526 
       
   527 /**
       
   528 Constructor
       
   529 @internalTechnology
       
   530 */
       
   531 CICalProperty::CICalProperty()
       
   532 	{
       
   533 	TRACE_ENTRY_POINT;
       
   534 	TRACE_EXIT_POINT;
       
   535 	}
       
   536 
       
   537 /**
       
   538 Constructor
       
   539 @param aValue The initial value.
       
   540 @internalTechnology
       
   541 */
       
   542 CICalProperty::CICalProperty(CICalValue* aValue)
       
   543  :	iValue(aValue)
       
   544 	{
       
   545 	TRACE_ENTRY_POINT;
       
   546 	TRACE_EXIT_POINT;
       
   547 	}
       
   548 
       
   549 /**
       
   550 Internal construction
       
   551 @param aType The type of property.
       
   552 @internalTechnology
       
   553 */
       
   554 void CICalProperty::ConstructL(const TDesC& aType)
       
   555 	{
       
   556 	TRACE_ENTRY_POINT;
       
   557 	
       
   558 	iType = aType.AllocL();
       
   559 	
       
   560 	TRACE_EXIT_POINT;
       
   561 	}
       
   562 
       
   563 /**
       
   564 Internal construction.
       
   565 @param aType The type of property.
       
   566 @param aValue A value of the property.
       
   567 @internalTechnology
       
   568 */
       
   569 void CICalProperty::ConstructL(const TDesC& aType, const TDesC& aValue)
       
   570 	{
       
   571 	TRACE_ENTRY_POINT;
       
   572 	
       
   573 	ConstructL(aType);
       
   574 	
       
   575 	// Add the value.
       
   576 	AddValueL(aValue);
       
   577 	
       
   578 	TRACE_EXIT_POINT;
       
   579 	}
       
   580 	
       
   581 /**
       
   582 Internal construction. Takes ownership of the passed value pointer and
       
   583 deletes it if this function leaves.
       
   584 @param aType The type of property.
       
   585 @param aValue A value of the property - this class takes ownership.
       
   586 @internalTechnology
       
   587 */
       
   588 void CICalProperty::ConstructL(const TDesC& aType, CICalValue* aValue)
       
   589 	{
       
   590 	TRACE_ENTRY_POINT;
       
   591 	
       
   592 	ConstructL(aType);
       
   593 	
       
   594 	// Add the value.
       
   595 	iValue = NULL;	// If we got this far then we can release direct ownership of the value.
       
   596 	AddValueL(aValue);	// Value is deleted if this leaves.
       
   597 	
       
   598 	TRACE_EXIT_POINT;
       
   599 	}
       
   600 
       
   601 // End of File