Home | History | Annotate | Download | only in Console
      1 // PercentPrinter.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "../../../Common/IntToString.h"
      6 
      7 #include "PercentPrinter.h"
      8 
      9 static const unsigned kPercentsSize = 4;
     10 
     11 CPercentPrinter::~CPercentPrinter()
     12 {
     13   ClosePrint(false);
     14 }
     15 
     16 void CPercentPrinterState::ClearCurState()
     17 {
     18   Completed = 0;
     19   Total = ((UInt64)(Int64)-1);
     20   Files = 0;
     21   Command.Empty();
     22   FileName.Empty();
     23 }
     24 
     25 void CPercentPrinter::ClosePrint(bool needFlush)
     26 {
     27   unsigned num = _printedString.Len();
     28   if (num != 0)
     29   {
     30 
     31   unsigned i;
     32 
     33   /* '\r' in old MAC OS means "new line".
     34      So we can't use '\r' in some systems */
     35 
     36   #ifdef _WIN32
     37     char *start = _temp.GetBuf(num  + 2);
     38     char *p = start;
     39     *p++ = '\r';
     40     for (i = 0; i < num; i++) *p++ = ' ';
     41     *p++ = '\r';
     42   #else
     43     char *start = _temp.GetBuf(num * 3);
     44     char *p = start;
     45     for (i = 0; i < num; i++) *p++ = '\b';
     46     for (i = 0; i < num; i++) *p++ = ' ';
     47     for (i = 0; i < num; i++) *p++ = '\b';
     48   #endif
     49 
     50   *p = 0;
     51   _temp.ReleaseBuf_SetLen((unsigned)(p - start));
     52   *_so << _temp;
     53   }
     54   if (needFlush)
     55     _so->Flush();
     56   _printedString.Empty();
     57 }
     58 
     59 void CPercentPrinter::GetPercents()
     60 {
     61   char s[32];
     62   unsigned size;
     63   {
     64     char c = '%';
     65     UInt64 val = 0;
     66     if (Total == (UInt64)(Int64)-1)
     67     {
     68       val = Completed >> 20;
     69       c = 'M';
     70     }
     71     else if (Total != 0)
     72       val = Completed * 100 / Total;
     73     ConvertUInt64ToString(val, s);
     74     size = (unsigned)strlen(s);
     75     s[size++] = c;
     76     s[size] = 0;
     77   }
     78 
     79   while (size < kPercentsSize)
     80   {
     81     _s += ' ';
     82     size++;
     83   }
     84 
     85   _s += s;
     86 }
     87 
     88 void CPercentPrinter::Print()
     89 {
     90   DWORD tick = 0;
     91   if (_tickStep != 0)
     92     tick = GetTickCount();
     93 
     94   bool onlyPercentsChanged = false;
     95 
     96   if (!_printedString.IsEmpty())
     97   {
     98     if (_tickStep != 0 && (UInt32)(tick - _prevTick) < _tickStep)
     99       return;
    100 
    101     CPercentPrinterState &st = *this;
    102     if (_printedState.Command == st.Command
    103         && _printedState.FileName == st.FileName
    104         && _printedState.Files == st.Files)
    105     {
    106       if (_printedState.Total == st.Total
    107           && _printedState.Completed == st.Completed)
    108         return;
    109       onlyPercentsChanged = true;
    110     }
    111   }
    112 
    113   _s.Empty();
    114 
    115   GetPercents();
    116 
    117   if (onlyPercentsChanged && _s == _printedPercents)
    118     return;
    119 
    120   _printedPercents = _s;
    121 
    122   if (Files != 0)
    123   {
    124     char s[32];
    125     ConvertUInt64ToString(Files, s);
    126     // unsigned size = (unsigned)strlen(s);
    127     // for (; size < 3; size++) _s += ' ';
    128     _s += ' ';
    129     _s += s;
    130     // _s += "f";
    131   }
    132 
    133 
    134   if (!Command.IsEmpty())
    135   {
    136     _s += ' ';
    137     _s += Command;
    138   }
    139 
    140   if (!FileName.IsEmpty() && _s.Len() < MaxLen)
    141   {
    142     _s += ' ';
    143 
    144     StdOut_Convert_UString_to_AString(FileName, _temp);
    145     _temp.Replace('\n', ' ');
    146     if (_s.Len() + _temp.Len() > MaxLen)
    147     {
    148       unsigned len = FileName.Len();
    149       for (; len != 0;)
    150       {
    151         unsigned delta = len / 8;
    152         if (delta == 0)
    153           delta = 1;
    154         len -= delta;
    155         _tempU = FileName;
    156         _tempU.Delete(len / 2, FileName.Len() - len);
    157         _tempU.Insert(len / 2, L" . ");
    158         StdOut_Convert_UString_to_AString(_tempU, _temp);
    159         if (_s.Len() + _temp.Len() <= MaxLen)
    160           break;
    161       }
    162       if (len == 0)
    163         _temp.Empty();
    164     }
    165     _s += _temp;
    166   }
    167 
    168   if (_printedString != _s)
    169   {
    170     ClosePrint(false);
    171     *_so << _s;
    172     if (NeedFlush)
    173       _so->Flush();
    174     _printedString = _s;
    175   }
    176 
    177   _printedState = *this;
    178 
    179   if (_tickStep != 0)
    180     _prevTick = tick;
    181 }
    182