19e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project//
29e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// � Copyright Henrik Ravn 2004
39e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project//
4381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes// Use, modification and distribution are subject to the Boost Software License, Version 1.0.
59e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project// (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
69e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project//
79e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
89e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectusing System;
99e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectusing System.Runtime.InteropServices;
109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectusing System.Text;
119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Projectnamespace DotZLib
149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project{
159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    #region ChecksumGeneratorBase
169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /// <summary>
179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /// Implements the common functionality needed for all <see cref="ChecksumGenerator"/>s
189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /// </summary>
199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /// <example></example>
209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    public abstract class ChecksumGeneratorBase : ChecksumGenerator
219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// The value of the current checksum
249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        protected uint _current;
269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
28381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        /// Initializes a new instance of the checksum generator base - the current checksum is
299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// set to zero
309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public ChecksumGeneratorBase()
329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _current = 0;
349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Initializes a new instance of the checksum generator basewith a specified value
389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="initialValue">The value to set the current checksum to</param>
409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public ChecksumGeneratorBase(uint initialValue)
419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            _current = initialValue;
439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Resets the current checksum to zero
479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public void Reset() { _current = 0; }
499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Gets the current checksum value
529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public uint Value { get { return _current; } }
549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
559e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Updates the current checksum with part of an array of bytes
579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="data">The data to update the checksum with</param>
599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="offset">Where in <c>data</c> to start updating</param>
609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="count">The number of bytes from <c>data</c> to use</param>
619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
64381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes        /// <remarks>All the other <c>Update</c> methods are implmeneted in terms of this one.
659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// This is therefore the only method a derived class has to implement</remarks>
669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public abstract void Update(byte[] data, int offset, int count);
679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Updates the current checksum with an array of bytes.
709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="data">The data to update the checksum with</param>
729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public void Update(byte[] data)
739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            Update(data, 0, data.Length);
759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Updates the current checksum with the data from a string
799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="data">The string to update the checksum with</param>
819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks>
829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public void Update(string data)
839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project			Update(Encoding.UTF8.GetBytes(data));
859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Updates the current checksum with the data from a string, using a specific encoding
899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="data">The string to update the checksum with</param>
919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="encoding">The encoding to use</param>
929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public void Update(string data, Encoding encoding)
939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            Update(encoding.GetBytes(data));
959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    #endregion
999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    #region CRC32
1019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /// <summary>
1029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /// Implements a CRC32 checksum generator
1039e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /// </summary>
104381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    public sealed class CRC32Checksum : ChecksumGeneratorBase
1059e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
1069e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        #region DLL imports
1079e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1089e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
1099e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        private static extern uint crc32(uint crc, int data, uint length);
1109e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1119e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        #endregion
1129e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1139e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
1149e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Initializes a new instance of the CRC32 checksum generator
1159e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
1169e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public CRC32Checksum() : base() {}
1179e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1189e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
1199e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Initializes a new instance of the CRC32 checksum generator with a specified value
1209e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
1219e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="initialValue">The value to set the current checksum to</param>
1229e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public CRC32Checksum(uint initialValue) : base(initialValue) {}
1239e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1249e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
1259e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Updates the current checksum with part of an array of bytes
1269e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
1279e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="data">The data to update the checksum with</param>
1289e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="offset">Where in <c>data</c> to start updating</param>
1299e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="count">The number of bytes from <c>data</c> to use</param>
1309e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
1319e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
1329e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
1339e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public override void Update(byte[] data, int offset, int count)
1349e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
1359e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
1369e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if ((offset+count) > data.Length) throw new ArgumentException();
1379e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
1389e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            try
1399e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
1409e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
1419e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
1429e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            finally
1439e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
1449e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                hData.Free();
1459e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
1469e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
1479e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1489e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
1499e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    #endregion
1509e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1519e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    #region Adler
1529e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /// <summary>
1539e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /// Implements a checksum generator that computes the Adler checksum on data
1549e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    /// </summary>
155381716e9396b55b1adb8235b020c37344f60ab07Elliott Hughes    public sealed class AdlerChecksum : ChecksumGeneratorBase
1569e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    {
1579e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        #region DLL imports
1589e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1599e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)]
1609e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        private static extern uint adler32(uint adler, int data, uint length);
1619e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1629e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        #endregion
1639e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1649e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
1659e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Initializes a new instance of the Adler checksum generator
1669e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
1679e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public AdlerChecksum() : base() {}
1689e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1699e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
1709e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Initializes a new instance of the Adler checksum generator with a specified value
1719e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
1729e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="initialValue">The value to set the current checksum to</param>
1739e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public AdlerChecksum(uint initialValue) : base(initialValue) {}
1749e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1759e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <summary>
1769e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// Updates the current checksum with part of an array of bytes
1779e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// </summary>
1789e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="data">The data to update the checksum with</param>
1799e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="offset">Where in <c>data</c> to start updating</param>
1809e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <param name="count">The number of bytes from <c>data</c> to use</param>
1819e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception>
1829e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception>
1839e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception>
1849e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        public override void Update(byte[] data, int offset, int count)
1859e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        {
1869e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException();
1879e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            if ((offset+count) > data.Length) throw new ArgumentException();
1889e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned);
1899e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            try
1909e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
1919e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count);
1929e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
1939e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            finally
1949e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            {
1959e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project                hData.Free();
1969e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project            }
1979e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project        }
1989e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
1999e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    }
2009e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project    #endregion
2019e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project
2029e38dfa2f95fce609707a0941f10af9a785288deThe Android Open Source Project}