Ejemplo n.º 1
0
static void
add_timezone_cb (icalparameter *param,
                 gpointer data)
{
	icaltimezone *tz;
	const gchar *tzid;
	icalcomponent *vtz_comp;
	ForeachTzidData *f_data = (ForeachTzidData *) data;

	tzid = icalparameter_get_tzid (param);
	if (!tzid)
		return;

	tz = icalcomponent_get_timezone (f_data->vcal_comp, tzid);
	if (tz)
		return;

	tz = icalcomponent_get_timezone (f_data->icalcomp, tzid);
	if (!tz) {
		tz = icaltimezone_get_builtin_timezone_from_tzid (tzid);
		if (!tz)
			return;
	}

	vtz_comp = icaltimezone_get_component (tz);
	if (!vtz_comp)
		return;

	icalcomponent_add_component (
		f_data->vcal_comp,
		icalcomponent_new_clone (vtz_comp));
}
/**
 * e_cal_tzlookup_icomp:
 * @custom: must be a icalcomponent pointer which contains
 *          either a VCALENDAR with VTIMEZONEs or VTIMEZONES
 *          directly
 *
 * An implementation of the tzlookup callback which backends
 * like the file backend can use. Searches for the timezone
 * in the component list.
 */
icaltimezone *e_cal_tzlookup_icomp(const char *tzid,
                                   const void *custom,
                                   GError **error)
{
    icalcomponent *icomp = (icalcomponent *)custom;

    return icalcomponent_get_timezone(icomp, (char *)tzid);
}
/**
 * e_cal_tzlookup_icomp:
 * @tzid: ID of the timezone to lookup
 * @custom: must be a icalcomponent pointer which contains
 *          either a VCALENDAR with VTIMEZONEs or VTIMEZONES
 *          directly
 * @error: an error description in case of a failure
 *
 * An implementation of the tzlookup callback which backends
 * like the file backend can use. Searches for the timezone
 * in the component list.
 *
 * Returns: A timezone object, or %NULL if not found inside @custom. This object is owned
 *   by the @custom, thus do not free it.
 *
 * Since: 2.24
 *
 * Deprecated: 3.2: Use e_cal_client_tzlookup_icomp() instead.
 **/
icaltimezone *
e_cal_tzlookup_icomp (const gchar *tzid,
                      gconstpointer custom,
                      GError **error)
{
    icalcomponent *icomp = (icalcomponent *) custom;

    return icalcomponent_get_timezone (icomp, (gchar *) tzid);
}
calIcalComponent::GetLibicalTimezone()
{
    NS_ASSERTION(icalcomponent_isa(mComponent) == ICAL_VTIMEZONE_COMPONENT, "no VTIMEZONE -- unexpected!");
    if (!mTimezone && (icalcomponent_isa(mComponent) == ICAL_VTIMEZONE_COMPONENT)) {
        // xxx todo: libical needs a parent VCALENDAR to retrieve a icaltimezone
        NS_ASSERTION(mParent, "VTIMEZONE has no parent!");
        if (mParent) {
            icalproperty * const tzidProp = icalcomponent_get_first_property(mComponent, ICAL_TZID_PROPERTY);
            NS_ASSERTION(tzidProp, "no TZID property in VTIMEZONE!?");
            if (tzidProp) {
                mTimezone = icalcomponent_get_timezone(mParent->GetLibicalComponent(),
                                                       icalvalue_get_string(icalproperty_get_value(tzidProp)));
            }
        }
    }
    return mTimezone;
}
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;
}