| Index: base/third_party/nspr/prtime.cc
|
| diff --git a/base/third_party/nspr/prtime.cc b/base/third_party/nspr/prtime.cc
|
| index 177cc90243feb0040e5d0a0353b67f3df139e0c2..e7c202ffe53af67376b102b92ce5f092bc542a2f 100644
|
| --- a/base/third_party/nspr/prtime.cc
|
| +++ b/base/third_party/nspr/prtime.cc
|
| @@ -53,8 +53,8 @@
|
| * PR_NormalizeTime
|
| * PR_GMTParameters
|
| * PR_ImplodeTime
|
| - * This was modified to use the Win32 SYSTEMTIME/FILETIME structures
|
| - * and the timezone offsets are applied to the FILETIME structure.
|
| + * Upstream implementation from
|
| + * http://lxr.mozilla.org/nspr/source/pr/src/misc/prtime.c#221
|
| * All types and macros are defined in the base/third_party/prtime.h file.
|
| * These have been copied from the following nspr files. We have only copied
|
| * over the types we need.
|
| @@ -71,135 +71,20 @@
|
| #include "base/third_party/nspr/prtime.h"
|
| #include "build/build_config.h"
|
|
|
| -#if defined(OS_WIN)
|
| -#include <windows.h>
|
| -#elif defined(OS_MACOSX)
|
| -#include <CoreFoundation/CoreFoundation.h>
|
| -#elif defined(OS_ANDROID)
|
| -#include <ctype.h>
|
| -#include "base/os_compat_android.h" // For timegm()
|
| -#elif defined(OS_NACL)
|
| -#include "base/os_compat_nacl.h" // For timegm()
|
| -#endif
|
| #include <errno.h> /* for EINVAL */
|
| #include <time.h>
|
|
|
| -/* Implements the Unix localtime_r() function for windows */
|
| -#if defined(OS_WIN)
|
| -static void localtime_r(const time_t* secs, struct tm* time) {
|
| - (void) localtime_s(time, secs);
|
| -}
|
| -#endif
|
| -
|
| /*
|
| - *------------------------------------------------------------------------
|
| - *
|
| - * PR_ImplodeTime --
|
| - *
|
| - * Cf. time_t mktime(struct tm *tp)
|
| - * Note that 1 year has < 2^25 seconds. So an PRInt32 is large enough.
|
| - *
|
| - *------------------------------------------------------------------------
|
| + * Long-long (64-bit signed integer type) support macros used by
|
| + * PR_ImplodeTime().
|
| + * See http://lxr.mozilla.org/nspr/source/pr/include/prlong.h
|
| */
|
| -PRTime
|
| -PR_ImplodeTime(const PRExplodedTime *exploded)
|
| -{
|
| - // This is important, we want to make sure multiplications are
|
| - // done with the correct precision.
|
| - static const PRTime kSecondsToMicroseconds = static_cast<PRTime>(1000000);
|
| -#if defined(OS_WIN)
|
| - // Create the system struct representing our exploded time.
|
| - SYSTEMTIME st = {};
|
| - FILETIME ft = {};
|
| - ULARGE_INTEGER uli = {};
|
| -
|
| - st.wYear = exploded->tm_year;
|
| - st.wMonth = static_cast<WORD>(exploded->tm_month + 1);
|
| - st.wDayOfWeek = exploded->tm_wday;
|
| - st.wDay = static_cast<WORD>(exploded->tm_mday);
|
| - st.wHour = static_cast<WORD>(exploded->tm_hour);
|
| - st.wMinute = static_cast<WORD>(exploded->tm_min);
|
| - st.wSecond = static_cast<WORD>(exploded->tm_sec);
|
| - st.wMilliseconds = static_cast<WORD>(exploded->tm_usec/1000);
|
| - // Convert to FILETIME.
|
| - if (!SystemTimeToFileTime(&st, &ft)) {
|
| - NOTREACHED() << "Unable to convert time";
|
| - return 0;
|
| - }
|
| - // Apply offsets.
|
| - uli.LowPart = ft.dwLowDateTime;
|
| - uli.HighPart = ft.dwHighDateTime;
|
| - // Convert from Windows epoch to NSPR epoch, and 100-nanoseconds units
|
| - // to microsecond units.
|
| - PRTime result =
|
| - static_cast<PRTime>((uli.QuadPart / 10) - 11644473600000000i64);
|
| - // Adjust for time zone and dst. Convert from seconds to microseconds.
|
| - result -= (exploded->tm_params.tp_gmt_offset +
|
| - exploded->tm_params.tp_dst_offset) * kSecondsToMicroseconds;
|
| - // Add microseconds that cannot be represented in |st|.
|
| - result += exploded->tm_usec % 1000;
|
| - return result;
|
| -#elif defined(OS_MACOSX)
|
| - // Create the system struct representing our exploded time.
|
| - CFGregorianDate gregorian_date;
|
| - gregorian_date.year = exploded->tm_year;
|
| - gregorian_date.month = exploded->tm_month + 1;
|
| - gregorian_date.day = exploded->tm_mday;
|
| - gregorian_date.hour = exploded->tm_hour;
|
| - gregorian_date.minute = exploded->tm_min;
|
| - gregorian_date.second = exploded->tm_sec;
|
| -
|
| - // Compute |absolute_time| in seconds, correct for gmt and dst
|
| - // (note the combined offset will be negative when we need to add it), then
|
| - // convert to microseconds which is what PRTime expects.
|
| - CFAbsoluteTime absolute_time =
|
| - CFGregorianDateGetAbsoluteTime(gregorian_date, NULL);
|
| - PRTime result = static_cast<PRTime>(absolute_time);
|
| - result -= exploded->tm_params.tp_gmt_offset +
|
| - exploded->tm_params.tp_dst_offset;
|
| - result += kCFAbsoluteTimeIntervalSince1970; // PRTime epoch is 1970
|
| - result *= kSecondsToMicroseconds;
|
| - result += exploded->tm_usec;
|
| - return result;
|
| -#elif defined(OS_POSIX)
|
| - struct tm exp_tm = {0};
|
| - exp_tm.tm_sec = exploded->tm_sec;
|
| - exp_tm.tm_min = exploded->tm_min;
|
| - exp_tm.tm_hour = exploded->tm_hour;
|
| - exp_tm.tm_mday = exploded->tm_mday;
|
| - exp_tm.tm_mon = exploded->tm_month;
|
| - exp_tm.tm_year = exploded->tm_year - 1900;
|
| -
|
| - time_t absolute_time = timegm(&exp_tm);
|
| -
|
| - // If timegm returned -1. Since we don't pass it a time zone, the only
|
| - // valid case of returning -1 is 1 second before Epoch (Dec 31, 1969).
|
| - if (absolute_time == -1 &&
|
| - !(exploded->tm_year == 1969 && exploded->tm_month == 11 &&
|
| - exploded->tm_mday == 31 && exploded->tm_hour == 23 &&
|
| - exploded->tm_min == 59 && exploded->tm_sec == 59)) {
|
| - // If we get here, time_t must be 32 bits.
|
| - // Date was possibly too far in the future and would overflow. Return
|
| - // the most future date possible (year 2038).
|
| - if (exploded->tm_year >= 1970)
|
| - return INT_MAX * kSecondsToMicroseconds;
|
| - // Date was possibly too far in the past and would underflow. Return
|
| - // the most past date possible (year 1901).
|
| - return INT_MIN * kSecondsToMicroseconds;
|
| - }
|
| -
|
| - PRTime result = static_cast<PRTime>(absolute_time);
|
| - result -= exploded->tm_params.tp_gmt_offset +
|
| - exploded->tm_params.tp_dst_offset;
|
| - result *= kSecondsToMicroseconds;
|
| - result += exploded->tm_usec;
|
| - return result;
|
| -#else
|
| -#error No PR_ImplodeTime implemented on your platform.
|
| -#endif
|
| -}
|
| +#define LL_I2L(l, i) ((l) = (PRInt64)(i))
|
| +#define LL_MUL(r, a, b) ((r) = (a) * (b))
|
| +#define LL_ADD(r, a, b) ((r) = (a) + (b))
|
| +#define LL_SUB(r, a, b) ((r) = (a) - (b))
|
|
|
| -/*
|
| +/*
|
| * The COUNT_LEAPS macro counts the number of leap years passed by
|
| * till the start of the given year Y. At the start of the year 4
|
| * A.D. the number of leap years passed by is 0, while at the start of
|
| @@ -214,9 +99,16 @@ PR_ImplodeTime(const PRExplodedTime *exploded)
|
| * midnight 00:00:00.
|
| */
|
|
|
| -#define COUNT_LEAPS(Y) ( ((Y)-1)/4 - ((Y)-1)/100 + ((Y)-1)/400 )
|
| -#define COUNT_DAYS(Y) ( ((Y)-1)*365 + COUNT_LEAPS(Y) )
|
| -#define DAYS_BETWEEN_YEARS(A, B) (COUNT_DAYS(B) - COUNT_DAYS(A))
|
| +#define COUNT_LEAPS(Y) (((Y)-1) / 4 - ((Y)-1) / 100 + ((Y)-1) / 400)
|
| +#define COUNT_DAYS(Y) (((Y)-1) * 365 + COUNT_LEAPS(Y))
|
| +#define DAYS_BETWEEN_YEARS(A, B) (COUNT_DAYS(B) - COUNT_DAYS(A))
|
| +
|
| +/* Implements the Unix localtime_r() function for windows */
|
| +#if defined(OS_WIN)
|
| +static void localtime_r(const time_t* secs, struct tm* time) {
|
| + (void) localtime_s(time, secs);
|
| +}
|
| +#endif
|
|
|
| /*
|
| * Static variables used by functions in this file
|
| @@ -242,6 +134,56 @@ static const PRInt8 nDays[2][12] = {
|
| };
|
|
|
| /*
|
| + *------------------------------------------------------------------------
|
| + *
|
| + * PR_ImplodeTime --
|
| + *
|
| + * Cf. time_t mktime(struct tm *tp)
|
| + * Note that 1 year has < 2^25 seconds. So an PRInt32 is large enough.
|
| + *
|
| + *------------------------------------------------------------------------
|
| + */
|
| +PRTime
|
| +PR_ImplodeTime(const PRExplodedTime *exploded)
|
| +{
|
| + PRExplodedTime copy;
|
| + PRTime retVal;
|
| + PRInt64 secPerDay, usecPerSec;
|
| + PRInt64 temp;
|
| + PRInt64 numSecs64;
|
| + PRInt32 numDays;
|
| + PRInt32 numSecs;
|
| +
|
| + /* Normalize first. Do this on our copy */
|
| + copy = *exploded;
|
| + PR_NormalizeTime(©, PR_GMTParameters);
|
| +
|
| + numDays = DAYS_BETWEEN_YEARS(1970, copy.tm_year);
|
| +
|
| + numSecs = copy.tm_yday * 86400 + copy.tm_hour * 3600 + copy.tm_min * 60 +
|
| + copy.tm_sec;
|
| +
|
| + LL_I2L(temp, numDays);
|
| + LL_I2L(secPerDay, 86400);
|
| + LL_MUL(temp, temp, secPerDay);
|
| + LL_I2L(numSecs64, numSecs);
|
| + LL_ADD(numSecs64, numSecs64, temp);
|
| +
|
| + /* apply the GMT and DST offsets */
|
| + LL_I2L(temp, copy.tm_params.tp_gmt_offset);
|
| + LL_SUB(numSecs64, numSecs64, temp);
|
| + LL_I2L(temp, copy.tm_params.tp_dst_offset);
|
| + LL_SUB(numSecs64, numSecs64, temp);
|
| +
|
| + LL_I2L(usecPerSec, 1000000L);
|
| + LL_MUL(temp, numSecs64, usecPerSec);
|
| + LL_I2L(retVal, copy.tm_usec);
|
| + LL_ADD(retVal, retVal, temp);
|
| +
|
| + return retVal;
|
| +}
|
| +
|
| +/*
|
| *-------------------------------------------------------------------------
|
| *
|
| * IsLeapYear --
|
|
|