xref: /third_party/lzma/CPP/7zip/UI/Console/HashCon.cpp (revision 370b324c)
1370b324cSopenharmony_ci// HashCon.cpp
2370b324cSopenharmony_ci
3370b324cSopenharmony_ci#include "StdAfx.h"
4370b324cSopenharmony_ci
5370b324cSopenharmony_ci#include "../../../Common/IntToString.h"
6370b324cSopenharmony_ci
7370b324cSopenharmony_ci#include "../../../Windows/FileName.h"
8370b324cSopenharmony_ci
9370b324cSopenharmony_ci#include "ConsoleClose.h"
10370b324cSopenharmony_ci#include "HashCon.h"
11370b324cSopenharmony_ci
12370b324cSopenharmony_cistatic const char * const kEmptyFileAlias = "[Content]";
13370b324cSopenharmony_ci
14370b324cSopenharmony_cistatic const char * const kScanningMessage = "Scanning";
15370b324cSopenharmony_ci
16370b324cSopenharmony_cistatic HRESULT CheckBreak2()
17370b324cSopenharmony_ci{
18370b324cSopenharmony_ci  return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK;
19370b324cSopenharmony_ci}
20370b324cSopenharmony_ci
21370b324cSopenharmony_ciHRESULT CHashCallbackConsole::CheckBreak()
22370b324cSopenharmony_ci{
23370b324cSopenharmony_ci  return CheckBreak2();
24370b324cSopenharmony_ci}
25370b324cSopenharmony_ci
26370b324cSopenharmony_ciHRESULT CHashCallbackConsole::StartScanning()
27370b324cSopenharmony_ci{
28370b324cSopenharmony_ci  if (PrintHeaders && _so)
29370b324cSopenharmony_ci    *_so << kScanningMessage << endl;
30370b324cSopenharmony_ci  if (NeedPercents())
31370b324cSopenharmony_ci  {
32370b324cSopenharmony_ci    _percent.ClearCurState();
33370b324cSopenharmony_ci    _percent.Command = "Scan";
34370b324cSopenharmony_ci  }
35370b324cSopenharmony_ci  return CheckBreak2();
36370b324cSopenharmony_ci}
37370b324cSopenharmony_ci
38370b324cSopenharmony_ciHRESULT CHashCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool isDir)
39370b324cSopenharmony_ci{
40370b324cSopenharmony_ci  if (NeedPercents())
41370b324cSopenharmony_ci  {
42370b324cSopenharmony_ci    _percent.Files = st.NumDirs + st.NumFiles + st.NumAltStreams;
43370b324cSopenharmony_ci    _percent.Completed = st.GetTotalBytes();
44370b324cSopenharmony_ci    _percent.FileName = fs2us(path);
45370b324cSopenharmony_ci    if (isDir)
46370b324cSopenharmony_ci      NWindows::NFile::NName::NormalizeDirPathPrefix(_percent.FileName);
47370b324cSopenharmony_ci    _percent.Print();
48370b324cSopenharmony_ci  }
49370b324cSopenharmony_ci  return CheckBreak2();
50370b324cSopenharmony_ci}
51370b324cSopenharmony_ci
52370b324cSopenharmony_ciHRESULT CHashCallbackConsole::ScanError(const FString &path, DWORD systemError)
53370b324cSopenharmony_ci{
54370b324cSopenharmony_ci  return ScanError_Base(path, systemError);
55370b324cSopenharmony_ci}
56370b324cSopenharmony_ci
57370b324cSopenharmony_civoid Print_DirItemsStat(AString &s, const CDirItemsStat &st);
58370b324cSopenharmony_ci
59370b324cSopenharmony_ciHRESULT CHashCallbackConsole::FinishScanning(const CDirItemsStat &st)
60370b324cSopenharmony_ci{
61370b324cSopenharmony_ci  if (NeedPercents())
62370b324cSopenharmony_ci  {
63370b324cSopenharmony_ci    _percent.ClosePrint(true);
64370b324cSopenharmony_ci    _percent.ClearCurState();
65370b324cSopenharmony_ci  }
66370b324cSopenharmony_ci  if (PrintHeaders && _so)
67370b324cSopenharmony_ci  {
68370b324cSopenharmony_ci    Print_DirItemsStat(_s, st);
69370b324cSopenharmony_ci    *_so << _s << endl << endl;
70370b324cSopenharmony_ci  }
71370b324cSopenharmony_ci  return CheckBreak2();
72370b324cSopenharmony_ci}
73370b324cSopenharmony_ci
74370b324cSopenharmony_ciHRESULT CHashCallbackConsole::SetNumFiles(UInt64 /* numFiles */)
75370b324cSopenharmony_ci{
76370b324cSopenharmony_ci  return CheckBreak2();
77370b324cSopenharmony_ci}
78370b324cSopenharmony_ci
79370b324cSopenharmony_ciHRESULT CHashCallbackConsole::SetTotal(UInt64 size)
80370b324cSopenharmony_ci{
81370b324cSopenharmony_ci  if (NeedPercents())
82370b324cSopenharmony_ci  {
83370b324cSopenharmony_ci    _percent.Total = size;
84370b324cSopenharmony_ci    _percent.Print();
85370b324cSopenharmony_ci  }
86370b324cSopenharmony_ci  return CheckBreak2();
87370b324cSopenharmony_ci}
88370b324cSopenharmony_ci
89370b324cSopenharmony_ciHRESULT CHashCallbackConsole::SetCompleted(const UInt64 *completeValue)
90370b324cSopenharmony_ci{
91370b324cSopenharmony_ci  if (completeValue && NeedPercents())
92370b324cSopenharmony_ci  {
93370b324cSopenharmony_ci    _percent.Completed = *completeValue;
94370b324cSopenharmony_ci    _percent.Print();
95370b324cSopenharmony_ci  }
96370b324cSopenharmony_ci  return CheckBreak2();
97370b324cSopenharmony_ci}
98370b324cSopenharmony_ci
99370b324cSopenharmony_cistatic void AddMinuses(AString &s, unsigned num)
100370b324cSopenharmony_ci{
101370b324cSopenharmony_ci  for (unsigned i = 0; i < num; i++)
102370b324cSopenharmony_ci    s.Add_Minus();
103370b324cSopenharmony_ci}
104370b324cSopenharmony_ci
105370b324cSopenharmony_cistatic void AddSpaces_if_Positive(AString &s, int num)
106370b324cSopenharmony_ci{
107370b324cSopenharmony_ci  for (int i = 0; i < num; i++)
108370b324cSopenharmony_ci    s.Add_Space();
109370b324cSopenharmony_ci}
110370b324cSopenharmony_ci
111370b324cSopenharmony_cistatic void SetSpacesAndNul(char *s, unsigned num)
112370b324cSopenharmony_ci{
113370b324cSopenharmony_ci  for (unsigned i = 0; i < num; i++)
114370b324cSopenharmony_ci    s[i] = ' ';
115370b324cSopenharmony_ci  s[num] = 0;
116370b324cSopenharmony_ci}
117370b324cSopenharmony_ci
118370b324cSopenharmony_cistatic void SetSpacesAndNul_if_Positive(char *s, int num)
119370b324cSopenharmony_ci{
120370b324cSopenharmony_ci  if (num < 0)
121370b324cSopenharmony_ci    return;
122370b324cSopenharmony_ci  for (int i = 0; i < num; i++)
123370b324cSopenharmony_ci    s[i] = ' ';
124370b324cSopenharmony_ci  s[num] = 0;
125370b324cSopenharmony_ci}
126370b324cSopenharmony_ci
127370b324cSopenharmony_cistatic const unsigned kSizeField_Len = 13;
128370b324cSopenharmony_cistatic const unsigned kNameField_Len = 12;
129370b324cSopenharmony_ci
130370b324cSopenharmony_cistatic const unsigned kHashColumnWidth_Min = 4 * 2;
131370b324cSopenharmony_ci
132370b324cSopenharmony_cistatic unsigned GetColumnWidth(unsigned digestSize)
133370b324cSopenharmony_ci{
134370b324cSopenharmony_ci  unsigned width = digestSize * 2;
135370b324cSopenharmony_ci  return width < kHashColumnWidth_Min ? kHashColumnWidth_Min: width;
136370b324cSopenharmony_ci}
137370b324cSopenharmony_ci
138370b324cSopenharmony_ci
139370b324cSopenharmony_ciAString CHashCallbackConsole::GetFields() const
140370b324cSopenharmony_ci{
141370b324cSopenharmony_ci  AString s (PrintFields);
142370b324cSopenharmony_ci  if (s.IsEmpty())
143370b324cSopenharmony_ci    s = "hsn";
144370b324cSopenharmony_ci  s.MakeLower_Ascii();
145370b324cSopenharmony_ci  return s;
146370b324cSopenharmony_ci}
147370b324cSopenharmony_ci
148370b324cSopenharmony_ci
149370b324cSopenharmony_civoid CHashCallbackConsole::PrintSeparatorLine(const CObjectVector<CHasherState> &hashers)
150370b324cSopenharmony_ci{
151370b324cSopenharmony_ci  _s.Empty();
152370b324cSopenharmony_ci  const AString fields = GetFields();
153370b324cSopenharmony_ci  for (unsigned pos = 0; pos < fields.Len(); pos++)
154370b324cSopenharmony_ci  {
155370b324cSopenharmony_ci    const char c = fields[pos];
156370b324cSopenharmony_ci    if (c == 'h')
157370b324cSopenharmony_ci    {
158370b324cSopenharmony_ci      for (unsigned i = 0; i < hashers.Size(); i++)
159370b324cSopenharmony_ci      {
160370b324cSopenharmony_ci        AddSpace();
161370b324cSopenharmony_ci        const CHasherState &h = hashers[i];
162370b324cSopenharmony_ci        AddMinuses(_s, GetColumnWidth(h.DigestSize));
163370b324cSopenharmony_ci      }
164370b324cSopenharmony_ci    }
165370b324cSopenharmony_ci    else if (c == 's')
166370b324cSopenharmony_ci    {
167370b324cSopenharmony_ci      AddSpace();
168370b324cSopenharmony_ci      AddMinuses(_s, kSizeField_Len);
169370b324cSopenharmony_ci    }
170370b324cSopenharmony_ci    else if (c == 'n')
171370b324cSopenharmony_ci    {
172370b324cSopenharmony_ci      AddSpacesBeforeName();
173370b324cSopenharmony_ci      AddMinuses(_s, kNameField_Len);
174370b324cSopenharmony_ci    }
175370b324cSopenharmony_ci  }
176370b324cSopenharmony_ci
177370b324cSopenharmony_ci  *_so << _s << endl;
178370b324cSopenharmony_ci}
179370b324cSopenharmony_ci
180370b324cSopenharmony_ci
181370b324cSopenharmony_ciHRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb)
182370b324cSopenharmony_ci{
183370b324cSopenharmony_ci  if (PrintHeaders && _so)
184370b324cSopenharmony_ci  {
185370b324cSopenharmony_ci    _s.Empty();
186370b324cSopenharmony_ci    ClosePercents_for_so();
187370b324cSopenharmony_ci
188370b324cSopenharmony_ci    const AString fields = GetFields();
189370b324cSopenharmony_ci    for (unsigned pos = 0; pos < fields.Len(); pos++)
190370b324cSopenharmony_ci    {
191370b324cSopenharmony_ci      const char c = fields[pos];
192370b324cSopenharmony_ci      if (c == 'h')
193370b324cSopenharmony_ci      {
194370b324cSopenharmony_ci        FOR_VECTOR (i, hb.Hashers)
195370b324cSopenharmony_ci        {
196370b324cSopenharmony_ci          AddSpace();
197370b324cSopenharmony_ci          const CHasherState &h = hb.Hashers[i];
198370b324cSopenharmony_ci          _s += h.Name;
199370b324cSopenharmony_ci          AddSpaces_if_Positive(_s, (int)GetColumnWidth(h.DigestSize) - (int)h.Name.Len());
200370b324cSopenharmony_ci        }
201370b324cSopenharmony_ci      }
202370b324cSopenharmony_ci
203370b324cSopenharmony_ci      else if (c == 's')
204370b324cSopenharmony_ci      {
205370b324cSopenharmony_ci        AddSpace();
206370b324cSopenharmony_ci        const AString s2 ("Size");
207370b324cSopenharmony_ci        AddSpaces_if_Positive(_s, (int)kSizeField_Len - (int)s2.Len());
208370b324cSopenharmony_ci        _s += s2;
209370b324cSopenharmony_ci      }
210370b324cSopenharmony_ci      else if (c == 'n')
211370b324cSopenharmony_ci      {
212370b324cSopenharmony_ci        AddSpacesBeforeName();
213370b324cSopenharmony_ci        _s += "Name";
214370b324cSopenharmony_ci      }
215370b324cSopenharmony_ci    }
216370b324cSopenharmony_ci
217370b324cSopenharmony_ci    *_so << _s << endl;
218370b324cSopenharmony_ci    PrintSeparatorLine(hb.Hashers);
219370b324cSopenharmony_ci  }
220370b324cSopenharmony_ci
221370b324cSopenharmony_ci  return CheckBreak2();
222370b324cSopenharmony_ci}
223370b324cSopenharmony_ci
224370b324cSopenharmony_ciHRESULT CHashCallbackConsole::OpenFileError(const FString &path, DWORD systemError)
225370b324cSopenharmony_ci{
226370b324cSopenharmony_ci  return OpenFileError_Base(path, systemError);
227370b324cSopenharmony_ci}
228370b324cSopenharmony_ci
229370b324cSopenharmony_ciHRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool isDir)
230370b324cSopenharmony_ci{
231370b324cSopenharmony_ci  _fileName = name;
232370b324cSopenharmony_ci  if (isDir)
233370b324cSopenharmony_ci    NWindows::NFile::NName::NormalizeDirPathPrefix(_fileName);
234370b324cSopenharmony_ci
235370b324cSopenharmony_ci  if (NeedPercents())
236370b324cSopenharmony_ci  {
237370b324cSopenharmony_ci    if (PrintNameInPercents)
238370b324cSopenharmony_ci    {
239370b324cSopenharmony_ci      _percent.FileName.Empty();
240370b324cSopenharmony_ci      if (name)
241370b324cSopenharmony_ci        _percent.FileName = name;
242370b324cSopenharmony_ci    }
243370b324cSopenharmony_ci   _percent.Print();
244370b324cSopenharmony_ci  }
245370b324cSopenharmony_ci  return CheckBreak2();
246370b324cSopenharmony_ci}
247370b324cSopenharmony_ci
248370b324cSopenharmony_ci
249370b324cSopenharmony_cistatic const unsigned k_DigestStringSize = k_HashCalc_DigestSize_Max * 2 + k_HashCalc_ExtraSize * 2 + 16;
250370b324cSopenharmony_ci
251370b324cSopenharmony_ci
252370b324cSopenharmony_ci
253370b324cSopenharmony_civoid CHashCallbackConsole::PrintResultLine(UInt64 fileSize,
254370b324cSopenharmony_ci    const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash,
255370b324cSopenharmony_ci    const AString &path)
256370b324cSopenharmony_ci{
257370b324cSopenharmony_ci  ClosePercents_for_so();
258370b324cSopenharmony_ci
259370b324cSopenharmony_ci  _s.Empty();
260370b324cSopenharmony_ci  const AString fields = GetFields();
261370b324cSopenharmony_ci
262370b324cSopenharmony_ci  for (unsigned pos = 0; pos < fields.Len(); pos++)
263370b324cSopenharmony_ci  {
264370b324cSopenharmony_ci    const char c = fields[pos];
265370b324cSopenharmony_ci    if (c == 'h')
266370b324cSopenharmony_ci    {
267370b324cSopenharmony_ci      FOR_VECTOR (i, hashers)
268370b324cSopenharmony_ci      {
269370b324cSopenharmony_ci        AddSpace();
270370b324cSopenharmony_ci        const CHasherState &h = hashers[i];
271370b324cSopenharmony_ci        char s[k_DigestStringSize];
272370b324cSopenharmony_ci        s[0] = 0;
273370b324cSopenharmony_ci        if (showHash)
274370b324cSopenharmony_ci          h.WriteToString(digestIndex, s);
275370b324cSopenharmony_ci        const unsigned len = (unsigned)strlen(s);
276370b324cSopenharmony_ci        SetSpacesAndNul_if_Positive(s + len, (int)GetColumnWidth(h.DigestSize) - (int)len);
277370b324cSopenharmony_ci        _s += s;
278370b324cSopenharmony_ci      }
279370b324cSopenharmony_ci    }
280370b324cSopenharmony_ci    else if (c == 's')
281370b324cSopenharmony_ci    {
282370b324cSopenharmony_ci      AddSpace();
283370b324cSopenharmony_ci      char s[kSizeField_Len + 32];
284370b324cSopenharmony_ci      char *p = s;
285370b324cSopenharmony_ci      SetSpacesAndNul(s, kSizeField_Len);
286370b324cSopenharmony_ci      if (showHash)
287370b324cSopenharmony_ci      {
288370b324cSopenharmony_ci        p = s + kSizeField_Len;
289370b324cSopenharmony_ci        ConvertUInt64ToString(fileSize, p);
290370b324cSopenharmony_ci        const int numSpaces = (int)kSizeField_Len - (int)strlen(p);
291370b324cSopenharmony_ci        if (numSpaces > 0)
292370b324cSopenharmony_ci          p -= (unsigned)numSpaces;
293370b324cSopenharmony_ci      }
294370b324cSopenharmony_ci      _s += p;
295370b324cSopenharmony_ci    }
296370b324cSopenharmony_ci    else if (c == 'n')
297370b324cSopenharmony_ci    {
298370b324cSopenharmony_ci      AddSpacesBeforeName();
299370b324cSopenharmony_ci      _s += path;
300370b324cSopenharmony_ci    }
301370b324cSopenharmony_ci  }
302370b324cSopenharmony_ci
303370b324cSopenharmony_ci  *_so << _s;
304370b324cSopenharmony_ci}
305370b324cSopenharmony_ci
306370b324cSopenharmony_ci
307370b324cSopenharmony_ciHRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash)
308370b324cSopenharmony_ci{
309370b324cSopenharmony_ci  if (_so)
310370b324cSopenharmony_ci  {
311370b324cSopenharmony_ci    AString s;
312370b324cSopenharmony_ci    if (_fileName.IsEmpty())
313370b324cSopenharmony_ci      s = kEmptyFileAlias;
314370b324cSopenharmony_ci    else
315370b324cSopenharmony_ci    {
316370b324cSopenharmony_ci      UString temp (_fileName);
317370b324cSopenharmony_ci      _so->Normalize_UString(temp);
318370b324cSopenharmony_ci      _so->Convert_UString_to_AString(temp, s);
319370b324cSopenharmony_ci    }
320370b324cSopenharmony_ci    PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash, s);
321370b324cSopenharmony_ci
322370b324cSopenharmony_ci    /*
323370b324cSopenharmony_ci    PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash);
324370b324cSopenharmony_ci    if (PrintName)
325370b324cSopenharmony_ci    {
326370b324cSopenharmony_ci      if (_fileName.IsEmpty())
327370b324cSopenharmony_ci        *_so << kEmptyFileAlias;
328370b324cSopenharmony_ci      else
329370b324cSopenharmony_ci        _so->NormalizePrint_UString(_fileName);
330370b324cSopenharmony_ci    }
331370b324cSopenharmony_ci    */
332370b324cSopenharmony_ci    // if (PrintNewLine)
333370b324cSopenharmony_ci      *_so << endl;
334370b324cSopenharmony_ci  }
335370b324cSopenharmony_ci
336370b324cSopenharmony_ci  if (NeedPercents())
337370b324cSopenharmony_ci  {
338370b324cSopenharmony_ci    _percent.Files++;
339370b324cSopenharmony_ci    _percent.Print();
340370b324cSopenharmony_ci  }
341370b324cSopenharmony_ci
342370b324cSopenharmony_ci  return CheckBreak2();
343370b324cSopenharmony_ci}
344370b324cSopenharmony_ci
345370b324cSopenharmony_cistatic const char * const k_DigestTitles[] =
346370b324cSopenharmony_ci{
347370b324cSopenharmony_ci    " : "
348370b324cSopenharmony_ci  , " for data:              "
349370b324cSopenharmony_ci  , " for data and names:    "
350370b324cSopenharmony_ci  , " for streams and names: "
351370b324cSopenharmony_ci};
352370b324cSopenharmony_ci
353370b324cSopenharmony_cistatic void PrintSum(CStdOutStream &so, const CHasherState &h, unsigned digestIndex)
354370b324cSopenharmony_ci{
355370b324cSopenharmony_ci  so << h.Name;
356370b324cSopenharmony_ci
357370b324cSopenharmony_ci  {
358370b324cSopenharmony_ci    AString temp;
359370b324cSopenharmony_ci    AddSpaces_if_Positive(temp, 6 - (int)h.Name.Len());
360370b324cSopenharmony_ci    so << temp;
361370b324cSopenharmony_ci  }
362370b324cSopenharmony_ci
363370b324cSopenharmony_ci  so << k_DigestTitles[digestIndex];
364370b324cSopenharmony_ci
365370b324cSopenharmony_ci  char s[k_DigestStringSize];
366370b324cSopenharmony_ci  // s[0] = 0;
367370b324cSopenharmony_ci  h.WriteToString(digestIndex, s);
368370b324cSopenharmony_ci  so << s << endl;
369370b324cSopenharmony_ci}
370370b324cSopenharmony_ci
371370b324cSopenharmony_civoid PrintHashStat(CStdOutStream &so, const CHashBundle &hb)
372370b324cSopenharmony_ci{
373370b324cSopenharmony_ci  FOR_VECTOR (i, hb.Hashers)
374370b324cSopenharmony_ci  {
375370b324cSopenharmony_ci    const CHasherState &h = hb.Hashers[i];
376370b324cSopenharmony_ci    PrintSum(so, h, k_HashCalc_Index_DataSum);
377370b324cSopenharmony_ci    if (hb.NumFiles != 1 || hb.NumDirs != 0)
378370b324cSopenharmony_ci      PrintSum(so, h, k_HashCalc_Index_NamesSum);
379370b324cSopenharmony_ci    if (hb.NumAltStreams != 0)
380370b324cSopenharmony_ci      PrintSum(so, h, k_HashCalc_Index_StreamsSum);
381370b324cSopenharmony_ci    so << endl;
382370b324cSopenharmony_ci  }
383370b324cSopenharmony_ci}
384370b324cSopenharmony_ci
385370b324cSopenharmony_civoid CHashCallbackConsole::PrintProperty(const char *name, UInt64 value)
386370b324cSopenharmony_ci{
387370b324cSopenharmony_ci  char s[32];
388370b324cSopenharmony_ci  s[0] = ':';
389370b324cSopenharmony_ci  s[1] = ' ';
390370b324cSopenharmony_ci  ConvertUInt64ToString(value, s + 2);
391370b324cSopenharmony_ci  *_so << name << s << endl;
392370b324cSopenharmony_ci}
393370b324cSopenharmony_ci
394370b324cSopenharmony_ciHRESULT CHashCallbackConsole::AfterLastFile(CHashBundle &hb)
395370b324cSopenharmony_ci{
396370b324cSopenharmony_ci  ClosePercents2();
397370b324cSopenharmony_ci
398370b324cSopenharmony_ci  if (PrintHeaders && _so)
399370b324cSopenharmony_ci  {
400370b324cSopenharmony_ci    PrintSeparatorLine(hb.Hashers);
401370b324cSopenharmony_ci
402370b324cSopenharmony_ci    PrintResultLine(hb.FilesSize, hb.Hashers, k_HashCalc_Index_DataSum, true, AString());
403370b324cSopenharmony_ci
404370b324cSopenharmony_ci    *_so << endl << endl;
405370b324cSopenharmony_ci
406370b324cSopenharmony_ci    if (hb.NumFiles != 1 || hb.NumDirs != 0)
407370b324cSopenharmony_ci    {
408370b324cSopenharmony_ci      if (hb.NumDirs != 0)
409370b324cSopenharmony_ci        PrintProperty("Folders", hb.NumDirs);
410370b324cSopenharmony_ci      PrintProperty("Files", hb.NumFiles);
411370b324cSopenharmony_ci    }
412370b324cSopenharmony_ci
413370b324cSopenharmony_ci    PrintProperty("Size", hb.FilesSize);
414370b324cSopenharmony_ci
415370b324cSopenharmony_ci    if (hb.NumAltStreams != 0)
416370b324cSopenharmony_ci    {
417370b324cSopenharmony_ci      PrintProperty("Alternate streams", hb.NumAltStreams);
418370b324cSopenharmony_ci      PrintProperty("Alternate streams size", hb.AltStreamsSize);
419370b324cSopenharmony_ci    }
420370b324cSopenharmony_ci
421370b324cSopenharmony_ci    *_so << endl;
422370b324cSopenharmony_ci    PrintHashStat(*_so, hb);
423370b324cSopenharmony_ci  }
424370b324cSopenharmony_ci
425370b324cSopenharmony_ci  return S_OK;
426370b324cSopenharmony_ci}
427