1 module utile.miniz; 2 import std.conv, std.file, std.array, std.stdio, std.string, std.algorithm, 3 std.exception, utile.miniz.binding; 4 5 final class Zip 6 { 7 this(string name, bool writeable = true, bool create = false) 8 { 9 auto s = name.toStringz; 10 11 if (create) 12 { 13 assert(writeable, `cannot create in readonly mode`); 14 15 mz_zip_writer_init_file_v2(&_zip, name.toStringz, 0, 16 MZ_ZIP_FLAG_WRITE_ZIP64 | MZ_ZIP_FLAG_WRITE_ALLOW_READING); 17 } 18 else 19 { 20 enforce(name.exists, `archive does not exist`); 21 22 mz_zip_reader_init_file(&_zip, s, 0); 23 24 if (writeable) 25 { 26 mz_zip_writer_init_from_reader(&_zip, s); 27 } 28 else 29 { 30 _ro = true; 31 } 32 } 33 } 34 35 ~this() 36 { 37 if (_ro) 38 { 39 mz_zip_reader_end(&_zip); 40 } 41 else 42 { 43 mz_zip_writer_finalize_archive(&_zip); 44 mz_zip_writer_end(&_zip); 45 } 46 } 47 48 auto get(string name) 49 { 50 auto idx = mz_zip_reader_locate_file(&_zip, name.toStringz, null, 0); 51 enforce(idx >= 0, lastError); 52 53 mz_zip_archive_file_stat s; 54 enforce(mz_zip_reader_file_stat(&_zip, idx, &s), lastError); 55 56 auto res = new ubyte[cast(size_t)s.m_uncomp_size]; 57 58 enforce(mz_zip_reader_extract_to_mem(&_zip, idx, res.ptr, res.length, 0), lastError); 59 return res; 60 } 61 62 void put(string name, in void[] data) 63 { 64 mz_zip_writer_add_mem(&_zip, name.toStringz, data.ptr, data.length, 0); 65 } 66 67 private: 68 auto lastError() 69 { 70 return mz_zip_get_last_error(&_zip).mz_zip_get_error_string.fromStringz.assumeUnique; 71 } 72 73 bool _ro; 74 mz_zip_archive _zip; 75 }