home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #19 / NN_1992_19.iso / spool / comp / lang / modula2 / 1106 < prev    next >
Encoding:
Internet Message Format  |  1992-09-04  |  8.1 KB

  1. Path: sparky!uunet!mcsun!Germany.EU.net!unidui!flyer!easix!tron.gun.de!g_dotzel
  2. From: g_dotzel@tron.gun.de (Guenter Dotzel)
  3. Newsgroups: comp.lang.modula2
  4. Subject: Re: Of Mice & Modula-2/Random Files
  5. Message-ID: <28V60357CV@tron.gun.de>
  6. Organization: TRON Public Mailbox, Neurath, Germany
  7. Date: Mon, 31 Aug 92 09:37:00 +0200
  8. Lines: 257
  9.  
  10. MWALLS%NMSU.EDU@USENET.ZER wrote on Sat, 08-29-1992 at 21:01 h
  11. under the subject 'Of Mice & Modula-2':
  12.  
  13. >       In BASIC you can open a Random (or Indexed) file by using the
  14. > following: ...
  15. >       where record size is the number of bytes set aside per record.
  16. >       Then, at any time while it is open, one can get or put information
  17. > into a specific point in the file by using: ...
  18. >       (where rec is the record to be accessed)
  19. > Is there a way to do this in Modula-2.  This is probably a stupid
  20. > question, but I really don't know.
  21.  
  22. Yes, you *can* do that quite easily and portable in Modula-2 (see example
  23. below), provided you have the ISO M2 Std Lib available.
  24.  
  25. ***** Note,
  26. ***** We port this library to any popular platform on request, so
  27. ***** if anybody needs this library for his/her favorite compiler/platform,
  28. ***** please send email
  29.  
  30. ----cut here------>
  31.   To Guenter Dotzel, email/internet: g_dotzel@ame.nbg.sub.org
  32.   
  33.   We are using the _______ V___ Modula-2 compiler under ______ V____
  34.   We are using the _______ V___ Oberon-2 compiler under ______ V____
  35.   and would be happy to see an implementation of the ISO M2 Std Lib
  36.   for that compiler/system.
  37.   Best wishes, ....
  38. <----cut here------
  39.  
  40. I'll post a summary/statistic for the requests received in Oct-92.
  41. Also I'll provide a portation schedule for the top-most popular platforms.
  42.  
  43. Random File Access:
  44. I've already posted the following random file access example and test programs
  45. some months ago, but maybe its worth to post 200 lines of code again:
  46.  
  47. MODULE TestPos;
  48. (* ISO Modula-2 I/O-Library test program for random file access.
  49.    This program runs under VAX/VMS using ModulaWare's compiler kit MVR V3.20.
  50.    This program also runs on the Mac with using p1 compiler/ISO M2 Std Lib.
  51.    An Oberon-2 version of this program is contained in a follow up message.
  52.    
  53.    (c) 1992 by ModulaWare GmbH, written by Elmar Baumgart 10-Mar-1992,
  54.      27-Mar-1992 (skip multiple blank lines)
  55.  
  56.   - If at the start of the program the hash table file DATA does not
  57.     exist, a new file is created and initialized.
  58.     Otherwise, the existing file called DATA is used.
  59.   - The program reads two files called INSERT and SEARCH. Both files
  60.     may have any text file format.
  61.   - inserts token strings from file INSERT into a hash-table file DATA
  62.   - searches token strings from file SEARCH in file DATA
  63. *)
  64. FROM ProgramArgs IMPORT IsArgPresent, ArgChan;
  65. IMPORT STextIO, SWholeIO;
  66. FROM IOResult IMPORT ReadResult, ReadResults;
  67. FROM TextIO IMPORT WriteString, ReadToken, SkipLine, ReadString;
  68. IMPORT SeqFile;
  69. FROM RndFile IMPORT OpenClean, OpenOld, read, write, text, binary, 
  70.   ChanId, OpenResults, Close, FilePos, SetPos, NewPos, StartPos;
  71. FROM RawIO IMPORT Write, Read;
  72.  
  73. CONST
  74.   ITEMLENGTH = 40;
  75.   ITEMS = 3877;  (*prime*)   (*creates ITEMS * ITEMLENGTH hash-table on disk*)
  76.   DATA = 0; INSERT = 1; SEARCH = 2;
  77.  
  78. TYPE
  79.   WCproc = PROCEDURE(CARDINAL, CARDINAL);
  80.   WSproc = PROCEDURE(ARRAY OF CHAR);
  81.   ItemType = ARRAY[0..ITEMLENGTH-1] OF CHAR;
  82.   fnam = ARRAY[0..255] OF CHAR;
  83.   Args = ARRAY[DATA..SEARCH] OF fnam;
  84.  
  85. VAR
  86.   WC: WCproc; WS: WSproc; NL: PROC;
  87.   data, ins, sea: ChanId;
  88.   free: INTEGER;
  89.   file: Args;
  90.   startPos: FilePos;
  91.  
  92. PROCEDURE CalcPos(Key: CARDINAL): FilePos;
  93. BEGIN
  94.   RETURN NewPos(data, Key, ITEMLENGTH, startPos);
  95. END CalcPos;
  96.  
  97. PROCEDURE CalcKey(item: ARRAY OF CHAR): CARDINAL;
  98. VAR len, i, key: CARDINAL;
  99. BEGIN
  100.   len:= LENGTH(item);
  101.   key:= 1;
  102.   IF len > 0 THEN
  103.     FOR i:= 0 TO len-1 DO
  104.       key:= (key * (ORD(item[i]) MOD 26 + 1)) MOD ITEMS;
  105.     END;
  106.   END;
  107.   RETURN key;
  108. END CalcKey;
  109.  
  110. PROCEDURE EQUAL(old, new: ARRAY OF CHAR): BOOLEAN;
  111. VAR i: INTEGER; eq: BOOLEAN; len: INTEGER;
  112. BEGIN
  113.   i:= 0; eq:= TRUE; len:= LENGTH(new);
  114.   WHILE (i < len) AND eq DO
  115.     eq:= old[i] = new[i]; INC(i);
  116.   END;
  117.   RETURN eq;
  118. END EQUAL;
  119.  
  120. PROCEDURE Insert(item: ARRAY OF CHAR);
  121. VAR Key, offset: CARDINAL; atPos: ItemType; eq: BOOLEAN;
  122. BEGIN
  123.   IF free > 0 THEN
  124.     Key:= CalcKey(item);
  125.     SetPos(data, CalcPos(Key));
  126.     Read(data, atPos); offset:= 0; 
  127.     eq:= EQUAL(atPos, item);
  128.     WHILE NOT eq AND (atPos[0] <> 0C) AND (offset < ITEMS) DO
  129.       IF ReadResult(data) = endOfInput THEN SetPos(data, startPos);
  130.       END;
  131.       Read(data, atPos);
  132.       eq:= EQUAL(atPos, item); INC(offset);
  133.     END;
  134.     IF eq THEN WS('already inserted');
  135.     ELSE
  136.       SetPos(data, CalcPos((Key + offset) MOD ITEMS));
  137.       Write(data, item);
  138.       WS('        inserted');
  139.       DEC(free);
  140.     END;
  141.     WC(offset, 4); WS(' "'); WS(item); WS('"'); NL;
  142.   ELSE WS('-table full-'); NL;
  143.   END;
  144. END Insert;
  145.  
  146. PROCEDURE Search(item: ARRAY OF CHAR);
  147. VAR Key, offset: CARDINAL; atPos: ItemType; eq: BOOLEAN;
  148. BEGIN
  149.   Key:= CalcKey(item);
  150.   SetPos(data, CalcPos(Key));
  151.   Read(data, atPos); offset:= 0; 
  152.   eq:= EQUAL(atPos, item);
  153.   WHILE NOT eq AND (atPos[0] <> 0C) AND (offset < ITEMS) DO 
  154.     IF ReadResult(data) = endOfInput THEN SetPos(data, startPos);
  155.     END;
  156.     Read(data, atPos);
  157.     eq:= EQUAL(atPos, item); INC(offset);
  158.   END;
  159.   IF offset >= ITEMS THEN eq:= FALSE;
  160.   END;
  161.   IF eq THEN WS('    found');
  162.   ELSE WS('not found');
  163.   END;
  164.   WC(offset, 4); WS(' "'); WS(item); WS('"'); NL;
  165. END Search;
  166.  
  167. PROCEDURE InsertIt;
  168. VAR item: ItemType;
  169. BEGIN
  170.   SeqFile.OpenRead(ins, file[INSERT], text, ores);
  171.   IF ores <> opened THEN WS('failed to open '); WS(file[INSERT]); NL;
  172.   ELSE
  173.     WS('Inserting token strings from file '); WS(file[INSERT]); NL;
  174.     ReadToken(ins, item);
  175.     WHILE ReadResult(ins) <> endOfInput DO
  176.       Insert(item);
  177.       ReadToken(ins, item);
  178.       WHILE ReadResult(ins) = endOfLine DO 
  179.         SkipLine(ins);
  180.         ReadToken(ins, item);
  181.       END;
  182.     END;
  183.     SeqFile.Close(ins);
  184.   END;
  185. END InsertIt;
  186.  
  187. PROCEDURE SearchIt;
  188. VAR item: ItemType;
  189. BEGIN
  190.   SeqFile.OpenRead(sea, file[SEARCH], text, ores);
  191.   IF ores <> opened THEN WS('failed to open '); WS(file[SEARCH]); NL;
  192.   ELSE
  193.     WS('Searching token strings from file '); WS(file[SEARCH]); NL;
  194.     ReadToken(sea, item);
  195.     WHILE ReadResult(sea) <> endOfInput DO
  196.       Search(item);
  197.       ReadToken(sea, item);
  198.       WHILE ReadResult(sea) = endOfLine DO 
  199.         SkipLine(sea);
  200.         ReadToken(sea, item);
  201.       END;
  202.     END;
  203.     SeqFile.Close(sea);
  204.   END;
  205. END SearchIt;
  206.  
  207. PROCEDURE TestIt;
  208. BEGIN
  209.   InsertIt; NL;
  210.   SearchIt;
  211. END TestIt;
  212.  
  213. VAR 
  214.   ores: OpenResults;
  215.   empty: ItemType;
  216.   i: INTEGER; wrongArgs: BOOLEAN;
  217.  
  218. BEGIN
  219.   free:= ITEMS;
  220.   FOR i:= 0 TO ITEMLENGTH-1 DO empty[i]:= 0C;
  221.   END;
  222.   WC:= SWholeIO.WriteCard; WS:= STextIO.WriteString; NL:= STextIO.WriteLn;
  223.   i:= 0;
  224.   WHILE (ReadResult(ArgChan()) <> endOfInput) AND (i <= SEARCH) DO
  225.     ReadToken(ArgChan(), file[i]); INC(i);
  226.   END;
  227.  
  228.   IF (ReadResult(ArgChan()) <> endOfInput) AND (i > SEARCH) THEN
  229.     OpenOld(data, file[DATA], read + write + binary, ores);
  230.     IF ores = noSuchFile THEN
  231.       OpenClean(data, file[DATA], read + write + binary, ores); 
  232.       IF ores = opened THEN
  233.         FOR i:= 1 TO ITEMS DO Write(data, empty);
  234.         END;
  235.         startPos:= StartPos(data);
  236.         TestIt;
  237.         Close(data);
  238.       ELSE WS('data file not present, create failed'); NL;
  239.       END;
  240.     ELSIF ores = opened THEN
  241.       startPos:= StartPos(data);
  242.       i:= 0; Read(data, empty);
  243.       WHILE ReadResult(data) <> endOfInput DO INC(i); Read(data, empty);
  244.         IF empty[0] <> 0C THEN DEC(free);
  245.         END;
  246.       END;
  247.       IF i <> ITEMS THEN WS(file[DATA]); WS(' is of illegal size'); NL;
  248.       ELSE TestIt; 
  249.       END;
  250.       Close(data);
  251.     ELSE WS('data file present, access failed'); NL;
  252.     END;
  253.     WC(free, 1); WS(' entries free in '); WS(file[DATA]); NL;
  254.   ELSE WS('  TESTPOS hash-file insert-file search-file '); NL;
  255.   END;
  256. END TestPos.
  257.  
  258. Guenter Dotzel, ModulaWare GmbH, Wilhelmstr. 17A, D-W 8520 Erlangen/F.R.Germany
  259. Modula-2 & Oberon-2 Compiler Manufactur (VAX/VMS, OS/2 and Unix-Platforms)
  260. Tel. +49 (9131) 208395, Fax +49 (9131) 28205.
  261. E-mail/Internet: 100023.2527@compuserve.com
  262.                  g_dotzel@ame.nbg.sub.org
  263.  
  264.