202 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
		
		
			
		
	
	
			202 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C#
		
	
	
	
	
	
| 
								 | 
							
								//
							 | 
						|||
| 
								 | 
							
								// <20> 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
							 | 
						|||
| 
								 | 
							
								
							 | 
						|||
| 
								 | 
							
								}
							 |