Back to index

php5  5.3.10
Defines | Functions
parse_tz.c File Reference
#include "timelib.h"
#include <stdio.h>
#include <strings.h>
#include "timezonedb.h"

Go to the source code of this file.

Defines

#define timelib_conv_int(l)   ((l & 0x000000ff) << 24) + ((l & 0x0000ff00) << 8) + ((l & 0x00ff0000) >> 8) + ((l & 0xff000000) >> 24)

Functions

static void read_preamble (const unsigned char **tzf, timelib_tzinfo *tz)
static void read_header (const unsigned char **tzf, timelib_tzinfo *tz)
static void read_transistions (const unsigned char **tzf, timelib_tzinfo *tz)
static void read_types (const unsigned char **tzf, timelib_tzinfo *tz)
static void read_location (const unsigned char **tzf, timelib_tzinfo *tz)
void timelib_dump_tzinfo (timelib_tzinfo *tz)
static int seek_to_tz_position (const unsigned char **tzf, char *timezone, const timelib_tzdb *tzdb)
const timelib_tzdbtimelib_builtin_db (void)
const timelib_tzdb_index_entrytimelib_timezone_builtin_identifiers_list (int *count)
int timelib_timezone_id_is_valid (char *timezone, const timelib_tzdb *tzdb)
timelib_tzinfotimelib_parse_tzfile (char *timezone, const timelib_tzdb *tzdb)
static ttinfofetch_timezone_offset (timelib_tzinfo *tz, timelib_sll ts, timelib_sll *transition_time)
static tlinfofetch_leaptime_offset (timelib_tzinfo *tz, timelib_sll ts)
int timelib_timestamp_is_in_dst (timelib_sll ts, timelib_tzinfo *tz)
timelib_time_offsettimelib_get_time_zone_info (timelib_sll ts, timelib_tzinfo *tz)
timelib_sll timelib_get_current_offset (timelib_time *t)

Define Documentation

#define timelib_conv_int (   l)    ((l & 0x000000ff) << 24) + ((l & 0x0000ff00) << 8) + ((l & 0x00ff0000) >> 8) + ((l & 0xff000000) >> 24)

Definition at line 49 of file parse_tz.c.


Function Documentation

static tlinfo* fetch_leaptime_offset ( timelib_tzinfo tz,
timelib_sll  ts 
) [static]

Definition at line 379 of file parse_tz.c.

{
       int i;

       if (!tz->leapcnt || !tz->leap_times) {
              return NULL;
       }

       for (i = tz->leapcnt - 1; i > 0; i--) {
              if (ts > tz->leap_times[i].trans) {
                     return &(tz->leap_times[i]);
              }
       }
       return NULL;
}

Here is the caller graph for this function:

static ttinfo* fetch_timezone_offset ( timelib_tzinfo tz,
timelib_sll  ts,
timelib_sll transition_time 
) [static]

Definition at line 335 of file parse_tz.c.

{
       uint32_t i;

       /* If there is no transistion time, we pick the first one, if that doesn't
        * exist we return NULL */
       if (!tz->timecnt || !tz->trans) {
              *transition_time = 0;
              if (tz->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
        * 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]) {
              uint32_t j;

              *transition_time = 0;
              j = 0;
              while (j < tz->timecnt && tz->type[j].isdst) {
                     ++j;
              }
              if (j == tz->timecnt) {
                     j = 0;
              }
              return &(tz->type[j]);
       }

       /* In all other cases we loop through the available transtion times to find
        * the correct entry */
       for (i = 0; i < tz->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]]);
}

Here is the caller graph for this function:

static void read_header ( const unsigned char **  tzf,
timelib_tzinfo tz 
) [static]

Definition at line 70 of file parse_tz.c.

{
       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]);
       *tzf += sizeof(buffer);
}

Here is the caller graph for this function:

static void read_location ( const unsigned char **  tzf,
timelib_tzinfo tz 
) [static]

Definition at line 197 of file parse_tz.c.

{
       uint32_t buffer[3];
       uint32_t comments_len;

       memcpy(&buffer, *tzf, sizeof(buffer));
       tz->location.latitude = timelib_conv_int(buffer[0]);
       tz->location.latitude = (tz->location.latitude / 100000) - 90;
       tz->location.longitude = timelib_conv_int(buffer[1]);
       tz->location.longitude = (tz->location.longitude / 100000) - 180;
       comments_len = timelib_conv_int(buffer[2]);
       *tzf += sizeof(buffer);

       tz->location.comments = malloc(comments_len + 1);
       memcpy(tz->location.comments, *tzf, comments_len);
       tz->location.comments[comments_len] = '\0';
       *tzf += comments_len;
}

Here is the caller graph for this function:

static void read_preamble ( const unsigned char **  tzf,
timelib_tzinfo tz 
) [static]

