using System; using System.IO; using ICSharpCode.SharpZipLib.GZip; namespace AlicizaX { public static partial class Utility { /// /// 压缩解压缩相关的实用函数。 /// public static partial class Compression { private const int CachedBytesLength = 0x1000; /// /// 压缩数据。 /// /// 要压缩的数据的二进制流。 /// 压缩后的数据的二进制流。 public static byte[] Compress(byte[] bytes) { if (bytes == null) { throw new GameFrameworkException("Bytes is invalid."); } return Compress(bytes, 0, bytes.Length); } /// /// 压缩数据。 /// /// 要压缩的数据的二进制流。 /// 压缩后的数据的二进制流。 /// 是否压缩数据成功。 public static bool Compress(byte[] bytes, Stream compressedStream) { if (bytes == null) { throw new GameFrameworkException("Bytes is invalid."); } return Compress(bytes, 0, bytes.Length, compressedStream); } /// /// 压缩数据。 /// /// 要压缩的数据的二进制流。 /// 要压缩的数据的二进制流的偏移。 /// 要压缩的数据的二进制流的长度。 /// 压缩后的数据的二进制流。 public static byte[] Compress(byte[] bytes, int offset, int length) { using (MemoryStream compressedStream = new MemoryStream()) { if (Compress(bytes, offset, length, compressedStream)) { return compressedStream.ToArray(); } else { return null; } } } /// /// 压缩数据。 /// /// 要压缩的数据的二进制流。 /// 要压缩的数据的二进制流的偏移。 /// 要压缩的数据的二进制流的长度。 /// 压缩后的数据的二进制流。 /// 是否压缩数据成功。 public static bool Compress(byte[] bytes, int offset, int length, Stream compressedStream) { if (bytes == null) { throw new GameFrameworkException("Bytes is invalid."); } if (offset < 0 || length < 0 || offset + length > bytes.Length) { throw new GameFrameworkException("Offset or length is invalid."); } if (compressedStream == null) { throw new GameFrameworkException("Compressed stream is invalid."); } try { using (GZipOutputStream gzipOutputStream = new GZipOutputStream(compressedStream)) { gzipOutputStream.Write(bytes, offset, length); gzipOutputStream.Finish(); } ProcessHeader(compressedStream); return true; } catch (Exception exception) { if (exception is GameFrameworkException) { throw; } throw new GameFrameworkException(Text.Format("Can not compress with exception '{0}'.", exception), exception); } } /// /// 压缩数据。 /// /// 要压缩的数据的二进制流。 /// 压缩后的数据的二进制流。 public static byte[] Compress(Stream stream) { using (MemoryStream compressedStream = new MemoryStream()) { if (Compress(stream, compressedStream)) { return compressedStream.ToArray(); } else { return null; } } } /// /// 压缩数据。 /// /// 要压缩的数据的二进制流。 /// 压缩后的数据的二进制流。 /// 是否压缩数据成功。 public static bool Compress(Stream stream, Stream compressedStream) { if (stream == null) { throw new GameFrameworkException("Stream is invalid."); } if (compressedStream == null) { throw new GameFrameworkException("Compressed stream is invalid."); } try { byte[] cachedBytes = new byte[CachedBytesLength]; using (GZipOutputStream gzipOutputStream = new GZipOutputStream(compressedStream)) { int bytesRead; while ((bytesRead = stream.Read(cachedBytes, 0, CachedBytesLength)) > 0) { gzipOutputStream.Write(cachedBytes, 0, bytesRead); } gzipOutputStream.Finish(); } ProcessHeader(compressedStream); return true; } catch (Exception exception) { if (exception is GameFrameworkException) { throw; } throw new GameFrameworkException(Text.Format("Can not compress with exception '{0}'.", exception), exception); } } /// /// 解压缩数据。 /// /// 要解压缩的数据的二进制流。 /// 解压缩后的数据的二进制流。 public static byte[] Decompress(byte[] bytes) { if (bytes == null) { throw new GameFrameworkException("Bytes is invalid."); } return Decompress(bytes, 0, bytes.Length); } /// /// 解压缩数据。 /// /// 要解压缩的数据的二进制流。 /// 解压缩后的数据的二进制流。 /// 是否解压缩数据成功。 public static bool Decompress(byte[] bytes, Stream decompressedStream) { if (bytes == null) { throw new GameFrameworkException("Bytes is invalid."); } return Decompress(bytes, 0, bytes.Length, decompressedStream); } /// /// 解压缩数据。 /// /// 要解压缩的数据的二进制流。 /// 要解压缩的数据的二进制流的偏移。 /// 要解压缩的数据的二进制流的长度。 /// 解压缩后的数据的二进制流。 public static byte[] Decompress(byte[] bytes, int offset, int length) { using (MemoryStream decompressedStream = new MemoryStream()) { if (Decompress(bytes, offset, length, decompressedStream)) { return decompressedStream.ToArray(); } else { return null; } } } /// /// 解压缩数据。 /// /// 要解压缩的数据的二进制流。 /// 要解压缩的数据的二进制流的偏移。 /// 要解压缩的数据的二进制流的长度。 /// 解压缩后的数据的二进制流。 /// 是否解压缩数据成功。 public static bool Decompress(byte[] bytes, int offset, int length, Stream decompressedStream) { if (bytes == null) { throw new GameFrameworkException("Bytes is invalid."); } if (offset < 0 || length < 0 || offset + length > bytes.Length) { throw new GameFrameworkException("Offset or length is invalid."); } if (decompressedStream == null) { throw new GameFrameworkException("Decompressed stream is invalid."); } try { byte[] cachedBytes = new byte[CachedBytesLength]; using (MemoryStream memoryStream = new MemoryStream(bytes, offset, length, false)) using (GZipInputStream gzipInputStream = new GZipInputStream(memoryStream)) { int bytesRead; while ((bytesRead = gzipInputStream.Read(cachedBytes, 0, CachedBytesLength)) > 0) { decompressedStream.Write(cachedBytes, 0, bytesRead); } } return true; } catch (Exception exception) { if (exception is GameFrameworkException) { throw; } throw new GameFrameworkException(Text.Format("Can not decompress with exception '{0}'.", exception), exception); } } /// /// 解压缩数据。 /// /// 要解压缩的数据的二进制流。 /// 是否解压缩数据成功。 public static byte[] Decompress(Stream stream) { using (MemoryStream decompressedStream = new MemoryStream()) { if (Decompress(stream, decompressedStream)) { return decompressedStream.ToArray(); } else { return null; } } } /// /// 解压缩数据。 /// /// 要解压缩的数据的二进制流。 /// 解压缩后的数据的二进制流。 /// 是否解压缩数据成功。 public static bool Decompress(Stream stream, Stream decompressedStream) { if (stream == null) { throw new GameFrameworkException("Stream is invalid."); } if (decompressedStream == null) { throw new GameFrameworkException("Decompressed stream is invalid."); } try { byte[] cachedBytes = new byte[CachedBytesLength]; using (GZipInputStream gzipInputStream = new GZipInputStream(stream)) { int bytesRead; while ((bytesRead = gzipInputStream.Read(cachedBytes, 0, CachedBytesLength)) > 0) { decompressedStream.Write(cachedBytes, 0, bytesRead); } } return true; } catch (Exception exception) { if (exception is GameFrameworkException) { throw; } throw new GameFrameworkException(Text.Format("Can not decompress with exception '{0}'.", exception), exception); } } private static void ProcessHeader(Stream compressedStream) { if (compressedStream.Length < 8L) { return; } long current = compressedStream.Position; compressedStream.Position = 4L; compressedStream.WriteByte(25); compressedStream.WriteByte(134); compressedStream.WriteByte(2); compressedStream.WriteByte(32); compressedStream.Position = current; } } } }