Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
dertime.c File Reference
#include "prtypes.h"
#include "prtime.h"
#include "secder.h"
#include "prlong.h"
#include "secerr.h"

Go to the source code of this file.

Defines

#define HIDIGIT(v)   (((v) / 10) + '0')
#define LODIGIT(v)   (((v) % 10) + '0')
#define C_SINGLE_QUOTE   '\047'
#define DIGITHI(dig)   (((dig) - '0') * 10)
#define DIGITLO(dig)   ((dig) - '0')
#define ISDIGIT(dig)   (((dig) >= '0') && ((dig) <= '9'))
#define CAPTURE(var, p, label)
#define SECMIN   ((time_t) 60L)
#define SECHOUR   (60L*SECMIN)
#define SECDAY   (24L*SECHOUR)
#define SECYEAR   (365L*SECDAY)

Functions

SECStatus DER_TimeToUTCTimeArena (PRArenaPool *arenaOpt, SECItem *dst, int64 gmttime)
SECStatus DER_TimeToUTCTime (SECItem *dst, int64 gmttime)
SECStatus DER_AsciiToTime (int64 *dst, const char *string)
SECStatus DER_UTCTimeToTime (int64 *dst, const SECItem *time)
SECStatus DER_TimeToGeneralizedTimeArena (PRArenaPool *arenaOpt, SECItem *dst, int64 gmttime)
SECStatus DER_TimeToGeneralizedTime (SECItem *dst, int64 gmttime)
SECStatus DER_GeneralizedTimeToTime (int64 *dst, const SECItem *time)

Variables

static long monthToDayInYear [12]
static const PRTime January1st1 = (PRTime) LL_INIT(0xff234001U, 0x00d44000U)
static const PRTime January1st1950 = (PRTime) LL_INIT(0xfffdc1f8U, 0x793da000U)
static const PRTime January1st2050 = LL_INIT(0x0008f81e, 0x1b098000)
static const PRTime January1st10000 = LL_INIT(0x0384440c, 0xcc736000)

Define Documentation

#define C_SINGLE_QUOTE   '\047'

Definition at line 46 of file dertime.c.

#define CAPTURE (   var,
  p,
  label 
)
Value:
{                                                  \
    if (!ISDIGIT((p)[0]) || !ISDIGIT((p)[1])) goto label; \
    (var) = ((p)[0] - '0') * 10 + ((p)[1] - '0');         \
}

Definition at line 51 of file dertime.c.

#define DIGITHI (   dig)    (((dig) - '0') * 10)

Definition at line 48 of file dertime.c.

#define DIGITLO (   dig)    ((dig) - '0')

Definition at line 49 of file dertime.c.

#define HIDIGIT (   v)    (((v) / 10) + '0')

Definition at line 43 of file dertime.c.

#define ISDIGIT (   dig)    (((dig) >= '0') && ((dig) <= '9'))

Definition at line 50 of file dertime.c.

#define LODIGIT (   v)    (((v) % 10) + '0')

Definition at line 44 of file dertime.c.

#define SECDAY   (24L*SECHOUR)

Definition at line 59 of file dertime.c.

#define SECHOUR   (60L*SECMIN)

Definition at line 58 of file dertime.c.

#define SECMIN   ((time_t) 60L)

Definition at line 57 of file dertime.c.

#define SECYEAR   (365L*SECDAY)

Definition at line 60 of file dertime.c.


Function Documentation

SECStatus DER_AsciiToTime ( int64 dst,
const char *  string 
)

Definition at line 145 of file dertime.c.

