fixed bugs:
- work around Mono bug in GZipStream (see http://sourceforge.net/p/keepass/bugs/1373/) by including a custom GZipStream implementation - fixed issue with export database to System file picker location - fixed issues with preference options crashing with ActivityNotFound (due to changes in Xamarin 5.1, see https://bugzilla.xamarin.com/show_bug.cgi?id=33617 updated manifest/changelog
This commit is contained in:
		| @@ -33,6 +33,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MPTest", "MPTest\MPTest.csp | |||||||
| EndProject | EndProject | ||||||
| Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MasterKeePlugin", "MasterKeePlugin\MasterKeePlugin.csproj", "{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}" | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MasterKeePlugin", "MasterKeePlugin\MasterKeePlugin.csproj", "{9A4C5BAA-1A8A-49B4-BBC3-60D4871FB36C}" | ||||||
| EndProject | EndProject | ||||||
|  | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ZlibAndroid", "ZlibAndroid\ZlibAndroid.csproj", "{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}" | ||||||
|  | EndProject | ||||||
| Global | Global | ||||||
| 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | 	GlobalSection(SolutionConfigurationPlatforms) = preSolution | ||||||
| 		Debug|Any CPU = Debug|Any CPU | 		Debug|Any CPU = Debug|Any CPU | ||||||
| @@ -227,6 +229,30 @@ Global | |||||||
| 		{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU | 		{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|Mixed Platforms.Build.0 = ReleaseNoNet|Any CPU | ||||||
| 		{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU | 		{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU | ||||||
| 		{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU | 		{5CF675A5-9BEE-4720-BED9-D5BF14A2EBF9}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Win32.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|Win32.Build.0 = Debug|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|x64.ActiveCfg = Debug|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Debug|x64.Build.0 = Debug|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|Any CPU.ActiveCfg = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|Any CPU.Build.0 = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|Mixed Platforms.Build.0 = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|Win32.ActiveCfg = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|Win32.Build.0 = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|x64.ActiveCfg = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.Release|x64.Build.0 = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Any CPU.ActiveCfg = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Any CPU.Build.0 = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Mixed Platforms.ActiveCfg = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Mixed Platforms.Build.0 = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Win32.ActiveCfg = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|Win32.Build.0 = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|x64.ActiveCfg = Release|Any CPU | ||||||
|  | 		{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}.ReleaseNoNet|x64.Build.0 = Release|Any CPU | ||||||
| 		{70D3844A-D9FA-4A64-B205-A84C6A822196}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | 		{70D3844A-D9FA-4A64-B205-A84C6A822196}.Debug|Any CPU.ActiveCfg = Debug|Any CPU | ||||||
| 		{70D3844A-D9FA-4A64-B205-A84C6A822196}.Debug|Any CPU.Build.0 = Debug|Any CPU | 		{70D3844A-D9FA-4A64-B205-A84C6A822196}.Debug|Any CPU.Build.0 = Debug|Any CPU | ||||||
| 		{70D3844A-D9FA-4A64-B205-A84C6A822196}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU | 		{70D3844A-D9FA-4A64-B205-A84C6A822196}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU | ||||||
|   | |||||||
| @@ -12,7 +12,8 @@ | |||||||
|     <AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile> |     <AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile> | ||||||
|     <AndroidResgenClass>Resource</AndroidResgenClass> |     <AndroidResgenClass>Resource</AndroidResgenClass> | ||||||
|     <AssemblyName>KeePassLib2Android</AssemblyName> |     <AssemblyName>KeePassLib2Android</AssemblyName> | ||||||
|     <TargetFrameworkVersion>v4.0.3</TargetFrameworkVersion> |     <TargetFrameworkVersion>v5.0</TargetFrameworkVersion> | ||||||
|  |     <AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk> | ||||||
|   </PropertyGroup> |   </PropertyGroup> | ||||||
|   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||||||
|     <DebugSymbols>True</DebugSymbols> |     <DebugSymbols>True</DebugSymbols> | ||||||
| @@ -156,6 +157,10 @@ | |||||||
|       <Project>{70D3844A-D9FA-4A64-B205-A84C6A822196}</Project> |       <Project>{70D3844A-D9FA-4A64-B205-A84C6A822196}</Project> | ||||||
|       <Name>KP2AKdbLibraryBinding</Name> |       <Name>KP2AKdbLibraryBinding</Name> | ||||||
|     </ProjectReference> |     </ProjectReference> | ||||||
|  |     <ProjectReference Include="..\ZlibAndroid\ZlibAndroid.csproj"> | ||||||
|  |       <Project>{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}</Project> | ||||||
|  |       <Name>ZlibAndroid</Name> | ||||||
|  |     </ProjectReference> | ||||||
|   </ItemGroup> |   </ItemGroup> | ||||||
|   <Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" /> |   <Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" /> | ||||||
| </Project> | </Project> | ||||||
| @@ -114,7 +114,7 @@ namespace KeePassLib.Serialization | |||||||
| 						!m_bRepairMode); | 						!m_bRepairMode); | ||||||
|  |  | ||||||
| 					if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip) | 					if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip) | ||||||
| 						readerStream = new GZipStream(sHashed, CompressionMode.Decompress); | 						readerStream = new Ionic.Zlib.GZipStream(sHashed, Ionic.Zlib.CompressionMode.Decompress); | ||||||
| 					else readerStream = sHashed; | 					else readerStream = sHashed; | ||||||
| 				} | 				} | ||||||
| 				else if(kdbFormat == KdbxFormat.PlainXml) | 				else if(kdbFormat == KdbxFormat.PlainXml) | ||||||
|   | |||||||
| @@ -115,7 +115,7 @@ namespace KeePassLib.Serialization | |||||||
| 					Stream sHashed = new HashedBlockStream(sEncrypted, true); | 					Stream sHashed = new HashedBlockStream(sEncrypted, true); | ||||||
|  |  | ||||||
| 					if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip) | 					if(m_pwDatabase.Compression == PwCompressionAlgorithm.GZip) | ||||||
| 						writerStream = new GZipStream(sHashed, CompressionMode.Compress); | 						writerStream = new Ionic.Zlib.GZipStream(sHashed, Ionic.Zlib.CompressionMode.Compress); | ||||||
| 					else | 					else | ||||||
| 						writerStream = sHashed; | 						writerStream = sHashed; | ||||||
| 				} | 				} | ||||||
|   | |||||||
| @@ -103,7 +103,7 @@ namespace KeePassLib.Translation | |||||||
| 				FileAccess.Write, FileShare.None); | 				FileAccess.Write, FileShare.None); | ||||||
|  |  | ||||||
| #if !KeePassLibSD | #if !KeePassLibSD | ||||||
| 			GZipStream gz = new GZipStream(fs, CompressionMode.Compress); | 			Ionic.Zlib.GZipStream gz = new Ionic.Zlib.GZipStream(fs, Ionic.Zlib.CompressionMode.Compress); | ||||||
| #else | #else | ||||||
| 			GZipOutputStream gz = new GZipOutputStream(fs); | 			GZipOutputStream gz = new GZipOutputStream(fs); | ||||||
| #endif | #endif | ||||||
| @@ -132,7 +132,7 @@ namespace KeePassLib.Translation | |||||||
| 				FileAccess.Read, FileShare.Read); | 				FileAccess.Read, FileShare.Read); | ||||||
|  |  | ||||||
| #if !KeePassLibSD | #if !KeePassLibSD | ||||||
| 			GZipStream gz = new GZipStream(fs, CompressionMode.Decompress); | 			Ionic.Zlib.GZipStream gz = new Ionic.Zlib.GZipStream(fs, Ionic.Zlib.CompressionMode.Decompress); | ||||||
| #else | #else | ||||||
| 			GZipInputStream gz = new GZipInputStream(fs); | 			GZipInputStream gz = new GZipInputStream(fs); | ||||||
| #endif | #endif | ||||||
|   | |||||||
| @@ -68,7 +68,7 @@ namespace KeePassLib.Utility | |||||||
|  |  | ||||||
| 				FileStream fsOut = new FileStream(strPath, FileMode.Create, | 				FileStream fsOut = new FileStream(strPath, FileMode.Create, | ||||||
| 					FileAccess.Write, FileShare.None); | 					FileAccess.Write, FileShare.None); | ||||||
| 				GZipStream gz = new GZipStream(fsOut, CompressionMode.Compress); | 				Ionic.Zlib.GZipStream gz = new Ionic.Zlib.GZipStream(fsOut, CompressionMode.Compress); | ||||||
| 				m_swOut = new StreamWriter(gz); | 				m_swOut = new StreamWriter(gz); | ||||||
|  |  | ||||||
| 				AppLogEx.Log("Started logging on " + dtNow.ToString("s") + "."); | 				AppLogEx.Log("Started logging on " + dtNow.ToString("s") + "."); | ||||||
|   | |||||||
| @@ -430,7 +430,7 @@ namespace KeePassLib.Utility | |||||||
| 			if(pbData.Length == 0) return pbData; | 			if(pbData.Length == 0) return pbData; | ||||||
|  |  | ||||||
| 			MemoryStream msCompressed = new MemoryStream(); | 			MemoryStream msCompressed = new MemoryStream(); | ||||||
| 			GZipStream gz = new GZipStream(msCompressed, CompressionMode.Compress); | 			Ionic.Zlib.GZipStream gz = new Ionic.Zlib.GZipStream(msCompressed, Ionic.Zlib.CompressionMode.Compress); | ||||||
| 			MemoryStream msSource = new MemoryStream(pbData, false); | 			MemoryStream msSource = new MemoryStream(pbData, false); | ||||||
| 			MemUtil.CopyStream(msSource, gz); | 			MemUtil.CopyStream(msSource, gz); | ||||||
| 			gz.Close(); | 			gz.Close(); | ||||||
| @@ -447,7 +447,7 @@ namespace KeePassLib.Utility | |||||||
| 			if(pbCompressed.Length == 0) return pbCompressed; | 			if(pbCompressed.Length == 0) return pbCompressed; | ||||||
|  |  | ||||||
| 			MemoryStream msCompressed = new MemoryStream(pbCompressed, false); | 			MemoryStream msCompressed = new MemoryStream(pbCompressed, false); | ||||||
| 			GZipStream gz = new GZipStream(msCompressed, CompressionMode.Decompress); | 			Ionic.Zlib.GZipStream gz = new Ionic.Zlib.GZipStream(msCompressed, Ionic.Zlib.CompressionMode.Decompress); | ||||||
| 			MemoryStream msData = new MemoryStream(); | 			MemoryStream msData = new MemoryStream(); | ||||||
| 			MemUtil.CopyStream(gz, msData); | 			MemUtil.CopyStream(gz, msData); | ||||||
| 			gz.Close(); | 			gz.Close(); | ||||||
|   | |||||||
							
								
								
									
										814
									
								
								src/ZlibAndroid/CRC32.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										814
									
								
								src/ZlibAndroid/CRC32.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,814 @@ | |||||||
