home *** CD-ROM | disk | FTP | other *** search
/ Amiga ISO Collection / AmigaUtilCD2.iso / Programming / Misc / OB3.2D2.DMS / in.adf / Module / FileSystem.mod < prev    next >
Encoding:
Text File  |  1994-08-05  |  17.5 KB  |  716 lines

  1. (*-------------------------------------------------------------------------*)
  2. (*                                                                         *)
  3. (*  Amiga Oberon Library Module: FileSystem           Date: 02-Nov-92      *)
  4. (*                                                                         *)
  5. (*   © 1992 by Fridtjof Siebert                                            *)
  6. (*                                                                         *)
  7. (*-------------------------------------------------------------------------*)
  8.  
  9. (*-------------------------------------------------------------------------
  10.  
  11.    Dieses Modul erleichtert das Arbeiten mit Dateien. Es stellt Prozeduren
  12.    zur Dateiverwaltung zur Verfügung.
  13.  
  14.    Die Geschwindigkeit liegt normalerweise über der von Dos, da beim Lesen
  15.    und Schreiben Puffer verwendet werden.
  16.  
  17.    Die Prozeduren, die ein boolsches Ergebnis liefern, waren immer
  18.    erfolgreich, wenn sie TRUE zurückliefern. Ansonsten steht in der
  19.    Variable File.status die Fehlernummer, die eine genauere Diagnose der
  20.    Fehlerursache erlaubt.
  21.  
  22.    Die Prozedur Delete() macht das gleiche wie Close(), löscht danach aber
  23.    die bearbeitete Datei.
  24.  
  25. -------------------------------------------------------------------------*)
  26.  
  27. MODULE FileSystem;
  28.  
  29. IMPORT d  * := Dos,
  30.        e  * := Exec,
  31.        sys  := SYSTEM,
  32.        BT * := BasicTypes,
  33.        sd   := SecureDos;
  34.  
  35. CONST
  36.   BufSize = 1024;
  37.  
  38. (* File.status: *)
  39.  
  40.   ok        * = 0;  (* alles in Ordnung   *)
  41.   eof       * = 1;  (* Dateiende erreicht *)
  42.   readerr   * = 2;  (* Lesefehler         *)
  43.   writeerr  * = 3;  (* Schreibfehler      *)
  44.   onlyread  * = 4;  (* aus Datei darf nur gelesen werden    *)
  45.   onlywrite * = 5;  (* in Datei darf nur geschrieben werden *)
  46.   toofar    * = 6;  (* mit Move, Forward oder Backward zu weit gesprungen *)
  47.   outofmem  * = 7;  (* kein freier Speicher mehr *)
  48.   cantopen  * = 8;  (* konnte Datei nicht öffnen *)
  49.   cantlock  * = 9;  (* konnte Datei nicht locken *)
  50.  
  51. TYPE
  52.   FilePtr * = POINTER TO File;
  53.   File * = RECORD (BT.ANYDesc)
  54.  
  55.     handle    - : d.FileHandlePtr;
  56.     status    - : INTEGER;
  57.     write     - : BOOLEAN;
  58.     read      - : BOOLEAN;
  59.     name      - : ARRAY 256 OF CHAR;
  60.  
  61.     buffer      : POINTER TO ARRAY BufSize OF sys.BYTE;
  62.     string    - : BT.DynString;
  63.     bufpos      : INTEGER;
  64.     buflen      : LONGINT;
  65.     pos         : LONGINT;
  66.     size        : LONGINT;
  67.     lastRead    : BOOLEAN;
  68.  
  69.   END;
  70.  
  71. VAR
  72.   info: d.FileInfoBlock;
  73.  
  74.  
  75. (*-------------------------------------------------------------------------*)
  76.  
  77.  
  78. (*------  Open:  ------*)
  79.  
  80.  
  81. PROCEDURE Open*(VAR file: File;
  82.                     name: ARRAY OF CHAR;
  83.                     write: BOOLEAN): BOOLEAN;
  84.  
  85. (* öffnet die Datei mit dem Namen 'name'. Ist write TRUE, wird die Datei
  86.    neu erzeugt und zum Schreiben geöffnet. Sonst wird sie zum Lesen
  87.    geöffnet. Das Ergebnis ist TRUE, wenn alles ordnungsgemäß verlief. *)
  88.  
  89. VAR
  90.   mode: INTEGER;
  91.   lock: d.FileLockPtr;
  92.  
  93. BEGIN
  94.   file.buffer := NIL; file.handle := NIL; lock := NIL;
  95.   LOOP
  96.     NEW(file.buffer);
  97.     COPY(name,file.name);
  98.     IF write THEN mode := d.newFile
  99.              ELSE mode := d.oldFile END;
  100.     file.handle := sd.Open(name,mode);
  101.     IF file.handle = NIL THEN file.status := cantopen; EXIT END;
  102.     IF write THEN
  103.       file.size := 0;
  104.     ELSE
  105.       lock := sd.Lock(name,d.sharedLock);
  106.       IF lock=NIL                 THEN file.status := cantlock; EXIT END;
  107.       IF ~ d.Examine(lock,info) THEN file.status := cantlock; EXIT END;
  108.       file.size := info.size;
  109.       sd.UnLock(lock);
  110.     END;
  111.     file.bufpos := 0;
  112.     file.buflen := 0;
  113.     file.pos    := 0;
  114.     file.write  := write;
  115.     file.read   := ~ write;
  116.     file.status := ok;
  117.     RETURN TRUE;
  118.   END;
  119.   file.buffer := NIL;
  120.   IF file.handle#NIL THEN sd.Close(file.handle); file.handle := NIL END;
  121.   IF lock#NIL THEN sd.UnLock(lock) END;
  122.   RETURN FALSE;
  123. END Open;
  124.  
  125.  
  126. (*------  OpenReadWrite:  ------*)
  127.  
  128.  
  129. PROCEDURE OpenReadWrite*(VAR file: File;
  130.                          name: ARRAY OF CHAR): BOOLEAN;
  131.  
  132. (* öffnet die Datei mit dem Namen 'name' zum wechselnd schreibenden
  133.    und lesenden Zugriff. Das Ergebnis ist TRUE, wenn alles
  134.    ordnungsgemäß verlief. *)
  135.  
  136. VAR
  137.   lock: d.FileLockPtr;
  138.  
  139. BEGIN
  140.   file.buffer := NIL; file.handle := NIL; lock := NIL;
  141.   LOOP
  142.     NEW(file.buffer);
  143.     COPY(name,file.name);
  144.     file.handle := sd.Open(name,d.oldFile);
  145.     IF file.handle # NIL THEN
  146.       lock := sd.Lock(name,d.sharedLock);
  147.       IF lock=NIL                 THEN file.status := cantlock; EXIT END;
  148.       IF ~ d.Examine(lock,info) THEN file.status := cantlock; EXIT END;
  149.       file.size := info.size;
  150.       sd.UnLock(lock);
  151.     ELSE
  152.       file.handle := sd.Open(name,d.newFile);
  153.       IF file.handle = NIL THEN file.status := cantopen; EXIT END;
  154.       file.size := 0;
  155.     END;
  156.     file.bufpos := 0;
  157.     file.buflen := 0;
  158.     file.pos    := 0;
  159.     file.write  := TRUE;
  160.     file.read   := TRUE;
  161.     file.status := ok;
  162.     RETURN TRUE;
  163.   END;
  164.   file.buffer := NIL;
  165.   IF file.handle#NIL THEN sd.Close(file.handle); file.handle := NIL END;
  166.   IF lock#NIL THEN sd.UnLock(lock) END;
  167.   RETURN FALSE;
  168. END OpenReadWrite;
  169.  
  170.  
  171. PROCEDURE WriteBuf(VAR file: File): BOOLEAN;
  172.  
  173. VAR i,j,l: INTEGER;
  174.  
  175. BEGIN
  176.   i := 0; j := file.bufpos; file.bufpos := 0;
  177.   REPEAT
  178.     l := SHORT(d.Write(file.handle,file.buffer[i],j));
  179.     IF l<0 THEN
  180.       file.status := writeerr;
  181.       RETURN FALSE
  182.     END;
  183.     INC(i,l); DEC(j,l);
  184.   UNTIL j<=0;
  185.   file.status := ok;
  186.   RETURN TRUE;
  187. END WriteBuf;
  188.  
  189.  
  190.  
  191. PROCEDURE EmptyWriteBuf(VAR file: File): BOOLEAN;
  192.  
  193. BEGIN
  194.   IF file.write & (file.bufpos#0) THEN RETURN WriteBuf(file) END;
  195.   file.status := ok;
  196.   RETURN TRUE;
  197. END EmptyWriteBuf;
  198.  
  199.  
  200. (*------  Close:  ------*)
  201.  
  202.  
  203. PROCEDURE Close*(VAR file: File): BOOLEAN;
  204.  
  205. (*
  206.  * schließt die Datei file. Ergebnis ist TRUE, wenn alles korrekt verlief.
  207.  *)
  208.  
  209. VAR res: BOOLEAN;
  210.  
  211. BEGIN
  212.   file.status := ok;
  213.   res := TRUE;
  214.   IF file.write & (~ file.read OR ~ file.lastRead) THEN
  215.     res := EmptyWriteBuf(file);
  216.     file.bufpos := 0;
  217.     file.buflen := 0;
  218.     file.lastRead := TRUE;
  219.   END;
  220.   sd.Close(file.handle); file.handle := NIL;
  221.   (* $IF GarbageCollector *)
  222.     file.buffer := NIL;
  223.   (* $ELSE *)
  224.     DISPOSE(file.buffer);
  225.   (* $END *)
  226.   file.string := NIL;
  227.   RETURN res;
  228. END Close;
  229.  
  230.  
  231. (*-------------------------------------------------------------------------*)
  232.  
  233.  
  234. (*------  Read:  ------*)
  235.  
  236.  
  237. PROCEDURE Read*(VAR file: File; VAR to: ARRAY OF sys.BYTE): BOOLEAN;
  238.  
  239. (* liest LEN(to) Bytes aus file nach to. Ergebnis ist TRUE, wenn alles
  240. korrekt verlieft. *)
  241.  
  242. VAR
  243.   cnt: LONGINT;
  244.   bufpos: INTEGER;
  245.  
  246. BEGIN
  247.   IF ~ file.read THEN file.status := onlywrite; RETURN FALSE END;
  248.   IF file.write & ~ file.lastRead THEN
  249.     IF ~ EmptyWriteBuf(file) THEN RETURN FALSE END;
  250.     file.bufpos := 0;
  251.     file.buflen := 0;
  252.     file.lastRead := TRUE;
  253.   END;
  254.   cnt := 0; bufpos := file.bufpos;
  255.   WHILE cnt<LEN(to) DO
  256.     IF (bufpos=file.buflen) THEN
  257.       file.bufpos := 0; bufpos := 0;
  258.       file.buflen := d.Read(file.handle,file.buffer^,BufSize);
  259.       IF file.buflen=0 THEN file.status := eof;     RETURN FALSE END;
  260.       IF file.buflen<0 THEN file.status := readerr; RETURN FALSE END;
  261.     END;
  262.     to[cnt] := file.buffer[bufpos];
  263.     INC(cnt); INC(bufpos);
  264.   END;
  265.   file.bufpos := bufpos;
  266.   INC(file.pos,cnt);
  267.   file.status := ok;
  268.   RETURN TRUE;
  269. END Read;
  270.  
  271.  
  272. (*------  ReadChar:  ------*)
  273.  
  274.  
  275. PROCEDURE ReadChar*(VAR file: File; VAR ch: CHAR): BOOLEAN;
  276.  
  277. (* liest ein Zeichen aus file. Ergebnis ist TRUE, wenn alles korrekt
  278. verlieft. *)
  279.  
  280. BEGIN
  281.   IF ~ file.read THEN file.status := onlywrite; RETURN FALSE END;
  282.   IF file.write & ~ file.lastRead THEN
  283.     IF ~ EmptyWriteBuf(file) THEN RETURN FALSE END;
  284.     file.bufpos := 0;
  285.     file.buflen := 0;
  286.     file.lastRead := TRUE;
  287.   END;
  288.   IF (file.bufpos=file.buflen) THEN
  289.     file.bufpos := 0;
  290.     file.buflen := d.Read(file.handle,file.buffer^,BufSize);
  291.     IF file.buflen=0 THEN file.status := eof;     RETURN FALSE END;
  292.     IF file.buflen<0 THEN file.status := readerr; RETURN FALSE END;
  293.   END;
  294.   ch := file.buffer[file.bufpos];
  295.   INC(file.bufpos);
  296.   INC(file.pos);
  297.   file.status := ok;
  298.   RETURN TRUE;
  299. END ReadChar;
  300.  
  301.  
  302. (*------  ReadString:  ------*)
  303.  
  304.  
  305. PROCEDURE ReadString*(VAR file: File; VAR to: ARRAY OF CHAR): BOOLEAN;
  306.  
  307. (* liest einen String aus file nach to. Stringende ist durch 0X oder 0AX
  308. markiert. Ergebnis ist TRUE, wenn alles korrekt verlieft. *)
  309.  
  310. VAR
  311.   cnt: LONGINT;
  312.   bufpos: INTEGER;
  313.   eos: BOOLEAN;
  314.  
  315. BEGIN
  316.   IF ~ file.read THEN file.status := onlywrite; RETURN FALSE END;
  317.   IF file.write & ~ file.lastRead THEN
  318.     IF ~ EmptyWriteBuf(file) THEN RETURN FALSE END;
  319.     file.bufpos := 0;
  320.     file.buflen := 0;
  321.     file.lastRead := TRUE;
  322.   END;
  323.   cnt := 0; bufpos := file.bufpos; eos := FALSE;
  324.   WHILE (cnt<LEN(to)) & ~ eos DO
  325.     IF (bufpos=file.buflen) THEN
  326.       file.bufpos := 0; bufpos := 0;
  327.       file.buflen := d.Read(file.handle,file.buffer^,BufSize);
  328.       IF file.buflen=0 THEN file.status := eof;     RETURN FALSE END;
  329.       IF file.buflen<0 THEN file.status := readerr; RETURN FALSE END;
  330.     END;
  331.     to[cnt] := file.buffer[bufpos];
  332.     CASE to[cnt] OF 0X,0AX: eos := TRUE; to[cnt] := 0X | ELSE END;
  333.     INC(cnt); INC(bufpos);
  334.   END;
  335.   file.bufpos := bufpos;
  336.   INC(file.pos,cnt);
  337.   file.status := ok;
  338.   RETURN TRUE;
  339. END ReadString;
  340.  
  341.  
  342. (*------  ReadLongString:  ------*)
  343.  
  344.  
  345. PROCEDURE ReadLongString*(VAR file: File): BOOLEAN;
  346.  
  347. (*
  348.  * liest einen String aus file nach file.string. Stringende ist durch 0X oder 0AX
  349.  * markiert. Ergebnis ist TRUE, wenn alles korrekt verlieft.
  350.  *)
  351.  
  352. VAR
  353.   cnt: LONGINT;
  354.   bufpos: INTEGER;
  355.   eos: BOOLEAN;
  356.   new: BT.DynString;
  357.  
  358. BEGIN
  359.   IF ~ file.read THEN file.status := onlywrite; RETURN FALSE END;
  360.   IF file.string=NIL THEN
  361.     NEW(file.string,100H);
  362.   END;
  363.   file.string[0] := 0X;
  364.   IF file.write & ~ file.lastRead THEN
  365.     IF ~ EmptyWriteBuf(file) THEN RETURN FALSE END;
  366.     file.bufpos := 0;
  367.     file.buflen := 0;
  368.     file.lastRead := TRUE;
  369.   END;
  370.   cnt := 0; bufpos := file.bufpos; eos := FALSE;
  371.   REPEAT
  372.     IF cnt>=LEN(file.string^) THEN
  373.       NEW(new,2*cnt);
  374.       COPY(file.string^,new^);
  375.       file.string := new;
  376.     END;
  377.     IF (bufpos=file.buflen) THEN
  378.       file.bufpos := 0; bufpos := 0;
  379.       file.buflen := d.Read(file.handle,file.buffer^,BufSize);
  380.       IF file.buflen=0 THEN file.status := eof;     file.string[cnt] := 0X; RETURN FALSE END;
  381.       IF file.buflen<0 THEN file.status := readerr; file.string[cnt] := 0X; RETURN FALSE END;
  382.     END;
  383.     file.string[cnt] := file.buffer[bufpos];
  384.     CASE file.string[cnt] OF
  385.     | 0X,0AX:
  386.         eos := TRUE;
  387.         file.string[cnt] := 0X
  388.     ELSE END;
  389.     INC(cnt);
  390.     INC(bufpos);
  391.   UNTIL eos;
  392.   file.bufpos := bufpos;
  393.   INC(file.pos,cnt);
  394.   file.status := ok;
  395.   RETURN TRUE;
  396. END ReadLongString;
  397.  
  398.  
  399. (*------  ReadBlock:  ------*)
  400.  
  401.  
  402. PROCEDURE ReadBlock*(VAR file: File; to: e.APTR; size: LONGINT): BOOLEAN;
  403.  
  404. (* liest size Bytes aus file nach to^. Ergebnis ist TRUE, wenn alles
  405.  * korrekt verlieft.
  406.  *)
  407.  
  408. TYPE
  409.   BytePtr = UNTRACED POINTER TO sys.BYTE;
  410.  
  411. VAR
  412.   cnt: LONGINT;
  413.   bufpos: INTEGER;
  414.   ptrtob: BytePtr;
  415.  
  416. BEGIN
  417.   IF ~ file.read THEN file.status := onlywrite; RETURN FALSE END;
  418.   IF file.write & ~ file.lastRead THEN
  419.     IF ~ EmptyWriteBuf(file) THEN RETURN FALSE END;
  420.     file.bufpos := 0;
  421.     file.buflen := 0;
  422.     file.lastRead := TRUE;
  423.   END;
  424.   ptrtob := to;
  425.   cnt := 0; bufpos := file.bufpos;
  426.   WHILE cnt<size DO
  427.     IF (bufpos=file.buflen) THEN
  428.       file.bufpos := 0; bufpos := 0;
  429.       file.buflen := d.Read(file.handle,file.buffer^,BufSize);
  430.       IF file.buflen=0 THEN file.status := eof;     RETURN FALSE END;
  431.       IF file.buflen<0 THEN file.status := readerr; RETURN FALSE END;
  432.     END;
  433.     ptrtob^ := file.buffer[bufpos];
  434.     INC(cnt); ptrtob := sys.VAL(BytePtr,sys.VAL(LONGINT,ptrtob)+1); INC(bufpos);
  435.   END;
  436.   file.bufpos := bufpos;
  437.   INC(file.pos,size);
  438.   file.status := ok;
  439.   RETURN TRUE;
  440. END ReadBlock;
  441.  
  442.  
  443. (*-------------------------------------------------------------------------*)
  444.  
  445.  
  446. (*------  Write:  ------*)
  447.  
  448.  
  449. PROCEDURE Write*(VAR file: File; from: ARRAY OF sys.BYTE): BOOLEAN;  (* $CopyArrays- *)
  450.  
  451. (* schreibt LEN(to) Bytes aus from in die Datei file. Ergebnis ist TRUE,
  452.  * wenn alles korrekt verlieft.
  453.  *)
  454.  
  455. VAR
  456.   cnt: LONGINT;
  457.   bufpos: INTEGER;
  458.  
  459. BEGIN
  460.   IF ~ file.write THEN file.status := onlyread; RETURN FALSE END;
  461.   IF file.read & file.lastRead THEN
  462.     IF d.Seek(file.handle,file.pos,d.beginning)=0 THEN END;
  463.     file.bufpos := 0;
  464.     file.buflen := 0;
  465.     file.lastRead := FALSE;
  466.   END;
  467.   cnt := 0; bufpos := file.bufpos;
  468.   WHILE cnt<LEN(from) DO
  469.     IF (bufpos=BufSize) THEN
  470.       file.bufpos := bufpos;
  471.       bufpos := 0;
  472.       IF ~ WriteBuf(file) THEN RETURN FALSE END;
  473.     END;
  474.     file.buffer[bufpos] := from[cnt];
  475.     INC(cnt); INC(bufpos);
  476.   END;
  477.   file.bufpos := bufpos;
  478.   INC(file.pos,cnt);
  479.   IF file.pos>file.size THEN file.size := file.pos END;
  480.   file.status := ok;
  481.   RETURN TRUE;
  482. END Write;
  483.  
  484.  
  485. (*------  WriteChar:  ------*)
  486.  
  487.  
  488. PROCEDURE WriteChar*(VAR file: File; ch: CHAR): BOOLEAN;
  489.  
  490. (* schreibt 1 Char in die Datei file. Ergebnis ist TRUE, wenn alles korrekt
  491. verlieft. *)
  492.  
  493. BEGIN
  494.   IF ~ file.write THEN file.status := onlyread; RETURN FALSE END;
  495.   IF file.read & file.lastRead THEN
  496.     IF d.Seek(file.handle,file.pos,d.beginning)=0 THEN END;
  497.     file.bufpos := 0;
  498.     file.buflen := 0;
  499.     file.lastRead := FALSE;
  500.   END;
  501.   IF file.bufpos=BufSize THEN
  502.     IF ~ WriteBuf(file) THEN RETURN FALSE END;
  503.   END;
  504.   file.buffer[file.bufpos] := ch;
  505.   INC(file.bufpos);
  506.   INC(file.pos);
  507.   IF file.pos>file.size THEN file.size := file.pos END;
  508.   file.status := ok;
  509.   RETURN TRUE;
  510. END WriteChar;
  511.  
  512.  
  513. (*------  WriteString:  ------*)
  514.  
  515.  
  516. PROCEDURE WriteString*(VAR file: File; from: ARRAY OF CHAR): BOOLEAN; (* $CopyArrays- *)
  517.  
  518. (* schreibt String in die Datei. Danach wird eine LF in die Datei
  519. geschrieben. Ergebnis ist TRUE, wenn alles korrekt verlieft. *)
  520.  
  521. VAR
  522.   cnt: LONGINT;
  523.   bufpos: INTEGER;
  524.   eos: BOOLEAN;
  525.  
  526. BEGIN
  527.   IF ~ file.write THEN file.status := onlyread; RETURN FALSE END;
  528.   IF file.read & file.lastRead THEN
  529.     IF d.Seek(file.handle,file.pos,d.beginning)=0 THEN END;
  530.     file.bufpos := 0;
  531.     file.buflen := 0;
  532.     file.lastRead := FALSE;
  533.   END;
  534.   cnt := 0; bufpos := file.bufpos; eos := FALSE;
  535.   WHILE (cnt<LEN(from)) & ~ eos DO
  536.     IF (bufpos=BufSize) THEN
  537.       file.bufpos := bufpos;
  538.       bufpos := 0;
  539.       IF ~ WriteBuf(file) THEN RETURN FALSE END;
  540.     END;
  541.     IF from[cnt] = 0X THEN
  542.       eos := TRUE;
  543.       file.buffer[bufpos] := 0AX;
  544.     ELSE
  545.       file.buffer[bufpos] := from[cnt];
  546.     END;
  547.     INC(cnt); INC(bufpos);
  548.   END;
  549.   file.bufpos := bufpos;
  550.   INC(file.pos,cnt);
  551.   IF file.pos>file.size THEN file.size := file.pos END;
  552.   file.status := ok;
  553.   RETURN TRUE;
  554. END WriteString;
  555.  
  556.  
  557. (*------  WriteBlock:  ------*)
  558.  
  559.  
  560. PROCEDURE WriteBlock*(VAR file: File; from: e.APTR; size: LONGINT): BOOLEAN;
  561.  
  562. (* schreibt size Bytes aus from^ in die Datei file. Ergebnis ist TRUE, wenn
  563. alles korrekt verlieft. *)
  564.  
  565. TYPE
  566.   BytePtr = UNTRACED POINTER TO sys.BYTE;
  567.  
  568. VAR
  569.   cnt: LONGINT;
  570.   bufpos: INTEGER;
  571.   ptrtob: BytePtr;
  572.  
  573. BEGIN
  574.   IF ~ file.write THEN file.status := onlyread; RETURN FALSE END;
  575.   IF file.read & file.lastRead THEN
  576.     IF d.Seek(file.handle,file.pos,d.beginning)=0 THEN END;
  577.     file.bufpos := 0;
  578.     file.buflen := 0;
  579.     file.lastRead := FALSE;
  580.   END;
  581.   cnt := 0; bufpos := file.bufpos; ptrtob := from;
  582.   WHILE cnt<size DO
  583.     IF (bufpos=BufSize) THEN
  584.       file.bufpos := bufpos;
  585.       bufpos := 0;
  586.       IF ~ WriteBuf(file) THEN RETURN FALSE END;
  587.     END;
  588.     file.buffer[bufpos] := ptrtob^;
  589.     INC(cnt); INC(bufpos); ptrtob := sys.VAL(BytePtr,sys.VAL(LONGINT,ptrtob)+1);
  590.   END;
  591.   file.bufpos := bufpos;
  592.   INC(file.pos,cnt);
  593.   IF file.pos>file.size THEN file.size := file.pos END;
  594.   file.status := ok;
  595.   RETURN TRUE;
  596. END WriteBlock;
  597.  
  598.  
  599. (*-------------------------------------------------------------------------*)
  600.  
  601.  
  602. (*------  Size:  ------*)
  603.  
  604.  
  605. PROCEDURE Size*(VAR file: File): LONGINT;
  606.  
  607. (* Ergibt die Größe der Datei *)
  608.  
  609. BEGIN
  610.   RETURN file.size;
  611. END Size;
  612.  
  613.  
  614. (*------  Position:  ------*)
  615.  
  616.  
  617. PROCEDURE Position* (VAR file: File): LONGINT;
  618.  
  619. (* Ergibt die aktuelle Position innerhalb der Datei *)
  620.  
  621. BEGIN
  622.   RETURN file.pos;
  623. END Position;
  624.  
  625.  
  626. (*-------------------------------------------------------------------------*)
  627.  
  628.  
  629. (*------  Move:  ------*)
  630.  
  631.  
  632. PROCEDURE Move*(VAR file: File; to: LONGINT): BOOLEAN;
  633.  
  634. (* spring an die Stelle to (vom Dateianfang ausgehend). Ergebnis ist TRUE,
  635. wenn alles korrekt verlieft. *)
  636.  
  637. VAR l: LONGINT;
  638.  
  639. BEGIN
  640.   IF file.write & ~ file.lastRead THEN
  641.     IF ~ EmptyWriteBuf(file)    THEN                        RETURN FALSE END;
  642.     file.bufpos := 0;
  643.     file.buflen := 0;
  644.     file.lastRead := TRUE;
  645.   END;
  646.   IF (to>file.size) OR (to<0) THEN file.status := toofar; RETURN FALSE END;
  647.   IF d.Seek(file.handle,to,d.beginning)=0 THEN END;
  648.   file.status := ok;
  649.   file.buflen := 0;
  650.   file.bufpos := 0;
  651.   file.pos := to;
  652.   RETURN TRUE;
  653. END Move;
  654.  
  655.  
  656. (*------  Forward:  ------*)
  657.  
  658.  
  659. PROCEDURE Forward*(VAR file: File; to: LONGINT): BOOLEAN;
  660.  
  661. (* überspringt to Bytes. Ergebnis ist TRUE, wenn alles korrekt verlieft. *)
  662.  
  663. BEGIN
  664.   RETURN Move(file,file.pos+to);
  665. END Forward;
  666.  
  667.  
  668. (*------  Backward:  ------*)
  669.  
  670.  
  671. PROCEDURE Backward*(VAR file: File; to: LONGINT): BOOLEAN;
  672.  
  673. (* springt to Bytes zurück . Ergebnis ist TRUE, wenn alles korrekt
  674. verlieft. *)
  675.  
  676. BEGIN
  677.   RETURN Move(file,file.pos-to);
  678. END Backward;
  679.  
  680.  
  681. (*-------------------------------------------------------------------------*)
  682.  
  683. PROCEDURE Delete*(VAR file: File): BOOLEAN;
  684.  
  685. (* schließt und löscht die Datei *)
  686.  
  687. BEGIN
  688.   IF file.handle#NIL THEN IF Close(file) THEN END END;
  689.   RETURN d.DeleteFile(file.name);
  690. END Delete;
  691.  
  692.  
  693. (*-------------------------------------------------------------------------*)
  694.  
  695.  
  696. PROCEDURE Exists*(name: ARRAY OF CHAR): BOOLEAN;
  697.  
  698. (* prüft, ob die Datei mit dem Namen 'name' existiert. *)
  699.  
  700. VAR lock: d.FileLockPtr;
  701.  
  702. BEGIN
  703.   lock := sd.Lock(name,d.sharedLock);
  704.   IF lock#NIL THEN
  705.     sd.UnLock(lock); RETURN TRUE
  706.   ELSE
  707.     RETURN FALSE;
  708.   END;
  709. END Exists;
  710.  
  711.  
  712. END FileSystem.
  713.  
  714.  
  715.  
  716.