Definition at line 52 of file parse_tz.c.

{
       /* skip ID */
       *tzf += 4;
       
       /* read BC flag */
       tz->bc = (**tzf == '\1');
       *tzf += 1;

       /* read country code */
       memcpy(tz->location.country_code, *tzf, 2);
       tz->location.country_code[2] = '\0';
       *tzf += 2;

       /* skip read of preamble */
       *tzf += 13;
}

Here is the caller graph for this function:

static void read_transistions ( const unsigned char **  tzf,
timelib_tzinfo tz 
) [static]

Definition at line 84 of file parse_tz.c.

{
       int32_t *buffer = NULL;
       uint32_t i;
       unsigned char *cbuffer = NULL;

       if (tz->timecnt) {
              buffer = (int32_t*) malloc(tz->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++) {
                     buffer[i] = timelib_conv_int(buffer[i]);
              }

              cbuffer = (unsigned char*) malloc(tz->timecnt * sizeof(unsigned char));
              if (!cbuffer) {
                     free(buffer);
                     return;
              }
              memcpy(cbuffer, *tzf, sizeof(unsigned char) * tz->timecnt);
              *tzf += sizeof(unsigned char) * tz->timecnt;
       }
       
       tz->trans = buffer;
       tz->trans_idx = cbuffer;
}

Here is the caller graph for this function:

static void read_types ( const unsigned char **  tzf,
timelib_tzinfo tz 
) [static]

Definition at line 114 of file parse_tz.c.

