From: handa Date: Sat, 11 Jul 2009 07:24:42 +0000 (+0000) Subject: *** empty log message *** X-Git-Url: http://git.chise.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e33f30915fcea0bd1f8c944306ca9e26b9d7242a;p=m17n%2Fm17n-lib-cs.git *** empty log message *** --- diff --git a/MCharTable.cs b/MCharTable.cs new file mode 100644 index 0000000..6845767 --- /dev/null +++ b/MCharTable.cs @@ -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 Current + { + get { return new KeyValuePair (it.c, it.value); } + } + } + } +} diff --git a/MDatabase.cs b/MDatabase.cs index b558789..32de922 100644 --- a/MDatabase.cs +++ b/MDatabase.cs @@ -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; } diff --git a/MSymbol.cs b/MSymbol.cs index 563feb0..0fbadab 100644 --- a/MSymbol.cs +++ b/MSymbol.cs @@ -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) diff --git a/Makefile b/Makefile index 279083c..6c9114f 100644 --- 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