summaryrefslogtreecommitdiff
path: root/contrib/dotzlib/DotZLib
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/dotzlib/DotZLib')
-rw-r--r--contrib/dotzlib/DotZLib/AssemblyInfo.cs58
-rw-r--r--contrib/dotzlib/DotZLib/ChecksumImpl.cs202
-rw-r--r--contrib/dotzlib/DotZLib/CircularBuffer.cs83
-rw-r--r--contrib/dotzlib/DotZLib/CodecBase.cs198
-rw-r--r--contrib/dotzlib/DotZLib/Deflater.cs106
-rw-r--r--contrib/dotzlib/DotZLib/DotZLib.cs288
-rw-r--r--contrib/dotzlib/DotZLib/DotZLib.csproj141
-rw-r--r--contrib/dotzlib/DotZLib/GZipStream.cs301
-rw-r--r--contrib/dotzlib/DotZLib/Inflater.cs105
-rw-r--r--contrib/dotzlib/DotZLib/UnitTests.cs274
10 files changed, 1756 insertions, 0 deletions
diff --git a/contrib/dotzlib/DotZLib/AssemblyInfo.cs b/contrib/dotzlib/DotZLib/AssemblyInfo.cs
new file mode 100644
index 0000000..6fc0fdc
--- /dev/null
+++ b/contrib/dotzlib/DotZLib/AssemblyInfo.cs
@@ -0,0 +1,58 @@
1using System.Reflection;
2using System.Runtime.CompilerServices;
3
4//
5// General Information about an assembly is controlled through the following
6// set of attributes. Change these attribute values to modify the information
7// associated with an assembly.
8//
9[assembly: AssemblyTitle("DotZLib")]
10[assembly: AssemblyDescription(".Net bindings for ZLib compression dll 1.2.x")]
11[assembly: AssemblyConfiguration("")]
12[assembly: AssemblyCompany("Henrik Ravn")]
13[assembly: AssemblyProduct("")]
14[assembly: AssemblyCopyright("(c) 2004 by Henrik Ravn")]
15[assembly: AssemblyTrademark("")]
16[assembly: AssemblyCulture("")]
17
18//
19// Version information for an assembly consists of the following four values:
20//
21// Major Version
22// Minor Version
23// Build Number
24// Revision
25//
26// You can specify all the values or you can default the Revision and Build Numbers
27// by using the '*' as shown below:
28
29[assembly: AssemblyVersion("1.0.*")]
30
31//
32// In order to sign your assembly you must specify a key to use. Refer to the
33// Microsoft .NET Framework documentation for more information on assembly signing.
34//
35// Use the attributes below to control which key is used for signing.
36//
37// Notes:
38// (*) If no key is specified, the assembly is not signed.
39// (*) KeyName refers to a key that has been installed in the Crypto Service
40// Provider (CSP) on your machine. KeyFile refers to a file which contains
41// a key.
42// (*) If the KeyFile and the KeyName values are both specified, the
43// following processing occurs:
44// (1) If the KeyName can be found in the CSP, that key is used.
45// (2) If the KeyName does not exist and the KeyFile does exist, the key
46// in the KeyFile is installed into the CSP and used.
47// (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility.
48// When specifying the KeyFile, the location of the KeyFile should be
49// relative to the project output directory which is
50// %Project Directory%\obj\<configuration>. For example, if your KeyFile is
51// located in the project directory, you would specify the AssemblyKeyFile
52// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]
53// (*) Delay Signing is an advanced option - see the Microsoft .NET Framework
54// documentation for more information on this.
55//
56[assembly: AssemblyDelaySign(false)]
57[assembly: AssemblyKeyFile("")]
58[assembly: AssemblyKeyName("")]
diff --git a/contrib/dotzlib/DotZLib/ChecksumImpl.cs b/contrib/dotzlib/DotZLib/ChecksumImpl.cs
new file mode 100644
index 0000000..dfe7e90
--- /dev/null
+++ b/contrib/dotzlib/DotZLib/ChecksumImpl.cs
@@ -0,0 +1,202 @@
1//
2// © Copyright Henrik Ravn 2004
3//
4// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8using System;
9using System.Runtime.InteropServices;
10using System.Text;
11
12
13namespace DotZLib
14{
15 #region ChecksumGeneratorBase
16 /// <summary>
17 /// Implements the common functionality needed for all <see cref="ChecksumGenerator"/>s
18 /// </summary>
19 /// <example></example>
20 public abstract class ChecksumGeneratorBase : ChecksumGenerator
21 {
22 /// <summary>
23 /// The value of the current checksum
24 /// </summary>
25 protected uint _current;
26
27 /// <summary>
28 /// Initializes a new instance of the checksum generator base - the current checksum is
29 /// set to zero
30 /// </summary>
31 public ChecksumGeneratorBase()
32 {
33 _current = 0;
34 }
35
36 /// <summary>
37 /// Initializes a new instance of the checksum generator basewith a specified value
38 /// </summary>
39 /// <param name="initialValue">The value to set the current checksum to</param>
40 public ChecksumGeneratorBase(uint initialValue)
41 {
42 _current = initialValue;
43 }
44
45 /// <summary>
46 /// Resets the current checksum to zero
47 /// </summary>
48 public void Reset() { _current = 0; }
49
50 /// <summary>
51 /// Gets the current checksum value
52 /// </summary>
53 public uint Value { get { return _current; } }
54
55 /// <summary>
56 /// Updates the current checksum with part of an array of bytes
57 /// </summary>
58 /// <param name="data">The data to update the checksum with</param>
59 /// <param name="offset">Where in <c>data</c> to start updating</param>
60 /// <param name="count">The number of bytes from <c>data</c> to use</param>
61 /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
62 /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
63 /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
64 /// <remarks>All the other <c>Update</c> methods are implmeneted in terms of this one.
65 /// This is therefore the only method a derived class has to implement</remarks>
66 public abstract void Update(byte[] data, int offset, int count);
67
68 /// <summary>
69 /// Updates the current checksum with an array of bytes.
70 /// </summary>
71 /// <param name="data">The data to update the checksum with</param>
72 public void Update(byte[] data)
73 {
74 Update(data, 0, data.Length);
75 }
76
77 /// <summary>
78 /// Updates the current checksum with the data from a string
79 /// </summary>
80 /// <param name="data">The string to update the checksum with</param>
81 /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
82 public void Update(string data)
83 {
84 Update(Encoding.UTF8.GetBytes(data));
85 }
86
87 /// <summary>
88 /// Updates the current checksum with the data from a string, using a specific encoding
89 /// </summary>
90 /// <param name="data">The string to update the checksum with</param>
91 /// <param name="encoding">The encoding to use</param>
92 public void Update(string data, Encoding encoding)
93 {
94 Update(encoding.GetBytes(data));
95 }
96
97 }
98 #endregion
99
100 #region CRC32
101 /// <summary>
102 /// Implements a CRC32 checksum generator
103 /// </summary>
104 public sealed class CRC32Checksum : ChecksumGeneratorBase
105 {
106 #region DLL imports
107
108 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
109 private static extern uint crc32(uint crc, int data, uint length);
110
111 #endregion
112
113 /// <summary>
114 /// Initializes a new instance of the CRC32 checksum generator
115 /// </summary>
116 public CRC32Checksum() : base() {}
117
118 /// <summary>
119 /// Initializes a new instance of the CRC32 checksum generator with a specified value
120 /// </summary>
121 /// <param name="initialValue">The value to set the current checksum to</param>
122 public CRC32Checksum(uint initialValue) : base(initialValue) {}
123
124 /// <summary>
125 /// Updates the current checksum with part of an array of bytes
126 /// </summary>
127 /// <param name="data">The data to update the checksum with</param>
128 /// <param name="offset">Where in <c>data</c> to start updating</param>
129 /// <param name="count">The number of bytes from <c>data</c> to use</param>
130 /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
131 /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
132 /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
133 public override void Update(byte[] data, int offset, int count)
134 {
135 if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
136 if ((offset+count) > data.Length) throw new ArgumentException();
137 GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
138 try
139 {
140 _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
141 }
142 finally
143 {
144 hData.Free();
145 }
146 }
147
148 }
149 #endregion
150
151 #region Adler
152 /// <summary>
153 /// Implements a checksum generator that computes the Adler checksum on data
154 /// </summary>
155 public sealed class AdlerChecksum : ChecksumGeneratorBase
156 {
157 #region DLL imports
158
159 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
160 private static extern uint adler32(uint adler, int data, uint length);
161
162 #endregion
163
164 /// <summary>
165 /// Initializes a new instance of the Adler checksum generator
166 /// </summary>
167 public AdlerChecksum() : base() {}
168
169 /// <summary>
170 /// Initializes a new instance of the Adler checksum generator with a specified value
171 /// </summary>
172 /// <param name="initialValue">The value to set the current checksum to</param>
173 public AdlerChecksum(uint initialValue) : base(initialValue) {}
174
175 /// <summary>
176 /// Updates the current checksum with part of an array of bytes
177 /// </summary>
178 /// <param name="data">The data to update the checksum with</param>
179 /// <param name="offset">Where in <c>data</c> to start updating</param>
180 /// <param name="count">The number of bytes from <c>data</c> to use</param>
181 /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
182 /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
183 /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
184 public override void Update(byte[] data, int offset, int count)
185 {
186 if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
187 if ((offset+count) > data.Length) throw new ArgumentException();
188 GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
189 try
190 {
191 _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
192 }
193 finally
194 {
195 hData.Free();
196 }
197 }
198
199 }
200 #endregion
201
202} \ No newline at end of file
diff --git a/contrib/dotzlib/DotZLib/CircularBuffer.cs b/contrib/dotzlib/DotZLib/CircularBuffer.cs
new file mode 100644
index 0000000..16997e9
--- /dev/null
+++ b/contrib/dotzlib/DotZLib/CircularBuffer.cs
@@ -0,0 +1,83 @@
1//
2// © Copyright Henrik Ravn 2004
3//
4// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8using System;
9using System.Diagnostics;
10
11namespace DotZLib
12{
13
14 /// <summary>
15 /// This class implements a circular buffer
16 /// </summary>
17 internal class CircularBuffer
18 {
19 #region Private data
20 private int _capacity;
21 private int _head;
22 private int _tail;
23 private int _size;
24 private byte[] _buffer;
25 #endregion
26
27 public CircularBuffer(int capacity)
28 {
29 Debug.Assert( capacity > 0 );
30 _buffer = new byte[capacity];
31 _capacity = capacity;
32 _head = 0;
33 _tail = 0;
34 _size = 0;
35 }
36
37 public int Size { get { return _size; } }
38
39 public int Put(byte[] source, int offset, int count)
40 {
41 Debug.Assert( count > 0 );
42 int trueCount = Math.Min(count, _capacity - Size);
43 for (int i = 0; i < trueCount; ++i)
44 _buffer[(_tail+i) % _capacity] = source[offset+i];
45 _tail += trueCount;
46 _tail %= _capacity;
47 _size += trueCount;
48 return trueCount;
49 }
50
51 public bool Put(byte b)
52 {
53 if (Size == _capacity) // no room
54 return false;
55 _buffer[_tail++] = b;
56 _tail %= _capacity;
57 ++_size;
58 return true;
59 }
60
61 public int Get(byte[] destination, int offset, int count)
62 {
63 int trueCount = Math.Min(count,Size);
64 for (int i = 0; i < trueCount; ++i)
65 destination[offset + i] = _buffer[(_head+i) % _capacity];
66 _head += trueCount;
67 _head %= _capacity;
68 _size -= trueCount;
69 return trueCount;
70 }
71
72 public int Get()
73 {
74 if (Size == 0)
75 return -1;
76
77 int result = (int)_buffer[_head++ % _capacity];
78 --_size;
79 return result;
80 }
81
82 }
83}
diff --git a/contrib/dotzlib/DotZLib/CodecBase.cs b/contrib/dotzlib/DotZLib/CodecBase.cs
new file mode 100644
index 0000000..954db7d
--- /dev/null
+++ b/contrib/dotzlib/DotZLib/CodecBase.cs
@@ -0,0 +1,198 @@
1//
2// © Copyright Henrik Ravn 2004
3//
4// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8using System;
9using System.Runtime.InteropServices;
10
11namespace DotZLib
12{
13 /// <summary>
14 /// Implements the common functionality needed for all <see cref="Codec"/>s
15 /// </summary>
16 public abstract class CodecBase : Codec, IDisposable
17 {
18
19 #region Data members
20
21 /// <summary>
22 /// Instance of the internal zlib buffer structure that is
23 /// passed to all functions in the zlib dll
24 /// </summary>
25 internal ZStream _ztream = new ZStream();
26
27 /// <summary>
28 /// True if the object instance has been disposed, false otherwise
29 /// </summary>
30 protected bool _isDisposed = false;
31
32 /// <summary>
33 /// The size of the internal buffers
34 /// </summary>
35 protected const int kBufferSize = 16384;
36
37 private byte[] _outBuffer = new byte[kBufferSize];
38 private byte[] _inBuffer = new byte[kBufferSize];
39
40 private GCHandle _hInput;
41 private GCHandle _hOutput;
42
43 private uint _checksum = 0;
44
45 #endregion
46
47 /// <summary>
48 /// Initializes a new instance of the <c>CodeBase</c> class.
49 /// </summary>
50 public CodecBase()
51 {
52 try
53 {
54 _hInput = GCHandle.Alloc(_inBuffer, GCHandleType.Pinned);
55 _hOutput = GCHandle.Alloc(_outBuffer, GCHandleType.Pinned);
56 }
57 catch (Exception)
58 {
59 CleanUp(false);
60 throw;
61 }
62 }
63
64
65 #region Codec Members
66
67 /// <summary>
68 /// Occurs when more processed data are available.
69 /// </summary>
70 public event DataAvailableHandler DataAvailable;
71
72 /// <summary>
73 /// Fires the <see cref="DataAvailable"/> event
74 /// </summary>
75 protected void OnDataAvailable()
76 {
77 if (_ztream.total_out > 0)
78 {
79 if (DataAvailable != null)
80 DataAvailable( _outBuffer, 0, (int)_ztream.total_out);
81 resetOutput();
82 }
83 }
84
85 /// <summary>
86 /// Adds more data to the codec to be processed.
87 /// </summary>
88 /// <param name="data">Byte array containing the data to be added to the codec</param>
89 /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
90 public void Add(byte[] data)
91 {
92 Add(data,0,data.Length);
93 }
94
95 /// <summary>
96 /// Adds more data to the codec to be processed.
97 /// </summary>
98 /// <param name="data">Byte array containing the data to be added to the codec</param>
99 /// <param name="offset">The index of the first byte to add from <c>data</c></param>
100 /// <param name="count">The number of bytes to add</param>
101 /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
102 /// <remarks>This must be implemented by a derived class</remarks>
103 public abstract void Add(byte[] data, int offset, int count);
104
105 /// <summary>
106 /// Finishes up any pending data that needs to be processed and handled.
107 /// </summary>
108 /// <remarks>This must be implemented by a derived class</remarks>
109 public abstract void Finish();
110
111 /// <summary>
112 /// Gets the checksum of the data that has been added so far
113 /// </summary>
114 public uint Checksum { get { return _checksum; } }
115
116 #endregion
117
118 #region Destructor & IDisposable stuff
119
120 /// <summary>
121 /// Destroys this instance
122 /// </summary>
123 ~CodecBase()
124 {
125 CleanUp(false);
126 }
127
128 /// <summary>
129 /// Releases any unmanaged resources and calls the <see cref="CleanUp()"/> method of the derived class
130 /// </summary>
131 public void Dispose()
132 {
133 CleanUp(true);
134 }
135
136 /// <summary>
137 /// Performs any codec specific cleanup
138 /// </summary>
139 /// <remarks>This must be implemented by a derived class</remarks>
140 protected abstract void CleanUp();
141
142 // performs the release of the handles and calls the dereived CleanUp()
143 private void CleanUp(bool isDisposing)
144 {
145 if (!_isDisposed)
146 {
147 CleanUp();
148 if (_hInput.IsAllocated)
149 _hInput.Free();
150 if (_hOutput.IsAllocated)
151 _hOutput.Free();
152
153 _isDisposed = true;
154 }
155 }
156
157
158 #endregion
159
160 #region Helper methods
161
162 /// <summary>
163 /// Copies a number of bytes to the internal codec buffer - ready for proccesing
164 /// </summary>
165 /// <param name="data">The byte array that contains the data to copy</param>
166 /// <param name="startIndex">The index of the first byte to copy</param>
167 /// <param name="count">The number of bytes to copy from <c>data</c></param>
168 protected void copyInput(byte[] data, int startIndex, int count)
169 {
170 Array.Copy(data, startIndex, _inBuffer,0, count);
171 _ztream.next_in = _hInput.AddrOfPinnedObject();
172 _ztream.total_in = 0;
173 _ztream.avail_in = (uint)count;
174
175 }
176
177 /// <summary>
178 /// Resets the internal output buffers to a known state - ready for processing
179 /// </summary>
180 protected void resetOutput()
181 {
182 _ztream.total_out = 0;
183 _ztream.avail_out = kBufferSize;
184 _ztream.next_out = _hOutput.AddrOfPinnedObject();
185 }
186
187 /// <summary>
188 /// Updates the running checksum property
189 /// </summary>
190 /// <param name="newSum">The new checksum value</param>
191 protected void setChecksum(uint newSum)
192 {
193 _checksum = newSum;
194 }
195 #endregion
196
197 }
198}
diff --git a/contrib/dotzlib/DotZLib/Deflater.cs b/contrib/dotzlib/DotZLib/Deflater.cs
new file mode 100644
index 0000000..d7b8dcc
--- /dev/null
+++ b/contrib/dotzlib/DotZLib/Deflater.cs
@@ -0,0 +1,106 @@
1//
2// © Copyright Henrik Ravn 2004
3//
4// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8using System;
9using System.Diagnostics;
10using System.Runtime.InteropServices;
11
12namespace DotZLib
13{
14
15 /// <summary>
16 /// Implements a data compressor, using the deflate algorithm in the ZLib dll
17 /// </summary>
18 public sealed class Deflater : CodecBase
19 {
20 #region Dll imports
21 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
22 private static extern int deflateInit_(ref ZStream sz, int level, string vs, int size);
23
24 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
25 private static extern int deflate(ref ZStream sz, int flush);
26
27 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
28 private static extern int deflateReset(ref ZStream sz);
29
30 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
31 private static extern int deflateEnd(ref ZStream sz);
32 #endregion
33
34 /// <summary>
35 /// Constructs an new instance of the <c>Deflater</c>
36 /// </summary>
37 /// <param name="level">The compression level to use for this <c>Deflater</c></param>
38 public Deflater(CompressLevel level) : base()
39 {
40 int retval = deflateInit_(ref _ztream, (int)level, Info.Version, Marshal.SizeOf(_ztream));
41 if (retval != 0)
42 throw new ZLibException(retval, "Could not initialize deflater");
43
44 resetOutput();
45 }
46
47 /// <summary>
48 /// Adds more data to the codec to be processed.
49 /// </summary>
50 /// <param name="data">Byte array containing the data to be added to the codec</param>
51 /// <param name="offset">The index of the first byte to add from <c>data</c></param>
52 /// <param name="count">The number of bytes to add</param>
53 /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
54 public override void Add(byte[] data, int offset, int count)
55 {
56 if (data == null) throw new ArgumentNullException();
57 if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
58 if ((offset+count) > data.Length) throw new ArgumentException();
59
60 int total = count;
61 int inputIndex = offset;
62 int err = 0;
63
64 while (err >= 0 && inputIndex < total)
65 {
66 copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
67 while (err >= 0 && _ztream.avail_in > 0)
68 {
69 err = deflate(ref _ztream, (int)FlushTypes.None);
70 if (err == 0)
71 while (_ztream.avail_out == 0)
72 {
73 OnDataAvailable();
74 err = deflate(ref _ztream, (int)FlushTypes.None);
75 }
76 inputIndex += (int)_ztream.total_in;
77 }
78 }
79 setChecksum( _ztream.adler );
80 }
81
82
83 /// <summary>
84 /// Finishes up any pending data that needs to be processed and handled.
85 /// </summary>
86 public override void Finish()
87 {
88 int err;
89 do
90 {
91 err = deflate(ref _ztream, (int)FlushTypes.Finish);
92 OnDataAvailable();
93 }
94 while (err == 0);
95 setChecksum( _ztream.adler );
96 deflateReset(ref _ztream);
97 resetOutput();
98 }
99
100 /// <summary>
101 /// Closes the internal zlib deflate stream
102 /// </summary>
103 protected override void CleanUp() { deflateEnd(ref _ztream); }
104
105 }
106}
diff --git a/contrib/dotzlib/DotZLib/DotZLib.cs b/contrib/dotzlib/DotZLib/DotZLib.cs
new file mode 100644
index 0000000..410deb0
--- /dev/null
+++ b/contrib/dotzlib/DotZLib/DotZLib.cs
@@ -0,0 +1,288 @@
1//
2// © Copyright Henrik Ravn 2004
3//
4// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8using System;
9using System.IO;
10using System.Runtime.InteropServices;
11using System.Text;
12
13
14namespace DotZLib
15{
16
17 #region Internal types
18
19 /// <summary>
20 /// Defines constants for the various flush types used with zlib
21 /// </summary>
22 internal enum FlushTypes
23 {
24 None, Partial, Sync, Full, Finish, Block
25 }
26
27 #region ZStream structure
28 // internal mapping of the zlib zstream structure for marshalling
29 [StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0, CharSet=CharSet.Ansi)]
30 internal struct ZStream
31 {
32 public IntPtr next_in;
33 public uint avail_in;
34 public uint total_in;
35
36 public IntPtr next_out;
37 public uint avail_out;
38 public uint total_out;
39
40 [MarshalAs(UnmanagedType.LPStr)]
41 string msg;
42 uint state;
43
44 uint zalloc;
45 uint zfree;
46 uint opaque;
47
48 int data_type;
49 public uint adler;
50 uint reserved;
51 }
52
53 #endregion
54
55 #endregion
56
57 #region Public enums
58 /// <summary>
59 /// Defines constants for the available compression levels in zlib
60 /// </summary>
61 public enum CompressLevel : int
62 {
63 /// <summary>
64 /// The default compression level with a reasonable compromise between compression and speed
65 /// </summary>
66 Default = -1,
67 /// <summary>
68 /// No compression at all. The data are passed straight through.
69 /// </summary>
70 None = 0,
71 /// <summary>
72 /// The maximum compression rate available.
73 /// </summary>
74 Best = 9,
75 /// <summary>
76 /// The fastest available compression level.
77 /// </summary>
78 Fastest = 1
79 }
80 #endregion
81
82 #region Exception classes
83 /// <summary>
84 /// The exception that is thrown when an error occurs on the zlib dll
85 /// </summary>
86 public class ZLibException : ApplicationException
87 {
88 /// <summary>
89 /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
90 /// error message and error code
91 /// </summary>
92 /// <param name="errorCode">The zlib error code that caused the exception</param>
93 /// <param name="msg">A message that (hopefully) describes the error</param>
94 public ZLibException(int errorCode, string msg) : base(String.Format("ZLib error {0} {1}", errorCode, msg))
95 {
96 }
97
98 /// <summary>
99 /// Initializes a new instance of the <see cref="ZLibException"/> class with a specified
100 /// error code
101 /// </summary>
102 /// <param name="errorCode">The zlib error code that caused the exception</param>
103 public ZLibException(int errorCode) : base(String.Format("ZLib error {0}", errorCode))
104 {
105 }
106 }
107 #endregion
108
109 #region Interfaces
110
111 /// <summary>
112 /// Declares methods and properties that enables a running checksum to be calculated
113 /// </summary>
114 public interface ChecksumGenerator
115 {
116 /// <summary>
117 /// Gets the current value of the checksum
118 /// </summary>
119 uint Value { get; }
120
121 /// <summary>
122 /// Clears the current checksum to 0
123 /// </summary>
124 void Reset();
125
126 /// <summary>
127 /// Updates the current checksum with an array of bytes
128 /// </summary>
129 /// <param name="data">The data to update the checksum with</param>
130 void Update(byte[] data);
131
132 /// <summary>
133 /// Updates the current checksum with part of an array of bytes
134 /// </summary>
135 /// <param name="data">The data to update the checksum with</param>
136 /// <param name="offset">Where in <c>data</c> to start updating</param>
137 /// <param name="count">The number of bytes from <c>data</c> to use</param>
138 /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
139 /// <exception cref="ArgumentNullException"><c>data</c> is a null reference</exception>
140 /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
141 void Update(byte[] data, int offset, int count);
142
143 /// <summary>
144 /// Updates the current checksum with the data from a string
145 /// </summary>
146 /// <param name="data">The string to update the checksum with</param>
147 /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
148 void Update(string data);
149
150 /// <summary>
151 /// Updates the current checksum with the data from a string, using a specific encoding
152 /// </summary>
153 /// <param name="data">The string to update the checksum with</param>
154 /// <param name="encoding">The encoding to use</param>
155 void Update(string data, Encoding encoding);
156 }
157
158
159 /// <summary>
160 /// Represents the method that will be called from a codec when new data
161 /// are available.
162 /// </summary>
163 /// <paramref name="data">The byte array containing the processed data</paramref>
164 /// <paramref name="startIndex">The index of the first processed byte in <c>data</c></paramref>
165 /// <paramref name="count">The number of processed bytes available</paramref>
166 /// <remarks>On return from this method, the data may be overwritten, so grab it while you can.
167 /// You cannot assume that startIndex will be zero.
168 /// </remarks>
169 public delegate void DataAvailableHandler(byte[] data, int startIndex, int count);
170
171 /// <summary>
172 /// Declares methods and events for implementing compressors/decompressors
173 /// </summary>
174 public interface Codec
175 {
176 /// <summary>
177 /// Occurs when more processed data are available.
178 /// </summary>
179 event DataAvailableHandler DataAvailable;
180
181 /// <summary>
182 /// Adds more data to the codec to be processed.
183 /// </summary>
184 /// <param name="data">Byte array containing the data to be added to the codec</param>
185 /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
186 void Add(byte[] data);
187
188 /// <summary>
189 /// Adds more data to the codec to be processed.
190 /// </summary>
191 /// <param name="data">Byte array containing the data to be added to the codec</param>
192 /// <param name="offset">The index of the first byte to add from <c>data</c></param>
193 /// <param name="count">The number of bytes to add</param>
194 /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
195 void Add(byte[] data, int offset, int count);
196
197 /// <summary>
198 /// Finishes up any pending data that needs to be processed and handled.
199 /// </summary>
200 void Finish();
201
202 /// <summary>
203 /// Gets the checksum of the data that has been added so far
204 /// </summary>
205 uint Checksum { get; }
206
207
208 }
209
210 #endregion
211
212 #region Classes
213 /// <summary>
214 /// Encapsulates general information about the ZLib library
215 /// </summary>
216 public class Info
217 {
218 #region DLL imports
219 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
220 private static extern uint zlibCompileFlags();
221
222 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
223 private static extern string zlibVersion();
224 #endregion
225
226 #region Private stuff
227 private uint _flags;
228
229 // helper function that unpacks a bitsize mask
230 private static int bitSize(uint bits)
231 {
232 switch (bits)
233 {
234 case 0: return 16;
235 case 1: return 32;
236 case 2: return 64;
237 }
238 return -1;
239 }
240 #endregion
241
242 /// <summary>
243 /// Constructs an instance of the <c>Info</c> class.
244 /// </summary>
245 public Info()
246 {
247 _flags = zlibCompileFlags();
248 }
249
250 /// <summary>
251 /// True if the library is compiled with debug info
252 /// </summary>
253 public bool HasDebugInfo { get { return 0 != (_flags & 0x100); } }
254
255 /// <summary>
256 /// True if the library is compiled with assembly optimizations
257 /// </summary>
258 public bool UsesAssemblyCode { get { return 0 != (_flags & 0x200); } }
259
260 /// <summary>
261 /// Gets the size of the unsigned int that was compiled into Zlib
262 /// </summary>
263 public int SizeOfUInt { get { return bitSize(_flags & 3); } }
264
265 /// <summary>
266 /// Gets the size of the unsigned long that was compiled into Zlib
267 /// </summary>
268 public int SizeOfULong { get { return bitSize((_flags >> 2) & 3); } }
269
270 /// <summary>
271 /// Gets the size of the pointers that were compiled into Zlib
272 /// </summary>
273 public int SizeOfPointer { get { return bitSize((_flags >> 4) & 3); } }
274
275 /// <summary>
276 /// Gets the size of the z_off_t type that was compiled into Zlib
277 /// </summary>
278 public int SizeOfOffset { get { return bitSize((_flags >> 6) & 3); } }
279
280 /// <summary>
281 /// Gets the version of ZLib as a string, e.g. "1.2.1"
282 /// </summary>
283 public static string Version { get { return zlibVersion(); } }
284 }
285
286 #endregion
287
288}
diff --git a/contrib/dotzlib/DotZLib/DotZLib.csproj b/contrib/dotzlib/DotZLib/DotZLib.csproj
new file mode 100644
index 0000000..71eeb85
--- /dev/null
+++ b/contrib/dotzlib/DotZLib/DotZLib.csproj
@@ -0,0 +1,141 @@
1<VisualStudioProject>
2 <CSHARP
3 ProjectType = "Local"
4 ProductVersion = "7.10.3077"
5 SchemaVersion = "2.0"
6 ProjectGuid = "{BB1EE0B1-1808-46CB-B786-949D91117FC5}"
7 >
8 <Build>
9 <Settings
10 ApplicationIcon = ""
11 AssemblyKeyContainerName = ""
12 AssemblyName = "DotZLib"
13 AssemblyOriginatorKeyFile = ""
14 DefaultClientScript = "JScript"
15 DefaultHTMLPageLayout = "Grid"
16 DefaultTargetSchema = "IE50"
17 DelaySign = "false"
18 OutputType = "Library"
19 PreBuildEvent = ""
20 PostBuildEvent = ""
21 RootNamespace = "DotZLib"
22 RunPostBuildEvent = "OnBuildSuccess"
23 StartupObject = ""
24 >
25 <Config
26 Name = "Debug"
27 AllowUnsafeBlocks = "false"
28 BaseAddress = "285212672"
29 CheckForOverflowUnderflow = "false"
30 ConfigurationOverrideFile = ""
31 DefineConstants = "DEBUG;TRACE"
32 DocumentationFile = "docs\DotZLib.xml"
33 DebugSymbols = "true"
34 FileAlignment = "4096"
35 IncrementalBuild = "false"
36 NoStdLib = "false"
37 NoWarn = "1591"
38 Optimize = "false"
39 OutputPath = "bin\Debug\"
40 RegisterForComInterop = "false"
41 RemoveIntegerChecks = "false"
42 TreatWarningsAsErrors = "false"
43 WarningLevel = "4"
44 />
45 <Config
46 Name = "Release"
47 AllowUnsafeBlocks = "false"
48 BaseAddress = "285212672"
49 CheckForOverflowUnderflow = "false"
50 ConfigurationOverrideFile = ""
51 DefineConstants = "TRACE"
52 DocumentationFile = "docs\DotZLib.xml"
53 DebugSymbols = "false"
54 FileAlignment = "4096"
55 IncrementalBuild = "false"
56 NoStdLib = "false"
57 NoWarn = ""
58 Optimize = "true"
59 OutputPath = "bin\Release\"
60 RegisterForComInterop = "false"
61 RemoveIntegerChecks = "false"
62 TreatWarningsAsErrors = "false"
63 WarningLevel = "4"
64 />
65 </Settings>
66 <References>
67 <Reference
68 Name = "System"
69 AssemblyName = "System"
70 HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.dll"
71 />
72 <Reference
73 Name = "System.Data"
74 AssemblyName = "System.Data"
75 HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.Data.dll"
76 />
77 <Reference
78 Name = "System.XML"
79 AssemblyName = "System.Xml"
80 HintPath = "C:\WINNT\Microsoft.NET\Framework\v1.1.4322\System.XML.dll"
81 />
82 <Reference
83 Name = "nunit.framework"
84 AssemblyName = "nunit.framework"
85 HintPath = "E:\apps\NUnit V2.1\\bin\nunit.framework.dll"
86 AssemblyFolderKey = "hklm\dn\nunit.framework"
87 />
88 </References>
89 </Build>
90 <Files>
91 <Include>
92 <File
93 RelPath = "AssemblyInfo.cs"
94 SubType = "Code"
95 BuildAction = "Compile"
96 />
97 <File
98 RelPath = "ChecksumImpl.cs"
99 SubType = "Code"
100 BuildAction = "Compile"
101 />
102 <File
103 RelPath = "CircularBuffer.cs"
104 SubType = "Code"
105 BuildAction = "Compile"
106 />
107 <File
108 RelPath = "CodecBase.cs"
109 SubType = "Code"
110 BuildAction = "Compile"
111 />
112 <File
113 RelPath = "Deflater.cs"
114 SubType = "Code"
115 BuildAction = "Compile"
116 />
117 <File
118 RelPath = "DotZLib.cs"
119 SubType = "Code"
120 BuildAction = "Compile"
121 />
122 <File
123 RelPath = "GZipStream.cs"
124 SubType = "Code"
125 BuildAction = "Compile"
126 />
127 <File
128 RelPath = "Inflater.cs"
129 SubType = "Code"
130 BuildAction = "Compile"
131 />
132 <File
133 RelPath = "UnitTests.cs"
134 SubType = "Code"
135 BuildAction = "Compile"
136 />
137 </Include>
138 </Files>
139 </CSHARP>
140</VisualStudioProject>
141
diff --git a/contrib/dotzlib/DotZLib/GZipStream.cs b/contrib/dotzlib/DotZLib/GZipStream.cs
new file mode 100644
index 0000000..f861675
--- /dev/null
+++ b/contrib/dotzlib/DotZLib/GZipStream.cs
@@ -0,0 +1,301 @@
1//
2// © Copyright Henrik Ravn 2004
3//
4// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8using System;
9using System.IO;
10using System.Runtime.InteropServices;
11
12namespace DotZLib
13{
14 /// <summary>
15 /// Implements a compressed <see cref="Stream"/>, in GZip (.gz) format.
16 /// </summary>
17 public class GZipStream : Stream, IDisposable
18 {
19 #region Dll Imports
20 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
21 private static extern IntPtr gzopen(string name, string mode);
22
23 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
24 private static extern int gzclose(IntPtr gzFile);
25
26 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
27 private static extern int gzwrite(IntPtr gzFile, int data, int length);
28
29 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
30 private static extern int gzread(IntPtr gzFile, int data, int length);
31
32 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
33 private static extern int gzgetc(IntPtr gzFile);
34
35 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
36 private static extern int gzputc(IntPtr gzFile, int c);
37
38 #endregion
39
40 #region Private data
41 private IntPtr _gzFile;
42 private bool _isDisposed = false;
43 private bool _isWriting;
44 #endregion
45
46 #region Constructors
47 /// <summary>
48 /// Creates a new file as a writeable GZipStream
49 /// </summary>
50 /// <param name="fileName">The name of the compressed file to create</param>
51 /// <param name="level">The compression level to use when adding data</param>
52 /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
53 public GZipStream(string fileName, CompressLevel level)
54 {
55 _isWriting = true;
56 _gzFile = gzopen(fileName, String.Format("wb{0}", (int)level));
57 if (_gzFile == IntPtr.Zero)
58 throw new ZLibException(-1, "Could not open " + fileName);
59 }
60
61 /// <summary>
62 /// Opens an existing file as a readable GZipStream
63 /// </summary>
64 /// <param name="fileName">The name of the file to open</param>
65 /// <exception cref="ZLibException">If an error occurred in the internal zlib function</exception>
66 public GZipStream(string fileName)
67 {
68 _isWriting = false;
69 _gzFile = gzopen(fileName, "rb");
70 if (_gzFile == IntPtr.Zero)
71 throw new ZLibException(-1, "Could not open " + fileName);
72
73 }
74 #endregion
75
76 #region Access properties
77 /// <summary>
78 /// Returns true of this stream can be read from, false otherwise
79 /// </summary>
80 public override bool CanRead
81 {
82 get
83 {
84 return !_isWriting;
85 }
86 }
87
88
89 /// <summary>
90 /// Returns false.
91 /// </summary>
92 public override bool CanSeek
93 {
94 get
95 {
96 return false;
97 }
98 }
99
100 /// <summary>
101 /// Returns true if this tsream is writeable, false otherwise
102 /// </summary>
103 public override bool CanWrite
104 {
105 get
106 {
107 return _isWriting;
108 }
109 }
110 #endregion
111
112 #region Destructor & IDispose stuff
113
114 /// <summary>
115 /// Destroys this instance
116 /// </summary>
117 ~GZipStream()
118 {
119 cleanUp(false);
120 }
121
122 /// <summary>
123 /// Closes the external file handle
124 /// </summary>
125 public void Dispose()
126 {
127 cleanUp(true);
128 }
129
130 // Does the actual closing of the file handle.
131 private void cleanUp(bool isDisposing)
132 {
133 if (!_isDisposed)
134 {
135 gzclose(_gzFile);
136 _isDisposed = true;
137 }
138 }
139 #endregion
140
141 #region Basic reading and writing
142 /// <summary>
143 /// Attempts to read a number of bytes from the stream.
144 /// </summary>
145 /// <param name="buffer">The destination data buffer</param>
146 /// <param name="offset">The index of the first destination byte in <c>buffer</c></param>
147 /// <param name="count">The number of bytes requested</param>
148 /// <returns>The number of bytes read</returns>
149 /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
150 /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
151 /// <exception cref="ArgumentException">If <c>offset</c> + <c>count</c> is &gt; buffer.Length</exception>
152 /// <exception cref="NotSupportedException">If this stream is not readable.</exception>
153 /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
154 public override int Read(byte[] buffer, int offset, int count)
155 {
156 if (!CanRead) throw new NotSupportedException();
157 if (buffer == null) throw new ArgumentNullException();
158 if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
159 if ((offset+count) > buffer.Length) throw new ArgumentException();
160 if (_isDisposed) throw new ObjectDisposedException("GZipStream");
161
162 GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
163 int result;
164 try
165 {
166 result = gzread(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
167 if (result < 0)
168 throw new IOException();
169 }
170 finally
171 {
172 h.Free();
173 }
174 return result;
175 }
176
177 /// <summary>
178 /// Attempts to read a single byte from the stream.
179 /// </summary>
180 /// <returns>The byte that was read, or -1 in case of error or End-Of-File</returns>
181 public override int ReadByte()
182 {
183 if (!CanRead) throw new NotSupportedException();
184 if (_isDisposed) throw new ObjectDisposedException("GZipStream");
185 return gzgetc(_gzFile);
186 }
187
188 /// <summary>
189 /// Writes a number of bytes to the stream
190 /// </summary>
191 /// <param name="buffer"></param>
192 /// <param name="offset"></param>
193 /// <param name="count"></param>
194 /// <exception cref="ArgumentNullException">If <c>buffer</c> is null</exception>
195 /// <exception cref="ArgumentOutOfRangeException">If <c>count</c> or <c>offset</c> are negative</exception>
196 /// <exception cref="ArgumentException">If <c>offset</c> + <c>count</c> is &gt; buffer.Length</exception>
197 /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
198 /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
199 public override void Write(byte[] buffer, int offset, int count)
200 {
201 if (!CanWrite) throw new NotSupportedException();
202 if (buffer == null) throw new ArgumentNullException();
203 if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
204 if ((offset+count) > buffer.Length) throw new ArgumentException();
205 if (_isDisposed) throw new ObjectDisposedException("GZipStream");
206
207 GCHandle h = GCHandle.Alloc(buffer, GCHandleType.Pinned);
208 try
209 {
210 int result = gzwrite(_gzFile, h.AddrOfPinnedObject().ToInt32() + offset, count);
211 if (result < 0)
212 throw new IOException();
213 }
214 finally
215 {
216 h.Free();
217 }
218 }
219
220 /// <summary>
221 /// Writes a single byte to the stream
222 /// </summary>
223 /// <param name="value">The byte to add to the stream.</param>
224 /// <exception cref="NotSupportedException">If this stream is not writeable.</exception>
225 /// <exception cref="ObjectDisposedException">If this stream has been disposed.</exception>
226 public override void WriteByte(byte value)
227 {
228 if (!CanWrite) throw new NotSupportedException();
229 if (_isDisposed) throw new ObjectDisposedException("GZipStream");
230
231 int result = gzputc(_gzFile, (int)value);
232 if (result < 0)
233 throw new IOException();
234 }
235 #endregion
236
237 #region Position & length stuff
238 /// <summary>
239 /// Not supported.
240 /// </summary>
241 /// <param name="value"></param>
242 /// <exception cref="NotSupportedException">Always thrown</exception>
243 public override void SetLength(long value)
244 {
245 throw new NotSupportedException();
246 }
247
248 /// <summary>
249 /// Not suppported.
250 /// </summary>
251 /// <param name="offset"></param>
252 /// <param name="origin"></param>
253 /// <returns></returns>
254 /// <exception cref="NotSupportedException">Always thrown</exception>
255 public override long Seek(long offset, SeekOrigin origin)
256 {
257 throw new NotSupportedException();
258 }
259
260 /// <summary>
261 /// Flushes the <c>GZipStream</c>.
262 /// </summary>
263 /// <remarks>In this implementation, this method does nothing. This is because excessive
264 /// flushing may degrade the achievable compression rates.</remarks>
265 public override void Flush()
266 {
267 // left empty on purpose
268 }
269
270 /// <summary>
271 /// Gets/sets the current position in the <c>GZipStream</c>. Not suppported.
272 /// </summary>
273 /// <remarks>In this implementation this property is not supported</remarks>
274 /// <exception cref="NotSupportedException">Always thrown</exception>
275 public override long Position
276 {
277 get
278 {
279 throw new NotSupportedException();
280 }
281 set
282 {
283 throw new NotSupportedException();
284 }
285 }
286
287 /// <summary>
288 /// Gets the size of the stream. Not suppported.
289 /// </summary>
290 /// <remarks>In this implementation this property is not supported</remarks>
291 /// <exception cref="NotSupportedException">Always thrown</exception>
292 public override long Length
293 {
294 get
295 {
296 throw new NotSupportedException();
297 }
298 }
299 #endregion
300 }
301}
diff --git a/contrib/dotzlib/DotZLib/Inflater.cs b/contrib/dotzlib/DotZLib/Inflater.cs
new file mode 100644
index 0000000..4e60cda
--- /dev/null
+++ b/contrib/dotzlib/DotZLib/Inflater.cs
@@ -0,0 +1,105 @@
1//
2// © Copyright Henrik Ravn 2004
3//
4// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8using System;
9using System.Diagnostics;
10using System.Runtime.InteropServices;
11
12namespace DotZLib
13{
14
15 /// <summary>
16 /// Implements a data decompressor, using the inflate algorithm in the ZLib dll
17 /// </summary>
18 public class Inflater : CodecBase
19 {
20 #region Dll imports
21 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl, CharSet=CharSet.Ansi)]
22 private static extern int inflateInit_(ref ZStream sz, string vs, int size);
23
24 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
25 private static extern int inflate(ref ZStream sz, int flush);
26
27 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
28 private static extern int inflateReset(ref ZStream sz);
29
30 [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
31 private static extern int inflateEnd(ref ZStream sz);
32 #endregion
33
34 /// <summary>
35 /// Constructs an new instance of the <c>Inflater</c>
36 /// </summary>
37 public Inflater() : base()
38 {
39 int retval = inflateInit_(ref _ztream, Info.Version, Marshal.SizeOf(_ztream));
40 if (retval != 0)
41 throw new ZLibException(retval, "Could not initialize inflater");
42
43 resetOutput();
44 }
45
46
47 /// <summary>
48 /// Adds more data to the codec to be processed.
49 /// </summary>
50 /// <param name="data">Byte array containing the data to be added to the codec</param>
51 /// <param name="offset">The index of the first byte to add from <c>data</c></param>
52 /// <param name="count">The number of bytes to add</param>
53 /// <remarks>Adding data may, or may not, raise the <c>DataAvailable</c> event</remarks>
54 public override void Add(byte[] data, int offset, int count)
55 {
56 if (data == null) throw new ArgumentNullException();
57 if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
58 if ((offset+count) > data.Length) throw new ArgumentException();
59
60 int total = count;
61 int inputIndex = offset;
62 int err = 0;
63
64 while (err >= 0 && inputIndex < total)
65 {
66 copyInput(data, inputIndex, Math.Min(total - inputIndex, kBufferSize));
67 err = inflate(ref _ztream, (int)FlushTypes.None);
68 if (err == 0)
69 while (_ztream.avail_out == 0)
70 {
71 OnDataAvailable();
72 err = inflate(ref _ztream, (int)FlushTypes.None);
73 }
74
75 inputIndex += (int)_ztream.total_in;
76 }
77 setChecksum( _ztream.adler );
78 }
79
80
81 /// <summary>
82 /// Finishes up any pending data that needs to be processed and handled.
83 /// </summary>
84 public override void Finish()
85 {
86 int err;
87 do
88 {
89 err = inflate(ref _ztream, (int)FlushTypes.Finish);
90 OnDataAvailable();
91 }
92 while (err == 0);
93 setChecksum( _ztream.adler );
94 inflateReset(ref _ztream);
95 resetOutput();
96 }
97
98 /// <summary>
99 /// Closes the internal zlib inflate stream
100 /// </summary>
101 protected override void CleanUp() { inflateEnd(ref _ztream); }
102
103
104 }
105}
diff --git a/contrib/dotzlib/DotZLib/UnitTests.cs b/contrib/dotzlib/DotZLib/UnitTests.cs
new file mode 100644
index 0000000..2f374b6
--- /dev/null
+++ b/contrib/dotzlib/DotZLib/UnitTests.cs
@@ -0,0 +1,274 @@
1//
2// © Copyright Henrik Ravn 2004
3//
4// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
5// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6//
7
8using System;
9using System.Collections;
10using System.IO;
11
12// uncomment the define below to include unit tests
13//#define nunit
14#if nunit
15using NUnit.Framework;
16
17// Unit tests for the DotZLib class library
18// ----------------------------------------
19//
20// Use this with NUnit 2 from http://www.nunit.org
21//
22
23namespace DotZLibTests
24{
25 using DotZLib;
26
27 // helper methods
28 internal class Utils
29 {
30 public static bool byteArrEqual( byte[] lhs, byte[] rhs )
31 {
32 if (lhs.Length != rhs.Length)
33 return false;
34 for (int i = lhs.Length-1; i >= 0; --i)
35 if (lhs[i] != rhs[i])
36 return false;
37 return true;
38 }
39
40 }
41
42
43 [TestFixture]
44 public class CircBufferTests
45 {
46 #region Circular buffer tests
47 [Test]
48 public void SinglePutGet()
49 {
50 CircularBuffer buf = new CircularBuffer(10);
51 Assert.AreEqual( 0, buf.Size );
52 Assert.AreEqual( -1, buf.Get() );
53
54 Assert.IsTrue(buf.Put( 1 ));
55 Assert.AreEqual( 1, buf.Size );
56 Assert.AreEqual( 1, buf.Get() );
57 Assert.AreEqual( 0, buf.Size );
58 Assert.AreEqual( -1, buf.Get() );
59 }
60
61 [Test]
62 public void BlockPutGet()
63 {
64 CircularBuffer buf = new CircularBuffer(10);
65 byte[] arr = {1,2,3,4,5,6,7,8,9,10};
66 Assert.AreEqual( 10, buf.Put(arr,0,10) );
67 Assert.AreEqual( 10, buf.Size );
68 Assert.IsFalse( buf.Put(11) );
69 Assert.AreEqual( 1, buf.Get() );
70 Assert.IsTrue( buf.Put(11) );
71
72 byte[] arr2 = (byte[])arr.Clone();
73 Assert.AreEqual( 9, buf.Get(arr2,1,9) );
74 Assert.IsTrue( Utils.byteArrEqual(arr,arr2) );
75 }
76
77 #endregion
78 }
79
80 [TestFixture]
81 public class ChecksumTests
82 {
83 #region CRC32 Tests
84 [Test]
85 public void CRC32_Null()
86 {
87 CRC32Checksum crc32 = new CRC32Checksum();
88 Assert.AreEqual( 0, crc32.Value );
89
90 crc32 = new CRC32Checksum(1);
91 Assert.AreEqual( 1, crc32.Value );
92
93 crc32 = new CRC32Checksum(556);
94 Assert.AreEqual( 556, crc32.Value );
95 }
96
97 [Test]
98 public void CRC32_Data()
99 {
100 CRC32Checksum crc32 = new CRC32Checksum();
101 byte[] data = { 1,2,3,4,5,6,7 };
102 crc32.Update(data);
103 Assert.AreEqual( 0x70e46888, crc32.Value );
104
105 crc32 = new CRC32Checksum();
106 crc32.Update("penguin");
107 Assert.AreEqual( 0x0e5c1a120, crc32.Value );
108
109 crc32 = new CRC32Checksum(1);
110 crc32.Update("penguin");
111 Assert.AreEqual(0x43b6aa94, crc32.Value);
112
113 }
114 #endregion
115
116 #region Adler tests
117
118 [Test]
119 public void Adler_Null()
120 {
121 AdlerChecksum adler = new AdlerChecksum();
122 Assert.AreEqual(0, adler.Value);
123
124 adler = new AdlerChecksum(1);
125 Assert.AreEqual( 1, adler.Value );
126
127 adler = new AdlerChecksum(556);
128 Assert.AreEqual( 556, adler.Value );
129 }
130
131 [Test]
132 public void Adler_Data()
133 {
134 AdlerChecksum adler = new AdlerChecksum(1);
135 byte[] data = { 1,2,3,4,5,6,7 };
136 adler.Update(data);
137 Assert.AreEqual( 0x5b001d, adler.Value );
138
139 adler = new AdlerChecksum();
140 adler.Update("penguin");
141 Assert.AreEqual(0x0bcf02f6, adler.Value );
142
143 adler = new AdlerChecksum(1);
144 adler.Update("penguin");
145 Assert.AreEqual(0x0bd602f7, adler.Value);
146
147 }
148 #endregion
149 }
150
151 [TestFixture]
152 public class InfoTests
153 {
154 #region Info tests
155 [Test]
156 public void Info_Version()
157 {
158 Info info = new Info();
159 Assert.AreEqual("1.2.2", Info.Version);
160 Assert.AreEqual(32, info.SizeOfUInt);
161 Assert.AreEqual(32, info.SizeOfULong);
162 Assert.AreEqual(32, info.SizeOfPointer);
163 Assert.AreEqual(32, info.SizeOfOffset);
164 }
165 #endregion
166 }
167
168 [TestFixture]
169 public class DeflateInflateTests
170 {
171 #region Deflate tests
172 [Test]
173 public void Deflate_Init()
174 {
175 using (Deflater def = new Deflater(CompressLevel.Default))
176 {
177 }
178 }
179
180 private ArrayList compressedData = new ArrayList();
181 private uint adler1;
182
183 private ArrayList uncompressedData = new ArrayList();
184 private uint adler2;
185
186 public void CDataAvail(byte[] data, int startIndex, int count)
187 {
188 for (int i = 0; i < count; ++i)
189 compressedData.Add(data[i+startIndex]);
190 }
191
192 [Test]
193 public void Deflate_Compress()
194 {
195 compressedData.Clear();
196
197 byte[] testData = new byte[35000];
198 for (int i = 0; i < testData.Length; ++i)
199 testData[i] = 5;
200
201 using (Deflater def = new Deflater((CompressLevel)5))
202 {
203 def.DataAvailable += new DataAvailableHandler(CDataAvail);
204 def.Add(testData);
205 def.Finish();
206 adler1 = def.Checksum;
207 }
208 }
209 #endregion
210
211 #region Inflate tests
212 [Test]
213 public void Inflate_Init()
214 {
215 using (Inflater inf = new Inflater())
216 {
217 }
218 }
219
220 private void DDataAvail(byte[] data, int startIndex, int count)
221 {
222 for (int i = 0; i < count; ++i)
223 uncompressedData.Add(data[i+startIndex]);
224 }
225
226 [Test]
227 public void Inflate_Expand()
228 {
229 uncompressedData.Clear();
230
231 using (Inflater inf = new Inflater())
232 {
233 inf.DataAvailable += new DataAvailableHandler(DDataAvail);
234 inf.Add((byte[])compressedData.ToArray(typeof(byte)));
235 inf.Finish();
236 adler2 = inf.Checksum;
237 }
238 Assert.AreEqual( adler1, adler2 );
239 }
240 #endregion
241 }
242
243 [TestFixture]
244 public class GZipStreamTests
245 {
246 #region GZipStream test
247 [Test]
248 public void GZipStream_WriteRead()
249 {
250 using (GZipStream gzOut = new GZipStream("gzstream.gz", CompressLevel.Best))
251 {
252 BinaryWriter writer = new BinaryWriter(gzOut);
253 writer.Write("hi there");
254 writer.Write(Math.PI);
255 writer.Write(42);
256 }
257
258 using (GZipStream gzIn = new GZipStream("gzstream.gz"))
259 {
260 BinaryReader reader = new BinaryReader(gzIn);
261 string s = reader.ReadString();
262 Assert.AreEqual("hi there",s);
263 double d = reader.ReadDouble();
264 Assert.AreEqual(Math.PI, d);
265 int i = reader.ReadInt32();
266 Assert.AreEqual(42,i);
267 }
268
269 }
270 #endregion
271 }
272}
273
274#endif \ No newline at end of file