summaryrefslogtreecommitdiff
path: root/src/libical/icaltz-util.c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2013-05-04 21:39:27 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2013-05-04 21:39:27 +0000
commitfec6336699f34758d3e6cb41b2edf902fedb9035 (patch)
tree8256c1dbf3ca7c9e58a3dbecf07cf826fb2e0ce2 /src/libical/icaltz-util.c
parent7dbffd7e2b0067e834801617c5c486e3177f6709 (diff)
downloadlibical-master.tar.gz
Diffstat (limited to 'src/libical/icaltz-util.c')
-rw-r--r--src/libical/icaltz-util.c211
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)