Annotation of embedaddon/php/ext/fileinfo/libmagic/cdf_time.c, revision 1.1

1.1     ! misho       1: /*-
        !             2:  * Copyright (c) 2008 Christos Zoulas
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms, with or without
        !             6:  * modification, are permitted provided that the following conditions
        !             7:  * are met:
        !             8:  * 1. Redistributions of source code must retain the above copyright
        !             9:  *    notice, this list of conditions and the following disclaimer.
        !            10:  * 2. Redistributions in binary form must reproduce the above copyright
        !            11:  *    notice, this list of conditions and the following disclaimer in the
        !            12:  *    documentation and/or other materials provided with the distribution.
        !            13:  *
        !            14:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
        !            15:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            16:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            17:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
        !            18:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            19:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            20:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            21:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            22:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            23:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            24:  * POSSIBILITY OF SUCH DAMAGE.
        !            25:  */
        !            26: 
        !            27: #include "file.h"
        !            28: 
        !            29: #ifndef lint
        !            30: FILE_RCSID("@(#)$File: cdf_time.c,v 1.6 2009/03/10 11:44:29 christos Exp $")
        !            31: #endif
        !            32: 
        !            33: #include <time.h>
        !            34: #ifdef TEST
        !            35: #include <err.h>
        !            36: #endif
        !            37: #include <string.h>
        !            38: 
        !            39: #include "cdf.h"
        !            40: 
        !            41: #define isleap(y) ((((y) % 4) == 0) && \
        !            42:     ((((y) % 100) != 0) || (((y) % 400) == 0)))
        !            43: 
        !            44: static const int mdays[] = {
        !            45:     31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
        !            46: };
        !            47: 
        !            48: /*
        !            49:  * Return the number of days between jan 01 1601 and jan 01 of year.
        !            50:  */
        !            51: static int
        !            52: cdf_getdays(int year)
        !            53: {
        !            54:        int days = 0;
        !            55:        int y;
        !            56: 
        !            57:        for (y = CDF_BASE_YEAR; y < year; y++)
        !            58:                days += isleap(y) + 365;
        !            59:                
        !            60:        return days;
        !            61: }
        !            62: 
        !            63: /*
        !            64:  * Return the day within the month
        !            65:  */
        !            66: static int
        !            67: cdf_getday(int year, int days)
        !            68: {
        !            69:        size_t m;
        !            70: 
        !            71:        for (m = 0; m < sizeof(mdays) / sizeof(mdays[0]); m++) {
        !            72:                int sub = mdays[m] + (m == 1 && isleap(year));
        !            73:                if (days < sub)
        !            74:                        return days;
        !            75:                days -= sub;
        !            76:        }
        !            77:        return days;
        !            78: }
        !            79: 
        !            80: /* 
        !            81:  * Return the 0...11 month number.
        !            82:  */
        !            83: static int
        !            84: cdf_getmonth(int year, int days)
        !            85: {
        !            86:        size_t m;
        !            87: 
        !            88:        for (m = 0; m < sizeof(mdays) / sizeof(mdays[0]); m++) {
        !            89:                days -= mdays[m];
        !            90:                if (m == 1 && isleap(year))
        !            91:                        days--;
        !            92:                if (days <= 0)
        !            93:                        return (int)m;
        !            94:        }
        !            95:        return (int)m;
        !            96: }
        !            97: 
        !            98: int
        !            99: cdf_timestamp_to_timespec(struct timeval *ts, cdf_timestamp_t t)
        !           100: {
        !           101:        struct tm tm;
        !           102: #ifdef HAVE_STRUCT_TM_TM_ZONE
        !           103:        static char UTC[] = "UTC";
        !           104: #endif
        !           105:        int rdays;
        !           106: 
        !           107:        /* Time interval, in microseconds */
        !           108:        ts->tv_usec = (t % CDF_TIME_PREC) * CDF_TIME_PREC;
        !           109: 
        !           110:        t /= CDF_TIME_PREC;
        !           111:        tm.tm_sec = t % 60;
        !           112:        t /= 60;
        !           113: 
        !           114:        tm.tm_min = t % 60;
        !           115:        t /= 60;
        !           116: 
        !           117:        tm.tm_hour = t % 24;
        !           118:        t /= 24;
        !           119: 
        !           120:        /* XXX: Approx */
        !           121:        tm.tm_year = CDF_BASE_YEAR + (t / 365);
        !           122: 
        !           123:        rdays = cdf_getdays(tm.tm_year);
        !           124:        t -= rdays;
        !           125:        tm.tm_mday = cdf_getday(tm.tm_year, t);
        !           126:        tm.tm_mon = cdf_getmonth(tm.tm_year, t);
        !           127:        tm.tm_wday = 0;
        !           128:        tm.tm_yday = 0;
        !           129:        tm.tm_isdst = 0;
        !           130: #ifdef HAVE_STRUCT_TM_TM_GMTOFF
        !           131:        tm.tm_gmtoff = 0;
        !           132: #endif
        !           133: #ifdef HAVE_STRUCT_TM_TM_ZONE
        !           134:        tm.tm_zone = UTC;
        !           135: #endif
        !           136:        tm.tm_year -= 1900;
        !           137:        ts->tv_sec = mktime(&tm);
        !           138:        if (ts->tv_sec == -1) {
        !           139:                errno = EINVAL;
        !           140:                return -1;
        !           141:        }
        !           142:        return 0;
        !           143: }
        !           144: 
        !           145: int
        !           146: cdf_timespec_to_timestamp(cdf_timestamp_t *t, const struct timeval *ts)
        !           147: {
        !           148:        (void)&t;
        !           149:        (void)&ts;
        !           150: #ifdef notyet
        !           151:        struct tm tm;
        !           152:        if (gmtime_r(&ts->ts_sec, &tm) == NULL) {
        !           153:                errno = EINVAL;
        !           154:                return -1;
        !           155:        }
        !           156:        *t = (ts->ts_usec / CDF_TIME_PREC) * CDF_TIME_PREC;
        !           157:        *t = tm.tm_sec;
        !           158:        *t += tm.tm_min * 60;
        !           159:        *t += tm.tm_hour * 60 * 60;
        !           160:        *t += tm.tm_mday * 60 * 60 * 24;
        !           161: #endif
        !           162:        return 0;
        !           163: }
        !           164: 
        !           165: 
        !           166: #ifdef TEST
        !           167: int
        !           168: main(int argc, char *argv[])
        !           169: {
        !           170:        struct timeval ts;
        !           171:        static const cdf_timestamp_t tst = 0x01A5E403C2D59C00ULL;
        !           172:        static const char *ref = "Sat Apr 23 01:30:00 1977";
        !           173:        char *p, *q;
        !           174: 
        !           175:        cdf_timestamp_to_timespec(&ts, tst);
        !           176:        p = ctime(&ts.tv_sec);
        !           177:        if ((q = strchr(p, '\n')) != NULL)
        !           178:                *q = '\0';
        !           179:        if (strcmp(ref, p) != 0)
        !           180:                errx(1, "Error date %s != %s\n", ref, p);
        !           181:        return 0;
        !           182: }
        !           183: #endif

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>