tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

HashCon.cpp (8057B)


      1 // HashCon.cpp
      2 
      3 #include "StdAfx.h"
      4 
      5 #include "../../../Common/IntToString.h"
      6 
      7 #include "ConsoleClose.h"
      8 #include "HashCon.h"
      9 
     10 static const char * const kEmptyFileAlias = "[Content]";
     11 
     12 static const char * const kScanningMessage = "Scanning";
     13 
     14 static HRESULT CheckBreak2()
     15 {
     16  return NConsoleClose::TestBreakSignal() ? E_ABORT : S_OK;
     17 }
     18 
     19 HRESULT CHashCallbackConsole::CheckBreak()
     20 {
     21  return CheckBreak2();
     22 }
     23 
     24 HRESULT CHashCallbackConsole::StartScanning()
     25 {
     26  if (PrintHeaders && _so)
     27    *_so << kScanningMessage << endl;
     28  if (NeedPercents())
     29  {
     30    _percent.ClearCurState();
     31    _percent.Command = "Scan";
     32  }
     33  return CheckBreak2();
     34 }
     35 
     36 HRESULT CHashCallbackConsole::ScanProgress(const CDirItemsStat &st, const FString &path, bool /* isDir */)
     37 {
     38  if (NeedPercents())
     39  {
     40    _percent.Files = st.NumDirs + st.NumFiles + st.NumAltStreams;
     41    _percent.Completed = st.GetTotalBytes();
     42    _percent.FileName = fs2us(path);
     43    _percent.Print();
     44  }
     45  return CheckBreak2();
     46 }
     47 
     48 HRESULT CHashCallbackConsole::ScanError(const FString &path, DWORD systemError)
     49 {
     50  return ScanError_Base(path, systemError);
     51 }
     52 
     53 void Print_DirItemsStat(AString &s, const CDirItemsStat &st);
     54 
     55 HRESULT CHashCallbackConsole::FinishScanning(const CDirItemsStat &st)
     56 {
     57  if (NeedPercents())
     58  {
     59    _percent.ClosePrint(true);
     60    _percent.ClearCurState();
     61  }
     62  if (PrintHeaders && _so)
     63  {
     64    Print_DirItemsStat(_s, st);
     65    *_so << _s << endl << endl;
     66  }
     67  return CheckBreak2();
     68 }
     69 
     70 HRESULT CHashCallbackConsole::SetNumFiles(UInt64 /* numFiles */)
     71 {
     72  return CheckBreak2();
     73 }
     74 
     75 HRESULT CHashCallbackConsole::SetTotal(UInt64 size)
     76 {
     77  if (NeedPercents())
     78  {
     79    _percent.Total = size;
     80    _percent.Print();
     81  }
     82  return CheckBreak2();
     83 }
     84 
     85 HRESULT CHashCallbackConsole::SetCompleted(const UInt64 *completeValue)
     86 {
     87  if (completeValue && NeedPercents())
     88  {
     89    _percent.Completed = *completeValue;
     90    _percent.Print();
     91  }
     92  return CheckBreak2();
     93 }
     94 
     95 static void AddMinuses(AString &s, unsigned num)
     96 {
     97  for (unsigned i = 0; i < num; i++)
     98    s += '-';
     99 }
    100 
    101 static void AddSpaces_if_Positive(AString &s, int num)
    102 {
    103  for (int i = 0; i < num; i++)
    104    s.Add_Space();
    105 }
    106 
    107 static void SetSpacesAndNul(char *s, unsigned num)
    108 {
    109  for (unsigned i = 0; i < num; i++)
    110    s[i] = ' ';
    111  s[num] = 0;
    112 }
    113 
    114 static const unsigned kSizeField_Len = 13;
    115 static const unsigned kNameField_Len = 12;
    116 
    117 static const unsigned kHashColumnWidth_Min = 4 * 2;
    118 
    119 static unsigned GetColumnWidth(unsigned digestSize)
    120 {
    121  unsigned width = digestSize * 2;
    122  return width < kHashColumnWidth_Min ? kHashColumnWidth_Min: width;
    123 }
    124 
    125 void CHashCallbackConsole::PrintSeparatorLine(const CObjectVector<CHasherState> &hashers)
    126 {
    127  _s.Empty();
    128  
    129  for (unsigned i = 0; i < hashers.Size(); i++)
    130  {
    131    if (i != 0)
    132      _s.Add_Space();
    133    const CHasherState &h = hashers[i];
    134    AddMinuses(_s, GetColumnWidth(h.DigestSize));
    135  }
    136 
    137  if (PrintSize)
    138  {
    139    _s.Add_Space();
    140    AddMinuses(_s, kSizeField_Len);
    141  }
    142 
    143  if (PrintName)
    144  {
    145    AddSpacesBeforeName();
    146    AddMinuses(_s, kNameField_Len);
    147  }
    148  
    149  *_so << _s << endl;
    150 }
    151 
    152 HRESULT CHashCallbackConsole::BeforeFirstFile(const CHashBundle &hb)
    153 {
    154  if (PrintHeaders && _so)
    155  {
    156    _s.Empty();
    157    ClosePercents_for_so();
    158    
    159    FOR_VECTOR (i, hb.Hashers)
    160    {
    161      if (i != 0)
    162        _s.Add_Space();
    163      const CHasherState &h = hb.Hashers[i];
    164      _s += h.Name;
    165      AddSpaces_if_Positive(_s, (int)GetColumnWidth(h.DigestSize) - (int)h.Name.Len());
    166    }
    167    
    168    if (PrintSize)
    169    {
    170      _s.Add_Space();
    171      const AString s2 ("Size");
    172      AddSpaces_if_Positive(_s, (int)kSizeField_Len - (int)s2.Len());
    173      _s += s2;
    174    }
    175    
    176    if (PrintName)
    177    {
    178      AddSpacesBeforeName();
    179      _s += "Name";
    180    }
    181    
    182    *_so << _s << endl;
    183    PrintSeparatorLine(hb.Hashers);
    184  }
    185  
    186  return CheckBreak2();
    187 }
    188 
    189 HRESULT CHashCallbackConsole::OpenFileError(const FString &path, DWORD systemError)
    190 {
    191  return OpenFileError_Base(path, systemError);
    192 }
    193 
    194 HRESULT CHashCallbackConsole::GetStream(const wchar_t *name, bool /* isFolder */)
    195 {
    196  _fileName = name;
    197 
    198  if (NeedPercents())
    199  {
    200    if (PrintNameInPercents)
    201    {
    202      _percent.FileName.Empty();
    203      if (name)
    204        _percent.FileName = name;
    205    }
    206   _percent.Print();
    207  }
    208  return CheckBreak2();
    209 }
    210 
    211 void CHashCallbackConsole::PrintResultLine(UInt64 fileSize,
    212    const CObjectVector<CHasherState> &hashers, unsigned digestIndex, bool showHash)
    213 {
    214  ClosePercents_for_so();
    215 
    216  _s.Empty();
    217 
    218  FOR_VECTOR (i, hashers)
    219  {
    220    const CHasherState &h = hashers[i];
    221    char s[k_HashCalc_DigestSize_Max * 2 + 64];
    222    s[0] = 0;
    223    if (showHash)
    224      AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize);
    225    SetSpacesAndNul(s + strlen(s), (int)GetColumnWidth(h.DigestSize) - (int)strlen(s));
    226    if (i != 0)
    227      _s.Add_Space();
    228    _s += s;
    229  }
    230  
    231  if (PrintSize)
    232  {
    233    _s.Add_Space();
    234 
    235    char s[kSizeField_Len + 32];
    236    char *p = s;
    237    
    238    if (showHash)
    239    {
    240      p = s + kSizeField_Len;
    241      ConvertUInt64ToString(fileSize, p);
    242      int numSpaces = kSizeField_Len - (int)strlen(p);
    243      if (numSpaces > 0)
    244      {
    245        p -= (unsigned)numSpaces;
    246        for (unsigned i = 0; i < (unsigned)numSpaces; i++)
    247          p[i] = ' ';
    248      }
    249    }
    250    else
    251      SetSpacesAndNul(s, kSizeField_Len);
    252    
    253    _s += p;
    254  }
    255 
    256  if (PrintName)
    257    AddSpacesBeforeName();
    258  
    259  *_so << _s;
    260 }
    261 
    262 HRESULT CHashCallbackConsole::SetOperationResult(UInt64 fileSize, const CHashBundle &hb, bool showHash)
    263 {
    264  if (_so)
    265  {
    266    PrintResultLine(fileSize, hb.Hashers, k_HashCalc_Index_Current, showHash);
    267    if (PrintName)
    268    {
    269      if (_fileName.IsEmpty())
    270        *_so << kEmptyFileAlias;
    271      else
    272        _so->NormalizePrint_UString(_fileName);
    273    }
    274    *_so << endl;
    275  }
    276  
    277  if (NeedPercents())
    278  {
    279    _percent.Files++;
    280    _percent.Print();
    281  }
    282 
    283  return CheckBreak2();
    284 }
    285 
    286 static const char * const k_DigestTitles[] =
    287 {
    288    " : "
    289  , " for data:              "
    290  , " for data and names:    "
    291  , " for streams and names: "
    292 };
    293 
    294 static void PrintSum(CStdOutStream &so, const CHasherState &h, unsigned digestIndex)
    295 {
    296  so << h.Name;
    297  
    298  {
    299    AString temp;
    300    AddSpaces_if_Positive(temp, 6 - (int)h.Name.Len());
    301    so << temp;
    302  }
    303 
    304  so << k_DigestTitles[digestIndex];
    305 
    306  char s[k_HashCalc_DigestSize_Max * 2 + 64];
    307  s[0] = 0;
    308  AddHashHexToString(s, h.Digests[digestIndex], h.DigestSize);
    309  so << s << endl;
    310 }
    311 
    312 void PrintHashStat(CStdOutStream &so, const CHashBundle &hb)
    313 {
    314  FOR_VECTOR (i, hb.Hashers)
    315  {
    316    const CHasherState &h = hb.Hashers[i];
    317    PrintSum(so, h, k_HashCalc_Index_DataSum);
    318    if (hb.NumFiles != 1 || hb.NumDirs != 0)
    319      PrintSum(so, h, k_HashCalc_Index_NamesSum);
    320    if (hb.NumAltStreams != 0)
    321      PrintSum(so, h, k_HashCalc_Index_StreamsSum);
    322    so << endl;
    323  }
    324 }
    325 
    326 void CHashCallbackConsole::PrintProperty(const char *name, UInt64 value)
    327 {
    328  char s[32];
    329  s[0] = ':';
    330  s[1] = ' ';
    331  ConvertUInt64ToString(value, s + 2);
    332  *_so << name << s << endl;
    333 }
    334 
    335 HRESULT CHashCallbackConsole::AfterLastFile(const CHashBundle &hb)
    336 {
    337  ClosePercents2();
    338  
    339  if (PrintHeaders && _so)
    340  {
    341    PrintSeparatorLine(hb.Hashers);
    342    
    343    PrintResultLine(hb.FilesSize, hb.Hashers, k_HashCalc_Index_DataSum, true);
    344    
    345    *_so << endl << endl;
    346    
    347    if (hb.NumFiles != 1 || hb.NumDirs != 0)
    348    {
    349      if (hb.NumDirs != 0)
    350        PrintProperty("Folders", hb.NumDirs);
    351      PrintProperty("Files", hb.NumFiles);
    352    }
    353    
    354    PrintProperty("Size", hb.FilesSize);
    355    
    356    if (hb.NumAltStreams != 0)
    357    {
    358      PrintProperty("Alternate streams", hb.NumAltStreams);
    359      PrintProperty("Alternate streams size", hb.AltStreamsSize);
    360    }
    361    
    362    *_so << endl;
    363    PrintHashStat(*_so, hb);
    364  }
    365 
    366  return S_OK;
    367 }