mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-10-26 22:12:16 +01:00
Bug 631382 - GTimeZone support for zoneinfo version 1
This commit is contained in:
@@ -117,12 +117,16 @@ struct ttinfo
|
|||||||
struct _GTimeZone
|
struct _GTimeZone
|
||||||
{
|
{
|
||||||
gchar *name;
|
gchar *name;
|
||||||
|
gchar version;
|
||||||
GBytes *zoneinfo;
|
GBytes *zoneinfo;
|
||||||
|
|
||||||
const struct tzhead *header;
|
const struct tzhead *header;
|
||||||
const struct ttinfo *infos;
|
const struct ttinfo *infos;
|
||||||
const gint64_be *trans;
|
union
|
||||||
|
{
|
||||||
|
const gint32_be *one;
|
||||||
|
const gint64_be *two;
|
||||||
|
} trans;
|
||||||
const guint8 *indices;
|
const guint8 *indices;
|
||||||
const gchar *abbrs;
|
const gchar *abbrs;
|
||||||
gint timecnt;
|
gint timecnt;
|
||||||
@@ -408,8 +412,7 @@ g_time_zone_new (const gchar *identifier)
|
|||||||
gsize size;
|
gsize size;
|
||||||
const struct tzhead *header = g_bytes_get_data (tz->zoneinfo, &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, "TZif", 4))
|
||||||
if (size < sizeof (struct tzhead) || memcmp (header, "TZif2", 5))
|
|
||||||
{
|
{
|
||||||
g_bytes_unref (tz->zoneinfo);
|
g_bytes_unref (tz->zoneinfo);
|
||||||
tz->zoneinfo = NULL;
|
tz->zoneinfo = NULL;
|
||||||
@@ -417,21 +420,32 @@ g_time_zone_new (const gchar *identifier)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
gint typecnt;
|
gint typecnt;
|
||||||
|
tz->version = header->tzh_version;
|
||||||
/* we trust the file completely. */
|
/* we trust the file completely. */
|
||||||
tz->header = (const struct tzhead *)
|
if (tz->version == '2')
|
||||||
(((const gchar *) (header + 1)) +
|
tz->header = (const struct tzhead *)
|
||||||
guint32_from_be(header->tzh_ttisgmtcnt) +
|
(((const gchar *) (header + 1)) +
|
||||||
guint32_from_be(header->tzh_ttisstdcnt) +
|
guint32_from_be(header->tzh_ttisgmtcnt) +
|
||||||
8 * guint32_from_be(header->tzh_leapcnt) +
|
guint32_from_be(header->tzh_ttisstdcnt) +
|
||||||
5 * guint32_from_be(header->tzh_timecnt) +
|
8 * guint32_from_be(header->tzh_leapcnt) +
|
||||||
6 * guint32_from_be(header->tzh_typecnt) +
|
5 * guint32_from_be(header->tzh_timecnt) +
|
||||||
guint32_from_be(header->tzh_charcnt));
|
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);
|
typecnt = guint32_from_be (tz->header->tzh_typecnt);
|
||||||
tz->timecnt = guint32_from_be (tz->header->tzh_timecnt);
|
tz->timecnt = guint32_from_be (tz->header->tzh_timecnt);
|
||||||
tz->trans = (gconstpointer) (tz->header + 1);
|
if (tz->version == '2')
|
||||||
tz->indices = (gconstpointer) (tz->trans + tz->timecnt);
|
{
|
||||||
|
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->infos = (gconstpointer) (tz->indices + tz->timecnt);
|
||||||
tz->abbrs = (gconstpointer) (tz->infos + typecnt);
|
tz->abbrs = (gconstpointer) (tz->infos + typecnt);
|
||||||
}
|
}
|
||||||
@@ -507,8 +521,12 @@ interval_start (GTimeZone *tz,
|
|||||||
gint interval)
|
gint interval)
|
||||||
{
|
{
|
||||||
if (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;
|
return G_MININT64;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -517,8 +535,12 @@ interval_end (GTimeZone *tz,
|
|||||||
gint interval)
|
gint interval)
|
||||||
{
|
{
|
||||||
if (interval < tz->timecnt)
|
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;
|
return G_MAXINT64;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user