diff src/timeconv.c @ 16:c508ee15dfca

switch to automake/autoconf
author carl
date Sun, 19 Feb 2006 18:47:46 -0800
parents
children b2a7f2e0926a
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/timeconv.c	Sun Feb 19 18:47:46 2006 -0800
@@ -0,0 +1,127 @@
+/***********************************************************************
+ *
+ * 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 incluided 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"
+
+time_t fileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder );
+char * fileTimeToAscii (const FILETIME *filetime);
+
+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
+}