Make System.Web.Script.Serialization.JavaScriptSerializer.ConvertToType(Type, object...
[mono.git] / mcs / class / Npgsql / Npgsql / HashAlgorithm.cs
1 //
2 // System.Security.Cryptography HashAlgorithm Class implementation
3 //
4 // Authors:
5 //   Matthew S. Ford (Matthew.S.Ford@Rose-Hulman.Edu)
6 //   Sebastien Pouliot (spouliot@motus.com)
7 //
8 // Copyright 2001 by Matthew S. Ford.
9 // Portions (C) 2002 Motus Technologies Inc. (http://www.motus.com)
10 //
11 // Comment: Adapted to the Project from Mono CVS as Sebastien Pouliot suggested to enable
12 // support of Npgsql MD5 authentication in platforms which don't have support for MD5 algorithm.
13 //
14
15
16 using System;
17 using System.IO;
18
19
20 namespace Npgsql
21 {
22
23
24     // Comment: Removed the ICryptoTransform implementation as this interface may be not supported by
25     // all platforms.
26
27     internal abstract class HashAlgorithm : IDisposable
28     {
29         protected byte[] HashValue; // Caches the hash after it is calculated.  Accessed through the Hash property.
30         protected int HashSizeValue; // The size of the hash in bits.
31         protected int State;  // nonzero when in use;  zero when not in use
32         private bool disposed;
33
34         /// <summary>
35         /// Called from constructor of derived class.
36         /// </summary>
37         protected HashAlgorithm ()
38         {
39             disposed = false;
40         }
41
42         /// <summary>
43         /// Finalizer for HashAlgorithm
44         /// </summary>
45         ~HashAlgorithm ()
46         {
47             Dispose(false);
48         }
49
50         /// <summary>
51         /// Get whether or not the hash can transform multiple blocks at a time.
52         /// Note: MUST be overriden if descendant can transform multiple block
53         /// on a single call!
54         /// </summary>
55         public virtual bool CanTransformMultipleBlocks {
56             get
57             {
58                 return true;
59             }
60         }
61
62         public virtual bool CanReuseTransform {
63             get
64             {
65                 return true;
66             }
67         }
68
69         public void Clear()
70         {
71             // same as System.IDisposable.Dispose() which is documented
72             Dispose (true);
73         }
74
75         /// <summary>
76         /// Computes the entire hash of all the bytes in the byte array.
77         /// </summary>
78         public byte[] ComputeHash (byte[] input)
79         {
80             return ComputeHash (input, 0, input.Length);
81         }
82
83         public byte[] ComputeHash (byte[] buffer, int offset, int count)
84         {
85             if (disposed)
86                 throw new ObjectDisposedException ("HashAlgorithm");
87
88             HashCore (buffer, offset, count);
89             HashValue = HashFinal ();
90             Initialize ();
91
92             return HashValue;
93         }
94
95         public byte[] ComputeHash (Stream inputStream)
96         {
97             // don't read stream unless object is ready to use
98             if (disposed)
99                 throw new ObjectDisposedException ("HashAlgorithm");
100
101             int l = (int) (inputStream.Length - inputStream.Position);
102             byte[] buffer = new byte [l];
103             inputStream.Read (buffer, 0, l);
104
105             return ComputeHash (buffer, 0, l);
106         }
107
108         // Commented out because it uses the CryptoConfig which can't be available in all platforms
109
110         /*
111         /// <summary>
112         /// Creates the default implementation of the default hash algorithm (SHA1).
113         /// </summary>
114         public static HashAlgorithm Create ()
115         {
116                 return Create ("System.Security.Cryptography.HashAlgorithm");
117         }*/
118
119         /*
120         /// <summary>
121         /// Creates a specific implementation of the general hash idea.
122         /// </summary>
123         /// <param name="hashName">Specifies which derived class to create.</param>
124         public static HashAlgorithm Create (string hashName)
125         {
126                 return (HashAlgorithm) CryptoConfig.CreateFromName (hashName);
127         }*/
128
129
130
131         // Changed Exception type because it uses the CryptographicUnexpectedOperationException
132         // which can't be available in all platforms.
133         /// <summary>
134         /// Gets the previously computed hash.
135         /// </summary>
136         public virtual byte[] Hash {
137             get
138             {
139                 if (HashValue == null)
140                     throw new NullReferenceException("HashValue is null");
141                 return HashValue;
142             }
143         }
144
145         /// <summary>
146         /// When overridden in a derived class, drives the hashing function.
147         /// </summary>
148         /// <param name="rgb"></param>
149         /// <param name="start"></param>
150         /// <param name="size"></param>
151         protected abstract void HashCore (byte[] rgb, int start, int size);
152
153         /// <summary>
154         /// When overridden in a derived class, this pads and hashes whatever data might be left in the buffers and then returns the hash created.
155         /// </summary>
156         protected abstract byte[] HashFinal ();
157
158         /// <summary>
159         /// Returns the size in bits of the hash.
160         /// </summary>
161         public virtual int HashSize {
162             get
163             {
164                 return HashSizeValue;
165             }
166         }
167
168         /// <summary>
169         /// When overridden in a derived class, initializes the object to prepare for hashing.
170         /// </summary>
171         public abstract void Initialize ();
172
173         protected virtual void Dispose (bool disposing)
174         {
175             disposed = true;
176         }
177
178         /// <summary>
179         /// Must be overriden if not 1
180         /// </summary>
181         public virtual int InputBlockSize {
182             get
183             {
184                 return 1;
185             }
186         }
187
188         /// <summary>
189         /// Must be overriden if not 1
190         /// </summary>
191         public virtual int OutputBlockSize {
192             get
193             {
194                 return 1;
195             }
196         }
197
198         void IDisposable.Dispose ()
199         {
200             Dispose (true);
201             GC.SuppressFinalize (this);  // Finalization is now unnecessary
202         }
203
204         /// <summary>
205         /// Used for stream chaining.  Computes hash as data passes through it.
206         /// </summary>
207         /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
208         /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
209         /// <param name="inputCount">The number of bytes to be copied.</param>
210         /// <param name="outputBuffer">The buffer to write the copied data to.</param>
211         /// <param name="outputOffset">At what point in the outputBuffer to write the data at.</param>
212         public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
213         {
214             Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, outputOffset, inputCount);
215             HashCore (inputBuffer, inputOffset, inputCount);
216
217             return inputCount;
218         }
219
220         /// <summary>
221         /// Used for stream chaining.  Computes hash as data passes through it.  Finishes off the hash.
222         /// </summary>
223         /// <param name="inputBuffer">The buffer from which to grab the data to be copied.</param>
224         /// <param name="inputOffset">The offset into the input buffer to start reading at.</param>
225         /// <param name="inputCount">The number of bytes to be copied.</param>
226         public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
227         {
228             byte[] outputBuffer = new byte[inputCount];
229
230             Buffer.BlockCopy (inputBuffer, inputOffset, outputBuffer, 0, inputCount);
231
232             HashCore (inputBuffer, inputOffset, inputCount);
233             HashValue = HashFinal ();
234             Initialize ();
235
236             return outputBuffer;
237         }
238     }
239
240 }