<> <> <> <> <> <> DIRECTORY OtherNode, RefTab, Rope; OtherNodeImpl: CEDAR PROGRAM IMPORTS RefTab EXPORTS OtherNode = BEGIN OPEN OtherNode; ROPE: TYPE = Rope.ROPE; <<-- ***** Operations>> ReaderProcRef: TYPE = REF ReaderProcRec; ReaderProcRec: TYPE = RECORD [proc: ReadSpecsProc]; WriterProcRef: TYPE = REF WriterProcRec; WriterProcRec: TYPE = RECORD [proc: WriteSpecsProc]; CopierProcRef: TYPE = REF CopierProcRec; CopierProcRec: TYPE = RECORD [proc: CopyInfoProc]; readerTable: RefTab.Ref _ RefTab.Create[]; writerTable: RefTab.Ref _ RefTab.Create[]; copierTable: RefTab.Ref _ RefTab.Create[]; Register: PUBLIC PROC [variety: ATOM, reader: ReadSpecsProc, writer: WriteSpecsProc, copier: CopyInfoProc] = { <<-- registers these procs for this variety of node>> <<-- they will be called by DoSpecs, GetSpecs, and CopyInfo >> IF variety=NIL THEN RETURN; [] _ RefTab.Store[readerTable,variety,NEW[ReaderProcRec _ [reader]]]; [] _ RefTab.Store[writerTable,variety,NEW[WriterProcRec _ [writer]]]; [] _ RefTab.Store[copierTable,variety,NEW[CopierProcRec _ [copier]]] }; DoSpecs: PUBLIC PROC [n: RefOtherNode, specs: ROPE] = { <<-- used when reading files>> <<-- calls the registered reader for this variety of node>> <<-- sets n.info _ specs if no reader is registered>> procRef: ReaderProcRef; proc: ReadSpecsProc; IF n.variety=NIL OR (procRef _ NARROW[RefTab.Fetch[readerTable,n.variety].val])=NIL OR (proc _ procRef.proc)=NIL THEN n.info _ specs ELSE proc[n,specs] }; GetSpecs: PUBLIC PROC [n: RefOtherNode] RETURNS [specs: ROPE] = { <<-- used when writing files>> <<-- calls the registered writer for this variety of node>> <<-- if no writer is registered, returns n.info if it is a rope, NIL otherwise>> procRef: WriterProcRef; proc: WriteSpecsProc; IF n.variety=NIL OR (procRef _ NARROW[RefTab.Fetch[writerTable,n.variety].val])=NIL OR (proc _ procRef.proc)=NIL THEN IF n.info=NIL THEN specs _ NIL ELSE WITH n.info SELECT FROM rope: ROPE => specs _ rope; ENDCASE => specs _ NIL ELSE specs _ proc[n] }; CopyInfo: PUBLIC PROC [old: RefOtherNode] RETURNS [newinfo: REF ANY] = { <<-- used when copying nodes>> <<-- calls the registered copier for this variety of node>> <<-- if no copier is registered, returns old.info>> procRef: CopierProcRef; proc: CopyInfoProc; IF old.variety=NIL OR (procRef _ NARROW[RefTab.Fetch[copierTable,old.variety].val])=NIL OR (proc _ procRef.proc)=NIL THEN newinfo _ old.info ELSE newinfo _ proc[old] }; <<-- ***** Initialization>> Start: PUBLIC PROC = { }; END.