diff options
Diffstat (limited to 'ext')
-rw-r--r-- | ext/date/lib/parse_tz.c | 168 | ||||
-rw-r--r-- | ext/date/lib/timelib.c | 40 | ||||
-rw-r--r-- | ext/date/lib/timelib_structs.h | 22 |
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; |