Fix null sessions in HttpContextWrapper.Session
[mono.git] / mcs / class / corlib / System.Text / Encoding.cs
index 2c7130dd0a36dc85aaf815246bfe860e7047e837..7033b15d075ec8bb9d5a2e06dcfaa95ee74eb103 100644 (file)
@@ -35,13 +35,8 @@ using System.Runtime.CompilerServices;
 using System.Runtime.InteropServices;
 
 [Serializable]
-#if NET_2_0
 [ComVisible (true)]
-#endif
-public abstract class Encoding
-#if NET_2_0
-       : ICloneable
-#endif
+public abstract class Encoding : ICloneable
 {
        // Code page used by this encoding.
        internal int codePage;
@@ -62,7 +57,6 @@ public abstract class Encoding
        {
                this.codePage = windows_code_page = codePage;
 
-#if NET_2_0
                switch (codePage) {
                default:
                        // MS has "InternalBestFit{Decoder|Encoder}Fallback
@@ -81,11 +75,10 @@ public abstract class Encoding
                case 12001: // UTF32
                case 65000: // UTF7
                case 65001: // UTF8
-                       decoder_fallback = new DecoderReplacementFallback (String.Empty);
-                       encoder_fallback = new EncoderReplacementFallback (String.Empty);
+                       decoder_fallback = DecoderFallback.StandardSafeFallback;
+                       encoder_fallback = EncoderFallback.StandardSafeFallback;
                        break;
                }
-#endif
        }
 
        // until we change the callers:
@@ -93,7 +86,6 @@ public abstract class Encoding
                return arg;
        }
 
-#if NET_2_0
        DecoderFallback decoder_fallback;
        EncoderFallback encoder_fallback;
 
@@ -107,14 +99,9 @@ public abstract class Encoding
                get { return false; }
        }
 
-       [MonoTODO ("not used yet")]
        [ComVisible (false)]
        public DecoderFallback DecoderFallback {
-               get {
-                       if (decoder_fallback == null)
-                               decoder_fallback = new DecoderReplacementFallback (String.Empty);
-                       return decoder_fallback;
-               }
+               get { return decoder_fallback; }
                set {
                        if (IsReadOnly)
                                throw new InvalidOperationException ("This Encoding is readonly.");
@@ -124,14 +111,9 @@ public abstract class Encoding
                }
        }
 
-       [MonoTODO ("not used yet")]
        [ComVisible (false)]
        public EncoderFallback EncoderFallback {
-               get {
-                       if (encoder_fallback == null)
-                               encoder_fallback = new EncoderReplacementFallback (String.Empty);
-                       return encoder_fallback;
-               }
+               get { return encoder_fallback; }
                set {
                        if (IsReadOnly)
                                throw new InvalidOperationException ("This Encoding is readonly.");
@@ -148,7 +130,6 @@ public abstract class Encoding
                if (d != null)
                        decoder_fallback = d;
        }
-#endif
 
        // Convert between two encodings.
        public static byte[] Convert (Encoding srcEncoding, Encoding dstEncoding,
@@ -189,17 +170,13 @@ public abstract class Encoding
        }
 
        // Determine if two Encoding objects are equal.
-       public override bool Equals (Object obj)
+       public override bool Equals (Object value)
        {
-               Encoding enc = (obj as Encoding);
+               Encoding enc = (value as Encoding);
                if (enc != null) {
-#if NET_2_0
                        return codePage == enc.codePage &&
                                DecoderFallback.Equals (enc.DecoderFallback) &&
                                EncoderFallback.Equals (enc.EncoderFallback);
-#else
-                       return (codePage == enc.codePage);
-#endif
                } else {
                        return false;
                }
@@ -216,16 +193,11 @@ public abstract class Encoding
 
                if (s.Length == 0)
                        return 0;
-#if NET_2_0
                unsafe {
                        fixed (char* cptr = s) {
                                return GetByteCount (cptr, s.Length);
                        }
                }
-#else
-               char[] chars = s.ToCharArray ();
-               return GetByteCount (chars, 0, chars.Length);
-#endif
        }
        public virtual int GetByteCount (char[] chars)
        {
@@ -246,10 +218,9 @@ public abstract class Encoding
        {
                if (s == null)
                        throw new ArgumentNullException ("s");
-#if NET_2_0
                if (charIndex < 0 || charIndex > s.Length)
                        throw new ArgumentOutOfRangeException ("charIndex", _("ArgRange_Array"));
-               if (charCount < 0 || charIndex + charCount > s.Length)
+               if (charCount < 0 || charIndex > (s.Length - charCount))
                        throw new ArgumentOutOfRangeException ("charCount", _("ArgRange_Array"));
                if (byteIndex < 0 || byteIndex > bytes.Length)
                        throw new ArgumentOutOfRangeException ("byteIndex", _("ArgRange_Array"));
@@ -266,21 +237,17 @@ public abstract class Encoding
                                }
                        }
                }
