[encoding] as part of referencesource import, use new EncodingHelper class.
authorAtsushi Eno <atsushieno@gmail.com>
Thu, 12 Feb 2015 20:24:47 +0000 (04:24 +0800)
committerAtsushi Eno <atsushieno@gmail.com>
Thu, 12 Feb 2015 20:24:47 +0000 (04:24 +0800)
This will remain after importing referencesource and offer mono-only
internals for some classes. This involves icall (owner class) change.

mcs/class/corlib/System.IO/BinaryReader.cs
mcs/class/corlib/System.IO/BinaryWriter.cs
mcs/class/corlib/System.IO/File.cs
mcs/class/corlib/System.IO/StreamReader.cs
mcs/class/corlib/System.IO/StreamWriter.cs
mcs/class/corlib/System.Text/EncodingHelper.cs [new file with mode: 0644]
mcs/class/corlib/System/Console.cs
mcs/class/corlib/corlib.dll.sources
mono/metadata/icall-def.h
mono/metadata/icall.c

index 0ee3a5c94c4621dacb0bc354d9c04c66ed96a0fc..73235c9c23d14f10337b09296ca8ca8d80a01623 100644 (file)
@@ -58,7 +58,7 @@ namespace System.IO {
                private bool m_disposed;
                
                public BinaryReader(Stream input) 
-                       : this(input, Encoding.UTF8UnmarkedUnsafe)
+                       : this(input, EncodingHelper.UTF8UnmarkedUnsafe)
                {
                }
                
index 292573c45ac7429bdc673b0779d8971d6408332e..e433115ea629b4fed017caed31c896cc5bc25184 100644 (file)
@@ -51,11 +51,11 @@ namespace System.IO {
                int maxCharsPerRound;
                bool disposed;
 
-               protected BinaryWriter() : this (Stream.Null, Encoding.UTF8UnmarkedUnsafe)
+               protected BinaryWriter() : this (Stream.Null, EncodingHelper.UTF8UnmarkedUnsafe)
                {
                }
 
-               public BinaryWriter(Stream output) : this(output, Encoding.UTF8UnmarkedUnsafe)
+               public BinaryWriter(Stream output) : this(output, EncodingHelper.UTF8UnmarkedUnsafe)
                {
                }
                
index de1758611c936cd78e37e8310a5ae226f906e8c9..8f4b57290c822e271064aadd68ae09223bed966d 100644 (file)
@@ -575,7 +575,7 @@ namespace System.IO
 
                public static void WriteAllText (string path, string contents)
                {
-                       WriteAllText (path, contents, Encoding.UTF8Unmarked);
+                       WriteAllText (path, contents, EncodingHelper.UTF8Unmarked);
                }
 
                public static void WriteAllText (string path, string contents, Encoding encoding)
index 1adf8ab51accd07f3c00a3cf6da0fe55097338b3..e32675a0a994d8db4bcef8ddc7aed5fc7bf95855 100644 (file)
@@ -328,7 +328,7 @@ namespace System.IO {
                                        return 0;
 
                                if (input_buffer [0] == 0xef && input_buffer [1] == 0xbb && input_buffer [2] == 0xbf){
-                                       this.encoding = Encoding.UTF8Unmarked;
+                                       this.encoding = EncodingHelper.UTF8Unmarked;
                                        return 3;
                                }
 
@@ -343,7 +343,7 @@ namespace System.IO {
                                if (input_buffer [0] == 0 && input_buffer [1] == 0
                                        && input_buffer [2] == 0xfe && input_buffer [3] == 0xff)
                                {
-                                       this.encoding = Encoding.BigEndianUTF32;
+                                       this.encoding = EncodingHelper.BigEndianUTF32;
                                        return 4;
                                }
 
index ef4e866f3c4bf1fc8c627f2257fb315fa2aca0f1..73aeac939aa418268c4e486f90e7b623701d9536 100644 (file)
@@ -59,10 +59,10 @@ namespace System.IO {
                readonly bool leave_open;\r
                IDecoupledTask async_task;\r
 \r
-               public new static readonly StreamWriter Null = new StreamWriter (Stream.Null, Encoding.UTF8Unmarked, 1);\r
+               public new static readonly StreamWriter Null = new StreamWriter (Stream.Null, EncodingHelper.UTF8Unmarked, 1);\r
 \r
                public StreamWriter (Stream stream)\r
-                       : this (stream, Encoding.UTF8Unmarked, DefaultBufferSize) {}\r
+                       : this (stream, EncodingHelper.UTF8Unmarked, DefaultBufferSize) {}\r
 \r
                public StreamWriter (Stream stream, Encoding encoding)\r
                        : this (stream, encoding, DefaultBufferSize) {}\r
@@ -102,10 +102,10 @@ namespace System.IO {
                }\r
 \r
                public StreamWriter (string path)\r
-                       : this (path, false, Encoding.UTF8Unmarked, DefaultFileBufferSize) {}\r
+                       : this (path, false, EncodingHelper.UTF8Unmarked, DefaultFileBufferSize) {}\r
 \r
                public StreamWriter (string path, bool append)\r
-                       : this (path, append, Encoding.UTF8Unmarked, DefaultFileBufferSize) {}\r
+                       : this (path, append, EncodingHelper.UTF8Unmarked, DefaultFileBufferSize) {}\r
 \r
                public StreamWriter (string path, bool append, Encoding encoding)\r
                        : this (path, append, encoding, DefaultFileBufferSize) {}\r
diff --git a/mcs/class/corlib/System.Text/EncodingHelper.cs b/mcs/class/corlib/System.Text/EncodingHelper.cs
new file mode 100644 (file)
index 0000000..8431257
--- /dev/null
@@ -0,0 +1,195 @@
+using System;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Security;
+
+namespace System.Text
+{
+
+internal static class EncodingHelper
+{
+       //
+       // Only internal, to be used by the class libraries: Unmarked and non-input-validating
+       //
+       internal static Encoding UTF8Unmarked {
+               get {
+                       if (utf8EncodingWithoutMarkers == null) {
+                               lock (lockobj){
+                                       if (utf8EncodingWithoutMarkers == null){
+                                               utf8EncodingWithoutMarkers = new UTF8Encoding (false, false);
+//                                             utf8EncodingWithoutMarkers.is_readonly = true;
+                                       }
+                               }
+                       }
+
+                       return utf8EncodingWithoutMarkers;
+               }
+       }
+       
+       //
+       // 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);
+                                               typeof (Encoding).GetField ("is_readonly", BindingFlags.NonPublic | BindingFlags.Instance).SetValue (utf8EncodingUnsafe, false);
+                                               utf8EncodingUnsafe.DecoderFallback = new DecoderReplacementFallback (String.Empty);
+                                               typeof (Encoding).GetField ("is_readonly", BindingFlags.NonPublic | BindingFlags.Instance).SetValue (utf8EncodingUnsafe, true);
+                                       }
+                               }
+                       }
+
+                       return utf8EncodingUnsafe;
+               }
+       }
+
+       // Get the standard big-endian UTF-32 encoding object.
+       internal static Encoding BigEndianUTF32
+       {
+               get {
+                       if (bigEndianUTF32Encoding == null) {
+                               lock (lockobj) {
+                                       if (bigEndianUTF32Encoding == null) {
+                                               bigEndianUTF32Encoding = new UTF32Encoding (true, true);
+//                                             bigEndianUTF32Encoding.is_readonly = true;
+                                       }
+                               }
+                       }
+
+                       return bigEndianUTF32Encoding;
+               }
+       }
+       static volatile Encoding utf8EncodingWithoutMarkers;
+       static volatile Encoding utf8EncodingUnsafe;
+       static volatile Encoding bigEndianUTF32Encoding;
+       static readonly object lockobj = new object ();
+
+       [MethodImpl (MethodImplOptions.InternalCall)]
+       extern internal static string InternalCodePage (ref int code_page);
+
+       internal static Encoding GetDefaultEncoding ()
+       {
+               Encoding enc = null;
+                                               // See if the underlying system knows what
+                                               // code page handler we should be using.
+                                               int code_page = 1;
+                                               
+                                               string code_page_name = InternalCodePage (ref code_page);
+                                               try {
+                                                       if (code_page == -1)
+                                                               enc = Encoding.GetEncoding (code_page_name);
+                                                       else {
+                                                               // map the codepage from internal to our numbers
+                                                               code_page = code_page & 0x0fffffff;
+                                                               switch (code_page){
+                                                               case 1: code_page = 20127; break; // ASCIIEncoding.ASCII_CODE_PAGE
+                                                               case 2: code_page = 65007; break; // UTF7Encoding.UTF7_CODE_PAGE
+                                                               case 3: code_page = 65001; break; // UTF8Encoding.UTF8_CODE_PAGE
+                                                               case 4: code_page = 1200; break; // UnicodeEncoding.UNICODE_CODE_PAGE
+                                                               case 5: code_page = 1201; break; // UnicodeEncoding.BIG_UNICODE_CODE_PAGE
+                                                               case 6: code_page = 1252; break; // Latin1Encoding.ISOLATIN_CODE_PAGE
+                                                               }
+                                                               enc = Encoding.GetEncoding (code_page);
+                                                       }
+                                               } catch (NotSupportedException) {
+                                                       // code_page is not supported on underlying platform
+                                                       enc = EncodingHelper.UTF8Unmarked;
+                                               } catch (ArgumentException) {
+                                                       // code_page_name is not a valid code page, or is 
+                                                       // not supported by underlying OS
+                                                       enc = EncodingHelper.UTF8Unmarked;
+                                               }
+               return enc;
+       }
+
+       // Loaded copy of the "I18N" assembly.  We need to move
+       // this into a class in "System.Private" eventually.
+       private static Assembly i18nAssembly;
+       private static bool i18nDisabled;
+
+       // Invoke a specific method on the "I18N" manager object.
+       // Returns NULL if the method failed.
+       internal static Object InvokeI18N (String name, params Object[] args)
+       {
+               lock (lockobj) {
+                       // Bail out if we previously detected that there
+                       // is insufficent engine support for I18N handling.
+                       if (i18nDisabled) {
+                               return null;
+                       }
+
+                       // Find or load the "I18N" assembly.
+                       if (i18nAssembly == null) {
+                               try {
+                                       try {
+                                               i18nAssembly = Assembly.Load (Consts.AssemblyI18N);
+                                       } catch (NotImplementedException) {
+                                               // Assembly loading unsupported by the engine.
+                                               i18nDisabled = true;
+                                               return null;
+                                       }
+                                       if (i18nAssembly == null) {
+                                               return null;
+                                       }
+                               } catch (SystemException) {
+                                       return null;
+                               }
+                       }
+
+                       // Find the "I18N.Common.Manager" class.
+                       Type managerClass;
+                       try {
+                               managerClass = i18nAssembly.GetType ("I18N.Common.Manager");
+                       } catch (NotImplementedException) {
+                               // "GetType" is not supported by the engine.
+                               i18nDisabled = true;
+                               return null;
+                       }
+                       if (managerClass == null) {
+                               return null;
+                       }
+
+                       // Get the value of the "PrimaryManager" property.
+                       Object manager;
+                       try {
+                               manager = managerClass.InvokeMember
+                                               ("PrimaryManager",
+                                                BindingFlags.GetProperty |
+                                                       BindingFlags.Static |
+                                                       BindingFlags.Public,
+                                                null, null, null, null, null, null);
+                               if (manager == null) {
+                                       return null;
+                               }
+                       } catch (MissingMethodException) {
+                               return null;
+                       } catch (SecurityException) {
+                               return null;
+                       } catch (NotImplementedException) {
+                               // "InvokeMember" is not supported by the engine.
+                               i18nDisabled = true;
+                               return null;
+                       }
+
+                       // Invoke the requested method on the manager.
+                       try {
+                               return managerClass.InvokeMember
+                                               (name,
+                                                BindingFlags.InvokeMethod |
+                                                       BindingFlags.Instance |
+                                                       BindingFlags.Public,
+                                                null, manager, args, null, null, null);
+                       } catch (MissingMethodException) {
+                               return null;
+                       } catch (SecurityException) {
+                               return null;
+                       }
+               }
+       }
+}
+
+}
\ No newline at end of file
index c0cc6f85e0775ed821ed52817a241796d73301c3..caa92b8446033b1aaa4b8e2a48a1347996afe8b9 100644 (file)
@@ -125,11 +125,11 @@ namespace System
                                // UTF-8 ZWNBSP (zero-width non-breaking space).
                                //
                                int code_page = 0;
