PHP  
 PHP: Test and Code Coverage Analysis
downloads | QA | documentation | faq | getting help | mailing lists | reporting bugs | php.net sites | links | my php.net 
 

LTP GCOV extension - code coverage report
Current view: directory - date/lib - parse_tz.c
Test: PHP Code Coverage
Date: 2009-11-19 Instrumented lines: 185
Code covered: 71.9 % Executed lines: 133
Legend: not executed executed

       1                 : /*
       2                 :    +----------------------------------------------------------------------+
       3                 :    | PHP Version 5                                                        |
       4                 :    +----------------------------------------------------------------------+
       5                 :    | Copyright (c) 1997-2009 The PHP Group                                |
       6                 :    +----------------------------------------------------------------------+
       7                 :    | This source file is subject to version 3.01 of the PHP license,      |
       8                 :    | that is bundled with this package in the file LICENSE, and is        |
       9                 :    | available through the world-wide-web at the following url:           |
      10                 :    | http://www.php.net/license/3_01.txt                                  |
      11                 :    | If you did not receive a copy of the PHP license and are unable to   |
      12                 :    | obtain it through the world-wide-web, please send a note to          |
      13                 :    | license@php.net so we can mail you a copy immediately.               |
      14                 :    +----------------------------------------------------------------------+
      15                 :    | Authors: Derick Rethans <derick@derickrethans.nl>                    |
      16                 :    +----------------------------------------------------------------------+
      17                 :  */
      18                 : 
      19                 : /* $Id: parse_tz.c 272374 2008-12-31 11:17:49Z sebastian $ */
      20                 : 
      21                 : #include "timelib.h"
      22                 : 
      23                 : #include <stdio.h>
      24                 : 
      25                 : #ifdef HAVE_LOCALE_H
      26                 : #include <locale.h>
      27                 : #endif
      28                 : 
      29                 : #ifdef HAVE_STRING_H
      30                 : #include <string.h>
      31                 : #else
      32                 : #include <strings.h>
      33                 : #endif
      34                 : #include "timezonedb.h"
      35                 : 
      36                 : #if (defined(__APPLE__) || defined(__APPLE_CC__)) && (defined(__BIG_ENDIAN__) || defined(__LITTLE_ENDIAN__))
      37                 : # if defined(__LITTLE_ENDIAN__)
      38                 : #  undef WORDS_BIGENDIAN
      39                 : # else 
      40                 : #  if defined(__BIG_ENDIAN__)
      41                 : #   define WORDS_BIGENDIAN
      42                 : #  endif
      43                 : # endif
      44                 : #endif
      45                 : 
      46                 : #ifdef WORDS_BIGENDIAN
      47                 : #define timelib_conv_int(l) (l)
      48                 : #else
      49                 : #define timelib_conv_int(l) ((l & 0x000000ff) << 24) + ((l & 0x0000ff00) << 8) + ((l & 0x00ff0000) >> 8) + ((l & 0xff000000) >> 24)
      50                 : #endif
      51                 : 
      52                 : static void read_header(char **tzf, timelib_tzinfo *tz)
      53             673 : {
      54                 :         uint32_t buffer[6];
      55                 : 
      56             673 :         memcpy(&buffer, *tzf, sizeof(buffer));
      57             673 :         tz->ttisgmtcnt = timelib_conv_int(buffer[0]);
      58             673 :         tz->ttisstdcnt = timelib_conv_int(buffer[1]);
      59             673 :         tz->leapcnt    = timelib_conv_int(buffer[2]);
      60             673 :         tz->timecnt    = timelib_conv_int(buffer[3]);
      61             673 :         tz->typecnt    = timelib_conv_int(buffer[4]);
      62             673 :         tz->charcnt    = timelib_conv_int(buffer[5]);
      63             673 :         *tzf += sizeof(buffer);
      64             673 : }
      65                 : 
      66                 : static void read_transistions(char **tzf, timelib_tzinfo *tz)
      67             673 : {
      68             673 :         int32_t *buffer = NULL;
      69                 :         uint32_t i;
      70             673 :         unsigned char *cbuffer = NULL;
      71                 : 
      72             673 :         if (tz->timecnt) {
      73             334 :                 buffer = (int32_t*) malloc(tz->timecnt * sizeof(int32_t));
      74             334 :                 if (!buffer) {
      75               0 :                         return;
      76                 :                 }
      77             334 :                 memcpy(buffer, *tzf, sizeof(int32_t) * tz->timecnt);
      78             334 :                 *tzf += (sizeof(int32_t) * tz->timecnt);
      79           47517 :                 for (i = 0; i < tz->timecnt; i++) {
      80           47183 :                         buffer[i] = timelib_conv_int(buffer[i]);
      81                 :                 }
      82                 : 
      83             334 :                 cbuffer = (unsigned char*) malloc(tz->timecnt * sizeof(unsigned char));
      84             334 :                 if (!cbuffer) {
      85               0 :                         return;
      86                 :                 }
      87             334 :                 memcpy(cbuffer, *tzf, sizeof(unsigned char) * tz->timecnt);
      88             334 :                 *tzf += sizeof(unsigned char) * tz->timecnt;
      89                 :         }
      90                 :         
      91             673 :         tz->trans = buffer;
      92             673 :         tz->trans_idx = cbuffer;
      93                 : }
      94                 : 
      95                 : static void read_types(char **tzf, timelib_tzinfo *tz)
      96             673 : {
      97                 :         unsigned char *buffer;
      98                 :         int32_t *leap_buffer;
      99                 :         unsigned int i, j;
     100                 : 
     101             673 :         buffer = (unsigned char*) malloc(tz->typecnt * sizeof(unsigned char) * 6);
     102             673 :         if (!buffer) {
     103               0 :                 return;
     104                 :         }
     105             673 :         memcpy(buffer, *tzf, sizeof(unsigned char) * 6 * tz->typecnt);
     106             673 :         *tzf += sizeof(unsigned char) * 6 * tz->typecnt;
     107                 : 
     108             673 :         tz->type = (ttinfo*) malloc(tz->typecnt * sizeof(struct ttinfo));
     109             673 :         if (!tz->type) {
     110               0 :                 return;
     111                 :         }
     112                 : 
     113            2915 :         for (i = 0; i < tz->typecnt; i++) {
     114            2242 :                 j = i * 6;
     115            2242 :                 tz->type[i].offset = (buffer[j] * 16777216) + (buffer[j + 1] * 65536) + (buffer[j + 2] * 256) + buffer[j + 3];
     116            2242 :                 tz->type[i].isdst = buffer[j + 4];
     117            2242 :                 tz->type[i].abbr_idx = buffer[j + 5];
     118                 :         }
     119             673 :         free(buffer);
     120                 : 
     121             673 :         tz->timezone_abbr = (char*) malloc(tz->charcnt);
     122             673 :         if (!tz->timezone_abbr) {
     123               0 :                 return;
     124                 :         }
     125             673 :         memcpy(tz->timezone_abbr, *tzf, sizeof(char) * tz->charcnt);
     126             673 :         *tzf += sizeof(char) * tz->charcnt;
     127                 : 
     128             673 :         if (tz->leapcnt) {
     129               0 :                 leap_buffer = (int32_t *) malloc(tz->leapcnt * 2 * sizeof(int32_t));
     130               0 :                 if (!leap_buffer) {
     131               0 :                         return;
     132                 :                 }
     133               0 :                 memcpy(leap_buffer, *tzf, sizeof(int32_t) * tz->leapcnt * 2);
     134               0 :                 *tzf += sizeof(int32_t) * tz->leapcnt * 2;
     135                 : 
     136               0 :                 tz->leap_times = (tlinfo*) malloc(tz->leapcnt * sizeof(tlinfo));
     137               0 :                 if (!tz->leap_times) {
     138               0 :                         return;
     139                 :                 }
     140               0 :                 for (i = 0; i < tz->leapcnt; i++) {
     141               0 :                         tz->leap_times[i].trans = timelib_conv_int(leap_buffer[i * 2]);
     142               0 :                         tz->leap_times[i].offset = timelib_conv_int(leap_buffer[i * 2 + 1]);
     143                 :                 }
     144               0 :                 free(leap_buffer);
     145                 :         }
     146                 : 
     147             673 :         if (tz->ttisstdcnt) {
     148             673 :                 buffer = (unsigned char*) malloc(tz->ttisstdcnt * sizeof(unsigned char));
     149             673 :                 if (!buffer) {
     150               0 :                         return;
     151                 :                 }
     152             673 :                 memcpy(buffer, *tzf, sizeof(unsigned char) * tz->ttisstdcnt);
     153             673 :                 *tzf += sizeof(unsigned char) * tz->ttisstdcnt;
     154                 : 
     155            2915 :                 for (i = 0; i < tz->ttisstdcnt; i++) {
     156            2242 :                         tz->type[i].isstdcnt = buffer[i];
     157                 :                 }
     158             673 :                 free(buffer);
     159                 :         }
     160                 : 
     161             673 :         if (tz->ttisgmtcnt) {
     162             673 :                 buffer = (unsigned char*) malloc(tz->ttisgmtcnt * sizeof(unsigned char));
     163             673 :                 if (!buffer) {
     164               0 :                         return;
     165                 :                 }
     166             673 :                 memcpy(buffer, *tzf, sizeof(unsigned char) * tz->ttisgmtcnt);
     167             673 :                 *tzf += sizeof(unsigned char) * tz->ttisgmtcnt;
     168                 : 
     169            2915 :                 for (i = 0; i < tz->ttisgmtcnt; i++) {
     170            2242 :                         tz->type[i].isgmtcnt = buffer[i];
     171                 :                 }
     172             673 :                 free(buffer);
     173                 :         }
     174                 : }
     175                 : 
     176                 : void timelib_dump_tzinfo(timelib_tzinfo *tz)
     177               0 : {
     178                 :         uint32_t i;
     179                 : 
     180               0 :         printf("UTC/Local count:   %lu\n", (unsigned long) tz->ttisgmtcnt);
     181               0 :         printf("Std/Wall count:    %lu\n", (unsigned long) tz->ttisstdcnt);
     182               0 :         printf("Leap.sec. count:   %lu\n", (unsigned long) tz->leapcnt);
     183               0 :         printf("Trans. count:      %lu\n", (unsigned long) tz->timecnt);
     184               0 :         printf("Local types count: %lu\n", (unsigned long) tz->typecnt);
     185               0 :         printf("Zone Abbr. count:  %lu\n", (unsigned long) tz->charcnt);
     186                 : 
     187               0 :         printf ("%8s (%12s) = %3d [%5ld %1d %3d '%s' (%d,%d)]\n",
     188                 :                 "", "", 0,
     189                 :                 (long int) tz->type[0].offset,
     190                 :                 tz->type[0].isdst,
     191                 :                 tz->type[0].abbr_idx,
     192                 :                 &tz->timezone_abbr[tz->type[0].abbr_idx],
     193                 :                 tz->type[0].isstdcnt,
     194                 :                 tz->type[0].isgmtcnt
     195                 :                 );
     196               0 :         for (i = 0; i < tz->timecnt; i++) {
     197               0 :                 printf ("%08X (%12d) = %3d [%5ld %1d %3d '%s' (%d,%d)]\n",
     198                 :                         tz->trans[i], tz->trans[i], tz->trans_idx[i],
     199                 :                         (long int) tz->type[tz->trans_idx[i]].offset,
     200                 :                         tz->type[tz->trans_idx[i]].isdst,
     201                 :                         tz->type[tz->trans_idx[i]].abbr_idx,
     202                 :                         &tz->timezone_abbr[tz->type[tz->trans_idx[i]].abbr_idx],
     203                 :                         tz->type[tz->trans_idx[i]].isstdcnt,
     204                 :                         tz->type[tz->trans_idx[i]].isgmtcnt
     205                 :                         );
     206                 :         }
     207               0 :         for (i = 0; i < tz->leapcnt; i++) {
     208               0 :                 printf ("%08X (%12ld) = %d\n",
     209                 :                         tz->leap_times[i].trans,
     210                 :                         (long) tz->leap_times[i].trans,
     211                 :                         tz->leap_times[i].offset);
     212                 :         }
     213               0 : }
     214                 : 
     215                 : static int seek_to_tz_position(const unsigned char **tzf, char *timezone, const timelib_tzdb *tzdb)
     216            2223 : {
     217            2223 :         int left = 0, right = tzdb->index_size - 1;
     218                 : #ifdef HAVE_SETLOCALE
     219            2223 :         char *cur_locale = NULL, *tmp;
     220                 : 
     221            2223 :         tmp = setlocale(LC_CTYPE, NULL);
     222            2223 :         if (tmp) {
     223            2223 :                 cur_locale = strdup(tmp);
     224                 :         }
     225            2223 :         setlocale(LC_CTYPE, "C");
     226                 : #endif  
     227                 : 
     228                 :         do {
     229           18266 :                 int mid = ((unsigned)left + right) >> 1;
     230           18266 :                 int cmp = strcasecmp(timezone, tzdb->index[mid].id);
     231                 : 
     232           18266 :                 if (cmp < 0) {
     233            6726 :                         right = mid - 1;
     234           11540 :                 } else if (cmp > 0) {
     235            9389 :                         left = mid + 1;
     236                 :                 } else { /* (cmp == 0) */
     237            2151 :                         (*tzf) = &(tzdb->data[tzdb->index[mid].pos + 20]);
     238                 : #ifdef HAVE_SETLOCALE
     239            2151 :                         setlocale(LC_CTYPE, cur_locale);
     240            2151 :                         if (cur_locale) free(cur_locale);
     241                 : #endif  
     242            2151 :                         return 1;
     243                 :                 }
     244                 : 
     245           16115 :         } while (left <= right);
     246                 : 
     247                 : #ifdef HAVE_SETLOCALE
     248              72 :         setlocale(LC_CTYPE, cur_locale);
     249              72 :         if (cur_locale) free(cur_locale);
     250                 : #endif  
     251              72 :         return 0;
     252                 : }
     253                 : 
     254                 : const timelib_tzdb *timelib_builtin_db(void)
     255           17834 : {
     256           17834 :         return &timezonedb_builtin;
     257                 : }
     258                 : 
     259                 : const timelib_tzdb_index_entry *timelib_timezone_builtin_identifiers_list(int *count)
     260               0 : {
     261               0 :         *count = sizeof(timezonedb_idx_builtin) / sizeof(*timezonedb_idx_builtin);
     262               0 :         return timezonedb_idx_builtin;
     263                 : }
     264                 : 
     265                 : int timelib_timezone_id_is_valid(char *timezone, const timelib_tzdb *tzdb)
     266            1505 : {
     267                 :         const unsigned char *tzf;
     268            1505 :         return (seek_to_tz_position(&tzf, timezone, tzdb));
     269                 : }
     270                 : 
     271                 : timelib_tzinfo *timelib_parse_tzfile(char *timezone, const timelib_tzdb *tzdb)
     272             718 : {
     273                 :         const unsigned char *tzf;
     274                 :         timelib_tzinfo *tmp;
     275                 : 
     276             718 :         if (seek_to_tz_position(&tzf, timezone, tzdb)) {
     277             673 :                 tmp = timelib_tzinfo_ctor(timezone);
     278                 : 
     279             673 :                 read_header((char**) &tzf, tmp);
     280             673 :                 read_transistions((char**) &tzf, tmp);
     281             673 :                 read_types((char**) &tzf, tmp);
     282                 :         } else {
     283              45 :                 tmp = NULL;
     284                 :         }
     285                 : 
     286             718 :         return tmp;
     287                 : }
     288                 : 
     289                 : static ttinfo* fetch_timezone_offset(timelib_tzinfo *tz, timelib_sll ts, timelib_sll *transition_time)
     290           23996 : {
     291                 :         uint32_t i;
     292                 : 
     293                 :         /* If there is no transistion time, we pick the first one, if that doesn't
     294                 :          * exist we return NULL */
     295           23996 :         if (!tz->timecnt || !tz->trans) {
     296           16093 :                 *transition_time = 0;
     297           16093 :                 if (tz->typecnt == 1) {
     298           16093 :                         return &(tz->type[0]);
     299                 :                 }
     300               0 :                 return NULL;
     301                 :         }
     302                 : 
     303                 :         /* If the TS is lower than the first transistion time, then we scan over
     304                 :          * all the transistion times to find the first non-DST one, or the first
     305                 :          * one in case there are only DST entries. Not sure which smartass came up
     306                 :          * with this idea in the first though :) */
     307            7903 :         if (ts < tz->trans[0]) {
     308                 :                 uint32_t j;
     309                 : 
     310             323 :                 *transition_time = 0;
     311             323 :                 j = 0;
     312             868 :                 while (j < tz->timecnt && tz->type[j].isdst) {
     313             222 :                         ++j;
     314                 :                 }
     315             323 :                 if (j == tz->timecnt) {
     316               0 :                         j = 0;
     317                 :                 }
     318             323 :                 return &(tz->type[j]);
     319                 :         }
     320                 : 
     321                 :         /* In all other cases we loop through the available transtion times to find
     322                 :          * the correct entry */
     323          618992 :         for (i = 0; i < tz->timecnt; i++) {
     324          616513 :                 if (ts < tz->trans[i]) {
     325            5101 :                         *transition_time = tz->trans[i - 1];
     326            5101 :                         return &(tz->type[tz->trans_idx[i - 1]]);
     327                 :                 }
     328                 :         }
     329            2479 :         *transition_time = tz->trans[tz->timecnt - 1];
     330            2479 :         return &(tz->type[tz->trans_idx[tz->timecnt - 1]]);
     331                 : }
     332                 : 
     333                 : static tlinfo* fetch_leaptime_offset(timelib_tzinfo *tz, timelib_sll ts)
     334           23996 : {
     335                 :         int i;
     336                 : 
     337           23996 :         if (!tz->leapcnt || !tz->leap_times) {
     338           23996 :                 return NULL;
     339                 :         }
     340                 : 
     341               0 :         for (i = tz->leapcnt - 1; i > 0; i--) {
     342               0 :                 if (ts > tz->leap_times[i].trans) {
     343               0 :                         return &(tz->leap_times[i]);
     344                 :                 }
     345                 :         }
     346               0 :         return NULL;
     347                 : }
     348                 : 
     349                 : int timelib_timestamp_is_in_dst(timelib_sll ts, timelib_tzinfo *tz)
     350               0 : {
     351                 :         ttinfo *to;
     352                 :         timelib_sll dummy;
     353                 :         
     354               0 :         if ((to = fetch_timezone_offset(tz, ts, &dummy))) {
     355               0 :                 return to->isdst;
     356                 :         }
     357               0 :         return -1;
     358                 : }
     359                 : 
     360                 : timelib_time_offset *timelib_get_time_zone_info(timelib_sll ts, timelib_tzinfo *tz)
     361           23996 : {
     362                 :         ttinfo *to;
     363                 :         tlinfo *tl;
     364           23996 :         int32_t offset = 0, leap_secs = 0;
     365                 :         char *abbr;
     366           23996 :         timelib_time_offset *tmp = timelib_time_offset_ctor();
     367                 :         timelib_sll                transistion_time;
     368                 : 
     369           23996 :         if ((to = fetch_timezone_offset(tz, ts, &transistion_time))) {
     370           23996 :                 offset = to->offset;
     371           23996 :                 abbr = &(tz->timezone_abbr[to->abbr_idx]);
     372           23996 :                 tmp->is_dst = to->isdst;
     373           23996 :                 tmp->transistion_time = transistion_time;
     374                 :         } else {
     375               0 :                 offset = 0;
     376               0 :                 abbr = tz->timezone_abbr;
     377               0 :                 tmp->is_dst = 0;
     378               0 :                 tmp->transistion_time = 0;
     379                 :         }
     380                 : 
     381           23996 :         if ((tl = fetch_leaptime_offset(tz, ts))) {
     382               0 :                 leap_secs = -tl->offset;
     383                 :         }
     384                 : 
     385           23996 :         tmp->offset = offset;
     386           23996 :         tmp->leap_secs = leap_secs;
     387           23996 :         tmp->abbr = abbr ? strdup(abbr) : strdup("GMT");
     388                 : 
     389           23996 :         return tmp;
     390                 : }
     391                 : 
     392                 : timelib_sll timelib_get_current_offset(timelib_time *t)
     393              36 : {
     394                 :         timelib_time_offset *gmt_offset;
     395                 :         timelib_sll retval;
     396                 :                         
     397              36 :         switch (t->zone_type) {
     398                 :                 case TIMELIB_ZONETYPE_ABBR:
     399                 :                 case TIMELIB_ZONETYPE_OFFSET:
     400               0 :                         return (t->z + t->dst) * -60;
     401                 :                         
     402                 :                 case TIMELIB_ZONETYPE_ID:
     403              36 :                         gmt_offset = timelib_get_time_zone_info(t->sse, t->tz_info);
     404              36 :                         retval = gmt_offset->offset;
     405              36 :                         timelib_time_offset_dtor(gmt_offset);
     406              36 :                         return retval;
     407                 : 
     408                 :                 default:
     409               0 :                         return 0;
     410                 :         }
     411                 : }

Generated by: LTP GCOV extension version 1.5

Generated at Thu, 19 Nov 2009 08:20:05 +0000 (5 days ago)

Copyright © 2005-2009 The PHP Group
All rights reserved.