cprover
mz_zip_archive.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: mz_zip library wrapper
4 
5 Author: Diffblue Ltd
6 
7 \*******************************************************************/
8 
9 #include "mz_zip_archive.h"
10 #include <stdexcept>
11 #include <string>
12 #include <vector>
13 #include <algorithm>
14 #define _LARGEFILE64_SOURCE 1
15 #include <miniz/miniz.h>
16 
17 // Original struct is an anonymous struct with a typedef, This is
18 // required to remove internals from the header file
20 {
21 public:
22  explicit mz_zip_archive_statet(const std::string &filename):
23  mz_zip_archive({ })
24  {
25  if(MZ_TRUE!=mz_zip_reader_init_file(this, filename.data(), 0))
26  throw std::runtime_error("MZT: Could not load a file: "+filename);
27  }
28 
29  mz_zip_archive_statet(const void *data, size_t size):
30  mz_zip_archive({ })
31  {
32  if(MZ_TRUE!=mz_zip_reader_init_mem(this, data, size, 0))
33  throw std::runtime_error("MZT: Could not load data from memory");
34  }
35 
41  {
42  mz_zip_reader_end(this);
43  }
44 };
45 
46 static_assert(sizeof(mz_uint)<=sizeof(size_t),
47  "size_t cannot store mz_zip file ids, choose a larger type");
48 
49 mz_zip_archivet::mz_zip_archivet(const std::string &filename):
50  m_state(new mz_zip_archive_statet(filename)) { }
51 
52 mz_zip_archivet::mz_zip_archivet(const void *data, size_t size):
53  m_state(new mz_zip_archive_statet(data, size)) { }
54 
55 // VS Compatibility
57  m_state(std::move(other.m_state)) { }
58 
59 // Has to be defined here because header is incomplete
61 
62 // VS Compatibility
64 {
65  m_state=std::move(other.m_state);
66  return *this;
67 }
68 
70 {
72 }
73 
74 std::string mz_zip_archivet::get_filename(const size_t index)
75 {
76  const auto id=static_cast<mz_uint>(index);
77  std::vector<char> buffer;
78  buffer.resize(mz_zip_reader_get_filename(m_state.get(), id, nullptr, 0));
79  mz_zip_reader_get_filename(m_state.get(), id, buffer.data(), buffer.size());
80  // Buffer may contain junk returned after \0
81  const auto null_char_it=std::find(buffer.cbegin(), buffer.cend(), '\0');
82  return { buffer.cbegin(), null_char_it };
83 }
84 
85 std::string mz_zip_archivet::extract(const size_t index)
86 {
87  const auto id=static_cast<mz_uint>(index);
88  mz_zip_archive_file_stat file_stat={ };
89  const mz_bool stat_ok=mz_zip_reader_file_stat(m_state.get(), id, &file_stat);
90  if(stat_ok==MZ_TRUE)
91  {
92  std::vector<char> buffer(file_stat.m_uncomp_size);
94  m_state.get(), id, buffer.data(), buffer.size(), 0);
95  if(read_ok==MZ_TRUE)
96  return { buffer.cbegin(), buffer.cend() };
97  }
98  throw std::runtime_error("Could not extract the file");
99 }
100 
mz_zip_archivet(const std::string &filename)
Open a zip archive.
bool mz_bool
Definition: miniz.h:541
mz_bool mz_zip_reader_file_stat(mz_zip_archive *pZip, mz_uint file_index, mz_zip_archive_file_stat *pStat)
Definition: miniz.cpp:7179
mz_uint mz_zip_reader_get_num_files(mz_zip_archive *pZip)
Definition: miniz.cpp:7124
mz_bool mz_zip_reader_init_file(mz_zip_archive *pZip, const char *pFilename, mz_uint32 flags)
Definition: miniz.cpp:3813
STL namespace.
std::string extract(size_t index)
Get contents of nth file in the archive.
Thin object-oriented wrapper around the MZ Zip library Zip file reader and extractor.
std::unique_ptr< mz_zip_archive_statet > m_state
mz_zip_archive_statet & operator=(const mz_zip_archive_statet &)=delete
unsigned int mz_uint
Definition: miniz.h:538
mz_bool mz_zip_reader_extract_to_mem(mz_zip_archive *pZip, mz_uint file_index, void *pBuf, size_t buf_size, mz_uint flags)
Definition: miniz.cpp:4408
mz_bool mz_zip_reader_end(mz_zip_archive *pZip)
Definition: miniz.cpp:3734
mz_uint64 m_uncomp_size
Definition: miniz.h:996
mz_bool mz_zip_reader_init_mem(mz_zip_archive *pZip, const void *pMem, size_t size, mz_uint flags)
Definition: miniz.cpp:3766
#define MZ_TRUE
Definition: miniz.h:544
mz_uint mz_zip_reader_get_filename(mz_zip_archive *pZip, mz_uint file_index, char *pFilename, mz_uint filename_buf_size)
Definition: miniz.cpp:7158
mz_zip_archive_statet(const std::string &filename)
std::string get_filename(size_t index)
Get file name of nth file in the archive.
mz_zip_archive_statet(const void *data, size_t size)
size_t get_num_files()
Get number of files in the archive.
mz_zip_archivet & operator=(const mz_zip_archivet &)=delete
Definition: kdev_t.h:24