X-Git-Url: https://deadsoftware.ru/gitweb?p=cpc.git;a=blobdiff_plain;f=src%2Fgeneric%2FDsw%2FMod%2FDocuments.cp;h=8ebfa3abf46acdc39903eb1fb572d496a7524f9a;hp=12cb6b5338dcbc474be472a3727879b31fac122d;hb=d04c6367a927c536552ae595c92cc15347d3a65f;hpb=4de97bf7ae01a78248a15ff69031824c5b089e31 diff --git a/src/generic/Dsw/Mod/Documents.cp b/src/generic/Dsw/Mod/Documents.cp index 12cb6b5..8ebfa3a 100644 --- a/src/generic/Dsw/Mod/Documents.cp +++ b/src/generic/Dsw/Mod/Documents.cp @@ -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.