Mercurial > libpst
view src/timeconv.c @ 59:7d5c637aaafb
General cleanup and code fixes.
Use autoscan to cleanup our autoconf system.
Use autoconf to detect when we need to use our XGetopt files and other header files.
Decode BCC field.
Fix missing LE32_CPU byte swapping for FILETIME types.
author | Carl Byington <carl@five-ten-sg.com> |
---|---|
date | Thu, 14 Feb 2008 14:55:32 -0800 |
parents | b2a7f2e0926a |
children | cfd6175f9334 |
line wrap: on
line source
/*********************************************************************** * * Borrowed from WINE sources!! (http://www.winehq.com) * Converts a Win32 FILETIME structure to a UNIX time_t value */ /*** WARNING **** * This file is not to be included in a Visual C++ Project * It will make the whole project fail to compile * There are functions in libpst.c to handle the dates * Do not use this one */ #include <time.h> #include "common.h" #include "timeconv.h" char * fileTimeToAscii (const FILETIME *filetime) { time_t t1; t1 = fileTimeToUnixTime(filetime,0); return ctime(&t1); } struct tm * fileTimeToStructTM (const FILETIME *filetime) { time_t t1; t1 = fileTimeToUnixTime(filetime, 0); return gmtime(&t1); } /*********************************************************************** * DOSFS_FileTimeToUnixTime * * Convert a FILETIME format to Unix time. * If not NULL, 'remainder' contains the fractional part of the filetime, * in the range of [0..9999999] (even if time_t is negative). */ time_t fileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder ) { /* Read the comment in the function DOSFS_UnixTimeToFileTime. */ #if USE_LONG_LONG long long int t = filetime->dwHighDateTime; t <<= 32; t += (UINT32)filetime->dwLowDateTime; t -= 116444736000000000LL; if (t < 0) { if (remainder) *remainder = 9999999 - (-t - 1) % 10000000; return -1 - ((-t - 1) / 10000000); } else { if (remainder) *remainder = t % 10000000; return t / 10000000; } #else /* ISO version */ UINT32 a0; /* 16 bit, low bits */ UINT32 a1; /* 16 bit, medium bits */ UINT32 a2; /* 32 bit, high bits */ UINT32 r; /* remainder of division */ unsigned int carry; /* carry bit for subtraction */ int negative; /* whether a represents a negative value */ /* Copy the time values to a2/a1/a0 */ a2 = (UINT32)filetime->dwHighDateTime; a1 = ((UINT32)filetime->dwLowDateTime ) >> 16; a0 = ((UINT32)filetime->dwLowDateTime ) & 0xffff; /* Subtract the time difference */ if (a0 >= 32768 ) a0 -= 32768 , carry = 0; else a0 += (1 << 16) - 32768 , carry = 1; if (a1 >= 54590 + carry) a1 -= 54590 + carry, carry = 0; else a1 += (1 << 16) - 54590 - carry, carry = 1; a2 -= 27111902 + carry; /* If a is negative, replace a by (-1-a) */ negative = (a2 >= ((UINT32)1) << 31); if (negative) { /* Set a to -a - 1 (a is a2/a1/a0) */ a0 = 0xffff - a0; a1 = 0xffff - a1; a2 = ~a2; } /* Divide a by 10000000 (a = a2/a1/a0), put the rest into r. Split the divisor into 10000 * 1000 which are both less than 0xffff. */ a1 += (a2 % 10000) << 16; a2 /= 10000; a0 += (a1 % 10000) << 16; a1 /= 10000; r = a0 % 10000; a0 /= 10000; a1 += (a2 % 1000) << 16; a2 /= 1000; a0 += (a1 % 1000) << 16; a1 /= 1000; r += (a0 % 1000) * 10000; a0 /= 1000; /* If a was negative, replace a by (-1-a) and r by (9999999 - r) */ if (negative) { /* Set a to -a - 1 (a is a2/a1/a0) */ a0 = 0xffff - a0; a1 = 0xffff - a1; a2 = ~a2; r = 9999999 - r; } if (remainder) *remainder = r; /* Do not replace this by << 32, it gives a compiler warning and it does not work. */ return ((((time_t)a2) << 16) << 16) + (a1 << 16) + a0; #endif }