Copyright (C) 1992, Digital Equipment Corporation                         
 All rights reserved.                                                      
 See the file COPYRIGHT for a full description.                            
 Last modified on Fri Nov 20 20:59:20 PST 1992 by meehan     
      modified on Tue Jun 16 13:16:23 PDT 1992 by muller     
      modified on Wed May  3 11:10:09 PDT 1989 by mbrown     
      modified on Tue Oct 11 19:06:48 1988 by chan           


IMPORT Rd, MText, Thread;

  T <: Public;
  Public = Rd.T OBJECT
             init (m         : MText.T  := NIL;
                   start     : CARDINAL := 0;
                   rangeStart: CARDINAL := 0;
                   rangeEnd  : CARDINAL := LAST (CARDINAL);
                   reverse   : BOOLEAN  := FALSE            ): T
                   RAISES {Rd.Failure, Thread.Alerted}
rd.init(m, ...) initializes a seekable, non-intermittent reader for the MText m.

It is intended that this method be called more than once, to re-initialize a reader (and avoid re-allocating storage for rd.buff); in this case, it is permitted for m to be NIL, and the default value is the MText that was previously used by the reader.

The reader's source may be a proper subsequence of the underlying MText, and the reader can be initialized to read in reverse order.

src(rd) comprises the characters of m that are contained in the interval

       [first(rd) .. last(rd)]
       first(rd)) = rangeStart
       last(rd) = MIN (rangeEnd, MText.Length(m)) - 1]
       len(rd) = MAX (last(rd) - first(rd) + 1, 0)
In a forward reader (reverse = FALSE), Rd.GetChar delivers characters from start to last(rd). Rd.Index returns the index relative to first(rd). Hence just after a forward reader rd is initialized,
       cur(rd) = start - first(rd)
In a reverse reader, Rd.GetChar delivers characters from start-1 (not start) to first(rd). Rd.Index returns the index relative to last(rd)+1. Hence just after a reverse reader rd is initialized,
       cur(rd) = last(rd) + 1 - start
Thus the value returned by Rd.Index increases by 1 with each call to Rd.GetChar, regardless of the reader's direction.

The coordinate system used by Rd.Seek is consistent with Rd.Index.

If the underlying MText is modified, the reader is invalid and should be re-initialized.

rd.init calls Rd.Seek(rd, rd.cur), which can raise Rd.Failure or Thread.Alerted.

Synchronization: it is not possible to have several readers reading the mtext concurrently. The reason is that a read to a file node causes the mtext data structure to change. If you don't use file nodes, then it's safe. (JRM doesn't believe this.)

PROCEDURE New (m         : MText.T;
               start     : CARDINAL  := 0;
               rangeStart: CARDINAL  := 0;
               rangeEnd  : CARDINAL  := LAST (CARDINAL);
               reverse   : BOOLEAN   := FALSE            ): T
  RAISES {Rd.Failure, Thread.Alerted};
This is equivalent to
      NEW (T).init (m, start, rangeStart, rangeEnd, reverse, alertable)

END MTextRd.