home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!mcsun!Germany.EU.net!unidui!flyer!easix!tron.gun.de!g_dotzel
- From: g_dotzel@tron.gun.de (Guenter Dotzel)
- Newsgroups: comp.lang.modula2
- Subject: Re: Of Mice & Modula-2/Random Files
- Message-ID: <28V60357CV@tron.gun.de>
- Organization: TRON Public Mailbox, Neurath, Germany
- Date: Mon, 31 Aug 92 09:37:00 +0200
- Lines: 257
-
- MWALLS%NMSU.EDU@USENET.ZER wrote on Sat, 08-29-1992 at 21:01 h
- under the subject 'Of Mice & Modula-2':
-
- > In BASIC you can open a Random (or Indexed) file by using the
- > following: ...
- > where record size is the number of bytes set aside per record.
- >
- > Then, at any time while it is open, one can get or put information
- > into a specific point in the file by using: ...
- > (where rec is the record to be accessed)
- >
- > Is there a way to do this in Modula-2. This is probably a stupid
- > question, but I really don't know.
- >
-
- Yes, you *can* do that quite easily and portable in Modula-2 (see example
- below), provided you have the ISO M2 Std Lib available.
-
- ***** Note,
- ***** We port this library to any popular platform on request, so
- ***** if anybody needs this library for his/her favorite compiler/platform,
- ***** please send email
-
- ----cut here------>
- To Guenter Dotzel, email/internet: g_dotzel@ame.nbg.sub.org
-
- We are using the _______ V___ Modula-2 compiler under ______ V____
- We are using the _______ V___ Oberon-2 compiler under ______ V____
- and would be happy to see an implementation of the ISO M2 Std Lib
- for that compiler/system.
- Best wishes, ....
- <----cut here------
-
- I'll post a summary/statistic for the requests received in Oct-92.
- Also I'll provide a portation schedule for the top-most popular platforms.
-
- Random File Access:
- I've already posted the following random file access example and test programs
- some months ago, but maybe its worth to post 200 lines of code again:
-
- MODULE TestPos;
- (* ISO Modula-2 I/O-Library test program for random file access.
- This program runs under VAX/VMS using ModulaWare's compiler kit MVR V3.20.
- This program also runs on the Mac with using p1 compiler/ISO M2 Std Lib.
- An Oberon-2 version of this program is contained in a follow up message.
-
- (c) 1992 by ModulaWare GmbH, written by Elmar Baumgart 10-Mar-1992,
- 27-Mar-1992 (skip multiple blank lines)
-
- - If at the start of the program the hash table file DATA does not
- exist, a new file is created and initialized.
- Otherwise, the existing file called DATA is used.
- - The program reads two files called INSERT and SEARCH. Both files
- may have any text file format.
- - inserts token strings from file INSERT into a hash-table file DATA
- - searches token strings from file SEARCH in file DATA
- *)
- FROM ProgramArgs IMPORT IsArgPresent, ArgChan;
- IMPORT STextIO, SWholeIO;
- FROM IOResult IMPORT ReadResult, ReadResults;
- FROM TextIO IMPORT WriteString, ReadToken, SkipLine, ReadString;
- IMPORT SeqFile;
- FROM RndFile IMPORT OpenClean, OpenOld, read, write, text, binary,
- ChanId, OpenResults, Close, FilePos, SetPos, NewPos, StartPos;
- FROM RawIO IMPORT Write, Read;
-
- CONST
- ITEMLENGTH = 40;
- ITEMS = 3877; (*prime*) (*creates ITEMS * ITEMLENGTH hash-table on disk*)
- DATA = 0; INSERT = 1; SEARCH = 2;
-
- TYPE
- WCproc = PROCEDURE(CARDINAL, CARDINAL);
- WSproc = PROCEDURE(ARRAY OF CHAR);
- ItemType = ARRAY[0..ITEMLENGTH-1] OF CHAR;
- fnam = ARRAY[0..255] OF CHAR;
- Args = ARRAY[DATA..SEARCH] OF fnam;
-
- VAR
- WC: WCproc; WS: WSproc; NL: PROC;
- data, ins, sea: ChanId;
- free: INTEGER;
- file: Args;
- startPos: FilePos;
-
- PROCEDURE CalcPos(Key: CARDINAL): FilePos;
- BEGIN
- RETURN NewPos(data, Key, ITEMLENGTH, startPos);
- END CalcPos;
-
- PROCEDURE CalcKey(item: ARRAY OF CHAR): CARDINAL;
- VAR len, i, key: CARDINAL;
- BEGIN
- len:= LENGTH(item);
- key:= 1;
- IF len > 0 THEN
- FOR i:= 0 TO len-1 DO
- key:= (key * (ORD(item[i]) MOD 26 + 1)) MOD ITEMS;
- END;
- END;
- RETURN key;
- END CalcKey;
-
- PROCEDURE EQUAL(old, new: ARRAY OF CHAR): BOOLEAN;
- VAR i: INTEGER; eq: BOOLEAN; len: INTEGER;
- BEGIN
- i:= 0; eq:= TRUE; len:= LENGTH(new);
- WHILE (i < len) AND eq DO
- eq:= old[i] = new[i]; INC(i);
- END;
- RETURN eq;
- END EQUAL;
-
- PROCEDURE Insert(item: ARRAY OF CHAR);
- VAR Key, offset: CARDINAL; atPos: ItemType; eq: BOOLEAN;
- BEGIN
- IF free > 0 THEN
- Key:= CalcKey(item);
- SetPos(data, CalcPos(Key));
- Read(data, atPos); offset:= 0;
- eq:= EQUAL(atPos, item);
- WHILE NOT eq AND (atPos[0] <> 0C) AND (offset < ITEMS) DO
- IF ReadResult(data) = endOfInput THEN SetPos(data, startPos);
- END;
- Read(data, atPos);
- eq:= EQUAL(atPos, item); INC(offset);
- END;
- IF eq THEN WS('already inserted');
- ELSE
- SetPos(data, CalcPos((Key + offset) MOD ITEMS));
- Write(data, item);
- WS(' inserted');
- DEC(free);
- END;
- WC(offset, 4); WS(' "'); WS(item); WS('"'); NL;
- ELSE WS('-table full-'); NL;
- END;
- END Insert;
-
- PROCEDURE Search(item: ARRAY OF CHAR);
- VAR Key, offset: CARDINAL; atPos: ItemType; eq: BOOLEAN;
- BEGIN
- Key:= CalcKey(item);
- SetPos(data, CalcPos(Key));
- Read(data, atPos); offset:= 0;
- eq:= EQUAL(atPos, item);
- WHILE NOT eq AND (atPos[0] <> 0C) AND (offset < ITEMS) DO
- IF ReadResult(data) = endOfInput THEN SetPos(data, startPos);
- END;
- Read(data, atPos);
- eq:= EQUAL(atPos, item); INC(offset);
- END;
- IF offset >= ITEMS THEN eq:= FALSE;
- END;
- IF eq THEN WS(' found');
- ELSE WS('not found');
- END;
- WC(offset, 4); WS(' "'); WS(item); WS('"'); NL;
- END Search;
-
- PROCEDURE InsertIt;
- VAR item: ItemType;
- BEGIN
- SeqFile.OpenRead(ins, file[INSERT], text, ores);
- IF ores <> opened THEN WS('failed to open '); WS(file[INSERT]); NL;
- ELSE
- WS('Inserting token strings from file '); WS(file[INSERT]); NL;
- ReadToken(ins, item);
- WHILE ReadResult(ins) <> endOfInput DO
- Insert(item);
- ReadToken(ins, item);
- WHILE ReadResult(ins) = endOfLine DO
- SkipLine(ins);
- ReadToken(ins, item);
- END;
- END;
- SeqFile.Close(ins);
- END;
- END InsertIt;
-
- PROCEDURE SearchIt;
- VAR item: ItemType;
- BEGIN
- SeqFile.OpenRead(sea, file[SEARCH], text, ores);
- IF ores <> opened THEN WS('failed to open '); WS(file[SEARCH]); NL;
- ELSE
- WS('Searching token strings from file '); WS(file[SEARCH]); NL;
- ReadToken(sea, item);
- WHILE ReadResult(sea) <> endOfInput DO
- Search(item);
- ReadToken(sea, item);
- WHILE ReadResult(sea) = endOfLine DO
- SkipLine(sea);
- ReadToken(sea, item);
- END;
- END;
- SeqFile.Close(sea);
- END;
- END SearchIt;
-
- PROCEDURE TestIt;
- BEGIN
- InsertIt; NL;
- SearchIt;
- END TestIt;
-
- VAR
- ores: OpenResults;
- empty: ItemType;
- i: INTEGER; wrongArgs: BOOLEAN;
-
- BEGIN
- free:= ITEMS;
- FOR i:= 0 TO ITEMLENGTH-1 DO empty[i]:= 0C;
- END;
- WC:= SWholeIO.WriteCard; WS:= STextIO.WriteString; NL:= STextIO.WriteLn;
- i:= 0;
- WHILE (ReadResult(ArgChan()) <> endOfInput) AND (i <= SEARCH) DO
- ReadToken(ArgChan(), file[i]); INC(i);
- END;
-
- IF (ReadResult(ArgChan()) <> endOfInput) AND (i > SEARCH) THEN
- OpenOld(data, file[DATA], read + write + binary, ores);
- IF ores = noSuchFile THEN
- OpenClean(data, file[DATA], read + write + binary, ores);
- IF ores = opened THEN
- FOR i:= 1 TO ITEMS DO Write(data, empty);
- END;
- startPos:= StartPos(data);
- TestIt;
- Close(data);
- ELSE WS('data file not present, create failed'); NL;
- END;
- ELSIF ores = opened THEN
- startPos:= StartPos(data);
- i:= 0; Read(data, empty);
- WHILE ReadResult(data) <> endOfInput DO INC(i); Read(data, empty);
- IF empty[0] <> 0C THEN DEC(free);
- END;
- END;
- IF i <> ITEMS THEN WS(file[DATA]); WS(' is of illegal size'); NL;
- ELSE TestIt;
- END;
- Close(data);
- ELSE WS('data file present, access failed'); NL;
- END;
- WC(free, 1); WS(' entries free in '); WS(file[DATA]); NL;
- ELSE WS(' TESTPOS hash-file insert-file search-file '); NL;
- END;
- END TestPos.
-
- Guenter Dotzel, ModulaWare GmbH, Wilhelmstr. 17A, D-W 8520 Erlangen/F.R.Germany
- Modula-2 & Oberon-2 Compiler Manufactur (VAX/VMS, OS/2 and Unix-Platforms)
- Tel. +49 (9131) 208395, Fax +49 (9131) 28205.
- E-mail/Internet: 100023.2527@compuserve.com
- g_dotzel@ame.nbg.sub.org
-
-