Add IStorage::CalculateHashes

To conveniently calculate the SHA256 and CRC32 hashes of a file without reading the entire file into memory at once.
This commit is contained in:
Robert Müller 2023-09-30 16:57:39 +02:00
parent b60b14bf61
commit 7f694e8fc9
2 changed files with 37 additions and 0 deletions

View file

@ -1,5 +1,6 @@
/* (c) Magnus Auvinen. See licence.txt in the root of the distribution for more information. */
/* If you are missing that file, acquire a complete release at teeworlds.com. */
#include <base/hash_ctxt.h>
#include <base/math.h>
#include <base/system.h>
@ -13,6 +14,8 @@
#include <cstdlib>
#endif
#include <zlib.h>
class CStorage : public IStorage
{
public:
@ -538,6 +541,37 @@ public:
return pResult;
}
bool CalculateHashes(const char *pFilename, int Type, SHA256_DIGEST *pSha256, unsigned *pCrc) override
{
dbg_assert(pSha256 != nullptr || pCrc != nullptr, "At least one output argument required");
IOHANDLE File = OpenFile(pFilename, IOFLAG_READ, Type);
if(!File)
return false;
SHA256_CTX Sha256Ctxt;
if(pSha256 != nullptr)
sha256_init(&Sha256Ctxt);
if(pCrc != nullptr)
*pCrc = 0;
unsigned char aBuffer[64 * 1024];
while(true)
{
unsigned Bytes = io_read(File, aBuffer, sizeof(aBuffer));
if(Bytes == 0)
break;
if(pSha256 != nullptr)
sha256_update(&Sha256Ctxt, aBuffer, Bytes);
if(pCrc != nullptr)
*pCrc = crc32(*pCrc, aBuffer, Bytes);
}
if(pSha256 != nullptr)
*pSha256 = sha256_finish(&Sha256Ctxt);
io_close(File);
return true;
}
struct CFindCBData
{
CStorage *m_pStorage;

View file

@ -3,6 +3,8 @@
#ifndef ENGINE_STORAGE_H
#define ENGINE_STORAGE_H
#include <base/hash.h>
#include "kernel.h"
#include <set>
@ -51,6 +53,7 @@ public:
virtual bool FolderExists(const char *pFilename, int Type) = 0;
virtual bool ReadFile(const char *pFilename, int Type, void **ppResult, unsigned *pResultLen) = 0;
virtual char *ReadFileStr(const char *pFilename, int Type) = 0;
virtual bool CalculateHashes(const char *pFilename, int Type, SHA256_DIGEST *pSha256, unsigned *pCrc = nullptr) = 0;
virtual bool FindFile(const char *pFilename, const char *pPath, int Type, char *pBuffer, int BufferSize) = 0;
virtual size_t FindFiles(const char *pFilename, const char *pPath, int Type, std::set<std::string> *pEntries) = 0;
virtual bool RemoveFile(const char *pFilename, int Type) = 0;