// Author:
// Sergey Chaban (serge@wildwestsoftware.com)
//
+// (C) 2004 Novell (http://www.novell.com)
+// Copyright (C) 2004 Novell, Inc (http://www.novell.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+//
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
-using System;
+using System.Globalization;
namespace System.Security.Cryptography {
private bool m_disposed;
- /// <summary>
- /// Default constructor.
- /// </summary>
public ToBase64Transform ()
{
}
- ~ToBase64Transform ()
+ ~ToBase64Transform ()
{
Dispose (false);
}
- /// <summary>
- /// </summary>
public bool CanTransformMultipleBlocks {
- get {
- return false;
- }
+ get { return false; }
}
- public bool CanReuseTransform {
- get { return false; }
+ public virtual bool CanReuseTransform {
+ get { return true; }
}
- /// <summary>
- /// Returns the input block size for the Base64 encoder.
- /// </summary>
- /// <remarks>
- /// The returned value is always 3.
- /// </remarks>
public int InputBlockSize {
- get {
- return 3;
- }
+ get { return 3; }
}
-
- /// <summary>
- /// Returns the output block size for the Base64 encoder.
- /// </summary>
- /// <remarks>
- /// The value returned by this property is always 4.
- /// </remarks>
public int OutputBlockSize {
- get {
- return 4;
- }
+ get { return 4; }
}
public void Clear()
}
}
- /// <summary>
- /// </summary>
- public int TransformBlock (byte [] inputBuffer,
- int inputOffset,
- int inputCount,
- byte [] outputBuffer,
- int outputOffset)
+ // LAMESPEC: It's not clear from docs what should be happening
+ // here if inputCount > InputBlockSize. It just "Converts the
+ // specified region of the specified byte array" and that's all.
+ public int TransformBlock (byte[] inputBuffer, int inputOffset, int inputCount, byte[] outputBuffer, int outputOffset)
{
- if (inputCount != this.InputBlockSize)
- throw new CryptographicException();
-
- byte [] lookup = Base64Table.EncodeTable;
+ if (m_disposed)
+ throw new ObjectDisposedException ("TransformBlock");
+ if (inputBuffer == null)
+ throw new ArgumentNullException ("inputBuffer");
+ if (outputBuffer == null)
+ throw new ArgumentNullException ("outputBuffer");
+ if (inputCount < 0)
+ throw new ArgumentException ("inputCount", "< 0");
+ if (inputCount > inputBuffer.Length)
+ throw new ArgumentException ("inputCount", Locale.GetText ("Overflow"));
+ if (inputOffset < 0)
+ throw new ArgumentOutOfRangeException ("inputOffset", "< 0");
+ // ordered to avoid possible integer overflow
+ if (inputOffset > inputBuffer.Length - inputCount)
+ throw new ArgumentException ("inputOffset", Locale.GetText ("Overflow"));
+ // ordered to avoid possible integer overflow
+#if NET_2_0
+ if (outputOffset < 0)
+ throw new ArgumentOutOfRangeException ("outputOffset", "< 0");
+ if (outputOffset > outputBuffer.Length - inputCount)
+ throw new ArgumentException ("outputOffset", Locale.GetText ("Overflow"));
+#else
+ if ((outputOffset < 0) || (outputOffset > outputBuffer.Length - inputCount))
+ throw new IndexOutOfRangeException ("outputOffset");
+#endif
+/// To match MS implementation
+// if (inputCount != this.InputBlockSize)
+// throw new CryptographicException (Locale.GetText ("Invalid input length"));
+
+ byte[] lookup = Base64Constants.EncodeTable;
int b1 = inputBuffer [inputOffset];
int b2 = inputBuffer [inputOffset + 1];
return this.OutputBlockSize;
}
-
-
-
- // LAMESPEC: It's not clear from Beta2 docs what should be
- // happening here if inputCount > InputBlockSize.
- // It just "Converts the specified region of the specified
- // byte array" and that's all.
- // Beta2 implementation throws some strange (and undocumented)
- // exception in such case. The exception is thrown by
- // System.Convert and not the method itself.
- // Anyhow, this implementation just encodes blocks of any size,
- // like any usual Base64 encoder.
-
- /// <summary>
- /// </summary>
- public byte [] TransformFinalBlock (byte [] inputBuffer,
- int inputOffset,
- int inputCount)
+ public byte[] TransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
+ {
+ if (m_disposed)
+ throw new ObjectDisposedException ("TransformFinalBlock");
+ if (inputBuffer == null)
+ throw new ArgumentNullException ("inputBuffer");
+ if (inputCount < 0)
+ throw new ArgumentException ("inputCount", "< 0");
+ if (inputOffset > inputBuffer.Length - inputCount)
+ throw new ArgumentException ("inputCount", Locale.GetText ("Overflow"));
+ if (inputCount > this.InputBlockSize)
+ throw new ArgumentOutOfRangeException (Locale.GetText ("Invalid input length"));
+
+ return InternalTransformFinalBlock (inputBuffer, inputOffset, inputCount);
+ }
+
+ // Mono System.Convert depends on the ability to process multiple blocks
+ internal byte[] InternalTransformFinalBlock (byte[] inputBuffer, int inputOffset, int inputCount)
{
int blockLen = this.InputBlockSize;
int outLen = this.OutputBlockSize;
int fullBlocks = inputCount / blockLen;
int tail = inputCount % blockLen;
- byte [] res = new byte [(inputCount != 0)
+ byte[] res = new byte [(inputCount != 0)
? ((inputCount + 2) / blockLen) * outLen
: 0];
outputOffset += outLen;
}
-
- byte [] lookup = Base64Table.EncodeTable;
+ byte[] lookup = Base64Constants.EncodeTable;
int b1,b2;
-
// When fewer than 24 input bits are available
// in an input group, zero bits are added
// (on the right) to form an integral number of
// one-byte padding
res [outputOffset+3] = (byte)'=';
break;
-
- default:
- break;
}
return res;
}
-
- } // ToBase64Transform
-
-
-
-
- [MonoTODO ("Put me in a separate file")]
- internal sealed class Base64Table {
-
- // This is the Base64 alphabet as described in RFC 2045
- // (Table 1, page 25).
- private static string ALPHABET =
- "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
- private static byte[] encodeTable;
- private static byte[] decodeTable;
-
-
- static Base64Table ()
- {
- int len = ALPHABET.Length;
-
- encodeTable = new byte [len];
-
- for (int i=0; i < len; i++) {
- encodeTable [i] = (byte) ALPHABET [i];
- }
-
-
- decodeTable = new byte [1 + (int)'z'];
-
- for (int i=0; i < decodeTable.Length; i++) {
- decodeTable [i] = Byte.MaxValue;
- }
-
- for (int i=0; i < len; i++) {
- char ch = ALPHABET [i];
- decodeTable [(int)ch] = (byte) i;
- }
- }
-
-
- private Base64Table ()
- {
- // Never instantiated.
- }
-
-
- internal static byte [] EncodeTable {
- get {
- return encodeTable;
- }
- }
-
- internal static byte [] DecodeTable {
- get {
- return decodeTable;
- }
- }
-
- } // Base64Table
-
-} // System.Security.Cryptography
+ }
+}