javaextensions/pim/versit/src.s60/cpimeventpropertyconverter.cpp
branchRCL_3
changeset 19 04becd199f91
child 23 98ccebc37403
--- /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 <vcal.h>
+
+// ============================ 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<const CPIMParserProperty&>(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<TPIMDate>& 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<CParserPropertyValueDate*>(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<CParserPropertyValueAlarm*>(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<CParserPropertyValueHBufC*>(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<CParserPropertyValueRecurrence*>(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<CParserPropertyValueMultiDateTime*>(aProperty.Value());
+    CArrayPtr<TVersitDateTime>* 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<CParserPropertyValueHBufC*>(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<TVersitDateTime>* versitExDates =
+            new(ELeave) CArrayPtrFlat<TVersitDateTime> (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<TPIMField>* 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