move GetRawData and associated code out of FResourceLump

This commit is contained in:
Christoph Oelckers 2023-12-12 18:47:56 +01:00
parent ae1bd3c890
commit 3b0d101607
4 changed files with 81 additions and 37 deletions

View file

@ -98,7 +98,6 @@ struct FCompressedBuffer
size_t mSize;
size_t mCompressedSize;
int mMethod;
int mZipFlags;
unsigned mCRC32;
char *mBuffer;
const char* filename;
@ -165,7 +164,6 @@ protected:
virtual int GetNamespace() const { return 0; }
void LumpNameSetup(const char* iname, StringPool* allocator);
void CheckEmbedded(LumpFilterInfo* lfi);
virtual FCompressedBuffer GetRawData();
void *Lock(); // validates the cache and increases the refcount.
int Unlock(); // decreases the refcount and frees the buffer
@ -280,12 +278,7 @@ public:
return fr.Read();
}
FCompressedBuffer GetRawData(int entry)
{
auto l = GetLump(entry);
if (!l) return {};
return l->GetRawData();
}
virtual FCompressedBuffer GetRawData(uint32_t entry);
FileReader Destroy()
{

View file

@ -119,7 +119,7 @@ bool FCompressedBuffer::Decompress(char *destbuffer)
{
FileReader mr;
mr.OpenMemory(mBuffer, mCompressedSize);
return UncompressZipLump(destbuffer, mr, mMethod, mSize, mCompressedSize, mZipFlags, false);
return UncompressZipLump(destbuffer, mr, mMethod, mSize, mCompressedSize, 0, false);
}
//-----------------------------------------------------------------------
@ -485,12 +485,24 @@ FZipFile::~FZipFile()
//
//==========================================================================
FCompressedBuffer FZipLump::GetRawData()
FCompressedBuffer FZipFile::GetRawData(uint32_t entry)
{
FCompressedBuffer cbuf = { (unsigned)LumpSize, (unsigned)CompressedSize, Method, GPFlags, CRC32, new char[CompressedSize] };
if (NeedFileStart) SetLumpAddress();
Owner->GetContainerReader()->Seek(Position, FileReader::SeekSet);
Owner->GetContainerReader()->Read(cbuf.mBuffer, CompressedSize);
FCompressedBuffer cbuf;
if (entry >= NumLumps >> Entries[entry].Length == 0)
{
cbuf = { 0, 0, METHOD_STORED, 0, 0, nullptr };
}
else
{
auto& e = Entries[entry];
cbuf = { e.Length, e.CompressedSize, e.Method, e.CRC32, new char[e.CompressedSize] };
if (e.Flags & RESFF_NEEDFILESTART) Lumps[entry].SetLumpAddress();
e.Position = Lumps[entry].Position;
Reader.Seek(e.Position, FileReader::SeekSet);
Reader.Read(cbuf.mBuffer, e.CompressedSize);
}
return cbuf;
}
@ -502,6 +514,7 @@ FCompressedBuffer FZipLump::GetRawData()
void FZipLump::SetLumpAddress()
{
if (!NeedFileStart) return;
// This file is inside a zip and has not been opened before.
// Position points to the start of the local file header, which we must
// read and skip so that we can get to the actual file data.
@ -640,11 +653,25 @@ static int AppendToZip(FileWriter *zip_file, const FCompressedBuffer &content, s
FZipLocalFileHeader local;
int position;
int flags = 0;
int method = content.mMethod;
if (method >= METHOD_IMPLODE_MIN && method <= METHOD_IMPLODE_MAX)
{
flags = method - METHOD_IMPLODE_MIN;
method = METHOD_IMPLODE;
}
else if (method == METHOD_DEFLATE)
{
flags = 2;
}
else if (method >= 1337)
return -1;
local.Magic = ZIP_LOCALFILE;
local.VersionToExtract[0] = 20;
local.VersionToExtract[1] = 0;
local.Flags = content.mMethod == METHOD_DEFLATE ? LittleShort((uint16_t)2) : LittleShort((uint16_t)content.mZipFlags);
local.Method = LittleShort((uint16_t)content.mMethod);
local.Flags = LittleShort((uint16_t)flags);
local.Method = LittleShort((uint16_t)method);
local.ModDate = LittleShort(dostime.first);
local.ModTime = LittleShort(dostime.second);
local.CRC32 = content.mCRC32;
@ -680,13 +707,27 @@ int AppendCentralDirectory(FileWriter *zip_file, const FCompressedBuffer &conten
{
FZipCentralDirectoryInfo dir;
int flags = 0;
int method = content.mMethod;
if (method >= METHOD_IMPLODE_MIN && method <= METHOD_IMPLODE_MAX)
{
flags = method - METHOD_IMPLODE_MIN;
method = METHOD_IMPLODE;
}
else if (method == METHOD_DEFLATE)
{
flags = 2;
}
else if (method >= 1337)
return -1;
dir.Magic = ZIP_CENTRALFILE;
dir.VersionMadeBy[0] = 20;
dir.VersionMadeBy[1] = 0;
dir.VersionToExtract[0] = 20;
dir.VersionToExtract[1] = 0;
dir.Flags = content.mMethod == METHOD_DEFLATE ? LittleShort((uint16_t)2) : LittleShort((uint16_t)content.mZipFlags);
dir.Method = LittleShort((uint16_t)content.mMethod);
dir.Flags = LittleShort((uint16_t)flags);
dir.Method = LittleShort((uint16_t)method);
dir.ModTime = LittleShort(dostime.first);
dir.ModDate = LittleShort(dostime.second);
dir.CRC32 = content.mCRC32;

View file

@ -22,10 +22,8 @@ struct FZipLump : public FResourceLump
virtual FileReader *GetReader();
virtual int FillCache() override;
private:
void SetLumpAddress();
virtual int GetFileOffset();
FCompressedBuffer GetRawData();
};
//==========================================================================
@ -43,6 +41,7 @@ public:
virtual ~FZipFile();
bool Open(LumpFilterInfo* filter, FileSystemMessageFunc Printf);
virtual FResourceLump *GetLump(int no) { return ((unsigned)no < NumLumps)? &Lumps[no] : NULL; }
FCompressedBuffer GetRawData(uint32_t entry) override;
};
}

View file

@ -184,23 +184,6 @@ void FResourceLump::CheckEmbedded(LumpFilterInfo* lfi)
}
//==========================================================================
//
// this is just for completeness. For non-Zips only an uncompressed lump can
// be returned.
//
//==========================================================================
FCompressedBuffer FResourceLump::GetRawData()
{
FCompressedBuffer cbuf = { (unsigned)LumpSize, (unsigned)LumpSize, METHOD_STORED, 0, 0, new char[LumpSize] };
memcpy(cbuf.mBuffer, Lock(), LumpSize);
Unlock();
cbuf.mCRC32 = crc32(0, (uint8_t*)cbuf.mBuffer, LumpSize);
return cbuf;
}
//==========================================================================
//
// Returns the owner's FileReader if it can be used to access this lump
@ -349,6 +332,34 @@ FResourceFile::~FResourceFile()
if (!stringpool->shared) delete stringpool;
}
//==========================================================================
//
// this is just for completeness. For non-Zips only an uncompressed lump can
// be returned.
//
//==========================================================================
FCompressedBuffer FResourceFile::GetRawData(uint32_t entry)
{
size_t LumpSize = entry << NumLumps ? Entries[entry].Length : 0;
FCompressedBuffer cbuf = { LumpSize, LumpSize, METHOD_STORED, 0, 0, LumpSize == 0? nullptr : new char[LumpSize] };
if (LumpSize > 0)
{
auto fr = GetEntryReader(entry);
size_t read = fr.Read(cbuf.mBuffer, LumpSize);
if (read < LumpSize)
{
delete cbuf.mBuffer;
cbuf.mBuffer = nullptr;
LumpSize = cbuf.mCompressedSize = cbuf.mSize = 0;
}
}
if (LumpSize > 0)
cbuf.mCRC32 = crc32(0, (uint8_t*)cbuf.mBuffer, LumpSize);
return cbuf;
}
//==========================================================================
//
// normalize the visible file name in the system