1// PercentPrinter.cpp 2 3#include "StdAfx.h" 4 5#include "../../../Common/IntToString.h" 6 7#include "PercentPrinter.h" 8 9static const unsigned kPercentsSize = 4; 10 11CPercentPrinter::~CPercentPrinter() 12{ 13 ClosePrint(false); 14} 15 16void CPercentPrinterState::ClearCurState() 17{ 18 Completed = 0; 19 Total = ((UInt64)(Int64)-1); 20 Files = 0; 21 Command.Empty(); 22 FileName.Empty(); 23} 24 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 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 89void CPercentPrinter::Print() 90{ 91 DWORD tick = 0; 92 if (_tickStep != 0) 93 tick = GetTickCount(); 94 95 bool onlyPercentsChanged = false; 96 97 if (!_printedString.IsEmpty()) 98 { 99 if (_tickStep != 0 && (UInt32)(tick - _prevTick) < _tickStep) 100 return; 101 102 CPercentPrinterState &st = *this; 103 if (_printedState.Command == st.Command 104 && _printedState.FileName == st.FileName 105 && _printedState.Files == st.Files) 106 { 107 if (_printedState.Total == st.Total 108 && _printedState.Completed == st.Completed) 109 return; 110 onlyPercentsChanged = true; 111 } 112 } 113 114 _s.Empty(); 115 116 GetPercents(); 117 118 if (onlyPercentsChanged && _s == _printedPercents) 119 return; 120 121 _printedPercents = _s; 122 123 if (Files != 0) 124 { 125 char s[32]; 126 ConvertUInt64ToString(Files, s); 127 // unsigned size = (unsigned)strlen(s); 128 // for (; size < 3; size++) _s.Add_Space(); 129 _s.Add_Space(); 130 _s += s; 131 // _s += "f"; 132 } 133 134 135 if (!Command.IsEmpty()) 136 { 137 _s.Add_Space(); 138 _s += Command; 139 } 140 141 if (!FileName.IsEmpty() && _s.Len() < MaxLen) 142 { 143 _s.Add_Space(); 144 145 _tempU = FileName; 146 _so->Normalize_UString(_tempU); 147 _so->Convert_UString_to_AString(_tempU, _temp); 148 if (_s.Len() + _temp.Len() > MaxLen) 149 { 150 unsigned len = FileName.Len(); 151 for (; len != 0;) 152 { 153 unsigned delta = len / 8; 154 if (delta == 0) 155 delta = 1; 156 len -= delta; 157 _tempU = FileName; 158 _tempU.Delete(len / 2, _tempU.Len() - len); 159 _tempU.Insert(len / 2, L" . "); 160 _so->Normalize_UString(_tempU); 161 _so->Convert_UString_to_AString(_tempU, _temp); 162 if (_s.Len() + _temp.Len() <= MaxLen) 163 break; 164 } 165 if (len == 0) 166 _temp.Empty(); 167 } 168 _s += _temp; 169 } 170 171 if (_printedString != _s) 172 { 173 ClosePrint(false); 174 *_so << _s; 175 if (NeedFlush) 176 _so->Flush(); 177 _printedString = _s; 178 } 179 180 _printedState = *this; 181 182 if (_tickStep != 0) 183 _prevTick = tick; 184} 185