LoadAltoDumpFile.mesa: Read Alto dump format file
Copyright Ó 1987 by Xerox Corporation. All rights reserved.
taken from description in [Indigo]<AltoDocs>EXECUTIVE.TTY
Willie-Sue, September 29, 1987 10:58:39 am PDT

DIRECTORY
Basics,
BasicTime USING [FromPupTime, GMT],
Commander,
CommandTool,
FS,
IO,
Loader USING [BCDBuildTime],
RefText,
Rope,
ViewerClasses USING [Viewer],
ViewerIO USING [CreateViewerStreams],
ViewerOps USING [FindViewer, OpenIcon];
LoadAltoDumpFile: CEDAR MONITOR
IMPORTS
BasicTime, Commander, CommandTool, FS, IO, Loader, Rope, ViewerIO, ViewerOps
= BEGIN
ROPE: TYPE = Rope.ROPE;
STREAM: TYPE = IO.STREAM;
Viewer: TYPE = ViewerClasses.Viewer;
nameBuffer: REF TEXT = NEW[TEXT[RefText.line]];
copyBuffer: REF TEXT = NEW[TEXT[RefText.page]];
copyBufferPtr: LONG POINTER TO CARD16
LOOPHOLE[LOOPHOLE[copyBuffer, LONG POINTER] + 2];
out: STREAM;
BlockType: TYPE = BYTE;
NameBlock: BlockType = 377B;
DataBlock: BlockType = 376B;
ErrorBlock: BlockType = 375B;
EndBlock: BlockType = 374B;
DateBlock: BlockType = 373B;
-- * * * * * * * * * * * * * * ** * * * * * * * * * * * * * *
Main: Commander.CommandProc = {
dumpFile: ROPE = CommandTool.NextArgument[cmd];
wDir: ROPE = CommandTool.CurrentWorkingDirectory[];
fullName: ROPE = FS.ExpandName[dumpFile, wDir].fullFName;
strm: STREAMFS.StreamOpen[fileName: fullName];
IF strm = NIL THEN {
cmd.out.PutF["Could not open %g - quitting\n", [rope[fullName]] ];
RETURN;
};
out ← TSStream["LoadAltoDumpFile"];
out.PutF["\n\n<<<<<<<<<< LoadAltoDumpFile of %g\n",
 [time[Loader.BCDBuildTime[LoadAltoDumpFile.Main]]] ];
out.PutF["\t working directory is %g\n", [rope[wDir]] ];
DoLoadDumpFile[strm, fullName, wDir];
};
DoLoadDumpFile: PROC[strm: STREAM, dumpfile, wDir: ROPE ] = {
lastFile: ROPE;
lastStrm: STREAM;
badChecksums: CARD16;
lastTotalBytes: INT ← 0;
CleanUp: PROC = {
IF lastStrm = NIL THEN RETURN;
lastStrm.Close[];
IF lastTotalBytes # 0 THEN
out.PutF[" (%g bytes)\n", [integer[lastTotalBytes]] ];
lastStrm ← NIL;
lastFile ← NIL;
};
DO
bt: BlockType = LOOPHOLE[strm.GetChar[]];
SELECT bt FROM
EndBlock => {
CleanUp[];
out.PutF[">>>>>>>>>>Done loading %g\n", [rope[dumpfile]] ];
RETURN};
NameBlock => {
CleanUp[];
lastFile ← ReadName[strm, nameBuffer];
badChecksums ← 0;
};
DataBlock => {
count: CARD16 = GetWord[strm];
checkSum: CARD16 = GetWord[strm];
computed: CARD16 ← count;
IF lastStrm = NIL THEN {  -- skipping this data
strm.SetIndex[strm.GetIndex[] + count];
LOOP;
};
[] ← strm.GetBlock[copyBuffer, 0, count];
lastStrm.PutBlock[copyBuffer];
lastTotalBytes ← lastTotalBytes + count;
FOR i: CARD16 IN [0..count/2) DO
TRUSTED { computed ← computed + (copyBufferPtr+i)^ };
ENDLOOP;
IF computed = checkSum THEN LOOP;
out.PutF["Computed %bB # given checksum %bB; dumpfile pos %g\n",
[cardinal[computed]], [cardinal[checkSum]], [integer[strm.GetIndex[]]] ];
out.PutF["**** Skipping file %g\n", [rope[lastFile]] ];
lastTotalBytes ← 0;
CleanUp[];
};
DateBlock => {
ln: Basics.LongNumber;
gmt: BasicTime.GMT;
ok: BOOLTRUE;
try: FS.OpenFile ← FS.nullOpenFile;
ln.hh ← LOOPHOLE[strm.GetChar[]];
ln.hl ← LOOPHOLE[strm.GetChar[]];
ln.lh ← LOOPHOLE[strm.GetChar[]];
ln.ll ← LOOPHOLE[strm.GetChar[]];
[] ← strm.GetChar[];
[] ← strm.GetChar[];
gmt ← BasicTime.FromPupTime[LOOPHOLE[ln]];
IF lastStrm # NIL THEN LOOP; -- ignore if not right after name block
IF lastFile = NIL THEN LOOP;
see if this file already exists
try ← FS.Open[name: lastFile, wantedCreatedTime: gmt, wDir: wDir ! FS.Error => {
IF error.code # $unknownCreatedTime THEN {
out.PutF["\n****FS error with explanation: %g - quitting\n",
 [rope[error.explanation]] ];
ok ← FALSE;
};
CONTINUE;
} ];
IF ~ ok THEN { CleanUp[]; RETURN };
IF try = FS.nullOpenFile THEN {
lastStrm ← FS.StreamOpen[fileName: lastFile, accessOptions: $create, wDir: wDir];
FS.SetByteCountAndCreatedTime[
file: FS.OpenFileFromStream[lastStrm], created: gmt];
out.PutF["***Creating %g of %g ... ", [rope[lastFile]], [time[gmt]] ];
lastTotalBytes ← 0;
}
ELSE {
out.PutF["\t%g of %g already exists - skipping\n",
[rope[lastFile]], [time[gmt]] ];
FS.Close[try];
};
};
ENDCASE => {
out.PutF["\n BadBlockType %g - quitting\n", [cardinal[bt]] ];
CleanUp[];
RETURN
};
ENDLOOP;
};
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
ReadName: PROC[in: STREAM, buffer: REF TEXT] RETURNS[ROPE] = {
Converts from the MB name format to a rope.
i: INTEGER ← 0;
[] ← in.GetChar[];  -- throw away two bytes first
[] ← in.GetChar[];
DO
char: CHAR ← in.GetChar[];
IF char = '\000 THEN EXIT;
buffer[i] ← char;
i ← i + 1;
ENDLOOP;
buffer.length ← i;
RETURN[Rope.FromRefText[buffer]];
};
GetWord: PROC[in: STREAM] RETURNS[CARD16] = {
num: Basics.ShortNumber;
num.hi ← LOOPHOLE[in.GetChar[]];
num.lo ← LOOPHOLE[in.GetChar[]];
RETURN[num.sc];
};
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
TSStream: PROC[name: ROPE] RETURNS [STREAM] = {
v: ViewerClasses.Viewer ← ViewerOps.FindViewer[name];
out: STREAM ← ViewerIO.CreateViewerStreams[name, v].out;
IF v#NIL THEN IF v.iconic THEN ViewerOps.OpenIcon[v];
RETURN[out];
};
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Commander.Register["LoadAltoDumpFile", Main, "Reads and Loads an Alto Dump File"];
END.