-- XFileIOImpl.mesa -- Created by Jeff Weinstein on 6-May-87 23:10:07 DIRECTORY CString, Heap, MFile, MStream, Stream, String, XFileIO; XFileIOImpl:PROGRAM IMPORTS CString, Heap, MFile, MStream, Stream, String EXPORTS XFileIO = BEGIN z:UNCOUNTED ZONE ← Heap.systemZone; FiOpenForRead:PUBLIC PROCEDURE[name:CString.CString] RETURNS [fid:Stream.Handle] = BEGIN string:LONG STRING ← CString.CStringToLongString[name,z]; fid ← MStream.ReadOnly[string,[NIL,NIL] ! MStream.Error => { fid ← NIL; CONTINUE;}]; String.FreeString[z, string]; END; FiClose:PUBLIC PROCEDURE[fid:Stream.Handle] = BEGIN Stream.Delete[fid]; END; FiRead:PUBLIC PROCEDURE[buf:LONG POINTER, itemsize:CARDINAL, nitem:CARDINAL, fid:Stream.Handle] RETURNS[itemsRead:CARDINAL] = BEGIN why:Stream.CompletionCode; bytes:CARDINAL; [bytesTransferred:bytes,why:why] ← Stream.GetBlock[fid,[buf,0,nitem*itemsize]]; itemsRead ← bytes / itemsize; END; SetDefaultFontPath:PUBLIC PROCEDURE[name:CString.CString] = BEGIN string:LONG STRING ← CString.CStringToLongString[name,z]; path:MFile.SearchPath ← z.NEW[MFile.SearchPathObject[1]]; path.length ← 1; path.directories[0] ← string; [] ← MFile.SetSearchPath[path]; String.FreeString[z,string]; z.FREE[@path]; END; SetFontPath:PUBLIC PROCEDURE[path:XFileIO.FontPath] = BEGIN sPath:MFile.SearchPath ← z.NEW[MFile.SearchPathObject[path.npaths]]; sPath.length ← path.npaths; FOR i:INTEGER IN [0..path.npaths) DO sPath.directories[i] ← CString.CStringToLongString[path.paths[i],z]; ENDLOOP; [] ← MFile.SetSearchPath[sPath]; FOR i:INTEGER IN [0..path.npaths) DO String.FreeString[z,sPath.directories[i]]; ENDLOOP; z.FREE[@sPath]; END; ExpandFontName:PUBLIC PROCEDURE[name:CString.CString, pathName:LONG POINTER TO CString.CString, zone:UNCOUNTED ZONE] RETURNS[nameLen:CARDINAL] = BEGIN numNames:CARDINAL; names:LONG POINTER TO ARRAY [0..0) OF LONG STRING; pattern:LONG STRING ← CString.CStringToLongString[name,z]; [names,numNames] ← LookupFiles[pattern, 1]; IF numNames # 1 THEN BEGIN nameLen ← 0; pathName↑ ← LOOPHOLE[LONG[0]]; END ELSE BEGIN nameLen ← names[0].length; pathName↑ ← CString.LongStringToCString[names[0],zone]; END; FreeNames[names,numNames]; String.FreeString[z,pattern]; END; ExpandFontNamePattern:PUBLIC PROCEDURE[pattern:CString.CString, maxNames:CARDINAL, zone:UNCOUNTED ZONE] RETURNS [paths:XFileIO.FontPath] = BEGIN names:LONG POINTER TO ARRAY [0..0) OF LONG STRING; numNames:CARDINAL; string:LONG STRING ← CString.CStringToLongString[pattern,z]; paths ← zone.NEW[XFileIO.FontPathRec]; [names, numNames] ← LookupFiles[string,maxNames]; IF numNames > 0 THEN BEGIN paths.npaths ← numNames; -- paths.length ← zone.NEW[ARRAY[0..numNames) OF INTEGER]; -- paths.paths ← zone.NEW[ARRAY[0..numNames) OF CString.CString]; paths.length ← Heap.MakeNode[z:zone, n:SIZE[INTEGER]*numNames]; paths.paths ← Heap.MakeNode[z:zone, n:SIZE[CString.CString]*numNames]; FOR i:CARDINAL IN [0..numNames) DO paths.length[i] ← names[i].length; paths.paths[i] ← CString.LongStringToCString[names[i],zone]; ENDLOOP; END ELSE paths↑ ← [0,NIL,NIL]; FreeNames[names,numNames]; String.FreeString[z,string]; END; LookupFiles:PROCEDURE[pattern:LONG STRING, maxNames:CARDINAL] RETURNS [names:LONG POINTER TO ARRAY [0..0) OF LONG STRING, numNames:CARDINAL] = BEGIN EnumProc:MFile.EnumerateProc = BEGIN names[numNames] ← String.CopyToNewString[fullName,z]; numNames ← numNames + 1; IF numNames >= maxNames THEN done ← TRUE; END; numNames ← 0; -- names ← z.NEW[ARRAY[0..maxNames) OF LONG STRING]; names ← Heap.MakeNode[z:z, n:SIZE[LONG STRING]*maxNames]; MFile.EnumerateDirectory[name:pattern, proc:EnumProc, which:filesOnly]; END; FreeNames:PROCEDURE[names:LONG POINTER TO ARRAY [0..0) OF LONG STRING, numNames:CARDINAL] = BEGIN FOR i:CARDINAL IN [0..numNames) DO String.FreeString[z,names[i]]; ENDLOOP; z.FREE[@names]; END; END...