According the specification in a case of read-only files NewWriter should return NIL.
However the code of HostFiles is next:System/Docu/Files wrote:PROCEDURE (f: File) NewWriter (old: Writer): Writer
NEW, ABSTRACT
Returns a writer which has the appropriate type (for this file type). If old = NIL, then a new writer is allocated. If old # NIL and old has the appropriate type, old is returned. Otherwise, a new writer is allocated. The returned writer is connected to f, and its position is somewhere on the file. If an old writer is passed as parameter, the old position will be retained if possible.
If an old writer is passed as parameter, it is the application's responsibility to guarantee that it is not in use anymore. Passing an unused old writer is recommended because it avoids unnecessary allocations.
Read-only files allow no writers at all. In such cases, NewWriter returns NIL.
Post
result # NIL
old # NIL & old.Base() = f
result.Pos() = old.Pos()
old = NIL OR old.Base() # f
result.Pos() = f.Length()
result = NIL
read-only file
Code: Select all
PROCEDURE (f: File) NewWriter (old: Files.Writer): Files.Writer;
VAR w: Writer;
BEGIN (* portable *)
ASSERT(f.state # closed, 20); ASSERT(f.state # shared, 21);
IF (old # NIL) & (old IS Writer) THEN w := old(Writer) ELSE NEW(w) END;
IF w.base # f THEN
w.base := f; w.buf := NIL; w.SetPos(f.len)
END;
RETURN w
END NewWriter;
Ilya had suggested next solution:
Code: Select all
PROCEDURE (f: File) NewWriter (old: Files.Writer): Files.Writer;
VAR w: Writer;
BEGIN (* portable *)
ASSERT(f.state # closed, 20);
IF f.state # shared THEN
IF (old # NIL) & (old IS Writer) THEN w := old(Writer) ELSE NEW(w) END;
IF w.base # f THEN
w.base := f; w.buf := NIL; w.SetPos(f.len)
END;
RETURN w
ELSE
RETURN NIL
END
END NewWriter;