NS_IMETHODIMP
calIcalComponent::GetNextProperty(const nsACString &kind, calIIcalProperty **prop)
{
    NS_ENSURE_ARG_POINTER(prop);

    icalproperty_kind propkind =
        icalproperty_string_to_kind(PromiseFlatCString(kind).get());

    if (propkind == ICAL_NO_PROPERTY)
        return NS_ERROR_INVALID_ARG;
    icalproperty *icalprop = nullptr;
    if (propkind == ICAL_X_PROPERTY) {
        for (icalprop =
                 icalcomponent_get_next_property(mComponent, ICAL_X_PROPERTY);
             icalprop;
             icalprop = icalcomponent_get_next_property(mComponent,
                                                        ICAL_X_PROPERTY)) {

            if (kind.Equals(icalproperty_get_x_name(icalprop)))
                break;
        }
    } else {
        icalprop = icalcomponent_get_next_property(mComponent, propkind);
    }

    if (!icalprop) {
        *prop = nullptr;
        return NS_OK;
    }

    *prop = new calIcalProperty(icalprop, this);
    CAL_ENSURE_MEMORY(*prop);
    NS_ADDREF(*prop);
    return NS_OK;
}
NS_IMETHODIMP
calIcalComponent::GetNextSubcomponent(const nsACString& kind,
                                      calIIcalComponent **subcomp)
{
    NS_ENSURE_ARG_POINTER(subcomp);

    icalcomponent_kind compkind =
        icalcomponent_string_to_kind(PromiseFlatCString(kind).get());

    // Maybe someday I'll support X-COMPONENTs
    if (compkind == ICAL_NO_COMPONENT || compkind == ICAL_X_COMPONENT)
        return NS_ERROR_INVALID_ARG;

    icalcomponent *ical =
        icalcomponent_get_next_component(mComponent, compkind);
    if (!ical) {
        *subcomp = nullptr;
        return NS_OK;
    }

    *subcomp = new calIcalComponent(ical, this);
    CAL_ENSURE_MEMORY(*subcomp);
    NS_ADDREF(*subcomp);
    return NS_OK;
}
NS_IMETHODIMP
calIcalComponent::GetReferencedTimezones(uint32_t * aCount, calITimezone *** aTimezones)
{
    NS_ENSURE_ARG_POINTER(aCount);
    NS_ENSURE_ARG_POINTER(aTimezones);

    uint32_t const count = mReferencedTimezones.Count();
    if (count == 0) {
        *aCount = 0;
        *aTimezones = nullptr;
        return NS_OK;
    }

    calITimezone ** const timezones = static_cast<calITimezone **>(
        moz_xmalloc(sizeof(calITimezone *) * count));
    CAL_ENSURE_MEMORY(timezones);
    // tzptr will get used as an iterator by the enumerator function
    calITimezone ** tzptr = timezones;
    for (auto iter = mReferencedTimezones.ConstIter(); !iter.Done(); iter.Next() ) {
        NS_ADDREF(*tzptr = iter.Data());
        ++tzptr;
    }

    *aTimezones = timezones;
    *aCount = count;
    return NS_OK;
}
Ejemplo n.º 4
0
/* readonly attribute string className; */
NS_IMETHODIMP
calDateTime::GetClassName(char ** aClassName)
{
    NS_ENSURE_ARG_POINTER(aClassName);
    *aClassName = static_cast<char *>(nsMemory::Clone(CAL_STRLEN_ARGS("calDateTime") +1));
    CAL_ENSURE_MEMORY(*aClassName);
    return NS_OK;
}
Ejemplo n.º 5
0
NS_IMETHODIMP
calDateTime::Clone(calIDateTime **aResult)
{
    NS_ENSURE_ARG_POINTER(aResult);
    icaltimetype itt;
    ToIcalTime(&itt);
    calDateTime * const cdt = new calDateTime(&itt, mTimezone);
    CAL_ENSURE_MEMORY(cdt);
    NS_ADDREF(*aResult = cdt);
    return NS_OK;
}
Ejemplo n.º 6
0
NS_IMETHODIMP
calDateTime::GetIcalString(nsACString& aResult)
{
    icaltimetype t;
    ToIcalTime(&t);

    // note that ics is owned by libical, so we don't need to free
    char const * const ics = icaltime_as_ical_string(t);
    CAL_ENSURE_MEMORY(ics);
    aResult.Assign(ics);
    return NS_OK;
}
NS_IMETHODIMP
calICSService::CreateIcalPropertyFromString(const nsACString &str, calIIcalProperty **prop)
{
    NS_ENSURE_ARG_POINTER(prop);

    icalproperty *icalprop = icalproperty_new_from_string(PromiseFlatCString(str).get());

    *prop = new calIcalProperty(icalprop, nullptr);
    CAL_ENSURE_MEMORY(*prop);
    NS_ADDREF(*prop);
    return NS_OK;
}
nsresult calIcalProperty::setDatetime_(calIcalComponent * parent,
                                       icalproperty * prop,
                                       calIDateTime * dt)
{
    NS_ENSURE_ARG_POINTER(prop);
    NS_ENSURE_ARG_POINTER(dt);

    nsresult rv;
    nsCOMPtr<calIDateTimeLibical> icaldt = do_QueryInterface(dt, &rv);
    NS_ENSURE_SUCCESS(rv, rv);

    icaltimetype itt;
    icaldt->ToIcalTime(&itt);

    if (parent) {
        if (!itt.is_utc) {
            nsCOMPtr<calITimezone> tz;
            rv = dt->GetTimezone(getter_AddRefs(tz));
            NS_ENSURE_SUCCESS(rv, rv);
            if (itt.zone) {
                rv = parent->getParentVCalendarOrThis()->AddTimezoneReference(tz);
                NS_ENSURE_SUCCESS(rv, rv);
                icalparameter * const param = icalparameter_new_from_value_string(
                    ICAL_TZID_PARAMETER, icaltimezone_get_tzid(const_cast<icaltimezone *>(itt.zone)));
                icalproperty_set_parameter(prop, param);
            } else { // either floating or phantom:
                bool b = false;
                if (NS_FAILED(tz->GetIsFloating(&b)) || !b) {
                    // restore the same phantom TZID:
                    nsAutoCString tzid;
                    rv = tz->GetTzid(tzid);
                    NS_ENSURE_SUCCESS(rv, rv);
                    icalparameter * const param = icalparameter_new_from_value_string(ICAL_TZID_PARAMETER,
                                                                                      tzid.get());
                    icalproperty_set_parameter(prop, param);
                }
            }
        }
    } else if (!itt.is_date && !itt.is_utc && itt.zone) {
        // no parent to add the CTIMEZONE to: coerce DATETIMEs to UTC, DATEs to floating
        icaltimezone_convert_time(&itt,
                                  const_cast<icaltimezone *>(itt.zone),
                                  icaltimezone_get_utc_timezone());
        itt.zone = icaltimezone_get_utc_timezone();
        itt.is_utc = 1;
    }

    icalvalue * const val = icalvalue_new_datetime(itt);
    CAL_ENSURE_MEMORY(val);
    icalproperty_set_value(prop, val);
    return NS_OK;
}
Ejemplo n.º 9
0
NS_IMETHODIMP
calRecurrenceRule::Clone(calIRecurrenceItem **aResult)
{
    calRecurrenceRule * const crc = new calRecurrenceRule();
    CAL_ENSURE_MEMORY(crc);

    crc->mIsNegative = mIsNegative;
    crc->mIsByCount = mIsByCount;
    crc->mIcalRecur = mIcalRecur;

    NS_ADDREF(*aResult = crc);
    return NS_OK;
}
Ejemplo n.º 10
0
NS_IMETHODIMP
calDateTime::GetEndOfMonth(calIDateTime ** aResult)
{
    NS_ENSURE_ARG_POINTER(aResult);

    icaltimetype icalt;
    ToIcalTime(&icalt);
    icalt.day = icaltime_days_in_month(icalt.month, icalt.year);
    icalt.is_date = 1;

    calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
    CAL_ENSURE_MEMORY(cdt);
    NS_ADDREF(*aResult = cdt);
    return NS_OK;
}
Ejemplo n.º 11
0
NS_IMETHODIMP
calDateTime::GetStartOfMonth(calIDateTime ** aResult)
{
    NS_ENSURE_ARG_POINTER(aResult);
    ensureTimezone();

    icaltimetype icalt;
    ToIcalTime(&icalt);
    icalt.day = 1;
    icalt.is_date = 1;

    calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
    CAL_ENSURE_MEMORY(cdt);
    NS_ADDREF(*aResult = cdt);
    return NS_OK;
}
Ejemplo n.º 12
0
NS_IMETHODIMP
calDateTime::GetEndOfWeek(calIDateTime ** aResult)
{
    NS_ENSURE_ARG_POINTER(aResult);

    icaltimetype icalt;
    ToIcalTime(&icalt);
    int day_of_week = icaltime_day_of_week(icalt);
    if (day_of_week < 7)
        icaltime_adjust(&icalt, 7 - day_of_week, 0, 0, 0);
    icalt.is_date = 1;

    calDateTime * const cdt = new calDateTime(&icalt, mTimezone);
    CAL_ENSURE_MEMORY(cdt);
    NS_ADDREF(*aResult = cdt);
    return NS_OK;
}
Ejemplo n.º 13
0
nsresult calIcalComponent::SetDateTimeAttribute(icalproperty_kind kind,
                                                calIDateTime * dt)
{
    ClearAllProperties(kind);
    bool isValid;
    if (!dt || NS_FAILED(dt->GetIsValid(&isValid)) || !isValid) {
        return NS_OK;
    }
    icalproperty *prop = icalproperty_new(kind);
    CAL_ENSURE_MEMORY(prop);
    nsresult rc = calIcalProperty::setDatetime_(this, prop, dt);
    if (NS_SUCCEEDED(rc))
        icalcomponent_add_property(mComponent, prop);
    else
        icalproperty_free(prop);
    return rc;
}
Ejemplo n.º 14
0
NS_IMETHODIMP
calDateTime::SubtractDate(calIDateTime *aDate, calIDuration **aDuration)
{
    NS_ENSURE_ARG_POINTER(aDate);
    NS_ENSURE_ARG_POINTER(aDuration);

    // same as icaltime_subtract(), but minding timezones:
    PRTime t2t;
    aDate->GetNativeTime(&t2t);
    // for a duration, need to convert the difference in microseconds (prtime)
    // to seconds (libical), so divide by one million.
    icaldurationtype const idt = icaldurationtype_from_int(
        static_cast<int>((mNativeTime - t2t) / int64_t(PR_USEC_PER_SEC)));

    calDuration * const dur = new calDuration(&idt);
    CAL_ENSURE_MEMORY(dur);
    NS_ADDREF(*aDuration = dur);
    return NS_OK;
}
Ejemplo n.º 15
0
NS_IMETHODIMP
calICSService::CreateIcalProperty(const nsACString &kind, calIIcalProperty **prop)
{
    NS_ENSURE_ARG_POINTER(prop);
    icalproperty_kind propkind =
        icalproperty_string_to_kind(PromiseFlatCString(kind).get());

    if (propkind == ICAL_NO_PROPERTY)
        return NS_ERROR_INVALID_ARG;

    icalproperty *icalprop = icalproperty_new(propkind);
    if (!icalprop)
        return NS_ERROR_OUT_OF_MEMORY; // XXX translate

    if (propkind == ICAL_X_PROPERTY)
        icalproperty_set_x_name(icalprop, PromiseFlatCString(kind).get());

    *prop = new calIcalProperty(icalprop, nullptr);
    CAL_ENSURE_MEMORY(*prop);
    NS_ADDREF(*prop);
    return NS_OK;
}
Ejemplo n.º 16
0
NS_IMETHODIMP
calDateTime::GetInTimezone(calITimezone * aTimezone, calIDateTime ** aResult)
{
    NS_ENSURE_ARG_POINTER(aTimezone);
    NS_ENSURE_ARG_POINTER(aResult);

    if (mIsDate) {
        // if it's a date, we really just want to make a copy of this
        // and set the timezone.
        nsresult rv = Clone(aResult);
        if (NS_SUCCEEDED(rv)) {
            rv = (*aResult)->SetTimezone(aTimezone);
        }
        return rv;
    } else {
        icaltimetype icalt;
        ToIcalTime(&icalt);

        icaltimezone * tz = cal::getIcalTimezone(aTimezone);
        if (icalt.zone == tz) {
            return Clone(aResult);
        }

        /* If there's a zone, we need to convert; otherwise, we just
         * assign, since this item is floating */
        if (icalt.zone && tz) {
            icaltimezone_convert_time(&icalt, const_cast<icaltimezone *>(icalt.zone), tz);
        }
        icalt.zone = tz;
        icalt.is_utc = (tz && tz == icaltimezone_get_utc_timezone());

        calDateTime * cdt = new calDateTime(&icalt, aTimezone);
        CAL_ENSURE_MEMORY(cdt);
        NS_ADDREF (*aResult = cdt);
        return NS_OK;
    }
}
Ejemplo n.º 17
0
NS_IMETHODIMP
calIcalComponent::GetReferencedTimezones(uint32_t * aCount, calITimezone *** aTimezones)
{
    NS_ENSURE_ARG_POINTER(aCount);
    NS_ENSURE_ARG_POINTER(aTimezones);

    uint32_t const count = mReferencedTimezones.Count();
    if (count == 0) {
        *aCount = 0;
        *aTimezones = nullptr;
        return NS_OK;
    }

    calITimezone ** const timezones = static_cast<calITimezone **>(
        nsMemory::Alloc(sizeof(calITimezone *) * count));
    CAL_ENSURE_MEMORY(timezones);
    // tzptr will get used as an iterator by the enumerator function
    calITimezone ** tzptr = timezones;
    mReferencedTimezones.EnumerateRead(TimezoneHashToTimezoneArray, &tzptr);

    *aTimezones = timezones;
    *aCount = count;
    return NS_OK;
}
Ejemplo n.º 18
0
nsresult calIcalProperty::getDatetime_(calIcalComponent * parent,
                                       icalproperty * prop,
                                       calIDateTime ** dtp)
{
    icalvalue * const val = icalproperty_get_value(prop);
    icalvalue_kind const valkind = icalvalue_isa(val);
    if (valkind != ICAL_DATETIME_VALUE && valkind != ICAL_DATE_VALUE) {
        return NS_ERROR_UNEXPECTED;
    }
    icaltimetype itt = icalvalue_get_datetime(val);

    char const* tzid_ = nullptr;
    if (!itt.is_utc) {
        if (itt.zone) {
            tzid_ = icaltimezone_get_tzid(const_cast<icaltimezone *>(itt.zone));
        } else {
            // Need to get the tzid param. Unfortunatly, libical tends to return raw
            // ics strings, with quotes and everything. That's not what we want. Need
            // to work around.
            icalparameter * const tzparam = icalproperty_get_first_parameter(prop, ICAL_TZID_PARAMETER);
            if (tzparam) {
                tzid_ = icalparameter_get_xvalue(tzparam);
            }
        }
    }

    nsCOMPtr<calITimezone> tz;
    if (tzid_) {
        nsDependentCString const tzid(tzid_);
        calIcalComponent * comp = nullptr;
        if (parent) {
            comp = parent->getParentVCalendarOrThis();
        }
        // look up parent if timezone is already referenced:
        if (comp) {
            comp->mReferencedTimezones.Get(tzid, getter_AddRefs(tz));
        }
        if (!tz) {
            if (parent) {
                // passed tz provider has precedence over timezone service:
                calITimezoneProvider * const tzProvider = parent->getTzProvider();
                if (tzProvider) {
                    tzProvider->GetTimezone(tzid, getter_AddRefs(tz));
                    NS_ASSERTION(tz, tzid_);
                }
            }
            if (!tz) {
                // look up tz in tz service.
                // this hides errors from incorrect ics files, which could state
                // a TZID that is not present in the ics file.
                // The other way round, it makes this product more error tolerant.
                nsresult rv = cal::getTimezoneService()->GetTimezone(tzid, getter_AddRefs(tz));

                if (NS_FAILED(rv) || !tz) {
                    icaltimezone const* zone = itt.zone;
                    if (!zone && comp) {
                        // look up parent VCALENDAR for VTIMEZONE:
                        zone = icalcomponent_get_timezone(comp->mComponent, tzid_);
                        NS_ASSERTION(zone, tzid_);
                    }
                    if (zone) {
                        // We need to decouple this (inner) VTIMEZONE from the parent VCALENDAR to avoid
                        // running into circular references (referenced timezones):
                        icaltimezone * const clonedZone = icaltimezone_new();
                        CAL_ENSURE_MEMORY(clonedZone);
                        icalcomponent * const clonedZoneComp =
                            icalcomponent_new_clone(icaltimezone_get_component(const_cast<icaltimezone *>(zone)));
                        if (!clonedZoneComp) {
                            icaltimezone_free(clonedZone, 1 /* free struct */);
                            CAL_ENSURE_MEMORY(clonedZoneComp);
                        }
                        if (!icaltimezone_set_component(clonedZone, clonedZoneComp)) {
                            icaltimezone_free(clonedZone, 1 /* free struct */);
                            return NS_ERROR_INVALID_ARG;
                        }
                        nsCOMPtr<calIIcalComponent> const tzComp(new calIcalComponent(clonedZone, clonedZoneComp));
                        CAL_ENSURE_MEMORY(tzComp);
                        tz = new calTimezone(tzid, tzComp);
                        CAL_ENSURE_MEMORY(tz);
                    } else { // install phantom timezone, so the data could be repaired:
                        tz = new calTimezone(tzid, nullptr);
                        CAL_ENSURE_MEMORY(tz);
                    }
                }
            }
            if (comp && tz) {
                // assure timezone is known:
                comp->AddTimezoneReference(tz);
            }
        }
        if (tz) {
            // correct itt which would else appear floating:
            itt.zone = cal::getIcalTimezone(tz);
            itt.is_utc = 0;
        } else {
            cal::logMissingTimezone(tzid_);
        }
    }
    *dtp = new calDateTime(&itt, tz);
    CAL_ENSURE_MEMORY(*dtp);
    NS_ADDREF(*dtp);
    return NS_OK;
}