{
    long year, month, mday, hour, minute, second, hourOff, minOff, days;
    int64 result, tmp1, tmp2;

    if (string == NULL) {
       goto loser;
    }
    
    /* Verify time is formatted properly and capture information */
    second = 0;
    hourOff = 0;
    minOff = 0;
    CAPTURE(year,string+0,loser);
    if (year < 50) {
       /* ASSUME that year # is in the 2000's, not the 1900's */
       year += 100;
    }
    CAPTURE(month,string+2,loser);
    if ((month == 0) || (month > 12)) goto loser;
    CAPTURE(mday,string+4,loser);
    if ((mday == 0) || (mday > 31)) goto loser;
    CAPTURE(hour,string+6,loser);
    if (hour > 23) goto loser;
    CAPTURE(minute,string+8,loser);
    if (minute > 59) goto loser;
    if (ISDIGIT(string[10])) {
       CAPTURE(second,string+10,loser);
       if (second > 59) goto loser;
       string += 2;
    }
    if (string[10] == '+') {
       CAPTURE(hourOff,string+11,loser);
       if (hourOff > 23) goto loser;
       CAPTURE(minOff,string+13,loser);
       if (minOff > 59) goto loser;
    } else if (string[10] == '-') {
       CAPTURE(hourOff,string+11,loser);
       if (hourOff > 23) goto loser;
       hourOff = -hourOff;
       CAPTURE(minOff,string+13,loser);
       if (minOff > 59) goto loser;
       minOff = -minOff;
    } else if (string[10] != 'Z') {
       goto loser;
    }
    
    
    /* Convert pieces back into a single value year  */
    LL_I2L(tmp1, (year-70L));
    LL_I2L(tmp2, SECYEAR);
    LL_MUL(result, tmp1, tmp2);
    
    LL_I2L(tmp1, ( (mday-1L)*SECDAY + hour*SECHOUR + minute*SECMIN -
                hourOff*SECHOUR - minOff*SECMIN + second ) );
    LL_ADD(result, result, tmp1);

    /*
    ** Have to specially handle the day in the month and the year, to
    ** take into account leap days. The return time value is in
    ** seconds since January 1st, 12:00am 1970, so start examining
    ** the time after that. We can't represent a time before that.
    */

    /* Using two digit years, we can only represent dates from 1970
       to 2069. As a result, we cannot run into the leap year rule
       that states that 1700, 2100, etc. are not leap years (but 2000
       is). In other words, there are no years in the span of time
       that we can represent that are == 0 mod 4 but are not leap
       years. Whew.
       */

    days = monthToDayInYear[month-1];
    days += (year - 68)/4;

    if (((year % 4) == 0) && (month < 3)) {
       days--;
    }
   
    LL_I2L(tmp1, (days * SECDAY) );
    LL_ADD(result, result, tmp1 );

    /* convert to micro seconds */
    LL_I2L(tmp1, PR_USEC_PER_SEC);
    LL_MUL(result, result, tmp1);

    *dst = result;
    return SECSuccess;

  loser:
    PORT_SetError(SEC_ERROR_INVALID_TIME);
    return SECFailure;
       
}

Here is the caller graph for this function:

SECStatus DER_GeneralizedTimeToTime ( int64 dst,
const SECItem *  time 
)

Definition at line 330 of file dertime.c.

