mirror of https://github.com/madler/zlib.git
parent
7a6955760b
commit
79fbcdc939
55 changed files with 2167 additions and 194 deletions
Binary file not shown.
@ -0,0 +1,21 @@ |
|||||||
|
Microsoft Visual Studio Solution File, Format Version 8.00 |
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotZLib", "DotZLib\DotZLib.csproj", "{BB1EE0B1-1808-46CB-B786-949D91117FC5}" |
||||||
|
ProjectSection(ProjectDependencies) = postProject |
||||||
|
EndProjectSection |
||||||
|
EndProject |
||||||
|
Global |
||||||
|
GlobalSection(SolutionConfiguration) = preSolution |
||||||
|
Debug = Debug |
||||||
|
Release = Release |
||||||
|
EndGlobalSection |
||||||
|
GlobalSection(ProjectConfiguration) = postSolution |
||||||
|
{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.ActiveCfg = Debug|.NET |
||||||
|
{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Debug.Build.0 = Debug|.NET |
||||||
|
{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.ActiveCfg = Release|.NET |
||||||
|
{BB1EE0B1-1808-46CB-B786-949D91117FC5}.Release.Build.0 = Release|.NET |
||||||
|
EndGlobalSection |
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution |
||||||
|
EndGlobalSection |
||||||
|
GlobalSection(ExtensibilityAddIns) = postSolution |
||||||
|
EndGlobalSection |
||||||
|
EndGlobal |
@ -0,0 +1,58 @@ |
|||||||
|
using System.Reflection; |
||||||
|
using System.Runtime.CompilerServices; |
||||||
|
|
||||||
|
// |
||||||
|
// General Information about an assembly is controlled through the following |
||||||
|
// set of attributes. Change these attribute values to modify the information |
||||||
|
// associated with an assembly. |
||||||
|
// |
||||||
|
[assembly: AssemblyTitle("DotZLib")] |
||||||
|
[assembly: AssemblyDescription(".Net bindings for ZLib compression dll 1.2.x")] |
||||||
|
[assembly: AssemblyConfiguration("")] |
||||||
|
[assembly: AssemblyCompany("Henrik Ravn")] |
||||||
|
[assembly: AssemblyProduct("")] |
||||||
|
[assembly: AssemblyCopyright("(c) 2004 by Henrik Ravn")] |
||||||
|
[assembly: AssemblyTrademark("")] |
||||||
|
[assembly: AssemblyCulture("")] |
||||||
|
|
||||||
|
// |
||||||
|
// Version information for an assembly consists of the following four values: |
||||||
|
// |
||||||
|
// Major Version |
||||||
|
// Minor Version |
||||||
|
// Build Number |
||||||
|
// Revision |
||||||
|
// |
||||||
|
// You can specify all the values or you can default the Revision and Build Numbers |
||||||
|
// by using the '*' as shown below: |
||||||
|
|
||||||
|
[assembly: AssemblyVersion("1.0.*")] |
||||||
|
|
||||||
|
// |
||||||
|
// In order to sign your assembly you must specify a key to use. Refer to the |
||||||
|
// Microsoft .NET Framework documentation for more information on assembly signing. |
||||||
|
// |
||||||
|
// Use the attributes below to control which key is used for signing. |
||||||
|
// |
||||||
|
// Notes: |
||||||
|
// (*) If no key is specified, the assembly is not signed. |
||||||
|
// (*) KeyName refers to a key that has been installed in the Crypto Service |
||||||
|
// Provider (CSP) on your machine. KeyFile refers to a file which contains |
||||||
|
// a key. |
||||||
|
// (*) If the KeyFile and the KeyName values are both specified, the |
||||||
|
// following processing occurs: |
||||||
|
// (1) If the KeyName can be found in the CSP, that key is used. |
||||||
|
// (2) If the KeyName does not exist and the KeyFile does exist, the key |
||||||
|
// in the KeyFile is installed into the CSP and used. |
||||||
|
// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility. |
||||||
|
// When specifying the KeyFile, the location of the KeyFile should be |
||||||
|
// relative to the project output directory which is |
||||||
|
// %Project Directory%\obj\<configuration>. For example, if your KeyFile is |
||||||
|
// located in the project directory, you would specify the AssemblyKeyFile |
||||||
|
// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")] |
||||||
|
// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework |
||||||
|
// documentation for more information on this. |
||||||
|
// |
||||||
|
[assembly: AssemblyDelaySign(false)] |
||||||
|
[assembly: AssemblyKeyFile("")] |
||||||
|
[assembly: AssemblyKeyName("")] |
@ -0,0 +1,202 @@ |
|||||||
|
// |
||||||
|
// © Copyright Henrik Ravn 2004 |
||||||
|
// |
||||||
|
// Use, modification and distribution are subject to the Boost Software License, Version 1.0. |
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
||||||
|
// |
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Runtime.InteropServices; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
|
||||||
|
namespace DotZLib |
||||||
|
{ |
||||||
|
#region ChecksumGeneratorBase |
||||||
|
/// <summary> |
||||||
|
/// Implements the common functionality needed for all <see cref="ChecksumGenerator"/>s |
||||||
|
/// </summary> |
||||||
|
/// <example></example> |
||||||
|
public abstract class ChecksumGeneratorBase : ChecksumGenerator |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// The value of the current checksum |
||||||
|
/// </summary> |
||||||
|
protected uint _current; |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Initializes a new instance of the checksum generator base - the current checksum is |
||||||
|
/// set to zero |
||||||
|
/// </summary> |
||||||
|
public ChecksumGeneratorBase() |
||||||
|
{ |
||||||
|
_current = 0; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Initializes a new instance of the checksum generator basewith a specified value |
||||||
|
/// </summary> |
||||||
|
/// <param name="initialValue">The value to set the current checksum to</param> |
||||||
|
public ChecksumGeneratorBase(uint initialValue) |
||||||
|
{ |
||||||
|
_current = initialValue; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Resets the current checksum to zero |
||||||
|
/// </summary> |
||||||
|
public void Reset() { _current = 0; } |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the current checksum value |
||||||
|
/// </summary> |
||||||
|
public uint Value { get { return _current; } } |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Updates the current checksum with part of an array of bytes |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">The data to update the checksum with</param> |
||||||
|
/// <param name="offset">Where in <c>data</c> to start updating</param> |
||||||
|
/// <param name="count">The number of bytes from <c>data</c> to use</param> |
||||||
|
/// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception> |
||||||
|
/// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception> |
||||||
|
/// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception> |
||||||
|
/// <remarks>All the other <c>Update</c> methods are implmeneted in terms of this one. |
||||||
|
/// This is therefore the only method a derived class has to implement</remarks> |
||||||
|
public abstract void Update(byte[] data, int offset, int count); |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Updates the current checksum with an array of bytes. |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">The data to update the checksum with</param> |
||||||
|
public void Update(byte[] data) |
||||||
|
{ |
||||||
|
Update(data, 0, data.Length); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Updates the current checksum with the data from a string |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">The string to update the checksum with</param> |
||||||
|
/// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks> |
||||||
|
public void Update(string data) |
||||||
|
{ |
||||||
|
Update(Encoding.UTF8.GetBytes(data)); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Updates the current checksum with the data from a string, using a specific encoding |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">The string to update the checksum with</param> |
||||||
|
/// <param name="encoding">The encoding to use</param> |
||||||
|
public void Update(string data, Encoding encoding) |
||||||
|
{ |
||||||
|
Update(encoding.GetBytes(data)); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
#endregion |
||||||
|
|
||||||
|
#region CRC32 |
||||||
|
/// <summary> |
||||||
|
/// Implements a CRC32 checksum generator |
||||||
|
/// </summary> |
||||||
|
public sealed class CRC32Checksum : ChecksumGeneratorBase |
||||||
|
{ |
||||||
|
#region DLL imports |
||||||
|
|
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern uint crc32(uint crc, int data, uint length); |
||||||
|
|
||||||
|
#endregion |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Initializes a new instance of the CRC32 checksum generator |
||||||
|
/// </summary> |
||||||
|
public CRC32Checksum() : base() {} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Initializes a new instance of the CRC32 checksum generator with a specified value |
||||||
|
/// </summary> |
||||||
|
/// <param name="initialValue">The value to set the current checksum to</param> |
||||||
|
public CRC32Checksum(uint initialValue) : base(initialValue) {} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Updates the current checksum with part of an array of bytes |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">The data to update the checksum with</param> |
||||||
|
/// <param name="offset">Where in <c>data</c> to start updating</param> |
||||||
|
/// <param name="count">The number of bytes from <c>data</c> to use</param> |
||||||
|
/// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception> |
||||||
|
/// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception> |
||||||
|
/// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception> |
||||||
|
public override void Update(byte[] data, int offset, int count) |
||||||
|
{ |
||||||
|
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); |
||||||
|
if ((offset+count) > data.Length) throw new ArgumentException(); |
||||||
|
GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned); |
||||||
|
try |
||||||
|
{ |
||||||
|
_current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count); |
||||||
|
} |
||||||
|
finally |
||||||
|
{ |
||||||
|
hData.Free(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Adler |
||||||
|
/// <summary> |
||||||
|
/// Implements a checksum generator that computes the Adler checksum on data |
||||||
|
/// </summary> |
||||||
|
public sealed class AdlerChecksum : ChecksumGeneratorBase |
||||||
|
{ |
||||||
|
#region DLL imports |
||||||
|
|
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern uint adler32(uint adler, int data, uint length); |
||||||
|
|
||||||
|
#endregion |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Initializes a new instance of the Adler checksum generator |
||||||
|
/// </summary> |
||||||
|
public AdlerChecksum() : base() {} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Initializes a new instance of the Adler checksum generator with a specified value |
||||||
|
/// </summary> |
||||||
|
/// <param name="initialValue">The value to set the current checksum to</param> |
||||||
|
public AdlerChecksum(uint initialValue) : base(initialValue) {} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Updates the current checksum with part of an array of bytes |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">The data to update the checksum with</param> |
||||||
|
/// <param name="offset">Where in <c>data</c> to start updating</param> |
||||||
|
/// <param name="count">The number of bytes from <c>data</c> to use</param> |
||||||
|
/// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception> |
||||||
|
/// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception> |
||||||
|
/// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception> |
||||||
|
public override void Update(byte[] data, int offset, int count) |
||||||
|
{ |
||||||
|
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); |
||||||
|
if ((offset+count) > data.Length) throw new ArgumentException(); |
||||||
|
GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned); |
||||||
|
try |
||||||
|
{ |
||||||
|
_current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count); |
||||||
|
} |
||||||
|
finally |
||||||
|
{ |
||||||
|
hData.Free(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
#endregion |
||||||
|
|
||||||
|
} |
@ -0,0 +1,83 @@ |
|||||||
|
// |
||||||
|
// © Copyright Henrik Ravn 2004 |
||||||
|
// |
||||||
|
// Use, modification and distribution are subject to the Boost Software License, Version 1.0. |
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
||||||
|
// |
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Diagnostics; |
||||||
|
|
||||||
|
namespace DotZLib |
||||||
|
{ |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// This class implements a circular buffer |
||||||
|
/// </summary> |
||||||
|
internal class CircularBuffer |
||||||
|
{ |
||||||
|
#region Private data |
||||||
|
private int _capacity; |
||||||
|
private int _head; |
||||||
|
private int _tail; |
||||||
|
private int _size; |
||||||
|
private byte[] _buffer; |
||||||
|
#endregion |
||||||
|
|
||||||
|
public CircularBuffer(int capacity) |
||||||
|
{ |
||||||
|
Debug.Assert( capacity > 0 ); |
||||||
|
_buffer = new byte[capacity]; |
||||||
|
_capacity = capacity; |
||||||
|
_head = 0; |
||||||
|
_tail = 0; |
||||||
|
_size = 0; |
||||||
|
} |
||||||
|
|
||||||
|
public int Size { get { return _size; } } |
||||||
|
|
||||||
|
public int Put(byte[] source, int offset, int count) |
||||||
|
{ |
||||||
|
Debug.Assert( count > 0 ); |
||||||
|
int trueCount = Math.Min(count, _capacity - Size); |
||||||
|
for (int i = 0; i < trueCount; ++i) |
||||||
|
_buffer[(_tail+i) % _capacity] = source[offset+i]; |
||||||
|
_tail += trueCount; |
||||||
|
_tail %= _capacity; |
||||||
|
_size += trueCount; |
||||||
|
return trueCount; |
||||||
|
} |
||||||
|
|
||||||
|
public bool Put(byte b) |
||||||
|
{ |
||||||
|
if (Size == _capacity) // no room |
||||||
|
return false; |
||||||
|
_buffer[_tail++] = b; |
||||||
|
_tail %= _capacity; |
||||||
|
++_size; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
public int Get(byte[] destination, int offset, int count) |
||||||
|
{ |
||||||
|
int trueCount = Math.Min(count,Size); |
||||||
|
for (int i = 0; i < trueCount; ++i) |
||||||
|
destination[offset + i] = _buffer[(_head+i) % _capacity]; |
||||||
|
_head += trueCount; |
||||||
|
_head %= _capacity; |
||||||
|
_size -= trueCount; |
||||||
|
return trueCount; |
||||||
|
} |
||||||
|
|
||||||
|
public int Get() |
||||||
|
{ |
||||||
|
if (Size == 0) |
||||||
|
return -1; |
||||||
|
|
||||||
|
int result = (int)_buffer[_head++ % _capacity]; |
||||||
|
--_size; |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,198 @@ |
|||||||
|
// |
||||||
|
// © Copyright Henrik Ravn 2004 |
||||||
|
// |
||||||
|
// Use, modification and distribution are subject to the Boost Software License, Version 1.0. |
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
||||||
|
// |
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Runtime.InteropServices; |
||||||
|
|
||||||
|
namespace DotZLib |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// Implements the common functionality needed for all <see cref="Codec"/>s |
||||||
|
/// </summary> |
||||||
|
public abstract class CodecBase : Codec, IDisposable |
||||||
|
{ |
||||||
|
|
||||||
|
#region Data members |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Instance of the internal zlib buffer structure that is |
||||||
|
/// passed to all functions in the zlib dll |
||||||
|
/// </summary> |
||||||
|
internal ZStream _ztream = new ZStream(); |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// True if the object instance has been disposed, false otherwise |
||||||
|
/// </summary> |
||||||
|
protected bool _isDisposed = false; |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// The size of the internal buffers |
||||||
|
/// </summary> |
||||||
|
protected const int kBufferSize = 16384; |
||||||
|
|
||||||
|
private byte[] _outBuffer = new byte[kBufferSize]; |
||||||
|
private byte[] _inBuffer = new byte[kBufferSize]; |
||||||
|
|
||||||
|
private GCHandle _hInput; |
||||||
|
private GCHandle _hOutput; |
||||||
|
|
||||||
|
private uint _checksum = 0; |
||||||
|
|
||||||
|
#endregion |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Initializes a new instance of the <c>CodeBase</c> class. |
||||||
|
/// </summary> |
||||||
|
public CodecBase() |
||||||
|
{ |
||||||
|
try |
||||||
|
{ |
||||||
|
_hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned); |
||||||
|
_hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned); |
||||||
|
} |
||||||
|
catch (Exception) |
||||||
|
{ |
||||||
|
CleanUp(false); |
||||||
|
throw; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
#region Codec Members |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Occurs when more processed data are available. |
||||||
|
/// </summary> |
||||||
|
public event DataAvailableHandler DataAvailable; |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Fires the <see cref="DataAvailable"/> event |
||||||
|
/// </summary> |
||||||
|
protected void OnDataAvailable() |
||||||
|
{ |
||||||
|
if (_ztream.total_out > 0) |
||||||
|
{ |
||||||
|
if (DataAvailable != null) |
||||||
|
DataAvailable( _outBuffer, 0, (int)_ztream.total_out); |
||||||
|
resetOutput(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Adds more data to the codec to be processed. |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">Byte array containing the data to be added to the codec</param> |
||||||
|
/// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks> |
||||||
|
public void Add(byte[] data) |
||||||
|
{ |
||||||
|
Add(data,0,data.Length); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Adds more data to the codec to be processed. |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">Byte array containing the data to be added to the codec</param> |
||||||
|
/// <param name="offset">The index of the first byte to add from <c>data</c></param> |
||||||
|
/// <param name="count">The number of bytes to add</param> |
||||||
|
/// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks> |
||||||
|
/// <remarks>This must be implemented by a derived class</remarks> |
||||||
|
public abstract void Add(byte[] data, int offset, int count); |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Finishes up any pending data that needs to be processed and handled. |
||||||
|
/// </summary> |
||||||
|
/// <remarks>This must be implemented by a derived class</remarks> |
||||||
|
public abstract void Finish(); |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the checksum of the data that has been added so far |
||||||
|
/// </summary> |
||||||
|
public uint Checksum { get { return _checksum; } } |
||||||
|
|
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Destructor & IDisposable stuff |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Destroys this instance |
||||||
|
/// </summary> |
||||||
|
~CodecBase() |
||||||
|
{ |
||||||
|
CleanUp(false); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Releases any unmanaged resources and calls the <see cref="CleanUp()"/> method of the derived class |
||||||
|
/// </summary> |
||||||
|
public void Dispose() |
||||||
|
{ |
||||||
|
CleanUp(true); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Performs any codec specific cleanup |
||||||
|
/// </summary> |
||||||
|
/// <remarks>This must be implemented by a derived class</remarks> |
||||||
|
protected abstract void CleanUp(); |
||||||
|
|
||||||
|
// performs the release of the handles and calls the dereived CleanUp() |
||||||
|
private void CleanUp(bool isDisposing) |
||||||
|
{ |
||||||
|
if (!_isDisposed) |
||||||
|
{ |
||||||
|
CleanUp(); |
||||||
|
if (_hInput.IsAllocated) |
||||||
|
_hInput.Free(); |
||||||
|
if (_hOutput.IsAllocated) |
||||||
|
_hOutput.Free(); |
||||||
|
|
||||||
|
_isDisposed = true; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Helper methods |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Copies a number of bytes to the internal codec buffer - ready for proccesing |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">The byte array that contains the data to copy</param> |
||||||
|
/// <param name="startIndex">The index of the first byte to copy</param> |
||||||
|
/// <param name="count">The number of bytes to copy from <c>data</c></param> |
||||||
|
protected void copyInput(byte[] data, int startIndex, int count) |
||||||
|
{ |
||||||
|
Array.Copy(data, startIndex, _inBuffer,0, count); |
||||||
|
_ztream.next_in = _hInput.AddrOfPinnedObject(); |
||||||
|
_ztream.total_in = 0; |
||||||
|
_ztream.avail_in = (uint)count; |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Resets the internal output buffers to a known state - ready for processing |
||||||
|
/// </summary> |
||||||
|
protected void resetOutput() |
||||||
|
{ |
||||||
|
_ztream.total_out = 0; |
||||||
|
_ztream.avail_out = kBufferSize; |
||||||
|
_ztream.next_out = _hOutput.AddrOfPinnedObject(); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Updates the running checksum property |
||||||
|
/// </summary> |
||||||
|
/// <param name="newSum">The new checksum value</param> |
||||||
|
protected void setChecksum(uint newSum) |
||||||
|
{ |
||||||
|
_checksum = newSum; |
||||||
|
} |
||||||
|
#endregion |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,106 @@ |
|||||||
|
// |
||||||
|
// © Copyright Henrik Ravn 2004 |
||||||
|
// |
||||||
|
// Use, modification and distribution are subject to the Boost Software License, Version 1.0. |
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
||||||
|
// |
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Diagnostics; |
||||||
|
using System.Runtime.InteropServices; |
||||||
|
|
||||||
|
namespace DotZLib |
||||||
|
{ |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Implements a data compressor, using the deflate algorithm in the ZLib dll |
||||||
|
/// </summary> |
||||||
|
public sealed class Deflater : CodecBase |
||||||
|
{ |
||||||
|
#region Dll imports |
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] |
||||||
|
private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size); |
||||||
|
|
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern int deflate(ref ZStream sz, int flush); |
||||||
|
|
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern int deflateReset(ref ZStream sz); |
||||||
|
|
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern int deflateEnd(ref ZStream sz); |
||||||
|
#endregion |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Constructs an new instance of the <c>Deflater</c> |
||||||
|
/// </summary> |
||||||
|
/// <param name="level">The compression level to use for this <c>Deflater</c></param> |
||||||
|
public Deflater(CompressLevel level) : base() |
||||||
|
{ |
||||||
|
int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream)); |
||||||
|
if (retval != 0) |
||||||
|
throw new ZLibException(retval, "Could not initialize deflater"); |
||||||
|
|
||||||
|
resetOutput(); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Adds more data to the codec to be processed. |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">Byte array containing the data to be added to the codec</param> |
||||||
|
/// <param name="offset">The index of the first byte to add from <c>data</c></param> |
||||||
|
/// <param name="count">The number of bytes to add</param> |
||||||
|
/// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks> |
||||||
|
public override void Add(byte[] data, int offset, int count) |
||||||
|
{ |
||||||
|
if (data == null) throw new ArgumentNullException(); |
||||||
|
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); |
||||||
|
if ((offset+count) > data.Length) throw new ArgumentException(); |
||||||
|
|
||||||
|
int total = count; |
||||||
|
int inputIndex = offset; |
||||||
|
int err = 0; |
||||||
|
|
||||||
|
while (err >= 0 && inputIndex < total) |
||||||
|
{ |
||||||
|
copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize)); |
||||||
|
while (err >= 0 && _ztream.avail_in > 0) |
||||||
|
{ |
||||||
|
err = deflate(ref _ztream, (int)FlushTypes.None); |
||||||
|
if (err == 0) |
||||||
|
while (_ztream.avail_out == 0) |
||||||
|
{ |
||||||
|
OnDataAvailable(); |
||||||
|
err = deflate(ref _ztream, (int)FlushTypes.None); |
||||||
|
} |
||||||
|
inputIndex += (int)_ztream.total_in; |
||||||
|
} |
||||||
|
} |
||||||
|
setChecksum( _ztream.adler ); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Finishes up any pending data that needs to be processed and handled. |
||||||
|
/// </summary> |
||||||
|
public override void Finish() |
||||||
|
{ |
||||||
|
int err; |
||||||
|
do |
||||||
|
{ |
||||||
|
err = deflate(ref _ztream, (int)FlushTypes.Finish); |
||||||
|
OnDataAvailable(); |
||||||
|
} |
||||||
|
while (err == 0); |
||||||
|
setChecksum( _ztream.adler ); |
||||||
|
deflateReset(ref _ztream); |
||||||
|
resetOutput(); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Closes the internal zlib deflate stream |
||||||
|
/// </summary> |
||||||
|
protected override void CleanUp() { deflateEnd(ref _ztream); } |
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,288 @@ |
|||||||
|
// |
||||||
|
// © Copyright Henrik Ravn 2004 |
||||||
|
// |
||||||
|
// Use, modification and distribution are subject to the Boost Software License, Version 1.0. |
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
||||||
|
// |
||||||
|
|
||||||
|
using System; |
||||||
|
using System.IO; |
||||||
|
using System.Runtime.InteropServices; |
||||||
|
using System.Text; |
||||||
|
|
||||||
|
|
||||||
|
namespace DotZLib |
||||||
|
{ |
||||||
|
|
||||||
|
#region Internal types |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Defines constants for the various flush types used with zlib |
||||||
|
/// </summary> |
||||||
|
internal enum FlushTypes |
||||||
|
{ |
||||||
|
None, Partial, Sync, Full, Finish, Block |
||||||
|
} |
||||||
|
|
||||||
|
#region ZStream structure |
||||||
|
// internal mapping of the zlib zstream structure for marshalling |
||||||
|
[StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)] |
||||||
|
internal struct ZStream |
||||||
|
{ |
||||||
|
public IntPtr next_in; |
||||||
|
public uint avail_in; |
||||||
|
public uint total_in; |
||||||
|
|
||||||
|
public IntPtr next_out; |
||||||
|
public uint avail_out; |
||||||
|
public uint total_out; |
||||||
|
|
||||||
|
[MarshalAs(UnmanagedType.LPStr)] |
||||||
|
string msg; |
||||||
|
uint state; |
||||||
|
|
||||||
|
uint zalloc; |
||||||
|
uint zfree; |
||||||
|
uint opaque; |
||||||
|
|
||||||
|
int data_type; |
||||||
|
public uint adler; |
||||||
|
uint reserved; |
||||||
|
} |
||||||
|
|
||||||
|
#endregion |
||||||
|
|
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Public enums |
||||||
|
/// <summary> |
||||||
|
/// Defines constants for the available compression levels in zlib |
||||||
|
/// </summary> |
||||||
|
public enum CompressLevel : int |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// The default compression level with a reasonable compromise between compression and speed |
||||||
|
/// </summary> |
||||||
|
Default = -1, |
||||||
|
/// <summary> |
||||||
|
/// No compression at all. The data are passed straight through. |
||||||
|
/// </summary> |
||||||
|
None = 0, |
||||||
|
/// <summary> |
||||||
|
/// The maximum compression rate available. |
||||||
|
/// </summary> |
||||||
|
Best = 9, |
||||||
|
/// <summary> |
||||||
|
/// The fastest available compression level. |
||||||
|
/// </summary> |
||||||
|
Fastest = 1 |
||||||
|
} |
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Exception classes |
||||||
|
/// <summary> |
||||||
|
/// The exception that is thrown when an error occurs on the zlib dll |
||||||
|
/// </summary> |
||||||
|
public class ZLibException : ApplicationException |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// Initializes a new instance of the <see cref="ZLibException"/> class with a specified |
||||||
|
/// error message and error code |
||||||
|
/// </summary> |
||||||
|
/// <param name="errorCode">The zlib error code that caused the exception</param> |
||||||
|
/// <param name="msg">A message that (hopefully) describes the error</param> |
||||||
|
public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg)) |
||||||
|
{ |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Initializes a new instance of the <see cref="ZLibException"/> class with a specified |
||||||
|
/// error code |
||||||
|
/// </summary> |
||||||
|
/// <param name="errorCode">The zlib error code that caused the exception</param> |
||||||
|
public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode)) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Interfaces |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Declares methods and properties that enables a running checksum to be calculated |
||||||
|
/// </summary> |
||||||
|
public interface ChecksumGenerator |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// Gets the current value of the checksum |
||||||
|
/// </summary> |
||||||
|
uint Value { get; } |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Clears the current checksum to 0 |
||||||
|
/// </summary> |
||||||
|
void Reset(); |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Updates the current checksum with an array of bytes |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">The data to update the checksum with</param> |
||||||
|
void Update(byte[] data); |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Updates the current checksum with part of an array of bytes |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">The data to update the checksum with</param> |
||||||
|
/// <param name="offset">Where in <c>data</c> to start updating</param> |
||||||
|
/// <param name="count">The number of bytes from <c>data</c> to use</param> |
||||||
|
/// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception> |
||||||
|
/// <exception cref="ArgumentNullException"><c>data</c> is a null reference</exception> |
||||||
|
/// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception> |
||||||
|
void Update(byte[] data, int offset, int count); |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Updates the current checksum with the data from a string |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">The string to update the checksum with</param> |
||||||
|
/// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks> |
||||||
|
void Update(string data); |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Updates the current checksum with the data from a string, using a specific encoding |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">The string to update the checksum with</param> |
||||||
|
/// <param name="encoding">The encoding to use</param> |
||||||
|
void Update(string data, Encoding encoding); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Represents the method that will be called from a codec when new data |
||||||
|
/// are available. |
||||||
|
/// </summary> |
||||||
|
/// <paramref name="data">The byte array containing the processed data</paramref> |
||||||
|
/// <paramref name="startIndex">The index of the first processed byte in <c>data</c></paramref> |
||||||
|
/// <paramref name="count">The number of processed bytes available</paramref> |
||||||
|
/// <remarks>On return from this method, the data may be overwritten, so grab it while you can. |
||||||
|
/// You cannot assume that startIndex will be zero. |
||||||
|
/// </remarks> |
||||||
|
public delegate void DataAvailableHandler(byte[] data, int startIndex, int count); |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Declares methods and events for implementing compressors/decompressors |
||||||
|
/// </summary> |
||||||
|
public interface Codec |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// Occurs when more processed data are available. |
||||||
|
/// </summary> |
||||||
|
event DataAvailableHandler DataAvailable; |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Adds more data to the codec to be processed. |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">Byte array containing the data to be added to the codec</param> |
||||||
|
/// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks> |
||||||
|
void Add(byte[] data); |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Adds more data to the codec to be processed. |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">Byte array containing the data to be added to the codec</param> |
||||||
|
/// <param name="offset">The index of the first byte to add from <c>data</c></param> |
||||||
|
/// <param name="count">The number of bytes to add</param> |
||||||
|
/// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks> |
||||||
|
void Add(byte[] data, int offset, int count); |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Finishes up any pending data that needs to be processed and handled. |
||||||
|
/// </summary> |
||||||
|
void Finish(); |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the checksum of the data that has been added so far |
||||||
|
/// </summary> |
||||||
|
uint Checksum { get; } |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Classes |
||||||
|
/// <summary> |
||||||
|
/// Encapsulates general information about the ZLib library |
||||||
|
/// </summary> |
||||||
|
public class Info |
||||||
|
{ |
||||||
|
#region DLL imports |
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern uint zlibCompileFlags(); |
||||||
|
|
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern string zlibVersion(); |
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Private stuff |
||||||
|
private uint _flags; |
||||||
|
|
||||||
|
// helper function that unpacks a bitsize mask |
||||||
|
private static int bitSize(uint bits) |
||||||
|
{ |
||||||
|
switch (bits) |
||||||
|
{ |
||||||
|
case 0: return 16; |
||||||
|
case 1: return 32; |
||||||
|
case 2: return 64; |
||||||
|
} |
||||||
|
return -1; |
||||||
|
} |
||||||
|
#endregion |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Constructs an instance of the <c>Info</c> class. |
||||||
|
/// </summary> |
||||||
|
public Info() |
||||||
|
{ |
||||||
|
_flags = zlibCompileFlags(); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// True if the library is compiled with debug info |
||||||
|
/// </summary> |
||||||
|
public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } } |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// True if the library is compiled with assembly optimizations |
||||||
|
/// </summary> |
||||||
|
public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } } |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the size of the unsigned int that was compiled into Zlib |
||||||
|
/// </summary> |
||||||
|
public int SizeOfUInt { get { return bitSize(_flags & 3); } } |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the size of the unsigned long that was compiled into Zlib |
||||||
|
/// </summary> |
||||||
|
public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } } |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the size of the pointers that were compiled into Zlib |
||||||
|
/// </summary> |
||||||
|
public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } } |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the size of the z_off_t type that was compiled into Zlib |
||||||
|
/// </summary> |
||||||
|
public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } } |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the version of ZLib as a string, e.g. "1.2.1" |
||||||
|
/// </summary> |
||||||
|
public static string Version { get { return zlibVersion(); } } |
||||||
|
} |
||||||
|
|
||||||
|
#endregion |
||||||
|
|
||||||
|
} |
@ -0,0 +1,141 @@ |
|||||||
|
<VisualStudioProject> |
||||||
|
<CSHARP |
||||||
|
ProjectType = "Local" |
||||||
|
ProductVersion = "7.10.3077" |
||||||
|
SchemaVersion = "2.0" |
||||||
|
ProjectGuid = "{BB1EE0B1-1808-46CB-B786-949D91117FC5}" |
||||||
|
> |
||||||
|
<Build> |
||||||
|
<Settings |
||||||
|
ApplicationIcon = "" |
||||||
|
AssemblyKeyContainerName = "" |
||||||
|
AssemblyName = "DotZLib" |
||||||
|
AssemblyOriginatorKeyFile = "" |
||||||
|
DefaultClientScript = "JScript" |
||||||
|
DefaultHTMLPageLayout = "Grid" |
||||||
|
DefaultTargetSchema = "IE50" |
||||||
|
DelaySign = "false" |
||||||
|
OutputType = "Library" |
||||||
|
PreBuildEvent = "" |
||||||
|
PostBuildEvent = "" |
||||||
|
RootNamespace = "DotZLib" |
||||||
|
RunPostBuildEvent = "OnBuildSuccess" |
||||||
|
StartupObject = "" |
||||||
|
> |
||||||
|
<Config |
||||||
|
Name = "Debug" |
||||||
|
AllowUnsafeBlocks = "false" |
||||||
|
BaseAddress = "285212672" |
||||||
|
CheckForOverflowUnderflow = "false" |
||||||
|
ConfigurationOverrideFile = "" |
||||||
|
DefineConstants = "DEBUG;TRACE" |
||||||
|
DocumentationFile = "docs\DotZLib.xml" |
||||||
|
DebugSymbols = "true" |
||||||
|
FileAlignment = "4096" |
||||||
|
IncrementalBuild = "false" |
||||||
|
NoStdLib = "false" |
||||||
|
NoWarn = "1591" |
||||||
|
Optimize = "false" |
||||||
|
OutputPath = "bin\Debug\" |
||||||
|
RegisterForComInterop = "false" |
||||||
|
RemoveIntegerChecks = "false" |
||||||
|
TreatWarningsAsErrors = "false" |
||||||
|
WarningLevel = "4" |
||||||
|
/> |
||||||
|
<Config |
||||||
|
Name = "Release" |
||||||
|
AllowUnsafeBlocks = "false" |
||||||
|
BaseAddress = "285212672" |
||||||
|
CheckForOverflowUnderflow = "false" |
||||||
|
ConfigurationOverrideFile = "" |
||||||
|
DefineConstants = "TRACE" |
||||||
|
DocumentationFile = "docs\DotZLib.xml" |
||||||
|
DebugSymbols = "false" |
||||||
|
FileAlignment = "4096" |
||||||
|
IncrementalBuild = "false" |
||||||
|
NoStdLib = "false" |
||||||
|
NoWarn = "" |
||||||
|
Optimize = "true" |
||||||
|
OutputPath = "bin\Release\" |
||||||
|
RegisterForComInterop = "false" |
||||||
|
RemoveIntegerChecks = "false" |
||||||
|
TreatWarningsAsErrors = "false" |
||||||
|
WarningLevel = "4" |
||||||
|
/> |
||||||
|
</Settings> |
||||||
|
<References> |
||||||
|
<Reference |
||||||
|
Name = "System" |
||||||
|
AssemblyName = "System" |
||||||
|
HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.dll" |
||||||
|
/> |
||||||
|
<Reference |
||||||
|
Name = "System.Data" |
||||||
|
AssemblyName = "System.Data" |
||||||
|
HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Data.dll" |
||||||
|
/> |
||||||
|
<Reference |
||||||
|
Name = "System.XML" |
||||||
|
AssemblyName = "System.Xml" |
||||||
|
HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.XML.dll" |
||||||
|
/> |
||||||
|
<Reference |
||||||
|
Name = "nunit.framework" |
||||||
|
AssemblyName = "nunit.framework" |
||||||
|
HintPath = "E:\apps\NUnit V2.1\\bin\nunit.framework.dll" |
||||||
|
AssemblyFolderKey = "hklm\dn\nunit.framework" |
||||||
|
/> |
||||||
|
</References> |
||||||
|
</Build> |
||||||
|
<Files> |
||||||
|
<Include> |
||||||
|
<File |
||||||
|
RelPath = "AssemblyInfo.cs" |
||||||
|
SubType = "Code" |
||||||
|
BuildAction = "Compile" |
||||||
|
/> |
||||||
|
<File |
||||||
|
RelPath = "ChecksumImpl.cs" |
||||||
|
SubType = "Code" |
||||||
|
BuildAction = "Compile" |
||||||
|
/> |
||||||
|
<File |
||||||
|
RelPath = "CircularBuffer.cs" |
||||||
|
SubType = "Code" |
||||||
|
BuildAction = "Compile" |
||||||
|
/> |
||||||
|
<File |
||||||
|
RelPath = "CodecBase.cs" |
||||||
|
SubType = "Code" |
||||||
|
BuildAction = "Compile" |
||||||
|
/> |
||||||
|
<File |
||||||
|
RelPath = "Deflater.cs" |
||||||
|
SubType = "Code" |
||||||
|
BuildAction = "Compile" |
||||||
|
/> |
||||||
|
<File |
||||||
|
RelPath = "DotZLib.cs" |
||||||
|
SubType = "Code" |
||||||
|
BuildAction = "Compile" |
||||||
|
/> |
||||||
|
<File |
||||||
|
RelPath = "GZipStream.cs" |
||||||
|
SubType = "Code" |
||||||
|
BuildAction = "Compile" |
||||||
|
/> |
||||||
|
<File |
||||||
|
RelPath = "Inflater.cs" |
||||||
|
SubType = "Code" |
||||||
|
BuildAction = "Compile" |
||||||
|
/> |
||||||
|
<File |
||||||
|
RelPath = "UnitTests.cs" |
||||||
|
SubType = "Code" |
||||||
|
BuildAction = "Compile" |
||||||
|
/> |
||||||
|
</Include> |
||||||
|
</Files> |
||||||
|
</CSHARP> |
||||||
|
</VisualStudioProject> |
||||||
|
|
@ -0,0 +1,301 @@ |
|||||||
|
// |
||||||
|
// © Copyright Henrik Ravn 2004 |
||||||
|
// |
||||||
|
// Use, modification and distribution are subject to the Boost Software License, Version 1.0. |
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
||||||
|
// |
||||||
|
|
||||||
|
using System; |
||||||
|
using System.IO; |
||||||
|
using System.Runtime.InteropServices; |
||||||
|
|
||||||
|
namespace DotZLib |
||||||
|
{ |
||||||
|
/// <summary> |
||||||
|
/// Implements a compressed <see cref="Stream"/>, in GZip (.gz) format. |
||||||
|
/// </summary> |
||||||
|
public class GZipStream : Stream, IDisposable |
||||||
|
{ |
||||||
|
#region Dll Imports |
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] |
||||||
|
private static extern IntPtr gzopen(string name, string mode); |
||||||
|
|
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern int gzclose(IntPtr gzFile); |
||||||
|
|
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern int gzwrite(IntPtr gzFile, int data, int length); |
||||||
|
|
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern int gzread(IntPtr gzFile, int data, int length); |
||||||
|
|
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern int gzgetc(IntPtr gzFile); |
||||||
|
|
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern int gzputc(IntPtr gzFile, int c); |
||||||
|
|
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Private data |
||||||
|
private IntPtr _gzFile; |
||||||
|
private bool _isDisposed = false; |
||||||
|
private bool _isWriting; |
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Constructors |
||||||
|
/// <summary> |
||||||
|
/// Creates a new file as a writeable GZipStream |
||||||
|
/// </summary> |
||||||
|
/// <param name="fileName">The name of the compressed file to create</param> |
||||||
|
/// <param name="level">The compression level to use when adding data</param> |
||||||
|
/// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception> |
||||||
|
public GZipStream(string fileName, CompressLevel level) |
||||||
|
{ |
||||||
|
_isWriting = true; |
||||||
|
_gzFile = gzopen(fileName, String.Format("wb{0}", (int)level)); |
||||||
|
if (_gzFile == IntPtr.Zero) |
||||||
|
throw new ZLibException(-1, "Could not open " + fileName); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Opens an existing file as a readable GZipStream |
||||||
|
/// </summary> |
||||||
|
/// <param name="fileName">The name of the file to open</param> |
||||||
|
/// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception> |
||||||
|
public GZipStream(string fileName) |
||||||
|
{ |
||||||
|
_isWriting = false; |
||||||
|
_gzFile = gzopen(fileName, "rb"); |
||||||
|
if (_gzFile == IntPtr.Zero) |
||||||
|
throw new ZLibException(-1, "Could not open " + fileName); |
||||||
|
|
||||||
|
} |
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Access properties |
||||||
|
/// <summary> |
||||||
|
/// Returns true of this stream can be read from, false otherwise |
||||||
|
/// </summary> |
||||||
|
public override bool CanRead |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return !_isWriting; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Returns false. |
||||||
|
/// </summary> |
||||||
|
public override bool CanSeek |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return false; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Returns true if this tsream is writeable, false otherwise |
||||||
|
/// </summary> |
||||||
|
public override bool CanWrite |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
return _isWriting; |
||||||
|
} |
||||||
|
} |
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Destructor & IDispose stuff |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Destroys this instance |
||||||
|
/// </summary> |
||||||
|
~GZipStream() |
||||||
|
{ |
||||||
|
cleanUp(false); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Closes the external file handle |
||||||
|
/// </summary> |
||||||
|
public void Dispose() |
||||||
|
{ |
||||||
|
cleanUp(true); |
||||||
|
} |
||||||
|
|
||||||
|
// Does the actual closing of the file handle. |
||||||
|
private void cleanUp(bool isDisposing) |
||||||
|
{ |
||||||
|
if (!_isDisposed) |
||||||
|
{ |
||||||
|
gzclose(_gzFile); |
||||||
|
_isDisposed = true; |
||||||
|
} |
||||||
|
} |
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Basic reading and writing |
||||||
|
/// <summary> |
||||||
|
/// Attempts to read a number of bytes from the stream. |
||||||
|
/// </summary> |
||||||
|
/// <param name="buffer">The destination data buffer</param> |
||||||
|
/// <param name="offset">The index of the first destination byte in <c>buffer</c></param> |
||||||
|
/// <param name="count">The number of bytes requested</param> |
||||||
|
/// <returns>The number of bytes read</returns> |
||||||
|
/// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception> |
||||||
|
/// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception> |
||||||
|
/// <exception cref="ArgumentException">If <c>offset</c> + <c>count</c> is > buffer.Length</exception> |
||||||
|
/// <exception cref="NotSupportedException">If this stream is not readable.</exception> |
||||||
|
/// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception> |
||||||
|
public override int Read(byte[] buffer, int offset, int count) |
||||||
|
{ |
||||||
|
if (!CanRead) throw new NotSupportedException(); |
||||||
|
if (buffer == null) throw new ArgumentNullException(); |
||||||
|
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); |
||||||
|
if ((offset+count) > buffer.Length) throw new ArgumentException(); |
||||||
|
if (_isDisposed) throw new ObjectDisposedException("GZipStream"); |
||||||
|
|
||||||
|
GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned); |
||||||
|
int result; |
||||||
|
try |
||||||
|
{ |
||||||
|
result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count); |
||||||
|
if (result < 0) |
||||||
|
throw new IOException(); |
||||||
|
} |
||||||
|
finally |
||||||
|
{ |
||||||
|
h.Free(); |
||||||
|
} |
||||||
|
return result; |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Attempts to read a single byte from the stream. |
||||||
|
/// </summary> |
||||||
|
/// <returns>The byte that was read, or -1 in case of error or End-Of-File</returns> |
||||||
|
public override int ReadByte() |
||||||
|
{ |
||||||
|
if (!CanRead) throw new NotSupportedException(); |
||||||
|
if (_isDisposed) throw new ObjectDisposedException("GZipStream"); |
||||||
|
return gzgetc(_gzFile); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Writes a number of bytes to the stream |
||||||
|
/// </summary> |
||||||
|
/// <param name="buffer"></param> |
||||||
|
/// <param name="offset"></param> |
||||||
|
/// <param name="count"></param> |
||||||
|
/// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception> |
||||||
|
/// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception> |
||||||
|
/// <exception cref="ArgumentException">If <c>offset</c> + <c>count</c> is > buffer.Length</exception> |
||||||
|
/// <exception cref="NotSupportedException">If this stream is not writeable.</exception> |
||||||
|
/// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception> |
||||||
|
public override void Write(byte[] buffer, int offset, int count) |
||||||
|
{ |
||||||
|
if (!CanWrite) throw new NotSupportedException(); |
||||||
|
if (buffer == null) throw new ArgumentNullException(); |
||||||
|
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); |
||||||
|
if ((offset+count) > buffer.Length) throw new ArgumentException(); |
||||||
|
if (_isDisposed) throw new ObjectDisposedException("GZipStream"); |
||||||
|
|
||||||
|
GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned); |
||||||
|
try |
||||||
|
{ |
||||||
|
int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count); |
||||||
|
if (result < 0) |
||||||
|
throw new IOException(); |
||||||
|
} |
||||||
|
finally |
||||||
|
{ |
||||||
|
h.Free(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Writes a single byte to the stream |
||||||
|
/// </summary> |
||||||
|
/// <param name="value">The byte to add to the stream.</param> |
||||||
|
/// <exception cref="NotSupportedException">If this stream is not writeable.</exception> |
||||||
|
/// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception> |
||||||
|
public override void WriteByte(byte value) |
||||||
|
{ |
||||||
|
if (!CanWrite) throw new NotSupportedException(); |
||||||
|
if (_isDisposed) throw new ObjectDisposedException("GZipStream"); |
||||||
|
|
||||||
|
int result = gzputc(_gzFile, (int)value); |
||||||
|
if (result < 0) |
||||||
|
throw new IOException(); |
||||||
|
} |
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Position & length stuff |
||||||
|
/// <summary> |
||||||
|
/// Not supported. |
||||||
|
/// </summary> |
||||||
|
/// <param name="value"></param> |
||||||
|
/// <exception cref="NotSupportedException">Always thrown</exception> |
||||||
|
public override void SetLength(long value) |
||||||
|
{ |
||||||
|
throw new NotSupportedException(); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Not suppported. |
||||||
|
/// </summary> |
||||||
|
/// <param name="offset"></param> |
||||||
|
/// <param name="origin"></param> |
||||||
|
/// <returns></returns> |
||||||
|
/// <exception cref="NotSupportedException">Always thrown</exception> |
||||||
|
public override long Seek(long offset, SeekOrigin origin) |
||||||
|
{ |
||||||
|
throw new NotSupportedException(); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Flushes the <c>GZipStream</c>. |
||||||
|
/// </summary> |
||||||
|
/// <remarks>In this implementation, this method does nothing. This is because excessive |
||||||
|
/// flushing may degrade the achievable compression rates.</remarks> |
||||||
|
public override void Flush() |
||||||
|
{ |
||||||
|
// left empty on purpose |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets/sets the current position in the <c>GZipStream</c>. Not suppported. |
||||||
|
/// </summary> |
||||||
|
/// <remarks>In this implementation this property is not supported</remarks> |
||||||
|
/// <exception cref="NotSupportedException">Always thrown</exception> |
||||||
|
public override long Position |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
throw new NotSupportedException(); |
||||||
|
} |
||||||
|
set |
||||||
|
{ |
||||||
|
throw new NotSupportedException(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Gets the size of the stream. Not suppported. |
||||||
|
/// </summary> |
||||||
|
/// <remarks>In this implementation this property is not supported</remarks> |
||||||
|
/// <exception cref="NotSupportedException">Always thrown</exception> |
||||||
|
public override long Length |
||||||
|
{ |
||||||
|
get |
||||||
|
{ |
||||||
|
throw new NotSupportedException(); |
||||||
|
} |
||||||
|
} |
||||||
|
#endregion |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,105 @@ |
|||||||
|
// |
||||||
|
// © Copyright Henrik Ravn 2004 |
||||||
|
// |
||||||
|
// Use, modification and distribution are subject to the Boost Software License, Version 1.0. |
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
||||||
|
// |
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Diagnostics; |
||||||
|
using System.Runtime.InteropServices; |
||||||
|
|
||||||
|
namespace DotZLib |
||||||
|
{ |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Implements a data decompressor, using the inflate algorithm in the ZLib dll |
||||||
|
/// </summary> |
||||||
|
public class Inflater : CodecBase |
||||||
|
{ |
||||||
|
#region Dll imports |
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)] |
||||||
|
private static extern int inflateInit_(ref ZStream sz, string vs, int size); |
||||||
|
|
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern int inflate(ref ZStream sz, int flush); |
||||||
|
|
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern int inflateReset(ref ZStream sz); |
||||||
|
|
||||||
|
[DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] |
||||||
|
private static extern int inflateEnd(ref ZStream sz); |
||||||
|
#endregion |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Constructs an new instance of the <c>Inflater</c> |
||||||
|
/// </summary> |
||||||
|
public Inflater() : base() |
||||||
|
{ |
||||||
|
int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream)); |
||||||
|
if (retval != 0) |
||||||
|
throw new ZLibException(retval, "Could not initialize inflater"); |
||||||
|
|
||||||
|
resetOutput(); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Adds more data to the codec to be processed. |
||||||
|
/// </summary> |
||||||
|
/// <param name="data">Byte array containing the data to be added to the codec</param> |
||||||
|
/// <param name="offset">The index of the first byte to add from <c>data</c></param> |
||||||
|
/// <param name="count">The number of bytes to add</param> |
||||||
|
/// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks> |
||||||
|
public override void Add(byte[] data, int offset, int count) |
||||||
|
{ |
||||||
|
if (data == null) throw new ArgumentNullException(); |
||||||
|
if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); |
||||||
|
if ((offset+count) > data.Length) throw new ArgumentException(); |
||||||
|
|
||||||
|
int total = count; |
||||||
|
int inputIndex = offset; |
||||||
|
int err = 0; |
||||||
|
|
||||||
|
while (err >= 0 && inputIndex < total) |
||||||
|
{ |
||||||
|
copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize)); |
||||||
|
err = inflate(ref _ztream, (int)FlushTypes.None); |
||||||
|
if (err == 0) |
||||||
|
while (_ztream.avail_out == 0) |
||||||
|
{ |
||||||
|
OnDataAvailable(); |
||||||
|
err = inflate(ref _ztream, (int)FlushTypes.None); |
||||||
|
} |
||||||
|
|
||||||
|
inputIndex += (int)_ztream.total_in; |
||||||
|
} |
||||||
|
setChecksum( _ztream.adler ); |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Finishes up any pending data that needs to be processed and handled. |
||||||
|
/// </summary> |
||||||
|
public override void Finish() |
||||||
|
{ |
||||||
|
int err; |
||||||
|
do |
||||||
|
{ |
||||||
|
err = inflate(ref _ztream, (int)FlushTypes.Finish); |
||||||
|
OnDataAvailable(); |
||||||
|
} |
||||||
|
while (err == 0); |
||||||
|
setChecksum( _ztream.adler ); |
||||||
|
inflateReset(ref _ztream); |
||||||
|
resetOutput(); |
||||||
|
} |
||||||
|
|
||||||
|
/// <summary> |
||||||
|
/// Closes the internal zlib inflate stream |
||||||
|
/// </summary> |
||||||
|
protected override void CleanUp() { inflateEnd(ref _ztream); } |
||||||
|
|
||||||
|
|
||||||
|
} |
||||||
|
} |
@ -0,0 +1,274 @@ |
|||||||
|
// |
||||||
|
// © Copyright Henrik Ravn 2004 |
||||||
|
// |
||||||
|
// Use, modification and distribution are subject to the Boost Software License, Version 1.0. |
||||||
|
// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
||||||
|
// |
||||||
|
|
||||||
|
using System; |
||||||
|
using System.Collections; |
||||||
|
using System.IO; |
||||||
|
|
||||||
|
// uncomment the define below to include unit tests |
||||||
|
//#define nunit |
||||||
|
#if nunit |
||||||
|
using NUnit.Framework; |
||||||
|
|
||||||
|
// Unit tests for the DotZLib class library |
||||||
|
// ---------------------------------------- |
||||||
|
// |
||||||
|
// Use this with NUnit 2 from http://www.nunit.org |
||||||
|
// |
||||||
|
|
||||||
|
namespace DotZLibTests |
||||||
|
{ |
||||||
|
using DotZLib; |
||||||
|
|
||||||
|
// helper methods |
||||||
|
internal class Utils |
||||||
|
{ |
||||||
|
public static bool byteArrEqual( byte[] lhs, byte[] rhs ) |
||||||
|
{ |
||||||
|
if (lhs.Length != rhs.Length) |
||||||
|
return false; |
||||||
|
for (int i = lhs.Length-1; i >= 0; --i) |
||||||
|
if (lhs[i] != rhs[i]) |
||||||
|
return false; |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
[TestFixture] |
||||||
|
public class CircBufferTests |
||||||
|
{ |
||||||
|
#region Circular buffer tests |
||||||
|
[Test] |
||||||
|
public void SinglePutGet() |
||||||
|
{ |
||||||
|
CircularBuffer buf = new CircularBuffer(10); |
||||||
|
Assert.AreEqual( 0, buf.Size ); |
||||||
|
Assert.AreEqual( -1, buf.Get() ); |
||||||
|
|
||||||
|
Assert.IsTrue(buf.Put( 1 )); |
||||||
|
Assert.AreEqual( 1, buf.Size ); |
||||||
|
Assert.AreEqual( 1, buf.Get() ); |
||||||
|
Assert.AreEqual( 0, buf.Size ); |
||||||
|
Assert.AreEqual( -1, buf.Get() ); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void BlockPutGet() |
||||||
|
{ |
||||||
|
CircularBuffer buf = new CircularBuffer(10); |
||||||
|
byte[] arr = {1,2,3,4,5,6,7,8,9,10}; |
||||||
|
Assert.AreEqual( 10, buf.Put(arr,0,10) ); |
||||||
|
Assert.AreEqual( 10, buf.Size ); |
||||||
|
Assert.IsFalse( buf.Put(11) ); |
||||||
|
Assert.AreEqual( 1, buf.Get() ); |
||||||
|
Assert.IsTrue( buf.Put(11) ); |
||||||
|
|
||||||
|
byte[] arr2 = (byte[])arr.Clone(); |
||||||
|
Assert.AreEqual( 9, buf.Get(arr2,1,9) ); |
||||||
|
Assert.IsTrue( Utils.byteArrEqual(arr,arr2) ); |
||||||
|
} |
||||||
|
|
||||||
|
#endregion |
||||||
|
} |
||||||
|
|
||||||
|
[TestFixture] |
||||||
|
public class ChecksumTests |
||||||
|
{ |
||||||
|
#region CRC32 Tests |
||||||
|
[Test] |
||||||
|
public void CRC32_Null() |
||||||
|
{ |
||||||
|
CRC32Checksum crc32 = new CRC32Checksum(); |
||||||
|
Assert.AreEqual( 0, crc32.Value ); |
||||||
|
|
||||||
|
crc32 = new CRC32Checksum(1); |
||||||
|
Assert.AreEqual( 1, crc32.Value ); |
||||||
|
|
||||||
|
crc32 = new CRC32Checksum(556); |
||||||
|
Assert.AreEqual( 556, crc32.Value ); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void CRC32_Data() |
||||||
|
{ |
||||||
|
CRC32Checksum crc32 = new CRC32Checksum(); |
||||||
|
byte[] data = { 1,2,3,4,5,6,7 }; |
||||||
|
crc32.Update(data); |
||||||
|
Assert.AreEqual( 0x70e46888, crc32.Value ); |
||||||
|
|
||||||
|
crc32 = new CRC32Checksum(); |
||||||
|
crc32.Update("penguin"); |
||||||
|
Assert.AreEqual( 0x0e5c1a120, crc32.Value ); |
||||||
|
|
||||||
|
crc32 = new CRC32Checksum(1); |
||||||
|
crc32.Update("penguin"); |
||||||
|
Assert.AreEqual(0x43b6aa94, crc32.Value); |
||||||
|
|
||||||
|
} |
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Adler tests |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void Adler_Null() |
||||||
|
{ |
||||||
|
AdlerChecksum adler = new AdlerChecksum(); |
||||||
|
Assert.AreEqual(0, adler.Value); |
||||||
|
|
||||||
|
adler = new AdlerChecksum(1); |
||||||
|
Assert.AreEqual( 1, adler.Value ); |
||||||
|
|
||||||
|
adler = new AdlerChecksum(556); |
||||||
|
Assert.AreEqual( 556, adler.Value ); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void Adler_Data() |
||||||
|
{ |
||||||
|
AdlerChecksum adler = new AdlerChecksum(1); |
||||||
|
byte[] data = { 1,2,3,4,5,6,7 }; |
||||||
|
adler.Update(data); |
||||||
|
Assert.AreEqual( 0x5b001d, adler.Value ); |
||||||
|
|
||||||
|
adler = new AdlerChecksum(); |
||||||
|
adler.Update("penguin"); |
||||||
|
Assert.AreEqual(0x0bcf02f6, adler.Value ); |
||||||
|
|
||||||
|
adler = new AdlerChecksum(1); |
||||||
|
adler.Update("penguin"); |
||||||
|
Assert.AreEqual(0x0bd602f7, adler.Value); |
||||||
|
|
||||||
|
} |
||||||
|
#endregion |
||||||
|
} |
||||||
|
|
||||||
|
[TestFixture] |
||||||
|
public class InfoTests |
||||||
|
{ |
||||||
|
#region Info tests |
||||||
|
[Test] |
||||||
|
public void Info_Version() |
||||||
|
{ |
||||||
|
Info info = new Info(); |
||||||
|
Assert.AreEqual("1.2.2", Info.Version); |
||||||
|
Assert.AreEqual(32, info.SizeOfUInt); |
||||||
|
Assert.AreEqual(32, info.SizeOfULong); |
||||||
|
Assert.AreEqual(32, info.SizeOfPointer); |
||||||
|
Assert.AreEqual(32, info.SizeOfOffset); |
||||||
|
} |
||||||
|
#endregion |
||||||
|
} |
||||||
|
|
||||||
|
[TestFixture] |
||||||
|
public class DeflateInflateTests |
||||||
|
{ |
||||||
|
#region Deflate tests |
||||||
|
[Test] |
||||||
|
public void Deflate_Init() |
||||||
|
{ |
||||||
|
using (Deflater def = new Deflater(CompressLevel.Default)) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private ArrayList compressedData = new ArrayList(); |
||||||
|
private uint adler1; |
||||||
|
|
||||||
|
private ArrayList uncompressedData = new ArrayList(); |
||||||
|
private uint adler2; |
||||||
|
|
||||||
|
public void CDataAvail(byte[] data, int startIndex, int count) |
||||||
|
{ |
||||||
|
for (int i = 0; i < count; ++i) |
||||||
|
compressedData.Add(data[i+startIndex]); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void Deflate_Compress() |
||||||
|
{ |
||||||
|
compressedData.Clear(); |
||||||
|
|
||||||
|
byte[] testData = new byte[35000]; |
||||||
|
for (int i = 0; i < testData.Length; ++i) |
||||||
|
testData[i] = 5; |
||||||
|
|
||||||
|
using (Deflater def = new Deflater((CompressLevel)5)) |
||||||
|
{ |
||||||
|
def.DataAvailable += new DataAvailableHandler(CDataAvail); |
||||||
|
def.Add(testData); |
||||||
|
def.Finish(); |
||||||
|
adler1 = def.Checksum; |
||||||
|
} |
||||||
|
} |
||||||
|
#endregion |
||||||
|
|
||||||
|
#region Inflate tests |
||||||
|
[Test] |
||||||
|
public void Inflate_Init() |
||||||
|
{ |
||||||
|
using (Inflater inf = new Inflater()) |
||||||
|
{ |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private void DDataAvail(byte[] data, int startIndex, int count) |
||||||
|
{ |
||||||
|
for (int i = 0; i < count; ++i) |
||||||
|
uncompressedData.Add(data[i+startIndex]); |
||||||
|
} |
||||||
|
|
||||||
|
[Test] |
||||||
|
public void Inflate_Expand() |
||||||
|
{ |
||||||
|
uncompressedData.Clear(); |
||||||
|
|
||||||
|
using (Inflater inf = new Inflater()) |
||||||
|
{ |
||||||
|
inf.DataAvailable += new DataAvailableHandler(DDataAvail); |
||||||
|
inf.Add((byte[])compressedData.ToArray(typeof(byte))); |
||||||
|
inf.Finish(); |
||||||
|
adler2 = inf.Checksum; |
||||||
|
} |
||||||
|
Assert.AreEqual( adler1, adler2 ); |
||||||
|
} |
||||||
|
#endregion |
||||||
|
} |
||||||
|
|
||||||
|
[TestFixture] |
||||||
|
public class GZipStreamTests |
||||||
|
{ |
||||||
|
#region GZipStream test |
||||||
|
[Test] |
||||||
|
public void GZipStream_WriteRead() |
||||||
|
{ |
||||||
|
using (GZipStream gzOut = new GZipStream("gzstream.gz", CompressLevel.Best)) |
||||||
|
{ |
||||||
|
BinaryWriter writer = new BinaryWriter(gzOut); |
||||||
|
writer.Write("hi there"); |
||||||
|
writer.Write(Math.PI); |
||||||
|
writer.Write(42); |
||||||
|
} |
||||||
|
|
||||||
|
using (GZipStream gzIn = new GZipStream("gzstream.gz")) |
||||||
|
{ |
||||||
|
BinaryReader reader = new BinaryReader(gzIn); |
||||||
|
string s = reader.ReadString(); |
||||||
|
Assert.AreEqual("hi there",s); |
||||||
|
double d = reader.ReadDouble(); |
||||||
|
Assert.AreEqual(Math.PI, d); |
||||||
|
int i = reader.ReadInt32(); |
||||||
|
Assert.AreEqual(42,i); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
#endregion |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,23 @@ |
|||||||
|
Boost Software License - Version 1.0 - August 17th, 2003 |
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person or organization |
||||||
|
obtaining a copy of the software and accompanying documentation covered by |
||||||
|
this license (the "Software") to use, reproduce, display, distribute, |
||||||
|
execute, and transmit the Software, and to prepare derivative works of the |
||||||
|
Software, and to permit third-parties to whom the Software is furnished to |
||||||
|
do so, all subject to the following: |
||||||
|
|
||||||
|
The copyright notices in the Software and this entire statement, including |
||||||
|
the above license grant, this restriction and the following disclaimer, |
||||||
|
must be included in all copies of the Software, in whole or in part, and |
||||||
|
all derivative works of the Software, unless such copies or derivative |
||||||
|
works are solely in the form of machine-executable object code generated by |
||||||
|
a source language processor. |
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
||||||
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT |
||||||
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE |
||||||
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, |
||||||
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
||||||
|
DEALINGS IN THE SOFTWARE. |
@ -0,0 +1,58 @@ |
|||||||
|
This directory contains a .Net wrapper class library for the ZLib1.dll |
||||||
|
|
||||||
|
The wrapper includes support for inflating/deflating memory buffers, |
||||||
|
.Net streaming wrappers for the gz streams part of zlib, and wrappers |
||||||
|
for the checksum parts of zlib. See DotZLib/UnitTests.cs for examples. |
||||||
|
|
||||||
|
Directory structure: |
||||||
|
-------------------- |
||||||
|
|
||||||
|
LICENSE_1_0.txt - License file. |
||||||
|
readme.txt - This file. |
||||||
|
DotZLib.chm - Class library documentation |
||||||
|
DotZLib.build - NAnt build file |
||||||
|
DotZLib.sln - Microsoft Visual Studio 2003 solution file |
||||||
|
|
||||||
|
DotZLib\*.cs - Source files for the class library |
||||||
|
|
||||||
|
Unit tests: |
||||||
|
----------- |
||||||
|
The file DotZLib/UnitTests.cs contains unit tests for use with NUnit 2.1 or higher. |
||||||
|
To include unit tests in the build, define nunit before building. |
||||||
|
|
||||||
|
|
||||||
|
Build instructions: |
||||||
|
------------------- |
||||||
|
|
||||||
|
1. Using Visual Studio.Net 2003: |
||||||
|
Open DotZLib.sln in VS.Net and build from there. Output file (DotZLib.dll) |
||||||
|
will be found ./DotZLib/bin/release or ./DotZLib/bin/debug, depending on |
||||||
|
you are building the release or debug version of the library. Check |
||||||
|
DotZLib/UnitTests.cs for instructions on how to include unit tests in the |
||||||
|
build. |
||||||
|
|
||||||
|
2. Using NAnt: |
||||||
|
Open a command prompt with access to the build environment and run nant |
||||||
|
in the same directory as the DotZLib.build file. |
||||||
|
You can define 2 properties on the nant command-line to control the build: |
||||||
|
debug={true|false} to toggle between release/debug builds (default=true). |
||||||
|
nunit={true|false} to include or esclude unit tests (default=true). |
||||||
|
Also the target clean will remove binaries. |
||||||
|
Output file (DotZLib.dll) will be found in either ./DotZLib/bin/release |
||||||
|
or ./DotZLib/bin/debug, depending on whether you are building the release |
||||||
|
or debug version of the library. |
||||||
|
|
||||||
|
Examples: |
||||||
|
nant -D:debug=false -D:nunit=false |
||||||
|
will build a release mode version of the library without unit tests. |
||||||
|
nant |
||||||
|
will build a debug version of the library with unit tests |
||||||
|
nant clean |
||||||
|
will remove all previously built files. |
||||||
|
|
||||||
|
|
||||||
|
--------------------------------- |
||||||
|
Copyright (c) Henrik Ravn 2004 |
||||||
|
|
||||||
|
Use, modification and distribution are subject to the Boost Software License, Version 1.0. |
||||||
|
(See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) |
@ -1,3 +1,3 @@ |
|||||||
This directory contains files that have not been updated for zlib 1.2.1 |
This directory contains files that have not been updated for zlib 1.2.x |
||||||
|
|
||||||
(Volunteers are encouraged to help clean this up. Thanks.) |
(Volunteers are encouraged to help clean this up. Thanks.) |
||||||
|
@ -0,0 +1,3 @@ |
|||||||
|
|
||||||
|
To build zlib using the Microsoft Visual C++ environment, |
||||||
|
use the appropriate project from the projects/ directory. |
Loading…
Reference in new issue