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 }