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