using System.Reflection;
using UUtil = Mono.Globalization.Unicode.MSCompatUnicodeTableUtil;
+using PtrStream = System.IO.UnmanagedMemoryStream;
namespace Mono.Globalization.Unicode
{
#endregion
- internal class MSCompatUnicodeTable
+ unsafe internal class MSCompatUnicodeTable
{
public static TailoringInfo GetTailoringInfo (int lcid)
{
}
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).
#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);
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;
.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
// 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")) {
tailoringInfos [i] = ti;
}
reader.ReadByte (); // dummy
- IsHiragana ((char) reader.ReadByte ()); // dummy
+ reader.ReadByte (); // dummy
// tailorings
count = reader.ReadInt32 ();
tailorings = new char [count];
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,
}
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;
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) {
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;
}
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;
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;
}
*/
- 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;
#endregion
- byte Category (int cp)
+ unsafe byte Category (int cp)
{
if (cp < 0x3000 || cjkTable == null)
return Uni.Category (cp);
Uni.Category (cp);
}
- byte Level1 (int cp)
+ unsafe byte Level1 (int cp)
{
if (cp < 0x3000 || cjkTable == null)
return Uni.Level1 (cp);
Uni.Level1 (cp);
}
- byte Level2 (int cp, ExtenderType ext)
+ unsafe byte Level2 (int cp, ExtenderType ext)
{
if (ext == ExtenderType.Buggy)
return 5;
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);
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
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
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
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
// 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
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);
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: 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
System.Globalization/TextElementEnumerator.cs
Index: Makefile
===================================================================
---- Makefile (revision 47350)
+--- Makefile (revision 47495)
+++ Makefile (working copy)
@@ -3,13 +3,24 @@
include ../../build/rules.make
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)
/* 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;
}
}
+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