2 using System.Collections.Generic;
9 public delegate object MDatabaseLoader (MDatabaseTag tag,
12 public struct MDatabaseTag
14 public MSymbol Tag0, Tag1, Tag2, Tag3;
16 public MDatabaseTag (MSymbol tag0)
18 Tag0 = tag0; Tag1 = Tag2 = Tag3 = MSymbol.nil;
21 public MDatabaseTag (MSymbol tag0, MSymbol tag1)
23 Tag0 = tag0; Tag1 = tag1; Tag2 = Tag3 = MSymbol.nil;
26 public MDatabaseTag (MSymbol tag0, MSymbol tag1, MSymbol tag2)
28 Tag0 = tag0; Tag1 = tag1; Tag2 = tag2; Tag3 = MSymbol.nil;
31 public MDatabaseTag (MSymbol tag0, MSymbol tag1,
32 MSymbol tag2, MSymbol tag3)
34 Tag0 = tag0; Tag1 = tag1; Tag2 = tag2; Tag3 = tag3;
38 public class MDatabase
40 private class MDatabaseDir
42 public string Dirname;
43 public DirectoryInfo Info;
44 public DateTime LastScanned;
46 public MDatabaseDir (string dirname)
50 Info = new DirectoryInfo (dirname);
56 public bool StatusChanged {
58 bool exists = Directory.Exists (Dirname);
68 return (LastScanned < Info.LastWriteTime);
74 Info = new DirectoryInfo (Dirname);
82 public void UpdateStatus ()
84 LastScanned = DateTime.Now;
88 private class MDatabaseDefinition
90 private static readonly MSymbol Mversion;
91 public MDatabaseTag Tag;
92 public string Description;
93 public MText Filename;
94 public bool IsWildcard;
95 public MSymbol Format;
96 public MSymbol Schema;
97 public MText SchemaFile;
99 public bool Supported;
101 static MDatabaseDefinition ()
103 Mversion = new MSymbol ("version");
106 public MDatabaseDefinition (MPlist plist)
108 MSymbol[] tags = new MSymbol[4];
111 for (i = 0; plist.IsSymbol; i++, plist = plist.Next)
112 tags[i] = plist.Symbol;
114 tags[i++] = MSymbol.nil;
115 Tag = new MDatabaseTag (tags[0], tags[1], tags[2], tags[3]);
118 Filename = plist.Text;
121 else if (plist.IsPlist)
123 MPlist p = plist.Plist;
126 Filename = plist.Text;
145 props = new MPlist ();
146 foreach (MPlist pl in plist)
152 if (p.IsSymbol && p.Symbol == Mversion
153 && ! check_version (p.Next))
160 private bool check_version (MPlist plist)
163 int major, minor, release;
167 str = plist.Text.ToString ().Split ('.');
170 try { major = int.Parse (str[0]); } catch { return false; }
171 try { minor = int.Parse (str[1]); } catch { return false; }
172 try { release = int.Parse (str[2]); } catch { return false; }
173 return (M17N.MajorVersion > major
174 || (M17N.MajorVersion == major
175 && (M17N.MinorVersion > minor
176 || (M17N.MinorVersion == minor
177 && M17N.ReleaseNumber >= release))));
181 private static MDatabaseDir[] DBDirs = new MDatabaseDir[3];
183 private const string SystemDirectory = "/usr/share/m17n";
185 private static Dictionary<MDatabaseTag, MDatabase> DBDict
186 = new Dictionary<MDatabaseTag, MDatabase> ();
191 /// The database was defined automatically (from mdb.dir
192 /// file(s)) with no wildcard tag.
194 /// The database was defined automatically (from mdb.dir
195 /// file(s)) with a wildcard tag to define multiple databases
196 /// of the same kind.
198 /// The database was defined explicitely (by MDatabaseDefine).
202 /// Status of database
203 private enum MDBStatus
205 // The database file is currently disabled. It means that the
206 // database file is not readable or the database is deleted by
207 // the modification of "mdb.dir".
209 // The database file has not yet been loaded, or was modified
210 // after the previous loading.
212 // The database file has not been modified after the previous
215 // The database file is updated but the validation was failed.
216 // If this is for a database directory, the directory is
217 // readable but "mdb.dir" doesn't exist in it.
221 public readonly MDatabaseTag Tag;
222 private MDatabaseLoader Loader;
223 private object ExtraInfo;
225 private bool IsSystemDatabase;
226 private DirectoryInfo Dir;
227 private MText Filename;
228 private FileInfo FileInfo;
229 private FileInfo Validater;
230 private int MajorVersion, MinorVersion, ReleaseNumber;
231 private MDBType DBType;
232 private MDBStatus DBStatus;
233 private MSymbol Format;
234 private MSymbol Schema;
235 private DateTime Mtime;
236 private DateTime Ltime;
237 private MPlist Props;
239 public static string ApplicationDirectory;
241 private MDatabase (MDatabaseTag tag, MDatabaseLoader loader,
246 ExtraInfo = extra_info;
249 private MDatabase (MDatabaseTag tag, string filename)
252 Filename = new MText (filename);
255 public static MDatabase Define (MDatabaseTag tag, MDatabaseLoader loader,
258 MDatabase db = MDatabase.Find (tag);
263 db.ExtraInfo = extra_info;
266 return new MDatabase (tag, loader, extra_info);
269 public static MDatabase Define (MDatabaseTag tag, string filename)
271 MDatabase db = MDatabase.Find (tag);
276 db.Filename = new MText (filename);
279 return new MDatabase (tag, filename);
284 string share_dir = (Environment.GetFolderPath
285 (Environment.SpecialFolder.CommonApplicationData));
286 string usr_dir = (Environment.GetFolderPath
287 (Environment.SpecialFolder.ApplicationData));
290 DBDirs[0] = new MDatabaseDir (Path.Combine (usr_dir, ".m17n.d"));
291 } catch (ArgumentException) {
292 DBDirs[0] = new MDatabaseDir (Path.Combine (usr_dir, "_m17n.d"));
295 DBDirs[2] = new MDatabaseDir (Path.Combine (share_dir, "m17n"));
298 internal static void Update ()
304 public static MDatabase Find (MDatabaseTag tag)
308 return (DBDict.TryGetValue (tag, out db) ? db : null);
311 public object Load ()
313 return (Loader != null ? Loader (Tag, ExtraInfo)
314 : load (MSymbol.nil, MSymbol.nil));
317 public object Load (MSymbol key, MSymbol stop)
321 return load (key, stop);
324 private object load (MSymbol key, MSymbol stop)
326 Ltime = DateTime.Now;