Home | History | Annotate | Line # | Download | only in DotZLib
      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 
      8 using System;
      9 using System.Runtime.InteropServices;
     10 using System.Text;
     11 
     12 
     13 namespace 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 base with 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 implemented 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 }