-#else
-               return GetBytes (s.ToCharArray(), charIndex, charCount, bytes, byteIndex);
-#endif
        }
        public virtual byte[] GetBytes (String s)
        {
                if (s == null)
                        throw new ArgumentNullException ("s");
 
-#if NET_2_0
                if (s.Length == 0)
-                       return new byte [0];
+                       return EmptyArray<byte>.Value;
                int byteCount = GetByteCount (s);
                if (byteCount == 0)
-                       return new byte [0];
+                       return EmptyArray<byte>.Value;
                unsafe {
                        fixed (char* cptr = s) {
                                byte [] bytes = new byte [byteCount];
@@ -291,14 +258,8 @@ public abstract class Encoding
                                }
                        }
                }
-#else
-               char[] chars = s.ToCharArray ();
-               int numBytes = GetByteCount (chars, 0, chars.Length);
-               byte[] bytes = new byte [numBytes];
-               GetBytes (chars, 0, chars.Length, bytes, 0);
-               return bytes;
-#endif
        }
+
        public virtual byte[] GetBytes (char[] chars, int index, int count)
        {
                int numBytes = GetByteCount (chars, index, count);
@@ -452,14 +413,14 @@ public abstract class Encoding
 #else
        public
 #endif
-       static Encoding GetEncoding (int codePage)
+       static Encoding GetEncoding (int codepage)
        {
-               if (codePage < 0 || codePage > 0xffff)
+               if (codepage < 0 || codepage > 0xffff)
                        throw new ArgumentOutOfRangeException ("codepage", 
                                "Valid values are between 0 and 65535, inclusive.");
 
                // Check for the builtin code pages first.
-               switch (codePage) {
+               switch (codepage) {
                        case 0: return Default;
 
                        case ASCIIEncoding.ASCII_CODE_PAGE:
@@ -471,13 +432,11 @@ public abstract class Encoding
                        case UTF8Encoding.UTF8_CODE_PAGE:
                                return UTF8;
 
-#if NET_2_0
                        case UTF32Encoding.UTF32_CODE_PAGE:
                                return UTF32;
 
                        case UTF32Encoding.BIG_UTF32_CODE_PAGE:
                                return BigEndianUTF32;
-#endif
 
                        case UnicodeEncoding.UNICODE_CODE_PAGE:
                                return Unicode;
@@ -485,21 +444,22 @@ public abstract class Encoding
                        case UnicodeEncoding.BIG_UNICODE_CODE_PAGE:
                                return BigEndianUnicode;
 
+#if !MOONLIGHT
                        case Latin1Encoding.ISOLATIN_CODE_PAGE:
                                return ISOLatin1;
-
+#endif
                        default: break;
                }
-
+#if !MOONLIGHT
                // Try to obtain a code page handler from the I18N handler.
-               Encoding enc = (Encoding)(InvokeI18N ("GetEncoding", codePage));
+               Encoding enc = (Encoding)(InvokeI18N ("GetEncoding", codepage));
                if (enc != null) {
                        enc.is_readonly = true;
                        return enc;
                }
 
                // Build a code page class name.
-               String cpName = "System.Text.CP" + codePage.ToString ();
+               String cpName = "System.Text.CP" + codepage.ToString ();
 
                // Look for a code page converter in this assembly.
                Assembly assembly = Assembly.GetExecutingAssembly ();
@@ -518,15 +478,14 @@ public abstract class Encoding
                        enc.is_readonly = true;
                        return enc;
                }
-
+#endif // !NET_2_1
                // We have no idea how to handle this code page.
                throw new NotSupportedException
-                       (String.Format ("CodePage {0} not supported", codePage.ToString ()));
+                       (String.Format ("CodePage {0} not supported", codepage.ToString ()));
        }
 
 #if !ECMA_COMPAT
 
-#if NET_2_0
        [ComVisible (false)]
        public virtual object Clone ()
        {
@@ -535,7 +494,9 @@ public abstract class Encoding
                return e;
        }
 
-       public static Encoding GetEncoding (int codePage,
+#if !MOONLIGHT
+
+       public static Encoding GetEncoding (int codepage,
                EncoderFallback encoderFallback, DecoderFallback decoderFallback)
        {
                if (encoderFallback == null)
@@ -543,7 +504,7 @@ public abstract class Encoding
                if (decoderFallback == null)
                        throw new ArgumentNullException ("decoderFallback");
 
-               Encoding e = GetEncoding (codePage).Clone () as Encoding;
+               Encoding e = GetEncoding (codepage).Clone () as Encoding;
                e.is_readonly = false;
                e.encoder_fallback = encoderFallback;
                e.decoder_fallback = decoderFallback;
@@ -565,6 +526,8 @@ public abstract class Encoding
                return e;
        }
 
+#endif // !NET_2_1
+
        static EncodingInfo [] encoding_infos;
 
        // FIXME: As everyone would agree, this implementation is so *hacky*
@@ -602,78 +565,88 @@ public abstract class Encoding
                return encoding_infos;
        }
 
+#if !MOONLIGHT
+       [ComVisible (false)]
        public bool IsAlwaysNormalized ()
        {
                return IsAlwaysNormalized (NormalizationForm.FormC);
        }
 
+       [ComVisible (false)]
        public virtual bool IsAlwaysNormalized (NormalizationForm form)
        {
                // umm, ASCIIEncoding should have overriden this method, no?
                return form == NormalizationForm.FormC && this is ASCIIEncoding;
        }
-#endif
-
-       // Table of builtin web encoding names and the corresponding code pages.
-       private static readonly object[] encodings =
-               {
-                       ASCIIEncoding.ASCII_CODE_PAGE,
-                       "ascii", "us_ascii", "us", "ansi_x3.4_1968",
-                       "ansi_x3.4_1986", "cp367", "csascii", "ibm367",
-                       "iso_ir_6", "iso646_us", "iso_646.irv:1991",
-
-                       UTF7Encoding.UTF7_CODE_PAGE,
-                       "utf_7", "csunicode11utf7", "unicode_1_1_utf_7",
-                       "unicode_2_0_utf_7", "x_unicode_1_1_utf_7",
-                       "x_unicode_2_0_utf_7",
-                       
-                       UTF8Encoding.UTF8_CODE_PAGE,
-                       "utf_8", "unicode_1_1_utf_8", "unicode_2_0_utf_8",
-                       "x_unicode_1_1_utf_8", "x_unicode_2_0_utf_8",
-
-                       UnicodeEncoding.UNICODE_CODE_PAGE,
-                       "utf_16", "UTF_16LE", "ucs_2", "unicode",
-                       "iso_10646_ucs2",
-
-                       UnicodeEncoding.BIG_UNICODE_CODE_PAGE,
-                       "unicodefffe", "utf_16be",
-
-#if NET_2_0
-                       UTF32Encoding.UTF32_CODE_PAGE,
-                       "utf_32", "UTF_32LE", "ucs_4",
-
-                       UTF32Encoding.BIG_UTF32_CODE_PAGE,
-                       "UTF_32BE",
-#endif
-
-                       Latin1Encoding.ISOLATIN_CODE_PAGE,
-                       "iso_8859_1", "latin1"
-               };
+#endif // NET_2_1
 
        // Get an encoding object for a specific web encoding name.
-       public static Encoding GetEncoding (String name)
+       public static Encoding GetEncoding (string name)
        {
                // Validate the parameters.
                if (name == null) {
                        throw new ArgumentNullException ("name");
                }
-
+               
                string converted = name.ToLowerInvariant ().Replace ('-', '_');
                
-               // Search the table for a name match.
-               int code = 0;
-               for (int i = 0; i < encodings.Length; ++i) {
-                       object o = encodings [i];
-                       
-                       if (o is int){
-                               code = (int) o;
-                               continue;
-                       }
-                       
-                       if (converted == ((string)encodings [i]))
-                               return GetEncoding (code);
+               // Builtin web encoding names and the corresponding code pages.
+               switch (converted) {
+               case "ascii":
+               case "us_ascii":
+               case "us":
+               case "ansi_x3.4_1968":
+               case "ansi_x3.4_1986":
+               case "cp367":
+               case "csascii":
+               case "ibm367":
+               case "iso_ir_6":
+               case "iso646_us":
+               case "iso_646.irv:1991":
+                       return GetEncoding (ASCIIEncoding.ASCII_CODE_PAGE);
+
+               case "utf_7":
+               case "csunicode11utf7":
+               case "unicode_1_1_utf_7":
+               case "unicode_2_0_utf_7":
+               case "x_unicode_1_1_utf_7":
+               case "x_unicode_2_0_utf_7":
+                       return GetEncoding (UTF7Encoding.UTF7_CODE_PAGE);
+               
+               case "utf_8":
+               case "unicode_1_1_utf_8":
+               case "unicode_2_0_utf_8":
+               case "x_unicode_1_1_utf_8":
+               case "x_unicode_2_0_utf_8":
+                       return GetEncoding (UTF8Encoding.UTF8_CODE_PAGE);
+               
+               case "utf_16":
+               case "utf_16le":
+               case "ucs_2":
+               case "unicode":
+               case "iso_10646_ucs2":
+                       return GetEncoding (UnicodeEncoding.UNICODE_CODE_PAGE);
+
+               case "unicodefffe":
+               case "utf_16be":
+                       return GetEncoding (UnicodeEncoding.BIG_UNICODE_CODE_PAGE);
+               
+               case "utf_32":
+               case "utf_32le":
+               case "ucs_4":
+                       return GetEncoding (UTF32Encoding.UTF32_CODE_PAGE);
+
+               case "utf_32be":
+                       return GetEncoding (UTF32Encoding.BIG_UTF32_CODE_PAGE);
+
+#if !MOONLIGHT
+               case "iso_8859_1":
+               case "latin1":
+                       return GetEncoding (Latin1Encoding.ISOLATIN_CODE_PAGE);
+#endif
                }
-
+               
+#if !MOONLIGHT
                // Try to obtain a web encoding handler from the I18N handler.
                Encoding enc = (Encoding)(InvokeI18N ("GetEncoding", name));
                if (enc != null) {
@@ -697,7 +670,7 @@ public abstract class Encoding
                if (type != null) {
                        return (Encoding)(Activator.CreateInstance (type));
                }
-
+#endif
                // We have no idea how to handle this encoding name.
                throw new ArgumentException (String.Format ("Encoding name '{0}' not "
                        + "supported", name), "name");
@@ -708,11 +681,7 @@ public abstract class Encoding
        // Get a hash code for this instance.
        public override int GetHashCode ()
        {
-#if NET_2_0
                return DecoderFallback.GetHashCode () << 24 + EncoderFallback.GetHashCode () << 16 + codePage;
-#else
-               return codePage;
-#endif
        }
 
        // Get the maximum number of bytes needed to encode a
@@ -726,7 +695,7 @@ public abstract class Encoding
        // Get the identifying preamble for this encoding.
        public virtual byte[] GetPreamble ()
        {
-               return new byte [0];
+               return EmptyArray<byte>.Value;
        }
 
        // Decode a buffer of bytes into a string.
@@ -744,13 +713,13 @@ public abstract class Encoding
 
 #if !ECMA_COMPAT
 
-       internal string body_name;
-       internal string encoding_name;
-       internal string header_name;
        internal bool is_mail_news_display;
        internal bool is_mail_news_save;
        internal bool is_browser_save = false;
        internal bool is_browser_display = false;
+       internal string body_name;
+       internal string encoding_name;
+       internal string header_name;
        internal string web_name;
 
        // Get the mail body name for this encoding.
@@ -846,11 +815,9 @@ public abstract class Encoding
        static volatile Encoding utf8EncodingWithoutMarkers;
        static volatile Encoding unicodeEncoding;
        static volatile Encoding isoLatin1Encoding;
-       static volatile Encoding unixConsoleEncoding;
-#if NET_2_0
+       static volatile Encoding utf8EncodingUnsafe;
        static volatile Encoding utf32Encoding;
        static volatile Encoding bigEndianUTF32Encoding;
-#endif
 
        static readonly object lockobj = new object ();
 
@@ -862,7 +829,7 @@ public abstract class Encoding
                                lock (lockobj) {
                                        if (asciiEncoding == null) {
                                                asciiEncoding = new ASCIIEncoding ();
-                                               asciiEncoding.is_readonly = true;
+//                                             asciiEncoding.is_readonly = true;
                                        }
                                }
                        }
@@ -879,7 +846,7 @@ public abstract class Encoding
                                lock (lockobj) {
                                        if (bigEndianEncoding == null) {
                                                bigEndianEncoding = new UnicodeEncoding (true, true);
-                                               bigEndianEncoding.is_readonly = true;
+//                                             bigEndianEncoding.is_readonly = true;
                                        }
                                }
                        }
@@ -915,17 +882,27 @@ public abstract class Encoding
                                                                case 3: code_page = UTF8Encoding.UTF8_CODE_PAGE; break;
                                                                case 4: code_page = UnicodeEncoding.UNICODE_CODE_PAGE; break;
                                                                case 5: code_page = UnicodeEncoding.BIG_UNICODE_CODE_PAGE; break;
+#if !MOONLIGHT
                                                                case 6: code_page = Latin1Encoding.ISOLATIN_CODE_PAGE; break;
+#endif
                                                                }
                                                                defaultEncoding = GetEncoding (code_page);
                                                        }
                                                } catch (NotSupportedException) {
+#if MOONLIGHT
+                                                       defaultEncoding = UTF8;
+#else
                                                        // code_page is not supported on underlying platform
                                                        defaultEncoding = UTF8Unmarked;
+#endif
                                                } catch (ArgumentException) {
                                                        // code_page_name is not a valid code page, or is 
                                                        // not supported by underlying OS
+#if MOONLIGHT
+                                                       defaultEncoding = UTF8;
+#else
                                                        defaultEncoding = UTF8Unmarked;
+#endif
                                                }
                                                defaultEncoding.is_readonly = true;
                                        }