{
       unsigned char *buffer;
       int32_t *leap_buffer;
       unsigned int i, j;

       buffer = (unsigned char*) malloc(tz->typecnt * sizeof(unsigned char) * 6);
       if (!buffer) {
              return;
       }
       memcpy(buffer, *tzf, sizeof(unsigned char) * 6 * tz->typecnt);
       *tzf += sizeof(unsigned char) * 6 * tz->typecnt;

       tz->type = (ttinfo*) malloc(tz->typecnt * sizeof(struct ttinfo));
       if (!tz->type) {
              free(buffer);
              return;
       }

       for (i = 0; i < tz->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];
              tz->type[i].abbr_idx = buffer[j + 5];
       }
       free(buffer);

       tz->timezone_abbr = (char*) malloc(tz->charcnt);
       if (!tz->timezone_abbr) {
              return;
       }
       memcpy(tz->timezone_abbr, *tzf, sizeof(char) * tz->charcnt);
       *tzf += sizeof(char) * tz->charcnt;

       if (tz->leapcnt) {
              leap_buffer = (int32_t *) malloc(tz->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;

              tz->leap_times = (tlinfo*) malloc(tz->leapcnt * sizeof(tlinfo));
              if (!tz->leap_times) {
                     free(leap_buffer);
                     return;
              }
              for (i = 0; i < tz->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 (!buffer) {
                     return;
              }
              memcpy(buffer, *tzf, sizeof(unsigned char) * tz->ttisstdcnt);
              *tzf += sizeof(unsigned char) * tz->ttisstdcnt;

              for (i = 0; i < tz->ttisstdcnt; i++) {
                     tz->type[i].isstdcnt = buffer[i];
              }
              free(buffer);
       }

       if (tz->ttisgmtcnt) {
              buffer = (unsigned char*) malloc(tz->ttisgmtcnt * sizeof(unsigned char));
              if (!buffer) {
                     return;
              }
              memcpy(buffer, *tzf, sizeof(unsigned char) * tz->ttisgmtcnt);
              *tzf += sizeof(unsigned char) * tz->ttisgmtcnt;

              for (i = 0; i < tz->ttisgmtcnt; i++) {
                     tz->type[i].isgmtcnt = buffer[i];
              }
              free(buffer);
       }
}

Here is the caller graph for this function:

static int seek_to_tz_position ( const unsigned char **  tzf,
char *  timezone,
const timelib_tzdb tzdb 
) [static]

Definition at line 259 of file parse_tz.c.

{
       int left = 0, right = tzdb->index_size - 1;
#ifdef HAVE_SETLOCALE
       char *cur_locale = NULL, *tmp;

       tmp = setlocale(LC_CTYPE, NULL);
       if (tmp) {
              cur_locale = strdup(tmp);
       }
       setlocale(LC_CTYPE, "C");
#endif 

       do {
              int mid = ((unsigned)left + right) >> 1;
              int cmp = strcasecmp(timezone, tzdb->index[mid].id);

              if (cmp < 0) {
                     right = mid - 1;
              } else if (cmp > 0) {
                     left = mid + 1;
              } else { /* (cmp == 0) */
                     (*tzf) = &(tzdb->data[tzdb->index[mid].pos]);
#ifdef HAVE_SETLOCALE
                     setlocale(LC_CTYPE, cur_locale);
                     if (cur_locale) free(cur_locale);
#endif 
                     return 1;
              }

       } while (left <= right);

#ifdef HAVE_SETLOCALE
       setlocale(LC_CTYPE, cur_locale);
       if (cur_locale) free(cur_locale);
#endif 
       return 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

const timelib_tzdb* timelib_builtin_db ( void  )

Definition at line 298 of file parse_tz.c.

{
       return &timezonedb_builtin;
}

Here is the caller graph for this function:

Definition at line 216 of file parse_tz.c.

{
       uint32_t i;

       printf("Country Code:      %s\n", tz->location.country_code);
       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 ("%8s (%12s) = %3d [%5ld %1d %3d '%s' (%d,%d)]\n",
              "", "", 0,
              (long int) tz->type[0].offset,
              tz->type[0].isdst,
              tz->type[0].abbr_idx,
              &tz->timezone_abbr[tz->type[0].abbr_idx],
              tz->type[0].isstdcnt,
              tz->type[0].isgmtcnt
              );
       for (i = 0; i < tz->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,
                     tz->type[tz->trans_idx[i]].isdst,
                     tz->type[tz->trans_idx[i]].abbr_idx,
                     &tz->timezone_abbr[tz->type[tz->trans_idx[i]].abbr_idx],
                     tz->type[tz->trans_idx[i]].isstdcnt,
                     tz->type[tz->trans_idx[i]].isgmtcnt
                     );
       }
       for (i = 0; i < tz->leapcnt; i++) {
              printf ("%08X (%12ld) = %d\n",
                     tz->leap_times[i].trans,
                     (long) tz->leap_times[i].trans,
                     tz->leap_times[i].offset);
       }
}

Definition at line 438 of file parse_tz.c.

{
       timelib_time_offset *gmt_offset;
       timelib_sll retval;
                     
       switch (t->zone_type) {
              case TIMELIB_ZONETYPE_ABBR:
              case TIMELIB_ZONETYPE_OFFSET:
                     return (t->z + t->dst) * -60;
                     
              case TIMELIB_ZONETYPE_ID:
                     gmt_offset = timelib_get_time_zone_info(t->sse, t->tz_info);
                     retval = gmt_offset->offset;
                     timelib_time_offset_dtor(gmt_offset);
                     return retval;

              default:
                     return 0;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 406 of file parse_tz.c.

{
       ttinfo *to;
       tlinfo *tl;
       int32_t offset = 0, leap_secs = 0;
       char *abbr;
       timelib_time_offset *tmp = timelib_time_offset_ctor();
       timelib_sll                transistion_time;

       if ((to = fetch_timezone_offset(tz, ts, &transistion_time))) {
              offset = to->offset;
              abbr = &(tz->timezone_abbr[to->abbr_idx]);
              tmp->is_dst = to->isdst;
              tmp->transistion_time = transistion_time;
       } else {
              offset = 0;
              abbr = tz->timezone_abbr;
              tmp->is_dst = 0;
              tmp->transistion_time = 0;
       }

       if ((tl = fetch_leaptime_offset(tz, ts))) {
              leap_secs = -tl->offset;
       }

       tmp->offset = offset;
       tmp->leap_secs = leap_secs;
       tmp->abbr = abbr ? strdup(abbr) : strdup("GMT");

       return tmp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

timelib_tzinfo* timelib_parse_tzfile ( char *  timezone,
const timelib_tzdb tzdb 
)

Definition at line 315 of file parse_tz.c.

{
       const unsigned char *tzf;
       timelib_tzinfo *tmp;

       if (seek_to_tz_position(&tzf, timezone, tzdb)) {
              tmp = timelib_tzinfo_ctor(timezone);

              read_preamble(&tzf, tmp);
              read_header(&tzf, tmp);
              read_transistions(&tzf, tmp);
              read_types(&tzf, tmp);
              read_location(&tzf, tmp);
       } else {
              tmp = NULL;
       }

       return tmp;
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 395 of file parse_tz.c.

{
       ttinfo *to;
       timelib_sll dummy;
       
       if ((to = fetch_timezone_offset(tz, ts, &dummy))) {
              return to->isdst;
       }
       return -1;
}

Here is the call graph for this function:

Definition at line 303 of file parse_tz.c.

{
       *count = sizeof(timezonedb_idx_builtin) / sizeof(*timezonedb_idx_builtin);
       return timezonedb_idx_builtin;
}
int timelib_timezone_id_is_valid ( char *  timezone,
const timelib_tzdb tzdb 
)

Definition at line 309 of file parse_tz.c.

{
       const unsigned char *tzf;
       return (seek_to_tz_position(&tzf, timezone, tzdb));
}

Here is the call graph for this function:

Here is the caller graph for this function: