summaryrefslogtreecommitdiff
path: root/ext
diff options
context:
space:
mode:
Diffstat (limited to 'ext')
-rw-r--r--ext/date/lib/parse_tz.c168
-rw-r--r--ext/date/lib/timelib.c40
-rw-r--r--ext/date/lib/timelib_structs.h22
3 files changed, 127 insertions, 103 deletions
diff --git a/ext/date/lib/parse_tz.c b/ext/date/lib/parse_tz.c
index db29495a85..8a48fadb63 100644
--- a/ext/date/lib/parse_tz.c
+++ b/ext/date/lib/parse_tz.c
@@ -77,20 +77,20 @@ static void read_header(const unsigned char **tzf, timelib_tzinfo *tz)
uint32_t buffer[6];
memcpy(&buffer, *tzf, sizeof(buffer));
- tz->ttisgmtcnt = timelib_conv_int(buffer[0]);
- tz->ttisstdcnt = timelib_conv_int(buffer[1]);
- tz->leapcnt = timelib_conv_int(buffer[2]);
- tz->timecnt = timelib_conv_int(buffer[3]);
- tz->typecnt = timelib_conv_int(buffer[4]);
- tz->charcnt = timelib_conv_int(buffer[5]);
+ tz->bit32.ttisgmtcnt = timelib_conv_int(buffer[0]);
+ tz->bit32.ttisstdcnt = timelib_conv_int(buffer[1]);
+ tz->bit32.leapcnt = timelib_conv_int(buffer[2]);
+ tz->bit32.timecnt = timelib_conv_int(buffer[3]);
+ tz->bit32.typecnt = timelib_conv_int(buffer[4]);
+ tz->bit32.charcnt = timelib_conv_int(buffer[5]);
*tzf += sizeof(buffer);
}
-static void skip_transistions_64bit(const unsigned char **tzf, timelib_tzinfo *tz)
+static void skip_64bit_transistions(const unsigned char **tzf, timelib_tzinfo *tz)
{
- if (tz->timecnt) {
- *tzf += (sizeof(int64_t) * (tz->timecnt + 1));
- *tzf += (sizeof(unsigned char) * (tz->timecnt + 1));
+ if (tz->bit64.timecnt) {
+ *tzf += (sizeof(int64_t) * tz->bit64.timecnt);
+ *tzf += (sizeof(unsigned char) * tz->bit64.timecnt);
}
}
@@ -100,42 +100,42 @@ static void read_transistions(const unsigned char **tzf, timelib_tzinfo *tz)
uint32_t i;
unsigned char *cbuffer = NULL;
- if (tz->timecnt) {
- buffer = (int32_t*) malloc(tz->timecnt * sizeof(int32_t));
+ if (tz->bit32.timecnt) {
+ buffer = (int32_t*) malloc(tz->bit32.timecnt * sizeof(int32_t));
if (!buffer) {
return;
}
- memcpy(buffer, *tzf, sizeof(int32_t) * tz->timecnt);
- *tzf += (sizeof(int32_t) * tz->timecnt);
- for (i = 0; i < tz->timecnt; i++) {
+ memcpy(buffer, *tzf, sizeof(int32_t) * tz->bit32.timecnt);
+ *tzf += (sizeof(int32_t) * tz->bit32.timecnt);
+ for (i = 0; i < tz->bit32.timecnt; i++) {
buffer[i] = timelib_conv_int(buffer[i]);
}
- cbuffer = (unsigned char*) malloc(tz->timecnt * sizeof(unsigned char));
+ cbuffer = (unsigned char*) malloc(tz->bit32.timecnt * sizeof(unsigned char));
if (!cbuffer) {
free(buffer);
return;
}
- memcpy(cbuffer, *tzf, sizeof(unsigned char) * tz->timecnt);
- *tzf += sizeof(unsigned char) * tz->timecnt;
+ memcpy(cbuffer, *tzf, sizeof(unsigned char) * tz->bit32.timecnt);
+ *tzf += sizeof(unsigned char) * tz->bit32.timecnt;
}
tz->trans = buffer;
tz->trans_idx = cbuffer;
}
-static void skip_types_64bit(const unsigned char **tzf, timelib_tzinfo *tz)
+static void skip_64bit_types(const unsigned char **tzf, timelib_tzinfo *tz)
{
- *tzf += sizeof(unsigned char) * 6 * tz->typecnt;
- *tzf += sizeof(char) * tz->charcnt;
- if (tz->leapcnt) {
- *tzf += sizeof(int64_t) * tz->leapcnt * 2;
+ *tzf += sizeof(unsigned char) * 6 * tz->bit64.typecnt;
+ *tzf += sizeof(char) * tz->bit64.charcnt;
+ if (tz->bit64.leapcnt) {
+ *tzf += sizeof(int64_t) * tz->bit64.leapcnt * 2;
}
- if (tz->ttisstdcnt) {
- *tzf += sizeof(unsigned char) * tz->ttisstdcnt;
+ if (tz->bit64.ttisstdcnt) {
+ *tzf += sizeof(unsigned char) * tz->bit64.ttisstdcnt;
}
- if (tz->ttisgmtcnt) {
- *tzf += sizeof(unsigned char) * tz->ttisgmtcnt;
+ if (tz->bit64.ttisgmtcnt) {
+ *tzf += sizeof(unsigned char) * tz->bit64.ttisgmtcnt;
}
}
@@ -145,20 +145,20 @@ static void read_types(const unsigned char **tzf, timelib_tzinfo *tz)
int32_t *leap_buffer;
unsigned int i, j;
- buffer = (unsigned char*) malloc(tz->typecnt * sizeof(unsigned char) * 6);
+ buffer = (unsigned char*) malloc(tz->bit32.typecnt * sizeof(unsigned char) * 6);
if (!buffer) {
return;
}
- memcpy(buffer, *tzf, sizeof(unsigned char) * 6 * tz->typecnt);
- *tzf += sizeof(unsigned char) * 6 * tz->typecnt;
+ memcpy(buffer, *tzf, sizeof(unsigned char) * 6 * tz->bit32.typecnt);
+ *tzf += sizeof(unsigned char) * 6 * tz->bit32.typecnt;
- tz->type = (ttinfo*) malloc(tz->typecnt * sizeof(struct ttinfo));
+ tz->type = (ttinfo*) malloc(tz->bit32.typecnt * sizeof(struct ttinfo));
if (!tz->type) {
free(buffer);
return;
}
- for (i = 0; i < tz->typecnt; i++) {
+ for (i = 0; i < tz->bit32.typecnt; i++) {
j = i * 6;
tz->type[i].offset = (buffer[j] * 16777216) + (buffer[j + 1] * 65536) + (buffer[j + 2] * 256) + buffer[j + 3];
tz->type[i].isdst = buffer[j + 4];
@@ -166,56 +166,56 @@ static void read_types(const unsigned char **tzf, timelib_tzinfo *tz)
}
free(buffer);
- tz->timezone_abbr = (char*) malloc(tz->charcnt);
+ tz->timezone_abbr = (char*) malloc(tz->bit32.charcnt);
if (!tz->timezone_abbr) {
return;
}
- memcpy(tz->timezone_abbr, *tzf, sizeof(char) * tz->charcnt);
- *tzf += sizeof(char) * tz->charcnt;
+ memcpy(tz->timezone_abbr, *tzf, sizeof(char) * tz->bit32.charcnt);
+ *tzf += sizeof(char) * tz->bit32.charcnt;
- if (tz->leapcnt) {
- leap_buffer = (int32_t *) malloc(tz->leapcnt * 2 * sizeof(int32_t));
+ if (tz->bit32.leapcnt) {
+ leap_buffer = (int32_t *) malloc(tz->bit32.leapcnt * 2 * sizeof(int32_t));
if (!leap_buffer) {
return;
}
- memcpy(leap_buffer, *tzf, sizeof(int32_t) * tz->leapcnt * 2);
- *tzf += sizeof(int32_t) * tz->leapcnt * 2;
+ memcpy(leap_buffer, *tzf, sizeof(int32_t) * tz->bit32.leapcnt * 2);
+ *tzf += sizeof(int32_t) * tz->bit32.leapcnt * 2;
- tz->leap_times = (tlinfo*) malloc(tz->leapcnt * sizeof(tlinfo));
+ tz->leap_times = (tlinfo*) malloc(tz->bit32.leapcnt * sizeof(tlinfo));
if (!tz->leap_times) {
free(leap_buffer);
return;
}
- for (i = 0; i < tz->leapcnt; i++) {
+ for (i = 0; i < tz->bit32.leapcnt; i++) {
tz->leap_times[i].trans = timelib_conv_int(leap_buffer[i * 2]);
tz->leap_times[i].offset = timelib_conv_int(leap_buffer[i * 2 + 1]);
}
free(leap_buffer);
}
- if (tz->ttisstdcnt) {
- buffer = (unsigned char*) malloc(tz->ttisstdcnt * sizeof(unsigned char));
+ if (tz->bit32.ttisstdcnt) {
+ buffer = (unsigned char*) malloc(tz->bit32.ttisstdcnt * sizeof(unsigned char));
if (!buffer) {
return;
}
- memcpy(buffer, *tzf, sizeof(unsigned char) * tz->ttisstdcnt);
- *tzf += sizeof(unsigned char) * tz->ttisstdcnt;
+ memcpy(buffer, *tzf, sizeof(unsigned char) * tz->bit32.ttisstdcnt);
+ *tzf += sizeof(unsigned char) * tz->bit32.ttisstdcnt;
- for (i = 0; i < tz->ttisstdcnt; i++) {
+ for (i = 0; i < tz->bit32.ttisstdcnt; i++) {
tz->type[i].isstdcnt = buffer[i];
}
free(buffer);
}
- if (tz->ttisgmtcnt) {
- buffer = (unsigned char*) malloc(tz->ttisgmtcnt * sizeof(unsigned char));
+ if (tz->bit32.ttisgmtcnt) {
+ buffer = (unsigned char*) malloc(tz->bit32.ttisgmtcnt * sizeof(unsigned char));
if (!buffer) {
return;
}
- memcpy(buffer, *tzf, sizeof(unsigned char) * tz->ttisgmtcnt);
- *tzf += sizeof(unsigned char) * tz->ttisgmtcnt;
+ memcpy(buffer, *tzf, sizeof(unsigned char) * tz->bit32.ttisgmtcnt);
+ *tzf += sizeof(unsigned char) * tz->bit32.ttisgmtcnt;
- for (i = 0; i < tz->ttisgmtcnt; i++) {
+ for (i = 0; i < tz->bit32.ttisgmtcnt; i++) {
tz->type[i].isgmtcnt = buffer[i];
}
free(buffer);
@@ -261,12 +261,12 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz)
printf("Geo Location: %f,%f\n", tz->location.latitude, tz->location.longitude);
printf("Comments:\n%s\n", tz->location.comments);
printf("BC: %s\n", tz->bc ? "" : "yes");
- printf("UTC/Local count: %lu\n", (unsigned long) tz->ttisgmtcnt);
- printf("Std/Wall count: %lu\n", (unsigned long) tz->ttisstdcnt);
- printf("Leap.sec. count: %lu\n", (unsigned long) tz->leapcnt);
- printf("Trans. count: %lu\n", (unsigned long) tz->timecnt);
- printf("Local types count: %lu\n", (unsigned long) tz->typecnt);
- printf("Zone Abbr. count: %lu\n", (unsigned long) tz->charcnt);
+ printf("UTC/Local count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.ttisgmtcnt);
+ printf("Std/Wall count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.ttisstdcnt);
+ printf("Leap.sec. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.leapcnt);
+ printf("Trans. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.timecnt);
+ printf("Local types count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.typecnt);
+ printf("Zone Abbr. count: " TIMELIB_ULONG_FMT "\n", (timelib_ulong) tz->bit32.charcnt);
printf ("%8s (%12s) = %3d [%5ld %1d %3d '%s' (%d,%d)]\n",
"", "", 0,
@@ -277,7 +277,7 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz)
tz->type[0].isstdcnt,
tz->type[0].isgmtcnt
);
- for (i = 0; i < tz->timecnt; i++) {
+ for (i = 0; i < tz->bit32.timecnt; i++) {
printf ("%08X (%12d) = %3d [%5ld %1d %3d '%s' (%d,%d)]\n",
tz->trans[i], tz->trans[i], tz->trans_idx[i],
(long int) tz->type[tz->trans_idx[i]].offset,
@@ -288,7 +288,7 @@ void timelib_dump_tzinfo(timelib_tzinfo *tz)
tz->type[tz->trans_idx[i]].isgmtcnt
);
}
- for (i = 0; i < tz->leapcnt; i++) {
+ for (i = 0; i < tz->bit32.leapcnt; i++) {
printf ("%08X (%12ld) = %d\n",
tz->leap_times[i].trans,
(long) tz->leap_times[i].trans,
@@ -352,10 +352,23 @@ int timelib_timezone_id_is_valid(char *timezone, const timelib_tzdb *tzdb)
return (seek_to_tz_position(&tzf, timezone, tzdb));
}
-static void skip_2nd_header_and_data(const unsigned char **tzf, timelib_tzinfo *tz)
+static void skip_64bit_preamble(const unsigned char **tzf, timelib_tzinfo *tz)
{
- *tzf += 20; /* skip 2nd header (preamble) */
- *tzf += sizeof(int32_t) * 6; /* Counts */
+ *tzf += 20;
+}
+
+static void read_64bit_header(const unsigned char **tzf, timelib_tzinfo *tz)
+{
+ uint32_t buffer[6];
+
+ memcpy(&buffer, *tzf, sizeof(buffer));
+ tz->bit64.ttisgmtcnt = timelib_conv_int(buffer[0]);
+ tz->bit64.ttisstdcnt = timelib_conv_int(buffer[1]);
+ tz->bit64.leapcnt = timelib_conv_int(buffer[2]);
+ tz->bit64.timecnt = timelib_conv_int(buffer[3]);
+ tz->bit64.typecnt = timelib_conv_int(buffer[4]);
+ tz->bit64.charcnt = timelib_conv_int(buffer[5]);
+ *tzf += sizeof(buffer);
}
timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb)
@@ -372,9 +385,10 @@ timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb)
read_transistions(&tzf, tmp);
read_types(&tzf, tmp);
if (version == 2) {
- skip_2nd_header_and_data(&tzf, tmp);
- skip_transistions_64bit(&tzf, tmp);
- skip_types_64bit(&tzf, tmp);
+ skip_64bit_preamble(&tzf, tmp);
+ read_64bit_header(&tzf, tmp);
+ skip_64bit_transistions(&tzf, tmp);
+ skip_64bit_types(&tzf, tmp);
skip_posix_string(&tzf, tmp);
}
read_location(&tzf, tmp);
@@ -389,18 +403,18 @@ static ttinfo* fetch_timezone_offset(timelib_tzinfo *tz, timelib_sll ts, timelib
{
uint32_t i;
- /* If there is no transistion time, we pick the first one, if that doesn't
+ /* If there is no transition time, we pick the first one, if that doesn't
* exist we return NULL */
- if (!tz->timecnt || !tz->trans) {
+ if (!tz->bit32.timecnt || !tz->trans) {
*transition_time = 0;
- if (tz->typecnt == 1) {
+ if (tz->bit32.typecnt == 1) {
return &(tz->type[0]);
}
return NULL;
}
- /* If the TS is lower than the first transistion time, then we scan over
- * all the transistion times to find the first non-DST one, or the first
+ /* If the TS is lower than the first transition time, then we scan over
+ * all the transition times to find the first non-DST one, or the first
* one in case there are only DST entries. Not sure which smartass came up
* with this idea in the first though :) */
if (ts < tz->trans[0]) {
@@ -408,10 +422,10 @@ static ttinfo* fetch_timezone_offset(timelib_tzinfo *tz, timelib_sll ts, timelib
*transition_time = 0;
j = 0;
- while (j < tz->timecnt && tz->type[j].isdst) {
+ while (j < tz->bit32.timecnt && tz->type[j].isdst) {
++j;
}
- if (j == tz->timecnt) {
+ if (j == tz->bit32.timecnt) {
j = 0;
}
return &(tz->type[j]);
@@ -419,25 +433,25 @@ static ttinfo* fetch_timezone_offset(timelib_tzinfo *tz, timelib_sll ts, timelib
/* In all other cases we loop through the available transtion times to find
* the correct entry */
- for (i = 0; i < tz->timecnt; i++) {
+ for (i = 0; i < tz->bit32.timecnt; i++) {
if (ts < tz->trans[i]) {
*transition_time = tz->trans[i - 1];
return &(tz->type[tz->trans_idx[i - 1]]);
}
}
- *transition_time = tz->trans[tz->timecnt - 1];
- return &(tz->type[tz->trans_idx[tz->timecnt - 1]]);
+ *transition_time = tz->trans[tz->bit32.timecnt - 1];
+ return &(tz->type[tz->trans_idx[tz->bit32.timecnt - 1]]);
}
static tlinfo* fetch_leaptime_offset(timelib_tzinfo *tz, timelib_sll ts)
{
int i;
- if (!tz->leapcnt || !tz->leap_times) {
+ if (!tz->bit32.leapcnt || !tz->leap_times) {
return NULL;
}
- for (i = tz->leapcnt - 1; i > 0; i--) {
+ for (i = tz->bit32.leapcnt - 1; i > 0; i--) {
if (ts > tz->leap_times[i].trans) {
return &(tz->leap_times[i]);
}
diff --git a/ext/date/lib/timelib.c b/ext/date/lib/timelib.c
index b2da6f86c9..b0bb699a96 100644
--- a/ext/date/lib/timelib.c
+++ b/ext/date/lib/timelib.c
@@ -116,26 +116,26 @@ timelib_tzinfo* timelib_tzinfo_ctor(char *name)
timelib_tzinfo *timelib_tzinfo_clone(timelib_tzinfo *tz)
{
timelib_tzinfo *tmp = timelib_tzinfo_ctor(tz->name);
- tmp->ttisgmtcnt = tz->ttisgmtcnt;
- tmp->ttisstdcnt = tz->ttisstdcnt;
- tmp->leapcnt = tz->leapcnt;
- tmp->timecnt = tz->timecnt;
- tmp->typecnt = tz->typecnt;
- tmp->charcnt = tz->charcnt;
-
- tmp->trans = (int32_t *) malloc(tz->timecnt * sizeof(int32_t));
- tmp->trans_idx = (unsigned char*) malloc(tz->timecnt * sizeof(unsigned char));
- memcpy(tmp->trans, tz->trans, tz->timecnt * sizeof(int32_t));
- memcpy(tmp->trans_idx, tz->trans_idx, tz->timecnt * sizeof(unsigned char));
-
- tmp->type = (ttinfo*) malloc(tz->typecnt * sizeof(struct ttinfo));
- memcpy(tmp->type, tz->type, tz->typecnt * sizeof(struct ttinfo));
-
- tmp->timezone_abbr = (char*) malloc(tz->charcnt);
- memcpy(tmp->timezone_abbr, tz->timezone_abbr, tz->charcnt);
-
- tmp->leap_times = (tlinfo*) malloc(tz->leapcnt * sizeof(tlinfo));
- memcpy(tmp->leap_times, tz->leap_times, tz->leapcnt * sizeof(tlinfo));
+ tmp->bit32.ttisgmtcnt = tz->bit32.ttisgmtcnt;
+ tmp->bit32.ttisstdcnt = tz->bit32.ttisstdcnt;
+ tmp->bit32.leapcnt = tz->bit32.leapcnt;
+ tmp->bit32.timecnt = tz->bit32.timecnt;
+ tmp->bit32.typecnt = tz->bit32.typecnt;
+ tmp->bit32.charcnt = tz->bit32.charcnt;
+
+ tmp->trans = (int32_t *) malloc(tz->bit32.timecnt * sizeof(int32_t));
+ tmp->trans_idx = (unsigned char*) malloc(tz->bit32.timecnt * sizeof(unsigned char));
+ memcpy(tmp->trans, tz->trans, tz->bit32.timecnt * sizeof(int32_t));
+ memcpy(tmp->trans_idx, tz->trans_idx, tz->bit32.timecnt * sizeof(unsigned char));
+
+ tmp->type = (ttinfo*) malloc(tz->bit32.typecnt * sizeof(struct ttinfo));
+ memcpy(tmp->type, tz->type, tz->bit32.typecnt * sizeof(struct ttinfo));
+
+ tmp->timezone_abbr = (char*) malloc(tz->bit32.charcnt);
+ memcpy(tmp->timezone_abbr, tz->timezone_abbr, tz->bit32.charcnt);
+
+ tmp->leap_times = (tlinfo*) malloc(tz->bit32.leapcnt * sizeof(tlinfo));
+ memcpy(tmp->leap_times, tz->leap_times, tz->bit32.leapcnt * sizeof(tlinfo));
return tmp;
}
diff --git a/ext/date/lib/timelib_structs.h b/ext/date/lib/timelib_structs.h
index 8f36fe1ba7..f16dc45242 100644
--- a/ext/date/lib/timelib_structs.h
+++ b/ext/date/lib/timelib_structs.h
@@ -104,12 +104,22 @@ typedef struct tlocinfo
typedef struct timelib_tzinfo
{
char *name;
- uint32_t ttisgmtcnt;
- uint32_t ttisstdcnt;
- uint32_t leapcnt;
- uint32_t timecnt;
- uint32_t typecnt;
- uint32_t charcnt;
+ struct {
+ uint32_t ttisgmtcnt;
+ uint32_t ttisstdcnt;
+ uint32_t leapcnt;
+ uint32_t timecnt;
+ uint32_t typecnt;
+ uint32_t charcnt;
+ } bit32;
+ struct {
+ uint64_t ttisgmtcnt;
+ uint64_t ttisstdcnt;
+ uint64_t leapcnt;
+ uint64_t timecnt;
+ uint64_t typecnt;
+ uint64_t charcnt;
+ } bit64;
int32_t *trans;
unsigned char *trans_idx;