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