index 12cb6b5338dcbc474be472a3727879b31fac122d..8ebfa3abf46acdc39903eb1fb572d496a7524f9a 100644 (file)
MODULE DswDocuments;
MODULE DswDocuments;
- IMPORT Files;
+ IMPORT SYSTEM, Kernel, Files;
(* !!! make better store type and version checking *)
TYPE
Name = ARRAY 256 OF SHORTCHAR;
(* !!! make better store type and version checking *)
TYPE
Name = ARRAY 256 OF SHORTCHAR;
+ ShortString = POINTER TO ARRAY OF SHORTCHAR;
+ String = POINTER TO ARRAY OF CHAR;
+
Store = RECORD
(* type: Name; *)
next, down, len: INTEGER;
Store = RECORD
(* type: Name; *)
next, down, len: INTEGER;
isElem: BOOLEAN;
END;
isElem: BOOLEAN;
END;
- Text* = POINTER TO RECORD
- t*: POINTER TO ARRAY OF CHAR;
+ Model* = POINTER TO ABSTRACT RECORD END;
+
+ Reader* = POINTER TO ABSTRACT RECORD
+ eot*: BOOLEAN;
+ char*: CHAR;
+ END;
+
+ StdModel = POINTER TO RECORD (Model)
+ str: String;
+ len: INTEGER
+ END;
+
+ StdReader = POINTER TO RECORD (Reader)
+ base: StdModel;
+ i: INTEGER
END;
END;
- PROCEDURE Import* (loc: Files.Locator; IN name: Files.Name; OUT text: Text; OUT res: INTEGER);
+ VAR
+ oldReader: Files.Reader;
+
+ PROCEDURE (m: Model) NewReader* (old: Reader): Reader, NEW, ABSTRACT;
+ PROCEDURE (m: Model) Length* (): INTEGER, NEW, ABSTRACT;
+
+ PROCEDURE (r: Reader) Base* (): Model, NEW, ABSTRACT;
+ PROCEDURE (r: Reader) Pos* (): INTEGER, NEW, ABSTRACT;
+ PROCEDURE (r: Reader) SetPos* (pos: INTEGER), NEW, ABSTRACT;
+ PROCEDURE (r: Reader) Read*, NEW, ABSTRACT;
+ PROCEDURE (r: Reader) ReadPrev*, NEW, ABSTRACT;
+
+ PROCEDURE (m: StdModel) NewReader (old: Reader): StdReader;
+ VAR r: StdReader;
+ BEGIN
+ IF (old # NIL) & (old IS StdReader) THEN r := old(StdReader) ELSE NEW(r) END;
+ r.eot := FALSE; r.char := 0X; r.base := m; r.i := 0;
+ RETURN r
+ END NewReader;
+
+ PROCEDURE (m: StdModel) Length (): INTEGER;
+ BEGIN
+ RETURN m.len
+ END Length;
+
+
+ PROCEDURE (r: StdReader) Base (): StdModel;
+ BEGIN
+ RETURN r.base
+ END Base;
+
+ PROCEDURE (r: StdReader) Pos (): INTEGER;
+ BEGIN
+ RETURN r.i
+ END Pos;
+
+ PROCEDURE (r: StdReader) SetPos (pos: INTEGER);
+ BEGIN
+ ASSERT(pos >= 0, 20);
+ ASSERT(pos <= r.base.len, 21);
+ r.i := pos
+ END SetPos;
+
+ PROCEDURE (r: StdReader) Read;
+ BEGIN
+ IF r.i < r.base.len THEN
+ r.char := r.base.str[r.i]; r.eot := FALSE; INC(r.i)
+ ELSE
+ r.char := 0X; r.eot := TRUE
+ END
+ END Read;
+
+ PROCEDURE (r: StdReader) ReadPrev;
+ BEGIN
+ IF r.i > 0 THEN
+ DEC(r.i); r.char := r.base.str[r.i]; r.eot := FALSE
+ ELSE
+ r.char := 0X; r.eot := TRUE
+ END
+ END ReadPrev;
+
+
+ PROCEDURE Import* (loc: Files.Locator; IN name: Files.Name; OUT m: Model; OUT res: INTEGER);
CONST
docTag = 6F4F4443H; docVersion = 0;
Step = 256;
CONST
docTag = 6F4F4443H; docVersion = 0;
Step = 256;
- VAR f: Files.File; r: Files.Reader; tag, version, chid: INTEGER; s: Store;
+ VAR f: Files.File; r: Files.Reader; tag, version, chid: INTEGER; s: Store; text: StdModel;
PROCEDURE AddChar (ch: CHAR);
PROCEDURE AddChar (ch: CHAR);
- VAR i, len: INTEGER; t: POINTER TO ARRAY OF CHAR;
+ VAR i, len: INTEGER; t: String;
BEGIN
IF text = NIL THEN
BEGIN
IF text = NIL THEN
- NEW(text); NEW(text.t, Step); chid := 0
+ NEW(text); NEW(text.str, Step); chid := 0
END;
END;
- len := LEN(text.t);
+ len := LEN(text.str);
IF chid + 1 >= len THEN
IF chid + 1 >= len THEN
- NEW(t, len + Step);
- FOR i := 0 TO len - 1 DO
- t[i] := text.t[i]
- END;
- text.t := t
+ NEW(t, len + Step); t^ := text.str$; text.str := t;
END;
END;
- text.t[chid] := ch; INC(chid);
- text.t[chid] := 0X;
+ text.str[chid] := ch; INC(chid);
+ text.str[chid] := 0X;
+ text.len := chid
END AddChar;
PROCEDURE ReadSChar (OUT x: SHORTCHAR);
END AddChar;
PROCEDURE ReadSChar (OUT x: SHORTCHAR);
END;
r.ReadByte(ano)
END;
END;
r.ReadByte(ano)
END;
+ m := text;
res := 0 (* ok *)
ELSE
res := 4 (* unsupported text model version *)
res := 0 (* ok *)
ELSE
res := 4 (* unsupported text model version *)
BEGIN
ASSERT(loc # NIL, 20);
ASSERT(name # "", 21);
BEGIN
ASSERT(loc # NIL, 20);
ASSERT(name # "", 21);
- text := NIL;
+ m := NIL; res := 0;
f := Files.dir.Old(loc, name, Files.shared);
IF f # NIL THEN
IF f.Length() > 8 THEN (* !!! calculate minimal document size *)
f := Files.dir.Old(loc, name, Files.shared);
IF f # NIL THEN
IF f.Length() > 8 THEN (* !!! calculate minimal document size *)
END
END Import;
END
END Import;
+ PROCEDURE Open* (loc: Files.Locator; IN name: Files.Name; OUT m: Model; OUT res: INTEGER);
+ VAR f: Files.File; r: Files.Reader; len: INTEGER; s: ShortString; l: String; text: StdModel;
+ BEGIN
+ m := NIL; res := 0;
+ Import(loc, name, m, res);
+ IF res = 2 THEN
+ f := Files.dir.Old(loc, name, Files.shared);
+ IF f # NIL THEN
+ len := f.Length();
+ r := f.NewReader(oldReader); oldReader := r; r.SetPos(0);
+ NEW(s, len + 1); r.ReadBytes(SYSTEM.THISARRAY(SYSTEM.ADR(s[0]), len + 1), 0, len);
+ NEW(l, len + 1); Kernel.Utf8ToString(s, l, res);
+ IF res = 0 THEN
+ NEW(text); text.str := l; text.len := LEN(text.str$); m := text; res := 0 (* ok *)
+ ELSE
+ res := 5 (* broken encoding *)
+ END;
+ f.Close
+ ELSE
+ res := 1 (* unable to open *)
+ END
+ END
+ END Open;
+
END DswDocuments.
END DswDocuments.