chdman/3rdparty/lzma/CPP/7zip/UI/Console/PercentPrinter.cpp
2022-01-05 08:45:19 +02:00

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;
}