diff --git a/src/common/filesystem/include/fs_files.h b/src/common/filesystem/include/fs_files.h index 0fff342725..115b51704c 100644 --- a/src/common/filesystem/include/fs_files.h +++ b/src/common/filesystem/include/fs_files.h @@ -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& data); // take the given array bool OpenMemoryArray(FileData& data); // take the given array Size Tell() const diff --git a/src/common/filesystem/source/files.cpp b/src/common/filesystem/source/files.cpp index 38ac730d71..55ae2d8c04 100644 --- a/src/common/filesystem/source/files.cpp +++ b/src/common/filesystem/source/files.cpp @@ -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>((const char *)mem, length); - return true; -} - bool FileReader::OpenMemoryArray(FileData& data) { Close(); - if (data.size() > 0) mReader = new MemoryArrayReader(data); + if (data.size() > 0) mReader = new MemoryArrayReader(data); return true; } diff --git a/src/common/filesystem/source/files_decompress.cpp b/src/common/filesystem/source/files_decompress.cpp index 0942b271da..899f59af4a 100644 --- a/src/common/filesystem/source/files_decompress.cpp +++ b/src/common/filesystem/source/files_decompress.cpp @@ -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; - 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; - 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; - 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(length, 256); for (FileReader::Size i = 0; i < cryptlen; ++i) { bufr[i] ^= i >> 1; } + fr = new MemoryArrayReader(buffer); + flags &= ~DCF_SEEKABLE; break; } diff --git a/src/common/filesystem/source/files_internal.h b/src/common/filesystem/source/files_internal.h index f8563eebcb..08f4865994 100644 --- a/src/common/filesystem/source/files_internal.h +++ b/src/common/filesystem/source/files_internal.h @@ -31,7 +31,7 @@ public: class BufferingReader : public MemoryReader { - std::vector buf; + FileData buf; std::unique_ptr 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 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& data); // take the given array - - } diff --git a/src/common/filesystem/source/filesystem.cpp b/src/common/filesystem/source/filesystem.cpp index 1127e6715c..e08c8292a8 100644 --- a/src/common/filesystem/source/filesystem.cpp +++ b/src/common/filesystem/source/filesystem.cpp @@ -301,7 +301,8 @@ bool FileSystem::InitMultipleFiles (std::vector& 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);