BlackCherrySidedoorImpl.mesa
Copyright Ó 1990, 1993 by Xerox Corporation. All rights reserved.
Willie-Sue, October 25, 1990 5:40:06 pm PDT
Willie-s, July 20, 1993 5:15 pm PDT
DIRECTORY
BlackCherry,
BlackCherryInternal,
BlackCherrySidedoor,
IO,
RefText,
Rope;
BlackCherrySidedoorImpl: CEDAR MONITOR
IMPORTS
BlackCherryInternal, BlackCherrySidedoor, IO, Rope
EXPORTS
BlackCherryInternal
~ BEGIN OPEN BlackCherry, BlackCherryInternal, BlackCherrySidedoor;
ROPE: TYPE ~ Rope.ROPE;
STREAM: TYPE ~ IO.STREAM;
Header/Attribute names
Creating new logs from other sources
BCMailLog: PUBLIC PROC[
fileData: BlackCherry.BCFileData, strmProc: MsgFromStreamProc, ropeProc: MsgFromRopesProc]
RETURNS[ok: BOOL ¬ FALSE] = {
writeStream: STREAM = fileData.writeStream;
posForEntry: INT ~ writeStream.GetIndex[];
endOfMsgs, posForMsgs: INT;
numMsgs: INT ¬ 0;
msgH, lastMsgH, thisMsgH: MsgHandle;
writeStream.PutF[relTocPointerEntryTemplate, [integer[0]], [integer[0]] ];
posForMsgs ¬ writeStream.GetIndex[];
DO
entryPos, msgTemplatePos, headersPos, thisTextLen, thisFormatLen: INT;
streamForMsg: STREAM;
thisMsgID, text, formatting: ROPE;
unRead: BOOL;
IF strmProc # NIL THEN {
[streamForMsg, thisMsgID, unRead, thisTextLen, thisFormatLen] ¬ strmProc[];
IF streamForMsg = NIL THEN EXIT;
}
ELSE {
[thisMsgID, text, formatting, unRead] ¬ ropeProc[];
IF thisMsgID = NIL THEN EXIT;
IF NOT Rope.IsEmpty[formatting] THEN text ¬ text.Substr[1];
};
numMsgs ¬ numMsgs + 1;
writeStream.SetIndex[entryPos ¬ writeStream.GetLength[]];
writeStream.PutF1[headerEntryTemplate, [integer[0]] ];
msgTemplatePos ¬ writeStream.GetIndex[];
writeStream.PutF[createMsgTemplate, [rope[thisMsgID]], [integer[0]], [integer[0]] ];
headersPos ¬ writeStream.GetIndex[];
IF streamForMsg # NIL THEN
CopyBytes[to: writeStream, from: streamForMsg, num: thisTextLen+thisFormatLen]
ELSE {
writeStream.PutRope[text];
writeStream.PutRope[formatting];
thisTextLen ¬ text.Length[];
thisFormatLen ¬ formatting.Length[];
};
writeStream.PutChar['\r];
writeStream.SetIndex[msgTemplatePos];
writeStream.PutF[createMsgTemplate, [rope[thisMsgID]], [integer[thisTextLen]], [integer[thisFormatLen]] ];
writeStream.SetIndex[entryPos];
writeStream.PutF1[headerEntryTemplate, [integer[writeStream.GetLength[] - entryPos]] ];
thisMsgH ¬ NEW[MsgHandleRec ¬ [headersPos: headersPos, textLen: thisTextLen, formatPos: headersPos+thisTextLen, formatLen: thisFormatLen] ];
thisMsgH.unRead ¬ unRead;
thisMsgH.entryStart ¬ entryPos;
thisMsgH.entryLen ¬ writeStream.GetLength[] - entryPos;
IF ( msgH = NIL )
THEN msgH ¬ lastMsgH ¬ thisMsgH
ELSE IF ( thisMsgH # NIL )
THEN { lastMsgH.next ¬ thisMsgH; lastMsgH ¬ thisMsgH };
ENDLOOP;
endOfMsgs ¬ writeStream.GetLength[];
writeStream.SetIndex[posForEntry];
writeStream.PutF[relTocPointerEntryTemplate, [integer[posForMsgs-posForEntry]], [integer[endOfMsgs]] ];
[] ¬ BlackCherryInternal.WriteTOC[fileData.readStream, writeStream, numMsgs, 0, msgH, TRUE];
fileData.writeStream.Close[];
fileData.readStream.Close[ ! IO.Error => CONTINUE];
ok ¬ TRUE;
};
Buffered Stream Copy
bufsiz: NAT ~ RefText.page;
copyBuffer: REF TEXT ¬ NEW[TEXT[bufsiz]];
CopyBytes: PROC [to, from: IO.STREAM, num: INT] ~ {
bytes: INT ¬ num;
WHILE ( bytes >= bufsiz ) DO
[] ¬ from.GetBlock[copyBuffer, 0, bufsiz];
to.PutBlock[copyBuffer];
bytes ¬ bytes - bufsiz;
ENDLOOP;
IF ( bytes # 0 ) THEN {
[] ¬ from.GetBlock[copyBuffer, 0, bytes];
to.PutBlock[copyBuffer];
};
};
END.