DIRECTORY Rope, IO, File, MonitoredQueue, RopeReader, RopeEditingBLT; FileWriter: CEDAR DEFINITIONS IMPORTS RopeEditingBLT, RopeReader, MonitoredQueue = BEGIN ROPE: TYPE = Rope.ROPE; Offset: TYPE = LONG INTEGER; Ref: TYPE = REF FileWriterBody; FileWriterBody: PRIVATE TYPE = RECORD [ block: REF TEXT, -- current block of characters blockList: BlockList, -- list of blocks blockQueue: MonitoredQueue.MQ, -- monitored queue of blocks blockCount: NAT _ 0, -- number added to queue/list stream: IO.Handle, -- file being written toRope: BOOLEAN, -- true if output to rope instead of file closeStream: BOOLEAN, -- true if should close stream after write consumer: PROCESS, -- removes blocks from queue kind: OfWriter _ unused ]; OfWriter: TYPE = {control, comment, data, unused}; BlockList: TYPE = REF BlockListBody; BlockListBody: TYPE = RECORD[block: REF TEXT, next: BlockList]; blockSize: NAT = 512; OpenC: PROC [capability: File.Capability, start: Offset _ 0, makeControl: BOOLEAN _ TRUE] RETURNS [control, data: Ref]; ToRope: PROC [makeControl: BOOLEAN _ TRUE] RETURNS [control, data: Ref]; ToStream: PROC [stream: IO.Handle, makeControl: BOOLEAN _ TRUE] RETURNS [control, data: Ref]; Close: PROC [control, data: Ref, textOnly: BOOLEAN] RETURNS [dataLen, count: Offset, output: ROPE]; WriteChar: PROC [c: CHARACTER, writer: Ref] = INLINE { loc: NAT; block: REF TEXT _ writer.block; IF (loc_block.length) >= blockSize THEN -- buffer is full { block _ BumpWriter[writer]; loc _ 0 }; block[loc] _ c; block.length _ loc+1 }; WriteRope: PROC [r: ROPE, size: Offset, writer: Ref, reader: RopeReader.Ref, start: Offset_0] = INLINE { cnt: NAT; block: REF TEXT _ writer.block; RopeReader.SetPosition[reader,r,start]; UNTIL size=0 DO IF block.length >= blockSize THEN -- buffer is full block _ BumpWriter[writer]; cnt _ RopeReader.GetString[reader:reader, str:block, length:size]; size _ size-cnt; ENDLOOP }; WriteText: PROC [txt: REF READONLY TEXT, writer: Ref] = INLINE { cnt, loc, txtLoc: NAT; size: NAT _ txt.length; block: REF TEXT _ writer.block; txtLoc _ 0; UNTIL size=0 DO IF (loc_block.length) >= blockSize THEN -- buffer is full { block _ BumpWriter[writer]; loc _ block.length }; cnt _ MIN[blockSize-loc,size]; RopeEditingBLT.StringToStringBlt[txt,txtLoc,block,loc,cnt]; size _ size-cnt; txtLoc _ txtLoc+cnt; block.length _ loc+cnt; ENDLOOP }; BumpWriter: PRIVATE PROC [writer: Ref] RETURNS [REF TEXT]; Start: PROC; -- for initialization only END. ÈFileWriter.Mesa written by Paxton. March 1981 last written by Paxton. August 24, 1982 9:31 am Last Edited by: Lamming, June 10, 1983 1:29 pm -- move chars to end of list and allocate a new one Êl˜JšÏc™Jš™Jš/™/J™.J˜JšÏk ˜ J˜Jšžœ˜J˜J˜J˜ J˜J˜Jšœ ž˜Jšžœ-˜4Jšž˜J˜Jšžœžœžœ˜Jšœžœžœžœ˜J˜Jšœžœžœ˜šœžœžœžœ˜'Jšœžœžœ˜/Jšœ˜'Jšœžœ˜;Jšœ žœ˜2Jšœžœ ˜(Jšœžœ)˜:Jšœ žœ*˜@Jšœ žœ˜/J˜J˜—Jšœ žœ$˜2Jšœ žœžœ˜$Jš œžœžœžœžœ˜?Jšœ žœ˜J˜šÏnœžœ?žœžœ˜YJšžœ˜J˜—Jš Ÿœžœžœžœžœ˜HJ˜š Ÿœžœ žœžœžœ˜?Jšžœ˜J˜—šŸœžœ žœ˜3Jšžœ"žœ˜/J˜—šŸ œžœž œžœ˜6Jšœžœ˜ Jšœžœžœ˜šžœ!žœ˜9J˜(—J˜'J˜—šŸ œž˜JšœžœHžœ˜XJšœžœ˜ Jšœžœžœ˜J˜'šžœž˜šžœžœ˜3J˜—J˜BJ˜Jšžœ˜ J˜——š Ÿ œžœžœžœžœžœ˜@Jšœžœ˜Jšœžœ˜Jšœžœžœ˜J˜ šžœž˜šžœ!žœ˜9J˜3—Jšœžœ˜J˜;J˜=Jšžœ˜ J˜——š Ÿ œžœžœžœžœžœ˜:Jš3™3J˜—JšŸœžœ˜'J˜Jšžœ˜J˜—…— ¢ Ö