27 #include "casadi/core/filesystem_impl.hpp"
36 src.seekg(0, std::ios::beg);
37 const std::string& s = src.str();
40 zip_source_t* zip_src = zip_source_buffer_create(s.data(), s.size(), 0, &errorp);
43 casadi_error(
"Failed to create zip source: " +
44 std::string(zip_error_strerror(&errorp)) +
"\n");
48 zip_t* archive = zip_open_from_source(zip_src, 0, &errorp);
50 zip_source_free(zip_src);
51 casadi_error(
"Failed to open zip from source: " +
52 std::string(zip_error_strerror(&errorp)) +
"\n");
59 zip_t* za = zip_open(zip_path.c_str(), ZIP_RDONLY, &err);
61 casadi_error(
"Cannot open ZIP file: " + zip_path);
71 zip_int64_t num_entries = zip_get_num_entries(za, 0);
72 if (num_entries < 0) {
74 casadi_error(
"Cannot read ZIP contents.");
79 for (zip_uint64_t i = 0; i < static_cast<zip_uint64_t>(num_entries); ++i) {
80 const char* name = zip_get_name(za, i, 0);
82 uerr() <<
"Error: Cannot get file name for entry " << i << std::endl;
86 std::string full_path = output_dir +
"/" + name;
87 if (full_path.back() ==
'/') {
88 filesystem.exposed.create_directories(full_path);
90 std::string dir_path = full_path.substr(0, full_path.find_last_of(
'/'));
91 filesystem.exposed.create_directories(dir_path);
93 zip_file_t* zf = zip_fopen_index(za, i, 0);
95 uerr() <<
"Error: Cannot open file in ZIP: " << name << std::endl;
99 std::ofstream out_file(full_path, std::ios::binary);
101 uerr() <<
"Error: Cannot write file: " << full_path << std::endl;
107 zip_int64_t bytes_read;
108 while ((bytes_read = zip_fread(zf, buffer,
sizeof(buffer))) > 0) {
109 out_file.write(buffer, bytes_read);
112 if (bytes_read < 0) {
113 uerr() <<
"Error: Read failed for file in ZIP: " << name << std::endl;
126 const std::string& archive_name) {
127 std::ifstream file(file_path, std::ios::binary | std::ios::ate);
129 uerr() <<
"Error: Cannot open file: " << file_path << std::endl;
133 std::streamsize size = file.tellg();
134 file.seekg(0, std::ios::beg);
136 char* data =
static_cast<char*
>(malloc(size));
138 uerr() <<
"Error: Memory allocation failed for file: " << file_path << std::endl;
142 if (!file.read(data, size)) {
143 uerr() <<
"Error: Cannot read file: " << file_path << std::endl;
149 zip_source_t* source = zip_source_buffer_create(data, size, 1, &ziperr);
151 uerr() <<
"Error: Cannot create zip source for file: " << file_path
152 <<
": " << zip_error_strerror(&ziperr) << std::endl;
154 zip_error_fini(&ziperr);
158 zip_int64_t idx = zip_file_add(archive, archive_name.c_str(), source, ZIP_FL_ENC_UTF_8);
160 zip_source_free(source);
161 uerr() <<
"Error: Cannot add file to archive: " << archive_name << std::endl;
169 const std::string& base_dir,
170 const std::string& current_dir,
171 const std::string& rel_prefix) {
173 std::vector<std::string> entries = filesystem.exposed.iterate_directory_names(current_dir);
175 for (
const std::string& full_path : entries) {
176 std::string rel_path = full_path.substr(base_dir.size() + 1);
178 if (filesystem.exposed.is_directory(full_path)) {
179 zip_dir_add(archive, (rel_path +
"/").c_str(), ZIP_FL_ENC_UTF_8);
188 zip_error_init(&error);
190 zip_source_t* src = zip_source_buffer_create(
nullptr, 0, 0, &error);
192 uerr() <<
"Failed to create zip source buffer: "
193 << zip_error_strerror(&error) << std::endl;
194 zip_error_fini(&error);
199 zip_source_keep(src);
201 zip_t* archive = zip_open_from_source(src, ZIP_TRUNCATE, &error);
203 uerr() <<
"Failed to open zip archive from source: "
204 << zip_error_strerror(&error) << std::endl;
205 zip_source_free(src);
206 zip_error_fini(&error);
212 }
catch (
const std::exception& e) {
213 uerr() <<
"Exception while zipping directory: " << e.what() << std::endl;
214 zip_discard(archive);
215 zip_error_fini(&error);
219 if (zip_close(archive) != 0) {
220 uerr() <<
"Failed to finalize zip archive: "
221 << zip_error_strerror(&error) << std::endl;
222 zip_source_free(src);
223 zip_error_fini(&error);
228 if (zip_source_open(src) < 0) {
229 uerr() <<
"Failed to open zip source for reading." << std::endl;
230 zip_source_free(src);
231 zip_error_fini(&error);
236 if (zip_source_seek(src, 0, SEEK_END) < 0) {
237 uerr() <<
"Failed to seek to end of zip source." << std::endl;
238 zip_source_close(src);
239 zip_source_free(src);
240 zip_error_fini(&error);
244 zip_int64_t size = zip_source_tell(src);
246 uerr() <<
"Failed to get size of zip source." << std::endl;
247 zip_source_close(src);
248 zip_source_free(src);
249 zip_error_fini(&error);
253 if (zip_source_seek(src, 0, SEEK_SET) < 0) {
254 uerr() <<
"Failed to rewind zip source." << std::endl;
255 zip_source_close(src);
256 zip_source_free(src);
257 zip_error_fini(&error);
261 if (zip_source_seek(src, 0, SEEK_SET) < 0) {
262 uerr() <<
"Failed to rewind zip source." << std::endl;
263 zip_source_close(src);
264 zip_source_free(src);
265 zip_error_fini(&error);
271 zip_int64_t bytes_read;
273 while ((bytes_read = zip_source_read(src, buf,
sizeof(buf))) > 0) {
274 output.write(buf, bytes_read);
276 uerr() <<
"Write error while streaming zip data to output." << std::endl;
277 zip_source_close(src);
278 zip_source_free(src);
279 zip_error_fini(&error);
284 zip_source_close(src);
285 zip_source_free(src);
286 zip_error_fini(&error);
288 if (bytes_read < 0) {
289 uerr() <<
"Error reading from zip source." << std::endl;
297 bool zip_to_path(
const std::string& dir_path,
const std::string& zip_path) {
298 std::ofstream ofs(zip_path, std::ios::binary);
300 uerr() <<
"Failed to open output file: " << zip_path << std::endl;
307 bool zip_to_path2(
const std::string& dir_path,
const std::string& zip_path) {
309 zip_t* archive = zip_open(zip_path.c_str(), ZIP_CREATE | ZIP_TRUNCATE, &errorp);
311 zip_error_t ziperror;
312 zip_error_init_with_code(&ziperror, errorp);
313 uerr() <<
"Error: Cannot open zip archive " << zip_path <<
": "
314 << zip_error_strerror(&ziperror) << std::endl;
315 zip_error_fini(&ziperror);
321 }
catch (
const std::exception& e) {
322 uerr() <<
"Exception while zipping directory: " << e.what() << std::endl;
323 zip_discard(archive);
327 if (zip_close(archive) < 0) {
328 uerr() <<
"Error: Cannot finalize zip archive: " << zip_strerror(archive) << std::endl;
329 zip_discard(archive);
337 int CASADI_ARCHIVER_LIBZIP_EXPORT
339 plugin->name =
"libzip";
341 plugin->version = CASADI_VERSION;
static void assert_enabled()
static const std::string meta_doc
A documentation string.
static Plugin & getPlugin(const std::string &pname)
Load and get the creator function.
static void registerPlugin(const Plugin &plugin, bool needs_lock=true)
Register an integrator in the factory.
int CASADI_ARCHIVER_LIBZIP_EXPORT casadi_register_archiver_libzip(Archiver::Plugin *plugin)
bool zip_to_path(const std::string &dir_path, const std::string &zip_path)
bool extract_zip_from_path(const std::string &zip_path, const std::string &output_dir)
bool extract_zip_internal(zip_t *za, const std::string &output_dir)
bool add_file_to_zip(zip_t *archive, const std::string &file_path, const std::string &archive_name)
bool zip_to_stream(const std::string &dir, std::ostream &output)
void add_directory_recursive(zip_t *archive, const std::string &base_dir, const std::string ¤t_dir, const std::string &rel_prefix)
bool extract_zip_from_stringstream(std::stringstream &src, const std::string &output_dir)
void CASADI_ARCHIVER_LIBZIP_EXPORT casadi_load_archiver_libzip()
bool zip_to_path2(const std::string &dir_path, const std::string &zip_path)