-- AppendOp.mesa -- Edited by Schroeder, Wednesday Nov. 5, 1980 2:32 pm PST. -- Edited by Brotz, November 30, 1981 10:41 AM DIRECTORY csD: FROM "CoreStreamDefs" USING [Close, GetLength, OpenFromName, Position, Read, Reset, SetPosition, StreamHandle, Write, WriteBlock], exD: FROM "ExceptionDefs" USING [moveTargetExists], inD: FROM "InteractorDefs" USING [AskUserToConfirm], mfD: FROM "MailFormatDefs" USING [CreateStamp, ParseStamp], opD: FROM "OperationsDefs" USING [NoMoveReason], tsD: FROM "TOCSelectionDefs" USING [FirstSelectedEntry, NextSelectedEntry], vmD: FROM "VirtualMgrDefs" USING [GetTOCFixedPart, PageNumber, TOCFixedPart, TOCFixedPartPtr, TOCHandle, TOCIndex], VMDefs USING [Deactivate, Error, Page, pageByteSize, PageNumber, ReadPage]; AppendOp: PROGRAM IMPORTS csD, inD, mfD, tsD, vmD, VMDefs EXPORTS opD = BEGIN NoMessagesMoved: PUBLIC ERROR [reason: opD.NoMoveReason] = CODE; -- May be raised by AppendMailToFileOperation if no messages are actually moved. AppendMailToFileOperation: PUBLIC PROCEDURE [toc: vmD.TOCHandle, key: CARDINAL, appendFileName: STRING] = -- Opens the appendFile named, appends all undeleted selected messages to that file with -- stamps, closes append file. Skips any messages in the range that are deleted. -- May raise NoMessagesMoved. BEGIN outputSH: csD.StreamHandle _ csD.OpenFromName[appendFileName, byte, append]; tOCEntry: vmD.TOCFixedPart; tb: vmD.TOCFixedPartPtr = @tOCEntry; b, putCount, bytesToCopy, bytesOnThisPage, inBufferStart: CARDINAL; messageIndex: vmD.TOCIndex; inBuffer: VMDefs.Page; inBufferPageNumber: VMDefs.PageNumber; failureState: opD.NoMoveReason _ noUndeleted; -- internal procedures of AppendMailToFileOperation AGetChar: PROCEDURE RETURNS [CHARACTER] = BEGIN RETURN[csD.Read[outputSH]]; END; -- of AGetChar -- APutChar: PROCEDURE [c: CHARACTER] = BEGIN putCount _ putCount + 1; csD.Write[outputSH, c]; END; -- of AGetChar -- -- code for AppendMailToFileOperation BEGIN -- for EXITS -- ENABLE VMDefs.Error => BEGIN csD.Reset[outputSH]; failureState _ IF reason = resources THEN diskFull ELSE diskError; GOTO bailOut; END; position: csD.Position = csD.GetLength[outputSH]; IF position # 0 THEN BEGIN -- see if target file looks like a mail file. stampOk: BOOLEAN; csD.SetPosition[outputSH, 0]; stampOk _ mfD.ParseStamp[AGetChar, tb]; csD.Reset[outputSH]; IF ~stampOk THEN {IF ~inD.AskUserToConfirm[exD.moveTargetExists] THEN GOTO bailOut}; END; FOR messageIndex _ tsD.FirstSelectedEntry[toc, key], tsD.NextSelectedEntry[toc, key, messageIndex] UNTIL messageIndex = 0 DO -- loop for each message vmD.GetTOCFixedPart[toc, key, messageIndex, tb]; IF ~tb.deleted THEN BEGIN -- copy this message -- IF tb.changed THEN BEGIN putCount _ 0; mfD.CreateStamp[tb, APutChar]; b _ tb.firstByte + putCount; tb.firstPage _ tb.firstPage + b / 512; tb.firstByte _ b MOD 512; tb.offsetToHeader _ tb.offsetToHeader - putCount; END; inBufferPageNumber _ tb.firstPage; inBufferStart _ tb.firstByte; bytesToCopy _ tb.offsetToHeader + tb.textLength; UNTIL bytesToCopy = 0 DO inBuffer _ VMDefs.ReadPage[[toc.mailFile, inBufferPageNumber], 2]; bytesOnThisPage _ MIN[bytesToCopy, VMDefs.pageByteSize - inBufferStart]; csD.WriteBlock[outputSH, inBuffer, inBufferStart, bytesOnThisPage ! UNWIND => VMDefs.Deactivate[inBuffer]]; inBufferStart _ 0; inBufferPageNumber _ inBufferPageNumber + 1; bytesToCopy _ bytesToCopy - bytesOnThisPage; VMDefs.Deactivate[inBuffer]; ENDLOOP; failureState _ ok; END; -- copy this message -- ENDLOOP; -- loop for each message EXITS bailOut => NULL; END; -- of EXITS block csD.Close[outputSH]; IF failureState # ok THEN ERROR NoMessagesMoved[failureState]; END; -- of AppendMailToFileOperation -- END. -- of AppendOp --z20461(529)\f1