home *** CD-ROM | disk | FTP | other *** search
/ Gold Fish 3 / goldfish_volume_3.bin / files / dev / obero / oberon / projectoberonsrc / files.mod (.txt) < prev    next >
Encoding:
Oberon Text  |  1994-10-17  |  15.4 KB  |  484 lines

  1. Syntax10.Scn.Fnt
  2. MODULE Files;  (*NW 11.1.86 / 22.9.93*)
  3.     IMPORT SYSTEM, Kernel, FileDir;
  4.     (*A file consists of a sequence of pages. The first page
  5.         contains the header. Part of the header is the page table, an array
  6.         of disk addresses to the pages. A file is referenced through riders.
  7.         A rider indicates a current position and refers to a file*)
  8.     CONST MaxBufs    = 4;
  9.                 HS         = FileDir.HeaderSize;
  10.                 SS         = FileDir.SectorSize;
  11.                 STS        = FileDir.SecTabSize;
  12.                 XS         = FileDir.IndexSize;
  13.     TYPE  DiskAdr = LONGINT;
  14.                 File*   = POINTER TO Handle;
  15.                 Buffer   = POINTER TO BufferRecord;
  16.                 FileHd  = POINTER TO FileDir.FileHeader;
  17.                 Index  = POINTER TO IndexRecord;
  18.         Rider* =
  19.             RECORD eof*: BOOLEAN;
  20.                 res*: LONGINT;
  21.                 file: File;
  22.                 apos, bpos: INTEGER;
  23.                 buf: Buffer;
  24.                 unused: LONGINT
  25.             END ;
  26.         Handle =
  27.             RECORD next: File;
  28.                 aleng, bleng: INTEGER;
  29.                 nofbufs: INTEGER;
  30.                 modH: BOOLEAN;
  31.                 firstbuf: Buffer;
  32.                 sechint: DiskAdr;
  33.                 name: FileDir.FileName;
  34.                 time, date: LONGINT;
  35.                 unused: ARRAY 1 OF LONGINT;
  36.                 ext:  ARRAY FileDir.ExTabSize OF Index;
  37.                 sec: FileDir.SectorTable
  38.             END ;
  39.         BufferRecord =
  40.             RECORD apos, lim: INTEGER;
  41.                 mod: BOOLEAN;
  42.                 next: Buffer;
  43.                 data: FileDir.DataSector
  44.             END ;
  45.         IndexRecord =
  46.             RECORD adr: DiskAdr;
  47.                 mod: BOOLEAN;
  48.                 sec: FileDir.IndexSector
  49.             END ;
  50.         (*aleng * SS + bleng = length (including header)
  51.             apos * SS + bpos = current position
  52.             0 <= bpos <= lim <= SS
  53.             0 <= apos <= aleng < PgTabSize
  54.             (apos < aleng) & (lim = SS) OR (apos = aleng) *)
  55.     VAR root: File;  (*list of open files*)
  56.     (*Exported procedure:
  57.         Old, New, Register, Close, Purge, Length, GetDate,
  58.         Set, Read, ReadBytes, Write, WriteBytes, Pos, Base,
  59.         Rename, Delete*)
  60.     PROCEDURE Check(VAR s: ARRAY OF CHAR;
  61.                                             VAR name: FileDir.FileName; VAR res: INTEGER);
  62.         VAR i: INTEGER; ch: CHAR;
  63.     BEGIN ch := s[0]; i := 0;
  64.         IF ("A" <= CAP(ch)) & (CAP(ch) <= "Z") THEN
  65.             LOOP name[i] := ch; INC(i); ch := s[i];
  66.                 IF ch = 0X THEN
  67.                     WHILE i < FileDir.FnLength DO name[i] := 0X; INC(i) END ;
  68.                     res := 0; EXIT
  69.                 END ;
  70.                 IF ~(("A" <= CAP(ch)) & (CAP(ch) <= "Z")
  71.                     OR ("0" <= ch) & (ch <= "9") OR (ch = ".")) THEN res := 3; EXIT
  72.                 END ;
  73.                 IF i = FileDir.FnLength THEN res := 4; EXIT END ;
  74.             END
  75.         ELSIF ch = 0X THEN name[0] := 0X; res := -1
  76.         ELSE res := 3
  77.         END
  78.     END Check;
  79.     PROCEDURE Old*(name: ARRAY OF CHAR): File;
  80.         VAR i, k, res: INTEGER;
  81.             f: File;
  82.             header: DiskAdr;
  83.             buf: Buffer;
  84.             head: FileHd;
  85.             namebuf: FileDir.FileName;
  86.             inxpg: Index;
  87.     BEGIN f := NIL; Check(name, namebuf, res);
  88.         IF res = 0 THEN
  89.             FileDir.Search(namebuf, header);
  90.             IF header # 0 THEN f := root;
  91.                 WHILE (f # NIL) & (f.sec[0] # header) DO f := f.next END ;
  92.                 IF f = NIL THEN
  93.                     NEW(buf); buf.apos := 0; buf.next := buf; buf.mod := FALSE;
  94.                     head := SYSTEM.VAL(FileHd, SYSTEM.ADR(buf.data));
  95.                     Kernel.GetSector(header, head^);
  96.                     NEW(f); f.aleng := head.aleng; f.bleng := head.bleng;
  97.                     f.time := head.time; f.date := head.date;
  98.                     IF f.aleng = 0 THEN buf.lim := f.bleng ELSE buf.lim := SS END ;
  99.                     f.firstbuf := buf; f.nofbufs := 1; f.name[0] := 0X;
  100.                     f.sec := head.sec;
  101.                     k := (f.aleng + (XS-STS)) DIV XS; i := 0;
  102.                     WHILE i < k DO
  103.                         NEW(inxpg); inxpg.adr := head.ext[i]; inxpg.mod := FALSE;
  104.                         Kernel.GetSector(inxpg.adr, inxpg.sec); f.ext[i] := inxpg; INC(i)
  105.                     END ;
  106.                     WHILE i < FileDir.ExTabSize DO f.ext[i] := NIL; INC(i) END ;
  107.                     f.sechint := header; f.modH := FALSE; f.next := root; root := f 
  108.                 END
  109.             END
  110.         END ;
  111.         RETURN f
  112.     END Old;
  113.     PROCEDURE New*(name: ARRAY OF CHAR): File;
  114.         VAR i, res: INTEGER;
  115.             f: File;
  116.             buf: Buffer;
  117.             head: FileHd;
  118.             namebuf: FileDir.FileName;
  119.     BEGIN f := NIL; Check(name, namebuf, res);
  120.         IF res <= 0 THEN
  121.             NEW(buf); buf.apos := 0; buf.mod := TRUE; buf.lim := HS; buf.next := buf;
  122.             head := SYSTEM.VAL(FileHd, SYSTEM.ADR(buf.data));
  123.             head.mark := FileDir.HeaderMark;
  124.             head.aleng := 0; head.bleng := HS; head.name := namebuf;
  125.             Kernel.GetClock(head.time, head.date);
  126.             NEW(f); f.aleng := 0; f.bleng := HS; f.modH := TRUE;
  127.             f.time := head.time; f.date := head.date;
  128.             f.firstbuf := buf; f.nofbufs := 1; f.name := namebuf; f.sechint := 0;
  129.             i := 0;
  130.             REPEAT f.ext[i] := NIL; head.ext[i] := 0; INC(i) UNTIL i = FileDir.ExTabSize;
  131.             i := 0;
  132.             REPEAT f.sec[i] := 0; head.sec[i] := 0; INC(i) UNTIL i = STS
  133.         END ;
  134.         RETURN f
  135.     END New;
  136.     PROCEDURE UpdateHeader(f: File; VAR h: FileDir.FileHeader);
  137.         VAR k: INTEGER;
  138.     BEGIN h.aleng := f.aleng; h.bleng := f.bleng;
  139.         h.sec := f.sec; k := (f.aleng + (XS-STS)) DIV XS;
  140.         WHILE k > 0 DO DEC(k); h.ext[k] := f.ext[k].adr END
  141.     END UpdateHeader;
  142.     PROCEDURE ReadBuf(f: File; buf: Buffer; pos: INTEGER);
  143.         VAR sec: DiskAdr;
  144.     BEGIN
  145.         IF pos < STS THEN sec := f.sec[pos]
  146.         ELSE sec := f.ext[(pos-STS) DIV XS].sec.x[(pos-STS) MOD XS]
  147.         END ;
  148.         Kernel.GetSector(sec, buf.data);
  149.         IF pos < f.aleng THEN buf.lim := SS ELSE buf.lim := f.bleng END ;
  150.         buf.apos := pos; buf.mod := FALSE
  151.     END ReadBuf;
  152.     PROCEDURE WriteBuf(f: File; buf: Buffer);
  153.         VAR i, k: INTEGER;
  154.             secadr: DiskAdr; inx: Index;
  155.     BEGIN
  156.         IF buf.apos < STS THEN
  157.             secadr := f.sec[buf.apos];
  158.             IF secadr = 0 THEN
  159.                 Kernel.AllocSector(f.sechint, secadr);
  160.                 f.modH := TRUE; f.sec[buf.apos] := secadr; f.sechint := secadr
  161.             END ;
  162.             IF buf.apos = 0 THEN
  163.                 UpdateHeader(f, SYSTEM.VAL(FileDir.FileHeader, buf.data)); f.modH := FALSE
  164.             END
  165.         ELSE i := (buf.apos - STS) DIV XS; inx := f.ext[i];
  166.             IF inx = NIL THEN
  167.                 NEW(inx); inx.adr := 0; inx.sec.x[0] := 0; f.ext[i] := inx; f.modH := TRUE
  168.             END ;
  169.             k := (buf.apos - STS) MOD XS; secadr := inx.sec.x[k];
  170.             IF secadr = 0 THEN
  171.                 Kernel.AllocSector(f.sechint, secadr);
  172.                 f.modH := TRUE; inx.mod := TRUE; inx.sec.x[k] := secadr; f.sechint := secadr
  173.             END
  174.         END ;
  175.         Kernel.PutSector(secadr, buf.data); buf.mod := FALSE
  176.     END WriteBuf;
  177.     PROCEDURE Buf(f: File; pos: INTEGER): Buffer;
  178.         VAR buf: Buffer;
  179.     BEGIN buf := f.firstbuf;
  180.         LOOP
  181.             IF buf.apos = pos THEN EXIT END ;
  182.             buf := buf.next;
  183.             IF buf = f.firstbuf THEN buf := NIL; EXIT END
  184.         END ;
  185.         RETURN buf
  186.     END Buf;
  187.     PROCEDURE GetBuf(f: File; pos: INTEGER): Buffer;
  188.         VAR buf: Buffer;
  189.     BEGIN buf := f.firstbuf;
  190.         LOOP
  191.             IF buf.apos = pos THEN EXIT END ;
  192.             IF buf.next = f.firstbuf THEN
  193.                 IF f.nofbufs < MaxBufs THEN (*allocate new buffer*)
  194.                     NEW(buf); buf.next := f.firstbuf.next; f.firstbuf.next := buf;
  195.                     INC(f.nofbufs)
  196.                 ELSE (*take one of the buffers*) f.firstbuf := buf;
  197.                     IF buf.mod THEN WriteBuf(f, buf) END
  198.                 END ;
  199.                 buf.apos := pos;
  200.                 IF pos <= f.aleng THEN ReadBuf(f, buf, pos) END ;
  201.                 EXIT
  202.             END ;
  203.             buf := buf.next
  204.         END ;
  205.         RETURN buf
  206.     END GetBuf;
  207.     PROCEDURE Unbuffer(f: File);
  208.         VAR i, k: INTEGER;
  209.             buf: Buffer;
  210.             inx: Index;
  211.             head: FileDir.FileHeader;
  212.     BEGIN buf := f.firstbuf;
  213.         REPEAT
  214.             IF buf.mod THEN WriteBuf(f, buf) END ;
  215.             buf := buf.next
  216.         UNTIL buf = f.firstbuf;
  217.         k := (f.aleng + (XS-STS)) DIV XS; i := 0;
  218.         WHILE i < k DO
  219.             inx := f.ext[i]; INC(i);
  220.             IF inx.mod THEN
  221.                 IF inx.adr = 0 THEN
  222.                     Kernel.AllocSector(f.sechint, inx.adr); f.sechint := inx.adr; f.modH := TRUE
  223.                 END ;
  224.                 Kernel.PutSector(inx.adr, inx.sec); inx.mod := FALSE
  225.             END
  226.         END ;
  227.         IF f.modH THEN
  228.             Kernel.GetSector(f.sec[0], head); UpdateHeader(f, head);
  229.             Kernel.PutSector(f.sec[0], head); f.modH := FALSE
  230.         END
  231.     END Unbuffer;
  232.     PROCEDURE Register*(f: File);
  233.     BEGIN
  234.         IF (f # NIL) & (f.name[0] > 0X) THEN
  235.             Unbuffer(f); FileDir.Insert(f.name, f.sec[0]); f.name[0] := 0X; f.next := root; root := f
  236.         END ;
  237.     END Register;
  238.     PROCEDURE Close*(f: File);
  239.     BEGIN
  240.         IF f # NIL THEN Unbuffer(f) END ;
  241.     END Close;
  242.     PROCEDURE Purge*(f: File);
  243.         VAR a, i, j, k: INTEGER;
  244.             ind: FileDir.IndexSector;
  245.     BEGIN
  246.         IF f # NIL THEN a := f.aleng + 1; f.aleng := 0; f.bleng := HS;
  247.             IF a <= STS THEN i := a
  248.             ELSE i := STS; DEC(a, i);
  249.                 j := (a-1) MOD XS + 1; k := (a-1) DIV XS + 1;
  250.                 REPEAT DEC(k); Kernel.GetSector(f.ext[k].adr, ind);
  251.                     REPEAT DEC(j); Kernel.FreeSector(ind.x[j]) UNTIL j = 0;
  252.                     Kernel.FreeSector(f.ext[k].adr); j := XS
  253.                 UNTIL k = 0
  254.             END ;
  255.             REPEAT DEC(i); Kernel.FreeSector(f.sec[i]); f.sec[i] := 0
  256.             UNTIL i = 0;
  257.             f.nofbufs := 1; f.firstbuf.next := NIL; f.modH := TRUE
  258.         END
  259.     END Purge;
  260.     PROCEDURE Length*(f: File): LONGINT;
  261.     BEGIN RETURN LONG(f.aleng)*SS + f.bleng - HS
  262.     END Length;
  263.     PROCEDURE GetDate*(f: File; VAR t, d: LONGINT);
  264.     BEGIN t := f.time; d := f.date
  265.     END GetDate;
  266.     (*---------------------------Read/Write---------------------------*)
  267.     PROCEDURE Set*(VAR r: Rider; f: File; pos: LONGINT);
  268.         VAR a, b: INTEGER;
  269.     BEGIN  r.eof := FALSE; r.res := 0;
  270.         IF f # NIL THEN
  271.             IF pos < 0 THEN a := 0; b := HS
  272.             ELSIF pos < LONG(f.aleng)*SS + f.bleng - HS THEN
  273.                 a := SHORT((pos + HS) DIV SS); b := SHORT((pos + HS) MOD SS);
  274.             ELSE a := f.aleng; b := f.bleng
  275.             END ;
  276.             r.file := f; r.apos := a; r.bpos := b; r.buf := f.firstbuf
  277.         ELSE r.file:= NIL
  278.         END
  279.     END Set;
  280.     PROCEDURE Pos*(VAR r: Rider): LONGINT;
  281.     BEGIN RETURN LONG(r.apos)*SS + r.bpos - HS
  282.     END Pos;
  283.     PROCEDURE Base*(VAR r: Rider): File;
  284.     BEGIN RETURN r.file
  285.     END Base;
  286.     PROCEDURE Read*(VAR r: Rider; VAR x: SYSTEM.BYTE);
  287.         VAR buf: Buffer;
  288.     BEGIN
  289.         IF r.apos # r.buf.apos THEN r.buf := GetBuf(r.file, r.apos) END ;
  290.         IF r.bpos < r.buf.lim THEN
  291.             x := r.buf.data.B[r.bpos]; INC(r.bpos)
  292.         ELSIF r.apos < r.file.aleng THEN
  293.             INC(r.apos); buf := Buf(r.file, r.apos);
  294.             IF buf = NIL THEN
  295.                 IF r.buf.mod THEN WriteBuf(r.file, r.buf) END ;
  296.                 ReadBuf(r.file, r.buf, r.apos)
  297.             ELSE r.buf := buf
  298.             END ;
  299.             x := r.buf.data.B[0]; r.bpos := 1
  300.         ELSE
  301.             x := 0X; r.eof := TRUE
  302.         END
  303.     END Read;
  304.     PROCEDURE ReadBytes*(VAR r: Rider; VAR x: ARRAY OF SYSTEM.BYTE; n: LONGINT);
  305.         VAR src, dst, m: LONGINT; buf: Buffer;
  306.     BEGIN dst := SYSTEM.ADR(x);
  307.         IF LEN(x) < n THEN HALT(25) END ;
  308.         IF r.apos # r.buf.apos THEN r.buf := GetBuf(r.file, r.apos) END ;
  309.         LOOP
  310.             IF n <= 0 THEN EXIT END ;
  311.             src := SYSTEM.ADR(r.buf.data.B) + r.bpos; m := r.bpos + n;
  312.             IF m <= r.buf.lim THEN
  313.                 SYSTEM.MOVE(src, dst, n); r.bpos := SHORT(m); r.res := 0; EXIT
  314.             ELSIF r.buf.lim = SS THEN
  315.                 m := r.buf.lim - r.bpos;
  316.                 IF m > 0 THEN SYSTEM.MOVE(src, dst, m); INC(dst, m); DEC(n, m) END ;
  317.                 IF r.apos < r.file.aleng THEN
  318.                     INC(r.apos); r.bpos := 0; buf := Buf(r.file, r.apos);
  319.                     IF buf = NIL THEN
  320.                         IF r.buf.mod THEN WriteBuf(r.file, r.buf) END ;
  321.                         ReadBuf(r.file, r.buf, r.apos)
  322.                     ELSE r.buf := buf
  323.                     END
  324.                 ELSE r.res := n; r.eof := TRUE; EXIT
  325.                 END
  326.             ELSE m := r.buf.lim - r.bpos;
  327.                 IF m > 0 THEN SYSTEM.MOVE(src, dst, m); r.bpos := r.buf.lim END ;
  328.                 r.res := n - m; r.eof := TRUE; EXIT
  329.             END
  330.         END
  331.     END ReadBytes;
  332.     PROCEDURE ReadInt*(VAR R: Rider; VAR x: INTEGER);
  333.         VAR x0, x1: SHORTINT;
  334.     BEGIN Read(R, x0); Read(R, x1);
  335.         x := LONG(x1) * 100H + LONG(x0) MOD 100H
  336.     END ReadInt;
  337.     PROCEDURE ReadLInt*(VAR R: Rider; VAR x: LONGINT);
  338.     BEGIN ReadBytes(R, x, 4)
  339.     END ReadLInt;
  340.     PROCEDURE ReadSet*(VAR R: Rider; VAR x: SET);
  341.     BEGIN ReadBytes(R, x, 4)
  342.     END ReadSet;
  343.     PROCEDURE ReadBool*(VAR R: Rider; VAR x: BOOLEAN);
  344.         VAR s: SHORTINT;
  345.     BEGIN Read(R, s); x := s # 0
  346.     END ReadBool;
  347.     PROCEDURE ReadReal*(VAR R: Rider; VAR x: REAL);
  348.     BEGIN ReadBytes(R, x, 4)
  349.     END ReadReal;
  350.     PROCEDURE ReadLReal*(VAR R: Rider; VAR x: LONGREAL);
  351.     BEGIN ReadBytes(R, x, 8)
  352.     END ReadLReal;
  353.     PROCEDURE ReadString*(VAR R: Rider; VAR x: ARRAY OF CHAR);
  354.         VAR i: INTEGER; ch: CHAR;
  355.     BEGIN i := 0;
  356.         LOOP
  357.             Read(R, ch); x[i] := ch; INC(i);
  358.             IF ch = 0X THEN EXIT END ;
  359.             IF i = LEN(x) THEN x[i-1] := 0X;
  360.                 REPEAT Read(R, ch) UNTIL ch = 0X;
  361.                 EXIT
  362.             END
  363.         END
  364.     END ReadString;
  365.     PROCEDURE ReadNum*(VAR R: Rider; VAR x: LONGINT);
  366.         VAR ch: CHAR; n: INTEGER; y: LONGINT;
  367.     BEGIN n := 0; y := 0; Read(R, ch);
  368.         WHILE ch >= 80X DO INC(y, SYSTEM.LSH(LONG(ch) - 128, n)); INC(n, 7); Read(R, ch) END;
  369.         x := ASH(SYSTEM.LSH(LONG(ch), 25), n-25) + y
  370.     END ReadNum;
  371.     PROCEDURE NewExt(f: File);
  372.         VAR i, k: INTEGER; ext: Index;
  373.     BEGIN k := (f.aleng - STS) DIV XS;
  374.         IF k = FileDir.ExTabSize THEN HALT(23) END ;
  375.         NEW(ext); ext.adr := 0; ext.mod := TRUE; f.ext[k] := ext; i := XS;
  376.         REPEAT DEC(i); ext.sec.x[i] := 0 UNTIL i = 0
  377.     END NewExt;
  378.     PROCEDURE Write*(VAR r: Rider; x: SYSTEM.BYTE);
  379.         VAR f: File; buf: Buffer;
  380.     BEGIN
  381.         IF r.apos # r.buf.apos THEN r.buf := GetBuf(r.file, r.apos) END ;
  382.         IF r.bpos >= r.buf.lim THEN
  383.             IF r.bpos < SS THEN
  384.                 INC(r.buf.lim); INC(r.file.bleng); r.file.modH := TRUE
  385.             ELSE f := r.file; WriteBuf(f, r.buf); INC(r.apos); buf := Buf(r.file, r.apos);
  386.                 IF buf = NIL THEN
  387.                     IF r.apos <= f.aleng THEN ReadBuf(f, r.buf, r.apos)
  388.                     ELSE r.buf.apos := r.apos; r.buf.lim := 1; INC(f.aleng); f.bleng := 1; f.modH := TRUE;
  389.                         IF (f.aleng - STS) MOD XS = 0 THEN NewExt(f) END
  390.                     END
  391.                 ELSE r.buf := buf
  392.                 END ;
  393.                 r.bpos := 0
  394.             END
  395.         END ;
  396.         r.buf.data.B[r.bpos] := x; INC(r.bpos); r.buf.mod := TRUE
  397.     END Write;
  398.     PROCEDURE WriteBytes*(VAR r: Rider; VAR x: ARRAY OF SYSTEM.BYTE; n: LONGINT);
  399.         VAR src, dst, m: LONGINT; f: File; buf: Buffer;
  400.     BEGIN src := SYSTEM.ADR(x);
  401.         IF LEN(x) < n THEN HALT(25) END ;
  402.         IF r.apos # r.buf.apos THEN r.buf := GetBuf(r.file, r.apos) END ;
  403.         LOOP
  404.             IF n <= 0 THEN EXIT END ;
  405.             r.buf.mod := TRUE; dst := SYSTEM.ADR(r.buf.data.B) + r.bpos; m := r.bpos + n;
  406.             IF m <= r.buf.lim THEN
  407.                 SYSTEM.MOVE(src, dst, n); r.bpos := SHORT(m); EXIT
  408.             ELSIF m <= SS THEN
  409.                 SYSTEM.MOVE(src, dst, n); r.bpos := SHORT(m);
  410.                 r.file.bleng := SHORT(m); r.buf.lim := SHORT(m); r.file.modH := TRUE; EXIT
  411.             ELSE m := SS - r.bpos;
  412.                 IF m > 0 THEN SYSTEM.MOVE(src, dst, m); INC(src, m); DEC(n, m) END ;
  413.                 f := r.file; WriteBuf(f, r.buf); INC(r.apos); r.bpos := 0; buf := Buf(f, r.apos);
  414.                 IF buf = NIL THEN
  415.                     IF r.apos <= f.aleng THEN ReadBuf(f, r.buf, r.apos)
  416.                     ELSE r.buf.apos := r.apos; r.buf.lim := 0; INC(f.aleng); f.bleng := 0; f.modH := TRUE;
  417.                         IF (f.aleng - STS) MOD XS = 0 THEN NewExt(f) END
  418.                     END
  419.                 ELSE r.buf := buf
  420.                 END
  421.             END
  422.         END
  423.     END WriteBytes;
  424.     PROCEDURE WriteInt*(VAR R: Rider; x: INTEGER);
  425.     BEGIN Write(R, SHORT(x)); Write(R, SHORT(x DIV 100H))
  426.     END WriteInt;
  427.     PROCEDURE WriteLInt*(VAR R: Rider; x: LONGINT);
  428.     BEGIN WriteBytes(R, x, 4)
  429.     END WriteLInt;
  430.     PROCEDURE WriteSet*(VAR R: Rider; x: SET);
  431.     BEGIN WriteBytes(R, x, 4)
  432.     END WriteSet;
  433.     PROCEDURE WriteBool*(VAR R: Rider; x: BOOLEAN);
  434.     BEGIN
  435.         IF x THEN Write(R, 1) ELSE Write(R, 0) END
  436.     END WriteBool;
  437.     PROCEDURE WriteReal*(VAR R: Rider; x: REAL);
  438.     BEGIN WriteBytes(R, x, 4)
  439.     END WriteReal;
  440.     PROCEDURE WriteLReal*(VAR R: Rider; x: LONGREAL);
  441.     BEGIN WriteBytes(R, x, 8)
  442.     END WriteLReal;
  443.     PROCEDURE WriteString*(VAR R: Rider; x: ARRAY OF CHAR);
  444.         VAR i: INTEGER; ch: CHAR;
  445.     BEGIN i := 0;
  446.         LOOP ch := x[i]; Write(R, ch); INC(i);
  447.             IF ch = 0X THEN EXIT END ;
  448.             IF i = LEN(x) THEN Write(R, 0X); EXIT END
  449.         END
  450.     END WriteString;
  451.     PROCEDURE WriteNum*(VAR R: Rider; x: LONGINT);
  452.     BEGIN
  453.         WHILE (x < - 64) OR (x > 63) DO Write(R, CHR(x MOD 128 + 128)); x := x DIV 128 END;
  454.         Write(R, CHR(x MOD 128))
  455.     END WriteNum;
  456.     PROCEDURE Delete*(name: ARRAY OF CHAR; VAR res: INTEGER);
  457.         VAR adr: DiskAdr;
  458.                 namebuf: FileDir.FileName;
  459.     BEGIN Check(name, namebuf, res);
  460.         IF res = 0 THEN
  461.             FileDir.Delete(namebuf, adr);
  462.             IF adr = 0 THEN res := 2 END
  463.         END
  464.     END Delete;
  465.     PROCEDURE Rename*(old, new: ARRAY OF CHAR; VAR res: INTEGER);
  466.         VAR adr: DiskAdr;
  467.                 oldbuf, newbuf: FileDir.FileName;
  468.                 head: FileDir.FileHeader;
  469.     BEGIN Check(old, oldbuf, res);
  470.         IF res = 0 THEN
  471.             Check(new, newbuf, res);
  472.             IF res = 0 THEN
  473.                 FileDir.Delete(oldbuf, adr);
  474.                 IF adr # 0 THEN
  475.                     FileDir.Insert(newbuf, adr);
  476.                     Kernel.GetSector(adr, head); head.name := newbuf; Kernel.PutSector(adr, head)
  477.                 ELSE res := 2
  478.                 END
  479.             END
  480.         END
  481.     END Rename;
  482. BEGIN Kernel.FileRoot := SYSTEM.ADR(root)
  483. END Files.
  484.