"Fossies" - the Fresh Open Source Software Archive

Member "unrar/timefn.cpp" (4 May 2022, 7755 Bytes) of package /linux/misc/unrarsrc-6.1.7.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "timefn.cpp" see the Fossies "Dox" file reference documentation.

    1 #include "rar.hpp"
    2 
    3 void RarTime::GetLocal(RarLocalTime *lt)
    4 {
    5 #ifdef _WIN_ALL
    6   FILETIME ft;
    7   GetWinFT(&ft);
    8   FILETIME lft;
    9 
   10   if (WinNT() < WNT_VISTA)
   11   {
   12     // SystemTimeToTzSpecificLocalTime based code produces 1 hour error on XP.
   13     FileTimeToLocalFileTime(&ft,&lft);
   14   }
   15   else
   16   {
   17     // We use these functions instead of FileTimeToLocalFileTime according to
   18     // MSDN recommendation: "To account for daylight saving time
   19     // when converting a file time to a local time ..."
   20     SYSTEMTIME st1,st2;
   21     FileTimeToSystemTime(&ft,&st1);
   22     SystemTimeToTzSpecificLocalTime(NULL,&st1,&st2);
   23     SystemTimeToFileTime(&st2,&lft);
   24 
   25     // Correct precision loss (low 4 decimal digits) in FileTimeToSystemTime.
   26     FILETIME rft;
   27     SystemTimeToFileTime(&st1,&rft);
   28     uint64 Corrected=INT32TO64(ft.dwHighDateTime,ft.dwLowDateTime)-
   29                      INT32TO64(rft.dwHighDateTime,rft.dwLowDateTime)+
   30                      INT32TO64(lft.dwHighDateTime,lft.dwLowDateTime);
   31     lft.dwLowDateTime=(DWORD)Corrected;
   32     lft.dwHighDateTime=(DWORD)(Corrected>>32);
   33   }
   34 
   35   SYSTEMTIME st;
   36   FileTimeToSystemTime(&lft,&st);
   37   lt->Year=st.wYear;
   38   lt->Month=st.wMonth;
   39   lt->Day=st.wDay;
   40   lt->Hour=st.wHour;
   41   lt->Minute=st.wMinute;
   42   lt->Second=st.wSecond;
   43   lt->wDay=st.wDayOfWeek;
   44   lt->yDay=lt->Day-1;
   45 
   46   static int mdays[12]={31,28,31,30,31,30,31,31,30,31,30,31};
   47   for (uint I=1;I<lt->Month && I<=ASIZE(mdays);I++)
   48     lt->yDay+=mdays[I-1];
   49 
   50   if (lt->Month>2 && IsLeapYear(lt->Year))
   51     lt->yDay++;
   52 #else
   53   time_t ut=GetUnix();
   54   struct tm *t;
   55   t=localtime(&ut);
   56 
   57   lt->Year=t->tm_year+1900;
   58   lt->Month=t->tm_mon+1;
   59   lt->Day=t->tm_mday;
   60   lt->Hour=t->tm_hour;
   61   lt->Minute=t->tm_min;
   62   lt->Second=t->tm_sec;
   63   lt->wDay=t->tm_wday;
   64   lt->yDay=t->tm_yday;
   65 #endif
   66   lt->Reminder=(itime % TICKS_PER_SECOND);
   67 }
   68 
   69 
   70 void RarTime::SetLocal(RarLocalTime *lt)
   71 {
   72 #ifdef _WIN_ALL
   73   SYSTEMTIME st;
   74   st.wYear=lt->Year;
   75   st.wMonth=lt->Month;
   76   st.wDay=lt->Day;
   77   st.wHour=lt->Hour;
   78   st.wMinute=lt->Minute;
   79   st.wSecond=lt->Second;
   80   st.wMilliseconds=0;
   81   st.wDayOfWeek=0;
   82   FILETIME lft;
   83   if (SystemTimeToFileTime(&st,&lft))
   84   {
   85     FILETIME ft;
   86 
   87     if (WinNT() < WNT_VISTA)
   88     {
   89       // TzSpecificLocalTimeToSystemTime based code produces 1 hour error on XP.
   90       LocalFileTimeToFileTime(&lft,&ft);
   91     }
   92     else
   93     {
   94       // Reverse procedure which we do in GetLocal.
   95       SYSTEMTIME st1,st2;
   96       FileTimeToSystemTime(&lft,&st2); // st2 might be unequal to st, because we added lt->Reminder to lft.
   97       TzSpecificLocalTimeToSystemTime(NULL,&st2,&st1);
   98       SystemTimeToFileTime(&st1,&ft);
   99 
  100       // Correct precision loss (low 4 decimal digits) in FileTimeToSystemTime.
  101       FILETIME rft;
  102       SystemTimeToFileTime(&st2,&rft);
  103       uint64 Corrected=INT32TO64(lft.dwHighDateTime,lft.dwLowDateTime)-
  104                        INT32TO64(rft.dwHighDateTime,rft.dwLowDateTime)+
  105                        INT32TO64(ft.dwHighDateTime,ft.dwLowDateTime);
  106       ft.dwLowDateTime=(DWORD)Corrected;
  107       ft.dwHighDateTime=(DWORD)(Corrected>>32);
  108     }
  109 
  110     SetWinFT(&ft);
  111   }
  112   else
  113     Reset();
  114 #else
  115   struct tm t;
  116 
  117   t.tm_sec=lt->Second;
  118   t.tm_min=lt->Minute;
  119   t.tm_hour=lt->Hour;
  120   t.tm_mday=lt->Day;
  121   t.tm_mon=lt->Month-1;
  122   t.tm_year=lt->Year-1900;
  123   t.tm_isdst=-1;
  124   SetUnix(mktime(&t));
  125 #endif
  126   itime+=lt->Reminder;
  127 }
  128 
  129 
  130 
  131 
  132 #ifdef _WIN_ALL
  133 void RarTime::GetWinFT(FILETIME *ft)
  134 {
  135   _ULARGE_INTEGER ul;
  136   ul.QuadPart=GetWin();
  137   ft->dwLowDateTime=ul.LowPart;
  138   ft->dwHighDateTime=ul.HighPart;
  139 }
  140 
  141 
  142 void RarTime::SetWinFT(FILETIME *ft)
  143 {
  144   _ULARGE_INTEGER ul = {ft->dwLowDateTime, ft->dwHighDateTime};
  145   SetWin(ul.QuadPart);
  146 }
  147 #endif
  148 
  149 
  150 // Get 64-bit representation of Windows FILETIME (100ns since 01.01.1601).
  151 uint64 RarTime::GetWin()
  152 {
  153   return itime/(TICKS_PER_SECOND/10000000);
  154 }
  155 
  156 
  157 // Set 64-bit representation of Windows FILETIME (100ns since 01.01.1601).
  158 void RarTime::SetWin(uint64 WinTime)
  159 {
  160   itime=WinTime*(TICKS_PER_SECOND/10000000);
  161 }
  162 
  163 
  164 time_t RarTime::GetUnix()
  165 {
  166   return time_t(GetUnixNS()/1000000000);
  167 }
  168 
  169 
  170 void RarTime::SetUnix(time_t ut)
  171 {
  172   if (sizeof(ut)>4)
  173     SetUnixNS(uint64(ut)*1000000000);
  174   else
  175   {
  176     // Convert 32-bit and possibly signed time_t to uint32 first,
  177     // uint64 cast is not enough. Otherwise sign can expand to 64 bits.
  178     SetUnixNS(uint64(uint32(ut))*1000000000);
  179   }
  180 }
  181 
  182 
  183 // Get the high precision Unix time in nanoseconds since 01-01-1970.
  184 uint64 RarTime::GetUnixNS()
  185 {
  186   // 11644473600000000000 - number of ns between 01-01-1601 and 01-01-1970.
  187   uint64 ushift=INT32TO64(0xA1997B0B,0x4C6A0000);
  188   return itime*(1000000000/TICKS_PER_SECOND)-ushift;
  189 }
  190 
  191 
  192 // Set the high precision Unix time in nanoseconds since 01-01-1970.
  193 void RarTime::SetUnixNS(uint64 ns)
  194 {
  195   // 11644473600000000000 - number of ns between 01-01-1601 and 01-01-1970.
  196   uint64 ushift=INT32TO64(0xA1997B0B,0x4C6A0000);
  197   itime=(ns+ushift)/(1000000000/TICKS_PER_SECOND);
  198 }
  199 
  200 
  201 uint RarTime::GetDos()
  202 {
  203   RarLocalTime lt;
  204   GetLocal(&lt);
  205   uint DosTime=(lt.Second/2)|(lt.Minute<<5)|(lt.Hour<<11)|
  206                (lt.Day<<16)|(lt.Month<<21)|((lt.Year-1980)<<25);
  207   return DosTime;
  208 }
  209 
  210 
  211 void RarTime::SetDos(uint DosTime)
  212 {
  213   RarLocalTime lt;
  214   lt.Second=(DosTime & 0x1f)*2;
  215   lt.Minute=(DosTime>>5) & 0x3f;
  216   lt.Hour=(DosTime>>11) & 0x1f;
  217   lt.Day=(DosTime>>16) & 0x1f;
  218   lt.Month=(DosTime>>21) & 0x0f;
  219   lt.Year=(DosTime>>25)+1980;
  220   lt.Reminder=0;
  221   SetLocal(&lt);
  222 }
  223 
  224 
  225 void RarTime::GetText(wchar *DateStr,size_t MaxSize,bool FullMS)
  226 {
  227   if (IsSet())
  228   {
  229     RarLocalTime lt;
  230     GetLocal(&lt);
  231     if (FullMS)
  232       swprintf(DateStr,MaxSize,L"%u-%02u-%02u %02u:%02u:%02u,%09u",lt.Year,lt.Month,lt.Day,lt.Hour,lt.Minute,lt.Second,lt.Reminder*(1000000000/TICKS_PER_SECOND));
  233     else
  234       swprintf(DateStr,MaxSize,L"%u-%02u-%02u %02u:%02u",lt.Year,lt.Month,lt.Day,lt.Hour,lt.Minute);
  235   }
  236   else
  237   {
  238     // We use escape before '?' to avoid weird C trigraph characters.
  239     wcsncpyz(DateStr,L"\?\?\?\?-\?\?-\?\? \?\?:\?\?",MaxSize);
  240   }
  241 }
  242 
  243 
  244 #ifndef SFX_MODULE
  245 void RarTime::SetIsoText(const wchar *TimeText)
  246 {
  247   int Field[6];
  248   memset(Field,0,sizeof(Field));
  249   for (uint DigitCount=0;*TimeText!=0;TimeText++)
  250     if (IsDigit(*TimeText))
  251     {
  252       int FieldPos=DigitCount<4 ? 0:(DigitCount-4)/2+1;
  253       if (FieldPos<ASIZE(Field))
  254         Field[FieldPos]=Field[FieldPos]*10+*TimeText-'0';
  255       DigitCount++;
  256     }
  257   RarLocalTime lt;
  258   lt.Second=Field[5];
  259   lt.Minute=Field[4];
  260   lt.Hour=Field[3];
  261   lt.Day=Field[2]==0 ? 1:Field[2];
  262   lt.Month=Field[1]==0 ? 1:Field[1];
  263   lt.Year=Field[0];
  264   lt.Reminder=0;
  265   SetLocal(&lt);
  266 }
  267 #endif
  268 
  269 
  270 #ifndef SFX_MODULE
  271 void RarTime::SetAgeText(const wchar *TimeText)
  272 {
  273   uint Seconds=0,Value=0;
  274   for (uint I=0;TimeText[I]!=0;I++)
  275   {
  276     wchar Ch=TimeText[I];
  277     if (IsDigit(Ch))
  278       Value=Value*10+Ch-'0';
  279     else
  280     {
  281       switch(etoupperw(Ch))
  282       {
  283         case 'D':
  284           Seconds+=Value*24*3600;
  285           break;
  286         case 'H':
  287           Seconds+=Value*3600;
  288           break;
  289         case 'M':
  290           Seconds+=Value*60;
  291           break;
  292         case 'S':
  293           Seconds+=Value;
  294           break;
  295       }
  296       Value=0;
  297     }
  298   }
  299   SetCurrentTime();
  300   itime-=uint64(Seconds)*TICKS_PER_SECOND;
  301 }
  302 #endif
  303 
  304 
  305 void RarTime::SetCurrentTime()
  306 {
  307 #ifdef _WIN_ALL
  308   FILETIME ft;
  309   SYSTEMTIME st;
  310   GetSystemTime(&st);
  311   SystemTimeToFileTime(&st,&ft);
  312   SetWinFT(&ft);
  313 #else
  314   time_t st;
  315   time(&st);
  316   SetUnix(st);
  317 #endif
  318 }
  319 
  320 
  321 // Add the specified signed number of nanoseconds.
  322 void RarTime::Adjust(int64 ns)
  323 {
  324   ns/=1000000000/TICKS_PER_SECOND; // Convert ns to internal ticks.
  325   itime+=(uint64)ns;
  326 }
  327 
  328 
  329 #ifndef SFX_MODULE
  330 const wchar *GetMonthName(int Month)
  331 {
  332   return uiGetMonthName(Month);
  333 }
  334 #endif
  335 
  336 
  337 bool IsLeapYear(int Year)
  338 {
  339   return (Year&3)==0 && (Year%100!=0 || Year%400==0);
  340 }