1 // PercentPrinter.cpp
2 
3 #include "StdAfx.h"
4 
5 #include "../../../Common/Defs.h"
6 #include "../../../Common/IntToString.h"
7 
8 #include "PercentPrinter.h"
9 
10 static const unsigned kPaddingSize = 2;
11 static const unsigned kPercentsSize = 4;
12 static const unsigned kMaxExtraSize = kPaddingSize + 32 + kPercentsSize;
13 
ClearPrev(char * p,unsigned num)14 static void ClearPrev(char *p, unsigned num)
15 {
16   unsigned i;
17   for (i = 0; i < num; i++) *p++ = '\b';
18   for (i = 0; i < num; i++) *p++ = ' ';
19   for (i = 0; i < num; i++) *p++ = '\b';
20   *p = '\0';
21 }
22 
ClosePrint()23 void CPercentPrinter::ClosePrint()
24 {
25   if (m_NumExtraChars == 0)
26     return;
27   char s[kMaxExtraSize * 3 + 1];
28   ClearPrev(s, m_NumExtraChars);
29   (*OutStream) << s;
30   m_NumExtraChars = 0;
31 }
32 
PrintString(const char * s)33 void CPercentPrinter::PrintString(const char *s)
34 {
35   ClosePrint();
36   (*OutStream) << s;
37 }
38 
PrintString(const wchar_t * s)39 void CPercentPrinter::PrintString(const wchar_t *s)
40 {
41   ClosePrint();
42   (*OutStream) << s;
43 }
44 
PrintNewLine()45 void CPercentPrinter::PrintNewLine()
46 {
47   ClosePrint();
48   (*OutStream) << "\n";
49 }
50 
RePrintRatio()51 void CPercentPrinter::RePrintRatio()
52 {
53   char s[32];
54   unsigned size;
55   {
56     char c = '%';
57     UInt64 value = 0;
58     if (m_Total == (UInt64)(Int64)-1)
59     {
60       value = m_CurValue >> 20;
61       c = 'M';
62     }
63     else if (m_Total != 0)
64       value = m_CurValue * 100 / m_Total;
65     ConvertUInt64ToString(value, s);
66     size = (unsigned)strlen(s);
67     s[size++] = c;
68     s[size] = '\0';
69   }
70 
71   unsigned extraSize = kPaddingSize + MyMax(size, kPercentsSize);
72   if (extraSize < m_NumExtraChars)
73     extraSize = m_NumExtraChars;
74 
75   char fullString[kMaxExtraSize * 3];
76   char *p = fullString;
77   unsigned i;
78   if (m_NumExtraChars == 0)
79   {
80     for (i = 0; i < extraSize; i++)
81       *p++ = ' ';
82     m_NumExtraChars = extraSize;
83   }
84 
85   for (i = 0; i < m_NumExtraChars; i++)
86     *p++ = '\b';
87   m_NumExtraChars = extraSize;
88   for (; size < extraSize; size++)
89     *p++ = ' ';
90   MyStringCopy(p, s);
91   (*OutStream) << fullString;
92   OutStream->Flush();
93   m_PrevValue = m_CurValue;
94 }
95 
PrintRatio()96 void CPercentPrinter::PrintRatio()
97 {
98   if (m_CurValue < m_PrevValue + m_MinStepSize &&
99       m_CurValue + m_MinStepSize > m_PrevValue && m_NumExtraChars != 0)
100     return;
101   RePrintRatio();
102 }
103