comparison modules/zip/ZipArchive.cpp @ 486:7ee8da32da98

Unify all in modules/
author David Demelier <markand@malikania.fr>
date Fri, 13 Nov 2015 09:26:46 +0100
parents
children
comparison
equal deleted inserted replaced
485:898d8b29a4f1 486:7ee8da32da98
1 /*
2 * ZipArchive.cpp -- wrapper around libzip
3 *
4 * Copyright (c) 2013-2015 David Demelier <markand@malikania.fr>
5 *
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
9 *
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18
19 #include <cerrno>
20 #include <cstdlib>
21 #include <cstring>
22 #include <stdexcept>
23
24 #include "ZipArchive.h"
25
26 namespace source {
27
28 /* --------------------------------------------------------
29 * Buffer (zip_source_buffer)
30 * -------------------------------------------------------- */
31
32 Buffer::Buffer(std::string data)
33 : m_data(std::move(data))
34 {
35 }
36
37 struct zip_source *Buffer::source(struct zip *archive) const
38 {
39 auto size = m_data.size();
40 auto data = static_cast<char *>(std::malloc(size));
41
42 if (data == nullptr)
43 throw std::runtime_error(std::strerror(errno));
44
45 std::memcpy(data, m_data.data(), size);
46
47 auto src = zip_source_buffer(archive, data, size, 1);
48
49 if (src == nullptr) {
50 std::free(data);
51 throw std::runtime_error(zip_strerror(archive));
52 }
53
54 return src;
55 }
56
57 /* --------------------------------------------------------
58 * File (zip_source_file)
59 * -------------------------------------------------------- */
60
61 File::File(std::string path, ZipUint64 start, ZipInt64 length)
62 : m_path(std::move(path))
63 , m_start(start)
64 , m_length(length)
65 {
66 }
67
68 struct zip_source *File::source(struct zip *archive) const
69 {
70 auto src = zip_source_file(archive, m_path.c_str(), m_start, m_length);
71
72 if (src == nullptr)
73 throw std::runtime_error(zip_strerror(archive));
74
75 return src;
76 }
77
78 } // !source
79
80 /* --------------------------------------------------------
81 * ZipArchive
82 * ------------------------------------------------------- */
83
84 ZipArchive::ZipArchive(const std::string &path, ZipFlags flags)
85 : m_handle(nullptr, nullptr)
86 {
87 int error;
88 struct zip *archive = zip_open(path.c_str(), flags, &error);
89
90 if (archive == nullptr)
91 {
92 char buf[128]{};
93
94 zip_error_to_str(buf, sizeof (buf), error, errno);
95
96 throw std::runtime_error(buf);
97 }
98
99 m_handle = { archive, zip_close };
100 }
101
102 void ZipArchive::setFileComment(ZipUint64 index, const std::string &text, ZipFlags flags)
103 {
104 auto size = text.size();
105 auto cstr = (size == 0) ? nullptr : text.c_str();
106
107 if (zip_file_set_comment(m_handle.get(), index, cstr, size, flags) < 0)
108 throw std::runtime_error(zip_strerror(m_handle.get()));
109 }
110
111 std::string ZipArchive::getFileComment(ZipUint64 index, ZipFlags flags) const
112 {
113 zip_uint32_t length = 0;
114 auto text = zip_file_get_comment(m_handle.get(), index, &length, flags);
115
116 if (text == nullptr)
117 throw std::runtime_error(zip_strerror(m_handle.get()));
118
119 return { text, length };
120 }
121
122 void ZipArchive::setComment(const std::string &comment)
123 {
124 if (zip_set_archive_comment(m_handle.get(), comment.c_str(), comment.size()) < 0)
125 throw std::runtime_error(zip_strerror(m_handle.get()));
126 }
127
128 std::string ZipArchive::getComment(ZipFlags flags) const
129 {
130 int length = 0;
131 auto text = zip_get_archive_comment(m_handle.get(), &length, flags);
132
133 if (text == nullptr)
134 throw std::runtime_error(zip_strerror(m_handle.get()));
135
136 return { text, static_cast<size_t>(length) };
137 }
138
139 bool ZipArchive::exists(const std::string &name, ZipFlags flags) const noexcept
140 {
141 return zip_name_locate(m_handle.get(), name.c_str(), flags) >= 0;
142 }
143
144 ZipInt64 ZipArchive::find(const std::string &name, ZipFlags flags) const
145 {
146 auto index = zip_name_locate(m_handle.get(), name.c_str(), flags);
147
148 if (index < 0)
149 throw std::runtime_error(zip_strerror(m_handle.get()));
150
151 return index;
152 }
153
154 ZipStat ZipArchive::stat(const std::string &name, ZipFlags flags) const
155 {
156 ZipStat st;
157
158 if (zip_stat(m_handle.get(), name.c_str(), flags, &st) < 0)
159 throw std::runtime_error(zip_strerror(m_handle.get()));
160
161 return st;
162 }
163
164 ZipStat ZipArchive::stat(ZipUint64 index, ZipFlags flags) const
165 {
166 ZipStat st;
167
168 if (zip_stat_index(m_handle.get(), index, flags, &st) < 0)
169 throw std::runtime_error(zip_strerror(m_handle.get()));
170
171 return st;
172 }
173
174 ZipInt64 ZipArchive::add(const ZipSource &source, const std::string &name, ZipFlags flags)
175 {
176 auto src = source.source(m_handle.get());
177 auto ret = zip_file_add(m_handle.get(), name.c_str(), src, flags);
178
179 if (ret < 0) {
180 zip_source_free(src);
181 throw std::runtime_error(zip_strerror(m_handle.get()));
182 }
183
184 return ret;
185 }
186
187 ZipInt64 ZipArchive::addDirectory(const std::string &directory, ZipFlags flags)
188 {
189 auto ret = zip_dir_add(m_handle.get(), directory.c_str(), flags);
190
191 if (ret < 0)
192 throw std::runtime_error(zip_strerror(m_handle.get()));
193
194 return ret;
195 }
196
197 void ZipArchive::replace(const ZipSource &source, ZipUint64 index, ZipFlags flags)
198 {
199 auto src = source.source(m_handle.get());
200
201 if (zip_file_replace(m_handle.get(), index, src, flags) < 0) {
202 zip_source_free(src);
203 throw std::runtime_error(zip_strerror(m_handle.get()));
204 }
205 }
206
207 ZipFile ZipArchive::open(const std::string &name, ZipFlags flags, const std::string &password)
208 {
209 struct zip_file *file;
210
211 if (password.size() > 0)
212 file = zip_fopen_encrypted(m_handle.get(), name.c_str(), flags, password.c_str());
213 else
214 file = zip_fopen(m_handle.get(), name.c_str(), flags);
215
216 if (file == nullptr)
217 throw std::runtime_error(zip_strerror(m_handle.get()));
218
219 return file;
220 }
221
222 ZipFile ZipArchive::open(ZipUint64 index, ZipFlags flags, const std::string &password)
223 {
224 struct zip_file *file;
225
226 if (password.size() > 0)
227 file = zip_fopen_index_encrypted(m_handle.get(), index, flags, password.c_str());
228 else
229 file = zip_fopen_index(m_handle.get(), index, flags);
230
231 if (file == nullptr)
232 throw std::runtime_error(zip_strerror(m_handle.get()));
233
234 return file;
235 }
236
237 void ZipArchive::rename(ZipUint64 index, const std::string &name, ZipFlags flags)
238 {
239 if (zip_file_rename(m_handle.get(), index, name.c_str(), flags) < 0)
240 throw std::runtime_error(zip_strerror(m_handle.get()));
241 }
242
243 void ZipArchive::setFileCompression(ZipUint64 index, ZipInt32 comp, ZipUint32 flags)
244 {
245 if (zip_set_file_compression(m_handle.get(), index, comp, flags) < 0)
246 throw std::runtime_error(zip_strerror(m_handle.get()));
247 }
248
249 void ZipArchive::remove(ZipUint64 index)
250 {
251 if (zip_delete(m_handle.get(), index) < 0)
252 throw std::runtime_error(zip_strerror(m_handle.get()));
253 }
254
255 ZipInt64 ZipArchive::numEntries(ZipFlags flags) const noexcept
256 {
257 return zip_get_num_entries(m_handle.get(), flags);
258 }
259
260 void ZipArchive::unchange(ZipUint64 index)
261 {
262 if (zip_unchange(m_handle.get(), index) < 0)
263 throw std::runtime_error(zip_strerror(m_handle.get()));
264 }
265
266 void ZipArchive::unchangeAll()
267 {
268 if (zip_unchange_all(m_handle.get()) < 0)
269 throw std::runtime_error(zip_strerror(m_handle.get()));
270 }
271
272 void ZipArchive::unchangeArchive()
273 {
274 if (zip_unchange_archive(m_handle.get()) < 0)
275 throw std::runtime_error(zip_strerror(m_handle.get()));
276 }
277
278 void ZipArchive::setDefaultPassword(const std::string &password)
279 {
280 auto cstr = (password.size() > 0) ? password.c_str() : nullptr;
281
282 if (zip_set_default_password(m_handle.get(), cstr) < 0)
283 throw std::runtime_error(zip_strerror(m_handle.get()));
284 }
285
286 void ZipArchive::setFlag(ZipFlags flags, int value)
287 {
288 if (zip_set_archive_flag(m_handle.get(), flags, value) < 0)
289 throw std::runtime_error(zip_strerror(m_handle.get()));
290 }
291
292 int ZipArchive::getFlag(ZipFlags which, ZipFlags flags) const
293 {
294 auto ret = zip_get_archive_flag(m_handle.get(), which, flags);
295
296 if (ret < 0)
297 throw std::runtime_error(zip_strerror(m_handle.get()));
298
299 return ret;
300 }