MODULE Converters;
(**
project = "BlackBox"
organization = "www.oberon.ch"
contributors = "Oberon microsystems"
version = "System/Rsrc/About"
copyright = "System/Rsrc/About"
license = "Docu/BB-License"
changes = ""
issues = ""
**)
IMPORT Meta, Files, Stores, Dialog;
CONST
(* hints *)
importAll* = 0; (* can import all file types *)
canceled = 8;
TYPE
Importer* = PROCEDURE (f: Files.File; OUT s: Stores.Store);
Exporter* = PROCEDURE (s: Stores.Store; f: Files.File);
Converter* = POINTER TO RECORD
next-: Converter;
imp-, exp-: Dialog.String;
storeType-: Stores.TypeName;
fileType-: Files.Type;
opts-: SET
END;
ImpVal = RECORD (Meta.Value) p: Importer END;
ExpVal = RECORD (Meta.Value) p: Exporter END;
VAR
list-: Converter;
doc: Converter;
PROCEDURE GetCommand (name: Dialog.String; VAR val: Meta.Value; VAR ok: BOOLEAN);
VAR i: Meta.Item;
BEGIN
Meta.LookupPath(name, i);
IF (i.obj = Meta.procObj) OR (i.obj = Meta.varObj) & (i.typ = Meta.procTyp) THEN
i.GetVal(val, ok)
ELSE ok := FALSE
END
END GetCommand;
PROCEDURE Register* (imp, exp: Dialog.String; storeType: Stores.TypeName; fileType: Files.Type; opts: SET);
VAR e, f: Converter;
BEGIN
ASSERT((imp # "") OR (exp # ""), 20); ASSERT(fileType # "", 21);
NEW(e); e.next := NIL;
e.imp := imp; e.exp := exp; e.fileType := fileType; e.storeType := storeType; e.opts := opts;
IF (storeType = "") & (doc = NIL) THEN doc := e END;
IF list = NIL THEN list := e
ELSE f := list;
WHILE f.next # NIL DO f := f.next END;
f.next := e
END
END Register;
PROCEDURE Import* (loc: Files.Locator; name: Files.Name; VAR conv: Converter; OUT s: Stores.Store);
VAR file: Files.File; val: ImpVal; ok: BOOLEAN;
BEGIN
ASSERT(loc # NIL, 20); ASSERT(name # "", 21);
file := Files.dir.Old(loc, name, Files.shared); s := NIL;
IF file # NIL THEN
IF conv = NIL THEN
conv := list;
WHILE (conv # NIL) & ((conv.fileType # file.type) OR (conv.imp = "")) DO conv := conv.next END;
IF conv = NIL THEN
conv := list; WHILE (conv # NIL) & ~(importAll IN conv.opts) DO conv := conv.next END
END
ELSE ASSERT(conv.imp # "", 22)
END;
IF conv # NIL THEN
GetCommand(conv.imp, val, ok);
IF ok THEN val.p(file, s)
ELSE Dialog.ShowMsg("#System:ConverterFailed")
END
ELSE Dialog.ShowMsg("#System:NoConverterFound")
END
END
END Import;
PROCEDURE Export* (loc: Files.Locator; name: Files.Name; conv: Converter; s: Stores.Store);
VAR res: INTEGER; file: Files.File; val: ExpVal; ok: BOOLEAN;
BEGIN
ASSERT(s # NIL, 20); ASSERT(~(s IS Stores.Alien), 21);
ASSERT(loc # NIL, 22); ASSERT(name # "", 23);
file := Files.dir.New(loc, Files.ask); (* fileLoc := loc; *)
IF file # NIL THEN
IF conv = NIL THEN
conv := doc
ELSE ASSERT(conv.exp # "", 24)
END;
GetCommand(conv.exp, val, ok);
IF ok THEN
val.p(s, file);
IF loc.res # canceled THEN
file.Register(name, conv.fileType, Files.ask, res); loc.res := res
END
ELSE Dialog.ShowMsg("#System:ConverterFailed"); loc.res := canceled
END
END
END Export;
BEGIN
list := NIL
END Converters.