*** empty log message ***
authorhanda <handa>
Sat, 11 Jul 2009 07:24:42 +0000 (07:24 +0000)
committerhanda <handa>
Sat, 11 Jul 2009 07:24:42 +0000 (07:24 +0000)
MCharTable.cs [new file with mode: 0644]
MDatabase.cs
MSymbol.cs
Makefile

diff --git a/MCharTable.cs b/MCharTable.cs
new file mode 100644 (file)
index 0000000..6845767
--- /dev/null
@@ -0,0 +1,168 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using M17N;
+using M17N.Core;
+
+namespace M17N.Core
+{
+  public class MCharTable : IEnumerable
+  {
+    private static readonly int[] nchars
+      = new int[] { 0x110000, 0x10000, 0x1000, 0x80 };
+    private static readonly int[] slots
+      = new int[] { 17, 16, 32, 128 };
+    private static readonly int[] mask
+      = new int[] { 0x11FFFF, 0xFFFF, 0xFFF, 0x7F };
+    private static readonly int[] shift
+      = new int[] { 16, 12, 7, 0 };
+
+    private int index (int c) { return ((c & mask[depth]) >> shift[depth]); }
+
+    private MCharTable parent;
+    private int depth;
+    private int min_char, max_char;
+    private object[] contents;
+
+    public MCharTable ()
+      {
+       parent = null;
+       depth = 0;
+       min_char = 0x110000;
+       max_char = 0;
+       contents = new object[slots[0]];
+      }
+
+    private MCharTable (MCharTable parent, int min_char, object value)
+      {
+       this.parent = parent;
+       this.min_char = min_char;
+       depth = parent.depth + 1;
+       max_char = min_char + nchars[depth] - 1;
+       contents = new object[slots[depth]];
+       for (int i = 0; i < slots[depth]; i++)
+         contents[i] = value;
+      }
+
+    private object Get (int c)
+    {
+      object slot = contents[index (c)];
+      if (slot is MCharTable)
+       return ((MCharTable) slot).Get (c);
+      return slot;
+    }
+
+    private void Set (int c, object value)
+    {
+      if (depth == 3)
+       contents[c & mask[3]] = value;
+      else
+       {
+         int i = index (c);
+         int offset = depth == 0 ? 0 : min_char;
+
+         if (! (contents[i] is MCharTable))
+           contents[i] = new MCharTable (this, offset + i << shift[depth],
+                                         contents[i]);
+         ((MCharTable) contents[i]).Set (c, value);
+       }
+    }
+
+    public object this[int c]
+    {
+      get {
+       if (c < 0 || c > 0x10FFFF)
+         throw new ArgumentException ("Invalid character: " + c);
+       if (min_char > c || max_char < c)
+         return null;
+       return Get (c);
+      }
+
+      set {
+       if (c < 0 || c > 0x10FFFF)
+         throw new ArgumentException ("Invalid character: " + c);
+       if (value is MCharTable)
+         throw new ArgumentException ("Invalid value type: MCharTable");
+       if (min_char > c)
+         min_char = c;
+       if (max_char < c)
+         max_char = c;
+       Set (c, value);
+      }
+    }
+
+    private class MCharTableIT
+    {
+      public int c;
+      public object value;
+      public MCharTable table;
+
+      public MCharTableIT (int c, object value, MCharTable table)
+      {
+       this.c = c;
+       this.value = value;
+       this.table = table;
+      }
+
+      public override string ToString ()
+      {
+       return (String.Format ("<{0:X},{1}>", c, value));
+      }
+    }
+
+    private bool Next (MCharTableIT it)
+    {
+      Console.WriteLine ("Depth:{0} ({1:X}-{2:X}) IT:{3}", depth, min_char, max_char, it);
+      if (it.c > max_char)
+       return (parent != null ? parent.Next (it) : false);
+
+      object value = null;
+      for (int i = index (it.c);
+          i < slots[depth] && (value = contents[i]) == null;
+          i++, it.c = min_char + i << shift[depth]);
+      Console.WriteLine ("IT:{1}", depth, it);
+      if (value == null)
+       return (parent != null ? parent.Next (it) : false);
+      if (value is MCharTable)
+       return ((MCharTable) value).Next (it);
+      it.table = this;
+      it.value = value;
+      return true;
+    }
+
+    // for IEnumerable interface
+    public IEnumerator GetEnumerator()
+    {
+      return new MCharTableEnum (this);
+    }
+
+    private class MCharTableEnum : IEnumerator
+    {
+      private MCharTable table;
+      private MCharTableIT it;
+
+      public MCharTableEnum (MCharTable table)
+       {
+         this.table = table;
+         it = new MCharTableIT (-1, null, table);
+       }
+
+      public bool MoveNext ()
+      {
+       it.c++;
+       return it.table.Next (it);
+      }
+
+      public void Reset ()
+      {
+       it.c = -1;
+       it.table = table;
+      }
+
+      public KeyValuePair<int, object> Current
+      {
+        get { return new KeyValuePair<int, object> (it.c, it.value); }
+      }
+    }
+  }
+}
index b558789..32de922 100644 (file)
@@ -865,18 +865,38 @@ namespace M17N.Core
 
     public object Load ()
     {
-      return (loader != null ? loader (tag, ExtraInfo)
-             : load (MSymbol.nil, MSymbol.nil));
+      if (loader != null)
+       return loader (tag, ExtraInfo);
+
+      if (Info.Format == Mchar_table)
+       return load_char_table ();
+      if (Info.Format == Mcharset)
+       return load_charset ();
+
+      MPlist plist = null;
+      using (FileStream stream = File.OpenRead (FileInfo.FullName))
+       plist = new MPlist (stream);
+      return plist;
     }
 
     public object Load (MSymbol key, MSymbol stop)
     {
-      if (loader != null)
-       return null;
-      return load (key, stop);
+      if (loader != null || Info.Format != MSymbol.plist)
+       throw new ArgumentException
+         ("Key can't be specified for loading this database");
+
+      MPlist plist = null;
+      using (FileStream stream = File.OpenRead (FileInfo.FullName))
+       plist = new MPlist (stream, key, stop);
+      return plist;
+    }
+
+    private object load_charset ()
+    {
+      return null;
     }
 
-    private object load (MSymbol key, MSymbol stop)
+    private object load_char_table ()
     {
       return null;
     }
index 563feb0..0fbadab 100644 (file)
@@ -55,7 +55,7 @@ namespace M17N.Core
 
       if ((flags & MProperty.Flags.BothSticky) != MProperty.Flags.None
          && (flags & MProperty.Flags.Sensitive) != MProperty.Flags.None)
-       throw new Exception ("Sensitive property can't be sticky");
+       throw new Exception ("A property can't be both sticky and sensitve");
       if (sym.flags == null)
        sym.flags = flags;
       else if (sym.flags != flags)
index 279083c..6c9114f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -1,8 +1,8 @@
 CS=gmcs
 
 M17N_SRC = M17N.cs
-CORE_SRC = MSymbol.cs MPlist.cs MText.cs MDatabase.cs
-EXAMPLE = symbol.exe plist.exe text.exe textprop.exe database.exe
+CORE_SRC = MSymbol.cs MPlist.cs MCharTable.cs MText.cs MDatabase.cs
+EXAMPLE = symbol.exe plist.exe chartab.exe text.exe textprop.exe database.exe
 TEST = rearsticky.exe frontsticky.exe \
        sensitive.exe frontsensitive.exe rearsensitive.exe