@@ -936,6 +913,8 @@ public abstract class Encoding
                }
        }
 
+#if !MOONLIGHT
+
        // Get the ISO Latin1 encoding object.
        private static Encoding ISOLatin1
        {
@@ -944,7 +923,7 @@ public abstract class Encoding
                                lock (lockobj) {
                                        if (isoLatin1Encoding == null) {
                                                isoLatin1Encoding = new Latin1Encoding ();
-                                               isoLatin1Encoding.is_readonly = true;
+//                                             isoLatin1Encoding.is_readonly = true;
                                        }
                                }
                        }
@@ -953,6 +932,8 @@ public abstract class Encoding
                }
        }
 
+#endif
+
        // Get the standard UTF-7 encoding object.
 #if ECMA_COMPAT
        private
@@ -966,7 +947,7 @@ public abstract class Encoding
                                lock (lockobj) {
                                        if (utf7Encoding == null) {
                                                utf7Encoding = new UTF7Encoding ();
-                                               utf7Encoding.is_readonly = true;
+//                                             utf7Encoding.is_readonly = true;
                                        }
                                }
                        }
@@ -983,7 +964,7 @@ public abstract class Encoding
                                lock (lockobj) {
                                        if (utf8EncodingWithMarkers == null) {
                                                utf8EncodingWithMarkers = new UTF8Encoding (true);
-                                               utf8EncodingWithMarkers.is_readonly = true;
+//                                             utf8EncodingWithMarkers.is_readonly = true;
                                        }
                                }
                        }
@@ -1001,7 +982,7 @@ public abstract class Encoding
                                lock (lockobj){
                                        if (utf8EncodingWithoutMarkers == null){
                                                utf8EncodingWithoutMarkers = new UTF8Encoding (false, false);
-                                               utf8EncodingWithoutMarkers.is_readonly = true;
+//                                             utf8EncodingWithoutMarkers.is_readonly = true;
                                        }
                                }
                        }
@@ -1010,6 +991,26 @@ public abstract class Encoding
                }
        }
        
+       //
+       // Only internal, to be used by the class libraries: Unmarked and non-input-validating
+       //
+       internal static Encoding UTF8UnmarkedUnsafe {
+               get {
+                       if (utf8EncodingUnsafe == null) {
+                               lock (lockobj){
+                                       if (utf8EncodingUnsafe == null){
+                                               utf8EncodingUnsafe = new UTF8Encoding (false, false);
+                                               utf8EncodingUnsafe.is_readonly = false;
+                                               utf8EncodingUnsafe.DecoderFallback = new DecoderReplacementFallback (String.Empty);
+                                               utf8EncodingUnsafe.is_readonly = true;
+                                       }
+                               }
+                       }
+
+                       return utf8EncodingUnsafe;
+               }
+       }
+       
        // Get the standard little-endian Unicode encoding object.
        public static Encoding Unicode
        {
@@ -1018,7 +1019,7 @@ public abstract class Encoding
                                lock (lockobj) {
                                        if (unicodeEncoding == null) {
                                                unicodeEncoding = new UnicodeEncoding (false, true);
-                                               unicodeEncoding.is_readonly = true;
+//                                             unicodeEncoding.is_readonly = true;
                                        }
                                }
                        }
