1 1.1 christos // 2 1.1 christos // Copyright Henrik Ravn 2004 3 1.1 christos // 4 1.1.1.2 christos // Use, modification and distribution are subject to the Boost Software License, Version 1.0. 5 1.1 christos // (See accompanying file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 6 1.1 christos // 7 1.1 christos 8 1.1 christos using System; 9 1.1 christos using System.Runtime.InteropServices; 10 1.1 christos using System.Text; 11 1.1 christos 12 1.1 christos 13 1.1 christos namespace DotZLib 14 1.1 christos { 15 1.1 christos #region ChecksumGeneratorBase 16 1.1 christos /// <summary> 17 1.1 christos /// Implements the common functionality needed for all <see cref="ChecksumGenerator"/>s 18 1.1 christos /// </summary> 19 1.1 christos /// <example></example> 20 1.1 christos public abstract class ChecksumGeneratorBase : ChecksumGenerator 21 1.1 christos { 22 1.1 christos /// <summary> 23 1.1 christos /// The value of the current checksum 24 1.1 christos /// </summary> 25 1.1 christos protected uint _current; 26 1.1 christos 27 1.1 christos /// <summary> 28 1.1.1.2 christos /// Initializes a new instance of the checksum generator base - the current checksum is 29 1.1 christos /// set to zero 30 1.1 christos /// </summary> 31 1.1 christos public ChecksumGeneratorBase() 32 1.1 christos { 33 1.1 christos _current = 0; 34 1.1 christos } 35 1.1 christos 36 1.1 christos /// <summary> 37 1.1.1.3 christos /// Initializes a new instance of the checksum generator base with a specified value 38 1.1 christos /// </summary> 39 1.1 christos /// <param name="initialValue">The value to set the current checksum to</param> 40 1.1 christos public ChecksumGeneratorBase(uint initialValue) 41 1.1 christos { 42 1.1 christos _current = initialValue; 43 1.1 christos } 44 1.1 christos 45 1.1 christos /// <summary> 46 1.1 christos /// Resets the current checksum to zero 47 1.1 christos /// </summary> 48 1.1 christos public void Reset() { _current = 0; } 49 1.1 christos 50 1.1 christos /// <summary> 51 1.1 christos /// Gets the current checksum value 52 1.1 christos /// </summary> 53 1.1 christos public uint Value { get { return _current; } } 54 1.1 christos 55 1.1 christos /// <summary> 56 1.1 christos /// Updates the current checksum with part of an array of bytes 57 1.1 christos /// </summary> 58 1.1 christos /// <param name="data">The data to update the checksum with</param> 59 1.1 christos /// <param name="offset">Where in <c>data</c> to start updating</param> 60 1.1 christos /// <param name="count">The number of bytes from <c>data</c> to use</param> 61 1.1 christos /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception> 62 1.1 christos /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception> 63 1.1 christos /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception> 64 1.1.1.3 christos /// <remarks>All the other <c>Update</c> methods are implemented in terms of this one. 65 1.1 christos /// This is therefore the only method a derived class has to implement</remarks> 66 1.1 christos public abstract void Update(byte[] data, int offset, int count); 67 1.1 christos 68 1.1 christos /// <summary> 69 1.1 christos /// Updates the current checksum with an array of bytes. 70 1.1 christos /// </summary> 71 1.1 christos /// <param name="data">The data to update the checksum with</param> 72 1.1 christos public void Update(byte[] data) 73 1.1 christos { 74 1.1 christos Update(data, 0, data.Length); 75 1.1 christos } 76 1.1 christos 77 1.1 christos /// <summary> 78 1.1 christos /// Updates the current checksum with the data from a string 79 1.1 christos /// </summary> 80 1.1 christos /// <param name="data">The string to update the checksum with</param> 81 1.1 christos /// <remarks>The characters in the string are converted by the UTF-8 encoding</remarks> 82 1.1 christos public void Update(string data) 83 1.1 christos { 84 1.1 christos Update(Encoding.UTF8.GetBytes(data)); 85 1.1 christos } 86 1.1 christos 87 1.1 christos /// <summary> 88 1.1 christos /// Updates the current checksum with the data from a string, using a specific encoding 89 1.1 christos /// </summary> 90 1.1 christos /// <param name="data">The string to update the checksum with</param> 91 1.1 christos /// <param name="encoding">The encoding to use</param> 92 1.1 christos public void Update(string data, Encoding encoding) 93 1.1 christos { 94 1.1 christos Update(encoding.GetBytes(data)); 95 1.1 christos } 96 1.1 christos 97 1.1 christos } 98 1.1 christos #endregion 99 1.1 christos 100 1.1 christos #region CRC32 101 1.1 christos /// <summary> 102 1.1 christos /// Implements a CRC32 checksum generator 103 1.1 christos /// </summary> 104 1.1.1.2 christos public sealed class CRC32Checksum : ChecksumGeneratorBase 105 1.1 christos { 106 1.1 christos #region DLL imports 107 1.1 christos 108 1.1 christos [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] 109 1.1 christos private static extern uint crc32(uint crc, int data, uint length); 110 1.1 christos 111 1.1 christos #endregion 112 1.1 christos 113 1.1 christos /// <summary> 114 1.1 christos /// Initializes a new instance of the CRC32 checksum generator 115 1.1 christos /// </summary> 116 1.1 christos public CRC32Checksum() : base() {} 117 1.1 christos 118 1.1 christos /// <summary> 119 1.1 christos /// Initializes a new instance of the CRC32 checksum generator with a specified value 120 1.1 christos /// </summary> 121 1.1 christos /// <param name="initialValue">The value to set the current checksum to</param> 122 1.1 christos public CRC32Checksum(uint initialValue) : base(initialValue) {} 123 1.1 christos 124 1.1 christos /// <summary> 125 1.1 christos /// Updates the current checksum with part of an array of bytes 126 1.1 christos /// </summary> 127 1.1 christos /// <param name="data">The data to update the checksum with</param> 128 1.1 christos /// <param name="offset">Where in <c>data</c> to start updating</param> 129 1.1 christos /// <param name="count">The number of bytes from <c>data</c> to use</param> 130 1.1 christos /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception> 131 1.1 christos /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception> 132 1.1 christos /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception> 133 1.1 christos public override void Update(byte[] data, int offset, int count) 134 1.1 christos { 135 1.1 christos if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); 136 1.1 christos if ((offset+count) > data.Length) throw new ArgumentException(); 137 1.1 christos GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned); 138 1.1 christos try 139 1.1 christos { 140 1.1 christos _current = crc32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count); 141 1.1 christos } 142 1.1 christos finally 143 1.1 christos { 144 1.1 christos hData.Free(); 145 1.1 christos } 146 1.1 christos } 147 1.1 christos 148 1.1 christos } 149 1.1 christos #endregion 150 1.1 christos 151 1.1 christos #region Adler 152 1.1 christos /// <summary> 153 1.1 christos /// Implements a checksum generator that computes the Adler checksum on data 154 1.1 christos /// </summary> 155 1.1.1.2 christos public sealed class AdlerChecksum : ChecksumGeneratorBase 156 1.1 christos { 157 1.1 christos #region DLL imports 158 1.1 christos 159 1.1 christos [DllImport("ZLIB1.dll", CallingConvention=CallingConvention.Cdecl)] 160 1.1 christos private static extern uint adler32(uint adler, int data, uint length); 161 1.1 christos 162 1.1 christos #endregion 163 1.1 christos 164 1.1 christos /// <summary> 165 1.1 christos /// Initializes a new instance of the Adler checksum generator 166 1.1 christos /// </summary> 167 1.1 christos public AdlerChecksum() : base() {} 168 1.1 christos 169 1.1 christos /// <summary> 170 1.1 christos /// Initializes a new instance of the Adler checksum generator with a specified value 171 1.1 christos /// </summary> 172 1.1 christos /// <param name="initialValue">The value to set the current checksum to</param> 173 1.1 christos public AdlerChecksum(uint initialValue) : base(initialValue) {} 174 1.1 christos 175 1.1 christos /// <summary> 176 1.1 christos /// Updates the current checksum with part of an array of bytes 177 1.1 christos /// </summary> 178 1.1 christos /// <param name="data">The data to update the checksum with</param> 179 1.1 christos /// <param name="offset">Where in <c>data</c> to start updating</param> 180 1.1 christos /// <param name="count">The number of bytes from <c>data</c> to use</param> 181 1.1 christos /// <exception cref="ArgumentException">The sum of offset and count is larger than the length of <c>data</c></exception> 182 1.1 christos /// <exception cref="NullReferenceException"><c>data</c> is a null reference</exception> 183 1.1 christos /// <exception cref="ArgumentOutOfRangeException">Offset or count is negative.</exception> 184 1.1 christos public override void Update(byte[] data, int offset, int count) 185 1.1 christos { 186 1.1 christos if (offset < 0 || count < 0) throw new ArgumentOutOfRangeException(); 187 1.1 christos if ((offset+count) > data.Length) throw new ArgumentException(); 188 1.1 christos GCHandle hData = GCHandle.Alloc(data, GCHandleType.Pinned); 189 1.1 christos try 190 1.1 christos { 191 1.1 christos _current = adler32(_current, hData.AddrOfPinnedObject().ToInt32()+offset, (uint)count); 192 1.1 christos } 193 1.1 christos finally 194 1.1 christos { 195 1.1 christos hData.Free(); 196 1.1 christos } 197 1.1 christos } 198 1.1 christos 199 1.1 christos } 200 1.1 christos #endregion 201 1.1 christos 202 1.1 christos }