<<>> <> <> <> DIRECTORY Basics, Convert, Rope, RopeFile, IO; RopeFileStreamImpl: CEDAR MONITOR LOCKS self USING self: ByteSequenceObject IMPORTS Convert, IO, Rope, RopeFile EXPORTS RopeFile ~ BEGIN ROPE: TYPE ~ Rope.ROPE; ByteSequenceObject: TYPE ~ RopeFile.ByteSequenceObject; DeactivateResult: TYPE ~ RopeFile.DeactivateResult; Data: TYPE ~ REF DataRep; DataRep: TYPE ~ RECORD [ stream: IO.STREAM, fileName: ROPE, created: ROPE ]; StreamDeactivate: ENTRY PROC [self: ByteSequenceObject, final: BOOL] RETURNS [DeactivateResult] ~ { data: Data ~ NARROW[self.data]; IF data.stream = NIL THEN RETURN [alreadyInactive]; IF final THEN { IO.Close[data.stream]; data.stream ¬ NIL; RETURN [ok] }; RETURN [cant] }; StreamEqual: ENTRY PROC [self, other: ByteSequenceObject] RETURNS [BOOL] ~ { data: Data ~ NARROW[self.data]; RETURN [FALSE] }; StreamDescribe: ENTRY PROC [self: ByteSequenceObject] RETURNS [fileName: ROPE, created: ROPE, open: BOOL] ~ { data: Data ~ NARROW[self.data]; RETURN [fileName: data.fileName, created: data.created, open: data.stream#NIL] }; StreamMove: ENTRY UNSAFE PROC [self: ByteSequenceObject, block: Basics.UnsafeBlock, start: INT] RETURNS [charsMoved: INT ¬ 0] ~ UNCHECKED { ENABLE UNWIND => NULL; data: Data ~ NARROW[self.data]; IF data.stream # NIL THEN { IO.SetIndex[data.stream, start]; charsMoved ¬ IO.UnsafeGetBlock[data.stream, block]; }; }; ByteSequenceObjectFromStream: PUBLIC PROC [stream: IO.STREAM] RETURNS [ByteSequenceObject] ~ { length: INT ~ IO.GetLength[stream]; data: Data ~ NEW[DataRep ¬ [stream: stream, fileName: NIL, created: "??"]]; IO.SetIndex[stream, 0]; -- Make sure SetIndex is provided on this stream. data.fileName ¬ Rope.Cat[""]; RETURN [RopeFile.CreateByteSequenceObject[length: length, data: data, equal: StreamEqual, deactivate: StreamDeactivate, describe: StreamDescribe, move: StreamMove]]; }; FromStream: PUBLIC PROC [stream: IO.STREAM, start: INT ¬ 0, len: INT ¬ LAST[INT], flatten: BOOL ¬ FALSE] RETURNS [rope: ROPE] ~ { IF flatten THEN { IO.SetIndex[stream, start]; rope ¬ IO.GetRope[stream, len, FALSE]; IO.Close[stream]; } ELSE { byteSequenceObject: ByteSequenceObject ~ ByteSequenceObjectFromStream[stream]; rope ¬ RopeFile.FromByteSequenceObject[byteSequenceObject]; }; }; END.