Skip to content

Instantly share code, notes, and snippets.

@camillol
Created March 29, 2012 09:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save camillol/2235202 to your computer and use it in GitHub Desktop.
Save camillol/2235202 to your computer and use it in GitHub Desktop.
patch to let glib access timezone info on OS X
diff --git a/glib/gtimezone.c b/glib/gtimezone.c
index 8195106..08125ff 100644
--- a/glib/gtimezone.c
+++ b/glib/gtimezone.c
@@ -168,8 +168,12 @@ again:
G_UNLOCK(time_zones);
}
- if (tz->zoneinfo)
+ if (tz->zoneinfo) {
+ if (tz->header && tz->header->tzh_version != '2')
+ g_free (tz->trans);
+
g_bytes_unref (tz->zoneinfo);
+ }
g_free (tz->name);
@@ -408,13 +412,13 @@ 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))
+ /* check that it is a TZif file */
+ if (size < sizeof (struct tzhead) || memcmp (header, "TZif", 4))
{
g_bytes_unref (tz->zoneinfo);
tz->zoneinfo = NULL;
}
- else
+ else if (header->tzh_version == '2') /* version 2 */
{
gint typecnt;
@@ -435,6 +439,28 @@ g_time_zone_new (const gchar *identifier)
tz->infos = (gconstpointer) (tz->indices + tz->timecnt);
tz->abbrs = (gconstpointer) (tz->infos + typecnt);
}
+ else /* assume version 1 */
+ {
+ gint typecnt, i;
+
+ /* use first header */
+ tz->header = header;
+ typecnt = guint32_from_be (tz->header->tzh_typecnt);
+ tz->timecnt = guint32_from_be (tz->header->tzh_timecnt);
+
+ /* in version 1, transition times are 4 bytes long, so we need to convert them */
+ const gint32_be *trans32 = (gconstpointer) (tz->header + 1);
+ gint64_be *trans64 = g_malloc (sizeof (*tz->trans) * tz->timecnt);
+ for (i = 0; i < tz->timecnt; i++) {
+ gint64 tmp = GINT64_TO_BE (gint32_from_be (trans32[i]));
+ memcpy (&trans64[i], &tmp, sizeof tmp);
+ }
+ tz->trans = trans64;
+
+ tz->indices = (gconstpointer) (trans32 + tz->timecnt);
+ tz->infos = (gconstpointer) (tz->indices + tz->timecnt);
+ tz->abbrs = (gconstpointer) (tz->infos + typecnt);
+ }
}
if (identifier)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment