Fix the 1.1 build.
[mono.git] / mcs / class / corlib / System.Text / UTF7Encoding.cs
old mode 100755 (executable)
new mode 100644 (file)
index d024829..00eb0cd
@@ -28,9 +28,13 @@ namespace System.Text
 {
 
 using System;
+using System.Runtime.InteropServices;
 
 [Serializable]
-[MonoTODO ("Fix serialization compatibility with MS.NET")]
+#if NET_2_0
+[ComVisible (true)]
+#endif
+[MonoTODO ("Serialization format not compatible with .NET")]
 #if ECMA_COMPAT
 internal
 #else
@@ -66,7 +70,7 @@ class UTF7Encoding : Encoding
        private static readonly sbyte[] base64Values = {
                -1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1, // 00
                -1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, -1, -1, -1, -1, // 10
-               -1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, -1, 62, -1, -1, 63, // 20
+               -1, -1, -1, -1, -1, -1, -1, -1,   -1, -1, -1, 62, -1, -1, -1, 63, // 20
                52, 53, 54, 55, 56, 57, 58, 59,   60, 61, -1, -1, -1, -1, -1, -1, // 30
 
                -1,  0,  1,  2,  3,  4,  5,  6,    7,  8,  9, 10, 11, 12, 13, 14, // 40
@@ -105,6 +109,26 @@ class UTF7Encoding : Encoding
                windows_code_page = UnicodeEncoding.UNICODE_CODE_PAGE;
        }
 
+#if NET_2_0
+       [ComVisible (false)]
+       public override int GetHashCode ()
+       {
+               int basis = base.GetHashCode ();
+               return allowOptionals ? -basis : basis;
+       }
+
+       [ComVisible(false)]
+       public override bool Equals (object value)
+       {
+               UTF7Encoding e = value as UTF7Encoding;
+               if (e == null)
+                       return false;
+               return allowOptionals == e.allowOptionals &&
+                       EncoderFallback.Equals (e.EncoderFallback) &&
+                       DecoderFallback.Equals (e.DecoderFallback);
+       }
+#endif
+
        // Internal version of "GetByteCount" that can handle
        // a rolling state between calls.
        private static int InternalGetByteCount
@@ -400,8 +424,8 @@ class UTF7Encoding : Encoding
                                        // End of a base64 sequence.
                                        if (prevIsPlus) {
                                                ++length;
-                                               leftOverSize = 0;
                                        }
+                                       leftOverSize = 0;
                                        normal = true;
                                } else if (base64 [byteval] != -1) {
                                        // Extra character in a base64 sequence.
@@ -457,6 +481,7 @@ class UTF7Encoding : Encoding
                int byteval, b64value;
                bool normal = ((leftOver & 0x01000000) == 0);
                bool prevIsPlus = ((leftOver & 0x02000000) != 0);
+               bool afterHighSurrogate = ((leftOver & 0x04000000) != 0);
                int leftOverSize = ((leftOver >> 16) & 0xFF);
                int leftOverBits = (leftOver & 0xFFFF);
                sbyte[] base64 = base64Values;
@@ -469,6 +494,9 @@ class UTF7Encoding : Encoding
                                        if (posn >= charLength) {
                                                throw new ArgumentException (_("Arg_InsufficientSpace"), "chars");
                                        }
+                                       if (afterHighSurrogate) {
+                                               throw new ArgumentException (_("Arg_InvalidUTF7"), "chars");
+                                       }
                                        chars[posn++] = (char)byteval;
                                } else {
                                        // Start of a base64-encoded character.
@@ -483,6 +511,9 @@ class UTF7Encoding : Encoding
                                                if (posn >= charLength) {
                                                        throw new ArgumentException (_("Arg_InsufficientSpace"), "chars");
                                                }
+                                               if (afterHighSurrogate) {
+                                                       throw new ArgumentException (_("Arg_InvalidUTF7"), "chars");
+                                               }
                                                chars[posn++] = '+';
                                        }
                                        // RFC1642 Rule #2
@@ -503,13 +534,26 @@ class UTF7Encoding : Encoding
                                                        throw new ArgumentException (_("Arg_InsufficientSpace"), "chars");
                                                }
                                                leftOverSize -= 16;
