User Device for ISO Std Channel I/O to Memory
By Tom Breeden (tmb@virginia.edu)
I wanted to try implementing a new "device" to be useable integrated into the ISO standard
channel I/O system. This enables output (and input) to your device to use the various
procedures in ISO standard modules like TextIO, WholeIO, IOResult, IOChan, etc.
Or, even more useful, to use higher level formatting and output routines of your own
that make use of the ISO standard IO modules.
Ideally, I would have been able to consult
The M2 ISO Standard I/O Architecture Manual,
but actually ended up consulting the sources for modules like SeqFile, as implemented
by R. Sutcliffe and G. Tischer, and modified by Stony Brook Software for their
Windows distribution.
Another problem was that I did not really have my own different device. However, I did have
a module for manipulating large amounts of text in memory, TextBlocks, and this could
serve as the source and target of the channel IO.
So, here it is, module TBChans, along with TextBlocks, and a simple demo program TBChansDemo.
I have used it on both Stony Brook Modula-2 and on a semi-ISO (unreleased)
M2 compiler for Amiga (M68040).
The files in the download TBChans.zip
include the complete sources of TBChans and TextBlocks, plus some dynamic string handling
and other modules they depend upon.
Your comments are appreciated.
(*#########################*)
DEFINITION MODULE TBChans; (* v0.1-031802 *)
(*#########################*)
(* by Thomas Breeden, tmb@virginia.edu *)
(*
"Device" for ISO Std Channel I/O to memory.
This is an initial try at implementing a new ISO channel to use with
TextIO, WholeIO, etc.
The implementation is layered on a module, TextBlocks, and the GetTB()
provides a hook to get the underlying text data.
*)
(*
Copyright (C) 1997-2003 Thomas Breeden.
Permission to use, copy, modify and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided that
the above copyright notice appear in all copies and that both the copyright
notice and this permission notice appear in supporting documentation.
Thomas Breeden makes no representations about the suitability of this software
for any purpose. It is provided "as is" without express or implied warranty.
*)
IMPORT IOChan, ChanConsts;
FROM TextBlocks IMPORT TextBlock;
TYPE ChanId = IOChan.ChanId;
OpenResults = ChanConsts.OpenResults;
PROCEDURE OpenTB(VAR cid:ChanId; VAR res:OpenResults);
PROCEDURE Reread(cid:ChanId);
PROCEDURE Rewrite(cid:ChanId);
PROCEDURE Close(VAR cid:ChanId);
PROCEDURE IsTBFile(cid:ChanId):BOOLEAN;
PROCEDURE GetTB(cid:ChanId):TextBlock;
(* NOTE 1. Writes always go at the end, unless Rewrite() was just called.
2. Currently, only text r/w, no rawIO.
3. OpenTB() always creates an empty TextBlock. It is ok to get that
with GetTB() and fill it up externally before doing any reads with
channel IO procs.
4. CloseTB() deallocates the TextBlock.
VERSION HISTORY
vx.x-090397
v0.1-031802 -Changed OpenTBWrite() to just OpenTB(). For now, all TBChans
are Read/Write. Rewrite clears it.
*)
END TBChans.
|
TBChansDemo Modules and Files
Dec-20-2003
Thomas Breeden, tmb@virginia.edu
TBChansDemo - Program: simple demo of TBChans and TextBlocks modules.
- uses TBChans and TextIO procs to fill up the TextBlock
from standard input, and "native" TextBlock procs to send the
input lines to standard output in the reverse order.
TBChans - ISO Std Channel I/O to memory.
TextBlocks - in-memory, line-oriented, dynamically-extending blocks of text.
Dynamically allocated string processing
DynStr0 - Basic procedures, size fixed at create time.
DynStr1 - Common procedures
DynStr1C - Common procedures, one character parameter
DynStr3 - As above, but size will be reallocated on assignment.
Null delimited static string processing
Str0 - Basic procedures.
Debugging0 - Assert and Debug procs.
TBChansDemo Program
TBChansDemo is a very simple demo program of a user-written "device" with the
ISO Standard channel IO procedures.
The underlying "device" is embodied in the modules TextBlocks and DynStr0
supporting in-memory text storage, and the ISO IOLink'd interface module TBChans.
The demo simply uses TBChans and TextIO procs to fill up the TextBlock
from standard input, and "native" TextBlock procs to send the input lines
to standard output in the reverse order.
eg, If the file Numbers.txt contains 1 through 5, one number on each line,
the command
TBChansDemo <Numbers.txt
produces the output
5
4
3
2
1
NOTE:
- It was written in the Stony Brook M2 v4 system. If you run it without
redirecting standard input, type in a ^Z to force an endOfInput.
- Module Debugging0's implementation is Windows specific.
(*###########################*)
DEFINITION MODULE TextBlocks; (* $VER: TextBlocks.def 0.0 (11.10.03) *)
(*###########################*)
(* by Thomas Breeden, tmb@virginia.edu *)
(*
TextBlocks are in-memory, line-oriented, dynamically-extending blocks
of text. They can be written, read, and to some extent edited with this
module.
TextBlocks are layered on top of dynamic strings implemented by the
DynStrX modules.
*)
(*
Copyright (C) 1997-2003 Thomas Breeden.
Permission to use, copy, modify and distribute this software and its
documentation for any purpose and without fee is hereby granted, provided that
the above copyright notice appear in all copies and that both the copyright
notice and this permission notice appear in supporting documentation.
Thomas Breeden makes no representations about the suitability of this software
for any purpose. It is provided "as is" without express or implied warranty.
*)
(* GoToMark should return BOOLEAN? *)
FROM DynStr0 IMPORT DynStr, DynStrPtr;
TYPE TextBlock;
TYPE MarkType = [0..4];
PROCEDURE AllocBlock():TextBlock;
PROCEDURE EmptyBlock(blk:TextBlock);
PROCEDURE DeallocBlock(VAR blk:TextBlock);
(* also does EmptyBlock *)
PROCEDURE InvalidBlock():TextBlock;
(*------------------------------------*)
(* Writing Procedures *)
PROCEDURE AppendBlockStr0(blk:TextBlock; VAR str:ARRAY OF CHAR);
PROCEDURE AppendBlockdStr(blk:TextBlock; txt:DynStr);
PROCEDURE AppendBlockChar(blk:TextBlock; ch:CHAR);
(* The 3 procs above add text to the last line in the TextBlock, but dont
create a new line (unless CF or LF or CRLF is embedded *)
PROCEDURE NewBlockLine(blk:TextBlock);
PROCEDURE AddBlockLine(blk:TextBlock; line:DynStr);
(* The 2 procs above first add a new line to the end
of the TextBlock *)
PROCEDURE AppendBlockLine(blk:TextBlock; appText:DynStr):BOOLEAN;
(* append text to just read line *)
PROCEDURE DeleteBlockLine(blk:TextBlock);
(* delete the line just read *)
PROCEDURE BeforeInsertBlockLine(blk:TextBlock; line:DynStr);
(* sets "justread" to the inserted, and the reader to line after the inserted line *)
PROCEDURE AfterInsertBlockLine(blk:TextBlock; line:DynStr);
(* sets "justread" to the inserted, and the reader to line after the inserted line *)
PROCEDURE ReplaceBlockLine(blk:TextBlock; line:DynStr);
(* The 5 procs above can act on text in the middle of the TextBlock. They act
on the line "just read" *)
(*------------------------------------*)
(* Reading Procedures *)
PROCEDURE ResetBlockRead(blk:TextBlock);
(* sets the reader to before beginning, and "justread" to NIL *)
PROCEDURE SetEndBlockRead(blk:TextBlock);
(* sets the reader to beyond end, and the "justread" to end line *)
PROCEDURE GetBlockTxt(blk:TextBlock; VAR dtxt:DynStr);
(* This returns the entire TextBlock as one dynamic string line, with
line separator replaced by space *)
PROCEDURE NextBlockLine(blk:TextBlock; VAR line:DynStr):BOOLEAN;
PROCEDURE PrevBlockLine(blk:TextBlock; VAR line:DynStr):BOOLEAN;
PROCEDURE ReadBlockLine(blk:TextBlock; VAR line:DynStr):BOOLEAN;
PROCEDURE GoToLine(blk:TextBlock; LineNum:CARDINAL; VAR line:DynStr):BOOLEAN;
(* sequentially, from 0 *)
PROCEDURE GotoMark(blk:TextBlock; WhichMark:MarkType; VAR line:DynStr);
(* The previous 6 procs copy text from the TextBlock to your dynamic string
parameter. You must have called a dStrCreate() to initialize it. The memory
it's .str pointer references may have be re-allocated on return *)
PROCEDURE Mark(blk:TextBlock; WhichMark:MarkType);
(* line just read is marked *)
PROCEDURE NextBlockLineRef(blk:TextBlock; VAR line:DynStrPtr):BOOLEAN;
PROCEDURE PrevBlockLineRef(blk:TextBlock; VAR line:DynStrPtr):BOOLEAN;
PROCEDURE RefBlockLine(blk:TextBlock; VAR line:DynStrPtr):BOOLEAN;
PROCEDURE GoToLineRef(blk:TextBlock; LineNum:CARDINAL; VAR line:DynStrPtr):BOOLEAN;
PROCEDURE GotoMarkRef(blk:TextBlock; WhichMark:MarkType; VAR line:DynStrPtr);
(* The previous 5 procs do not copy text, but return a pointer into the TextBlock
itself, which stores lines a dynamic strings. *)
(* NOTE:
1. The Append... funcs will create a new block line on
receiving a LF, CR, or CRLF.
2. Adding a line with NewBlockLine(), AddBlockLine(), InsertAfterBlkLine(),
or InsertBeforeBlkLine, always changes the reading state as if a
NextBlockLine() had been done into the new line, no matter where the
rdr was before.
3. The ...Ref() procs can be much faster for getting at the text, but remember
that the DynStr line belongs to the TextBlock, not you.
4. GoToLine/Ref() is likely to be much slower than GotoMark/Ref().
VERSION HISTORY
v0.0-052397 -first
-052598 -Added GoToLine(), GoToLineRef(),Next/PrevBlockLineRef()
0.0 (10.6.03) - unified StonyBrook and Benchmark versions. Added InvalidBlock() to
Benchmark version and changed LONGCARD to CARDINAL;
added NextBlockLineRef(), PrevBlockLineRef(),
GoToLine(), and GoToLineRef() to Stony Brook Version.
(16.6.03) - Added GoToMarkRef()
(4.7.03) - Added RefBlockLine() and ReadBlockLine()
- "Fixed" all the Ref...() procs to return a DynStrPtr, so that
the caller can actually fiddle with the length of the dynstr in
the TextBlock, not just read it.
(11.10.3) - Added AppendBlockLine()
*)
END TextBlocks.
|
The M2 ISO Standard I/O Architecture Manual
<Not yet written?>
<In the ISO Standard Document?>
|