IPReader.mesa
Copyright © 1984 Xerox Corporation. All rights reserved.
Doug Wyatt, August 24, 1984 10:43:47 am PDT
Token-level interface for reading encoded Interpress masters
DIRECTORY
IO USING [STREAM],
IPBasic USING [Op, Rational, Version, XeroxPixelVectorType],
Rope USING [ROPE];
IPReader: CEDAR DEFINITIONS
~ BEGIN
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
Op: TYPE ~ IPBasic.Op;
Rational: TYPE ~ IPBasic.Rational;
Version: TYPE ~ IPBasic.Version;
ErrorCode: TYPE ~ {
ok, -- initial value for an ErrorCode
bug, -- implementation bug
unimplemented, -- operation not currently implemented
unknownEncoding, -- the requested encoding is not implemented
illegalHeader, -- invalid header for an Interpress master
illegalStructure, -- the skeleton of the master is malformed
illegalToken, -- a token is malformed
wrongType, -- token to be parsed has the wrong type
overflow, -- numeric overflow while trying to parse a number
closed -- tried to operate on a closed reader
};
Error: ERROR[code: ErrorCode, explanation: ROPENIL];
Index: TYPE ~ INT; -- a byte position in the master
nullIndex: Index ~ -1;
TokenType: TYPE ~ {
nil,
op, -- value is token.op
shortNumber, -- value is token.shortNumber
integer, -- use ReadInt or ReadReal
rational, -- use ReadRational or ReadReal
real, -- use ReadReal
identifier, -- value is token text
string, -- value is token text (uses Xerox Character Code Standard encoding)
insertfile, -- value is token text
comment, -- value is token text
annotation, -- value is token text
largeVector, -- use ReadLargeVector
eof -- end of file
};
Token: TYPE ~ RECORD[
type: TokenType,
op: Op,
shortNumber: INTEGER,
index: Index
];
nullToken: Token ~ [type: $nil, op: $nil, shortNumber: 0, index: 0];
LargeVector: TYPE ~ REF LargeVectorRep;
LargeVectorRep: TYPE ~ RECORD[
source: STREAM,
bytesPerElement: [0..256),
type: IPBasic.XeroxPixelVectorType ← $nil
];
Reader: TYPE ~ REF ReaderRep;
ReaderRep: TYPE ~ RECORD[
class: Class, -- procedures for reading the encoding
stream: STREAM, -- input stream on the master
buffer: REF TEXT -- scratch text buffer
];
Class: TYPE ~ REF ClassRep;
ClassRep: TYPE ~ RECORD[
encoding: ATOM ←,
getToken: PROC[reader: Reader, buffer: REF TEXTNIL, flushComments: BOOLTRUE]
RETURNS[token: Token, text: REF TEXT] ←,
readInt: PROC[reader: Reader, token: Token, text: REF TEXT] RETURNS[INT] ←,
readRational: PROC[reader: Reader, token: Token, text: REF TEXT] RETURNS[Rational] ←,
readReal: PROC[reader: Reader, token: Token, text: REF TEXT] RETURNS[REAL] ←,
readLargeVector: PROC[reader: Reader, token: Token] RETURNS[LargeVector] ←,
finishBody: PROC[reader: Reader] ← NIL
];
Open: PROC[name: ROPE] RETURNS[Reader];
Open the named file, parse the header to determine the encoding, and return a Reader.
Create: PROC[stream: STREAM, encoding: ATOM, version: Version] RETURNS[Reader];
Create a Reader for the given stream. Starts reading at the current stream index.
Close: PROC[reader: Reader];
Close the reader's stream and prevent further calls on the reader.
GetIndex: PROC[reader: Reader] RETURNS[Index];
SetIndex: PROC[reader: Reader, index: Index];
GetToken: PROC[reader: Reader, buffer: REF TEXTNIL, flushComments: BOOLTRUE]
RETURNS[token: Token, text: REF TEXT]
~ INLINE { RETURN reader.class.getToken[reader, buffer, flushComments] };
ReadInt: PROC[reader: Reader, token: Token, text: REF TEXT] RETURNS[INT]
~ INLINE { RETURN reader.class.readInt[reader, token, text] };
ReadRational: PROC[reader: Reader, token: Token, text: REF TEXT] RETURNS[Rational]
~ INLINE { RETURN reader.class.readRational[reader, token, text] };
ReadReal: PROC[reader: Reader, token: Token, text: REF TEXT] RETURNS[REAL]
~ INLINE { RETURN reader.class.readReal[reader, token, text] };
ReadLargeVector: PROC[reader: Reader, token: Token] RETURNS[LargeVector];
FinishBody: PROC[reader: Reader];
StreamFromInputStream: PROC[stream: STREAM] RETURNS[STREAM];
Node: TYPE ~ REF NodeRep;
BodyNode: TYPE ~ REF NodeRep[body];
BlockNode: TYPE ~ REF NodeRep[block];
NodeRep: TYPE ~ RECORD[
instructions: Index ← nullIndex, -- nullIndex if no instructions
content: SELECT tag: * FROM
body => [body: Index],
block => [block: Block],
ENDCASE
];
Block: TYPE ~ REF BlockRep;
BlockRep: TYPE ~ RECORD[
noPages: BOOL,
preamble: Node,
nodes: SEQUENCE size: NAT OF Node
];
GetSkeleton: PROC[reader: Reader] RETURNS[Block];
Register: PROC[class: Class];
END.