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 (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()89void 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