/** * Get CRC of the data in the specified archive. * Returns 0 if file could not be opened. */ unsigned int CArchiveScanner::GetCRC(const std::string& arcName) { CRC crc; CArchiveBase* ar; std::list<std::string> files; //! Try to open an archive ar = CArchiveFactory::OpenArchive(arcName); if (!ar) { return 0; // It wasn't an archive } //! Load ignore list. IFileFilter* ignore = CreateIgnoreFilter(ar); for (unsigned fid = 0; fid != ar->NumFiles(); ++fid) { std::string name; int size; ar->FileInfo(fid, name, size); if (ignore->Match(name)) { continue; } StringToLowerInPlace(name); //! case insensitive hash files.push_back(name); } files.sort(); //! Add all files in sorted order for (std::list<std::string>::iterator i = files.begin(); i != files.end(); ++i) { const unsigned int nameCRC = CRC().Update(i->data(), i->size()).GetDigest(); const unsigned fid = ar->FindFile(*i); const unsigned int dataCRC = ar->GetCrc32(fid); crc.Update(nameCRC); crc.Update(dataCRC); } delete ignore; delete ar; unsigned int digest = crc.GetDigest(); //! A value of 0 is used to indicate no crc.. so never return that //! Shouldn't happen all that often if (digest == 0) { return 4711; } else { return digest; } }
/** Get CRC of the data in the specified archive. Returns 0 if file could not be opened. */ unsigned int CArchiveScanner::GetCRC(const string& arcName) { CRC crc; CArchiveBase* ar; std::list<string> files; // Try to open an archive ar = CArchiveFactory::OpenArchive(arcName); if (!ar) { return 0; // It wasn't an archive } // Load ignore list. IFileFilter* ignore = CreateIgnoreFilter(ar); string name; int size; // Sort all file paths for deterministic behaviour for (int cur = 0; (cur = ar->FindFiles(cur, &name, &size)); /* no-op */) { if (ignore->Match(name)) { continue; } const string lower = StringToLower(name); // case insensitive hash files.push_back(lower); } files.sort(); // Add all files in sorted order for (std::list<string>::iterator i = files.begin(); i != files.end(); i++ ) { const unsigned int nameCRC = CRC().Update(i->data(), i->size()).GetDigest(); const unsigned int dataCRC = ar->GetCrc32(*i); crc.Update(nameCRC); crc.Update(dataCRC); } delete ignore; delete ar; unsigned int digest = crc.GetDigest(); // A value of 0 is used to indicate no crc.. so never return that // Shouldn't happen all that often if (digest == 0) { return 4711; } else { return digest; } }