2005-07-22 Atsushi Enomoto <atsushi@ximian.com>
authorAtsushi Eno <atsushieno@gmail.com>
Fri, 22 Jul 2005 09:20:13 +0000 (09:20 -0000)
committerAtsushi Eno <atsushieno@gmail.com>
Fri, 22 Jul 2005 09:20:13 +0000 (09:20 -0000)
* SimpleCollator.cs,
  MSCompatUnicodeTable.cs,
  create-mscompat-collation-table.cs : Now they use unmanaged pointers
  instead of managed arrays.
* managed-collation.patch : Now it contains patch for IntPtrStream.cs
  and Assembly.cs as well.

svn path=/trunk/mcs/; revision=47552

mcs/class/corlib/Mono.Globalization.Unicode/ChangeLog
mcs/class/corlib/Mono.Globalization.Unicode/MSCompatUnicodeTable.cs
mcs/class/corlib/Mono.Globalization.Unicode/SimpleCollator.cs
mcs/class/corlib/Mono.Globalization.Unicode/create-mscompat-collation-table.cs
mcs/class/corlib/Mono.Globalization.Unicode/managed-collation.patch

index 97c4ab718128c451bfa48bf13b2ff8ad0f1c70fc..fbcb5abd4eac543760dea7d204a52332f87e4b30 100644 (file)
@@ -1,3 +1,12 @@
+2005-07-22  Atsushi Enomoto  <atsushi@ximian.com>
+
+       * SimpleCollator.cs,
+         MSCompatUnicodeTable.cs,
+         create-mscompat-collation-table.cs : Now they use unmanaged pointers
+         instead of managed arrays.
+       * managed-collation.patch : Now it contains patch for IntPtrStream.cs
+         and Assembly.cs as well.
+
 2005-07-22  Atsushi Enomoto  <atsushi@ximian.com>
 
        * MSCompatUnicodeTable.cs,
index 7bf498748b94f0c091460addc134fdd5f1496eb2..0f71862a53283c2432c8b760c7154abd985b5a10 100644 (file)
@@ -5,6 +5,7 @@ using System.IO;
 using System.Reflection;
 
 using UUtil = Mono.Globalization.Unicode.MSCompatUnicodeTableUtil;
