RopeFileStreamImpl.mesa
Copyright Ó 1991, 1992 by Xerox Corporation. All rights reserved.
Michael Plass, October 15, 1991 5:22 pm PDT
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["<anon: ", Convert.RopeFromRope[IO.GetRope[stream, 30, FALSE], FALSE], ">"];
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.