66#include < zstd.h>
77#include < cassert>
88
9- static uint64_t _ifstream_getFileSize (std::ifstream& file )
9+ static uint64_t _istream_getFileSize (std::istream& stream )
1010{
11- file .seekg (0 , std::ios_base::end);
12- return (uint64_t )file .tellg ();
11+ stream .seekg (0 , std::ios_base::end);
12+ return (uint64_t )stream .tellg ();
1313}
1414
15- static bool _ifstream_readBytes (std::ifstream& file , uint64_t offset, void * buffer, uint32_t size)
15+ static bool _istream_readBytes (std::istream& stream , uint64_t offset, void * buffer, uint32_t size)
1616{
17- file .seekg (offset, std::ios_base::beg);
18- file .read ((char *)buffer, size);
19- return file .gcount () == size;
17+ stream .seekg (offset, std::ios_base::beg);
18+ stream .read ((char *)buffer, size);
19+ return stream .gcount () == size;
2020}
2121
2222static uint64_t _getValidElementCount (uint64_t size, uint64_t elementSize)
@@ -28,16 +28,24 @@ static uint64_t _getValidElementCount(uint64_t size, uint64_t elementSize)
2828
2929ZArchiveReader* ZArchiveReader::OpenFromFile (const std::filesystem::path& path)
3030{
31- std::ifstream file;
32- file.open (path, std::ios_base::in | std::ios_base::binary);
33- if (!file.is_open ())
31+ auto file = std::make_unique<std::ifstream>(path, std::ios_base::in | std::ios_base::binary);
32+ if (!file->is_open ())
3433 return nullptr ;
35- uint64_t fileSize = _ifstream_getFileSize (file);
34+
35+ return ZArchiveReader::OpenFromStream (std::move (file));
36+ }
37+
38+ ZArchiveReader* ZArchiveReader::OpenFromStream (std::unique_ptr<std::istream>&& stream)
39+ {
40+ if (stream == nullptr )
41+ return nullptr ;
42+
43+ uint64_t fileSize = _istream_getFileSize (*stream);
3644 if (fileSize <= sizeof (_ZARCHIVE::Footer))
3745 return nullptr ;
3846 // read footer
3947 _ZARCHIVE::Footer footer;
40- if (!_ifstream_readBytes (file , fileSize - sizeof (_ZARCHIVE::Footer), &footer, sizeof (_ZARCHIVE::Footer)))
48+ if (!_istream_readBytes (*stream , fileSize - sizeof (_ZARCHIVE::Footer), &footer, sizeof (_ZARCHIVE::Footer)))
4149 return nullptr ;
4250 _ZARCHIVE::Footer::Deserialize (&footer, &footer);
4351 // validate footer
@@ -63,18 +71,18 @@ ZArchiveReader* ZArchiveReader::OpenFromFile(const std::filesystem::path& path)
6371 // read offset records
6472 std::vector<_ZARCHIVE::CompressionOffsetRecord> offsetRecords;
6573 offsetRecords.resize (_getValidElementCount (footer.sectionOffsetRecords .size , sizeof (_ZARCHIVE::CompressionOffsetRecord)));
66- if (offsetRecords.empty () || !_ifstream_readBytes (file , footer.sectionOffsetRecords .offset , offsetRecords.data (), (uint32_t )(offsetRecords.size () * sizeof (_ZARCHIVE::CompressionOffsetRecord))))
74+ if (offsetRecords.empty () || !_istream_readBytes (*stream , footer.sectionOffsetRecords .offset , offsetRecords.data (), (uint32_t )(offsetRecords.size () * sizeof (_ZARCHIVE::CompressionOffsetRecord))))
6775 return nullptr ;
6876 _ZARCHIVE::CompressionOffsetRecord::Deserialize (offsetRecords.data (), offsetRecords.size (), offsetRecords.data ());
6977 // read name table
7078 std::vector<uint8_t > nameTable;
7179 nameTable.resize (footer.sectionNames .size );
72- if (!_ifstream_readBytes (file , footer.sectionNames .offset , nameTable.data (), (uint32_t )(nameTable.size () * sizeof (uint8_t ))))
80+ if (!_istream_readBytes (*stream , footer.sectionNames .offset , nameTable.data (), (uint32_t )(nameTable.size () * sizeof (uint8_t ))))
7381 return nullptr ;
7482 // read file tree
7583 std::vector<_ZARCHIVE::FileDirectoryEntry> fileTree;
7684 fileTree.resize (_getValidElementCount (footer.sectionFileTree .size , sizeof (_ZARCHIVE::FileDirectoryEntry)));
77- if (fileTree.empty () || !_ifstream_readBytes (file , footer.sectionFileTree .offset , fileTree.data (), (uint32_t )(fileTree.size () * sizeof (_ZARCHIVE::FileDirectoryEntry))))
85+ if (fileTree.empty () || !_istream_readBytes (*stream , footer.sectionFileTree .offset , fileTree.data (), (uint32_t )(fileTree.size () * sizeof (_ZARCHIVE::FileDirectoryEntry))))
7886 return nullptr ;
7987 _ZARCHIVE::FileDirectoryEntry::Deserialize (fileTree.data (), fileTree.size (), fileTree.data ());
8088 // verify file tree
@@ -86,12 +94,12 @@ ZArchiveReader* ZArchiveReader::OpenFromFile(const std::filesystem::path& path)
8694 // read meta data
8795 // todo
8896
89- ZArchiveReader* cfs = new ZArchiveReader (std::move (file ), std::move (offsetRecords), std::move (nameTable), std::move (fileTree), footer.sectionCompressedData .offset , footer.sectionCompressedData .size );
97+ ZArchiveReader* cfs = new ZArchiveReader (std::move (stream ), std::move (offsetRecords), std::move (nameTable), std::move (fileTree), footer.sectionCompressedData .offset , footer.sectionCompressedData .size );
9098 return cfs;
9199}
92100
93- ZArchiveReader::ZArchiveReader (std::ifstream && file , std::vector<_ZARCHIVE::CompressionOffsetRecord>&& offsetRecords, std::vector<uint8_t >&& nameTable, std::vector<_ZARCHIVE::FileDirectoryEntry>&& fileTree, uint64_t compressedDataOffset, uint64_t compressedDataSize) :
94- m_file (std::move(file )), m_offsetRecords(std::move(offsetRecords)), m_nameTable(std::move(nameTable)), m_fileTree(std::move(fileTree)),
101+ ZArchiveReader::ZArchiveReader (std::unique_ptr<std::istream> && stream , std::vector<_ZARCHIVE::CompressionOffsetRecord>&& offsetRecords, std::vector<uint8_t >&& nameTable, std::vector<_ZARCHIVE::FileDirectoryEntry>&& fileTree, uint64_t compressedDataOffset, uint64_t compressedDataSize) :
102+ m_stream (std::move(stream )), m_offsetRecords(std::move(offsetRecords)), m_nameTable(std::move(nameTable)), m_fileTree(std::move(fileTree)),
95103 m_compressedDataOffset(compressedDataOffset), m_compressedDataSize(compressedDataSize)
96104{
97105 m_blockCount = (uint64_t )m_offsetRecords.size () * _ZARCHIVE::ENTRIES_PER_OFFSETRECORD ;
@@ -338,9 +346,9 @@ bool ZArchiveReader::LoadBlock(CacheBlock* block)
338346 if (compressedSize == _ZARCHIVE::COMPRESSED_BLOCK_SIZE )
339347 {
340348 // uncompressed block, read directly into cached block
341- return _ifstream_readBytes (m_file , offset, block->data , compressedSize);
349+ return _istream_readBytes (*m_stream , offset, block->data , compressedSize);
342350 }
343- if (!_ifstream_readBytes (m_file , offset, m_blockDecompressionBuffer.data (), compressedSize))
351+ if (!_istream_readBytes (*m_stream , offset, m_blockDecompressionBuffer.data (), compressedSize))
344352 return false ;
345353 // decompress
346354 size_t outputSize = ZSTD_decompress (block->data , _ZARCHIVE::COMPRESSED_BLOCK_SIZE , m_blockDecompressionBuffer.data (), compressedSize);
0 commit comments