{
    PRExplodedTime genTime;
    const char *string;
    long hourOff, minOff;
    uint16 century;
    char localBuf[20];

    /* Minimum valid GeneralizedTime is ccyymmddhhmmZ       which is 13 bytes.
    ** Maximum valid GeneralizedTime is ccyymmddhhmmss+0000 which is 19 bytes.
    ** 20 should be large enough for all valid encoded times. 
    */
    if (!time || !time->data || time->len < 13)
        goto loser;
    if (time->len >= sizeof localBuf) {
        string = (const char *)time->data;
    } else {
       memset(localBuf, 0, sizeof localBuf);
        memcpy(localBuf, time->data, time->len);
       string = (const char *)localBuf;
    }

    memset(&genTime, 0, sizeof genTime);

    /* Verify time is formatted properly and capture information */
    hourOff = 0;
    minOff = 0;

    CAPTURE(century, string+0, loser);
    century *= 100;
    CAPTURE(genTime.tm_year,string+2,loser);
    genTime.tm_year += century;

    CAPTURE(genTime.tm_month,string+4,loser);
    if ((genTime.tm_month == 0) || (genTime.tm_month > 12)) goto loser;

    /* NSPR month base is 0 */
    --genTime.tm_month;
    
    CAPTURE(genTime.tm_mday,string+6,loser);
    if ((genTime.tm_mday == 0) || (genTime.tm_mday > 31)) goto loser;
    
    CAPTURE(genTime.tm_hour,string+8,loser);
    if (genTime.tm_hour > 23) goto loser;
    
    CAPTURE(genTime.tm_min,string+10,loser);
    if (genTime.tm_min > 59) goto loser;
    
    if (ISDIGIT(string[12])) {
       CAPTURE(genTime.tm_sec,string+12,loser);
       if (genTime.tm_sec > 59) goto loser;
       string += 2;
    }
    if (string[12] == '+') {
       CAPTURE(hourOff,string+13,loser);
       if (hourOff > 23) goto loser;
       CAPTURE(minOff,string+15,loser);
       if (minOff > 59) goto loser;
    } else if (string[12] == '-') {
       CAPTURE(hourOff,string+13,loser);
       if (hourOff > 23) goto loser;
       hourOff = -hourOff;
       CAPTURE(minOff,string+15,loser);
       if (minOff > 59) goto loser;
       minOff = -minOff;
    } else if (string[12] != 'Z') {
       goto loser;
    }

    /* Since the values of hourOff and minOff are small, there will
       be no loss of data by the conversion to int8 */
    /* Convert the GMT offset to seconds and save it it genTime
       for the implode time process */
    genTime.tm_params.tp_gmt_offset = (PRInt32)((hourOff * 60L + minOff) * 60L);
    *dst = PR_ImplodeTime (&genTime);
    return SECSuccess;

  loser:
    PORT_SetError(SEC_ERROR_INVALID_TIME);
    return SECFailure;
       
}

Here is the caller graph for this function:

SECStatus DER_TimeToGeneralizedTime ( SECItem *  dst,
int64  gmttime 
)

Definition at line 318 of file dertime.c.

{
    return DER_TimeToGeneralizedTimeArena(NULL, dst, gmttime);
}
SECStatus DER_TimeToGeneralizedTimeArena ( PRArenaPool arenaOpt,
SECItem *  dst,
int64  gmttime 
)

Definition at line 273 of file dertime.c.

{
    PRExplodedTime printableTime;
    unsigned char *d;

    if ( (gmttime<January1st1) || (gmttime>=January1st10000) ) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    dst->len = 15;
    if (arenaOpt) {
        dst->data = d = (unsigned char*) PORT_ArenaAlloc(arenaOpt, dst->len);
    } else {
        dst->data = d = (unsigned char*) PORT_Alloc(dst->len);
    }
    dst->type = siGeneralizedTime;
    if (!d) {
       return SECFailure;
    }

    /* Convert an int64 time to a printable format.  */
    PR_ExplodeTime(gmttime, PR_GMTParameters, &printableTime);

    /* The month in Generalized time is base one */
    printableTime.tm_month++;

    d[0] = (printableTime.tm_year /1000) + '0';
    d[1] = ((printableTime.tm_year % 1000) / 100) + '0';
    d[2] = ((printableTime.tm_year % 100) / 10) + '0';
    d[3] = (printableTime.tm_year % 10) + '0';
    d[4] = HIDIGIT(printableTime.tm_month);
    d[5] = LODIGIT(printableTime.tm_month);
    d[6] = HIDIGIT(printableTime.tm_mday);
    d[7] = LODIGIT(printableTime.tm_mday);
    d[8] = HIDIGIT(printableTime.tm_hour);
    d[9] = LODIGIT(printableTime.tm_hour);
    d[10] = HIDIGIT(printableTime.tm_min);
    d[11] = LODIGIT(printableTime.tm_min);
    d[12] = HIDIGIT(printableTime.tm_sec);
    d[13] = LODIGIT(printableTime.tm_sec);
    d[14] = 'Z';
    return SECSuccess;
}

Here is the caller graph for this function:

SECStatus DER_TimeToUTCTime ( SECItem *  dst,
int64  gmttime 
)

Definition at line 132 of file dertime.c.

