diff options
Diffstat (limited to 'CPP/7zip/UI/Console/PercentPrinter.cpp')
-rw-r--r-- | CPP/7zip/UI/Console/PercentPrinter.cpp | 183 |
1 files changed, 183 insertions, 0 deletions
diff --git a/CPP/7zip/UI/Console/PercentPrinter.cpp b/CPP/7zip/UI/Console/PercentPrinter.cpp new file mode 100644 index 0000000..4341fd9 --- /dev/null +++ b/CPP/7zip/UI/Console/PercentPrinter.cpp | |||
@@ -0,0 +1,183 @@ | |||
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 | _tempU = FileName; | ||
145 | _so->Normalize_UString(_tempU); | ||
146 | _so->Convert_UString_to_AString(_tempU, _temp); | ||
147 | if (_s.Len() + _temp.Len() > MaxLen) | ||
148 | { | ||
149 | unsigned len = FileName.Len(); | ||
150 | for (; len != 0;) | ||
151 | { | ||
152 | unsigned delta = len / 8; | ||
153 | if (delta == 0) | ||
154 | delta = 1; | ||
155 | len -= delta; | ||
156 | _tempU = FileName; | ||
157 | _tempU.Delete(len / 2, _tempU.Len() - len); | ||
158 | _tempU.Insert(len / 2, L" . "); | ||
159 | _so->Normalize_UString(_tempU); | ||
160 | _so->Convert_UString_to_AString(_tempU, _temp); | ||
161 | if (_s.Len() + _temp.Len() <= MaxLen) | ||
162 | break; | ||
163 | } | ||
164 | if (len == 0) | ||
165 | _temp.Empty(); | ||
166 | } | ||
167 | _s += _temp; | ||
168 | } | ||
169 | |||
170 | if (_printedString != _s) | ||
171 | { | ||
172 | ClosePrint(false); | ||
173 | *_so << _s; | ||
174 | if (NeedFlush) | ||
175 | _so->Flush(); | ||
176 | _printedString = _s; | ||
177 | } | ||
178 | |||
179 | _printedState = *this; | ||
180 | |||
181 | if (_tickStep != 0) | ||
182 | _prevTick = tick; | ||
183 | } | ||