using CommonLang.Concurrent; using CommonLang.IO; using MPQ; using MPQ.Updater; using System; using System.IO; namespace CommonMPQ.SharpZipLib { public class SharpZipLibMPQDirver : MPQDirver { public override bool RunUnzipSingle(MPQUpdater updater, MPQUpdater.RemoteFileInfo zip, MPQUpdater.RemoteFileInfo mpq, AtomicLong process) { return Unzip.SharpZipLib_RunUnzipMPQ(updater, zip, mpq, process); } } public class Unzip { public static int BUFF_SIZE = 1024 * 1024 * 16; public static bool SharpZipLib_DecompressZ(ArraySegment<byte> src, ArraySegment<byte> dst) { using (var input = new MemoryStream(src.Array, src.Offset, src.Count)) { using (var zstream = new Zip.Compression.Streams.InflaterInputStream(input, new Zip.Compression.Inflater(false), Math.Min(dst.Count, BUFF_SIZE))) { IOUtil.ReadToEnd(zstream, dst.Array, dst.Offset, dst.Count); } } return true; } public static bool SharpZipLib_RunUnzipMPQ(MPQUpdater updater, MPQUpdater.RemoteFileInfo zip_file, MPQUpdater.RemoteFileInfo mpq_file, AtomicLong current_unzip_bytes) { using (FileStream fis = new FileStream(zip_file.file.FullName, FileMode.Open, FileAccess.Read)) { using (FileStream fos = new FileStream(mpq_file.file.FullName, FileMode.Create, FileAccess.Write)) { try { if (MPQUpdater.ZIP_EXT.ToLower().EndsWith(".zip")) { using (var zipf = new CommonMPQ.SharpZipLib.Zip.ZipFile(fis)) { var e = zipf.GetEnumerator(); if (e.MoveNext()) { var ze = (CommonMPQ.SharpZipLib.Zip.ZipEntry)(e.Current); Stream zipin = zipf.GetInputStream(ze); if (IOUtil.ReadTo(zipin, fos, mpq_file.size, (int readed) => { current_unzip_bytes += readed; return !updater.IsDisposing; }, 1024 * 1024) == false) { return false; } } zipf.Close(); } } else if (MPQUpdater.ZIP_EXT.ToLower().EndsWith(".mgz")) { var gstream = new CommonMPQ.SharpZipLib.GZip.GZipInputStream(fis); if (IOUtil.ReadTo(gstream, fos, mpq_file.size, (int readed) => { current_unzip_bytes += readed; return !updater.IsDisposing; }, 1024 * 1024) == false) { return false; } gstream.Close(); } else if (MPQUpdater.ZIP_EXT.ToLower().EndsWith(".z")) { var gstream = new CommonMPQ.SharpZipLib.Zip.Compression.Streams.InflaterInputStream(fis); if (IOUtil.ReadTo(gstream, fos, mpq_file.size, (int readed) => { current_unzip_bytes += readed; return !updater.IsDisposing; }, 1024 * 1024) == false) { return false; } gstream.Close(); } return true; } finally { fos.Close(); fis.Close(); } } } } } }