-- file: SortMailMain.mesa
-- edited by Brotz, August 20, 1982 5:31 PM
-- edited by Taft, May 8, 1983 5:07 PM

DIRECTORY
csD: FROM "CoreStreamDefs",
DateAndTime,
exD: FROM "ExceptionDefs",
inD: FROM "InteractorDefs",
IODefs,
intCommon,
MessageParse,
mfD: FROM "MailFormatDefs",
Storage,
TimeDefs,
vmD: FROM "VirtualMgrDefs";

SortMailMain: PROGRAM
IMPORTS csD, DateAndTime, exD, intC: intCommon, IODefs, MessageParse, mfD, Storage,
vmD =

BEGIN

SortRecord: TYPE = RECORD
[tocIndex: vmD.TOCIndex,
time: TimeDefs.PackedTime];


Sort: PROCEDURE [newFile: STRING] =
BEGIN
toc: vmD.TOCHandle ← intC.tocTextNbr.toc;
key, slot: CARDINAL;
outOfOrder: BOOLEAN ← FALSE;
sortArray: POINTER TO ARRAY [0 .. 0) OF SortRecord;
dm: vmD.DisplayMessagePtr;
time: TimeDefs.PackedTime;
fieldRec: ARRAY [0 .. 1) OF MessageParse.FieldRec;
fieldRecDesc: MessageParse.FieldRecDescriptor ← DESCRIPTOR[fieldRec];
IF toc = NIL THEN {exD.DisplayExceptionString["No current mail file."L]; RETURN};
key ← vmD.WaitForLock[toc];
IF toc.indexFF <= 2 THEN
BEGIN
exD.DisplayExceptionString["Current mail file is already sorted."L];
vmD.UnlockTOC[toc, key];
RETURN;
END;
sortArray ← Storage.Node[SIZE[SortRecord] * (toc.indexFF - 1)];
fieldRec[0].name ← "Date"L;
dm ← vmD.AllocateDisplayMessageObject[];
FOR tocIndex: vmD.TOCIndex IN [1 .. toc.indexFF) DO
vmD.LoadDisplayMessage[toc, key, tocIndex, dm];
MessageParse.ParseMessage[dm, fieldRecDesc];
IF fieldRec[0].found = 0 THEN time ← LAST[LONG CARDINAL]
ELSE BEGIN
dateString: STRING ← [100];
dateString.length ← MIN[100, fieldRec[0].bodyEnd - fieldRec[0].bodyStart];
FOR i: CARDINAL IN [0 .. dateString.length) DO
dateString[i] ← vmD.GetMessageChar[dm, fieldRec[0].bodyStart + i];
ENDLOOP;
[time, ] ← DateAndTime.Parse[dateString
! DateAndTime.Unintelligible => {time ← LAST[LONG CARDINAL]; CONTINUE}];
END;
FOR i: CARDINAL DECREASING IN [0 .. tocIndex - 1) DO
IF time >= sortArray[i].time THEN {slot ← i + 1; EXIT};
REPEAT
FINISHED => slot ← 0;
ENDLOOP;
FOR i: CARDINAL DECREASING IN [slot .. tocIndex - 1) DO
sortArray[i + 1] ← sortArray[i];
ENDLOOP;
sortArray[slot] ← SortRecord[tocIndex, time];
IF slot + 1 < tocIndex THEN outOfOrder ← TRUE;
vmD.FlushDisplayMessage[dm, key];
ENDLOOP;
vmD.FreeVirtualMessageObject[dm];
IF outOfOrder THEN
BEGIN
mailFileStream, newFileStream: csD.StreamHandle;
fp: vmD.TOCFixedPart;

PutStampChar: PROCEDURE [c: CHARACTER] =
{csD.Write[newFileStream, c]};

mailFileStream ← csD.Open[toc.mailFile, byte, write];
newFileStream ← csD.OpenFromName[newFile, byte, write];
FOR tocIndex: vmD.TOCIndex IN [1 .. toc.indexFF) DO
vmD.GetTOCFixedPart[toc, key, sortArray[tocIndex - 1].tocIndex, @fp];
mfD.CreateStamp[@fp, PutStampChar];
csD.SetPosition[mailFileStream, csD.MapPageByteToPosition[fp.firstPage, fp.firstByte] + fp.offsetToHeader];
csD.StreamCopy
[from: mailFileStream, to: newFileStream, fromItems: fp.textLength];
ENDLOOP;
csD.Close[newFileStream];
csD.Close[mailFileStream];
END
ELSE exD.DisplayExceptionString["Mail file is already sorted."L];
Storage.Free[sortArray];
vmD.UnlockTOC[toc, key];
END; -- of Sort --


newFile: STRING ← [80];
IODefs.WriteString["New file: "];
IODefs.ReadLine[newFile];
Sort[newFile];


END. -- of SortMailMain --