*** empty log message ***
[m17n/m17n-lib-cs.git] / MSymbol.cs
index fe2a698..c687a0f 100644 (file)
 using System;
-using System.Collections;
+using System.Collections.Generic;
 using M17N.Core;
 
 namespace M17N.Core
 {
-  public class MSymbol
+  public sealed class MSymbol
   {
-    static private Hashtable pool = new Hashtable ();
-
-    private class MSymbolData
+    private static Dictionary<string, MSymbol> pool
+      = new Dictionary<string, MSymbol> ();
+
+    public readonly string Name;
+    private MPlist Plist;
+    internal MProperty.Flags? flags;
+
+    public static MSymbol nil = MSymbol.Of ("nil");
+    public static MSymbol t = MSymbol.Of ("t");
+    public static MSymbol symbol = MSymbol.Of ("symbol");
+    public static MSymbol mtext = MSymbol.Of ("mtext");
+    public static MSymbol mstring = MSymbol.Of ("string");
+    public static MSymbol plist = MSymbol.Of ("plist");
+    public static MSymbol integer = MSymbol.Of ("integer");
+
+    private MSymbol (string name)
     {
-      public readonly string Name;
-      public readonly MTextProperty.Flags Flags;
-      public object Value;
-      public MPlist Plist;
-
-      public MSymbolData (string name, MTextProperty.Flags flags)
-      {
-       Name = name;
-       Flags = flags;
-      }
+      Name = name;
     }
 
-    private MSymbolData data;
+    public static implicit operator MSymbol (string name)
+    {
+      return Of (name);
+    }
 
-    public static MSymbol nil = new MSymbol ("nil");
-    public static MSymbol t = new MSymbol ("t");
-    public static MSymbol symbol = new MSymbol ("symbol");
-    public static MSymbol mtext = new MSymbol ("mtext");
-    public static MSymbol plist = new MSymbol ("plist");
-    public static MSymbol integer = new MSymbol ("integer");
+    public static explicit operator string (MSymbol sym)
+    {
+      return sym.Name;
+    }
 
-    public MSymbol (string name)
+    public static MSymbol Of (string name)
     {
-      if (! pool.ContainsKey (name))
+      lock (pool)
        {
-         data = new MSymbolData (name, MTextProperty.Flags.None);
-         pool.Add (name, data);
+         MSymbol sym;
+
+         if (! pool.TryGetValue (name, out sym))
+           {
+             sym = new MSymbol (name);
+             pool[name] = sym;
+           }
+         return sym;
        }
-      else
-       data = (MSymbolData) pool[name];
     }
 
-    public MSymbol (string name, MTextProperty.Flags flags)
+    public static MSymbol PropertyKey (string name)
     {
-      if (! pool.ContainsKey (name))
-       {
-         data = new MSymbolData (name, flags);
-         pool.Add (name, data);
-       }
-      else
-       {
-         if (((MSymbolData) pool[name]).Flags != flags)
-           throw new ArgumentException ("Invalid MTextProperty.Flags");
-       }
+      MSymbol sym = MSymbol.Of (name);
+
+      if (sym.flags == null)
+       sym.flags = MProperty.Flags.None;;
+      return sym;
     }
 
-    public MTextProperty.Flags TextPropertyFlags { get { return data.Flags; } }
+    public static MSymbol PropertyKey (string name, MProperty.Flags flags)
+    {
+      MSymbol sym = MSymbol.Of (name);
+
+      if ((flags & MProperty.Flags.BothSticky) != MProperty.Flags.None
+         && (flags & MProperty.Flags.Sensitive) != MProperty.Flags.None)
+       throw new Exception ("A property can't be both sticky and sensitve");
+      if (sym.flags == null)
+       sym.flags = flags;
+      else if (sym.flags != flags)
+       throw new Exception ("Flags of PropertyKey mismatch");
+      return sym;
+    }
 
     public override string ToString ()
     {
       string str = "";
 
-      foreach (char c in data.Name)
+      foreach (char c in Name)
        {
-         if (c == '\\' || c == ' ' || c == '\'' || c == '\"' || c == ':')
+         if (c == '\\' || c == ' ' || c == '\'' || c == '\"'
+             || c == '(' || c == ')')
            str += "\\";
          str += c;
        }
       return str;
     }
 
-    public static bool operator== (MSymbol sym1, MSymbol sym2)
-    {
-      if (System.Object.ReferenceEquals(sym1, sym2))
-        return true;
-      if (((object) sym1 == null) || ((object) sym2 == null))
-        return false;
-      return sym1.data == sym2.data;
-    }
-
-    public static bool operator!= (MSymbol sym1, MSymbol sym2)
-    {
-      return ! (sym1 == sym2);
-    }
-
-    public override bool Equals (object sym)
-    {
-      if (sym == null)
-       return false;
-      return (this.data == ((MSymbol) sym).data);
-    }
-
-    public override int GetHashCode ()
-    {
-      return (data.Name.GetHashCode ());
-    }
-
     public MPlist Find (MSymbol key)
     {
-      return (data.Plist == null ? null : data.Plist.Find (key));
+      return (Plist == null ? null : Plist.Find (key));
     }
 
     public object Get (MSymbol key)
     {
-      return (data.Plist == null ? null : data.Plist.Get (key));
+      return (Plist == null ? null : Plist.Get (key));
     }
 
     public object Put (MSymbol key, object val)
     {
-      if (data.Plist == null)
-       data.Plist = new MPlist ();
-      return data.Plist.Put (key, val);
+      if (Plist == null)
+       Plist = new MPlist ();
+      return Plist.Put (key, val);
     }
   }
 }