*** empty log message ***
[m17n/m17n-lib-cs.git] / MSymbol.cs
index b92bcbf..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 static Dictionary<string, MSymbol> pool
+      = new Dictionary<string, MSymbol> ();
 
-    private class MSymbolData
-    {
-      public string name;
-      public object value;
-      public MPlist plist;
-
-      public MSymbolData (string name)
-      {
-       this.name = name;
-      }
-    }
+    public readonly string Name;
+    private MPlist Plist;
+    internal MProperty.Flags? flags;
 
-    private MSymbolData data;
+    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");
 
-    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");
+    private MSymbol (string name)
+    {
+      Name = name;
+    }
 
-    public MSymbol (string name)
+    public static implicit operator MSymbol (string name)
     {
-      if (! pool.ContainsKey (name))
-       {
-         data = new MSymbolData (name);
-         pool.Add (name, data);
-       }
-      else
-       data = (MSymbolData) pool[name];
+      return Of (name);
     }
 
-    public override string ToString ()
+    public static explicit operator string (MSymbol sym)
     {
-      string str = "";
+      return sym.Name;
+    }
 
-      foreach (char c in data.name)
+    public static MSymbol Of (string name)
+    {
+      lock (pool)
        {
-         if (c == '\\' || c == ' ' || c == '\'' || c == '\"' || c == ':')
-           str += "\\";
-         str += c;
+         MSymbol sym;
+
+         if (! pool.TryGetValue (name, out sym))
+           {
+             sym = new MSymbol (name);
+             pool[name] = sym;
+           }
+         return sym;
        }
-      return str;
     }
 
-    public override bool Equals (object sym)
+    public static MSymbol PropertyKey (string name)
     {
-      if (sym == null)
-       return false;
-      return (this.data == ((MSymbol) sym).data);
-    }
+      MSymbol sym = MSymbol.Of (name);
 
-    public override int GetHashCode ()
-    {
-      return (data.name.GetHashCode ());
+      if (sym.flags == null)
+       sym.flags = MProperty.Flags.None;;
+      return sym;
     }
 
-    public static bool operator== (MSymbol sym1, MSymbol sym2)
+    public static MSymbol PropertyKey (string name, MProperty.Flags flags)
     {
-      return (sym1.data == sym2.data);
+      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 static bool operator!= (MSymbol sym1, MSymbol sym2)
+    public override string ToString ()
     {
-      return (sym1.data != sym2.data);
+      string str = "";
+
+      foreach (char c in Name)
+       {
+         if (c == '\\' || c == ' ' || c == '\'' || c == '\"'
+             || c == '(' || c == ')')
+           str += "\\";
+         str += c;
+       }
+      return str;
     }
 
     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);
     }
   }
 }