[glib] Bug 631382 - GTimeZone support for zoneinfo version 1



commit 86a8ec047e43e5767604bea5d0b31b65165a8c94
Author: John Ralls <jralls ceridwen us>
Date:   Mon Sep 24 10:54:38 2012 -0700

    Bug 631382 - GTimeZone support for zoneinfo version 1

 glib/gtimezone.c |   62 ++++++++++++++++++++++++++++++++++++-----------------
 1 files changed, 42 insertions(+), 20 deletions(-)
---
diff --git a/glib/gtimezone.c b/glib/gtimezone.c
index e513f3b..50e7f39 100644
--- a/glib/gtimezone.c
+++ b/glib/gtimezone.c
@@ -117,12 +117,16 @@ struct ttinfo
 struct _GTimeZone
 {
   gchar   *name;
-
-  GBytes *zoneinfo;
+  gchar    version;
+  GBytes  *zoneinfo;
 
   const struct tzhead *header;
   const struct ttinfo *infos;
-  const gint64_be     *trans;
+  union
+  {
+    const gint32_be     *one;
+    const gint64_be     *two;
+  } trans;
   const guint8        *indices;
   const gchar         *abbrs;
   gint                 timecnt;
@@ -408,8 +412,7 @@ g_time_zone_new (const gchar *identifier)
           gsize size;
           const struct tzhead *header = g_bytes_get_data (tz->zoneinfo, &size);
 
-          /* we only bother to support version 2 */
-          if (size < sizeof (struct tzhead) || memcmp (header, "TZif2", 5))
+          if (size < sizeof (struct tzhead) || memcmp (header, "TZif", 4))
             {
               g_bytes_unref (tz->zoneinfo);
               tz->zoneinfo = NULL;
@@ -417,21 +420,32 @@ g_time_zone_new (const gchar *identifier)
           else
             {
               gint typecnt;
-
+              tz->version = header->tzh_version;
               /* we trust the file completely. */
-              tz->header = (const struct tzhead *)
-                (((const gchar *) (header + 1)) +
-                  guint32_from_be(header->tzh_ttisgmtcnt) +
-                  guint32_from_be(header->tzh_ttisstdcnt) +
-                  8 * guint32_from_be(header->tzh_leapcnt) +
-                  5 * guint32_from_be(header->tzh_timecnt) +
-                  6 * guint32_from_be(header->tzh_typecnt) +
-                  guint32_from_be(header->tzh_charcnt));
+              if (tz->version == '2')
+                tz->header = (const struct tzhead *)
+                  (((const gchar *) (header + 1)) +
+                   guint32_from_be(header->tzh_ttisgmtcnt) +
+                   guint32_from_be(header->tzh_ttisstdcnt) +
+                   8 * guint32_from_be(header->tzh_leapcnt) +
+                   5 * guint32_from_be(header->tzh_timecnt) +
+                   6 * guint32_from_be(header->tzh_typecnt) +
+                   guint32_from_be(header->tzh_charcnt));
+              else
+                tz->header = header;
 
               typecnt     = guint32_from_be (tz->header->tzh_typecnt);
               tz->timecnt = guint32_from_be (tz->header->tzh_timecnt);
-              tz->trans   = (gconstpointer) (tz->header + 1);
-              tz->indices = (gconstpointer) (tz->trans + tz->timecnt);
+              if (tz->version == '2')
+                {
+                  tz->trans.two = (gconstpointer) (tz->header + 1);
+                  tz->indices   = (gconstpointer) (tz->trans.two + tz->timecnt);
+                }
+              else
+                {
+                  tz->trans.one = (gconstpointer) (tz->header + 1);
+                  tz->indices   = (gconstpointer) (tz->trans.one + tz->timecnt);
+                }
               tz->infos   = (gconstpointer) (tz->indices + tz->timecnt);
               tz->abbrs   = (gconstpointer) (tz->infos + typecnt);
             }
@@ -507,8 +521,12 @@ interval_start (GTimeZone *tz,
                 gint       interval)
 {
   if (interval)
-    return gint64_from_be (tz->trans[interval - 1]);
-
+    {
+      if (tz->version == '2')
+        return gint64_from_be (tz->trans.two[interval - 1]);
+      else
+        return gint32_from_be (tz->trans.one[interval - 1]);
+    }
   return G_MININT64;
 }
 
@@ -517,8 +535,12 @@ interval_end (GTimeZone *tz,
               gint       interval)
 {
   if (interval < tz->timecnt)
-    return gint64_from_be (tz->trans[interval]) - 1;
-
+    {
+      if (tz->version == '2')
+        return gint64_from_be (tz->trans.two[interval]) - 1;
+      else
+        return gint32_from_be (tz->trans.one[interval]) - 1;
+    }
   return G_MAXINT64;
 }
 



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]