diff -r f5050f1da672 -r 04becd199f91 javaextensions/pim/versit/src.s60/cpimeventpropertyconverter.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/javaextensions/pim/versit/src.s60/cpimeventpropertyconverter.cpp Tue Apr 27 16:30:29 2010 +0300 @@ -0,0 +1,768 @@ +/* +* Copyright (c) 2008 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: Converts event properties PIM API <-> versit + * +*/ + + +// CLASS HEADER +#include "cpimeventpropertyconverter.h" + +// INTERNAL INCLUDES +#include "pimcommon.h" // tpimfield +#include "pimpanics.h" +#include "pimversit.h" +#include "cpimparserproperty.h" +#include "cpimitem.h" +#include "cpimeventitem.h" +#include "mpimrepeatruledata.h" +#include "cleanupresetanddestroy.h" +#include "logger.h" + +// EXTERNAL INCLUDES +#include + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::NewL +// Two-phased constructor. +// ----------------------------------------------------------------------------- +// +CPIMEventPropertyConverter* CPIMEventPropertyConverter::NewL() +{ + JELOG2(EPim); + CPIMEventPropertyConverter* self = + new(ELeave) CPIMEventPropertyConverter(); + return self; +} + +// Destructor +CPIMEventPropertyConverter::~CPIMEventPropertyConverter() +{ + JELOG2(EPim); +} + +// ----------------------------------------------------------------------------- +// CPIMCardConverter::ConvertPropertyL +// Inserts a proprety from a vEvent to a PIM Event Item as a field +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::ConvertPropertyL( + const CParserProperty& aProperty, // property to convert + CPIMEventItem& aItem, // item to insert the field to + TPIMDate& aAlarm) // DALARM is stored here +{ + JELOG2(EPim); + TUid valueTypeUid = aProperty.Uid(); + TInt valueType = valueTypeUid.iUid; + + // The following, rather ugly, cast makes it possible for us to access + // the protected iArrayOfParams field. + const CPIMParserProperty& property = + static_cast(aProperty); + + if (aProperty.Name().CompareF(KVersitTokenCLASS) == 0) + { + ConvertClassPropertyL(property, aItem); + } + else + { + switch (valueType) + { + case KVersitPropertyDateTimeUid: + { + // Start, End, DALARM + ConvertDatePropertyL(property, aItem); + break; + } + case KVersitPropertyHBufCUid: + { + // summary, location + ConvertStringPropertyL(property, aItem); + break; + } + case KVersitPropertyMultiDateTimeUid: + { + // exdate + ConvertExDatePropertyL(property, aItem); + break; + } + case KVCalPropertyRecurrenceUid: + { + // repeat rule + ConvertRepeatRulePropertyL(property, aItem); + break; + } + case KVCalPropertyAlarmUid: + { + // DALARM + ConvertAlarmPropertyL(property, aAlarm); + break; + } + default: + { + // don't support, don't care + } + } + } +} + +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::ConvertEventFieldL +// Inserts a Field from a PIM Event Item to CParserVCard as a property. +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::ConvertEventFieldL(const CPIMItem& aItem, // item to read the field from + CParserVCalEntity& aParser, // parser to insert the property to. + TPIMEventField aField) // field to convert +{ + JELOG2(EPim); + TInt valueCount = aItem.CountValuesL(aField); + for (TInt i = 0; i < valueCount; i++) + { + switch (aField) + { + case EPIMEventAlarm: + { + ConvertAlarmFieldL(aItem, aParser, aField, i); + break; + } + case EPIMEventStart: + case EPIMEventEnd: + case EPIMEventRevision: + { + ConvertDateFieldL(aItem, aParser, aField, i); + break; + } + case EPIMEventSummary: + case EPIMEventLocation: + case EPIMEventNote: + // UID is required by VFX. Do not fix even though this is wrong + case EPIMEventUid: + { + ConvertStringFieldL(aItem, aParser, aField, i); + break; + } + case EPIMEventClass: + { + ConvertClassFieldL(aItem, aParser, aField, i); + break; + } + default: + { + __ASSERT_DEBUG(EFalse, User::Panic(KPIMPanicCategory, + EPIMPanicUnsupportedField)); + return; + } + } + } +} + +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::ConvertRepeatRuleL +// Inserts a repeat rule to a parser. +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::ConvertRepeatRuleL( + const MPIMRepeatRuleData* aRepeat, CParserVCalEntity& aParser) +{ + JELOG2(EPim); + // First exception dates + const CArrayFix& exceptionDates = aRepeat->GetExceptDatesL(); + ConvertExceptionDatesL(exceptionDates, aParser); + + // The interval is always set to 1 - only exception is every 2 weeks repeat + TInt interval = 1; + TInt frequency = 0; + TVersitDateTime* versitEndDate = NULL; + + GetRepeatRuleFieldsL(aRepeat, &interval, &frequency, &versitEndDate); + if (versitEndDate) + { + CleanupDeletePushL(versitEndDate); + } + + CVersitRecurrence* recurrence = CreateRecurrenceL(frequency, interval, + versitEndDate); + + if (versitEndDate) + { + CleanupStack::Pop(versitEndDate); // versitEndDate is owned by recurrence now + } + CleanupStack::PushL(recurrence); + + CParserPropertyValue* propertyValue = + new(ELeave) CParserPropertyValueRecurrence(recurrence); + // recurrence is now owned by propertyValue + CleanupStack::Pop(recurrence); + AddPropertyToParserL(propertyValue, KVersitTokenRRULE(), aParser); + // Needed cleanup stack items are popped out in the AddPropretyToParserL +} + +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::CPIMEventPropertyConverter +// C++ default constructor can NOT contain any code, that +// might leave. +// ----------------------------------------------------------------------------- +// +CPIMEventPropertyConverter::CPIMEventPropertyConverter() +{ + JELOG2(EPim); +} + +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::ConvertDatePropertyL +// Converts a date field from a vCard to a PIM Event Item +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::ConvertDatePropertyL( + const CPIMParserProperty& aProperty, // property to convert + CPIMEventItem& aItem) +{ + JELOG2(EPim); + TPIMField field = aProperty.MatchEventField(); + // Do not match unrecognized fields + if (field == -1) + { + return; + } + + CParserPropertyValueDate* propertyValue = + static_cast(aProperty.Value()); + const TVersitDateTime* value = propertyValue->Value(); + + TPIMDate date(value->iDateTime); + aItem.AddDateL(field, KPIMAttrNone, date); +} + +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::ConvertAlarmPropertyL +// Converts an alarm field from a vCard to a PIM Event Item +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::ConvertAlarmPropertyL( + const CPIMParserProperty& aProperty, // property to convert + TPIMDate& aAlarm) // item to insert the field to +{ + JELOG2(EPim); + if (aProperty.MatchEventField() != EPIMEventAlarm) + { + return; + } + + CParserPropertyValueAlarm* propertyValue = + static_cast(aProperty.Value()); + const CVersitAlarm* value = propertyValue->Value(); + + const TVersitDateTime* versitDT = value->iRunTime; + TPIMDate date(versitDT->iDateTime); + + aAlarm = date; +} + +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::ConvertStringPropertyL +// Converts a string property from a vCalendar to a PIM Event Item +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::ConvertStringPropertyL( + const CPIMParserProperty& aProperty, // property to convert + CPIMEventItem& aItem) // item to insert the field to +{ + JELOG2(EPim); + TPIMField field = aProperty.MatchEventField(); + // Do not convert unrecognized fields + if (field == -1) + { + return; + } + + CParserPropertyValueHBufC* propertyValue = + static_cast(aProperty.Value()); + HBufC* value = propertyValue->TakeValueOwnership(); + CleanupStack::PushL(value); + aItem.AddStringL(field, KPIMAttrNone, value); + CleanupStack::Pop(value); // owned by aItem +} + +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::ConvertRepeatRulePropertyL +// Inserts RRULE proprety from a vEvent to a PIM Event Item as a repeat rule +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::ConvertRepeatRulePropertyL( + const CPIMParserProperty& aProperty, // property to convert + CPIMEventItem& aItem) // item to insert the field to +{ + JELOG2(EPim); + if (aProperty.Name().CompareF(KVersitTokenRRULE) != 0) + { + // Some unsupported recurrence data (i.e. EXRULE) + return; + } + MPIMRepeatRuleData* repeatRule = aItem.GetRepeat(); + + CParserPropertyValueRecurrence* propertyValue = + static_cast(aProperty.Value()); + CVersitRecurrence* value = propertyValue->Value(); + switch (value->iRepeatType) + { + case CVersitRecurrence::EDaily: + { + repeatRule->SetIntL(EPIMRepeatRuleFrequency, EPIMRepeatRuleDaily); + break; + } + case CVersitRecurrence::EWeekly: + { + repeatRule->SetIntL(EPIMRepeatRuleFrequency, EPIMRepeatRuleWeekly); + repeatRule->SetIntL(EPIMRepeatRuleInterval, value->iInterval); + break; + } + case CVersitRecurrence::EMonthlyByPos: + case CVersitRecurrence::EMonthlyByDay: + { + repeatRule->SetIntL(EPIMRepeatRuleFrequency, EPIMRepeatRuleMonthly); + break; + } + case CVersitRecurrence::EYearlyByMonth: + case CVersitRecurrence::EYearlyByDay: + { + repeatRule->SetIntL(EPIMRepeatRuleFrequency, EPIMRepeatRuleYearly); + break; + } + default: + { + // unknown frequency + return; + } + } + + TVersitDateTime* versitEndDate = value->iEndDate; + if (versitEndDate) + { + TPIMDate endDate(versitEndDate->iDateTime); + repeatRule->SetDateL(EPIMRepeatRuleEnd, endDate); + } + + aItem.SetRepeating(ETrue); +} +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::ConvertExDatePropertyL +// Inserts EXDATE proprety from a vEvent to a PIM Event Item as a repeat rule +// field +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::ConvertExDatePropertyL( + const CPIMParserProperty& aProperty, // property to convert + CPIMEventItem& aItem) // item to insert the field to +{ + JELOG2(EPim); + if (aProperty.Name().CompareF(KVersitTokenEXDATE) != 0) + { + // some unsupported multidate + return; + } + MPIMRepeatRuleData* repeatRule = aItem.GetRepeat(); + + CParserPropertyValueMultiDateTime* propertyValue = + static_cast(aProperty.Value()); + CArrayPtr* value = propertyValue->Value(); + TInt valueCount = value->Count(); + for (TInt i = 0; i < valueCount; i++) + { + TPIMDate date(value->At(i)->iDateTime); + repeatRule->AddExceptDateL(date); + } +} + +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::ConvertClassPropertyL +// Converts CLASS property to a PIM Event item. +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::ConvertClassPropertyL( + const CPIMParserProperty& aProperty, CPIMEventItem& aItem) +{ + JELOG2(EPim); + CParserPropertyValueHBufC* propertyValue = + static_cast(aProperty.Value()); + + const TPtrC classStringPtr = propertyValue->Value(); + TInt classInt = KErrCorrupt; + + if (classStringPtr.CompareF(KPIMClassStringPublic) == 0) + { + classInt = EPIMEventClassPublic; + } + else if (classStringPtr.CompareF(KPIMClassStringPrivate) == 0) + { + classInt = EPIMEventClassPrivate; + } + else if (classStringPtr.CompareF(KPIMClassStringConfidential) == 0) + { + classInt = EPIMEventClassConfidential; + } + // else the class value in the originating vCalendar is flawed - ignore + + if (classInt != KErrCorrupt) + { + aItem.addInt(EPIMEventClass, KPIMAttrNone, classInt); + } +} + +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::ConvertExceptionDatesL +// Inserts exceptiondates to a parser. +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::ConvertExceptionDatesL(const CArrayFix< + TPIMDate>& aDates, CParserVCalEntity& aParser) +{ + JELOG2(EPim); + TInt exDateCount = aDates.Count(); + if (exDateCount > 0) + { + CArrayPtrFlat* versitExDates = + new(ELeave) CArrayPtrFlat (exDateCount); + CleanupStack::PushL(versitExDates); + CleanupResetAndDestroyPushL(*versitExDates); + for (TInt i = 0; i < exDateCount; i++) + { + TVersitDateTime + * versitDateTime = + new(ELeave) TVersitDateTime(aDates.At(i).DateTime(), TVersitDateTime::EIsUTC); + CleanupDeletePushL(versitDateTime); + versitExDates->AppendL(versitDateTime); + CleanupStack::Pop(versitDateTime); // versitDateTime + } + CParserPropertyValue* propertyValue = + new(ELeave) CParserPropertyValueMultiDateTime(versitExDates); + CleanupStack::Pop(2); // versitExDates is now owned by propertyValue + AddPropertyToParserL(propertyValue, KVersitTokenEXDATE(), aParser); + // Needed cleanup stack items are popped out in the AddPropretyToParserL + } +} +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::ConvertDateFieldL +// Converts a date field from a PIM Event Item to a CParserVCard. +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::ConvertDateFieldL(const CPIMItem& aItem, // item to convert from + CParserVCalEntity& aParser, // parser to insert the property to. + TPIMEventField aField, // field to convert + TInt aIndex) // index to the field +{ + JELOG2(EPim); + const TPIMDate date = aItem.GetDateL(aField, aIndex); + TDateTime dateTime = date.DateTime(); + TVersitDateTime* versitDateTime = + new(ELeave) TVersitDateTime(dateTime, TVersitDateTime::EIsUTC); + CleanupDeletePushL(versitDateTime); + + CParserPropertyValue* propertyValue = + new(ELeave) CParserPropertyValueDateTime(versitDateTime); + // versitDateTime is now owned by propertyValue + CleanupStack::Pop(versitDateTime); + + switch (aField) + { + case EPIMEventStart: + { + AddPropertyToParserL(propertyValue, KVersitTokenDTSTART(), aParser); + // Needed cleanup stack items are popped + // out in the AddPropretyToParserL + break; + } + case EPIMEventEnd: + { + AddPropertyToParserL(propertyValue, KVersitTokenDTEND(), aParser); + // Needed cleanup stack items are popped + // out in the AddPropretyToParserL + break; + } + case EPIMEventRevision: + { + AddPropertyToParserL(propertyValue, KVersitTokenLASTMODIFIED(), aParser); + // Needed cleanup stack items are popped + // out in the AddPropretyToParserL + break; + } + default: + { + __ASSERT_DEBUG(EFalse, User::Panic(KPIMPanicCategory, + EPIMPanicUnsupportedDateField)); + } + } +} +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::ConvertAlarmFieldL +// Converts an alarm field from a PIM Event Item to a CParserVCard. +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::ConvertAlarmFieldL(const CPIMItem& aItem, // item to convert from + CParserVCalEntity& aParser, // parser to insert the property to. + TPIMEventField aField, // field to convert + TInt aIndex) // index to the field +{ + JELOG2(EPim); + const TInt KAlarmInterval = aItem.getInt(aField, aIndex); + const TTimeIntervalSeconds KTimeInterval(KAlarmInterval); + + // Check that there exists start date. If item is not written to + // database there might not be start date present + if (aItem.CountValuesL(EPIMEventStart) == 0) + { + return; + } + + // Start date present, so conversion can be made + const TPIMDate KStartDate = aItem.GetDateL(EPIMEventStart, 0); + TTime alarmTime(KStartDate); + alarmTime -= KTimeInterval; + TDateTime dateTime = alarmTime.DateTime(); + TVersitDateTime* versitDateTime = + new(ELeave) TVersitDateTime(dateTime, TVersitDateTime::EIsUTC); + CleanupDeletePushL(versitDateTime); + + CVersitAlarm* versitAlarm = CVersitAlarm::NewL(versitDateTime, NULL, 0, + KNullDesC, KNullDesC); + // versitDateTime is now owned by versitAlarm + CleanupStack::Pop(versitDateTime); + CleanupStack::PushL(versitAlarm); + CParserPropertyValue* propertyValue = + new(ELeave) CParserPropertyValueAlarm(versitAlarm); + // versitAlarm is now owned by propertyValue + CleanupStack::Pop(versitAlarm); + AddPropertyToParserL(propertyValue, KVersitTokenDALARM(), aParser); + // Needed cleanup stack items are popped out in the AddPropretyToParserL +} +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::ConvertStringFieldL +// Converts a string field from a PIM Event Item to vCard +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::ConvertStringFieldL(const CPIMItem& aItem, // item to convert from + CParserVCalEntity& aParser, // parser to write to + TPIMEventField aField, // field to convert + TInt aIndex) // index to the field +{ + JELOG2(EPim); + const TDesC& string = aItem.GetStringL(aField, aIndex); + CParserPropertyValue* propertyValue = CParserPropertyValueHBufC::NewL( + string); + + switch (aField) + { + case EPIMEventSummary: + { + AddPropertyToParserL(propertyValue, KVersitTokenSUMMARY(), aParser); + // Needed cleanup stack items are popped + // out in the AddPropretyToParserL + break; + } + case EPIMEventLocation: + { + AddPropertyToParserL(propertyValue, KVersitTokenLOCATION(), aParser); + // Needed cleanup stack items are popped + // out in the AddPropretyToParserL + break; + } + case EPIMEventNote: + { + AddPropertyToParserL(propertyValue, KVersitTokenDESCRIPTION(), aParser); + // Needed cleanup stack items are popped + // out in the AddPropretyToParserL + break; + } + case EPIMEventUid: + { + AddPropertyToParserL(propertyValue, KVersitTokenUID(), aParser); + // Needed cleanup stack items are popped + // out in the AddPropretyToParserL + break; + } + default: + { + __ASSERT_DEBUG(EFalse, User::Panic(KPIMPanicCategory, + EPIMPanicUnsupportedStringField)); + } + } +} + +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::ConvertClassFieldL +// Converts Event.CLASS field to a vCalendar. +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::ConvertClassFieldL(const CPIMItem& aItem, + CParserVCalEntity& aParser, TPIMEventField aField, TInt aIndex) +{ + JELOG2(EPim); + const TInt classVal = aItem.getInt(aField, aIndex); + TPtrC classString(KPIMClassStringConfidential); + + switch (classVal) + { + case EPIMEventClassConfidential: + { + classString.Set(KPIMClassStringConfidential); + break; + } + case EPIMEventClassPrivate: + { + classString.Set(KPIMClassStringPrivate); + break; + } + case EPIMEventClassPublic: + { + classString.Set(KPIMClassStringPublic); + break; + } + default: + { + __ASSERT_DEBUG(EFalse, User::Invariant()); + break; + } + } + + CParserPropertyValue* propertyValue = CParserPropertyValueHBufC::NewL( + classString); + AddPropertyToParserL(propertyValue, KVersitTokenCLASS(), aParser); + // Needed cleanup stack items are popped out in the AddPropretyToParserL +} + +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::GetRepeatRuleFieldsL +// Gets the fields from a repeat rule +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::GetRepeatRuleFieldsL( + const MPIMRepeatRuleData* aRepeat, // Fields are read from this + TInt* aInterval, // interval is stored here + TInt* aFrequency, // frequency is stored here + TVersitDateTime** aVersitEndDate) // end date is stored here +{ + JELOG2(EPim); + TBool endExists = EFalse; + CArrayFix* repeatFields = aRepeat->GetFieldsL(); + CleanupStack::PushL(repeatFields); + TInt fieldCount = repeatFields->Count(); + for (TInt i = 0; i < fieldCount; i++) + { + switch (repeatFields->At(i)) + { + case EPIMRepeatRuleFrequency: + { + *aFrequency = aRepeat->GetIntL(EPIMRepeatRuleFrequency); + break; + } + case EPIMRepeatRuleInterval: + { + *aInterval = aRepeat->GetIntL(EPIMRepeatRuleInterval); + break; + } + case EPIMRepeatRuleEnd: + { + endExists = ETrue; + break; + } + default: + { + // We ignore other fields + } + } + } + CleanupStack::PopAndDestroy(repeatFields); + if (endExists) + { + TPIMDate endDate = aRepeat->GetDateL(EPIMRepeatRuleEnd); + *aVersitEndDate + = new(ELeave) TVersitDateTime(endDate.DateTime(), TVersitDateTime::EIsUTC); + } +} +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::CreateRecurrenceL +// Makes a CVersitRecurrence according to parameters +// ----------------------------------------------------------------------------- +// +CVersitRecurrence* CPIMEventPropertyConverter::CreateRecurrenceL( + TInt aFrequency, TInt aInterval, TVersitDateTime* aVersitEndDate) +{ + JELOG2(EPim); + CVersitRecurrence* recurrence = NULL; + switch (aFrequency) + { + case EPIMRepeatRuleDaily: + { + recurrence + = new(ELeave) CVersitRecurrenceDaily(aInterval, 0, aVersitEndDate); + break; + } + case EPIMRepeatRuleWeekly: + { + recurrence + = new(ELeave) CVersitRecurrenceWeekly(aInterval, 0, aVersitEndDate, NULL); + break; + } + case EPIMRepeatRuleMonthly: + { + recurrence + = new(ELeave) CVersitRecurrenceMonthlyByDay( + aInterval, 0, aVersitEndDate, NULL, NULL, NULL); + break; + } + case EPIMRepeatRuleYearly: + { + recurrence + = new(ELeave) CVersitRecurrenceYearlyByDay(aInterval, 0, aVersitEndDate, NULL); + break; + } + default: + { + User::Leave(KErrNotSupported); + } + } + return recurrence; +} + +// ----------------------------------------------------------------------------- +// CPIMEventPropertyConverter::AddPropertyToParserL +// adds a new property value to the parser. NOTE that the property value can be +// of any type and it is taken to ownership within this function. +// ----------------------------------------------------------------------------- +// +void CPIMEventPropertyConverter::AddPropertyToParserL( + CParserPropertyValue* aPropertyValue, const TDesC8& aPropertyName, + CParserVCalEntity& aParser) +{ + JELOG2(EPim); + // Add property value to the cleanup stack. It should not be added + // before this call. This function is an exception and reduces much code + CleanupStack::PushL(aPropertyValue); + // Create a new parser property from the property value, its name and + // array of parameters. If there are no parameters, the aArrayOfParams + // should be NULL and the parser property will be generated without params + CParserProperty* property = CParserProperty::NewL(*aPropertyValue, + aPropertyName, NULL); + // property takes ownership of the property value + CleanupStack::Pop(aPropertyValue); + // NOTE: property MUST not be pushed to the cleanup stack since the + // AddPropertyL pushes it right away to the cleanup stack. So, we must not + // push it here to avoid duplicate stack pointers + aParser.AddPropertyL(property); + // Property is now owned by the parser but we do not have to pop it +} + +// End of file