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);
}
}
}