Chris@4: // Chris@4: // © Copyright Henrik Ravn 2004 Chris@4: // Chris@4: // Use, modification and distribution are subject to the Boost Software License, Version 1.0. Chris@4: // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) Chris@4: // Chris@4: Chris@4: using System; Chris@4: using System.Runtime.InteropServices; Chris@4: using System.Text; Chris@4: Chris@4: Chris@4: namespace DotZLib Chris@4: { Chris@4: #region ChecksumGeneratorBase Chris@4: /// Chris@4: /// Implements the common functionality needed for all s Chris@4: /// Chris@4: /// Chris@4: public abstract class ChecksumGeneratorBase : ChecksumGenerator Chris@4: { Chris@4: /// Chris@4: /// The value of the current checksum Chris@4: /// Chris@4: protected uint _current; Chris@4: Chris@4: /// Chris@4: /// Initializes a new instance of the checksum generator base - the current checksum is Chris@4: /// set to zero Chris@4: /// Chris@4: public ChecksumGeneratorBase() Chris@4: { Chris@4: _current = 0; Chris@4: } Chris@4: Chris@4: /// Chris@4: /// Initializes a new instance of the checksum generator basewith a specified value Chris@4: /// Chris@4: /// The value to set the current checksum to Chris@4: public ChecksumGeneratorBase(uint initialValue) Chris@4: { Chris@4: _current = initialValue; Chris@4: } Chris@4: Chris@4: /// Chris@4: /// Resets the current checksum to zero Chris@4: /// Chris@4: public void Reset() { _current = 0; } Chris@4: Chris@4: /// Chris@4: /// Gets the current checksum value Chris@4: /// Chris@4: public uint Value { get { return _current; } } Chris@4: Chris@4: /// Chris@4: /// Updates the current checksum with part of an array of bytes Chris@4: /// Chris@4: /// The data to update the checksum with Chris@4: /// Where in data to start updating Chris@4: /// The number of bytes from data to use Chris@4: /// The sum of offset and count is larger than the length of data Chris@4: /// data is a null reference Chris@4: /// Offset or count is negative. Chris@4: /// All the other Update methods are implmeneted in terms of this one. Chris@4: /// This is therefore the only method a derived class has to implement Chris@4: public abstract void Update(byte[] data, int offset, int count); Chris@4: Chris@4: /// Chris@4: /// Updates the current checksum with an array of bytes. Chris@4: /// Chris@4: /// The data to update the checksum with Chris@4: public void Update(byte[] data) Chris@4: { Chris@4: Update(data, 0, data.Length); Chris@4: } Chris@4: Chris@4: /// Chris@4: /// Updates the current checksum with the data from a string Chris@4: /// Chris@4: /// The string to update the checksum with Chris@4: /// The characters in the string are converted by the UTF-8 encoding Chris@4: public void Update(string data) Chris@4: { Chris@4: Update(Encoding.UTF8.GetBytes(data)); Chris@4: } Chris@4: Chris@4: /// Chris@4: /// Updates the current checksum with the data from a string, using a specific encoding Chris@4: /// Chris@4: /// The string to update the checksum with Chris@4: /// The encoding to use Chris@4: public void Update(string data, Encoding encoding) Chris@4: { Chris@4: Update(encoding.GetBytes(data)); Chris@4: } Chris@4: Chris@4: } Chris@4: #endregion Chris@4: Chris@4: #region CRC32 Chris@4: /// Chris@4: /// Implements a CRC32 checksum generator Chris@4: /// Chris@4: public sealed class CRC32Checksum : ChecksumGeneratorBase Chris@4: { Chris@4: #region DLL imports Chris@4: Chris@4: [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] Chris@4: private static extern uint crc32(uint crc, int data, uint length); Chris@4: Chris@4: #endregion Chris@4: Chris@4: /// Chris@4: /// Initializes a new instance of the CRC32 checksum generator Chris@4: /// Chris@4: public CRC32Checksum() : base() {} Chris@4: Chris@4: /// Chris@4: /// Initializes a new instance of the CRC32 checksum generator with a specified value Chris@4: /// Chris@4: /// The value to set the current checksum to Chris@4: public CRC32Checksum(uint initialValue) : base(initialValue) {} Chris@4: Chris@4: /// Chris@4: /// Updates the current checksum with part of an array of bytes Chris@4: /// Chris@4: /// The data to update the checksum with Chris@4: /// Where in data to start updating Chris@4: /// The number of bytes from data to use Chris@4: /// The sum of offset and count is larger than the length of data Chris@4: /// data is a null reference Chris@4: /// Offset or count is negative. Chris@4: public override void Update(byte[] data, int offset, int count) Chris@4: { Chris@4: if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); Chris@4: if ((offset+count) > data.Length) throw new ArgumentException(); Chris@4: GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned); Chris@4: try Chris@4: { Chris@4: _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count); Chris@4: } Chris@4: finally Chris@4: { Chris@4: hData.Free(); Chris@4: } Chris@4: } Chris@4: Chris@4: } Chris@4: #endregion Chris@4: Chris@4: #region Adler Chris@4: /// Chris@4: /// Implements a checksum generator that computes the Adler checksum on data Chris@4: /// Chris@4: public sealed class AdlerChecksum : ChecksumGeneratorBase Chris@4: { Chris@4: #region DLL imports Chris@4: Chris@4: [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] Chris@4: private static extern uint adler32(uint adler, int data, uint length); Chris@4: Chris@4: #endregion Chris@4: Chris@4: /// Chris@4: /// Initializes a new instance of the Adler checksum generator Chris@4: /// Chris@4: public AdlerChecksum() : base() {} Chris@4: Chris@4: /// Chris@4: /// Initializes a new instance of the Adler checksum generator with a specified value Chris@4: /// Chris@4: /// The value to set the current checksum to Chris@4: public AdlerChecksum(uint initialValue) : base(initialValue) {} Chris@4: Chris@4: /// Chris@4: /// Updates the current checksum with part of an array of bytes Chris@4: /// Chris@4: /// The data to update the checksum with Chris@4: /// Where in data to start updating Chris@4: /// The number of bytes from data to use Chris@4: /// The sum of offset and count is larger than the length of data Chris@4: /// data is a null reference Chris@4: /// Offset or count is negative. Chris@4: public override void Update(byte[] data, int offset, int count) Chris@4: { Chris@4: if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); Chris@4: if ((offset+count) > data.Length) throw new ArgumentException(); Chris@4: GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned); Chris@4: try Chris@4: { Chris@4: _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count); Chris@4: } Chris@4: finally Chris@4: { Chris@4: hData.Free(); Chris@4: } Chris@4: } Chris@4: Chris@4: } Chris@4: #endregion Chris@4: Chris@4: }