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;
100 std::ostream& out_file = *out_file_ptr;
102 uerr() <<
"Error: Cannot write file: " << full_path << std::endl;
108 zip_int64_t bytes_read;
109 while ((bytes_read = zip_fread(zf, buffer,
sizeof(buffer))) > 0) {
110 out_file.write(buffer, bytes_read);
113 if (bytes_read < 0) {
114 uerr() <<
"Error: Read failed for file in ZIP: " << name << std::endl;
117 out_file_ptr.reset();
127 const std::string& archive_name) {
129 std::istream& file = *file_ptr;
131 uerr() <<
"Error: Cannot open file: " << file_path << std::endl;
135 std::streamsize size = file.tellg();
136 file.seekg(0, std::ios::beg);
138 char* data =
static_cast<char*
>(malloc(size));
140 uerr() <<
"Error: Memory allocation failed for file: " << file_path << std::endl;
144 if (!file.read(data, size)) {
145 uerr() <<
"Error: Cannot read file: " << file_path << std::endl;
151 zip_source_t* source = zip_source_buffer_create(data, size, 1, &ziperr);
153 uerr() <<
"Error: Cannot create zip source for file: " << file_path
154 <<
": " << zip_error_strerror(&ziperr) << std::endl;
156 zip_error_fini(&ziperr);
160 zip_int64_t idx = zip_file_add(archive, archive_name.c_str(), source, ZIP_FL_ENC_UTF_8);
162 zip_source_free(source);
163 uerr() <<
"Error: Cannot add file to archive: " << archive_name << std::endl;
171 const std::string& base_dir,
172 const std::string& current_dir,
173 const std::string& rel_prefix) {
175 std::vector<std::string> entries = filesystem.exposed.iterate_directory_names(current_dir);
177 for (
const std::string& full_path : entries) {
178 std::string rel_path = full_path.substr(base_dir.size() + 1);
180 if (filesystem.exposed.is_directory(full_path)) {
181 zip_dir_add(archive, (rel_path +
"/").c_str(), ZIP_FL_ENC_UTF_8);
190 zip_error_init(&error);
192 zip_source_t* src = zip_source_buffer_create(
nullptr, 0, 0, &error);
194 uerr() <<
"Failed to create zip source buffer: "
195 << zip_error_strerror(&error) << std::endl;
196 zip_error_fini(&error);
201 zip_source_keep(src);
203 zip_t* archive = zip_open_from_source(src, ZIP_TRUNCATE, &error);
205 uerr() <<
"Failed to open zip archive from source: "
206 << zip_error_strerror(&error) << std::endl;
207 zip_source_free(src);
208 zip_error_fini(&error);
214 }
catch (
const std::exception& e) {
215 uerr() <<
"Exception while zipping directory: " << e.what() << std::endl;
216 zip_discard(archive);
217 zip_error_fini(&error);
221 if (zip_close(archive) != 0) {
222 uerr() <<
"Failed to finalize zip archive: "
223 << zip_error_strerror(&error) << std::endl;
224 zip_source_free(src);
225 zip_error_fini(&error);
230 if (zip_source_open(src) < 0) {
231 uerr() <<
"Failed to open zip source for reading." << std::endl;
232 zip_source_free(src);
233 zip_error_fini(&error);
238 if (zip_source_seek(src, 0, SEEK_END) < 0) {
239 uerr() <<
"Failed to seek to end of zip source." << std::endl;
240 zip_source_close(src);
241 zip_source_free(src);
242 zip_error_fini(&error);
246 zip_int64_t size = zip_source_tell(src);
248 uerr() <<
"Failed to get size of zip source." << std::endl;
249 zip_source_close(src);
250 zip_source_free(src);
251 zip_error_fini(&error);
255 if (zip_source_seek(src, 0, SEEK_SET) < 0) {
256 uerr() <<
"Failed to rewind zip source." << std::endl;
257 zip_source_close(src);
258 zip_source_free(src);
259 zip_error_fini(&error);
263 if (zip_source_seek(src, 0, SEEK_SET) < 0) {
264 uerr() <<
"Failed to rewind zip source." << std::endl;
265 zip_source_close(src);
266 zip_source_free(src);
267 zip_error_fini(&error);
273 zip_int64_t bytes_read;
275 while ((bytes_read = zip_source_read(src, buf,
sizeof(buf))) > 0) {
276 output.write(buf, bytes_read);
278 uerr() <<
"Write error while streaming zip data to output." << std::endl;
279 zip_source_close(src);
280 zip_source_free(src);
281 zip_error_fini(&error);
286 zip_source_close(src);
287 zip_source_free(src);
288 zip_error_fini(&error);
290 if (bytes_read < 0) {
291 uerr() <<
"Error reading from zip source." << std::endl;
299 bool zip_to_path(
const std::string& dir_path,
const std::string& zip_path) {
301 std::ostream& ofs = *ofs_ptr;
303 uerr() <<
"Failed to open output file: " << zip_path << std::endl;
310 bool zip_to_path2(
const std::string& dir_path,
const std::string& zip_path) {
312 zip_t* archive = zip_open(zip_path.c_str(), ZIP_CREATE | ZIP_TRUNCATE, &errorp);
314 zip_error_t ziperror;
315 zip_error_init_with_code(&ziperror, errorp);
316 uerr() <<
"Error: Cannot open zip archive " << zip_path <<
": "
317 << zip_error_strerror(&ziperror) << std::endl;
318 zip_error_fini(&ziperror);
324 }
catch (
const std::exception& e) {
325 uerr() <<
"Exception while zipping directory: " << e.what() << std::endl;
326 zip_discard(archive);
330 if (zip_close(archive) < 0) {
331 uerr() <<
"Error: Cannot finalize zip archive: " << zip_strerror(archive) << std::endl;
332 zip_discard(archive);
340 int CASADI_ARCHIVER_LIBZIP_EXPORT
342 plugin->name =
"libzip";
344 plugin->version = CASADI_VERSION;
static std::unique_ptr< std::ostream > ofstream_ptr(const std::string &path, std::ios_base::openmode mode=std::ios_base::out)
static std::unique_ptr< std::istream > ifstream_ptr(const std::string &path, std::ios_base::openmode mode=std::ios_base::in, bool fail=true)
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)