diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2013-05-04 21:39:27 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2013-05-04 21:39:27 +0000 |
commit | fec6336699f34758d3e6cb41b2edf902fedb9035 (patch) | |
tree | 8256c1dbf3ca7c9e58a3dbecf07cf826fb2e0ce2 /src/libical/icaltz-util.c | |
parent | 7dbffd7e2b0067e834801617c5c486e3177f6709 (diff) | |
download | libical-master.tar.gz |
libical-1.0HEADlibical-1.0master
Diffstat (limited to 'src/libical/icaltz-util.c')
-rw-r--r-- | src/libical/icaltz-util.c | 211 |
1 files changed, 81 insertions, 130 deletions
diff --git a/src/libical/icaltz-util.c b/src/libical/icaltz-util.c index d999457..adf7598 100644 --- a/src/libical/icaltz-util.c +++ b/src/libical/icaltz-util.c @@ -25,12 +25,20 @@ #endif #include <string.h> +#ifdef HAVE_STDINT_H +#include <stdint.h> +#endif + #if defined(sun) && defined(__SVR4) +#include <sys/types.h> #include <sys/byteorder.h> #else # ifdef HAVE_BYTESWAP_H # include <byteswap.h> # endif +# ifdef HAVE_ENDIAN_H +# include <endian.h> +# else # ifdef HAVE_SYS_ENDIAN_H # include <sys/endian.h> # ifdef bswap32 @@ -39,12 +47,10 @@ # define bswap_32 swap32 # endif # endif -# ifdef HAVE_ENDIAN_H -# include <endian.h> -# endif +# endif #endif -#ifdef WIN32 +#ifdef _MSC_VER #if !defined(HAVE_BYTESWAP_H) && !defined(HAVE_SYS_ENDIAN_H) && !defined(HAVE_ENDIAN_H) #define bswap_16(x) (((x) << 8) & 0xff00) | (((x) >> 8 ) & 0xff) #define bswap_32(x) (((x) << 24) & 0xff000000) \ @@ -63,6 +69,12 @@ #include <io.h> #endif +#if defined(__APPLE__) +#define bswap_16(x) (((x) << 8) & 0xff00) | (((x) >> 8 ) & 0xff) +#define bswap_32 __builtin_bswap32 +#define bswap_64 __builtin_bswap64 +#endif + #ifndef PATH_MAX #define PATH_MAX 512 #endif @@ -176,42 +188,8 @@ zname_from_stridx (char *str, long int idx) return ret; } -static void -find_transidx (time_t *transitions, ttinfo *types, int *trans_idx, long int num_trans, int *stdidx, int *dstidx) -{ - time_t now = time (NULL); - int i, found = 0, idx; - - for (i = 0; i < num_trans; i++) { - if (now < transitions [i]) { - found = 1; - break; - } - } - - /* If the transition time is not found, it means the timezone does not have the dst changes */ - if (!found) { - *stdidx = i -1; - return; - } - - idx = trans_idx [i]; - types [idx].isdst ? (*dstidx = i) : (*stdidx = i); - - if (i < num_trans - 1) - i++; - else - return; - - idx = trans_idx [i]; - types [idx].isdst ? (*dstidx = i) : (*stdidx = i); - - return; -} - - static void -set_zone_directory (void) +set_zonedir (void) { char file_path[PATH_MAX]; const char *fname = ZONES_TAB_SYSTEM_FILENAME; @@ -231,7 +209,7 @@ const char * icaltzutil_get_zone_directory (void) { if (!zdir) - set_zone_directory (); + set_zonedir (); return zdir; } @@ -257,24 +235,28 @@ icaltzutil_fetch_timezone (const char *location) int ret = 0; FILE *f; tzinfo type_cnts; - unsigned int num_trans, num_types, num_chars, num_leaps, num_isstd, num_isgmt; + unsigned int i, num_trans, num_types, num_chars, num_leaps, num_isstd, num_isgmt; time_t *transitions = NULL; - time_t trans; - int *trans_idx = NULL, dstidx = -1, stdidx = -1, pos, sign, zidx, zp_idx, i; + time_t trans, start, end; + int *trans_idx = NULL, pos, sign, zidx, zp_idx, idx, prev_idx; ttinfo *types = NULL; char *znames = NULL, *full_path, *tzid, *r_trans, *temp; leap *leaps = NULL; - icalcomponent *tz_comp = NULL, *dst_comp = NULL, *std_comp = NULL; + icalcomponent *tz_comp = NULL, *comp = NULL; icalproperty *icalprop; icaltimetype dtstart, icaltime; struct icalrecurrencetype ical_recur; + const char *basedir; - if (!zdir) - set_zone_directory (); - - full_path = (char *) malloc (strlen (zdir) + strlen (location) + 2); - sprintf (full_path,"%s/%s",zdir, location); - + basedir = icaltzutil_get_zone_directory(); + if (!basedir) { + icalerror_set_errno (ICAL_FILE_ERROR); + return NULL; + } + + full_path = (char *) malloc (strlen (basedir) + strlen (location) + 2); + sprintf (full_path,"%s/%s",basedir, location); + if ((f = fopen (full_path, "rb")) == 0) { icalerror_set_errno (ICAL_FILE_ERROR); free (full_path); @@ -319,7 +301,10 @@ icaltzutil_fetch_timezone (const char *location) EFREAD(a, 4, 1, f); c = fgetc (f); types [i].isdst = c; - c = fgetc (f); + if((c = fgetc (f)) < 0) { + c = 0; + break; + } types [i].abbr = c; types [i].gmtoff = decode (a); } @@ -361,11 +346,6 @@ icaltzutil_fetch_timezone (const char *location) for (i = 0; i < num_types; i++) types [i].zname = zname_from_stridx (znames, types [i].abbr); - if (num_trans != 0) - find_transidx (transitions, types, trans_idx, num_trans, &stdidx, &dstidx); - else - stdidx = 0; - tz_comp = icalcomponent_new (ICAL_VTIMEZONE_COMPONENT); /* Add tzid property */ @@ -378,83 +358,54 @@ icaltzutil_fetch_timezone (const char *location) icalprop = icalproperty_new_x (location); icalproperty_set_x_name (icalprop, "X-LIC-LOCATION"); icalcomponent_add_property (tz_comp, icalprop); - - if (stdidx != -1) { - if (num_trans != 0) - zidx = trans_idx [stdidx]; - else - zidx = 0; - - std_comp = icalcomponent_new (ICAL_XSTANDARD_COMPONENT); - icalprop = icalproperty_new_tzname (types [zidx].zname); - icalcomponent_add_property (std_comp, icalprop); - - trans = transitions [stdidx] + types [zidx].gmtoff; - icaltime = icaltime_from_timet (trans, 0); - dtstart = icaltime; - dtstart.year = 1970; - dtstart.minute = dtstart.second = 0; - icalprop = icalproperty_new_dtstart (dtstart); - icalcomponent_add_property (std_comp, icalprop); - - /* If DST changes are present use RRULE */ - if (dstidx != -1) { - zp_idx = trans_idx [stdidx-1]; - icalrecurrencetype_clear (&ical_recur); - ical_recur.freq = ICAL_YEARLY_RECURRENCE; - ical_recur.by_month [0] = icaltime.month; - pos = calculate_pos (icaltime); - pos < 0 ? (sign = -1): (sign = 1); - ical_recur.by_day [0] = sign * ((abs (pos) * 8) + icaltime_day_of_week (icaltime)); - icalprop = icalproperty_new_rrule (ical_recur); - icalcomponent_add_property (std_comp, icalprop); - - icalprop = icalproperty_new_tzoffsetfrom (types [zp_idx].gmtoff); - icalcomponent_add_property (std_comp, icalprop); - } else { - icalprop = icalproperty_new_tzoffsetfrom (types [zidx].gmtoff); - icalcomponent_add_property (std_comp, icalprop); - } - icalprop = icalproperty_new_tzoffsetto (types [zidx].gmtoff); - icalcomponent_add_property (std_comp, icalprop); - - icalcomponent_add_component (tz_comp, std_comp); - } else - icalerror_set_errno (ICAL_MALFORMEDDATA_ERROR); - - if (dstidx != -1) { - zidx = trans_idx [dstidx]; - zp_idx = trans_idx [dstidx-1]; - dst_comp = icalcomponent_new (ICAL_XDAYLIGHT_COMPONENT); - icalprop = icalproperty_new_tzname (types [zidx].zname); - icalcomponent_add_property (dst_comp, icalprop); - - trans = transitions [dstidx] + types [zidx].gmtoff; - icaltime = icaltime_from_timet (trans, 0); - dtstart = icaltime; - dtstart.year = 1970; - dtstart.minute = dtstart.second = 0; + prev_idx = 0; + if (num_trans == 0) { + prev_idx = idx = 0; + + } else { + idx = trans_idx[0]; + } + start = 0; + for (i = 1; i < num_trans; i++, start = end) { + prev_idx = idx; + idx = trans_idx [i]; + end = transitions [i] + types [prev_idx].gmtoff; + /* don't bother starting until the epoch */ + if (0 > end) + continue; + + if (types [prev_idx].isdst) + comp = icalcomponent_new (ICAL_XDAYLIGHT_COMPONENT); + else + comp = icalcomponent_new (ICAL_XSTANDARD_COMPONENT); + icalprop = icalproperty_new_tzname (types [prev_idx].zname); + icalcomponent_add_property (comp, icalprop); + dtstart = icaltime_from_timet(start, 0); icalprop = icalproperty_new_dtstart (dtstart); - icalcomponent_add_property (dst_comp, icalprop); - - icalrecurrencetype_clear (&ical_recur); - ical_recur.freq = ICAL_YEARLY_RECURRENCE; - ical_recur.by_month [0] = icaltime.month; - pos = calculate_pos (icaltime); - pos < 0 ? (sign = -1): (sign = 1); - ical_recur.by_day [0] = sign * ((abs (pos) * 8) + icaltime_day_of_week (icaltime)); - icalprop = icalproperty_new_rrule (ical_recur); - icalcomponent_add_property (dst_comp, icalprop); - - icalprop = icalproperty_new_tzoffsetfrom (types [zp_idx].gmtoff); - icalcomponent_add_property (dst_comp, icalprop); - - icalprop = icalproperty_new_tzoffsetto (types [zidx].gmtoff); - icalcomponent_add_property (dst_comp, icalprop); - - icalcomponent_add_component (tz_comp, dst_comp); + icalcomponent_add_property (comp, icalprop); + icalprop = icalproperty_new_tzoffsetfrom (types [idx].gmtoff); + icalcomponent_add_property (comp, icalprop); + icalprop = icalproperty_new_tzoffsetto (types [prev_idx].gmtoff); + icalcomponent_add_property (comp, icalprop); + icalcomponent_add_component (tz_comp, comp); } + /* finally, add a last zone with no end date */ + if (types [idx].isdst) + comp = icalcomponent_new (ICAL_XDAYLIGHT_COMPONENT); + else + comp = icalcomponent_new (ICAL_XSTANDARD_COMPONENT); + icalprop = icalproperty_new_tzname (types [idx].zname); + icalcomponent_add_property (comp, icalprop); + dtstart = icaltime_from_timet(start, 0); + icalprop = icalproperty_new_dtstart (dtstart); + icalcomponent_add_property (comp, icalprop); + icalprop = icalproperty_new_tzoffsetfrom (types [prev_idx].gmtoff); + icalcomponent_add_property (comp, icalprop); + icalprop = icalproperty_new_tzoffsetto (types [idx].gmtoff); + icalcomponent_add_property (comp, icalprop); + icalcomponent_add_component (tz_comp, comp); + error: if (f) |