TiogaAccessDoc.tioga
Last edited by Michael Plass, February 4, 1985 1:55:23 pm PST
TiogaAccess
CEDAR 5.2 — FOR INTERNAL XEROX USE ONLY
TiogaAccess
Michael Plass
© Copyright 1985 Xerox Corporation. All rights reserved.
Client package for the sequential processing of Tioga documents or selections, including looks and formatting information.
Keywords: Tioga, read, write, selection, document, looks, format
XEROX  Xerox Corporation
   Palo Alto Research Center
   3333 Coyote Hill Road
   Palo Alto, California 94304

For Internal Xerox Use Only
1. TiogaAccess.mesa
This interface provides a facility that makes it easy to write Cedar programs that can process Tioga documents in all their glory, i.e., including the node properties and looks. To this end it defines a record type CharWithLooks that is just what it sounds like — an 8-bit character code together with a boolean array of looks for that character. It also defines a Reader type and a Writer type, analogous to an input and output stream, respectively, but trafficing in objects of type CharWithLooks instead of CHAR. There is a special value of type CharWithLooks that is used to delimit tioga nodes. The extra information about nodes (format, comment flag, level, property list) are made available via the NodeInfo type and its associated operations GetNodeInfo and PutNodeInfo. There a a collection of operations for creating Readers from a variety of sources, and for writing the contents of a Writer to a variety of destinations. Among these possible sources and destinations are a file, the current (primary) selection, and the contents of a Tioga viewer.
The emphasis for this interface is to make it as easy as possible for the client to deal with all the richness of Tioga's document structure; to this end, some efficency concessions have been made. A reader works by making a copy of the source and holding onto it; however only the node structure has to be copied, thanks to the fact that ROPEs and the run structures of looks are immutable. A writer works by constructing a new document structure in virtual memory; this may cause some problems for very large documents. If much of the document is being passed unaltered, consider using CopyNode instead of Gets and Puts; this will increase the sharing of structures, and so decrease the load on VM. There is a Buffer type defined, analogous to an unbounded REF TEXT, but for CharWithLooks. Don't use this to gain efficiency, but only where it fits your needs.
Operations that read and write the selection are atomic, so nothing will break if you do no extra locking. This is the best course of action to take while you are debugging, since it is hard to debug while the selection is locked. However, if your program both reads and writes the selection, use TiogaOps.CallWithLocks to keep the selection from changing during your computation. If you do this, be sure to try and catch all errors that might be caused by bad user input or missing files, etc. It's also a good idea to put a catch phrase as in the example below, to pick up anything you might have missed; this way you won't lock up the user's world with one of your bugs.
2. Examples
Copying the selection into a file, one character at a time.
SaveSelection: PROC [fileName: ROPE] ~ {
out: TiogaAccess.Writer ← TiogaAccess.Create[];
in: TiogaAccess.Reader ← TiogaAccess.FromSelection[];
UNTIL TiogaAccess.EndOf[in] DO
nodeInfo: TiogaAccess.NodeInfo ← TiogaAccess.GetNodeInfo[in];
TiogaAccess.PutNodeInfo[out, nodeInfo];
DO
candl: TiogaAccess.CharWithLooks ← TiogaAccess.Get[in];
TiogaAccess.Put[out, candl];
IF candl.endOfNode THEN EXIT;
ENDLOOP;
ENDLOOP;
TiogaAccess.DoneWith[in];
TiogaAccess.WriteFile[out, fileName];
};
Replacing a selected filename by the file's contents, using CopyNode.
GetSelection: PROC ~ {
selection: TiogaAccess.Reader ← TiogaAccess.FromSelection[];
fileName: ROPE ← TiogaAccess.PeekRope[selection];
buffer: TiogaAccess.Buffer ← TiogaAccess.ObtainBuffer[];
out: TiogaAccess.Writer ← TiogaAccess.Create[];
in: TiogaAccess.Reader ← TiogaAccess.FromFile[fileName];
Could catch FS.Error here for bad name or missing file.
TiogaAccess.DoneWith[selection];
IF NOT TiogaAccess.EndOf[in] THEN [] ← TiogaAccess.Get[in];
Discard root; failure to do this will cause the WriteSelection to fail.
UNTIL TiogaAccess.EndOf[in] DO
[] ← TiogaAccess.CopyNode[out, in]
ENDLOOP;
TiogaAccess.ReleaseBuffer[buffer];
TiogaAccess.DoneWith[in];
TiogaAccess.WriteSelection[out];
};
Reversing each node in the selection, using buffers.
ReverseBuffer: PROC [buffer: TiogaAccess.Buffer] ~ {
size: INT ← buffer.BufferSize-1;
Do not include the end-of-node mark.
FOR i: INT IN [0..size/2) DO
t: TiogaAccess.CharWithLooks ← buffer.Fetch[i];
buffer.Store[i, buffer.Fetch[size-1-i]];
buffer.Store[size-1-i, t]
ENDLOOP;
};
ReverseSelection: PROC ~ {
buffer: TiogaAccess.Buffer ← TiogaAccess.ObtainBuffer[];
out: TiogaAccess.Writer ← TiogaAccess.Create[];
in: TiogaAccess.Reader ← TiogaAccess.FromSelection[];
UNTIL TiogaAccess.EndOf[in] DO
nodeInfo: TiogaAccess.NodeInfo ← TiogaAccess.GetNodeInfo[in];
nodeEnd: BOOLEAN ← TiogaAccess.GetBuffer[in, buffer];
IF NOT nodeEnd THEN ERROR;
TiogaAccess.PutNodeInfo[out, nodeInfo];
ReverseBuffer[buffer];
TiogaAccess.PutBuffer[out, buffer];
ENDLOOP;
TiogaAccess.ReleaseBuffer[buffer];
TiogaAccess.DoneWith[in];
TiogaAccess.WriteSelection[out];
};
Same thing, locking the selection to avoid races with the user.
LockedReverseSelection: PROC ~ {
action: PROC [ref: TiogaOps.Ref] ~ {ReverseSelection[]};
TiogaOps.CallWithLocks[action ! RuntimeError.UNCAUGHT => {
MessageWindow.Append["Unknown error in ReverseSelection", TRUE];
MessageWindow.Blink[];
CONTINUE
}];
};