all repos — mgba @ 3b353ac62190a00765812938e86e04b753196736

mGBA Game Boy Advance Emulator

src/third-party/zlib/contrib/dotzlib/DotZLib/ChecksumImpl.cs (view raw)

  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}