xref: /aosp_15_r20/external/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
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 
~CPercentPrinter()11 CPercentPrinter::~CPercentPrinter()
12 {
13   ClosePrint(false);
14 }
15 
ClearCurState()16 void CPercentPrinterState::ClearCurState()
17 {
18   Completed = 0;
19   Total = ((UInt64)(Int64)-1);
20   Files = 0;
21   Command.Empty();
22   FileName.Empty();
23 }
24 
ClosePrint(bool needFlush)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 
GetPercents()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         (Total == 0 && Completed != 0))
68     {
69       val = Completed >> 20;
70       c = 'M';
71     }
72     else if (Total != 0)
73       val = Completed * 100 / Total;
74     ConvertUInt64ToString(val, s);
75     size = (unsigned)strlen(s);
76     s[size++] = c;
77     s[size] = 0;
78   }
79 
80   while (size < kPercentsSize)
81   {
82     _s.Add_Space();
83     size++;
84   }
85 
86   _s += s;
87 }
88 
Print()89 void CPercentPrinter::Print()
90 {
91   if (DisablePrint)
92     return;
93   DWORD tick = 0;
94   if (_tickStep != 0)
95     tick = GetTickCount();
96 
97   bool onlyPercentsChanged = false;
98 
99   if (!_printedString.IsEmpty())
100   {
101     if (_tickStep != 0 && (UInt32)(tick - _prevTick) < _tickStep)
102       return;
103 
104     CPercentPrinterState &st = *this;
105     if (_printedState.Command == st.Command
106         && _printedState.FileName == st.FileName
107         && _printedState.Files == st.Files)
108     {
109       if (_printedState.Total == st.Total
110           && _printedState.Completed == st.Completed)
111         return;
112       onlyPercentsChanged = true;
113     }
114   }
115 
116   _s.Empty();
117 
118   GetPercents();
119 
120   if (onlyPercentsChanged && _s == _printedPercents)
121     return;
122 
123   _printedPercents = _s;
124 
125   if (Files != 0)
126   {
127     char s[32];
128     ConvertUInt64ToString(Files, s);
129     // unsigned size = (unsigned)strlen(s);
130     // for (; size < 3; size++) _s.Add_Space();
131     _s.Add_Space();
132     _s += s;
133     // _s += "f";
134   }
135 
136 
137   if (!Command.IsEmpty())
138   {
139     _s.Add_Space();
140     _s += Command;
141   }
142 
143   if (!FileName.IsEmpty() && _s.Len() < MaxLen)
144   {
145     _s.Add_Space();
146 
147     _tempU = FileName;
148     _so->Normalize_UString_Path(_tempU);
149     _so->Convert_UString_to_AString(_tempU, _temp);
150     if (_s.Len() + _temp.Len() > MaxLen)
151     {
152       unsigned len = FileName.Len();
153       for (; len != 0;)
154       {
155         unsigned delta = len / 8;
156         if (delta == 0)
157           delta = 1;
158         len -= delta;
159         _tempU = FileName;
160         _tempU.Delete(len / 2, _tempU.Len() - len);
161         _tempU.Insert(len / 2, L" . ");
162         _so->Normalize_UString_Path(_tempU);
163         _so->Convert_UString_to_AString(_tempU, _temp);
164         if (_s.Len() + _temp.Len() <= MaxLen)
165           break;
166       }
167       if (len == 0)
168         _temp.Empty();
169     }
170     _s += _temp;
171   }
172 
173   if (_printedString != _s)
174   {
175     ClosePrint(false);
176     *_so << _s;
177     if (NeedFlush)
178       _so->Flush();
179     _printedString = _s;
180   }
181 
182   _printedState = *this;
183 
184   if (_tickStep != 0)
185     _prevTick = tick;
186 }
187