@@ -1027,7 +1028,6 @@ public abstract class Encoding
                }
        }
 
-#if NET_2_0
        // Get the standard little-endian UTF-32 encoding object.
        public static Encoding UTF32
        {
@@ -1036,7 +1036,7 @@ public abstract class Encoding
                                lock (lockobj) {
                                        if (utf32Encoding == null) {
                                                utf32Encoding = new UTF32Encoding (false, true);
-                                               utf32Encoding.is_readonly = true;
+//                                             utf32Encoding.is_readonly = true;
                                        }
                                }
                        }
@@ -1046,14 +1046,14 @@ public abstract class Encoding
        }
 
        // Get the standard big-endian UTF-32 encoding object.
-       private static Encoding BigEndianUTF32
+       internal static Encoding BigEndianUTF32
        {
                get {
                        if (bigEndianUTF32Encoding == null) {
                                lock (lockobj) {
                                        if (bigEndianUTF32Encoding == null) {
                                                bigEndianUTF32Encoding = new UTF32Encoding (true, true);
-                                               bigEndianUTF32Encoding.is_readonly = true;
+//                                             bigEndianUTF32Encoding.is_readonly = true;
                                        }
                                }
                        }
@@ -1061,7 +1061,6 @@ public abstract class Encoding
                        return bigEndianUTF32Encoding;
                }
        }
