<> <> <> <<>> <> <<1) a file whose server name contains ".alpine" is presumed to be an Alpine file.>> <<2) the special server name "StableStorage" identifies a file residing in stable storage; the file name syntax is [StableStorage]copy.broadside where bank in [0..15], copy in [0..3], and broadside in [0..1].>> <<3) any other file is presumed to be an ordinary FS file.>> <> <<>> <<*** Currently, all of the code for accessing StableFS is commented out. ***>> <<>> DIRECTORY AlpineFS USING [Open, Create, OpenOrCreate, StreamOpen], BasicTime USING [GMT, nullGMT], <> FS USING [--Close,-- ComponentPositions, Create, --Error,-- ExpandName, Lock, Open, OpenFile, OpenOrCreate, StreamOpen, --StreamFromOpenFile,-- AccessOptions, StreamOptions, defaultStreamOptions, ByteCount, StreamBufferParms, defaultStreamBufferParms, ExtendFileProc, nullOpenFile], IO USING [STREAM], Rope USING [Equal, Find, ROPE, Substr], <> GeneralFS; GeneralFSImpl: CEDAR PROGRAM IMPORTS AlpineFS, --Convert,-- FS, Rope--, StableFS-- EXPORTS GeneralFS ~ BEGIN ROPE: TYPE = Rope.ROPE; STREAM: TYPE = IO.STREAM; FileClass: TYPE = {local, alpine, stable}; GuessClass: PROC [name: ROPE, wDir: ROPE] RETURNS [class: FileClass, fname: ROPE] ~ { cp: FS.ComponentPositions; server: ROPE; [fname, cp] _ FS.ExpandName[name, wDir]; server _ Rope.Substr[fname, cp.server.start, cp.server.length]; class _ SELECT TRUE FROM Rope.Find[server, ".Alpine", 0, FALSE] # -1 => alpine, Rope.Equal[server, "StableStorage", FALSE] => stable, ENDCASE => local; }; <> <copy.broadside.>> <> <> <> <> <> <> <> <> <> <<};>> Open: PUBLIC PROC [name: ROPE, lock: FS.Lock _ $read, wantedCreatedTime: BasicTime.GMT _ BasicTime.nullGMT, remoteCheck: BOOL _ TRUE, wDir: ROPE _ NIL ] RETURNS [FS.OpenFile] ~ { fname: ROPE; class: FileClass; [class, fname] _ GuessClass[name, wDir]; RETURN[ SELECT class FROM local => FS.Open[fname, lock, wantedCreatedTime, remoteCheck, wDir], alpine => AlpineFS.Open[name: fname, wantedCreatedTime: wantedCreatedTime, access: lock, wDir: wDir], < StableFS.Open[NameToStableID[fname]],>> ENDCASE => FS.nullOpenFile]; }; Create: PUBLIC PROC [name: ROPE, setPages: BOOL _ TRUE, pages: INT _ 0, setKeep: BOOL _ FALSE, keep: CARDINAL _ 1, wDir: ROPE _ NIL ] RETURNS [FS.OpenFile] ~ { fname: ROPE; class: FileClass; [class, fname] _ GuessClass[name, wDir]; RETURN[ SELECT class FROM local => FS.Create[fname, setPages, pages, setKeep, keep, wDir], alpine => AlpineFS.Create[name: fname, pages: pages, keep: keep, wDir: wDir], < StableFS.Create[NameToStableID[fname]],>> ENDCASE => FS.nullOpenFile]; }; OpenOrCreate: PUBLIC PROC [name: ROPE, keep: CARDINAL _ 1, pages: INT _ 5, wDir: ROPE _ NIL ] RETURNS [FS.OpenFile] ~ { fname: ROPE; class: FileClass; [class, fname] _ GuessClass[name, wDir]; RETURN[ SELECT class FROM local => FS.OpenOrCreate[fname, keep, pages, wDir], alpine => AlpineFS.OpenOrCreate[name: fname, pages: pages, keep: keep, wDir: wDir], < StableFS.Open[NameToStableID[fname]],>> ENDCASE => FS.nullOpenFile]; }; StreamOpen: PUBLIC PROC [fileName: ROPE, accessOptions: FS.AccessOptions _ $read, streamOptions: FS.StreamOptions _ FS.defaultStreamOptions, keep: CARDINAL _ 1, createByteCount: FS.ByteCount _ 2560, streamBufferParms: FS.StreamBufferParms _ FS.defaultStreamBufferParms, extendFileProc: FS.ExtendFileProc _ NIL, wantedCreatedTime: BasicTime.GMT _ BasicTime.nullGMT, remoteCheck: BOOL _ TRUE, wDir: ROPE _ NIL ] RETURNS [STREAM] ~ { <> <> <> <<$read => StableFS.Open[sid],>> <<$create => StableFS.Create[sid],>> <<$append => StableFS.Open[sid],>> <<$write => StableFS.Open[sid],>> < ERROR;>> <> < FS.Close[open]]];>> <<};>> fname: ROPE; class: FileClass; [class, fname] _ GuessClass[fileName, wDir]; RETURN[ SELECT class FROM local => FS.StreamOpen[fname, accessOptions, streamOptions, keep, createByteCount, streamBufferParms, extendFileProc, wantedCreatedTime, remoteCheck, wDir], alpine => AlpineFS.StreamOpen[fname, accessOptions, [], keep, createByteCount, streamBufferParms, extendFileProc, wDir], < StableStreamOpen[NameToStableID[fname]],>> ENDCASE => NIL]; }; END. <> <>