aboutsummaryrefslogtreecommitdiff
path: root/CPP/7zip/UI/Console/HashCon.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'CPP/7zip/UI/Console/HashCon.cpp')
-rw-r--r--CPP/7zip/UI/Console/HashCon.cpp274
1 files changed, 274 insertions, 0 deletions
diff --git a/CPP/7zip/UI/Console/HashCon.cpp b/CPP/7zip/UI/Console/HashCon.cpp
new file mode 100644
index 0000000..a9e62c2
--- /dev/null
+++ b/CPP/7zip/UI/Console/HashCon.cpp
@@ -0,0 +1,274 @@
+// HashCon.cpp
+
+#include "StdAfx.h"
+
+#include "../../../Common/IntToString.h"
+#include "../../../Common/StringConvert.h"
+
+#include "../../../Windows/ErrorMsg.h"
+
+#include "ConsoleClose.h"
+#include "HashCon.h"
+
+static const wchar_t *kEmptyFileAlias = L"[Content]";
+
+static const char *kScanningMessage = "Scanning";
+
+HRESULT CHashCallbackConsole::CheckBreak()
+{
+ return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK;
+}
+
+HRESULT CHashCallbackConsole::StartScanning()
+{
+ (*OutStream) << kScanningMessage;
+ return CheckBreak();
+}
+
+HRESULT CHashCallbackConsole::ScanProgress(UInt64 /* numFolders */, UInt64 /* numFiles */, UInt64 /* totalSize */, const wchar_t * /* path */, bool /* isDir */)
+{
+ return CheckBreak();
+}
+
+HRESULT CHashCallbackConsole::CanNotFindError(const wchar_t *name, DWORD systemError)
+{
+ return CanNotFindError_Base(name, systemError);
+}
+
+HRESULT CHashCallbackConsole::FinishScanning()
+{
+ (*OutStream) << endl << endl;
+ return CheckBreak();
+}
+
+HRESULT CHashCallbackConsole::SetNumFiles(UInt64 /* numFiles */)
+{
+ return CheckBreak();
+}
+
+HRESULT CHashCallbackConsole::SetTotal(UInt64 size)
+{
+ if (EnablePercents)
+ m_PercentPrinter.SetTotal(size);
+ return CheckBreak();
+}
+
+HRESULT CHashCallbackConsole::SetCompleted(const UInt64 *completeValue)
+{
+ if (completeValue && EnablePercents)
+ {
+ m_PercentPrinter.SetRatio(*completeValue);
+ m_PercentPrinter.PrintRatio();
+ }
+ return CheckBreak();
+}
+
+static void AddMinuses(AString &s, unsigned num)
+{
+ for (unsigned i = 0; i < num; i++)
+ s += '-';
+}
+
+static void SetSpaces(char *s, int num)
+{
+ for (int i = 0; i < num; i++)
+ s[i] = ' ';
+}
+
+static void SetSpacesAndNul(char *s, int num)
+{
+ SetSpaces(s, num);
+ s[num] = 0;
+}
+
+static void AddSpaces(UString &s, int num)
+{
+ for (int i = 0; i < num; i++)
+ s += ' ';
+}
+
+static const int kSizeField_Len = 13;
+static const int kNameField_Len = 12;
+
+static unsigned GetColumnWidth(unsigned digestSize)
+{
+ unsigned width = digestSize * 2;
+ const unsigned kMinColumnWidth = 8;
+ return width < kMinColumnWidth ? kMinColumnWidth: width;
+}
+
+void CHashCallbackConsole::PrintSeparatorLine(const CObjectVector<CHasherState> &hashers)
+{
+ AString s;
+ for (unsigned i = 0; i < hashers.Size(); i++)
+ {
+ const CHasherState &h = hashers[i];
+ AddMinuses(s, GetColumnWidth(h.DigestSize));
+ s += ' ';
+ }
+ AddMinuses(s, kSizeField_Len);
+ s += " ";
+ AddMinuses(s, kNameField_Len);
+ m_PercentPrinter.PrintString(s);
+ m_PercentPrinter.PrintNewLine();
+}
+
+HRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb)
+{
+ UString s;
+ FOR_VECTOR (i, hb.Hashers)
+ {
+ const CHasherState &h = hb.Hashers[i];
+ s += h.Name;
+ AddSpaces(s, (int)GetColumnWidth(h.DigestSize) - h.Name.Len() + 1);
+ }
+ UString s2 = L"Size";
+ AddSpaces(s, kSizeField_Len - s2.Len());
+ s += s2;
+ s += L" ";
+ s += L"Name";
+ m_PercentPrinter.PrintString(s);
+ m_PercentPrinter.PrintNewLine();
+ PrintSeparatorLine(hb.Hashers);
+ return CheckBreak();
+}
+
+HRESULT CHashCallbackConsole::OpenFileError(const wchar_t *name, DWORD systemError)
+{
+ FailedCodes.Add(systemError);
+ FailedFiles.Add(name);
+ // if (systemError == ERROR_SHARING_VIOLATION)
+ {
+ m_PercentPrinter.PrintString(name);
+ m_PercentPrinter.PrintString(": WARNING: ");
+ m_PercentPrinter.PrintString(NWindows::NError::MyFormatMessage(systemError));
+ return S_FALSE;
+ }
+ // return systemError;
+}
+
+HRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool /* isFolder */)
+{
+ m_FileName = name;
+ return CheckBreak();
+}
+
+void CHashCallbackConsole::PrintResultLine(UInt64 fileSize,
+ const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash)
+{
+ 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) + 1);
+ m_PercentPrinter.PrintString(s);
+ }
+ char s[64];
+ s[0] = 0;
+ char *p = s;
+ if (showHash && fileSize != 0)
+ {
+ p = s + 32;
+ ConvertUInt64ToString(fileSize, p);
+ int numSpaces = kSizeField_Len - (int)strlen(p);
+ if (numSpaces > 0)
+ {
+ p -= numSpaces;
+ SetSpaces(p, numSpaces);
+ }
+ }
+ else
+ SetSpacesAndNul(s, kSizeField_Len - (int)strlen(s));
+ unsigned len = (unsigned)strlen(p);
+ p[len] = ' ';
+ p[len + 1] = ' ';
+ p[len + 2] = 0;
+ m_PercentPrinter.PrintString(p);
+}
+
+HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash)
+{
+ PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash);
+ if (m_FileName.IsEmpty())
+ m_PercentPrinter.PrintString(kEmptyFileAlias);
+ else
+ m_PercentPrinter.PrintString(m_FileName);
+ m_PercentPrinter.PrintNewLine();
+ return S_OK;
+}
+
+static const char *k_DigestTitles[] =
+{
+ " :"
+ , " for data: "
+ , " for data and names: "
+ , " for streams and names: "
+};
+
+static void PrintSum(CStdOutStream &p, const CHasherState &h, unsigned digestIndex)
+{
+ char s[k_HashCalc_DigestSize_Max * 2 + 64];
+ UString name = h.Name;
+ AddSpaces(name, 6 - (int)name.Len());
+ p << name;
+ p << k_DigestTitles[digestIndex];
+ s[0] = 0;
+ AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize);
+ p << s;
+ p << "\n";
+}
+
+
+void PrintHashStat(CStdOutStream &p, const CHashBundle &hb)
+{
+ FOR_VECTOR (i, hb.Hashers)
+ {
+ const CHasherState &h = hb.Hashers[i];
+ p << "\n";
+ PrintSum(p, h, k_HashCalc_Index_DataSum);
+ if (hb.NumFiles != 1 || hb.NumDirs != 0)
+ PrintSum(p, h, k_HashCalc_Index_NamesSum);
+ if (hb.NumAltStreams != 0)
+ PrintSum(p, h, k_HashCalc_Index_StreamsSum);
+ }
+}
+
+void CHashCallbackConsole::PrintProperty(const char *name, UInt64 value)
+{
+ char s[32];
+ s[0] = ':';
+ s[1] = ' ';
+ ConvertUInt64ToString(value, s + 2);
+ m_PercentPrinter.PrintString(name);
+ m_PercentPrinter.PrintString(s);
+ m_PercentPrinter.PrintNewLine();
+}
+
+HRESULT CHashCallbackConsole::AfterLastFile(const CHashBundle &hb)
+{
+ PrintSeparatorLine(hb.Hashers);
+
+ PrintResultLine(hb.FilesSize, hb.Hashers, k_HashCalc_Index_DataSum, true);
+ m_PercentPrinter.PrintNewLine();
+ m_PercentPrinter.PrintNewLine();
+
+ 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("AltStreams", hb.NumAltStreams);
+ PrintProperty("AltStreams size", hb.AltStreamsSize);
+ }
+ PrintHashStat(*m_PercentPrinter.OutStream, hb);
+ m_PercentPrinter.PrintNewLine();
+ return S_OK;
+}