[operations] [attributes] [fields] [template] [definition]
[implementation] [documentation]
To use the search tool you need to use a browser which supports JAVA (c)

[next] [prev] [superclass] [next peer] [prev peer] [subclass] [index] [hierarchy]

MacServer

inherits from Object

Object <- MacServer



Operations

Get list of all operations

NewStreamNear


Attributes

Get list of all attributes

Class MacServer defines no new attributes.


Fields

No fields are defined by MacServer or any of its superclasses.


Instance template

instance MacServer tag;
end instance;

Class definition

/* A Writer is a character output stream.  The basic operation
   on a writer is "PutChar", which extends a writer's character
   sequence by one character. Some writers (called ``seekable
   writers'') also allow overwriting in the middle of the
   sequence.  For example, writers to random access files are
   seekable, but writers to terminals and sequential files are not.

   Writers can be (and usually are) buffered. This means that
   operations on the writer don't immediately affect the underlying
   target of the writer, but are saved up and performed later.  For
   example, a writer to a disk file is not likely to update the disk
   after each character.

   Abstractly, a writer "wr" consists of:

| len(wr)       `a non-negative integer`
| c(wr)         `a character sequence of length "len(wr)"`
| cur(wr)       `an integer in the range "[0..len(wr)]"`
| target(wr)    `a character sequence`
| closed(wr)    `a boolean`
| seekable(wr)  `a boolean`
| buffered(wr)  `a boolean`

   These values are generally not directly represented in the data
   fields of a writer object, but in principle they determine the
   state of the writer.

   The sequence "c(wr)" is zero-based: "c(wr)[i]" is valid for "i"
   from 0 through "len(wr)-1".  The value of "cur(wr)" is the index of
   the character in "c(wr)" that will be replaced or appended by the
   next call to "PutChar".  If "wr" is not seekable, then "cur(wr)" is
   always equal to "len(wr)", since in this case all writing happens
   at the end.

   The difference between "c(wr)" and "target(wr)" reflects the
   buffering: if "wr" is not buffered, then "target(wr)" is updated to
   equal "c(wr)" after every operation; if "wr" is buffered, then
   updates to "target(wr)" can be delayed.  For example, in a writer
   to a file, "target(wr)" is the actual sequence of characters on the
   disk; in a writer to a terminal, "target(wr)" is the sequence of
   characters that have actually been transmitted.  (This sequence may
   not exist in any data structure, but it still exists abstractly.)

   If "wr" is buffered, then the assignment "target(wr) := c(wr)" can
   happen asynchronously at any time, although the procedures in this
   interface are atomic with respect to such assignments.

   If you are implementing a long-lived writer class, such as a pipe
   or TCP stream, the index of the writer may eventually overflow,
   causing the program to crash with a bounds fault.  We recommend
   that you provide an operation to reset the writer index, which the
   client can call periodically.

   It is useful to specify the effect of several of the procedures in
   this interface in terms of the action "PutC(wr, ch)", which outputs
   the character "ch" to the writer "wr":

| PutC(wr, ch) =
|   IF closed(wr) THEN `Cause checked runtime error` END;
|   IF cur(wr) = len(wr) THEN
|     `Extend "c(wr)" by one character, incrementing "len(wr)"`
|   END;
|   c(wr)[cur(wr)] := ch;
|   INC(cur(wr));

   "PutC" is used only in specifying the interface; it is not a real
   procedure. */

// intrinsic Length(wr: T): CARDINAL RAISES {Failure, Alerted};
// intrinsic Index(wr: T): CARDINAL RAISES {};
// intrinsic Seekable(wr: T): BOOLEAN RAISES {};
// intrinsic Closed(wr: T): BOOLEAN RAISES {};
// intrinsic Buffered(wr: T): BOOLEAN RAISES {};
/* These procedures return "len(wr)", "cur(wr)", "seekable(wr)",
   "closed(wr)", and "buffered(wr)", respectively. "Length" and
   "Index" cause a checked runtime error if "wr" is closed; the other
   three procedures do not. */

/* Let wr be a writer, which abstractly is given by c(wr), target(wr),
cur(wr), closed(wr), seekable(wr), buffered(wr).  The actual
representation of wr is an object of type Wr.T.  The wr.cur,
wr.closed, wr.seekable, and wr.buffered fields in the object represent
the corresponding abstract attributes of wr.  The wr.buff, wr.st,
wr.lo, and wr.hi fields in the object represent a buffer containing
the unflushed part of c(wr).  The target of the writer is represented
in some class-specific way, which is not specified by this interface.

More precisely, we say that the state of the writer object wr 
is valid if the following conditions V1 through V5 hold:

V1. the cur field and the booleans are correct:
        wr.cur = cur(wr)  AND wr.closed = closed(wr)  AND 
    wr.buffered = buffered(wr)  AND wr.seekable = seekable(wr)

V2. the indexes of any unflushed characters are in the range
[lo..cur-1]. That is, for all i not in [wr.lo..wr.cur-1],

    c(wr)[i] = target(wr)[i]

V3. the (possibly) unflushed characters are stored in buff starting
with buff[st].  That is, for all i in [wr.lo..wr.cur-1],

        c(wr)[i] = wr.buff[wr.st + i - wr.lo]

(Usually st is zero. Non-zero values may be useful to satisfy buffer
alignment constraints.)

V4. the current position is either contained in the buffer, or just
past the buffer:

    wr.lo <= wr.cur <= wr.hi

It is possible that buff = NIL in a valid state, since the range of
i's in V3 can be empty; for example, in the case lo = hi = cur.

V5. if closed(wr) then wr.buff = NIL AND wr.lo = wr.hi

We say that the state is ready if the buffer contains the current
position; that is, if

   NOT wr.closed AND wr.buff # NIL AND  wr.lo <= cur(wr) < wr.hi

If the state is ready, then Wr.PutChar can be implemented by storing
into the buffer.  The class-independent code does exactly this, until
the buffer is full, at which point it calls a class method to consume
the buffer and provide a new one.  Together V4 and V5 imply
that if wr.cur # wr.hi then wr.buff # NIL and NOT wr.closed.  Therefore
a valid writer is ready if "wr.cur # wr.hi".

In general, the class-independent code modifies cur and buff[i] for i
in the range [st..st+(hi-1)-lo], but not the buff reference itself,
st, lo, or hi (except that "Wr.Close" modifies "wr.lo" and "wr.cur" and
sets "wr.buff" to NIL in order to maintain invariant V5). */
Define Class MacServer;
    inherits from Object;

    operation NewStreamNear(nearThis: Object): Stream;  
        // create a new stream object
end class;