• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
8 using System;
9 using System.Runtime.InteropServices;
10 using System.Text;
11 
12 
13 namespace 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>
ChecksumGeneratorBase()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>
ChecksumGeneratorBase(uint initialValue)40         public ChecksumGeneratorBase(uint initialValue)
41         {
42             _current = initialValue;
43         }
44 
45         /// <summary>
46         /// Resets the current checksum to zero
47         /// </summary>
Reset()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>
Update(byte[] data, int offset, int count)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>
Update(byte[] data)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>
Update(string data)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>
Update(string data, Encoding encoding)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)]
crc32(uint crc, int data, uint length)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>
CRC32Checksum()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>
CRC32Checksum(uint initialValue)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>
Update(byte[] data, int offset, int count)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)]
adler32(uint adler, int data, uint length)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>
AdlerChecksum()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>
AdlerChecksum(uint initialValue)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>
Update(byte[] data, int offset, int count)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 }