xref: /minix3/common/dist/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs (revision 44bedb31d842b4b0444105519bcf929a69fe2dc1)
1*44bedb31SLionel Sambuc //
2*44bedb31SLionel Sambuc // � Copyright Henrik Ravn 2004
3*44bedb31SLionel Sambuc //
4*44bedb31SLionel Sambuc // Use, modification and distribution are subject to the Boost Software License, Version 1.0.
5*44bedb31SLionel Sambuc // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6*44bedb31SLionel Sambuc //
7*44bedb31SLionel Sambuc 
8*44bedb31SLionel Sambuc using System;
9*44bedb31SLionel Sambuc using System.Runtime.InteropServices;
10*44bedb31SLionel Sambuc using System.Text;
11*44bedb31SLionel Sambuc 
12*44bedb31SLionel Sambuc 
13*44bedb31SLionel Sambuc namespace DotZLib
14*44bedb31SLionel Sambuc {
15*44bedb31SLionel Sambuc     #region ChecksumGeneratorBase
16*44bedb31SLionel Sambuc     /// <summary>
17*44bedb31SLionel Sambuc     /// Implements the common functionality needed for all <see cref="ChecksumGenerator"/>s
18*44bedb31SLionel Sambuc     /// </summary>
19*44bedb31SLionel Sambuc     /// <example></example>
20*44bedb31SLionel Sambuc     public abstract class ChecksumGeneratorBase : ChecksumGenerator
21*44bedb31SLionel Sambuc     {
22*44bedb31SLionel Sambuc         /// <summary>
23*44bedb31SLionel Sambuc         /// The value of the current checksum
24*44bedb31SLionel Sambuc         /// </summary>
25*44bedb31SLionel Sambuc         protected uint _current;
26*44bedb31SLionel Sambuc 
27*44bedb31SLionel Sambuc         /// <summary>
28*44bedb31SLionel Sambuc         /// Initializes a new instance of the checksum generator base - the current checksum is
29*44bedb31SLionel Sambuc         /// set to zero
30*44bedb31SLionel Sambuc         /// </summary>
ChecksumGeneratorBase()31*44bedb31SLionel Sambuc         public ChecksumGeneratorBase()
32*44bedb31SLionel Sambuc         {
33*44bedb31SLionel Sambuc             _current = 0;
34*44bedb31SLionel Sambuc         }
35*44bedb31SLionel Sambuc 
36*44bedb31SLionel Sambuc         /// <summary>
37*44bedb31SLionel Sambuc         /// Initializes a new instance of the checksum generator basewith a specified value
38*44bedb31SLionel Sambuc         /// </summary>
39*44bedb31SLionel Sambuc         /// <param name="initialValue">The value to set the current checksum to</param>
ChecksumGeneratorBase(uint initialValue)40*44bedb31SLionel Sambuc         public ChecksumGeneratorBase(uint initialValue)
41*44bedb31SLionel Sambuc         {
42*44bedb31SLionel Sambuc             _current = initialValue;
43*44bedb31SLionel Sambuc         }
44*44bedb31SLionel Sambuc 
45*44bedb31SLionel Sambuc         /// <summary>
46*44bedb31SLionel Sambuc         /// Resets the current checksum to zero
47*44bedb31SLionel Sambuc         /// </summary>
Reset()48*44bedb31SLionel Sambuc         public void Reset() { _current = 0; }
49*44bedb31SLionel Sambuc 
50*44bedb31SLionel Sambuc         /// <summary>
51*44bedb31SLionel Sambuc         /// Gets the current checksum value
52*44bedb31SLionel Sambuc         /// </summary>
53*44bedb31SLionel Sambuc         public uint Value { get { return _current; } }
54*44bedb31SLionel Sambuc 
55*44bedb31SLionel Sambuc         /// <summary>
56*44bedb31SLionel Sambuc         /// Updates the current checksum with part of an array of bytes
57*44bedb31SLionel Sambuc         /// </summary>
58*44bedb31SLionel Sambuc         /// <param name="data">The data to update the checksum with</param>
59*44bedb31SLionel Sambuc         /// <param name="offset">Where in <c>data</c> to start updating</param>
60*44bedb31SLionel Sambuc         /// <param name="count">The number of bytes from <c>data</c> to use</param>
61*44bedb31SLionel Sambuc         /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
62*44bedb31SLionel Sambuc         /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
63*44bedb31SLionel Sambuc         /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
64*44bedb31SLionel Sambuc         /// <remarks>All the other <c>Update</c> methods are implmeneted in terms of this one.
65*44bedb31SLionel Sambuc         /// This is therefore the only method a derived class has to implement</remarks>
Update(byte[] data, int offset, int count)66*44bedb31SLionel Sambuc         public abstract void Update(byte[] data, int offset, int count);
67*44bedb31SLionel Sambuc 
68*44bedb31SLionel Sambuc         /// <summary>
69*44bedb31SLionel Sambuc         /// Updates the current checksum with an array of bytes.
70*44bedb31SLionel Sambuc         /// </summary>
71*44bedb31SLionel Sambuc         /// <param name="data">The data to update the checksum with</param>
Update(byte[] data)72*44bedb31SLionel Sambuc         public void Update(byte[] data)
73*44bedb31SLionel Sambuc         {
74*44bedb31SLionel Sambuc             Update(data, 0, data.Length);
75*44bedb31SLionel Sambuc         }
76*44bedb31SLionel Sambuc 
77*44bedb31SLionel Sambuc         /// <summary>
78*44bedb31SLionel Sambuc         /// Updates the current checksum with the data from a string
79*44bedb31SLionel Sambuc         /// </summary>
80*44bedb31SLionel Sambuc         /// <param name="data">The string to update the checksum with</param>
81*44bedb31SLionel Sambuc         /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
Update(string data)82*44bedb31SLionel Sambuc         public void Update(string data)
83*44bedb31SLionel Sambuc         {
84*44bedb31SLionel Sambuc 			Update(Encoding.UTF8.GetBytes(data));
85*44bedb31SLionel Sambuc         }
86*44bedb31SLionel Sambuc 
87*44bedb31SLionel Sambuc         /// <summary>
88*44bedb31SLionel Sambuc         /// Updates the current checksum with the data from a string, using a specific encoding
89*44bedb31SLionel Sambuc         /// </summary>
90*44bedb31SLionel Sambuc         /// <param name="data">The string to update the checksum with</param>
91*44bedb31SLionel Sambuc         /// <param name="encoding">The encoding to use</param>
Update(string data, Encoding encoding)92*44bedb31SLionel Sambuc         public void Update(string data, Encoding encoding)
93*44bedb31SLionel Sambuc         {
94*44bedb31SLionel Sambuc             Update(encoding.GetBytes(data));
95*44bedb31SLionel Sambuc         }
96*44bedb31SLionel Sambuc 
97*44bedb31SLionel Sambuc     }
98*44bedb31SLionel Sambuc     #endregion
99*44bedb31SLionel Sambuc 
100*44bedb31SLionel Sambuc     #region CRC32
101*44bedb31SLionel Sambuc     /// <summary>
102*44bedb31SLionel Sambuc     /// Implements a CRC32 checksum generator
103*44bedb31SLionel Sambuc     /// </summary>
104*44bedb31SLionel Sambuc     public sealed class CRC32Checksum : ChecksumGeneratorBase
105*44bedb31SLionel Sambuc     {
106*44bedb31SLionel Sambuc         #region DLL imports
107*44bedb31SLionel Sambuc 
108*44bedb31SLionel Sambuc         [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
crc32(uint crc, int data, uint length)109*44bedb31SLionel Sambuc         private static extern uint crc32(uint crc, int data, uint length);
110*44bedb31SLionel Sambuc 
111*44bedb31SLionel Sambuc         #endregion
112*44bedb31SLionel Sambuc 
113*44bedb31SLionel Sambuc         /// <summary>
114*44bedb31SLionel Sambuc         /// Initializes a new instance of the CRC32 checksum generator
115*44bedb31SLionel Sambuc         /// </summary>
CRC32Checksum()116*44bedb31SLionel Sambuc         public CRC32Checksum() : base() {}
117*44bedb31SLionel Sambuc 
118*44bedb31SLionel Sambuc         /// <summary>
119*44bedb31SLionel Sambuc         /// Initializes a new instance of the CRC32 checksum generator with a specified value
120*44bedb31SLionel Sambuc         /// </summary>
121*44bedb31SLionel Sambuc         /// <param name="initialValue">The value to set the current checksum to</param>
CRC32Checksum(uint initialValue)122*44bedb31SLionel Sambuc         public CRC32Checksum(uint initialValue) : base(initialValue) {}
123*44bedb31SLionel Sambuc 
124*44bedb31SLionel Sambuc         /// <summary>
125*44bedb31SLionel Sambuc         /// Updates the current checksum with part of an array of bytes
126*44bedb31SLionel Sambuc         /// </summary>
127*44bedb31SLionel Sambuc         /// <param name="data">The data to update the checksum with</param>
128*44bedb31SLionel Sambuc         /// <param name="offset">Where in <c>data</c> to start updating</param>
129*44bedb31SLionel Sambuc         /// <param name="count">The number of bytes from <c>data</c> to use</param>
130*44bedb31SLionel Sambuc         /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
131*44bedb31SLionel Sambuc         /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
132*44bedb31SLionel Sambuc         /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
Update(byte[] data, int offset, int count)133*44bedb31SLionel Sambuc         public override void Update(byte[] data, int offset, int count)
134*44bedb31SLionel Sambuc         {
135*44bedb31SLionel Sambuc             if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
136*44bedb31SLionel Sambuc             if ((offset+count) > data.Length) throw new ArgumentException();
137*44bedb31SLionel Sambuc             GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
138*44bedb31SLionel Sambuc             try
139*44bedb31SLionel Sambuc             {
140*44bedb31SLionel Sambuc                 _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
141*44bedb31SLionel Sambuc             }
142*44bedb31SLionel Sambuc             finally
143*44bedb31SLionel Sambuc             {
144*44bedb31SLionel Sambuc                 hData.Free();
145*44bedb31SLionel Sambuc             }
146*44bedb31SLionel Sambuc         }
147*44bedb31SLionel Sambuc 
148*44bedb31SLionel Sambuc     }
149*44bedb31SLionel Sambuc     #endregion
150*44bedb31SLionel Sambuc 
151*44bedb31SLionel Sambuc     #region Adler
152*44bedb31SLionel Sambuc     /// <summary>
153*44bedb31SLionel Sambuc     /// Implements a checksum generator that computes the Adler checksum on data
154*44bedb31SLionel Sambuc     /// </summary>
155*44bedb31SLionel Sambuc     public sealed class AdlerChecksum : ChecksumGeneratorBase
156*44bedb31SLionel Sambuc     {
157*44bedb31SLionel Sambuc         #region DLL imports
158*44bedb31SLionel Sambuc 
159*44bedb31SLionel Sambuc         [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
adler32(uint adler, int data, uint length)160*44bedb31SLionel Sambuc         private static extern uint adler32(uint adler, int data, uint length);
161*44bedb31SLionel Sambuc 
162*44bedb31SLionel Sambuc         #endregion
163*44bedb31SLionel Sambuc 
164*44bedb31SLionel Sambuc         /// <summary>
165*44bedb31SLionel Sambuc         /// Initializes a new instance of the Adler checksum generator
166*44bedb31SLionel Sambuc         /// </summary>
AdlerChecksum()167*44bedb31SLionel Sambuc         public AdlerChecksum() : base() {}
168*44bedb31SLionel Sambuc 
169*44bedb31SLionel Sambuc         /// <summary>
170*44bedb31SLionel Sambuc         /// Initializes a new instance of the Adler checksum generator with a specified value
171*44bedb31SLionel Sambuc         /// </summary>
172*44bedb31SLionel Sambuc         /// <param name="initialValue">The value to set the current checksum to</param>
AdlerChecksum(uint initialValue)173*44bedb31SLionel Sambuc         public AdlerChecksum(uint initialValue) : base(initialValue) {}
174*44bedb31SLionel Sambuc 
175*44bedb31SLionel Sambuc         /// <summary>
176*44bedb31SLionel Sambuc         /// Updates the current checksum with part of an array of bytes
177*44bedb31SLionel Sambuc         /// </summary>
178*44bedb31SLionel Sambuc         /// <param name="data">The data to update the checksum with</param>
179*44bedb31SLionel Sambuc         /// <param name="offset">Where in <c>data</c> to start updating</param>
180*44bedb31SLionel Sambuc         /// <param name="count">The number of bytes from <c>data</c> to use</param>
181*44bedb31SLionel Sambuc         /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
182*44bedb31SLionel Sambuc         /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
183*44bedb31SLionel Sambuc         /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
Update(byte[] data, int offset, int count)184*44bedb31SLionel Sambuc         public override void Update(byte[] data, int offset, int count)
185*44bedb31SLionel Sambuc         {
186*44bedb31SLionel Sambuc             if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
187*44bedb31SLionel Sambuc             if ((offset+count) > data.Length) throw new ArgumentException();
188*44bedb31SLionel Sambuc             GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
189*44bedb31SLionel Sambuc             try
190*44bedb31SLionel Sambuc             {
191*44bedb31SLionel Sambuc                 _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
192*44bedb31SLionel Sambuc             }
193*44bedb31SLionel Sambuc             finally
194*44bedb31SLionel Sambuc             {
195*44bedb31SLionel Sambuc                 hData.Free();
196*44bedb31SLionel Sambuc             }
197*44bedb31SLionel Sambuc         }
198*44bedb31SLionel Sambuc 
199*44bedb31SLionel Sambuc     }
200*44bedb31SLionel Sambuc     #endregion
201*44bedb31SLionel Sambuc 
202*44bedb31SLionel Sambuc }