{
    return DER_TimeToUTCTimeArena(NULL, dst, gmttime);
}
SECStatus DER_TimeToUTCTimeArena ( PRArenaPool arenaOpt,
SECItem *  dst,
int64  gmttime 
)

Definition at line 84 of file dertime.c.

{
    PRExplodedTime printableTime;
    unsigned char *d;

    if ( (gmttime < January1st1950) || (gmttime >= January1st2050) ) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }

    dst->len = 13;
    if (arenaOpt) {
        dst->data = d = (unsigned char*) PORT_ArenaAlloc(arenaOpt, dst->len);
    } else {
        dst->data = d = (unsigned char*) PORT_Alloc(dst->len);
    }
    dst->type = siUTCTime;
    if (!d) {
       return SECFailure;
    }

    /* Convert an int64 time to a printable format.  */
    PR_ExplodeTime(gmttime, PR_GMTParameters, &printableTime);

    /* The month in UTC time is base one */
    printableTime.tm_month++;

    /* remove the century since it's added to the tm_year by the 
       PR_ExplodeTime routine, but is not needed for UTC time */
    printableTime.tm_year %= 100; 

    d[0] = HIDIGIT(printableTime.tm_year);
    d[1] = LODIGIT(printableTime.tm_year);
    d[2] = HIDIGIT(printableTime.tm_month);
    d[3] = LODIGIT(printableTime.tm_month);
    d[4] = HIDIGIT(printableTime.tm_mday);
    d[5] = LODIGIT(printableTime.tm_mday);
    d[6] = HIDIGIT(printableTime.tm_hour);
    d[7] = LODIGIT(printableTime.tm_hour);
    d[8] = HIDIGIT(printableTime.tm_min);
    d[9] = LODIGIT(printableTime.tm_min);
    d[10] = HIDIGIT(printableTime.tm_sec);
    d[11] = LODIGIT(printableTime.tm_sec);
    d[12] = 'Z';
    return SECSuccess;
}

Here is the caller graph for this function:

SECStatus DER_UTCTimeToTime ( int64 dst,
const SECItem *  time 
)

Definition at line 241 of file dertime.c.

{
    const char * string;
    char localBuf[20]; 

    /* Minimum valid UTCTime is yymmddhhmmZ       which is 11 bytes. 
    ** Maximum valid UTCTime is yymmddhhmmss+0000 which is 17 bytes.
    ** 20 should be large enough for all valid encoded times. 
    */
    if (!time || !time->data || time->len < 11) {
       PORT_SetError(SEC_ERROR_INVALID_TIME);
       return SECFailure;
    }
    if (time->len >= sizeof localBuf) { 
       string = (const char *)time->data;
    } else {
       memset(localBuf, 0, sizeof localBuf);
       memcpy(localBuf, time->data, time->len);
        string = (const char *)localBuf;
    }
    return DER_AsciiToTime(dst, string);
}

Here is the caller graph for this function:


Variable Documentation

const PRTime January1st1 = (PRTime) LL_INIT(0xff234001U, 0x00d44000U) [static]

Definition at line 77 of file dertime.c.

const PRTime January1st10000 = LL_INIT(0x0384440c, 0xcc736000) [static]

Definition at line 80 of file dertime.c.

const PRTime January1st1950 = (PRTime) LL_INIT(0xfffdc1f8U, 0x793da000U) [static]

Definition at line 78 of file dertime.c.

const PRTime January1st2050 = LL_INIT(0x0008f81e, 0x1b098000) [static]

Definition at line 79 of file dertime.c.

long monthToDayInYear[12] [static]
Initial value:
 {
    0,
    31,
    31+28,
    31+28+31,
    31+28+31+30,
    31+28+31+30+31,
    31+28+31+30+31+30,
    31+28+31+30+31+30+31,
    31+28+31+30+31+30+31+31,
    31+28+31+30+31+30+31+31+30,
    31+28+31+30+31+30+31+31+30+31,
    31+28+31+30+31+30+31+31+30+31+30,
}

Definition at line 62 of file dertime.c.