annotate 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
16
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
1 /***********************************************************************
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
2 *
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
3 * Borrowed from WINE sources!! (http://www.winehq.com)
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
4 * Converts a Win32 FILETIME structure to a UNIX time_t value
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
5 */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
6
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
7 /*** WARNING ****
59
7d5c637aaafb General cleanup and code fixes.
Carl Byington <carl@five-ten-sg.com>
parents: 46
diff changeset
8 * This file is not to be included in a Visual C++ Project
16
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
9 * It will make the whole project fail to compile
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
10 * There are functions in libpst.c to handle the dates
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
11 * Do not use this one
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
12 */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
13
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
14 #include <time.h>
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
15 #include "common.h"
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
16 #include "timeconv.h"
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
17
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
18 char * fileTimeToAscii (const FILETIME *filetime) {
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
19 time_t t1;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
20
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
21 t1 = fileTimeToUnixTime(filetime,0);
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
22 return ctime(&t1);
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
23 }
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
24
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
25 struct tm * fileTimeToStructTM (const FILETIME *filetime) {
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
26 time_t t1;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
27 t1 = fileTimeToUnixTime(filetime, 0);
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
28 return gmtime(&t1);
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
29 }
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
30
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
31 /***********************************************************************
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
32 * DOSFS_FileTimeToUnixTime
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
33 *
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
34 * Convert a FILETIME format to Unix time.
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
35 * If not NULL, 'remainder' contains the fractional part of the filetime,
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
36 * in the range of [0..9999999] (even if time_t is negative).
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
37 */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
38 time_t fileTimeToUnixTime( const FILETIME *filetime, DWORD *remainder )
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
39 {
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
40 /* Read the comment in the function DOSFS_UnixTimeToFileTime. */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
41 #if USE_LONG_LONG
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
42
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
43 long long int t = filetime->dwHighDateTime;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
44 t <<= 32;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
45 t += (UINT32)filetime->dwLowDateTime;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
46 t -= 116444736000000000LL;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
47 if (t < 0)
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
48 {
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
49 if (remainder) *remainder = 9999999 - (-t - 1) % 10000000;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
50 return -1 - ((-t - 1) / 10000000);
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
51 }
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
52 else
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
53 {
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
54 if (remainder) *remainder = t % 10000000;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
55 return t / 10000000;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
56 }
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
57
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
58 #else /* ISO version */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
59
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
60 UINT32 a0; /* 16 bit, low bits */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
61 UINT32 a1; /* 16 bit, medium bits */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
62 UINT32 a2; /* 32 bit, high bits */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
63 UINT32 r; /* remainder of division */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
64 unsigned int carry; /* carry bit for subtraction */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
65 int negative; /* whether a represents a negative value */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
66
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
67 /* Copy the time values to a2/a1/a0 */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
68 a2 = (UINT32)filetime->dwHighDateTime;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
69 a1 = ((UINT32)filetime->dwLowDateTime ) >> 16;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
70 a0 = ((UINT32)filetime->dwLowDateTime ) & 0xffff;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
71
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
72 /* Subtract the time difference */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
73 if (a0 >= 32768 ) a0 -= 32768 , carry = 0;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
74 else a0 += (1 << 16) - 32768 , carry = 1;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
75
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
76 if (a1 >= 54590 + carry) a1 -= 54590 + carry, carry = 0;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
77 else a1 += (1 << 16) - 54590 - carry, carry = 1;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
78
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
79 a2 -= 27111902 + carry;
46
b2a7f2e0926a more fixes for 64 bit format
carl
parents: 16
diff changeset
80
16
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
81 /* If a is negative, replace a by (-1-a) */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
82 negative = (a2 >= ((UINT32)1) << 31);
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
83 if (negative)
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
84 {
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
85 /* Set a to -a - 1 (a is a2/a1/a0) */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
86 a0 = 0xffff - a0;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
87 a1 = 0xffff - a1;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
88 a2 = ~a2;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
89 }
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
90
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
91 /* Divide a by 10000000 (a = a2/a1/a0), put the rest into r.
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
92 Split the divisor into 10000 * 1000 which are both less than 0xffff. */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
93 a1 += (a2 % 10000) << 16;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
94 a2 /= 10000;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
95 a0 += (a1 % 10000) << 16;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
96 a1 /= 10000;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
97 r = a0 % 10000;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
98 a0 /= 10000;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
99
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
100 a1 += (a2 % 1000) << 16;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
101 a2 /= 1000;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
102 a0 += (a1 % 1000) << 16;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
103 a1 /= 1000;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
104 r += (a0 % 1000) * 10000;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
105 a0 /= 1000;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
106
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
107 /* If a was negative, replace a by (-1-a) and r by (9999999 - r) */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
108 if (negative)
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
109 {
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
110 /* Set a to -a - 1 (a is a2/a1/a0) */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
111 a0 = 0xffff - a0;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
112 a1 = 0xffff - a1;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
113 a2 = ~a2;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
114
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
115 r = 9999999 - r;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
116 }
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
117
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
118 if (remainder) *remainder = r;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
119
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
120 /* Do not replace this by << 32, it gives a compiler warning and it does
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
121 not work. */
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
122 return ((((time_t)a2) << 16) << 16) + (a1 << 16) + a0;
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
123 #endif
c508ee15dfca switch to automake/autoconf
carl
parents:
diff changeset
124 }