Faster Files.Read, Files.Readline, Strings.Length

This commit is contained in:
Dave Brown 2019-11-11 12:56:43 +00:00
parent 2ddbf5d517
commit 20943d67db
2 changed files with 57 additions and 24 deletions

69
src/runtime/Files.Mod Normal file → Executable file
View file

@ -398,18 +398,23 @@ MODULE Files; (* J. Templ 1.12. 89/12.4.95 Oberon files mapped onto Unix files
PROCEDURE Read* (VAR r: Rider; VAR x: SYSTEM.BYTE); PROCEDURE Read* (VAR r: Rider; VAR x: SYSTEM.BYTE);
VAR offset: LONGINT; buf: Buffer; VAR offset: LONGINT; buf: Buffer;
BEGIN BEGIN
buf := r.buf; offset := r.offset; IF (r.org = r.buf.org) & (r.offset < r.buf.size) THEN (* Fast case *)
IF r.org # buf.org THEN x := r.buf.data[r.offset];
Set(r, buf.f, r.org + offset); buf := r.buf; offset := r.offset INC(r.offset)
END; ELSE (* Slow case *)
Assert(offset <= buf.size); buf := r.buf; offset := r.offset;
IF (offset < buf.size) THEN IF r.org # buf.org THEN
x := buf.data[offset]; r.offset := offset + 1 Set(r, buf.f, r.org + offset); buf := r.buf; offset := r.offset
ELSIF r.org + offset < buf.f.len THEN END;
Set(r, r.buf.f, r.org + offset); Assert(offset <= buf.size);
x := r.buf.data[0]; r.offset := 1 IF (offset < buf.size) THEN
ELSE x := buf.data[offset]; r.offset := offset + 1
x := 0X; r.eof := TRUE ELSIF r.org + offset < buf.f.len THEN
Set(r, r.buf.f, r.org + offset);
x := r.buf.data[0]; r.offset := 1
ELSE
x := 0X; r.eof := TRUE
END
END END
END Read; END Read;
@ -635,15 +640,43 @@ Especially Length would become fairly complex.
REPEAT Read(R, ch); x[i] := ch; INC(i) UNTIL ch = 0X REPEAT Read(R, ch); x[i] := ch; INC(i) UNTIL ch = 0X
END ReadString; END ReadString;
PROCEDURE ReadLine* (VAR R: Rider; VAR x: ARRAY OF CHAR); PROCEDURE ReadLine* (VAR r: Rider; VAR x: ARRAY OF CHAR);
VAR i: INTEGER; VAR i: INTEGER; offset, limit: LONGINT; buffer: Buffer; eoln: BOOLEAN; ch: CHAR;
BEGIN BEGIN
i := 0; REPEAT Read(R, x[i]); INC(i) UNTIL (x[i-1] = 0X) OR (x[i-1] = 0AX); i := 0; limit := LEN(x)-1;
IF x[i-1] = 0AX THEN DEC(i) END; (* Omit trailing LF *) offset := r.offset; buffer := r.buf;
IF (i > 0) & (x[i-1] = 0DX) THEN DEC(i) END; (* Also omit preceeding trailing CR if present. *) eoln := r.eof OR (limit = 0);
x[i] := 0X; (* Guarantee zero termination. *) WHILE ~eoln DO
IF (r.org # buffer.org) OR (offset >= buffer.size) THEN (* Refresh buffer *)
IF r.org + offset < buffer.f.len THEN
Set(r, buffer.f, r.org+offset);
offset := r.offset; buffer := r.buf; eoln := r.eof;
ELSE
r.eof := TRUE; eoln := TRUE;
END
END;
WHILE (offset < buffer.size) & ~eoln DO
ch := SYSTEM.VAL(CHAR, buffer.data[offset]); INC(offset);
IF (ch # 0X) & (ch # 0AX) THEN
x[i] := ch; INC(i); eoln := i >= limit
ELSE
eoln := TRUE
END
END;
r.offset := offset;
IF i=limit THEN eoln := TRUE END
END;
IF (i>0) & (x[i-1] = 0DX) THEN DEC(i) END; (* Exclude CR if present at eol *)
x[i] := 0X
END ReadLine; END ReadLine;
(* old readline code:
REPEAT Read(R, x[i]); INC(i) UNTIL (x[i-1] = 0X) OR (x[i-1] = 0AX);
IF x[i-1] = 0AX THEN DEC(i) END; ( * Omit trailing LF * )
IF (i > 0) & (x[i-1] = 0DX) THEN DEC(i) END; ( * Also omit preceeding trailing CR if present. * )
x[i] := 0X; ( * Guarantee zero termination. * )
*)
PROCEDURE ReadNum*(VAR R: Rider; VAR x: ARRAY OF SYSTEM.BYTE); PROCEDURE ReadNum*(VAR R: Rider; VAR x: ARRAY OF SYSTEM.BYTE);
VAR s, b: SYSTEM.INT8; q: SYSTEM.INT64; VAR s, b: SYSTEM.INT8; q: SYSTEM.INT64;
BEGIN s := 0; q := 0; Read(R, b); BEGIN s := 0; q := 0; Read(R, b);

4
src/runtime/Strings.Mod Normal file → Executable file
View file

@ -29,9 +29,9 @@ Strings.Cap(s)
-------------------------------------------------------------*) -------------------------------------------------------------*)
(* added from trianus v4 *) (* added from trianus v4 *)
MODULE Strings; (*HM 94-06-22 / *) (* noch 2017-06-21 *) MODULE Strings; (*HM 94-06-22 / *) (* noch 2017-06-21 *)
IMPORT Reals; IMPORT Reals, SYSTEM;
PROCEDURE Length* (s: ARRAY OF CHAR): INTEGER; PROCEDURE Length* (s: ARRAY [1] OF CHAR): INTEGER;
VAR i: LONGINT; VAR i: LONGINT;
BEGIN BEGIN
i := 0; WHILE (i < LEN(s)) & (s[i] # 0X) DO INC(i) END; i := 0; WHILE (i < LEN(s)) & (s[i] # 0X) DO INC(i) END;