DEADSOFTWARE

move plain text loading to DswDocuments
authorDeaDDooMER <deaddoomer@deadsoftware.ru>
Thu, 6 Feb 2020 21:10:09 +0000 (00:10 +0300)
committerDeaDDooMER <deaddoomer@deadsoftware.ru>
Thu, 6 Feb 2020 21:10:09 +0000 (00:10 +0300)
src/generic/Dsw/Mod/Compiler486Main.cp
src/generic/Dsw/Mod/CompilerCPfrontMain.cp
src/generic/Dsw/Mod/Documents.cp

index 5461907738b518d28937737892394e19b1a00c6f..ad9c972d439c2b73aa2b3b868f6c90668b139859 100644 (file)
@@ -279,44 +279,28 @@ MODULE DswCompiler486Main;
 
   PROCEDURE ReadText (s: Elem): POINTER TO ARRAY OF CHAR;
     VAR
-      i, len, res: INTEGER;
-      text: DswDocuments.Text;
-      loc: Files.Locator; f: Files.File; r: Files.Reader;
-      ssrc: POINTER TO ARRAY OF SHORTCHAR;
+      i, res: INTEGER;
+      m: DswDocuments.Model;
+      r: DswDocuments.Reader;
+      loc: Files.Locator;
       src: POINTER TO ARRAY OF CHAR;
-      x: POINTER TO ARRAY OF BYTE;
       num: ARRAY 32 OF CHAR;
   BEGIN
-    src := NIL;
     loc := Files.dir.This(s.dir);
-    DswDocuments.Import(loc, s.name, text, res);
-    Strings.IntToString(res, num);
-    IF res = 0 THEN
-      src := text.t
-    ELSIF res = 2 THEN
-      f := Files.dir.Old(loc, s.name, Files.shared);
-      IF f # NIL THEN
-        len := f.Length();
-        r := f.NewReader(NIL);
-        NEW(x, len + 1);
-        r.ReadBytes(x, 0, len);
-        NEW(ssrc, len + 1);
-        FOR i := 0 TO len - 1 DO
-          ssrc[i] := SHORT(CHR(x[i]))
-        END;
-        ssrc[i] := 0X;
-        x := NIL;
-        NEW(src, len + 1);
-        Kernel.Utf8ToString(ssrc, src, res);
-        ssrc := NIL;
-        f.Close
-      END
-    ELSE
-      IF DevCPM.verbose > 0 THEN
-        Console.WriteStr("document error ");
-        Console.WriteStr(num);
-        Console.WriteLn
+    DswDocuments.Open(loc, s.name, m, res);
+    IF m # NIL THEN
+      r := m.NewReader(NIL);
+      NEW(src, m.Length() + 1);
+      IF src # NIL THEN
+        FOR i := 0 TO m.Length() - 1 DO
+          r.Read; src[i] := r.char
+        END
       END
+    ELSIF DevCPM.verbose > 0 THEN
+      Strings.IntToString(res, num);
+      Console.WriteStr("document error ");
+      Console.WriteStr(num);
+      Console.WriteLn
     END;
     IF src = NIL THEN
       Console.WriteStr("unable to open file ");
index bf5bb1b69fe186c12fb0be1219f6378b9a762f68..1043752445d50c7e03409a631a72ea42eb61c16e 100644 (file)
@@ -299,44 +299,28 @@ MODULE DswCompilerCPfrontMain;
 
   PROCEDURE ReadText (s: Elem): POINTER TO ARRAY OF CHAR;
     VAR
-      i, len, res: INTEGER;
-      text: DswDocuments.Text;
-      loc: Files.Locator; f: Files.File; r: Files.Reader;
-      ssrc: POINTER TO ARRAY OF SHORTCHAR;
+      i, res: INTEGER;
+      m: DswDocuments.Model;
+      r: DswDocuments.Reader;
+      loc: Files.Locator;
       src: POINTER TO ARRAY OF CHAR;
-      x: POINTER TO ARRAY OF BYTE;
       num: ARRAY 32 OF CHAR;
   BEGIN
-    src := NIL;
     loc := Files.dir.This(s.dir);
-    DswDocuments.Import(loc, s.name, text, res);
-    Strings.IntToString(res, num);
-    IF res = 0 THEN
-      src := text.t
-    ELSIF res = 2 THEN
-      f := Files.dir.Old(loc, s.name, Files.shared);
-      IF f # NIL THEN
-        len := f.Length();
-        r := f.NewReader(NIL);
-        NEW(x, len + 1);
-        r.ReadBytes(x, 0, len);
-        NEW(ssrc, len + 1);
-        FOR i := 0 TO len - 1 DO
-          ssrc[i] := SHORT(CHR(x[i]))
-        END;
-        ssrc[i] := 0X;
-        x := NIL;
-        NEW(src, len + 1);
-        Kernel.Utf8ToString(ssrc, src, res);
-        ssrc := NIL;
-        f.Close
-      END
-    ELSE
-      IF DevCPM.verbose > 0 THEN
-        Console.WriteStr("document error ");
-        Console.WriteStr(num);
-        Console.WriteLn
+    DswDocuments.Open(loc, s.name, m, res);
+    IF m # NIL THEN
+      r := m.NewReader(NIL);
+      NEW(src, m.Length() + 1);
+      IF src # NIL THEN
+        FOR i := 0 TO m.Length() - 1 DO
+          r.Read; src[i] := r.char
+        END
       END
+    ELSIF DevCPM.verbose > 0 THEN
+      Strings.IntToString(res, num);
+      Console.WriteStr("document error ");
+      Console.WriteStr(num);
+      Console.WriteLn
     END;
     IF src = NIL THEN
       Console.WriteStr("unable to open file ");
index 12cb6b5338dcbc474be472a3727879b31fac122d..8ebfa3abf46acdc39903eb1fb572d496a7524f9a 100644 (file)
@@ -1,12 +1,15 @@
 MODULE DswDocuments;
 
-  IMPORT Files;
+  IMPORT SYSTEM, Kernel, Files;
 
   (* !!! 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;
@@ -14,32 +17,104 @@ MODULE DswDocuments;
       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;
 
-  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;
-    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);
-      VAR i, len: INTEGER; t: POINTER TO ARRAY OF CHAR;
+      VAR i, len: INTEGER; t: String;
     BEGIN
       IF text = NIL THEN
-        NEW(text); NEW(text.t, Step); chid := 0
+        NEW(text); NEW(text.str, Step); chid := 0
       END;
-      len := LEN(text.t);
+      len := LEN(text.str);
       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;
-      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);
@@ -137,6 +212,7 @@ MODULE DswDocuments;
           END;
           r.ReadByte(ano)
         END;
+        m := text;
         res := 0 (* ok *)
       ELSE
         res := 4 (* unsupported text model version *)
@@ -202,7 +278,7 @@ MODULE DswDocuments;
   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 *)
@@ -230,4 +306,28 @@ MODULE DswDocuments;
     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.