@@ -13,11 +13,36 @@ namespace {
1313
1414class ReaderBuffer final : public std::streambuf {
1515public:
16- explicit ReaderBuffer (mz_zip_reader_extract_iter_state *iter);
17- ReaderBuffer (mz_zip_reader_extract_iter_state *iter, std::size_t buffer_size);
18- ~ReaderBuffer () final ;
16+ explicit ReaderBuffer (mz_zip_reader_extract_iter_state *iter)
17+ : ReaderBuffer(iter, 4098 ) {}
18+ ReaderBuffer (mz_zip_reader_extract_iter_state *iter,
19+ std::size_t buffer_size) {
20+ if (iter == nullptr ) {
21+ throw std::invalid_argument (" ReaderBuffer: iter is nullptr" );
22+ }
23+ m_iter = iter;
24+ m_remaining = iter->file_stat .m_uncomp_size ;
25+ m_buffer_size = buffer_size;
26+ m_buffer = new char [m_buffer_size];
27+ }
28+ ~ReaderBuffer () final {
29+ mz_zip_reader_extract_iter_free (m_iter);
30+ delete[] m_buffer;
31+ }
32+
33+ int underflow () final {
34+ if (m_remaining <= 0 ) {
35+ return std::char_traits<char >::eof ();
36+ }
1937
20- int underflow () final ;
38+ const std::uint64_t amount = std::min (m_remaining, m_buffer_size);
39+ const std::uint32_t result =
40+ mz_zip_reader_extract_iter_read (m_iter, m_buffer, amount);
41+ m_remaining -= result;
42+ setg (m_buffer, m_buffer, m_buffer + result);
43+
44+ return std::char_traits<char >::to_int_type (*gptr ());
45+ }
2146
2247private:
2348 mz_zip_reader_extract_iter_state *m_iter{};
@@ -29,52 +54,26 @@ class ReaderBuffer final : public std::streambuf {
2954class FileInZipIstream final : public std::istream {
3055public:
3156 FileInZipIstream (std::shared_ptr<Archive> archive,
32- std::unique_ptr<ReaderBuffer> sbuf);
57+ std::unique_ptr<ReaderBuffer> sbuf)
58+ : std::istream(sbuf.get()), m_archive{std::move (archive)},
59+ m_sbuf{std::move (sbuf)} {
60+ if (m_archive == nullptr ) {
61+ throw std::invalid_argument (" FileInZipIstream: archive is nullptr" );
62+ }
63+ if (m_sbuf == nullptr ) {
64+ throw std::invalid_argument (" FileInZipIstream: sbuf is nullptr" );
65+ }
66+ }
3367 FileInZipIstream (std::shared_ptr<Archive> archive,
34- mz_zip_reader_extract_iter_state *iter);
68+ mz_zip_reader_extract_iter_state *iter)
69+ : FileInZipIstream(std::move(archive),
70+ std::make_unique<ReaderBuffer>(iter)) {}
3571
3672private:
3773 std::shared_ptr<Archive> m_archive;
3874 std::unique_ptr<ReaderBuffer> m_sbuf;
3975};
4076
41- ReaderBuffer::ReaderBuffer (mz_zip_reader_extract_iter_state *iter)
42- : ReaderBuffer(iter, 4098 ) {}
43-
44- ReaderBuffer::ReaderBuffer (mz_zip_reader_extract_iter_state *iter,
45- const std::size_t buffer_size)
46- : m_iter{iter}, m_remaining{iter->file_stat .m_uncomp_size },
47- m_buffer_size{buffer_size}, m_buffer{new char [m_buffer_size]} {}
48-
49- ReaderBuffer::~ReaderBuffer () {
50- mz_zip_reader_extract_iter_free (m_iter);
51- delete[] m_buffer;
52- }
53-
54- int ReaderBuffer::underflow () {
55- if (m_remaining <= 0 ) {
56- return std::char_traits<char >::eof ();
57- }
58-
59- const std::uint64_t amount = std::min (m_remaining, m_buffer_size);
60- const std::uint32_t result =
61- mz_zip_reader_extract_iter_read (m_iter, m_buffer, amount);
62- m_remaining -= result;
63- setg (m_buffer, m_buffer, m_buffer + result);
64-
65- return std::char_traits<char >::to_int_type (*gptr ());
66- }
67-
68- FileInZipIstream::FileInZipIstream (std::shared_ptr<Archive> archive,
69- std::unique_ptr<ReaderBuffer> sbuf)
70- : std::istream(sbuf.get()), m_archive{std::move (archive)},
71- m_sbuf{std::move (sbuf)} {}
72-
73- FileInZipIstream::FileInZipIstream (std::shared_ptr<Archive> archive,
74- mz_zip_reader_extract_iter_state *iter)
75- : FileInZipIstream(std::move(archive),
76- std::make_unique<ReaderBuffer>(iter)) {}
77-
7877} // namespace
7978
8079Archive::Archive (const std::shared_ptr<common::MemoryFile> &file)
@@ -85,6 +84,9 @@ Archive::Archive(const std::shared_ptr<common::DiskFile> &file)
8584
8685Archive::Archive (std::shared_ptr<abstract::File> file)
8786 : m_file{std::move (file)}, m_data{m_file->stream ()} {
87+ if (m_file == nullptr ) {
88+ throw std::invalid_argument (" Archive: file is nullptr" );
89+ }
8890 init_ ();
8991}
9092
@@ -128,7 +130,11 @@ std::shared_ptr<abstract::File> Archive::file() const { return m_file; }
128130
129131FileInZip::FileInZip (std::shared_ptr<Archive> archive,
130132 const std::uint32_t index)
131- : m_archive{std::move (archive)}, m_index{index} {}
133+ : m_archive{std::move (archive)}, m_index{index} {
134+ if (m_archive == nullptr ) {
135+ throw std::invalid_argument (" FileInZip: archive is nullptr" );
136+ }
137+ }
132138
133139FileLocation FileInZip::location () const noexcept {
134140 return m_archive->file ()->location ();
@@ -140,12 +146,23 @@ std::size_t FileInZip::size() const {
140146 return stat.m_uncomp_size ;
141147}
142148
143- std::optional<common::Path> FileInZip::disk_path () const { return {}; }
149+ std::optional<common::Path> FileInZip::disk_path () const {
150+ return std::nullopt ;
151+ }
144152
145153const char *FileInZip::memory_data () const { return nullptr ; }
146154
147155std::unique_ptr<std::istream> FileInZip::stream () const {
156+ if (mz_zip_reader_is_file_encrypted (m_archive->zip (), m_index)) {
157+ return nullptr ;
158+ }
159+ if (!mz_zip_reader_is_file_supported (m_archive->zip (), m_index)) {
160+ return nullptr ;
161+ }
148162 auto iter = mz_zip_reader_extract_iter_new (m_archive->zip (), m_index, 0 );
163+ if (iter == nullptr ) {
164+ return nullptr ;
165+ }
149166 return std::make_unique<FileInZipIstream>(m_archive, iter);
150167}
151168
0 commit comments