ns/releases/3.04/source/util/Checksum.cpp
tankefugl 19b458f8bc Branched for 3.0.4 balance
git-svn-id: https://unknownworlds.svn.cloudforge.com/ns1@141 67975925-1194-0748-b3d5-c16f83f1a3a1
2005-05-29 10:59:29 +00:00

337 lines
9.4 KiB
C++

//======== (C) Copyright 2002 Charles G. Cleveland All rights reserved. =========
//
// The copyright to the contents herein is the property of Charles G. Cleveland.
// The contents may be used and/or copied only with the written permission of
// Charles G. Cleveland, or in accordance with the terms and conditions stipulated in
// the agreement/contract under which the contents have been supplied.
//
// Purpose:
//
// $Workfile: Checksum.cpp $
// $Date: 2002/05/23 04:03:11 $
//
//-------------------------------------------------------------------------------
// $Log: Checksum.cpp,v $
// Revision 1.1 2002/05/23 04:03:11 Flayra
// - Post-crash checkin. Restored @Backup from around 4/16. Contains changes for last four weeks of development.
//
//===============================================================================
#include "util/Checksum.h"
#include "util/STLUtil.h"
const string kFormattedStringDelimiter = " -> ";
const string kFormattedStringEOL = "\n";
ChecksumEntry::ChecksumEntry(void)
{
this->mChecksum = 0;
}
uint32 ChecksumEntry::GetChecksum() const
{
return this->mChecksum;
}
const string& ChecksumEntry::GetDescription() const
{
return this->mChecksumDescription;
}
string ChecksumEntry::GetFormattedString() const
{
string theFormattedString = this->mChecksumDescription;
theFormattedString += kFormattedStringDelimiter;
theFormattedString += MakeStringFromInt(this->mChecksum);
theFormattedString += kFormattedStringEOL;
return theFormattedString;
}
void ChecksumEntry::SetChecksum(uint32 inChecksum)
{
this->mChecksum = inChecksum;
}
void ChecksumEntry::SetDescription(const string& inDescription)
{
this->mChecksumDescription = inDescription;
}
bool ChecksumEntry::SetFromFormattedString(const string& inFormattedString)
{
bool theSuccess = false;
int theEOL = inFormattedString.find(kFormattedStringEOL);
if(theEOL != std::string::npos)
{
string theNonDelimitedString = inFormattedString.substr(0, theEOL);
// Parse out delimiter
int theSplit = theNonDelimitedString.find(kFormattedStringDelimiter);
if(theSplit != std::string::npos)
{
// Everything before it is description
string theDescription = theNonDelimitedString.substr(0, theSplit-1);
// Everything after is checksum
string theChecksumString = theNonDelimitedString.substr(theSplit + kFormattedStringDelimiter.size());
this->mChecksumDescription = theDescription;
this->mChecksum = MakeIntFromString(theChecksumString);
theSuccess = true;
}
}
return theSuccess;
}
bool ChecksumEntry::Compare(const ChecksumEntry& inChecksumEntry, string& theErrorString) const
{
bool theReturnCode = false;
if(inChecksumEntry.mChecksumDescription != this->mChecksumDescription)
{
sprintf(theErrorString, "ChecksumEntry::Compare failed, the tags don't match: %s != %s\n", inChecksumEntry.mChecksumDescription.c_str(), this->mChecksumDescription.c_str());
}
else if(inChecksumEntry.mChecksum != this->mChecksum)
{
sprintf(theErrorString, "ChecksumEntry::Compare failed, checksums don't match: %u != %u (%s)\n", inChecksumEntry.mChecksum, this->mChecksum, inChecksumEntry.mChecksumDescription.c_str());
}
else
{
theReturnCode = true;
}
return theReturnCode;
}
Checksum::Checksum(bool inVerboseMode)
{
this->mIsVerboseMode = inVerboseMode;
}
void Checksum::AddChecksum(const string& inInfoString, uint32 inChecksum)
{
ChecksumEntry theChecksumEntry;
// Add a new tagged checksum or just add the new checksum number to our total depending on verbose mode
if(this->mIsVerboseMode)
{
// Initialize new checksum entry
theChecksumEntry.SetDescription(inInfoString);
theChecksumEntry.SetChecksum(inChecksum);
// Add our new entry
this->mChecksumList.push_back(theChecksumEntry);
}
else
{
this->AddChecksum(inChecksum);
}
}
void Checksum::AddFloatChecksum(const string& inInfoString, float inChecksum)
{
// Convert float to uint32
uint32 theUint32Checksum = (uint32)(inChecksum*1000.0f);
this->AddChecksum(inInfoString, theUint32Checksum);
}
void Checksum::AddChecksum(uint32 inChecksum)
{
ChecksumList::iterator theIterator;
ChecksumEntry theNewEntry;
// Make sure there is at least one checksum already, add one otherwise
if(this->mChecksumList.size() == 0)
{
// Add new checksum with no description
this->mChecksumList.push_back(theNewEntry);
}
// Get iterator to last checksum
theIterator = this->mChecksumList.end() - 1;
// Add inChecksum to the existing value
theIterator->SetChecksum(theIterator->GetChecksum() + inChecksum);
}
bool Checksum::Compare(const Checksum& inChecksum, StringList& outErrors) const
{
ChecksumList::const_iterator theIncomingIter = inChecksum.mChecksumList.begin();
ChecksumList::const_iterator theSourceIter = this->mChecksumList.begin();
string theErrorString;
int32 theChecksumCount = 0;
bool theReturnCode = true;
// Only try compare if both checksums are in the same mode
if(this->GetIsVerboseMode() == inChecksum.GetIsVerboseMode())
{
if(this->mChecksumList.size() == inChecksum.mChecksumList.size())
{
for( ; theSourceIter != this->mChecksumList.end(); theSourceIter++, theIncomingIter++)
{
if(!(theSourceIter->Compare(*theIncomingIter, theErrorString)))
{
outErrors.push_back(theErrorString);
theReturnCode = false;
}
theChecksumCount++;
}
}
else
{
sprintf(theErrorString, "Checksum::Compare(): Checksum sizes don't match. Source size is %d and other size is %d.\n", this->mChecksumList.size(), inChecksum.mChecksumList.size());
outErrors.push_back(theErrorString);
theReturnCode = false;
}
}
else
{
sprintf(theErrorString, "Checksum::Compare(): One checksum is in verbose mode, the other isn't.\n");
outErrors.push_back(theErrorString);
theReturnCode = false;
}
return theReturnCode;
}
bool Checksum::GetIsVerboseMode(void) const
{
return this->mIsVerboseMode;
}
uint32 Checksum::GetTotalChecksum(void) const
{
ChecksumList::const_iterator theSourceIter = this->mChecksumList.begin();
uint32 theTotalChecksum = 0;
for( ; theSourceIter != this->mChecksumList.end(); theSourceIter++)
{
theTotalChecksum += theSourceIter->mChecksum;
}
return theTotalChecksum;
}
void Checksum::PrintReport(void) const
{
// ChecksumList::const_iterator theSourceIter = this->mChecksumList.begin();
//
// ::ESReport("Checksum::PrintReport(): begin.\n");
// for( ; theSourceIter != this->mChecksumList.end(); theSourceIter++)
// {
// ::ESReport(" %s, %u\r\n", (const char*)(theSourceIter->mChecksumDescription), theSourceIter->mChecksum);
// }
// ::ESReport("Checksum::PrintReport(): complete.\n");
}
bool Checksum::ReadFromFile(const char* inFilename)
{
bool theSuccess = false;
this->mChecksumList.clear();
ifstream theStream(inFilename);
if(theStream.is_open())
{
string theStartString;
theStream >> theStartString;
// Read in num checksums
int theNumChecksums = 0;
theStream >> theNumChecksums;
// Read in pairs of checksums
for(int i = 0; i < theNumChecksums; i++)
{
string theFormattedString;
theStream >> theFormattedString;
ChecksumEntry theNewEntry;
theNewEntry.SetFromFormattedString(theFormattedString);
this->mChecksumList.push_back(theNewEntry);
}
string theEndString;
theStream >> theEndString;
theStream.close();
}
return theSuccess;
}
bool Checksum::SaveToFile(const char* inFilename) const
{
bool theSuccess = false;
// open file for writing
ofstream theStream(inFilename);
if(theStream.is_open())
{
string theStartString("CHECKSUM-REPORT:\r\n");
theStream << theStartString;
int theNumChecksums = this->mChecksumList.size();
theStream << theNumChecksums;
// dump everything to it
for(ChecksumList::const_iterator theIter = this->mChecksumList.begin(); theIter != this->mChecksumList.end(); theIter++)
{
string theFormattedDescription = theIter->GetFormattedString();
theStream << theFormattedDescription;
}
string theEndString("END.\r\n");
theStream << theEndString;
theStream.close();
theSuccess = true;
}
// FILE* theFile = fopen(inFilename, "wt");
// if(theFile)
// {
// string theStartString("Checksum report:\r\n");
// fwrite(theStartString.c_str(), theStartString.length(), 1, theFile);
//
// // dump everything to it
// for(ChecksumList::const_iterator theIter = this->mChecksumList.begin(); theIter != this->mChecksumList.end(); theIter++)
// {
// const string& theFormattedString = theIter->GetFormattedString();
// fwrite(theFormattedString.c_str(), theFormattedString.length(), 1, theFile);
// fwrite("\r\n", 2, 1, theFile);
// }
//
// string theEndString("Checksum report complete.\r\n");
// fwrite(theEndString.c_str(), theEndString.length(), 1, theFile);
//
// // close it
// int theCloseRC = fclose(theFile);
// if(theCloseRC == 0)
// {
// theSuccess = true;
// }
// }
// ChecksumList::const_iterator theSourceIter = this->mChecksumList.begin();
//
// ::ESReport("Checksum::PrintReport(): begin.\n");
// for( ; theSourceIter != this->mChecksumList.end(); theSourceIter++)
// {
// ::ESReport(" %s, %u\r\n", (const char*)(theSourceIter->mChecksumDescription), theSourceIter->mChecksum);
// }
// ::ESReport("Checksum::PrintReport(): complete.\n");
return theSuccess;
}