TiogaAccessDoc.tioga
Last edited by Michael Plass, March 25, 1985 5:12:38 pm PST
Doug Wyatt, August 27, 1986 5:34:28 pm PDT
TiogaAccess
CEDAR 7.0 — 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 properties and looks. To this end it defines a record type TiogaChar that consists of a 16-bit character code (in two parts), a boolean array of looks for that character, and a character property list. It also defines a Reader type and a Writer type, analogous to an input and output stream, respectively, but trafficking in objects of type TiogaChar instead of CHAR. There is a special kind of TiogaChar that is used to delimit tioga nodes; it contains the information from the node's property list, along with the change in nesting level for the following node. There 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 (via the interface TiogaAccessViewer).
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 efficiency 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.
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
DO
tiogaChar: TiogaAccess.TiogaChar ← TiogaAccess.Get[in];
TiogaAccess.Put[out, tiogaChar];
IF tiogaChar.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 ~ {
out: TiogaAccess.Writer ← TiogaAccess.Create[];
selection: TiogaAccess.Reader ← TiogaAccess.FromSelection[];
fileName: ROPE ← TiogaAccess.PeekRope[selection];
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.DoneWith[in];
TiogaAccess.WriteSelection[out];
};
Reversing each node in the selection, using buffers.
ReverseSelection:
PROC ~ {
buffer: LIST OF TiogaAccess.TiogaChar;
out: TiogaAccess.Writer ← TiogaAccess.Create[];
in: TiogaAccess.Reader ← TiogaAccess.FromSelection[];
UNTIL TiogaAccess.EndOf[in]
DO
tiogaChar: TiogaAccess.TiogaChar;
DO
tiogaChar ← TiogaAccess.Get[in];
IF tiogaChar.endOfNode THEN EXIT;
buffer ← CONS[tiogaChar, buffer];
ENDLOOP;
UNTIL buffer =
NIL
DO
t: LIST OF TiogaAccess.TiogaChar ← buffer;
buffer ← t.rest;
t.rest ← NIL;
TiogaAccess.Put[out, t.first];
ENDLOOP;
TiogaAccess.Put[out, tiogaChar];
ENDLOOP;
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
}];
};