DIRECTORY Atom, G3dBasic, G3dMatrix, IO, Rope, TiogaAccess; G3dIO: CEDAR DEFINITIONS ~ BEGIN PropList: TYPE ~ Atom.PropList; IntegerSequence: TYPE ~ G3dBasic.IntegerSequence; NatSequence: TYPE ~ G3dBasic.NatSequence; Pair: TYPE ~ G3dBasic.Pair; PairSequence: TYPE ~ G3dBasic.PairSequence; Quad: TYPE ~ G3dBasic.Quad; RealSequence: TYPE ~ G3dBasic.RealSequence; SurfaceSequence: TYPE ~ G3dBasic.SurfaceSequence; Triple: TYPE ~ G3dBasic.Triple; TripleSequence: TYPE ~ G3dBasic.TripleSequence; Matrix: TYPE ~ G3dMatrix.Matrix; STREAM: TYPE ~ IO.STREAM; ROPE: TYPE ~ Rope.ROPE; Writer: TYPE ~ TiogaAccess.Writer; FieldType: TYPE ~ {integer, real, pair, triple, nats, none}; FieldDescription: TYPE ~ RECORD [id: ROPE, type: FieldType]; Field: TYPE ~ REF FieldRep; FieldRep: TYPE ~ RECORD [ id: ROPE, -- name of the field type: FieldType, -- type of the field sequence: REF ANY -- ref to field sequence ]; FieldSequence: TYPE ~ REF FieldSequenceRep; FieldSequenceRep: TYPE ~ RECORD [ length: NAT, element: SEQUENCE maxLength: INTEGER OF Field ]; Line: TYPE ~ REF LineRep; LineRep: TYPE ~ RECORD [ type: {key, blank, data, comment}, -- type of line rope: ROPE ¬ NIL, -- text of this line index: INTEGER ¬ 0, -- current index into the rope length: INTEGER ¬ 0, -- length of the rope stream: STREAM ¬ NIL -- the associated io stream ]; ErrorType: TYPE ~ {notFound, format, convert}; Error: ERROR [reason, lineText: ROPE, lineNumber: NAT]; ErrorReport: PROC [errorType: ErrorType, line: Line ¬ NIL, keyWord: ROPE ¬ NIL]; ObtainLine: PROC RETURNS [Line]; ReleaseLine: PROC [line: Line]; LineNumber: PROC [line: Line] RETURNS [INTEGER]; NextKeyWord: PROC [ stream: STREAM, circularSearch: BOOL ¬ FALSE, maxNLinesToTest: CARDINAL ¬ LAST[CARDINAL]] RETURNS [key: ROPE]; FindKeyWord: PROC [ stream: STREAM, keyWord: ROPE, circularSearch: BOOL ¬ FALSE, maxNLinesToTest: CARDINAL ¬ LAST[CARDINAL], line: Line ¬ NIL] RETURNS [Line]; InitializeFields: PROC [keyLine: Line] RETURNS [FieldSequence]; NumberOfLinesToConvert: PROC [stream: STREAM] RETURNS [INTEGER]; NWordsInRope: PROC [line: ROPE] RETURNS [INTEGER]; GetStream: PROC [fileName: ROPE] RETURNS [STREAM]; GetLine: PROC [stream: STREAM, line: Line ¬ NIL] RETURNS [Line]; GetDataLine: PROC [stream: STREAM, line: Line ¬ NIL] RETURNS [Line]; GetWord: PROC [line: Line] RETURNS [ROPE]; GetInteger: PROC [line: Line] RETURNS [INTEGER]; GetReal: PROC [line: Line] RETURNS [REAL]; GetPair: PROC [line: Line] RETURNS [Pair]; GetTriple: PROC [line: Line] RETURNS [Triple]; GetNats: PROC [line: Line] RETURNS [nats: NatSequence]; ReadRope: PROC [stream: STREAM, keyWord: ROPE, circularSearch: BOOL ¬ FALSE] RETURNS [ROPE]; ReadInteger: PROC [stream: STREAM, keyWord: ROPE, circularSearch: BOOL ¬ FALSE] RETURNS [INTEGER]; ReadReal: PROC [stream: STREAM, keyWord: ROPE, circularSearch: BOOL ¬ FALSE] RETURNS [REAL]; ReadPair: PROC [stream: STREAM, keyWord: ROPE, circularSearch: BOOL ¬ FALSE] RETURNS [Pair]; ReadTriple: PROC [stream: STREAM, keyWord: ROPE, circularSearch: BOOL ¬ FALSE] RETURNS [Triple]; ReadIntegerSequence: PROC [ stream: STREAM, keyWord: ROPE, circularSearch: BOOL ¬ FALSE, nElements: INT ¬ 0] RETURNS [IntegerSequence]; ReadRealSequence: PROC [ stream: STREAM, keyWord: ROPE, circularSearch: BOOL ¬ FALSE, nElements: INT ¬ 0] RETURNS [RealSequence]; ReadPairSequence: PROC [ stream: STREAM, keyWord: ROPE, circularSearch: BOOL ¬ FALSE, nElements: INT ¬ 0] RETURNS [PairSequence]; ReadTripleSequence: PROC [ stream: STREAM, keyWord: ROPE, circularSearch: BOOL ¬ FALSE, nElements: INT ¬ 0] RETURNS [TripleSequence]; ReadSurfaceSequence: PROC [ stream: STREAM, keyWord: ROPE, circularSearch: BOOL ¬ FALSE, nElements: INT ¬ 0] RETURNS [SurfaceSequence]; ReadFields: PROC [ stream: STREAM, keyWord: ROPE, circularSearch: BOOL ¬ FALSE, nElements: INT ¬ 0] RETURNS [FieldSequence]; ReadMatrix: PROC [stream: STREAM] RETURNS [Matrix]; WritePair: PROC [stream: STREAM, p: Pair]; WriteTriple: PROC [stream: STREAM, t: Triple]; WriteJustified: PROC [stream: STREAM, r: REAL]; WriteFields: PROC [stream: STREAM, keyWord: ROPE, fields: FieldSequence]; WriteMatrix: PROC [stream: STREAM, m: Matrix]; ReadPointsPolygons: PROC [fileName: ROPE] RETURNS [points: TripleSequence, polygons: SurfaceSequence, errorMessage: ROPE]; WritePointsPolygons: PROC [fileName: ROPE, points: TripleSequence, polygons: SurfaceSequence]; PrintPair: PROC [stream: STREAM, pair: Pair, name: ROPE ¬ NIL]; PrintTriple: PROC [stream: STREAM, triple: Triple, name: ROPE ¬ NIL]; PrintQuad: PROC [stream: STREAM, quad: Quad, name: ROPE ¬ NIL]; PrintMatrix: PROC [stream: STREAM, matrix: Matrix, name: ROPE ¬ NIL]; WriteCreate: PROC [title: ROPE] RETURNS [Writer]; WriteNode: PROC [ w: Writer, node: ROPE, looks: ROPE ¬ NIL, comment: BOOL ¬ FALSE, format: ATOM ¬ NIL]; WritePartialNode: PROC [w: Writer, node: ROPE, looks: ROPE ¬ NIL, comment: BOOL ¬ FALSE]; WriteKey: PROC [w: Writer, key: ROPE, val1, val2, val3: IO.Value ¬ [null[]]]; WriteNodeEnd: PROC [w: Writer]; END. Ό G3dIO.mesa Copyright Σ 1985, 1992 by Xerox Corporation. All rights reserved. Bloomenthal, July 22, 1992 1:33 pm PDT Ken Fishkin, August 20, 1992 4:02 pm PDT Type Declarations Imported Types Local Types File Format Data in a G3dIO file is preceded by a separate keyLine that specifyies the data format. This keyLine is a keyWord followed by a `~' and an arbitrary number of field descriptions. The field descriptions, optionally be separated by commas, consist of a colon-terminated identifier and a case-insensitive fieldType. A sample keyLine is: PointSet~ id: Integer, xyzCoords: Triple, rgbColor: Triple The data following a keyLine is terminated by another keyLine or by end of file. Any line that is not a keyLine, is not a blank line, and does not begin with "--" is a dataLine and is assumed to contain valid data whose format is defined by the preceding keyLine. Whitespace may appear before any of the punctuations ('~', ':', or ','). Comments begin with "--"; they may be a separate line within the file or may terminate a dataLine or keyLine. The file is presumed Tioga formatted. If the file is opened elsewhere, its streamOption.tiogaRead must be TRUE; otherwise Tioga formatting at the end of the file will be mistaken for data. Errors Raises Error with the proper reason. Procedures that take a keyWord as an argument may raise ERROR Error["keyWord not found"]. Procedures that return data may raise ERROR Error["bad conversion"]. Procedures that fail to find expected data may raise ERROR ["bad format"]. Support Procedures Obtain a line from the pool. Release the line back to the pool. Return the line number at which line occurs within the file; return -1 if not found. Return the next keyWord. The file index points to the beginning of the key line. The keyWord search terminates after maxLinesToTest lines have been searched. Return the line beginning with keyWord followed by "~"; line is returned with its index set to after the "~". If line is passed non-NIL, it is used for storage. The file index points to the beginning of the line following the key line. The keyWord search terminates after maxLinesToTest lines have been searched. Allocate the fields for this keyLine, set their id's and types, but not their sequences. Return the number of lines before next keyLine that are non-blank and non-comment. This will not alter the stream pointer. Return the number of words in the line. Get Procedures Return the opened filestream (or NIL if error in opening file). Return the next line from the stream. Use line if non-NIL. Return the next dataLine. Use line if non-NIL. Return the next whitespace-delimited word in line, advancing the line index by one word. Convert the next word in line to an integer and advance the line index accordingly. Convert the next word in line to a real and advance the line index accordingly. Convert the next two words in line to a pair and advance the line index accordingly. Convert the next three words in line to a triple and advance the line index accordingly. Convert the remainder of the line into a sequence of nats. Read Procedures The following read procedures leave the stream pointer at the end of the data read. All searches for a keyWord begin at the current file position. If circularSearch is TRUE, the search will, upon reaching end of file, resume at the file beginning and stop at the current position. Return remainder of the key line after the keyWord. Return integer after the key line. Return real after the key line. Return pair after the key line. Return triple after the key line. The remaining Read procedures take an optional argument, nElements. If nElements is left defaulted to zero, then the read procedure will attempt to convert all lines past the keyWord line until a new keyWord line or comment line is found. The number of such lines is first determined by reading ahead in the file. This can be time consuming for large files. If the client knows the number of such lines, however, this look-ahead can be eliminated by supplying a positive value for nElements. If key non-nil, search file forward from current stream position for the key; if not found, search file from its beginning. Read a sequence of lines from the file, beginning after the keyWord. For example, suppose a file contains the key line: Polygons~ index: Integer color: Triple vertices: Nats followed by a set of lines, each containing a polygon index (integer), a color (triple) and a sequence of vertex indices (nats). The information could be read from the file as follows: indices: IntegerSequence; colors: TripleSequence; vertices: SurfaceSequence; polygons: FieldSequence _ IO3d.ReadFields[stream, "Polygons"]; FOR n: NAT IN [0..fields.length) DO SELECT TRUE FROM Rope.Equal[polygons[n].id, "index"] => indices _ NARROW[polygons[n].sequence]; Rope.Equal[polygons[n].id, "color"] => colors _ NARROW[polygons[n].sequence]; Rope.Equal[polygons[n].id, "vertices"] => vertices _ NARROW[polygons[n].sequence]; ENDCASE => NULL; ENDLOOP; If one wished, for example, to print the vertices of the second polygon: IF polygons.length > 1 THEN { FOR n: NAT IN [0..vertices[1].length) DO Print[vertices[1][n]]; ENDLOOP; }; Write Procedures Write the pair to the given stream. Write the triple to the given stream. Write the real to the given stream; if r >= 0, then justify with a space. Write the fields to the stream given the keyWord. Write the matrix to the given stream. Points/Polys Procedures Read points, polygons from a file. If an error is encounted, points and polygons will be set to NIL. The file is presumed to contain two lists: a points list of triples preceded by the header, "~Points" a polygon list of natSequences preceded by the header, "~Polygons" Write points, polygons to a file. Printing Procedures print the value of pair on the given stream, optionally preceded by name. print the value of triple on the given stream, optionally preceded by name. print the value of quad on the given stream, optionally preceded by name. print the value of matrix on the given stream, optionally preceded by name. TiogaAccess Create the file. Write entire node with the given looks and format. Add to the current node. Add to the current node the key, in bold, and the value. Add end of node to current node. Κ R–"cedarcode" style•NewlineDelimiter ™™ Jšœ Οeœ6™BJ™&J™(J˜JšΟk œžœ˜;J˜—šΡblnœžœž ˜Jšœž˜—headšΟl™š ™Jšœ žœ˜"Jšœžœ˜2Jšœžœ˜+Jšœ žœ˜Jšœžœ˜,Jšœ žœ˜Jšœžœ˜,Jšœžœ˜1Jšœ žœ˜"Jšœžœ˜0Jšœ žœ˜#Jšžœžœžœžœ˜Jšžœžœžœ˜Jšœ žœ˜%—š  ™ Jšœ žœ-˜>Jšœžœžœžœ˜J™šžœžœžœž™#šžœžœž™Jšœ1žœ™NJšœ0žœ™MJšœ5žœ™RJšžœžœ™—Jšžœ™——J™J™H™šžœžœ™šžœžœžœž™(J™Jšžœ™ —J™———J˜Jš€ œžœ žœžœ ˜3—š ™š€ œžœ žœ ˜*J™#J˜—š€ œžœ žœ ˜.J™%J˜—š€œžœ žœžœ˜/J™IJ˜—š€ œžœ žœ žœ˜JJ™1—J˜š€ œžœ žœ˜/J™%——š ™š€œžœ žœ˜)JšžœCžœ˜PJ˜J™"Jšœ=£œ™A™*J™:J™B—J˜—š€œžœ žœ5˜^J™!——š ™š € œžœ žœžœžœ˜?J™IJ˜—š € œžœ žœžœžœ˜EJ™KJ˜—š € œžœ žœžœžœ˜?J™IJ˜—š € œžœ žœžœžœ˜EJ™K——š  ™ š€ œžœ žœžœ ˜1J™J˜—š€ œžœ˜J˜ Jšœžœ˜ Jšœžœžœ˜Jšœ žœžœ˜Jšœžœžœ˜J™2J˜—š€œžœžœ žœžœ žœžœ˜YJ™J˜—š€œžœžœžœ˜MJ™8J™—š€ œžœ ˜J™ —J™—šžœ˜J™J™——…—08>