HostFiles.NewWriter violating the specification
|Assignee:||I. Denisov||% Done:|
According to the specification (System/Docu/Files) in case of read-only files (shared) NewWriter should return NIL. The current implementation, however, generates a TRAP. The specification needs to be aligned with the implementation. In order to be able to avoid the TRAP, two new File methods (Shared() and Closed()) should be introduced that return the file's current state.
Reported by Ilya Ermakov, 2009-10-12.
Documentation for Files fixed according the sources logic. New procedures Shared() and Closed() were added for balancing of ASSERTs inside NewWriter procedure. Refs: #22
#2 Updated by J. Templ about 4 years ago
- Description updated (diff)
PROCEDURE (f: File) NewWriter (old: Writer): Writer
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.
[b]Read-only files allow no writers at all. In such cases, NewWriter returns NIL.[/b]
result # NIL
old # NIL & old.Base() = f
result.Pos() = old.Pos()
old = NIL OR old.Base() # f
result.Pos() = f.Length()
result = NIL
However the code of HostFiles is next: 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;
ASSERT; means TRAP except RETURN NIL.