--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.IO;
+using M17N;
+using M17N.Core;
+
+namespace M17N.Core
+{
+ public delegate object MDatabaseLoader (MDatabaseTag tag,
+ object extra_info);
+
+ public struct MDatabaseTag
+ {
+ public MSymbol Tag0, Tag1, Tag2, Tag3;
+
+ public MDatabaseTag (MSymbol tag0)
+ {
+ Tag0 = tag0; Tag1 = Tag2 = Tag3 = MSymbol.nil;
+ }
+
+ public MDatabaseTag (MSymbol tag0, MSymbol tag1)
+ {
+ Tag0 = tag0; Tag1 = tag1; Tag2 = Tag3 = MSymbol.nil;
+ }
+
+ public MDatabaseTag (MSymbol tag0, MSymbol tag1, MSymbol tag2)
+ {
+ Tag0 = tag0; Tag1 = tag1; Tag2 = tag2; Tag3 = MSymbol.nil;
+ }
+
+ public MDatabaseTag (MSymbol tag0, MSymbol tag1, MSymbol tag2, MSymbol tag3)
+ {
+ Tag0 = tag0; Tag1 = tag1; Tag2 = tag2; Tag3 = tag3;
+ }
+ }
+
+ public class MDatabase
+ {
+ /// Type of database
+ private enum MDBType
+ {
+ /// The database was defined automatically (from mdb.dir
+ /// file(s)) with no wildcard tag.
+ AUTO,
+ /// The database was defined automatically (from mdb.dir
+ /// file(s)) with a wildcard tag to define multiple databases
+ /// of the same kind.
+ AUTO_WILDCARD,
+ /// The database was defined explicitely (by MDatabaseDefine).
+ EXPLICIT
+ };
+
+ /// Status of database
+ private enum MDBStatus
+ {
+ // The database file is currently disabled. It means that the
+ // database file is not readable or the database is deleted by
+ // the modification of "mdb.dir".
+ DISABLED,
+ // The database file has not yet been loaded, or was modified
+ // after the previous loading.
+ OUTDATED,
+ // The database file has not been modified after the previous
+ // loading.
+ UPDATED,
+ // The database file is updated but the validation was failed.
+ // If this is for a database directory, the directory is
+ // readable but "mdb.dir" doesn't exist in it.
+ INVALID
+ };
+
+ private static Dictionary<MDatabaseTag, MDatabase> db_dict
+ = new Dictionary<MDatabaseTag, MDatabase> ();
+
+ private MDatabaseTag tag;
+ private MDatabaseLoader loader;
+ private object extra_info;
+
+ private bool system_database;
+ private DirectoryInfo dir;
+ private FileInfo file;
+ private FileInfo validater;
+ private int major_version, minor_version, release_number;
+ private MDBType type;
+ private MDBStatus status;
+ private MSymbol format;
+ private MSymbol schema;
+ private DateTime mtime;
+ private DateTime ltime;
+ private MPlist props;
+
+ public static string ApplicationDirectory;
+
+ public MDatabase (MDatabaseTag tag, MDatabaseLoader loader,
+ object extra_info)
+ {
+ this.tag = tag;
+ this.loader = loader;
+ this.extra_info = extra_info;
+ }
+
+ public MDatabase (MDatabaseTag tag, string filename)
+ {
+ this.tag = tag;
+ this.loader = load;
+ }
+
+ public MDatabaseTag Tag { get { return tag; } }
+
+ public static MDatabase Find (MDatabaseTag tag)
+ {
+ MDatabase db;
+
+ return (db_dict.TryGetValue (tag, out db) ? db : null);
+ }
+
+ public object Load ()
+ {
+ return loader (tag, extra_info);
+ }
+
+ private object load (MDatabaseTag tag, object extra_info)
+ {
+ ltime = DateTime.Now;
+ return null;
+ }
+
+ }
+
+}
\ No newline at end of file
using System;
using System.Collections;
+using System.IO;
+using M17N;
using M17N.Core;
namespace M17N.Core
Val = null;
}
+ public MPlist (MStreamReader reader)
+ {
+ MSymbol key;
+ object val;
+ bool result = reader.ReadElement (out key, out val);
+
+ Key = key;
+ Val = val;
+ if (result)
+ next = new MPlist (reader);
+ }
+
private MPlist (MSymbol key, object val)
{
Key = key;
public override string ToString ()
{
- string str = "";
+ string str = "(";
for (MPlist p = this; ! p.IsEmpty; p = p.next)
{
- str += (p == this ? "(" : " ") + p.Key + ":" + p.Val;
+ if (p != this)
+ str += " ";
+ if (p.Key != MSymbol.symbol
+ && p.Key != MSymbol.integer
+ && p.Key != MSymbol.plist
+ && p.Key != MSymbol.mtext)
+ str += p.Key + ":";
+ str += p.Val;
}
return str + ")";
}
return find (key).Val;
}
+ private delegate MPlist MPlistDelegate (MSymbol key, object val);
+
+ private MPlist mplist_op (MPlistDelegate op, object val)
+ {
+ Type type = val.GetType ();
+
+ if (Object.ReferenceEquals (type, typeof (MSymbol)))
+ return op (MSymbol.symbol, val);
+ if (Object.ReferenceEquals (type, typeof (MText)))
+ return op (MSymbol.mtext, val);
+ if (Object.ReferenceEquals (type, typeof (MPlist)))
+ return op (MSymbol.plist, val);
+ if (Object.ReferenceEquals (type, typeof (int)))
+ return op (MSymbol.integer, val);
+ return op (MSymbol.t, val);
+ }
+
public MPlist Set (MSymbol key, object val)
{
if (IsEmpty)
return this;
}
+ public MPlist Set (object val)
+ {
+ return mplist_op (Set, val);
+ }
+
public MPlist Put (MSymbol key, object val)
{
return find (key).Set (key, val);
}
+ public MPlist Put (object val)
+ {
+ return mplist_op (Put, val);
+ }
+
public MPlist Push (MSymbol key, object val)
{
MPlist p = new MPlist (Key, Val);
return this;
}
- public object Pop ()
+ public MPlist Push (object val)
{
+ return mplist_op (Push, val);
+ }
+
+ public object Pop (out MSymbol key)
+ {
+ key = Key;
if (IsEmpty)
return null;
return val;
}
+ public object Pop ()
+ {
+ MSymbol key;
+ return Pop (out key);
+ }
+
public MPlist Add (MSymbol key, object val)
{
MPlist p;
}
}
}
+
+ public class MStreamReader : StreamReader
+ {
+ private static char[] escaped_char = new char[128];
+ private static int[] hexadecimal = new int[128];
+
+ public MStreamReader (Stream stream) : base (stream)
+ {
+ }
+
+ static MStreamReader ()
+ {
+ for (int i = 0; i < 128; i++)
+ escaped_char[i] = (char) i;
+ escaped_char['e'] = (char) 27;
+ escaped_char['b'] = '\b';
+ escaped_char['f'] = '\f';
+ escaped_char['n'] = '\n';
+ escaped_char['r'] = '\r';
+ escaped_char['t'] = '\t';
+ escaped_char['\\'] = '\\';
+ for (int i = 0; i < 128; i++)
+ hexadecimal[i] = -1;
+ for (int i = '0'; i <= '9'; i++)
+ hexadecimal[i] = i - '0';
+ for (int i = 'A'; i <= 'F'; i++)
+ hexadecimal[i] = hexadecimal[i + 'a' - 'A'] = i -'A' + 10;
+ }
+
+ internal int PeekChar ()
+ {
+ bool comment = false;
+ int c;
+
+ while ((c = Peek ()) != -1)
+ {
+ if (comment)
+ {
+ if ((c = Read ()) == '\n')
+ comment = false;
+ }
+ else
+ {
+ if (c == ';')
+ comment = true;
+ else if (c != ' ' && c != '\t' && c != '\n')
+ return c;
+ Read ();
+ }
+ }
+ return c;
+ }
+
+ internal int ReadHexadecimal ()
+ {
+ int i = 0, c;
+
+ while ((c = Peek ()) >= 0 && c < 128 && (c = hexadecimal[c]) >= 0)
+ {
+ Read ();
+ i = (i * 16) + c;
+ }
+ return i;
+ }
+
+ internal int ReadInteger ()
+ {
+ int i = 0, c;
+
+ while ((c = Peek ()) >= '0' && c <= '9')
+ i = (i * 10) + (Read () - '0');
+ return i;
+ }
+
+ internal int ReadChar ()
+ {
+ int c = Read ();
+
+ if (c == '\\')
+ {
+ c = Read ();
+ if (c == -1)
+ return -1;
+ if (c == 'x' || c == 'u')
+ return ReadHexadecimal ();
+ if (c < 128)
+ c = escaped_char[c];
+ }
+ return c;
+ }
+
+ internal MText ReadMtext ()
+ {
+ MText mt = new MText ();
+ int c;
+
+ while ((c = Peek ()) != -1 && c != '"')
+ {
+ if (c == '\\')
+ {
+ c = ReadChar ();
+ if (Peek () == '\n')
+ {
+ ReadChar ();
+ continue;
+ }
+ if (c == -1)
+ {
+ mt.Cat ('\\');
+ break;
+ }
+ mt.Cat (c);
+ }
+ else
+ mt.Cat (Read ());
+ }
+ if (c == '"')
+ Read ();
+ return mt;
+ }
+
+ internal string ReadSymbolName ()
+ {
+ int c = Peek ();
+
+ if (c == -1 || c == '(' || c == ' ' || c == '\n' || c == '"')
+ return "";
+ Read ();
+ if (c == '\\')
+ {
+ c = Read ();
+ if (c == -1)
+ c = '\\';
+ }
+ return (char) c + ReadSymbolName ();
+ }
+
+ internal bool ReadElement (out MSymbol key, out object val)
+ {
+ int c = PeekChar ();
+
+ if (c == '(')
+ {
+ Read ();
+ val = new MPlist (this);
+ key = MSymbol.plist;
+ }
+ else if (c == '"')
+ {
+ Read ();
+ val = ReadMtext ();
+ key = MSymbol.mtext;
+ }
+ else if (c >= '0' && c <= '9')
+ {
+ int i = ReadInteger ();
+
+ val = i;
+ key = MSymbol.integer;
+ }
+ else if (c == '-')
+ {
+ Read ();
+ c = Peek ();
+ if (c >= '0' && c <= '9')
+ {
+ int i = ReadInteger ();
+ val = - i;
+ key = MSymbol.integer;
+ }
+ else
+ {
+ string str = ReadSymbolName ();
+
+ val = new MSymbol ("-" + str);
+ key = MSymbol.symbol;
+ }
+ }
+ else if (c == '?')
+ {
+ Read ();
+ val = ReadChar ();
+ key = MSymbol.integer;
+ }
+ else if (c == '#')
+ {
+ Read ();
+ if ((c = Peek ()) == 'x' || c == 'u')
+ {
+ Read ();
+ val = ReadHexadecimal ();
+ key = MSymbol.integer;
+ }
+ else
+ {
+ string str = ReadSymbolName ();
+
+ val = new MSymbol ("#" + (char) c + str);
+ key = MSymbol.symbol;
+ }
+ }
+ else if (c == -1 || c == ')')
+ {
+ if (c == ')')
+ Read ();
+ val = null;
+ key = MSymbol.nil;
+ return false;
+ }
+ else
+ {
+ val = new MSymbol (ReadSymbolName ());
+ key = MSymbol.symbol;
+ }
+ return true;
+ }
+ }
}
private MSymbolData data;
- static public MSymbol nil = new MSymbol ("nil");
- static public MSymbol t = new MSymbol ("t");
+ 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 MSymbol (string name)
{
public override bool Equals (object sym)
{
+ if (sym == null)
+ return false;
return (this.data == ((MSymbol) sym).data);
}
}
}
+ private void insert (int pos, int c)
+ {
+ check_pos (pos, true);
+
+ int pos_idx = pos_to_idx (this, pos);
+
+ if (c < 0x10000)
+ {
+ char ch = (char) c;
+ sb.Insert (pos_idx, ch);
+ }
+ else
+ {
+ char high = (char) (0xD800 + ((c - 0x10000) >> 10));
+ char low = (char) (0xDC00 + ((c - 0x10000) & 0x3FF));
+ sb.Insert (pos_idx, low);
+ sb.Insert (pos_idx, high);
+ }
+ nchars++;
+ foreach (MPlist plist in intervals)
+ ((MInterval) plist.Val).Insert (pos,
+ new MInterval (plist.Key, this, 1));
+ }
+
public int this[int i]
{
set {
return (new MText (sb.ToString ()));
}
+ public MText Ins (int pos, int c)
+ {
+ insert (pos, c);
+ return this;
+ }
+
public MText Ins (int pos, MText mt)
{
insert (pos, mt, 0, mt.nchars);
return this;
}
+ public MText Cat (int c)
+ {
+ insert (nchars, c);
+ return this;
+ }
+
public MText Del (int from, int to)
{
if (check_range (from, to, true))
-M17N_SRC = M17N.cs
-CORE_SRC = MSymbol.cs MPlist.cs MText.cs
CS=gmcs
-all: M17N.dll symbol.exe plist.exe mtext.exe textprop.exe
+M17N_SRC = M17N.cs
+CORE_SRC = MSymbol.cs MPlist.cs MText.cs MDatabase.cs
+TEST_PROG = symbol.exe plist.exe mtext.exe textprop.exe db.exe
+
+all: ${TEST_PROG}
M17N.dll: ${M17N_SRC}
$(CS) /out:$@ /t:library ${M17N_SRC}
M17NCore.dll: M17N.dll ${CORE_SRC}
- $(CS) /out:$@ /t:library /r:M17N.dll ${CORE_SRC}
-
-mtext.exe: mtext.cs M17NCore.dll
- $(CS) -codepage:65001 /r:M17NCore mtext.cs
+ $(CS) /out:$@ /t:library /r:M17N.dll /doc:M17NCore.xml ${CORE_SRC}
-symbol.exe: symbol.cs M17NCore.dll
- $(CS) -codepage:65001 /r:M17N.dll /r:M17NCore symbol.cs
-
-plist.exe: plist.cs M17NCore.dll
- $(CS) -codepage:65001 /r:M17NCore plist.cs
-
-textprop.exe: textprop.cs M17NCore.dll
- $(CS) -codepage:65001 /r:M17N.dll /r:M17NCore textprop.cs
+%.exe: %.cs M17NCore.dll
+ $(CS) -codepage:65001 /r:M17N.dll /r:M17NCore $<
clean:
rm -f *.dll *.exe
+
+temp.exe: temp.cs
+ $(CS) temp.cs
using System;
+using System.IO;
using System.Collections.Generic;
+using M17N;
using M17N.Core;
public class Test
foreach (MPlist p in plist)
Console.WriteLine (p.Key + ":" + p.Val);
Console.WriteLine (plist.Clone ());
+
+ M17N.M17N.debug = true;
+
+ using (FileStream stream = File.OpenRead ("temp.plist"))
+ {
+ MStreamReader reader = new MStreamReader (stream);
+ Console.WriteLine (new MPlist (reader));
+ }
+
+ plist = new MPlist ();
+ plist.Push (new MSymbol ("abc"));
+ plist.Push (new MText ("abc"));
+ plist.Push (new MPlist ());
+ plist.Push (123);
+ plist.Push (4.5);
+ Console.WriteLine (plist);
+
+ MSymbol tmp = MSymbol.nil;
+ if (tmp == null)
+ Console.WriteLine ("null");
}
}
--- /dev/null
+"\xC0"
+(a 123)
+-10
+?\xC0
\ No newline at end of file