DIRECTORY Basics USING [bytesPerWord], FS USING [defaultStreamOptions, OpenFile, StreamFromOpenFile, StreamOptions], IO USING [GetBlock, GetIndex, GetLength, STREAM], Rope, RopeEdit, RopeEditingAlloc, RopeEditingBLT, RopeFile USING [FromStream], RopeFrom, RopePrivate, RopeReader; RopeFromFileImpl: CEDAR MONITOR IMPORTS FS, IO, Rope, RopeEdit, RopeEditingAlloc, RopeEditingBLT, RopeFile, RopeFrom, RopePrivate EXPORTS RopeFrom SHARES Rope = BEGIN OPEN RopeFrom, RopePrivate; charsPerArray: NAT = RopeReader.charsPerArray; charsPerSpace: NAT = charsPerArray; spaceMin: NAT = charsPerSpace/2; -- put in shared array if less than 1/2 CharsArray: TYPE = RopeReader.CharsArray; Chars: TYPE = REF CharsArray; File: PUBLIC PROC [ file: FS.OpenFile, start: Offset _ 0, length: Offset _ MaxLen, activate: BOOLEAN _ FALSE, fileLen: Offset _ MaxLen] RETURNS [rope: ROPE] = { stream: IO.STREAM _ NIL; options: FS.StreamOptions _ FS.defaultStreamOptions; options[tiogaRead] _ FALSE; -- include the formatting information options[closeFSOpenFileOnClose] _ FALSE; -- don't close the openFile stream _ FS.StreamFromOpenFile[ openFile: file, accessRights: $read, streamOptions: options, streamBufferParms: [vmPagesPerBuffer: 2, nBuffers: 1]]; RETURN[RopeFile.FromStream[stream: stream, start: start, len: length]]; }; Stream: PUBLIC PROC [stream: IO.STREAM, length: Offset _ MaxLen] RETURNS [rope: ROPE] = { MakeRope: PROC [len: Offset] RETURNS [ROPE] = { chars: REF RopeReader.CharsArray; start, nchars, charloc: NAT; base: ROPE; IF len = 0 THEN RETURN [NIL]; IF len > charsPerSpace THEN { -- split into balanced parts half: Offset = MAX[len/2,charsPerSpace]; front: ROPE = MakeRope[half]; -- ensure proper evaluation order! front first back: ROPE = MakeRope[len-half]; -- then the back RETURN [Rope.Concat[front,back]]; }; nchars _ Short[len]; [chars, start, base] _ RopeEditingAlloc.AllocWords[ (nchars+(Basics.bytesPerWord-1))/Basics.bytesPerWord]; charloc _ start; UNTIL nchars = 0 DO nread: NAT; block.length _ 0; nread _ IO.GetBlock[self: stream, block: block, startIndex: 0, count: nchars]; RopeEditingBLT.StringToArrayBlt[block,0,chars,charloc,nread]; nchars _ nchars-nread; charloc _ charloc+nread; ENDLOOP; RETURN [qZone.NEW[Tsubstr _ [node[substr[len,base,start,1+RopeEdit.Depth[base]]]]]] }; start,fileLen: Offset; block: REF TEXT; fileLen _ IO.GetLength[stream]; start _ IO.GetIndex[stream]; IF fileLen <= start THEN RETURN [NIL]; length _ MIN[length,fileLen-start]; IF length = 0 THEN RETURN [NIL]; block _ RopeEditingAlloc.GetBlock[]; rope _ MakeRope[length]; RopeEditingAlloc.FreeBlock[block]; }; StartRopeFromFile: PUBLIC PROC = { }; END. FRopeFromFileImpl.Mesa written by Bill Paxton, February 1981 Paxton, November 12, 1982 3:17 pm Maxwell, January 5, 1983 12:11 pm Russ Atkinson, July 26, 1983 5:28 pm Paul Rovner, August 10, 1983 4:23 pm Doug Wyatt, December 5, 1983 1:54 pm -- ***** Operations byte address in file where rope will start 0 means first page after leader page defaults to rest of file beyond start if activate is true, the system will start swapping the characters into real memory fileLen is # of bytes in file, excluding leader page (usually defaulted to rest of file) -- ***** Initialization ʬ˜šÏc™Jš&™&Jš!™!J™!J™$J™$J™$J™—šÏk ˜ Jšœžœ˜JšžœžœE˜MJšžœžœ!žœ˜1J˜J˜ J˜J˜Jšœ žœ˜J˜ J˜ J˜ J˜—šœž ˜šž˜JšžœžœS˜Y—Jšžœ ˜Jšžœ˜ Jšœž œ˜#—J˜Jšœžœ˜.Jšœžœ˜#Jšœ žœ'˜HJ˜Jšœ žœ˜)Jšœžœžœ ˜J˜Jš™J˜šÏnœžœžœ˜Jšœžœ ˜˜Jšœ*™*Jš$™$—šœ˜Jšœ%™%—šœ žœžœ˜JšœS™S—šœ˜JšœX™X—Jšžœžœ˜Jšœžœžœžœ˜Jšœ žœžœ˜4Jšœžœ%˜AJšœ"žœ˜Dšœ žœ˜Jšœ<˜