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