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 }