182 lines
3.4 KiB
C++
182 lines
3.4 KiB
C++
// PercentPrinter.cpp
|
|
|
|
#include "StdAfx.h"
|
|
|
|
#include "../../../Common/IntToString.h"
|
|
|
|
#include "PercentPrinter.h"
|
|
|
|
static const unsigned kPercentsSize = 4;
|
|
|
|
CPercentPrinter::~CPercentPrinter()
|
|
{
|
|
ClosePrint(false);
|
|
}
|
|
|
|
void CPercentPrinterState::ClearCurState()
|
|
{
|
|
Completed = 0;
|
|
Total = ((UInt64)(Int64)-1);
|
|
Files = 0;
|
|
Command.Empty();
|
|
FileName.Empty();
|
|
}
|
|
|
|
void CPercentPrinter::ClosePrint(bool needFlush)
|
|
{
|
|
unsigned num = _printedString.Len();
|
|
if (num != 0)
|
|
{
|
|
|
|
unsigned i;
|
|
|
|
/* '\r' in old MAC OS means "new line".
|
|
So we can't use '\r' in some systems */
|
|
|
|
#ifdef _WIN32
|
|
char *start = _temp.GetBuf(num + 2);
|
|
char *p = start;
|
|
*p++ = '\r';
|
|
for (i = 0; i < num; i++) *p++ = ' ';
|
|
*p++ = '\r';
|
|
#else
|
|
char *start = _temp.GetBuf(num * 3);
|
|
char *p = start;
|
|
for (i = 0; i < num; i++) *p++ = '\b';
|
|
for (i = 0; i < num; i++) *p++ = ' ';
|
|
for (i = 0; i < num; i++) *p++ = '\b';
|
|
#endif
|
|
|
|
*p = 0;
|
|
_temp.ReleaseBuf_SetLen((unsigned)(p - start));
|
|
*_so << _temp;
|
|
}
|
|
if (needFlush)
|
|
_so->Flush();
|
|
_printedString.Empty();
|
|
}
|
|
|
|
void CPercentPrinter::GetPercents()
|
|
{
|
|
char s[32];
|
|
unsigned size;
|
|
{
|
|
char c = '%';
|
|
UInt64 val = 0;
|
|
if (Total == (UInt64)(Int64)-1)
|
|
{
|
|
val = Completed >> 20;
|
|
c = 'M';
|
|
}
|
|
else if (Total != 0)
|
|
val = Completed * 100 / Total;
|
|
ConvertUInt64ToString(val, s);
|
|
size = (unsigned)strlen(s);
|
|
s[size++] = c;
|
|
s[size] = 0;
|
|
}
|
|
|
|
while (size < kPercentsSize)
|
|
{
|
|
_s += ' ';
|
|
size++;
|
|
}
|
|
|
|
_s += s;
|
|
}
|
|
|
|
void CPercentPrinter::Print()
|
|
{
|
|
DWORD tick = 0;
|
|
if (_tickStep != 0)
|
|
tick = GetTickCount();
|
|
|
|
bool onlyPercentsChanged = false;
|
|
|
|
if (!_printedString.IsEmpty())
|
|
{
|
|
if (_tickStep != 0 && (UInt32)(tick - _prevTick) < _tickStep)
|
|
return;
|
|
|
|
CPercentPrinterState &st = *this;
|
|
if (_printedState.Command == st.Command
|
|
&& _printedState.FileName == st.FileName
|
|
&& _printedState.Files == st.Files)
|
|
{
|
|
if (_printedState.Total == st.Total
|
|
&& _printedState.Completed == st.Completed)
|
|
return;
|
|
onlyPercentsChanged = true;
|
|
}
|
|
}
|
|
|
|
_s.Empty();
|
|
|
|
GetPercents();
|
|
|
|
if (onlyPercentsChanged && _s == _printedPercents)
|
|
return;
|
|
|
|
_printedPercents = _s;
|
|
|
|
if (Files != 0)
|
|
{
|
|
char s[32];
|
|
ConvertUInt64ToString(Files, s);
|
|
// unsigned size = (unsigned)strlen(s);
|
|
// for (; size < 3; size++) _s += ' ';
|
|
_s += ' ';
|
|
_s += s;
|
|
// _s += "f";
|
|
}
|
|
|
|
|
|
if (!Command.IsEmpty())
|
|
{
|
|
_s += ' ';
|
|
_s += Command;
|
|
}
|
|
|
|
if (!FileName.IsEmpty() && _s.Len() < MaxLen)
|
|
{
|
|
_s += ' ';
|
|
|
|
StdOut_Convert_UString_to_AString(FileName, _temp);
|
|
_temp.Replace('\n', ' ');
|
|
if (_s.Len() + _temp.Len() > MaxLen)
|
|
{
|
|
unsigned len = FileName.Len();
|
|
for (; len != 0;)
|
|
{
|
|
unsigned delta = len / 8;
|
|
if (delta == 0)
|
|
delta = 1;
|
|
len -= delta;
|
|
_tempU = FileName;
|
|
_tempU.Delete(len / 2, FileName.Len() - len);
|
|
_tempU.Insert(len / 2, L" . ");
|
|
StdOut_Convert_UString_to_AString(_tempU, _temp);
|
|
if (_s.Len() + _temp.Len() <= MaxLen)
|
|
break;
|
|
}
|
|
if (len == 0)
|
|
_temp.Empty();
|
|
}
|
|
_s += _temp;
|
|
}
|
|
|
|
if (_printedString != _s)
|
|
{
|
|
ClosePrint(false);
|
|
*_so << _s;
|
|
if (NeedFlush)
|
|
_so->Flush();
|
|
_printedString = _s;
|
|
}
|
|
|
|
_printedState = *this;
|
|
|
|
if (_tickStep != 0)
|
|
_prevTick = tick;
|
|
}
|