diff -r 000000000000 -r f979ecb2b13e calendarengines/versit2/src/ICalBase.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/calendarengines/versit2/src/ICalBase.cpp Tue Feb 02 10:12:19 2010 +0200 @@ -0,0 +1,685 @@ +/* +* Copyright (c) 2002-2004 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: Class implementing the definition of CICalBase. This class is base class from which ICal class has been derived. +* +*/ + + + +// Class include. +#include "ICalBase.h" // CICalBase + +//debug +#include "calendarengines_debug.h" + +// User includes. +#include "ICalComponent.h" // CICalComponent +#include "ICalContentLineReader.h" // CICalContentLineReader +#include "ICalContentLineWriter.h" // CICalContentLineWriter +#include "ICalErrors.h" // Error codes +#include "ICalKeyWords.h" // Literals +#include "ICalProperty.h" // CICalProperty +#include "ICalUtil.h" // NICalUtil +#include "ICalValue.h" // CICalValue + +using namespace NICalUtil; + +/** +Destructor. +@internalTechnology +*/ +CICalBase::~CICalBase() + { + TRACE_ENTRY_POINT; + + iComponents.ResetAndDestroy(); + iProperties.ResetAndDestroy(); + + TRACE_EXIT_POINT; + } + +/** +Creates a new property with a value from the given parameters, adds it to +this object and returns a modifiable reference to it. +@param aName Name of the property to add. +@param aValue Value of the property to add. +@return A reference to a new property owned by this object. +@leave Leaves with KErrUnsupportedProperty if the given property is not valid. +for this component. +@publishedPartner +*/ +EXPORT_C CICalProperty& CICalBase::AddPropertyL(const TDesC& aName, const TDesC& aValue) + { + TRACE_ENTRY_POINT; + + CICalProperty* property = CreatePropertyL(aName); // Not taking ownership. + + if (!property) + { + User::Leave(KErrUnsupportedProperty); + } + + property->AddValueL(aValue); + + TRACE_EXIT_POINT; + return *property; + } + +/** +Creates a new property with a value and adds it to this object, returning a +reference to it. Ownership of aValue is transferred and it will be deleted if +this function leaves. +@leave Leaves with KErrPropertyHasNoValue if aValue is Null. +@leave Leaves with KErrUnsupportedProperty if the given property is not valid. +@return A new property +@publishedPartner +*/ +EXPORT_C CICalProperty& CICalBase::AddPropertyL(const TDesC& aName, CICalValue* aValue) + { + TRACE_ENTRY_POINT; + + if (!aValue) + { + User::Leave(KErrPropertyHasNoValue); + } + + CleanupStack::PushL(aValue); + CICalProperty* property = CreatePropertyL(aName); // Not taking ownership. + + if (!property) + { + User::Leave(KErrUnsupportedProperty); + } + + CleanupStack::Pop(aValue); + property->AddValueL(aValue); + + TRACE_EXIT_POINT; + return *property; + } + +/** +Creates a new component, adds it to this object, and returns a modifiable +reference to it. +@param aType The type of component to be created. +@return A new component +@leave Leaves with KErrUnsupportedComponent if the given component is not a +valid subcomponent for this object. +@publishedPartner +*/ +EXPORT_C CICalComponent& CICalBase::AddComponentL(TICalComponentType aType) + { + TRACE_ENTRY_POINT; + + CICalComponent* component = CreateComponentL(aType); // Not taking ownership. + + if (!component) + { + User::Leave(KErrUnsupportedComponent); + } + TRACE_EXIT_POINT; + return *component; + } + +/** +Access function for the component array. +@return The array of components as a constant reference. +@publishedPartner +*/ +EXPORT_C const RPointerArray& CICalBase::Components() const + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + return iComponents; + } + +/** +Access function for the property array. +@return The array of properties as a constant reference. +@publishedPartner +*/ +EXPORT_C const RPointerArray& CICalBase::Properties() const + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + return iProperties; + } + +/** +Returns the descriptor form of this component type. +@return The descriptor form of this component type. +@publishedPartner +*/ +EXPORT_C const TDesC& CICalBase::TypeStringL() const + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + return TypeStringL(iComponentType); + } + +/** +Access method returning the concrete type as an enumeration. +@return The type of the concrete derived class. +@publishedPartner +*/ +EXPORT_C CICalBase::TICalComponentType CICalBase::Type() const + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + return iComponentType; + } + +/** +Checks for a component already existing in current object's sub-components +@param aType The type of the component to check. +@return ETrue if the property does exist, EFalse otherwise +@publishedPartner +*/ +EXPORT_C TBool CICalBase::ComponentExists(TICalComponentType aType) const + { + const TInt count = iComponents.Count(); + + for (TInt i = 0; i < count; i++) + { + if (iComponents[i]->Type() == aType) + { + TRACE_EXIT_POINT; + return ETrue; + } + } + + TRACE_EXIT_POINT; + return EFalse; + } + +/** +Finds the first property with a particular name and returns a pointer to it. +Ownership is not passed out. +@param aName The name of the property to search for. +@return A pointer to the property, or NULL. +@publishedPartner +*/ +EXPORT_C const CICalProperty* CICalBase::FindProperty(const TDesC& aName) const + { + TRACE_ENTRY_POINT; + + const TInt count = iProperties.Count(); + + for (TInt p = 0; p < count; ++p) + { + if (iProperties[p]->Type().CompareF(aName) == 0) + { + TRACE_EXIT_POINT; + return iProperties[p]; + } + } + + TRACE_EXIT_POINT; + return NULL; + } + +/** +Takes a line reader and reads lines from it until the end of the component is +located. Any other END:, or an end of file, are treated as errors. +@param aReader The line reader to read from. +@leave Leaves with KErrCorrupt if the component is corrupt. +@internalTechnology +*/ +void CICalBase::InternalizeL(CICalContentLineReader& aReader) + { + TRACE_ENTRY_POINT; + + TPtrC line; + TPtrC name; + TPtrC parameters; + TPtrC values; + + TInt error(aReader.GetNextContentLine(line)); + + while (error == KErrNone) + { + if (ExtractSectionsL(line, name, parameters, values) == KErrNone) + { + if (name.CompareF(KICalBegin) == 0) + { + // This is the start of a component: + + TICalComponentType type(TypeFromNameL(values)); + + if (type == EICalInvalid) + { + aReader.SkipComponentL(values); + } + else + { + CICalComponent* component = CreateComponentL(type); // Not taking ownership. + + if (component) + { + component->InternalizeL(aReader); + } + else + { + // This component cannot be nested - ignore it + aReader.SkipComponentL(values); + } + } + } + else if (name.CompareF(KICalEnd) == 0) + { + // This is the end of a component. + if (values.CompareF(TypeStringL(iComponentType)) != 0) + { + User::Leave(KErrCorrupt); // This is the end of a different component! + } + break; + } + else + { + // This is a property + + // Only allow properties with at least one value - if there is no value then + // ignore the property and continue. + if (values.Length() > 0) + { + CICalProperty* property = CreatePropertyL(name); // Not taking ownership + if (property) + { + if (name.CompareF(KICalRRule) == 0) + { + // This is a special case - commas have a different meaning. + ExtractParametersL(parameters, *property); + property->AddValueL(values); + } + else if (name.CompareF(KICalCategories) == 0) + { + // Outlook escapes the comma separators between categories. + // This is not part of the iCal specification. + ExtractParametersL(parameters, *property); + ExtractPropertyValuesL(values, *property, EEscapeValueSeparators); + } + else if (name.CompareF(KICalTzid) == 0) + { + // Outlook doesn't escape commas in TZID fields. + // This is not part of the iCal specification. + ExtractParametersL(parameters, *property); + property->AddValueL(values); + } + else + { + ExtractPropertyL(parameters, values, *property); + } + + // Remove property if it doesn't have a value. + if (property->Values().Count() == 0) + { + TInt index(iProperties.Find(property)); + + if (index >= 0) + { + iProperties.Remove(index); + } + + delete property; + } + else + { + // If the property is a method, remember it. + if (name.CompareF(KICalMethod) == 0) + { + TPtrC val; + val.Set(property->Values()[0]->TextL()); + if (val.CompareF(KICalPublish) == 0) + { + iMethod = CICalBase::EMethodPublish; + } + else if (val.CompareF(KICalRequest) == 0) + { + iMethod = CICalBase::EMethodRequest; + } + else if (val.CompareF(KICalReply) == 0) + { + iMethod = CICalBase::EMethodReply; + } + else if (val.CompareF(KICalAdd) == 0) + { + iMethod = CICalBase::EMethodAdd; + } + else if (val.CompareF(KICalCancel) == 0) + { + iMethod = CICalBase::EMethodCancel; + } + else if (val.CompareF(KICalRefresh) == 0) + { + iMethod = CICalBase::EMethodRefresh; + } + else if (val.CompareF(KICalCounter) == 0) + { + iMethod = CICalBase::EMethodCounter; + } + else if (val.CompareF(KICalDeclineCounter) == 0) + { + iMethod = CICalBase::EMethodDeclineCounter; + } + else + { + User::Leave(KErrCorrupt); + } + } + } + } + } + } + } + + error = aReader.GetNextContentLine(line); + } + + if ((error != KErrNone) && (error != KErrEof)) + { + User::Leave(error); + } + + TRACE_EXIT_POINT; + } + +/** +Takes a line writer and exports this component, including all owned properties +and sub components, to it. +@param aWriter the writer to export to. +@internalTechnology +*/ +void CICalBase::ExternalizeL(CICalContentLineWriter& aWriter) const + { + TRACE_ENTRY_POINT; + + aWriter.AppendL(KICalBegin()); + aWriter.AppendL(KICalColon()); + aWriter.AppendL(TypeStringL(iComponentType)); + + aWriter.WriteContentLineL(); + + // Externalize any component properties: + TInt count(iProperties.Count()); + + for (TInt prop = 0; prop < count; ++prop) + { + // Only externalise properties with a value. + if (iProperties[prop]->Values().Count() > 0) + { + iProperties[prop]->ExternalizeL(aWriter); + } + } + + // Externalize any child components: + count = iComponents.Count(); + for (TInt comp = 0; comp < count; ++comp) + { + iComponents[comp]->ExternalizeL(aWriter); + } + + aWriter.AppendL(KICalEnd()); + aWriter.AppendL(KICalColon()); + aWriter.AppendL(TypeStringL(iComponentType)); + aWriter.WriteContentLineL(); + + TRACE_EXIT_POINT; + } + +/** +Converts between a TICalComponentType and the type as a descriptor. +@param aName The type as a descriptor. +@return The type as an enumeration. +@leave KErrCorrupt if this is not a valid type. +@internalTechnology +*/ +CICalBase::TICalComponentType CICalBase::TypeFromNameL(const TDesC& aName) + { + TRACE_ENTRY_POINT; + + TICalComponentType type(EICalInvalid); + + if (aName.CompareF(KICalVCalendar) == 0) + { + type = EICalCalendar; + } + else if (aName.CompareF(KICalEvent) == 0) + { + type = EICalEvent; + } + else if (aName.CompareF(KICalTodo) == 0) + { + type = EICalTodo; + } + else if (aName.CompareF(KICalJournal) == 0) + { + type = EICalJournal; + } + else if (aName.CompareF(KICalAlarm) == 0) + { + type = EICalAlarm; + } + else if (aName.CompareF(KICalTimeZone) == 0) + { + type = EICalTimeZone; + } + else if (aName.CompareF(KICalFreeBusy) == 0) + { + type = EICalFreeBusy; + } + else if (aName.CompareF(KICalStandard) == 0) + { + type = EICalStandard; + } + else if (aName.CompareF(KICalDaylight) == 0) + { + type = EICalDaylight; + } + else + { + type = EICalInvalid; + } + + TRACE_EXIT_POINT; + return type; + } + +/** +Constructor +@internalTechnology +*/ +CICalBase::CICalBase() + { + TRACE_ENTRY_POINT; + TRACE_EXIT_POINT; + } + +/** +Converts between a TICalComponentType and the type as a descriptor. +@param aType The type as an enumeration. +@return The type as a descriptor. +@leave KErrCorrupt if this is not a valid type. +@internalTechnology +*/ +const TDesC& CICalBase::TypeStringL(TICalComponentType aType) const + { + TRACE_ENTRY_POINT; + + switch (aType) + { + case EICalCalendar: + TRACE_EXIT_POINT; + return KICalVCalendar(); + case EICalEvent: + TRACE_EXIT_POINT; + return KICalEvent(); + case EICalJournal: + TRACE_EXIT_POINT; + return KICalJournal(); + case EICalAlarm: + TRACE_EXIT_POINT; + return KICalAlarm(); + case EICalFreeBusy: + TRACE_EXIT_POINT; + return KICalFreeBusy(); + case EICalTodo: + TRACE_EXIT_POINT; + return KICalTodo(); + case EICalTimeZone: + TRACE_EXIT_POINT; + return KICalTimeZone(); + case EICalStandard: + TRACE_EXIT_POINT; + return KICalStandard(); + case EICalDaylight: + TRACE_EXIT_POINT; + return KICalDaylight(); + case EICalInvalid: + // Fall through... + default: + User::Leave(KErrCorrupt); + break; + }; + + TRACE_EXIT_POINT; + return KNullDesC; // Never reached. + } + +/** +Private implementation of AddComponentL(), used directly during InternalizeL(). +Checks that the given component can be nested within this component. The returned +pointer will be NULL if it is not supported - the calling function does NOT take +ownership of the returned pointer. +@param aType The type of component to be created. +@return pointer to newly added component. This will be NULL if the property is +not supported. +@leave Leaves if there is an error adding a new component. +@internalTechnology +*/ +CICalComponent* CICalBase::CreateComponentL(TICalComponentType aType) + { + TRACE_ENTRY_POINT; + + CICalComponent* component = NULL; + + if (ValidateComponent(aType)) + { + component = CICalComponent::CreateICalComponentLC(aType, iMethod); + User::LeaveIfError(iComponents.Append(component)); + CleanupStack::Pop(component); + } + + TRACE_EXIT_POINT; + return component; + } + +/** +Private implementation of AddPropertyL(), used directly during InternalizeL(). +Checks that the given property is supported by this component. The returned +pointer will be NULL if it is not supported - the calling function does NOT +take ownership of the returned pointer. +@param aName Name of the property to add. +@return pointer to newly added property. This will be NULL if the property is +not supported. +@leave Leaves if there is an error adding a new property. +@internalTechnology +*/ +CICalProperty* CICalBase::CreatePropertyL(const TDesC& aName) + { + TRACE_ENTRY_POINT; + + CICalProperty* property = NULL; + + if (ValidateProperty(aName)) + { + property = CICalProperty::NewLC(aName); + User::LeaveIfError(iProperties.Append(property)); + CleanupStack::Pop(property); + } + + TRACE_EXIT_POINT; + return property; + } + +TBool CICalBase::ValidateProperty(const TDesC& aName) const + { + TRACE_ENTRY_POINT; + + if ( + //Not checking properties in these components here... + (iComponentType == EICalCalendar) || (iComponentType == EICalAlarm) || + (iComponentType == EICalTimeZone) || (iComponentType == EICalDaylight) || + (iComponentType == EICalStandard) || (iComponentType == EICalJournal) || + (iComponentType == EICalEvent) || (iComponentType == EICalTodo) || + + //If no METHOD property exists, then RFC2446 does not apply... + (iComponentMethodBitMask & EMaskEventNone) || + (iComponentMethodBitMask & EMaskTodoNone) || + (iComponentMethodBitMask & EMaskJournalNone) || + (iComponentMethodBitMask & EMaskFreeBusyNone) || + + //Validate the property against RFC2446 + ((iComponentMethodBitMask & EICalAttendeeFlags) && (aName.CompareF(KICalAttendee) == 0)) || + ((iComponentMethodBitMask & EICalDtStampFlags) && (aName.CompareF(KICalDtstamp) == 0)) || + ((iComponentMethodBitMask & EICalDtStartFlags) && (aName.CompareF(KICalDtstart) == 0)) || + ((iComponentMethodBitMask & EICalOrganizerFlags) && (aName.CompareF(KICalOrganizer) == 0)) || + ((iComponentMethodBitMask & EICalSummaryFlags) && (aName.CompareF(KICalSummary) == 0)) || + ((iComponentMethodBitMask & EICalUIDFlags) && (aName.CompareF(KICalUid) == 0)) || + ((iComponentMethodBitMask & EICalRecurrenceIdFlags) && (aName.CompareF(KICalRecurrenceId) == 0)) || + ((iComponentMethodBitMask & EICalSequenceFlags) && (aName.CompareF(KICalSequence) == 0)) || + ((iComponentMethodBitMask & EICalAttachFlags) && (aName.CompareF(KICalAttach) == 0)) || + ((iComponentMethodBitMask & EICalCategoriesFlags) && (aName.CompareF(KICalCategories) == 0)) || + ((iComponentMethodBitMask & EICalClassFlags) && (aName.CompareF(KICalClass) == 0)) || + ((iComponentMethodBitMask & EICalCommentFlags) && (aName.CompareF(KICalComment) == 0)) || + ((iComponentMethodBitMask & EICalContactFlags) && (aName.CompareF(KICalContact) == 0)) || + ((iComponentMethodBitMask & EICalCreatedFlags) && (aName.CompareF(KICalCreated) == 0)) || + ((iComponentMethodBitMask & EICalDescriptionFlags) && (aName.CompareF(KICalDescription) == 0)) || + ((iComponentMethodBitMask & EICalDtEndFlags) && (aName.CompareF(KICalDtend) == 0)) || + ((iComponentMethodBitMask & EICalDurationFlags) && (aName.CompareF(KICalDuration) == 0)) || + ((iComponentMethodBitMask & EICalExDateFlags) && (aName.CompareF(KICalExdate) == 0)) || + ((iComponentMethodBitMask & EICalExRuleFlags) && (aName.CompareF(KICalExrule) == 0)) || + ((iComponentMethodBitMask & EICalGeoFlags) && (aName.CompareF(KICalGeo) == 0)) || + ((iComponentMethodBitMask & EICalLastModifiedFlags) && (aName.CompareF(KICalLastmodified) == 0)) || + ((iComponentMethodBitMask & EICalLocationFlags) && (aName.CompareF(KICalLocation) == 0)) || + ((iComponentMethodBitMask & EICalPriorityFlags) && (aName.CompareF(KICalPriority) == 0)) || + ((iComponentMethodBitMask & EICalRDateFlags) && (aName.CompareF(KICalRdate) == 0)) || + ((iComponentMethodBitMask & EICalRelatedToFlags) && (aName.CompareF(KICalRelatedto) == 0)) || + ((iComponentMethodBitMask & EICalRequestStatusFlags) && (aName.CompareF(KICalRequeststatus) == 0)) || + ((iComponentMethodBitMask & EICalResourcesFlags) && (aName.CompareF(KICalResources) == 0)) || + ((iComponentMethodBitMask & EICalRRuleFlags) && (aName.CompareF(KICalRRule) == 0)) || + ((iComponentMethodBitMask & EICalStatusFlags) && (aName.CompareF(KICalStatus) == 0)) || + ((iComponentMethodBitMask & EICalTranspFlags) && (aName.CompareF(KICalTransp) == 0)) || + ((iComponentMethodBitMask & EICalUrlFlags) && (aName.CompareF(KICalUrl) == 0)) || + ((iComponentMethodBitMask & EICalDueFlags) && (aName.CompareF(KICalDue) == 0)) || + ((iComponentMethodBitMask & EICalPercentCompleteFlags) && (aName.CompareF(KICalPercentcomplete) == 0)) || + ((iComponentMethodBitMask & EICalFreeBusyFlags) && (aName.CompareF(KICalFreebusy) == 0)) + ) + { + TRACE_EXIT_POINT; + return ValidatePropertyImpl(aName); + } + + //Allow all X-Properties + else if ((aName.Length() >= 2) && (aName.Left(2).CompareF(KICalXProperty) == 0)) + { + TRACE_EXIT_POINT; + return ETrue; + } + + TRACE_EXIT_POINT; + return EFalse; + } + +// End of File +