-                               Encoding.InternalCodePage (ref code_page);
+                               EncodingHelper.InternalCodePage (ref code_page);
 
                                if (code_page != -1 && ((code_page & 0x0fffffff) == 3 // UTF8Encoding.UTF8_CODE_PAGE
                                        || ((code_page & 0x10000000) != 0)))
-                                       inputEncoding = outputEncoding = Encoding.UTF8Unmarked;
+                                       inputEncoding = outputEncoding = EncodingHelper.UTF8Unmarked;
                                else
                                        inputEncoding = outputEncoding = Encoding.Default;
                        }
index cc33b47564409c14b8ddebc3f1e7e15094ae5519..909e28db3e63f07463e2d2ce166483526ba733b4 100644 (file)
@@ -1375,6 +1375,7 @@ System.Text/Encoding.cs
 System.Text/EncodingEncoder.cs
 System.Text/EncodingDecoder.cs
 System.Text/EncodingInfo.cs
+System.Text/EncodingHelper.cs
 System.Text/Latin1Encoding.cs
 System.Text/MLangCodePageEncoding.cs
 System.Text/NormalizationForm.cs
index 29edd2afa0de071afbda4ba39fceec73183bf30b..c6ac27f86297146a790505b50c154039a7c5c2f9 100644 (file)
@@ -806,8 +806,8 @@ ICALL(STRING_10, "InternalIntern", ves_icall_System_String_InternalIntern)
 ICALL(STRING_11, "InternalIsInterned", ves_icall_System_String_InternalIsInterned)
 ICALL(STRING_12, "InternalSetLength", ves_icall_System_String_InternalSetLength)
 
-ICALL_TYPE(TENC, "System.Text.Encoding", TENC_1)
-ICALL(TENC_1, "InternalCodePage", ves_icall_System_Text_Encoding_InternalCodePage)
+ICALL_TYPE(TENC, "System.Text.EncodingHelper", TENC_1)
+ICALL(TENC_1, "InternalCodePage", ves_icall_System_Text_EncodingHelper_InternalCodePage)
 
 ICALL_TYPE(ILOCK, "System.Threading.Interlocked", ILOCK_1)
 ICALL(ILOCK_1, "Add(int&,int)", ves_icall_System_Threading_Interlocked_Add_Int)
index 838894339eb63bb6903a8ded99f7338ba22274d8..545d7608c14d0d1aa478f39ff372554dd7e21625 100644 (file)
@@ -6505,7 +6505,7 @@ static const char *encodings [] = {
  * returns the code page as a string
  */
 ICALL_EXPORT MonoString*
-ves_icall_System_Text_Encoding_InternalCodePage (gint32 *int_code_page) 
+ves_icall_System_Text_EncodingHelper_InternalCodePage (gint32 *int_code_page) 
 {
        const char *cset;
        const char *p;