/**
 * 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;
	}
}
Exemple #2
0
/** 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;
    }
}