annotate timeconv.c @ 12:3f627519a92d stable-0-5-2

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