PStringImpl.Mesa
Copyright (c) Xerox Corporation, 1982. All rights reserved.
Last Modified On 20-Nov-81 16:34:07 by JHM
Schmidt August 22, 1982 1:41 pm
lasted edited by Satterthwaite, April 18, 1986 4:49:25 pm PST
DIRECTORY
FS: TYPE USING [GetInfo, Error, nullOpenFile, Open, OpenFile, Read],
IO: TYPE USING [GetInt, int, PutFR, RIS],
PL: TYPE USING[RErr],
Process: TYPE USING [Detach],
PString: TYPE USING [Stream],
Rope: TYPE USING [Fetch, Flatten, Length, MakeRope, MapType, ROPE, Substr],
SafeStorage: TYPE USING [EstablishFinalization, FinalizationQueue, FQNext, NewFQ],
VM: TYPE USING [AddressForPageNumber, Allocate, Free, Interval, MakeReadOnly];
PStringImpl: CEDAR PROGRAM
IMPORTS FS, IO, PL, Process, Rope, SafeStorage, VM
EXPORTS PString = {
ROPE: TYPE = Rope.ROPE;
Stream: TYPE = PString.Stream;
FileHandle: TYPE = REF FileRecord;
FileRecord:
PRIVATE
TYPE =
RECORD[
len: INT, s: VM.Interval, p: LONG POINTER TO PACKED ARRAY [0..0) OF CHAR];
fq: SafeStorage.FinalizationQueue;
BoundsError: ERROR = CODE;
minCoerceSize: INT = 100;
OpenFiles: LIST OF FileHandle ← LIST[NIL];
MTSt: ROPE = "";
CopyStream:
PUBLIC
PROC[n: Stream]
RETURNS[Stream] = {
RETURN[n]};
ConvertStream:
PUBLIC
PROC[s: Stream]
RETURNS [ans:
ROPE] = {
IF s.node=NIL THEN RETURN [MTSt];
RETURN[s.node.Substr[s.place]]};
Empty:
PUBLIC
PROC[n:
ROPE]
RETURNS [
BOOL] =
{RETURN[n.Length=0]};
EmptyS:
PUBLIC
PROC[n: Stream]
RETURNS [
BOOL] =
{RETURN[n.node=NIL]};
MyFetch:
PROC[data:
REF, index:
INT]
RETURNS[
CHAR] =
TRUSTED {
fh: FileHandle ← NARROW[data];
IF index >= fh.len THEN ERROR BoundsError;
RETURN[(fh.p+(index/2))[index MOD 2]]};
Finalizer:
PROC = {
DO
fh: FileHandle = NARROW -- LOOPHOLE -- [SafeStorage.FQNext[fq]];
Close[fh];
ENDLOOP};
Item:
PUBLIC
PROC[s: Stream]
RETURNS[c:
CHAR, ns: Stream] = {
IF s.node=NIL THEN RETURN[0C, s];
ns ← [place: s.place+1, node: s.node];
c ← s.node.Fetch[s.place];
IF ns.place=s.node.Length THEN ns.node ← NIL;
};
MakeInt:
PUBLIC
PROC[n:
ROPE]
RETURNS[cnt:
INT] = {
RETURN[IO.RIS[n].GetInt[]]};
MakeNUM:
PUBLIC
PROC[i:
INT]
RETURNS [
ROPE] = {
RETURN[IO.PutFR[,IO.int[i]]]};
MyMap: Rope.MapType =
TRUSTED {
fh: FileHandle ← NARROW[base];
IF start>fh.len THEN ERROR BoundsError;
FOR i: INT IN [start..MIN[fh.len, start+len]) DO
IF action[(fh.p+(i/2))[i MOD 2]] THEN RETURN[TRUE];
ENDLOOP;
RETURN[FALSE]};
NewStream:
PUBLIC
PROC[n:
ROPE]
RETURNS[s: Stream] = {
IF Empty[n] THEN n ← NIL;
RETURN[[place: 0, node: n]]
};
Open: PROC [name: ROPE]
RETURNS [fh: FileHandle, len:
INT] = {
file: FS.OpenFile ← FS.nullOpenFile;
file ← FS.Open[name: name, lock: $read
! FS.Error--[error: FS.ErrorDesc]-- => IF error.code=$unknownFile THEN CONTINUE];
IF file = FS.nullOpenFile THEN RETURN[NIL,0];
fh ← NEW[FileRecord];
fh.s ← VM.Allocate[file.GetInfo[].pages];
TRUSTED {
fh.p ← VM.AddressForPageNumber[fh.s.page];
file.Read[from: 0, nPages: fh.s.count, to: fh.p]};
(fh.s).MakeReadOnly[];
len ← file.GetInfo[].bytes;
OpenFiles ← CONS[fh, OpenFiles];
};
Close:
PROC [f: FileHandle] =
{TRUSTED{(f.s).Free[]};
FOR t: LIST OF FileHandle ← OpenFiles, t.rest UNTIL t=NIL
DO IF t.first=f THEN t^ ← t.rest^
ENDLOOP};
StringToFile:
PUBLIC
PROC[name:
ROPE]
RETURNS[ans:
ROPE] = {
fi: FileHandle;
len: INT;
IF name = NIL THEN PL.RErr["File name must be non-null string"];
IF name.Length >= 100 THEN PL.RErr["File name too long (>100)"];
ans ← NIL;
[fi, len] ← Open[name];
IF fi=NIL THEN ans ← NIL
ELSE {fi.len ← len;
ans ← Rope.MakeRope[fi, len, MyFetch, MyMap];
IF ans.Length < minCoerceSize THEN ans ← ans.Flatten[]};
};
Sub:
PUBLIC
PROC[n:
ROPE, inx:
INT]
RETURNS[
CHAR] = {
RETURN[n.Fetch[inx]]};
SubStream:
PUBLIC
PROC[s:Stream,i:
INT]
RETURNS [
CHAR] = {
RETURN[IF s.node = NIL THEN '\000 ELSE Sub[s.node,s.place+i]];
};
SubString:
PUBLIC
PROC[str:
ROPE, ii, jj:
INT]
RETURNS [ans:
ROPE] =
{RETURN[str.Substr[ii, jj-ii]]};
SubStringStream:
PUBLIC
PROC[s: Stream,i,j:
INT]
RETURNS [
ROPE] = {
RETURN[IF s.node = NIL THEN MTSt ELSE SubString[s.node,s.place+i, s.place+j]];
};
fq ← SafeStorage.NewFQ[];
SafeStorage.EstablishFinalization[CODE[FileRecord], 1, fq];
TRUSTED{Process.Detach[FORK Finalizer]}
}.