|  | // CRC32.cs | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // Copyright (c) 2011 Dino Chiesa. | ||||||
|  | // All rights reserved. | ||||||
|  | // | ||||||
|  | // This code module is part of DotNetZip, a zipfile class library. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This code is licensed under the Microsoft Public License. | ||||||
|  | // See the file License.txt for the license details. | ||||||
|  | // More info on: http://dotnetzip.codeplex.com | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // Last Saved: <2011-August-02 18:25:54> | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This module defines the CRC32 class, which can do the CRC32 algorithm, using | ||||||
|  | // arbitrary starting polynomials, and bit reversal. The bit reversal is what | ||||||
|  | // distinguishes this CRC-32 used in BZip2 from the CRC-32 that is used in PKZIP | ||||||
|  | // files, or GZIP files. This class does both. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | using System; | ||||||
|  | using Interop = System.Runtime.InteropServices; | ||||||
|  |  | ||||||
|  | namespace Ionic.Crc | ||||||
|  | { | ||||||
|  |     /// <summary> | ||||||
|  |     ///   Computes a CRC-32. The CRC-32 algorithm is parameterized - you | ||||||
|  |     ///   can set the polynomial and enable or disable bit | ||||||
|  |     ///   reversal. This can be used for GZIP, BZip2, or ZIP. | ||||||
|  |     /// </summary> | ||||||
|  |     /// <remarks> | ||||||
|  |     ///   This type is used internally by DotNetZip; it is generally not used | ||||||
|  |     ///   directly by applications wishing to create, read, or manipulate zip | ||||||
|  |     ///   archive files. | ||||||
|  |     /// </remarks> | ||||||
|  |  | ||||||
|  |     [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000C")] | ||||||
|  |     [Interop.ComVisible(true)] | ||||||
|  | #if !NETCF | ||||||
|  |     [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)] | ||||||
|  | #endif | ||||||
|  |     public class CRC32 | ||||||
|  |     { | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Indicates the total number of bytes applied to the CRC. | ||||||
|  |         /// </summary> | ||||||
|  |         public Int64 TotalBytesRead | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 return _TotalBytesRead; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Indicates the current CRC for all blocks slurped in. | ||||||
|  |         /// </summary> | ||||||
|  |         public Int32 Crc32Result | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 return unchecked((Int32)(~_register)); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Returns the CRC32 for the specified stream. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="input">The stream over which to calculate the CRC32</param> | ||||||
|  |         /// <returns>the CRC32 calculation</returns> | ||||||
|  |         public Int32 GetCrc32(System.IO.Stream input) | ||||||
|  |         { | ||||||
|  |             return GetCrc32AndCopy(input, null); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Returns the CRC32 for the specified stream, and writes the input into the | ||||||
|  |         /// output stream. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="input">The stream over which to calculate the CRC32</param> | ||||||
|  |         /// <param name="output">The stream into which to deflate the input</param> | ||||||
|  |         /// <returns>the CRC32 calculation</returns> | ||||||
|  |         public Int32 GetCrc32AndCopy(System.IO.Stream input, System.IO.Stream output) | ||||||
|  |         { | ||||||
|  |             if (input == null) | ||||||
|  |                 throw new Exception("The input stream must not be null."); | ||||||
|  |  | ||||||
|  |             unchecked | ||||||
|  |             { | ||||||
|  |                 byte[] buffer = new byte[BUFFER_SIZE]; | ||||||
|  |                 int readSize = BUFFER_SIZE; | ||||||
|  |  | ||||||
|  |                 _TotalBytesRead = 0; | ||||||
|  |                 int count = input.Read(buffer, 0, readSize); | ||||||
|  |                 if (output != null) output.Write(buffer, 0, count); | ||||||
|  |                 _TotalBytesRead += count; | ||||||
|  |                 while (count > 0) | ||||||
|  |                 { | ||||||
|  |                     SlurpBlock(buffer, 0, count); | ||||||
|  |                     count = input.Read(buffer, 0, readSize); | ||||||
|  |                     if (output != null) output.Write(buffer, 0, count); | ||||||
|  |                     _TotalBytesRead += count; | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 return (Int32)(~_register); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Get the CRC32 for the given (word,byte) combo.  This is a | ||||||
|  |         ///   computation defined by PKzip for PKZIP 2.0 (weak) encryption. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="W">The word to start with.</param> | ||||||
|  |         /// <param name="B">The byte to combine it with.</param> | ||||||
|  |         /// <returns>The CRC-ized result.</returns> | ||||||
|  |         public Int32 ComputeCrc32(Int32 W, byte B) | ||||||
|  |         { | ||||||
|  |             return _InternalComputeCrc32((UInt32)W, B); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         internal Int32 _InternalComputeCrc32(UInt32 W, byte B) | ||||||
|  |         { | ||||||
|  |             return (Int32)(crc32Table[(W ^ B) & 0xFF] ^ (W >> 8)); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Update the value for the running CRC32 using the given block of bytes. | ||||||
|  |         /// This is useful when using the CRC32() class in a Stream. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="block">block of bytes to slurp</param> | ||||||
|  |         /// <param name="offset">starting point in the block</param> | ||||||
|  |         /// <param name="count">how many bytes within the block to slurp</param> | ||||||
|  |         public void SlurpBlock(byte[] block, int offset, int count) | ||||||
|  |         { | ||||||
|  |             if (block == null) | ||||||
|  |                 throw new Exception("The data buffer must not be null."); | ||||||
|  |  | ||||||
|  |             // bzip algorithm | ||||||
|  |             for (int i = 0; i < count; i++) | ||||||
|  |             { | ||||||
|  |                 int x = offset + i; | ||||||
|  |                 byte b = block[x]; | ||||||
|  |                 if (this.reverseBits) | ||||||
|  |                 { | ||||||
|  |                     UInt32 temp = (_register >> 24) ^ b; | ||||||
|  |                     _register = (_register << 8) ^ crc32Table[temp]; | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     UInt32 temp = (_register & 0x000000FF) ^ b; | ||||||
|  |                     _register = (_register >> 8) ^ crc32Table[temp]; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             _TotalBytesRead += count; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Process one byte in the CRC. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name = "b">the byte to include into the CRC .  </param> | ||||||
|  |         public void UpdateCRC(byte b) | ||||||
|  |         { | ||||||
|  |             if (this.reverseBits) | ||||||
|  |             { | ||||||
|  |                 UInt32 temp = (_register >> 24) ^ b; | ||||||
|  |                 _register = (_register << 8) ^ crc32Table[temp]; | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 UInt32 temp = (_register & 0x000000FF) ^ b; | ||||||
|  |                 _register = (_register >> 8) ^ crc32Table[temp]; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Process a run of N identical bytes into the CRC. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     This method serves as an optimization for updating the CRC when a | ||||||
|  |         ///     run of identical bytes is found. Rather than passing in a buffer of | ||||||
|  |         ///     length n, containing all identical bytes b, this method accepts the | ||||||
|  |         ///     byte value and the length of the (virtual) buffer - the length of | ||||||
|  |         ///     the run. | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <param name = "b">the byte to include into the CRC.  </param> | ||||||
|  |         /// <param name = "n">the number of times that byte should be repeated. </param> | ||||||
|  |         public void UpdateCRC(byte b, int n) | ||||||
|  |         { | ||||||
|  |             while (n-- > 0) | ||||||
|  |             { | ||||||
|  |                 if (this.reverseBits) | ||||||
|  |                 { | ||||||
|  |                     uint temp = (_register >> 24) ^ b; | ||||||
|  |                     _register = (_register << 8) ^ crc32Table[(temp >= 0) | ||||||
|  |                                                               ? temp | ||||||
|  |                                                               : (temp + 256)]; | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     UInt32 temp = (_register & 0x000000FF) ^ b; | ||||||
|  |                     _register = (_register >> 8) ^ crc32Table[(temp >= 0) | ||||||
|  |                                                               ? temp | ||||||
|  |                                                               : (temp + 256)]; | ||||||
|  |  | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         private static uint ReverseBits(uint data) | ||||||
|  |         { | ||||||
|  |             unchecked | ||||||
|  |             { | ||||||
|  |                 uint ret = data; | ||||||
|  |                 ret = (ret & 0x55555555) << 1 | (ret >> 1) & 0x55555555; | ||||||
|  |                 ret = (ret & 0x33333333) << 2 | (ret >> 2) & 0x33333333; | ||||||
|  |                 ret = (ret & 0x0F0F0F0F) << 4 | (ret >> 4) & 0x0F0F0F0F; | ||||||
|  |                 ret = (ret << 24) | ((ret & 0xFF00) << 8) | ((ret >> 8) & 0xFF00) | (ret >> 24); | ||||||
|  |                 return ret; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private static byte ReverseBits(byte data) | ||||||
|  |         { | ||||||
|  |             unchecked | ||||||
|  |             { | ||||||
|  |                 uint u = (uint)data * 0x00020202; | ||||||
|  |                 uint m = 0x01044010; | ||||||
|  |                 uint s = u & m; | ||||||
|  |                 uint t = (u << 2) & (m << 1); | ||||||
|  |                 return (byte)((0x01001001 * (s + t)) >> 24); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         private void GenerateLookupTable() | ||||||
|  |         { | ||||||
|  |             crc32Table = new UInt32[256]; | ||||||
|  |             unchecked | ||||||
|  |             { | ||||||
|  |                 UInt32 dwCrc; | ||||||
|  |                 byte i = 0; | ||||||
|  |                 do | ||||||
|  |                 { | ||||||
|  |                     dwCrc = i; | ||||||
|  |                     for (byte j = 8; j > 0; j--) | ||||||
|  |                     { | ||||||
|  |                         if ((dwCrc & 1) == 1) | ||||||
|  |                         { | ||||||
|  |                             dwCrc = (dwCrc >> 1) ^ dwPolynomial; | ||||||
|  |                         } | ||||||
|  |                         else | ||||||
|  |                         { | ||||||
|  |                             dwCrc >>= 1; | ||||||
|  |                         } | ||||||
|  |                     } | ||||||
|  |                     if (reverseBits) | ||||||
|  |                     { | ||||||
|  |                         crc32Table[ReverseBits(i)] = ReverseBits(dwCrc); | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         crc32Table[i] = dwCrc; | ||||||
|  |                     } | ||||||
|  |                     i++; | ||||||
|  |                 } while (i!=0); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  | #if VERBOSE | ||||||
|  |             Console.WriteLine(); | ||||||
|  |             Console.WriteLine("private static readonly UInt32[] crc32Table = {"); | ||||||
|  |             for (int i = 0; i < crc32Table.Length; i+=4) | ||||||
|  |             { | ||||||
|  |                 Console.Write("   "); | ||||||
|  |                 for (int j=0; j < 4; j++) | ||||||
|  |                 { | ||||||
|  |                     Console.Write(" 0x{0:X8}U,", crc32Table[i+j]); | ||||||
|  |                 } | ||||||
|  |                 Console.WriteLine(); | ||||||
|  |             } | ||||||
|  |             Console.WriteLine("};"); | ||||||
|  |             Console.WriteLine(); | ||||||
|  | #endif | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         private uint gf2_matrix_times(uint[] matrix, uint vec) | ||||||
|  |         { | ||||||
|  |             uint sum = 0; | ||||||
|  |             int i=0; | ||||||
|  |             while (vec != 0) | ||||||
|  |             { | ||||||
|  |                 if ((vec & 0x01)== 0x01) | ||||||
|  |                     sum ^= matrix[i]; | ||||||
|  |                 vec >>= 1; | ||||||
|  |                 i++; | ||||||
|  |             } | ||||||
|  |             return sum; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private void gf2_matrix_square(uint[] square, uint[] mat) | ||||||
|  |         { | ||||||
|  |             for (int i = 0; i < 32; i++) | ||||||
|  |                 square[i] = gf2_matrix_times(mat, mat[i]); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Combines the given CRC32 value with the current running total. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   This is useful when using a divide-and-conquer approach to | ||||||
|  |         ///   calculating a CRC.  Multiple threads can each calculate a | ||||||
|  |         ///   CRC32 on a segment of the data, and then combine the | ||||||
|  |         ///   individual CRC32 values at the end. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <param name="crc">the crc value to be combined with this one</param> | ||||||
|  |         /// <param name="length">the length of data the CRC value was calculated on</param> | ||||||
|  |         public void Combine(int crc, int length) | ||||||
|  |         { | ||||||
|  |             uint[] even = new uint[32];     // even-power-of-two zeros operator | ||||||
|  |             uint[] odd = new uint[32];      // odd-power-of-two zeros operator | ||||||
|  |  | ||||||
|  |             if (length == 0) | ||||||
|  |                 return; | ||||||
|  |  | ||||||
|  |             uint crc1= ~_register; | ||||||
|  |             uint crc2= (uint) crc; | ||||||
|  |  | ||||||
|  |             // put operator for one zero bit in odd | ||||||
|  |             odd[0] = this.dwPolynomial;  // the CRC-32 polynomial | ||||||
|  |             uint row = 1; | ||||||
|  |             for (int i = 1; i < 32; i++) | ||||||
|  |             { | ||||||
|  |                 odd[i] = row; | ||||||
|  |                 row <<= 1; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             // put operator for two zero bits in even | ||||||
|  |             gf2_matrix_square(even, odd); | ||||||
|  |  | ||||||
|  |             // put operator for four zero bits in odd | ||||||
|  |             gf2_matrix_square(odd, even); | ||||||
|  |  | ||||||
|  |             uint len2 = (uint) length; | ||||||
|  |  | ||||||
|  |             // apply len2 zeros to crc1 (first square will put the operator for one | ||||||
|  |             // zero byte, eight zero bits, in even) | ||||||
|  |             do { | ||||||
|  |                 // apply zeros operator for this bit of len2 | ||||||
|  |                 gf2_matrix_square(even, odd); | ||||||
|  |  | ||||||
|  |                 if ((len2 & 1)== 1) | ||||||
|  |                     crc1 = gf2_matrix_times(even, crc1); | ||||||
|  |                 len2 >>= 1; | ||||||
|  |  | ||||||
|  |                 if (len2 == 0) | ||||||
|  |                     break; | ||||||
|  |  | ||||||
|  |                 // another iteration of the loop with odd and even swapped | ||||||
|  |                 gf2_matrix_square(odd, even); | ||||||
|  |                 if ((len2 & 1)==1) | ||||||
|  |                     crc1 = gf2_matrix_times(odd, crc1); | ||||||
|  |                 len2 >>= 1; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             } while (len2 != 0); | ||||||
|  |  | ||||||
|  |             crc1 ^= crc2; | ||||||
|  |  | ||||||
|  |             _register= ~crc1; | ||||||
|  |  | ||||||
|  |             //return (int) crc1; | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Create an instance of the CRC32 class using the default settings: no | ||||||
|  |         ///   bit reversal, and a polynomial of 0xEDB88320. | ||||||
|  |         /// </summary> | ||||||
|  |         public CRC32() : this(false) | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Create an instance of the CRC32 class, specifying whether to reverse | ||||||
|  |         ///   data bits or not. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name='reverseBits'> | ||||||
|  |         ///   specify true if the instance should reverse data bits. | ||||||
|  |         /// </param> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     In the CRC-32 used by BZip2, the bits are reversed. Therefore if you | ||||||
|  |         ///     want a CRC32 with compatibility with BZip2, you should pass true | ||||||
|  |         ///     here. In the CRC-32 used by GZIP and PKZIP, the bits are not | ||||||
|  |         ///     reversed; Therefore if you want a CRC32 with compatibility with | ||||||
|  |         ///     those, you should pass false. | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         public CRC32(bool reverseBits) : | ||||||
|  |             this( unchecked((int)0xEDB88320), reverseBits) | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Create an instance of the CRC32 class, specifying the polynomial and | ||||||
|  |         ///   whether to reverse data bits or not. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name='polynomial'> | ||||||
|  |         ///   The polynomial to use for the CRC, expressed in the reversed (LSB) | ||||||
|  |         ///   format: the highest ordered bit in the polynomial value is the | ||||||
|  |         ///   coefficient of the 0th power; the second-highest order bit is the | ||||||
|  |         ///   coefficient of the 1 power, and so on. Expressed this way, the | ||||||
|  |         ///   polynomial for the CRC-32C used in IEEE 802.3, is 0xEDB88320. | ||||||
|  |         /// </param> | ||||||
|  |         /// <param name='reverseBits'> | ||||||
|  |         ///   specify true if the instance should reverse data bits. | ||||||
|  |         /// </param> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     In the CRC-32 used by BZip2, the bits are reversed. Therefore if you | ||||||
|  |         ///     want a CRC32 with compatibility with BZip2, you should pass true | ||||||
|  |         ///     here for the <c>reverseBits</c> parameter. In the CRC-32 used by | ||||||
|  |         ///     GZIP and PKZIP, the bits are not reversed; Therefore if you want a | ||||||
|  |         ///     CRC32 with compatibility with those, you should pass false for the | ||||||
|  |         ///     <c>reverseBits</c> parameter. | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         public CRC32(int polynomial, bool reverseBits) | ||||||
|  |         { | ||||||
|  |             this.reverseBits = reverseBits; | ||||||
|  |             this.dwPolynomial = (uint) polynomial; | ||||||
|  |             this.GenerateLookupTable(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Reset the CRC-32 class - clear the CRC "remainder register." | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     Use this when employing a single instance of this class to compute | ||||||
|  |         ///     multiple, distinct CRCs on multiple, distinct data blocks. | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         public void Reset() | ||||||
|  |         { | ||||||
|  |             _register = 0xFFFFFFFFU; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // private member vars | ||||||
|  |         private UInt32 dwPolynomial; | ||||||
|  |         private Int64 _TotalBytesRead; | ||||||
|  |         private bool reverseBits; | ||||||
|  |         private UInt32[] crc32Table; | ||||||
|  |         private const int BUFFER_SIZE = 8192; | ||||||
|  |         private UInt32 _register = 0xFFFFFFFFU; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// A Stream that calculates a CRC32 (a checksum) on all bytes read, | ||||||
|  |     /// or on all bytes written. | ||||||
|  |     /// </summary> | ||||||
|  |     /// | ||||||
|  |     /// <remarks> | ||||||
|  |     /// <para> | ||||||
|  |     /// This class can be used to verify the CRC of a ZipEntry when | ||||||
|  |     /// reading from a stream, or to calculate a CRC when writing to a | ||||||
|  |     /// stream.  The stream should be used to either read, or write, but | ||||||
|  |     /// not both.  If you intermix reads and writes, the results are not | ||||||
|  |     /// defined. | ||||||
|  |     /// </para> | ||||||
|  |     /// | ||||||
|  |     /// <para> | ||||||
|  |     /// This class is intended primarily for use internally by the | ||||||
|  |     /// DotNetZip library. | ||||||
|  |     /// </para> | ||||||
|  |     /// </remarks> | ||||||
|  |     public class CrcCalculatorStream : System.IO.Stream, System.IDisposable | ||||||
|  |     { | ||||||
|  |         private static readonly Int64 UnsetLengthLimit = -99; | ||||||
|  |  | ||||||
|  |         internal System.IO.Stream _innerStream; | ||||||
|  |         private CRC32 _Crc32; | ||||||
|  |         private Int64 _lengthLimit = -99; | ||||||
|  |         private bool _leaveOpen; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The default constructor. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     Instances returned from this constructor will leave the underlying | ||||||
|  |         ///     stream open upon Close().  The stream uses the default CRC32 | ||||||
|  |         ///     algorithm, which implies a polynomial of 0xEDB88320. | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <param name="stream">The underlying stream</param> | ||||||
|  |         public CrcCalculatorStream(System.IO.Stream stream) | ||||||
|  |             : this(true, CrcCalculatorStream.UnsetLengthLimit, stream, null) | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   The constructor allows the caller to specify how to handle the | ||||||
|  |         ///   underlying stream at close. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     The stream uses the default CRC32 algorithm, which implies a | ||||||
|  |         ///     polynomial of 0xEDB88320. | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <param name="stream">The underlying stream</param> | ||||||
|  |         /// <param name="leaveOpen">true to leave the underlying stream | ||||||
|  |         /// open upon close of the <c>CrcCalculatorStream</c>; false otherwise.</param> | ||||||
|  |         public CrcCalculatorStream(System.IO.Stream stream, bool leaveOpen) | ||||||
|  |             : this(leaveOpen, CrcCalculatorStream.UnsetLengthLimit, stream, null) | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   A constructor allowing the specification of the length of the stream | ||||||
|  |         ///   to read. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     The stream uses the default CRC32 algorithm, which implies a | ||||||
|  |         ///     polynomial of 0xEDB88320. | ||||||
|  |         ///   </para> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     Instances returned from this constructor will leave the underlying | ||||||
|  |         ///     stream open upon Close(). | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <param name="stream">The underlying stream</param> | ||||||
|  |         /// <param name="length">The length of the stream to slurp</param> | ||||||
|  |         public CrcCalculatorStream(System.IO.Stream stream, Int64 length) | ||||||
|  |             : this(true, length, stream, null) | ||||||
|  |         { | ||||||
|  |             if (length < 0) | ||||||
|  |                 throw new ArgumentException("length"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   A constructor allowing the specification of the length of the stream | ||||||
|  |         ///   to read, as well as whether to keep the underlying stream open upon | ||||||
|  |         ///   Close(). | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     The stream uses the default CRC32 algorithm, which implies a | ||||||
|  |         ///     polynomial of 0xEDB88320. | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <param name="stream">The underlying stream</param> | ||||||
|  |         /// <param name="length">The length of the stream to slurp</param> | ||||||
|  |         /// <param name="leaveOpen">true to leave the underlying stream | ||||||
|  |         /// open upon close of the <c>CrcCalculatorStream</c>; false otherwise.</param> | ||||||
|  |         public CrcCalculatorStream(System.IO.Stream stream, Int64 length, bool leaveOpen) | ||||||
|  |             : this(leaveOpen, length, stream, null) | ||||||
|  |         { | ||||||
|  |             if (length < 0) | ||||||
|  |                 throw new ArgumentException("length"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   A constructor allowing the specification of the length of the stream | ||||||
|  |         ///   to read, as well as whether to keep the underlying stream open upon | ||||||
|  |         ///   Close(), and the CRC32 instance to use. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     The stream uses the specified CRC32 instance, which allows the | ||||||
|  |         ///     application to specify how the CRC gets calculated. | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <param name="stream">The underlying stream</param> | ||||||
|  |         /// <param name="length">The length of the stream to slurp</param> | ||||||
|  |         /// <param name="leaveOpen">true to leave the underlying stream | ||||||
|  |         /// open upon close of the <c>CrcCalculatorStream</c>; false otherwise.</param> | ||||||
|  |         /// <param name="crc32">the CRC32 instance to use to calculate the CRC32</param> | ||||||
|  |         public CrcCalculatorStream(System.IO.Stream stream, Int64 length, bool leaveOpen, | ||||||
|  |                                    CRC32 crc32) | ||||||
|  |             : this(leaveOpen, length, stream, crc32) | ||||||
|  |         { | ||||||
|  |             if (length < 0) | ||||||
|  |                 throw new ArgumentException("length"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         // This ctor is private - no validation is done here.  This is to allow the use | ||||||
|  |         // of a (specific) negative value for the _lengthLimit, to indicate that there | ||||||
|  |         // is no length set.  So we validate the length limit in those ctors that use an | ||||||
|  |         // explicit param, otherwise we don't validate, because it could be our special | ||||||
|  |         // value. | ||||||
|  |         private CrcCalculatorStream | ||||||
|  |             (bool leaveOpen, Int64 length, System.IO.Stream stream, CRC32 crc32) | ||||||
|  |             : base() | ||||||
|  |         { | ||||||
|  |             _innerStream = stream; | ||||||
|  |             _Crc32 = crc32 ?? new CRC32(); | ||||||
|  |             _lengthLimit = length; | ||||||
|  |             _leaveOpen = leaveOpen; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Gets the total number of bytes run through the CRC32 calculator. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   This is either the total number of bytes read, or the total number of | ||||||
|  |         ///   bytes written, depending on the direction of this stream. | ||||||
|  |         /// </remarks> | ||||||
|  |         public Int64 TotalBytesSlurped | ||||||
|  |         { | ||||||
|  |             get { return _Crc32.TotalBytesRead; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Provides the current CRC for all blocks slurped in. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     The running total of the CRC is kept as data is written or read | ||||||
|  |         ///     through the stream.  read this property after all reads or writes to | ||||||
|  |         ///     get an accurate CRC for the entire stream. | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         public Int32 Crc | ||||||
|  |         { | ||||||
|  |             get { return _Crc32.Crc32Result; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Indicates whether the underlying stream will be left open when the | ||||||
|  |         ///   <c>CrcCalculatorStream</c> is Closed. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     Set this at any point before calling <see cref="Close()"/>. | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         public bool LeaveOpen | ||||||
|  |         { | ||||||
|  |             get { return _leaveOpen; } | ||||||
|  |             set { _leaveOpen = value; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Read from the stream | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="buffer">the buffer to read</param> | ||||||
|  |         /// <param name="offset">the offset at which to start</param> | ||||||
|  |         /// <param name="count">the number of bytes to read</param> | ||||||
|  |         /// <returns>the number of bytes actually read</returns> | ||||||
|  |         public override int Read(byte[] buffer, int offset, int count) | ||||||
|  |         { | ||||||
|  |             int bytesToRead = count; | ||||||
|  |  | ||||||
|  |             // Need to limit the # of bytes returned, if the stream is intended to have | ||||||
|  |             // a definite length.  This is especially useful when returning a stream for | ||||||
|  |             // the uncompressed data directly to the application.  The app won't | ||||||
|  |             // necessarily read only the UncompressedSize number of bytes.  For example | ||||||
|  |             // wrapping the stream returned from OpenReader() into a StreadReader() and | ||||||
|  |             // calling ReadToEnd() on it, We can "over-read" the zip data and get a | ||||||
|  |             // corrupt string.  The length limits that, prevents that problem. | ||||||
|  |  | ||||||
|  |             if (_lengthLimit != CrcCalculatorStream.UnsetLengthLimit) | ||||||
|  |             { | ||||||
|  |                 if (_Crc32.TotalBytesRead >= _lengthLimit) return 0; // EOF | ||||||
|  |                 Int64 bytesRemaining = _lengthLimit - _Crc32.TotalBytesRead; | ||||||
|  |                 if (bytesRemaining < count) bytesToRead = (int)bytesRemaining; | ||||||
|  |             } | ||||||
|  |             int n = _innerStream.Read(buffer, offset, bytesToRead); | ||||||
|  |             if (n > 0) _Crc32.SlurpBlock(buffer, offset, n); | ||||||
|  |             return n; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Write to the stream. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="buffer">the buffer from which to write</param> | ||||||
|  |         /// <param name="offset">the offset at which to start writing</param> | ||||||
|  |         /// <param name="count">the number of bytes to write</param> | ||||||
|  |         public override void Write(byte[] buffer, int offset, int count) | ||||||
|  |         { | ||||||
|  |             if (count > 0) _Crc32.SlurpBlock(buffer, offset, count); | ||||||
|  |             _innerStream.Write(buffer, offset, count); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Indicates whether the stream supports reading. | ||||||
|  |         /// </summary> | ||||||
|  |         public override bool CanRead | ||||||
|  |         { | ||||||
|  |             get { return _innerStream.CanRead; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Indicates whether the stream supports seeking. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     Always returns false. | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         public override bool CanSeek | ||||||
|  |         { | ||||||
|  |             get { return false; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Indicates whether the stream supports writing. | ||||||
|  |         /// </summary> | ||||||
|  |         public override bool CanWrite | ||||||
|  |         { | ||||||
|  |             get { return _innerStream.CanWrite; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Flush the stream. | ||||||
|  |         /// </summary> | ||||||
|  |         public override void Flush() | ||||||
|  |         { | ||||||
|  |             _innerStream.Flush(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Returns the length of the underlying stream. | ||||||
|  |         /// </summary> | ||||||
|  |         public override long Length | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 if (_lengthLimit == CrcCalculatorStream.UnsetLengthLimit) | ||||||
|  |                     return _innerStream.Length; | ||||||
|  |                 else return _lengthLimit; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   The getter for this property returns the total bytes read. | ||||||
|  |         ///   If you use the setter, it will throw | ||||||
|  |         /// <see cref="NotSupportedException"/>. | ||||||
|  |         /// </summary> | ||||||
|  |         public override long Position | ||||||
|  |         { | ||||||
|  |             get { return _Crc32.TotalBytesRead; } | ||||||
|  |             set { throw new NotSupportedException(); } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Seeking is not supported on this stream. This method always throws | ||||||
|  |         /// <see cref="NotSupportedException"/> | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="offset">N/A</param> | ||||||
|  |         /// <param name="origin">N/A</param> | ||||||
|  |         /// <returns>N/A</returns> | ||||||
|  |         public override long Seek(long offset, System.IO.SeekOrigin origin) | ||||||
|  |         { | ||||||
|  |             throw new NotSupportedException(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// This method always throws | ||||||
|  |         /// <see cref="NotSupportedException"/> | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="value">N/A</param> | ||||||
|  |         public override void SetLength(long value) | ||||||
|  |         { | ||||||
|  |             throw new NotSupportedException(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         void IDisposable.Dispose() | ||||||
|  |         { | ||||||
|  |             Close(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Closes the stream. | ||||||
|  |         /// </summary> | ||||||
|  |         public override void Close() | ||||||
|  |         { | ||||||
|  |             base.Close(); | ||||||
|  |             if (!_leaveOpen) | ||||||
|  |                 _innerStream.Close(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										1879
									
								
								src/ZlibAndroid/Deflate.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1879
									
								
								src/ZlibAndroid/Deflate.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										740
									
								
								src/ZlibAndroid/DeflateStream.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										740
									
								
								src/ZlibAndroid/DeflateStream.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,740 @@ | |||||||
|  | // DeflateStream.cs | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // Copyright (c) 2009-2010 Dino Chiesa. | ||||||
|  | // All rights reserved. | ||||||
|  | // | ||||||
|  | // This code module is part of DotNetZip, a zipfile class library. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This code is licensed under the Microsoft Public License. | ||||||
|  | // See the file License.txt for the license details. | ||||||
|  | // More info on: http://dotnetzip.codeplex.com | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // last saved (in emacs): | ||||||
|  | // Time-stamp: <2011-July-31 14:48:11> | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This module defines the DeflateStream class, which can be used as a replacement for | ||||||
|  | // the System.IO.Compression.DeflateStream class in the .NET BCL. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | using System; | ||||||
|  |  | ||||||
|  | namespace Ionic.Zlib | ||||||
|  | { | ||||||
|  |     /// <summary> | ||||||
|  |     /// A class for compressing and decompressing streams using the Deflate algorithm. | ||||||
|  |     /// </summary> | ||||||
|  |     /// | ||||||
|  |     /// <remarks> | ||||||
|  |     /// | ||||||
|  |     /// <para> | ||||||
|  |     ///   The DeflateStream is a <see | ||||||
|  |     ///   href="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator</see> on a <see | ||||||
|  |     ///   cref="System.IO.Stream"/>.  It adds DEFLATE compression or decompression to any | ||||||
|  |     ///   stream. | ||||||
|  |     /// </para> | ||||||
|  |     /// | ||||||
|  |     /// <para> | ||||||
|  |     ///   Using this stream, applications can compress or decompress data via stream | ||||||
|  |     ///   <c>Read</c> and <c>Write</c> operations.  Either compresssion or decompression | ||||||
|  |     ///   can occur through either reading or writing. The compression format used is | ||||||
|  |     ///   DEFLATE, which is documented in <see | ||||||
|  |     ///   href="http://www.ietf.org/rfc/rfc1951.txt">IETF RFC 1951</see>, "DEFLATE | ||||||
|  |     ///   Compressed Data Format Specification version 1.3.". | ||||||
|  |     /// </para> | ||||||
|  |     /// | ||||||
|  |     /// <para> | ||||||
|  |     ///   This class is similar to <see cref="ZlibStream"/>, except that | ||||||
|  |     ///   <c>ZlibStream</c> adds the <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC | ||||||
|  |     ///   1950 - ZLIB</see> framing bytes to a compressed stream when compressing, or | ||||||
|  |     ///   expects the RFC1950 framing bytes when decompressing. The <c>DeflateStream</c> | ||||||
|  |     ///   does not. | ||||||
|  |     /// </para> | ||||||
|  |     /// | ||||||
|  |     /// </remarks> | ||||||
|  |     /// | ||||||
|  |     /// <seealso cref="ZlibStream" /> | ||||||
|  |     /// <seealso cref="GZipStream" /> | ||||||
|  |     public class DeflateStream : System.IO.Stream | ||||||
|  |     { | ||||||
|  |         internal ZlibBaseStream _baseStream; | ||||||
|  |         internal System.IO.Stream _innerStream; | ||||||
|  |         bool _disposed; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Create a DeflateStream using the specified CompressionMode. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   When mode is <c>CompressionMode.Compress</c>, the DeflateStream will use | ||||||
|  |         ///   the default compression level. The "captive" stream will be closed when | ||||||
|  |         ///   the DeflateStream is closed. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <example> | ||||||
|  |         /// This example uses a DeflateStream to compress data from a file, and writes | ||||||
|  |         /// the compressed data to another file. | ||||||
|  |         /// <code> | ||||||
|  |         /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) | ||||||
|  |         /// { | ||||||
|  |         ///     using (var raw = System.IO.File.Create(fileToCompress + ".deflated")) | ||||||
|  |         ///     { | ||||||
|  |         ///         using (Stream compressor = new DeflateStream(raw, CompressionMode.Compress)) | ||||||
|  |         ///         { | ||||||
|  |         ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE]; | ||||||
|  |         ///             int n; | ||||||
|  |         ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0) | ||||||
|  |         ///             { | ||||||
|  |         ///                 compressor.Write(buffer, 0, n); | ||||||
|  |         ///             } | ||||||
|  |         ///         } | ||||||
|  |         ///     } | ||||||
|  |         /// } | ||||||
|  |         /// </code> | ||||||
|  |         /// | ||||||
|  |         /// <code lang="VB"> | ||||||
|  |         /// Using input As Stream = File.OpenRead(fileToCompress) | ||||||
|  |         ///     Using raw As FileStream = File.Create(fileToCompress & ".deflated") | ||||||
|  |         ///         Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress) | ||||||
|  |         ///             Dim buffer As Byte() = New Byte(4096) {} | ||||||
|  |         ///             Dim n As Integer = -1 | ||||||
|  |         ///             Do While (n <> 0) | ||||||
|  |         ///                 If (n > 0) Then | ||||||
|  |         ///                     compressor.Write(buffer, 0, n) | ||||||
|  |         ///                 End If | ||||||
|  |         ///                 n = input.Read(buffer, 0, buffer.Length) | ||||||
|  |         ///             Loop | ||||||
|  |         ///         End Using | ||||||
|  |         ///     End Using | ||||||
|  |         /// End Using | ||||||
|  |         /// </code> | ||||||
|  |         /// </example> | ||||||
|  |         /// <param name="stream">The stream which will be read or written.</param> | ||||||
|  |         /// <param name="mode">Indicates whether the DeflateStream will compress or decompress.</param> | ||||||
|  |         public DeflateStream(System.IO.Stream stream, CompressionMode mode) | ||||||
|  |             : this(stream, mode, CompressionLevel.Default, false) | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Create a DeflateStream using the specified CompressionMode and the specified CompressionLevel. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   When mode is <c>CompressionMode.Decompress</c>, the level parameter is | ||||||
|  |         ///   ignored.  The "captive" stream will be closed when the DeflateStream is | ||||||
|  |         ///   closed. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <example> | ||||||
|  |         /// | ||||||
|  |         ///   This example uses a DeflateStream to compress data from a file, and writes | ||||||
|  |         ///   the compressed data to another file. | ||||||
|  |         /// | ||||||
|  |         /// <code> | ||||||
|  |         /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) | ||||||
|  |         /// { | ||||||
|  |         ///     using (var raw = System.IO.File.Create(fileToCompress + ".deflated")) | ||||||
|  |         ///     { | ||||||
|  |         ///         using (Stream compressor = new DeflateStream(raw, | ||||||
|  |         ///                                                      CompressionMode.Compress, | ||||||
|  |         ///                                                      CompressionLevel.BestCompression)) | ||||||
|  |         ///         { | ||||||
|  |         ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE]; | ||||||
|  |         ///             int n= -1; | ||||||
|  |         ///             while (n != 0) | ||||||
|  |         ///             { | ||||||
|  |         ///                 if (n > 0) | ||||||
|  |         ///                     compressor.Write(buffer, 0, n); | ||||||
|  |         ///                 n= input.Read(buffer, 0, buffer.Length); | ||||||
|  |         ///             } | ||||||
|  |         ///         } | ||||||
|  |         ///     } | ||||||
|  |         /// } | ||||||
|  |         /// </code> | ||||||
|  |         /// | ||||||
|  |         /// <code lang="VB"> | ||||||
|  |         /// Using input As Stream = File.OpenRead(fileToCompress) | ||||||
|  |         ///     Using raw As FileStream = File.Create(fileToCompress & ".deflated") | ||||||
|  |         ///         Using compressor As Stream = New DeflateStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression) | ||||||
|  |         ///             Dim buffer As Byte() = New Byte(4096) {} | ||||||
|  |         ///             Dim n As Integer = -1 | ||||||
|  |         ///             Do While (n <> 0) | ||||||
|  |         ///                 If (n > 0) Then | ||||||
|  |         ///                     compressor.Write(buffer, 0, n) | ||||||
|  |         ///                 End If | ||||||
|  |         ///                 n = input.Read(buffer, 0, buffer.Length) | ||||||
|  |         ///             Loop | ||||||
|  |         ///         End Using | ||||||
|  |         ///     End Using | ||||||
|  |         /// End Using | ||||||
|  |         /// </code> | ||||||
|  |         /// </example> | ||||||
|  |         /// <param name="stream">The stream to be read or written while deflating or inflating.</param> | ||||||
|  |         /// <param name="mode">Indicates whether the <c>DeflateStream</c> will compress or decompress.</param> | ||||||
|  |         /// <param name="level">A tuning knob to trade speed for effectiveness.</param> | ||||||
|  |         public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level) | ||||||
|  |             : this(stream, mode, level, false) | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Create a <c>DeflateStream</c> using the specified | ||||||
|  |         ///   <c>CompressionMode</c>, and explicitly specify whether the | ||||||
|  |         ///   stream should be left open after Deflation or Inflation. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   This constructor allows the application to request that the captive stream | ||||||
|  |         ///   remain open after the deflation or inflation occurs.  By default, after | ||||||
|  |         ///   <c>Close()</c> is called on the stream, the captive stream is also | ||||||
|  |         ///   closed. In some cases this is not desired, for example if the stream is a | ||||||
|  |         ///   memory stream that will be re-read after compression.  Specify true for | ||||||
|  |         ///   the <paramref name="leaveOpen"/> parameter to leave the stream open. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   The <c>DeflateStream</c> will use the default compression level. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   See the other overloads of this constructor for example code. | ||||||
|  |         /// </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <param name="stream"> | ||||||
|  |         ///   The stream which will be read or written. This is called the | ||||||
|  |         ///   "captive" stream in other places in this documentation. | ||||||
|  |         /// </param> | ||||||
|  |         /// | ||||||
|  |         /// <param name="mode"> | ||||||
|  |         ///   Indicates whether the <c>DeflateStream</c> will compress or decompress. | ||||||
|  |         /// </param> | ||||||
|  |         /// | ||||||
|  |         /// <param name="leaveOpen">true if the application would like the stream to | ||||||
|  |         /// remain open after inflation/deflation.</param> | ||||||
|  |         public DeflateStream(System.IO.Stream stream, CompressionMode mode, bool leaveOpen) | ||||||
|  |             : this(stream, mode, CompressionLevel.Default, leaveOpen) | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Create a <c>DeflateStream</c> using the specified <c>CompressionMode</c> | ||||||
|  |         ///   and the specified <c>CompressionLevel</c>, and explicitly specify whether | ||||||
|  |         ///   the stream should be left open after Deflation or Inflation. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   When mode is <c>CompressionMode.Decompress</c>, the level parameter is ignored. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   This constructor allows the application to request that the captive stream | ||||||
|  |         ///   remain open after the deflation or inflation occurs.  By default, after | ||||||
|  |         ///   <c>Close()</c> is called on the stream, the captive stream is also | ||||||
|  |         ///   closed. In some cases this is not desired, for example if the stream is a | ||||||
|  |         ///   <see cref="System.IO.MemoryStream"/> that will be re-read after | ||||||
|  |         ///   compression.  Specify true for the <paramref name="leaveOpen"/> parameter | ||||||
|  |         ///   to leave the stream open. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <example> | ||||||
|  |         /// | ||||||
|  |         ///   This example shows how to use a <c>DeflateStream</c> to compress data from | ||||||
|  |         ///   a file, and store the compressed data into another file. | ||||||
|  |         /// | ||||||
|  |         /// <code> | ||||||
|  |         /// using (var output = System.IO.File.Create(fileToCompress + ".deflated")) | ||||||
|  |         /// { | ||||||
|  |         ///     using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) | ||||||
|  |         ///     { | ||||||
|  |         ///         using (Stream compressor = new DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true)) | ||||||
|  |         ///         { | ||||||
|  |         ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE]; | ||||||
|  |         ///             int n= -1; | ||||||
|  |         ///             while (n != 0) | ||||||
|  |         ///             { | ||||||
|  |         ///                 if (n > 0) | ||||||
|  |         ///                     compressor.Write(buffer, 0, n); | ||||||
|  |         ///                 n= input.Read(buffer, 0, buffer.Length); | ||||||
|  |         ///             } | ||||||
|  |         ///         } | ||||||
|  |         ///     } | ||||||
|  |         ///     // can write additional data to the output stream here | ||||||
|  |         /// } | ||||||
|  |         /// </code> | ||||||
|  |         /// | ||||||
|  |         /// <code lang="VB"> | ||||||
|  |         /// Using output As FileStream = File.Create(fileToCompress & ".deflated") | ||||||
|  |         ///     Using input As Stream = File.OpenRead(fileToCompress) | ||||||
|  |         ///         Using compressor As Stream = New DeflateStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True) | ||||||
|  |         ///             Dim buffer As Byte() = New Byte(4096) {} | ||||||
|  |         ///             Dim n As Integer = -1 | ||||||
|  |         ///             Do While (n <> 0) | ||||||
|  |         ///                 If (n > 0) Then | ||||||
|  |         ///                     compressor.Write(buffer, 0, n) | ||||||
|  |         ///                 End If | ||||||
|  |         ///                 n = input.Read(buffer, 0, buffer.Length) | ||||||
|  |         ///             Loop | ||||||
|  |         ///         End Using | ||||||
|  |         ///     End Using | ||||||
|  |         ///     ' can write additional data to the output stream here. | ||||||
|  |         /// End Using | ||||||
|  |         /// </code> | ||||||
|  |         /// </example> | ||||||
|  |         /// <param name="stream">The stream which will be read or written.</param> | ||||||
|  |         /// <param name="mode">Indicates whether the DeflateStream will compress or decompress.</param> | ||||||
|  |         /// <param name="leaveOpen">true if the application would like the stream to remain open after inflation/deflation.</param> | ||||||
|  |         /// <param name="level">A tuning knob to trade speed for effectiveness.</param> | ||||||
|  |         public DeflateStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen) | ||||||
|  |         { | ||||||
|  |             _innerStream = stream; | ||||||
|  |             _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.DEFLATE, leaveOpen); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         #region Zlib properties | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// This property sets the flush behavior on the stream. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> See the ZLIB documentation for the meaning of the flush behavior. | ||||||
|  |         /// </remarks> | ||||||
|  |         virtual public FlushType FlushMode | ||||||
|  |         { | ||||||
|  |             get { return (this._baseStream._flushMode); } | ||||||
|  |             set | ||||||
|  |             { | ||||||
|  |                 if (_disposed) throw new ObjectDisposedException("DeflateStream"); | ||||||
|  |                 this._baseStream._flushMode = value; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   The size of the working buffer for the compression codec. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         /// <para> | ||||||
|  |         ///   The working buffer is used for all stream operations.  The default size is | ||||||
|  |         ///   1024 bytes.  The minimum size is 128 bytes. You may get better performance | ||||||
|  |         ///   with a larger buffer.  Then again, you might not.  You would have to test | ||||||
|  |         ///   it. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   Set this before the first call to <c>Read()</c> or <c>Write()</c> on the | ||||||
|  |         ///   stream. If you try to set it afterwards, it will throw. | ||||||
|  |         /// </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         public int BufferSize | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 return this._baseStream._bufferSize; | ||||||
|  |             } | ||||||
|  |             set | ||||||
|  |             { | ||||||
|  |                 if (_disposed) throw new ObjectDisposedException("DeflateStream"); | ||||||
|  |                 if (this._baseStream._workingBuffer != null) | ||||||
|  |                     throw new ZlibException("The working buffer is already set."); | ||||||
|  |                 if (value < ZlibConstants.WorkingBufferSizeMin) | ||||||
|  |                     throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin)); | ||||||
|  |                 this._baseStream._bufferSize = value; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   The ZLIB strategy to be used during compression. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   By tweaking this parameter, you may be able to optimize the compression for | ||||||
|  |         ///   data with particular characteristics. | ||||||
|  |         /// </remarks> | ||||||
|  |         public CompressionStrategy Strategy | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 return this._baseStream.Strategy; | ||||||
|  |             } | ||||||
|  |             set | ||||||
|  |             { | ||||||
|  |             if (_disposed) throw new ObjectDisposedException("DeflateStream"); | ||||||
|  |                 this._baseStream.Strategy = value; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> Returns the total number of bytes input so far.</summary> | ||||||
|  |         virtual public long TotalIn | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 return this._baseStream._z.TotalBytesIn; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> Returns the total number of bytes output so far.</summary> | ||||||
|  |         virtual public long TotalOut | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 return this._baseStream._z.TotalBytesOut; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         #endregion | ||||||
|  |  | ||||||
|  |         #region System.IO.Stream methods | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Dispose the stream. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     This may or may not result in a <c>Close()</c> call on the captive | ||||||
|  |         ///     stream.  See the constructors that have a <c>leaveOpen</c> parameter | ||||||
|  |         ///     for more information. | ||||||
|  |         ///   </para> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     Application code won't call this code directly.  This method may be | ||||||
|  |         ///     invoked in two distinct scenarios.  If disposing == true, the method | ||||||
|  |         ///     has been called directly or indirectly by a user's code, for example | ||||||
|  |         ///     via the public Dispose() method. In this case, both managed and | ||||||
|  |         ///     unmanaged resources can be referenced and disposed.  If disposing == | ||||||
|  |         ///     false, the method has been called by the runtime from inside the | ||||||
|  |         ///     object finalizer and this method should not reference other objects; | ||||||
|  |         ///     in that case only unmanaged resources must be referenced or | ||||||
|  |         ///     disposed. | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <param name="disposing"> | ||||||
|  |         ///   true if the Dispose method was invoked by user code. | ||||||
|  |         /// </param> | ||||||
|  |         protected override void Dispose(bool disposing) | ||||||
|  |         { | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 if (!_disposed) | ||||||
|  |                 { | ||||||
|  |                     if (disposing && (this._baseStream != null)) | ||||||
|  |                         this._baseStream.Close(); | ||||||
|  |                     _disposed = true; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             finally | ||||||
|  |             { | ||||||
|  |                 base.Dispose(disposing); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Indicates whether the stream can be read. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// The return value depends on whether the captive stream supports reading. | ||||||
|  |         /// </remarks> | ||||||
|  |         public override bool CanRead | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 if (_disposed) throw new ObjectDisposedException("DeflateStream"); | ||||||
|  |                 return _baseStream._stream.CanRead; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Indicates whether the stream supports Seek operations. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// Always returns false. | ||||||
|  |         /// </remarks> | ||||||
|  |         public override bool CanSeek | ||||||
|  |         { | ||||||
|  |             get { return false; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Indicates whether the stream can be written. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// The return value depends on whether the captive stream supports writing. | ||||||
|  |         /// </remarks> | ||||||
|  |         public override bool CanWrite | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 if (_disposed) throw new ObjectDisposedException("DeflateStream"); | ||||||
|  |                 return _baseStream._stream.CanWrite; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Flush the stream. | ||||||
|  |         /// </summary> | ||||||
|  |         public override void Flush() | ||||||
|  |         { | ||||||
|  |             if (_disposed) throw new ObjectDisposedException("DeflateStream"); | ||||||
|  |             _baseStream.Flush(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Reading this property always throws a <see cref="NotImplementedException"/>. | ||||||
|  |         /// </summary> | ||||||
|  |         public override long Length | ||||||
|  |         { | ||||||
|  |             get { throw new NotImplementedException(); } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The position of the stream pointer. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   Setting this property always throws a <see | ||||||
|  |         ///   cref="NotImplementedException"/>. Reading will return the total bytes | ||||||
|  |         ///   written out, if used in writing, or the total bytes read in, if used in | ||||||
|  |         ///   reading.  The count may refer to compressed bytes or uncompressed bytes, | ||||||
|  |         ///   depending on how you've used the stream. | ||||||
|  |         /// </remarks> | ||||||
|  |         public override long Position | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Writer) | ||||||
|  |                     return this._baseStream._z.TotalBytesOut; | ||||||
|  |                 if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Reader) | ||||||
|  |                     return this._baseStream._z.TotalBytesIn; | ||||||
|  |                 return 0; | ||||||
|  |             } | ||||||
|  |             set { throw new NotImplementedException(); } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Read data from the stream. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   If you wish to use the <c>DeflateStream</c> to compress data while | ||||||
|  |         ///   reading, you can create a <c>DeflateStream</c> with | ||||||
|  |         ///   <c>CompressionMode.Compress</c>, providing an uncompressed data stream. | ||||||
|  |         ///   Then call Read() on that <c>DeflateStream</c>, and the data read will be | ||||||
|  |         ///   compressed as you read.  If you wish to use the <c>DeflateStream</c> to | ||||||
|  |         ///   decompress data while reading, you can create a <c>DeflateStream</c> with | ||||||
|  |         ///   <c>CompressionMode.Decompress</c>, providing a readable compressed data | ||||||
|  |         ///   stream.  Then call Read() on that <c>DeflateStream</c>, and the data read | ||||||
|  |         ///   will be decompressed as you read. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   A <c>DeflateStream</c> can be used for <c>Read()</c> or <c>Write()</c>, but not both. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <param name="buffer">The buffer into which the read data should be placed.</param> | ||||||
|  |         /// <param name="offset">the offset within that data array to put the first byte read.</param> | ||||||
|  |         /// <param name="count">the number of bytes to read.</param> | ||||||
|  |         /// <returns>the number of bytes actually read</returns> | ||||||
|  |         public override int Read(byte[] buffer, int offset, int count) | ||||||
|  |         { | ||||||
|  |             if (_disposed) throw new ObjectDisposedException("DeflateStream"); | ||||||
|  |             return _baseStream.Read(buffer, offset, count); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Calling this method always throws a <see cref="NotImplementedException"/>. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="offset">this is irrelevant, since it will always throw!</param> | ||||||
|  |         /// <param name="origin">this is irrelevant, since it will always throw!</param> | ||||||
|  |         /// <returns>irrelevant!</returns> | ||||||
|  |         public override long Seek(long offset, System.IO.SeekOrigin origin) | ||||||
|  |         { | ||||||
|  |             throw new NotImplementedException(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Calling this method always throws a <see cref="NotImplementedException"/>. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="value">this is irrelevant, since it will always throw!</param> | ||||||
|  |         public override void SetLength(long value) | ||||||
|  |         { | ||||||
|  |             throw new NotImplementedException(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Write data to the stream. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   If you wish to use the <c>DeflateStream</c> to compress data while | ||||||
|  |         ///   writing, you can create a <c>DeflateStream</c> with | ||||||
|  |         ///   <c>CompressionMode.Compress</c>, and a writable output stream.  Then call | ||||||
|  |         ///   <c>Write()</c> on that <c>DeflateStream</c>, providing uncompressed data | ||||||
|  |         ///   as input.  The data sent to the output stream will be the compressed form | ||||||
|  |         ///   of the data written.  If you wish to use the <c>DeflateStream</c> to | ||||||
|  |         ///   decompress data while writing, you can create a <c>DeflateStream</c> with | ||||||
|  |         ///   <c>CompressionMode.Decompress</c>, and a writable output stream.  Then | ||||||
|  |         ///   call <c>Write()</c> on that stream, providing previously compressed | ||||||
|  |         ///   data. The data sent to the output stream will be the decompressed form of | ||||||
|  |         ///   the data written. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   A <c>DeflateStream</c> can be used for <c>Read()</c> or <c>Write()</c>, | ||||||
|  |         ///   but not both. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <param name="buffer">The buffer holding data to write to the stream.</param> | ||||||
|  |         /// <param name="offset">the offset within that data array to find the first byte to write.</param> | ||||||
|  |         /// <param name="count">the number of bytes to write.</param> | ||||||
|  |         public override void Write(byte[] buffer, int offset, int count) | ||||||
|  |         { | ||||||
|  |             if (_disposed) throw new ObjectDisposedException("DeflateStream"); | ||||||
|  |             _baseStream.Write(buffer, offset, count); | ||||||
|  |         } | ||||||
|  |         #endregion | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Compress a string into a byte array using DEFLATE (RFC 1951). | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   Uncompress it with <see cref="DeflateStream.UncompressString(byte[])"/>. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <seealso cref="DeflateStream.UncompressString(byte[])">DeflateStream.UncompressString(byte[])</seealso> | ||||||
|  |         /// <seealso cref="DeflateStream.CompressBuffer(byte[])">DeflateStream.CompressBuffer(byte[])</seealso> | ||||||
|  |         /// <seealso cref="GZipStream.CompressString(string)">GZipStream.CompressString(string)</seealso> | ||||||
|  |         /// <seealso cref="ZlibStream.CompressString(string)">ZlibStream.CompressString(string)</seealso> | ||||||
|  |         /// | ||||||
|  |         /// <param name="s"> | ||||||
|  |         ///   A string to compress. The string will first be encoded | ||||||
|  |         ///   using UTF8, then compressed. | ||||||
|  |         /// </param> | ||||||
|  |         /// | ||||||
|  |         /// <returns>The string in compressed form</returns> | ||||||
|  |         public static byte[] CompressString(String s) | ||||||
|  |         { | ||||||
|  |             using (var ms = new System.IO.MemoryStream()) | ||||||
|  |             { | ||||||
|  |                 System.IO.Stream compressor = | ||||||
|  |                     new DeflateStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression); | ||||||
|  |                 ZlibBaseStream.CompressString(s, compressor); | ||||||
|  |                 return ms.ToArray(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Compress a byte array into a new byte array using DEFLATE. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   Uncompress it with <see cref="DeflateStream.UncompressBuffer(byte[])"/>. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <seealso cref="DeflateStream.CompressString(string)">DeflateStream.CompressString(string)</seealso> | ||||||
|  |         /// <seealso cref="DeflateStream.UncompressBuffer(byte[])">DeflateStream.UncompressBuffer(byte[])</seealso> | ||||||
|  |         /// <seealso cref="GZipStream.CompressBuffer(byte[])">GZipStream.CompressBuffer(byte[])</seealso> | ||||||
|  |         /// <seealso cref="ZlibStream.CompressBuffer(byte[])">ZlibStream.CompressBuffer(byte[])</seealso> | ||||||
|  |         /// | ||||||
|  |         /// <param name="b"> | ||||||
|  |         ///   A buffer to compress. | ||||||
|  |         /// </param> | ||||||
|  |         /// | ||||||
|  |         /// <returns>The data in compressed form</returns> | ||||||
|  |         public static byte[] CompressBuffer(byte[] b) | ||||||
|  |         { | ||||||
|  |             using (var ms = new System.IO.MemoryStream()) | ||||||
|  |             { | ||||||
|  |                 System.IO.Stream compressor = | ||||||
|  |                     new DeflateStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression ); | ||||||
|  |  | ||||||
|  |                 ZlibBaseStream.CompressBuffer(b, compressor); | ||||||
|  |                 return ms.ToArray(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Uncompress a DEFLATE'd byte array into a single string. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <seealso cref="DeflateStream.CompressString(String)">DeflateStream.CompressString(String)</seealso> | ||||||
|  |         /// <seealso cref="DeflateStream.UncompressBuffer(byte[])">DeflateStream.UncompressBuffer(byte[])</seealso> | ||||||
|  |         /// <seealso cref="GZipStream.UncompressString(byte[])">GZipStream.UncompressString(byte[])</seealso> | ||||||
|  |         /// <seealso cref="ZlibStream.UncompressString(byte[])">ZlibStream.UncompressString(byte[])</seealso> | ||||||
|  |         /// | ||||||
|  |         /// <param name="compressed"> | ||||||
|  |         ///   A buffer containing DEFLATE-compressed data. | ||||||
|  |         /// </param> | ||||||
|  |         /// | ||||||
|  |         /// <returns>The uncompressed string</returns> | ||||||
|  |         public static String UncompressString(byte[] compressed) | ||||||
|  |         { | ||||||
|  |             using (var input = new System.IO.MemoryStream(compressed)) | ||||||
|  |             { | ||||||
|  |                 System.IO.Stream decompressor = | ||||||
|  |                     new DeflateStream(input, CompressionMode.Decompress); | ||||||
|  |  | ||||||
|  |                 return ZlibBaseStream.UncompressString(compressed, decompressor); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Uncompress a DEFLATE'd byte array into a byte array. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <seealso cref="DeflateStream.CompressBuffer(byte[])">DeflateStream.CompressBuffer(byte[])</seealso> | ||||||
|  |         /// <seealso cref="DeflateStream.UncompressString(byte[])">DeflateStream.UncompressString(byte[])</seealso> | ||||||
|  |         /// <seealso cref="GZipStream.UncompressBuffer(byte[])">GZipStream.UncompressBuffer(byte[])</seealso> | ||||||
|  |         /// <seealso cref="ZlibStream.UncompressBuffer(byte[])">ZlibStream.UncompressBuffer(byte[])</seealso> | ||||||
|  |         /// | ||||||
|  |         /// <param name="compressed"> | ||||||
|  |         ///   A buffer containing data that has been compressed with DEFLATE. | ||||||
|  |         /// </param> | ||||||
|  |         /// | ||||||
|  |         /// <returns>The data in uncompressed form</returns> | ||||||
|  |         public static byte[] UncompressBuffer(byte[] compressed) | ||||||
|  |         { | ||||||
|  |             using (var input = new System.IO.MemoryStream(compressed)) | ||||||
|  |             { | ||||||
|  |                 System.IO.Stream decompressor = | ||||||
|  |                     new DeflateStream( input, CompressionMode.Decompress ); | ||||||
|  |  | ||||||
|  |                 return ZlibBaseStream.UncompressBuffer(compressed, decompressor); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										1033
									
								
								src/ZlibAndroid/GZipStream.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1033
									
								
								src/ZlibAndroid/GZipStream.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										436
									
								
								src/ZlibAndroid/InfTree.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										436
									
								
								src/ZlibAndroid/InfTree.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,436 @@ | |||||||
|  | // Inftree.cs | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.   | ||||||
|  | // All rights reserved. | ||||||
|  | // | ||||||
|  | // This code module is part of DotNetZip, a zipfile class library. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This code is licensed under the Microsoft Public License.  | ||||||
|  | // See the file License.txt for the license details. | ||||||
|  | // More info on: http://dotnetzip.codeplex.com | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // last saved (in emacs):  | ||||||
|  | // Time-stamp: <2009-October-28 12:43:54> | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This module defines classes used in  decompression. This code is derived | ||||||
|  | // from the jzlib implementation of zlib. In keeping with the license for jzlib,  | ||||||
|  | // the copyright to that code is below. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | //  | ||||||
|  | // Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. | ||||||
|  | //  | ||||||
|  | // Redistribution and use in source and binary forms, with or without | ||||||
|  | // modification, are permitted provided that the following conditions are met: | ||||||
|  | //  | ||||||
|  | // 1. Redistributions of source code must retain the above copyright notice, | ||||||
|  | // this list of conditions and the following disclaimer. | ||||||
|  | //  | ||||||
|  | // 2. Redistributions in binary form must reproduce the above copyright  | ||||||
|  | // notice, this list of conditions and the following disclaimer in  | ||||||
|  | // the documentation and/or other materials provided with the distribution. | ||||||
|  | //  | ||||||
|  | // 3. The names of the authors may not be used to endorse or promote products | ||||||
|  | // derived from this software without specific prior written permission. | ||||||
|  | //  | ||||||
|  | // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, | ||||||
|  | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, | ||||||
|  | // INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||||
|  | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||||
|  | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, | ||||||
|  | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||||||
|  | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||||||
|  | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||||||
|  | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
|  | //  | ||||||
|  | // ----------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // This program is based on zlib-1.1.3; credit to authors | ||||||
|  | // Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) | ||||||
|  | // and contributors of zlib. | ||||||
|  | // | ||||||
|  | // ----------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | using System; | ||||||
|  | namespace Ionic.Zlib | ||||||
|  | { | ||||||
|  |          | ||||||
|  |         sealed class InfTree | ||||||
|  |         { | ||||||
|  |                  | ||||||
|  |                 private const int MANY = 1440; | ||||||
|  |                  | ||||||
|  |                 private const int Z_OK = 0; | ||||||
|  |                 private const int Z_STREAM_END = 1; | ||||||
|  |                 private const int Z_NEED_DICT = 2; | ||||||
|  |                 private const int Z_ERRNO = - 1; | ||||||
|  |                 private const int Z_STREAM_ERROR = - 2; | ||||||
|  |                 private const int Z_DATA_ERROR = - 3; | ||||||
|  |                 private const int Z_MEM_ERROR = - 4; | ||||||
|  |                 private const int Z_BUF_ERROR = - 5; | ||||||
|  |                 private const int Z_VERSION_ERROR = - 6; | ||||||
|  |                  | ||||||
|  |                 internal const int fixed_bl = 9; | ||||||
|  |                 internal const int fixed_bd = 5; | ||||||
|  |                  | ||||||
|  |                 //UPGRADE_NOTE: Final was removed from the declaration of 'fixed_tl'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" | ||||||
|  |                 internal static readonly int[] fixed_tl = new int[]{96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 192, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 160, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 224, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 144, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 208, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 176, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 240, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 200, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 168, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 232, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 152, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 216, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 184, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 248, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 196, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 164, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 228, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 148, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 212, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 180, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 244, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 204, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 172, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 236, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 156, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 220, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 188, 0, 8, 14, 0, 8, 142, 0, 8, 78, 0, 9, 252, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 194, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 162, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 226, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 146, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 210, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 178, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 242, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 202, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 170, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 234, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 154, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 218, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 186,  | ||||||
|  |                         0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 250, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 198, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 166, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 230, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 150, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 214, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 182, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 246, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 206, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 174, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 238, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 158, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 222, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 190, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 254, 96, 7, 256, 0, 8, 80, 0, 8, 16, 84, 8, 115, 82, 7, 31, 0, 8, 112, 0, 8, 48, 0, 9, 193, 80, 7, 10, 0, 8, 96, 0, 8, 32, 0, 9, 161, 0, 8, 0, 0, 8, 128, 0, 8, 64, 0, 9, 225, 80, 7, 6, 0, 8, 88, 0, 8, 24, 0, 9, 145, 83, 7, 59, 0, 8, 120, 0, 8, 56, 0, 9, 209, 81, 7, 17, 0, 8, 104, 0, 8, 40, 0, 9, 177, 0, 8, 8, 0, 8, 136, 0, 8, 72, 0, 9, 241, 80, 7, 4, 0, 8, 84, 0, 8, 20, 85, 8, 227, 83, 7, 43, 0, 8, 116, 0, 8, 52, 0, 9, 201, 81, 7, 13, 0, 8, 100, 0, 8, 36, 0, 9, 169, 0, 8, 4, 0, 8, 132, 0, 8, 68, 0, 9, 233, 80, 7, 8, 0, 8, 92, 0, 8, 28, 0, 9, 153, 84, 7, 83, 0, 8, 124, 0, 8, 60, 0, 9, 217, 82, 7, 23, 0, 8, 108, 0, 8, 44, 0, 9, 185, 0, 8, 12, 0, 8, 140, 0, 8, 76, 0, 9, 249, 80, 7, 3, 0, 8, 82, 0, 8, 18, 85, 8, 163, 83, 7, 35, 0, 8, 114, 0, 8, 50, 0, 9, 197, 81, 7, 11, 0, 8, 98, 0, 8, 34, 0, 9, 165, 0, 8, 2, 0, 8, 130, 0, 8, 66, 0, 9, 229, 80, 7, 7, 0, 8, 90, 0, 8, 26, 0, 9, 149, 84, 7, 67, 0, 8, 122, 0, 8, 58, 0, 9, 213, 82, 7, 19, 0, 8, 106, 0, 8, 42, 0, 9, 181, 0, 8, 10, 0, 8, 138, 0, 8, 74, 0, 9, 245, 80, 7, 5, 0, 8, 86, 0, 8, 22, 192, 8, 0, 83, 7, 51, 0, 8, 118, 0, 8, 54, 0, 9, 205, 81, 7, 15, 0, 8, 102, 0, 8, 38, 0, 9, 173, 0, 8, 6, 0, 8, 134, 0, 8, 70, 0, 9, 237, 80, 7, 9, 0, 8, 94, 0, 8, 30, 0, 9, 157, 84, 7, 99, 0, 8, 126, 0, 8, 62, 0, 9, 221, 82, 7, 27, 0, 8, 110, 0, 8, 46, 0, 9, 189, 0, 8,  | ||||||
|  |                         14, 0, 8, 142, 0, 8, 78, 0, 9, 253, 96, 7, 256, 0, 8, 81, 0, 8, 17, 85, 8, 131, 82, 7, 31, 0, 8, 113, 0, 8, 49, 0, 9, 195, 80, 7, 10, 0, 8, 97, 0, 8, 33, 0, 9, 163, 0, 8, 1, 0, 8, 129, 0, 8, 65, 0, 9, 227, 80, 7, 6, 0, 8, 89, 0, 8, 25, 0, 9, 147, 83, 7, 59, 0, 8, 121, 0, 8, 57, 0, 9, 211, 81, 7, 17, 0, 8, 105, 0, 8, 41, 0, 9, 179, 0, 8, 9, 0, 8, 137, 0, 8, 73, 0, 9, 243, 80, 7, 4, 0, 8, 85, 0, 8, 21, 80, 8, 258, 83, 7, 43, 0, 8, 117, 0, 8, 53, 0, 9, 203, 81, 7, 13, 0, 8, 101, 0, 8, 37, 0, 9, 171, 0, 8, 5, 0, 8, 133, 0, 8, 69, 0, 9, 235, 80, 7, 8, 0, 8, 93, 0, 8, 29, 0, 9, 155, 84, 7, 83, 0, 8, 125, 0, 8, 61, 0, 9, 219, 82, 7, 23, 0, 8, 109, 0, 8, 45, 0, 9, 187, 0, 8, 13, 0, 8, 141, 0, 8, 77, 0, 9, 251, 80, 7, 3, 0, 8, 83, 0, 8, 19, 85, 8, 195, 83, 7, 35, 0, 8, 115, 0, 8, 51, 0, 9, 199, 81, 7, 11, 0, 8, 99, 0, 8, 35, 0, 9, 167, 0, 8, 3, 0, 8, 131, 0, 8, 67, 0, 9, 231, 80, 7, 7, 0, 8, 91, 0, 8, 27, 0, 9, 151, 84, 7, 67, 0, 8, 123, 0, 8, 59, 0, 9, 215, 82, 7, 19, 0, 8, 107, 0, 8, 43, 0, 9, 183, 0, 8, 11, 0, 8, 139, 0, 8, 75, 0, 9, 247, 80, 7, 5, 0, 8, 87, 0, 8, 23, 192, 8, 0, 83, 7, 51, 0, 8, 119, 0, 8, 55, 0, 9, 207, 81, 7, 15, 0, 8, 103, 0, 8, 39, 0, 9, 175, 0, 8, 7, 0, 8, 135, 0, 8, 71, 0, 9, 239, 80, 7, 9, 0, 8, 95, 0, 8, 31, 0, 9, 159, 84, 7, 99, 0, 8, 127, 0, 8, 63, 0, 9, 223, 82, 7, 27, 0, 8, 111, 0, 8, 47, 0, 9, 191, 0, 8, 15, 0, 8, 143, 0, 8, 79, 0, 9, 255}; | ||||||
|  |                 //UPGRADE_NOTE: Final was removed from the declaration of 'fixed_td'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" | ||||||
|  |                 internal static readonly int[] fixed_td = new int[]{80, 5, 1, 87, 5, 257, 83, 5, 17, 91, 5, 4097, 81, 5, 5, 89, 5, 1025, 85, 5, 65, 93, 5, 16385, 80, 5, 3, 88, 5, 513, 84, 5, 33, 92, 5, 8193, 82, 5, 9, 90, 5, 2049, 86, 5, 129, 192, 5, 24577, 80, 5, 2, 87, 5, 385, 83, 5, 25, 91, 5, 6145, 81, 5, 7, 89, 5, 1537, 85, 5, 97, 93, 5, 24577, 80, 5, 4, 88, 5, 769, 84, 5, 49, 92, 5, 12289, 82, 5, 13, 90, 5, 3073, 86, 5, 193, 192, 5, 24577}; | ||||||
|  |                  | ||||||
|  |                 // Tables for deflate from PKZIP's appnote.txt. | ||||||
|  |                 //UPGRADE_NOTE: Final was removed from the declaration of 'cplens'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" | ||||||
|  |                 internal static readonly int[] cplens = new int[]{3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31, 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0}; | ||||||
|  |                  | ||||||
|  |                 // see note #13 above about 258 | ||||||
|  |                 //UPGRADE_NOTE: Final was removed from the declaration of 'cplext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" | ||||||
|  |                 internal static readonly int[] cplext = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0, 112, 112}; | ||||||
|  |                  | ||||||
|  |                 //UPGRADE_NOTE: Final was removed from the declaration of 'cpdist'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" | ||||||
|  |                 internal static readonly int[] cpdist = new int[]{1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193, 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145, 8193, 12289, 16385, 24577}; | ||||||
|  |                  | ||||||
|  |                 //UPGRADE_NOTE: Final was removed from the declaration of 'cpdext'. "ms-help://MS.VSCC.v80/dv_commoner/local/redirect.htm?index='!DefaultContextWindowIndex'&keyword='jlca1003'" | ||||||
|  |                 internal static readonly int[] cpdext = new int[]{0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13}; | ||||||
|  |                  | ||||||
|  |                 // If BMAX needs to be larger than 16, then h and x[] should be uLong. | ||||||
|  |                 internal const int BMAX = 15; // maximum bit length of any code | ||||||
|  |                  | ||||||
|  |                 internal int[] hn = null; // hufts used in space | ||||||
|  |                 internal int[] v = null; // work area for huft_build  | ||||||
|  |                 internal int[] c = null; // bit length count table | ||||||
|  |                 internal int[] r = null; // table entry for structure assignment | ||||||
|  |                 internal int[] u = null; // table stack | ||||||
|  |                 internal int[] x = null; // bit offsets, then code stack | ||||||
|  |                  | ||||||
|  |                 private int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v) | ||||||
|  |                 { | ||||||
|  |                         // Given a list of code lengths and a maximum table size, make a set of | ||||||
|  |                         // tables to decode that set of codes.  Return Z_OK on success, Z_BUF_ERROR | ||||||
|  |                         // if the given code set is incomplete (the tables are still built in this | ||||||
|  |                         // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of | ||||||
|  |                         // lengths), or Z_MEM_ERROR if not enough memory. | ||||||
|  |                          | ||||||
|  |                         int a; // counter for codes of length k | ||||||
|  |                         int f; // i repeats in table every f entries | ||||||
|  |                         int g; // maximum code length | ||||||
|  |                         int h; // table level | ||||||
|  |                         int i; // counter, current code | ||||||
|  |                         int j; // counter | ||||||
|  |                         int k; // number of bits in current code | ||||||
|  |                         int l; // bits per table (returned in m) | ||||||
|  |                         int mask; // (1 << w) - 1, to avoid cc -O bug on HP | ||||||
|  |                         int p; // pointer into c[], b[], or v[] | ||||||
|  |                         int q; // points to current table | ||||||
|  |                         int w; // bits before this table == (l * h) | ||||||
|  |                         int xp; // pointer into x | ||||||
|  |                         int y; // number of dummy codes added | ||||||
|  |                         int z; // number of entries in current table | ||||||
|  |                          | ||||||
|  |                         // Generate counts for each bit length | ||||||
|  |                          | ||||||
|  |                         p = 0; i = n; | ||||||
|  |                         do  | ||||||
|  |                         { | ||||||
|  |                                 c[b[bindex + p]]++; p++; i--; // assume all entries <= BMAX | ||||||
|  |                         } | ||||||
|  |                         while (i != 0); | ||||||
|  |                          | ||||||
|  |                         if (c[0] == n) | ||||||
|  |                         { | ||||||
|  |                                 // null input--all zero length codes | ||||||
|  |                                 t[0] = - 1; | ||||||
|  |                                 m[0] = 0; | ||||||
|  |                                 return Z_OK; | ||||||
|  |                         } | ||||||
|  |                          | ||||||
|  |                         // Find minimum and maximum length, bound *m by those | ||||||
|  |                         l = m[0]; | ||||||
|  |                         for (j = 1; j <= BMAX; j++) | ||||||
|  |                                 if (c[j] != 0) | ||||||
|  |                                         break; | ||||||
|  |                         k = j; // minimum code length | ||||||
|  |                         if (l < j) | ||||||
|  |                         { | ||||||
|  |                                 l = j; | ||||||
|  |                         } | ||||||
|  |                         for (i = BMAX; i != 0; i--) | ||||||
|  |                         { | ||||||
|  |                                 if (c[i] != 0) | ||||||
|  |                                         break; | ||||||
|  |                         } | ||||||
|  |                         g = i; // maximum code length | ||||||
|  |                         if (l > i) | ||||||
|  |                         { | ||||||
|  |                                 l = i; | ||||||
|  |                         } | ||||||
|  |                         m[0] = l; | ||||||
|  |                          | ||||||
|  |                         // Adjust last length count to fill out codes, if needed | ||||||
|  |                         for (y = 1 << j; j < i; j++, y <<= 1) | ||||||
|  |                         { | ||||||
|  |                                 if ((y -= c[j]) < 0) | ||||||
|  |                                 { | ||||||
|  |                                         return Z_DATA_ERROR; | ||||||
|  |                                 } | ||||||
|  |                         } | ||||||
|  |                         if ((y -= c[i]) < 0) | ||||||
|  |                         { | ||||||
|  |                                 return Z_DATA_ERROR; | ||||||
|  |                         } | ||||||
|  |                         c[i] += y; | ||||||
|  |                          | ||||||
|  |                         // Generate starting offsets into the value table for each length | ||||||
|  |                         x[1] = j = 0; | ||||||
|  |                         p = 1; xp = 2; | ||||||
|  |                         while (--i != 0) | ||||||
|  |                         { | ||||||
|  |                                 // note that i == g from above | ||||||
|  |                                 x[xp] = (j += c[p]); | ||||||
|  |                                 xp++; | ||||||
|  |                                 p++; | ||||||
|  |                         } | ||||||
|  |                          | ||||||
|  |                         // Make a table of values in order of bit lengths | ||||||
|  |                         i = 0; p = 0; | ||||||
|  |                         do  | ||||||
|  |                         { | ||||||
|  |                                 if ((j = b[bindex + p]) != 0) | ||||||
|  |                                 { | ||||||
|  |                                         v[x[j]++] = i; | ||||||
|  |                                 } | ||||||
|  |                                 p++; | ||||||
|  |                         } | ||||||
|  |                         while (++i < n); | ||||||
|  |                         n = x[g]; // set n to length of v | ||||||
|  |                          | ||||||
|  |                         // Generate the Huffman codes and for each, make the table entries | ||||||
|  |                         x[0] = i = 0; // first Huffman code is zero | ||||||
|  |                         p = 0; // grab values in bit order | ||||||
|  |                         h = - 1; // no tables yet--level -1 | ||||||
|  |                         w = - l; // bits decoded == (l * h) | ||||||
|  |                         u[0] = 0; // just to keep compilers happy | ||||||
|  |                         q = 0; // ditto | ||||||
|  |                         z = 0; // ditto | ||||||
|  |                          | ||||||
|  |                         // go through the bit lengths (k already is bits in shortest code) | ||||||
|  |                         for (; k <= g; k++) | ||||||
|  |                         { | ||||||
|  |                                 a = c[k]; | ||||||
|  |                                 while (a-- != 0) | ||||||
|  |                                 { | ||||||
|  |                                         // here i is the Huffman code of length k bits for value *p | ||||||
|  |                                         // make tables up to required level | ||||||
|  |                                         while (k > w + l) | ||||||
|  |                                         { | ||||||
|  |                                                 h++; | ||||||
|  |                                                 w += l; // previous table always l bits | ||||||
|  |                                                 // compute minimum size table less than or equal to l bits | ||||||
|  |                                                 z = g - w; | ||||||
|  |                                                 z = (z > l)?l:z; // table size upper limit | ||||||
|  |                                                 if ((f = 1 << (j = k - w)) > a + 1) | ||||||
|  |                                                 { | ||||||
|  |                                                         // try a k-w bit table | ||||||
|  |                                                         // too few codes for k-w bit table | ||||||
|  |                                                         f -= (a + 1); // deduct codes from patterns left | ||||||
|  |                                                         xp = k; | ||||||
|  |                                                         if (j < z) | ||||||
|  |                                                         { | ||||||
|  |                                                                 while (++j < z) | ||||||
|  |                                                                 { | ||||||
|  |                                                                         // try smaller tables up to z bits | ||||||
|  |                                                                         if ((f <<= 1) <= c[++xp]) | ||||||
|  |                                                                                 break; // enough codes to use up j bits | ||||||
|  |                                                                         f -= c[xp]; // else deduct codes from patterns | ||||||
|  |                                                                 } | ||||||
|  |                                                         } | ||||||
|  |                                                 } | ||||||
|  |                                                 z = 1 << j; // table entries for j-bit table | ||||||
|  |                                                  | ||||||
|  |                                                 // allocate new table | ||||||
|  |                                                 if (hn[0] + z > MANY) | ||||||
|  |                                                 { | ||||||
|  |                                                         // (note: doesn't matter for fixed) | ||||||
|  |                                                         return Z_DATA_ERROR; // overflow of MANY | ||||||
|  |                                                 } | ||||||
|  |                                                 u[h] = q = hn[0]; // DEBUG | ||||||
|  |                                                 hn[0] += z; | ||||||
|  |                                                  | ||||||
|  |                                                 // connect to last table, if there is one | ||||||
|  |                                                 if (h != 0) | ||||||
|  |                                                 { | ||||||
|  |                                                         x[h] = i; // save pattern for backing up | ||||||
|  |                                                         r[0] = (sbyte) j; // bits in this table | ||||||
|  |                                                         r[1] = (sbyte) l; // bits to dump before this table | ||||||
|  |                                                         j = SharedUtils.URShift(i, (w - l)); | ||||||
|  |                                                         r[2] = (int) (q - u[h - 1] - j); // offset to this table | ||||||
|  |                                                         Array.Copy(r, 0, hp, (u[h - 1] + j) * 3, 3); // connect to last table | ||||||
|  |                                                 } | ||||||
|  |                                                 else | ||||||
|  |                                                 { | ||||||
|  |                                                         t[0] = q; // first table is returned result | ||||||
|  |                                                 } | ||||||
|  |                                         } | ||||||
|  |                                          | ||||||
|  |                                         // set up table entry in r | ||||||
|  |                                         r[1] = (sbyte) (k - w); | ||||||
|  |                                         if (p >= n) | ||||||
|  |                                         { | ||||||
|  |                                                 r[0] = 128 + 64; // out of values--invalid code | ||||||
|  |                                         } | ||||||
|  |                                         else if (v[p] < s) | ||||||
|  |                                         { | ||||||
|  |                                                 r[0] = (sbyte) (v[p] < 256?0:32 + 64); // 256 is end-of-block | ||||||
|  |                                                 r[2] = v[p++]; // simple code is just the value | ||||||
|  |                                         } | ||||||
|  |                                         else | ||||||
|  |                                         { | ||||||
|  |                                                 r[0] = (sbyte) (e[v[p] - s] + 16 + 64); // non-simple--look up in lists | ||||||
|  |                                                 r[2] = d[v[p++] - s]; | ||||||
|  |                                         } | ||||||
|  |                                          | ||||||
|  |                                         // fill code-like entries with r | ||||||
|  |                                         f = 1 << (k - w); | ||||||
|  |                                         for (j = SharedUtils.URShift(i, w); j < z; j += f) | ||||||
|  |                                         { | ||||||
|  |                                                 Array.Copy(r, 0, hp, (q + j) * 3, 3); | ||||||
|  |                                         } | ||||||
|  |                                          | ||||||
|  |                                         // backwards increment the k-bit code i | ||||||
|  |                                         for (j = 1 << (k - 1); (i & j) != 0; j = SharedUtils.URShift(j, 1)) | ||||||
|  |                                         { | ||||||
|  |                                                 i ^= j; | ||||||
|  |                                         } | ||||||
|  |                                         i ^= j; | ||||||
|  |                                          | ||||||
|  |                                         // backup over finished tables | ||||||
|  |                                         mask = (1 << w) - 1; // needed on HP, cc -O bug | ||||||
|  |                                         while ((i & mask) != x[h]) | ||||||
|  |                                         { | ||||||
|  |                                                 h--; // don't need to update q | ||||||
|  |                                                 w -= l; | ||||||
|  |                                                 mask = (1 << w) - 1; | ||||||
|  |                                         } | ||||||
|  |                                 } | ||||||
|  |                         } | ||||||
|  |                         // Return Z_BUF_ERROR if we were given an incomplete table | ||||||
|  |                         return y != 0 && g != 1?Z_BUF_ERROR:Z_OK; | ||||||
|  |                 } | ||||||
|  |                  | ||||||
|  |                 internal int inflate_trees_bits(int[] c, int[] bb, int[] tb, int[] hp, ZlibCodec z) | ||||||
|  |                 { | ||||||
|  |                         int result; | ||||||
|  |                         initWorkArea(19); | ||||||
|  |                         hn[0] = 0; | ||||||
|  |                         result = huft_build(c, 0, 19, 19, null, null, tb, bb, hp, hn, v); | ||||||
|  |                          | ||||||
|  |                         if (result == Z_DATA_ERROR) | ||||||
|  |                         { | ||||||
|  |                                 z.Message = "oversubscribed dynamic bit lengths tree"; | ||||||
|  |                         } | ||||||
|  |                         else if (result == Z_BUF_ERROR || bb[0] == 0) | ||||||
|  |                         { | ||||||
|  |                                 z.Message = "incomplete dynamic bit lengths tree"; | ||||||
|  |                                 result = Z_DATA_ERROR; | ||||||
|  |                         } | ||||||
|  |                         return result; | ||||||
|  |                 } | ||||||
|  |                  | ||||||
|  |                 internal int inflate_trees_dynamic(int nl, int nd, int[] c, int[] bl, int[] bd, int[] tl, int[] td, int[] hp, ZlibCodec z) | ||||||
|  |                 { | ||||||
|  |                         int result; | ||||||
|  |                          | ||||||
|  |                         // build literal/length tree | ||||||
|  |                         initWorkArea(288); | ||||||
|  |                         hn[0] = 0; | ||||||
|  |                         result = huft_build(c, 0, nl, 257, cplens, cplext, tl, bl, hp, hn, v); | ||||||
|  |                         if (result != Z_OK || bl[0] == 0) | ||||||
|  |                         { | ||||||
|  |                                 if (result == Z_DATA_ERROR) | ||||||
|  |                                 { | ||||||
|  |                                         z.Message = "oversubscribed literal/length tree"; | ||||||
|  |                                 } | ||||||
|  |                                 else if (result != Z_MEM_ERROR) | ||||||
|  |                                 { | ||||||
|  |                                         z.Message = "incomplete literal/length tree"; | ||||||
|  |                                         result = Z_DATA_ERROR; | ||||||
|  |                                 } | ||||||
|  |                                 return result; | ||||||
|  |                         } | ||||||
|  |                          | ||||||
|  |                         // build distance tree | ||||||
|  |                         initWorkArea(288); | ||||||
|  |                         result = huft_build(c, nl, nd, 0, cpdist, cpdext, td, bd, hp, hn, v); | ||||||
|  |                          | ||||||
|  |                         if (result != Z_OK || (bd[0] == 0 && nl > 257)) | ||||||
|  |                         { | ||||||
|  |                                 if (result == Z_DATA_ERROR) | ||||||
|  |                                 { | ||||||
|  |                                         z.Message = "oversubscribed distance tree"; | ||||||
|  |                                 } | ||||||
|  |                                 else if (result == Z_BUF_ERROR) | ||||||
|  |                                 { | ||||||
|  |                                         z.Message = "incomplete distance tree"; | ||||||
|  |                                         result = Z_DATA_ERROR; | ||||||
|  |                                 } | ||||||
|  |                                 else if (result != Z_MEM_ERROR) | ||||||
|  |                                 { | ||||||
|  |                                         z.Message = "empty distance tree with lengths"; | ||||||
|  |                                         result = Z_DATA_ERROR; | ||||||
|  |                                 } | ||||||
|  |                                 return result; | ||||||
|  |                         } | ||||||
|  |                          | ||||||
|  |                         return Z_OK; | ||||||
|  |                 } | ||||||
|  |                  | ||||||
|  |                 internal static int inflate_trees_fixed(int[] bl, int[] bd, int[][] tl, int[][] td, ZlibCodec z) | ||||||
|  |                 { | ||||||
|  |                         bl[0] = fixed_bl; | ||||||
|  |                         bd[0] = fixed_bd; | ||||||
|  |                         tl[0] = fixed_tl; | ||||||
|  |                         td[0] = fixed_td; | ||||||
|  |                         return Z_OK; | ||||||
|  |                 } | ||||||
|  |                  | ||||||
|  |                 private void  initWorkArea(int vsize) | ||||||
|  |                 { | ||||||
|  |                         if (hn == null) | ||||||
|  |                         { | ||||||
|  |                                 hn = new int[1]; | ||||||
|  |                                 v = new int[vsize]; | ||||||
|  |                                 c = new int[BMAX + 1]; | ||||||
|  |                                 r = new int[3]; | ||||||
|  |                                 u = new int[BMAX]; | ||||||
|  |                                 x = new int[BMAX + 1]; | ||||||
|  |                         } | ||||||
|  |                         else | ||||||
|  |                         { | ||||||
|  |                             if (v.Length < vsize) | ||||||
|  |                             { | ||||||
|  |                                 v = new int[vsize]; | ||||||
|  |                             } | ||||||
|  |                             Array.Clear(v,0,vsize); | ||||||
|  |                             Array.Clear(c,0,BMAX+1); | ||||||
|  |                             r[0]=0; r[1]=0; r[2]=0; | ||||||
|  |                             //  for(int i=0; i<BMAX; i++){u[i]=0;} | ||||||
|  |                             //Array.Copy(c, 0, u, 0, BMAX); | ||||||
|  |                             Array.Clear(u,0,BMAX); | ||||||
|  |                             //  for(int i=0; i<BMAX+1; i++){x[i]=0;} | ||||||
|  |                             //Array.Copy(c, 0, x, 0, BMAX + 1); | ||||||
|  |                             Array.Clear(x,0,BMAX+1); | ||||||
|  |                         } | ||||||
|  |                 } | ||||||
|  |         } | ||||||
|  | } | ||||||
							
								
								
									
										1796
									
								
								src/ZlibAndroid/Inflate.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1796
									
								
								src/ZlibAndroid/Inflate.cs
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										44
									
								
								src/ZlibAndroid/Resources/AboutResources.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								src/ZlibAndroid/Resources/AboutResources.txt
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,44 @@ | |||||||
|  | Images, layout descriptions, binary blobs and string dictionaries can be included  | ||||||
|  | in your application as resource files.  Various Android APIs are designed to  | ||||||
|  | operate on the resource IDs instead of dealing with images, strings or binary blobs  | ||||||
|  | directly. | ||||||
|  |  | ||||||
|  | For example, a sample Android app that contains a user interface layout (main.axml), | ||||||
|  | an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png)  | ||||||
|  | would keep its resources in the "Resources" directory of the application: | ||||||
|  |  | ||||||
|  | Resources/ | ||||||
|  |     drawable/ | ||||||
|  |         icon.png | ||||||
|  |  | ||||||
|  |     layout/ | ||||||
|  |         main.axml | ||||||
|  |  | ||||||
|  |     values/ | ||||||
|  |         strings.xml | ||||||
|  |  | ||||||
|  | In order to get the build system to recognize Android resources, set the build action to | ||||||
|  | "AndroidResource".  The native Android APIs do not operate directly with filenames, but  | ||||||
|  | instead operate on resource IDs.  When you compile an Android application that uses resources,  | ||||||
|  | the build system will package the resources for distribution and generate a class called "R"  | ||||||
|  | (this is an Android convention) that contains the tokens for each one of the resources  | ||||||
|  | included. For example, for the above Resources layout, this is what the R class would expose: | ||||||
|  |  | ||||||
|  | public class R { | ||||||
|  |     public class drawable { | ||||||
|  |         public const int icon = 0x123; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public class layout { | ||||||
|  |         public const int main = 0x456; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public class strings { | ||||||
|  |         public const int first_string = 0xabc; | ||||||
|  |         public const int second_string = 0xbcd; | ||||||
|  |     } | ||||||
|  | } | ||||||
|  |  | ||||||
|  | You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main  | ||||||
|  | to reference the layout/main.axml file, or R.strings.first_string to reference the first  | ||||||
|  | string in the dictionary file values/strings.xml. | ||||||
							
								
								
									
										4
									
								
								src/ZlibAndroid/Resources/values/Strings.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/ZlibAndroid/Resources/values/Strings.xml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <resources> | ||||||
|  | 	<string name="library_name">ZlibAndroid</string> | ||||||
|  | </resources> | ||||||
							
								
								
									
										423
									
								
								src/ZlibAndroid/Tree.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										423
									
								
								src/ZlibAndroid/Tree.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,423 @@ | |||||||
|  | // Tree.cs | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.   | ||||||
|  | // All rights reserved. | ||||||
|  | // | ||||||
|  | // This code module is part of DotNetZip, a zipfile class library. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This code is licensed under the Microsoft Public License.  | ||||||
|  | // See the file License.txt for the license details. | ||||||
|  | // More info on: http://dotnetzip.codeplex.com | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // last saved (in emacs):  | ||||||
|  | // Time-stamp: <2009-October-28 13:29:50> | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This module defines classes for zlib compression and | ||||||
|  | // decompression. This code is derived from the jzlib implementation of | ||||||
|  | // zlib. In keeping with the license for jzlib, the copyright to that | ||||||
|  | // code is below. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | //  | ||||||
|  | // Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. | ||||||
|  | //  | ||||||
|  | // Redistribution and use in source and binary forms, with or without | ||||||
|  | // modification, are permitted provided that the following conditions are met: | ||||||
|  | //  | ||||||
|  | // 1. Redistributions of source code must retain the above copyright notice, | ||||||
|  | // this list of conditions and the following disclaimer. | ||||||
|  | //  | ||||||
|  | // 2. Redistributions in binary form must reproduce the above copyright  | ||||||
|  | // notice, this list of conditions and the following disclaimer in  | ||||||
|  | // the documentation and/or other materials provided with the distribution. | ||||||
|  | //  | ||||||
|  | // 3. The names of the authors may not be used to endorse or promote products | ||||||
|  | // derived from this software without specific prior written permission. | ||||||
|  | //  | ||||||
|  | // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, | ||||||
|  | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, | ||||||
|  | // INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||||
|  | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||||
|  | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, | ||||||
|  | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||||||
|  | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||||||
|  | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||||||
|  | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
|  | //  | ||||||
|  | // ----------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // This program is based on zlib-1.1.3; credit to authors | ||||||
|  | // Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) | ||||||
|  | // and contributors of zlib. | ||||||
|  | // | ||||||
|  | // ----------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  |  | ||||||
|  | using System; | ||||||
|  |  | ||||||
|  | namespace Ionic.Zlib | ||||||
|  | { | ||||||
|  |     sealed class Tree | ||||||
|  |     { | ||||||
|  |         private static readonly int HEAP_SIZE = (2 * InternalConstants.L_CODES + 1); | ||||||
|  |                  | ||||||
|  |         // extra bits for each length code | ||||||
|  |         internal static readonly int[] ExtraLengthBits = new int[] | ||||||
|  |         { | ||||||
|  |             0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, | ||||||
|  |             3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 5, 0 | ||||||
|  |         }; | ||||||
|  |                  | ||||||
|  |         // extra bits for each distance code | ||||||
|  |         internal static readonly int[] ExtraDistanceBits = new int[] | ||||||
|  |         { | ||||||
|  |             0, 0, 0, 0, 1, 1,  2,  2,  3,  3,  4,  4,  5,  5,  6,  6, | ||||||
|  |             7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13 | ||||||
|  |         }; | ||||||
|  |                  | ||||||
|  |         // extra bits for each bit length code | ||||||
|  |         internal static readonly int[] extra_blbits = new int[]{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7}; | ||||||
|  |                  | ||||||
|  |         internal static readonly sbyte[] bl_order = new sbyte[]{16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15}; | ||||||
|  |                  | ||||||
|  |                  | ||||||
|  |         // The lengths of the bit length codes are sent in order of decreasing | ||||||
|  |         // probability, to avoid transmitting the lengths for unused bit | ||||||
|  |         // length codes. | ||||||
|  |                  | ||||||
|  |         internal const int Buf_size = 8 * 2; | ||||||
|  |                  | ||||||
|  |         // see definition of array dist_code below | ||||||
|  |         //internal const int DIST_CODE_LEN = 512; | ||||||
|  |                  | ||||||
|  |         private static readonly sbyte[] _dist_code = new sbyte[] | ||||||
|  |         { | ||||||
|  |             0,  1,  2,  3,  4,  4,  5,  5,  6,  6,  6,  6,  7,  7,  7,  7,  | ||||||
|  |             8,  8,  8,  8,  8,  8,  8,  8,  9,  9,  9,  9,  9,  9,  9,  9, | ||||||
|  |             10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10,  | ||||||
|  |             11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,  | ||||||
|  |             12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  | ||||||
|  |             12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,  | ||||||
|  |             13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  | ||||||
|  |             13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,  | ||||||
|  |             14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  | ||||||
|  |             14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  | ||||||
|  |             14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  | ||||||
|  |             14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,  | ||||||
|  |             15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  | ||||||
|  |             15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  | ||||||
|  |             15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  | ||||||
|  |             15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,  | ||||||
|  |             0,   0, 16, 17, 18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21,  | ||||||
|  |             22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,  | ||||||
|  |             24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,  | ||||||
|  |             25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,  | ||||||
|  |             26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,  | ||||||
|  |             26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,  | ||||||
|  |             27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  | ||||||
|  |             27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,  | ||||||
|  |             28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,  | ||||||
|  |             28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,  | ||||||
|  |             28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,  | ||||||
|  |             28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,  | ||||||
|  |             29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,  | ||||||
|  |             29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,  | ||||||
|  |             29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,  | ||||||
|  |             29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29 | ||||||
|  |         }; | ||||||
|  |                  | ||||||
|  |         internal static readonly sbyte[] LengthCode = new sbyte[] | ||||||
|  |         { | ||||||
|  |             0,   1,  2,  3,  4,  5,  6,  7,  8,  8,  9,  9, 10, 10, 11, 11, | ||||||
|  |             12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, | ||||||
|  |             16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 17, 17, 17, 17, | ||||||
|  |             18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19, 19, 19, 19, 19, | ||||||
|  |             20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, | ||||||
|  |             21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, | ||||||
|  |             22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, | ||||||
|  |             23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, | ||||||
|  |             24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, | ||||||
|  |             24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, | ||||||
|  |             25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | ||||||
|  |             25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, | ||||||
|  |             26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, | ||||||
|  |             26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, | ||||||
|  |             27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, | ||||||
|  |             27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28 | ||||||
|  |         }; | ||||||
|  |                  | ||||||
|  |  | ||||||
|  |         internal static readonly int[] LengthBase = new int[] | ||||||
|  |         { | ||||||
|  |             0,   1,  2,  3,  4,  5,  6,   7,   8,  10,  12,  14, 16, 20, 24, 28, | ||||||
|  |             32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 0 | ||||||
|  |         }; | ||||||
|  |                  | ||||||
|  |  | ||||||
|  |         internal static readonly int[] DistanceBase = new int[] | ||||||
|  |         { | ||||||
|  |             0, 1, 2, 3, 4, 6, 8, 12, 16, 24, 32, 48, 64, 96, 128, 192, | ||||||
|  |             256, 384, 512, 768, 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576 | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |          | ||||||
|  |         /// <summary> | ||||||
|  |         /// Map from a distance to a distance code. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks>  | ||||||
|  |         /// No side effects. _dist_code[256] and _dist_code[257] are never used. | ||||||
|  |         /// </remarks> | ||||||
|  |         internal static int DistanceCode(int dist) | ||||||
|  |         { | ||||||
|  |             return (dist < 256) | ||||||
|  |                 ? _dist_code[dist] | ||||||
|  |                 : _dist_code[256 + SharedUtils.URShift(dist, 7)]; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         internal short[] dyn_tree; // the dynamic tree | ||||||
|  |         internal int max_code; // largest code with non zero frequency | ||||||
|  |         internal StaticTree staticTree; // the corresponding static tree | ||||||
|  |                  | ||||||
|  |         // Compute the optimal bit lengths for a tree and update the total bit length | ||||||
|  |         // for the current block. | ||||||
|  |         // IN assertion: the fields freq and dad are set, heap[heap_max] and | ||||||
|  |         //    above are the tree nodes sorted by increasing frequency. | ||||||
|  |         // OUT assertions: the field len is set to the optimal bit length, the | ||||||
|  |         //     array bl_count contains the frequencies for each bit length. | ||||||
|  |         //     The length opt_len is updated; static_len is also updated if stree is | ||||||
|  |         //     not null. | ||||||
|  |         internal void  gen_bitlen(DeflateManager s) | ||||||
|  |         { | ||||||
|  |             short[] tree = dyn_tree; | ||||||
|  |             short[] stree = staticTree.treeCodes; | ||||||
|  |             int[] extra = staticTree.extraBits; | ||||||
|  |             int base_Renamed = staticTree.extraBase; | ||||||
|  |             int max_length = staticTree.maxLength; | ||||||
|  |             int h; // heap index | ||||||
|  |             int n, m; // iterate over the tree elements | ||||||
|  |             int bits; // bit length | ||||||
|  |             int xbits; // extra bits | ||||||
|  |             short f; // frequency | ||||||
|  |             int overflow = 0; // number of elements with bit length too large | ||||||
|  |                          | ||||||
|  |             for (bits = 0; bits <= InternalConstants.MAX_BITS; bits++) | ||||||
|  |                 s.bl_count[bits] = 0; | ||||||
|  |                          | ||||||
|  |             // In a first pass, compute the optimal bit lengths (which may | ||||||
|  |             // overflow in the case of the bit length tree). | ||||||
|  |             tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap | ||||||
|  |                          | ||||||
|  |             for (h = s.heap_max + 1; h < HEAP_SIZE; h++) | ||||||
|  |             { | ||||||
|  |                 n = s.heap[h]; | ||||||
|  |                 bits = tree[tree[n * 2 + 1] * 2 + 1] + 1; | ||||||
|  |                 if (bits > max_length) | ||||||
|  |                 { | ||||||
|  |                     bits = max_length; overflow++; | ||||||
|  |                 } | ||||||
|  |                 tree[n * 2 + 1] = (short) bits; | ||||||
|  |                 // We overwrite tree[n*2+1] which is no longer needed | ||||||
|  |                                  | ||||||
|  |                 if (n > max_code) | ||||||
|  |                     continue; // not a leaf node | ||||||
|  |                                  | ||||||
|  |                 s.bl_count[bits]++; | ||||||
|  |                 xbits = 0; | ||||||
|  |                 if (n >= base_Renamed) | ||||||
|  |                     xbits = extra[n - base_Renamed]; | ||||||
|  |                 f = tree[n * 2]; | ||||||
|  |                 s.opt_len += f * (bits + xbits); | ||||||
|  |                 if (stree != null) | ||||||
|  |                     s.static_len += f * (stree[n * 2 + 1] + xbits); | ||||||
|  |             } | ||||||
|  |             if (overflow == 0) | ||||||
|  |                 return ; | ||||||
|  |                          | ||||||
|  |             // This happens for example on obj2 and pic of the Calgary corpus | ||||||
|  |             // Find the first bit length which could increase: | ||||||
|  |             do  | ||||||
|  |             { | ||||||
|  |                 bits = max_length - 1; | ||||||
|  |                 while (s.bl_count[bits] == 0) | ||||||
|  |                     bits--; | ||||||
|  |                 s.bl_count[bits]--; // move one leaf down the tree | ||||||
|  |                 s.bl_count[bits + 1] = (short) (s.bl_count[bits + 1] + 2); // move one overflow item as its brother | ||||||
|  |                 s.bl_count[max_length]--; | ||||||
|  |                 // The brother of the overflow item also moves one step up, | ||||||
|  |                 // but this does not affect bl_count[max_length] | ||||||
|  |                 overflow -= 2; | ||||||
|  |             } | ||||||
|  |             while (overflow > 0); | ||||||
|  |                          | ||||||
|  |             for (bits = max_length; bits != 0; bits--) | ||||||
|  |             { | ||||||
|  |                 n = s.bl_count[bits]; | ||||||
|  |                 while (n != 0) | ||||||
|  |                 { | ||||||
|  |                     m = s.heap[--h]; | ||||||
|  |                     if (m > max_code) | ||||||
|  |                         continue; | ||||||
|  |                     if (tree[m * 2 + 1] != bits) | ||||||
|  |                     { | ||||||
|  |                         s.opt_len = (int) (s.opt_len + ((long) bits - (long) tree[m * 2 + 1]) * (long) tree[m * 2]); | ||||||
|  |                         tree[m * 2 + 1] = (short) bits; | ||||||
|  |                     } | ||||||
|  |                     n--; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |                  | ||||||
|  |         // Construct one Huffman tree and assigns the code bit strings and lengths. | ||||||
|  |         // Update the total bit length for the current block. | ||||||
|  |         // IN assertion: the field freq is set for all tree elements. | ||||||
|  |         // OUT assertions: the fields len and code are set to the optimal bit length | ||||||
|  |         //     and corresponding code. The length opt_len is updated; static_len is | ||||||
|  |         //     also updated if stree is not null. The field max_code is set. | ||||||
|  |         internal void  build_tree(DeflateManager s) | ||||||
|  |         { | ||||||
|  |             short[] tree  = dyn_tree; | ||||||
|  |             short[] stree = staticTree.treeCodes; | ||||||
|  |             int elems     = staticTree.elems; | ||||||
|  |             int n, m;            // iterate over heap elements | ||||||
|  |             int max_code  = -1;  // largest code with non zero frequency | ||||||
|  |             int node;            // new node being created | ||||||
|  |                          | ||||||
|  |             // Construct the initial heap, with least frequent element in | ||||||
|  |             // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1]. | ||||||
|  |             // heap[0] is not used. | ||||||
|  |             s.heap_len = 0; | ||||||
|  |             s.heap_max = HEAP_SIZE; | ||||||
|  |                          | ||||||
|  |             for (n = 0; n < elems; n++) | ||||||
|  |             { | ||||||
|  |                 if (tree[n * 2] != 0) | ||||||
|  |                 { | ||||||
|  |                     s.heap[++s.heap_len] = max_code = n; | ||||||
|  |                     s.depth[n] = 0; | ||||||
|  |                 } | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     tree[n * 2 + 1] = 0; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |                          | ||||||
|  |             // The pkzip format requires that at least one distance code exists, | ||||||
|  |             // and that at least one bit should be sent even if there is only one | ||||||
|  |             // possible code. So to avoid special checks later on we force at least | ||||||
|  |             // two codes of non zero frequency. | ||||||
|  |             while (s.heap_len < 2) | ||||||
|  |             { | ||||||
|  |                 node = s.heap[++s.heap_len] = (max_code < 2?++max_code:0); | ||||||
|  |                 tree[node * 2] = 1; | ||||||
|  |                 s.depth[node] = 0; | ||||||
|  |                 s.opt_len--; | ||||||
|  |                 if (stree != null) | ||||||
|  |                     s.static_len -= stree[node * 2 + 1]; | ||||||
|  |                 // node is 0 or 1 so it does not have extra bits | ||||||
|  |             } | ||||||
|  |             this.max_code = max_code; | ||||||
|  |                          | ||||||
|  |             // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree, | ||||||
|  |             // establish sub-heaps of increasing lengths: | ||||||
|  |                          | ||||||
|  |             for (n = s.heap_len / 2; n >= 1; n--) | ||||||
|  |                 s.pqdownheap(tree, n); | ||||||
|  |                          | ||||||
|  |             // Construct the Huffman tree by repeatedly combining the least two | ||||||
|  |             // frequent nodes. | ||||||
|  |                          | ||||||
|  |             node = elems; // next internal node of the tree | ||||||
|  |             do  | ||||||
|  |             { | ||||||
|  |                 // n = node of least frequency | ||||||
|  |                 n = s.heap[1]; | ||||||
|  |                 s.heap[1] = s.heap[s.heap_len--]; | ||||||
|  |                 s.pqdownheap(tree, 1); | ||||||
|  |                 m = s.heap[1]; // m = node of next least frequency | ||||||
|  |                                  | ||||||
|  |                 s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency | ||||||
|  |                 s.heap[--s.heap_max] = m; | ||||||
|  |                                  | ||||||
|  |                 // Create a new node father of n and m | ||||||
|  |                 tree[node * 2] = unchecked((short) (tree[n * 2] + tree[m * 2])); | ||||||
|  |                 s.depth[node] = (sbyte) (System.Math.Max((byte) s.depth[n], (byte) s.depth[m]) + 1); | ||||||
|  |                 tree[n * 2 + 1] = tree[m * 2 + 1] = (short) node; | ||||||
|  |                                  | ||||||
|  |                 // and insert the new node in the heap | ||||||
|  |                 s.heap[1] = node++; | ||||||
|  |                 s.pqdownheap(tree, 1); | ||||||
|  |             } | ||||||
|  |             while (s.heap_len >= 2); | ||||||
|  |                          | ||||||
|  |             s.heap[--s.heap_max] = s.heap[1]; | ||||||
|  |                          | ||||||
|  |             // At this point, the fields freq and dad are set. We can now | ||||||
|  |             // generate the bit lengths. | ||||||
|  |                          | ||||||
|  |             gen_bitlen(s); | ||||||
|  |                          | ||||||
|  |             // The field len is now set, we can generate the bit codes | ||||||
|  |             gen_codes(tree, max_code, s.bl_count); | ||||||
|  |         } | ||||||
|  |                  | ||||||
|  |         // Generate the codes for a given tree and bit counts (which need not be | ||||||
|  |         // optimal). | ||||||
|  |         // IN assertion: the array bl_count contains the bit length statistics for | ||||||
|  |         // the given tree and the field len is set for all tree elements. | ||||||
|  |         // OUT assertion: the field code is set for all tree elements of non | ||||||
|  |         //     zero code length. | ||||||
|  |         internal static void  gen_codes(short[] tree, int max_code, short[] bl_count) | ||||||
|  |         { | ||||||
|  |             short[] next_code = new short[InternalConstants.MAX_BITS + 1]; // next code value for each bit length | ||||||
|  |             short code = 0; // running code value | ||||||
|  |             int bits; // bit index | ||||||
|  |             int n; // code index | ||||||
|  |                          | ||||||
|  |             // The distribution counts are first used to generate the code values | ||||||
|  |             // without bit reversal. | ||||||
|  |             for (bits = 1; bits <= InternalConstants.MAX_BITS; bits++) | ||||||
|  |                 unchecked { | ||||||
|  |                     next_code[bits] = code = (short) ((code + bl_count[bits - 1]) << 1); | ||||||
|  |                 } | ||||||
|  |                          | ||||||
|  |             // Check that the bit counts in bl_count are consistent. The last code | ||||||
|  |             // must be all ones. | ||||||
|  |             //Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1, | ||||||
|  |             //        "inconsistent bit counts"); | ||||||
|  |             //Tracev((stderr,"\ngen_codes: max_code %d ", max_code)); | ||||||
|  |                          | ||||||
|  |             for (n = 0; n <= max_code; n++) | ||||||
|  |             { | ||||||
|  |                 int len = tree[n * 2 + 1]; | ||||||
|  |                 if (len == 0) | ||||||
|  |                     continue; | ||||||
|  |                 // Now reverse the bits | ||||||
|  |                 tree[n * 2] =  unchecked((short) (bi_reverse(next_code[len]++, len))); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |                  | ||||||
|  |         // Reverse the first len bits of a code, using straightforward code (a faster | ||||||
|  |         // method would use a table) | ||||||
|  |         // IN assertion: 1 <= len <= 15 | ||||||
|  |         internal static int bi_reverse(int code, int len) | ||||||
|  |         { | ||||||
|  |             int res = 0; | ||||||
|  |             do  | ||||||
|  |             { | ||||||
|  |                 res |= code & 1; | ||||||
|  |                 code >>= 1; //SharedUtils.URShift(code, 1); | ||||||
|  |                 res <<= 1; | ||||||
|  |             } | ||||||
|  |             while (--len > 0); | ||||||
|  |             return res >> 1; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										546
									
								
								src/ZlibAndroid/Zlib.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										546
									
								
								src/ZlibAndroid/Zlib.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,546 @@ | |||||||
|  | // Zlib.cs | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // Copyright (c) 2009-2011 Dino Chiesa and Microsoft Corporation. | ||||||
|  | // All rights reserved. | ||||||
|  | // | ||||||
|  | // This code module is part of DotNetZip, a zipfile class library. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This code is licensed under the Microsoft Public License. | ||||||
|  | // See the file License.txt for the license details. | ||||||
|  | // More info on: http://dotnetzip.codeplex.com | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // Last Saved: <2011-August-03 19:52:28> | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This module defines classes for ZLIB compression and | ||||||
|  | // decompression. This code is derived from the jzlib implementation of | ||||||
|  | // zlib, but significantly modified.  The object model is not the same, | ||||||
|  | // and many of the behaviors are new or different.  Nonetheless, in | ||||||
|  | // keeping with the license for jzlib, the copyright to that code is | ||||||
|  | // included below. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // The following notice applies to jzlib: | ||||||
|  | // | ||||||
|  | // Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. | ||||||
|  | // | ||||||
|  | // Redistribution and use in source and binary forms, with or without | ||||||
|  | // modification, are permitted provided that the following conditions are met: | ||||||
|  | // | ||||||
|  | // 1. Redistributions of source code must retain the above copyright notice, | ||||||
|  | // this list of conditions and the following disclaimer. | ||||||
|  | // | ||||||
|  | // 2. Redistributions in binary form must reproduce the above copyright | ||||||
|  | // notice, this list of conditions and the following disclaimer in | ||||||
|  | // the documentation and/or other materials provided with the distribution. | ||||||
|  | // | ||||||
|  | // 3. The names of the authors may not be used to endorse or promote products | ||||||
|  | // derived from this software without specific prior written permission. | ||||||
|  | // | ||||||
|  | // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, | ||||||
|  | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, | ||||||
|  | // INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||||
|  | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||||
|  | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, | ||||||
|  | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||||||
|  | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||||||
|  | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||||||
|  | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
|  | // | ||||||
|  | // ----------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // jzlib is based on zlib-1.1.3. | ||||||
|  | // | ||||||
|  | // The following notice applies to zlib: | ||||||
|  | // | ||||||
|  | // ----------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // Copyright (C) 1995-2004 Jean-loup Gailly and Mark Adler | ||||||
|  | // | ||||||
|  | //   The ZLIB software is provided 'as-is', without any express or implied | ||||||
|  | //   warranty.  In no event will the authors be held liable for any damages | ||||||
|  | //   arising from the use of this software. | ||||||
|  | // | ||||||
|  | //   Permission is granted to anyone to use this software for any purpose, | ||||||
|  | //   including commercial applications, and to alter it and redistribute it | ||||||
|  | //   freely, subject to the following restrictions: | ||||||
|  | // | ||||||
|  | //   1. The origin of this software must not be misrepresented; you must not | ||||||
|  | //      claim that you wrote the original software. If you use this software | ||||||
|  | //      in a product, an acknowledgment in the product documentation would be | ||||||
|  | //      appreciated but is not required. | ||||||
|  | //   2. Altered source versions must be plainly marked as such, and must not be | ||||||
|  | //      misrepresented as being the original software. | ||||||
|  | //   3. This notice may not be removed or altered from any source distribution. | ||||||
|  | // | ||||||
|  | //   Jean-loup Gailly jloup@gzip.org | ||||||
|  | //   Mark Adler madler@alumni.caltech.edu | ||||||
|  | // | ||||||
|  | // ----------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | using System; | ||||||
|  | using Interop=System.Runtime.InteropServices; | ||||||
|  |  | ||||||
|  | namespace Ionic.Zlib | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// Describes how to flush the current deflate operation. | ||||||
|  |     /// </summary> | ||||||
|  |     /// <remarks> | ||||||
|  |     /// The different FlushType values are useful when using a Deflate in a streaming application. | ||||||
|  |     /// </remarks> | ||||||
|  |     public enum FlushType | ||||||
|  |     { | ||||||
|  |         /// <summary>No flush at all.</summary> | ||||||
|  |         None = 0, | ||||||
|  |  | ||||||
|  |         /// <summary>Closes the current block, but doesn't flush it to | ||||||
|  |         /// the output. Used internally only in hypothetical | ||||||
|  |         /// scenarios.  This was supposed to be removed by Zlib, but it is | ||||||
|  |         /// still in use in some edge cases. | ||||||
|  |         /// </summary> | ||||||
|  |         Partial, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Use this during compression to specify that all pending output should be | ||||||
|  |         /// flushed to the output buffer and the output should be aligned on a byte | ||||||
|  |         /// boundary.  You might use this in a streaming communication scenario, so that | ||||||
|  |         /// the decompressor can get all input data available so far.  When using this | ||||||
|  |         /// with a ZlibCodec, <c>AvailableBytesIn</c> will be zero after the call if | ||||||
|  |         /// enough output space has been provided before the call.  Flushing will | ||||||
|  |         /// degrade compression and so it should be used only when necessary. | ||||||
|  |         /// </summary> | ||||||
|  |         Sync, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Use this during compression to specify that all output should be flushed, as | ||||||
|  |         /// with <c>FlushType.Sync</c>, but also, the compression state should be reset | ||||||
|  |         /// so that decompression can restart from this point if previous compressed | ||||||
|  |         /// data has been damaged or if random access is desired.  Using | ||||||
|  |         /// <c>FlushType.Full</c> too often can significantly degrade the compression. | ||||||
|  |         /// </summary> | ||||||
|  |         Full, | ||||||
|  |  | ||||||
|  |         /// <summary>Signals the end of the compression/decompression stream.</summary> | ||||||
|  |         Finish, | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// The compression level to be used when using a DeflateStream or ZlibStream with CompressionMode.Compress. | ||||||
|  |     /// </summary> | ||||||
|  |     public enum CompressionLevel | ||||||
|  |     { | ||||||
|  |         /// <summary> | ||||||
|  |         /// None means that the data will be simply stored, with no change at all. | ||||||
|  |         /// If you are producing ZIPs for use on Mac OSX, be aware that archives produced with CompressionLevel.None | ||||||
|  |         /// cannot be opened with the default zip reader. Use a different CompressionLevel. | ||||||
|  |         /// </summary> | ||||||
|  |         None= 0, | ||||||
|  |         /// <summary> | ||||||
|  |         /// Same as None. | ||||||
|  |         /// </summary> | ||||||
|  |         Level0 = 0, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The fastest but least effective compression. | ||||||
|  |         /// </summary> | ||||||
|  |         BestSpeed = 1, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// A synonym for BestSpeed. | ||||||
|  |         /// </summary> | ||||||
|  |         Level1 = 1, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// A little slower, but better, than level 1. | ||||||
|  |         /// </summary> | ||||||
|  |         Level2 = 2, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// A little slower, but better, than level 2. | ||||||
|  |         /// </summary> | ||||||
|  |         Level3 = 3, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// A little slower, but better, than level 3. | ||||||
|  |         /// </summary> | ||||||
|  |         Level4 = 4, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// A little slower than level 4, but with better compression. | ||||||
|  |         /// </summary> | ||||||
|  |         Level5 = 5, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The default compression level, with a good balance of speed and compression efficiency. | ||||||
|  |         /// </summary> | ||||||
|  |         Default = 6, | ||||||
|  |         /// <summary> | ||||||
|  |         /// A synonym for Default. | ||||||
|  |         /// </summary> | ||||||
|  |         Level6 = 6, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Pretty good compression! | ||||||
|  |         /// </summary> | ||||||
|  |         Level7 = 7, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///  Better compression than Level7! | ||||||
|  |         /// </summary> | ||||||
|  |         Level8 = 8, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The "best" compression, where best means greatest reduction in size of the input data stream. | ||||||
|  |         /// This is also the slowest compression. | ||||||
|  |         /// </summary> | ||||||
|  |         BestCompression = 9, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// A synonym for BestCompression. | ||||||
|  |         /// </summary> | ||||||
|  |         Level9 = 9, | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// Describes options for how the compression algorithm is executed.  Different strategies | ||||||
|  |     /// work better on different sorts of data.  The strategy parameter can affect the compression | ||||||
|  |     /// ratio and the speed of compression but not the correctness of the compresssion. | ||||||
|  |     /// </summary> | ||||||
|  |     public enum CompressionStrategy | ||||||
|  |     { | ||||||
|  |         /// <summary> | ||||||
|  |         /// The default strategy is probably the best for normal data. | ||||||
|  |         /// </summary> | ||||||
|  |         Default = 0, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The <c>Filtered</c> strategy is intended to be used most effectively with data produced by a | ||||||
|  |         /// filter or predictor.  By this definition, filtered data consists mostly of small | ||||||
|  |         /// values with a somewhat random distribution.  In this case, the compression algorithm | ||||||
|  |         /// is tuned to compress them better.  The effect of <c>Filtered</c> is to force more Huffman | ||||||
|  |         /// coding and less string matching; it is a half-step between <c>Default</c> and <c>HuffmanOnly</c>. | ||||||
|  |         /// </summary> | ||||||
|  |         Filtered = 1, | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Using <c>HuffmanOnly</c> will force the compressor to do Huffman encoding only, with no | ||||||
|  |         /// string matching. | ||||||
|  |         /// </summary> | ||||||
|  |         HuffmanOnly = 2, | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// An enum to specify the direction of transcoding - whether to compress or decompress. | ||||||
|  |     /// </summary> | ||||||
|  |     public enum CompressionMode | ||||||
|  |     { | ||||||
|  |         /// <summary> | ||||||
|  |         /// Used to specify that the stream should compress the data. | ||||||
|  |         /// </summary> | ||||||
|  |         Compress= 0, | ||||||
|  |         /// <summary> | ||||||
|  |         /// Used to specify that the stream should decompress the data. | ||||||
|  |         /// </summary> | ||||||
|  |         Decompress = 1, | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// A general purpose exception class for exceptions in the Zlib library. | ||||||
|  |     /// </summary> | ||||||
|  |     [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000E")] | ||||||
|  |     public class ZlibException : System.Exception | ||||||
|  |     { | ||||||
|  |         /// <summary> | ||||||
|  |         /// The ZlibException class captures exception information generated | ||||||
|  |         /// by the Zlib library. | ||||||
|  |         /// </summary> | ||||||
|  |         public ZlibException() | ||||||
|  |             : base() | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// This ctor collects a message attached to the exception. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="s">the message for the exception.</param> | ||||||
|  |         public ZlibException(System.String s) | ||||||
|  |             : base(s) | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     internal class SharedUtils | ||||||
|  |     { | ||||||
|  |         /// <summary> | ||||||
|  |         /// Performs an unsigned bitwise right shift with the specified number | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="number">Number to operate on</param> | ||||||
|  |         /// <param name="bits">Ammount of bits to shift</param> | ||||||
|  |         /// <returns>The resulting number from the shift operation</returns> | ||||||
|  |         public static int URShift(int number, int bits) | ||||||
|  |         { | ||||||
|  |             return (int)((uint)number >> bits); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  | #if NOT | ||||||
|  |         /// <summary> | ||||||
|  |         /// Performs an unsigned bitwise right shift with the specified number | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="number">Number to operate on</param> | ||||||
|  |         /// <param name="bits">Ammount of bits to shift</param> | ||||||
|  |         /// <returns>The resulting number from the shift operation</returns> | ||||||
|  |         public static long URShift(long number, int bits) | ||||||
|  |         { | ||||||
|  |             return (long) ((UInt64)number >> bits); | ||||||
|  |         } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Reads a number of characters from the current source TextReader and writes | ||||||
|  |         ///   the data to the target array at the specified index. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <param name="sourceTextReader">The source TextReader to read from</param> | ||||||
|  |         /// <param name="target">Contains the array of characteres read from the source TextReader.</param> | ||||||
|  |         /// <param name="start">The starting index of the target array.</param> | ||||||
|  |         /// <param name="count">The maximum number of characters to read from the source TextReader.</param> | ||||||
|  |         /// | ||||||
|  |         /// <returns> | ||||||
|  |         ///   The number of characters read. The number will be less than or equal to | ||||||
|  |         ///   count depending on the data available in the source TextReader. Returns -1 | ||||||
|  |         ///   if the end of the stream is reached. | ||||||
|  |         /// </returns> | ||||||
|  |         public static System.Int32 ReadInput(System.IO.TextReader sourceTextReader, byte[] target, int start, int count) | ||||||
|  |         { | ||||||
|  |             // Returns 0 bytes if not enough space in target | ||||||
|  |             if (target.Length == 0) return 0; | ||||||
|  |  | ||||||
|  |             char[] charArray = new char[target.Length]; | ||||||
|  |             int bytesRead = sourceTextReader.Read(charArray, start, count); | ||||||
|  |  | ||||||
|  |             // Returns -1 if EOF | ||||||
|  |             if (bytesRead == 0) return -1; | ||||||
|  |  | ||||||
|  |             for (int index = start; index < start + bytesRead; index++) | ||||||
|  |                 target[index] = (byte)charArray[index]; | ||||||
|  |  | ||||||
|  |             return bytesRead; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         internal static byte[] ToByteArray(System.String sourceString) | ||||||
|  |         { | ||||||
|  |             return System.Text.UTF8Encoding.UTF8.GetBytes(sourceString); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         internal static char[] ToCharArray(byte[] byteArray) | ||||||
|  |         { | ||||||
|  |             return System.Text.UTF8Encoding.UTF8.GetChars(byteArray); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     internal static class InternalConstants | ||||||
|  |     { | ||||||
|  |         internal static readonly int MAX_BITS     = 15; | ||||||
|  |         internal static readonly int BL_CODES     = 19; | ||||||
|  |         internal static readonly int D_CODES      = 30; | ||||||
|  |         internal static readonly int LITERALS     = 256; | ||||||
|  |         internal static readonly int LENGTH_CODES = 29; | ||||||
|  |         internal static readonly int L_CODES      = (LITERALS + 1 + LENGTH_CODES); | ||||||
|  |  | ||||||
|  |         // Bit length codes must not exceed MAX_BL_BITS bits | ||||||
|  |         internal static readonly int MAX_BL_BITS  = 7; | ||||||
|  |  | ||||||
|  |         // repeat previous bit length 3-6 times (2 bits of repeat count) | ||||||
|  |         internal static readonly int REP_3_6      = 16; | ||||||
|  |  | ||||||
|  |         // repeat a zero length 3-10 times  (3 bits of repeat count) | ||||||
|  |         internal static readonly int REPZ_3_10    = 17; | ||||||
|  |  | ||||||
|  |         // repeat a zero length 11-138 times  (7 bits of repeat count) | ||||||
|  |         internal static readonly int REPZ_11_138  = 18; | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     internal sealed class StaticTree | ||||||
|  |     { | ||||||
|  |         internal static readonly short[] lengthAndLiteralsTreeCodes = new short[] { | ||||||
|  |             12, 8, 140, 8, 76, 8, 204, 8, 44, 8, 172, 8, 108, 8, 236, 8, | ||||||
|  |             28, 8, 156, 8, 92, 8, 220, 8, 60, 8, 188, 8, 124, 8, 252, 8, | ||||||
|  |              2, 8, 130, 8, 66, 8, 194, 8, 34, 8, 162, 8, 98, 8, 226, 8, | ||||||
|  |             18, 8, 146, 8, 82, 8, 210, 8, 50, 8, 178, 8, 114, 8, 242, 8, | ||||||
|  |             10, 8, 138, 8, 74, 8, 202, 8, 42, 8, 170, 8, 106, 8, 234, 8, | ||||||
|  |             26, 8, 154, 8, 90, 8, 218, 8, 58, 8, 186, 8, 122, 8, 250, 8, | ||||||
|  |              6, 8, 134, 8, 70, 8, 198, 8, 38, 8, 166, 8, 102, 8, 230, 8, | ||||||
|  |             22, 8, 150, 8, 86, 8, 214, 8, 54, 8, 182, 8, 118, 8, 246, 8, | ||||||
|  |             14, 8, 142, 8, 78, 8, 206, 8, 46, 8, 174, 8, 110, 8, 238, 8, | ||||||
|  |             30, 8, 158, 8, 94, 8, 222, 8, 62, 8, 190, 8, 126, 8, 254, 8, | ||||||
|  |              1, 8, 129, 8, 65, 8, 193, 8, 33, 8, 161, 8, 97, 8, 225, 8, | ||||||
|  |             17, 8, 145, 8, 81, 8, 209, 8, 49, 8, 177, 8, 113, 8, 241, 8, | ||||||
|  |              9, 8, 137, 8, 73, 8, 201, 8, 41, 8, 169, 8, 105, 8, 233, 8, | ||||||
|  |             25, 8, 153, 8, 89, 8, 217, 8, 57, 8, 185, 8, 121, 8, 249, 8, | ||||||
|  |              5, 8, 133, 8, 69, 8, 197, 8, 37, 8, 165, 8, 101, 8, 229, 8, | ||||||
|  |             21, 8, 149, 8, 85, 8, 213, 8, 53, 8, 181, 8, 117, 8, 245, 8, | ||||||
|  |             13, 8, 141, 8, 77, 8, 205, 8, 45, 8, 173, 8, 109, 8, 237, 8, | ||||||
|  |             29, 8, 157, 8, 93, 8, 221, 8, 61, 8, 189, 8, 125, 8, 253, 8, | ||||||
|  |             19, 9, 275, 9, 147, 9, 403, 9, 83, 9, 339, 9, 211, 9, 467, 9, | ||||||
|  |             51, 9, 307, 9, 179, 9, 435, 9, 115, 9, 371, 9, 243, 9, 499, 9, | ||||||
|  |             11, 9, 267, 9, 139, 9, 395, 9, 75, 9, 331, 9, 203, 9, 459, 9, | ||||||
|  |             43, 9, 299, 9, 171, 9, 427, 9, 107, 9, 363, 9, 235, 9, 491, 9, | ||||||
|  |             27, 9, 283, 9, 155, 9, 411, 9, 91, 9, 347, 9, 219, 9, 475, 9, | ||||||
|  |             59, 9, 315, 9, 187, 9, 443, 9, 123, 9, 379, 9, 251, 9, 507, 9, | ||||||
|  |              7, 9, 263, 9, 135, 9, 391, 9, 71, 9, 327, 9, 199, 9, 455, 9, | ||||||
|  |             39, 9, 295, 9, 167, 9, 423, 9, 103, 9, 359, 9, 231, 9, 487, 9, | ||||||
|  |             23, 9, 279, 9, 151, 9, 407, 9, 87, 9, 343, 9, 215, 9, 471, 9, | ||||||
|  |             55, 9, 311, 9, 183, 9, 439, 9, 119, 9, 375, 9, 247, 9, 503, 9, | ||||||
|  |             15, 9, 271, 9, 143, 9, 399, 9, 79, 9, 335, 9, 207, 9, 463, 9, | ||||||
|  |             47, 9, 303, 9, 175, 9, 431, 9, 111, 9, 367, 9, 239, 9, 495, 9, | ||||||
|  |             31, 9, 287, 9, 159, 9, 415, 9, 95, 9, 351, 9, 223, 9, 479, 9, | ||||||
|  |             63, 9, 319, 9, 191, 9, 447, 9, 127, 9, 383, 9, 255, 9, 511, 9, | ||||||
|  |              0, 7, 64, 7, 32, 7, 96, 7, 16, 7, 80, 7, 48, 7, 112, 7, | ||||||
|  |              8, 7, 72, 7, 40, 7, 104, 7, 24, 7, 88, 7, 56, 7, 120, 7, | ||||||
|  |              4, 7, 68, 7, 36, 7, 100, 7, 20, 7, 84, 7, 52, 7, 116, 7, | ||||||
|  |              3, 8, 131, 8, 67, 8, 195, 8, 35, 8, 163, 8, 99, 8, 227, 8 | ||||||
|  |         }; | ||||||
|  |  | ||||||
|  |         internal static readonly short[] distTreeCodes = new short[] { | ||||||
|  |             0, 5, 16, 5, 8, 5, 24, 5, 4, 5, 20, 5, 12, 5, 28, 5, | ||||||
|  |             2, 5, 18, 5, 10, 5, 26, 5, 6, 5, 22, 5, 14, 5, 30, 5, | ||||||
|  |             1, 5, 17, 5, 9, 5, 25, 5, 5, 5, 21, 5, 13, 5, 29, 5, | ||||||
|  |             3, 5, 19, 5, 11, 5, 27, 5, 7, 5, 23, 5 }; | ||||||
|  |  | ||||||
|  |         internal static readonly StaticTree Literals; | ||||||
|  |         internal static readonly StaticTree Distances; | ||||||
|  |         internal static readonly StaticTree BitLengths; | ||||||
|  |  | ||||||
|  |         internal short[] treeCodes; // static tree or null | ||||||
|  |         internal int[] extraBits;   // extra bits for each code or null | ||||||
|  |         internal int extraBase;     // base index for extra_bits | ||||||
|  |         internal int elems;         // max number of elements in the tree | ||||||
|  |         internal int maxLength;     // max bit length for the codes | ||||||
|  |  | ||||||
|  |         private StaticTree(short[] treeCodes, int[] extraBits, int extraBase, int elems, int maxLength) | ||||||
|  |         { | ||||||
|  |             this.treeCodes = treeCodes; | ||||||
|  |             this.extraBits = extraBits; | ||||||
|  |             this.extraBase = extraBase; | ||||||
|  |             this.elems = elems; | ||||||
|  |             this.maxLength = maxLength; | ||||||
|  |         } | ||||||
|  |         static StaticTree() | ||||||
|  |         { | ||||||
|  |             Literals = new StaticTree(lengthAndLiteralsTreeCodes, Tree.ExtraLengthBits, InternalConstants.LITERALS + 1, InternalConstants.L_CODES, InternalConstants.MAX_BITS); | ||||||
|  |             Distances = new StaticTree(distTreeCodes, Tree.ExtraDistanceBits, 0, InternalConstants.D_CODES, InternalConstants.MAX_BITS); | ||||||
|  |             BitLengths = new StaticTree(null, Tree.extra_blbits, 0, InternalConstants.BL_CODES, InternalConstants.MAX_BL_BITS); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// Computes an Adler-32 checksum. | ||||||
|  |     /// </summary> | ||||||
|  |     /// <remarks> | ||||||
|  |     /// The Adler checksum is similar to a CRC checksum, but faster to compute, though less | ||||||
|  |     /// reliable.  It is used in producing RFC1950 compressed streams.  The Adler checksum | ||||||
|  |     /// is a required part of the "ZLIB" standard.  Applications will almost never need to | ||||||
|  |     /// use this class directly. | ||||||
|  |     /// </remarks> | ||||||
|  |     /// | ||||||
|  |     /// <exclude/> | ||||||
|  |     public sealed class Adler | ||||||
|  |     { | ||||||
|  |         // largest prime smaller than 65536 | ||||||
|  |         private static readonly uint BASE = 65521; | ||||||
|  |         // NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 | ||||||
|  |         private static readonly int NMAX = 5552; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #pragma warning disable 3001 | ||||||
|  | #pragma warning disable 3002 | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Calculates the Adler32 checksum. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     This is used within ZLIB.  You probably don't need to use this directly. | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <example> | ||||||
|  |         ///    To compute an Adler32 checksum on a byte array: | ||||||
|  |         ///  <code> | ||||||
|  |         ///    var adler = Adler.Adler32(0, null, 0, 0); | ||||||
|  |         ///    adler = Adler.Adler32(adler, buffer, index, length); | ||||||
|  |         ///  </code> | ||||||
|  |         /// </example> | ||||||
|  |         public static uint Adler32(uint adler, byte[] buf, int index, int len) | ||||||
|  |         { | ||||||
|  |             if (buf == null) | ||||||
|  |                 return 1; | ||||||
|  |  | ||||||
|  |             uint s1 = (uint) (adler & 0xffff); | ||||||
|  |             uint s2 = (uint) ((adler >> 16) & 0xffff); | ||||||
|  |  | ||||||
|  |             while (len > 0) | ||||||
|  |             { | ||||||
|  |                 int k = len < NMAX ? len : NMAX; | ||||||
|  |                 len -= k; | ||||||
|  |                 while (k >= 16) | ||||||
|  |                 { | ||||||
|  |                     //s1 += (buf[index++] & 0xff); s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     s1 += buf[index++]; s2 += s1; | ||||||
|  |                     k -= 16; | ||||||
|  |                 } | ||||||
|  |                 if (k != 0) | ||||||
|  |                 { | ||||||
|  |                     do | ||||||
|  |                     { | ||||||
|  |                         s1 += buf[index++]; | ||||||
|  |                         s2 += s1; | ||||||
|  |                     } | ||||||
|  |                     while (--k != 0); | ||||||
|  |                 } | ||||||
|  |                 s1 %= BASE; | ||||||
|  |                 s2 %= BASE; | ||||||
|  |             } | ||||||
|  |             return (uint)((s2 << 16) | s1); | ||||||
|  |         } | ||||||
|  | #pragma warning restore 3001 | ||||||
|  | #pragma warning restore 3002 | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										66
									
								
								src/ZlibAndroid/ZlibAndroid.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								src/ZlibAndroid/ZlibAndroid.csproj
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,66 @@ | |||||||
|  | <?xml version="1.0" encoding="utf-8"?> | ||||||
|  | <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | ||||||
|  |   <PropertyGroup> | ||||||
|  |     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> | ||||||
|  |     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> | ||||||
|  |     <ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> | ||||||
|  |     <ProjectGuid>{6C29A7E7-E016-4FC1-B1A0-DEE26AC711BB}</ProjectGuid> | ||||||
|  |     <OutputType>Library</OutputType> | ||||||
|  |     <RootNamespace>ZlibAndroid</RootNamespace> | ||||||
|  |     <AndroidResgenFile>Resources\Resource.designer.cs</AndroidResgenFile> | ||||||
|  |     <AndroidResgenClass>Resource</AndroidResgenClass> | ||||||
|  |     <MonoAndroidResourcePrefix>Resources</MonoAndroidResourcePrefix> | ||||||
|  |     <MonoAndroidAssetsPrefix>Assets</MonoAndroidAssetsPrefix> | ||||||
|  |     <AndroidUseLatestPlatformSdk>True</AndroidUseLatestPlatformSdk> | ||||||
|  |     <AssemblyName>ZlibAndroid</AssemblyName> | ||||||
|  |     <TargetFrameworkVersion>v5.0</TargetFrameworkVersion> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> | ||||||
|  |     <DebugSymbols>true</DebugSymbols> | ||||||
|  |     <DebugType>full</DebugType> | ||||||
|  |     <Optimize>false</Optimize> | ||||||
|  |     <OutputPath>bin\Debug</OutputPath> | ||||||
|  |     <DefineConstants>DEBUG;</DefineConstants> | ||||||
|  |     <ErrorReport>prompt</ErrorReport> | ||||||
|  |     <WarningLevel>4</WarningLevel> | ||||||
|  |     <ConsolePause>false</ConsolePause> | ||||||
|  |     <AndroidLinkMode>None</AndroidLinkMode> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||||||
|  |     <DebugType>full</DebugType> | ||||||
|  |     <Optimize>true</Optimize> | ||||||
|  |     <OutputPath>bin\Release</OutputPath> | ||||||
|  |     <ErrorReport>prompt</ErrorReport> | ||||||
|  |     <WarningLevel>4</WarningLevel> | ||||||
|  |     <ConsolePause>false</ConsolePause> | ||||||
|  |     <AndroidUseSharedRuntime>false</AndroidUseSharedRuntime> | ||||||
|  |   </PropertyGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <Reference Include="System" /> | ||||||
|  |     <Reference Include="System.Xml" /> | ||||||
|  |     <Reference Include="System.Core" /> | ||||||
|  |     <Reference Include="Mono.Android" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <Compile Include="Resources\Resource.designer.cs" /> | ||||||
|  |     <Compile Include="CRC32.cs" /> | ||||||
|  |     <Compile Include="Deflate.cs" /> | ||||||
|  |     <Compile Include="DeflateStream.cs" /> | ||||||
|  |     <Compile Include="GZipStream.cs" /> | ||||||
|  |     <Compile Include="Inflate.cs" /> | ||||||
|  |     <Compile Include="InfTree.cs" /> | ||||||
|  |     <Compile Include="Tree.cs" /> | ||||||
|  |     <Compile Include="Zlib.cs" /> | ||||||
|  |     <Compile Include="ZlibBaseStream.cs" /> | ||||||
|  |     <Compile Include="ZlibCodec.cs" /> | ||||||
|  |     <Compile Include="ZlibConstants.cs" /> | ||||||
|  |     <Compile Include="ZlibStream.cs" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <None Include="Resources\AboutResources.txt" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <ItemGroup> | ||||||
|  |     <AndroidResource Include="Resources\values\Strings.xml" /> | ||||||
|  |   </ItemGroup> | ||||||
|  |   <Import Project="$(MSBuildExtensionsPath)\Novell\Novell.MonoDroid.CSharp.targets" /> | ||||||
|  | </Project> | ||||||
							
								
								
									
										627
									
								
								src/ZlibAndroid/ZlibBaseStream.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										627
									
								
								src/ZlibAndroid/ZlibBaseStream.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,627 @@ | |||||||
|  | // ZlibBaseStream.cs | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. | ||||||
|  | // All rights reserved. | ||||||
|  | // | ||||||
|  | // This code module is part of DotNetZip, a zipfile class library. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This code is licensed under the Microsoft Public License. | ||||||
|  | // See the file License.txt for the license details. | ||||||
|  | // More info on: http://dotnetzip.codeplex.com | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // last saved (in emacs): | ||||||
|  | // Time-stamp: <2011-August-06 21:22:38> | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This module defines the ZlibBaseStream class, which is an intnernal | ||||||
|  | // base class for DeflateStream, ZlibStream and GZipStream. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | using System; | ||||||
|  | using System.IO; | ||||||
|  |  | ||||||
|  | namespace Ionic.Zlib | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     internal enum ZlibStreamFlavor { ZLIB = 1950, DEFLATE = 1951, GZIP = 1952 } | ||||||
|  |  | ||||||
|  |     internal class ZlibBaseStream : System.IO.Stream | ||||||
|  |     { | ||||||
|  |         protected internal ZlibCodec _z = null; // deferred init... new ZlibCodec(); | ||||||
|  |  | ||||||
|  |         protected internal StreamMode _streamMode = StreamMode.Undefined; | ||||||
|  |         protected internal FlushType _flushMode; | ||||||
|  |         protected internal ZlibStreamFlavor _flavor; | ||||||
|  |         protected internal CompressionMode _compressionMode; | ||||||
|  |         protected internal CompressionLevel _level; | ||||||
|  |         protected internal bool _leaveOpen; | ||||||
|  |         protected internal byte[] _workingBuffer; | ||||||
|  |         protected internal int _bufferSize = ZlibConstants.WorkingBufferSizeDefault; | ||||||
|  |         protected internal byte[] _buf1 = new byte[1]; | ||||||
|  |  | ||||||
|  |         protected internal System.IO.Stream _stream; | ||||||
|  |         protected internal CompressionStrategy Strategy = CompressionStrategy.Default; | ||||||
|  |  | ||||||
|  |         // workitem 7159 | ||||||
|  |         Ionic.Crc.CRC32 crc; | ||||||
|  |         protected internal string _GzipFileName; | ||||||
|  |         protected internal string _GzipComment; | ||||||
|  |         protected internal DateTime _GzipMtime; | ||||||
|  |         protected internal int _gzipHeaderByteCount; | ||||||
|  |  | ||||||
|  |         internal int Crc32 { get { if (crc == null) return 0; return crc.Crc32Result; } } | ||||||
|  |  | ||||||
|  |         public ZlibBaseStream(System.IO.Stream stream, | ||||||
|  |                               CompressionMode compressionMode, | ||||||
|  |                               CompressionLevel level, | ||||||
|  |                               ZlibStreamFlavor flavor, | ||||||
|  |                               bool leaveOpen) | ||||||
|  |             : base() | ||||||
|  |         { | ||||||
|  |             this._flushMode = FlushType.None; | ||||||
|  |             //this._workingBuffer = new byte[WORKING_BUFFER_SIZE_DEFAULT]; | ||||||
|  |             this._stream = stream; | ||||||
|  |             this._leaveOpen = leaveOpen; | ||||||
|  |             this._compressionMode = compressionMode; | ||||||
|  |             this._flavor = flavor; | ||||||
|  |             this._level = level; | ||||||
|  |             // workitem 7159 | ||||||
|  |             if (flavor == ZlibStreamFlavor.GZIP) | ||||||
|  |             { | ||||||
|  |                 this.crc = new Ionic.Crc.CRC32(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         protected internal bool _wantCompress | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 return (this._compressionMode == CompressionMode.Compress); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private ZlibCodec z | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 if (_z == null) | ||||||
|  |                 { | ||||||
|  |                     bool wantRfc1950Header = (this._flavor == ZlibStreamFlavor.ZLIB); | ||||||
|  |                     _z = new ZlibCodec(); | ||||||
|  |                     if (this._compressionMode == CompressionMode.Decompress) | ||||||
|  |                     { | ||||||
|  |                         _z.InitializeInflate(wantRfc1950Header); | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         _z.Strategy = Strategy; | ||||||
|  |                         _z.InitializeDeflate(this._level, wantRfc1950Header); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 return _z; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         private byte[] workingBuffer | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 if (_workingBuffer == null) | ||||||
|  |                     _workingBuffer = new byte[_bufferSize]; | ||||||
|  |                 return _workingBuffer; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         public override void Write(System.Byte[] buffer, int offset, int count) | ||||||
|  |         { | ||||||
|  |             // workitem 7159 | ||||||
|  |             // calculate the CRC on the unccompressed data  (before writing) | ||||||
|  |             if (crc != null) | ||||||
|  |                 crc.SlurpBlock(buffer, offset, count); | ||||||
|  |  | ||||||
|  |             if (_streamMode == StreamMode.Undefined) | ||||||
|  |                 _streamMode = StreamMode.Writer; | ||||||
|  |             else if (_streamMode != StreamMode.Writer) | ||||||
|  |                 throw new ZlibException("Cannot Write after Reading."); | ||||||
|  |  | ||||||
|  |             if (count == 0) | ||||||
|  |                 return; | ||||||
|  |  | ||||||
|  |             // first reference of z property will initialize the private var _z | ||||||
|  |             z.InputBuffer = buffer; | ||||||
|  |             _z.NextIn = offset; | ||||||
|  |             _z.AvailableBytesIn = count; | ||||||
|  |             bool done = false; | ||||||
|  |             do | ||||||
|  |             { | ||||||
|  |                 _z.OutputBuffer = workingBuffer; | ||||||
|  |                 _z.NextOut = 0; | ||||||
|  |                 _z.AvailableBytesOut = _workingBuffer.Length; | ||||||
|  |                 int rc = (_wantCompress) | ||||||
|  |                     ? _z.Deflate(_flushMode) | ||||||
|  |                     : _z.Inflate(_flushMode); | ||||||
|  |                 if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) | ||||||
|  |                     throw new ZlibException((_wantCompress ? "de" : "in") + "flating: " + _z.Message); | ||||||
|  |  | ||||||
|  |                 //if (_workingBuffer.Length - _z.AvailableBytesOut > 0) | ||||||
|  |                 _stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut); | ||||||
|  |  | ||||||
|  |                 done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0; | ||||||
|  |  | ||||||
|  |                 // If GZIP and de-compress, we're done when 8 bytes remain. | ||||||
|  |                 if (_flavor == ZlibStreamFlavor.GZIP && !_wantCompress) | ||||||
|  |                     done = (_z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0); | ||||||
|  |  | ||||||
|  |             } | ||||||
|  |             while (!done); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         private void finish() | ||||||
|  |         { | ||||||
|  |             if (_z == null) return; | ||||||
|  |  | ||||||
|  |             if (_streamMode == StreamMode.Writer) | ||||||
|  |             { | ||||||
|  |                 bool done = false; | ||||||
|  |                 do | ||||||
|  |                 { | ||||||
|  |                     _z.OutputBuffer = workingBuffer; | ||||||
|  |                     _z.NextOut = 0; | ||||||
|  |                     _z.AvailableBytesOut = _workingBuffer.Length; | ||||||
|  |                     int rc = (_wantCompress) | ||||||
|  |                         ? _z.Deflate(FlushType.Finish) | ||||||
|  |                         : _z.Inflate(FlushType.Finish); | ||||||
|  |  | ||||||
|  |                     if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) | ||||||
|  |                     { | ||||||
|  |                         string verb = (_wantCompress ? "de" : "in") + "flating"; | ||||||
|  |                         if (_z.Message == null) | ||||||
|  |                             throw new ZlibException(String.Format("{0}: (rc = {1})", verb, rc)); | ||||||
|  |                         else | ||||||
|  |                             throw new ZlibException(verb + ": " + _z.Message); | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     if (_workingBuffer.Length - _z.AvailableBytesOut > 0) | ||||||
|  |                     { | ||||||
|  |                         _stream.Write(_workingBuffer, 0, _workingBuffer.Length - _z.AvailableBytesOut); | ||||||
|  |                     } | ||||||
|  |  | ||||||
|  |                     done = _z.AvailableBytesIn == 0 && _z.AvailableBytesOut != 0; | ||||||
|  |                     // If GZIP and de-compress, we're done when 8 bytes remain. | ||||||
|  |                     if (_flavor == ZlibStreamFlavor.GZIP && !_wantCompress) | ||||||
|  |                         done = (_z.AvailableBytesIn == 8 && _z.AvailableBytesOut != 0); | ||||||
|  |  | ||||||
|  |                 } | ||||||
|  |                 while (!done); | ||||||
|  |  | ||||||
|  |                 Flush(); | ||||||
|  |  | ||||||
|  |                 // workitem 7159 | ||||||
|  |                 if (_flavor == ZlibStreamFlavor.GZIP) | ||||||
|  |                 { | ||||||
|  |                     if (_wantCompress) | ||||||
|  |                     { | ||||||
|  |                         // Emit the GZIP trailer: CRC32 and  size mod 2^32 | ||||||
|  |                         int c1 = crc.Crc32Result; | ||||||
|  |                         _stream.Write(BitConverter.GetBytes(c1), 0, 4); | ||||||
|  |                         int c2 = (Int32)(crc.TotalBytesRead & 0x00000000FFFFFFFF); | ||||||
|  |                         _stream.Write(BitConverter.GetBytes(c2), 0, 4); | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         throw new ZlibException("Writing with decompression is not supported."); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             // workitem 7159 | ||||||
|  |             else if (_streamMode == StreamMode.Reader) | ||||||
|  |             { | ||||||
|  |                 if (_flavor == ZlibStreamFlavor.GZIP) | ||||||
|  |                 { | ||||||
|  |                     if (!_wantCompress) | ||||||
|  |                     { | ||||||
|  |                         // workitem 8501: handle edge case (decompress empty stream) | ||||||
|  |                         if (_z.TotalBytesOut == 0L) | ||||||
|  |                             return; | ||||||
|  |  | ||||||
|  |                         // Read and potentially verify the GZIP trailer: | ||||||
|  |                         // CRC32 and size mod 2^32 | ||||||
|  |                         byte[] trailer = new byte[8]; | ||||||
|  |  | ||||||
|  |                         // workitems 8679 & 12554 | ||||||
|  |                         if (_z.AvailableBytesIn < 8) | ||||||
|  |                         { | ||||||
|  |                             // Make sure we have read to the end of the stream | ||||||
|  |                             Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, _z.AvailableBytesIn); | ||||||
|  |                             int bytesNeeded = 8 - _z.AvailableBytesIn; | ||||||
|  |                             int bytesRead = _stream.Read(trailer, | ||||||
|  |                                                          _z.AvailableBytesIn, | ||||||
|  |                                                          bytesNeeded); | ||||||
|  |                             if (bytesNeeded != bytesRead) | ||||||
|  |                             { | ||||||
|  |                                 throw new ZlibException(String.Format("Missing or incomplete GZIP trailer. Expected 8 bytes, got {0}.", | ||||||
|  |                                                                       _z.AvailableBytesIn + bytesRead)); | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                         else | ||||||
|  |                         { | ||||||
|  |                             Array.Copy(_z.InputBuffer, _z.NextIn, trailer, 0, trailer.Length); | ||||||
|  |                         } | ||||||
|  |  | ||||||
|  |                         Int32 crc32_expected = BitConverter.ToInt32(trailer, 0); | ||||||
|  |                         Int32 crc32_actual = crc.Crc32Result; | ||||||
|  |                         Int32 isize_expected = BitConverter.ToInt32(trailer, 4); | ||||||
|  |                         Int32 isize_actual = (Int32)(_z.TotalBytesOut & 0x00000000FFFFFFFF); | ||||||
|  |  | ||||||
|  |                         if (crc32_actual != crc32_expected) | ||||||
|  |                             throw new ZlibException(String.Format("Bad CRC32 in GZIP trailer. (actual({0:X8})!=expected({1:X8}))", crc32_actual, crc32_expected)); | ||||||
|  |  | ||||||
|  |                         if (isize_actual != isize_expected) | ||||||
|  |                             throw new ZlibException(String.Format("Bad size in GZIP trailer. (actual({0})!=expected({1}))", isize_actual, isize_expected)); | ||||||
|  |  | ||||||
|  |                     } | ||||||
|  |                     else | ||||||
|  |                     { | ||||||
|  |                         throw new ZlibException("Reading with compression is not supported."); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         private void end() | ||||||
|  |         { | ||||||
|  |             if (z == null) | ||||||
|  |                 return; | ||||||
|  |             if (_wantCompress) | ||||||
|  |             { | ||||||
|  |                 _z.EndDeflate(); | ||||||
|  |             } | ||||||
|  |             else | ||||||
|  |             { | ||||||
|  |                 _z.EndInflate(); | ||||||
|  |             } | ||||||
|  |             _z = null; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         public override void Close() | ||||||
|  |         { | ||||||
|  |             if (_stream == null) return; | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 finish(); | ||||||
|  |             } | ||||||
|  |             finally | ||||||
|  |             { | ||||||
|  |                 end(); | ||||||
|  |                 if (!_leaveOpen) _stream.Close(); | ||||||
|  |                 _stream = null; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override void Flush() | ||||||
|  |         { | ||||||
|  |             _stream.Flush(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override System.Int64 Seek(System.Int64 offset, System.IO.SeekOrigin origin) | ||||||
|  |         { | ||||||
|  |             throw new NotImplementedException(); | ||||||
|  |             //_outStream.Seek(offset, origin); | ||||||
|  |         } | ||||||
|  |         public override void SetLength(System.Int64 value) | ||||||
|  |         { | ||||||
|  |             _stream.SetLength(value); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #if NOT | ||||||
|  |         public int Read() | ||||||
|  |         { | ||||||
|  |             if (Read(_buf1, 0, 1) == 0) | ||||||
|  |                 return 0; | ||||||
|  |             // calculate CRC after reading | ||||||
|  |             if (crc!=null) | ||||||
|  |                 crc.SlurpBlock(_buf1,0,1); | ||||||
|  |             return (_buf1[0] & 0xFF); | ||||||
|  |         } | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  |         private bool nomoreinput = false; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         private string ReadZeroTerminatedString() | ||||||
|  |         { | ||||||
|  |             var list = new System.Collections.Generic.List<byte>(); | ||||||
|  |             bool done = false; | ||||||
|  |             do | ||||||
|  |             { | ||||||
|  |                 // workitem 7740 | ||||||
|  |                 int n = _stream.Read(_buf1, 0, 1); | ||||||
|  |                 if (n != 1) | ||||||
|  |                     throw new ZlibException("Unexpected EOF reading GZIP header."); | ||||||
|  |                 else | ||||||
|  |                 { | ||||||
|  |                     if (_buf1[0] == 0) | ||||||
|  |                         done = true; | ||||||
|  |                     else | ||||||
|  |                         list.Add(_buf1[0]); | ||||||
|  |                 } | ||||||
|  |             } while (!done); | ||||||
|  |             byte[] a = list.ToArray(); | ||||||
|  |             return GZipStream.iso8859dash1.GetString(a, 0, a.Length); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         private int _ReadAndValidateGzipHeader() | ||||||
|  |         { | ||||||
|  |             int totalBytesRead = 0; | ||||||
|  |             // read the header on the first read | ||||||
|  |             byte[] header = new byte[10]; | ||||||
|  |             int n = _stream.Read(header, 0, header.Length); | ||||||
|  |  | ||||||
|  |             // workitem 8501: handle edge case (decompress empty stream) | ||||||
|  |             if (n == 0) | ||||||
|  |                 return 0; | ||||||
|  |  | ||||||
|  |             if (n != 10) | ||||||
|  |                 throw new ZlibException("Not a valid GZIP stream."); | ||||||
|  |  | ||||||
|  |             if (header[0] != 0x1F || header[1] != 0x8B || header[2] != 8) | ||||||
|  |                 throw new ZlibException("Bad GZIP header."); | ||||||
|  |  | ||||||
|  |             Int32 timet = BitConverter.ToInt32(header, 4); | ||||||
|  |             _GzipMtime = GZipStream._unixEpoch.AddSeconds(timet); | ||||||
|  |             totalBytesRead += n; | ||||||
|  |             if ((header[3] & 0x04) == 0x04) | ||||||
|  |             { | ||||||
|  |                 // read and discard extra field | ||||||
|  |                 n = _stream.Read(header, 0, 2); // 2-byte length field | ||||||
|  |                 totalBytesRead += n; | ||||||
|  |  | ||||||
|  |                 Int16 extraLength = (Int16)(header[0] + header[1] * 256); | ||||||
|  |                 byte[] extra = new byte[extraLength]; | ||||||
|  |                 n = _stream.Read(extra, 0, extra.Length); | ||||||
|  |                 if (n != extraLength) | ||||||
|  |                     throw new ZlibException("Unexpected end-of-file reading GZIP header."); | ||||||
|  |                 totalBytesRead += n; | ||||||
|  |             } | ||||||
|  |             if ((header[3] & 0x08) == 0x08) | ||||||
|  |                 _GzipFileName = ReadZeroTerminatedString(); | ||||||
|  |             if ((header[3] & 0x10) == 0x010) | ||||||
|  |                 _GzipComment = ReadZeroTerminatedString(); | ||||||
|  |             if ((header[3] & 0x02) == 0x02) | ||||||
|  |                 Read(_buf1, 0, 1); // CRC16, ignore | ||||||
|  |  | ||||||
|  |             return totalBytesRead; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         public override System.Int32 Read(System.Byte[] buffer, System.Int32 offset, System.Int32 count) | ||||||
|  |         { | ||||||
|  |             // According to MS documentation, any implementation of the IO.Stream.Read function must: | ||||||
|  |             // (a) throw an exception if offset & count reference an invalid part of the buffer, | ||||||
|  |             //     or if count < 0, or if buffer is null | ||||||
|  |             // (b) return 0 only upon EOF, or if count = 0 | ||||||
|  |             // (c) if not EOF, then return at least 1 byte, up to <count> bytes | ||||||
|  |  | ||||||
|  |             if (_streamMode == StreamMode.Undefined) | ||||||
|  |             { | ||||||
|  |                 if (!this._stream.CanRead) throw new ZlibException("The stream is not readable."); | ||||||
|  |                 // for the first read, set up some controls. | ||||||
|  |                 _streamMode = StreamMode.Reader; | ||||||
|  |                 // (The first reference to _z goes through the private accessor which | ||||||
|  |                 // may initialize it.) | ||||||
|  |                 z.AvailableBytesIn = 0; | ||||||
|  |                 if (_flavor == ZlibStreamFlavor.GZIP) | ||||||
|  |                 { | ||||||
|  |                     _gzipHeaderByteCount = _ReadAndValidateGzipHeader(); | ||||||
|  |                     // workitem 8501: handle edge case (decompress empty stream) | ||||||
|  |                     if (_gzipHeaderByteCount == 0) | ||||||
|  |                         return 0; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             if (_streamMode != StreamMode.Reader) | ||||||
|  |                 throw new ZlibException("Cannot Read after Writing."); | ||||||
|  |  | ||||||
|  |             if (count == 0) return 0; | ||||||
|  |             if (nomoreinput && _wantCompress) return 0;  // workitem 8557 | ||||||
|  |             if (buffer == null) throw new ArgumentNullException("buffer"); | ||||||
|  |             if (count < 0) throw new ArgumentOutOfRangeException("count"); | ||||||
|  |             if (offset < buffer.GetLowerBound(0)) throw new ArgumentOutOfRangeException("offset"); | ||||||
|  |             if ((offset + count) > buffer.GetLength(0)) throw new ArgumentOutOfRangeException("count"); | ||||||
|  |  | ||||||
|  |             int rc = 0; | ||||||
|  |  | ||||||
|  |             // set up the output of the deflate/inflate codec: | ||||||
|  |             _z.OutputBuffer = buffer; | ||||||
|  |             _z.NextOut = offset; | ||||||
|  |             _z.AvailableBytesOut = count; | ||||||
|  |  | ||||||
|  |             // This is necessary in case _workingBuffer has been resized. (new byte[]) | ||||||
|  |             // (The first reference to _workingBuffer goes through the private accessor which | ||||||
|  |             // may initialize it.) | ||||||
|  |             _z.InputBuffer = workingBuffer; | ||||||
|  |  | ||||||
|  |             do | ||||||
|  |             { | ||||||
|  |                 // need data in _workingBuffer in order to deflate/inflate.  Here, we check if we have any. | ||||||
|  |                 if ((_z.AvailableBytesIn == 0) && (!nomoreinput)) | ||||||
|  |                 { | ||||||
|  |                     // No data available, so try to Read data from the captive stream. | ||||||
|  |                     _z.NextIn = 0; | ||||||
|  |                     _z.AvailableBytesIn = _stream.Read(_workingBuffer, 0, _workingBuffer.Length); | ||||||
|  |                     if (_z.AvailableBytesIn == 0) | ||||||
|  |                         nomoreinput = true; | ||||||
|  |  | ||||||
|  |                 } | ||||||
|  |                 // we have data in InputBuffer; now compress or decompress as appropriate | ||||||
|  |                 rc = (_wantCompress) | ||||||
|  |                     ? _z.Deflate(_flushMode) | ||||||
|  |                     : _z.Inflate(_flushMode); | ||||||
|  |  | ||||||
|  |                 if (nomoreinput && (rc == ZlibConstants.Z_BUF_ERROR)) | ||||||
|  |                     return 0; | ||||||
|  |  | ||||||
|  |                 if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) | ||||||
|  |                     throw new ZlibException(String.Format("{0}flating:  rc={1}  msg={2}", (_wantCompress ? "de" : "in"), rc, _z.Message)); | ||||||
|  |  | ||||||
|  |                 if ((nomoreinput || rc == ZlibConstants.Z_STREAM_END) && (_z.AvailableBytesOut == count)) | ||||||
|  |                     break; // nothing more to read | ||||||
|  |             } | ||||||
|  |             //while (_z.AvailableBytesOut == count && rc == ZlibConstants.Z_OK); | ||||||
|  |             while (_z.AvailableBytesOut > 0 && !nomoreinput && rc == ZlibConstants.Z_OK); | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             // workitem 8557 | ||||||
|  |             // is there more room in output? | ||||||
|  |             if (_z.AvailableBytesOut > 0) | ||||||
|  |             { | ||||||
|  |                 if (rc == ZlibConstants.Z_OK && _z.AvailableBytesIn == 0) | ||||||
|  |                 { | ||||||
|  |                     // deferred | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 // are we completely done reading? | ||||||
|  |                 if (nomoreinput) | ||||||
|  |                 { | ||||||
|  |                     // and in compression? | ||||||
|  |                     if (_wantCompress) | ||||||
|  |                     { | ||||||
|  |                         // no more input data available; therefore we flush to | ||||||
|  |                         // try to complete the read | ||||||
|  |                         rc = _z.Deflate(FlushType.Finish); | ||||||
|  |  | ||||||
|  |                         if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) | ||||||
|  |                             throw new ZlibException(String.Format("Deflating:  rc={0}  msg={1}", rc, _z.Message)); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |             rc = (count - _z.AvailableBytesOut); | ||||||
|  |  | ||||||
|  |             // calculate CRC after reading | ||||||
|  |             if (crc != null) | ||||||
|  |                 crc.SlurpBlock(buffer, offset, rc); | ||||||
|  |  | ||||||
|  |             return rc; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         public override System.Boolean CanRead | ||||||
|  |         { | ||||||
|  |             get { return this._stream.CanRead; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override System.Boolean CanSeek | ||||||
|  |         { | ||||||
|  |             get { return this._stream.CanSeek; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override System.Boolean CanWrite | ||||||
|  |         { | ||||||
|  |             get { return this._stream.CanWrite; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override System.Int64 Length | ||||||
|  |         { | ||||||
|  |             get { return _stream.Length; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public override long Position | ||||||
|  |         { | ||||||
|  |             get { throw new NotImplementedException(); } | ||||||
|  |             set { throw new NotImplementedException(); } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         internal enum StreamMode | ||||||
|  |         { | ||||||
|  |             Writer, | ||||||
|  |             Reader, | ||||||
|  |             Undefined, | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         public static void CompressString(String s, Stream compressor) | ||||||
|  |         { | ||||||
|  |             byte[] uncompressed = System.Text.Encoding.UTF8.GetBytes(s); | ||||||
|  |             using (compressor) | ||||||
|  |             { | ||||||
|  |                 compressor.Write(uncompressed, 0, uncompressed.Length); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static void CompressBuffer(byte[] b, Stream compressor) | ||||||
|  |         { | ||||||
|  |             // workitem 8460 | ||||||
|  |             using (compressor) | ||||||
|  |             { | ||||||
|  |                 compressor.Write(b, 0, b.Length); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static String UncompressString(byte[] compressed, Stream decompressor) | ||||||
|  |         { | ||||||
|  |             // workitem 8460 | ||||||
|  |             byte[] working = new byte[1024]; | ||||||
|  |             var encoding = System.Text.Encoding.UTF8; | ||||||
|  |             using (var output = new MemoryStream()) | ||||||
|  |             { | ||||||
|  |                 using (decompressor) | ||||||
|  |                 { | ||||||
|  |                     int n; | ||||||
|  |                     while ((n = decompressor.Read(working, 0, working.Length)) != 0) | ||||||
|  |                     { | ||||||
|  |                         output.Write(working, 0, n); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |  | ||||||
|  |                 // reset to allow read from start | ||||||
|  |                 output.Seek(0, SeekOrigin.Begin); | ||||||
|  |                 var sr = new StreamReader(output, encoding); | ||||||
|  |                 return sr.ReadToEnd(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public static byte[] UncompressBuffer(byte[] compressed, Stream decompressor) | ||||||
|  |         { | ||||||
|  |             // workitem 8460 | ||||||
|  |             byte[] working = new byte[1024]; | ||||||
|  |             using (var output = new MemoryStream()) | ||||||
|  |             { | ||||||
|  |                 using (decompressor) | ||||||
|  |                 { | ||||||
|  |                     int n; | ||||||
|  |                     while ((n = decompressor.Read(working, 0, working.Length)) != 0) | ||||||
|  |                     { | ||||||
|  |                         output.Write(working, 0, n); | ||||||
|  |                     } | ||||||
|  |                 } | ||||||
|  |                 return output.ToArray(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
							
								
								
									
										717
									
								
								src/ZlibAndroid/ZlibCodec.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										717
									
								
								src/ZlibAndroid/ZlibCodec.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,717 @@ | |||||||
|  | // ZlibCodec.cs | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.   | ||||||
|  | // All rights reserved. | ||||||
|  | // | ||||||
|  | // This code module is part of DotNetZip, a zipfile class library. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This code is licensed under the Microsoft Public License.  | ||||||
|  | // See the file License.txt for the license details. | ||||||
|  | // More info on: http://dotnetzip.codeplex.com | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // last saved (in emacs):  | ||||||
|  | // Time-stamp: <2009-November-03 15:40:51> | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This module defines a Codec for ZLIB compression and | ||||||
|  | // decompression. This code extends code that was based the jzlib | ||||||
|  | // implementation of zlib, but this code is completely novel.  The codec | ||||||
|  | // class is new, and encapsulates some behaviors that are new, and some | ||||||
|  | // that were present in other classes in the jzlib code base.  In | ||||||
|  | // keeping with the license for jzlib, the copyright to the jzlib code | ||||||
|  | // is included below. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | //  | ||||||
|  | // Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. | ||||||
|  | //  | ||||||
|  | // Redistribution and use in source and binary forms, with or without | ||||||
|  | // modification, are permitted provided that the following conditions are met: | ||||||
|  | //  | ||||||
|  | // 1. Redistributions of source code must retain the above copyright notice, | ||||||
|  | // this list of conditions and the following disclaimer. | ||||||
|  | //  | ||||||
|  | // 2. Redistributions in binary form must reproduce the above copyright  | ||||||
|  | // notice, this list of conditions and the following disclaimer in  | ||||||
|  | // the documentation and/or other materials provided with the distribution. | ||||||
|  | //  | ||||||
|  | // 3. The names of the authors may not be used to endorse or promote products | ||||||
|  | // derived from this software without specific prior written permission. | ||||||
|  | //  | ||||||
|  | // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, | ||||||
|  | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, | ||||||
|  | // INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||||
|  | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||||
|  | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, | ||||||
|  | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||||||
|  | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||||||
|  | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||||||
|  | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
|  | //  | ||||||
|  | // ----------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // This program is based on zlib-1.1.3; credit to authors | ||||||
|  | // Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) | ||||||
|  | // and contributors of zlib. | ||||||
|  | // | ||||||
|  | // ----------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  |  | ||||||
|  | using System; | ||||||
|  | using Interop=System.Runtime.InteropServices; | ||||||
|  |  | ||||||
|  | namespace Ionic.Zlib | ||||||
|  | { | ||||||
|  |     /// <summary> | ||||||
|  |     /// Encoder and Decoder for ZLIB and DEFLATE (IETF RFC1950 and RFC1951). | ||||||
|  |     /// </summary> | ||||||
|  |     /// | ||||||
|  |     /// <remarks> | ||||||
|  |     /// This class compresses and decompresses data according to the Deflate algorithm | ||||||
|  |     /// and optionally, the ZLIB format, as documented in <see | ||||||
|  |     /// href="http://www.ietf.org/rfc/rfc1950.txt">RFC 1950 - ZLIB</see> and <see | ||||||
|  |     /// href="http://www.ietf.org/rfc/rfc1951.txt">RFC 1951 - DEFLATE</see>. | ||||||
|  |     /// </remarks> | ||||||
|  |     [Interop.GuidAttribute("ebc25cf6-9120-4283-b972-0e5520d0000D")] | ||||||
|  |     [Interop.ComVisible(true)] | ||||||
|  | #if !NETCF     | ||||||
|  |     [Interop.ClassInterface(Interop.ClassInterfaceType.AutoDispatch)] | ||||||
|  | #endif | ||||||
|  |     sealed public class ZlibCodec | ||||||
|  |     { | ||||||
|  |         /// <summary> | ||||||
|  |         /// The buffer from which data is taken. | ||||||
|  |         /// </summary> | ||||||
|  |         public byte[] InputBuffer; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// An index into the InputBuffer array, indicating where to start reading.  | ||||||
|  |         /// </summary> | ||||||
|  |         public int NextIn; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The number of bytes available in the InputBuffer, starting at NextIn.  | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// Generally you should set this to InputBuffer.Length before the first Inflate() or Deflate() call.  | ||||||
|  |         /// The class will update this number as calls to Inflate/Deflate are made. | ||||||
|  |         /// </remarks> | ||||||
|  |         public int AvailableBytesIn; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Total number of bytes read so far, through all calls to Inflate()/Deflate(). | ||||||
|  |         /// </summary> | ||||||
|  |         public long TotalBytesIn; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Buffer to store output data. | ||||||
|  |         /// </summary> | ||||||
|  |         public byte[] OutputBuffer; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// An index into the OutputBuffer array, indicating where to start writing.  | ||||||
|  |         /// </summary> | ||||||
|  |         public int NextOut; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The number of bytes available in the OutputBuffer, starting at NextOut.  | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// Generally you should set this to OutputBuffer.Length before the first Inflate() or Deflate() call.  | ||||||
|  |         /// The class will update this number as calls to Inflate/Deflate are made. | ||||||
|  |         /// </remarks> | ||||||
|  |         public int AvailableBytesOut; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Total number of bytes written to the output so far, through all calls to Inflate()/Deflate(). | ||||||
|  |         /// </summary> | ||||||
|  |         public long TotalBytesOut; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// used for diagnostics, when something goes wrong! | ||||||
|  |         /// </summary> | ||||||
|  |         public System.String Message; | ||||||
|  |  | ||||||
|  |         internal DeflateManager dstate; | ||||||
|  |         internal InflateManager istate; | ||||||
|  |  | ||||||
|  |         internal uint _Adler32; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The compression level to use in this codec.  Useful only in compression mode. | ||||||
|  |         /// </summary> | ||||||
|  |         public CompressionLevel CompressLevel = CompressionLevel.Default; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The number of Window Bits to use.   | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// This gauges the size of the sliding window, and hence the  | ||||||
|  |         /// compression effectiveness as well as memory consumption. It's best to just leave this  | ||||||
|  |         /// setting alone if you don't know what it is.  The maximum value is 15 bits, which implies | ||||||
|  |         /// a 32k window.   | ||||||
|  |         /// </remarks> | ||||||
|  |         public int WindowBits = ZlibConstants.WindowBitsDefault; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The compression strategy to use. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// This is only effective in compression.  The theory offered by ZLIB is that different | ||||||
|  |         /// strategies could potentially produce significant differences in compression behavior | ||||||
|  |         /// for different data sets.  Unfortunately I don't have any good recommendations for how | ||||||
|  |         /// to set it differently.  When I tested changing the strategy I got minimally different | ||||||
|  |         /// compression performance. It's best to leave this property alone if you don't have a | ||||||
|  |         /// good feel for it.  Or, you may want to produce a test harness that runs through the | ||||||
|  |         /// different strategy options and evaluates them on different file types. If you do that, | ||||||
|  |         /// let me know your results. | ||||||
|  |         /// </remarks> | ||||||
|  |         public CompressionStrategy Strategy = CompressionStrategy.Default; | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The Adler32 checksum on the data transferred through the codec so far. You probably don't need to look at this. | ||||||
|  |         /// </summary> | ||||||
|  |         public int Adler32 { get { return (int)_Adler32; } } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Create a ZlibCodec. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// If you use this default constructor, you will later have to explicitly call  | ||||||
|  |         /// InitializeInflate() or InitializeDeflate() before using the ZlibCodec to compress  | ||||||
|  |         /// or decompress.  | ||||||
|  |         /// </remarks> | ||||||
|  |         public ZlibCodec() { } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Create a ZlibCodec that either compresses or decompresses. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="mode"> | ||||||
|  |         /// Indicates whether the codec should compress (deflate) or decompress (inflate). | ||||||
|  |         /// </param> | ||||||
|  |         public ZlibCodec(CompressionMode mode) | ||||||
|  |         { | ||||||
|  |             if (mode == CompressionMode.Compress) | ||||||
|  |             { | ||||||
|  |                 int rc = InitializeDeflate(); | ||||||
|  |                 if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for deflate."); | ||||||
|  |             } | ||||||
|  |             else if (mode == CompressionMode.Decompress) | ||||||
|  |             { | ||||||
|  |                 int rc = InitializeInflate(); | ||||||
|  |                 if (rc != ZlibConstants.Z_OK) throw new ZlibException("Cannot initialize for inflate."); | ||||||
|  |             } | ||||||
|  |             else throw new ZlibException("Invalid ZlibStreamFlavor."); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Initialize the inflation state.  | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// It is not necessary to call this before using the ZlibCodec to inflate data;  | ||||||
|  |         /// It is implicitly called when you call the constructor. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <returns>Z_OK if everything goes well.</returns> | ||||||
|  |         public int InitializeInflate() | ||||||
|  |         { | ||||||
|  |             return InitializeInflate(this.WindowBits); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Initialize the inflation state with an explicit flag to | ||||||
|  |         /// govern the handling of RFC1950 header bytes. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         /// By default, the ZLIB header defined in <see | ||||||
|  |         /// href="http://www.ietf.org/rfc/rfc1950.txt">RFC 1950</see> is expected.  If | ||||||
|  |         /// you want to read a zlib stream you should specify true for | ||||||
|  |         /// expectRfc1950Header.  If you have a deflate stream, you will want to specify | ||||||
|  |         /// false. It is only necessary to invoke this initializer explicitly if you | ||||||
|  |         /// want to specify false. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <param name="expectRfc1950Header">whether to expect an RFC1950 header byte | ||||||
|  |         /// pair when reading the stream of data to be inflated.</param> | ||||||
|  |         /// | ||||||
|  |         /// <returns>Z_OK if everything goes well.</returns> | ||||||
|  |         public int InitializeInflate(bool expectRfc1950Header) | ||||||
|  |         { | ||||||
|  |             return InitializeInflate(this.WindowBits, expectRfc1950Header); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Initialize the ZlibCodec for inflation, with the specified number of window bits.  | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="windowBits">The number of window bits to use. If you need to ask what that is,  | ||||||
|  |         /// then you shouldn't be calling this initializer.</param> | ||||||
|  |         /// <returns>Z_OK if all goes well.</returns> | ||||||
|  |         public int InitializeInflate(int windowBits) | ||||||
|  |         { | ||||||
|  |             this.WindowBits = windowBits;             | ||||||
|  |             return InitializeInflate(windowBits, true); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Initialize the inflation state with an explicit flag to govern the handling of | ||||||
|  |         /// RFC1950 header bytes.  | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         /// If you want to read a zlib stream you should specify true for | ||||||
|  |         /// expectRfc1950Header. In this case, the library will expect to find a ZLIB | ||||||
|  |         /// header, as defined in <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC | ||||||
|  |         /// 1950</see>, in the compressed stream.  If you will be reading a DEFLATE or | ||||||
|  |         /// GZIP stream, which does not have such a header, you will want to specify | ||||||
|  |         /// false. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <param name="expectRfc1950Header">whether to expect an RFC1950 header byte pair when reading  | ||||||
|  |         /// the stream of data to be inflated.</param> | ||||||
|  |         /// <param name="windowBits">The number of window bits to use. If you need to ask what that is,  | ||||||
|  |         /// then you shouldn't be calling this initializer.</param> | ||||||
|  |         /// <returns>Z_OK if everything goes well.</returns> | ||||||
|  |         public int InitializeInflate(int windowBits, bool expectRfc1950Header) | ||||||
|  |         { | ||||||
|  |             this.WindowBits = windowBits; | ||||||
|  |             if (dstate != null) throw new ZlibException("You may not call InitializeInflate() after calling InitializeDeflate()."); | ||||||
|  |             istate = new InflateManager(expectRfc1950Header); | ||||||
|  |             return istate.Initialize(this, windowBits); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Inflate the data in the InputBuffer, placing the result in the OutputBuffer. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// You must have set InputBuffer and OutputBuffer, NextIn and NextOut, and AvailableBytesIn and  | ||||||
|  |         /// AvailableBytesOut  before calling this method. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <example> | ||||||
|  |         /// <code> | ||||||
|  |         /// private void InflateBuffer() | ||||||
|  |         /// { | ||||||
|  |         ///     int bufferSize = 1024; | ||||||
|  |         ///     byte[] buffer = new byte[bufferSize]; | ||||||
|  |         ///     ZlibCodec decompressor = new ZlibCodec(); | ||||||
|  |         ///  | ||||||
|  |         ///     Console.WriteLine("\n============================================"); | ||||||
|  |         ///     Console.WriteLine("Size of Buffer to Inflate: {0} bytes.", CompressedBytes.Length); | ||||||
|  |         ///     MemoryStream ms = new MemoryStream(DecompressedBytes); | ||||||
|  |         ///  | ||||||
|  |         ///     int rc = decompressor.InitializeInflate(); | ||||||
|  |         ///  | ||||||
|  |         ///     decompressor.InputBuffer = CompressedBytes; | ||||||
|  |         ///     decompressor.NextIn = 0; | ||||||
|  |         ///     decompressor.AvailableBytesIn = CompressedBytes.Length; | ||||||
|  |         ///  | ||||||
|  |         ///     decompressor.OutputBuffer = buffer; | ||||||
|  |         ///  | ||||||
|  |         ///     // pass 1: inflate  | ||||||
|  |         ///     do | ||||||
|  |         ///     { | ||||||
|  |         ///         decompressor.NextOut = 0; | ||||||
|  |         ///         decompressor.AvailableBytesOut = buffer.Length; | ||||||
|  |         ///         rc = decompressor.Inflate(FlushType.None); | ||||||
|  |         ///  | ||||||
|  |         ///         if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) | ||||||
|  |         ///             throw new Exception("inflating: " + decompressor.Message); | ||||||
|  |         ///  | ||||||
|  |         ///         ms.Write(decompressor.OutputBuffer, 0, buffer.Length - decompressor.AvailableBytesOut); | ||||||
|  |         ///     } | ||||||
|  |         ///     while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0); | ||||||
|  |         ///  | ||||||
|  |         ///     // pass 2: finish and flush | ||||||
|  |         ///     do | ||||||
|  |         ///     { | ||||||
|  |         ///         decompressor.NextOut = 0; | ||||||
|  |         ///         decompressor.AvailableBytesOut = buffer.Length; | ||||||
|  |         ///         rc = decompressor.Inflate(FlushType.Finish); | ||||||
|  |         ///  | ||||||
|  |         ///         if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) | ||||||
|  |         ///             throw new Exception("inflating: " + decompressor.Message); | ||||||
|  |         ///  | ||||||
|  |         ///         if (buffer.Length - decompressor.AvailableBytesOut > 0) | ||||||
|  |         ///             ms.Write(buffer, 0, buffer.Length - decompressor.AvailableBytesOut); | ||||||
|  |         ///     } | ||||||
|  |         ///     while (decompressor.AvailableBytesIn > 0 || decompressor.AvailableBytesOut == 0); | ||||||
|  |         ///  | ||||||
|  |         ///     decompressor.EndInflate(); | ||||||
|  |         /// } | ||||||
|  |         /// | ||||||
|  |         /// </code> | ||||||
|  |         /// </example> | ||||||
|  |         /// <param name="flush">The flush to use when inflating.</param> | ||||||
|  |         /// <returns>Z_OK if everything goes well.</returns> | ||||||
|  |         public int Inflate(FlushType flush) | ||||||
|  |         { | ||||||
|  |             if (istate == null) | ||||||
|  |                 throw new ZlibException("No Inflate State!"); | ||||||
|  |             return istate.Inflate(flush); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Ends an inflation session.  | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// Call this after successively calling Inflate().  This will cause all buffers to be flushed.  | ||||||
|  |         /// After calling this you cannot call Inflate() without a intervening call to one of the | ||||||
|  |         /// InitializeInflate() overloads. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <returns>Z_OK if everything goes well.</returns> | ||||||
|  |         public int EndInflate() | ||||||
|  |         { | ||||||
|  |             if (istate == null) | ||||||
|  |                 throw new ZlibException("No Inflate State!"); | ||||||
|  |             int ret = istate.End(); | ||||||
|  |             istate = null; | ||||||
|  |             return ret; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// I don't know what this does! | ||||||
|  |         /// </summary> | ||||||
|  |         /// <returns>Z_OK if everything goes well.</returns> | ||||||
|  |         public int SyncInflate() | ||||||
|  |         { | ||||||
|  |             if (istate == null) | ||||||
|  |                 throw new ZlibException("No Inflate State!"); | ||||||
|  |             return istate.Sync(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Initialize the ZlibCodec for deflation operation. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// The codec will use the MAX window bits and the default level of compression. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <example> | ||||||
|  |         /// <code> | ||||||
|  |         ///  int bufferSize = 40000; | ||||||
|  |         ///  byte[] CompressedBytes = new byte[bufferSize]; | ||||||
|  |         ///  byte[] DecompressedBytes = new byte[bufferSize]; | ||||||
|  |         ///   | ||||||
|  |         ///  ZlibCodec compressor = new ZlibCodec(); | ||||||
|  |         ///   | ||||||
|  |         ///  compressor.InitializeDeflate(CompressionLevel.Default); | ||||||
|  |         ///   | ||||||
|  |         ///  compressor.InputBuffer = System.Text.ASCIIEncoding.ASCII.GetBytes(TextToCompress); | ||||||
|  |         ///  compressor.NextIn = 0; | ||||||
|  |         ///  compressor.AvailableBytesIn = compressor.InputBuffer.Length; | ||||||
|  |         ///   | ||||||
|  |         ///  compressor.OutputBuffer = CompressedBytes; | ||||||
|  |         ///  compressor.NextOut = 0; | ||||||
|  |         ///  compressor.AvailableBytesOut = CompressedBytes.Length; | ||||||
|  |         ///   | ||||||
|  |         ///  while (compressor.TotalBytesIn != TextToCompress.Length && compressor.TotalBytesOut < bufferSize) | ||||||
|  |         ///  { | ||||||
|  |         ///    compressor.Deflate(FlushType.None); | ||||||
|  |         ///  } | ||||||
|  |         ///   | ||||||
|  |         ///  while (true) | ||||||
|  |         ///  { | ||||||
|  |         ///    int rc= compressor.Deflate(FlushType.Finish); | ||||||
|  |         ///    if (rc == ZlibConstants.Z_STREAM_END) break; | ||||||
|  |         ///  } | ||||||
|  |         ///   | ||||||
|  |         ///  compressor.EndDeflate(); | ||||||
|  |         ///    | ||||||
|  |         /// </code> | ||||||
|  |         /// </example> | ||||||
|  |         /// <returns>Z_OK if all goes well. You generally don't need to check the return code.</returns> | ||||||
|  |         public int InitializeDeflate() | ||||||
|  |         { | ||||||
|  |             return _InternalInitializeDeflate(true); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// The codec will use the maximum window bits (15) and the specified | ||||||
|  |         /// CompressionLevel.  It will emit a ZLIB stream as it compresses. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <param name="level">The compression level for the codec.</param> | ||||||
|  |         /// <returns>Z_OK if all goes well.</returns> | ||||||
|  |         public int InitializeDeflate(CompressionLevel level) | ||||||
|  |         { | ||||||
|  |             this.CompressLevel = level; | ||||||
|  |             return _InternalInitializeDeflate(true); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel,  | ||||||
|  |         /// and the explicit flag governing whether to emit an RFC1950 header byte pair. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// The codec will use the maximum window bits (15) and the specified CompressionLevel. | ||||||
|  |         /// If you want to generate a zlib stream, you should specify true for | ||||||
|  |         /// wantRfc1950Header. In this case, the library will emit a ZLIB | ||||||
|  |         /// header, as defined in <see href="http://www.ietf.org/rfc/rfc1950.txt">RFC | ||||||
|  |         /// 1950</see>, in the compressed stream.   | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <param name="level">The compression level for the codec.</param> | ||||||
|  |         /// <param name="wantRfc1950Header">whether to emit an initial RFC1950 byte pair in the compressed stream.</param> | ||||||
|  |         /// <returns>Z_OK if all goes well.</returns> | ||||||
|  |         public int InitializeDeflate(CompressionLevel level, bool wantRfc1950Header) | ||||||
|  |         { | ||||||
|  |             this.CompressLevel = level; | ||||||
|  |             return _InternalInitializeDeflate(wantRfc1950Header); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Initialize the ZlibCodec for deflation operation, using the specified CompressionLevel,  | ||||||
|  |         /// and the specified number of window bits.  | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// The codec will use the specified number of window bits and the specified CompressionLevel. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <param name="level">The compression level for the codec.</param> | ||||||
|  |         /// <param name="bits">the number of window bits to use.  If you don't know what this means, don't use this method.</param> | ||||||
|  |         /// <returns>Z_OK if all goes well.</returns> | ||||||
|  |         public int InitializeDeflate(CompressionLevel level, int bits) | ||||||
|  |         { | ||||||
|  |             this.CompressLevel = level; | ||||||
|  |             this.WindowBits = bits; | ||||||
|  |             return _InternalInitializeDeflate(true); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Initialize the ZlibCodec for deflation operation, using the specified | ||||||
|  |         /// CompressionLevel, the specified number of window bits, and the explicit flag | ||||||
|  |         /// governing whether to emit an RFC1950 header byte pair. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <param name="level">The compression level for the codec.</param> | ||||||
|  |         /// <param name="wantRfc1950Header">whether to emit an initial RFC1950 byte pair in the compressed stream.</param> | ||||||
|  |         /// <param name="bits">the number of window bits to use.  If you don't know what this means, don't use this method.</param> | ||||||
|  |         /// <returns>Z_OK if all goes well.</returns> | ||||||
|  |         public int InitializeDeflate(CompressionLevel level, int bits, bool wantRfc1950Header) | ||||||
|  |         { | ||||||
|  |             this.CompressLevel = level; | ||||||
|  |             this.WindowBits = bits; | ||||||
|  |             return _InternalInitializeDeflate(wantRfc1950Header); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         private int _InternalInitializeDeflate(bool wantRfc1950Header) | ||||||
|  |         { | ||||||
|  |             if (istate != null) throw new ZlibException("You may not call InitializeDeflate() after calling InitializeInflate()."); | ||||||
|  |             dstate = new DeflateManager(); | ||||||
|  |             dstate.WantRfc1950HeaderBytes = wantRfc1950Header; | ||||||
|  |  | ||||||
|  |             return dstate.Initialize(this, this.CompressLevel, this.WindowBits, this.Strategy); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Deflate one batch of data. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// You must have set InputBuffer and OutputBuffer before calling this method. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <example> | ||||||
|  |         /// <code> | ||||||
|  |         /// private void DeflateBuffer(CompressionLevel level) | ||||||
|  |         /// { | ||||||
|  |         ///     int bufferSize = 1024; | ||||||
|  |         ///     byte[] buffer = new byte[bufferSize]; | ||||||
|  |         ///     ZlibCodec compressor = new ZlibCodec(); | ||||||
|  |         ///  | ||||||
|  |         ///     Console.WriteLine("\n============================================"); | ||||||
|  |         ///     Console.WriteLine("Size of Buffer to Deflate: {0} bytes.", UncompressedBytes.Length); | ||||||
|  |         ///     MemoryStream ms = new MemoryStream(); | ||||||
|  |         ///  | ||||||
|  |         ///     int rc = compressor.InitializeDeflate(level); | ||||||
|  |         ///  | ||||||
|  |         ///     compressor.InputBuffer = UncompressedBytes; | ||||||
|  |         ///     compressor.NextIn = 0; | ||||||
|  |         ///     compressor.AvailableBytesIn = UncompressedBytes.Length; | ||||||
|  |         ///  | ||||||
|  |         ///     compressor.OutputBuffer = buffer; | ||||||
|  |         ///  | ||||||
|  |         ///     // pass 1: deflate  | ||||||
|  |         ///     do | ||||||
|  |         ///     { | ||||||
|  |         ///         compressor.NextOut = 0; | ||||||
|  |         ///         compressor.AvailableBytesOut = buffer.Length; | ||||||
|  |         ///         rc = compressor.Deflate(FlushType.None); | ||||||
|  |         ///  | ||||||
|  |         ///         if (rc != ZlibConstants.Z_OK && rc != ZlibConstants.Z_STREAM_END) | ||||||
|  |         ///             throw new Exception("deflating: " + compressor.Message); | ||||||
|  |         ///  | ||||||
|  |         ///         ms.Write(compressor.OutputBuffer, 0, buffer.Length - compressor.AvailableBytesOut); | ||||||
|  |         ///     } | ||||||
|  |         ///     while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0); | ||||||
|  |         ///  | ||||||
|  |         ///     // pass 2: finish and flush | ||||||
|  |         ///     do | ||||||
|  |         ///     { | ||||||
|  |         ///         compressor.NextOut = 0; | ||||||
|  |         ///         compressor.AvailableBytesOut = buffer.Length; | ||||||
|  |         ///         rc = compressor.Deflate(FlushType.Finish); | ||||||
|  |         ///  | ||||||
|  |         ///         if (rc != ZlibConstants.Z_STREAM_END && rc != ZlibConstants.Z_OK) | ||||||
|  |         ///             throw new Exception("deflating: " + compressor.Message); | ||||||
|  |         ///  | ||||||
|  |         ///         if (buffer.Length - compressor.AvailableBytesOut > 0) | ||||||
|  |         ///             ms.Write(buffer, 0, buffer.Length - compressor.AvailableBytesOut); | ||||||
|  |         ///     } | ||||||
|  |         ///     while (compressor.AvailableBytesIn > 0 || compressor.AvailableBytesOut == 0); | ||||||
|  |         ///  | ||||||
|  |         ///     compressor.EndDeflate(); | ||||||
|  |         ///  | ||||||
|  |         ///     ms.Seek(0, SeekOrigin.Begin); | ||||||
|  |         ///     CompressedBytes = new byte[compressor.TotalBytesOut]; | ||||||
|  |         ///     ms.Read(CompressedBytes, 0, CompressedBytes.Length); | ||||||
|  |         /// } | ||||||
|  |         /// </code> | ||||||
|  |         /// </example> | ||||||
|  |         /// <param name="flush">whether to flush all data as you deflate. Generally you will want to  | ||||||
|  |         /// use Z_NO_FLUSH here, in a series of calls to Deflate(), and then call EndDeflate() to  | ||||||
|  |         /// flush everything.  | ||||||
|  |         /// </param> | ||||||
|  |         /// <returns>Z_OK if all goes well.</returns> | ||||||
|  |         public int Deflate(FlushType flush) | ||||||
|  |         { | ||||||
|  |             if (dstate == null) | ||||||
|  |                 throw new ZlibException("No Deflate State!"); | ||||||
|  |             return dstate.Deflate(flush); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// End a deflation session. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// Call this after making a series of one or more calls to Deflate(). All buffers are flushed. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <returns>Z_OK if all goes well.</returns> | ||||||
|  |         public int EndDeflate() | ||||||
|  |         { | ||||||
|  |             if (dstate == null) | ||||||
|  |                 throw new ZlibException("No Deflate State!"); | ||||||
|  |             // TODO: dinoch Tue, 03 Nov 2009  15:39 (test this) | ||||||
|  |             //int ret = dstate.End(); | ||||||
|  |             dstate = null; | ||||||
|  |             return ZlibConstants.Z_OK; //ret; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Reset a codec for another deflation session. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// Call this to reset the deflation state.  For example if a thread is deflating | ||||||
|  |         /// non-consecutive blocks, you can call Reset() after the Deflate(Sync) of the first | ||||||
|  |         /// block and before the next Deflate(None) of the second block. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <returns>Z_OK if all goes well.</returns> | ||||||
|  |         public void ResetDeflate() | ||||||
|  |         { | ||||||
|  |             if (dstate == null) | ||||||
|  |                 throw new ZlibException("No Deflate State!"); | ||||||
|  |             dstate.Reset(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Set the CompressionStrategy and CompressionLevel for a deflation session. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="level">the level of compression to use.</param> | ||||||
|  |         /// <param name="strategy">the strategy to use for compression.</param> | ||||||
|  |         /// <returns>Z_OK if all goes well.</returns> | ||||||
|  |         public int SetDeflateParams(CompressionLevel level, CompressionStrategy strategy) | ||||||
|  |         { | ||||||
|  |             if (dstate == null) | ||||||
|  |                 throw new ZlibException("No Deflate State!"); | ||||||
|  |             return dstate.SetParams(level, strategy); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Set the dictionary to be used for either Inflation or Deflation. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="dictionary">The dictionary bytes to use.</param> | ||||||
|  |         /// <returns>Z_OK if all goes well.</returns> | ||||||
|  |         public int SetDictionary(byte[] dictionary) | ||||||
|  |         { | ||||||
|  |             if (istate != null) | ||||||
|  |                 return istate.SetDictionary(dictionary); | ||||||
|  |  | ||||||
|  |             if (dstate != null) | ||||||
|  |                 return dstate.SetDictionary(dictionary); | ||||||
|  |  | ||||||
|  |             throw new ZlibException("No Inflate or Deflate state!"); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Flush as much pending output as possible. All deflate() output goes | ||||||
|  |         // through this function so some applications may wish to modify it | ||||||
|  |         // to avoid allocating a large strm->next_out buffer and copying into it. | ||||||
|  |         // (See also read_buf()). | ||||||
|  |         internal void flush_pending() | ||||||
|  |         { | ||||||
|  |             int len = dstate.pendingCount; | ||||||
|  |  | ||||||
|  |             if (len > AvailableBytesOut) | ||||||
|  |                 len = AvailableBytesOut; | ||||||
|  |             if (len == 0) | ||||||
|  |                 return; | ||||||
|  |  | ||||||
|  |             if (dstate.pending.Length <= dstate.nextPending || | ||||||
|  |                 OutputBuffer.Length <= NextOut || | ||||||
|  |                 dstate.pending.Length < (dstate.nextPending + len) || | ||||||
|  |                 OutputBuffer.Length < (NextOut + len)) | ||||||
|  |             { | ||||||
|  |                 throw new ZlibException(String.Format("Invalid State. (pending.Length={0}, pendingCount={1})", | ||||||
|  |                     dstate.pending.Length, dstate.pendingCount)); | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             Array.Copy(dstate.pending, dstate.nextPending, OutputBuffer, NextOut, len); | ||||||
|  |  | ||||||
|  |             NextOut             += len; | ||||||
|  |             dstate.nextPending  += len; | ||||||
|  |             TotalBytesOut       += len; | ||||||
|  |             AvailableBytesOut   -= len; | ||||||
|  |             dstate.pendingCount -= len; | ||||||
|  |             if (dstate.pendingCount == 0) | ||||||
|  |             { | ||||||
|  |                 dstate.nextPending = 0; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // Read a new buffer from the current input stream, update the adler32 | ||||||
|  |         // and total number of bytes read.  All deflate() input goes through | ||||||
|  |         // this function so some applications may wish to modify it to avoid | ||||||
|  |         // allocating a large strm->next_in buffer and copying from it. | ||||||
|  |         // (See also flush_pending()). | ||||||
|  |         internal int read_buf(byte[] buf, int start, int size) | ||||||
|  |         { | ||||||
|  |             int len = AvailableBytesIn; | ||||||
|  |  | ||||||
|  |             if (len > size) | ||||||
|  |                 len = size; | ||||||
|  |             if (len == 0) | ||||||
|  |                 return 0; | ||||||
|  |  | ||||||
|  |             AvailableBytesIn -= len; | ||||||
|  |  | ||||||
|  |             if (dstate.WantRfc1950HeaderBytes) | ||||||
|  |             { | ||||||
|  |                 _Adler32 = Adler.Adler32(_Adler32, InputBuffer, NextIn, len); | ||||||
|  |             } | ||||||
|  |             Array.Copy(InputBuffer, NextIn, buf, start, len); | ||||||
|  |             NextIn += len; | ||||||
|  |             TotalBytesIn += len; | ||||||
|  |             return len; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										128
									
								
								src/ZlibAndroid/ZlibConstants.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/ZlibAndroid/ZlibConstants.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,128 @@ | |||||||
|  | // ZlibConstants.cs | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // Copyright (c) 2009 Dino Chiesa and Microsoft Corporation.   | ||||||
|  | // All rights reserved. | ||||||
|  | // | ||||||
|  | // This code module is part of DotNetZip, a zipfile class library. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This code is licensed under the Microsoft Public License.  | ||||||
|  | // See the file License.txt for the license details. | ||||||
|  | // More info on: http://dotnetzip.codeplex.com | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // last saved (in emacs):  | ||||||
|  | // Time-stamp: <2009-November-03 18:50:19> | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This module defines constants used by the zlib class library.  This | ||||||
|  | // code is derived from the jzlib implementation of zlib, but | ||||||
|  | // significantly modified.  In keeping with the license for jzlib, the | ||||||
|  | // copyright to that code is included here. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | //  | ||||||
|  | // Copyright (c) 2000,2001,2002,2003 ymnk, JCraft,Inc. All rights reserved. | ||||||
|  | //  | ||||||
|  | // Redistribution and use in source and binary forms, with or without | ||||||
|  | // modification, are permitted provided that the following conditions are met: | ||||||
|  | //  | ||||||
|  | // 1. Redistributions of source code must retain the above copyright notice, | ||||||
|  | // this list of conditions and the following disclaimer. | ||||||
|  | //  | ||||||
|  | // 2. Redistributions in binary form must reproduce the above copyright  | ||||||
|  | // notice, this list of conditions and the following disclaimer in  | ||||||
|  | // the documentation and/or other materials provided with the distribution. | ||||||
|  | //  | ||||||
|  | // 3. The names of the authors may not be used to endorse or promote products | ||||||
|  | // derived from this software without specific prior written permission. | ||||||
|  | //  | ||||||
|  | // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, | ||||||
|  | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | ||||||
|  | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT, | ||||||
|  | // INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, | ||||||
|  | // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||||||
|  | // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, | ||||||
|  | // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||||||
|  | // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||||||
|  | // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, | ||||||
|  | // EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||||||
|  | //  | ||||||
|  | // ----------------------------------------------------------------------- | ||||||
|  | // | ||||||
|  | // This program is based on zlib-1.1.3; credit to authors | ||||||
|  | // Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu) | ||||||
|  | // and contributors of zlib. | ||||||
|  | // | ||||||
|  | // ----------------------------------------------------------------------- | ||||||
|  |  | ||||||
|  |  | ||||||
|  | using System; | ||||||
|  |  | ||||||
|  | namespace Ionic.Zlib | ||||||
|  | { | ||||||
|  |     /// <summary> | ||||||
|  |     /// A bunch of constants used in the Zlib interface. | ||||||
|  |     /// </summary> | ||||||
|  |     public static class ZlibConstants | ||||||
|  |     { | ||||||
|  |         /// <summary> | ||||||
|  |         /// The maximum number of window bits for the Deflate algorithm. | ||||||
|  |         /// </summary> | ||||||
|  |         public const int WindowBitsMax = 15; // 32K LZ77 window | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The default number of window bits for the Deflate algorithm. | ||||||
|  |         /// </summary> | ||||||
|  |         public const int WindowBitsDefault = WindowBitsMax; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// indicates everything is A-OK | ||||||
|  |         /// </summary> | ||||||
|  |         public const int Z_OK = 0; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Indicates that the last operation reached the end of the stream. | ||||||
|  |         /// </summary> | ||||||
|  |         public const int Z_STREAM_END = 1; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The operation ended in need of a dictionary.  | ||||||
|  |         /// </summary> | ||||||
|  |         public const int Z_NEED_DICT = 2; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// There was an error with the stream - not enough data, not open and readable, etc. | ||||||
|  |         /// </summary> | ||||||
|  |         public const int Z_STREAM_ERROR = -2; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// There was an error with the data - not enough data, bad data, etc. | ||||||
|  |         /// </summary> | ||||||
|  |         public const int Z_DATA_ERROR = -3; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// There was an error with the working buffer. | ||||||
|  |         /// </summary> | ||||||
|  |         public const int Z_BUF_ERROR = -5; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// The size of the working buffer used in the ZlibCodec class. Defaults to 8192 bytes. | ||||||
|  |         /// </summary> | ||||||
|  | #if NETCF         | ||||||
|  |         public const int WorkingBufferSizeDefault = 8192; | ||||||
|  | #else | ||||||
|  |         public const int WorkingBufferSizeDefault = 16384;  | ||||||
|  | #endif | ||||||
|  |         /// <summary> | ||||||
|  |         /// The minimum size of the working buffer used in the ZlibCodec class.  Currently it is 128 bytes. | ||||||
|  |         /// </summary> | ||||||
|  |         public const int WorkingBufferSizeMin = 1024; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  | } | ||||||
|  |  | ||||||
							
								
								
									
										725
									
								
								src/ZlibAndroid/ZlibStream.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										725
									
								
								src/ZlibAndroid/ZlibStream.cs
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,725 @@ | |||||||
|  | // ZlibStream.cs | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // Copyright (c) 2009 Dino Chiesa and Microsoft Corporation. | ||||||
|  | // All rights reserved. | ||||||
|  | // | ||||||
|  | // This code module is part of DotNetZip, a zipfile class library. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This code is licensed under the Microsoft Public License. | ||||||
|  | // See the file License.txt for the license details. | ||||||
|  | // More info on: http://dotnetzip.codeplex.com | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // last saved (in emacs): | ||||||
|  | // Time-stamp: <2011-July-31 14:53:33> | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  | // | ||||||
|  | // This module defines the ZlibStream class, which is similar in idea to | ||||||
|  | // the System.IO.Compression.DeflateStream and | ||||||
|  | // System.IO.Compression.GZipStream classes in the .NET BCL. | ||||||
|  | // | ||||||
|  | // ------------------------------------------------------------------ | ||||||
|  |  | ||||||
|  | using System; | ||||||
|  | using System.IO; | ||||||
|  |  | ||||||
|  | namespace Ionic.Zlib | ||||||
|  | { | ||||||
|  |  | ||||||
|  |     /// <summary> | ||||||
|  |     /// Represents a Zlib stream for compression or decompression. | ||||||
|  |     /// </summary> | ||||||
|  |     /// <remarks> | ||||||
|  |     /// | ||||||
|  |     /// <para> | ||||||
|  |     /// The ZlibStream is a <see | ||||||
|  |     /// href="http://en.wikipedia.org/wiki/Decorator_pattern">Decorator</see> on a <see | ||||||
|  |     /// cref="System.IO.Stream"/>.  It adds ZLIB compression or decompression to any | ||||||
|  |     /// stream. | ||||||
|  |     /// </para> | ||||||
|  |     /// | ||||||
|  |     /// <para> Using this stream, applications can compress or decompress data via | ||||||
|  |     /// stream <c>Read()</c> and <c>Write()</c> operations.  Either compresssion or | ||||||
|  |     /// decompression can occur through either reading or writing. The compression | ||||||
|  |     /// format used is ZLIB, which is documented in <see | ||||||
|  |     /// href="http://www.ietf.org/rfc/rfc1950.txt">IETF RFC 1950</see>, "ZLIB Compressed | ||||||
|  |     /// Data Format Specification version 3.3". This implementation of ZLIB always uses | ||||||
|  |     /// DEFLATE as the compression method.  (see <see | ||||||
|  |     /// href="http://www.ietf.org/rfc/rfc1951.txt">IETF RFC 1951</see>, "DEFLATE | ||||||
|  |     /// Compressed Data Format Specification version 1.3.") </para> | ||||||
|  |     /// | ||||||
|  |     /// <para> | ||||||
|  |     /// The ZLIB format allows for varying compression methods, window sizes, and dictionaries. | ||||||
|  |     /// This implementation always uses the DEFLATE compression method, a preset dictionary, | ||||||
|  |     /// and 15 window bits by default. | ||||||
|  |     /// </para> | ||||||
|  |     /// | ||||||
|  |     /// <para> | ||||||
|  |     /// This class is similar to <see cref="DeflateStream"/>, except that it adds the | ||||||
|  |     /// RFC1950 header and trailer bytes to a compressed stream when compressing, or expects | ||||||
|  |     /// the RFC1950 header and trailer bytes when decompressing.  It is also similar to the | ||||||
|  |     /// <see cref="GZipStream"/>. | ||||||
|  |     /// </para> | ||||||
|  |     /// </remarks> | ||||||
|  |     /// <seealso cref="DeflateStream" /> | ||||||
|  |     /// <seealso cref="GZipStream" /> | ||||||
|  |     public class ZlibStream : System.IO.Stream | ||||||
|  |     { | ||||||
|  |         internal ZlibBaseStream _baseStream; | ||||||
|  |         bool _disposed; | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Create a <c>ZlibStream</c> using the specified <c>CompressionMode</c>. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   When mode is <c>CompressionMode.Compress</c>, the <c>ZlibStream</c> | ||||||
|  |         ///   will use the default compression level. The "captive" stream will be | ||||||
|  |         ///   closed when the <c>ZlibStream</c> is closed. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <example> | ||||||
|  |         /// This example uses a <c>ZlibStream</c> to compress a file, and writes the | ||||||
|  |         /// compressed data to another file. | ||||||
|  |         /// <code> | ||||||
|  |         /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) | ||||||
|  |         /// { | ||||||
|  |         ///     using (var raw = System.IO.File.Create(fileToCompress + ".zlib")) | ||||||
|  |         ///     { | ||||||
|  |         ///         using (Stream compressor = new ZlibStream(raw, CompressionMode.Compress)) | ||||||
|  |         ///         { | ||||||
|  |         ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE]; | ||||||
|  |         ///             int n; | ||||||
|  |         ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0) | ||||||
|  |         ///             { | ||||||
|  |         ///                 compressor.Write(buffer, 0, n); | ||||||
|  |         ///             } | ||||||
|  |         ///         } | ||||||
|  |         ///     } | ||||||
|  |         /// } | ||||||
|  |         /// </code> | ||||||
|  |         /// <code lang="VB"> | ||||||
|  |         /// Using input As Stream = File.OpenRead(fileToCompress) | ||||||
|  |         ///     Using raw As FileStream = File.Create(fileToCompress & ".zlib") | ||||||
|  |         ///     Using compressor As Stream = New ZlibStream(raw, CompressionMode.Compress) | ||||||
|  |         ///         Dim buffer As Byte() = New Byte(4096) {} | ||||||
|  |         ///         Dim n As Integer = -1 | ||||||
|  |         ///         Do While (n <> 0) | ||||||
|  |         ///             If (n > 0) Then | ||||||
|  |         ///                 compressor.Write(buffer, 0, n) | ||||||
|  |         ///             End If | ||||||
|  |         ///             n = input.Read(buffer, 0, buffer.Length) | ||||||
|  |         ///         Loop | ||||||
|  |         ///     End Using | ||||||
|  |         ///     End Using | ||||||
|  |         /// End Using | ||||||
|  |         /// </code> | ||||||
|  |         /// </example> | ||||||
|  |         /// | ||||||
|  |         /// <param name="stream">The stream which will be read or written.</param> | ||||||
|  |         /// <param name="mode">Indicates whether the ZlibStream will compress or decompress.</param> | ||||||
|  |         public ZlibStream(System.IO.Stream stream, CompressionMode mode) | ||||||
|  |             : this(stream, mode, CompressionLevel.Default, false) | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Create a <c>ZlibStream</c> using the specified <c>CompressionMode</c> and | ||||||
|  |         ///   the specified <c>CompressionLevel</c>. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   When mode is <c>CompressionMode.Decompress</c>, the level parameter is ignored. | ||||||
|  |         ///   The "captive" stream will be closed when the <c>ZlibStream</c> is closed. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <example> | ||||||
|  |         ///   This example uses a <c>ZlibStream</c> to compress data from a file, and writes the | ||||||
|  |         ///   compressed data to another file. | ||||||
|  |         /// | ||||||
|  |         /// <code> | ||||||
|  |         /// using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) | ||||||
|  |         /// { | ||||||
|  |         ///     using (var raw = System.IO.File.Create(fileToCompress + ".zlib")) | ||||||
|  |         ///     { | ||||||
|  |         ///         using (Stream compressor = new ZlibStream(raw, | ||||||
|  |         ///                                                   CompressionMode.Compress, | ||||||
|  |         ///                                                   CompressionLevel.BestCompression)) | ||||||
|  |         ///         { | ||||||
|  |         ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE]; | ||||||
|  |         ///             int n; | ||||||
|  |         ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0) | ||||||
|  |         ///             { | ||||||
|  |         ///                 compressor.Write(buffer, 0, n); | ||||||
|  |         ///             } | ||||||
|  |         ///         } | ||||||
|  |         ///     } | ||||||
|  |         /// } | ||||||
|  |         /// </code> | ||||||
|  |         /// | ||||||
|  |         /// <code lang="VB"> | ||||||
|  |         /// Using input As Stream = File.OpenRead(fileToCompress) | ||||||
|  |         ///     Using raw As FileStream = File.Create(fileToCompress & ".zlib") | ||||||
|  |         ///         Using compressor As Stream = New ZlibStream(raw, CompressionMode.Compress, CompressionLevel.BestCompression) | ||||||
|  |         ///             Dim buffer As Byte() = New Byte(4096) {} | ||||||
|  |         ///             Dim n As Integer = -1 | ||||||
|  |         ///             Do While (n <> 0) | ||||||
|  |         ///                 If (n > 0) Then | ||||||
|  |         ///                     compressor.Write(buffer, 0, n) | ||||||
|  |         ///                 End If | ||||||
|  |         ///                 n = input.Read(buffer, 0, buffer.Length) | ||||||
|  |         ///             Loop | ||||||
|  |         ///         End Using | ||||||
|  |         ///     End Using | ||||||
|  |         /// End Using | ||||||
|  |         /// </code> | ||||||
|  |         /// </example> | ||||||
|  |         /// | ||||||
|  |         /// <param name="stream">The stream to be read or written while deflating or inflating.</param> | ||||||
|  |         /// <param name="mode">Indicates whether the ZlibStream will compress or decompress.</param> | ||||||
|  |         /// <param name="level">A tuning knob to trade speed for effectiveness.</param> | ||||||
|  |         public ZlibStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level) | ||||||
|  |             : this(stream, mode, level, false) | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Create a <c>ZlibStream</c> using the specified <c>CompressionMode</c>, and | ||||||
|  |         ///   explicitly specify whether the captive stream should be left open after | ||||||
|  |         ///   Deflation or Inflation. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   When mode is <c>CompressionMode.Compress</c>, the <c>ZlibStream</c> will use | ||||||
|  |         ///   the default compression level. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   This constructor allows the application to request that the captive stream | ||||||
|  |         ///   remain open after the deflation or inflation occurs.  By default, after | ||||||
|  |         ///   <c>Close()</c> is called on the stream, the captive stream is also | ||||||
|  |         ///   closed. In some cases this is not desired, for example if the stream is a | ||||||
|  |         ///   <see cref="System.IO.MemoryStream"/> that will be re-read after | ||||||
|  |         ///   compression.  Specify true for the <paramref name="leaveOpen"/> parameter to leave the stream | ||||||
|  |         ///   open. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         /// See the other overloads of this constructor for example code. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <param name="stream">The stream which will be read or written. This is called the | ||||||
|  |         /// "captive" stream in other places in this documentation.</param> | ||||||
|  |         /// <param name="mode">Indicates whether the ZlibStream will compress or decompress.</param> | ||||||
|  |         /// <param name="leaveOpen">true if the application would like the stream to remain | ||||||
|  |         /// open after inflation/deflation.</param> | ||||||
|  |         public ZlibStream(System.IO.Stream stream, CompressionMode mode, bool leaveOpen) | ||||||
|  |             : this(stream, mode, CompressionLevel.Default, leaveOpen) | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Create a <c>ZlibStream</c> using the specified <c>CompressionMode</c> | ||||||
|  |         ///   and the specified <c>CompressionLevel</c>, and explicitly specify | ||||||
|  |         ///   whether the stream should be left open after Deflation or Inflation. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   This constructor allows the application to request that the captive | ||||||
|  |         ///   stream remain open after the deflation or inflation occurs.  By | ||||||
|  |         ///   default, after <c>Close()</c> is called on the stream, the captive | ||||||
|  |         ///   stream is also closed. In some cases this is not desired, for example | ||||||
|  |         ///   if the stream is a <see cref="System.IO.MemoryStream"/> that will be | ||||||
|  |         ///   re-read after compression.  Specify true for the <paramref | ||||||
|  |         ///   name="leaveOpen"/> parameter to leave the stream open. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   When mode is <c>CompressionMode.Decompress</c>, the level parameter is | ||||||
|  |         ///   ignored. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <example> | ||||||
|  |         /// | ||||||
|  |         /// This example shows how to use a ZlibStream to compress the data from a file, | ||||||
|  |         /// and store the result into another file. The filestream remains open to allow | ||||||
|  |         /// additional data to be written to it. | ||||||
|  |         /// | ||||||
|  |         /// <code> | ||||||
|  |         /// using (var output = System.IO.File.Create(fileToCompress + ".zlib")) | ||||||
|  |         /// { | ||||||
|  |         ///     using (System.IO.Stream input = System.IO.File.OpenRead(fileToCompress)) | ||||||
|  |         ///     { | ||||||
|  |         ///         using (Stream compressor = new ZlibStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, true)) | ||||||
|  |         ///         { | ||||||
|  |         ///             byte[] buffer = new byte[WORKING_BUFFER_SIZE]; | ||||||
|  |         ///             int n; | ||||||
|  |         ///             while ((n= input.Read(buffer, 0, buffer.Length)) != 0) | ||||||
|  |         ///             { | ||||||
|  |         ///                 compressor.Write(buffer, 0, n); | ||||||
|  |         ///             } | ||||||
|  |         ///         } | ||||||
|  |         ///     } | ||||||
|  |         ///     // can write additional data to the output stream here | ||||||
|  |         /// } | ||||||
|  |         /// </code> | ||||||
|  |         /// <code lang="VB"> | ||||||
|  |         /// Using output As FileStream = File.Create(fileToCompress & ".zlib") | ||||||
|  |         ///     Using input As Stream = File.OpenRead(fileToCompress) | ||||||
|  |         ///         Using compressor As Stream = New ZlibStream(output, CompressionMode.Compress, CompressionLevel.BestCompression, True) | ||||||
|  |         ///             Dim buffer As Byte() = New Byte(4096) {} | ||||||
|  |         ///             Dim n As Integer = -1 | ||||||
|  |         ///             Do While (n <> 0) | ||||||
|  |         ///                 If (n > 0) Then | ||||||
|  |         ///                     compressor.Write(buffer, 0, n) | ||||||
|  |         ///                 End If | ||||||
|  |         ///                 n = input.Read(buffer, 0, buffer.Length) | ||||||
|  |         ///             Loop | ||||||
|  |         ///         End Using | ||||||
|  |         ///     End Using | ||||||
|  |         ///     ' can write additional data to the output stream here. | ||||||
|  |         /// End Using | ||||||
|  |         /// </code> | ||||||
|  |         /// </example> | ||||||
|  |         /// | ||||||
|  |         /// <param name="stream">The stream which will be read or written.</param> | ||||||
|  |         /// | ||||||
|  |         /// <param name="mode">Indicates whether the ZlibStream will compress or decompress.</param> | ||||||
|  |         /// | ||||||
|  |         /// <param name="leaveOpen"> | ||||||
|  |         /// true if the application would like the stream to remain open after | ||||||
|  |         /// inflation/deflation. | ||||||
|  |         /// </param> | ||||||
|  |         /// | ||||||
|  |         /// <param name="level"> | ||||||
|  |         /// A tuning knob to trade speed for effectiveness. This parameter is | ||||||
|  |         /// effective only when mode is <c>CompressionMode.Compress</c>. | ||||||
|  |         /// </param> | ||||||
|  |         public ZlibStream(System.IO.Stream stream, CompressionMode mode, CompressionLevel level, bool leaveOpen) | ||||||
|  |         { | ||||||
|  |             _baseStream = new ZlibBaseStream(stream, mode, level, ZlibStreamFlavor.ZLIB, leaveOpen); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         #region Zlib properties | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// This property sets the flush behavior on the stream. | ||||||
|  |         /// Sorry, though, not sure exactly how to describe all the various settings. | ||||||
|  |         /// </summary> | ||||||
|  |         virtual public FlushType FlushMode | ||||||
|  |         { | ||||||
|  |             get { return (this._baseStream._flushMode); } | ||||||
|  |             set | ||||||
|  |             { | ||||||
|  |                 if (_disposed) throw new ObjectDisposedException("ZlibStream"); | ||||||
|  |                 this._baseStream._flushMode = value; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   The size of the working buffer for the compression codec. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         /// <para> | ||||||
|  |         ///   The working buffer is used for all stream operations.  The default size is | ||||||
|  |         ///   1024 bytes. The minimum size is 128 bytes. You may get better performance | ||||||
|  |         ///   with a larger buffer.  Then again, you might not.  You would have to test | ||||||
|  |         ///   it. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   Set this before the first call to <c>Read()</c> or <c>Write()</c> on the | ||||||
|  |         ///   stream. If you try to set it afterwards, it will throw. | ||||||
|  |         /// </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         public int BufferSize | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 return this._baseStream._bufferSize; | ||||||
|  |             } | ||||||
|  |             set | ||||||
|  |             { | ||||||
|  |                 if (_disposed) throw new ObjectDisposedException("ZlibStream"); | ||||||
|  |                 if (this._baseStream._workingBuffer != null) | ||||||
|  |                     throw new ZlibException("The working buffer is already set."); | ||||||
|  |                 if (value < ZlibConstants.WorkingBufferSizeMin) | ||||||
|  |                     throw new ZlibException(String.Format("Don't be silly. {0} bytes?? Use a bigger buffer, at least {1}.", value, ZlibConstants.WorkingBufferSizeMin)); | ||||||
|  |                 this._baseStream._bufferSize = value; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> Returns the total number of bytes input so far.</summary> | ||||||
|  |         virtual public long TotalIn | ||||||
|  |         { | ||||||
|  |             get { return this._baseStream._z.TotalBytesIn; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> Returns the total number of bytes output so far.</summary> | ||||||
|  |         virtual public long TotalOut | ||||||
|  |         { | ||||||
|  |             get { return this._baseStream._z.TotalBytesOut; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         #endregion | ||||||
|  |  | ||||||
|  |         #region System.IO.Stream methods | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Dispose the stream. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     This may or may not result in a <c>Close()</c> call on the captive | ||||||
|  |         ///     stream.  See the constructors that have a <c>leaveOpen</c> parameter | ||||||
|  |         ///     for more information. | ||||||
|  |         ///   </para> | ||||||
|  |         ///   <para> | ||||||
|  |         ///     This method may be invoked in two distinct scenarios.  If disposing | ||||||
|  |         ///     == true, the method has been called directly or indirectly by a | ||||||
|  |         ///     user's code, for example via the public Dispose() method. In this | ||||||
|  |         ///     case, both managed and unmanaged resources can be referenced and | ||||||
|  |         ///     disposed.  If disposing == false, the method has been called by the | ||||||
|  |         ///     runtime from inside the object finalizer and this method should not | ||||||
|  |         ///     reference other objects; in that case only unmanaged resources must | ||||||
|  |         ///     be referenced or disposed. | ||||||
|  |         ///   </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <param name="disposing"> | ||||||
|  |         ///   indicates whether the Dispose method was invoked by user code. | ||||||
|  |         /// </param> | ||||||
|  |         protected override void Dispose(bool disposing) | ||||||
|  |         { | ||||||
|  |             try | ||||||
|  |             { | ||||||
|  |                 if (!_disposed) | ||||||
|  |                 { | ||||||
|  |                     if (disposing && (this._baseStream != null)) | ||||||
|  |                         this._baseStream.Close(); | ||||||
|  |                     _disposed = true; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |             finally | ||||||
|  |             { | ||||||
|  |                 base.Dispose(disposing); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Indicates whether the stream can be read. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// The return value depends on whether the captive stream supports reading. | ||||||
|  |         /// </remarks> | ||||||
|  |         public override bool CanRead | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 if (_disposed) throw new ObjectDisposedException("ZlibStream"); | ||||||
|  |                 return _baseStream._stream.CanRead; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Indicates whether the stream supports Seek operations. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// Always returns false. | ||||||
|  |         /// </remarks> | ||||||
|  |         public override bool CanSeek | ||||||
|  |         { | ||||||
|  |             get { return false; } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Indicates whether the stream can be written. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <remarks> | ||||||
|  |         /// The return value depends on whether the captive stream supports writing. | ||||||
|  |         /// </remarks> | ||||||
|  |         public override bool CanWrite | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 if (_disposed) throw new ObjectDisposedException("ZlibStream"); | ||||||
|  |                 return _baseStream._stream.CanWrite; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Flush the stream. | ||||||
|  |         /// </summary> | ||||||
|  |         public override void Flush() | ||||||
|  |         { | ||||||
|  |             if (_disposed) throw new ObjectDisposedException("ZlibStream"); | ||||||
|  |             _baseStream.Flush(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Reading this property always throws a <see cref="NotSupportedException"/>. | ||||||
|  |         /// </summary> | ||||||
|  |         public override long Length | ||||||
|  |         { | ||||||
|  |             get { throw new NotSupportedException(); } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   The position of the stream pointer. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   Setting this property always throws a <see | ||||||
|  |         ///   cref="NotSupportedException"/>. Reading will return the total bytes | ||||||
|  |         ///   written out, if used in writing, or the total bytes read in, if used in | ||||||
|  |         ///   reading.  The count may refer to compressed bytes or uncompressed bytes, | ||||||
|  |         ///   depending on how you've used the stream. | ||||||
|  |         /// </remarks> | ||||||
|  |         public override long Position | ||||||
|  |         { | ||||||
|  |             get | ||||||
|  |             { | ||||||
|  |                 if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Writer) | ||||||
|  |                     return this._baseStream._z.TotalBytesOut; | ||||||
|  |                 if (this._baseStream._streamMode == Ionic.Zlib.ZlibBaseStream.StreamMode.Reader) | ||||||
|  |                     return this._baseStream._z.TotalBytesIn; | ||||||
|  |                 return 0; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             set { throw new NotSupportedException(); } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Read data from the stream. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   If you wish to use the <c>ZlibStream</c> to compress data while reading, | ||||||
|  |         ///   you can create a <c>ZlibStream</c> with <c>CompressionMode.Compress</c>, | ||||||
|  |         ///   providing an uncompressed data stream.  Then call <c>Read()</c> on that | ||||||
|  |         ///   <c>ZlibStream</c>, and the data read will be compressed.  If you wish to | ||||||
|  |         ///   use the <c>ZlibStream</c> to decompress data while reading, you can create | ||||||
|  |         ///   a <c>ZlibStream</c> with <c>CompressionMode.Decompress</c>, providing a | ||||||
|  |         ///   readable compressed data stream.  Then call <c>Read()</c> on that | ||||||
|  |         ///   <c>ZlibStream</c>, and the data will be decompressed as it is read. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   A <c>ZlibStream</c> can be used for <c>Read()</c> or <c>Write()</c>, but | ||||||
|  |         ///   not both. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <param name="buffer"> | ||||||
|  |         /// The buffer into which the read data should be placed.</param> | ||||||
|  |         /// | ||||||
|  |         /// <param name="offset"> | ||||||
|  |         /// the offset within that data array to put the first byte read.</param> | ||||||
|  |         /// | ||||||
|  |         /// <param name="count">the number of bytes to read.</param> | ||||||
|  |         /// | ||||||
|  |         /// <returns>the number of bytes read</returns> | ||||||
|  |         public override int Read(byte[] buffer, int offset, int count) | ||||||
|  |         { | ||||||
|  |                 if (_disposed) throw new ObjectDisposedException("ZlibStream"); | ||||||
|  |             return _baseStream.Read(buffer, offset, count); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Calling this method always throws a <see cref="NotSupportedException"/>. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="offset"> | ||||||
|  |         ///   The offset to seek to.... | ||||||
|  |         ///   IF THIS METHOD ACTUALLY DID ANYTHING. | ||||||
|  |         /// </param> | ||||||
|  |         /// <param name="origin"> | ||||||
|  |         ///   The reference specifying how to apply the offset....  IF | ||||||
|  |         ///   THIS METHOD ACTUALLY DID ANYTHING. | ||||||
|  |         /// </param> | ||||||
|  |         /// | ||||||
|  |         /// <returns>nothing. This method always throws.</returns> | ||||||
|  |         public override long Seek(long offset, System.IO.SeekOrigin origin) | ||||||
|  |         { | ||||||
|  |             throw new NotSupportedException(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Calling this method always throws a <see cref="NotSupportedException"/>. | ||||||
|  |         /// </summary> | ||||||
|  |         /// <param name="value"> | ||||||
|  |         ///   The new value for the stream length....  IF | ||||||
|  |         ///   THIS METHOD ACTUALLY DID ANYTHING. | ||||||
|  |         /// </param> | ||||||
|  |         public override void SetLength(long value) | ||||||
|  |         { | ||||||
|  |             throw new NotSupportedException(); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         /// Write data to the stream. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   If you wish to use the <c>ZlibStream</c> to compress data while writing, | ||||||
|  |         ///   you can create a <c>ZlibStream</c> with <c>CompressionMode.Compress</c>, | ||||||
|  |         ///   and a writable output stream.  Then call <c>Write()</c> on that | ||||||
|  |         ///   <c>ZlibStream</c>, providing uncompressed data as input.  The data sent to | ||||||
|  |         ///   the output stream will be the compressed form of the data written.  If you | ||||||
|  |         ///   wish to use the <c>ZlibStream</c> to decompress data while writing, you | ||||||
|  |         ///   can create a <c>ZlibStream</c> with <c>CompressionMode.Decompress</c>, and a | ||||||
|  |         ///   writable output stream.  Then call <c>Write()</c> on that stream, | ||||||
|  |         ///   providing previously compressed data. The data sent to the output stream | ||||||
|  |         ///   will be the decompressed form of the data written. | ||||||
|  |         /// </para> | ||||||
|  |         /// | ||||||
|  |         /// <para> | ||||||
|  |         ///   A <c>ZlibStream</c> can be used for <c>Read()</c> or <c>Write()</c>, but not both. | ||||||
|  |         /// </para> | ||||||
|  |         /// </remarks> | ||||||
|  |         /// <param name="buffer">The buffer holding data to write to the stream.</param> | ||||||
|  |         /// <param name="offset">the offset within that data array to find the first byte to write.</param> | ||||||
|  |         /// <param name="count">the number of bytes to write.</param> | ||||||
|  |         public override void Write(byte[] buffer, int offset, int count) | ||||||
|  |         { | ||||||
|  |                 if (_disposed) throw new ObjectDisposedException("ZlibStream"); | ||||||
|  |             _baseStream.Write(buffer, offset, count); | ||||||
|  |         } | ||||||
|  |         #endregion | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Compress a string into a byte array using ZLIB. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   Uncompress it with <see cref="ZlibStream.UncompressString(byte[])"/>. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <seealso cref="ZlibStream.UncompressString(byte[])"/> | ||||||
|  |         /// <seealso cref="ZlibStream.CompressBuffer(byte[])"/> | ||||||
|  |         /// <seealso cref="GZipStream.CompressString(string)"/> | ||||||
|  |         /// | ||||||
|  |         /// <param name="s"> | ||||||
|  |         ///   A string to compress.  The string will first be encoded | ||||||
|  |         ///   using UTF8, then compressed. | ||||||
|  |         /// </param> | ||||||
|  |         /// | ||||||
|  |         /// <returns>The string in compressed form</returns> | ||||||
|  |         public static byte[] CompressString(String s) | ||||||
|  |         { | ||||||
|  |             using (var ms = new MemoryStream()) | ||||||
|  |             { | ||||||
|  |                 Stream compressor = | ||||||
|  |                     new ZlibStream(ms, CompressionMode.Compress, CompressionLevel.BestCompression); | ||||||
|  |                 ZlibBaseStream.CompressString(s, compressor); | ||||||
|  |                 return ms.ToArray(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Compress a byte array into a new byte array using ZLIB. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <remarks> | ||||||
|  |         ///   Uncompress it with <see cref="ZlibStream.UncompressBuffer(byte[])"/>. | ||||||
|  |         /// </remarks> | ||||||
|  |         /// | ||||||
|  |         /// <seealso cref="ZlibStream.CompressString(string)"/> | ||||||
|  |         /// <seealso cref="ZlibStream.UncompressBuffer(byte[])"/> | ||||||
|  |         /// | ||||||
|  |         /// <param name="b"> | ||||||
|  |         /// A buffer to compress. | ||||||
|  |         /// </param> | ||||||
|  |         /// | ||||||
|  |         /// <returns>The data in compressed form</returns> | ||||||
|  |         public static byte[] CompressBuffer(byte[] b) | ||||||
|  |         { | ||||||
|  |             using (var ms = new MemoryStream()) | ||||||
|  |             { | ||||||
|  |                 Stream compressor = | ||||||
|  |                     new ZlibStream( ms, CompressionMode.Compress, CompressionLevel.BestCompression ); | ||||||
|  |  | ||||||
|  |                 ZlibBaseStream.CompressBuffer(b, compressor); | ||||||
|  |                 return ms.ToArray(); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Uncompress a ZLIB-compressed byte array into a single string. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <seealso cref="ZlibStream.CompressString(String)"/> | ||||||
|  |         /// <seealso cref="ZlibStream.UncompressBuffer(byte[])"/> | ||||||
|  |         /// | ||||||
|  |         /// <param name="compressed"> | ||||||
|  |         ///   A buffer containing ZLIB-compressed data. | ||||||
|  |         /// </param> | ||||||
|  |         /// | ||||||
|  |         /// <returns>The uncompressed string</returns> | ||||||
|  |         public static String UncompressString(byte[] compressed) | ||||||
|  |         { | ||||||
|  |             using (var input = new MemoryStream(compressed)) | ||||||
|  |             { | ||||||
|  |                 Stream decompressor = | ||||||
|  |                     new ZlibStream(input, CompressionMode.Decompress); | ||||||
|  |  | ||||||
|  |                 return ZlibBaseStream.UncompressString(compressed, decompressor); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |         /// <summary> | ||||||
|  |         ///   Uncompress a ZLIB-compressed byte array into a byte array. | ||||||
|  |         /// </summary> | ||||||
|  |         /// | ||||||
|  |         /// <seealso cref="ZlibStream.CompressBuffer(byte[])"/> | ||||||
|  |         /// <seealso cref="ZlibStream.UncompressString(byte[])"/> | ||||||
|  |         /// | ||||||
|  |         /// <param name="compressed"> | ||||||
|  |         ///   A buffer containing ZLIB-compressed data. | ||||||
|  |         /// </param> | ||||||
|  |         /// | ||||||
|  |         /// <returns>The data in uncompressed form</returns> | ||||||
|  |         public static byte[] UncompressBuffer(byte[] compressed) | ||||||
|  |         { | ||||||
|  |             using (var input = new MemoryStream(compressed)) | ||||||
|  |             { | ||||||
|  |                 Stream decompressor = | ||||||
|  |                     new ZlibStream( input, CompressionMode.Decompress ); | ||||||
|  |  | ||||||
|  |                 return ZlibBaseStream.UncompressBuffer(compressed, decompressor); | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } | ||||||
| @@ -10,8 +10,8 @@ namespace keepass2android | |||||||
| { | { | ||||||
| 	[Activity(Label = "@string/app_name", | 	[Activity(Label = "@string/app_name", | ||||||
| 		ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden, | 		ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden, | ||||||
| 		Theme = "@style/Base")] | 		Theme = "@style/NoTitleBar")] | ||||||
| 	[IntentFilter(new[] { "keepass2android.AboutActivity" }, Categories = new[] { Intent.CategoryDefault })] | 	[IntentFilter(new[] { "kp2a.action.AboutActivity" }, Categories = new[] { Intent.CategoryDefault })] | ||||||
| 	public class AboutActivity: Activity, IDialogInterfaceOnDismissListener | 	public class AboutActivity: Activity, IDialogInterfaceOnDismissListener | ||||||
| 	{ | 	{ | ||||||
| 		private AboutDialog _dialog; | 		private AboutDialog _dialog; | ||||||
|   | |||||||
| @@ -26,6 +26,7 @@ namespace keepass2android | |||||||
| 			AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(ctx, Android.Resource.Style.ThemeHoloLightDialog)); | 			AlertDialog.Builder builder = new AlertDialog.Builder(new ContextThemeWrapper(ctx, Android.Resource.Style.ThemeHoloLightDialog)); | ||||||
| 			builder.SetTitle(ctx.GetString(Resource.String.ChangeLog_title)); | 			builder.SetTitle(ctx.GetString(Resource.String.ChangeLog_title)); | ||||||
| 			List<string> changeLog = new List<string>{ | 			List<string> changeLog = new List<string>{ | ||||||
|  | 					ctx.GetString(Resource.String.ChangeLog_0_9_8b),				 | ||||||
| 					ctx.GetString(Resource.String.ChangeLog_0_9_8), | 					ctx.GetString(Resource.String.ChangeLog_0_9_8), | ||||||
| #if !NoNet | #if !NoNet | ||||||
| 					//0.9.7b fixes were already included in 0.9.7 offline | 					//0.9.7b fixes were already included in 0.9.7 offline | ||||||
|   | |||||||
| @@ -357,6 +357,7 @@ namespace keepass2android | |||||||
| 				} | 				} | ||||||
| 				if (requestCode == RequestCodeDbFilename) | 				if (requestCode == RequestCodeDbFilename) | ||||||
| 				{ | 				{ | ||||||
|  | 					 | ||||||
| 					if (data.Data.Scheme == "content") | 					if (data.Data.Scheme == "content") | ||||||
| 					{ | 					{ | ||||||
| 						if ((int)Build.VERSION.SdkInt >= 19) | 						if ((int)Build.VERSION.SdkInt >= 19) | ||||||
|   | |||||||
| @@ -17,7 +17,7 @@ namespace keepass2android | |||||||
| 	[Activity(Label = "@string/app_name", | 	[Activity(Label = "@string/app_name", | ||||||
| 		ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden, | 		ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden, | ||||||
| 		Theme = "@style/Base")] | 		Theme = "@style/Base")] | ||||||
| 	[IntentFilter(new[] {"keepass2android.ExportDatabaseActivity"}, Categories = new[] {Intent.CategoryDefault})] | 	[IntentFilter(new[] {"kp2a.action.ExportDatabaseActivity"}, Categories = new[] {Intent.CategoryDefault})] | ||||||
| 	public class ExportDatabaseActivity : LockCloseActivity | 	public class ExportDatabaseActivity : LockCloseActivity | ||||||
| 	{ | 	{ | ||||||
| 		FileFormatProvider[] _ffp = new FileFormatProvider[] | 		FileFormatProvider[] _ffp = new FileFormatProvider[] | ||||||
| @@ -56,6 +56,12 @@ namespace keepass2android | |||||||
| 			if (resultCode == KeePass.ExitFileStorageSelectionOk) | 			if (resultCode == KeePass.ExitFileStorageSelectionOk) | ||||||
| 			{ | 			{ | ||||||
| 				string protocolId = data.GetStringExtra("protocolId"); | 				string protocolId = data.GetStringExtra("protocolId"); | ||||||
|  | 				if (protocolId == "content") | ||||||
|  | 				{ | ||||||
|  | 					Util.ShowBrowseDialog(this, RequestCodeDbFilename, true, true); | ||||||
|  | 				} | ||||||
|  | 				else | ||||||
|  | 				{ | ||||||
| 					App.Kp2a.GetFileStorage(protocolId).StartSelectFile(new FileStorageSetupInitiatorActivity(this, | 					App.Kp2a.GetFileStorage(protocolId).StartSelectFile(new FileStorageSetupInitiatorActivity(this, | ||||||
| 						OnActivityResult, | 						OnActivityResult, | ||||||
| 						defaultPath => | 						defaultPath => | ||||||
| @@ -67,6 +73,7 @@ namespace keepass2android | |||||||
| 												Intents.RequestCodeFileBrowseForOpen); | 												Intents.RequestCodeFileBrowseForOpen); | ||||||
| 						} | 						} | ||||||
| 						), true, RequestCodeDbFilename, protocolId); | 						), true, RequestCodeDbFilename, protocolId); | ||||||
|  | 				} | ||||||
| 				return; | 				return; | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
| @@ -74,7 +81,32 @@ namespace keepass2android | |||||||
| 			{ | 			{ | ||||||
| 				if (requestCode == RequestCodeDbFilename) | 				if (requestCode == RequestCodeDbFilename) | ||||||
| 				{ | 				{ | ||||||
|  |  | ||||||
|  | 					if (data.Data.Scheme == "content") | ||||||
|  | 					{ | ||||||
|  | 						if ((int)Android.OS.Build.VERSION.SdkInt >= 19) | ||||||
|  | 						{ | ||||||
|  | 							//try to take persistable permissions | ||||||
|  | 							try | ||||||
|  | 							{ | ||||||
|  | 								Kp2aLog.Log("TakePersistableUriPermission"); | ||||||
|  | 								var takeFlags = data.Flags | ||||||
|  | 									& (ActivityFlags.GrantReadUriPermission | ||||||
|  | 										| ActivityFlags.GrantWriteUriPermission); | ||||||
|  | 								this.ContentResolver.TakePersistableUriPermission(data.Data, takeFlags); | ||||||
|  | 							} | ||||||
|  | 							catch (Exception e) | ||||||
|  | 							{ | ||||||
|  | 								Kp2aLog.Log(e.ToString()); | ||||||
|  | 							} | ||||||
|  |  | ||||||
|  | 						} | ||||||
|  | 					} | ||||||
|  |  | ||||||
|  |  | ||||||
| 					string filename = Util.IntentToFilename(data, this); | 					string filename = Util.IntentToFilename(data, this); | ||||||
|  | 					if (filename == null) | ||||||
|  | 						filename = data.DataString; | ||||||
| 					 | 					 | ||||||
| 					bool fileExists = data.GetBooleanExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.result_file_exists", true); | 					bool fileExists = data.GetBooleanExtra("group.pals.android.lib.ui.filechooser.FileChooserActivity.result_file_exists", true); | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| <?xml version="1.0" encoding="utf-8"?> | <?xml version="1.0" encoding="utf-8"?> | ||||||
| <manifest xmlns:android="http://schemas.android.com/apk/res/android"  | <manifest xmlns:android="http://schemas.android.com/apk/res/android"  | ||||||
| 			android:versionCode="58"  | 			android:versionCode="59"  | ||||||
| 			android:versionName="0.9.8"  | 			android:versionName="0.9.8b"  | ||||||
| 			package="keepass2android.keepass2android"  | 			package="keepass2android.keepass2android"  | ||||||
| 			android:installLocation="auto"> | 			android:installLocation="auto"> | ||||||
| 	<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" /> | 	<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21" /> | ||||||
|   | |||||||
| @@ -461,6 +461,11 @@ Der Android Robot wird genutzt und wurde modifiziert basierend auf Arbeiten, die | |||||||
|   <string name="PreviewWarning">Bitte beachten! Dies ist eine Vorab-Version, die einige Fehler enthalten könnte! Wenn du *irgendetwas* unerwartetes feststellen solltest, lass es mich bitte wissen (auf Codeplex oder per E-Mail).</string> |   <string name="PreviewWarning">Bitte beachten! Dies ist eine Vorab-Version, die einige Fehler enthalten könnte! Wenn du *irgendetwas* unerwartetes feststellen solltest, lass es mich bitte wissen (auf Codeplex oder per E-Mail).</string> | ||||||
|   <string name="Continue">Fortfahren</string> |   <string name="Continue">Fortfahren</string> | ||||||
|   <string name="NoFilenameWarning">Der eingegebene Pfad scheint kein gültiger Dateiname zu sein. Bist du sicher, dass es sich um eine gültige Datei handelt?</string> |   <string name="NoFilenameWarning">Der eingegebene Pfad scheint kein gültiger Dateiname zu sein. Bist du sicher, dass es sich um eine gültige Datei handelt?</string> | ||||||
|  |   	<string name="NoFilenameWarning">The URI you have entered does not look like a filename. Are you sure this is a valid file?</string> | ||||||
|  | 		<string name="ChangeLog_0_9_8b"> | ||||||
|  | 		Version 0.9.8b\n | ||||||
|  | 		* Bugs behoben: Speichern schlug bei manchen Datenbanken fehl, Exportieren mit lokalem Ziel funktionierte nicht, manche Einstellungsoptionen führten zum Absturz\n | ||||||
|  | 	</string> | ||||||
| 	<string name="ChangeLog_0_9_8">		Version 0.9.8\n | 	<string name="ChangeLog_0_9_8">		Version 0.9.8\n | ||||||
| 		* Unterstützung für das Storage Access Framework (ermöglicht Schreiben auf SD-Karte und auf Google Drive mit KP2A Offline)\n | 		* Unterstützung für das Storage Access Framework (ermöglicht Schreiben auf SD-Karte und auf Google Drive mit KP2A Offline)\n | ||||||
| 		* Fehlerhafte Benutzereingaben bei WebDAV-URLs werden wenn möglich erkannt (Verzeichnis statt Datei)\n | 		* Fehlerhafte Benutzereingaben bei WebDAV-URLs werden wenn möglich erkannt (Verzeichnis statt Datei)\n | ||||||
|   | |||||||
| @@ -532,6 +532,10 @@ | |||||||
| 	 | 	 | ||||||
| 	<string name="Continue">Continue</string> | 	<string name="Continue">Continue</string> | ||||||
| 	<string name="NoFilenameWarning">The URI you have entered does not look like a filename. Are you sure this is a valid file?</string> | 	<string name="NoFilenameWarning">The URI you have entered does not look like a filename. Are you sure this is a valid file?</string> | ||||||
|  | 		<string name="ChangeLog_0_9_8b"> | ||||||
|  | 		Version 0.9.8b\n | ||||||
|  | 		* Bug fixes (Saving failed for some databases, exporting to local device not working, selecting some preference options crashed the app)\n | ||||||
|  | 	</string> | ||||||
|  |  | ||||||
| 	<string name="ChangeLog_0_9_8"> | 	<string name="ChangeLog_0_9_8"> | ||||||
| 		Version 0.9.8\n | 		Version 0.9.8\n | ||||||
|   | |||||||
| @@ -52,7 +52,7 @@ | |||||||
| 	  android:key="export_prefs" | 	  android:key="export_prefs" | ||||||
| 	  android:title="@string/export_prefs" | 	  android:title="@string/export_prefs" | ||||||
| 	  > | 	  > | ||||||
| 			<intent android:action="keepass2android.ExportDatabaseActivity"/> | 			<intent android:action="kp2a.action.ExportDatabaseActivity"/> | ||||||
| 		</PreferenceScreen> | 		</PreferenceScreen> | ||||||
|  |  | ||||||
| 		<Preference | 		<Preference | ||||||
| @@ -416,14 +416,14 @@ | |||||||
| 	</PreferenceScreen> | 	</PreferenceScreen> | ||||||
|  |  | ||||||
| 	<PreferenceScreen android:key="plugin_key" android:title="@string/plugins"> | 	<PreferenceScreen android:key="plugin_key" android:title="@string/plugins"> | ||||||
| 		<intent android:action="keepass2android.PluginListActivity"/> | 		<intent android:action="kp2a.action.PluginListActivity"/> | ||||||
| 	</PreferenceScreen> | 	</PreferenceScreen> | ||||||
|  |  | ||||||
| 	<PreferenceScreen | 	<PreferenceScreen | ||||||
| 			  android:key="@string/about_prefs_key" | 			  android:key="@string/about_prefs_key" | ||||||
| 			  android:title="@string/menu_about" | 			  android:title="@string/menu_about" | ||||||
| 			  > | 			  > | ||||||
| 		<intent android:action="keepass2android.AboutActivity"/> | 		<intent android:action="kp2a.action.AboutActivity"/> | ||||||
| 	</PreferenceScreen> | 	</PreferenceScreen> | ||||||
| 	 | 	 | ||||||
|  |  | ||||||
|   | |||||||
| @@ -10,7 +10,7 @@ using Keepass2android.Pluginsdk; | |||||||
| namespace keepass2android | namespace keepass2android | ||||||
| { | { | ||||||
| 	[Activity(Label = "@string/plugins", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden)] | 	[Activity(Label = "@string/plugins", ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.KeyboardHidden)] | ||||||
| 	[IntentFilter(new[] { "keepass2android.PluginListActivity" }, Categories = new[] { Intent.CategoryDefault })] | 	[IntentFilter(new[] { "kp2a.action.PluginListActivity" }, Categories = new[] { Intent.CategoryDefault })] | ||||||
| 	public class PluginListActivity : ListActivity | 	public class PluginListActivity : ListActivity | ||||||
| 	{ | 	{ | ||||||
| 		private PluginArrayAdapter _pluginArrayAdapter; | 		private PluginArrayAdapter _pluginArrayAdapter; | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Philipp Crocoll
					Philipp Crocoll