+using PtrStream = System.IO.UnmanagedMemoryStream;
 
 namespace Mono.Globalization.Unicode
 {
@@ -97,7 +98,7 @@ namespace Mono.Globalization.Unicode
 
        #endregion
 
-       internal class MSCompatUnicodeTable
+       unsafe internal class MSCompatUnicodeTable
        {
                public static TailoringInfo GetTailoringInfo (int lcid)
                {
@@ -170,8 +171,8 @@ namespace Mono.Globalization.Unicode
                }
 
                static void SetCJKReferences (string name,
-                       ref ushort [] cjkTable, ref CodePointIndexer cjkIndexer,
-                       ref byte [] cjkLv2Table, ref CodePointIndexer cjkLv2Indexer)
+                       ref ushort* cjkTable, ref CodePointIndexer cjkIndexer,
+                       ref byte* cjkLv2Table, ref CodePointIndexer cjkLv2Indexer)
                {
                        // as a part of mscorlib.dll, this invocation is
                        // somewhat extraneous (pointers were already assigned).
@@ -354,13 +355,63 @@ namespace Mono.Globalization.Unicode
 
                #endregion
 
+
+               static readonly byte* ignorableFlags;
+               static readonly byte* categories;
+               static readonly byte* level1;
+               static readonly byte* level2;
+               static readonly byte* level3;
+               static readonly ushort* widthCompat;
+               static ushort* cjkCHS;
+               static ushort* cjkCHT;
+               static ushort* cjkJA;
+               static ushort* cjkKO;
+               static byte* cjkKOlv2;
+
 #if GENERATE_TABLE
 
                public static readonly bool IsReady = true; // always
 
+               static MSCompatUnicodeTable ()
+               {
+                       fixed (byte* tmp = ignorableFlagsArr) {
+                               ignorableFlags = tmp;
+                       }
+                       fixed (byte* tmp = categoriesArr) {
+                               categories = tmp;
+                       }
+                       fixed (byte* tmp = level1Arr) {
+                               level1 = tmp;
+                       }
+                       fixed (byte* tmp = level2Arr) {
+                               level2 = tmp;
+                       }
+                       fixed (byte* tmp = level3Arr) {
+                               level3 = tmp;
+                       }
+                       fixed (ushort* tmp = widthCompatArr) {
+                               widthCompat = tmp;
+                       }
+                       fixed (ushort* tmp = cjkCHSArr) {
+                               cjkCHS = tmp;
+                       }
+                       fixed (ushort* tmp = cjkCHTArr) {
+                               cjkCHT = tmp;
+                       }
+                       fixed (ushort* tmp = cjkJAArr) {
+                               cjkJA = tmp;
+                       }
+                       fixed (ushort* tmp = cjkKOArr) {
+                               cjkKO = tmp;
+                       }
+                       fixed (byte* tmp = cjkKOlv2Arr) {
+                               cjkKOlv2 = tmp;
+                       }
+               }
+
                public static void FillCJK (string name,
-                       ref ushort [] cjkTable, ref CodePointIndexer cjkIndexer,
-                       ref byte [] cjkLv2Table, ref CodePointIndexer cjkLv2Indexer)
+                       ref ushort* cjkTable, ref CodePointIndexer cjkIndexer,
+                       ref byte* cjkLv2Table, ref CodePointIndexer cjkLv2Indexer)
                {
                        SetCJKReferences (name, ref cjkTable, ref cjkIndexer,
                                ref cjkLv2Table, ref cjkLv2Indexer);
@@ -369,17 +420,6 @@ namespace Mono.Globalization.Unicode
 
                static readonly char [] tailorings;
                static readonly TailoringInfo [] tailoringInfos;
-               static readonly byte [] ignorableFlags;
-               static readonly byte [] categories;
-               static readonly byte [] level1;
-               static readonly byte [] level2;
-               static readonly byte [] level3;
-               static readonly ushort [] widthCompat;
-               static ushort [] cjkCHS;
-               static ushort [] cjkCHT;
-               static ushort [] cjkJA;
-               static ushort [] cjkKO;
-               static byte [] cjkKOlv2;
                static object forLock = new object ();
 
                public static readonly bool IsReady = false;
@@ -390,9 +430,21 @@ namespace Mono.Globalization.Unicode
                                .GetManifestResourceStream (name);
                }
 
+               static uint ReadUInt32FromStream (Stream s)
+               {
+                       return (uint) (s.ReadByte () + (s.ReadByte () << 8) +
+                               (s.ReadByte () << 16) + (s.ReadByte () << 24));
+               }
+
+               static ushort ReadUInt16FromStream (Stream s)
+               {
+                       return (ushort) (s.ReadByte () + (s.ReadByte () << 8));
+               }
+
                static MSCompatUnicodeTable ()
                {
                        using (Stream s = GetResource ("collation.core.bin")) {
+                               PtrStream ms = s as PtrStream;
                                // FIXME: remove those lines later.
                                // actually this line should not be required,
                                // but when we switch from the corlib that
@@ -401,20 +453,18 @@ namespace Mono.Globalization.Unicode
                                // the corlib that runtime kicked and returns
                                // null (because old one does not have it).
                                // In such cases managed collation won't work.
-                               if (s == null)
+                               if (ms == null)
                                        return;
 
-                               BinaryReader reader = new BinaryReader (s);
-                               FillTable (reader, ref ignorableFlags);
-                               FillTable (reader, ref categories);
-                               FillTable (reader, ref level1);
-                               FillTable (reader, ref level2);
-                               FillTable (reader, ref level3);
-
-                               int size = reader.ReadInt32 ();
-                               widthCompat = new ushort [size];
-                               for (int i = 0; i < size; i++)
-                                       widthCompat [i] = reader.ReadUInt16 ();
+                               FillTable (ms, ref ignorableFlags);
+                               FillTable (ms, ref categories);
+                               FillTable (ms, ref level1);
+                               FillTable (ms, ref level2);
+                               FillTable (ms, ref level3);
+
+                               uint size = ReadUInt32FromStream (s);
+                               widthCompat = (ushort*) ((void*) ms.PositionPointer);
+                               ms.Seek (size * 2, SeekOrigin.Current);
                        }
 
                        using (Stream s = GetResource ("collation.tailoring.bin")) {
@@ -435,7 +485,7 @@ namespace Mono.Globalization.Unicode
                                        tailoringInfos [i] = ti;
                                }
                                reader.ReadByte (); // dummy
-                               IsHiragana ((char) reader.ReadByte ()); // dummy
+                               reader.ReadByte (); // dummy
                                // tailorings
                                count = reader.ReadInt32 ();
                                tailorings = new char [count];
@@ -446,16 +496,16 @@ namespace Mono.Globalization.Unicode
                        IsReady = true;
                }
 
-               static void FillTable (BinaryReader reader, ref byte [] bytes)
+               static void FillTable (PtrStream s, ref byte* bytes)
                {
-                       int size = reader.ReadInt32 ();
-                       bytes = new byte [size];
-                       reader.Read (bytes, 0, size);
+                       uint size = ReadUInt32FromStream (s);
+                       bytes = (byte*) ((void*) s.PositionPointer);
+                       s.Seek (size, SeekOrigin.Current);
                }
 
                public static void FillCJK (string culture,
-                       ref ushort [] cjkTable, ref CodePointIndexer cjkIndexer,
-                       ref byte [] cjkLv2Table, ref CodePointIndexer cjkLv2Indexer)
+                       ref ushort* cjkTable, ref CodePointIndexer cjkIndexer,
+                       ref byte* cjkLv2Table, ref CodePointIndexer cjkLv2Indexer)
                {
                        lock (forLock) {
                                FillCJKCore (culture,
@@ -467,8 +517,8 @@ namespace Mono.Globalization.Unicode
                }
 
                static void FillCJKCore (string culture,
-                       ref ushort [] cjkTable, ref CodePointIndexer cjkIndexer,
-                       ref byte [] cjkLv2Table, ref CodePointIndexer cjkLv2Indexer)
+                       ref ushort* cjkTable, ref CodePointIndexer cjkIndexer,
+                       ref byte* cjkLv2Table, ref CodePointIndexer cjkLv2Indexer)
                {
                        if (!IsReady)
                                return;
@@ -497,11 +547,12 @@ namespace Mono.Globalization.Unicode
                                return;
 
                        using (Stream s = GetResource (String.Format ("collation.{0}.bin", name))) {
-                               BinaryReader reader = new BinaryReader (s);
-                               int size = reader.ReadInt32 ();
-                               cjkTable = new ushort [size];
-                               for (int i = 0; i < size; i++)
-                                       cjkTable [i] = reader.ReadUInt16 ();
+                               PtrStream ms = s as PtrStream;
+                               if (ms != null) {
+                                       uint size = ReadUInt32FromStream (s);
+                                       cjkTable = (ushort*) ((void*) ms.PositionPointer);
+                                       ms.Seek (size * 2, SeekOrigin.Current);
+                               }
                        }
 
                        switch (culture) {
@@ -522,8 +573,9 @@ namespace Mono.Globalization.Unicode
                        if (name != "cjkKO")
                                return;
                        using (Stream s = GetResource ("collation.cjkKOlv2.bin")) {
-                               BinaryReader reader = new BinaryReader (s);
-                               FillTable (reader, ref cjkKOlv2);
+                               PtrStream ms = s as PtrStream;
+                               if (ms != null)
+                                       FillTable (ms, ref cjkKOlv2);
                        }
                        cjkLv2Table = cjkKOlv2;
                }
index 144ec5610afff198dce8b9b7e9d5dec1041acfd7..4ef63017e35b762a19e18fb2a056cfb91c3c3ae0 100644 (file)
@@ -71,9 +71,9 @@ namespace Mono.Globalization.Unicode
                bool ignoreKanaType;
                TextInfo textInfo; // for ToLower().
                bool frenchSort;
-               readonly ushort [] cjkTable;
+               unsafe readonly ushort* cjkTable;
                readonly CodePointIndexer cjkIndexer;
-               readonly byte [] cjkLv2Table;
+               unsafe readonly byte* cjkLv2Table;
                readonly CodePointIndexer cjkLv2Indexer;
                readonly int lcid;
                readonly Contraction [] contractions;
@@ -92,8 +92,11 @@ namespace Mono.Globalization.Unicode
                        textInfo = culture.TextInfo;
                        buf = new SortKeyBuffer (culture.LCID);
 
-                       SetCJKTable (culture, ref cjkTable, ref cjkIndexer,
-                               ref cjkLv2Table, ref cjkLv2Indexer);
+                       unsafe {
+                               SetCJKTable (culture,
+                                       ref cjkTable, ref cjkIndexer,
+                                       ref cjkLv2Table, ref cjkLv2Indexer);
+                       }
 
                        // Get tailoring info
                        TailoringInfo t = null;
@@ -189,9 +192,9 @@ Console.WriteLine (" -> '{0}'", c.Replacement);
                }
 */
 
-               private void SetCJKTable (CultureInfo culture,
-                       ref ushort [] cjkTable, ref CodePointIndexer cjkIndexer,
-                       ref byte [] cjkLv2Table, ref CodePointIndexer cjkLv2Indexer)
+               unsafe private void SetCJKTable (CultureInfo culture,
+                       ref ushort* cjkTable, ref CodePointIndexer cjkIndexer,
+                       ref byte* cjkLv2Table, ref CodePointIndexer cjkLv2Indexer)
                {
                        string name = GetNeutralCulture (culture).Name;
 
@@ -208,7 +211,7 @@ Console.WriteLine (" -> '{0}'", c.Replacement);
 
                #endregion
 
-               byte Category (int cp)
+               unsafe byte Category (int cp)
                {
                        if (cp < 0x3000 || cjkTable == null)
                                return Uni.Category (cp);
@@ -218,7 +221,7 @@ Console.WriteLine (" -> '{0}'", c.Replacement);
                                Uni.Category (cp);
                }
 
-               byte Level1 (int cp)
+               unsafe byte Level1 (int cp)
                {
                        if (cp < 0x3000 || cjkTable == null)
                                return Uni.Level1 (cp);
@@ -228,7 +231,7 @@ Console.WriteLine (" -> '{0}'", c.Replacement);
                                Uni.Level1 (cp);
                }
 
-               byte Level2 (int cp, ExtenderType ext)
+               unsafe byte Level2 (int cp, ExtenderType ext)
                {
                        if (ext == ExtenderType.Buggy)
                                return 5;
index 40e4a66436b96b2e0b5542af14336c6560065615..eb4ebba19e8cc40130f51c03b00e54c77aaa3858 100644 (file)
@@ -338,7 +338,7 @@ sw.Close ();
                        cjkKOlv2 = CompressArray (cjkKOlv2, UUtil.Cjk);
 
                        // Ignorables
-                       Result.WriteLine ("static readonly byte [] ignorableFlags = new byte [] {");
+                       Result.WriteLine ("static readonly byte [] ignorableFlagsArr = new byte [] {");
 #if Binary
                        MemoryStream ms = new MemoryStream ();
                        BinaryWriter binary = new BinaryWriter (ms);
@@ -361,7 +361,7 @@ sw.Close ();
                        Result.WriteLine ();
 
                        // Primary category
-                       Result.WriteLine ("static readonly byte [] categories = new byte [] {");
+                       Result.WriteLine ("static readonly byte [] categoriesArr = new byte [] {");
 #if Binary
                        binary.Write (categories.Length);
 #endif
@@ -382,7 +382,7 @@ sw.Close ();
                        Result.WriteLine ();
 
                        // Primary weight value
-                       Result.WriteLine ("static readonly byte [] level1 = new byte [] {");
+                       Result.WriteLine ("static readonly byte [] level1Arr = new byte [] {");
 #if Binary
                        binary.Write (level1.Length);
 #endif
@@ -403,7 +403,7 @@ sw.Close ();
                        Result.WriteLine ();
 
                        // Secondary weight
-                       Result.WriteLine ("static readonly byte [] level2 = new byte [] {");
+                       Result.WriteLine ("static readonly byte [] level2Arr = new byte [] {");
 #if Binary
                        binary.Write (level2.Length);
 #endif
@@ -424,7 +424,7 @@ sw.Close ();
                        Result.WriteLine ();
 
                        // Thirtiary weight
-                       Result.WriteLine ("static readonly byte [] level3 = new byte [] {");
+                       Result.WriteLine ("static readonly byte [] level3Arr = new byte [] {");
 #if Binary
                        binary.Write (level3.Length);
 #endif
@@ -447,7 +447,7 @@ sw.Close ();
                        // Width insensitivity mappings
                        // (for now it is more lightweight than dumping the
                        // entire NFKD table).
-                       Result.WriteLine ("static readonly ushort [] widthCompat = new ushort [] {");
+                       Result.WriteLine ("static readonly ushort [] widthCompatArr = new ushort [] {");
 #if Binary
                        binary.Write (widthCompat.Length);
 #endif
@@ -484,7 +484,7 @@ sw.Close ();
                void SerializeCJK (string name, ushort [] cjk, int max)
                {
                        int offset = 0;//char.MaxValue - cjk.Length;
-                       Result.WriteLine ("static ushort [] {0} = new ushort [] {{", name);
+                       Result.WriteLine ("static ushort [] {0}Arr = new ushort [] {{", name);
 #if Binary
                        MemoryStream ms = new MemoryStream ();
                        BinaryWriter binary = new BinaryWriter (ms);
@@ -517,7 +517,7 @@ sw.Close ();
                void SerializeCJK (string name, byte [] cjk, int max)
                {
                        int offset = 0;//char.MaxValue - cjk.Length;
-                       Result.WriteLine ("static byte [] {0} = new byte [] {{", name);
+                       Result.WriteLine ("static byte [] {0}Arr = new byte [] {{", name);
 #if Binary
                        MemoryStream ms = new MemoryStream ();
                        BinaryWriter binary = new BinaryWriter (ms);
index 8f57542134710632a1cd7c75b0fb83839fb2a47a..1faabe8cec391df74700299afcdcf781adf817bb 100644 (file)
@@ -1,6 +1,6 @@
 Index: corlib.dll.sources
 ===================================================================
---- corlib.dll.sources (revision 47350)
+--- corlib.dll.sources (revision 47495)
 +++ corlib.dll.sources (working copy)
 @@ -8,6 +8,12 @@
  Microsoft.Win32/Win32RegistryApi.cs
@@ -25,7 +25,7 @@ Index: corlib.dll.sources
  System.Globalization/TextElementEnumerator.cs
 Index: Makefile
 ===================================================================
---- Makefile   (revision 47350)
+--- Makefile   (revision 47495)
 +++ Makefile   (working copy)
 @@ -3,13 +3,24 @@
  include ../../build/rules.make
@@ -55,7 +55,7 @@ Index: Makefile
  LIBRARY_NAME = mscorlib.dll
 Index: System/String.cs
 ===================================================================
---- System/String.cs   (revision 47350)
+--- System/String.cs   (revision 47495)
 +++ System/String.cs   (working copy)
 @@ -746,7 +746,7 @@
                        if (this.length < value.length)
@@ -68,7 +68,7 @@ Index: System/String.cs
                /* This method is culture insensitive */
 Index: System.Globalization/CompareInfo.cs
 ===================================================================
---- System.Globalization/CompareInfo.cs        (revision 47350)
+--- System.Globalization/CompareInfo.cs        (revision 47495)
 +++ System.Globalization/CompareInfo.cs        (working copy)
 @@ -34,12 +34,25 @@
  using System.Reflection;
@@ -489,3 +489,98 @@ Index: System.Globalization/CompareInfo.cs
                        }
                }
  
+Index: System.IO/IntPtrStream.cs
+===================================================================
+--- System.IO/IntPtrStream.cs  (revision 47495)
++++ System.IO/IntPtrStream.cs  (working copy)
+@@ -1,5 +1,5 @@
+ //
+-// System.IO.IntPtrStream: A stream that is backed up by unmanaged memory
++// System.IO.UnmanagedMemoryStream: A stream that is backed up by unmanaged memory
+ //
+ // Author:
+ //   Miguel de Icaza (miguel@ximian.com)
+@@ -40,23 +40,31 @@
+ using System.Runtime.InteropServices;
+ namespace System.IO {
+-      internal class IntPtrStream : Stream {
++#if NET_2_0
++      public
++#else
++      internal
++#endif
++      class UnmanagedMemoryStream : Stream {
+               unsafe byte *base_address;
+-              int size;
+-              int position;
++              long size;
++              long position;
+               bool closed;
+               public event EventHandler Closed;
+-              
+-              public IntPtrStream (IntPtr base_address, int size)
++
++              [CLSCompliant (false)]
++              public unsafe UnmanagedMemoryStream (byte *base_address, long size)
+               {
+-                      unsafe {
+-                              this.base_address = (byte*)((void *)base_address);
+-                      }
++                      this.base_address = base_address;
+                       this.size = size;
+                       position = 0;
+               }
++              public IntPtr PositionPointer {
++                      get { unsafe { return new IntPtr (base_address + position); } }
++              }
++
+               public override bool CanRead {
+                       get {
+                               return true;
+@@ -115,7 +123,7 @@
+                               return 0;
+                       if (position > size - count)
+-                              count = size - position;
++                              count = (int) (size - position);
+                       unsafe {
+                               Marshal.Copy ((IntPtr) (base_address + position), buffer, offset, count);
+@@ -146,7 +154,7 @@
+                       if (closed)
+                               throw new ObjectDisposedException ("Stream has been closed");
+-                      int ref_point;
++                      long ref_point;
+                       switch (loc) {
+                       case SeekOrigin.Begin:
+                               if (offset < 0)
+@@ -165,7 +173,7 @@
+                       checked {
+                               try {
+-                                      ref_point += (int) offset;
++                                      ref_point += offset;
+                               } catch {
+                                       throw new ArgumentOutOfRangeException ("Too large seek destination");
+                               }
+Index: System.Reflection/Assembly.cs
+===================================================================
+--- System.Reflection/Assembly.cs      (revision 47495)
++++ System.Reflection/Assembly.cs      (working copy)
+@@ -274,7 +274,11 @@
+                       if (data == (IntPtr) 0)
+                               return null;
+                       else {
+-                              IntPtrStream stream = new IntPtrStream (data, size);
++                              UnmanagedMemoryStream stream = null;
++                              unsafe {
++                                      stream = new UnmanagedMemoryStream (
++                                              (byte*) ((void *) data), size);
++                              }
+                               /* 
+                                * The returned pointer points inside metadata, so
+                                * we have to increase the refcount of the module, and decrease