home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 10 / Fresh_Fish_10_2352.bin / new / dev / obero / oberon / projectoberonsrc / mfiles.mod (.txt) < prev    next >
Oberon Text  |  1994-10-18  |  5KB  |  160 lines

  1. Syntax10.Scn.Fnt
  2. MODULE MFiles;   (*NW 24.8.90 / 12.10.90  Ceres-3*)
  3.     IMPORT SYSTEM, Kernel, FileDir;
  4.     (*A file consists of a sequence of sectors. The first sector
  5.         contains the header. Part of the header is the sector table, an array
  6.         of addresses to the sectors. A file is referenced through riders.
  7.         A rider indicates a current position and refers to a file*)
  8.     CONST
  9.             HS         = FileDir.HeaderSize;
  10.             SS         = FileDir.SectorSize;
  11.             STS        = FileDir.SecTabSize;
  12.             XS         = FileDir.IndexSize;
  13.     TYPE File*   = POINTER TO Header;
  14.             Index  = POINTER TO FileDir.IndexSector;
  15.         Rider* =
  16.             RECORD eof*: BOOLEAN;
  17.                 res*: LONGINT;
  18.                 file: File;
  19.                 pos: LONGINT;
  20.                 unused: File;
  21.                 adr: LONGINT;
  22.             END ;
  23.         Header =
  24.             RECORD mark: LONGINT;
  25.                 name: FileDir.FileName;
  26.                 len, time, date: LONGINT;
  27.                 ext:  ARRAY FileDir.ExTabSize OF Index;
  28.                 sec: FileDir.SectorTable
  29.             END ;
  30.     PROCEDURE Old*(name: ARRAY OF CHAR): File;
  31.         VAR head: LONGINT;
  32.             namebuf: FileDir.FileName;
  33.     BEGIN COPY(name, namebuf);
  34.         FileDir.Search(namebuf, head); RETURN SYSTEM.VAL(File, head)
  35.     END Old;
  36.     PROCEDURE New*(name: ARRAY OF CHAR): File;
  37.         VAR f: File; head: LONGINT;
  38.     BEGIN f := NIL; Kernel.AllocSector(0, head);
  39.         IF head # 0 THEN
  40.             f := SYSTEM.VAL(File, head); f.mark := FileDir.HeaderMark;
  41.             f.len := HS; COPY(name, f.name);
  42.             Kernel.GetClock(f.time, f.date); f.sec[0] := head
  43.         END ;
  44.         RETURN f
  45.     END New;
  46.     PROCEDURE Register*(f: File);
  47.     BEGIN
  48.         IF (f # NIL) & (f.name[0] > 0X) THEN FileDir.Insert(f.name, f.sec[0]) END ;
  49.     END Register;
  50.     PROCEDURE Length*(f: File): LONGINT;
  51.     BEGIN RETURN f.len - HS
  52.     END Length;
  53.     PROCEDURE GetDate*(f: File; VAR t, d: LONGINT);
  54.     BEGIN t := f.time; d := f.date
  55.     END GetDate;
  56.     PROCEDURE Set*(VAR r: Rider; f: File; pos: LONGINT);
  57.         VAR m: INTEGER; n: LONGINT;
  58.     BEGIN  r.eof := FALSE; r.res := 0; r.unused := NIL;
  59.         IF f # NIL THEN
  60.             IF pos < 0 THEN r.pos := 0
  61.             ELSIF pos > f.len-HS THEN r.pos := f.len
  62.             ELSE r.pos := pos+HS
  63.             END ;
  64.             r.file := f; m := SHORT(r.pos DIV SS); n := r.pos MOD SS;
  65.             IF m < STS THEN r.adr := f.sec[m] + n
  66.             ELSE r.adr := f.ext[(m-STS) DIV XS].x[(m-STS) MOD XS] + n
  67.             END
  68.         END
  69.     END Set;
  70.     PROCEDURE Read*(VAR r: Rider; VAR x: SYSTEM.BYTE);
  71.         VAR m: INTEGER;
  72.     BEGIN
  73.         IF r.pos < r.file.len THEN
  74.             SYSTEM.GET(r.adr, x); INC(r.adr); INC(r.pos);
  75.             IF r.adr MOD SS = 0 THEN
  76.                 m := SHORT(r.pos DIV SS);
  77.                 IF m < STS THEN r.adr := r.file.sec[m]
  78.                 ELSE r.adr := r.file.ext[(m-STS) DIV XS].x[(m-STS) MOD XS]
  79.                 END
  80.             END
  81.         ELSE x := 0X; r.eof := TRUE
  82.         END
  83.     END Read;
  84.     PROCEDURE ReadBytes*(VAR r: Rider; VAR x: ARRAY OF SYSTEM.BYTE; n: LONGINT);
  85.         VAR src, dst, m: LONGINT; k: INTEGER;
  86.     BEGIN m := r.pos - r.file.len + n;
  87.         IF m > 0 THEN DEC(n, m); r.res := m; r.eof := TRUE END ;
  88.         src := r.adr; dst := SYSTEM.ADR(x); m := (-r.pos) MOD SS;
  89.         LOOP
  90.             IF n <= 0 THEN EXIT END ;
  91.             IF n <= m THEN SYSTEM.MOVE(src, dst, n); INC(r.pos, n); r.adr := src+n; EXIT END ;
  92.             SYSTEM.MOVE(src, dst, m); INC(r.pos, m); INC(dst,m); DEC(n, m);
  93.             k := SHORT(r.pos DIV SS); m := SS;
  94.             IF k < STS THEN src := r.file.sec[k]
  95.             ELSE src := r.file.ext[(k-STS) DIV SS].x[(k-STS) MOD XS]
  96.             END
  97.         END
  98.     END ReadBytes;
  99.     PROCEDURE Write*(VAR r: Rider; x: SYSTEM.BYTE);
  100.         VAR k, m, n: INTEGER; ix: LONGINT;
  101.     BEGIN
  102.         IF r.pos < r.file.len THEN
  103.             m := SHORT(r.pos DIV SS); INC(r.pos);
  104.             IF m < STS THEN r.adr := r.file.sec[m]
  105.             ELSE r.adr := r.file.ext[(m-STS) DIV XS].x[(m-STS) MOD XS]
  106.             END
  107.         ELSE 
  108.             IF r.adr MOD SS = 0 THEN
  109.                 m := SHORT(r.pos DIV SS);
  110.                 IF m < STS THEN Kernel.AllocSector(0, r.adr); r.file.sec[m] := r.adr
  111.                 ELSE n := (m-STS) DIV XS; k := (m-STS) MOD XS;
  112.                     IF k = 0 THEN (*new index*)
  113.                         Kernel.AllocSector(0, ix); r.file.ext[n] := SYSTEM.VAL(Index, ix)
  114.                     END ;
  115.                     Kernel.AllocSector(0, r.adr); r.file.ext[n].x[k] := r.adr
  116.                 END
  117.             END ;
  118.             INC(r.pos); r.file.len := r.pos
  119.         END ;
  120.         SYSTEM.PUT(r.adr, x); INC(r.adr)
  121.     END Write;
  122.     PROCEDURE WriteBytes*(VAR r: Rider; VAR x: ARRAY OF SYSTEM.BYTE; n: LONGINT);
  123.         VAR src, dst, m, ix: LONGINT;
  124.             k, lim, h0, h1: INTEGER;
  125.     BEGIN src := SYSTEM.ADR(x); dst := r.adr; m := (-r.pos) MOD SS; lim := SHORT(r.file.len DIV SS);
  126.         LOOP
  127.             IF n <= 0 THEN EXIT END ;
  128.             IF m = 0 THEN
  129.                 k := SHORT(r.pos DIV SS); m := SS;
  130.                 IF k > lim THEN
  131.                     Kernel.AllocSector(0, dst);
  132.                     IF k < STS THEN r.file.sec[k] := dst
  133.                     ELSE h1 := (k-STS) DIV XS; h0 := (k-STS) MOD XS;
  134.                         IF h0 = 0 THEN (*new extension index*)
  135.                             Kernel.AllocSector(0, ix); r.file.ext[h1] := SYSTEM.VAL(Index, ix)
  136.                         END ;
  137.                         r.file.ext[h1].x[h0] := dst
  138.                     END
  139.                 ELSIF k < STS THEN dst := r.file.sec[k]
  140.                 ELSE dst := r.file.ext[(k-STS) DIV XS].x[(k-STS) MOD XS]
  141.                 END ;
  142.             END ;
  143.             IF n < m THEN
  144.                 SYSTEM.MOVE(src, dst, n); INC(r.pos, n); r.adr := dst + n;
  145.                 IF r.pos >= r.file.len THEN r.file.len := r.pos END ;
  146.                 EXIT
  147.             END ;
  148.             SYSTEM.MOVE(src, dst, m); INC(r.pos, m);
  149.             IF r.pos >= r.file.len THEN r.file.len := r.pos END ;
  150.             INC(src, m); DEC(n, m); m := 0
  151.         END 
  152.     END WriteBytes;
  153.     PROCEDURE Pos*(VAR r: Rider): LONGINT;
  154.     BEGIN RETURN r.pos - HS
  155.     END Pos;
  156.     PROCEDURE Base*(VAR r: Rider): File;
  157.     BEGIN RETURN r.file
  158.     END Base;
  159. END MFiles.
  160.