-#endif
 
        // Forwarding decoder implementation.
        private sealed class ForwardingDecoder : Decoder
@@ -1072,9 +1071,9 @@ public abstract class Encoding
                public ForwardingDecoder (Encoding enc)
                {
                        encoding = enc;
-#if NET_2_0
-                       Fallback = encoding.DecoderFallback;
-#endif
+                       DecoderFallback fallback = encoding.DecoderFallback;
+                       if (fallback != null)
+                               Fallback = fallback;
                }
 
                // Override inherited methods.
@@ -1100,9 +1099,9 @@ public abstract class Encoding
                public ForwardingEncoder (Encoding enc)
                {
                        encoding = enc;
-#if NET_2_0
-                       Fallback = encoding.EncoderFallback;
-#endif
+                       EncoderFallback fallback = encoding.EncoderFallback;
+                       if (fallback != null)
+                               Fallback = fallback;
                }
 
                // Override inherited methods.
@@ -1119,7 +1118,6 @@ public abstract class Encoding
 
        } // class ForwardingEncoder
 
-#if NET_2_0
        [CLSCompliantAttribute(false)]
        [ComVisible (false)]
        public unsafe virtual int GetByteCount (char *chars, int count)
@@ -1206,8 +1204,6 @@ public abstract class Encoding
                
                return b.Length;
        }
-#endif
-
 }; // class Encoding
 
 }; // namespace System.Text