Mercurial > code
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 } |