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()11CPercentPrinter::~CPercentPrinter() 12 { 13 ClosePrint(false); 14 } 15 ClearCurState()16void 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)25void 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()59void 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 Print()88void 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 StdOut_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 StdOut_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 } 184