Source code

Revision control

Copy as Markdown

Other Tools

// HashCon.cpp↩
#include "StdAfx.h"
#include "../../../Common/IntToString.h"
#include "ConsoleClose.h"
#include "HashCon.h"
static const char * const kEmptyFileAlias = "[Content]";↩
static const char * const kScanningMessage = "Scanning";↩
static HRESULT CheckBreak2()↩
{↩
return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK;↩
}↩
HRESULT CHashCallbackConsole::CheckBreak()↩
{↩
return CheckBreak2();↩
}↩
HRESULT CHashCallbackConsole::StartScanning()↩
{↩
if (PrintHeaders && _so)↩
*_so << kScanningMessage << endl;↩
if (NeedPercents())↩
{↩
_percent.ClearCurState();↩
_percent.Command = "Scan";↩
}↩
return CheckBreak2();↩
}↩
HRESULT CHashCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */)↩
{↩
if (NeedPercents())↩
{↩
_percent.Files = st.NumDirs + st.NumFiles + st.NumAltStreams;↩
_percent.Completed = st.GetTotalBytes();↩
_percent.FileName = fs2us(path);↩
_percent.Print();↩
}↩
return CheckBreak2();↩
}↩
HRESULT CHashCallbackConsole::ScanError(const FString &path, DWORD systemError)↩
{↩
return ScanError_Base(path, systemError);↩
}↩
void Print_DirItemsStat(AString &s, const CDirItemsStat &st);↩
HRESULT CHashCallbackConsole::FinishScanning(const CDirItemsStat &st)↩
{↩
if (NeedPercents())↩
{↩
_percent.ClosePrint(true);↩
_percent.ClearCurState();↩
}↩
if (PrintHeaders && _so)↩
{↩
Print_DirItemsStat(_s, st);↩
*_so << _s << endl << endl;↩
}↩
return CheckBreak2();↩
}↩
HRESULT CHashCallbackConsole::SetNumFiles(UInt64 /* numFiles */)↩
{↩
return CheckBreak2();↩
}↩
HRESULT CHashCallbackConsole::SetTotal(UInt64 size)↩
{↩
if (NeedPercents())↩
{↩
_percent.Total = size;↩
_percent.Print();↩
}↩
return CheckBreak2();↩
}↩
HRESULT CHashCallbackConsole::SetCompleted(const UInt64 *completeValue)↩
{↩
if (completeValue && NeedPercents())↩
{↩
_percent.Completed = *completeValue;↩
_percent.Print();↩
}↩
return CheckBreak2();↩
}↩
static void AddMinuses(AString &s, unsigned num)↩
{↩
for (unsigned i = 0; i < num; i++)↩
s += '-';↩
}↩
static void AddSpaces_if_Positive(AString &s, int num)↩
{↩
for (int i = 0; i < num; i++)↩
s.Add_Space();↩
}↩
static void SetSpacesAndNul(char *s, unsigned num)↩
{↩
for (unsigned i = 0; i < num; i++)↩
s[i] = ' ';↩
s[num] = 0;↩
}↩
static const unsigned kSizeField_Len = 13;↩
static const unsigned kNameField_Len = 12;↩
static const unsigned kHashColumnWidth_Min = 4 * 2;↩
static unsigned GetColumnWidth(unsigned digestSize)↩
{↩
unsigned width = digestSize * 2;↩
return width < kHashColumnWidth_Min ? kHashColumnWidth_Min: width;↩
}↩
void CHashCallbackConsole::PrintSeparatorLine(const CObjectVector<CHasherState> &hashers)↩
{↩
_s.Empty();↩
for (unsigned i = 0; i < hashers.Size(); i++)↩
{↩
if (i != 0)↩
_s.Add_Space();↩
const CHasherState &h = hashers[i];↩
AddMinuses(_s, GetColumnWidth(h.DigestSize));↩
}↩
if (PrintSize)↩
{↩
_s.Add_Space();↩
AddMinuses(_s, kSizeField_Len);↩
}↩
if (PrintName)↩
{↩
AddSpacesBeforeName();↩
AddMinuses(_s, kNameField_Len);↩
}↩
*_so << _s << endl;↩
}↩
HRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb)↩
{↩
if (PrintHeaders && _so)↩
{↩
_s.Empty();↩
ClosePercents_for_so();↩
FOR_VECTOR (i, hb.Hashers)↩
{↩
if (i != 0)↩
_s.Add_Space();↩
const CHasherState &h = hb.Hashers[i];↩
_s += h.Name;↩
AddSpaces_if_Positive(_s, (int)GetColumnWidth(h.DigestSize) - (int)h.Name.Len());↩
}↩
if (PrintSize)↩
{↩
_s.Add_Space();↩
const AString s2 ("Size");↩
AddSpaces_if_Positive(_s, (int)kSizeField_Len - (int)s2.Len());↩
_s += s2;↩
}↩
if (PrintName)↩
{↩
AddSpacesBeforeName();↩
_s += "Name";↩
}↩
*_so << _s << endl;↩
PrintSeparatorLine(hb.Hashers);↩
}↩
return CheckBreak2();↩
}↩
HRESULT CHashCallbackConsole::OpenFileError(const FString &path, DWORD systemError)↩
{↩
return OpenFileError_Base(path, systemError);↩
}↩
HRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool /* isFolder */)↩
{↩
_fileName = name;↩
if (NeedPercents())↩
{↩
if (PrintNameInPercents)↩
{↩
_percent.FileName.Empty();↩
if (name)↩
_percent.FileName = name;↩
}↩
_percent.Print();↩
}↩
return CheckBreak2();↩
}↩
void CHashCallbackConsole::PrintResultLine(UInt64 fileSize,↩
const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash)↩
{↩
ClosePercents_for_so();↩
_s.Empty();↩
FOR_VECTOR (i, hashers)↩
{↩
const CHasherState &h = hashers[i];↩
char s[k_HashCalc_DigestSize_Max * 2 + 64];↩
s[0] = 0;↩
if (showHash)↩
AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize);↩
SetSpacesAndNul(s + strlen(s), (int)GetColumnWidth(h.DigestSize) - (int)strlen(s));↩
if (i != 0)↩
_s.Add_Space();↩
_s += s;↩
}↩
if (PrintSize)↩
{↩
_s.Add_Space();↩
char s[kSizeField_Len + 32];↩
char *p = s;↩
if (showHash)↩
{↩
p = s + kSizeField_Len;↩
ConvertUInt64ToString(fileSize, p);↩
int numSpaces = kSizeField_Len - (int)strlen(p);↩
if (numSpaces > 0)↩
{↩
p -= (unsigned)numSpaces;↩
for (unsigned i = 0; i < (unsigned)numSpaces; i++)↩
p[i] = ' ';↩
}↩
}↩
else
SetSpacesAndNul(s, kSizeField_Len);↩
_s += p;↩
}↩
if (PrintName)↩
AddSpacesBeforeName();↩
*_so << _s;↩
}↩
HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash)↩
{↩
if (_so)↩
{↩
PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash);↩
if (PrintName)↩
{↩
if (_fileName.IsEmpty())↩
*_so << kEmptyFileAlias;↩
else
_so->NormalizePrint_UString(_fileName);↩
}↩
*_so << endl;↩
}↩
if (NeedPercents())↩
{↩
_percent.Files++;↩
_percent.Print();↩
}↩
return CheckBreak2();↩
}↩
static const char * const k_DigestTitles[] =↩
{↩
" : "
, " for data: "
, " for data and names: "
, " for streams and names: "
};↩
static void PrintSum(CStdOutStream &so, const CHasherState &h, unsigned digestIndex)↩
{↩
so << h.Name;↩
{↩
AString temp;↩
AddSpaces_if_Positive(temp, 6 - (int)h.Name.Len());↩
so << temp;↩
}↩
so << k_DigestTitles[digestIndex];↩
char s[k_HashCalc_DigestSize_Max * 2 + 64];↩
s[0] = 0;↩
AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize);↩
so << s << endl;↩
}↩
void PrintHashStat(CStdOutStream &so, const CHashBundle &hb)↩
{↩
FOR_VECTOR (i, hb.Hashers)↩
{↩
const CHasherState &h = hb.Hashers[i];↩
PrintSum(so, h, k_HashCalc_Index_DataSum);↩
if (hb.NumFiles != 1 || hb.NumDirs != 0)↩
PrintSum(so, h, k_HashCalc_Index_NamesSum);↩
if (hb.NumAltStreams != 0)↩
PrintSum(so, h, k_HashCalc_Index_StreamsSum);↩
so << endl;↩
}↩
}↩
void CHashCallbackConsole::PrintProperty(const char *name, UInt64 value)↩
{↩
char s[32];↩
s[0] = ':';↩
s[1] = ' ';↩
ConvertUInt64ToString(value, s + 2);↩
*_so << name << s << endl;↩
}↩
HRESULT CHashCallbackConsole::AfterLastFile(const CHashBundle &hb)↩
{↩
ClosePercents2();↩
if (PrintHeaders && _so)↩
{↩
PrintSeparatorLine(hb.Hashers);↩
PrintResultLine(hb.FilesSize, hb.Hashers, k_HashCalc_Index_DataSum, true);↩
*_so << endl << endl;↩
if (hb.NumFiles != 1 || hb.NumDirs != 0)↩
{↩
if (hb.NumDirs != 0)↩
PrintProperty("Folders", hb.NumDirs);↩
PrintProperty("Files", hb.NumFiles);↩
}↩
PrintProperty("Size", hb.FilesSize);↩
if (hb.NumAltStreams != 0)↩
{↩
PrintProperty("Alternate streams", hb.NumAltStreams);↩
PrintProperty("Alternate streams size", hb.AltStreamsSize);↩
}↩
*_so << endl;↩
PrintHashStat(*_so, hb);↩
}↩
return S_OK;↩
}↩