xref: /aosp_15_r20/external/lzma/CPP/Windows/PropVariantConv.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1 // PropVariantConv.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../Common/IntToString.h"
6 
7 #include "Defs.h"
8 #include "PropVariantConv.h"
9 
10 #define UINT_TO_STR_2(c, val) { s[0] = (c); s[1] = (char)('0' + (val) / 10); s[2] = (char)('0' + (val) % 10); s += 3; }
11 
12 static const unsigned k_TimeStringBufferSize = 64;
13 
14 bool g_Timestamp_Show_UTC;
15 #if 0
16 bool g_Timestamp_Show_DisableZ;
17 bool g_Timestamp_Show_TDelimeter;
18 bool g_Timestamp_Show_ZoneOffset;
19 #endif
20 
21 Z7_NO_INLINE
ConvertUtcFileTimeToString2(const FILETIME & utc,unsigned ns100,char * s,int level,unsigned flags)22 bool ConvertUtcFileTimeToString2(const FILETIME &utc, unsigned ns100, char *s, int level, unsigned flags) throw()
23 {
24   *s = 0;
25   FILETIME ft;
26 
27 #if 0
28   Int64 bias64 = 0;
29 #endif
30 
31   const bool show_utc =
32       (flags & kTimestampPrintFlags_Force_UTC) ? true :
33       (flags & kTimestampPrintFlags_Force_LOCAL) ? false :
34       g_Timestamp_Show_UTC;
35 
36   if (show_utc)
37     ft = utc;
38   else
39   {
40     if (!FileTimeToLocalFileTime(&utc, &ft))
41       return false;
42 #if 0
43     if (g_Timestamp_Show_ZoneOffset)
44     {
45       const UInt64 utc64 = (((UInt64)utc.dwHighDateTime) << 32) + utc.dwLowDateTime;
46       const UInt64 loc64 = (((UInt64) ft.dwHighDateTime) << 32) +  ft.dwLowDateTime;
47       bias64 = (Int64)utc64 - (Int64)loc64;
48     }
49 #endif
50   }
51 
52   SYSTEMTIME st;
53   if (!BOOLToBool(FileTimeToSystemTime(&ft, &st)))
54   {
55     // win10 : that function doesn't work, if bit 63 of 64-bit FILETIME is set.
56     return false;
57   }
58 
59   {
60     unsigned val = st.wYear;
61     if (val >= 10000)
62     {
63       *s++ = (char)('0' + val / 10000);
64       val %= 10000;
65     }
66     s[3] = (char)('0' + val % 10); val /= 10;
67     s[2] = (char)('0' + val % 10); val /= 10;
68     s[1] = (char)('0' + val % 10);
69     s[0] = (char)('0' + val / 10);
70     s += 4;
71   }
72   UINT_TO_STR_2('-', st.wMonth)
73   UINT_TO_STR_2('-', st.wDay)
74 
75   if (level > kTimestampPrintLevel_DAY)
76   {
77     const char setChar =
78 #if 0
79       g_Timestamp_Show_TDelimeter ? 'T' : // ISO 8601
80 #endif
81       ' ';
82     UINT_TO_STR_2(setChar, st.wHour)
83     UINT_TO_STR_2(':', st.wMinute)
84 
85     if (level >= kTimestampPrintLevel_SEC)
86     {
87       UINT_TO_STR_2(':', st.wSecond)
88 
89       if (level > kTimestampPrintLevel_SEC)
90       {
91         *s++ = '.';
92         /*
93         {
94           unsigned val = st.wMilliseconds;
95           s[2] = (char)('0' + val % 10); val /= 10;
96           s[1] = (char)('0' + val % 10);
97           s[0] = (char)('0' + val / 10);
98           s += 3;
99         }
100         *s++ = ' ';
101         */
102 
103         {
104           unsigned numDigits = 7;
105           UInt32 val = (UInt32)((((UInt64)ft.dwHighDateTime << 32) + ft.dwLowDateTime) % 10000000);
106           for (unsigned i = numDigits; i != 0;)
107           {
108             i--;
109             s[i] = (char)('0' + val % 10); val /= 10;
110           }
111           if (numDigits > (unsigned)level)
112             numDigits = (unsigned)level;
113           s += numDigits;
114         }
115         if (level >= kTimestampPrintLevel_NTFS + 1)
116         {
117           *s++ = (char)('0' + (ns100 / 10));
118           if (level >= kTimestampPrintLevel_NTFS + 2)
119             *s++ = (char)('0' + (ns100 % 10));
120         }
121       }
122     }
123   }
124 
125   if (show_utc)
126   {
127     if ((flags & kTimestampPrintFlags_DisableZ) == 0
128 #if 0
129       && !g_Timestamp_Show_DisableZ
130 #endif
131       )
132       *s++ = 'Z';
133   }
134 #if 0
135   else if (g_Timestamp_Show_ZoneOffset)
136   {
137 #if 1
138     {
139       char c;
140       if (bias64 < 0)
141       {
142         bias64 = -bias64;
143         c = '+';
144       }
145       else
146         c = '-';
147       UInt32 bias = (UInt32)((UInt64)bias64 / (10000000 * 60));
148 #else
149     TIME_ZONE_INFORMATION zi;
150     const DWORD dw = GetTimeZoneInformation(&zi);
151     if (dw <= TIME_ZONE_ID_DAYLIGHT) // == 2
152     {
153       // UTC = LOCAL + Bias
154       Int32 bias = zi.Bias;
155       char c;
156       if (bias < 0)
157       {
158         bias = -bias;
159         c = '+';
160       }
161       else
162         c = '-';
163 #endif
164       const UInt32 hours = (UInt32)bias / 60;
165       const UInt32 mins = (UInt32)bias % 60;
166       UINT_TO_STR_2(c, hours)
167       UINT_TO_STR_2(':', mins)
168     }
169   }
170 #endif
171   *s = 0;
172   return true;
173 }
174 
175 
176 bool ConvertUtcFileTimeToString(const FILETIME &utc, char *s, int level) throw()
177 {
178   return ConvertUtcFileTimeToString2(utc, 0, s, level);
179 }
180 
181 bool ConvertUtcFileTimeToString2(const FILETIME &ft, unsigned ns100, wchar_t *dest, int level) throw()
182 {
183   char s[k_TimeStringBufferSize];
184   const bool res = ConvertUtcFileTimeToString2(ft, ns100, s, level);
185   for (unsigned i = 0;; i++)
186   {
187     const Byte c = (Byte)s[i];
188     dest[i] = c;
189     if (c == 0)
190       break;
191   }
192   return res;
193 }
194 
195 bool ConvertUtcFileTimeToString(const FILETIME &ft, wchar_t *dest, int level) throw()
196 {
197   char s[k_TimeStringBufferSize];
198   const bool res = ConvertUtcFileTimeToString(ft, s, level);
199   for (unsigned i = 0;; i++)
200   {
201     const Byte c = (Byte)s[i];
202     dest[i] = c;
203     if (c == 0)
204       break;
205   }
206   return res;
207 }
208 
209 
210 void ConvertPropVariantToShortString(const PROPVARIANT &prop, char *dest) throw()
211 {
212   *dest = 0;
213   switch (prop.vt)
214   {
215     case VT_EMPTY: return;
216     case VT_BSTR: dest[0] = '?'; dest[1] = 0; return;
217     case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return;
218     case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
219     case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
220     case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
221     case VT_FILETIME:
222     {
223       // const unsigned prec = prop.wReserved1;
224       int level = 0;
225       /*
226       if (prec == 0)
227         level = 7;
228       else if (prec > 16 && prec <= 16 + 9)
229         level = prec - 16;
230       */
231       ConvertUtcFileTimeToString(prop.filetime, dest, level);
232       return;
233     }
234     // case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
235     case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
236     case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
237     case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return;
238     case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? '+' : '-'; dest[1] = 0; return;
239     default: dest[0] = '?'; dest[1] = ':'; ConvertUInt64ToString(prop.vt, dest + 2);
240   }
241 }
242 
243 void ConvertPropVariantToShortString(const PROPVARIANT &prop, wchar_t *dest) throw()
244 {
245   *dest = 0;
246   switch (prop.vt)
247   {
248     case VT_EMPTY: return;
249     case VT_BSTR: dest[0] = '?'; dest[1] = 0; return;
250     case VT_UI1: ConvertUInt32ToString(prop.bVal, dest); return;
251     case VT_UI2: ConvertUInt32ToString(prop.uiVal, dest); return;
252     case VT_UI4: ConvertUInt32ToString(prop.ulVal, dest); return;
253     case VT_UI8: ConvertUInt64ToString(prop.uhVal.QuadPart, dest); return;
254     case VT_FILETIME:
255     {
256       // const unsigned prec = prop.wReserved1;
257       int level = 0;
258       /*
259       if (prec == 0)
260         level = 7;
261       else if (prec > 16 && prec <= 16 + 9)
262         level = prec - 16;
263       */
264       ConvertUtcFileTimeToString(prop.filetime, dest, level);
265       return;
266     }
267     // case VT_I1: return ConvertInt64ToString(prop.cVal, dest); return;
268     case VT_I2: ConvertInt64ToString(prop.iVal, dest); return;
269     case VT_I4: ConvertInt64ToString(prop.lVal, dest); return;
270     case VT_I8: ConvertInt64ToString(prop.hVal.QuadPart, dest); return;
271     case VT_BOOL: dest[0] = VARIANT_BOOLToBool(prop.boolVal) ? (wchar_t)'+' : (wchar_t)'-'; dest[1] = 0; return;
272     default: dest[0] = '?'; dest[1] = ':'; ConvertUInt32ToString(prop.vt, dest + 2);
273   }
274 }
275