(*****************************************************************************) (* Bibliotheks-Modul BYTEFILE *) (* Ermoeglicht auch unter CP/M das byteweise Lesen einer Datei *) (* *) (* (c MaxBytePuffer = 1024 kann auf Vielfache von 128 gesetzt werden ) *) (* (t BF_strl4 ) *) (* (p LiesBlock) *) (* *) (* t ByteFile entspricht FILE OF BYTE, *) (* kompatibel zu allen Diskettendateien *) (* p assignByteFile wie ASSIGN *) (* p resetByteFile wie RESET *) (* p rewriteByteFile wie REWRITE *) (* p CloseByteFile wie CLOSE *) (* f EOFByteFile wie EOF *) (* f LongFileSizeByteFile wie LONGFILESIZE, Ergebnis REAL! *) (* f LongFilePosByteFile wie LONGFILEPOS, Ergebnis REAL! *) (* p FlushByteFile wie FLUSH *) (* p LongSeekByteFile wie LONGSEEK, Position vom Typ REAL! *) (* p readByteFile wie READ *) (* p writeByteFile wie WRITE *) (* v IOResultByteFile wie IOResult (nur nach reset und rewrite) *) (* p eraseByteFile wie ERASE *) (* p renameByteFile wie RENAME *) (*****************************************************************************) CONST MaxBytePuffer = 1024; TYPE BF_str14 = STRING[14]; ByteFile = RECORD f : FILE; Puffer : ARRAY[1..MaxBytePuffer] OF byte; Ptr, Erster, Letzter, Size : integer; WriteFlag : boolean; END; VAR IOResultByteFile : integer; PROCEDURE LiesBlock(VAR BF : ByteFile; Nr : integer); FUNCTION MIN(x,y : integer):integer; BEGIN IF x=Erster) AND (Seite<=Letzter) THEN Ptr:=((Seite-Erster ) SHL 7) OR Nummer ELSE BEGIN FlushByteFile(BF); LiesBlock(BF,Seite); Ptr:=Nummer END; END; (* LongSeekByteFile *) FUNCTION LongFilePosByteFile(VAR BF : ByteFile) : real; BEGIN WITH BF DO LongFilePosByteFile:=128.0*pred(Erster)+Ptr END; (* LongFilePosByteFile *) FUNCTION EOFByteFile(VAR BF : ByteFile):boolean; BEGIN WITH BF DO EOFByteFile:=(Letzter=Size) AND (Ptr=succ(Letzter-Erster) SHL 7) END; (* EOFByteFile *) FUNCTION LongFileSizeByteFile(VAR BF : ByteFile) : real; BEGIN LongFileSizeByteFile:=128.0*BF.Size END; (* LongFileSizeByteFile *) PROCEDURE assignByteFile(VAR BF : ByteFile; Name : BF_str14); BEGIN WITH BF DO assign(f,Name); END; (* assignByteFile *) PROCEDURE resetByteFile(VAR BF : ByteFile); BEGIN WITH BF DO BEGIN (*$I-*) reset(f) (*$I+*); Letzter:=0; WriteFlag:=false; IOResultByteFile:=IOResult; IF IOResultByteFile=0 THEN BEGIN (*$I-*) Size:=FileSize(f) (*$I+*); IOResultByteFile:=IOResult; IF IOResultByteFile=0 THEN LongSeekByteFile(BF,0) END (* IF *) END (* WITH *) END; (* resetByteFile *) PROCEDURE rewriteByteFile(VAR BF : ByteFile); BEGIN WITH BF DO BEGIN (*$I-*) rewrite(f) (*$I+*); IOResultByteFile:=IOResult; Ptr:=0; Erster:=1; Letzter:=0; Size:=0; WriteFlag:=false END (* WITH *) END; (* rewriteByteFile *) PROCEDURE readByteFile(VAR BF : ByteFile; VAR B : byte); BEGIN WITH BF DO BEGIN IF Ptr=MaxBytePuffer THEN BEGIN FlushByteFile(BF); LiesBlock(BF,succ(Letzter)) END; Ptr:=succ(Ptr); B:=Puffer[Ptr] END (* WITH *) END; (* readByteFile *) PROCEDURE writeByteFile(VAR BF : ByteFile; B : Byte); FUNCTION MAX(x,y:integer):integer; BEGIN IF x>y THEN MAX:=x ELSE MAX:=y END; BEGIN WITH BF DO BEGIN IF Ptr=MaxBytePuffer THEN BEGIN FLushByteFile(BF); Erster:=succ(Letzter); Ptr:=0 END; Ptr:=succ(Ptr); Puffer[Ptr]:=B; Letzter:=MAX(Letzter,Erster+(pred(Ptr) SHR 7)); WriteFlag:=true; Size:=MAX(Size,Letzter) END (* WITH *) END; (* writeByteFile *) PROCEDURE closeByteFile(VAR BF : ByteFile); BEGIN FlushByteFile(BF); close(BF.f) END; (* closeByteFile *) PROCEDURE eraseByteFile(VAR BF : ByteFile); BEGIN erase(BF.f) END; (* eraseByteFile *) PROCEDURE renameByteFile(VAR BF : ByteFile; Name : BF_str14); BEGIN rename(BF.f,Name) END; (* renameByteFile *)