-                                               chars[posn++] = (char)(leftOverBits >> leftOverSize);
+                                               char nextChar = (char)(leftOverBits >> leftOverSize);
+                                               if ((nextChar & 0xFC00) == 0xD800) {
+                                                 afterHighSurrogate = true;
+                                               }
+                                               else if ((nextChar & 0xFC00) == 0xDC00) {
+                                                       if (!afterHighSurrogate) {
+                                                               throw new ArgumentException (_("Arg_InvalidUTF7"), "chars");
+                                                       }
+                                                       afterHighSurrogate = false;
+                                               }
+                                               chars[posn++] = nextChar;
                                                leftOverBits &= ((1 << leftOverSize) - 1);
                                        }
                                } else {
                                        if (posn >= charLength) {
                                                throw new ArgumentException (_("Arg_InsufficientSpace"), "chars");
                                        }
+                                       if (afterHighSurrogate) {
+                                               throw new ArgumentException (_("Arg_InvalidUTF7"), "chars");
+                                       }
                                        chars[posn++] = (char)byteval;
                                        normal = true;
                                        leftOverSize = 0;
@@ -520,7 +564,8 @@ class UTF7Encoding : Encoding
                }
                leftOver = (leftOverBits | (leftOverSize << 16) |
                                    (normal ? 0 : 0x01000000) |
-                                   (prevIsPlus ? 0x02000000 : 0));
+                                   (prevIsPlus ? 0x02000000 : 0) |
+                                   (afterHighSurrogate ? 0x04000000 : 0));
 
                // Return the final length to the caller.
                return posn - charIndex;
@@ -531,7 +576,11 @@ class UTF7Encoding : Encoding
                                                                 char[] chars, int charIndex)
        {
                int leftOver = 0;
-               return InternalGetChars (bytes, byteIndex, byteCount, chars, charIndex, ref leftOver);
+               int amount = InternalGetChars (bytes, byteIndex, byteCount, chars, charIndex, ref leftOver);
+               if ((leftOver & 0x04000000) != 0) {
+                       throw new ArgumentException (_("Arg_InvalidUTF7"), "chars");
+               }
+               return amount;
        }
 
        // Get the maximum number of bytes needed to encode a
@@ -625,6 +674,57 @@ class UTF7Encoding : Encoding
 
        } // class UTF7Encoder
 
+#if NET_2_0
+       // a bunch of practically missing implementations (but should just work)
+
+       [CLSCompliantAttribute (false)]
+       [ComVisible(false)]
+       public override unsafe int GetByteCount (char *chars, int count)
+       {
+               return base.GetByteCount (chars, count);
+       }
+
+       [ComVisible(false)]
+       public override int GetByteCount (string s)
+       {
+               return base.GetByteCount (s);
+       }
+
+       [ComVisible(false)]
+       [CLSCompliantAttribute (false)]
+       public override unsafe int GetBytes (char *chars, int charCount, byte* bytes, int byteCount)
+       {
+               return base.GetBytes (chars, charCount, bytes, byteCount);
+       }
+
+       [ComVisible(false)]
+       public override int GetBytes (string s, int charIndex, int charCount, byte [] bytes, int byteIndex)
+       {
+               return base.GetBytes (s, charIndex, charCount, bytes, byteIndex);
+       }
+
+       [ComVisible(false)]
+       [CLSCompliantAttribute (false)]
+       public override unsafe int GetCharCount (byte *bytes, int count)
+       {
+               return base.GetCharCount (bytes, count);
+       }
+
+       [ComVisible(false)]
+       [CLSCompliantAttribute (false)]
+       public override unsafe int GetChars (byte* bytes, int byteCount, char* chars, int charCount)
+       {
+               return base.GetChars (bytes, byteCount, chars, charCount);
+       }
+
+       [ComVisible(false)]
+       public override string GetString (byte [] bytes, int index, int count)
+       {
+               return base.GetString (bytes, index, count);
+       }
+
+#endif
+
 }; // class UTF7Encoding
 
 }; // namespace System.Text