streamline the buffer readers.

This commit is contained in:
Christoph Oelckers 2023-12-13 18:17:12 +01:00
parent 235d36fe69
commit 78a71bb662
5 changed files with 30 additions and 46 deletions

View file

@ -84,6 +84,13 @@ class FileData
public:
using value_type = uint8_t;
FileData() { memory = nullptr; length = 0; owned = true; }
FileData(const void* memory_, size_t len)
{
length = len;
memory = allocate(len);
if (memory_) memcpy(memory, memory_, len);
}
uint8_t* writable() const { return owned? (uint8_t*)memory : nullptr; }
const void* data() const { return memory; }
size_t size() const { return length; }
const char* string() const { return (const char*)memory; }
@ -233,8 +240,6 @@ public:
bool OpenFile(const char *filename, Size start = 0, Size length = -1, bool buffered = false);
bool OpenFilePart(FileReader &parent, Size start, Size length);
bool OpenMemory(const void *mem, Size length); // read directly from the buffer
bool OpenMemoryArray(const void *mem, Size length); // read from a copy of the buffer.
bool OpenMemoryArray(std::vector<uint8_t>& data); // take the given array
bool OpenMemoryArray(FileData& data); // take the given array
Size Tell() const

View file

@ -327,7 +327,7 @@ int BufferingReader::FillBuffer(ptrdiff_t newpos)
{
if (newpos > Length) newpos = Length;
if (newpos <= bufferpos) return 0;
auto read = baseReader->Read(&buf[bufferpos], newpos - bufferpos);
auto read = baseReader->Read(&buf.writable()[bufferpos], newpos - bufferpos);
bufferpos += read;
if (bufferpos == Length)
{
@ -392,17 +392,10 @@ bool FileReader::OpenMemory(const void *mem, FileReader::Size length)
return true;
}
bool FileReader::OpenMemoryArray(const void *mem, FileReader::Size length)
{
Close();
mReader = new MemoryArrayReader<std::vector<uint8_t>>((const char *)mem, length);
return true;
}
bool FileReader::OpenMemoryArray(FileData& data)
{
Close();
if (data.size() > 0) mReader = new MemoryArrayReader<FileData>(data);
if (data.size() > 0) mReader = new MemoryArrayReader(data);
return true;
}

View file

@ -929,48 +929,43 @@ bool OpenDecompressor(FileReader& self, FileReader &parent, FileReader::Size len
case METHOD_IMPLODE_4:
case METHOD_IMPLODE_6:
{
auto idec = new MemoryArrayReader<FileData>;
fr = idec;
auto& buffer = idec->GetArray();
auto bufr = (uint8_t*)buffer.allocate(length);
FileData buffer(nullptr, length);
FZipExploder exploder;
if (exploder.Explode(bufr, length, *p, p->GetLength(), method - METHOD_IMPLODE_MIN) == -1)
if (exploder.Explode(buffer.writable(), length, *p, p->GetLength(), method - METHOD_IMPLODE_MIN) == -1)
{
if (exceptions)
{
throw FileSystemException("DecompressImplode failed");
}
delete idec;
return false;
}
fr = new MemoryArrayReader(buffer);
flags &= ~DCF_SEEKABLE;
break;
}
case METHOD_SHRINK:
{
auto idec = new MemoryArrayReader<FileData>;
fr = idec;
auto& buffer = idec->GetArray();
auto bufr = (uint8_t*)buffer.allocate(length);
ShrinkLoop(bufr, length, *p, p->GetLength()); // this never fails.
FileData buffer(nullptr, length);
ShrinkLoop(buffer.writable(), length, *p, p->GetLength()); // this never fails.
fr = new MemoryArrayReader(buffer);
flags &= ~DCF_SEEKABLE;
break;
}
// While this could be msde a buffering reader it isn't worth the effort because only stock RFFs are encrypted and they do not contain large files.
// While this could be made a buffering reader it isn't worth the effort because only stock RFFs are encrypted and they do not contain large files.
case METHOD_RFFCRYPT:
{
auto idec = new MemoryArrayReader<FileData>;
fr = idec;
auto& buffer = idec->GetArray();
auto bufr = (uint8_t*)buffer.allocate(length);
p->Read(bufr, length);
FileData buffer = p->Read(length);
auto bufr = buffer.writable();
FileReader::Size cryptlen = std::min<FileReader::Size>(length, 256);
for (FileReader::Size i = 0; i < cryptlen; ++i)
{
bufr[i] ^= i >> 1;
}
fr = new MemoryArrayReader(buffer);
flags &= ~DCF_SEEKABLE;
break;
}

View file

@ -31,7 +31,7 @@ public:
class BufferingReader : public MemoryReader
{
std::vector<uint8_t> buf;
FileData buf;
std::unique_ptr<FileReaderInterface> baseReader;
ptrdiff_t bufferpos = 0;
@ -41,7 +41,7 @@ public:
: baseReader(base)
{
Length = base->Length;
buf.resize(Length);
buf.allocate(Length);
bufptr = (const char*)buf.data();
}
@ -58,10 +58,9 @@ public:
//
//==========================================================================
template<class T>
class MemoryArrayReader : public MemoryReader
{
T buf;
FileData buf;
public:
MemoryArrayReader()
@ -70,24 +69,18 @@ public:
Length = 0;
}
MemoryArrayReader(const char* buffer, ptrdiff_t length)
MemoryArrayReader(size_t len)
{
if (length > 0)
{
buf.resize(length);
memcpy(&buf[0], buffer, length);
}
buf.allocate(len);
UpdateBuffer();
}
MemoryArrayReader(T& buffer)
MemoryArrayReader(FileData& buffer)
{
buf = std::move(buffer);
UpdateBuffer();
}
T& GetArray() { return buf; }
void UpdateBuffer()
{
bufptr = (const char*)buf.data();
@ -96,7 +89,4 @@ public:
}
};
bool OpenMemoryArray(std::vector<uint8_t>& data); // take the given array
}

View file

@ -301,7 +301,8 @@ bool FileSystem::InitMultipleFiles (std::vector<std::string>& filenames, LumpFil
int FileSystem::AddFromBuffer(const char* name, char* data, int size, int id, int flags)
{
FileReader fr;
fr.OpenMemoryArray((uint8_t*)data, size);
FileData blob(data, size);
fr.OpenMemoryArray(blob);
// wrap this into a single lump resource file (should be done a little better later.)
auto rf = new FResourceFile(name, fr, stringpool);